tabi/static/js/accessibility.min.js

52 lines
1.7 KiB
JavaScript

document.addEventListener("DOMContentLoaded", function () {
initDropdownMenu();
});
function initDropdownMenu() {
const dropdown = document.querySelector('.dropdown');
const menuItems = document.querySelectorAll('[role="menuitem"]');
const menuButton = dropdown.querySelector('[role="button"]');
dropdown.addEventListener("toggle", handleToggle.bind(null, dropdown, menuItems, menuButton));
document.addEventListener("keydown", handleKeydown.bind(null, dropdown, menuItems, menuButton));
}
function handleToggle(dropdown, menuItems, menuButton) {
if (dropdown.hasAttribute('open')) {
focusMenuItem(menuItems, 0);
setAriaExpanded(menuButton, true);
} else {
menuButton.focus();
setAriaExpanded(menuButton, false);
}
}
function handleKeydown(dropdown, menuItems, menuButton, event) {
if (!dropdown.hasAttribute('open')) return;
let focusedItemIndex = Array.from(menuItems).indexOf(document.activeElement);
switch (event.key) {
case "ArrowDown":
event.preventDefault();
focusMenuItem(menuItems, (focusedItemIndex + 1) % menuItems.length);
break;
case "ArrowUp":
event.preventDefault();
focusMenuItem(menuItems, (focusedItemIndex - 1 + menuItems.length) % menuItems.length);
break;
case "Escape":
dropdown.removeAttribute('open');
setAriaExpanded(menuButton, false);
menuButton.focus();
break;
}
}
function focusMenuItem(menuItems, index) {
menuItems[index].focus();
}
function setAriaExpanded(element, state) {
element.setAttribute('aria-expanded', state ? 'true' : 'false');
}