Mirror: React hooks for accessible, common web interactions. UI super powers without the UI.
1import { inputSelectors } from './focus';
2
3const excludeSelector =
4 ':not([tabindex^="-"]):not([aria-modal]):not([role="dialog"])';
5
6/** Returns a given tab index for an element, defaulting to zero. */
7export const getTabIndex = (node: HTMLElement): number =>
8 (!node.isContentEditable && node.tabIndex) || 0;
9
10/** Returns whether an element is visible in the context of focusability. */
11export const isVisible = (node: Element): node is HTMLElement =>
12 node.matches(excludeSelector) && node.getClientRects().length > 0;
13
14/** Returns whether an element accepts text input. */
15export const isInputElement = (node: Element | null): boolean =>
16 !!node && node.matches(inputSelectors);
17
18export const contains = (
19 owner: Element | EventTarget | null,
20 node: Element | EventTarget | null
21): owner is HTMLElement =>
22 !!(
23 node &&
24 owner &&
25 (owner === node || (owner as Element).contains(node as Element))
26 );
27
28/** Returns the root element of the input element */
29export const getRoot = (node: Element): HTMLElement =>
30 (node.getRootNode() || document.body) as HTMLElement;