Drawer
Drawer is a Dialog pinned to a screen edge. It carries the full modal contract — focus trap,
scrim, Escape dismissal — and adds a side prop that anchors the surface left, right, top, or
bottom.
What it is
Dialog with one addition. Drawer.Content takes a side prop and
applies the fixed-edge positioning for it; everything else — the parts, the focus contract, the
dismissal behaviour — is Dialog unchanged. Because it composes Dialog.Content directly, it
inherits exitDurationMs and the exit-transition contract for free.
Install
Anatomy
API
Drawer exposes the same six parts as Dialog — Root, Trigger, Content, Title,
Description, Close. Root, Trigger, Title, Description, and Close are Dialog's parts
unchanged; see the Dialog API. Drawer.Content adds one prop:
Drawer.Content
stablefunction Drawer.Content(props: DrawerContentProps): JSX.Element | null
The screen edge the drawer is anchored to.
Every Dialog.Content prop — `dismissOnEscape`, `dismissOnScrimClick`, `exitDurationMs`, `style`.
Accessibility
Drawer is a modal, so the Dialog focus contract applies — focus moves into the surface on open, traps inside, and restores to the trigger on close. Escape and a scrim click dismiss it.
Include a Drawer.Title even when the drawer is a navigation panel. It is the surface's
accessible name; "Navigation" or "Menu" is enough, and without it a screen-reader user only hears
that a dialog opened.
Cross-platform notes
On web Drawer composes Dialog's Portal + Overlay + FocusScope, with the side styling applied as
position: fixed. On native the modal contract maps to the platform's modal presentation; the
side prop drives the slide-in edge. The compose-time API is identical on both targets.
Examples
A left-anchored navigation drawer:
An animated slide-out: