Reveal focused controls or details without leaving the page.
Drawer is built on top of Vaul by emilkowalski.
npx shadcn@latest add @iconiq/drawer"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>
);
}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.
openOptional controlled open state. Pair it with onOpenChange when parent state should own the drawer lifecycle.
Type boolean
defaultOpenInitial open state for uncontrolled usage. Vaul skips the first enter animation when the drawer is mounted open.
Type boolean
onOpenChangeCalled whenever the drawer opens or closes from the trigger, overlay, Escape key, close part, or drag release.
Type (open: boolean) => void
directionChooses 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"
modalKeeps focus and outside interaction modal while the drawer is open. Set false for non-modal command surfaces.
Type boolean·Default true
dismissibleAllows 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
handleOnlyWhen true, drag-to-close is limited to a Vaul Handle part instead of the full panel surface.
Type boolean·Default false
snapPointsOptional Vaul snap points for stepped drawer heights or widths. Values may be percentages or px strings.
Type (number | string)[]
asChildUse when a local button or link should remain the visible trigger element.
Type boolean
childrenInteractive content rendered by the trigger primitive.
Type ReactNode
childrenOverlay and panel content rendered outside the page flow.
Type ReactNode
classNameMerged with the default overlay tint and blur classes.
Type string
childrenDrawer body content rendered inside the animated panel.
Type ReactNode
classNameMerged with the direction-aware panel geometry and surface classes.
Type string
sizeControls panel width for left and right drawers and max height for top and bottom drawers.
Type "sm" | "default" | "lg" | "full"·Default "default"
showCloseButtonRenders an absolute close button in the panel corner. Useful for side drawers and quick dismissal.
Type boolean·Default false
showOverlayToggles the default overlay. Set false for non-modal surfaces or custom overlay composition.
Type boolean·Default true
overlayClassNameMerged onto DrawerOverlay when showOverlay is true.
Type string
childrenScrollable drawer content.
Type ReactNode
classNameMerged with the default body scroll classes.
Type string
variantDrawerAction tone. DrawerCancel uses the muted secondary style.
Type "default" | "destructive"
closeOnClickWhen false, the click handler runs without closing the drawer. Useful for async submit flows.
Type boolean·Default true
asChildCompose onto an existing button element.
Type boolean
childrenIcon or media rendered inside the circular slot.
Type ReactNode
childrenNested drawer composition rendered above the parent drawer.
Type ReactNode
asChildUse asChild to turn an existing footer action into the close control.
Type boolean
childrenInteractive content rendered by the close primitive.
Type ReactNode
childrenHeader content such as DrawerTitle and DrawerDescription.
Type ReactNode
classNameMerged with the default header spacing classes.
Type string
childrenFooter actions or supporting context.
Type ReactNode
classNameMerged with the default footer spacing classes.
Type string
childrenDrawer heading content.
Type ReactNode
classNameMerged with the default title typography classes.
Type string
childrenSupporting description copy beneath the drawer title.
Type ReactNode
classNameMerged with the default description typography classes.
Type string
overlayA fixed full-screen overlay fades in behind the drawer with a stronger black tint and backdrop blur support.
Type built-in
contentThe 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
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.