{"version":3,"file":"useKeyboardNavigation.cjs","sources":["../../../../src/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.ts"],"sourcesContent":["import { type RefObject, useEffect } from 'react'\n\nconst TABBABLE_SELECTOR = 'li button,li a,li [tabindex]:not([tabindex=\"-1\"])'\nconst DISABLED_SELECTOR = ':disabled,[aria-disabled=\"true\"]'\nconst isElementEnabled = (element: Element): boolean =>\n  !element.matches(DISABLED_SELECTOR) && !element.querySelector(DISABLED_SELECTOR)\n\nconst KEY_UP_REGEX = /^(Arrow)?(Up|Left)$/\nconst KEY_DOWN_REGEX = /^(Arrow)?(Down|Right)$/\n\nconst moveFocus = (element: Element, direction: 1 | -1) => {\n  let hoveredItem: Element | null = null\n  const tabbableItems: Element[] = []\n  let focusedIndex: number = -1\n\n  const pushTabbaleItem = (item: Element) => {\n    tabbableItems.push(item)\n\n    if (document.activeElement === item) {\n      focusedIndex = tabbableItems.length - 1\n    }\n  }\n\n  element.querySelectorAll(TABBABLE_SELECTOR).forEach((item) => {\n    if (hoveredItem === null && item.matches(':hover')) {\n      hoveredItem = item\n    }\n\n    if (isElementEnabled(item)) {\n      pushTabbaleItem(item)\n    }\n  })\n\n  let nextIndex = 0\n\n  if (focusedIndex > -1) {\n    // フォーカスされているアイテムが存在する場合\n    nextIndex = (focusedIndex + direction + tabbableItems.length) % tabbableItems.length\n  } else if (hoveredItem) {\n    // ホバー状態のアイテムが存在する場合\n    nextIndex =\n      (tabbableItems.indexOf(hoveredItem) + direction + tabbableItems.length) % tabbableItems.length\n  } else if (direction === -1) {\n    nextIndex = tabbableItems.length - 1\n  }\n\n  const nextItem = tabbableItems[nextIndex]\n\n  if (nextItem instanceof HTMLElement) {\n    nextItem.focus()\n  }\n}\n\nconst useKeyboardNavigation = (containerRef: RefObject<HTMLElement>) => {\n  useEffect(() => {\n    const handleKeyDown = (e: KeyboardEvent) => {\n      if (!containerRef.current || !document.activeElement) {\n        return\n      }\n\n      let direction: -1 | 0 | 1 = 0\n\n      // HINT: tabとarrow keyで挙動を揃えるため、tabもhandling対象にする\n      if (e.key === 'Tab') {\n        // HINT: tbのデフォルトの挙動の場合のみ、preventDefaultが必要\n        e.preventDefault()\n        direction = e.shiftKey ? -1 : 1\n      } else if (KEY_UP_REGEX.test(e.key)) {\n        direction = -1\n      } else if (KEY_DOWN_REGEX.test(e.key)) {\n        direction = 1\n      }\n\n      if (direction !== 0) {\n        moveFocus(containerRef.current, direction)\n      }\n    }\n\n    const eventKey = 'keydown'\n\n    document.addEventListener(eventKey, handleKeyDown)\n\n    return () => {\n      document.removeEventListener(eventKey, handleKeyDown)\n    }\n  }, [containerRef])\n}\n\nexport default useKeyboardNavigation\n"],"names":["useEffect"],"mappings":"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"}