Outlook_Addin_LLM/node_modules/@fluentui/react-aria/lib/activedescendant/useOptionWalker.js

81 lines
2.9 KiB
JavaScript

import * as React from 'react';
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
import { isHTMLElement } from '@fluentui/react-utilities';
export function useOptionWalker(options) {
const { matchOption } = options;
const { targetDocument } = useFluent();
const treeWalkerRef = React.useRef(null);
const listboxRef = React.useRef(null);
const optionFilter = React.useCallback((node)=>{
if (isHTMLElement(node) && matchOption(node)) {
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_SKIP;
}, [
matchOption
]);
const setListbox = React.useCallback((el)=>{
if (el && targetDocument) {
listboxRef.current = el;
treeWalkerRef.current = targetDocument.createTreeWalker(el, NodeFilter.SHOW_ELEMENT, optionFilter);
} else {
listboxRef.current = null;
}
}, [
targetDocument,
optionFilter
]);
const optionWalker = React.useMemo(()=>({
first: ()=>{
if (!treeWalkerRef.current || !listboxRef.current) {
return null;
}
treeWalkerRef.current.currentNode = listboxRef.current;
return treeWalkerRef.current.firstChild();
},
last: ()=>{
if (!treeWalkerRef.current || !listboxRef.current) {
return null;
}
treeWalkerRef.current.currentNode = listboxRef.current;
return treeWalkerRef.current.lastChild();
},
next: ()=>{
if (!treeWalkerRef.current) {
return null;
}
return treeWalkerRef.current.nextNode();
},
prev: ()=>{
if (!treeWalkerRef.current) {
return null;
}
return treeWalkerRef.current.previousNode();
},
find: (predicate, startFrom)=>{
if (!treeWalkerRef.current || !listboxRef.current) {
return null;
}
const start = startFrom ? targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.getElementById(startFrom) : null;
treeWalkerRef.current.currentNode = start !== null && start !== void 0 ? start : listboxRef.current;
let cur = treeWalkerRef.current.currentNode;
while(cur && !predicate(cur.id)){
cur = treeWalkerRef.current.nextNode();
}
return cur;
},
setCurrent: (el)=>{
if (!treeWalkerRef.current) {
return;
}
treeWalkerRef.current.currentNode = el;
}
}), [
targetDocument
]);
return {
optionWalker,
listboxCallbackRef: setListbox
};
}