{"version":3,"file":"use-keyboard-shortcut.cjs","names":[],"sources":["../../src/hooks/use-keyboard-shortcut.ts"],"sourcesContent":["import { useEffect } from \"react\";\n\nexport interface KeyboardShortcut {\n    /** Key name (`\"k\"`, `\"Enter\"`, `\"Escape\"`, `\"ArrowDown\"`, etc.). Case-insensitive. */\n    key: string;\n    ctrl?: boolean;\n    meta?: boolean;\n    shift?: boolean;\n    alt?: boolean;\n    /** Match either Ctrl or Cmd. Useful for cross-OS shortcuts. */\n    mod?: boolean;\n}\n\nexport interface UseKeyboardShortcutOptions {\n    /** Disable the shortcut without unmounting. Default: false. */\n    disabled?: boolean;\n    /** Listen to the entire window. Pass `false` to scope to a specific element via the handler. Default: true. */\n    global?: boolean;\n    /** Suppress the event from firing inside `<input>`/`<textarea>`/`[contenteditable]`. Default: true. */\n    ignoreInput?: boolean;\n}\n\nfunction matches(event: KeyboardEvent, shortcut: KeyboardShortcut): boolean {\n    if (event.key.toLowerCase() !== shortcut.key.toLowerCase()) return false;\n    const ctrl = !!shortcut.ctrl;\n    const meta = !!shortcut.meta;\n    const shift = !!shortcut.shift;\n    const alt = !!shortcut.alt;\n    if (shortcut.mod) {\n        if (!event.ctrlKey && !event.metaKey) return false;\n    } else {\n        if (event.ctrlKey !== ctrl) return false;\n        if (event.metaKey !== meta) return false;\n    }\n    if (event.shiftKey !== shift) return false;\n    if (event.altKey !== alt) return false;\n    return true;\n}\n\nfunction isEditable(target: EventTarget | null): boolean {\n    if (!(target instanceof HTMLElement)) return false;\n    const tag = target.tagName.toLowerCase();\n    if (tag === \"input\" || tag === \"textarea\" || tag === \"select\") return true;\n    return target.isContentEditable;\n}\n\n/**\n * Bind a global keyboard shortcut. Supports modifier combinations and a\n * cross-OS `mod` key (Ctrl on Windows/Linux, Cmd on macOS).\n *\n * The effect depends on the individual `shortcut` fields rather than on the\n * object itself: callers pass an inline literal (`{ key: \"k\", mod: true }`),\n * which is a fresh reference on every render and would otherwise tear down and\n * re-add the listener each time. `exhaustive-deps` is silenced for that line\n * because the destructured fields are the complete dependency set.\n *\n * @example\n * useKeyboardShortcut({ key: \"k\", mod: true }, () => openSearch());\n */\nexport function useKeyboardShortcut(\n    shortcut: KeyboardShortcut,\n    handler: (event: KeyboardEvent) => void,\n    options: UseKeyboardShortcutOptions = {},\n): void {\n    const { disabled = false, ignoreInput = true } = options;\n\n    useEffect(() => {\n        if (disabled || typeof window === \"undefined\") return;\n        const listener = (event: KeyboardEvent): void => {\n            if (ignoreInput && isEditable(event.target)) return;\n            if (matches(event, shortcut)) handler(event);\n        };\n        window.addEventListener(\"keydown\", listener);\n        return () => window.removeEventListener(\"keydown\", listener);\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [\n        disabled,\n        ignoreInput,\n        shortcut.key,\n        shortcut.ctrl,\n        shortcut.meta,\n        shortcut.shift,\n        shortcut.alt,\n        shortcut.mod,\n        handler,\n    ]);\n}\n"],"mappings":"uBAsBA,SAAS,EAAQ,EAAsB,EAAqC,CACxE,GAAI,EAAM,IAAI,YAAY,IAAM,EAAS,IAAI,YAAY,EAAG,MAAO,GACnE,IAAM,EAAO,CAAC,CAAC,EAAS,KAClB,EAAO,CAAC,CAAC,EAAS,KAClB,EAAQ,CAAC,CAAC,EAAS,MACnB,EAAM,CAAC,CAAC,EAAS,IACvB,GAAI,EAAS,IACL,IAAA,CAAC,EAAM,SAAW,CAAC,EAAM,QAAS,MAAO,EAAA,MAG7C,GADI,EAAM,UAAY,GAClB,EAAM,UAAY,EAAM,MAAO,GAIvC,OAFI,EAAM,WAAa,GACnB,EAAM,SAAW,CAEzB,CAEA,SAAS,EAAW,EAAqC,CACrD,GAAI,EAAE,aAAkB,aAAc,MAAO,GAC7C,IAAM,EAAM,EAAO,QAAQ,YAAY,EAEvC,OADI,IAAQ,SAAW,IAAQ,YAAc,IAAQ,UAC9C,EAAO,iBAClB,CAeA,SAAgB,EACZ,EACA,EACA,EAAsC,CAAC,EACnC,CACJ,GAAM,CAAE,WAAW,GAAO,cAAc,IAAS,GAEjD,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,GAAY,OAAO,OAAW,IAAa,OAC/C,IAAM,EAAY,GAA+B,CACzC,GAAe,EAAW,EAAM,MAAM,GACtC,EAAQ,EAAO,CAAQ,GAAG,EAAQ,CAAK,CAC/C,EAEA,OADA,OAAO,iBAAiB,UAAW,CAAQ,MAC9B,OAAO,oBAAoB,UAAW,CAAQ,CAE/D,EAAG,CACC,EACA,EACA,EAAS,IACT,EAAS,KACT,EAAS,KACT,EAAS,MACT,EAAS,IACT,EAAS,IACT,CACJ,CAAC,CACL"}