Files
headlessui/packages/@headlessui-vue/src/hooks/use-tree-walker.ts
T
Robin Malfait d950146bcc add use tree walker hook (#316)
* add useTreeWalker hooks

We got a PR to fix the createTreeWalker so that it also works in IE11.
We don't actively support IE11, so if things work (with polyfills) then
it's good but I don't want to maintain IE11 specific code.

That said, I wanted to abstract the createTreeWalker code to a nice
little hook. The fix for IE is also pretty small, it uses a function
instead of an object and it has a last argument that is deprecated, but
has no obvious effect for our use cases.

Since the incoming PR was based on the `main` branch (where we only had
1 reference to createTreeWalker), I wanted to make sure that we got all
the references on the latest `develop` branch.

Closes: #295
Co-authored-by: Simon VDB <simonvdbroeck@gmail.com>

* use useTreeWalker hook

Co-authored-by: Simon VDB <simonvdbroeck@gmail.com>
2021-04-09 12:29:32 +02:00

32 lines
814 B
TypeScript

import { watchEffect, ComputedRef } from 'vue'
type AcceptNode = (
node: HTMLElement
) =>
| typeof NodeFilter.FILTER_ACCEPT
| typeof NodeFilter.FILTER_SKIP
| typeof NodeFilter.FILTER_REJECT
export function useTreeWalker({
container,
accept,
walk,
enabled,
}: {
container: ComputedRef<HTMLElement | null>
accept: AcceptNode
walk(node: HTMLElement): void
enabled?: ComputedRef<boolean>
}) {
watchEffect(() => {
let root = container.value
if (!root) return
if (enabled !== undefined && !enabled.value) return
let acceptNode = Object.assign((node: HTMLElement) => accept(node), { acceptNode: accept })
let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, acceptNode, false)
while (walker.nextNode()) walk(walker.currentNode as HTMLElement)
})
}