Sheet
Estende o componente Dialog para exibir conteúdo que complementa o conteúdo principal da tela.
"use client";
import { Button } from "@blips/ui/components/button";
import { Input } from "@blips/ui/components/input";
import { Label } from "@blips/ui/components/label";
import {
Sheet,
SheetBody,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@blips/ui/components/sheet";
export default function SheetDemo() {
return (
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Open</Button>
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're done.
</SheetDescription>
</SheetHeader>
<SheetBody>
<div className="grid gap-4">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="name" className="text-right">
Name
</Label>
<Input
id="name"
value="Pedro Duarte"
className="col-span-3"
readOnly
/>
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="username" className="text-right">
Username
</Label>
<Input
id="username"
value="@peduarte"
className="col-span-3"
readOnly
/>
</div>
</div>
</SheetBody>
<SheetFooter>
<SheetClose asChild>
<Button type="submit">Save changes</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
);
}
Instalação
Uso
import {
Sheet,
SheetBody,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetSection,
SheetSectionTitle,
SheetTitle,
SheetTrigger,
} from "@blips/ui/components/sheet"<Sheet>
<SheetTrigger>Abrir</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Você tem certeza absoluta?</SheetTitle>
<SheetDescription>Esta ação não pode ser desfeita.</SheetDescription>
</SheetHeader>
<SheetBody>{/* conteúdo */}</SheetBody>
</SheetContent>
</Sheet>O SheetContent não tem padding próprio: o SheetHeader e o SheetFooter já trazem o seu, e todo conteúdo entre eles deve ficar dentro de um SheetBody — é ele que dá o padding interno e o scroll. Não coloque conteúdo solto direto no SheetContent.
Exemplos
Lado
Use a prop side no SheetContent para definir a borda da tela onde o sheet aparece. Os valores são top, right, bottom ou left.
"use client";
import { Button } from "@blips/ui/components/button";
import { Input } from "@blips/ui/components/input";
import { Label } from "@blips/ui/components/label";
import {
Sheet,
SheetBody,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@blips/ui/components/sheet";
const SHEET_SIDES = ["top", "right", "bottom", "left"] as const;
export default function SheetSide() {
return (
<div className="grid grid-cols-2 gap-2">
{SHEET_SIDES.map((side) => (
<Sheet key={side}>
<SheetTrigger asChild>
<Button variant="outline">{side}</Button>
</SheetTrigger>
<SheetContent side={side}>
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>
Make changes to your profile here. Click save when you're
done.
</SheetDescription>
</SheetHeader>
<SheetBody>
<div className="grid gap-4">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="name" className="text-right">
Name
</Label>
<Input
id="name"
value="Pedro Duarte"
className="col-span-3"
/>
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="username" className="text-right">
Username
</Label>
<Input
id="username"
value="@peduarte"
className="col-span-3"
/>
</div>
</div>
</SheetBody>
<SheetFooter>
<SheetClose asChild>
<Button type="submit">Save changes</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
))}
</div>
);
}
Corpo rolável e seções
Use SheetBody para o corpo com scroll próprio (cabeçalho e rodapé ficam fixos) e SheetSection + SheetSectionTitle para agrupar o conteúdo em blocos separados por borda. Ao conter SheetSection, o SheetBody zera o próprio padding e cada seção controla o seu.
"use client";
import { Button } from "@blips/ui/components/button";
import { Input } from "@blips/ui/components/input";
import { Label } from "@blips/ui/components/label";
import {
Sheet,
SheetBody,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetSection,
SheetSectionTitle,
SheetTitle,
SheetTrigger,
} from "@blips/ui/components/sheet";
export default function SheetSections() {
return (
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">Editar empreendimento</Button>
</SheetTrigger>
<SheetContent className="sm:data-[side=right]:max-w-lg">
<SheetHeader>
<SheetTitle>Editar empreendimento</SheetTitle>
<SheetDescription>
Atualize as informações. O corpo rola; cabeçalho e rodapé ficam
fixos.
</SheetDescription>
</SheetHeader>
<SheetBody>
<SheetSection>
<SheetSectionTitle>Informações gerais</SheetSectionTitle>
<div className="grid gap-3">
<div className="grid gap-1.5">
<Label htmlFor="name">Nome</Label>
<Input id="name" defaultValue="Residencial Aurora" />
</div>
<div className="grid gap-1.5">
<Label htmlFor="cnpj">CNPJ</Label>
<Input id="cnpj" defaultValue="12.345.678/0001-90" />
</div>
</div>
</SheetSection>
<SheetSection>
<SheetSectionTitle>Endereço</SheetSectionTitle>
<div className="grid gap-3">
<div className="grid gap-1.5">
<Label htmlFor="street">Logradouro</Label>
<Input id="street" defaultValue="Av. Paulista, 1000" />
</div>
<div className="grid gap-1.5">
<Label htmlFor="city">Cidade</Label>
<Input id="city" defaultValue="São Paulo" />
</div>
</div>
</SheetSection>
<SheetSection>
<SheetSectionTitle>Observações</SheetSectionTitle>
<div className="grid gap-1.5">
<Label htmlFor="notes">Notas internas</Label>
<Input id="notes" placeholder="Opcional" />
</div>
</SheetSection>
</SheetBody>
<SheetFooter>
<SheetClose asChild>
<Button type="submit">Salvar alterações</Button>
</SheetClose>
<SheetClose asChild>
<Button variant="outline">Cancelar</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
);
}
Anatomia
<Sheet>
<SheetTrigger />
<SheetContent>
<SheetHeader>
<SheetTitle />
<SheetDescription />
</SheetHeader>
<SheetBody>
<SheetSection>
<SheetSectionTitle />
{/* conteúdo da seção */}
</SheetSection>
</SheetBody>
<SheetFooter />
</SheetContent>
</Sheet>Referência da API
A maior parte das props vem do Radix UI Dialog. Os componentes de layout abaixo são da @blips/ui.
SheetBody
Corpo rolável entre o cabeçalho e o rodapé — flex-1 overflow-auto p-4. Quando contém SheetSection, remove o próprio padding (has-data-[slot=sheet-section]:p-0) e delega o espaçamento às seções.
SheetSection
Bloco de conteúdo agrupado dentro do SheetBody — border-t p-4. Cada seção tem uma borda no topo, separando a primeira do cabeçalho e cada seção seguinte da anterior.
SheetSectionTitle
Rótulo de uma SheetSection — text-sm font-medium text-muted-foreground.