UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

92 lines (91 loc) 3.02 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); function _export(target, all) { for (var name in all) Object.defineProperty(target, name, { enumerable: true, get: all[name], }); } _export(exports, { getFocusableElements: function () { return getFocusableElements; }, getTabbableElements: function () { return getTabbableElements; }, useFocusableElements: function () { return useFocusableElements; }, }); const _interop_require_wildcard = require('@swc/helpers/_/_interop_require_wildcard'); const _react = /*#__PURE__*/ _interop_require_wildcard._(require('react')); const _index = require('../hooks/index.js'); const tabbableElementsSelector = 'a[href], button, input, textarea, select, details, audio[controls], video[controls], [contenteditable]:not([contenteditable="false"]), [tabindex]:not([tabindex="-1"])'; const getTabbableElements = (container) => { if (!container) return []; let elements = container.querySelectorAll(tabbableElementsSelector); return Array.from(elements).filter( (el) => !el.hasAttribute('disabled') && !el.classList.contains('iui-disabled') && 'true' !== el.getAttribute('aria-disabled'), ); }; const getFocusableElements = (container) => { if (!container) return []; let elements = container.querySelectorAll( `${tabbableElementsSelector}, [tabindex="-1"]`, ); return Array.from(elements).filter( (el) => !el.hasAttribute('disabled') && !el.classList.contains('iui-disabled') && 'true' !== el.getAttribute('aria-disabled'), ); }; function useFocusableElements(root, extraOptions) { let focusableElementsRef = _react.useRef([]); let [focusableElements, setFocusableElements] = _react.useState( focusableElementsRef.current, ); let setFocusableElementsRefAndState = (newFocusableElements) => { focusableElementsRef.current = newFocusableElements; setFocusableElements(newFocusableElements); }; let { filter: filterProp } = extraOptions ?? {}; let filter = (0, _index.useLatestRef)(filterProp); let returnValue = _react.useMemo( () => ({ focusableElementsRef, focusableElements, }), [focusableElementsRef, focusableElements], ); return (0, _index.useSyncExternalStore)( _react.useCallback(() => { if (!root) { setFocusableElementsRefAndState([]); return () => {}; } updateFocusableElements(); let observer = new MutationObserver(() => updateFocusableElements()); observer.observe(root, { childList: true, subtree: true, }); return () => observer.disconnect(); function updateFocusableElements() { let newFocusableElements = getFocusableElements(root); if (filter.current) newFocusableElements = filter.current?.(newFocusableElements); setFocusableElementsRefAndState(newFocusableElements); } }, [root, filter]), () => returnValue, () => returnValue, ); }