MCPcopy
hub / github.com/primer/react / useFocusTrap

Function useFocusTrap

packages/react/src/hooks/useFocusTrap.ts:44–90  ·  view source on GitHub ↗
(
  settings?: FocusTrapHookSettings,
  dependencies: React.DependencyList = [],
)

Source from the content-addressed store, hash-verified

42 * @param settings {FocusTrapHookSettings}
43 */
44export function useFocusTrap(
45 settings?: FocusTrapHookSettings,
46 dependencies: React.DependencyList = [],
47): {containerRef: React.RefObject<HTMLElement>; initialFocusRef: React.RefObject<HTMLElement>} {
48 const containerRef = useProvidedRefOrCreate(settings?.containerRef)
49 const initialFocusRef = useProvidedRefOrCreate(settings?.initialFocusRef)
50 const disabled = settings?.disabled
51 const abortController = React.useRef<AbortController>()
52 const previousFocusedElement = React.useRef<Element | null>(null)
53
54 // If we are enabling a focus trap and haven't already stored the previously focused element
55 // go ahead an do that so we can restore later when the trap is disabled.
56 if (!previousFocusedElement.current && !settings?.disabled) {
57 previousFocusedElement.current = document.activeElement
58 }
59
60 // This function removes the event listeners that enable the focus trap and restores focus
61 // to the previously-focused element (if necessary).
62 function disableTrap() {
63 abortController.current?.abort()
64 if (settings?.returnFocusRef && settings.returnFocusRef.current instanceof HTMLElement) {
65 settings.returnFocusRef.current.focus()
66 } else if (settings?.restoreFocusOnCleanUp && previousFocusedElement.current instanceof HTMLElement) {
67 previousFocusedElement.current.focus()
68 previousFocusedElement.current = null
69 }
70 }
71
72 React.useEffect(
73 () => {
74 if (containerRef.current instanceof HTMLElement) {
75 if (!disabled) {
76 abortController.current = focusTrap(containerRef.current, initialFocusRef.current ?? undefined)
77 return () => {
78 disableTrap()
79 }
80 } else {
81 disableTrap()
82 }
83 }
84 },
85 // eslint-disable-next-line react-hooks/exhaustive-deps
86 [containerRef, initialFocusRef, disabled, ...dependencies],
87 )
88
89 return {containerRef, initialFocusRef}
90}

Callers 7

Dialog.tsxFile · 0.90
AnchoredOverlayFunction · 0.90
FocusTrapFunction · 0.90
RestoreFocusFunction · 0.90
CustomInitialFocusFunction · 0.90
DynamicFocusTrapContentsFunction · 0.90
MultipleFocusTrapsFunction · 0.90

Calls 2

useProvidedRefOrCreateFunction · 0.90
disableTrapFunction · 0.85

Tested by

no test coverage detected