{"version":3,"file":"use-focus-trap.cjs","names":[],"sources":["../../src/hooks/use-focus-trap.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { RefObject } from \"react\";\n\nconst FOCUSABLE_SELECTOR = [\n    \"a[href]\",\n    \"button:not([disabled])\",\n    \"textarea:not([disabled])\",\n    \"input:not([disabled])\",\n    \"select:not([disabled])\",\n    \"[tabindex]:not([tabindex='-1'])\",\n].join(\",\");\n\n/**\n * Trap keyboard focus inside `containerRef` while `active` is true. Cycles\n * Tab and Shift+Tab between the first and last focusable descendants. Pair\n * with Modal/Drawer for fully-accessible overlays.\n */\nexport function useFocusTrap(containerRef: RefObject<HTMLElement | null>, active: boolean): void {\n    useEffect(() => {\n        if (!active) return;\n        const container = containerRef.current;\n        if (!container) return;\n\n        const previouslyFocused = document.activeElement as HTMLElement | null;\n\n        function getFocusable(): HTMLElement[] {\n            return Array.from(\n                container?.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR) ?? [],\n            ).filter((el) => {\n                if (el.hasAttribute(\"aria-hidden\")) return false;\n                const style = typeof window !== \"undefined\" ? window.getComputedStyle(el) : null;\n                if (style && (style.display === \"none\" || style.visibility === \"hidden\")) {\n                    return false;\n                }\n                return true;\n            });\n        }\n\n        function handleKeydown(event: KeyboardEvent): void {\n            if (event.key !== \"Tab\") return;\n            const elements = getFocusable();\n            if (elements.length === 0) {\n                event.preventDefault();\n                return;\n            }\n            const first = elements[0]!;\n            const last = elements[elements.length - 1]!;\n            const current = document.activeElement as HTMLElement | null;\n            if (event.shiftKey) {\n                if (current === first || !current || !container?.contains(current)) {\n                    event.preventDefault();\n                    last.focus();\n                }\n            } else {\n                if (current === last) {\n                    event.preventDefault();\n                    first.focus();\n                }\n            }\n        }\n\n        const focusable = getFocusable();\n        focusable[0]?.focus();\n        document.addEventListener(\"keydown\", handleKeydown);\n        return () => {\n            document.removeEventListener(\"keydown\", handleKeydown);\n            previouslyFocused?.focus?.();\n        };\n    }, [containerRef, active]);\n}\n"],"mappings":"uBAGA,IAAM,EAAqB,CACvB,UACA,yBACA,2BACA,wBACA,yBACA,iCACJ,CAAC,CAAC,KAAK,GAAG,EAOV,SAAgB,EAAa,EAA6C,EAAuB,EAC7F,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,EAAQ,OACb,IAAM,EAAY,EAAa,QAC/B,GAAI,CAAC,EAAW,OAEhB,IAAM,EAAoB,SAAS,cAEnC,SAAS,GAA8B,CACnC,OAAO,MAAM,KACT,GAAW,iBAA8B,CAAkB,GAAK,CAAC,CACrE,CAAC,CAAC,OAAQ,GAAO,CACb,GAAI,EAAG,aAAa,aAAa,EAAG,MAAO,GAC3C,IAAM,EAAQ,OAAO,OAAW,IAAc,OAAO,iBAAiB,CAAE,EAAI,KAI5E,MAHI,IAAU,EAAM,UAAY,QAAU,EAAM,aAAe,QAInE,CAAC,CACL,CAEA,SAAS,EAAc,EAA4B,CAC/C,GAAI,EAAM,MAAQ,MAAO,OACzB,IAAM,EAAW,EAAa,EAC9B,GAAI,EAAS,SAAW,EAAG,CACvB,EAAM,eAAe,EACrB,MACJ,CACA,IAAM,EAAQ,EAAS,GACjB,EAAO,EAAS,EAAS,OAAS,GAClC,EAAU,SAAS,cACrB,EAAM,UACF,IAAY,GAAS,CAAC,GAAW,CAAC,GAAW,SAAS,CAAO,KAC7D,EAAM,eAAe,EACrB,EAAK,MAAM,GAGX,IAAY,IACZ,EAAM,eAAe,EACrB,EAAM,MAAM,EAGxB,CAKA,OAFA,EAAA,CAAA,CAAU,EAAE,EAAE,MAAM,EACpB,SAAS,iBAAiB,UAAW,CAAa,MACrC,CACT,SAAS,oBAAoB,UAAW,CAAa,EACrD,GAAmB,QAAQ,CAC/B,CACJ,EAAG,CAAC,EAAc,CAAM,CAAC,CAC7B"}