Drawer
A panel that rises from the bottom (or comes in from any edge), follows the finger and closes with a swipe, the way a phone's sheets do.
ui.drawer
components/ui/drawer.tsxUse case
Use it where the tool is used on a phone or a tablet: picking a time slot to book a meeting, setting an order's status on the shop floor, a short list of actions on a row. It tracks the swipe, stacks when a second drawer opens over it, and `showBar` draws the handle that says it can be pulled down. For a phone-sized action list it has its own rows (`DrawerMenu`, `DrawerMenuItem`, and checkbox and radio rows).
Use it when
- The screen is a phone or a tablet and the thumb is the pointer
- A short choice from the foot of the screen: a slot, a status, an action
- A list of actions that would be cramped as a dropdown on a phone
- One drawer opening over another, stacked
Use something else when
- On a wide window, a side panel for filters or a record: Sheet
- A form or a short task on a wide window: Dialog
- A list of actions from a button on a wide window: Dropdown menu
Examples
Code
Import
import { Button } from "@/components/ui/button"
import {
Drawer,
DrawerClose,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerPanel,
DrawerPopup,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer"Usage
<Drawer>
<DrawerTrigger render={<Button variant="secondary" />}>Book a Meeting</DrawerTrigger>
<DrawerPopup showBar>
<DrawerHeader>
<DrawerTitle>Book a meeting</DrawerTitle>
<DrawerDescription>Pick a time; swipe down to close.</DrawerDescription>
</DrawerHeader>
<DrawerPanel className="grid gap-3">
{["Tomorrow, 9:00", "Tomorrow, 14:30", "Thursday, 10:00"].map((t) => (
<Button key={t} variant="outline" className="justify-start">
{t}
</Button>
))}
</DrawerPanel>
<DrawerFooter>
<DrawerClose render={<Button className="w-full" size="lg" />}>Confirm</DrawerClose>
</DrawerFooter>
</DrawerPopup>
</Drawer>Rules
- There is no close button by default (`showCloseButton` is false): a swipe, the backdrop or a `DrawerClose` closes it, so the footer always offers one.
- A bottom drawer shows its handle with `showBar`, so the swipe can be found.
- Set the edge with `position` on `Drawer`: the popup reads it, and the swipe direction follows it.
- Content that can grow goes in `DrawerPanel`, which scrolls and fades at its edges.
- A `<form>` placed directly inside `DrawerPopup` is laid out as contents, so the footer stays at the bottom.