Skip to content
TrademarkTrademark
Docs
Components

FocusTrap

Updated: August 31, 2026
View on GitHub

FocusTrap cycles Tab and Shift+Tab within its subtree while active, and returns focus to wherever it came from when deactivated. It is the piece that makes a dialog keyboard-safe: without it Tab walks straight out of the panel into the page behind, which for a screen-reader or keyboard user means the dialog effectively is not modal.

DropdownWrapper uses it, and so does ArrowNavigation when you set trapFocus. Reach for it directly when you are building an overlay of your own.

What it traps

Focusable elements are found with button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"]), in DOM order. Two consequences worth knowing:

  • A region with no focusable elements focuses the container itself, so focus is still inside rather than left on the page behind.
  • Arrow keys are deliberately not handled — they pass through, so ArrowNavigation can own them. The two compose: FocusTrap decides what Tab may reach, ArrowNavigation decides what the arrows move between.

Controlling where focus lands

By default the trap focuses the first focusable element on activation and restores the previously focused element on deactivation. Both ends can be pointed somewhere specific.

Set autoFocus={false} when the region should open without stealing focus — an inline editor revealed under the cursor, say. Set restoreFocus={false} when the element that opened the region is gone by the time it closes, and returning focus to it would throw the user to the top of the document.

Escape

onEscape fires on the Escape key and nothing else — the trap never closes itself. Owning the open state in the caller is what lets a confirm step or an unsaved-changes prompt sit in between.

API reference

Type
Default
childrenrequired
React.ReactNode—
activerequired
Whether the trap is on. Required.
boolean—
onEscape
Called on the Escape key. The trap does not close itself.
() => void—
containerRef
Supply the container ref when the caller also needs it.
RefObject<HTMLDivElement | null>—
className
string—
style
React.CSSProperties—
initialFocusRef
Element to focus on activation, instead of the first focusable one.
RefObject<HTMLElement | null>—
returnFocusRef
Element to focus on deactivation, instead of the previously focused one.
RefObject<HTMLElement | null>—
restoreFocus
Return focus when it deactivates.
booleantrue
autoFocus
Move focus into the region when it activates.
booleantrue
Edit this page on GitHub