{"version":3,"names":["createEffect","createStableCallback","useAnimationsFinished","useOpenChangeComplete","parameters","enabled","open","ref","onComplete","onCompleteParam","isEnabled","runOnceAnimationsFinish","current","openValue","deps","undefined","abortController","AbortController","signal","abort"],"sources":["use-open-change-complete.ts"],"sourcesContent":["import { type Accessor, createEffect } from \"solid-js\";\nimport { createStableCallback } from \"../stable-callback\";\nimport { useAnimationsFinished } from \"../use-animations-finished\";\n\n/**\n * Plain `{ current }` ref shape that mirrors React's `RefObject<HTMLElement |\n * null>`. Kept structurally identical to the other `MutableRef<T>`\n * declarations in this codebase (see `use-latest-ref.ts`) so consumers can\n * pass the same object interchangeably.\n */\nexport interface MutableRef<T> {\n\tcurrent: T;\n}\n\nexport interface UseOpenChangeCompleteParameters {\n\t/**\n\t * Whether the hook is enabled. May be a plain boolean or a reactive\n\t * accessor. Defaults to `true`.\n\t */\n\tenabled?: boolean | Accessor<boolean> | undefined;\n\t/**\n\t * Whether the element is open. Must be a reactive accessor — Solid has no\n\t * re-render cycle, so changes arrive via signal reads.\n\t */\n\topen?: Accessor<boolean | undefined>;\n\t/**\n\t * Ref to the element being closed. Its `.current` is read at\n\t * invocation time, so a ref that is `null` during setup but populated\n\t * before the first `open` change still works correctly.\n\t */\n\tref: MutableRef<HTMLElement | null>;\n\t/**\n\t * Function to call when the animation completes (or there is no\n\t * animation). Stabilized internally via `createStableCallback` so\n\t * consumers may swap the function freely — the latest closure wins at\n\t * firing time.\n\t */\n\tonComplete: () => void;\n}\n\n/**\n * Calls the provided function when the CSS open/close animation or\n * transition on the referenced element completes.\n *\n * Port of Base UI React's\n * `packages/react/src/internals/useOpenChangeComplete.tsx`. The React\n * version re-runs its effect every time `open`, `enabled`, or the\n * stabilized `onComplete` changes — because the effect's dependency\n * array includes those inputs. The Solid equivalent uses a\n * `createEffect` split-form that tracks the same reactive inputs: each\n * change re-fires the apply, which aborts any prior in-flight wait and\n * schedules a fresh `runOnceAnimationsFinish` cycle.\n *\n * The `ref` is intentionally not reactive — matching React, which reads\n * `ref.current` lazily inside `useAnimationsFinished`'s closure. If the\n * ref populates after setup, the next `open` change will pick it up.\n *\n * @example\n * ```ts\n * const [open, setOpen] = createSignal(false);\n * let el!: HTMLDivElement;\n * useOpenChangeComplete({\n *   open,\n *   ref: { get current() { return el; }, set current(v) { el = v!; } },\n *   onComplete: () => setMounted(false),\n * });\n * ```\n */\nexport function useOpenChangeComplete(\n\tparameters: UseOpenChangeCompleteParameters,\n): void {\n\tconst { enabled = true, open, ref, onComplete: onCompleteParam } = parameters;\n\n\tconst isEnabled = (): boolean =>\n\t\ttypeof enabled === \"function\" ? enabled() : enabled;\n\n\t// Stabilize the consumer-provided callback. `createStableCallback` expects\n\t// a getter so the trampoline can forward to the latest reference at call\n\t// time; we bind to `onCompleteParam` captured in this closure — in Solid\n\t// the hook runs once per component, so this getter doesn't need to\n\t// re-resolve across renders (there are no renders), it just keeps the\n\t// identity stable for downstream captures.\n\tconst onComplete = createStableCallback<() => void>(() => onCompleteParam);\n\n\t// Resolve the element via the existing ref on each invocation.\n\t// `useAnimationsFinished` accepts an `ElementSource` which can be an\n\t// accessor that returns an element — a ref-reader accessor fits exactly.\n\tconst runOnceAnimationsFinish = useAnimationsFinished(() => ref.current);\n\n\t// Mirror React's `useEffect` with deps [enabled, open, onComplete,\n\t// runOnceAnimationsFinish]. The stable-callback trampolines don't\n\t// change, so the live deps are effectively `isEnabled()` and `open()`.\n\t// On each apply, abort any outstanding wait cycle (to cancel a stale\n\t// close wait when a rapid re-open arrives) and schedule a fresh one.\n\tcreateEffect(\n\t\t() => ({\n\t\t\tenabled: isEnabled(),\n\t\t\topenValue: open?.(),\n\t\t}),\n\t\t(deps) => {\n\t\t\tif (!deps.enabled) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst abortController = new AbortController();\n\t\t\trunOnceAnimationsFinish(onComplete, abortController.signal);\n\t\t\treturn () => {\n\t\t\t\tabortController.abort();\n\t\t\t};\n\t\t},\n\t);\n}\n"],"mappings":"AAAA,SAAwBA,YAAY,QAAQ,UAAU;AACtD,SAASC,oBAAoB,QAAQ,oBAAoB;AACzD,SAASC,qBAAqB,QAAQ,4BAA4B;;AAElE;AACA;AACA;AACA;AACA;AACA;;AA+BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CACpCC,UAA2C,EACpC;EACP,MAAM;IAAEC,OAAO,GAAG,IAAI;IAAEC,IAAI;IAAEC,GAAG;IAAEC,UAAU,EAAEC;EAAgB,CAAC,GAAGL,UAAU;EAE7E,MAAMM,SAAS,GAAGA,CAAA,KACjB,OAAOL,OAAO,KAAK,UAAU,GAAGA,OAAO,CAAC,CAAC,GAAGA,OAAO;;EAEpD;EACA;EACA;EACA;EACA;EACA;EACA,MAAMG,UAAU,GAAGP,oBAAoB,CAAa,MAAMQ,eAAe,CAAC;;EAE1E;EACA;EACA;EACA,MAAME,uBAAuB,GAAGT,qBAAqB,CAAC,MAAMK,GAAG,CAACK,OAAO,CAAC;;EAExE;EACA;EACA;EACA;EACA;EACAZ,YAAY,CACX,OAAO;IACNK,OAAO,EAAEK,SAAS,CAAC,CAAC;IACpBG,SAAS,EAAEP,IAAI,GAAG;EACnB,CAAC,CAAC,EACDQ,IAAI,IAAK;IACT,IAAI,CAACA,IAAI,CAACT,OAAO,EAAE;MAClB,OAAOU,SAAS;IACjB;IACA,MAAMC,eAAe,GAAG,IAAIC,eAAe,CAAC,CAAC;IAC7CN,uBAAuB,CAACH,UAAU,EAAEQ,eAAe,CAACE,MAAM,CAAC;IAC3D,OAAO,MAAM;MACZF,eAAe,CAACG,KAAK,CAAC,CAAC;IACxB,CAAC;EACF,CACD,CAAC;AACF","ignoreList":[]}