Drawer

Reveal focused controls or details without leaving the page.

Credits

Drawer is built on top of Vaul by emilkowalski.

Installation

npx shadcn@latest add @iconiq/drawer

File Structure

Usage

"use client";

import { useState } from "react";
import {
  Drawer,
  DrawerAction,
  DrawerCancel,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
  drawerTriggerSmClassName,
} from "@/components/ui/drawer";

export function DrawerPreview() {
  const [open, setOpen] = useState(false);

  return (
    <Drawer onOpenChange={setOpen} open={open}>
      <DrawerTrigger asChild>
        <button className={drawerTriggerSmClassName} type="button">
          Review
        </button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Review checklist</DrawerTitle>
        <DrawerDescription>
          Review the checklist and save your updates without leaving the page.
        </DrawerDescription>
        </DrawerHeader>
        <DrawerFooter>
          <DrawerCancel>Cancel</DrawerCancel>
          <DrawerAction>
            Save
          </DrawerAction>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  );
}

Responsive dialog pattern

For desktop-first flows, pair this drawer with a dialog: render Dialog from md: breakpoints upward and keep Drawer for mobile. Use the playground direction controls to preview bottom, top, left, and right placements before wiring your responsive breakpoint switch.

Props

Props
Description

Drawer

open

Optional controlled open state. Pair it with onOpenChange when parent state should own the drawer lifecycle.

Type boolean

defaultOpen

Initial open state for uncontrolled usage. Vaul skips the first enter animation when the drawer is mounted open.

Type boolean

onOpenChange

Called whenever the drawer opens or closes from the trigger, overlay, Escape key, close part, or drag release.

Type (open: boolean) => void

direction

Chooses the drawer edge and matching Vaul slide direction. The content classes style each direction with the appropriate inset and rounded leading edge.

Type "left" | "right" | "top" | "bottom"·Default "bottom"

modal

Keeps focus and outside interaction modal while the drawer is open. Set false for non-modal command surfaces.

Type boolean·Default true

dismissible

Allows overlay click, Escape, and drag gestures to close the drawer. Controlled drawers can disable this when a flow must be completed explicitly.

Type boolean·Default true

handleOnly

When true, drag-to-close is limited to a Vaul Handle part instead of the full panel surface.

Type boolean·Default false

snapPoints

Optional Vaul snap points for stepped drawer heights or widths. Values may be percentages or px strings.

Type (number | string)[]

DrawerTrigger

asChild

Use when a local button or link should remain the visible trigger element.

Type boolean

children

Interactive content rendered by the trigger primitive.

Type ReactNode

DrawerPortal

children

Overlay and panel content rendered outside the page flow.

Type ReactNode

DrawerOverlay

className

Merged with the default overlay tint and blur classes.

Type string

DrawerContent

children

Drawer body content rendered inside the animated panel.

Type ReactNode

className

Merged with the direction-aware panel geometry and surface classes.

Type string

size

Controls panel width for left and right drawers and max height for top and bottom drawers.

Type "sm" | "default" | "lg" | "full"·Default "default"

showCloseButton

Renders an absolute close button in the panel corner. Useful for side drawers and quick dismissal.

Type boolean·Default false

showOverlay

Toggles the default overlay. Set false for non-modal surfaces or custom overlay composition.

Type boolean·Default true

overlayClassName

Merged onto DrawerOverlay when showOverlay is true.

Type string

DrawerBody

children

Scrollable drawer content.

Type ReactNode

className

Merged with the default body scroll classes.

Type string

DrawerAction / DrawerCancel

variant

DrawerAction tone. DrawerCancel uses the muted secondary style.

Type "default" | "destructive"

closeOnClick

When false, the click handler runs without closing the drawer. Useful for async submit flows.

Type boolean·Default true

asChild

Compose onto an existing button element.

Type boolean

DrawerMedia

children

Icon or media rendered inside the circular slot.

Type ReactNode

DrawerNested

children

Nested drawer composition rendered above the parent drawer.

Type ReactNode

DrawerClose

asChild

Use asChild to turn an existing footer action into the close control.

Type boolean

children

Interactive content rendered by the close primitive.

Type ReactNode

DrawerHeader

children

Header content such as DrawerTitle and DrawerDescription.

Type ReactNode

className

Merged with the default header spacing classes.

Type string

DrawerFooter

children

Footer actions or supporting context.

Type ReactNode

className

Merged with the default footer spacing classes.

Type string

DrawerTitle

children

Drawer heading content.

Type ReactNode

className

Merged with the default title typography classes.

Type string

DrawerDescription

children

Supporting description copy beneath the drawer title.

Type ReactNode

className

Merged with the default description typography classes.

Type string

Motion and layout

overlay

A fixed full-screen overlay fades in behind the drawer with a stronger black tint and backdrop blur support.

Type built-in

content

The panel gets a fluid cubic-bezier open curve, a shorter close duration, GPU-friendly transform hints, and a slightly extended initial transform for a softer arrival.

Type built-in

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: vaul, lucide-react.

This page documents the Vaul install only. The Base UI and Radix UI provider options are visible for section consistency but disabled because this drawer is not a primitive-specific wrapper.

The generated registry file is /r/drawer.json.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.

Stay on the page while you review.Tapto continue.