@itwin/itwinui-react
Version:
A react component library for iTwinUI
46 lines (45 loc) • 1.42 kB
JavaScript
import * as React from 'react';
import { getTabbableElements } from '../functions/focusable.js';
export const FocusTrap = (props) => {
let { children } = props;
let firstFocusTrapRef = React.useRef(null);
let getFirstLastFocusables = React.useCallback(() => {
let childrenElement = firstFocusTrapRef.current?.nextElementSibling;
let elements = getTabbableElements(childrenElement);
let firstElement = elements[0];
let lastElement = elements[(elements.length || 1) - 1];
return [firstElement, lastElement];
}, []);
let onFirstFocus = React.useCallback(
(event) => {
let [firstElement, lastElement] = getFirstLastFocusables();
if (event.relatedTarget === firstElement) lastElement?.focus();
else firstElement?.focus();
},
[getFirstLastFocusables],
);
let onLastFocus = React.useCallback(
(event) => {
let [firstElement, lastElement] = getFirstLastFocusables();
if (event.relatedTarget === lastElement) firstElement?.focus();
else lastElement?.focus();
},
[getFirstLastFocusables],
);
return React.createElement(
React.Fragment,
null,
React.createElement('div', {
ref: firstFocusTrapRef,
tabIndex: 0,
onFocus: onFirstFocus,
'aria-hidden': true,
}),
children,
React.createElement('div', {
tabIndex: 0,
onFocus: onLastFocus,
'aria-hidden': true,
}),
);
};