UNPKG

@base-ui-components/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

64 lines (63 loc) 2.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.disableFocusInside = disableFocusInside; exports.enableFocusInside = enableFocusInside; exports.getNextTabbable = getNextTabbable; exports.getPreviousTabbable = getPreviousTabbable; exports.getTabbableOptions = void 0; exports.isOutsideEvent = isOutsideEvent; var _tabbable = require("tabbable"); var _element = require("./element"); const getTabbableOptions = () => ({ getShadowRoot: true, displayCheck: // JSDOM does not support the `tabbable` library. To solve this we can // check if `ResizeObserver` is a real function (not polyfilled), which // determines if the current environment is JSDOM-like. typeof ResizeObserver === 'function' && ResizeObserver.toString().includes('[native code]') ? 'full' : 'none' }); exports.getTabbableOptions = getTabbableOptions; function getTabbableIn(container, dir) { const list = (0, _tabbable.tabbable)(container, getTabbableOptions()); const len = list.length; if (len === 0) { return undefined; } const active = (0, _element.activeElement)((0, _element.getDocument)(container)); const index = list.indexOf(active); // eslint-disable-next-line no-nested-ternary const nextIndex = index === -1 ? dir === 1 ? 0 : len - 1 : index + dir; return list[nextIndex]; } function getNextTabbable(referenceElement) { return getTabbableIn((0, _element.getDocument)(referenceElement).body, 1) || referenceElement; } function getPreviousTabbable(referenceElement) { return getTabbableIn((0, _element.getDocument)(referenceElement).body, -1) || referenceElement; } function isOutsideEvent(event, container) { const containerElement = container || event.currentTarget; const relatedTarget = event.relatedTarget; return !relatedTarget || !(0, _element.contains)(containerElement, relatedTarget); } function disableFocusInside(container) { const tabbableElements = (0, _tabbable.tabbable)(container, getTabbableOptions()); tabbableElements.forEach(element => { element.dataset.tabindex = element.getAttribute('tabindex') || ''; element.setAttribute('tabindex', '-1'); }); } function enableFocusInside(container) { const elements = container.querySelectorAll('[data-tabindex]'); elements.forEach(element => { const tabindex = element.dataset.tabindex; delete element.dataset.tabindex; if (tabindex) { element.setAttribute('tabindex', tabindex); } else { element.removeAttribute('tabindex'); } }); }