Sheet

Overlay

Painel que desliza a partir de uma das quatro bordas da tela, para tarefas mais longas que um popover mas que não precisam de uma tela nova.

Carregando

Instalação

Recebe correções por update de versão. O caminho recomendado.

npm i @trdr/ui

import { Sheet } from "@trdr/ui/sheet"

Uso

import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader } from "@trdr/ui/sheet"

export function Exemplo() {
  return <Sheet />
}

Variantes

GrupoValoresPadrão
side
topbottomleftright
right

Props

SheetPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>
SheetTriggerPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>
SheetClosePropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>
SheetOverlayPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
SheetContentPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>, VariantProps<typeof sheetVariants>
PropTipoDescrição
showCloseButton?booleanMostra o botao "x" no canto superior direito. Default true.
SheetHeaderPropsestende React.HTMLAttributes<HTMLDivElement>
SheetFooterPropsestende React.HTMLAttributes<HTMLDivElement>
SheetTitlePropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
SheetDescriptionPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>

Quando usar

Use o sheet para uma tarefa secundaria com mais conteudo do que um popover comporta, mas que nao justifica sair da tela atual: ajustar os parametros de uma ordem, abrir um formulario de filtro complexo, mostrar detalhes de um item numa lista sem perder o contexto de onde o usuario estava. Ele e construido sobre o mesmo Dialog.* do Radix, entao herda foco preso, Escape e clique fora para fechar. Pense nele como o Dialog, so que ancorado numa borda em vez de centralizado.

Quando nao usar

Nao use sheet para confirmacao destrutiva: isso e o AlertDialog, que nao fecha ao clicar fora de proposito. Nao use em contexto de toque como a interacao principal (um app mobile, um breakpoint estreito): ali o gesto natural e arrastar para fechar, que e exatamente o que o Drawer oferece e o sheet nao. Um bom sinal de qual usar: se o dedo do usuario vai estar sobre o proprio painel a maior parte do tempo, e drawer; se a interacao e por ponteiro (clique, teclado), e sheet.

Anatomia

  • Sheet: a raiz, controla o estado aberto/fechado.
  • SheetTrigger (data-slot="sheet-trigger"): abre o painel. Use asChild para o filho virar o trigger.
  • SheetContent (data-slot="sheet-content"): o painel, dentro de um Portal, com o mesmo scrim e a mesma superficie (raio, borda, sombra) do Dialog. Aceita a prop side ("top", "right", "bottom", "left"), com "right" como padrao. O botao "x" no canto aparece por padrao; desligue com showCloseButton={false} quando o rodape ja tiver um botao de fechar explicito.
  • SheetHeader / SheetFooter: agrupam titulo/descricao e acoes, mesmo espacamento do Dialog.
  • SheetTitle / SheetDescription: mesma tipografia do Dialog, para os dois lerem como a mesma familia visual.
  • SheetClose: fecha o painel. Compoe com asChild e o Button do sistema para os botoes do rodape, do mesmo jeito que DialogClose.

Acessibilidade

Foco preso dentro do painel enquanto aberto, com o primeiro elemento focavel recebendo foco automatico. Escape fecha e devolve o foco ao trigger; clicar no overlay tambem fecha (diferente do AlertDialog). A entrada e saida usam as classes de animacao do tw-animate-css (data-[state=open]:slide-in-from-*, conforme o side) e respeitam motion-reduce pelas proprias utilidades do Tailwind.

Nota sobre o overlay

O design system nao tem um token dedicado para "fundo escurecido atras de modal" (a mesma lacuna documentada no Dialog). O sheet usa exatamente a mesma solucao: compor o token de fundo base bg-bg-primary com opacity-80, em vez de inventar um hex novo para essa familia de componentes.

Slots e tokens

Todo elemento renderizado carrega um data-slot para estilizar partes internas sem depender de classe da biblioteca. Os tokens listados são extraídos do código fonte.

[data-slot="sheet-close"][data-slot="sheet-content"][data-slot="sheet-description"][data-slot="sheet-footer"][data-slot="sheet-header"][data-slot="sheet-overlay"][data-slot="sheet-title"][data-slot="sheet-trigger"]
18 tokens usados
bg-bg-primarybg-cardborder-bborder-border-subtleborder-lborder-rborder-toutline-nonering-offset-2ring-offset-backgroundring-ringshadow-lgtext-b3text-card-foregroundtext-content-tertiarytext-foregroundtext-h5text-muted-foreground