{"version":3,"names":["isServer","createRenderEffect","createSignal","untrack","useTransitionStatus","openAccessor","enableIdleStateAccessor","deferEndingStateAccessor","canSettleEnterAccessor","initialOpen","initialEnableIdle","transitionStatus","setTransitionStatus","undefined","ownedWrite","name","mounted","setMounted","isOpen","isMounted","status","defer","id","requestAnimationFrame","cancelAnimationFrame","enableIdle","canSettle","middleId","innerId","outerId"],"sources":["use-transition-status.ts"],"sourcesContent":["import { isServer } from \"@solidjs/web\";\nimport {\n\ttype Accessor,\n\tcreateRenderEffect,\n\tcreateSignal,\n\tuntrack,\n} from \"solid-js\";\n\n/**\n * Transition status for a mounting/unmounting surface. Mirrors Base UI\n * React's `TransitionStatus` union\n * (`packages/react/src/internals/useTransitionStatus.ts`).\n */\nexport type TransitionStatus = \"starting\" | \"ending\" | \"idle\" | undefined;\n\nexport interface UseTransitionStatusReturn {\n\tmounted: Accessor<boolean>;\n\ttransitionStatus: Accessor<TransitionStatus>;\n\tsetMounted: (next: boolean) => void;\n}\n\n/**\n * Enter/exit state machine for animated surfaces (Collapsible, Dialog,\n * Popover, Tooltip). Ported from Base UI React's `useTransitionStatus`.\n *\n * ### Solid 2 port structure\n *\n * React's version writes during render and relies on synchronous re-renders\n * to re-evaluate the state-machine's `if` clauses. Solid 2 has neither\n * render-phase writes nor read-your-write inside a single effect apply\n * (microtask batching). Instead, the port uses layered `createRenderEffect`s\n * that mirror React's structure 1:1 — one effect per React `if`/\n * `useIsoLayoutEffect` block, each tracking the exact dependencies it\n * references. Writes re-fire effects that track the written signal; the\n * `if`-guards ensure idempotence (the re-fire sees the new value and the\n * branch no longer matches, so the effect terminates after one write).\n *\n * Internal signals opt into `ownedWrite` because effects write to them from\n * owned scope; without the opt-in Solid 2 throws `SIGNAL_WRITE_IN_OWNED_SCOPE`.\n */\nexport function useTransitionStatus(\n\topenAccessor: Accessor<boolean>,\n\tenableIdleStateAccessor: Accessor<boolean> = () => false,\n\tdeferEndingStateAccessor: Accessor<boolean> = () => false,\n\t/**\n\t * When provided, enter settle (`starting` → `idle` / `undefined`) is\n\t * deferred until this returns `true`. Used by `createMountTransition` so\n\t * `--*-height` is measured in px before `[data-starting-style]` is removed.\n\t */\n\tcanSettleEnterAccessor: Accessor<boolean> = () => true,\n): UseTransitionStatusReturn {\n\tconst initialOpen = untrack(openAccessor);\n\tconst initialEnableIdle = untrack(enableIdleStateAccessor);\n\n\tconst [transitionStatus, setTransitionStatus] =\n\t\tcreateSignal<TransitionStatus>(\n\t\t\tinitialOpen && initialEnableIdle ? \"idle\" : undefined,\n\t\t\t{ ownedWrite: true, name: \"transition-status.transitionStatus\" },\n\t\t);\n\tconst [mounted, setMounted] = createSignal<boolean>(initialOpen, {\n\t\townedWrite: true,\n\t\tname: \"transition-status.mounted\",\n\t});\n\n\t// Effect 1 — mount on open. Mirrors React line 23-26:\n\t//   if (open && !mounted) { setMounted(true); setTransitionStatus(\"starting\"); }\n\tcreateRenderEffect(\n\t\t() => openAccessor(),\n\t\t(isOpen) => {\n\t\t\tif (isOpen && !untrack(mounted)) {\n\t\t\t\tsetMounted(true);\n\t\t\t\tsetTransitionStatus(\"starting\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// Effect 2 — ending on close (synchronous). Mirrors React line 28-30:\n\t//   if (!open && mounted && status !== 'ending' && !defer) setStatus('ending');\n\tcreateRenderEffect(\n\t\t() => ({\n\t\t\tisOpen: openAccessor(),\n\t\t\tisMounted: mounted(),\n\t\t\tstatus: transitionStatus(),\n\t\t\tdefer: deferEndingStateAccessor(),\n\t\t}),\n\t\t({ isOpen, isMounted, status, defer }) => {\n\t\t\tif (!isOpen && isMounted && status !== \"ending\" && !defer) {\n\t\t\t\tsetTransitionStatus(\"ending\");\n\t\t\t}\n\t\t},\n\t);\n\n\t// Effect 3 — reset status on unmount after ending. Mirrors React line 32-34:\n\t//   if (!open && !mounted && status === 'ending') setStatus(undefined);\n\tcreateRenderEffect(\n\t\t() => ({\n\t\t\tisOpen: openAccessor(),\n\t\t\tisMounted: mounted(),\n\t\t\tstatus: transitionStatus(),\n\t\t}),\n\t\t({ isOpen, isMounted, status }) => {\n\t\t\tif (!isOpen && !isMounted && status === \"ending\") {\n\t\t\t\tsetTransitionStatus(undefined);\n\t\t\t}\n\t\t},\n\t);\n\n\t// Effect 4 — deferred ending via rAF. Mirrors React useIsoLayoutEffect at\n\t// line 36-48: schedules `setStatus('ending')` on next frame when close\n\t// fires in defer mode.\n\tcreateRenderEffect(\n\t\t() => ({\n\t\t\tisOpen: openAccessor(),\n\t\t\tisMounted: mounted(),\n\t\t\tstatus: transitionStatus(),\n\t\t\tdefer: deferEndingStateAccessor(),\n\t\t}),\n\t\t({ isOpen, isMounted, status, defer }) => {\n\t\t\tif (isServer) return undefined;\n\t\t\tif (!isOpen && isMounted && status !== \"ending\" && defer) {\n\t\t\t\tconst id = requestAnimationFrame(() => {\n\t\t\t\t\tsetTransitionStatus(\"ending\");\n\t\t\t\t});\n\t\t\t\treturn () => cancelAnimationFrame(id);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t);\n\n\t// Effect 5 — settle \"starting\" → undefined (non-idle mode). Mirrors React\n\t// line 50-64, but uses **three** rAFs: Solid mounts conditional panel DOM\n\t// in the same commit as `starting`, and enter measurement is deferred\n\t// until layout is ready — idle must not run until after that paint.\n\tcreateRenderEffect(\n\t\t() => ({\n\t\t\tisOpen: openAccessor(),\n\t\t\tenableIdle: enableIdleStateAccessor(),\n\t\t\tcanSettle: canSettleEnterAccessor(),\n\t\t}),\n\t\t({ isOpen, enableIdle, canSettle }) => {\n\t\t\tif (isServer) return undefined;\n\t\t\tif (!isOpen || enableIdle || !canSettle) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tlet middleId = 0;\n\t\t\tlet innerId = 0;\n\t\t\tconst outerId = requestAnimationFrame(() => {\n\t\t\t\tmiddleId = requestAnimationFrame(() => {\n\t\t\t\t\tinnerId = requestAnimationFrame(() => {\n\t\t\t\t\t\tsetTransitionStatus(undefined);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tcancelAnimationFrame(outerId);\n\t\t\t\tif (middleId !== 0) cancelAnimationFrame(middleId);\n\t\t\t\tif (innerId !== 0) cancelAnimationFrame(innerId);\n\t\t\t};\n\t\t},\n\t);\n\n\t// Effect 6 — idle mode: \"starting\" → \"idle\" after rAF. Mirrors React line\n\t// 66-82. When enableIdle flips a mounted-open into \"starting\" and a frame\n\t// later drops to \"idle\".\n\t//\n\t// Both the synchronous `\"starting\"` write and the rAF-scheduled `\"idle\"`\n\t// write are gated on `status !== \"idle\"`: this effect re-fires whenever\n\t// any of the tracked deps (`status` included) change, and without the\n\t// rAF guard we would keep scheduling frames every time `status` flipped\n\t// — including the frame we ourselves scheduled that wrote `\"idle\"` (the\n\t// re-fire then sees status === \"idle\", no-ops the synchronous write, but\n\t// previously queued a brand-new rAF). Guarding both writes on the same\n\t// condition keeps the effect idempotent once settled.\n\tcreateRenderEffect(\n\t\t() => ({\n\t\t\tisOpen: openAccessor(),\n\t\t\tisMounted: mounted(),\n\t\t\tstatus: transitionStatus(),\n\t\t\tenableIdle: enableIdleStateAccessor(),\n\t\t\tcanSettle: canSettleEnterAccessor(),\n\t\t}),\n\t\t({ isOpen, isMounted, status, enableIdle, canSettle }) => {\n\t\t\tif (isServer) return undefined;\n\t\t\tif (!isOpen || !enableIdle || !canSettle) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (status === \"idle\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (isOpen && isMounted) {\n\t\t\t\tsetTransitionStatus(\"starting\");\n\t\t\t}\n\t\t\t// One rAF, matching React (`useTransitionStatus` idle path) AND the\n\t\t\t// deferred-ending rAF in Effect 4: enter and exit transitions started\n\t\t\t// in the same flush (accordion item switch) begin on the SAME frame,\n\t\t\t// so paired heights interpolate in lockstep. `canSettle` already\n\t\t\t// guarantees the measured CSS vars + `[data-starting-style]` styles\n\t\t\t// were committed (with a forced reflow) before this effect runs, so\n\t\t\t// the browser has the 0-height style snapshot it needs — no extra\n\t\t\t// frames required.\n\t\t\tconst outerId = requestAnimationFrame(() => {\n\t\t\t\tsetTransitionStatus(\"idle\");\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tcancelAnimationFrame(outerId);\n\t\t\t};\n\t\t},\n\t);\n\n\treturn {\n\t\tmounted,\n\t\ttransitionStatus,\n\t\tsetMounted,\n\t};\n}\n"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAECC,kBAAkB,EAClBC,YAAY,EACZC,OAAO,QACD,UAAU;;AAEjB;AACA;AACA;AACA;AACA;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CAClCC,YAA+B,EAC/BC,uBAA0C,GAAGA,CAAA,KAAM,KAAK,EACxDC,wBAA2C,GAAGA,CAAA,KAAM,KAAK;AACzD;AACD;AACA;AACA;AACA;AACCC,sBAAyC,GAAGA,CAAA,KAAM,IAAI,EAC1B;EAC5B,MAAMC,WAAW,GAAGN,OAAO,CAACE,YAAY,CAAC;EACzC,MAAMK,iBAAiB,GAAGP,OAAO,CAACG,uBAAuB,CAAC;EAE1D,MAAM,CAACK,gBAAgB,EAAEC,mBAAmB,CAAC,GAC5CV,YAAY,CACXO,WAAW,IAAIC,iBAAiB,GAAG,MAAM,GAAGG,SAAS,EACrD;IAAEC,UAAU,EAAE,IAAI;IAAEC,IAAI,EAAE;EAAqC,CAChE,CAAC;EACF,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAGf,YAAY,CAAUO,WAAW,EAAE;IAChEK,UAAU,EAAE,IAAI;IAChBC,IAAI,EAAE;EACP,CAAC,CAAC;;EAEF;EACA;EACAd,kBAAkB,CACjB,MAAMI,YAAY,CAAC,CAAC,EACnBa,MAAM,IAAK;IACX,IAAIA,MAAM,IAAI,CAACf,OAAO,CAACa,OAAO,CAAC,EAAE;MAChCC,UAAU,CAAC,IAAI,CAAC;MAChBL,mBAAmB,CAAC,UAAU,CAAC;IAChC;EACD,CACD,CAAC;;EAED;EACA;EACAX,kBAAkB,CACjB,OAAO;IACNiB,MAAM,EAAEb,YAAY,CAAC,CAAC;IACtBc,SAAS,EAAEH,OAAO,CAAC,CAAC;IACpBI,MAAM,EAAET,gBAAgB,CAAC,CAAC;IAC1BU,KAAK,EAAEd,wBAAwB,CAAC;EACjC,CAAC,CAAC,EACF,CAAC;IAAEW,MAAM;IAAEC,SAAS;IAAEC,MAAM;IAAEC;EAAM,CAAC,KAAK;IACzC,IAAI,CAACH,MAAM,IAAIC,SAAS,IAAIC,MAAM,KAAK,QAAQ,IAAI,CAACC,KAAK,EAAE;MAC1DT,mBAAmB,CAAC,QAAQ,CAAC;IAC9B;EACD,CACD,CAAC;;EAED;EACA;EACAX,kBAAkB,CACjB,OAAO;IACNiB,MAAM,EAAEb,YAAY,CAAC,CAAC;IACtBc,SAAS,EAAEH,OAAO,CAAC,CAAC;IACpBI,MAAM,EAAET,gBAAgB,CAAC;EAC1B,CAAC,CAAC,EACF,CAAC;IAAEO,MAAM;IAAEC,SAAS;IAAEC;EAAO,CAAC,KAAK;IAClC,IAAI,CAACF,MAAM,IAAI,CAACC,SAAS,IAAIC,MAAM,KAAK,QAAQ,EAAE;MACjDR,mBAAmB,CAACC,SAAS,CAAC;IAC/B;EACD,CACD,CAAC;;EAED;EACA;EACA;EACAZ,kBAAkB,CACjB,OAAO;IACNiB,MAAM,EAAEb,YAAY,CAAC,CAAC;IACtBc,SAAS,EAAEH,OAAO,CAAC,CAAC;IACpBI,MAAM,EAAET,gBAAgB,CAAC,CAAC;IAC1BU,KAAK,EAAEd,wBAAwB,CAAC;EACjC,CAAC,CAAC,EACF,CAAC;IAAEW,MAAM;IAAEC,SAAS;IAAEC,MAAM;IAAEC;EAAM,CAAC,KAAK;IACzC,IAAIrB,QAAQ,EAAE,OAAOa,SAAS;IAC9B,IAAI,CAACK,MAAM,IAAIC,SAAS,IAAIC,MAAM,KAAK,QAAQ,IAAIC,KAAK,EAAE;MACzD,MAAMC,EAAE,GAAGC,qBAAqB,CAAC,MAAM;QACtCX,mBAAmB,CAAC,QAAQ,CAAC;MAC9B,CAAC,CAAC;MACF,OAAO,MAAMY,oBAAoB,CAACF,EAAE,CAAC;IACtC;IACA,OAAOT,SAAS;EACjB,CACD,CAAC;;EAED;EACA;EACA;EACA;EACAZ,kBAAkB,CACjB,OAAO;IACNiB,MAAM,EAAEb,YAAY,CAAC,CAAC;IACtBoB,UAAU,EAAEnB,uBAAuB,CAAC,CAAC;IACrCoB,SAAS,EAAElB,sBAAsB,CAAC;EACnC,CAAC,CAAC,EACF,CAAC;IAAEU,MAAM;IAAEO,UAAU;IAAEC;EAAU,CAAC,KAAK;IACtC,IAAI1B,QAAQ,EAAE,OAAOa,SAAS;IAC9B,IAAI,CAACK,MAAM,IAAIO,UAAU,IAAI,CAACC,SAAS,EAAE;MACxC,OAAOb,SAAS;IACjB;IACA,IAAIc,QAAQ,GAAG,CAAC;IAChB,IAAIC,OAAO,GAAG,CAAC;IACf,MAAMC,OAAO,GAAGN,qBAAqB,CAAC,MAAM;MAC3CI,QAAQ,GAAGJ,qBAAqB,CAAC,MAAM;QACtCK,OAAO,GAAGL,qBAAqB,CAAC,MAAM;UACrCX,mBAAmB,CAACC,SAAS,CAAC;QAC/B,CAAC,CAAC;MACH,CAAC,CAAC;IACH,CAAC,CAAC;IACF,OAAO,MAAM;MACZW,oBAAoB,CAACK,OAAO,CAAC;MAC7B,IAAIF,QAAQ,KAAK,CAAC,EAAEH,oBAAoB,CAACG,QAAQ,CAAC;MAClD,IAAIC,OAAO,KAAK,CAAC,EAAEJ,oBAAoB,CAACI,OAAO,CAAC;IACjD,CAAC;EACF,CACD,CAAC;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA3B,kBAAkB,CACjB,OAAO;IACNiB,MAAM,EAAEb,YAAY,CAAC,CAAC;IACtBc,SAAS,EAAEH,OAAO,CAAC,CAAC;IACpBI,MAAM,EAAET,gBAAgB,CAAC,CAAC;IAC1Bc,UAAU,EAAEnB,uBAAuB,CAAC,CAAC;IACrCoB,SAAS,EAAElB,sBAAsB,CAAC;EACnC,CAAC,CAAC,EACF,CAAC;IAAEU,MAAM;IAAEC,SAAS;IAAEC,MAAM;IAAEK,UAAU;IAAEC;EAAU,CAAC,KAAK;IACzD,IAAI1B,QAAQ,EAAE,OAAOa,SAAS;IAC9B,IAAI,CAACK,MAAM,IAAI,CAACO,UAAU,IAAI,CAACC,SAAS,EAAE;MACzC,OAAOb,SAAS;IACjB;IACA,IAAIO,MAAM,KAAK,MAAM,EAAE;MACtB,OAAOP,SAAS;IACjB;IACA,IAAIK,MAAM,IAAIC,SAAS,EAAE;MACxBP,mBAAmB,CAAC,UAAU,CAAC;IAChC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,MAAMiB,OAAO,GAAGN,qBAAqB,CAAC,MAAM;MAC3CX,mBAAmB,CAAC,MAAM,CAAC;IAC5B,CAAC,CAAC;IACF,OAAO,MAAM;MACZY,oBAAoB,CAACK,OAAO,CAAC;IAC9B,CAAC;EACF,CACD,CAAC;EAED,OAAO;IACNb,OAAO;IACPL,gBAAgB;IAChBM;EACD,CAAC;AACF","ignoreList":[]}