{"version":3,"names":["createSignal","untrack","isIOS","createStableCallback","useEnhancedClickHandler","useValueChanged","useOpenInteractionType","open","openMethod","setOpenMethod","handleTriggerClick","_event","interactionType","isOpen","nextOpen","previousOpen","onClick","onPointerDown","triggerProps"],"sources":["use-open-interaction-type.ts"],"sourcesContent":["import { type Accessor, createSignal, untrack } from \"solid-js\";\nimport { isIOS } from \"../floating-ui/detect-browser\";\nimport type { PropsLike } from \"../merge-props-n\";\nimport { createStableCallback } from \"../stable-callback\";\nimport {\n\ttype InteractionType,\n\tuseEnhancedClickHandler,\n} from \"../use-enhanced-click-handler\";\nimport { useValueChanged } from \"../use-value-changed\";\n\nexport type { InteractionType };\n\nexport interface UseOpenInteractionTypeReturn {\n\t/**\n\t * The interaction type that opened the component, or `null` when the\n\t * component is not currently open. Reactive accessor — mirrors React's\n\t * `openMethod` state value.\n\t */\n\topenMethod: Accessor<InteractionType | null>;\n\t/**\n\t * Trigger props to spread onto the opening element. Shape matches Base UI\n\t * React's return: `{ onClick, onPointerDown }`, ready for `mergePropsN`\n\t * composition.\n\t */\n\ttriggerProps: PropsLike;\n}\n\n/**\n * Determines the interaction type (keyboard, mouse, touch, etc.) that\n * opened the component.\n *\n * Port of Base UI React's\n * `packages/react/src/utils/useOpenInteractionType.ts`. The semantic\n * contract matches 1:1:\n *\n * - While the component is closed, the next `pointerdown` / `click` on\n *   the trigger captures the interaction type and stores it on open.\n * - While the component is open, additional clicks do NOT overwrite the\n *   captured type — the React source gates `setOpenMethod` on `!open`.\n * - When `open` transitions `true → false`, the captured type is reset\n *   to `null`.\n * - On iOS Safari the \"hitslop\" around touch targets can fire\n *   `mousedown` without a matching `pointerdown`, producing an empty\n *   `interactionType`. In that case we fall back to `\"touch\"`.\n *\n * Solid 2 notes:\n *\n * - `open` is an accessor — there is no render cycle, so consumers must\n *   thread reactive state through signals.\n * - `useValueChanged` handles the `true → false` reset idiomatically.\n * - `handleTriggerClick` is wrapped with `createStableCallback` to\n *   match React's `useStableCallback` contract; it's also what lets the\n *   closure read the latest `open()` value at invocation time without\n *   re-creating the inner callback.\n */\nexport function useOpenInteractionType(\n\topen: Accessor<boolean>,\n): UseOpenInteractionTypeReturn {\n\tconst [openMethod, setOpenMethod] = createSignal<InteractionType | null>(\n\t\tnull,\n\t);\n\n\t// `createStableCallback` returns a trampoline with a stable identity whose\n\t// body reads from the provided getter each time it fires. Our getter\n\t// closes over `open` and `setOpenMethod` — both are stable references\n\t// captured once at setup. Reading `open()` inside the handler (untracked,\n\t// since we're not inside an effect) gives us the current open state at\n\t// click time, matching React's read-through-closure semantics.\n\tconst handleTriggerClick = createStableCallback<\n\t\t(event: MouseEvent | PointerEvent, interactionType: InteractionType) => void\n\t>(() => (_event, interactionType) => {\n\t\t// Wrap in `untrack` so that — if this handler is ever invoked from\n\t\t// inside an effect apply — we don't subscribe to `open()` there.\n\t\tconst isOpen = untrack(open);\n\t\tif (!isOpen) {\n\t\t\tsetOpenMethod(\n\t\t\t\tinteractionType ||\n\t\t\t\t\t// iOS Safari hitslop: `mousedown` fires without a preceding\n\t\t\t\t\t// `pointerdown`, leaving `interactionType === \"\"`. Treat it\n\t\t\t\t\t// as a touch on iOS so downstream gating (focus rings, etc.)\n\t\t\t\t\t// behaves consistently.\n\t\t\t\t\t(isIOS ? \"touch\" : \"\"),\n\t\t\t);\n\t\t}\n\t});\n\n\t// Reset the captured type on every `true → false` transition. React's\n\t// original reads `previousOpen && !open`; `useValueChanged` fires with\n\t// `(next, previous)` on every change, so we just compare them directly.\n\tuseValueChanged<boolean>(open, (nextOpen, previousOpen) => {\n\t\tif (previousOpen && !nextOpen) {\n\t\t\tsetOpenMethod(null);\n\t\t}\n\t});\n\n\tconst { onClick, onPointerDown } = useEnhancedClickHandler(\n\t\thandleTriggerClick,\n\t) as {\n\t\tonClick: (event: MouseEvent | PointerEvent) => void;\n\t\tonPointerDown: (event: PointerEvent) => void;\n\t};\n\n\t// React's original memoizes the returned object; Solid components don't\n\t// re-run, so the object is allocated exactly once per consumer and its\n\t// identity is naturally stable.\n\treturn {\n\t\topenMethod,\n\t\ttriggerProps: { onClick, onPointerDown } as PropsLike,\n\t};\n}\n"],"mappings":"AAAA,SAAwBA,YAAY,EAAEC,OAAO,QAAQ,UAAU;AAC/D,SAASC,KAAK,QAAQ,+BAA+B;AAErD,SAASC,oBAAoB,QAAQ,oBAAoB;AACzD,SAECC,uBAAuB,QACjB,+BAA+B;AACtC,SAASC,eAAe,QAAQ,sBAAsB;AAmBtD;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,sBAAsBA,CACrCC,IAAuB,EACQ;EAC/B,MAAM,CAACC,UAAU,EAAEC,aAAa,CAAC,GAAGT,YAAY,CAC/C,IACD,CAAC;;EAED;EACA;EACA;EACA;EACA;EACA;EACA,MAAMU,kBAAkB,GAAGP,oBAAoB,CAE7C,MAAM,CAACQ,MAAM,EAAEC,eAAe,KAAK;IACpC;IACA;IACA,MAAMC,MAAM,GAAGZ,OAAO,CAACM,IAAI,CAAC;IAC5B,IAAI,CAACM,MAAM,EAAE;MACZJ,aAAa,CACZG,eAAe;MACd;MACA;MACA;MACA;MACCV,KAAK,GAAG,OAAO,GAAG,EAAE,CACvB,CAAC;IACF;EACD,CAAC,CAAC;;EAEF;EACA;EACA;EACAG,eAAe,CAAUE,IAAI,EAAE,CAACO,QAAQ,EAAEC,YAAY,KAAK;IAC1D,IAAIA,YAAY,IAAI,CAACD,QAAQ,EAAE;MAC9BL,aAAa,CAAC,IAAI,CAAC;IACpB;EACD,CAAC,CAAC;EAEF,MAAM;IAAEO,OAAO;IAAEC;EAAc,CAAC,GAAGb,uBAAuB,CACzDM,kBACD,CAGC;;EAED;EACA;EACA;EACA,OAAO;IACNF,UAAU;IACVU,YAAY,EAAE;MAAEF,OAAO;MAAEC;IAAc;EACxC,CAAC;AACF","ignoreList":[]}