Modal
Mantém uma tarefa curta e reversível em foco sem retirar a pessoa do contexto atual.
Design
Anatomia
Review changes 4
Check the details before applying this update.
The update can be reverted later from the activity log.
6.ds-modal-overlay) — backdrop em tela cheia que bloqueia interação com a página.2 Container (
.ds-modal) — superfície elevada com border-radius e sombra.3 Header (
.ds-modal__header) — contém heading opcional, descrição e button de fechar.4 Título (
.ds-modal__title) — vinculado via aria-labelledby.5 Button de fechar (
.ds-modal__close) — dispensa o modal.6 Corpo (
.ds-modal__body) — área de conteúdo com scroll.7 Rodape (
.ds-modal__footer) — buttons de ação alinhados a direita.
Exemplo interativo · React · shadcn/Base UI
Executado pela recipe React distribuída via shadcn e baseada em Base UI.
Tamanhos · React · shadcn/Base UI
Três dialogs independentes executados pela recipe shadcn com primitives Base UI.
Body customizado · React · shadcn/Base UI
Field, Input e Button da própria saída React compostos dentro do Dialog.
Mapeamento de tokens
| Propriedade | Token | Variável CSS |
|---|---|---|
| overlay background | component.modal.overlay.bg.default | --ds-modal-overlay-bg-default |
| surface | semantic.surface.elevated | --ds-surface-elevated |
| overlay padding | component.modal.overlay.padding.default | --ds-modal-overlay-padding-default |
| overlay z-index | component.modal.overlay.z-index.default | --ds-modal-overlay-z-index-default |
| border-radius | component.modal.radius.default | --ds-modal-radius-default |
| shadow | component.modal.shadow.default | --ds-modal-shadow-default |
| max-width | component.modal.max-width.{sm,md,lg} | --ds-modal-max-width-* |
| header spacing | component.modal.header.{padding-*,gap}.* | --ds-modal-header-*-* |
| body spacing/typography | component.modal.body.{padding-*,font-size,line-height,font-weight}.* | --ds-modal-body-*-* |
| description typography | component.modal.body.{font-size,line-height,font-weight}.* | --ds-modal-body-*-* |
| title typography | component.modal.title.{font-size,line-height,font-weight,letter-spacing}.* | --ds-modal-title-*-* |
| footer spacing | component.modal.footer.{padding-*,gap}.* | --ds-modal-footer-*-* |
| close target | component.modal.close.size.{sm,md,lg} | --ds-modal-close-size-* |
| close icon | component.modal.close.icon-size.{sm,md,lg} | --ds-modal-close-icon-size-* |
| close padding | component.modal.close.padding.{sm,md,lg} | --ds-modal-close-padding-* |
Uso
Quando usar
- Uma edição curta ou revisão precisa terminar antes de retornar ao contexto anterior.
- O conteúdo exige atenção concentrada, mas ainda não justifica uma página dedicada.
Quando não usar
- A tarefa é longa, possui várias etapas ou precisa continuar visível junto da página.
- A confirmação é destrutiva ou crítica; esse caso pertence ao contrato separado de Alert Dialog.
Composição React
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
<Dialog>
<DialogTrigger render={<Button type="button" />}>Abrir modal</DialogTrigger>
<DialogContent closeLabel="Fechar modal">
<DialogHeader>
<DialogTitle>Revisar alterações</DialogTitle>
<DialogDescription>Confirme antes de continuar.</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>Implementação
- Status
- Beta
- Distribuição
- Source via shadcn
Instalação
Configure o namespace uma única vez na integração React.
npx shadcn@latest add @tis/dialog @tis/buttonpnpm dlx shadcn@latest add @tis/dialog @tis/buttonyarn dlx shadcn@latest add @tis/dialog @tis/buttonbunx --bun shadcn@latest add @tis/dialog @tis/buttonContrato público
- Item do registry
@tis/dialog- Provider
- Base UI
- Distribuição
- Source copiado para a aplicação
- Status
- Beta
Acessibilidade
Interação por teclado
| Tecla | Ação |
|---|---|
Tab | Cicla o foco dentro do modal (focus trap) |
Shift+Tab | Cicla o foco para tras dentro do modal |
Escape | Fecha o modal |
Enter | Ativa o button focado |
O foco deve ser preso dentro do modal enquanto estiver aberto. Quando o modal fechar, o foco deve retornar ao elemento que o disparou.
Accessibility
| Critério WCAG | Requisito | Status |
|---|---|---|
| 2.4.3 Focus Order (A) | O foco move para dentro do modal ao abrir, fica preso dentro e retorna ao trigger ao fechar | ✓ |
| 2.4.11 Focus Appearance (AA) | Focus ring visível em todos os elementos interativos dentro do modal | ✓ |
| 4.1.2 Name, Role, Value (A) | role="dialog", aria-modal="true", aria-labelledby apontando para o título | ✓ |
| 1.4.11 Non-text Contrast (AA) | Button de fechar tem pelo menos 3:1 de ratio de contraste contra a superfície do modal | ✓ |
role="dialog" — identifica o modal como um diálogo.aria-modal="true" — informa a tecnologia assistiva que o conteúdo atras do modal esta inerte.aria-labelledby — referencia o id do elemento de título do modal.aria-label="Close modal" — obrigatorio no button de fechar.
Responsabilidade da saída
Preserve a semântica da Base UI e teste conteúdo real, foco visível e nomes acessíveis na aplicação consumidora.
Evidência de validação
Coberta pelo Storybook da saída independente e por verificações de browser, responsividade, teclado, Axe e bundle.