Drawer / sheet
Detalle al costado sin perder contexto (detalle de un equipo). En mobile, desde abajo.
Panel lateral usado por la app para editar conectores. El contenido ocupa todo el ancho en mobile y hasta 448 px en escritorio. El borde inferior es una variante disponible, no un flujo actual de la app.
Instalación
shadcn
npx shadcn@latest add https://design.moodinary.com/r/sheet.jsonimport
import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from "@moodinary/ui/components/sheet";Ejemplos
Conector a la derecha
Patrón del conector real: encabezado con estado, ajustes que scrollean y acciones abajo. Datos ilustrativos.
Código
team-detail.tsx
import { Button } from "@moodinary/ui/components/button";
import { Field, FieldHint, FieldLabel } from "@moodinary/ui/components/field";
import { Input } from "@moodinary/ui/components/input";
import {
Sheet,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@moodinary/ui/components/sheet";
export default function ConnectorSheet() {
return (
<Sheet>
<SheetTrigger render={<Button variant="secondary" />}>
Ver conector
</SheetTrigger>
<SheetContent className="flex w-full flex-col data-[side=right]:w-full sm:max-w-md">
<SheetHeader className="flex-row items-center gap-3 border-b">
<span
aria-hidden
className="grid size-10 shrink-0 place-items-center rounded-lg border bg-background"
>
↗
</span>
<div className="min-w-0">
<SheetTitle className="truncate">Avisos del equipo</SheetTitle>
<SheetDescription>Webhook · activo</SheetDescription>
</div>
</SheetHeader>
<div className="flex-1 space-y-6 overflow-y-auto p-4">
<section className="space-y-3">
<h3 className="font-medium text-sm">Ajustes</h3>
<Field>
<FieldLabel htmlFor="cn-name">Nombre</FieldLabel>
<Input defaultValue="Avisos del equipo" id="cn-name" />
</Field>
<Field>
<FieldLabel htmlFor="cn-url">URL</FieldLabel>
<Input
className="font-mono text-xs"
id="cn-url"
placeholder="https://ejemplo.com/eventos"
/>
<FieldHint>Dejalo vacío para mantener la actual.</FieldHint>
</Field>
</section>
<section className="space-y-2 border-t pt-4">
<h3 className="font-medium text-sm">Últimos envíos</h3>
<p className="text-muted-foreground text-sm">
Todavía no mandamos nada. Probalo para ver si llega.
</p>
</section>
</div>
<SheetFooter className="flex-row flex-wrap items-center gap-2 border-t">
<Button variant="primary">Guardar</Button>
<Button variant="outline">Probar</Button>
<Button variant="ghost">Pausar</Button>
<Button className="ml-auto" variant="link">
Eliminar
</Button>
</SheetFooter>
</SheetContent>
</Sheet>
);
}Drawer inferior
side="bottom" para acciones rápidas en pantallas chicas, como compartir un pulso.
Código
bottom.tsx
import { Button } from "@moodinary/ui/components/button";
import { CopyIcon } from "@moodinary/ui/components/icons";
import {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@moodinary/ui/components/sheet";
export default function SheetBottom() {
return (
<Sheet>
<SheetTrigger render={<Button variant="secondary" />}>
Abrir drawer inferior
</SheetTrigger>
<SheetContent
className="rounded-t-[14px]"
showCloseButton={false}
side="bottom"
>
<div
aria-hidden
className="mx-auto mt-2 h-1 w-9 rounded-full bg-line-2"
/>
<SheetHeader>
<SheetTitle>Compartir pulso</SheetTitle>
<SheetDescription>
Mostrá el QR al grupo o copiá el link.
</SheetDescription>
</SheetHeader>
<div className="flex gap-2 px-4 pb-6">
<SheetClose render={<Button />}>
<CopyIcon />
Copiar link
</SheetClose>
<SheetClose render={<Button variant="secondary" />}>
Cerrar
</SheetClose>
</div>
</SheetContent>
</Sheet>
);
}Props
SheetContent
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| side | "top" | "right" | "bottom" | "left" | "right" | Desde qué borde entra. |
| showCloseButton | boolean | true | Muestra la X arriba a la derecha. |
Sheet
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| open | boolean | - | Estado controlado. |
| onOpenChange | (open: boolean) => void | - | Se llama al abrir o cerrar. |
Cuándo sí y cuándo no
Hacé
- Usalo para detalles que se consultan y se cierran.
- Dejá las acciones abajo, siempre visibles.
- Abrilo desde abajo en mobile.
Evitá
- No lo uses para formularios largos; eso merece una página.
- No apiles dos sheets.
- No pongas datos de participantes individuales: los pulsos son anónimos.
Accesibilidad
- Esc cierra y el foco queda atrapado adentro.
- El foco vuelve al disparador al cerrar.
- El título tiene que describir qué se abrió.