Drawer
A modal native <dialog> pinned to the start or end edge, full height. Drawer.Root takes the same props as Dialog.Root plus side, and the inside is built from Dialog's parts: Dialog.Header, Dialog.Title, Dialog.Description, Dialog.Body, Dialog.Footer and Dialog.Close.
side is end by default. Start and end follow text direction, so in right-to-left text end is the left edge.
<Drawer.Root open={open} onOpenChange={setOpen}>
<Dialog.Header>
<Dialog.Title>Filters</Dialog.Title>
<Dialog.Close>Close</Dialog.Close>
</Dialog.Header>
<Dialog.Body>…</Dialog.Body>
</Drawer.Root>
When to use
When: A modal side panel for a task that needs room, such as filters, settings or details beside a list. Name it with Dialog.Title or aria-label.
When not: A short centered task or confirm → Dialog. A mobile picker from the bottom → BottomSheet. A panel that leaves the page usable → product layout, not a modal.
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| open | boolean | no | — | Controlled open state. Leave it out for an uncontrolled drawer. |
| defaultOpen | boolean | no | false | Shows the drawer on mount when uncontrolled. There is no trigger part, so once closed it opens again only on remount. |
| onOpenChange | (open: boolean, reason: DialogCloseReason) => void | no | — | Dismiss requests, with the same reasons as Dialog.Root. |
| side | 'start' | 'end' | no | 'end' | Inline edge it is pinned to. Follows text direction. |
| dismissOnEscape | boolean | no | true | Escape calls onOpenChange(false, "escape"). |
| dismissOnBackdrop | boolean | no | true | Scrim click calls onOpenChange(false, "backdrop"). |
| aria-label | string | no | — | Name when Dialog.Title is omitted. |