---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.43
secao: 17
titulo: "Toast — `estável` · validado pelo Rafael em 2026-08-04 (preview v0.15 + suite; teste de fogo do §1.13/1.13-b — aprovado)"
sequencia: 19 de 98
bytes_do_corpo: 6203
md5_do_corpo: a5480c745898744073feda63b97bda9d
gerado_por: 06-validacao/geradores/gen-camada-ia.py
nota: fatia GERADA — o corpo abaixo é byte a byte o trecho do canônico; edite o canônico, nunca esta fatia. Canônico inteiro em https://ds.seed.eng.br/01-canonicos/seed-componentes.md
---
## 17. Toast — `estável` · validado pelo Rafael em 2026-08-04 (preview v0.15 + suite; teste de fogo do §1.13/1.13-b — aprovado)

> **Base:** R1 — Carbon (5s, empilhamento, top-right), M1/M2/M3 oficiais (janela 4–10s, uma ação, acima da bottom-nav, "pode permanecer até o usuário agir"), NN/g (caso dos 5 minutos), EUI (10s, ação atual vs histórica), GitLab Pajamas. R2 — React Aria/Spectrum toast (landmark "Notificações", F6, foco restaurado, fila com prioridade), Radix (região + hotkey), Sonner/shadcn (+ auditoria WCAG 2026: 4s default viola 2.2.1), react-toastify (alt+t), Base Web (sem duração se houver ação), Angular Material, regra de leitura Byrne-Haber (5s+1s/120 palavras → mínimo aceitável 6s). R3 — WCAG 2.2.1 Timing Adjustable + 4.1.3, GitLab a11y issue (ação crítica dentro de role=status viola 2.2.1), SAP Fiori message toast (inferior-central), Ionic (swipe orientado pela posição, positionAnchor), bug documentado iOS (toast na base coberto pelo teclado), Mobbin (base = alcance do polegar), Baymard (confirmação só em label pequeno é perdida por subgrupo, especialmente mobile). Decisões Q1–Q7 conferidas pelo Rafael em 2026-08-04.

### 17.1 Papel e a régua de uso (Q1, emendado com Baymard)

Confirmação **efêmera e sobreposta** do desfecho da ação ATUAL (salvou, enviou, copiou). **O toast é o SEGUNDO sinal do desfecho; o primeiro é a própria UI refletindo o novo estado** (linha aparece na tabela, botão vira "salvo") — Baymard mediu usuários perdendo confirmações que existiam só como aviso pequeno. NUNCA: portador único de erro que exige ação (NN/g: usuária esperou 5 minutos por um erro que sumiu em 5s), erro de validação (é B4), informação histórica, saudação de sessão (EUI), marketing.

### 17.2 Decisões Q2–Q7

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| Q2 | Sucesso/informação = auto-dismiss; atenção = duração estendida; **erro = SEM auto-dismiss** (persiste até fechar). Erro em toast só para falha de operação assíncrona sem página-contexto (herda K2 e N4) | Auditoria shadcn: crítico = duration Infinity + dismissal manual; WCAG 2.2.1; M3: "pode permanecer até o usuário agir" | Erro auto-dismiss (perda de informação crítica) |
| Q3 | Duração: **8s default** (sucesso/informação) · **10s atenção** · erro persiste. Pausa em hover E em foco E com página oculta (`visibilitychange`); timer reinicia ao retomar | Janela oficial Material 4–10s; regra de leitura: mínimo aceitável 6s; 4s do Sonner reprova 2.2.1; EUI registrou como bug pausar só em mouseover sem foco | 4–5s (rápido demais); 10s fixo (atrasa a fila no uso denso do ERP) |
| Q4 | Máx. UMA ação; nunca "Fechar" como ação; nunca o único caminho para a função; **toast com ação não auto-dismissa**. Undo é o caso canônico | M3: uma ação, duas = dialog, snackbar nunca é o único acesso; Angular Material: sem duração quando há ação (AT precisa navegar até ela); GitLab: ação crítica em role=status viola 2.2.1 — a função existe na página sem limite | Ação com timer correndo |
| Q5 | Container = landmark `role="region"` + `aria-label="Notificações"`, alcançável por **F6** (atalho de foco); foco NUNCA roubado ao aparecer; ao fechar o último toast focado, foco RESTAURADO ao ponto anterior | React Aria (F6/Shift+F6 + restauração) e Radix (região rotulada + hotkey) convergem; sem landmark, usuário de teclado não alcança a ação antes do timeout | Toast fora de landmark; autofocus no toast |
| Q6 | Empilhamento: **máx. 3 visíveis**, mais novo no topo, excedente em FILA | Carbon (empilha, novo no topo) + React Aria (fila com limite); operações em lote do ERP perderiam confirmações no modelo um-por-vez | Material "um por vez" (descartado com porquê: lote ERP); ilimitado (avalanche) |
| Q7 | Posição: **desktop inferior-direita** · **mobile inferior-central**, acima de bottom-nav/teclado (offset via `visualViewport` + `--seed-safe-bottom`), swipe-para-baixo dismissa | EUI/GitLab: inferior-direita em produto denso (não cobre header/nav/cabeçalho de tabela — perfil dataviz SEED); Fiori: inferior-central; M2: acima da bottom-nav; Mobbin: base = polegar; bug iOS documentado do teclado motiva a regra do visualViewport (vira teste da suite); Ionic: swipe orientado pela posição | Top-right (Carbon — colide com a área de ações de página do ERP); top mobile (longe do polegar) |

### 17.3 ARIA e live region (o teste de fogo)

Segue T5 + nota 1.13-b: a REGIÃO (`role="region"`) existe no DOM desde o load; cada toast é inserido dentro dela já populado, com `role="status"` (sucesso/informação/atenção) ou `role="alert"` (erro) — valor sempre explícito (§2.6). `aria-atomic="true"` no toast. O botão fechar fica FORA do texto anunciado (aria-label próprio). Frase completa e específica nomeando o objeto ("Proposta #482 enviada", nunca "Sucesso").

### 17.4 Anatomia e tokens

Card 320–400px (mobile: `min(100vw - 32px, 400px)`) sobre `--seed-surface-overlay` + `--seed-shadow-overlay` (elevação de sobreposição, tokens v1.2 — no dark a borda sutil assume a separação); barra lateral 4px + ícone na severidade (T1/T3); texto `--seed-text-primary`; ação = botão ghost; fechar 44×44. Entrada/saída 160ms `--seed-ease-out`; `prefers-reduced-motion`: aparece/some seco. Gap de pilha 8px.

### 17.5 Microcopy

Passado para desfecho ("Proposta #482 enviada"), gerúndio para processo em andamento — regra herdada do Fluent, mas o toast de progresso ("Enviando…") fica DECIDIDO NO SUB-BLOCO B junto do progress (ponta solta declarada no consolidado). Sem "com sucesso" (implícito — EUI writing).

### 17.6 Os 7 testes

1. Card sobre página ≥3:1 pela borda/sombra (medir). 2. Severidade por cor + ícone + texto. 3. Grayscale: ícone + barra carregam. 4. Sucesso × erro a 1s (persistência + ícone). 5. Uma região para todos os toasts; um anúncio por toast. 6. Fila visível (contador "+2" quando há excedente). 7. 360px: inferior-central acima do teclado simulado; swipe; fechar 44px. *(Verificado: suite v0.15, aprovado.)*

---

