Drawer

A draggable panel with real physics. Swipe it closed on touch, scale the page behind it like a native sheet.

OverlaysVaul

Playground

Tweak the props, the preview and the code follow.

Props
<Drawer>
  <DrawerTrigger asChild>
    <Button variant="outline">Open drawer</Button>
  </DrawerTrigger>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Move to cycle</DrawerTitle>
      <DrawerDescription>Drag, swipe or press Esc to dismiss.</DrawerDescription>
    </DrawerHeader>
    <DrawerFooter>
      <Button>Cycle 24</Button>
      <DrawerClose asChild>
        <Button variant="outline">Cancel</Button>
      </DrawerClose>
    </DrawerFooter>
  </DrawerContent>
</Drawer>

Installation

npx @plumsydev/plum-ui add drawer

Usage

import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"
<Drawer>
  <DrawerTrigger>Open</DrawerTrigger>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Title</DrawerTitle>
      <DrawerDescription>Description</DrawerDescription>
    </DrawerHeader>
    <DrawerFooter>
      <DrawerClose>Close</DrawerClose>
    </DrawerFooter>
  </DrawerContent>
</Drawer>

Examples

Direction

Drawers can come from any edge with direction.

Snap points

Drag between a peek, half and full height — like a maps app.

API Reference

Drawer

PropTypeDefault
direction

Edge the drawer comes from.

"top" | "right" | "bottom" | "left""bottom"
shouldScaleBackground

Scales the page behind. Needs a `vaul-drawer-wrapper` attribute on your app wrapper.

booleantrue
snapPoints

Fractions or pixel values the drawer can rest at.

(number | string)[]—
dismissible

Allow closing by dragging or clicking outside.

booleantrue
open

Controlled open state.

boolean—
onOpenChange

Called when the open state changes.

(open: boolean) => void—

Notes

  • For the background scale effect, add vaul-drawer-wrapper="" to the element wrapping your app (and give it a background color).
  • A common pattern: render a Dialog on desktop and a Drawer on mobile with the same content.