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,22 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AriaLiveAnnouncer", {
enumerable: true,
get: function() {
return AriaLiveAnnouncer;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _renderAriaLiveAnnouncer = require("./renderAriaLiveAnnouncer");
const _useAriaLiveAnnouncer = require("./useAriaLiveAnnouncer");
const _useAriaLiveAnnouncerContextValues = require("./useAriaLiveAnnouncerContextValues");
const AriaLiveAnnouncer = (props)=>{
const state = (0, _useAriaLiveAnnouncer.useAriaLiveAnnouncer_unstable)(props);
const contextValues = (0, _useAriaLiveAnnouncerContextValues.useAriaLiveAnnouncerContextValues_unstable)(state);
return (0, _renderAriaLiveAnnouncer.renderAriaLiveAnnouncer_unstable)(state, contextValues);
};
AriaLiveAnnouncer.displayName = 'AriaLiveAnnouncer';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/AriaLiveAnnouncer/AriaLiveAnnouncer.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport type { AriaLiveAnnouncerProps } from './AriaLiveAnnouncer.types';\nimport { renderAriaLiveAnnouncer_unstable } from './renderAriaLiveAnnouncer';\nimport { useAriaLiveAnnouncer_unstable } from './useAriaLiveAnnouncer';\nimport { useAriaLiveAnnouncerContextValues_unstable } from './useAriaLiveAnnouncerContextValues';\n\n/**\n * A sample implementation of a component that manages aria live announcements.\n */\nexport const AriaLiveAnnouncer: React.FC<AriaLiveAnnouncerProps> = props => {\n const state = useAriaLiveAnnouncer_unstable(props);\n const contextValues = useAriaLiveAnnouncerContextValues_unstable(state);\n\n return renderAriaLiveAnnouncer_unstable(state, contextValues);\n};\n\nAriaLiveAnnouncer.displayName = 'AriaLiveAnnouncer';\n"],"names":["AriaLiveAnnouncer","props","state","useAriaLiveAnnouncer_unstable","contextValues","useAriaLiveAnnouncerContextValues_unstable","renderAriaLiveAnnouncer_unstable","displayName"],"mappings":"AAAA;;;;;+BAYaA;;;eAAAA;;;;iEAVU;yCAG0B;sCACH;mDACa;AAKpD,MAAMA,oBAAsDC,CAAAA;IACjE,MAAMC,QAAQC,IAAAA,mDAA6B,EAACF;IAC5C,MAAMG,gBAAgBC,IAAAA,6EAA0C,EAACH;IAEjE,OAAOI,IAAAA,yDAAgC,EAACJ,OAAOE;AACjD;AAEAJ,kBAAkBO,WAAW,GAAG"}

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/AriaLiveAnnouncer/AriaLiveAnnouncer.types.ts"],"sourcesContent":["import type { AnnounceContextValue } from '@fluentui/react-shared-contexts';\nimport * as React from 'react';\n\nexport type AriaLiveAnnounceFn = AnnounceContextValue['announce'];\n\nexport type AriaLiveMessage = {\n message: string;\n\n createdAt: number;\n\n priority: number;\n batchId?: string;\n};\n\nexport type AriaLiveAnnouncerProps = {\n children?: React.ReactNode;\n};\n\nexport type AriaLiveAnnouncerState = {\n announce: AriaLiveAnnounceFn;\n children?: React.ReactNode;\n};\n\nexport type AriaLiveAnnouncerContextValues = {\n announce: { announce: AriaLiveAnnounceFn };\n};\n"],"names":[],"mappings":";;;;;iEACuB"}

View File

@@ -0,0 +1,28 @@
"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, {
AriaLiveAnnouncer: function() {
return _AriaLiveAnnouncer.AriaLiveAnnouncer;
},
renderAriaLiveAnnouncer_unstable: function() {
return _renderAriaLiveAnnouncer.renderAriaLiveAnnouncer_unstable;
},
useAriaLiveAnnouncerContextValues_unstable: function() {
return _useAriaLiveAnnouncerContextValues.useAriaLiveAnnouncerContextValues_unstable;
},
useAriaLiveAnnouncer_unstable: function() {
return _useAriaLiveAnnouncer.useAriaLiveAnnouncer_unstable;
}
});
const _AriaLiveAnnouncer = require("./AriaLiveAnnouncer");
const _renderAriaLiveAnnouncer = require("./renderAriaLiveAnnouncer");
const _useAriaLiveAnnouncer = require("./useAriaLiveAnnouncer");
const _useAriaLiveAnnouncerContextValues = require("./useAriaLiveAnnouncerContextValues");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/AriaLiveAnnouncer/index.ts"],"sourcesContent":["export { AriaLiveAnnouncer } from './AriaLiveAnnouncer';\nexport type { AriaLiveAnnouncerProps, AriaLiveAnnouncerState } from './AriaLiveAnnouncer.types';\nexport { renderAriaLiveAnnouncer_unstable } from './renderAriaLiveAnnouncer';\nexport { useAriaLiveAnnouncer_unstable } from './useAriaLiveAnnouncer';\nexport { useAriaLiveAnnouncerContextValues_unstable } from './useAriaLiveAnnouncerContextValues';\n"],"names":["AriaLiveAnnouncer","renderAriaLiveAnnouncer_unstable","useAriaLiveAnnouncerContextValues_unstable","useAriaLiveAnnouncer_unstable"],"mappings":";;;;;;;;;;;IAASA,iBAAiB;eAAjBA,oCAAiB;;IAEjBC,gCAAgC;eAAhCA,yDAAgC;;IAEhCC,0CAA0C;eAA1CA,6EAA0C;;IAD1CC,6BAA6B;eAA7BA,mDAA6B;;;mCAHJ;yCAEe;sCACH;mDACa"}

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "renderAriaLiveAnnouncer_unstable", {
enumerable: true,
get: function() {
return renderAriaLiveAnnouncer_unstable;
}
});
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 renderAriaLiveAnnouncer_unstable = (state, contextValues)=>{
return /*#__PURE__*/ _react.createElement(_reactsharedcontexts.AnnounceProvider, {
value: contextValues.announce
}, state.children);
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/AriaLiveAnnouncer/renderAriaLiveAnnouncer.tsx"],"sourcesContent":["import * as React from 'react';\nimport { AnnounceProvider } from '@fluentui/react-shared-contexts';\n\nimport type { AriaLiveAnnouncerContextValues, AriaLiveAnnouncerState } from './AriaLiveAnnouncer.types';\nimport type { JSXElement } from '@fluentui/react-utilities';\n\nexport const renderAriaLiveAnnouncer_unstable = (\n state: AriaLiveAnnouncerState,\n contextValues: AriaLiveAnnouncerContextValues,\n): JSXElement => {\n return <AnnounceProvider value={contextValues.announce}>{state.children}</AnnounceProvider>;\n};\n"],"names":["renderAriaLiveAnnouncer_unstable","state","contextValues","AnnounceProvider","value","announce","children"],"mappings":";;;;+BAMaA;;;eAAAA;;;;iEANU;qCACU;AAK1B,MAAMA,mCAAmC,CAC9CC,OACAC;IAEA,qBAAO,qBAACC,qCAAgB;QAACC,OAAOF,cAAcG,QAAQ;OAAGJ,MAAMK,QAAQ;AACzE"}

View File

@@ -0,0 +1,34 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useAriaLiveAnnouncer_unstable", {
enumerable: true,
get: function() {
return useAriaLiveAnnouncer_unstable;
}
});
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 _useDomAnnounce = require("./useDomAnnounce");
const _useAriaNotifyAnnounce = require("./useAriaNotifyAnnounce");
const useAriaLiveAnnouncer_unstable = (props)=>{
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
const domAnnounce = (0, _useDomAnnounce.useDomAnnounce_unstable)();
const ariaNotifyAnnounce = (0, _useAriaNotifyAnnounce.useAriaNotifyAnnounce_unstable)();
const announce = _react.useMemo(()=>{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const supportsAriaNotify = typeof (targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.ariaNotify) === 'function';
return supportsAriaNotify ? ariaNotifyAnnounce : domAnnounce;
}, [
targetDocument,
ariaNotifyAnnounce,
domAnnounce
]);
return {
announce,
children: props.children
};
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/AriaLiveAnnouncer/useAriaLiveAnnouncer.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { useDomAnnounce_unstable } from './useDomAnnounce';\nimport { useAriaNotifyAnnounce_unstable } from './useAriaNotifyAnnounce';\n\nimport type { AriaLiveAnnouncerState, AriaLiveAnnouncerProps } from './AriaLiveAnnouncer.types';\n\nexport const useAriaLiveAnnouncer_unstable = (props: AriaLiveAnnouncerProps): AriaLiveAnnouncerState => {\n const { targetDocument } = useFluent();\n const domAnnounce = useDomAnnounce_unstable();\n const ariaNotifyAnnounce = useAriaNotifyAnnounce_unstable();\n\n const announce = React.useMemo(() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const supportsAriaNotify = typeof (targetDocument as any)?.ariaNotify === 'function';\n return supportsAriaNotify ? ariaNotifyAnnounce : domAnnounce;\n }, [targetDocument, ariaNotifyAnnounce, domAnnounce]);\n\n return {\n announce,\n children: props.children,\n };\n};\n"],"names":["useAriaLiveAnnouncer_unstable","props","targetDocument","useFluent","domAnnounce","useDomAnnounce_unstable","ariaNotifyAnnounce","useAriaNotifyAnnounce_unstable","announce","React","useMemo","supportsAriaNotify","ariaNotify","children"],"mappings":"AAAA;;;;;+BASaA;;;eAAAA;;;;iEAPU;qCACyB;gCACR;uCACO;AAIxC,MAAMA,gCAAgC,CAACC;IAC5C,MAAM,EAAEC,cAAc,EAAE,GAAGC,IAAAA,uCAAS;IACpC,MAAMC,cAAcC,IAAAA,uCAAuB;IAC3C,MAAMC,qBAAqBC,IAAAA,qDAA8B;IAEzD,MAAMC,WAAWC,OAAMC,OAAO,CAAC;QAC7B,8DAA8D;QAC9D,MAAMC,qBAAqB,QAAQT,2BAAAA,qCAAD,AAACA,eAAwBU,UAAU,MAAK;QAC1E,OAAOD,qBAAqBL,qBAAqBF;IACnD,GAAG;QAACF;QAAgBI;QAAoBF;KAAY;IAEpD,OAAO;QACLI;QACAK,UAAUZ,MAAMY,QAAQ;IAC1B;AACF"}

