@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
33 lines (32 loc) • 1.36 kB
JavaScript
import { TAB } from './keys';
import { isVisible } from './visible';
/**
* Chain focus order between passed elements.
* Passive (should be called inside keyboard event handler)
*/
export const handleFocusChain = (e, first, last) => {
if (e.key !== TAB)
return;
if (last && e.target === first && e.shiftKey) {
last.focus();
e.preventDefault();
return true;
}
if (first && e.target === last && !e.shiftKey) {
first.focus();
e.preventDefault();
return true;
}
};
const FOCUSABLE_SELECTOR = 'a[href], button, input, textarea, select, details, summary, output, [tabindex]:not([tabindex="-1"])';
const isFocusableAllowed = (el) => !el.hasAttribute('disabled') && !el.closest('[inert]');
/** @returns if the element is focusable */
export const isFocusable = (el) => el && el.matches(FOCUSABLE_SELECTOR) && isFocusableAllowed(el);
/**
* Gets keyboard-focusable elements within a specified root element
* @param root - root element
* @param visibilityOpt - visibility check options or false to skip visibility check
*/
export const getKeyboardFocusableElements = (root = document, visibilityOpt = { visibility: true }) => {
return Array.from(root.querySelectorAll(FOCUSABLE_SELECTOR)).filter((el) => isFocusableAllowed(el) && (!visibilityOpt || isVisible(el, visibilityOpt)));
};