Outlook_Addin_LLM/node_modules/@fluentui/react-aria/lib-commonjs/AriaLiveAnnouncer/useDomAnnounce.js

136 lines
5.1 KiB
JavaScript

"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 _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 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;
}
};
runCycle();
}, [
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.assign(element.style, VISUALLY_HIDDEN_STYLES);
targetDocument.body.append(element);
elementRef.current = element;
return ()=>{
element.remove();
elementRef.current = null;
clearAnnounceTimeout();
timeoutRef.current = undefined;
};
}, [
clearAnnounceTimeout,
targetDocument
]);
return announce;
};