Drawer

Swipeable slide-in panel with snap points for mobile-friendly interactions

Preview

Installation

Usage

Examples

Directions

Open drawer from different screen edges.

Snap Points

Configure multiple snap points for the drawer to rest at different heights.

Pixel-Based Snap Points

Use pixel values for fixed snap heights that don't depend on content size.

Sequential Snap Points

Enable sequentialSnap to prevent skipping snap points during fast swipes.

Floating Variant

Use the floating variant for a more elevated, modal-like appearance with rounded corners and shadow.

Music Player

A music player demonstrating progressive disclosure with snap points: mini player, expanded controls, and full queue view.

Scrollable Content

Use DrawerBody for scrollable content that works seamlessly with swipe gestures.

With Form

Include form elements within the drawer.

Use the footerVariant="inset" prop on DrawerContent for a visually separated footer with a muted background and top border.

Add className="sticky bottom-0" to DrawerFooter to keep it fixed at the bottom of the viewport as you drag the drawer down.

Non-Modal

Control modal behavior with the modal prop. modal={false} allows full page interaction with no focus trapping. modal="trap-focus" keeps focus within the drawer while still allowing page interaction.

API Reference

The Drawer component is built on top of Base UI's Dialog. All Base UI props are supported. The documentation below only covers custom props specific to our implementation.

For the complete Base UI API, see the Base UI Dialog documentation.

Props

Drawer

Root component that manages drawer state and provides context to child components. Wraps Base UI's Dialog.Root.

Prop

DrawerContent

Main drawer container with swipe gesture handling and positioning. Composes Dialog.Portal, Dialog.Backdrop, Dialog.Viewport, and Dialog.Popup. Props are forwarded to Dialog.Popup.

Prop

DrawerBody

Scrollable content area with adaptive padding based on surrounding elements. Wraps ScrollArea.

Prop

DrawerHandle

Visual drag indicator that doubles as a close button. Automatically adjusts orientation based on drawer direction.

Prop

Components

ComponentDescription
DrawerRoot component that manages state and provides context
DrawerTriggerButton that opens the drawer
DrawerPortalRenders drawer content into a portal
DrawerContentMain content container with swipe gesture handling
DrawerHandleVisual drag indicator (automatically adjusts for direction)
DrawerHeaderContainer for title and description with adaptive padding
DrawerTitleAccessible title element
DrawerDescriptionAccessible description element
DrawerBodyScrollable content area with adaptive padding
DrawerFooterContainer for action buttons, supports inset variant via content
DrawerCloseButton that closes the drawer
useDrawerHook to access drawer context (direction, snap state, etc.)

Nested Scrollable Content

Use DrawerBody for scrollable content inside the drawer. The component handles overflow automatically and adapts its padding based on surrounding elements (header, footer).

Animating Content Based on Snap Position

The drawer exposes a --drawer-snap-progress CSS custom property that animates from 0 (first snap) to 1 (last snap) as the drawer moves between snap points. This works in all browsers:

  • Chrome 115+: GPU-accelerated CSS scroll-driven animation (no React re-renders)
  • Other browsers: JavaScript fallback sets the variable automatically

Using the CSS Variable

Use --drawer-snap-progress directly in your styles for crossfade effects:

Or with Tailwind's arbitrary value syntax:

Conditional Logic with Render Props

CSS variables work great for visual properties like opacity, but some properties like pointer-events need conditional logic. Use the render prop pattern for these:

Render Prop Values

ValueDescription
snapProgressProgress between snap points (0 = first snap, 1 = last snap)
dragProgressProgress toward closed (0 = open, 1 = closed)
isDraggingWhether currently being dragged/scrolled
activeSnapPointCurrent active snap point value