focus-trap-react

A lightweight React component that traps and manages keyboard focus inside modals, dialogs, and other overlays for full keyboard accessibility.

Library
npm
v12.0.3
784stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
80/100Excellent
Development Activity96
Maintenance84
Community52
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture78
Code Quality88
Innovation74
Learning Curve80

focus-trap-react wraps the framework-agnostic focus-trap library in a single React component, <FocusTrap>, that keeps keyboard focus contained within a designated container. Mount it around a modal, dialog, or dropdown and it activates automatically, cycling Tab and Shift+Tab through the trap’s focusable elements and preventing focus from escaping to the rest of the page.

The component tracks the element that had focus before activation and restores it on deactivation, handles outside clicks, supports pausing and unpausing for coordinating multiple simultaneous traps, and works with either a single child container or an explicit list of containerElements. It targets React 18 and 19, ships TypeScript types out of the box, and is maintained by the same team behind the underlying focus-trap and tabbable packages it depends on.

What You Get

  • A single <FocusTrap> React component that activates on mount and deactivates on unmount by default
  • Automatic focus restoration to the previously focused element when the trap deactivates
  • Support for containerElements to define trap boundaries across multiple DOM nodes instead of a single child
  • Full pass-through of focus-trap’s createOptions via the focusTrapOptions prop, including click-outside and escape-key behavior
  • Built-in TypeScript type definitions (index.d.ts) for the component and its props

Common Use Cases

  • Building accessible modal dialogs where Tab/Shift+Tab must cycle only through the dialog’s controls
  • Trapping focus inside dropdown menus or popovers while they’re open
  • Implementing off-canvas navigation drawers that shouldn’t leak keyboard focus to the page behind them
  • Coordinating multiple simultaneous traps (e.g. nested dialogs) using the paused/active props

Under The Hood

Architecture The library is a single class, FocusTrap (in src/focus-trap-react.js), extending React.Component and wrapping the framework-agnostic focus-trap package. It splits configuration into internalOptions (the deactivation-related options it must own internally) and originalOptions (the consumer’s original values), which lets it intercept and coordinate focus-restoration timing before delegating everything else straight to focus-trap. React lifecycle methods (componentDidMount, componentDidUpdate, componentWillUnmount) drive setupFocusTrap()/deactivateTrap(), while render() either clones a single child with a callback ref to obtain its DOM node or accepts explicit containerElements for multi-node traps. There is no external state machine or DI; the whole module concentrates option normalization, deactivation sequencing, ref plumbing, and React 19 ref-shape handling into one class.

Tech Stack Built on React (peer dependency ^18.0.0 || ^19.0.0) and depends directly on focus-trap ^8.2.2 and tabbable ^6.5.0, both maintained by the same organization. Source is authored in JavaScript and compiled with Babel (@babel/preset-env, @babel/preset-react) into dist/; TypeScript is used only for the hand-written index.d.ts declarations, checked via tsc. Tooling includes ESLint 9’s flat config with typescript-eslint, React, import, Jest, and Cypress plugins, Prettier for formatting, Jest with @testing-library/react and jsdom for unit tests, Cypress plus start-server-and-test/budo for e2e demo testing, Changesets for release management, and GitHub Actions CI with Dependabot.

Code Quality The test suite (test/focus-trap-react.test.js) is a substantial 1,100+ line file using @testing-library/react and user-event against a real jsdom DOM, covering activation/deactivation, pause/unpause, focus restoration, outside clicks, containerElements, and React 18 Strict Mode remount behavior. Failure modes are explicit rather than swallowed — invalid focusTrapOptions values or a Fragment child throw descriptive errors instead of failing silently. Naming and comments are extensive and self-documenting, explaining non-obvious lifecycle interactions in detail. Type safety is provided by the maintained index.d.ts rather than the source itself being written in TypeScript. CI runs format, lint, coverage, type-checking, and Cypress e2e on every push.

API Design The public surface is deliberately small — one component with five props (children, active, paused, focusTrapOptions, containerElements) — while still exposing every focus-trap option through pass-through. The library normalizes React’s ref-handling differences between React 18 and 19 internally so consumers don’t need version-specific code, and it specifically detects and recovers from React 18 Strict Mode’s dev-only unmount/remount cycle by reactivating an existing trap instance rather than leaking a duplicate. It is best understood as a thin, carefully considered React lifecycle wrapper around focus-trap rather than a novel focus-management model of its own.

Used by 6 apps in this directory

TypeScript
68%
Apache 2.0

Appsmith

Developer Tools · Automation · No Code Platforms

40,825

Open-source low-code platform to build admin panels, dashboards, and internal tools connected to any database or API.

View details
93
Repo Health
79
Technical
66
Dependency
Built with
TypeScript68%
Java21%
Updated 3 days ago
TypeScript
97%
Other

nango

Developer Tools · Automation · Authentication

11,746

Build product integrations with AI using 800+ APIs — auth, proxy, and TypeScript functions on production-grade infrastructure.

View details
93
Repo Health
85
Technical
68
Dependency
Built with
TypeScript97%
Updated 3 days ago
TypeScript
94%
Other

OpenHands

AI Code Assistants · AI Development

86,377

The self-hosted developer control center for running AI coding agents — locally, in Docker, on VMs, or across cloud backends — with automation workflows for GitHub, Slack, and more.

View details
91
Repo Health
82
Technical
70
Dependency
Built with
TypeScript94%
Updated today
JavaScript
63%
AGPL 3.0

overleaf

Collaboration · Productivity

18,090

Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.

View details
82
Repo Health
80
Technical
62
Dependency
Built with
JavaScript63%
TypeScript29%
Updated 1 months ago
Rust
93%
Other

Tabby

AI Code Assistants

33,868

Self-hosted AI coding assistant — run GitHub Copilot-grade code completion on your own hardware with no cloud dependency.

View details
60
Repo Health
78
Technical
61
Dependency
Built with
Rust93%
Updated 2 months ago
JavaScript
55%
AGPL 3.0

ToolJet

Low Code Platforms · No Code Platforms · AI Agents

40,857

Open-source AI-native platform to build and deploy internal tools, workflows, and AI agents with a visual drag-and-drop builder and 80+ data source integrations.

View details
94
Repo Health
81
Technical
63
Dependency
Built with
JavaScript55%
TypeScript38%
Updated today

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search