useFocusTrap
Location: src/hooks/useFocusTrap.js
Overview
Traps keyboard focus within a container element, ensuring that Tab and Shift+Tab cycling stays within the container. This is essential for accessibility in modals, dialogs, and drawers, preventing keyboard users from tabbing to elements behind the overlay.
When activated, the hook automatically focuses the first focusable element in the container.
Signature
function useFocusTrap(isActive?: boolean): React.RefObject<HTMLElement>
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
isActive | boolean | No | true | Whether the focus trap is active. Set to false to disable trapping. |
Return Value
| Type | Description |
|---|---|
React.RefObject<HTMLElement> | A ref to attach to the container element that should trap focus |
Focusable Elements
The hook considers these elements as focusable:
button:not([disabled])input:not([disabled])textarea:not([disabled])select:not([disabled])a[href][tabindex]:not([tabindex="-1"])
Usage
import { useFocusTrap } from '../hooks/useFocusTrap';
function Modal({ isOpen, onClose, children }) {
const trapRef = useFocusTrap(isOpen);
if (!isOpen) return null;
return (
<div className="modal-overlay" onClick={onClose}>
<div ref={trapRef} className="modal-content" onClick={(e) => e.stopPropagation()}>
{children}
<button onClick={onClose}>Close</button>
</div>
</div>
);
}
Behavior
- When
isActivebecomestrue, the first focusable element inside the container receives focus. - Pressing Tab on the last focusable element wraps focus to the first.
- Pressing Shift+Tab on the first focusable element wraps focus to the last.
- The keydown listener is attached to the container element and cleaned up when the trap is deactivated or the component unmounts.
Notes
- The hook dynamically queries focusable elements on each Tab keypress, so it handles elements that appear or disappear after mount.
- If the container has no focusable elements, Tab keypresses are not intercepted.
- Pair this with
useEscapeKeyfor complete modal keyboard accessibility.
Last updated: 2026-02-07