@alaskaairux/auro-interruption
Version:
Auro custom auro-interruption element
57 lines (50 loc) • 1.68 kB
JavaScript
/* eslint-disable func-style */
/* eslint-disable max-statements */
/* eslint-disable no-param-reassign */
/**
* Recursively traverses a node's siblings and makes them inert and aria-hidden so that
* keyboard and screen reader focus is trapped within the dialog.
* @param {Element} node The node whose siblings should be made inert
* @returns {function} Cleanup function that removes inert and aria-hidden from the affected nodes.
*/
export function makeSiblingsInert(node) {
const hiddenElements = [],
inertElements = [];
/**
* Applies inert recursively to a node's siblings.
* @param {Element} currentNode The node whose siblings should be made inert
* @returns {void}
*/
function handleInert(currentNode) {
if (!currentNode.parentNode && currentNode.host) {
currentNode = currentNode.host;
}
if (currentNode.parentNode) {
for (const elem of currentNode.parentNode.childNodes) {
if (elem !== currentNode && elem.nodeType === Node.ELEMENT_NODE) {
elem.inert = true;
inertElements.push(elem);
if (!elem.hasAttribute('aria-hidden')) {
elem.setAttribute('aria-hidden', true);
hiddenElements.push(elem);
}
}
}
if (currentNode.parentNode !== document.body) {
handleInert(currentNode.parentNode);
}
}
}
/**
* Removes inert and aria-hidden from the affected nodes.
* @returns {void}
*/
function cleanupNodes() {
inertElements.forEach((el) => {
el.inert = false;
});
hiddenElements.forEach((el) => el.removeAttribute('aria-hidden'));
}
handleInert(node);
return cleanupNodes;
}