{"version":3,"file":"useKeyboardNavigation.cjs","sources":["../../../src/components/Dropdown/useKeyboardNavigation.ts"],"sourcesContent":["import { type RefObject, useCallback, useContext, useEffect } from 'react'\n\nimport { tabbable } from '../../libs/tabbable'\n\nimport { DropdownContext } from './Dropdown'\nimport { getFirstTabbable } from './dropdownHelper'\n\nconst KEY_ESCAPE = /^Esc(ape)?$/\n\nexport function useKeyboardNavigation(\n  wrapperRef: RefObject<HTMLDivElement>,\n  dummyFocusRef: RefObject<HTMLElement>,\n) {\n  const { triggerElementRef, rootTriggerRef, onClickCloser } = useContext(DropdownContext)\n\n  const handleKeyDown = useCallback(\n    (e: KeyboardEvent) => {\n      if (e.key === 'Tab') {\n        if (!wrapperRef.current || !triggerElementRef.current || !rootTriggerRef?.current) {\n          return\n        }\n\n        const tabbablesInContent = tabbable(wrapperRef.current)\n\n        if (tabbablesInContent.length === 0) {\n          return\n        }\n\n        const trigger = tabbable(triggerElementRef.current).at(-1)\n        const firstTabbable = tabbablesInContent[0]\n\n        if (e.target === trigger) {\n          if (e.shiftKey) {\n            // move focus previous of the Trigger\n            return\n          }\n\n          // focus a first tabbable element in the dropdown content\n          e.preventDefault()\n          firstTabbable.focus()\n\n          return\n        } else if (e.shiftKey) {\n          if (e.target === firstTabbable || e.target === dummyFocusRef.current) {\n            // focus the Trigger\n            e.preventDefault()\n            trigger!.focus()\n            onClickCloser()\n          }\n        } else if (e.target === tabbablesInContent.at(-1)) {\n          // move focus next of the Trigger\n          const rootTrigger = tabbable(rootTriggerRef.current).at(-1)\n\n          if (rootTrigger) {\n            rootTrigger.focus()\n            onClickCloser()\n          }\n        }\n      } else if (KEY_ESCAPE.test(e.key)) {\n        if (e.target && e.target === dummyFocusRef.current) {\n          onClickCloser()\n\n          return\n        }\n\n        const trigger = getFirstTabbable(triggerElementRef)\n\n        if (trigger && e.target === trigger) {\n          // close the dropdown when the Trigger is focused and Esc key is pressed\n          onClickCloser()\n\n          return\n        }\n\n        if (wrapperRef.current) {\n          for (const inner of tabbable(wrapperRef.current)) {\n            if (inner === e.target) {\n              // close the dropdown when an element that is included in dropdown content is focused and Esc key is pressed\n              onClickCloser()\n\n              break\n            }\n          }\n        }\n      }\n    },\n    [wrapperRef, triggerElementRef, rootTriggerRef, dummyFocusRef, onClickCloser],\n  )\n\n  useEffect(() => {\n    window.addEventListener('keydown', handleKeyDown)\n\n    return () => {\n      window.removeEventListener('keydown', handleKeyDown)\n    }\n  }, [handleKeyDown])\n}\n"],"names":["useContext","DropdownContext","useCallback","tabbable","getFirstTabbable","useEffect"],"mappings":"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"}