UNPKG

1.57 kBTypeScriptView Raw
1import { useEffect, useRef } from 'react';
2import { isBrowser } from './utils';
3import {
4 tabTrappingKey,
5 candidateSelectors,
6 getAllTabbingElements,
7} from './focusTrapJs';
8
9interface FocusTrapProps {
10 container?: React.RefObject<HTMLElement> | null;
11}
12
13export const FocusTrap = ({ container }: FocusTrapProps) => {
14 const refLastFocus = useRef<HTMLElement | null>();
15 /**
16 * Handle focus lock on the modal
17 */
18 useEffect(() => {
19 const handleKeyEvent = (event: KeyboardEvent) => {
20 if (container?.current) {
21 tabTrappingKey(event, container.current);
22 }
23 };
24
25 if (isBrowser) {
26 document.addEventListener('keydown', handleKeyEvent);
27 }
28 // On mount we focus on the first focusable element in the modal if there is one
29 if (isBrowser && container?.current) {
30 const allTabbingElements = getAllTabbingElements(container.current);
31 if (allTabbingElements[0]) {
32 // First we save the last focused element
33 // only if it's a focusable element
34 if (
35 candidateSelectors.findIndex((selector) =>
36 document.activeElement?.matches(selector)
37 ) !== -1
38 ) {
39 refLastFocus.current = document.activeElement as HTMLElement;
40 }
41 allTabbingElements[0].focus();
42 }
43 }
44 return () => {
45 if (isBrowser) {
46 document.removeEventListener('keydown', handleKeyEvent);
47 // On unmount we restore the focus to the last focused element
48 refLastFocus.current?.focus();
49 }
50 };
51 }, [container]);
52
53 return null;
54};