{"version":3,"file":"useAnimatedDetails.cjs","sources":["../../../../src/hooks/useAnimatedDetails/useAnimatedDetails.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\n/**\n * Lar deg animere et HTML details element med en summary trigger og noe innhold.\n * HTML strukturen din bør se ut som omtrent\n * <details ref={detailsRef}>\n *     <summary ref={summaryRef} onClick={onSummaryClick}>Trigger for å åpne</summary>\n *     <div ref={contentRef}>Ekspanderbart innhold</div>\n *  </details>\n *\n * @param onOpenChange Callback med informasjon om når elementet åpner/lukker seg.\n * @param isExpanded Styr åpning/lukking utenfra.\n * @deprecated Bruk heller `useAnimatedHeightBetween` eller lignende på selve innholdet\n */\nexport const useAnimatedDetails = ({\n    onOpenChange,\n    isExpanded,\n}: {\n    onOpenChange: (open: boolean, e: React.MouseEvent<HTMLElement>) => void;\n    isExpanded: boolean;\n}): {\n    detailsRef: React.RefObject<HTMLDetailsElement>;\n    summaryRef: React.RefObject<HTMLButtonElement>;\n    contentRef: React.RefObject<HTMLDivElement>;\n    onSummaryClick: React.MouseEventHandler<HTMLElement>;\n} => {\n    const detailsRef = useRef<HTMLDetailsElement>(null);\n    const summaryRef = useRef<HTMLButtonElement>(null);\n    const contentRef = useRef<HTMLDivElement>(null);\n    const animation = useRef<Animation | null>(null);\n\n    const [isClosing, setIsClosing] = useState(false);\n    const [isExpanding, setIsExpanding] = useState(false);\n\n    useEffect(() => {\n        onAnimationFinish(isExpanded);\n    }, [isExpanded]);\n\n    const onAnimationFinish = (open: boolean) => {\n        if (detailsRef.current && summaryRef.current) {\n            detailsRef.current.open = open;\n            animation.current = null;\n            setIsClosing(false);\n            setIsExpanding(false);\n            detailsRef.current.style.overflow = \"\";\n            detailsRef.current.style.height = \"\";\n        }\n    };\n\n    const open = (e: React.MouseEvent<HTMLElement>) => {\n        if (detailsRef.current && summaryRef.current) {\n            detailsRef.current.style.height = `${detailsRef.current.offsetHeight}px`;\n            detailsRef.current.open = true;\n            requestAnimationFrame(() => {\n                if (\n                    detailsRef.current &&\n                    summaryRef.current &&\n                    contentRef.current\n                ) {\n                    setIsExpanding(true);\n                    onOpenChange(true, e);\n                    const startHeight = detailsRef.current.offsetHeight;\n                    const endHeight =\n                        summaryRef.current.offsetHeight +\n                        contentRef.current.offsetHeight;\n\n                    if (animation.current) {\n                        animation.current.cancel();\n                    }\n\n                    if (detailsRef.current.animate) {\n                        animation.current = detailsRef.current.animate(\n                            {\n                                height: [`${startHeight}px`, `${endHeight}px`],\n                            },\n                            {\n                                duration: 150,\n                                easing: \"ease\",\n                            },\n                        );\n                        animation.current.onfinish = () =>\n                            onAnimationFinish(true);\n                        animation.current.oncancel = () =>\n                            setIsExpanding(false);\n                    }\n                }\n            });\n        }\n    };\n\n    const close = (e: React.MouseEvent<HTMLElement>) => {\n        if (detailsRef.current && summaryRef.current) {\n            setIsClosing(true);\n            onOpenChange(false, e);\n            const startHeight = detailsRef.current.offsetHeight;\n            const endHeight = summaryRef.current.offsetHeight;\n            if (animation.current) {\n                animation.current.cancel();\n            }\n\n            if (detailsRef.current.animate) {\n                animation.current = detailsRef.current.animate(\n                    {\n                        height: [`${startHeight}px`, `${endHeight}px`],\n                    },\n                    {\n                        duration: 150,\n                        easing: \"ease\",\n                    },\n                );\n                animation.current.onfinish = () => onAnimationFinish(false);\n                animation.current.oncancel = () => setIsClosing(false);\n            }\n        }\n    };\n\n    const onSummaryClick = (e: React.MouseEvent<HTMLElement>) => {\n        e.preventDefault();\n        if (detailsRef.current && summaryRef.current) {\n            detailsRef.current.style.overflow = \"hidden\";\n            if (isClosing || !detailsRef.current.open) {\n                open(e);\n            } else if (isExpanding || detailsRef.current.open) {\n                close(e);\n            }\n        }\n    };\n\n    return { detailsRef, summaryRef, contentRef, onSummaryClick };\n};\n"],"names":["onOpenChange","isExpanded","detailsRef","useRef","summaryRef","contentRef","animation","isClosing","setIsClosing","useState","isExpanding","setIsExpanding","useEffect","onAnimationFinish","open","current","style","overflow","height","onSummaryClick","e","preventDefault","offsetHeight","requestAnimationFrame","startHeight","endHeight","cancel","animate","duration","easing","onfinish","oncancel","close"],"mappings":"oIAckC,EAC9BA,aAAAA,EACAC,WAAAA,MAUA,MAAMC,EAAaC,EAAAA,OAA2B,MACxCC,EAAaD,EAAAA,OAA0B,MACvCE,EAAaF,EAAAA,OAAuB,MACpCG,EAAYH,EAAAA,OAAyB,OAEpCI,EAAWC,GAAgBC,EAAAA,UAAS,IACpCC,EAAaC,GAAkBF,EAAAA,UAAS,GAE/CG,EAAAA,UAAU,KACNC,EAAkBZ,IACnB,CAACA,IAEJ,MAAMY,EAAqBC,IACnBZ,EAAWa,SAAWX,EAAWW,UACjCb,EAAWa,QAAQD,KAAOA,EAC1BR,EAAUS,QAAU,KACpBP,GAAa,GACbG,GAAe,GACfT,EAAWa,QAAQC,MAAMC,SAAW,GACpCf,EAAWa,QAAQC,MAAME,OAAS,KAmF1C,MAAO,CAAEhB,WAAAA,EAAYE,WAAAA,EAAYC,WAAAA,EAAYc,eAZrBC,IACpBA,EAAEC,iBACEnB,EAAWa,SAAWX,EAAWW,UACjCb,EAAWa,QAAQC,MAAMC,SAAW,SAChCV,IAAcL,EAAWa,QAAQD,KAvE/BM,KACNlB,EAAWa,SAAWX,EAAWW,UACjCb,EAAWa,QAAQC,MAAME,OAAS,GAAGhB,EAAWa,QAAQO,iBACxDpB,EAAWa,QAAQD,MAAO,EAC1BS,sBAAsB,KAClB,GACIrB,EAAWa,SACXX,EAAWW,SACXV,EAAWU,QACb,CACEJ,GAAe,GACfX,GAAa,EAAMoB,GACnB,MAAMI,EAActB,EAAWa,QAAQO,aACjCG,EACFrB,EAAWW,QAAQO,aACnBjB,EAAWU,QAAQO,aAEnBhB,EAAUS,SACVT,EAAUS,QAAQW,SAGlBxB,EAAWa,QAAQY,UACnBrB,EAAUS,QAAUb,EAAWa,QAAQY,QACnC,CACIT,OAAQ,CAAC,GAAGM,MAAiB,GAAGC,QAEpC,CACIG,SAAU,IACVC,OAAQ,SAGhBvB,EAAUS,QAAQe,SAAW,IACzBjB,GAAkB,GACtBP,EAAUS,QAAQgB,SAAW,IACzBpB,GAAe,GAE3B,MAoCAG,CAAKM,IACEV,GAAeR,EAAWa,QAAQD,OAhCtCM,KACX,GAAIlB,EAAWa,SAAWX,EAAWW,QAAS,CAC1CP,GAAa,GACbR,GAAa,EAAOoB,GACpB,MAAMI,EAActB,EAAWa,QAAQO,aACjCG,EAAYrB,EAAWW,QAAQO,aACjChB,EAAUS,SACVT,EAAUS,QAAQW,SAGlBxB,EAAWa,QAAQY,UACnBrB,EAAUS,QAAUb,EAAWa,QAAQY,QACnC,CACIT,OAAQ,CAAC,GAAGM,MAAiB,GAAGC,QAEpC,CACIG,SAAU,IACVC,OAAQ,SAGhBvB,EAAUS,QAAQe,SAAW,IAAMjB,GAAkB,GACrDP,EAAUS,QAAQgB,SAAW,IAAMvB,GAAa,GAExD,GAUQwB,CAAMZ"}