@itwin/itwinui-react
Version:
A react component library for iTwinUI
92 lines (91 loc) • 3.02 kB
JavaScript
;
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,
);
}