Components
Drawer
A panel that slides up from the bottom of the screen, keeping the page behind it in view. Built for focused, touch-friendly tasks: quick edits, confirmations, or a short read, dismissed by dragging the handle or tapping outside.
Preview
Rendered with live Cognition tokens: the panel surface, overlay scrim, and text remap on theme change, no dark: classes. Trigger it to slide the panel up.
Variants
<Drawer>
<DrawerTrigger asChild>
<Button variant="outline">Open Drawer</Button>
</DrawerTrigger>
<DrawerContent>
<div className="mx-auto w-full max-w-sm">
<DrawerHeader>
<DrawerTitle>Move Goal</DrawerTitle>
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
</DrawerHeader>
{/* stepper + chart */}
<DrawerFooter>
<Button>Set Goal</Button>
<DrawerClose asChild>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</div>
</DrawerContent>
</Drawer><DrawerContent>
<div className="mx-auto w-full max-w-sm">
<DrawerHeader>
<DrawerTitle>Edit profile</DrawerTitle>
<DrawerDescription>Make changes to your profile here.</DrawerDescription>
</DrawerHeader>
<div className="grid gap-4 p-4">
<Input id="name" defaultValue="Tony Yates" />
<Input id="username" defaultValue="@tony" />
</div>
<DrawerFooter>…</DrawerFooter>
</div>
</DrawerContent><DrawerContent>
<div className="mx-auto w-full max-w-sm">
<DrawerHeader>
<DrawerTitle>Title Text</DrawerTitle>
<DrawerDescription>This is a drawer description.</DrawerDescription>
</DrawerHeader>
<div className="max-h-[50vh] overflow-y-auto px-4 text-sm text-text-subtle">
<p>…</p>
</div>
<DrawerFooter>…</DrawerFooter>
</div>
</DrawerContent>The same primitive frames a statistic with steppers, a short form, or a block of text. Constrain the body with mx-auto w-full max-w-sm so it stays readable on wide screens.
States
<Drawer>…</Drawer> {/* drag or tap overlay closes */}<Drawer dismissible={false}>…</Drawer> {/* only a button closes */}By default a drawer is dismissible: drag the handle down or tap the overlay. Set dismissible={false} to require an explicit action, for steps the user must acknowledge.
API
Don't and Do
Don't use a drawer for a desktop-first dialog: reach for Dialog there. And don't stack drawers or nest one inside another; a drawer is a single focused surface, not a navigation layer.
<Drawer>
<DrawerTrigger asChild>
<Button variant="outline">Open</Button>
</DrawerTrigger>
<DrawerContent>…</DrawerContent>
</Drawer>import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
export function GoalDrawer() {
return (
<Drawer>
<DrawerTrigger asChild>
<Button variant="outline">Open</Button>
</DrawerTrigger>
<DrawerContent>
<div className="mx-auto w-full max-w-sm">
<DrawerHeader>
<DrawerTitle>Move Goal</DrawerTitle>
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<Button>Set Goal</Button>
<DrawerClose asChild>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</div>
</DrawerContent>
</Drawer>
);
}