Drawer
A versatile drawer component for slide-out panels and mobile-first interfaces. Perfect for navigation menus, forms, and contextual actions.
Looking for a sleek way to add slide-out panels to your app? Drawers provide an elegant solution for mobile navigation, forms, and actions that need space without cluttering your main interface.
Interactive drawer
A drawer with interactive content and smooth animations:
Built on Vaul by Emil Kowalski, this drawer component brings native-like interactions with gesture support, smooth animations, and accessibility features.
npx shadcn@latest add drawer
Why drawers enhance user experience
Drawers offer intuitive interactions that users expect:
- Mobile-first design - Natural gesture support for touch interfaces
- Space efficient - Maximize content area while keeping actions accessible
- Gesture friendly - Swipe to open, drag to close feels intuitive
- Smooth animations - Physics-based animations that respond to user input
- Multiple directions - Slide from bottom, top, left, or right as needed
- Backdrop control - Click outside to close or prevent accidental dismissal
- Keyboard accessible - Full keyboard navigation and screen reader support
- Responsive ready - Combine with dialogs for desktop/mobile experiences
Essential drawer patterns
Simple confirmation drawer
Quick actions and confirmations work great in drawers:
Responsive dialog-drawer
Smart component that adapts to screen size:
Controlled drawer state
Programmatically control drawer visibility:
Multiple directions
Drawers can slide from any edge of the screen:
Nested drawers
Layer drawers for complex workflows:
API Reference
Drawer
The root component that manages drawer state and behavior.
Prop | Type | Default | Description |
---|---|---|---|
open | boolean | false | Whether the drawer is open |
onOpenChange | (open: boolean) => void | - | Callback when open state changes |
defaultOpen | boolean | false | Default open state (uncontrolled) |
modal | boolean | true | Whether to render as modal with backdrop |
direction | "top" | "bottom" | "left" | "right" | "bottom" | Direction drawer slides from |
dismissible | boolean | true | Whether drawer can be dismissed by user |
shouldScaleBackground | boolean | true | Whether to scale background content |
snapPoints | number[] | - | Snap points for drawer height (0-1) |
activeSnapPoint | number | - | Currently active snap point |
setActiveSnapPoint | (snapPoint: number) => void | - | Set active snap point |
children | React.ReactNode | - | Drawer content components |
DrawerTrigger
Button or element that opens the drawer.
Prop | Type | Default | Description |
---|---|---|---|
asChild | boolean | false | Render as child element instead of button |
children | React.ReactNode | - | Trigger content |
DrawerContent
The main content area that slides in and out.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
children | React.ReactNode | - | Content to display in drawer |
DrawerHeader
Header section with title and description.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
children | React.ReactNode | - | Header content (typically title and description) |
DrawerTitle
Accessible title for the drawer.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
children | React.ReactNode | - | Title text |
DrawerDescription
Optional description for additional context.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
children | React.ReactNode | - | Description text |
DrawerFooter
Footer area for actions and controls.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
children | React.ReactNode | - | Footer content (typically buttons) |
DrawerClose
Button that closes the drawer.
Prop | Type | Default | Description |
---|---|---|---|
asChild | boolean | false | Render as child element instead of button |
children | React.ReactNode | - | Close button content |
Drawer Directions
Direction | Behavior | Best Use Cases |
---|---|---|
bottom | Slides up from bottom edge | Mobile forms, actions, confirmations |
top | Slides down from top edge | Notifications, secondary menus |
left | Slides in from left edge | Navigation menus, filters |
right | Slides in from right edge | Shopping carts, settings panels |
Gesture Controls
Gesture | Action |
---|---|
Tap trigger | Open drawer |
Drag handle | Move drawer position |
Swipe down | Close bottom drawer |
Swipe up | Close top drawer |
Swipe right | Close left drawer |
Swipe left | Close right drawer |
Tap backdrop | Close drawer (if dismissible) |
Escape key | Close drawer |
Keyboard Navigation
Key | Action |
---|---|
Escape | Close drawer |
Tab | Move to next focusable element |
Shift + Tab | Move to previous focusable element |
Space /Enter | Activate focused element |
Snap Points
Snap points allow drawers to stop at specific heights:
Value | Description |
---|---|
0.5 | Half screen height |
0.8 | 80% of screen height |
1.0 | Full screen height |
Best practices for drawers
Design drawers that feel natural and responsive:
- Clear purpose - Each drawer should have a focused, specific task
- Appropriate direction - Bottom for mobile actions, sides for navigation
- Proper sizing - Don't make drawers too small or overwhelmingly large
- Gesture support - Allow drag-to-dismiss where it makes sense
- Loading states - Show loading indicators for async content
- Responsive design - Consider dialog alternatives for desktop
- Focus management - Trap focus inside modal drawers
- Content scrolling - Handle overflow content gracefully
- Performance - Lazy load content for better perceived performance
Dialog
React dialog component with focus trapping, keyboard navigation, and animations. Perfect for forms, confirmations, and modals that need user attention.
Dropdown Menu
A versatile dropdown menu component for actions, navigation, and settings. Built on Radix UI with customizable positioning and rich interactions.