Skip to content

feat(mobile): unify shell drawer + icon search + global kbd suppression#35

Merged
AlexandreCamillo merged 19 commits into
mainfrom
feat/mobile-shell-refinement
May 24, 2026
Merged

feat(mobile): unify shell drawer + icon search + global kbd suppression#35
AlexandreCamillo merged 19 commits into
mainfrom
feat/mobile-shell-refinement

Conversation

@AlexandreCamillo
Copy link
Copy Markdown
Owner

Summary

  • Sidebar pill becomes the universal mobile drawer trigger across every (app) route (home, projects, settings, annotations).
  • Search pill collapses to a 32×32 icon button next to the avatar at < 768 px; <Kbd> chips hidden site-wide via a single rule in Kbd.module.css.
  • Fixes the broken /projects shell grid that pushed the topbar offscreen on mobile (grid-template-rows: auto 1fr).
  • Removes the duplicate hamburger + drawer from ProjectSidebar.tsx (153 lines deleted) — Sidebar.tsx is now the sole owner of the mobile entry pattern.
  • New useIsMobile() hook (src/hooks/useIsMobile.ts) for live media-query reactivity.

Architecture

  • Native <dialog> + showModal() for focus-trap + ESC.
  • Four close paths: scrim tap, ESC, nav-link tap, ✕ button.
  • Sidebar always renders the collapsed pill on mobile (CSS forces the pill geometry); the React layer also force-collapses on mount via the useIsMobile hook.
  • Topbar search-pill aria-label is viewport-aware ('Search' on mobile, 'Search... (Ctrl+K)' on desktop).
  • Command palette gains a close button (28×28, top-right) on mobile; the keycap footer is hidden.

Test plan

  • `pnpm vitest run` — 745/745 (+9 new tests for `useIsMobile` + `Sidebar` drawer)
  • `pnpm exec tsc --noEmit` — clean
  • `pnpm exec biome check src/ tests/` — clean
  • Manual: `/_qa-mobile.html` walk at viewport 390 — sidebar drawer, search icon, command palette ✕, kbd hidden
  • Manual: desktop >= 768 px — morph + search-pill centered unchanged
  • `markup-qa` skill: visual diff after deploy

Out of scope

  • Mockup viewer mobile redesign (annotations rail, toolbar, pins, pinch-zoom) — separate spec.
  • Tablet breakpoint (768–1024 px).
  • Tooltip-on-touch redesign.

Docs

  • `docs/feature-catalog.md`: renamed `sidebar-mobile-hamburger` → `sidebar-mobile-trigger`, rewrote `sidebar-mobile-drawer`, extended `topbar-search-pill` + `command-palette` + `drop-overlay`, new `mobile-kbd-suppression` section.
  • `docs/frontend/styling.md`: added "Mobile rules" convention section.
  • `docs/frontend/components.md`: added "Mobile shell pattern" section.

@AlexandreCamillo
Copy link
Copy Markdown
Owner Author

QA report — live mobile validation @ viewport 390 × 844

Tested via /_qa-mobile.html (same-origin iframe wrapper, real CSS media-query active). Found 3 bugs not caught by unit tests; fixes pushed on top of the original 13 commits.

✅ Verified working

Surface Result
Sidebar pill (top-left) renders on every authed route, M. logo + collapse icon
Drawer open (tap pill) opens 280 px panel, scrim covers rest
Drawer close — scrim tap confirmed
Drawer close — ✕ button confirmed
Drawer close — ESC (native) unit test confirms close-event handler
Drawer close — nav-link tap fixed after QA (commit bbc4307) — now pathname-driven
Search → 32 × 32 icon next to avatar confirmed; aria-label Search on mobile
Command palette opens confirmed
Command palette ✕ closes confirmed
esc badge hidden on mobile fixed after QA (commit e36eb93) — was visible alongside ✕
Project route topbar at y=0 confirmed (was 533 before T3)
Project route main scrolls confirmed (was overflow: hidden before T3)
Old VscThreeBars hamburger gone confirmed (T6)
Breadcrumb doesn't collide with pill fixed after QA (commit cbda8cd) — topbar mobile padding now respects --sidebar-inset
All <Kbd> chips suppressed on mobile 6 elements in DOM, all visible:false (rect 0×0)

🐛 Found + fixed during live QA

  1. bbc4307 — drawer didn't close on tree-row tap. Tree items are <div role="treeitem"> not <a href>, so the closest('a[href]') check never matched. Replaced with usePathname() effect — fires on every navigation regardless of element shape.
  2. e36eb93 — palette esc badge rendered alongside the new ✕ close button on mobile. escBadge is a custom button (not a <Kbd>), so the global suppression didn't catch it. Added explicit display: none in the palette's mobile media query.
  3. cbda8cd — breadcrumb collided with the pill on /projects/... routes. The mobile topbar's left padding ignored --sidebar-inset. Now uses max(var(--space-sm), var(--sidebar-inset, 0)) on mobile too, and Sidebar.tsx sets the inset on mobile (was only on desktop-collapsed).

Branch state

  • 17 commits (13 plan tasks + 4 QA fixes including the test type-fix)
  • pnpm vitest run746/746 (was 745; +1 new test for pathname close)
  • pnpm exec tsc --noEmit — clean
  • pnpm exec biome check src/ tests/ — clean (1 pre-existing warning unrelated)

Not tested live (covered by unit tests only)

  • ESC native close — would need real keyboard input. Unit test exercises the close-event handler.
  • Desktop morph at ≥ 768 px — Chrome MCP window limited to 500 px inner; unit tests with useIsMobile=false verify morph + pill + search-pill center.

@AlexandreCamillo AlexandreCamillo merged commit 048c39e into main May 24, 2026
2 checks passed
@AlexandreCamillo AlexandreCamillo deleted the feat/mobile-shell-refinement branch May 24, 2026 05:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant