Overlays and modals

Drawer
v0.2.13
Ready for Production

A mobile-optimized bottom sheet component for product interfaces with full custom styling support. Built on Vaul with swipe gestures, scroll handling, and brand theming capabilities.

Prefer AI-assisted development?

This documentation is available via the Catalyst MCP Server. Learn how to connect →

Catalyst Drawer wraps Vaul with PMI design tokens and pre-styled subcomponents — giving you a production-ready mobile bottom sheet with swipe-to-dismiss, scroll handling, and accessible focus management out of the box.

Preview

Installation

npm install @pmi/catalyst-drawer
import {
  DrawerRoot,
  DrawerTrigger,
  DrawerPortal,
  DrawerOverlay,
  DrawerContent,
  DrawerHandle,
  DrawerClose,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
  DrawerFooter,
} from '@pmi/catalyst-drawer';

API Reference

Drawer is a compound component. The sections below summarize the API surface for each part.

DrawerRoot

Root container that manages open/closed state. Accepts all Vaul Drawer Root props.

DrawerTrigger

Element that opens the drawer. Accepts all Vaul Trigger props. Use asChild to render your own element:

DrawerPortal

Renders the drawer into a portal outside the current DOM tree. Accepts all Vaul Portal props.

DrawerOverlay

Semi-transparent backdrop behind the drawer. Forwards ref to HTMLDivElement. Accepts all Vaul Overlay props.

DrawerContent

Main content container. Forwards ref to HTMLDivElement. Accepts all Vaul Content props.

DrawerHandle

Visual drag handle for swipe gestures. Forwards ref to the underlying Vaul Handle element.

DrawerHeader

Container for DrawerTitle and DrawerDescription. Renders a div.

DrawerTitle

Heading for the drawer. Forwards ref to HTMLDivElement. Accepts all Vaul Title props.

DrawerDescription

Supporting description below the title. Forwards ref to HTMLDivElement. Accepts all Vaul Description props.

DrawerFooter

Container for action buttons at the bottom. Renders a div.

DrawerClose

Button to close the drawer. Accepts all Vaul Close props. Use asChild to render your own element.

Accessibility

Drawer is designed to meet WCAG 2.2 AA standards.

Keyboard Interactions

KeyAction
EscapeCloses the drawer

ARIA

  • aria-labelledby and aria-describedby are automatically wired between DrawerTitle/DrawerDescription and the drawer content region — inherited from Vaul.
  • Focus is trapped inside the drawer when open and restored to the trigger on close.
  • Always include a visible close affordance (e.g. DrawerClose with DrawerHandle) so keyboard and pointer users can dismiss the drawer.
  • Icon-only close buttons must have <span className="sr-only">Close</span> or aria-label for screen reader users.

See the WCAG Dialog Pattern for inherited baseline behavior.

Choosing the Right Component

Use Drawer for mobile bottom-sheet interactions. Reach for a different primitive when:

If you need…Use instead
A modal overlay that works on all screen sizesDialog
A side panel that slides in from the edgeSheet
A small contextual overlay anchored to a trigger elementPopover

On this page