import { useRef } from 'react';
export function useA11yAnnouncer() {
const timer = useRef<number | null>(null);
const announce = async (message: string) => {
const style = `border: 0; padding: 0; margin: 0; position: absolute !important;
height: 1px; width: 1px; overflow: hidden;
clip: rect(1px 1px 1px 1px); clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); white-space: nowrap;`.replaceAll(
/\n/g,
''
);
const appendAndAnnounce = async (element: Element, message: string) => {
return new Promise(resolve => {
if (!element.querySelector("[name='p_announceForAccessibility']")) {
const div = document.createElement('div');
div.setAttribute('name', 'div_announceForAccessibility');
div.setAttribute('style', style);
div.innerHTML = '<p aria-live="polite" name="p_announceForAccessibility"></p>';
element.appendChild(div);
}
const pElement = element.querySelector<HTMLParagraphElement>("[name='p_announceForAccessibility']");
if (!pElement) {
return;
}
pElement.innerText = '';
setTimeout(() => {
pElement.innerText = message;
resolve(void 0);
}, 200);
});
};
const announceMessages = async () => {
if (typeof window !== 'undefined') {
const bodyElement = document.body;
const dialogElements = document.body.querySelectorAll<HTMLDialogElement>(
'[role="dialog"][aria-modal="true"], dialog'
);
await appendAndAnnounce(bodyElement, message);
dialogElements.forEach(element => {
appendAndAnnounce(element, message);
});
}
};
await announceMessages();
timer.current = window.setTimeout(removeAnnounce, 1000);
};
const removeAnnounce = () => {
if (typeof window !== 'undefined') {
const divElements = document.body.querySelectorAll<HTMLDivElement>("[name='div_announceForAccessibility']");
if (!divElements || !timer.current) {
return;
}
divElements.forEach(element => {
element.parentNode?.removeChild(element);
});
clearTimeout(timer.current);
timer.current = null;
}
};
return [announce, removeAnnounce] as const;
}
답글 남기기
댓글을 달기 위해서는 로그인해야합니다.