Skip to content

fix(scroll): correct inverted list rendering and wheel direction on web#2331

Open
HuuNguyen312 wants to merge 1 commit into
Shopify:mainfrom
HuuNguyen312:fix/inverted-web-rendering-and-wheel
Open

fix(scroll): correct inverted list rendering and wheel direction on web#2331
HuuNguyen312 wants to merge 1 commit into
Shopify:mainfrom
HuuNguyen312:fix/inverted-web-rendering-and-wheel

Conversation

@HuuNguyen312

Copy link
Copy Markdown

Description

Fixes inverted list rendering and mouse-wheel direction on web (e.g. Electron). Native is unaffected.

On web, inverted lists are flipped with transform: scaleY(-1) (scaleX(-1) when horizontal). This broke two things:

1. Rendering froze (~20 items, then blank)

measureFirstChildLayout read mirrored getBoundingClientRect coordinates, so firstItemOffset grew with scroll instead of staying ~0. The internal scrollOffset (y - firstItemOffset) went negative → getVisibleLayouts clamped to index 0 → the engaged index froze → renderItem stopped being called while scrolling.

Fix: detect the scaleY(-1) transform and measure from the bottom edge when flipped, so firstItemOffset stays ~0 (matching non-inverted).

2. Mouse wheel scrolled the wrong way

The native wheel delta is not flipped by the container transform, so it scrolled opposite to the content.

Fix: a web-only useInvertedWheelFix hook re-inverts the wheel delta on the scroll node (-= deltaY, or -= deltaX when horizontal). Setting scrollTop / scrollLeft still fires the scroll event, so virtualization keeps working.

Native behavior is unchangedmeasureLayout.ts and the native hook variant (useInvertedWheelFix.ts) are no-ops / untouched.

Affected package: @shopify/flash-list

Changed files

File Change
src/recyclerview/utils/measureLayout.web.ts add isVerticallyFlipped, measure from bottom when flipped
src/recyclerview/hooks/useInvertedWheelFix.web.ts web wheel re-invert (new)
src/recyclerview/hooks/useInvertedWheelFix.ts native no-op (new)
src/recyclerview/RecyclerView.tsx wire up the hook

Reviewers' hat-rack 🎩

  • Web, inverted list — scroll up/down keeps rendering items (no blank area), wheel scrolls in the correct direction
  • Native (iOS/Android), inverted list — no behavior change; smooth scroll, renderItem fires as expected
  • firstItemOffset stays ~0 while scrolling an inverted list on web (was growing 1057 → 4009 → 9923 before the fix)

On web, inverted lists are flipped with transform: scaleY(-1). This broke two things:

- measureFirstChildLayout read mirrored getBoundingClientRect coordinates, so firstItemOffset grew with scroll and scrollOffset went negative, freezing the engaged index (~20 items rendered, then blank). Measure from the bottom edge when the container is vertically flipped so firstItemOffset stays ~0.
- The native mouse wheel is not flipped, so it scrolled the wrong way. Add a web-only useInvertedWheelFix hook that re-inverts the wheel delta on the scroll node (no-op on native).

Native behavior is unchanged: measureLayout.ts and the native hook variant are untouched.
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