Remove CampaignBottomNav and getCampaignBottomNav — mobile navigation is now sidebar-only (Sheet via SidebarTrigger). Drop the pb-24 padding that reserved space for the fixed bar; scroll uses symmetric p-4 on mobile. Impeccable: N/A (shell chrome removal, class B per plan). Plan: docs/plans/remover-bottom-nav-mobile.md
9.6 KiB
Remover bottom navigation bar no mobile
Status: entregue (2026-07-30)
Atualizado em: 2026-07-29
Item do roadmap: docs/roadmap.md (Trilha B — B73; chassis UX-1)
Impeccable: B — encaixe no shell (app); remove chrome, não cria rota nova
Appetite: ~0,25–0,5d eng; remover componente + ajustar padding do scroll + atualizar testes; sem migration
Responsável: —
Design (Impeccable)
Âncoras: PRODUCT.md (register product — clareza sob pressão; UX-1 ação-primeiro) / DESIGN.md (hybrid mobile top bar Mandate Red + sidebar Sheet) · tema data-theme='campaign'.
Na implementação (implement-roadmap-item): craft compacto → critique → polish (só chrome do shell).
Brief compacto:
- Persona / contexto: CG/assessor no celular — o ritual diário passa pelo Início (ações + busca); listas densas são visita ocasional, não navegação por domínio.
- Job principal: recuperar altura útil do viewport e deixar um único caminho de navegação secundária (sidebar via
SidebarTriggerno header vermelho). - Estratégia de cor: Restrained — remove barra fixa; header mobile existente permanece.
- Edit where you see: não — só chrome.
- Anti-goals: segunda barra de atalhos; reinventar drawer fora do
Sidebar; mover destinos para tabs no Início; exigir sidebar aberta por padrão no mobile.
Dados → decisão → apresentação
Dados: N/A — remoção de chrome de navegação; nenhuma métrica/série/mapa.
Contexto
O shell de /campanha monta hoje duas superfícies de navegação no mobile (<md):
- Header vermelho com
SidebarTrigger→CampaignSidebarem Sheet (collapsible="offcanvas"noCampaignSidebar, B38 ✓). CampaignBottomNavfixa (src/components/campaign/shell/CampaignBottomNav.tsx) com até 5 destinos derivados degetCampaignBottomNavemnav.ts— subconjunto destaffNav/leaderNav(exclui Quadro, Territórios, Apoiadores, Assessores).
O scroll global reserva espaço com pb-24 em src/app/(campaign)/campanha/(app)/layout.tsx para não cobrir conteúdo com a bottom bar. O chassis UX-1 (B43–B47 ✓, B65 ✓) ancorou busca + strip de ações acima dessa barra.
Decisão de produto (2026-07-29): o paradigma deixou de ser “navegar por domínio” (Início / Municípios / Lideranças / … na barra inferior) e passou a ser intenção (ações do Início, busca, wizards). A bottom bar só consome ~48–56 px + safe-area sem servir ao ritual diário. A navegação ocasional para listas de alto volume permanece no sidebar (fechado por padrão no mobile via CampaignSidebarViewportDefault quando não há cookie sidebar_state).
Evidência alinhada: fluxos-acao-primeiro-inicio.md — anti-goal “depender de sidebar para o ritual diário”; a barra inferior era o espelho mobile do modelo domínio-primeiro.
Objetivos
- Em viewport <
md: não renderizarCampaignBottomNav; navegação secundária só viaSidebarTrigger+ Sheet. - Remover o padding inferior artificial (
pb-24) docampaign-content-scrollno mobile — substituir por padding normal (p-4/pb-4ou equivalente) com safe-area só onde necessário (toasts/PWA, não nav fantasma). - Revalidar o dock do Início (B65 ✓): com a barra sumida, o grupo strip+busca pode usar o limite inferior real do scrollport; medir se o spacer
flex-1ainda precisa de ajuste. - Sidebar mobile continua fechada por padrão (
CampaignSidebarViewportDefault+ cookie) — sem mudar o default tablet/desktop (B38 ✓). - Apagar código morto:
CampaignBottomNav.tsx,getCampaignBottomNav, exports órfãos;pnpm exec kniplimpo. - Guardrails: sem migration, sem collection, sem Consent, sem server action;
print:hiddenpreservado; leader/staffgetCampaignNavintactos.
Decisões travadas
- Remover a bottom bar por completo — não esvaziar nem reduzir ícones. O produto não quer atalhos de domínio no mobile; busca + ações cobrem o caminho frequente. Rejeitado: manter 2–3 ícones (ainda compete com thumb zone); mover Municípios/Lideranças para tabs no Início (segundo sistema de nav); PWA shortcut bar nativa (fora de escopo).
- Sidebar como única navegação estrutural no mobile. O
SidebarTriggerno header vermelho já existe; não adicionar segundo gatilho flutuante. Rejeitado: FAB “Menu”; gesto edge-only sem affordance; abrir sidebar por padrão no mobile (contradiz B38 + campo com uma mão). - Apagar
getCampaignBottomNavcom o componente. Não deixar helper “para o dia em que redesenharmos a barra” — git history é o arquivo. Testes que citavam a barra passam a assertar sógetCampaignNav+getCampaignSecondaryNav. Rejeitado: deprecar com@deprecated(knip/CI bloqueia export morto). - Ajustar
pb-24no mesmo PR. O padding existia só pela altura da barra; mantê-lo após remoção devolve gap morto e contradiz B65. Rejeitado:pb-24“por segurança” sem medir (o dock do Início pode precisar depbmenor local, não global). - i18n e naming seguem o AGENTS.md: identificadores em inglês (
CampaignBottomNavdeletado; layout classes em inglês); copy visível em pt-BR no sidebar (aria-labeldo trigger já existe).
Questões em aberto
- Reduzir
pbglobal ou só revalidar o Início? Opções: A) trocarpb-24→pb-4no scroll global | B) manterpb-24nas outras rotas e só no Início usar dock | C)pbproporcional a safe-area apenas. Recomendação: A no layout global — a barra era a única razão do 24; listas longas ganham área útil; se alguma rota com FAB/toast colidir, corrigir pontualmente. (assumido — validar no craft com device real)
Abordagem proposta
flowchart TD
layout["(app)/layout.tsx"] --> scroll["campaign-content-scroll"]
layout --> header["header mobile + SidebarTrigger"]
layout --> sidebar["CampaignSidebar Sheet"]
layout -.remove.-> bottom["CampaignBottomNav DELETED"]
scroll --> pages["rotas /campanha/*"]
home["Início B65 dock"] --> scroll
Componentes:
src/app/(campaign)/campanha/(app)/layout.tsx: remover import/render deCampaignBottomNav; ajustarclassNamedo scroll (pb-24→pb-4oup-4simétrico no mobile); confirmar queSidebarTriggerno header mobile permanece.- Deletar
src/components/campaign/shell/CampaignBottomNav.tsx. src/components/campaign/shell/nav.ts: removergetCampaignBottomNave o comentário do cap de 5 itens; mantergetCampaignNav/getCampaignSecondaryNav/MUNICIPALITY_NAV_HREF.src/components/campaign/shell/CampaignSidebarViewportDefault.tsx: sem mudança de comportamento (já fecha sidebar <1024 sem cookie) — só verificar que mobile continua com default fechado.- Início (
CampaignHomeLayout/CampaignHomeStaffChrome): smoke visual após remoção da barra — o dock pode colar mais baixo; ajustar spacer se sobrar gap >~8 px (herança do B65). tests/unit/campaignIntelligenceConcepts.unit.spec.ts: teste “stays out of … mobile bottom bar” → assertar queCAMPAIGN_CONCEPTS_PATHnão está emgetCampaignNav(bottom bar deixa de existir).- E2E smoke: navegar via sidebar no mobile viewport — abrir Sheet, ir a Municípios, voltar (nenhum
nav[aria-label="Navegação principal"]no DOM). - Sem migration, sem collection, sem server action.
Dependências
- B43 ✓ (Início ação-primeiro) — decisão de paradigma; sem ela a barra ainda faria sentido como atalho de domínio.
- B65 ✓ (soft) — o dock foi desenhado acima da bottom nav; este item revisita o padding/âncora, não bloqueia o merge.
- B38 ✓ (soft) — sidebar Sheet + default fechado no mobile/tablet sem cookie.
- Nenhuma dependência dura de item pendente.
Não escopo
- Redesenhar itens do
staffNav/ reordenar sidebar — só remover a projeção mobile de 5 ícones. - Atalhos de domínio no Início (busca B48+ e ações B45 ✓ já cobrem).
- Mudar bottom nav em design-refs HTML legados (
docs/design-refs/latest/*.htmlcompb-24estático) — artefatos UX Pilot, não runtime. - PWA install banner /
InstallPwaToast— inalterados.
Rabbit holes
- Reintroduzir navegação por gestos sem affordance. Se alguém “só documentar” que o usuário deve arrastar: sem
SidebarTriggervisível, a descoberta cai. Mitigação: manter trigger no header; e2e cobre o caminho. - Padding inferior em cascata. Copiar
pb-24para o dock do Início “por precaução” recria o bug que este item remove. Mitigação: um únicopbno scroll global; ajuste local só com medição.
Adiado com gatilho
- Atalho “recentes” na sidebar (visitados) para compensar menos um toque na bottom bar. Revisitar quando: métrica de sessão mostrar >3 aberturas de sidebar só para repetir os mesmos 2 destinos — hoje busca + ações cobrem.
Referências
docs/roadmap.md(UX-1, B73)src/app/(campaign)/campanha/(app)/layout.tsx— montagem do shell epb-24src/components/campaign/shell/CampaignBottomNav.tsx— alvo de remoçãosrc/components/campaign/shell/nav.ts—getCampaignBottomNavsrc/components/campaign/shell/CampaignSidebarViewportDefault.tsx— default fechado mobiledocs/plans/ancorar-busca-acoes-inicio-mobile.md— decisões que citavam a bottom nav (contexto histórico B65)docs/plans/fluxos-acao-primeiro-inicio.md— anti-goal sidebar no ritual diáriodocs/plans/sidebar-recolhido-tablet.md— B38, mobile Sheet inalteradoPRODUCT.md— princípios 2 e 3 (clareza sob pressão; edit where you see)- AGENTS.md — Campaign auth shell; knip mata órfãos no mesmo PR