Dialog

Overlay

Janela modal que interrompe o fluxo para uma decisão ou tarefa curta, com o fundo bloqueado atrás dela.

Carregando

Instalação

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

npm i @trdr/ui

import { Dialog } from "@trdr/ui/dialog"

Uso

import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader } from "@trdr/ui/dialog"

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

Props

DialogPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>
DialogTriggerPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>
DialogClosePropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>
DialogOverlayPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
DialogContentPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
PropTipoDescrição
showCloseButton?booleanMostra o botao "x" no canto superior direito. Default true.
DialogHeaderPropsestende React.HTMLAttributes<HTMLDivElement>
DialogFooterPropsestende React.HTMLAttributes<HTMLDivElement>
DialogTitlePropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
DialogDescriptionPropsestende React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>

Quando usar

Use o dialog quando a tarefa precisa da atencao total do usuario antes de continuar: confirmar uma acao destrutiva ou irreversivel (encerrar posicao, excluir uma ordem), coletar uma resposta curta e obrigatoria, ou apresentar um formulario pequeno que bloqueia o resto da tela ate ser resolvido. O fundo escurecido (scrim) e o foco preso dentro da janela avisam: "responda isto antes de voltar para o book".

Quando nao usar

Nao use dialog para informacao que nao exige decisao (isso e um Popover ou um Toast), nem para navegacao entre telas (isso e uma rota, nao um modal). Para paineis persistentes de ferramenta dentro do terminal, com abas e controles de janela, o componente certo e a Janela (em construcao em fase posterior), nao o Dialog: a Janela e um painel de aplicacao, o Dialog e uma interrupcao pontual que fecha sozinha. Evite tambem empilhar dialog sobre dialog: se a confirmacao gera outra confirmacao, o fluxo provavelmente precisa ser redesenhado.

Anatomia

  • Dialog (Root): contexto de estado aberto/fechado. Nao renderiza elemento.
  • DialogTrigger: o que abre o dialog. Normalmente asChild em cima de um Button.
  • DialogPortal: reexport direto do Radix, para compor overlays customizados fora do DialogContent padrao. O DialogContent ja se embrulha nele sozinho.
  • DialogOverlay (data-slot="dialog-overlay"): o scrim atras da janela. Ja vem embutido no DialogContent, normalmente nao precisa ser usado direto.
  • DialogContent (data-slot="dialog-content"): a janela em si, centralizada na tela, com foco preso dentro dela (focus trap) e um botao "x" no canto (controlavel pela prop showCloseButton, default true).
  • DialogHeader / DialogFooter: faixas de layout para titulo+descricao e para os botoes de acao, respectivamente.
  • DialogTitle / DialogDescription: texto acessivel do dialog. O Radix liga os dois automaticamente ao DialogContent via aria-labelledby/aria-describedby.
  • DialogClose: fecha o dialog. Sem estilo proprio, componha com asChild em cima de um Button para os botoes "Cancelar"/"Confirmar" do rodape.

Acessibilidade

O Radix marca o DialogContent com role="dialog" e aria-modal="true", prende o foco dentro dele (Tab e Shift+Tab nao escapam para o resto da pagina), fecha com Escape e devolve o foco ao elemento que abriu o dialog. Todo DialogContent precisa de um DialogTitle (mesmo que visualmente escondido com sr-only, nunca omitido: o axe cobra nome acessivel para role="dialog"). Quando o titulo sozinho nao basta para entender a decisao, adicione DialogDescription.

Nota sobre o scrim

O design system nao tem, hoje, um token dedicado a "fundo escurecido atras de overlay modal" (lacuna registrada). Existe um token chamado bg-overlay no @theme, mas o valor dele e um branco translucido (#FFFFFF29 no escuro), pensado para um realce de vidro sobre superficie escura, nao para escurecer o que esta atras de um modal: usar esse token aqui teria a polaridade errada. A solucao adotada foi compor o proprio token de fundo base do app, bg-bg-primary (quase preto no tema escuro), com a utilidade de opacidade do Tailwind, opacity-80, em vez de inventar um hex novo. Isso funciona bem no caso principal do produto (terminal escuro as tres da manha), mas herda a polaridade do token no tema claro: nesse tema bg-bg-primary fica quase branco, entao o scrim visualmente esmaece pouco o conteudo atras. Quando o design system ganhar um token de scrim invariante de tema, troque a classe do DialogOverlay por ele.

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="dialog-close"][data-slot="dialog-content"][data-slot="dialog-description"][data-slot="dialog-footer"][data-slot="dialog-header"][data-slot="dialog-overlay"][data-slot="dialog-title"][data-slot="dialog-trigger"]
14 tokens usados
bg-bg-primarybg-cardborder-border-subtleoutline-nonering-offset-2ring-offset-backgroundring-ringshadow-lgtext-b3text-card-foregroundtext-content-tertiarytext-foregroundtext-h5text-muted-foreground