(element: HTMLElement, direction: 'next' | 'previous')
| 139 | } |
| 140 | |
| 141 | export function getVisibleElement(element: HTMLElement, direction: 'next' | 'previous'): HTMLElement | undefined { |
| 142 | const root = element.closest('[role=tree]') |
| 143 | |
| 144 | if (!root) return |
| 145 | |
| 146 | const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, node => { |
| 147 | if (!(node instanceof HTMLElement)) return NodeFilter.FILTER_SKIP |
| 148 | return node.getAttribute('role') === 'treeitem' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP |
| 149 | }) |
| 150 | |
| 151 | let current = walker.firstChild() |
| 152 | |
| 153 | while (current !== element) { |
| 154 | current = walker.nextNode() |
| 155 | } |
| 156 | |
| 157 | let next = direction === 'next' ? walker.nextNode() : walker.previousNode() |
| 158 | |
| 159 | // If next element is nested inside a collapsed subtree, continue iterating |
| 160 | while (next instanceof HTMLElement && next.parentElement?.closest('[role=treeitem][aria-expanded=false]')) { |
| 161 | next = direction === 'next' ? walker.nextNode() : walker.previousNode() |
| 162 | } |
| 163 | |
| 164 | return next instanceof HTMLElement ? next : undefined |
| 165 | } |
| 166 | |
| 167 | export function getFirstChildElement(element: HTMLElement): HTMLElement | undefined { |
| 168 | const firstChild = element.querySelector('[role=treeitem]') |
no outgoing calls
no test coverage detected