Skip to main content

@lexical/react/useFocusTrap

Functions

useFocusTrap()

useFocusTrap(containerRef, isActive, initialFocus?): void

Defined in: packages/lexical-react/src/useFocusTrap.ts:59

Traps Tab / Shift+Tab focus inside containerRef while isActive is true, and restores focus to the previously-focused element when the trap deactivates. Intended for modal dialogs and other transient overlays.

initialFocus chooses where to land when the trap activates:

  • 'firstFocusable' (default): focus the first focusable descendant.
  • 'container': focus the container itself. The container must satisfy tabIndex >= -1 (so it's programmatically focusable); callers typically set tabIndex={-1} to keep it out of the natural Tab order while remaining programmatically focusable. Use for dialogs whose first focusable is a dismiss/close action so the user lands on the dialog body and screen readers announce the dialog label before any control. initialFocus is expected to stay stable for the lifetime of the trap.

While the trap is active, any focus that lands outside the container is pulled back inside via a document-level focusin listener. This is what lets the trap recover from Safari's default Tab routing through the browser chrome, but it also means descendants that mount into a portal outside containerRef.current (autocomplete panels, tooltips, toasts that auto-focus themselves) will be yanked back as soon as they take focus. Portal them inside the container, or skip this hook for those dialogs. The pull-back always lands on the first focusable descendant (or the container as a fallback) — initialFocus only applies to the activation-time landing, not to subsequent escape recoveries. Only one trap should be mounted at a time — two active traps install competing document-level focusin listeners and will fight over focus.

Escape is not intercepted — the owner handles close-key behavior itself.

Parameters

containerRef

RefObject<HTMLElement | null>

isActive

boolean

initialFocus?

"firstFocusable" | "container"

Returns

void