Private
Public Access
1
0
Files

49 lines
1.7 KiB
JavaScript

'use client';
import * as React from 'react';
import { isHTMLElement } from '@fluentui/react-utilities';
/**
* Wraps an aria live announcement function.
* Aria live announcements can be detrimental once the user is already navigating
* multiple toasts. Once the user is focused inside the toaster, the announecments should be disabled.
* @param announce
* @returns A function to announce a toast and a ref to attach to the toaster element
*/ export function useToastAnnounce(announce) {
const activeRef = React.useRef(true);
const cleanupRef = React.useRef(()=>undefined);
const announceToast = React.useCallback((message, options)=>{
if (activeRef.current) {
announce(message, options);
}
}, [
announce
]);
const toasterRef = React.useCallback((el)=>{
if (!el) {
cleanupRef.current();
return;
}
const onFocusIn = (e)=>{
if (isHTMLElement(e.currentTarget) && e.currentTarget.contains(isHTMLElement(e.relatedTarget) ? e.relatedTarget : null)) {
return;
}
activeRef.current = false;
};
const onFocusOut = (e)=>{
if (isHTMLElement(e.currentTarget) && e.currentTarget.contains(isHTMLElement(e.relatedTarget) ? e.relatedTarget : null)) {
return;
}
activeRef.current = true;
};
el.addEventListener('focusin', onFocusIn);
el.addEventListener('focusout', onFocusOut);
cleanupRef.current = ()=>{
el.removeEventListener('focusin', onFocusIn);
el.removeEventListener('focusout', onFocusOut);
};
}, []);
return {
announceToast,
toasterRef
};
}