Basel Standard / Docs
Drawer
Bottom-sheet overlay for mobile-first tasks that should stay connected to the current page.
Drawers are for tasks that should rise from the bottom edge instead of interrupting the center of the screen. They work especially well on mobile where a bottom sheet feels more natural than a modal dialog. In this system the drawer is restrained and task-focused so the underlying page still feels present.
Installation
Purchase access, then open /account/install to issue a registry token.Usage
import {
Drawer,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer"
<Drawer shouldScaleBackground={false}>
<DrawerTrigger asChild>
<Button>Open drawer</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Mobile review queue</DrawerTitle>
<DrawerDescription>Continue the task without leaving the page.</DrawerDescription>
</DrawerHeader>
</DrawerContent>
</Drawer>
Why This Primitive Exists
Centered dialogs can feel heavy on mobile. A drawer preserves context while giving the user a clear temporary surface for the next action.
- Use it for mobile-first reviews, quick action lists, and short handoff tasks.
- Prefer it when the background page should stay mentally available.
- Avoid it for desktop-first workflows that need a centered decision surface or a persistent side rail.
Examples
Basic Bottom Sheet
The default pattern is a trigger followed by a short header and a small footer action cluster.
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Mobile review queue</DrawerTitle>
<DrawerDescription>Use the drawer for bottom-sheet tasks.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>{/* actions */}</DrawerFooter>
</DrawerContent>
Action List
Keep the internal structure concise. A drawer should finish one mobile task, not become a full app shell.
<div className="grid gap-2 px-4">
<div className="border p-3">Accept revised copy</div>
<div className="border p-3">Request another pass</div>
</div>
In Context
Drawers are most convincing when they are attached to a workflow card or mobile review surface rather than floating as an isolated demo.
Mobile workflow
This is a better fit for mobile handoffs and quick review queues than a centered dialog.
<CardContent>
<Drawer>
<DrawerTrigger asChild>
<Button>Open review sheet</Button>
</DrawerTrigger>
</Drawer>
</CardContent>
Guidance
Prefer Drawer For Mobile Handoffs
- Use it when the task should emerge from the bottom edge.
- Reach for
Dialogwhen the interaction is more desktop-centered or more interruptive. - Use
Sheetwhen the content should attach to a side of the viewport instead.
Keep The Task Short
- Limit the drawer to one clear action cluster or one short form.
- Avoid long, scroll-heavy content that turns the bottom sheet into a page replacement.
- Keep titles direct so the user can orient quickly on small screens.
Control Background Treatment Deliberately
- Use
shouldScaleBackground={false}when the shrinking page effect feels too theatrical for the product surface. - Let the background remain visible enough to preserve context.
- If the underlying content must disappear from attention completely, a dialog may be the better fit.
API Reference
Core Exports
| Export | Renders | Notes |
|---|---|---|
Drawer | DrawerPrimitive.Root | Root state container built on Vaul. |
DrawerTrigger | DrawerPrimitive.Trigger | Opens the bottom sheet. |
DrawerPortal | DrawerPrimitive.Portal | Portal wrapper for overlay and content. |
DrawerOverlay | DrawerPrimitive.Overlay | Full-screen dimmed overlay. |
DrawerContent | DrawerPrimitive.Content | Bottom-attached sheet surface with the shared top handle. |
DrawerHeader | div | Layout wrapper for title and description. |
DrawerFooter | div | Footer action stack. |
DrawerTitle | DrawerPrimitive.Title | Large uppercase heading. |
DrawerDescription | DrawerPrimitive.Description | Supporting task copy. |
DrawerClose | DrawerPrimitive.Close | Manual close control for custom actions. |
Notable Props
| Export | Prop | Type | Notes |
|---|---|---|---|
Drawer | shouldScaleBackground | boolean | Defaults to true; set false for a flatter background treatment. |
Drawer | open, defaultOpen, onOpenChange | Vaul root props | Supports controlled and uncontrolled state. |
DrawerTrigger | asChild | boolean | Keeps the trigger element type when composed with Button. |
DrawerContent | className plus Vaul content props | content props | Use to adjust height or internal layout. |
The drawer is implemented with Vaul, so drag gestures, focus behavior, and mobile sheet semantics come from the underlying primitive.