{"version":3,"file":"useAutoAnimateHeight.cjs","sources":["../../../../src/hooks/useAnimatedHeight/useAutoAnimateHeight.ts"],"sourcesContent":["import {\n    type RefObject,\n    useCallback,\n    useEffect,\n    useRef,\n    useState,\n} from \"react\";\nimport tokens from \"../../core/tokens.js\";\nimport type { Easing, Timing } from \"../../core/types.js\";\nimport { useBrowserPreferences } from \"../useBrowserPreferences/useBrowserPreferences.js\";\nimport { usePreviousValue } from \"../usePreviousValue/usePreviousValue.js\";\n\nconst defaultEasing = \"standard\";\nconst defaultTiming = \"expressive\";\n\nexport type UseAutoAnimatedHeightOptions<T extends HTMLElement> = {\n    easing?: Easing;\n    /**\n     * Overstyr standard timing\n     * @default \"expressive\"\n     */\n    timing?: Timing;\n    onTransitionStart?: (ref: RefObject<T | null>) => void;\n    onTransitionEnd?: (ref: RefObject<T | null>) => void;\n};\n\n/**\n * Gjør det enklere å animere høyden på et element når innholdet endrer seg, men kan brukes på mer generelt grunnlag.\n * Hooken tar inn en triggerverdi, og når denne endrer seg animeres høyden på elementet dersom den har endret seg.\n * @param trigger verdien som brukes til å trigge animasjonen. Dersom denne endrer seg animeres høyden på elementet.\n * @param options konfigurasjon for animasjonen, og lyttere for når animasjonen starter og slutter\n * @returns en referanse til elementet som skal animeres\n */\nexport function useAutoAnimatedHeight<T extends HTMLElement = HTMLElement>(\n    trigger: any,\n    options?: UseAutoAnimatedHeightOptions<T>,\n) {\n    const previousTriggerValue = usePreviousValue(trigger);\n    const [previousHeight, setPreviousHeight] = useState(0);\n\n    const easing = options?.easing || defaultEasing;\n    const timing = options?.timing || defaultTiming;\n    const transition = `${tokens.motion.timing[timing]} height ${tokens.motion.easing[easing]}`;\n\n    const { prefersReducedMotion } = useBrowserPreferences();\n\n    const raf1 = useRef<number>();\n    const raf2 = useRef<number>();\n    const elementRef = useRef<T>(null);\n\n    const handleTransitionEnd = useCallback(\n        (event: TransitionEvent) => {\n            const element = elementRef.current;\n\n            // Ignore bubbling transitions from within container\n            if (element && event.target === element) {\n                element.removeAttribute(\"style\");\n                options?.onTransitionEnd?.(elementRef);\n            }\n        },\n        [options],\n    );\n\n    const animateElement = useCallback(() => {\n        const element = elementRef.current;\n\n        if (!element) return;\n\n        element.removeAttribute(\"style\");\n        const newHeight = element.scrollHeight;\n\n        raf1.current = requestAnimationFrame(() => {\n            // Sett høyde tilbake til forrige høyde\n            element.style.removeProperty(\"transition\");\n            element.style.setProperty(\"height\", `${previousHeight}px`);\n            element.style.setProperty(\"overflow-y\", \"hidden\");\n\n            raf2.current = requestAnimationFrame(() => {\n                // Sett høyde til kollapset høyde og start transition\n                element.style.setProperty(\"transition\", transition);\n                element.style.setProperty(\"height\", `${newHeight}px`);\n            });\n        });\n\n        setPreviousHeight(newHeight);\n    }, [transition, previousHeight]);\n\n    const runAnimation = useCallback(() => {\n        const element = elementRef.current;\n\n        if (!element) return;\n\n        if (previousTriggerValue === undefined) {\n            // Første render\n            setPreviousHeight(element.scrollHeight);\n            return;\n        }\n\n        if (trigger === previousTriggerValue) {\n            // Ingen endring\n            return;\n        }\n\n        options?.onTransitionStart?.(elementRef);\n\n        if (prefersReducedMotion) {\n            options?.onTransitionEnd?.(elementRef); // make sure to call callback when animation is off\n            return;\n        }\n\n        animateElement();\n    }, [\n        animateElement,\n        trigger,\n        previousTriggerValue,\n        options,\n        prefersReducedMotion,\n    ]);\n\n    // biome-ignore lint/correctness/useExhaustiveDependencies: Vi vil trige med trigger\n    useEffect(() => {\n        runAnimation();\n    }, [trigger, runAnimation]);\n\n    useEffect(() => {\n        const element = elementRef.current;\n        if (element) {\n            element.addEventListener(\"transitionend\", handleTransitionEnd);\n        }\n\n        return () => {\n            if (element) {\n                element.removeEventListener(\n                    \"transitionend\",\n                    handleTransitionEnd,\n                );\n            }\n        };\n    }, [handleTransitionEnd]);\n\n    useEffect(() => {\n        const r1 = raf1.current;\n        const r2 = raf2.current;\n        return () => {\n            r1 && cancelAnimationFrame(r1);\n            r2 && cancelAnimationFrame(r2);\n        };\n    }, []);\n\n    return elementRef;\n}\n"],"names":["trigger","options","previousTriggerValue","usePreviousValue","previousHeight","setPreviousHeight","useState","easing","timing","transition","tokens","motion","prefersReducedMotion","useBrowserPreferences","raf1","useRef","raf2","elementRef","handleTransitionEnd","useCallback","event","element","current","target","removeAttribute","onTransitionEnd","animateElement","newHeight","scrollHeight","requestAnimationFrame","style","removeProperty","setProperty","runAnimation","onTransitionStart","useEffect","addEventListener","removeEventListener","r1","r2","cancelAnimationFrame"],"mappings":"gSAiCO,SACHA,EACAC,GAEA,MAAMC,EAAuBC,EAAAA,iBAAiBH,IACvCI,EAAgBC,GAAqBC,EAAAA,SAAS,GAE/CC,EAASN,GAASM,QA5BN,WA6BZC,EAASP,GAASO,QA5BN,aA6BZC,EAAa,GAAGC,EAAOC,OAAOH,OAAOA,aAAkBE,EAAOC,OAAOJ,OAAOA,MAE1EK,qBAAAA,GAAyBC,0BAE3BC,EAAOC,EAAAA,SACPC,EAAOD,EAAAA,SACPE,EAAaF,EAAAA,OAAU,MAEvBG,EAAsBC,EAAAA,YACvBC,IACG,MAAMC,EAAUJ,EAAWK,QAGvBD,GAAWD,EAAMG,SAAWF,IAC5BA,EAAQG,gBAAgB,SACxBvB,GAASwB,kBAAkBR,KAGnC,CAAChB,IAGCyB,EAAiBP,EAAAA,YAAY,KAC/B,MAAME,EAAUJ,EAAWK,QAE3B,IAAKD,EAAS,OAEdA,EAAQG,gBAAgB,SACxB,MAAMG,EAAYN,EAAQO,aAE1Bd,EAAKQ,QAAUO,sBAAsB,KAEjCR,EAAQS,MAAMC,eAAe,cAC7BV,EAAQS,MAAME,YAAY,SAAU,GAAG5B,OACvCiB,EAAQS,MAAME,YAAY,aAAc,UAExChB,EAAKM,QAAUO,sBAAsB,KAEjCR,EAAQS,MAAME,YAAY,aAAcvB,GACxCY,EAAQS,MAAME,YAAY,SAAU,GAAGL,WAI/CtB,EAAkBsB,IACnB,CAAClB,EAAYL,IAEV6B,EAAed,EAAAA,YAAY,KAC7B,MAAME,EAAUJ,EAAWK,QAE3B,GAAKD,EAEL,CAAA,QAA6B,IAAzBnB,EAGA,YADAG,EAAkBgB,EAAQO,cAI9B,GAAI5B,IAAYE,EAOhB,IAFAD,GAASiC,oBAAoBjB,GAEzBL,EAEA,YADAX,GAASwB,kBAAkBR,GAI/BS,GAAA,CAAA,GACD,CACCA,EACA1B,EACAE,EACAD,EACAW,IAIJuB,OAAAA,EAAAA,UAAU,KACNF,KACD,CAACjC,EAASiC,IAEbE,EAAAA,UAAU,KACN,MAAMd,EAAUJ,EAAWK,QAC3B,OAAID,GACAA,EAAQe,iBAAiB,gBAAiBlB,GAGvC,KACCG,GACAA,EAAQgB,oBACJ,gBACAnB,KAIb,CAACA,IAEJiB,EAAAA,UAAU,KACN,MAAMG,EAAKxB,EAAKQ,QACViB,EAAKvB,EAAKM,QAChB,MAAO,KACHgB,GAAME,qBAAqBF,GAC3BC,GAAMC,qBAAqBD,KAEhC,IAEItB,CACX"}