mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-15 10:43:07 +00:00
137 lines
8.3 KiB
Markdown
137 lines
8.3 KiB
Markdown
# 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):**
|
||
|
||
```text
|
||
┌─ página ───────────────────────────────────────┐
|
||
│ conteúdo │
|
||
├─ drawer ───────────────────────────────────────┤
|
||
│ ═ handle (TOPO) │
|
||
│ [○][○][○]… labels em 2 linhas visíveis │
|
||
│ ┌ Buscar na campanha (placeholder ok) ───────┐ │
|
||
│ └────────────────────────────────────────────┘ │
|
||
└────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**Collapsed (fechado / após scroll ↓):**
|
||
|
||
```text
|
||
┌─ 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
|
||
|
||
```mermaid
|
||
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
|