Home

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.drawercomponents/ui/drawer.tsx

Use case

For the AI

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.