Drawer
A bottom panel that adapts to mobile; swipe to dismiss, but never only by gesture.
Base UI reference ↗Installation
Run it from the root of a project already set up with zunoui init.
npx zunoui@latest add drawerDependencies
What add drawer installs alongside the component. The CLI skips any you already have in a compatible version.
ZUNO registry
@zuno/utils
npm
@base-ui/[email protected]
Examples
2 examples · 1 componentWith actions
Header, content and a footer with the primary action and a close.
Long content
The body scrolls inside the 85dvh panel; the handle and close stay put.
API reference
Keeps the props, events and refs of the matching Base UI primitive, plus ZUNO's styles.
| Prop | Type | Default |
|---|---|---|
DrawerRoot; open, defaultOpen, onOpenChange, snapPoints and modal. Swipes down to dismiss. | — | — |
DrawerTrigger / DrawerCloseOpen and close; use render to reuse Button. | button | — |
DrawerContentPortaled bottom panel with a handle, scrollable body and max 85dvh; showClose (true) adds the corner button. | div | — |
DrawerHeader / DrawerFooterTitle block and actions; the footer always stacks full width (primary first). | div | — |
DrawerTitle / DrawerDescriptionLabel and describe the dialog. | h2 / p | — |
States
The states that apply to this component and their visual treatment.
| State | Treatment |
|---|---|
| Closed | Only the trigger. |
| Open | Slides up over a dimmed backdrop. |
| Swiping | Follows the finger with no transition; the backdrop fades with progress. |
| Dismissed | Slides down; focus returns to the trigger. |
Accessibility
It is a modal dialog: focus moves inside, stays trapped and returns to the trigger; DrawerTitle and DrawerDescription label it.
Swiping is optional: Escape, the backdrop and the close button dismiss it too, so keyboard and switch users are never stuck.
The handle is decorative (aria-hidden); the body scrolls on its own and text stays selectable while swiping.
The slide and backdrop fade stop with reduced motion.