@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
38 lines (37 loc) • 1.59 kB
JavaScript
"use client";
//#region packages/@mantine/hooks/src/use-focus-trap/tabbable.ts
const TABBABLE_NODES = /input|select|textarea|button|object/;
const FOCUS_SELECTOR = "a, input, select, textarea, button, object, [tabindex]";
function hidden(element) {
return element.style.display === "none";
}
function visible(element) {
if (element.getAttribute("aria-hidden") || element.getAttribute("hidden") || element.getAttribute("type") === "hidden") return false;
let parentElement = element;
while (parentElement) {
if (parentElement === document.body || parentElement.nodeType === 11) break;
if (hidden(parentElement)) return false;
parentElement = parentElement.parentNode;
}
return true;
}
function getElementTabIndex(element) {
let tabIndex = element.getAttribute("tabindex");
if (tabIndex === null) tabIndex = void 0;
return parseInt(tabIndex, 10);
}
function focusable(element) {
const nodeName = element.nodeName.toLowerCase();
const isTabIndexNotNaN = !Number.isNaN(getElementTabIndex(element));
return (TABBABLE_NODES.test(nodeName) && !element.disabled || (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN)) && visible(element);
}
function tabbable(element) {
const tabIndex = getElementTabIndex(element);
return (Number.isNaN(tabIndex) || tabIndex >= 0) && focusable(element);
}
function findTabbableDescendants(element) {
return Array.from(element.querySelectorAll(FOCUS_SELECTOR)).filter(tabbable);
}
//#endregion
export { FOCUS_SELECTOR, findTabbableDescendants, focusable, tabbable };
//# sourceMappingURL=tabbable.mjs.map