d950146bcc
* 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>
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
import { useRef, useEffect } from 'react'
|
|
import { useIsoMorphicEffect } from './use-iso-morphic-effect'
|
|
|
|
type AcceptNode = (
|
|
node: HTMLElement
|
|
) =>
|
|
| typeof NodeFilter.FILTER_ACCEPT
|
|
| typeof NodeFilter.FILTER_SKIP
|
|
| typeof NodeFilter.FILTER_REJECT
|
|
|
|
export function useTreeWalker({
|
|
container,
|
|
accept,
|
|
walk,
|
|
enabled = true,
|
|
}: {
|
|
container: HTMLElement | null
|
|
accept: AcceptNode
|
|
walk(node: HTMLElement): void
|
|
enabled?: boolean
|
|
}) {
|
|
let acceptRef = useRef(accept)
|
|
let walkRef = useRef(walk)
|
|
|
|
useEffect(() => {
|
|
acceptRef.current = accept
|
|
walkRef.current = walk
|
|
}, [accept, walk])
|
|
|
|
useIsoMorphicEffect(() => {
|
|
if (!container) return
|
|
if (!enabled) return
|
|
|
|
let accept = acceptRef.current
|
|
let walk = walkRef.current
|
|
|
|
let acceptNode = Object.assign((node: HTMLElement) => accept(node), { acceptNode: accept })
|
|
let walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, acceptNode, false)
|
|
|
|
while (walker.nextNode()) walk(walker.currentNode as HTMLElement)
|
|
}, [container, enabled, acceptRef, walkRef])
|
|
}
|