0

Drawer

A drawer component for React.

"use client"

import * as React from "react"

Installation

bunx --bun shadcn@latest add @ondo-ui/drawer

Usage

import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"
<Drawer>
  <DrawerTrigger render={<Button variant="outline" />}>Open</DrawerTrigger>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Are you absolutely sure?</DrawerTitle>
      <DrawerDescription>This action cannot be undone.</DrawerDescription>
    </DrawerHeader>
    <div className="p-4">{/* Content here */}</div>
    <DrawerFooter>
      <Button>Submit</Button>
      <DrawerClose render={<Button variant="outline" />}>Cancel</DrawerClose>
    </DrawerFooter>
  </DrawerContent>
</Drawer>

Composition

Use the following composition to build a Drawer:

Drawer
├── DrawerTrigger
└── DrawerContent
    ├── DrawerHeader
    │   ├── DrawerTitle
    │   └── DrawerDescription
    └── DrawerFooter

DrawerContent composes the portal, overlay, viewport, and popup from Base UI. For lower-level control, DrawerPortal, DrawerOverlay, and DrawerSwipeHandle are also exported.

Examples

Position

Use the swipeDirection prop to set the side of the drawer.

Available options are up, right, down, and left.

import { Button } from "@/components/ui/button"
import {
  Drawer,

Swipe Handle

Use showSwipeHandle on Drawer to render a swipe handle.

"use client"

import { Button } from "@/components/ui/button"

Nested

Open drawers from inside another drawer. Parent drawers stay mounted and stack behind the frontmost drawer.

"use client"

import { useIsMobile } from "@/hooks/use-mobile"

Non Modal

Set modal={false} to allow interaction with the rest of the page while the drawer is open. Combine with disablePointerDismissal to prevent the drawer from closing on outside presses. Use modal="trap-focus" to keep focus inside the drawer while leaving scroll and pointer interaction unrestricted.

import { Button } from "@/components/ui/button"
import {
  Drawer,

Snap Points

Use snapPoints to snap a drawer to preset heights. Numbers between 0 and 1 represent fractions of the viewport. Numbers greater than 1 are treated as pixel values. String values support px and rem units. Snap points apply to vertical drawers.

Track the active snap point with the controlled snapPoint and onSnapPointChange props. At the full snap point, the drawer gets a data-expanded attribute you can style with the data-expanded: variant.

"use client"

import { Button } from "@/components/ui/button"

Responsive

You can combine the Dialog and Drawer components to create a responsive dialog. This renders a Dialog component on desktop and a Drawer on mobile.

"use client"

import * as React from "react"

API reference

The component wraps Base UI Drawer and accepts all of its props.