Skip to main content

Drawer

A panel that slides in from the edge of the screen to display supplementary content.

1'use client';
2
3import { Button } from '@/components/ui/button';
4import { Drawer } from '@/components/ui/drawer';
5
6export 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>
16
17 <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>
28
29 <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';
2
3import { Drawer } from '@/components/ui/drawer';
4
5const DRAWER_SIDES = ['top', 'right', 'bottom', 'left'] as const;
6
7export 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';
2
3import { Drawer } from '@/components/ui/drawer';
4import { Input } from '@/components/ui/input';
5import { Label } from '@/components/ui/label';
6
7export 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&apos;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 Name
22 </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 Username
28 </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

PropTypeDefaultDescription
childrenReactNode-Drawer trigger and content
defaultOpenbooleanfalseInitial open state
openboolean-Controlled open state
onOpenChange(open: boolean) => void-Callback when open changes

Drawer.Trigger

PropTypeDefaultDescription
childrenReactNode-Trigger button content
classNamestring-Additional CSS classes
variantButtonProps['variant']-Button variant
sizeButtonProps['size']-Button size

Drawer.Content

PropTypeDefaultDescription
side'bottom' | 'top' | 'left' | 'right''bottom'Side to slide from
showDragHandlebooleantrueShow drag handle for closing
classNamestring-Additional CSS classes

Drawer.Header

PropTypeDefaultDescription
classNamestring-Additional CSS classes

Drawer.Title

PropTypeDefaultDescription
classNamestring-Additional CSS classes

Drawer.Description

PropTypeDefaultDescription
classNamestring-Additional CSS classes

Drawer.Close

PropTypeDefaultDescription
childrenReactNode-Clickable content