default.tsx
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}
Instalación
pnpm dlx nachui add drawer
Anatomía
1import { Drawer } from '@/components/ui/drawer';
1<Drawer>2 <Drawer.Trigger>3 <Button>Abrir Drawer</Button>4 </Drawer.Trigger>5 <Drawer.Content>6 <Drawer.Header>7 <Drawer.Title>Título del Drawer</Drawer.Title>8 <Drawer.Description>Este es un componente drawer.</Drawer.Description>9 </Drawer.Header>10 <div>Tu contenido aquí</div>11 </Drawer.Content>12</Drawer>
Características
- Múltiples lados - Desliza desde abajo, arriba, izquierda o derecha
- Arrastrar para cerrar - Desliza para descartar en cualquier dirección
- Responsivo - Se adapta a diferentes tamaños de pantalla
- Animaciones suaves - Transiciones de deslizamiento basadas en resorte
- Trampa de foco - La navegación por teclado se mantiene dentro del drawer
- Bloqueo de scroll - Evita el desplazamiento del fondo cuando está abierto
Variantes
Posiciones (Positions)
positions.tsx
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}
Formulario (Form)
form.tsx
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}
Referencia de API
Drawer
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
children | ReactNode | - | Activador y contenido del drawer |
defaultOpen | boolean | false | Estado abierto inicial |
open | boolean | - | Estado abierto controlado |
onOpenChange | (open: boolean) => void | - | Callback cuando cambia el estado |
Drawer.Trigger
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
children | ReactNode | - | Contenido del botón activador |
className | string | - | Clases CSS adicionales |
variant | ButtonProps['variant'] | - | Variante del botón |
size | ButtonProps['size'] | - | Tamaño del botón |
Drawer.Content
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
side | 'bottom' | 'top' | 'left' | 'right' | 'bottom' | Lado desde el que deslizar |
showDragHandle | boolean | true | Mostrar asa de arrastre para cerrar |
className | string | - | Clases CSS adicionales |
Drawer.Header
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
className | string | - | Clases CSS adicionales |
Drawer.Title
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
className | string | - | Clases CSS adicionales |
Drawer.Description
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
className | string | - | Clases CSS adicionales |
Drawer.Close
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
children | ReactNode | - | Contenido clicable |