1 | import { useEffect, useRef } from 'react';
|
2 | import { isBrowser } from './utils';
|
3 | import {
|
4 | tabTrappingKey,
|
5 | candidateSelectors,
|
6 | getAllTabbingElements,
|
7 | } from './lib/focusTrapJs';
|
8 |
|
9 | interface FocusTrapProps {
|
10 | container?: React.RefObject<HTMLElement> | null;
|
11 | }
|
12 |
|
13 | export const FocusTrap = ({ container }: FocusTrapProps) => {
|
14 | const refLastFocus = useRef<HTMLElement | null>();
|
15 | |
16 |
|
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 |
|
29 | if (isBrowser && container?.current) {
|
30 | const allTabbingElements = getAllTabbingElements(container.current);
|
31 | if (allTabbingElements[0]) {
|
32 |
|
33 |
|
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 |
|
48 | refLastFocus.current?.focus();
|
49 | }
|
50 | };
|
51 | }, [container]);
|
52 |
|
53 | return null;
|
54 | };
|