teqo-backup/docs/plans/bottom-drawer-handle-scroll-peek.md

8.3 KiB
Raw Permalink Blame History

Bottom drawer — handle, gesto, scroll, peek discreto, labels 2 linhas

Status: implementado (PR) Atualizado em: 2026-08-01 Issue: #132 Priority: P1 Model: cursor-grok-4.5-medium Impeccable: C — chrome CampaignQuickActionsDrawer (comportamento + geometria) Appetite: ~1–1,5d eng; snap/gesto/scroll + peek busca + altura labels; sem migration Responsável: —

Design (Impeccable)

Âncoras: PRODUCT.md (thumb zone; Feel the action) / DESIGN.md · B79/B91/B100 · Base UI Drawer snap · tema campaign.

Na implementação (work-issue): craft compacto → critique → polish (viewport ~390; detalhe município; scroll real).

Brief compacto:

  • Persona / contexto: CG/assessor no celular fora do Início; uma mão; alterna ler a página e disparar ação/busca.
  • Job principal: (1) handle no topo do sheet; (2) puxar para baixo fecha/recolhe; (3) scroll página ↓ fecha, ↑ abre; (4) collapsed ainda mostra busca sem placeholder; (5) títulos das ações com 2 linhas visíveis.
  • Estratégia de cor: Restrained.
  • Edit where you see: não — launchers.
  • Anti-goals: scrim modal; FAB; bottom nav; redesenhar catálogos B80–B90; absorver crash da busca (→ B102 primeiro ou em paralelo sem bloquear geometria).

Wireframe (texto)

Dock (aberto):

┌─ página ───────────────────────────────────────┐
│ conteúdo                                       │
├─ drawer ───────────────────────────────────────┤
│ ═ handle (TOPO)                                │
│ [○][○][○]…  labels em 2 linhas visíveis        │
│ ┌ Buscar na campanha (placeholder ok) ───────┐ │
│ └────────────────────────────────────────────┘ │
└────────────────────────────────────────────────┘

Collapsed (fechado / após scroll ↓):

┌─ página (mais conteúdo) ───────────────────────┐
│ …                                              │
├────────────────────────────────────────────────┤
│ ═ handle                                       │
│ ┌ (input sem placeholder — discreto) ────────┐ │
│ └────────────────────────────────────────────┘ │
└────────────────────────────────────────────────┘

Gesto: drag handle/sheet ↓ → collapsed; scroll content ↓ → collapsed; scroll content ↑ → dock.

Dados → decisão → apresentação

Dados: N/A — chrome; hits = B48+ via provider existente.

Contexto

B100 ✓ (#114) definiu dock no load + collapse no scroll para baixo + reopen só tap/pull (explicitamente sem reopen no scroll-up). Follow-up a056616d reordenou o DOM para o handle ficar em baixo (“snap shows bottom band”) — produto agora rejeita: handle deve voltar ao topo; puxar ↓ deve recolher; scroll ↑ deve abrir. Collapsed deve manter a barra de busca visível sem placeholder. Labels line-clamp-2 existem no botão, mas dock 12rem + overflow-hidden + handle embaixo cortam a 2ª linha.

Objetivos

  • Handle no topo do DrawerContent (reverter ordem do a056616d); banda visível do snap mostra handle → ações → busca.
  • Swipe/drag para baixo no drawer recolhe para collapsed (Base UI swipeDirection="down" + snap; validar que não fica “só tap”).
  • Scroll do campaign-content-scroll: ↓ além do limiar → collapsed; ↑ (delta ou scrollTop caindo / direção) → dock. Não reabrir se busca uiFocused (assumido).
  • Collapsed: renderiza input de busca visível, placeholder="" (ou omitido); sem strip de ações (ou strip hidden). Tap no input / focus → dock + focus.
  • Altura do dock / overflow: 2ª linha dos labels visível (subir QUICK_ACTIONS_SNAP_DOCK e/ou overflow-y-auto na região de ações; tirar clip que come line-clamp-2).
  • Load / navegação: estado inicial = dock (B100).
  • Pins: unit direção scroll; e2e mobile handle no topo + collapse swipe se estável.
  • Sem migration / Consent.
  • Tracer: load dock → scroll ↓ collapsed (busca sem placeholder) → scroll ↑ dock → labels 2 linhas no viewport.

Decisões travadas

  • Supersede B100 no reopen por scroll-up e no collapsed “só handle”. Fonte: produto 2026-08-01. Rejeitado: manter “reopen só tap” (B100); collapsed só handle sem busca.
  • Handle no topo — reverter o DOM order do a056616d. Se a geometria do snap exigir padding-bottom Base UI, aplicar sem mover o handle para baixo. Rejeitado: handle embaixo como “fix” de banda visível.
  • Collapsed = handle + busca discreta (sem placeholder); ações hidden. Rejeitado: collapsed = só handle (B100); esconder busca no collapsed.
  • Scroll-up reabre com limiar de direção (delta ↑ ≥ N px) ou scrollTop caindo abaixo do limiar — craft escolhe o mais estável; pin no unit. Rejeitado: hysteresis multi-eixo complexa neste item.
  • i18n: ids dock/collapsed; aria pt-BR; placeholder vazio no collapsed (label sr-only permanece).

Questões em aberto

  • Limiar scroll-up para abrir? Opções: A) espelhar 24 px de delta ↑ | B) scrollTop < 24 (só perto do topo). Recomendação: A (simétrico ao collapse). ✅ travado em craft (quickActionsScrollDirection).
  • Focus no input collapsed: expande para dock automaticamente? Opções: A) sim | B) só digitar. Recomendação: A. ✅ travado em craft (uiFocused → dock).

