{"version":3,"names":["createChangeEventDetails","REASONS","contains","getNextTabbable","getTabbableAfterElement","getTabbableBeforeElement","isOutsideEvent","createStableCallback","useTriggerFocusGuards","store","triggerElementRef","preFocusGuardRef","current","handlePreFocusGuardFocus","event","setOpen","focusOut","currentTarget","previousTabbable","focus","handleFocusTargetFocus","positionerElement","select","context","beforeContentFocusGuardRef","nextTabbable","triggerFocusTargetRef","prevTabbable"],"sources":["use-trigger-focus-guards.ts"],"sourcesContent":["/**\n * Solid port of Base UI React's\n * `packages/react/src/utils/popups/useTriggerFocusGuards.ts`.\n *\n * Provides focus guard handlers for popup triggers (Popover, Menu).\n *\n * When the popup is open, invisible focus guard elements are placed\n * before and after the trigger. These handlers close the popup and move\n * focus to the appropriate tabbable element when the guards receive\n * focus (i.e. when the user tabs out).\n *\n * Port notes:\n *  - `React.useRef` → plain `{ current: null }` mutable ref literal, the\n *    same `MutableRef<T>` shape the rest of the Solid port uses.\n *  - `useStableCallback` → `createStableCallback`. In Solid the trampoline\n *    keeps identity stable across re-renders (although Solid component\n *    bodies don't re-run, the trampoline still insulates consumers that\n *    capture the callback reference into a long-lived structure).\n *  - `ReactDOM.flushSync` has no direct Solid equivalent — Solid batches\n *    updates synchronously inside event handlers already, so the\n *    `flushSync` wrapper is dropped.\n *  - `React.FocusEvent` → native `FocusEvent`. `event.nativeEvent` is\n *    already `FocusEvent` here, and `event.currentTarget` is the guard\n *    element.\n *  - `TriggerFocusGuardStore` is kept as a minimal structural interface\n *    so it can match both the in-flight `PopoverStore` and `MenuStore`\n *    ports without introducing a hard dependency on the real `PopupStore`\n *    (which is being ported on a parallel track).\n */\n\nimport {\n\ttype BaseUIChangeEventDetails,\n\tcreateChangeEventDetails,\n\tREASONS,\n} from \"../change-event-details\";\nimport { contains } from \"../dom/contains\";\nimport type { MutableRef } from \"../floating-ui/types\";\nimport {\n\ttype FocusableElement,\n\tgetNextTabbable,\n\tgetTabbableAfterElement,\n\tgetTabbableBeforeElement,\n\tisOutsideEvent,\n} from \"../floating-ui/utils/tabbable\";\nimport { createStableCallback } from \"../stable-callback\";\n\n/**\n * Minimal store interface required by the focus guard hook.\n * Both PopoverStore and MenuStore satisfy this interface.\n *\n * Kept as a structural shape rather than re-importing the real popup\n * store, so this file remains independent of the parallel `PopupStore`\n * port track.\n */\nexport interface TriggerFocusGuardStore {\n\tsetOpen(\n\t\topen: boolean,\n\t\teventDetails: BaseUIChangeEventDetails<typeof REASONS.focusOut>,\n\t): void;\n\tselect(key: \"positionerElement\"): HTMLElement | null;\n\tcontext: {\n\t\treadonly beforeContentFocusGuardRef: MutableRef<HTMLElement | null>;\n\t\treadonly triggerFocusTargetRef: MutableRef<HTMLElement | null>;\n\t};\n}\n\n/**\n * Provides focus guard handlers for popup triggers (Popover, Menu).\n *\n * When the popup is open, invisible focus guard elements are placed\n * before and after the trigger. These handlers close the popup and move\n * focus to the appropriate tabbable element when the guards receive\n * focus (i.e. when the user tabs out).\n */\nexport function useTriggerFocusGuards(\n\tstore: TriggerFocusGuardStore,\n\ttriggerElementRef: MutableRef<HTMLElement | null>,\n): {\n\tpreFocusGuardRef: MutableRef<HTMLElement | null>;\n\thandlePreFocusGuardFocus: (event: FocusEvent) => void;\n\thandleFocusTargetFocus: (event: FocusEvent) => void;\n} {\n\tconst preFocusGuardRef: MutableRef<HTMLElement | null> = { current: null };\n\n\tconst handlePreFocusGuardFocus = createStableCallback<\n\t\t(event: FocusEvent) => void\n\t>(() => (event: FocusEvent) => {\n\t\tstore.setOpen(\n\t\t\tfalse,\n\t\t\tcreateChangeEventDetails(\n\t\t\t\tREASONS.focusOut,\n\t\t\t\tevent,\n\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t),\n\t\t);\n\n\t\tconst previousTabbable: FocusableElement | null = getTabbableBeforeElement(\n\t\t\tpreFocusGuardRef.current,\n\t\t);\n\t\tpreviousTabbable?.focus();\n\t});\n\n\tconst handleFocusTargetFocus = createStableCallback<\n\t\t(event: FocusEvent) => void\n\t>(() => (event: FocusEvent) => {\n\t\tconst positionerElement = store.select(\"positionerElement\");\n\t\tif (positionerElement && isOutsideEvent(event, positionerElement)) {\n\t\t\tstore.context.beforeContentFocusGuardRef.current?.focus();\n\t\t} else {\n\t\t\tstore.setOpen(\n\t\t\t\tfalse,\n\t\t\t\tcreateChangeEventDetails(\n\t\t\t\t\tREASONS.focusOut,\n\t\t\t\t\tevent,\n\t\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tlet nextTabbable = getTabbableAfterElement(\n\t\t\t\tstore.context.triggerFocusTargetRef.current ||\n\t\t\t\t\ttriggerElementRef.current,\n\t\t\t);\n\n\t\t\twhile (\n\t\t\t\tnextTabbable !== null &&\n\t\t\t\tcontains(positionerElement, nextTabbable)\n\t\t\t) {\n\t\t\t\tconst prevTabbable = nextTabbable;\n\t\t\t\tnextTabbable = getNextTabbable(nextTabbable);\n\t\t\t\tif (nextTabbable === prevTabbable) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnextTabbable?.focus();\n\t\t}\n\t});\n\n\treturn { preFocusGuardRef, handlePreFocusGuardFocus, handleFocusTargetFocus };\n}\n"],"mappings":"AAAA;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;;AAEA,SAECA,wBAAwB,EACxBC,OAAO,QACD,yBAAyB;AAChC,SAASC,QAAQ,QAAQ,iBAAiB;AAE1C,SAECC,eAAe,EACfC,uBAAuB,EACvBC,wBAAwB,EACxBC,cAAc,QACR,+BAA+B;AACtC,SAASC,oBAAoB,QAAQ,oBAAoB;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CACpCC,KAA6B,EAC7BC,iBAAiD,EAKhD;EACD,MAAMC,gBAAgD,GAAG;IAAEC,OAAO,EAAE;EAAK,CAAC;EAE1E,MAAMC,wBAAwB,GAAGN,oBAAoB,CAEnD,MAAOO,KAAiB,IAAK;IAC9BL,KAAK,CAACM,OAAO,CACZ,KAAK,EACLf,wBAAwB,CACvBC,OAAO,CAACe,QAAQ,EAChBF,KAAK,EACLA,KAAK,CAACG,aACP,CACD,CAAC;IAED,MAAMC,gBAAyC,GAAGb,wBAAwB,CACzEM,gBAAgB,CAACC,OAClB,CAAC;IACDM,gBAAgB,EAAEC,KAAK,CAAC,CAAC;EAC1B,CAAC,CAAC;EAEF,MAAMC,sBAAsB,GAAGb,oBAAoB,CAEjD,MAAOO,KAAiB,IAAK;IAC9B,MAAMO,iBAAiB,GAAGZ,KAAK,CAACa,MAAM,CAAC,mBAAmB,CAAC;IAC3D,IAAID,iBAAiB,IAAIf,cAAc,CAACQ,KAAK,EAAEO,iBAAiB,CAAC,EAAE;MAClEZ,KAAK,CAACc,OAAO,CAACC,0BAA0B,CAACZ,OAAO,EAAEO,KAAK,CAAC,CAAC;IAC1D,CAAC,MAAM;MACNV,KAAK,CAACM,OAAO,CACZ,KAAK,EACLf,wBAAwB,CACvBC,OAAO,CAACe,QAAQ,EAChBF,KAAK,EACLA,KAAK,CAACG,aACP,CACD,CAAC;MAED,IAAIQ,YAAY,GAAGrB,uBAAuB,CACzCK,KAAK,CAACc,OAAO,CAACG,qBAAqB,CAACd,OAAO,IAC1CF,iBAAiB,CAACE,OACpB,CAAC;MAED,OACCa,YAAY,KAAK,IAAI,IACrBvB,QAAQ,CAACmB,iBAAiB,EAAEI,YAAY,CAAC,EACxC;QACD,MAAME,YAAY,GAAGF,YAAY;QACjCA,YAAY,GAAGtB,eAAe,CAACsB,YAAY,CAAC;QAC5C,IAAIA,YAAY,KAAKE,YAAY,EAAE;UAClC;QACD;MACD;MAEAF,YAAY,EAAEN,KAAK,CAAC,CAAC;IACtB;EACD,CAAC,CAAC;EAEF,OAAO;IAAER,gBAAgB;IAAEE,wBAAwB;IAAEO;EAAuB,CAAC;AAC9E","ignoreList":[]}