How to build an accessible Drawer in React
Renders role="dialog" with aria-modal; the title labels it via aria-labelledby and the description via aria-describedby. FocusScope traps Tab focus and restores it on close; DismissableLayer handles Escape and outside-pointer dismissal.
When to use a Drawer
- A side or edge panel for navigation, filters, or detail views that needs full-height space
- A modal surface that slides in and locks the page behind it while open
- A controllable open/close panel where the parent owns the state via open/onOpenChange
When not to use it
- A short yes/no confirmation — use AlertDialog
- Small content anchored to a trigger element — use Popover
- A gesture-driven, swipe-to-dismiss sheet — use Sheet
Keyboard interactions
Role dialog, verified at WCAG 2.2-AA.
EscapeTabShift+Tab
Common mistakes
Avoid: <Drawer title="Delete item?">Are you sure?</Drawer>
Prefer: <AlertDialog title="Delete item?" />
A full edge panel with focus trap and scroll lock is overkill for a yes/no decision
Example
<Drawer open={isOpen} onOpenChange={setIsOpen} title="Settings">
<SettingsForm />
</Drawer>