UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

1 lines 9.51 kB
{"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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"}