Pular para o conteúdo
Faculdade PhorteDesign System

Modal

Em andamento

Janela sobre a página que pede atenção ou decisão: prende o foco dentro dela, torna o resto da página inert, trava a rolagem do fundo, fecha com Esc, com o X ou com clique fora (que se pode desligar) e devolve o foco a quem abriu. O título é obrigatório; role="alertdialog" para a confirmação que interrompe.

Função
Estado e aviso
Também chamado de
diálogo, janela, pop-up, modal, caixa de diálogo
Mora em
app/components/molecules/Modal.tsx
Última mudança
2026-10-01

Prévia

A peça ao vivo, vinda da ficha, na largura escolhida. Em larguras fixas, ela roda num quadro do tamanho de uma tela de verdade.

1280px, em tamanho real

Variante Aberto, ao vivo — vem da ficha.Abrir sozinha(abre em outra aba)

Variantes na ficha

Lidas da ficha no build, na ordem do palco. Cada uma abre sozinha, sem o styleguide em volta — é o endereço que o palco carrega.

  1. Aberto
  2. Interativo
  3. Foco inicial no primeiro campo
  4. Sem elemento focável
  5. Retorno de foco ao acionador
  6. Confirmação destrutiva

Quando usar

Para uma decisão ou um formulário curto que precisa ser resolvido antes de seguir — confirmar a matrícula, excluir algo.

Faça

  • Escreva um title que diga o que se decide ("Confirme sua matrícula").
  • Ponha as ações no footer, com a principal por último.
  • Deixe o botão de fechar (showCloseButton), a menos que a decisão seja obrigatória.
  • Use size pela quantidade de conteúdo: sm a xl, ou full.
  • Em confirmação destrutiva, role="alertdialog" e closeOnBackdrop={false}: um clique errado no fundo não decide por ninguém (E63).
  • Use a origem do onClose (botao, fundo, escape) quando o fechamento precisa de tratamento — perguntar antes de descartar um rascunho, por exemplo.

Evite

  • Modal dentro de modal — um de cada vez.
  • Fluxo de várias etapas dentro do diálogo: aí é página.
  • Tirar toda saída: sem X, o Esc e uma ação de cancelar continuam obrigatórios.
  • Abrir sem ação da pessoa (ao carregar a página).
  • Renderizar solto no styleguide: ele toma a página — por isso a prévia dele abre num documento próprio.

Quando não usar. Para uma mensagem que não pede ação, use o Alert. Para escolher entre ações, o Dropdown. Para conteúdo longo, uma página.

Nota de uso

Prende o foco, devolve-o a quem abriu e torna o resto da página inert. Como (corrigido na E63): o diálogo vai por portal direto ao <body>, e o inert cai em todos os irmãos dele — o fundo inteiro, sem precisar subir ancestrais; a nota antiga descrevia uma cadeia de ancestrais que o código não usa. Um de cada vez, sempre com saída explícita (Esc e uma ação de cancelar, mesmo sem o X), e nunca fluxo de várias etapas. role="alertdialog" e closeOnBackdrop={false} para confirmação destrutiva. A entrada — esmaece e cresce de 95% a 100% em 200ms — só anima com movimento liberado no sistema; até a E46 a classe vinha de um plugin nunca instalado e o painel aparecia seco. Desde a E113 essa mecânica mora em app/lib/dialogo-modal.ts, que a Gaveta também usa: uma cópia só, com os testes das duas peças travando.

Anatomia

As partes, na ordem em que o olho — e o teclado — passam.

  1. Fundo — Escurece a página a 60% com desfoque. É só desenho: o clique fora do painel fecha pelo documento — o fechamento leve do `<dialog>` nativo (E137) —, salvo com `closeOnBackdrop={false}`.
  2. Painel — `--card`, cantos `rounded-xl`, na largura do `size`.
  3. Cabeçalho — Título (`h2`), descrição opcional e o botão "Fechar" de 44×44.
  4. Conteúdo — O `children`, com rolagem própria quando passa da altura.
  5. Rodapé — O `footer`, com as ações.

Estados

Os estados que a peça tem no código, e o que muda em cada um.

Estados da peça e o que muda em cada um
EstadoO que muda
FechadoNada é renderizado.
AbertoPortal no <body>, role="dialog" com aria-modal, resto da página inert e rolagem travada. Entra esmaecendo e crescendo de 95% em 200ms, só com movimento liberado.
Sem nada focávelO foco vai ao próprio painel, e o Tab não sai dele — conferido no teste da ficha.
Alertarole="alertdialog": o leitor anuncia como alerta e lê a descrição junto (E63).

Comportamento

Como a peça reage em cada situação
SituaçãoO que acontece
AbreGuarda quem tinha o foco e leva o foco ao primeiro elemento do conteúdo, pulando o "Fechar" — conferido nos testes da ficha: "Voltar" num diálogo de confirmação, o primeiro campo num formulário.
FechaDevolve o foco a quem abriu — pelo Esc e pelo fundo, conferido no teste da ficha —, destrava a rolagem e tira o inert da página.
Clique no fundoChama onClose("fundo"); com closeOnBackdrop={false}, não fecha, e o foco fica onde estava, dentro do diálogo — conferido no teste da ficha. Até a medição da E63 esse clique mandava o foco ao <body>.
Esc ou XChama onClose("escape") ou onClose("botao") (E63).
Elemento escondido dentroFica fora da volta do Tab (o filtro descarta o que não tem offsetParent).

Relacionados