{"version":3,"file":"useKeydown.mjs","sources":["../../../../../../src/components/ivue-tree/hooks/useKeydown.ts"],"sourcesContent":["import { onMounted, onUpdated, shallowRef, watch } from 'vue';\r\nimport { useEventListener } from '@vueuse/core';\r\nimport { EVENT_CODE } from '../../../utils/helpers';\r\n\r\n// type\r\nimport type { Ref } from 'vue';\r\nimport type TreeStore from '../store/tree-store';\r\n\r\nexport const useKeydown = (el: Ref<HTMLElement>, store: Ref<TreeStore>) => {\r\n  // tree元素数组\r\n  const treeItems = shallowRef<HTMLElement[]>([]);\r\n  // checkbox元素数组\r\n  const checkboxItems = shallowRef<HTMLElement[]>([]);\r\n\r\n  // methods\r\n\r\n  // 设置当前焦点\r\n  const initTabIndex = (): void => {\r\n    // tree元素数组\r\n    treeItems.value = Array.from(\r\n      el.value.querySelectorAll('.is-focusable[role=treeItem]')\r\n    );\r\n\r\n    // checkbox元素数组\r\n    checkboxItems.value = Array.from(\r\n      el.value.querySelectorAll('input[type=checkbox]')\r\n    );\r\n\r\n    // 多选选中的元素\r\n    const checkedItem = el.value.querySelectorAll('.is-checked[role=treeItem]');\r\n\r\n    if (checkedItem.length) {\r\n      checkedItem[0].setAttribute('tabindex', '0');\r\n\r\n      return;\r\n    }\r\n\r\n    treeItems.value[0]?.setAttribute('tabindex', '0');\r\n  };\r\n\r\n  // 键盘按下\r\n  const handleKeydown = (event: KeyboardEvent): void => {\r\n    const currentItem = event.target as HTMLElement;\r\n\r\n    if (!currentItem.className.includes('ivue-tree-node')) {\r\n      return;\r\n    }\r\n\r\n    // 键盘事件类型\r\n    const code = event.code;\r\n\r\n    // tree元素数组\r\n    treeItems.value = Array.from(\r\n      el.value.querySelectorAll('.is-focusable[role=treeItem]')\r\n    );\r\n\r\n    // 当前下标\r\n    const currentIndex = treeItems.value.indexOf(currentItem);\r\n    let nextIndex;\r\n\r\n    // 向上或者向下\r\n    if ([EVENT_CODE.up, EVENT_CODE.down].includes(code)) {\r\n      event.preventDefault();\r\n\r\n      // 向上\r\n      if (code === EVENT_CODE.up) {\r\n        // 第一个\r\n        if (currentIndex === -1) {\r\n          nextIndex = 0;\r\n        }\r\n        // 不是第一个 -1 向上选择焦点\r\n        else if (currentIndex !== 0) {\r\n          nextIndex = currentIndex - 1;\r\n        }\r\n        // 到达第一个后继续向上选择焦点重置为最后一个\r\n        else {\r\n          nextIndex = treeItems.value.length - 1;\r\n        }\r\n\r\n        // 开始的下标\r\n        const startIndex = nextIndex;\r\n\r\n        treeItems.value.forEach(() => {\r\n          if (\r\n            // 当前节点是否可以获取焦点\r\n            store.value.getNode(treeItems.value[nextIndex].dataset.key).canFocus\r\n          ) {\r\n            return;\r\n          }\r\n\r\n          // 下标递减\r\n          nextIndex--;\r\n\r\n          // 是否等于第一个\r\n          if (nextIndex === startIndex) {\r\n            nextIndex = -1;\r\n\r\n            return;\r\n          }\r\n\r\n          if (nextIndex < 0) {\r\n            nextIndex = treeItems.value.length - 1;\r\n          }\r\n        });\r\n      }\r\n      // 向下\r\n      else {\r\n        // 第一个\r\n        if (currentIndex === -1) {\r\n          nextIndex = 0;\r\n        }\r\n        // 当前下标 < 数组的长度\r\n        else if (currentIndex < treeItems.value.length - 1) {\r\n          // 下标增加\r\n          nextIndex = currentIndex + 1;\r\n        }\r\n        // 重置为第一个\r\n        else {\r\n          nextIndex = 0;\r\n        }\r\n\r\n        const startIndex = nextIndex;\r\n\r\n        treeItems.value.forEach(() => {\r\n          // 当前节点是否可以获取焦点\r\n          if (\r\n            store.value.getNode(treeItems.value[nextIndex].dataset.key).canFocus\r\n          ) {\r\n            return;\r\n          }\r\n\r\n          // 向上增加\r\n          nextIndex++;\r\n\r\n          // 等于最后一个\r\n          if (nextIndex === startIndex) {\r\n            nextIndex = -1;\r\n\r\n            return;\r\n          }\r\n\r\n          // 重置为第一个下标\r\n          if (nextIndex >= treeItems.value.length) {\r\n            nextIndex = 0;\r\n          }\r\n        });\r\n      }\r\n\r\n      // 设置焦点\r\n      nextIndex !== -1 && treeItems.value[nextIndex].focus();\r\n    }\r\n\r\n    // 键盘向左 ｜ 键盘向右\r\n    if ([EVENT_CODE.left, EVENT_CODE.right].includes(code)) {\r\n      event.preventDefault();\r\n\r\n      // 点击元素\r\n      currentItem.click();\r\n    }\r\n\r\n    // 当前元素\r\n    const hasInput = currentItem.querySelector(\r\n      '[type=\"checkbox\"]'\r\n    ) as HTMLInputElement;\r\n\r\n    // 键盘确认 ｜ 键盘空格\r\n    if ([EVENT_CODE.enter, EVENT_CODE.space].includes(code) && hasInput) {\r\n      event.preventDefault();\r\n\r\n      // 多选框点击\r\n      hasInput.click();\r\n    }\r\n  };\r\n\r\n  // watch\r\n\r\n  // 监听checkbox元素数组\r\n  watch(checkboxItems, (value) => {\r\n    // 重新设置取消焦点\r\n    value.forEach((checkbox) => {\r\n      checkbox.setAttribute('tabindex', '-1');\r\n    });\r\n  });\r\n\r\n  // onMounted\r\n  onMounted(() => {\r\n    // 设置当前焦点\r\n    initTabIndex();\r\n\r\n    useEventListener(el, 'keydown', handleKeydown);\r\n  });\r\n\r\n  // onUpdated\r\n  onUpdated(() => {\r\n    treeItems.value = Array.from(el.value.querySelectorAll('[role=treeItem]'));\r\n\r\n    checkboxItems.value = Array.from(\r\n      el.value.querySelectorAll('input[type=checkbox]')\r\n    );\r\n  });\r\n};\r\n"],"names":[],"mappings":"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"}