mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-27 17:50:56 +00:00
59 lines
1.9 KiB
JavaScript
59 lines
1.9 KiB
JavaScript
'use client';
|
|
'use strict';
|
|
|
|
const TABBABLE_NODES = /input|select|textarea|button|object/;
|
|
const FOCUS_SELECTOR = "a, input, select, textarea, button, object, [tabindex]";
|
|
function hidden(element) {
|
|
if (process.env.NODE_ENV === "test") {
|
|
return false;
|
|
}
|
|
return element.style.display === "none";
|
|
}
|
|
function visible(element) {
|
|
const isHidden = element.getAttribute("aria-hidden") || element.getAttribute("hidden") || element.getAttribute("type") === "hidden";
|
|
if (isHidden) {
|
|
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));
|
|
const res = (
|
|
// @ts-expect-error function accepts any html element but if it is a button, it should not be disabled to trigger the condition
|
|
TABBABLE_NODES.test(nodeName) && !element.disabled || (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN)
|
|
);
|
|
return res && visible(element);
|
|
}
|
|
function tabbable(element) {
|
|
const tabIndex = getElementTabIndex(element);
|
|
const isTabIndexNaN = Number.isNaN(tabIndex);
|
|
return (isTabIndexNaN || tabIndex >= 0) && focusable(element);
|
|
}
|
|
function findTabbableDescendants(element) {
|
|
return Array.from(element.querySelectorAll(FOCUS_SELECTOR)).filter(tabbable);
|
|
}
|
|
|
|
exports.FOCUS_SELECTOR = FOCUS_SELECTOR;
|
|
exports.findTabbableDescendants = findTabbableDescendants;
|
|
exports.focusable = focusable;
|
|
exports.tabbable = tabbable;
|
|
//# sourceMappingURL=tabbable.cjs.map
|