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,50 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ActiveDescendantContextProvider: function() {
return ActiveDescendantContextProvider;
},
useActiveDescendantContext: function() {
return useActiveDescendantContext;
},
useHasParentActiveDescendantContext: function() {
return useHasParentActiveDescendantContext;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const noop = ()=>undefined;
const activeDescendantContextDefaultValue = {
controller: {
active: noop,
blur: noop,
find: noop,
first: noop,
focus: noop,
focusLastActive: noop,
scrollActiveIntoView: noop,
last: noop,
next: noop,
prev: noop,
showAttributes: noop,
hideAttributes: noop,
showFocusVisibleAttributes: noop,
hideFocusVisibleAttributes: noop
}
};
const ActiveDescendantContext = _react.createContext(undefined);
const ActiveDescendantContextProvider = ActiveDescendantContext.Provider;
const useActiveDescendantContext = ()=>{
var _React_useContext;
return (_React_useContext = _react.useContext(ActiveDescendantContext)) !== null && _React_useContext !== void 0 ? _React_useContext : activeDescendantContextDefaultValue;
};
const useHasParentActiveDescendantContext = ()=>!!_react.useContext(ActiveDescendantContext);

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/activedescendant/ActiveDescendantContext.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { ActiveDescendantImperativeRef } from './types';\n\nexport type ActiveDescendantContextValue = {\n controller: ActiveDescendantImperativeRef;\n};\n\nconst noop = () => undefined;\n\nconst activeDescendantContextDefaultValue: ActiveDescendantContextValue = {\n controller: {\n active: noop,\n blur: noop,\n find: noop,\n first: noop,\n focus: noop,\n focusLastActive: noop,\n scrollActiveIntoView: noop,\n last: noop,\n next: noop,\n prev: noop,\n showAttributes: noop,\n hideAttributes: noop,\n showFocusVisibleAttributes: noop,\n hideFocusVisibleAttributes: noop,\n },\n};\n\nconst ActiveDescendantContext = React.createContext<ActiveDescendantContextValue | undefined>(undefined);\n\nexport const ActiveDescendantContextProvider = ActiveDescendantContext.Provider;\nexport const useActiveDescendantContext = (): ActiveDescendantContextValue =>\n React.useContext(ActiveDescendantContext) ?? activeDescendantContextDefaultValue;\nexport const useHasParentActiveDescendantContext = (): boolean => !!React.useContext(ActiveDescendantContext);\n"],"names":["ActiveDescendantContextProvider","useActiveDescendantContext","useHasParentActiveDescendantContext","noop","undefined","activeDescendantContextDefaultValue","controller","active","blur","find","first","focus","focusLastActive","scrollActiveIntoView","last","next","prev","showAttributes","hideAttributes","showFocusVisibleAttributes","hideFocusVisibleAttributes","ActiveDescendantContext","React","createContext","Provider","useContext"],"mappings":"AAAA;;;;;;;;;;;;IAgCaA,+BAA+B;eAA/BA;;IACAC,0BAA0B;eAA1BA;;IAEAC,mCAAmC;eAAnCA;;;;iEAjCU;AAOvB,MAAMC,OAAO,IAAMC;AAEnB,MAAMC,sCAAoE;IACxEC,YAAY;QACVC,QAAQJ;QACRK,MAAML;QACNM,MAAMN;QACNO,OAAOP;QACPQ,OAAOR;QACPS,iBAAiBT;QACjBU,sBAAsBV;QACtBW,MAAMX;QACNY,MAAMZ;QACNa,MAAMb;QACNc,gBAAgBd;QAChBe,gBAAgBf;QAChBgB,4BAA4BhB;QAC5BiB,4BAA4BjB;IAC9B;AACF;AAEA,MAAMkB,0BAA0BC,OAAMC,aAAa,CAA2CnB;AAEvF,MAAMJ,kCAAkCqB,wBAAwBG,QAAQ;AACxE,MAAMvB,6BAA6B;QACxCqB;WAAAA,CAAAA,oBAAAA,OAAMG,UAAU,CAACJ,sCAAjBC,+BAAAA,oBAA6CjB;;AACxC,MAAMH,sCAAsC,IAAe,CAAC,CAACoB,OAAMG,UAAU,CAACJ"}

View File

@@ -0,0 +1,22 @@
/**
* Applied to the element that is active descendant
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ACTIVEDESCENDANT_ATTRIBUTE: function() {
return ACTIVEDESCENDANT_ATTRIBUTE;
},
ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE: function() {
return ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE;
}
});
const ACTIVEDESCENDANT_ATTRIBUTE = 'data-activedescendant';
const ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE = 'data-activedescendant-focusvisible';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/activedescendant/constants.ts"],"sourcesContent":["/**\n * Applied to the element that is active descendant\n */\nexport const ACTIVEDESCENDANT_ATTRIBUTE = 'data-activedescendant';\n\n/**\n * Applied to the active descendant when the user is navigating with keyboard\n */\nexport const ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE = 'data-activedescendant-focusvisible';\n"],"names":["ACTIVEDESCENDANT_ATTRIBUTE","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE"],"mappings":"AAAA;;CAEC;;;;;;;;;;;IACYA,0BAA0B;eAA1BA;;IAKAC,uCAAuC;eAAvCA;;;AALN,MAAMD,6BAA6B;AAKnC,MAAMC,0CAA0C"}

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ACTIVEDESCENDANT_ATTRIBUTE: function() {
return _constants.ACTIVEDESCENDANT_ATTRIBUTE;
},
ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE: function() {
return _constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE;
},
ActiveDescendantContextProvider: function() {
return _ActiveDescendantContext.ActiveDescendantContextProvider;
},
createActiveDescendantChangeEvent: function() {
return _useActiveDescendant.createActiveDescendantChangeEvent;
},
useActiveDescendant: function() {
return _useActiveDescendant.useActiveDescendant;
},
useActiveDescendantContext: function() {
return _ActiveDescendantContext.useActiveDescendantContext;
},
useHasParentActiveDescendantContext: function() {
return _ActiveDescendantContext.useHasParentActiveDescendantContext;
}
});
const _ActiveDescendantContext = require("./ActiveDescendantContext");
const _useActiveDescendant = require("./useActiveDescendant");
const _constants = require("./constants");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/activedescendant/index.ts"],"sourcesContent":["export type { ActiveDescendantContextValue } from './ActiveDescendantContext';\nexport {\n ActiveDescendantContextProvider,\n useActiveDescendantContext,\n useHasParentActiveDescendantContext,\n} from './ActiveDescendantContext';\nexport type { ActiveDescendantChangeEvent } from './useActiveDescendant';\nexport { createActiveDescendantChangeEvent, useActiveDescendant } from './useActiveDescendant';\nexport { ACTIVEDESCENDANT_ATTRIBUTE, ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from './constants';\nexport type {\n ActiveDescendantImperativeRef,\n ActiveDescendantOptions,\n FindOptions,\n IteratorOptions,\n UseActiveDescendantReturn,\n} from './types';\n"],"names":["ACTIVEDESCENDANT_ATTRIBUTE","ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","ActiveDescendantContextProvider","createActiveDescendantChangeEvent","useActiveDescendant","useActiveDescendantContext","useHasParentActiveDescendantContext"],"mappings":";;;;;;;;;;;IAQSA,0BAA0B;eAA1BA,qCAA0B;;IAAEC,uCAAuC;eAAvCA,kDAAuC;;IAN1EC,+BAA+B;eAA/BA,wDAA+B;;IAKxBC,iCAAiC;eAAjCA,sDAAiC;;IAAEC,mBAAmB;eAAnBA,wCAAmB;;IAJ7DC,0BAA0B;eAA1BA,mDAA0B;;IAC1BC,mCAAmC;eAAnCA,4DAAmC;;;yCAC9B;qCAEgE;2BACa"}

View File

@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "scrollIntoView", {
enumerable: true,
get: function() {
return scrollIntoView;
}
});
const scrollIntoView = (target)=>{
if (!target) {
return;
}
const scrollParent = findScrollableParent(target.parentElement);
if (!scrollParent) {
return;
}
const { offsetHeight } = target;
const offsetTop = getTotalOffsetTop(target, scrollParent);
const { scrollMarginTop, scrollMarginBottom } = getScrollMargins(target);
const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;
const isAbove = offsetTop - scrollMarginTop < scrollTop;
const isBelow = offsetTop + offsetHeight + scrollMarginBottom > scrollTop + parentOffsetHeight;
const buffer = 2;
if (isAbove) {
scrollParent.scrollTo(0, offsetTop - scrollMarginTop - buffer);
} else if (isBelow) {
scrollParent.scrollTo(0, offsetTop + offsetHeight + scrollMarginBottom - parentOffsetHeight + buffer);
}
};
const findScrollableParent = (element)=>{
if (!element) {
return null;
}
if (element.scrollHeight > element.offsetHeight) {
return element;
}
return findScrollableParent(element.parentElement);
};
const getTotalOffsetTop = (element, scrollParent)=>{
if (!element || element === scrollParent) {
return 0;
}
if (element.contains(scrollParent)) {
// subtract the scroll parent's offset top from the running total if the offsetParent is above it
return scrollParent.offsetTop * -1;
}
return element.offsetTop + getTotalOffsetTop(element.offsetParent, scrollParent);
};
const getScrollMargins = (element)=>{
var _element_ownerDocument;
const win = (_element_ownerDocument = element.ownerDocument) === null || _element_ownerDocument === void 0 ? void 0 : _element_ownerDocument.defaultView;
if (!win) {
return {
scrollMarginTop: 0,
scrollMarginBottom: 0
};
}
const computedStyles = win.getComputedStyle(element);
var _getIntValueOfComputedStyle;
const scrollMarginTop = (_getIntValueOfComputedStyle = getIntValueOfComputedStyle(computedStyles.scrollMarginTop)) !== null && _getIntValueOfComputedStyle !== void 0 ? _getIntValueOfComputedStyle : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockStart);
var _getIntValueOfComputedStyle1;
const scrollMarginBottom = (_getIntValueOfComputedStyle1 = getIntValueOfComputedStyle(computedStyles.scrollMarginBottom)) !== null && _getIntValueOfComputedStyle1 !== void 0 ? _getIntValueOfComputedStyle1 : getIntValueOfComputedStyle(computedStyles.scrollMarginBlockEnd);
return {
scrollMarginTop,
scrollMarginBottom
};
};
const getIntValueOfComputedStyle = (computedStyle)=>{
return computedStyle ? parseInt(computedStyle, 10) : 0;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/activedescendant/scrollIntoView.ts"],"sourcesContent":["export const scrollIntoView = (target: HTMLElement | null | undefined): void => {\n if (!target) {\n return;\n }\n\n const scrollParent = findScrollableParent(target.parentElement as HTMLElement);\n if (!scrollParent) {\n return;\n }\n\n const { offsetHeight } = target;\n const offsetTop = getTotalOffsetTop(target, scrollParent);\n\n const { scrollMarginTop, scrollMarginBottom } = getScrollMargins(target);\n\n const { offsetHeight: parentOffsetHeight, scrollTop } = scrollParent;\n\n const isAbove = offsetTop - scrollMarginTop < scrollTop;\n const isBelow = offsetTop + offsetHeight + scrollMarginBottom > scrollTop + parentOffsetHeight;\n\n const buffer = 2;\n\n if (isAbove) {\n scrollParent.scrollTo(0, offsetTop - scrollMarginTop - buffer);\n } else if (isBelow) {\n scrollParent.scrollTo(0, offsetTop + offsetHeight + scrollMarginBottom - parentOffsetHeight + buffer);\n }\n};\n\nconst findScrollableParent = (element: HTMLElement | null): HTMLElement | null => {\n if (!element) {\n return null;\n }\n\n if (element.scrollHeight > element.offsetHeight) {\n return element;\n }\n\n return findScrollableParent(element.parentElement);\n};\n\nconst getTotalOffsetTop = (element: HTMLElement, scrollParent: HTMLElement): number => {\n if (!element || element === scrollParent) {\n return 0;\n }\n\n if (element.contains(scrollParent)) {\n // subtract the scroll parent's offset top from the running total if the offsetParent is above it\n return scrollParent.offsetTop * -1;\n }\n\n return element.offsetTop + getTotalOffsetTop(element.offsetParent as HTMLElement, scrollParent);\n};\n\nconst getScrollMargins = (element: HTMLElement) => {\n const win = element.ownerDocument?.defaultView;\n if (!win) {\n return {\n scrollMarginTop: 0,\n scrollMarginBottom: 0,\n };\n }\n\n const computedStyles = win.getComputedStyle(element);\n const scrollMarginTop =\n getIntValueOfComputedStyle(computedStyles.scrollMarginTop) ??\n getIntValueOfComputedStyle(computedStyles.scrollMarginBlockStart);\n const scrollMarginBottom =\n getIntValueOfComputedStyle(computedStyles.scrollMarginBottom) ??\n getIntValueOfComputedStyle(computedStyles.scrollMarginBlockEnd);\n return {\n scrollMarginTop,\n scrollMarginBottom,\n };\n};\n\nconst getIntValueOfComputedStyle = (computedStyle: string) => {\n return computedStyle ? parseInt(computedStyle, 10) : 0;\n};\n"],"names":["scrollIntoView","target","scrollParent","findScrollableParent","parentElement","offsetHeight","offsetTop","getTotalOffsetTop","scrollMarginTop","scrollMarginBottom","getScrollMargins","parentOffsetHeight","scrollTop","isAbove","isBelow","buffer","scrollTo","element","scrollHeight","contains","offsetParent","win","ownerDocument","defaultView","computedStyles","getComputedStyle","getIntValueOfComputedStyle","scrollMarginBlockStart","scrollMarginBlockEnd","computedStyle","parseInt"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,iBAAiB,CAACC;IAC7B,IAAI,CAACA,QAAQ;QACX;IACF;IAEA,MAAMC,eAAeC,qBAAqBF,OAAOG,aAAa;IAC9D,IAAI,CAACF,cAAc;QACjB;IACF;IAEA,MAAM,EAAEG,YAAY,EAAE,GAAGJ;IACzB,MAAMK,YAAYC,kBAAkBN,QAAQC;IAE5C,MAAM,EAAEM,eAAe,EAAEC,kBAAkB,EAAE,GAAGC,iBAAiBT;IAEjE,MAAM,EAAEI,cAAcM,kBAAkB,EAAEC,SAAS,EAAE,GAAGV;IAExD,MAAMW,UAAUP,YAAYE,kBAAkBI;IAC9C,MAAME,UAAUR,YAAYD,eAAeI,qBAAqBG,YAAYD;IAE5E,MAAMI,SAAS;IAEf,IAAIF,SAAS;QACXX,aAAac,QAAQ,CAAC,GAAGV,YAAYE,kBAAkBO;IACzD,OAAO,IAAID,SAAS;QAClBZ,aAAac,QAAQ,CAAC,GAAGV,YAAYD,eAAeI,qBAAqBE,qBAAqBI;IAChG;AACF;AAEA,MAAMZ,uBAAuB,CAACc;IAC5B,IAAI,CAACA,SAAS;QACZ,OAAO;IACT;IAEA,IAAIA,QAAQC,YAAY,GAAGD,QAAQZ,YAAY,EAAE;QAC/C,OAAOY;IACT;IAEA,OAAOd,qBAAqBc,QAAQb,aAAa;AACnD;AAEA,MAAMG,oBAAoB,CAACU,SAAsBf;IAC/C,IAAI,CAACe,WAAWA,YAAYf,cAAc;QACxC,OAAO;IACT;IAEA,IAAIe,QAAQE,QAAQ,CAACjB,eAAe;QAClC,iGAAiG;QACjG,OAAOA,aAAaI,SAAS,GAAG,CAAC;IACnC;IAEA,OAAOW,QAAQX,SAAS,GAAGC,kBAAkBU,QAAQG,YAAY,EAAiBlB;AACpF;AAEA,MAAMQ,mBAAmB,CAACO;QACZA;IAAZ,MAAMI,OAAMJ,yBAAAA,QAAQK,aAAa,cAArBL,6CAAAA,uBAAuBM,WAAW;IAC9C,IAAI,CAACF,KAAK;QACR,OAAO;YACLb,iBAAiB;YACjBC,oBAAoB;QACtB;IACF;IAEA,MAAMe,iBAAiBH,IAAII,gBAAgB,CAACR;QAE1CS;IADF,MAAMlB,kBACJkB,CAAAA,8BAAAA,2BAA2BF,eAAehB,eAAe,eAAzDkB,yCAAAA,8BACAA,2BAA2BF,eAAeG,sBAAsB;QAEhED;IADF,MAAMjB,qBACJiB,CAAAA,+BAAAA,2BAA2BF,eAAef,kBAAkB,eAA5DiB,0CAAAA,+BACAA,2BAA2BF,eAAeI,oBAAoB;IAChE,OAAO;QACLpB;QACAC;IACF;AACF;AAEA,MAAMiB,6BAA6B,CAACG;IAClC,OAAOA,gBAAgBC,SAASD,eAAe,MAAM;AACvD"}

View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/activedescendant/types.ts"],"sourcesContent":["import * as React from 'react';\n\nexport interface ActiveDescendantImperativeRef {\n first: (options?: IteratorOptions) => string | undefined;\n last: (options?: IteratorOptions) => string | undefined;\n next: (options?: IteratorOptions) => string | undefined;\n prev: (options?: IteratorOptions) => string | undefined;\n find: (predicate: (id: string) => boolean, options?: IteratorOptions & FindOptions) => string | undefined;\n blur: () => void;\n active: () => string | undefined;\n focus: (id: string) => void;\n /**\n * @deprecated This function is not used internally anymore and will be removed in the future\n */\n focusLastActive: () => void;\n /**\n * Scrolls the active option into view, if it still exists\n */\n scrollActiveIntoView: () => void;\n hideAttributes: () => void;\n showAttributes: () => void;\n hideFocusVisibleAttributes: () => void;\n showFocusVisibleAttributes: () => void;\n}\n\nexport interface ActiveDescendantOptions {\n /**\n * @param el - HTML element to test\n * @returns whether the element can be an active descendant\n */\n matchOption: (el: HTMLElement) => boolean;\n /**\n * Forward imperative refs when exposing functionality from a React component\n */\n imperativeRef?: React.RefObject<ActiveDescendantImperativeRef | null>;\n}\n\nexport interface FindOptions {\n /**\n * Starts the search from a specific id\n */\n startFrom?: string;\n}\n\nexport interface UseActiveDescendantReturn<\n TActiveParentElement extends HTMLElement = HTMLElement,\n TListboxElement extends HTMLElement = HTMLElement,\n> {\n /**\n * Attach this to the element that contains all active descendants\n */\n listboxRef: React.Ref<TListboxElement>;\n /**\n * Attach this to the element that has an active descendant\n */\n activeParentRef: React.Ref<TActiveParentElement>;\n /**\n * Imperative functions to manage active descendants within the listboxRef\n */\n controller: ActiveDescendantImperativeRef;\n}\n\nexport interface IteratorOptions {\n /**\n * When passive, the active descendant is changed\n * @default false\n */\n passive?: boolean;\n}\n"],"names":[],"mappings":";;;;;iEAAuB"}

View File

@@ -0,0 +1,238 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createActiveDescendantChangeEvent: function() {
return createActiveDescendantChangeEvent;
},
useActiveDescendant: function() {
return useActiveDescendant;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactutilities = require("@fluentui/react-utilities");
const _reacttabster = require("@fluentui/react-tabster");
const _useOptionWalker = require("./useOptionWalker");
const _constants = require("./constants");
const _scrollIntoView = require("./scrollIntoView");
const createActiveDescendantChangeEvent = (detail)=>new CustomEvent('activedescendantchange', {
bubbles: true,
cancelable: false,
composed: true,
detail
});
function useActiveDescendant(options) {
const { imperativeRef, matchOption: matchOptionUnstable } = options;
const focusVisibleRef = _react.useRef(false);
const shouldShowFocusVisibleAttrRef = _react.useRef(true);
const activeIdRef = _react.useRef(null);
const lastActiveIdRef = _react.useRef(null);
const activeParentRef = _react.useRef(null);
const attributeVisibilityRef = _react.useRef(true);
const removeAttribute = _react.useCallback(()=>{
var _activeParentRef_current;
(_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.removeAttribute('aria-activedescendant');
}, []);
const setAttribute = _react.useCallback((id)=>{
if (id) {
activeIdRef.current = id;
}
if (attributeVisibilityRef.current && activeIdRef.current) {
var _activeParentRef_current;
(_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.setAttribute('aria-activedescendant', activeIdRef.current);
}
}, []);
(0, _reacttabster.useOnKeyboardNavigationChange)((isNavigatingWithKeyboard)=>{
focusVisibleRef.current = isNavigatingWithKeyboard;
const active = getActiveDescendant();
if (!active) {
return;
}
if (isNavigatingWithKeyboard && shouldShowFocusVisibleAttrRef.current) {
active.setAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');
} else {
active.removeAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);
}
});
const matchOption = (0, _reactutilities.useEventCallback)(matchOptionUnstable);
const listboxRef = _react.useRef(null);
const { optionWalker, listboxCallbackRef } = (0, _useOptionWalker.useOptionWalker)({
matchOption
});
const getActiveDescendant = _react.useCallback(()=>{
var _listboxRef_current;
return (_listboxRef_current = listboxRef.current) === null || _listboxRef_current === void 0 ? void 0 : _listboxRef_current.querySelector(`#${activeIdRef.current}`);
}, [
listboxRef
]);
const setShouldShowFocusVisibleAttribute = _react.useCallback((shouldShow)=>{
shouldShowFocusVisibleAttrRef.current = shouldShow;
const active = getActiveDescendant();
if (!active) {
return;
}
if (shouldShow && focusVisibleRef.current) {
active.setAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');
} else {
active.removeAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);
}
}, [
getActiveDescendant
]);
const blurActiveDescendant = _react.useCallback(()=>{
const active = getActiveDescendant();
if (active) {
active.removeAttribute(_constants.ACTIVEDESCENDANT_ATTRIBUTE);
active.removeAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE);
}
removeAttribute();
lastActiveIdRef.current = activeIdRef.current;
activeIdRef.current = null;
var _active_id;
return (_active_id = active === null || active === void 0 ? void 0 : active.id) !== null && _active_id !== void 0 ? _active_id : null;
}, [
getActiveDescendant,
removeAttribute
]);
const focusActiveDescendant = _react.useCallback((nextActive)=>{
if (!nextActive) {
return;
}
const previousActiveId = blurActiveDescendant();
(0, _scrollIntoView.scrollIntoView)(nextActive);
setAttribute(nextActive.id);
nextActive.setAttribute(_constants.ACTIVEDESCENDANT_ATTRIBUTE, '');
if (focusVisibleRef.current && shouldShowFocusVisibleAttrRef.current) {
nextActive.setAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, '');
}
const event = createActiveDescendantChangeEvent({
id: nextActive.id,
previousId: previousActiveId
});
nextActive.dispatchEvent(event);
}, [
blurActiveDescendant,
setAttribute
]);
const controller = _react.useMemo(()=>({
first: ({ passive } = {})=>{
const first = optionWalker.first();
if (!passive) {
focusActiveDescendant(first);
}
return first === null || first === void 0 ? void 0 : first.id;
},
last: ({ passive } = {})=>{
const last = optionWalker.last();
if (!passive) {
focusActiveDescendant(last);
}
return last === null || last === void 0 ? void 0 : last.id;
},
next: ({ passive } = {})=>{
const active = getActiveDescendant();
if (!active) {
return;
}
optionWalker.setCurrent(active);
const next = optionWalker.next();
if (!passive) {
focusActiveDescendant(next);
}
return next === null || next === void 0 ? void 0 : next.id;
},
prev: ({ passive } = {})=>{
const active = getActiveDescendant();
if (!active) {
return;
}
optionWalker.setCurrent(active);
const next = optionWalker.prev();
if (!passive) {
focusActiveDescendant(next);
}
return next === null || next === void 0 ? void 0 : next.id;
},
blur: ()=>{
blurActiveDescendant();
},
active: ()=>{
var _getActiveDescendant;
return (_getActiveDescendant = getActiveDescendant()) === null || _getActiveDescendant === void 0 ? void 0 : _getActiveDescendant.id;
},
focus: (id)=>{
if (!listboxRef.current) {
return;
}
const target = listboxRef.current.querySelector(`#${id}`);
if (target) {
focusActiveDescendant(target);
}
},
focusLastActive: ()=>{
if (!listboxRef.current || !lastActiveIdRef.current) {
return;
}
const target = listboxRef.current.querySelector(`#${lastActiveIdRef.current}`);
if (target) {
focusActiveDescendant(target);
return true;
}
},
find (predicate, { passive, startFrom } = {}) {
const target = optionWalker.find(predicate, startFrom);
if (!passive) {
focusActiveDescendant(target);
}
return target === null || target === void 0 ? void 0 : target.id;
},
scrollActiveIntoView: ()=>{
if (!listboxRef.current) {
return;
}
const active = getActiveDescendant();
if (!active) {
return;
}
(0, _scrollIntoView.scrollIntoView)(active);
},
showAttributes () {
attributeVisibilityRef.current = true;
setAttribute();
},
hideAttributes () {
attributeVisibilityRef.current = false;
removeAttribute();
},
showFocusVisibleAttributes () {
setShouldShowFocusVisibleAttribute(true);
},
hideFocusVisibleAttributes () {
setShouldShowFocusVisibleAttribute(false);
}
}), [
optionWalker,
listboxRef,
setAttribute,
removeAttribute,
focusActiveDescendant,
blurActiveDescendant,
getActiveDescendant,
setShouldShowFocusVisibleAttribute
]);
_react.useImperativeHandle(imperativeRef, ()=>controller);
return {
listboxRef: (0, _reactutilities.useMergedRefs)(listboxRef, listboxCallbackRef),
activeParentRef,
controller
};
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,93 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useOptionWalker", {
enumerable: true,
get: function() {
return useOptionWalker;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _reactutilities = require("@fluentui/react-utilities");
function useOptionWalker(options) {
const { matchOption } = options;
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
const treeWalkerRef = _react.useRef(null);
const listboxRef = _react.useRef(null);
const optionFilter = _react.useCallback((node)=>{
if ((0, _reactutilities.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;
treeWalkerRef.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
};
}

File diff suppressed because one or more lines are too long