Drawer

A panel that slides in from the edge of the screen.

Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/drawer.json
Usage
Pass trigger, title, description, footer, and body children as props — no manual slot composition needed.
TSImport
import { Drawer } from "@/components/ui/drawer";
TSExample
import { Button } from "@/components/ui/button";
import { Drawer } from "@/components/ui/drawer";

export function Example() {
  return (
    <Drawer
      trigger={<Button variant="outline">Open</Button>}
      title="Are you sure?"
      description="This action cannot be undone."
      closeLabel="Cancel"
      direction="right"
    >
      {/* body content */}
    </Drawer>
  );
}
Composition
Anatomy of the Drawer primitive.
// Flat one-liner — covers most use cases
<Drawer
  trigger={<Button>Open</Button>}
  title="Title"
  description="Optional subtitle."
  footer={<Button className="w-full">Confirm</Button>}
  closeLabel="Cancel"       // convenience close button in footer
  direction="right"         // default for flat API
  isFloat                   // default true — card-style floating panel
  notch                     // default true — drag-handle pill
  open / onOpenChange        // controlled mode; omit trigger when using these
  contentClassName           // className forwarded to DrawerContent
  bodyClassName              // className forwarded to DrawerBody
>
  {body content}
</Drawer>

// Escape hatch — slot exports remain available for complex compositions
import {
  DrawerRoot, DrawerTrigger, DrawerContent,
  DrawerHeader, DrawerTitle, DrawerDescription,
  DrawerBody, DrawerFooter, DrawerClose,
} from "@/components/ui/drawer";
Basic
A right-side drawer triggered by a button. Pass trigger, title, description, footer, and body children — no manual slot composition needed.
Side
Pass `direction` to slide in from any edge. The radio group lets you pick top, bottom, left, or right at runtime.
Inset
Set `isFloat={false}` for an edge-flush drawer with no outer margin or rounded outer corners — the drawer runs all the way to the screen edge.
Controlled
Drive open state with `useState`. Pass `open` and `onOpenChange`. Omit `trigger` and handle the open button yourself.
Notchless
Set `notch={false}` to hide the drag-handle pill. Uses a bottom drawer here to make the missing notch visible — the prop works on any direction.
API Reference
All props on the flat Drawer component.

Drawer

PropTypeDefaultDescription
triggerReactNodeTrigger element rendered inside DrawerTrigger with asChild. Omit when using controlled mode.
titleReactNodeDrawer title. Omitting title and description skips DrawerHeader.
descriptionReactNodeOptional subtitle rendered below the title in muted text.
childrenReactNodeScrollable body content inside DrawerBody.
footerReactNodeFooter content. Omitting footer and closeLabel skips DrawerFooter.
closeLabelReactNodeConvenience: renders an outline close button in the footer via DrawerClose.
direction"top" | "bottom" | "left" | "right""right"Which edge the drawer slides in from.
isFloatbooleantrueFloating card style with inset margin and rounded corners. Set false for edge-flush.
notchbooleantrueShows or hides the drag-handle pill. Only visible on top/bottom drawers.
openbooleanControlled open state.
onOpenChange(open: boolean) => voidCallback fired when the open state changes.
dismissiblebooleantrueWhether clicking the overlay closes the drawer.
modalbooleantrueWhen false, background content remains interactive.
contentClassNamestringExtra className forwarded to DrawerContent.
bodyClassNamestringExtra className forwarded to DrawerBody.

Escape-hatch slot exports

PropTypeDefaultDescription
DrawerRootvaul RootRaw vaul drawer root (replaces old Drawer slot export). Accepts all vaul Root props.
DrawerContentcomponentisFloat (default true), notch (default true), plus all vaul Content props.
DrawerBodycomponentflex-1 overflow-y-auto scrollable area. Accepts className.
DrawerHeader / DrawerFootercomponentLayout wrappers. Accept className and children.
DrawerTitle / DrawerDescriptionvaul primitivesEmit data-slot markers used by CSS variant hooks.
DrawerTrigger / DrawerClosevaul primitivesUse asChild to wrap your own Button.