1'use client';23import { Button } from '@/components/ui/button';4import { Drawer } from '@/components/ui/drawer';56export function Default() {7 return (8 <Drawer>9 <Drawer.Trigger variant="outline">Open Drawer</Drawer.Trigger>10 <Drawer.Content side="right">11 <div className="flex flex-col gap-4">12 <h2 className="text-lg font-semibold">Notifications</h2>13 <p className="text-muted-foreground text-sm">14 You have 3 new messages and 1 system alert. Review them below.15 </p>1617 <div className="space-y-2 text-sm">18 <div className="bg-accent/10 rounded-md border p-3">19 <strong>Message from Jane:</strong> Your report is ready for download.20 </div>21 <div className="bg-accent/10 rounded-md border p-3">22 <strong>System Alert:</strong> Scheduled maintenance at 3:00 AM UTC.23 </div>24 <div className="bg-accent/10 rounded-md border p-3">25 <strong>Message from John:</strong> Please review the updated project plan.26 </div>27 </div>2829 <div className="mt-4 flex justify-end gap-2">30 <Drawer.Close>Dismiss All</Drawer.Close>31 <Button>View Details</Button>32 </div>33 </div>34 </Drawer.Content>35 </Drawer>36 );37}
Installation
pnpm dlx mateui add drawer
Anatomy
1import { Drawer } from '@/components/ui/drawer';
1<Drawer>2 <Drawer.Trigger>3 <Button>Open Drawer</Button>4 </Drawer.Trigger>5 <Drawer.Content>6 <Drawer.Header>7 <Drawer.Title>Drawer Title</Drawer.Title>8 <Drawer.Description>This is a drawer component.</Drawer.Description>9 </Drawer.Header>10 <div>Your content here</div>11 </Drawer.Content>12</Drawer>
Features
- Multiple sides - Slide from bottom, top, left, or right
- Drag to close - Swipe to dismiss in any direction
- Responsive - Adapts to different screen sizes
- Smooth animations - Spring-based slide transitions
- Focus trap - Keyboard navigation stays within the drawer
- Body scroll lock - Prevents background scrolling when open
Variants
Positions
1'use client';23import { Drawer } from '@/components/ui/drawer';45const DRAWER_SIDES = ['top', 'right', 'bottom', 'left'] as const;67export function Positions() {8 return (9 <div className="grid grid-cols-2 gap-4">10 {DRAWER_SIDES.map((side) => (11 <Drawer key={side}>12 <Drawer.Trigger className="w-full capitalize" variant="outline">13 {side}14 </Drawer.Trigger>15 <Drawer.Content side={side}>16 <Drawer.Header>17 <Drawer.Title>Edit profile</Drawer.Title>18 <Drawer.Description>19 Make changes to your profile here. Click save when you're done.20 </Drawer.Description>21 </Drawer.Header>22 <div className="py-4">23 <p className="text-muted-foreground text-sm">24 This drawer is appearing from the {side}.25 </p>26 </div>27 <div className="flex justify-end">28 <Drawer.Close>Save changes</Drawer.Close>29 </div>30 </Drawer.Content>31 </Drawer>32 ))}33 </div>34 );35}
Form
1'use client';23import { Drawer } from '@/components/ui/drawer';4import { Input } from '@/components/ui/input';5import { Label } from '@/components/ui/label';67export function Form() {8 return (9 <Drawer>10 <Drawer.Trigger variant="outline">Edit Profile</Drawer.Trigger>11 <Drawer.Content side="bottom">12 <Drawer.Header>13 <Drawer.Title>Edit profile</Drawer.Title>14 <Drawer.Description>15 Make changes to your profile here. Click save when you're done.16 </Drawer.Description>17 </Drawer.Header>18 <div className="grid gap-4 py-4">19 <div className="grid grid-cols-4 items-center gap-4">20 <Label htmlFor="name" className="text-right">21 Name22 </Label>23 <Input id="name" defaultValue="Ignacio Figueroa" className="col-span-3" />24 </div>25 <div className="grid grid-cols-4 items-center gap-4">26 <Label htmlFor="username" className="text-right">27 Username28 </Label>29 <Input id="username" defaultValue="@figueroaignacio" className="col-span-3" />30 </div>31 </div>32 <div className="flex justify-end">33 <Drawer.Close>Save changes</Drawer.Close>34 </div>35 </Drawer.Content>36 </Drawer>37 );38}
API Reference
Drawer
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | - | Drawer trigger and content |
defaultOpen | boolean | false | Initial open state |
open | boolean | - | Controlled open state |
onOpenChange | (open: boolean) => void | - | Callback when open changes |
Drawer.Trigger
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | - | Trigger button content |
className | string | - | Additional CSS classes |
variant | ButtonProps['variant'] | - | Button variant |
size | ButtonProps['size'] | - | Button size |
Drawer.Content
| Prop | Type | Default | Description |
|---|---|---|---|
side | 'bottom' | 'top' | 'left' | 'right' | 'bottom' | Side to slide from |
showDragHandle | boolean | true | Show drag handle for closing |
className | string | - | Additional CSS classes |
Drawer.Header
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
Drawer.Title
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
Drawer.Description
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
Drawer.Close
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | - | Clickable content |