Dialog
Janela modal que interrompe o fluxo para uma decisão ou tarefa curta, com o fundo bloqueado atrás dela.
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>| Prop | Tipo | Descrição |
|---|---|---|
| showCloseButton? | boolean | Mostra 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. NormalmenteasChildem cima de umButton.DialogPortal: reexport direto do Radix, para compor overlays customizados fora doDialogContentpadrao. ODialogContentja se embrulha nele sozinho.DialogOverlay(data-slot="dialog-overlay"): o scrim atras da janela. Ja vem embutido noDialogContent, 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 propshowCloseButton, defaulttrue).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 aoDialogContentviaaria-labelledby/aria-describedby.DialogClose: fecha o dialog. Sem estilo proprio, componha comasChildem cima de umButtonpara 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