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 · HTML/CSS/JS
Executado pelo runtime JavaScript estável ds-tis/modal.
Tamanhos · HTML/CSS/JS
Três dialogs independentes executados pelo runtime HTML/CSS/JavaScript estável.
Body customizado · HTML/CSS/JS
Form Field, Input e Buttons públicos compostos dentro do runtime Web.
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.
Implementação
- Status
- Estável
- Distribuição
- Pacote npm
Instalação
npm install ds-tispnpm add ds-tisyarn add ds-tisbun add ds-tisImportações
import 'ds-tis/css'
import { initModals } from 'ds-tis/modal'
initModals()Markup
<button type="button" data-ds-modal-open="review-modal">Revisar alterações</button>
<div class="ds-modal-overlay" id="review-modal" hidden>
<div class="ds-modal ds-modal--md" role="dialog" aria-modal="true" aria-labelledby="review-title">
<div class="ds-modal__header">
<h2 class="ds-modal__title" id="review-title">Revisar alterações</h2>
<button class="ds-modal__close" type="button" aria-label="Fechar modal">…</button>
</div>
<div class="ds-modal__body">Confira os dados antes de continuar.</div>
</div>
</div>Contrato da implementação Web
Runtime obrigatório
O CSS define anatomia e estados visuais, mas o contrato acessível do Modal — focus trap, Escape, inert no backdrop e retorno de foco — depende do módulo público ds-tis/modal (initModals / destroyModals). Eventos: ds-modal-open, ds-modal-close. Ao usar Modal interativamente, inicializar o runtime é parte da API; chame destroyModals ao desmontar.
Classes CSS
| Classe | Descrição |
|---|---|
ds-modal-overlay | Overlay backdrop em tela cheia |
ds-modal | Container do diálogo modal |
ds-modal--sm | Tamanho pequeno (--ds-modal-max-width-sm) |
ds-modal--md | Tamanho médio (--ds-modal-max-width-md) |
ds-modal--lg | Tamanho grande (--ds-modal-max-width-lg) |
ds-modal__header | Área de header com título e button de fechar |
ds-modal__heading | Wrapper opcional de título e descrição |
ds-modal__title | Texto do título do modal |
ds-modal__description | Texto descritivo opcional do header |
ds-modal__close | Button de fechar no header; o elemento representa o alvo interativo, não apenas o ícone |
ds-modal__body | Área de conteúdo do corpo com scroll |
ds-modal__footer | Área de rodapé para buttons de ação |
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
Inicialize o runtime público após o render e destrua-o quando a view responsável for desmontada.
Evidência de validação
Coberta pelo Storybook estável, testes do runtime público quando aplicável, cenários de teclado, responsividade e Axe.