✨ feat(mobile): slide between the feed's tabs - #26
Conversation
Moving between Recent and My Space swapped the panel in a single frame: only the switcher's pill animated, while the list underneath it merely gave way ~56px to the finger and then changed contents at once. The transition read as a cut, not a movement. Both lists are now mounted side by side on one track inside a clipping viewport, so `--tab-progress` moves them 1:1 with the gesture — halfway through a swipe each panel is half on screen, and a tap on the switcher animates the same way over the same 420ms as the pill. - `contentShift()` becomes `overscrollShift()`: zero wherever there is a panel to reveal (the track's own travel says it all), and a damped rubber band only past the first and last tab. - The track settles on `cubic-bezier(0.32,0.72,0,1)` rather than the pill's spring — a track that overshot its end would flash the background beyond the last panel. - Each panel is its own scroller and its own `tabpanel`, keeping its scroll position across switches; the off-screen one is `inert` and hidden from assistive tech. - Both lists now open a card's ⋯ menu through one shared handler instead of two copies of the same anchoring maths.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (5)
Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughThe swipe model now separates tab progress from bounded edge overscroll. The mobile home renders recent and space feeds as mounted, independently scrollable panels with per-tab accessibility relationships. ChangesFeed panel swipe behavior
Estimated code review effort: 3 (Moderate) | ~25 minutes Merge Risk: ⚪ Minimal · up to This PR changes mobile feed-tab navigation to animate both panels during swipes and tab selections while preserving each panel's scroll state; the supplied checks pass and no actionable merge-blocking risk remains. Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Gesture
participant useSwipeTabs
participant MobileHome
participant FeedPanel
Gesture->>useSwipeTabs: Update tab progress and overscroll
useSwipeTabs->>MobileHome: Apply container and track styles
MobileHome->>FeedPanel: Translate mounted feed panels
MobileHome->>FeedPanel: Update active accessibility state
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
klipcode | d346623 | Commit Preview URL Branch Preview URL |
Sep 02 2026, 07:56 PM |
What
Moving between Recent and My Space on the mobile home swapped the panel in a single frame: only the switcher's pill animated, while the list underneath it gave way ~56px to the finger and then changed contents at once. The transition read as a cut rather than a movement — you never saw one list leave while the other arrived.
Both lists are now mounted side by side on one track inside a clipping viewport, so
--tab-progressmoves them 1:1 with the gesture. Halfway through a swipe each panel is half on screen, and a tap on the switcher animates the same way, over the same 420ms as the pill.How
contentShift()→overscrollShift(): zero wherever there is a panel to reveal (the track's own travel says it all), and a damped rubber band only past the first and last tab.cubic-bezier(0.32,0.72,0,1)instead of the pill's spring — a track that overshot its end would flash the background beyond the last panel. Same duration, so pill and panels arrive together.tabpanel, so it keeps its scroll position across switches; the off-screen one isinertand hidden from assistive tech.Verification
Driven in the real app (dev server, Chromium at 390×844): mid-drag the Recent card leaves to the left while the My Space tree enters from the right, pill in between with its labels inverting; pressing a tab animates identically; pulling against an end gives only the rubber band.
pnpm exec tsc --noEmit,pnpm lint— cleanpnpm test— 193 passing (theoverscrollShifttests rewritten for the new semantics)pnpm exec playwright test e2e/mobile.spec.ts— 8/8 passing🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes