Skip to content

A11y/Feedback: nenhum toast é anunciado — os 12 erros do produto ("Sala não encontrada", "Sem conexão") são mudos para leitor de tela e distinguidos só por cor (Toast.tsx:22-41) (§VII.4) #129

Open

Description

@caioross

Contexto

docs/UI-AAA-OVERHAUL.md §VII.4, bloco Respeito ao usuário (binário): "WCAG AA". O canal de
feedback do produto inteiro é mudo para leitor de tela.

Verificado em origin/main@31c1c2d: o ToastProvider renderiza a pilha num <div className="fixed bottom-4 right-4 ..."> (Toast.tsx:22) sem aria-live e sem role. Um nó
que aparece no DOM sem região live não é anunciado — nenhum dos avisos do produto chega a quem
não olha para o canto inferior direito da tela.

São 15 push em 4 componentes de produção (HomeView 8 · RoomView 3 · Lobby 2 ·
Results 2), 12 deles kind: "error". Entre os mudos estão exatamente os que travam o
jogador na porta de entrada:

  • "Sala não encontrada" (HomeView.tsx:158)
  • "Partida em andamento, aguarda terminar" (HomeView.tsx:163)
  • "Sem conexão com o servidor" (HomeView.tsx:168)

O fluxo real: o jogador cola o código, aperta Enter (HomeView.tsx:351), nada acontece do
ponto de vista dele — a página não muda, o input não muda, e o único sinal de que a sala não
existe some sozinho em 3,5s (Toast.tsx:17).

Segundo defeito no mesmo componente: o único diferenciador entre info, success e error é a
cor da borda e do texto (Toast.tsx:32-36). Sem ícone, sem prefixo, sem texto. WCAG 1.4.1
(uso de cor) — vale também para daltônicos, que enxergam o toast e não sabem se é confirmação ou
erro.

Acceptance criteria

  1. Existem duas regiões live permanentes no DOM (montadas com o provider, mesmo sem nenhum
    toast): uma role="status" / aria-live="polite" para info e success, outra role="alert"
    / aria-live="assertive" para error. Duas regiões porque o role de um nó não pode mudar
    dinamicamente e ainda ser anunciado de forma confiável.
  2. O texto do toast entra numa região que já existia no DOM — criar a região junto com a
    mensagem não é anunciado de forma confiável em NVDA/VoiceOver.
  3. Cada toast carrega um indicador não-cromático do kind: ícone + rótulo textual (visível ou
    sr-only, ex.: "Erro: Sala não encontrada"). A cor deixa de ser o único canal.
  4. O mapeamento kind → { role, ariaLive, prefixo } é uma função pura exportada e coberta por
    teste (segue o padrão dos src/lib/*.test.ts, vitest em node env).
  5. Nenhum toast é anunciado duas vezes (cuidado com o nó duplicado se optar por região sr-only
    espelhando o visual).
  6. Gate verde: pnpm typecheck · pnpm test · pnpm build.

Dica de abordagem

  • Sem dependência nova (§7.3). O caminho mais curto: aplicar os atributos direto nos wrappers em
    Toast.tsx:22 — dois <div> irmãos sempre montados (um polite, um assertive), cada um com seu
    AnimatePresence filtrando os toasts do seu grupo.
  • Se preferir uma região sr-only separada do visual, cuide da duplicação: o texto visível
    também é lido no modo de navegação; prefira aria-hidden no visual ou não duplique.
  • AnimatePresence mantém o nó durante a saída (Toast.tsx:23); o anúncio acontece na entrada e
    isso é o que importa — não tente ligar anúncio à remoção.
  • Ponha o helper puro em src/lib/ (ex.: toastA11y.ts) para o AC 4 sair barato. Não adicione
    @testing-library/react: o projeto não tem, e dep nova é §7.2.
  • Verificação: dá para provar por DOM, não por interação — read_page no Browser pane devolve
    a árvore de acessibilidade, e javascript_tool confirma os atributos. Não dependa de
    computer{key} (não entrega keydown).

Escopo

§7.3 (UI/componentes). Não toca API, banco, engine nem a área sagrada. Fora de escopo
deliberado:
o setTimeout fixo de 3500ms (Toast.tsx:17) fere WCAG 2.2.1 (controle de tempo) —
pausar/estender no hover e no foco é uma fatia própria, fica para outra rodada para esta caber numa
só. prefers-reduced-motion é a #108.

Activity

  1. added
    P2Prioridade normal
    area:uiInterface, design system, animação, game feel
    on Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Prioridade normalarea:uiInterface, design system, animação, game feel

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions