{"version":3,"file":"useKeydown.mjs","sources":["../../../../../../../../packages/components/tree/src/model/useKeydown.ts"],"sourcesContent":["import { onMounted, onUpdated } from 'vue'\nimport { useEventListener } from '@vueuse/core'\nimport { EVENT_CODE } from '@hd-front-end/constants'\nimport { useNamespace } from '@hd-front-end/hooks'\nimport { getEventCode } from '@hd-front-end/utils'\n\nimport type TreeStore from './tree-store'\nimport type { Ref } from 'vue'\nimport type { Nullable } from '@hd-front-end/utils'\n\ninterface UseKeydownOption {\n  el$: Ref<HTMLElement | null>\n}\nexport function useKeydown({ el$ }: UseKeydownOption, store: Ref<TreeStore>) {\n  const ns = useNamespace('tree')\n\n  onMounted(() => {\n    initTabIndex()\n  })\n\n  onUpdated(() => {\n    const checkboxItems = Array.from(\n      el$.value!.querySelectorAll('input[type=checkbox]')\n    )\n    checkboxItems.forEach((checkbox) => {\n      checkbox.setAttribute('tabindex', '-1')\n    })\n  })\n\n  function canNodeFocus(treeItems: HTMLElement[], nextIndex: number): boolean {\n    const currentNode = store.value.getNode(treeItems[nextIndex].dataset.key!)\n    return (\n      currentNode.canFocus &&\n      currentNode.visible &&\n      (currentNode.parent?.expanded || currentNode.parent?.level === 0)\n    )\n  }\n\n  const handleKeydown = (ev: KeyboardEvent): void => {\n    const currentItem = ev.target as HTMLDivElement\n    if (!currentItem.className.includes(ns.b('node'))) return\n    const code = getEventCode(ev)\n    const treeItems: HTMLElement[] = Array.from(\n      el$.value!.querySelectorAll(`.${ns.is('focusable')}[role=treeitem]`)\n    )\n    const currentIndex = treeItems.indexOf(currentItem)\n    let nextIndex\n    if ([EVENT_CODE.up, EVENT_CODE.down].includes(code)) {\n      ev.preventDefault()\n      if (code === EVENT_CODE.up) {\n        nextIndex =\n          currentIndex === -1\n            ? 0\n            : currentIndex !== 0\n            ? currentIndex - 1\n            : treeItems.length - 1\n        const startIndex = nextIndex\n        while (true) {\n          if (canNodeFocus(treeItems, nextIndex)) {\n            break\n          }\n\n          nextIndex--\n          if (nextIndex === startIndex) {\n            nextIndex = -1\n            break\n          }\n          if (nextIndex < 0) {\n            nextIndex = treeItems.length - 1\n          }\n        }\n      } else {\n        nextIndex =\n          currentIndex === -1\n            ? 0\n            : currentIndex < treeItems.length - 1\n            ? currentIndex + 1\n            : 0\n        const startIndex = nextIndex\n        while (true) {\n          if (canNodeFocus(treeItems, nextIndex)) {\n            break\n          }\n\n          nextIndex++\n          if (nextIndex === startIndex) {\n            nextIndex = -1\n            break\n          }\n          if (nextIndex >= treeItems.length) {\n            nextIndex = 0\n          }\n        }\n      }\n      nextIndex !== -1 && treeItems[nextIndex].focus()\n    }\n    if ([EVENT_CODE.left, EVENT_CODE.right].includes(code)) {\n      ev.preventDefault()\n      currentItem.click()\n    }\n    const hasInput = currentItem.querySelector(\n      '[type=\"checkbox\"]'\n    ) as Nullable<HTMLInputElement>\n    if (\n      [EVENT_CODE.enter, EVENT_CODE.numpadEnter, EVENT_CODE.space].includes(\n        code\n      ) &&\n      hasInput\n    ) {\n      ev.preventDefault()\n      hasInput.click()\n    }\n  }\n\n  useEventListener(el$, 'keydown', handleKeydown)\n\n  const initTabIndex = (): void => {\n    if (!el$.value) return\n    const treeItems = Array.from(\n      el$.value.querySelectorAll(`.${ns.is('focusable')}[role=treeitem]`)\n    )\n    const checkboxItems = Array.from(\n      el$.value.querySelectorAll('input[type=checkbox]')\n    )\n    checkboxItems.forEach((checkbox) => {\n      checkbox.setAttribute('tabindex', '-1')\n    })\n    const checkedItem = el$.value.querySelectorAll(\n      `.${ns.is('checked')}[role=treeitem]`\n    )\n    if (checkedItem.length) {\n      checkedItem[0].setAttribute('tabindex', '0')\n      return\n    }\n    treeItems[0]?.setAttribute('tabindex', '0')\n  }\n}\n"],"names":[],"mappings":"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"}