in src/hooks/useFocusTrap.ts [36:80]
export function useFocusTrap(
settings?: FocusTrapHookSettings,
dependencies: React.DependencyList = []
): {containerRef: React.RefObject<HTMLElement>; initialFocusRef: React.RefObject<HTMLElement>} {
const containerRef = useProvidedRefOrCreate(settings?.containerRef)
const initialFocusRef = useProvidedRefOrCreate(settings?.initialFocusRef)
const disabled = settings?.disabled
const abortController = React.useRef<AbortController>()
const previousFocusedElement = React.useRef<Element | null>(null)
// If we are enabling a focus trap and haven't already stored the previously focused element
// go ahead an do that so we can restore later when the trap is disabled.
if (!previousFocusedElement.current && !settings?.disabled) {
previousFocusedElement.current = document.activeElement
}
// This function removes the event listeners that enable the focus trap and restores focus
// to the previously-focused element (if necessary).
function disableTrap() {
abortController.current?.abort()
if (settings?.restoreFocusOnCleanUp && previousFocusedElement.current instanceof HTMLElement) {
previousFocusedElement.current.focus()
previousFocusedElement.current = null
}
}
React.useEffect(
() => {
if (containerRef.current instanceof HTMLElement) {
if (!disabled) {
abortController.current = focusTrap(containerRef.current, initialFocusRef.current ?? undefined)
return () => {
disableTrap()
}
} else {
disableTrap()
}
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[containerRef, initialFocusRef, disabled, ...dependencies]
)
return {containerRef, initialFocusRef}
}