---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.43
secao: 53
titulo: "Filtro composto — `estável` (F7.2, 2026-08-15) · FC1–FC6 · fecha a lacuna C21"
sequencia: 55 de 98
bytes_do_corpo: 3239
md5_do_corpo: 40b54ddd6f8931bab340f52508cc4d57
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
---
## 53. Filtro composto — `estável` (F7.2, 2026-08-15) · FC1–FC6 · fecha a lacuna C21

> **Base (3 rodadas, 2026-08-15):** **R1/R2** — GitLab Pajamas (**3 a 5 dropdowns** é o teto do
> filtro simples; acima disso, *filter builder*) · a régua de mercado da **escalada progressiva**
> (filtros simples por padrão; o construtor só para quem precisa — forçar todo mundo pela gramática
> completa é o erro clássico) · Airtable/FT/Yahoo (sobreposição que cresce na vertical, uma
> condição por linha) · a estrutura que funciona é **árvore (AST) com indentação visual no lugar
> dos parênteses**, não CNF/DNF de dois níveis fixos. **R3** — `fieldset`/`legend` como agrupamento
> nativo de controles relacionados; grupo de rádios para operador exclusivo.

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| FC1 | **Dois regimes, com escalada explícita:** o regime SIMPLES é o §42 (chips + popover por dimensão, teto de 5 dimensões); o regime COMPOSTO só aparece quando o usuário pede | O construtor é a ferramenta certa para poucos e a errada para todos; e o §42 já resolve 90% dos casos com um clique | Substituir o §42 pelo construtor · esconder o construtor (quem precisa não acha) |
| FC2 | **Profundidade máxima 2** (grupo raiz + um subgrupo) | Além disso a condição deixa de ser legível como frase, e o custo de manter a AST na cabeça passa a ser do usuário. A gramática que resta é **texto** — fronteira de produto | Profundidade livre (o resumo em linguagem natural fica impossível) |
| FC3 | **Cada grupo é `fieldset` + `legend`; o operador é um `radiogroup`** com dois rádios (Todas = E · Qualquer = OU), e o operador aparece **uma vez por grupo**, nunca repetido entre linhas | O agrupamento fica exposto à AT sem ARIA; e "E" repetido em cada linha é o padrão que faz o usuário achar que pode misturar E e OU no mesmo nível | Operador por condição (produz expressão ambígua) · `select` de dois itens (mais cliques, menos visível) |
| FC4 | **A indentação visual substitui os parênteses**, com fio de 3px na cor da marca marcando o subgrupo | É como a estrutura é lida em qualquer editor de código; parênteses em UI viram erro de digitação | Mostrar a expressão com parênteses (transfere sintaxe ao usuário) |
| FC5 | **Resumo em linguagem natural com "N de M"**, sempre visível — inclusive com o painel recolhido | O contador é a prova de que o filtro fez algo (§42/TD1); e o resumo é o que permite conferir a lógica sem reabrir o construtor | Só o número · só a expressão (ilegível para quem não escreveu) |
| FC6 | **Fronteiras:** sintaxe textual de consulta, filtros salvos e filtro por coluna em texto livre = **produto**; campos de condição são de input restrito (select, data, número) | Herdado do TD5 — texto livre por dimensão produz filtro que ninguém consegue depurar | Query language no DS |

**Estado vazio próprio:** filtro composto que não casa nada tem vazio **com a saída dentro do
texto** — qual operador trocar, qual condição remover. Vazio genérico ("nenhum resultado") deixa o
usuário sem caminho de volta. *(Guardas: `suite-container.mjs`, FC-01…FC-03.)*

---

