{"version":3,"file":"useTransitionRender.hook.cjs","sources":["../../../src/hooks/use-transition-render/useTransitionRender.hook.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useState } from 'react'\r\n\r\nimport { vars } from '@theme/contract.css.ts'\r\n\r\nimport type { UseTransitionRenderReturnType } from '@hooks/use-transition-render/types'\r\nimport {\r\n    getPrefersReducedMotion,\r\n    resolveDurationMs\r\n} from '@hooks/use-transition-render/utils/useTransitionRender.utils.ts'\r\n\r\n/**\r\n * Manages mount/unmount transitions with a two-phase approach (visible → fading-in).\r\n *\r\n * Opening sequence:\r\n *   1. `useLayoutEffect` sets `isVisible=true` synchronously before the browser paints\r\n *      → element is in the DOM at its initial hidden state on the very first frame.\r\n *   2. Double `requestAnimationFrame` in `useEffect` waits for two rendered frames\r\n *      before setting `isFadingIn=true`, guaranteeing the CSS transition always starts\r\n *      from the painted hidden state (prevents flickering).\r\n *\r\n * Closing sequence:\r\n *   `isFadingIn=false` → CSS transition plays → after `duration` ms → `isVisible=false`\r\n *   and `shouldRenderContent=false`.\r\n *\r\n * When `prefers-reduced-motion: reduce` is active the effective duration is forced to\r\n * `0` so the element is removed from the DOM immediately after hiding, in sync with\r\n * the near-instant CSS transition set by the global `globals.css` rule.\r\n *\r\n * @param isOpen - Whether the element should be shown.\r\n * @param durationVar - CSS variable reference for the transition duration\r\n *   (e.g. `vars.duration.normal`). Defaults to the theme's normal duration.\r\n */\r\nexport const useTransitionRender = (\r\n    isOpen: boolean,\r\n    durationVar: string = vars.duration.normal,\r\n): UseTransitionRenderReturnType => {\r\n    const durationMs = resolveDurationMs(durationVar)\r\n    const effectiveDuration = getPrefersReducedMotion() ? 0 : durationMs\r\n    const [isVisible, setIsVisible] = useState(isOpen)\r\n    const [isFadingIn, setIsFadingIn] = useState(isOpen)\r\n\r\n    // Mount synchronously before paint so the element is in the DOM at opacity:0\r\n    // on the very first frame — no extra render cycle between null and the initial state.\r\n    useLayoutEffect(() => {\r\n        if (isOpen) {\r\n            setIsVisible(true)\r\n        }\r\n    }, [isOpen])\r\n\r\n    useEffect(() => {\r\n        if (isOpen) {\r\n            // Double RAF: frame 1 → element rendered; frame 2 → element painted at hidden\r\n            // state → THEN trigger the CSS transition.\r\n            let raf2: number\r\n            const raf1 = requestAnimationFrame(() => {\r\n                raf2 = requestAnimationFrame(() => setIsFadingIn(true))\r\n            })\r\n            return () => {\r\n                cancelAnimationFrame(raf1)\r\n                cancelAnimationFrame(raf2)\r\n            }\r\n        } else {\r\n            setIsFadingIn(false)\r\n            const timeout = setTimeout(() => setIsVisible(false), effectiveDuration)\r\n            return () => clearTimeout(timeout)\r\n        }\r\n    }, [isOpen, effectiveDuration])\r\n\r\n    return { isVisible, isFadingIn, shouldRenderContent: isVisible }\r\n}\r\n"],"names":["useTransitionRender","isOpen","durationVar","vars","durationMs","resolveDurationMs","effectiveDuration","getPrefersReducedMotion","isVisible","setIsVisible","useState","isFadingIn","setIsFadingIn","useLayoutEffect","useEffect","raf2","raf1","timeout"],"mappings":"sMAgCaA,EAAsB,CAC/BC,EACAC,EAAsBC,EAAAA,KAAK,SAAS,SACJ,CAChC,MAAMC,EAAaC,EAAAA,kBAAkBH,CAAW,EAC1CI,EAAoBC,EAAAA,0BAA4B,EAAIH,EACpD,CAACI,EAAWC,CAAY,EAAIC,EAAAA,SAAST,CAAM,EAC3C,CAACU,EAAYC,CAAa,EAAIF,EAAAA,SAAST,CAAM,EAInDY,OAAAA,EAAAA,gBAAgB,IAAM,CACdZ,GACAQ,EAAa,EAAI,CAEzB,EAAG,CAACR,CAAM,CAAC,EAEXa,EAAAA,UAAU,IAAM,CACZ,GAAIb,EAAQ,CAGR,IAAIc,EACJ,MAAMC,EAAO,sBAAsB,IAAM,CACrCD,EAAO,sBAAsB,IAAMH,EAAc,EAAI,CAAC,CAC1D,CAAC,EACD,MAAO,IAAM,CACT,qBAAqBI,CAAI,EACzB,qBAAqBD,CAAI,CAC7B,CACJ,KAAO,CACHH,EAAc,EAAK,EACnB,MAAMK,EAAU,WAAW,IAAMR,EAAa,EAAK,EAAGH,CAAiB,EACvE,MAAO,IAAM,aAAaW,CAAO,CACrC,CACJ,EAAG,CAAChB,EAAQK,CAAiB,CAAC,EAEvB,CAAE,UAAAE,EAAW,WAAAG,EAAY,oBAAqBH,CAAA,CACzD"}