Skip to content

fix(happy-app): web chat scroll direction inverted#1048

Open
chphch wants to merge 1 commit into
slopus:mainfrom
chphch:fix/793-web-scroll-direction
Open

fix(happy-app): web chat scroll direction inverted#1048
chphch wants to merge 1 commit into
slopus:mainfrom
chphch:fix/793-web-scroll-direction

Conversation

@chphch
Copy link
Copy Markdown
Contributor

@chphch chphch commented Apr 13, 2026

Closes #793.

The bug: On web, mouse wheel, trackpad, and middle-click auto-scroll all scroll in the wrong direction. React Native Web renders inverted={true} on the FlatList via transform: scaleY(-1), which flips the entire scroll container — every scroll interaction is mirrored, and maintainVisibleContentPosition is silently ignored. This PR fixes that by adding a web-only ChatList.web.tsx that uses CSS flex-direction: column-reverse (no transform), which gives the same visual layout (newest at bottom) using native browser flexbox; the messages array is already newest-first, matching column-reverse render order. Native ChatList.tsx is untouched — Expo/Metro auto-resolves .web.tsx for web builds (same pattern as MultiTextInput.web.tsx, Shaker.web.tsx).

Proof

Before / after recordings (mouse wheel + middle-click + trackpad two-finger): video pending — will attach before requesting human review per CONTRIBUTING.md.

Scope

  • 1 file added (ChatList.web.tsx, +60 LOC), zero existing code modified.
  • No native or shared-platform behaviour changes.

m-bers added a commit to m-bers/happy that referenced this pull request Apr 18, 2026
@chphch chphch force-pushed the fix/793-web-scroll-direction branch from b72b419 to b369e56 Compare April 26, 2026 05:44
@chphch
Copy link
Copy Markdown
Contributor Author

chphch commented Apr 26, 2026

Proof — wheel direction now correct on web

The bug: with inverted={true} on RN-Web FlatList → transform: scaleY(-1) on the container → wheel events inverted, maintainVisibleContentPosition silently dropped, middle-click auto-scroll reversed. The fix replaces this with flex-direction: column-reverse on a web-only ChatList.web.tsx (1 file, +60 LOC, native unaffected).

Side-by-side synthetic demo of the two CSS approaches scrolled with page.mouse.wheel(0, ±120) (real wheel events that go through the same native scroll handling the bug exhibits):

scroll fix

Captured scrollTop after each wheel gesture confirms the divergence:

step gesture BEFORE scrollTop AFTER scrollTop
0 (initial) 0 0
1 wheel up 0 (stuck — gesture inverted) -120 (history revealed)
2 wheel up 0 -240
3 wheel up 0 -360
4 wheel up 0 -480
5 wheel down 120 (now scrolls in wrong direction) -360 (back toward newest)
6 wheel down 240 -240
7 wheel down 360 -120

column-reverse gives the same visual layout (newest at the bottom) without any CSS transform on the container, so all native scroll interactions work as expected — exactly what RN-Web's inverted was trying to achieve in the first place. Mobile/native paths are untouched (Expo/Metro auto-resolves .web.tsx for web builds, same pattern as MultiTextInput.web.tsx, Shaker.web.tsx).

Capture details

Synthetic side-by-side because the relevant bug is purely about CSS-level scroll handling — the diff is 1 isolated component, no app-wide state involved. Reproduction page: two <div class="chat"> siblings, one with transform: scaleY(-1) (with inner scaleY(-1) on rows to undo text flip), one with flex-direction: column-reverse. Driven by page.mouse.wheel in headless Chromium.

@chphch chphch force-pushed the fix/793-web-scroll-direction branch 3 times, most recently from 4880e7a to 0674275 Compare May 3, 2026 18:00
@chphch chphch force-pushed the fix/793-web-scroll-direction branch from 0674275 to be03956 Compare May 8, 2026 18:00
Add ChatList.web.tsx that uses CSS `flex-direction: column-reverse`
instead of React Native's `inverted={true}` FlatList. On web, inverted
FlatList applies `transform: scaleY(-1)` which reverses all scroll
interactions including middle-click auto-scroll and trackpad gestures.

`column-reverse` provides the same visual layout (newest messages at
bottom, scroll up for history) using native browser layout, so all
scroll interactions work correctly.

Fixes slopus#793

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@chphch chphch force-pushed the fix/793-web-scroll-direction branch from be03956 to 253c229 Compare May 15, 2026 18:00
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.

bug(web): chat history cannot scroll — FlatList inverted+absolute layout broken on web

1 participant