Drawer

React Drawer components are gesture-driven panels that slide in from the edge of the screen. Unlike a standard Sheet, a Drawer supports drag-to-dismiss gestures, making it feel native and highly interactive, especially on mobile devices.

This Drawer component is built with React Aria for accessibility, Framer Motion for fluid gesture animations, and Tailwind CSS for styling. It supports all four sides and includes a customizable drag handle.

Installation

Install the component using the Tailgrids CLI.

npx @tailgrids/cli add drawer

Anatomy

The Drawer follows a composable pattern similar to the Sheet, but with built-in gesture support and a drag handle.

import {
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
  DrawerBody,
  DrawerFooter,
  DrawerClose
} from "@/registry/core/drawer";

export default function DrawerAnatomy() {
  return (
    <Drawer>
      <DrawerTrigger />
      <DrawerContent side="bottom">
        <DrawerHeader>
          <DrawerTitle />
          <DrawerDescription />
        </DrawerHeader>
        <DrawerBody />
        <DrawerFooter>
          <DrawerClose />
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  );
}

Usage

Create a drawer by composing the necessary components inside a root Drawer.

import {
  Drawer,
  DrawerTrigger,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription
} from "@/registry/core/drawer";

export default function DrawerExample() {
  return (
    <Drawer>
      <DrawerTrigger>Open Drawer</DrawerTrigger>
      <DrawerContent side="bottom">
        <DrawerHeader>
          <DrawerTitle>Options</DrawerTitle>
          <DrawerDescription>
            Manage your preferences here. Swipe down to close.
          </DrawerDescription>
        </DrawerHeader>
      </DrawerContent>
    </Drawer>
  );
}

Examples

Custom Sides

The side prop on DrawerContent allows you to control the entry point of the drawer. Options are top, right, bottom, and left. The drag handle and gesture axis automatically adapt to the chosen side.

Profile View

Use a drawer to display a quick profile overview or user details. The gesture-driven nature makes it feel like a native mobile app interaction.

Quick Settings

Drawers are excellent for quick settings or filters that users might want to tweak without leaving their current context.

Long Scrollable Content

Use DrawerBody for content that might exceed the screen height. The body will automatically scroll while keeping the header and footer fixed. The drag gesture intelligently handles the difference between scrolling the content and dragging the drawer itself.

API Reference

Drawer

The root component that manages the open/close state of the drawer.

PropTypeDefaultDescription
childrenReact.ReactNode-The trigger and content elements
isOpenboolean-Controlled open state
defaultOpenboolean-Uncontrolled default open state
onOpenChange(isOpen: boolean) => void-Called when the open state changes

DrawerTrigger

The element that opens the drawer when pressed.

PropTypeDefaultDescription
childrenReact.ReactNode-The trigger label or element
classNamestring-Additional CSS classes

DrawerContent

The primary layout component for the drawer panel. It handles the drag gestures, animations, and renders the drag handle automatically.

PropTypeDefaultDescription
sidetop | right | bottom | left"bottom"The edge of the screen the drawer slides from
childrenReact.ReactNode | (opts: { close: () => void }) => React.ReactNode-Content of the drawer. Supports render props for close() access
showCloseButtonbooleantrueWhether to show the default close button in the top-right
snapThresholdnumber-Threshold (in px) at which the drawer snaps closed. Defaults to 30% of viewport size
classNamestring-Additional CSS classes for the drawer panel

DrawerHeader

A wrapper for the title and description at the top of the drawer.

PropTypeDefaultDescription
childrenReact.ReactNode-Header content
classNamestring-Additional CSS classes

DrawerTitle

The accessible heading for the drawer.

PropTypeDefaultDescription
childrenReact.ReactNode-Title text
classNamestring-Additional CSS classes

DrawerDescription

Secondary text for the drawer header.

PropTypeDefaultDescription
childrenReact.ReactNode-Description text
classNamestring-Additional CSS classes

DrawerBody

A scrollable container for the main content of the drawer.

PropTypeDefaultDescription
childrenReact.ReactNode-Body content
classNamestring-Additional CSS classes

DrawerFooter

An action bar section at the bottom of the drawer.

PropTypeDefaultDescription
childrenReact.ReactNode-Footer content
showCloseButtonbooleanfalseWhether to render a built-in "Close" button
classNamestring-Additional CSS classes

DrawerClose

A specialized button that automatically closes the nearest drawer.

PropTypeDefaultDescription
childrenReact.ReactNode-The close button label/content
classNamestring-Additional CSS classes

Accessibility

  • Focus Management: Focus is automatically trapped inside the drawer when open and restored to the trigger element on close.
  • Keyboard Navigation: Pressing Escape or the close trigger closes the drawer.
  • ARIA Labeling: DrawerTitle uses slot="title" to provide an accessible label for the drawer component.
  • Screen Readers: The drawer is announced as a modal overlay, and background content is hidden from assistive technology when open.
  • Gestures: The drag-to-dismiss gesture provides an alternative, intuitive way to close the drawer, especially beneficial for touch users.