Skip to content

✨ feat(mobile): slide between the feed's tabs - #26

Merged
martinezharo merged 1 commit into
mainfrom
feat/mobile-tab-slide
Sep 2, 2026
Merged

✨ feat(mobile): slide between the feed's tabs#26
martinezharo merged 1 commit into
mainfrom
feat/mobile-tab-slide

Conversation

@martinezharo

@martinezharo martinezharo commented Sep 2, 2026

Copy link
Copy Markdown
Owner

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-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.

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.
  • The track settles on 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.
  • Each panel is its own scroller and its own tabpanel, so it keeps 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.

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 — clean
  • pnpm test — 193 passing (the overscrollShift tests 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

    • Mobile feed tabs now display recent and space content in independently scrollable panels.
    • Each tab is correctly associated with its corresponding content panel for improved accessibility.
    • Swipe navigation now supports smooth panel transitions and bounded, damped pull effects at the beginning and end of the tab list.
  • Bug Fixes

    • Preserved each panel’s scroll position when switching tabs.
    • Improved behavior for short, zero-movement, and boundary-reaching swipe gestures.

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.
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 810c45d4-57e2-4a1e-8a5c-4f03fbbdde9e

📥 Commits

Reviewing files that changed from the base of the PR and between 81671d8 and d346623.

📒 Files selected for processing (5)
  • src/__tests__/tabSwipe.test.ts
  • src/components/MobileHome/FeedTabs.tsx
  • src/components/MobileHome/MobileHome.tsx
  • src/hooks/useSwipeTabs.ts
  • src/lib/tabSwipe.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The 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.

Changes

Feed panel swipe behavior

Layer / File(s) Summary
Bounded overscroll state and transitions
src/lib/tabSwipe.ts, src/__tests__/tabSwipe.test.ts
Swipe progress remains clamped to real tabs. Edge overscroll is damped and capped through TAB_OVERSCROLL_VAR. Tests cover boundaries, degenerate surfaces, and painting.
Swipe hook track integration
src/hooks/useSwipeTabs.ts
The hook exposes trackProps and translates the panel track with tab progress plus overscroll.
Mounted feed panel rendering
src/components/MobileHome/FeedTabs.tsx, src/components/MobileHome/MobileHome.tsx
Recent and space feeds remain mounted in separate scrollable panels. Each tab uses its own panelId; inactive panels receive aria-hidden and inert. Snippet menu opening is shared by both lists.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to d3466

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: claude

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding sliding transitions between the mobile feed tabs.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/mobile-tab-slide

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

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

@martinezharo
martinezharo merged commit 07b42d8 into main Sep 2, 2026
3 checks passed
@martinezharo
martinezharo deleted the feat/mobile-tab-slide branch September 2, 2026 20:17
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