Drawer

The React Drawer component shows a panel that slides in from the edge of the screen. It supports drag gestures, so users can swipe to close it, especially on mobile devices.

It is useful for quick actions like settings, filters, or profile views without leaving the current page. For example, you can open a drawer from the bottom and swipe it down to close.

Built with React Aria, Framer Motion, and Tailwind CSS, it supports smooth animations, accessibility, and works well across different screen sizes.

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 stays inside the drawer when open and returns to the trigger when closed.
  • Keyboard support: Users can close the drawer using the Escape key or a close button.
  • Trigger behavior: The drawer opens via a trigger element and supports both mouse and keyboard interaction.
  • Screen reader support: The drawer is announced as a modal, and background content is hidden while it is open.
  • ARIA labeling: Use DrawerTitle and DrawerDescription to provide clear context for screen readers.
  • Gesture support: Users can close the drawer with drag or swipe gestures, improving usability on touch devices.