Blips
Documentação

Sheet

Estende o componente Dialog para exibir conteúdo que complementa o conteúdo principal da tela.

Carregando…
"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

pnpm add @blips/ui

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.

Carregando…
"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&apos;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.

Carregando…
"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.

PropTipoPadrão
classNamestring-

SheetSection

Bloco de conteúdo agrupado dentro do SheetBodyborder-t p-4. Cada seção tem uma borda no topo, separando a primeira do cabeçalho e cada seção seguinte da anterior.

PropTipoPadrão
classNamestring-

SheetSectionTitle

Rótulo de uma SheetSectiontext-sm font-medium text-muted-foreground.

PropTipoPadrão
classNamestring-