UNPKG

vuestic-ui

Version:
1 lines 7.65 kB
{"version":3,"file":"useTreeKeyboardNavigation.mjs","sources":["../../../../../../src/components/va-tree-view/hooks/useTreeKeyboardNavigation.ts"],"sourcesContent":["import { ExtractPropTypes } from 'vue'\n\nimport type { TreeNode, TreeView, TreeViewEmitsFunc } from '../types'\nimport { useTreeViewProps } from './useTreeHelpers'\n\ntype TreeNodeElement = HTMLElement | null\ntype UseTreeKeyboardNavigationMethods = Pick<TreeView, 'toggleNode' | 'toggleCheckbox'> & {\n emit: TreeViewEmitsFunc,\n}\n\nconst useTreeKeyboardNavigation = (\n props: ExtractPropTypes<typeof useTreeViewProps>,\n methods: UseTreeKeyboardNavigationMethods,\n) => {\n const { emit, toggleNode, toggleCheckbox } = methods\n const isElementExpanded = (currentElement: TreeNodeElement): boolean =>\n currentElement?.getAttribute('aria-expanded') === 'true'\n\n const getParentElement = (currentElement: TreeNodeElement): TreeNodeElement =>\n currentElement?.parentElement?.closest('.va-tree-node') || null\n\n const getPreviousElement = (currentElement: TreeNodeElement): TreeNodeElement =>\n currentElement?.previousElementSibling as TreeNodeElement\n\n const findPreviousElement = (currentElement: TreeNodeElement): TreeNodeElement => {\n if (!currentElement) {\n return null\n }\n\n let previousElement = getPreviousElement(currentElement)\n let lastChildElement = isElementExpanded(previousElement) && getLastChildElement(previousElement)\n\n if (lastChildElement) {\n do {\n if (isElementExpanded(lastChildElement)) {\n lastChildElement = getLastChildElement(lastChildElement)\n\n if (lastChildElement) {\n continue\n } else {\n break\n }\n } else {\n previousElement = lastChildElement\n break\n }\n } while (true)\n }\n\n if (!previousElement) {\n return getParentElement(currentElement)\n }\n\n return previousElement\n }\n\n const getNextElement = (currentElement: TreeNodeElement): TreeNodeElement =>\n currentElement?.nextElementSibling as TreeNodeElement\n\n const findNextElement = (currentElement: TreeNodeElement): TreeNodeElement => {\n if (!currentElement) {\n return null\n }\n\n let nextElement = getNextElement(currentElement)\n const isCurrentExpanded = isElementExpanded(currentElement)\n\n if (!nextElement) {\n let parentElement = getParentElement(currentElement)\n\n do {\n if (!getNextElement(parentElement)) {\n parentElement = getParentElement(parentElement)\n\n if (!parentElement) {\n break\n } else {\n continue\n }\n } else {\n nextElement = getNextElement(parentElement)\n break\n }\n } while (true)\n }\n\n if (isCurrentExpanded) {\n return getFirstChildElement(currentElement)\n }\n\n return nextElement\n }\n\n const getFirstChildElement = (currentElement: TreeNodeElement): TreeNodeElement => {\n return (currentElement?.querySelector('.va-tree-node-children')?.firstElementChild || null) as TreeNodeElement\n }\n\n const getLastChildElement = (currentElement: TreeNodeElement): TreeNodeElement => {\n return (currentElement?.querySelector('.va-tree-node-children')?.lastElementChild || null) as TreeNodeElement\n }\n\n const onHorizontalMove = (currentElement: TreeNodeElement, dir: 'left' | 'right', node: TreeNode) => {\n const isCurrentElementExpanded = isElementExpanded(currentElement)\n\n if (dir === 'left') {\n if (isCurrentElementExpanded) {\n toggleNode(node)\n } else {\n getParentElement(currentElement)?.focus()\n }\n } else {\n if (!isCurrentElementExpanded) {\n toggleNode(node)\n } else {\n getFirstChildElement(currentElement)?.focus()\n }\n }\n }\n\n const onVerticalMove = (currentElement: HTMLElement, dir: 'up' | 'down') => {\n if (dir === 'up') {\n findPreviousElement(currentElement)?.focus()\n } else {\n findNextElement(currentElement)?.focus()\n }\n }\n\n const handleKeyboardNavigation = (event: KeyboardEvent, node: TreeNode) => {\n const currentElement = event.target as HTMLElement\n\n switch (event.code) {\n case 'ArrowUp':\n onVerticalMove(currentElement, 'up')\n break\n case 'ArrowRight':\n onHorizontalMove(currentElement, 'right', node)\n break\n case 'ArrowDown':\n onVerticalMove(currentElement, 'down')\n break\n case 'ArrowLeft':\n onHorizontalMove(currentElement, 'left', node)\n break\n case 'Space':\n if (props.selectable) {\n const state = typeof node.checked !== 'undefined' ? !node.checked : null\n\n toggleCheckbox(node, state)\n } else {\n emit('update:selected', node)\n }\n\n break\n case 'Escape':\n if (!props.selectable) {\n emit('update:selected', null)\n }\n\n currentElement.blur()\n\n break\n default:\n currentElement.blur()\n }\n }\n\n return { handleKeyboardNavigation }\n}\n\nexport default useTreeKeyboardNavigation\n"],"names":[],"mappings":"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"}