Outlook_Addin_LLM/node_modules/@fluentui/react-tree/lib/hooks/useTreeNavigation.js

70 lines
2.6 KiB
JavaScript
Raw Normal View History

import { nextTypeAheadElement } from '../utils/nextTypeAheadElement';
import { treeDataTypes } from '../utils/tokens';
import { useRovingTabIndex } from './useRovingTabIndexes';
import * as React from 'react';
import { useHTMLElementWalkerRef } from './useHTMLElementWalkerRef';
import { useMergedRefs } from '@fluentui/react-utilities';
/**
* @internal
*/ export function useTreeNavigation() {
'use no memo';
const { rove, initialize: initializeRovingTabIndex } = useRovingTabIndex();
const { walkerRef, rootRef: walkerRootRef } = useHTMLElementWalkerRef();
const rootRefCallback = React.useCallback((root)=>{
if (root && walkerRef.current) {
initializeRovingTabIndex(walkerRef.current);
}
}, [
walkerRef,
initializeRovingTabIndex
]);
const getNextElement = (data)=>{
if (!walkerRef.current) {
return null;
}
switch(data.type){
case treeDataTypes.Click:
return data.target;
case treeDataTypes.TypeAhead:
walkerRef.current.currentElement = data.target;
return nextTypeAheadElement(walkerRef.current, data.event.key);
case treeDataTypes.ArrowLeft:
walkerRef.current.currentElement = data.target;
return walkerRef.current.parentElement();
case treeDataTypes.ArrowRight:
walkerRef.current.currentElement = data.target;
return walkerRef.current.firstChild();
case treeDataTypes.End:
walkerRef.current.currentElement = walkerRef.current.root;
return lastChildRecursive(walkerRef.current);
case treeDataTypes.Home:
walkerRef.current.currentElement = walkerRef.current.root;
return walkerRef.current.firstChild();
case treeDataTypes.ArrowDown:
walkerRef.current.currentElement = data.target;
return walkerRef.current.nextElement();
case treeDataTypes.ArrowUp:
walkerRef.current.currentElement = data.target;
return walkerRef.current.previousElement();
}
};
function navigate(data, focusOptions) {
const nextElement = getNextElement(data);
if (nextElement) {
rove(nextElement, focusOptions);
}
}
return {
navigate,
treeRef: useMergedRefs(walkerRootRef, rootRefCallback)
};
}
function lastChildRecursive(walker) {
let lastElement = null;
let nextElement = null;
while(nextElement = walker.lastChild()){
lastElement = nextElement;
}
return lastElement;
}