Abordagem proposta

flowchart TB
  Scroll["campaign-content-scroll"] -->|delta down| Collapsed
  Scroll -->|delta up| Dock
  Handle["handle TOP"] -->|swipe down| Collapsed
  Collapsed --> SearchPeek["search no placeholder"]
  Dock --> Strip["actions 2-line labels"]
  Dock --> SearchFull["search + placeholder"]

Componentes:

  • CampaignQuickActionsDrawer.tsx: ordem handle → context; collapsed mostra CampaignHomeSearch (ou slot) sem placeholder; dock mostra strip + search completa; overflow/altura.
  • CampaignQuickActionsHost.tsx / snap context: listener de scroll com direção (↑/↓); respeitar uiFocused.
  • campaignQuickActionSnap.ts: recalibrar QUICK_ACTIONS_SNAP_COLLAPSED / DOCK para caber handle+busca (collapsed) e strip 2 linhas+busca (dock).
  • CampaignHomeSearch / CampaignSearchInput: prop opcional placeholder / discreet para collapsed.
  • E2e / unit atualizar expectativas B100 (scroll-up agora reabre; collapsed tem busca).
  • Migration: Sem migration.

Dependências

  • Soft: B100 ✓, B91 ✓. Soft: B101 (bleed/gap da strip — pode pousar junto). Soft: B102 (crash) — se o crash bloquear teste manual da busca no drawer, priorizar B102.
  • Nenhuma dura de Issue aberta.

Não escopo

  • Crash focus/type → B102.
  • Gap/padding dos botões → B101.
  • Título “Sugestões” → B103.
  • Catálogos de ações por rota.

Rabbit holes

  • Terceiro snap “expanded” para resultados. Mitigação: Adiado; resultados rolam no dock ou a página.
  • position: fixed caseiro no lugar do Base UI. Mitigação: só se swipe+snap forem irrecuperáveis após handle no topo + padding-bottom correto.
  • Persistir snap em sessionStorage. Mitigação: fora; reset no pathname (B100).

Adiado com gatilho

  • Animação spring custom além do Base UI. Revisitar se critique pedir motion.
  • Peek de 1 ícone de ação no collapsed. Revisitar se a mesa achar busca-só pobre.

Referências

  • GitHub Issue #132 (B105)
  • CampaignQuickActionsDrawer.tsx · CampaignQuickActionsHost.tsx · campaignQuickActionSnap.ts · Drawer.tsx · docs/plans/bottom-drawer-peek-acoes-busca.md (B100 — supersedido em parte)
  • Commit a056616d (handle bottom — reverter ordem)
  • PRODUCT.md / DESIGN.md — Field Desk chrome