Traps focus within a DOM node — subsequently mounted traps will take control of focus and pause others until unmounted.
yarn add react-focus-manager
You must wrap the applicable section of your app in the FocusMarshal
, which provides context to the FocusTrap
descendants.
import { FocusTrap, FocusMarshal } from 'react-focus-marshal';
const Modal = () => createPortal(
<FocusTrap>
<div>
{/* modal content */}
</div>
</FocusTrap>,
document.body
);
const App = () => (
<FocusMarshal>
{someCondition ? <Modal /> : null}
</FocusMarshal>
);
Property | Description |
---|---|
children Node |
All children are passed through. |
Property | Description |
---|---|
children Element<HTMLElement | ComponentType> |
A single element to trap focus within. The underlying DOM node will be resolved on the component passed as children. |
Options OptionsType |
The options object that is passed to createFocusTrap . See below for definition. |
The FocusTrap
component is a thin wrapper around David Clark's fantastic focus-trap library. Whilst react-focus-marshal attempts to maintain feature parity, there are some minor differences; see fallbackFocus
property below.
For brevity:
FocusTarget
is equal toHTMLElement | string | () => HTMLElement
.ActivationFn
is equal toRef => void
.
Property | Description |
---|---|
onActivate ActivationFn |
A function that will be called when the focus trap activates. |
onDeactivate ActivationFn |
A function that will be called when the focus trap deactivates. |
initialFocus FocusTarget |
Defaults to the first "tabbable" element -- a string value will be passed to document.querySelector() . |
FocusTarget |
The required children element is used as a safe way to fulfill the contract with "focus-trap". |
escapeDeactivates boolean |
Default: true . If false, the Escape key will not trigger deactivation of the focus trap. |
clickOutsideDeactivates boolean |
Default: false . If true, a click outside the focus trap will deactivate the focus trap and allow the click event to do its thing. |
returnFocusOnDeactivate boolean |
Default: true . If false, when the trap is deactivated, focus will not return to the element that had focus before activation. |
This library may not meet your needs. Here are some alternative I came across whilst searching for this solution: