Skip to main content

useFocusTrap

Source ↗

Traps keyboard focus within a container element using sentinel elements. Automatically detects focusable elements inside the container and cycles Tab navigation between them. The hook configures sentinel divs imperatively (setting tabIndex, data-focus-trapper, and focus event listeners). The sentinels never keep the focus, they just forward it to the first/last focusable element.

By default auto-focuses the container when activated.

Used internally by the Popover component.

Import

import { useFocusTrap } from '@andrejground/lab';

Usage

import React from 'react';
import { useFocusTrap } from '@andrejground/lab';

export default function App() {
const [isActive, setIsActive] = React.useState(false);
const { trapContainerRef, startTrapRef, endTrapRef } =
useFocusTrap({ isActive });

return (
<div>
<button onClick={() => setIsActive(true)}>Open dialog</button>

{isActive && (
<div ref={trapContainerRef}>
<div ref={startTrapRef} />

<input placeholder="First field" />
<input placeholder="Middle field" />
<button onClick={() => setIsActive(false)}>Close</button>

<div ref={endTrapRef} />
</div>
)}
</div>
);
}

API

const { trapContainerRef, startTrapRef, endTrapRef } =
useFocusTrap({ isActive, shouldAutoFocus });
ParameterTypeDefaultDescription
isActiveboolean-Whether the focus trap is active
shouldAutoFocusbooleantrueAuto-focus the container on activation

Returns

PropertyTypeDescription
trapContainerRefRefObject<HTMLDivElement>Ref for the trap container
startTrapRefRefObject<HTMLDivElement>Ref for the first sentinel element
endTrapRefRefObject<HTMLDivElement>Ref for the last sentinel element