View File

@@ -0,0 +1,23 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useAriaLiveAnnouncerContextValues_unstable", {
enumerable: true,
get: function() {
return useAriaLiveAnnouncerContextValues_unstable;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
function useAriaLiveAnnouncerContextValues_unstable(state) {
const { announce } = state;
return _react.useMemo(()=>({
announce: {
announce
}
}), [
announce
]);
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/AriaLiveAnnouncer/useAriaLiveAnnouncerContextValues.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { AriaLiveAnnouncerContextValues, AriaLiveAnnouncerState } from './AriaLiveAnnouncer.types';\n\nexport function useAriaLiveAnnouncerContextValues_unstable(\n state: AriaLiveAnnouncerState,\n): AriaLiveAnnouncerContextValues {\n const { announce } = state;\n\n return React.useMemo(() => ({ announce: { announce } }), [announce]);\n}\n"],"names":["useAriaLiveAnnouncerContextValues_unstable","state","announce","React","useMemo"],"mappings":"AAAA;;;;;+BAKgBA;;;eAAAA;;;;iEAHO;AAGhB,SAASA,2CACdC,KAA6B;IAE7B,MAAM,EAAEC,QAAQ,EAAE,GAAGD;IAErB,OAAOE,OAAMC,OAAO,CAAC,IAAO,CAAA;YAAEF,UAAU;gBAAEA;YAAS;QAAE,CAAA,GAAI;QAACA;KAAS;AACrE"}

View File

@@ -0,0 +1,36 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useAriaNotifyAnnounce_unstable", {
enumerable: true,
get: function() {
return useAriaNotifyAnnounce_unstable;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const useAriaNotifyAnnounce_unstable = ()=>{
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
const announce = _react.useCallback((message, options = {})=>{
if (!targetDocument) {
return;
}
const { alert = false, polite } = options;
// default priority to 0 if polite, 2 if alert, and 1 by default
// used to set both ariaNotify's priority and interrupt
const defaultPriority = polite ? 0 : alert ? 2 : 1;
var _options_priority;
const priority = (_options_priority = options.priority) !== null && _options_priority !== void 0 ? _options_priority : defaultPriority;
// map fluent announce options to ariaNotify options
const ariaNotifyOptions = {
priority: priority > 1 ? 'high' : 'normal'
};
targetDocument.ariaNotify(message, ariaNotifyOptions);
}, [
targetDocument
]);
return announce;
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/AriaLiveAnnouncer/useAriaNotifyAnnounce.ts"],"sourcesContent":["'use client';\n\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport type { AnnounceOptions } from '@fluentui/react-shared-contexts';\nimport * as React from 'react';\n\nimport type { AriaLiveAnnounceFn } from './AriaLiveAnnouncer.types';\n\ntype AriaNotifyOptions = {\n priority?: 'high' | 'normal';\n};\n\ntype DocumentWithAriaNotify = Document & {\n ariaNotify: (message: string, options: AriaNotifyOptions) => void;\n};\n\n/* INTERNAL: implementation of the announcer using the ariaNotify API */\nexport const useAriaNotifyAnnounce_unstable = (): AriaLiveAnnounceFn => {\n const { targetDocument } = useFluent();\n\n const announce: AriaLiveAnnounceFn = React.useCallback(\n (message: string, options: AnnounceOptions = {}) => {\n if (!targetDocument) {\n return;\n }\n\n const { alert = false, polite } = options;\n\n // default priority to 0 if polite, 2 if alert, and 1 by default\n // used to set both ariaNotify's priority and interrupt\n const defaultPriority = polite ? 0 : alert ? 2 : 1;\n const priority = options.priority ?? defaultPriority;\n\n // map fluent announce options to ariaNotify options\n const ariaNotifyOptions: AriaNotifyOptions = {\n priority: priority > 1 ? 'high' : 'normal',\n };\n\n (targetDocument as DocumentWithAriaNotify).ariaNotify(message, ariaNotifyOptions);\n },\n [targetDocument],\n );\n\n return announce;\n};\n"],"names":["useAriaNotifyAnnounce_unstable","targetDocument","useFluent","announce","React","useCallback","message","options","alert","polite","defaultPriority","priority","ariaNotifyOptions","ariaNotify"],"mappings":"AAAA;;;;;+BAiBaA;;;eAAAA;;;;qCAfmC;iEAEzB;AAahB,MAAMA,iCAAiC;IAC5C,MAAM,EAAEC,cAAc,EAAE,GAAGC,IAAAA,uCAAS;IAEpC,MAAMC,WAA+BC,OAAMC,WAAW,CACpD,CAACC,SAAiBC,UAA2B,CAAC,CAAC;QAC7C,IAAI,CAACN,gBAAgB;YACnB;QACF;QAEA,MAAM,EAAEO,QAAQ,KAAK,EAAEC,MAAM,EAAE,GAAGF;QAElC,gEAAgE;QAChE,uDAAuD;QACvD,MAAMG,kBAAkBD,SAAS,IAAID,QAAQ,IAAI;YAChCD;QAAjB,MAAMI,WAAWJ,CAAAA,oBAAAA,QAAQI,QAAQ,cAAhBJ,+BAAAA,oBAAoBG;QAErC,oDAAoD;QACpD,MAAME,oBAAuC;YAC3CD,UAAUA,WAAW,IAAI,SAAS;QACpC;QAECV,eAA0CY,UAAU,CAACP,SAASM;IACjE,GACA;QAACX;KAAe;IAGlB,OAAOE;AACT"}

View File

@@ -0,0 +1,145 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useDomAnnounce_unstable", {
enumerable: true,
get: function() {
return useDomAnnounce_unstable;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _reactutilities = require("@fluentui/react-utilities");
const _reacttabster = require("@fluentui/react-tabster");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
/** The duration the message needs to be in present in DOM for screen readers to register a change and announce */ const MESSAGE_DURATION = 500;
const VISUALLY_HIDDEN_STYLES = {
clip: 'rect(0px, 0px, 0px, 0px)',
height: '1px',
margin: '-1px',
width: '1px',
position: 'absolute',
overflow: 'hidden',
textWrap: 'nowrap'
};
const useDomAnnounce_unstable = ()=>{
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
const timeoutRef = _react.useRef(undefined);
const [setAnnounceTimeout, clearAnnounceTimeout] = (0, _reactutilities.useTimeout)();
const tabsterNeverHiddenAttributes = (0, _reacttabster.useDangerousNeverHidden_unstable)();
const elementRef = _react.useRef(null);
const order = _react.useRef(0);
// investigate alert implementation later
// const [alertList, setAlertList] = React.useState<string[]>([]);
const batchMessages = _react.useRef([]);
const [messageQueue] = _react.useState(()=>(0, _reactutilities.createPriorityQueue)((a, b)=>{
if (a.priority !== b.priority) {
return b.priority - a.priority;
}
return a.createdAt - b.createdAt;
}));
const queueMessage = _react.useCallback(()=>{
if (timeoutRef.current || !elementRef.current) {
return;
}
const runCycle = ()=>{
if (!elementRef.current) {
return;
}
if (targetDocument && messageQueue.peek()) {
// need a wrapping element for Narrator/Edge, which currently does not pick up text-only live region changes
// consistently
// if this is fixed, we can set textContent to the string directly
const wrappingEl = targetDocument.createElement('span');
wrappingEl.innerText = messageQueue.all().filter((msg)=>msg.message.trim().length > 0).reduce((prevText, currMsg)=>prevText + currMsg.message + '. ', '');
elementRef.current.innerText = '';
elementRef.current.appendChild(wrappingEl);
messageQueue.clear();
batchMessages.current = [];
// begin new cycle to clear (or update) messages
timeoutRef.current = setAnnounceTimeout(()=>{
runCycle();
}, MESSAGE_DURATION);
} else {
elementRef.current.textContent = '';
clearAnnounceTimeout();
timeoutRef.current = undefined;
}
};
// Run the first cycle with a 0 timeout to ensure multiple messages in the same tick are handled
timeoutRef.current = setAnnounceTimeout(()=>{
runCycle();
}, 0);
}, [
clearAnnounceTimeout,
messageQueue,
setAnnounceTimeout,
targetDocument
]);
const announce = _react.useCallback((message, options = {})=>{
const { alert = false, priority = 0, batchId } = options;
// check if message is an alert
if (alert) {
// TODO: alert implementation
// setAlertList([...alertList, message]);
}
const liveMessage = {
message,
createdAt: order.current++,
priority,
batchId
};
// check if batchId exists
if (batchId) {
// update associated msg if it does
const batchMessage = batchMessages.current.find((msg)=>msg.batchId === batchId);
if (batchMessage) {
// replace existing message in queue
messageQueue.remove(batchMessage.message);
// update list of existing batchIds w/ most recent message
batchMessage.message = liveMessage;
} else {
// update list of existing batchIds, add new if doesn't already exist
batchMessages.current = [
...batchMessages.current,
{
batchId,
message: liveMessage
}
];
}
}
// add new message
messageQueue.enqueue(liveMessage);
queueMessage();
}, [
messageQueue,
queueMessage
]);
_react.useEffect(()=>{
if (!targetDocument) {
return;
}
const element = targetDocument.createElement('div');
element.setAttribute('aria-live', 'assertive');
Object.entries(tabsterNeverHiddenAttributes).forEach(([key, value])=>{
element.setAttribute(key, value);
});
Object.assign(element.style, VISUALLY_HIDDEN_STYLES);
targetDocument.body.append(element);
elementRef.current = element;
return ()=>{
element.remove();
elementRef.current = null;
clearAnnounceTimeout();
timeoutRef.current = undefined;
};
}, [
clearAnnounceTimeout,
tabsterNeverHiddenAttributes,
targetDocument
]);
return announce;
};

File diff suppressed because one or more lines are too long

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

View File

@@ -0,0 +1,20 @@
"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, {
useARIAButtonProps: function() {
return _useARIAButtonProps.useARIAButtonProps;
},
useARIAButtonShorthand: function() {
return _useARIAButtonShorthand.useARIAButtonShorthand;
}
});
const _useARIAButtonProps = require("./useARIAButtonProps");
const _useARIAButtonShorthand = require("./useARIAButtonShorthand");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/button/index.ts"],"sourcesContent":["export { useARIAButtonProps } from './useARIAButtonProps';\n// eslint-disable-next-line @typescript-eslint/no-deprecated\nexport { useARIAButtonShorthand } from './useARIAButtonShorthand';\nexport type {\n ARIAButtonAlteredProps,\n ARIAButtonElement,\n ARIAButtonElementIntersection,\n ARIAButtonProps,\n ARIAButtonResultProps,\n ARIAButtonSlotProps,\n ARIAButtonType,\n} from './types';\n"],"names":["useARIAButtonProps","useARIAButtonShorthand"],"mappings":";;;;;;;;;;;IAASA,kBAAkB;eAAlBA,sCAAkB;;IAElBC,sBAAsB;eAAtBA,8CAAsB;;;oCAFI;wCAEI"}

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/button/types.ts"],"sourcesContent":["import type {\n DistributiveOmit,\n ExtractSlotProps,\n Slot,\n UnionToIntersection,\n JSXIntrinsicElement,\n} from '@fluentui/react-utilities';\nimport * as React from 'react';\n\nexport type ARIAButtonType = 'button' | 'a' | 'div';\n\nexport type ARIAButtonElement<AlternateAs extends 'a' | 'div' = 'a' | 'div'> =\n | HTMLButtonElement\n | (AlternateAs extends 'a' ? HTMLAnchorElement : never)\n | (AlternateAs extends 'div' ? HTMLDivElement : never);\n\n/**\n * @internal\n */\nexport type ARIAButtonElementIntersection<AlternateAs extends 'a' | 'div' = 'a' | 'div'> = UnionToIntersection<\n ARIAButtonElement<AlternateAs>\n>;\n\n/**\n * Props expected by `useARIAButtonProps` hooks\n */\nexport type ARIAButtonProps<Type extends ARIAButtonType = ARIAButtonType> = DistributiveOmit<\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n React.PropsWithRef<JSXIntrinsicElement<Type>>,\n 'children'\n> & {\n disabled?: boolean;\n /**\n * When set, allows the button to be focusable even when it has been disabled.\n * This is used in scenarios where it is important to keep a consistent tab order\n * for screen reader and keyboard users. The primary example of this\n * pattern is when the disabled button is in a menu or a commandbar and is seldom used for standalone buttons.\n *\n * @default false\n */\n disabledFocusable?: boolean;\n};\n\nexport type ARIAButtonSlotProps<AlternateAs extends 'a' | 'div' = 'a' | 'div'> = ExtractSlotProps<\n Slot<'button', AlternateAs>\n> &\n Pick<ARIAButtonProps<ARIAButtonType>, 'disabled' | 'disabledFocusable'>;\n\n/**\n * Props that will be modified internally by `useARIAButtonProps` by each case.\n * This typing is to ensure a well specified return value for `useARIAbButtonProps`\n */\nexport type ARIAButtonAlteredProps<Type extends ARIAButtonType> =\n | (Type extends 'button'\n ? Pick<\n JSXIntrinsicElement<'button'>,\n 'onClick' | 'onKeyDown' | 'onKeyUp' | 'disabled' | 'aria-disabled' | 'tabIndex'\n >\n : never)\n | (Type extends 'a'\n ? Pick<\n JSXIntrinsicElement<'a'>,\n 'onClick' | 'onKeyDown' | 'onKeyUp' | 'aria-disabled' | 'tabIndex' | 'role' | 'href'\n >\n : never)\n | (Type extends 'div'\n ? Pick<JSXIntrinsicElement<'div'>, 'onClick' | 'onKeyDown' | 'onKeyUp' | 'aria-disabled' | 'tabIndex' | 'role'>\n : never);\n\n/**\n * Merge of props provided by the user and props provided internally.\n */\nexport type ARIAButtonResultProps<Type extends ARIAButtonType, Props> = Props &\n UnionToIntersection<ARIAButtonAlteredProps<Type>>;\n"],"names":[],"mappings":";;;;;iEAOuB"}

View File

@@ -0,0 +1,100 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useARIAButtonProps", {
enumerable: true,
get: function() {
return useARIAButtonProps;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _keyboardkeys = require("@fluentui/keyboard-keys");
const _reactutilities = require("@fluentui/react-utilities");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
function useARIAButtonProps(type, props) {
const { disabled, disabledFocusable = false, ['aria-disabled']: ariaDisabled, onClick, onKeyDown, onKeyUp, ...rest } = props !== null && props !== void 0 ? props : {};
const normalizedARIADisabled = typeof ariaDisabled === 'string' ? ariaDisabled === 'true' : ariaDisabled;
const isDisabled = disabled || disabledFocusable || normalizedARIADisabled;
const handleClick = (0, _reactutilities.useEventCallback)((ev)=>{
if (isDisabled) {
ev.preventDefault();
ev.stopPropagation();
} else {
onClick === null || onClick === void 0 ? void 0 : onClick(ev);
}
});
const handleKeyDown = (0, _reactutilities.useEventCallback)((ev)=>{
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(ev);
if (ev.isDefaultPrevented()) {
return;
}
const key = ev.key;
if (isDisabled && (key === _keyboardkeys.Enter || key === _keyboardkeys.Space)) {
ev.preventDefault();
ev.stopPropagation();
return;
}
if (key === _keyboardkeys.Space) {
ev.preventDefault();
return;
} else if (key === _keyboardkeys.Enter) {
ev.preventDefault();
ev.currentTarget.click();
}
});
const handleKeyUp = (0, _reactutilities.useEventCallback)((ev)=>{
onKeyUp === null || onKeyUp === void 0 ? void 0 : onKeyUp(ev);
if (ev.isDefaultPrevented()) {
return;
}
const key = ev.key;
if (isDisabled && (key === _keyboardkeys.Enter || key === _keyboardkeys.Space)) {
ev.preventDefault();
ev.stopPropagation();
return;
}
if (key === _keyboardkeys.Space) {
ev.preventDefault();
ev.currentTarget.click();
}
});
// If a <button> tag is to be rendered we just need to set disabled and aria-disabled correctly
if (type === 'button' || type === undefined) {
return {
...rest,
disabled: disabled && !disabledFocusable,
'aria-disabled': disabledFocusable ? true : normalizedARIADisabled,
// onclick should still use internal handler to ensure prevention if disabled
// if disabledFocusable then there's no requirement for handlers as those events should not be propagated
onClick: disabledFocusable ? undefined : handleClick,
onKeyUp: disabledFocusable ? undefined : onKeyUp,
onKeyDown: disabledFocusable ? undefined : onKeyDown
};
} else {
// the role needs to be explicitly set if the href is undefined
const isLink = !!rest.href;
let roleOverride = isLink ? undefined : 'button';
if (!roleOverride && isDisabled) {
// need to set role=link explicitly for disabled links
roleOverride = 'link';
}
const resultProps = {
role: roleOverride,
tabIndex: disabledFocusable || !isLink && !disabled ? 0 : undefined,
...rest,
// If it's not a <button> than listeners are required even with disabledFocusable
// Since you cannot assure the default behavior of the element
// E.g: <a> will redirect on click
onClick: handleClick,
onKeyUp: handleKeyUp,
onKeyDown: handleKeyDown,
'aria-disabled': isDisabled
};
if (type === 'a' && isDisabled) {
resultProps.href = undefined;
}
return resultProps;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useARIAButtonShorthand", {
enumerable: true,
get: function() {
return useARIAButtonShorthand;
}
});
const _reactutilities = require("@fluentui/react-utilities");
const _useARIAButtonProps = require("./useARIAButtonProps");
const useARIAButtonShorthand = (value, options)=>{
// eslint-disable-next-line @typescript-eslint/no-deprecated
const shorthand = (0, _reactutilities.resolveShorthand)(value, options);
var _shorthand_as;
const shorthandARIAButton = (0, _useARIAButtonProps.useARIAButtonProps)((_shorthand_as = shorthand === null || shorthand === void 0 ? void 0 : shorthand.as) !== null && _shorthand_as !== void 0 ? _shorthand_as : 'button', shorthand);
return shorthand && shorthandARIAButton;
// eslint-disable-next-line @typescript-eslint/no-deprecated
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/button/useARIAButtonShorthand.ts"],"sourcesContent":["'use client';\n\nimport { resolveShorthand } from '@fluentui/react-utilities';\nimport { useARIAButtonProps } from './useARIAButtonProps';\nimport type { ResolveShorthandFunction } from '@fluentui/react-utilities';\nimport type { ARIAButtonProps, ARIAButtonSlotProps, ARIAButtonType } from './types';\n\n/**\n * @internal\n *\n * @deprecated use useARIAButtonProps instead\n *\n * This function expects to receive a slot, if `as` property is not desired use `useARIAButtonProps` instead\n *\n * Button keyboard handling, role, disabled and tabIndex implementation that ensures ARIA spec\n * for multiple scenarios of shorthand properties. Ensuring 1st rule of ARIA for cases\n * where no attribute addition is required.\n */\nexport const useARIAButtonShorthand = ((value, options) => {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const shorthand = resolveShorthand(value, options);\n const shorthandARIAButton = useARIAButtonProps<ARIAButtonType, ARIAButtonProps>(shorthand?.as ?? 'button', shorthand);\n return shorthand && shorthandARIAButton;\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n}) as ResolveShorthandFunction<ARIAButtonSlotProps>;\n"],"names":["useARIAButtonShorthand","value","options","shorthand","resolveShorthand","shorthandARIAButton","useARIAButtonProps","as"],"mappings":"AAAA;;;;;+BAkBaA;;;eAAAA;;;gCAhBoB;oCACE;AAe5B,MAAMA,yBAA0B,CAACC,OAAOC;IAC7C,4DAA4D;IAC5D,MAAMC,YAAYC,IAAAA,gCAAgB,EAACH,OAAOC;QACsCC;IAAhF,MAAME,sBAAsBC,IAAAA,sCAAkB,EAAkCH,CAAAA,gBAAAA,sBAAAA,gCAAAA,UAAWI,EAAE,cAAbJ,2BAAAA,gBAAiB,UAAUA;IAC3G,OAAOA,aAAaE;AACpB,4DAA4D;AAC9D"}

View File

@@ -0,0 +1,53 @@
"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_FOCUSVISIBLE_ATTRIBUTE: function() {
return _activedescendant.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE;
},
ActiveDescendantContextProvider: function() {
return _activedescendant.ActiveDescendantContextProvider;
},
AriaLiveAnnouncer: function() {
return _index1.AriaLiveAnnouncer;
},
renderAriaLiveAnnouncer_unstable: function() {
return _index1.renderAriaLiveAnnouncer_unstable;
},
useARIAButtonProps: function() {
return _index.useARIAButtonProps;
},
// eslint-disable-next-line @typescript-eslint/no-deprecated
useARIAButtonShorthand: function() {
return _index.useARIAButtonShorthand;
},
useActiveDescendant: function() {
return _activedescendant.useActiveDescendant;
},
useActiveDescendantContext: function() {
return _activedescendant.useActiveDescendantContext;
},
useAriaLiveAnnouncerContextValues_unstable: function() {
return _index1.useAriaLiveAnnouncerContextValues_unstable;
},
useAriaLiveAnnouncer_unstable: function() {
return _index1.useAriaLiveAnnouncer_unstable;
},
useHasParentActiveDescendantContext: function() {
return _activedescendant.useHasParentActiveDescendantContext;
},
useTypingAnnounce: function() {
return _index2.useTypingAnnounce;
}
});
const _index = require("./button/index");
const _activedescendant = require("./activedescendant");
const _index1 = require("./AriaLiveAnnouncer/index");
const _index2 = require("./useTypingAnnounce/index");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n useARIAButtonShorthand,\n useARIAButtonProps,\n} from './button/index';\nexport {\n useActiveDescendant,\n ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE,\n ActiveDescendantContextProvider,\n useActiveDescendantContext,\n useHasParentActiveDescendantContext,\n} from './activedescendant';\nexport type {\n ActiveDescendantImperativeRef,\n ActiveDescendantOptions,\n ActiveDescendantContextValue,\n ActiveDescendantChangeEvent,\n} from './activedescendant';\nexport type {\n ARIAButtonSlotProps,\n ARIAButtonProps,\n ARIAButtonResultProps,\n ARIAButtonType,\n ARIAButtonElement,\n ARIAButtonElementIntersection,\n ARIAButtonAlteredProps,\n} from './button/index';\n\nexport {\n AriaLiveAnnouncer,\n renderAriaLiveAnnouncer_unstable,\n useAriaLiveAnnouncer_unstable,\n useAriaLiveAnnouncerContextValues_unstable,\n} from './AriaLiveAnnouncer/index';\nexport type { AriaLiveAnnouncerProps, AriaLiveAnnouncerState } from './AriaLiveAnnouncer/index';\n\nexport { useTypingAnnounce } from './useTypingAnnounce/index';\n"],"names":["ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE","ActiveDescendantContextProvider","AriaLiveAnnouncer","renderAriaLiveAnnouncer_unstable","useARIAButtonProps","useARIAButtonShorthand","useActiveDescendant","useActiveDescendantContext","useAriaLiveAnnouncerContextValues_unstable","useAriaLiveAnnouncer_unstable","useHasParentActiveDescendantContext","useTypingAnnounce"],"mappings":";;;;;;;;;;;IAOEA,uCAAuC;eAAvCA,yDAAuC;;IACvCC,+BAA+B;eAA/BA,iDAA+B;;IAqB/BC,iBAAiB;eAAjBA,yBAAiB;;IACjBC,gCAAgC;eAAhCA,wCAAgC;;IA3BhCC,kBAAkB;eAAlBA,yBAAkB;;IAFlB,4DAA4D;IAC5DC,sBAAsB;eAAtBA,6BAAsB;;IAItBC,mBAAmB;eAAnBA,qCAAmB;;IAGnBC,0BAA0B;eAA1BA,4CAA0B;;IAuB1BC,0CAA0C;eAA1CA,kDAA0C;;IAD1CC,6BAA6B;eAA7BA,qCAA6B;;IArB7BC,mCAAmC;eAAnCA,qDAAmC;;IA0B5BC,iBAAiB;eAAjBA,yBAAiB;;;uBAhCnB;kCAOA;wBAsBA;wBAG2B"}

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useTypingAnnounce", {
enumerable: true,
get: function() {
return _useTypingAnnounce.useTypingAnnounce;
}
});
const _useTypingAnnounce = require("./useTypingAnnounce");

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useTypingAnnounce/index.ts"],"sourcesContent":["export { useTypingAnnounce } from './useTypingAnnounce';\n"],"names":["useTypingAnnounce"],"mappings":";;;;+BAASA;;;eAAAA,oCAAiB;;;mCAAQ"}

View File

@@ -0,0 +1,83 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useTypingAnnounce", {
enumerable: true,
get: function() {
return useTypingAnnounce;
}
});
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 _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const valueMutationOptions = {
attributes: true,
subtree: true,
characterData: true,
attributeFilter: [
'value'
]
};
function useTypingAnnounce() {
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
const { announce } = (0, _reactsharedcontexts.useAnnounce)();
const inputRef = _react.useRef(null);
const observer = _react.useRef(undefined);
const [setTypingTimeout, clearTypingTimeout] = (0, _reactutilities.useTimeout)();
const messageQueue = _react.useRef([]);
const callback = _react.useCallback((mutationList, mutationObserver)=>{
setTypingTimeout(()=>{
messageQueue.current.forEach(({ message, options })=>{
announce(message, options);
});
messageQueue.current.length = 0;
mutationObserver.disconnect();
}, 500);
}, [
announce,
setTypingTimeout
]);
const typingAnnounce = _react.useCallback((message, options = {})=>{
messageQueue.current.push({
message,
options
});
if (inputRef.current && observer.current) {
observer.current.observe(inputRef.current, valueMutationOptions);
}
setTypingTimeout(()=>{
observer.current && callback([], observer.current);
}, 500);
}, [
callback,
inputRef,
setTypingTimeout
]);
_react.useEffect(()=>{
const win = targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.defaultView;
if (!win) {
return;
}
if (!observer.current) {
observer.current = new win.MutationObserver(callback);
}
return ()=>{
// Clean up the observer when the component unmounts
if (observer.current) {
observer.current.disconnect();
clearTypingTimeout();
}
};
}, [
callback,
clearTypingTimeout,
targetDocument
]);
return {
typingAnnounce,
inputRef
};
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/useTypingAnnounce/useTypingAnnounce.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useTimeout } from '@fluentui/react-utilities';\nimport { useAnnounce, useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport type { AnnounceOptions } from '@fluentui/react-shared-contexts';\nimport { AriaLiveAnnounceFn } from '../AriaLiveAnnouncer/AriaLiveAnnouncer.types';\n\ntype Message = {\n message: string;\n options: AnnounceOptions;\n};\n\nconst valueMutationOptions = {\n attributes: true,\n subtree: true,\n characterData: true,\n attributeFilter: ['value'],\n};\n\ninterface TypingAnnounceReturn<TInputElement extends HTMLElement = HTMLElement> {\n typingAnnounce: AriaLiveAnnounceFn;\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n inputRef: React.MutableRefObject<TInputElement | null>;\n}\n\nexport function useTypingAnnounce<\n TInputElement extends HTMLElement = HTMLElement,\n>(): TypingAnnounceReturn<TInputElement> {\n const { targetDocument } = useFluent();\n const { announce } = useAnnounce();\n\n const inputRef = React.useRef<TInputElement | null>(null);\n const observer = React.useRef<MutationObserver>(undefined);\n const [setTypingTimeout, clearTypingTimeout] = useTimeout();\n const messageQueue = React.useRef<Message[]>([]);\n\n const callback: MutationCallback = React.useCallback(\n (mutationList, mutationObserver) => {\n setTypingTimeout(() => {\n messageQueue.current.forEach(({ message, options }) => {\n announce(message, options);\n });\n messageQueue.current.length = 0;\n mutationObserver.disconnect();\n }, 500);\n },\n [announce, setTypingTimeout],\n );\n\n const typingAnnounce: AriaLiveAnnounceFn = React.useCallback(\n (message: string, options: AnnounceOptions = {}) => {\n messageQueue.current.push({ message, options });\n\n if (inputRef.current && observer.current) {\n observer.current.observe(inputRef.current, valueMutationOptions);\n }\n\n setTypingTimeout(() => {\n observer.current && callback([], observer.current);\n }, 500);\n },\n [callback, inputRef, setTypingTimeout],\n );\n\n React.useEffect(() => {\n const win = targetDocument?.defaultView;\n if (!win) {\n return;\n }\n\n if (!observer.current) {\n observer.current = new win.MutationObserver(callback);\n }\n\n return () => {\n // Clean up the observer when the component unmounts\n if (observer.current) {\n observer.current.disconnect();\n clearTypingTimeout();\n }\n };\n }, [callback, clearTypingTimeout, targetDocument]);\n\n return { typingAnnounce, inputRef };\n}\n"],"names":["useTypingAnnounce","valueMutationOptions","attributes","subtree","characterData","attributeFilter","targetDocument","useFluent","announce","useAnnounce","inputRef","React","useRef","observer","undefined","setTypingTimeout","clearTypingTimeout","useTimeout","messageQueue","callback","useCallback","mutationList","mutationObserver","current","forEach","message","options","length","disconnect","typingAnnounce","push","observe","useEffect","win","defaultView","MutationObserver"],"mappings":"AAAA;;;;;+BA0BgBA;;;eAAAA;;;;iEAxBO;gCACI;qCACkC;AAS7D,MAAMC,uBAAuB;IAC3BC,YAAY;IACZC,SAAS;IACTC,eAAe;IACfC,iBAAiB;QAAC;KAAQ;AAC5B;AAQO,SAASL;IAGd,MAAM,EAAEM,cAAc,EAAE,GAAGC,IAAAA,uCAAS;IACpC,MAAM,EAAEC,QAAQ,EAAE,GAAGC,IAAAA,gCAAW;IAEhC,MAAMC,WAAWC,OAAMC,MAAM,CAAuB;IACpD,MAAMC,WAAWF,OAAMC,MAAM,CAAmBE;IAChD,MAAM,CAACC,kBAAkBC,mBAAmB,GAAGC,IAAAA,0BAAU;IACzD,MAAMC,eAAeP,OAAMC,MAAM,CAAY,EAAE;IAE/C,MAAMO,WAA6BR,OAAMS,WAAW,CAClD,CAACC,cAAcC;QACbP,iBAAiB;YACfG,aAAaK,OAAO,CAACC,OAAO,CAAC,CAAC,EAAEC,OAAO,EAAEC,OAAO,EAAE;gBAChDlB,SAASiB,SAASC;YACpB;YACAR,aAAaK,OAAO,CAACI,MAAM,GAAG;YAC9BL,iBAAiBM,UAAU;QAC7B,GAAG;IACL,GACA;QAACpB;QAAUO;KAAiB;IAG9B,MAAMc,iBAAqClB,OAAMS,WAAW,CAC1D,CAACK,SAAiBC,UAA2B,CAAC,CAAC;QAC7CR,aAAaK,OAAO,CAACO,IAAI,CAAC;YAAEL;YAASC;QAAQ;QAE7C,IAAIhB,SAASa,OAAO,IAAIV,SAASU,OAAO,EAAE;YACxCV,SAASU,OAAO,CAACQ,OAAO,CAACrB,SAASa,OAAO,EAAEtB;QAC7C;QAEAc,iBAAiB;YACfF,SAASU,OAAO,IAAIJ,SAAS,EAAE,EAAEN,SAASU,OAAO;QACnD,GAAG;IACL,GACA;QAACJ;QAAUT;QAAUK;KAAiB;IAGxCJ,OAAMqB,SAAS,CAAC;QACd,MAAMC,MAAM3B,2BAAAA,qCAAAA,eAAgB4B,WAAW;QACvC,IAAI,CAACD,KAAK;YACR;QACF;QAEA,IAAI,CAACpB,SAASU,OAAO,EAAE;YACrBV,SAASU,OAAO,GAAG,IAAIU,IAAIE,gBAAgB,CAAChB;QAC9C;QAEA,OAAO;YACL,oDAAoD;YACpD,IAAIN,SAASU,OAAO,EAAE;gBACpBV,SAASU,OAAO,CAACK,UAAU;gBAC3BZ;YACF;QACF;IACF,GAAG;QAACG;QAAUH;QAAoBV;KAAe;IAEjD,OAAO;QAAEuB;QAAgBnB;IAAS;AACpC"}