Private
Public Access
1
0

feat: Fluent UI Outlook Lite + connections mockup

This commit is contained in:
2026-04-14 18:52:25 +00:00
parent 1199eff6c3
commit dfa4010406
34820 changed files with 1003813 additions and 205 deletions

View File

@@ -0,0 +1,67 @@
'use client';
import * as React from 'react';
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
import { useFocusedElementChange } from '@fluentui/react-tabster';
const findTreeItemRoot = (element)=>{
let parent = element.parentElement;
while(parent && parent.getAttribute('role') !== 'tree'){
parent = parent.parentElement;
}
return parent;
};
/**
* https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex
*
* @internal
*/ export function useRovingTabIndex() {
const currentElementRef = React.useRef(null);
const walkerRef = React.useRef(null);
const { targetDocument } = useFluent();
useFocusedElementChange((element)=>{
if ((element === null || element === void 0 ? void 0 : element.getAttribute('role')) === 'treeitem' && walkerRef.current && walkerRef.current.root.contains(element)) {
const treeitemRoot = findTreeItemRoot(element);
if (walkerRef.current.root !== treeitemRoot) {
return;
}
rove(element);
}
});
const initialize = React.useCallback((walker)=>{
walkerRef.current = walker;
walker.currentElement = walker.root;
let tabbableChild = walker.firstChild((element)=>element.tabIndex === 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP);
walker.currentElement = walker.root;
tabbableChild !== null && tabbableChild !== void 0 ? tabbableChild : tabbableChild = walker.firstChild();
if (!tabbableChild) {
return;
}
tabbableChild.tabIndex = 0;
currentElementRef.current = tabbableChild;
let nextElement = null;
while((nextElement = walker.nextElement()) && nextElement !== tabbableChild){
nextElement.tabIndex = -1;
}
}, []);
const rove = React.useCallback((nextElement, focusOptions)=>{
if (!currentElementRef.current) {
return;
}
currentElementRef.current.tabIndex = -1;
nextElement.tabIndex = 0;
nextElement.focus(focusOptions);
currentElementRef.current = nextElement;
}, []);
const forceUpdate = React.useCallback(()=>{
if ((currentElementRef.current === null || !(targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.body.contains(currentElementRef.current))) && walkerRef.current) {
initialize(walkerRef.current);
}
}, [
targetDocument,
initialize
]);
return {
rove,
initialize,
forceUpdate
};
}