makeup-focusables
Version:
Returns an array of all focusable descendants of the given element
31 lines (29 loc) • 1.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
const focusableElList = ["a[href]", "area[href]", "button:not([disabled])", "embed", "iframe", "input:not([disabled])", "object", "select:not([disabled])", "textarea:not([disabled])", "*[tabindex]", "*[contenteditable]"];
const focusableElSelector = focusableElList.join(",");
function _default(el) {
let keyboardOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
let callback = arguments.length > 2 ? arguments[2] : undefined;
if (callback) {
const request = requestAnimationFrame(() => {
callback(getFocusables(el, keyboardOnly));
});
return () => {
cancelAnimationFrame(request);
};
}
return getFocusables(el, keyboardOnly);
}
function getFocusables(el) {
let keyboardOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
// filter out elements with display: none or nested in a display: none parent
let focusableEls = [...el.querySelectorAll(focusableElSelector)].filter(focusableEl => !!(focusableEl.offsetWidth || focusableEl.offsetHeight || focusableEl.getClientRects().length));
if (keyboardOnly === true) {
focusableEls = focusableEls.filter(focusableEl => focusableEl.getAttribute("tabindex") !== "-1");
}
return focusableEls;
}