{"version":3,"file":"Scroll_Mask.B7G6-Rrc.mjs","names":["useRef"],"sources":["https:/framerusercontent.com/modules/rAvnUyHmG45uSwFWbaDl/ArcFbI6osPFuQPy4kvfy/Scroll_Mask.js"],"sourcesContent":["import{jsx as _jsx,jsxs as _jsxs}from\"react/jsx-runtime\";import{forwardRef,useEffect,useRef}from\"react\";const FADE=40// px, width of the edge fade\n;// A scroll container clips both axes, so anything a child paints outside the\n// padding box — a glow, an outer box-shadow, a focus ring — is cut off. The row\n// is given this much internal room on every side and pulled back out with a\n// matching negative margin, so the box grows without moving the layout.\n// Raise it if the shadow is blurrier or more offset than this.\nconst SHADOW_ROOM=24;// Fade the items rather than the scroll container. Set to false to go back to\n// masking the container itself — simpler, but it disables backdrop-filter on\n// everything inside the row.\nconst PER_ITEM_FADE=true;const SIDES=[\"Top\",\"Right\",\"Bottom\",\"Left\"];const MASK_PROPS=[\"-webkit-mask-image\",\"mask-image\",\"-webkit-mask-size\",\"mask-size\",\"-webkit-mask-position\",\"mask-position\",\"-webkit-mask-repeat\",\"mask-repeat\"];function clearMask(node){if(!node.dataset.scrollFadeMasked)return;for(const prop of MASK_PROPS)node.style.removeProperty(prop);delete node.dataset.scrollFadeMasked;}function setItemMask(node,image,size,position){node.style.setProperty(\"-webkit-mask-image\",image);node.style.setProperty(\"mask-image\",image);node.style.setProperty(\"-webkit-mask-size\",size);node.style.setProperty(\"mask-size\",size);node.style.setProperty(\"-webkit-mask-position\",position);node.style.setProperty(\"mask-position\",position);node.style.setProperty(\"-webkit-mask-repeat\",\"no-repeat\");node.style.setProperty(\"mask-repeat\",\"no-repeat\");node.dataset.scrollFadeMasked=\"true\";}/**\n * The element that actually paints the item. Framer wraps each instance in a\n * layout-transparent container, and masking the wrapper would put the real item\n * inside a backdrop root — the very thing this is avoiding. So descend through\n * single-child wrappers that fill their parent exactly, and stop at the element\n * that is genuinely smaller (the pill's label, say).\n */function maskTarget(child){let node=child;for(let depth=0;depth<4;depth++){if(node.children.length!==1)break;const inner=node.firstElementChild;if(!(inner instanceof HTMLElement))break;const outerRect=node.getBoundingClientRect();const innerRect=inner.getBoundingClientRect();if(Math.abs(outerRect.width-innerRect.width)>1||Math.abs(outerRect.height-innerRect.height)>1){break;}node=inner;}return node;}/**\n * How far the row may grow on each side before it escapes the nearest ancestor\n * that clips. Growing past that ancestor buys nothing — it would clip the glow\n * anyway — and on a container styled as a pill (background, radius, its own\n * overflow) the overhang turns into a stray scrollable area. So the row is only\n * allowed to expand into padding that ancestor already has.\n */function roomAllowedBy(el,want){let node=el.parentElement;while(node){const style=window.getComputedStyle(node);const clipsX=style.overflowX!==\"visible\";const clipsY=style.overflowY!==\"visible\";if(clipsX||clipsY){const limit=(side,clipped)=>clipped?Math.min(want,parseFloat(style[`padding${side}`])||0):want;return{Top:limit(\"Top\",clipsY),Bottom:limit(\"Bottom\",clipsY),Left:limit(\"Left\",clipsX),Right:limit(\"Right\",clipsX)};}node=node.parentElement;}return{Top:want,Right:want,Bottom:want,Left:want};}/**\n * Makes a row (tabs, chips, pills) scrollable when it overflows and fades\n * its edges with a real CSS mask, so the content dissolves into transparency\n * and any background can show through.\n *\n * The mask is given an explicit size matching the visible area. Its box is\n * anchored to the element's padding box and does NOT travel with the scrolled\n * content, so it must not be offset by scrollLeft — doing that pushes the mask\n * out of the viewport and makes half the row disappear.\n */export function withScrollFadeMask(Component){return /*#__PURE__*/forwardRef(function WithScrollFadeMask(props,ref){const hostRef=useRef(null);useEffect(()=>{const el=hostRef.current?.firstElementChild;if(!el)return;const vertical=window.getComputedStyle(el).flexDirection.startsWith(\"column\");// Grow the clipping box by SHADOW_ROOM on every side and take the\n// same amount back as margin. Done once per element: re-running it\n// would compound the padding.\nif(SHADOW_ROOM>0&&el.dataset.scrollFadeRoom!==\"true\"){const base=window.getComputedStyle(el);const room=roomAllowedBy(el,SHADOW_ROOM);for(const side of SIDES){if(room[side]<=0)continue;const padKey=`padding${side}`;const marginKey=`margin${side}`;const pad=parseFloat(base[padKey])||0;const margin=parseFloat(base[marginKey])||0;el.style[padKey]=`${pad+room[side]}px`;el.style[marginKey]=`${margin-room[side]}px`;}el.dataset.scrollFadeRoom=\"true\";}el.style.overflowX=vertical?\"hidden\":\"auto\";el.style.overflowY=vertical?\"auto\":\"hidden\";el.style.flexWrap=\"nowrap\";el.style.setProperty(\"scrollbar-width\",\"none\");el.style.setProperty(\"-ms-overflow-style\",\"none\");el.style.setProperty(\"-webkit-overflow-scrolling\",\"touch\");el.setAttribute(\"data-scroll-fade\",\"true\");const setMask=value=>{el.style.setProperty(\"-webkit-mask-image\",value);el.style.setProperty(\"mask-image\",value);};const setMaskGeometry=(size,position)=>{el.style.setProperty(\"-webkit-mask-size\",size);el.style.setProperty(\"mask-size\",size);el.style.setProperty(\"-webkit-mask-position\",position);el.style.setProperty(\"mask-position\",position);el.style.setProperty(\"-webkit-mask-repeat\",\"no-repeat\");el.style.setProperty(\"mask-repeat\",\"no-repeat\");};// Per-item fade. An element carrying a mask becomes a backdrop root,\n// which silently kills backdrop-filter on everything inside it — the\n// pills' blur stops sampling the page and they go flat. A mask on an\n// element does NOT break that element's own backdrop-filter, only its\n// descendants', so the fade is moved down onto the items themselves.\n// The row paints nothing of its own, so the result is identical.\nconst fadeItems=(atStart,atEnd)=>{const box=el.getBoundingClientRect();const viewStart=vertical?box.top:box.left;const viewEnd=vertical?box.bottom:box.right;for(const child of Array.from(el.children)){if(!(child instanceof HTMLElement))continue;const item=maskTarget(child);const rect=item.getBoundingClientRect();const start=vertical?rect.top:rect.left;const end=vertical?rect.bottom:rect.right;const needsStart=atStart&&start-SHADOW_ROOM<viewStart+FADE;const needsEnd=atEnd&&end+SHADOW_ROOM>viewEnd-FADE;if(!needsStart&&!needsEnd){clearMask(item);continue;}// The mask box is the item inflated by SHADOW_ROOM on every\n// side, so the item's own glow is not clipped by its mask.\nconst origin=start-SHADOW_ROOM;const from=needsStart?`transparent ${viewStart-origin}px, black ${viewStart-origin+FADE}px`:`black 0px`;const to=needsEnd?`black ${viewEnd-FADE-origin}px, transparent ${viewEnd-origin}px`:`black 100%`;setItemMask(item,`linear-gradient(to ${vertical?\"bottom\":\"right\"}, ${from}, ${to})`,`${rect.width+SHADOW_ROOM*2}px ${rect.height+SHADOW_ROOM*2}px`,`-${SHADOW_ROOM}px -${SHADOW_ROOM}px`);}};const update=()=>{const offset=vertical?el.scrollTop:el.scrollLeft;const viewport=vertical?el.clientHeight:el.clientWidth;const total=vertical?el.scrollHeight:el.scrollWidth;const atStart=offset>1;const atEnd=offset+viewport<total-1;if(PER_ITEM_FADE){setMask(\"none\");fadeItems(atStart,atEnd);return;}if(!atStart&&!atEnd){setMask(\"none\");return;}const from=atStart?`transparent 0px, black ${FADE}px`:`black 0px`;const to=atEnd?`black calc(100% - ${FADE}px), transparent 100%`:`black 100%`;setMask(`linear-gradient(to ${vertical?\"bottom\":\"right\"}, ${from}, ${to})`);setMaskGeometry(vertical?`100% ${viewport}px`:`${viewport}px 100%`,\"0px 0px\");};update();el.addEventListener(\"scroll\",update,{passive:true});const ro=new ResizeObserver(update);ro.observe(el);Array.from(el.children).forEach(c=>{if(c instanceof HTMLElement)ro.observe(c);});const mo=new MutationObserver(update);mo.observe(el,{childList:true,subtree:true});return()=>{el.removeEventListener(\"scroll\",update);ro.disconnect();mo.disconnect();for(const child of Array.from(el.children)){if(child instanceof HTMLElement)clearMask(maskTarget(child));}};},[]);return /*#__PURE__*/_jsxs(\"div\",{ref:hostRef,style:{display:\"contents\"},children:[/*#__PURE__*/_jsx(Component,{ref:ref,...props}),/*#__PURE__*/_jsx(\"style\",{children:`[data-scroll-fade=\"true\"]::-webkit-scrollbar { display: none; }`})]});});}\nexport const __FramerMetadata__ = {\"exports\":{\"withScrollFadeMask\":{\"type\":\"reactHoc\",\"name\":\"withScrollFadeMask\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./Scroll_Mask.map"],"mappings":"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"}