# useFocusTrap

Keeps keyboard focus inside an element while `active`, e.g. a custom modal or drawer. Returns a callback ref for the element.

On activation, focuses the element with `autofocus` inside, else the first focusable element, else the container itself. Tab and Shift+Tab move through the focusable elements in DOM order and wrap around, the same in every browser (Safari otherwise skips buttons). If focus moves outside (e.g. a click elsewhere), it is brought back. On deactivation or unmount, focus returns to the element that had it before, usually the button that opened the dialog.

## Import

```ts
import { useFocusTrap } from '@vincent.ri/react-tils'
// or only this hook
import { useFocusTrap } from '@vincent.ri/react-tils/useFocusTrap'
```

## Usage

```ts
function Drawer({ open, onClose }: { open: boolean; onClose: () => void }) {
  const ref = useFocusTrap<HTMLDivElement>(open)
  useHotkey('Escape', onClose, { enabled: open })
  if (!open) return null
  return (
    <div ref={ref} role="dialog" aria-modal="true" aria-label="Menu">
      <button onClick={onClose}>Close</button>
      <nav>…</nav>
    </div>
  )
}
```

## When to use it

A custom modal, drawer, or full-screen menu that you can't build with `<dialog>`.

## When not to

You can use `<dialog>` with `showModal()`; it traps focus, restores it, closes on Escape, and makes the rest of the page inert, with no JS. A focus trap alone doesn't hide the page from screen readers: also set `aria-modal="true"` on the dialog, or `inert` on the rest of the page.

## API

```ts
function useFocusTrap<T extends HTMLElement = HTMLElement>(active?: boolean): (element: T | null) => void
```

| Parameter | Description |
| --- | --- |
| `active` | Trap focus while `true`. Default `true`. |

**Returns** A callback ref. Pass it to the container's `ref` prop.

## Browser support

Works in all modern browsers.

---

512 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useFocusTrap.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useFocusTrap/
Previous: [useRovingFocus](https://vincentri.github.io/react-tils/hooks/useRovingFocus.md)
Next: [useFocusWithin](https://vincentri.github.io/react-tils/hooks/useFocusWithin.md)
