EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
hooks·hook·@astryxdesign/core

useFocusTrap

Traps focus within a container element following the WAI-ARIA dialog focus trap pattern. Listens to focus events on the document and redirects focus back into the container if it escapes via keyboard navigation. Handles both Tab and Shift+Tab wrapping. When the trap deactivates or unmounts, focus is restored to the element that was focused before activation, unless focus was already moved elsewhere or never entered the trap (so popups that keep focus on their trigger, like comboboxes, are unaffected). Mouse clicks outside the container are not intercepted; use a light-dismiss handler for that.

@astryxdesign/core/hooks

Signature

Call shape
useFocusTrap<T extends HTMLElement = HTMLElement>(options: UseFocusTrapOptions): UseFocusTrapReturn<T>
Parameters
NameType and behavior
optionsUseFocusTrapOptions · required
Configuration object for the focus trap.
options.isActiveboolean · required
Whether the focus trap is currently active.
options.onEscape() => void · optional
Callback when Escape key is pressed inside the trapped container.
Returns
NameType and behavior
containerRefReact.RefObject<HTMLElement | null>
Ref to attach to the container element that should trap focus.
focusFirst() => void
Focuses the first focusable element inside the container.

Usage

Traps focus within a container element following the WAI-ARIA dialog focus trap pattern. Listens to focus events on the document and redirects focus back into the container if it escapes via keyboard navigation. Handles both Tab and Shift+Tab wrapping. When the trap deactivates or unmounts, focus is restored to the element that was focused before activation, unless focus was already moved elsewhere or never entered the trap (so popups that keep focus on their trigger, like comboboxes, are unaffected). Mouse clicks outside the container are not intercepted; use a light-dismiss handler for that.

  • Call focusFirst() when opening a dialog/modal to move focus into the trapped region.
  • Provide an onEscape callback to close the dialog when Escape is pressed.
  • Rely on the built-in focus restoration on close; only add your own onHide focus handling when you need to send focus somewhere other than the previously-focused element.
  • Use on non-modal content like tooltips or dropdowns; those need light-dismiss, not focus trapping.