{"version":3,"file":"use-scroll.mjs","sources":["../../../src/value/use-scroll.ts"],"sourcesContent":["\"use client\"\n\nimport { AnimationPlaybackControls, motionValue } from \"motion-dom\"\nimport { invariant } from \"motion-utils\"\nimport { RefObject, useCallback, useEffect, useRef } from \"react\"\nimport { scroll } from \"../render/dom/scroll\"\nimport { ScrollInfoOptions } from \"../render/dom/scroll/types\"\nimport { canUseNativeTimeline } from \"../render/dom/scroll/utils/can-use-native-timeline\"\nimport { useConstant } from \"../utils/use-constant\"\nimport { useIsomorphicLayoutEffect } from \"../utils/use-isomorphic-effect\"\n\nexport interface UseScrollOptions\n    extends Omit<ScrollInfoOptions, \"container\" | \"target\"> {\n    container?: RefObject<HTMLElement | null>\n    target?: RefObject<HTMLElement | null>\n}\n\nconst createScrollMotionValues = () => ({\n    scrollX: motionValue(0),\n    scrollY: motionValue(0),\n    scrollXProgress: motionValue(0),\n    scrollYProgress: motionValue(0),\n})\n\nconst isRefPending = (ref?: RefObject<HTMLElement | null>) => {\n    if (!ref) return false\n    return !ref.current\n}\n\nfunction makeAccelerateConfig(\n    axis: \"x\" | \"y\",\n    options: Omit<UseScrollOptions, \"container\" | \"target\">,\n    container?: Element\n) {\n    return {\n        factory: (animation: AnimationPlaybackControls) =>\n            scroll(animation, { ...options, axis, container }),\n        times: [0, 1],\n        keyframes: [0, 1],\n        ease: (v: number) => v,\n        duration: 1,\n    }\n}\n\nexport function useScroll({\n    container,\n    target,\n    ...options\n}: UseScrollOptions = {}) {\n    const values = useConstant(createScrollMotionValues)\n\n    if (!target && canUseNativeTimeline()) {\n        const resolvedContainer = container?.current || undefined\n        values.scrollXProgress.accelerate = makeAccelerateConfig(\n            \"x\",\n            options,\n            resolvedContainer\n        )\n        values.scrollYProgress.accelerate = makeAccelerateConfig(\n            \"y\",\n            options,\n            resolvedContainer\n        )\n    }\n\n    const scrollAnimation = useRef<VoidFunction | null>(null)\n    const needsStart = useRef(false)\n\n    const start = useCallback(() => {\n        scrollAnimation.current = scroll(\n            (\n                _progress: number,\n                {\n                    x,\n                    y,\n                }: {\n                    x: { current: number; progress: number }\n                    y: { current: number; progress: number }\n                }\n            ) => {\n                values.scrollX.set(x.current)\n                values.scrollXProgress.set(x.progress)\n                values.scrollY.set(y.current)\n                values.scrollYProgress.set(y.progress)\n            },\n            {\n                ...options,\n                container: container?.current || undefined,\n                target: target?.current || undefined,\n            }\n        )\n\n        return () => {\n            scrollAnimation.current?.()\n        }\n    }, [container, target, JSON.stringify(options.offset)])\n\n    useIsomorphicLayoutEffect(() => {\n        needsStart.current = false\n\n        if (isRefPending(container) || isRefPending(target)) {\n            needsStart.current = true\n            return\n        } else {\n            return start()\n        }\n    }, [start])\n\n    useEffect(() => {\n        if (needsStart.current) {\n            invariant(\n                !isRefPending(container),\n                \"Container ref is defined but not hydrated\",\n                \"use-scroll-ref\"\n            )\n            invariant(\n                !isRefPending(target),\n                \"Target ref is defined but not hydrated\",\n                \"use-scroll-ref\"\n            )\n            return start()\n        } else {\n            return\n        }\n    }, [start])\n\n    return values\n}\n"],"names":[],"mappings":";;;;;;;;;AAiBA;AACI;AACA;AACA;AACA;AACH;AAED;AACI;AAAU;AACV;AACJ;AAEA;;AAMQ;AAEA;AACA;AACA;AACA;;AAER;AAEM;AAKF;AAEA;AACI;AACA;AAKA;;AAOJ;AACA;AAEA;AACI;;;;;AAeI;AAEI;AACA;AACA;AACH;AAGL;AACI;AACJ;AACJ;;AAGI;;AAGI;;;;;;AAKR;;AAGI;;;;;;;;AAeJ;AAEA;AACJ;;"}