feat(web): follow-finger drawer drag — open with a rightward swipe from anywhere on mobile #143
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab!143
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/140"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Replaces the mobile drawer's 24px left edge-zone snap gesture with a follow-finger drag that starts anywhere on the viewport (<1024px), per the grilled decision in the issue. The OS keeps the edge (iOS back swipe, Android gesture nav); we take the surface — a stolen touch arrives as
touchcanceland animates the half-dragged drawer back cleanly.What changed
web/src/lib/drawerGesture.ts(new) — pure gesture state machine (house pattern: no DOM, time enters only via event timestamps). Owns the arbitration and commit rules:scrollLeft > 0ancestor → page keeps the touch; at 0 the drawer may claim);web/src/lib/drawerGesture.test.ts(new) — 21 vitest cases pinning the full arbitration matrix (scroller split, editable, vertical bail, leftward-when-closed bail, clamping, 50% boundary, flick vs position, stale-sample hold, symmetric close, cancel-reset, taps).web/src/components/AppShell.tsx— binds the four touch listeners (touchmove non-passive so a claimed drag canpreventDefault), answers the machine's environment queries at touch start, tracks the touch by identifier (extra fingers ignored), pins the rail transform and scrim opacity to the finger during a drag, and settles by clearing inline styles and flipping signals in one batch so CSS animates from wherever the finger left off. Scrim is now mountable in the dragging state, not only when open; scrim tap still closes instantly.web/src/base.css—.drawer-draggingchoreography (transition off, visibility forced during drag) with the existing closed-drawer a11y visibility rules intact through the settle; theprefers-reduced-motionsnap rule now also out-specifies.shell.drawer-open .shell-railso a settle into the open state snaps instead of sliding.Desktop (≥1024px) is unchanged; velocity/intent constants are documented tuning knobs.
Verification
npm test: 39 files, 643 tests green (21 new).npm run lint,prettier --check,npm run build(tsc + vite): clean.Closes #140
🤖 Generated with Claude Code
https://claude.ai/code/session_01HhB6q9uhcy5mE8igkzjdER