Capítulo 44 de 108

Dialog

Core Idea

Janela sobreposta à janela principal (ou outro dialog), tornando o conteúdo por trás inerte. Uso padrão pra formulários modais e confirmações. Built on Base UI Dialog.

Key Concepts

  • DialogTrigger: aceita render={<Button variant="outline" />} para customizar o elemento que dispara o dialog (padrão Base UI de "render prop").
  • DialogContent: painel do modal; showCloseButton={false} remove o X padrão do canto superior direito.
  • DialogHeader / DialogTitle / DialogDescription: bloco de cabeçalho semântico.
  • DialogFooter: área de ações, geralmente com DialogClose + botão de submit.
  • DialogClose: fecha o dialog; também aceita render={<Button ... />} pra reaproveitar estilos de Button.

Code Examples

<Dialog>
  <DialogTrigger render={<Button variant="outline" />}>Open</DialogTrigger>
  <DialogContent className="sm:max-w-sm">
    <DialogHeader>
      <DialogTitle>Edit profile</DialogTitle>
      <DialogDescription>Make changes to your profile here.</DialogDescription>
    </DialogHeader>
    <DialogFooter>
      <DialogClose render={<Button variant="outline" />}>Cancel</DialogClose>
      <Button type="submit">Save changes</Button>
    </DialogFooter>
  </DialogContent>
</Dialog>
  • O que demonstra: estrutura padrão trigger + header + footer com render prop pra estilizar trigger/close como Button.
<DialogContent>
  <DialogHeader>...</DialogHeader>
  <div className="-mx-4 no-scrollbar max-h-[50vh] overflow-y-auto px-4">
    {/* conteúdo longo */}
  </div>
  <DialogFooter>...</DialogFooter>
</DialogContent>
  • O que demonstra: padrão de conteúdo rolável com footer fixo (sticky), usando max-h-[50vh] overflow-y-auto numa div interna em vez de rolar o DialogContent inteiro.

Reference Tables

Composição:

Dialog
├── DialogTrigger
└── DialogContent
    ├── DialogHeader
    │   ├── DialogTitle
    │   └── DialogDescription
    └── DialogFooter

Anti-patterns

  • Omitir DialogDescription: quebra acessibilidade (o Base UI espera título+descrição associados via aria).
  • Rolar o DialogContent inteiro para conteúdo longo: perde o header fixo; usar uma div interna com overflow-y-auto e max-h.

Key Takeaways

  1. render={<Button .../>} é o padrão do Base UI pra "vestir" trigger/close com outro componente sem quebrar a semântica do elemento original.
  2. showCloseButton={false} em DialogContent remove o X, útil quando o fechamento é só via DialogClose customizado no footer.
  3. Para scroll interno com header/footer fixos, envolver o conteúdo numa div com max-h-[50vh] overflow-y-auto, não o DialogContent todo.
  4. Instalação manual requer npm install @base-ui/react.
  5. Field/FieldGroup (de @/components/ui/field) é o padrão recomendado para formulários dentro do dialog.

Connects To

  • Alert Dialog: variante para confirmações destrutivas que não podem ser fechadas clicando fora.
  • Sheet: alternativa de painel lateral (não centralizado) para o mesmo padrão de overlay.
  • Field / Input / Label: compõem formulários dentro do DialogContent.