{"version":3,"file":"scroll.1c8ac9c4.js","sources":["../../../../utils/scroll.ts"],"sourcesContent":["/* eslint-disable */\n// @ts-nocheck\nimport { type Nullable } from '@/types/generic';\n\nexport interface BodyScrollOptions {\n reserveScrollBarGap?: boolean;\n allowTouchMove?: (el: any) => boolean;\n}\n\ninterface Lock {\n targetElement: any;\n options: BodyScrollOptions;\n}\n\n// Older browsers don't support event options, feature detect it.\nlet hasPassiveEvents = false;\nif (typeof window !== 'undefined') {\n const passiveTestOptions = {\n get passive() {\n hasPassiveEvents = true;\n return undefined;\n },\n };\n window.addEventListener('testPassive', null, passiveTestOptions);\n window.removeEventListener('testPassive', null, passiveTestOptions);\n}\n\nconst isIosDevice =\n typeof window !== 'undefined' &&\n window.navigator &&\n window.navigator.platform &&\n (/iP(ad|hone|od)/.test(window.navigator.platform) || (window.navigator.platform === 'MacIntel' && window.navigator.maxTouchPoints > 1));\n\ntype HandleScrollEvent = TouchEvent;\n\nlet locks: Array = [];\nlet documentListenerAdded: boolean = false;\nlet initialClientY: number = -1;\nlet previousBodyOverflowSetting;\nlet previousBodyPosition;\nlet previousBodyPaddingRight;\n\n// returns true if `el` should be allowed to receive touchmove events.\nconst allowTouchMove = (el: EventTarget): boolean =>\n locks.some((lock) => {\n if (lock.options.allowTouchMove && lock.options.allowTouchMove(el)) {\n return true;\n }\n\n return false;\n });\n\nconst preventDefault = (rawEvent: HandleScrollEvent): boolean => {\n const e = rawEvent || window.event;\n\n // For the case whereby consumers adds a touchmove event listener to document.\n // Recall that we do document.addEventListener('touchmove', preventDefault, { passive: false })\n // in disableBodyScroll - so if we provide this opportunity to allowTouchMove, then\n // the touchmove event on document will break.\n if (allowTouchMove(e.target)) {\n return true;\n }\n\n // Do not prevent if the event has more than one touch (usually meaning this is a multi touch gesture like pinch to zoom).\n if (e.touches.length > 1) return true;\n\n if (e.preventDefault) e.preventDefault();\n\n return false;\n};\n\nconst setOverflowHidden = (options?: BodyScrollOptions) => {\n // If previousBodyPaddingRight is already set, don't set it again.\n if (previousBodyPaddingRight === undefined) {\n const reserveScrollBarGap = !!options && options.reserveScrollBarGap === true;\n const scrollBarGap = window.innerWidth - document.documentElement.clientWidth;\n\n if (reserveScrollBarGap && scrollBarGap > 0) {\n const computedBodyPaddingRight = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'), 10);\n previousBodyPaddingRight = document.body.style.paddingRight;\n document.body.style.paddingRight = `${computedBodyPaddingRight + scrollBarGap}px`;\n }\n }\n\n // If previousBodyOverflowSetting is already set, don't set it again.\n if (previousBodyOverflowSetting === undefined) {\n previousBodyOverflowSetting = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n }\n};\n\nconst restoreOverflowSetting = () => {\n if (previousBodyPaddingRight !== undefined) {\n document.body.style.paddingRight = previousBodyPaddingRight;\n\n // Restore previousBodyPaddingRight to undefined so setOverflowHidden knows it\n // can be set again.\n previousBodyPaddingRight = undefined;\n }\n\n if (previousBodyOverflowSetting !== undefined) {\n document.body.style.overflow = previousBodyOverflowSetting;\n\n // Restore previousBodyOverflowSetting to undefined\n // so setOverflowHidden knows it can be set again.\n previousBodyOverflowSetting = undefined;\n }\n};\n\nconst setPositionFixed = () =>\n window.requestAnimationFrame(() => {\n // If previousBodyPosition is already set, don't set it again.\n if (previousBodyPosition === undefined) {\n previousBodyPosition = {\n position: document.body.style.position,\n top: document.body.style.top,\n left: document.body.style.left,\n };\n\n // Update the dom inside an animation frame\n const { scrollY, scrollX, innerHeight } = window;\n document.body.style.position = 'fixed';\n document.body.style.top = `${-scrollY}px`;\n document.body.style.left = `${-scrollX}px`;\n\n setTimeout(\n () =>\n window.requestAnimationFrame(() => {\n // Attempt to check if the bottom bar appeared due to the position change\n const bottomBarHeight = innerHeight - window.innerHeight;\n if (bottomBarHeight && scrollY >= innerHeight) {\n // Move the content further up so that the bottom bar doesn't hide it\n document.body.style.top = -(scrollY + bottomBarHeight);\n }\n }),\n 300\n );\n }\n });\n\nconst restorePositionSetting = () => {\n if (previousBodyPosition !== undefined) {\n // Convert the position from \"px\" to Int\n const y = -parseInt(document.body.style.top, 10);\n const x = -parseInt(document.body.style.left, 10);\n\n // Restore styles\n document.body.style.position = previousBodyPosition.position;\n document.body.style.top = previousBodyPosition.top;\n document.body.style.left = previousBodyPosition.left;\n\n // Restore scroll\n window.scrollTo(x, y);\n\n previousBodyPosition = undefined;\n }\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions\nconst isTargetElementTotallyScrolled = (targetElement: any): boolean =>\n targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false;\n\nconst handleScroll = (event: HandleScrollEvent, targetElement: any): boolean => {\n const clientY = event.targetTouches[0].clientY - initialClientY;\n\n if (event.target && allowTouchMove(event.target)) {\n return false;\n }\n\n if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {\n // element is at the top of its scroll.\n return preventDefault(event);\n }\n\n if (isTargetElementTotallyScrolled(targetElement) && clientY < 0) {\n // element is at the bottom of its scroll.\n return preventDefault(event);\n }\n\n event.stopPropagation();\n return true;\n};\n\nexport const disableBodyScroll = (targetElement: any, options?: BodyScrollOptions): void => {\n // targetElement must be provided\n if (!targetElement) {\n // eslint-disable-next-line no-console\n console.error('disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.');\n return;\n }\n\n // disableBodyScroll must not have been called on this targetElement before\n if (locks.some((lock) => lock.targetElement === targetElement)) {\n return;\n }\n\n const lock = {\n targetElement,\n options: options || {},\n };\n\n locks = [...locks, lock];\n\n if (isIosDevice) {\n setPositionFixed();\n } else {\n setOverflowHidden(options);\n }\n\n if (isIosDevice) {\n targetElement.ontouchstart = (event: HandleScrollEvent) => {\n if (event.targetTouches.length === 1) {\n // detect single touch.\n initialClientY = event.targetTouches[0].clientY;\n }\n };\n targetElement.ontouchmove = (event: HandleScrollEvent) => {\n if (event.targetTouches.length === 1) {\n // detect single touch.\n handleScroll(event, targetElement);\n }\n };\n\n if (!documentListenerAdded) {\n document.addEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);\n documentListenerAdded = true;\n }\n }\n};\n\nexport const clearAllBodyScrollLocks = (): void => {\n if (isIosDevice) {\n // Clear all locks ontouchstart/ontouchmove handlers, and the references.\n locks.forEach((lock: Lock) => {\n lock.targetElement.ontouchstart = null;\n lock.targetElement.ontouchmove = null;\n });\n\n if (documentListenerAdded) {\n document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);\n documentListenerAdded = false;\n }\n\n // Reset initial clientY.\n initialClientY = -1;\n }\n\n if (isIosDevice) {\n restorePositionSetting();\n } else {\n restoreOverflowSetting();\n }\n\n locks = [];\n};\n\nexport const enableBodyScroll = (targetElement: any): void => {\n if (!targetElement) {\n // eslint-disable-next-line no-console\n console.error('enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.');\n return;\n }\n\n locks = locks.filter((lock) => lock.targetElement !== targetElement);\n\n if (isIosDevice) {\n targetElement.ontouchstart = null;\n targetElement.ontouchmove = null;\n\n if (documentListenerAdded && locks.length === 0) {\n document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);\n documentListenerAdded = false;\n }\n }\n\n if (isIosDevice) {\n restorePositionSetting();\n } else {\n restoreOverflowSetting();\n }\n};\n\nexport function scrollLock(el: HTMLElement | Element): void {\n disableBodyScroll(el, {\n reserveScrollBarGap: true,\n allowTouchMove: (el) => {\n while (el && el !== document.body) {\n if (el.getAttribute('body-scroll-lock-ignore') !== null) {\n return true;\n }\n el = el.parentElement;\n }\n },\n });\n}\n\nexport function scrollUnlock(el: Nullable = null): void {\n if (el === null) {\n clearAllBodyScrollLocks();\n } else {\n enableBodyScroll(el);\n }\n}\n"],"names":["hasPassiveEvents","passiveTestOptions","isIosDevice","locks","documentListenerAdded","initialClientY","previousBodyOverflowSetting","previousBodyPosition","previousBodyPaddingRight","allowTouchMove","el","lock","preventDefault","rawEvent","setOverflowHidden","options","reserveScrollBarGap","scrollBarGap","computedBodyPaddingRight","restoreOverflowSetting","setPositionFixed","scrollY","scrollX","innerHeight","bottomBarHeight","restorePositionSetting","y","x","isTargetElementTotallyScrolled","targetElement","handleScroll","event","clientY","disableBodyScroll","clearAllBodyScrollLocks","enableBodyScroll","scrollLock","scrollUnlock"],"mappings":"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"}