Skip to content

Page the phone carousel one slide per swipe, including on iPhone Safari - #14

Merged
aharvard merged 1 commit into
mainfrom
claude/carousel-swipe-fix
Oct 9, 2026
Merged

aharvard merged 1 commit into
mainfrom
claude/carousel-swipe-fix

Conversation

@aharvard

@aharvard aharvard commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

On iPhone Safari, a swipe off the homepage's post slide still skipped the first record, even after #11. The deployed CSS has scroll-snap-stop: always, but WebKit doesn't hold a flick at the next slide: it settles on the snap point nearest the end of the fling's momentum. Since #10, the carousel's height also changes as a swipe crosses from one slide to the next, which can make Safari snap again partway through.

The component now pages the carousel itself on phones (≤700px). Once it runs, the carousel stops scrolling and snapping natively (.space[data-paged]):

  • A sideways drag follows your finger. On release, the carousel moves one slide if the drag covered a quarter of a slide or was a flick; otherwise it springs back.
  • A vertical drag still scrolls the page (touch-action: pan-y).
  • A sideways trackpad or wheel gesture moves one slide, however long its momentum runs.
  • Each swipe starts from the slide in view, unless a move is still animating. Quick swipes chain, and if anything else scrolls the carousel (a screen reader bringing a card into view, say), the next swipe starts from wherever it ended up.
  • The CSS snapping stays as the fallback until the script loads. Desktop is unchanged.

The height-fitting from #10 is untouched; it still follows the scroll position.

Testing. I couldn't test on WebKit: the iOS Simulator needs a full Xcode install, which this Mac doesn't have. Instead I drove headless Chrome over the DevTools protocol as a 375px touch phone:

  • Input.synthesizeScrollGesture touch flings from a slow quarter-slide drag up to 5000px/s each moved exactly one slide.
  • Short, slow drags sprang back.
  • Consecutive swipes chained forward and back, and a backward swipe on the first slide stayed put.
  • A vertical swipe over the carousel scrolled the page.
  • Trackpad-style wheel streams moved one slide each.

pnpm --dir documentation typecheck, pnpm --dir documentation test (16 of 16) and pnpm docs:build pass. Please check it on an iPhone before merging.

🤖 Generated with Claude Code

On iPhone Safari a swipe off the post still skipped the first record:
WebKit settles a flick on the snap point nearest its momentum and does not
hold it at the next one, scroll-snap-stop or not, and the carousel's height
now changes as a swipe crosses slides, which can set it snapping again.

Once the component runs, the carousel no longer scrolls or snaps natively.
A sideways drag follows the finger, and on release it moves one slide if it
went a quarter of a slide or was flicked, and springs back otherwise.
Vertical pans still scroll the page (touch-action: pan-y), and a sideways
trackpad or wheel gesture moves one slide however long its momentum runs.
Each swipe starts from the slide in view unless a move is still easing, so
quick swipes chain and anything else that scrolls the carousel is followed.
The CSS snapping stays as the fallback before the script loads.

Checked in headless Chrome as a 375px touch phone: swipes from a slow
quarter-slide drag to a 5000px/s flick each move exactly one slide, short
slow drags spring back, consecutive swipes chain both ways, and a vertical
swipe over the carousel scrolls the page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aharvard
aharvard requested a review from daveh-beep as a code owner October 9, 2026 21:30
@aharvard
aharvard merged commit 65d8d9e into main Oct 9, 2026
5 checks passed
@aharvard
aharvard deleted the claude/carousel-swipe-fix branch October 9, 2026 21:41
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