Componentes
50. Agrupamento de linhas
seed-componentes.md v1.43 · §50seção 52 de 9850-agrupamento-de-linhas-estavel-f7-2-2026-08-15.md · MD5 c0037b88Título completo no canon: Agrupamento de linhas — estável (F7.2, 2026-08-15) · AG1–AG8 · gabarito A2
Base (3 rodadas, 2026-08-15): R1 canon — Fiori (agrupamento existe nas tabelas responsiva e analítica, com formato de cabeçalho de grupo declarável; a régua de personalização é por número de colunas, ~20) · Polaris IndexTable (subheaders com props de acessibilidade próprias) · Oracle OTM (seleção pelo cabeçalho de grupo abrange o grupo inteiro) · HTML nativo (
<tbody>como rowgroup,th scope="rowgroup"/"colgroup"). R2 stack — TanStackgroupingcomgroupedColumnMode: 'reorder' | 'remove'. R3 normas — MDNrowrole (aria-expandedem linha pertence ao padrão grid/treegrid, não à tabela estática) · Adrian Roselli, "Table with Expando Rows" (o padrão funciona em<table>nativa: disclosure<button>comaria-expanded,display:table-row×none, linhas reveladas DEPOIS do controle na ordem do código,aria-controlsopcional — JAWS retirou o anúncio em 2019) · APG treegrid ("o código deste exemplo não é para produção") + Roselli (treegrid é widget composto, suporte pobre, "não vi em produção") · JAWS 2024 issue #791 (tabela aninhada não navega em JAWS + Chrome/Edge; NVDA navega).
| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| AG1 | Um <tbody> por grupo — rowgroup NATIVO. O cabeçalho de grupo é uma <tr> com um único <th colspan scope="colgroup"> |
A semântica de agrupamento já existe no HTML; ARIA nova aqui seria "bad ARIA" sobre estrutura que o browser já expõe | <div role="rowgroup"> (recria o que é nativo) · tabela dentro de tabela (JAWS 2024 não navega — #791) |
| AG2 | O disclosure é um <button aria-expanded> DENTRO do cabeçalho de grupo — nunca aria-expanded na <tr> |
aria-expanded na linha empurra a tabela para o padrão grid/treegrid (MDN), e o DT1 proíbe grid na v1. O botão é disclosure puro, padrão com suporte universal |
role="treegrid" (APG: não é para produção; suporte pobre) · linha inteira clicável (anti-padrão do DT1) |
| AG3 | Nome acessível do disclosure = rótulo + contagem ("Metalúrgica Andrade, 3 faturas"), e o estado vem do aria-expanded — nunca do texto |
Roselli: o leitor de tela não anuncia quantas linhas apareceram; a contagem no nome administra a expectativa antes do clique | Nome só com o rótulo (o usuário expande às cegas) · anunciar "expandido/recolhido" no texto (duplica o que a AT já diz) |
| AG4 | As linhas do grupo vêm DEPOIS do controle na ordem do código, e o par de visibilidade é display:table-row × display:none |
display:block numa <tr> destrói a semântica de linha (Roselli, Tables, CSS Display Properties, and ARIA); e linha revelada acima do controle deixa o usuário de AT sem saber onde ela apareceu |
visibility:hidden (ocupa espaço) · hidden no atributo (mesma coisa, mas some da guarda CSS) |
| AG5 | aria-controls é OPCIONAL e declarado como tal — presente aqui, com a nota de que JAWS retirou o anúncio em 2019 e sua ausência não cria barreira |
Manter a relação declarada custa nada e serve se o suporte voltar; prometer que ela funciona hoje seria falso | Depender de aria-controls para a navegação funcionar |
| AG6 | Contador junto ao rótulo (C26), com o ZERO EXPLÍCITO — 0 aparece, não some |
Zero é informação: "este grupo existe e está vazio" é diferente de "este grupo não existe". Medição do produto de referência: eles mostram NOVO CLIENTE 0 |
Esconder o contador no zero (o usuário passa a duvidar se o grupo sumiu) |
| AG7 | Grupo de contagem zero revela o vazio de escala mínima (Z3) — uma linha "Nenhum item neste grupo", nunca o nada |
Botão que não revela nada é botão morto — o mesmo defeito que o §25 já proíbe em preview, aqui em produção | Disclosure desabilitado (esconde a razão) · grupo zero oculto (contradiz o AG6) |
| AG8 | Um nível de agrupamento na v1. Subgrupo entra por demanda, com pesquisa própria | <tbody> não aninha, e a saída seria tabela dentro de tabela — que reprova em JAWS (#791). A profundidade que o ERP pede hoje é 1 |
Agrupamento em árvore dentro da tabela (é outro arquétipo: treegrid, descartado no AG2) |
Seleção dentro do grupo: ver a extensão do §41 (SL6). Pares de cor: todos herdados —
cabeçalho de grupo em surface-subtle com text-primary (12,63 claro / 14,02 escuro),
contador em text-muted (5,61 / 6,80), subtotal em text-secondary (7,13 / 9,10).
(Instrumento: contraste-f72.py; comportamento: suite-container.mjs, guardas AG-01…AG-08.)
Também cita o §50: tela-lista.