From 324e1c3c51235d365a771dd8234f3c6fbd131cf9 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Mon, 10 Aug 2026 01:45:13 -0300 Subject: [PATCH 1/3] =?UTF-8?q?feat(B184):=20omnibox=20mobile=20sem=20mold?= =?UTF-8?q?ura=20como=20padr=C3=A3o=20das=20listas=20(sticky=20no=20form,?= =?UTF-8?q?=20X=20de=20limpar=20no=20input,=20salvar=20filtro=20no=20heade?= =?UTF-8?q?r,=20cards=20edge-to-edge)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Chassis CampaignListOmnibox (B127): abaixo de md a label some (input carrega aria-label), o campo perde borda/sombra (md: restaura), o form do filtro vira barra sticky com linha separadora (sticky no form porque não escapa do containing block — a coluna do input dentro do wrapper curto não grudava), o texto Limpar vira X circular dentro do input (chips OU busca; slot sempre renderizado com invisible; hit target 44px; live region de limpeza), botão texto Limpar desktop-only. Padrão para as 11 listas via campaignListOmniboxFormClassName. - Municípios: Salvar filtro vira icon no header mobile (C94/C95 slot, presentation='icon', nome de rename = contrato 2.5.3); cards edge-to-edge com separador de linha (border-b last:border-b-0, -mx-4, gate md:). - Atualizações: Nova atualização vai para o header mobile (único trailing mobile-visible que grudaria na barra). - campaignMobileHeaderIconClassName compartilhada (3º consumidor). - E2E mobile novo (390x844) com pins: foco/aria-expanded após limpar, salvar -> renomear no header, cards, desktop invertido. - D7 registrado no caminho: sticky dos headers da tabela desktop morto. --- .../municipios-mobile-sem-moldura-impl.md | 92 +++++++++++++++++++ docs/plans/municipios-mobile-sem-moldura.md | 36 ++++---- docs/plans/sticky-tabela-desktop-quebrado.md | 44 +++++++++ .../campanha/(app)/municipios/page.tsx | 16 ++++ .../campaign/activity/ActivityFilters.tsx | 6 +- .../campaign/advisor/AdvisorFilters.tsx | 6 +- .../campaign/demand/DemandFilters.tsx | 6 +- .../campaign/leadership/LeadershipFilters.tsx | 6 +- .../municipality/CampaignUpdatesFilters.tsx | 26 +++++- .../municipality/MunicipalityFilters.tsx | 14 ++- .../MunicipalityListMobileCards.tsx | 11 ++- .../SaveMunicipalityFilterControl.tsx | 32 ++++++- .../municipality/TerritoryFilters.tsx | 6 +- .../organization/OrganizationFilters.tsx | 6 +- .../campaign/shared/CampaignListOmnibox.tsx | 90 +++++++++++++++++- .../campaign/shell/CampaignMobileTopBar.tsx | 9 ++ .../stateDeputy/StateDeputyFilters.tsx | 6 +- .../campaign/supporter/SupporterFilters.tsx | 6 +- tests/e2e/campaignMunicipalities.e2e.spec.ts | 87 ++++++++++++++++++ 19 files changed, 466 insertions(+), 39 deletions(-) create mode 100644 docs/plans/municipios-mobile-sem-moldura-impl.md create mode 100644 docs/plans/sticky-tabela-desktop-quebrado.md diff --git a/docs/plans/municipios-mobile-sem-moldura-impl.md b/docs/plans/municipios-mobile-sem-moldura-impl.md new file mode 100644 index 00000000..e50f047d --- /dev/null +++ b/docs/plans/municipios-mobile-sem-moldura-impl.md @@ -0,0 +1,92 @@ +# Impl: B184 — Omnibox mobile sem moldura (padrão de todas as listas) + cards edge-to-edge e salvar no header (municípios) + +Status: entregue em código (2026-08-09) +Atualizado em: 2026-08-10 +Issue: #514 +Intenção: docs/plans/municipios-mobile-sem-moldura.md +Appetite restante: ~0,5–1 dia eng (herdado; abordagem dentro do envelope) + +## Leitura da intenção + +- **Outcome:** no celular, o chrome do filtro de listas some: label oculta, omnibox sem moldura e sticky sob a barra superior com linha separadora, limpar vira X circular dentro do input (com chips **ou** busca digitada). **Escopo ampliado por decisão do humano (2026-08-09):** o look bare/sticky é o **padrão mobile do chassis `CampaignListOmnibox` — todas as listas `/campanha`**, não só municípios. Em municípios, adicionalmente: "Salvar filtro" vira icon button no header (mobile) e os cards ficam sem borda, edge-to-edge, separados por linha. +- **O que NÃO negociar:** desktop de todas as listas inalterado (label visível, box com borda, botão texto "Limpar", sem X); comportamento de filtragem (URL/navegação) intacto em todas as listas; chips continuam dentro da omnibox; fluxo do popover de salvar (nomear/renomear) intacto; cards edge-to-edge e salvar no header são municípios-only (outras listas não têm essa superfície/saved filters); sem dados/KPI novos. +- **O que reavaliar:** a hipótese da intenção escopava a municípios; a decisão do humano tornou o chassis o dono do padrão — prop opt-in morre, o look bare vira o default < `md` do chassis, e os 11 call sites mudam juntos. Cards e header continuam nos arquivos de municípios. + +## Abordagem recomendada + +```mermaid +flowchart LR + subgraph Chassis["CampaignListOmnibox (padrão < md, todos os 11 call sites)"] + L[Label: hidden md:block
input ganha aria-label={label} sempre] + B[Box: border-0 shadow-none md:border md:border-input md:shadow-xs] + S[Coluna do input: sticky top-0 z-20 -mx-4 border-b bg-background px-4 py-2
md:static md:mx-0 md:border-b-0 md:bg-transparent] + X["X circular no input: onClearAll && (chips || query)
aria-label='Limpar', md:hidden"] + C["'Limpar' texto: hidden md:inline-flex"] + end + subgraph Municipio["Municípios (adicional)"] + M2[SaveMunicipalityFilterControl no trailing: hidden md:inline-flex] + H1["page.tsx → SetCampaignHeaderAction → SaveMunicipalityFilterControl presentation='icon' + md:hidden"] + K1["Cards: gap-0 -mx-4 md:gap-4 md:mx-0; article border-b last:border-b-0 md:border md:rounded-xl"] + end + Chassis --> Municipio +``` + +**Opções consideradas:** + +- **A — Look bare como padrão do chassis (`CampaignListOmnibox`), sem prop.** Todos os 11 call sites herdam; desktop via variantes `md:`; nada muda nos adapters/URLs. +- **B — Prop opt-in `mobileBare` (plano anterior), só municípios.** +- **C — Cópia local do chassis para municípios.** + +**Recomendação:** A — a decisão do humano fez do look o padrão; prop opt-in viraria fricção para toda lista futura. O chassis é o dono do concern (B127) e não há divergência entre listas: todas passam `onClearAll`, todas limpam busca + filtros no `kind: 'clear'` (verificado em todos os 11 runActions), nenhuma tem trailing que precise ficar na região sticky (picker e ações ficam abaixo, fora da sticky, e as ações desktop-only já são `hidden md:flex`). Desktop continua 100% no comportamento atual via variantes `md:`. + +**Rejeitadas:** B porque o pedido agora é o padrão — cada lista futura teria que lembrar da prop; C porque duplica o contrato ARIA/combobox do chassis (o próprio plano da intenção proíbe "twin" do dono existente). + +### Componentes / mudanças + +- **`CampaignListOmnibox`** (`src/components/campaign/shared/CampaignListOmnibox.tsx`) — sem prop nova; abaixo de `md`: + - `label` → `hidden md:block` (o `