Scroll-view: honour auto_scroll_to, gap on Android, and chrome collapse - #27
Open
shanerbaner82 wants to merge 1 commit into
Open
Scroll-view: honour auto_scroll_to, gap on Android, and chrome collapse#27shanerbaner82 wants to merge 1 commit into
shanerbaner82 wants to merge 1 commit into
Conversation
Three related scroll-view renderer gaps, all surfaced while building a chat screen: auto_scroll_to had a PHP setter (ScrollView::autoScrollTo()) but no consumer on either platform — it was written into the wire payload and dropped. BenchmarkComponent relies on it to scroll a long list, so that scenario has been measuring a static list. iOS reuses the ScrollViewReader already on the vertical branch and scrolls to the target child's id; Android drives LazyColumn's listState by index. Both jump without animation on first appear and animate later moves, matching the existing scroll-anchor path. An explicit index wins over `scroll-anchor="bottom"`. Out-of-range and negative indices are no-ops. The `gap-*` class was read on iOS (into LazyVStack/LazyHStack spacing) and silently dropped on Android, because a lazy list arranges its own items rather than going through the flex engine. That gap matters more than it looks: the workaround is wrapping content in a <column> to get spacing, which collapses the whole list into a single lazy item and defeats virtualization entirely. Programmatic scrolls emit no nested-scroll deltas, so a collapsing top bar never learned the content moved. Both scroll paths now drive the new ChromeScrollController from nativephp/mobile. Skipped on the initial jump — opening a screen should not animate the chrome shut. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three scroll-view renderer gaps, all surfaced while building a chat screen.
Important
Depends on NativePHP/mobile-air#241 — this consumes
ChromeScrollControllerfrom core and will not compile without it. Merge and release that first.1.
auto_scroll_towas never implementedScrollView::autoScrollTo()sets the prop, but no renderer on either platform read it — it was written into the wire payload and dropped on the floor.BenchmarkComponent.php:992relies on it to scroll a long list, so that benchmark scenario has been measuring a static list.ScrollViewReaderalready on the vertical branch, scrolling to the target child's id; the horizontal branch gains a reader so it behaves the same.LazyColumn's existinglistStateby index;LazyRowgains a state to drive.Both jump without animation on first appear (opening at a target shouldn't look like a scroll) and animate later moves, matching the existing
scroll-anchorpath. An explicit index wins overscroll-anchor="bottom". Negative and out-of-range indices are no-ops.2.
gap-*was ignored on AndroidThe flex engine lays out ordinary containers, but a lazy list arranges its own items — so
gapwas read on iOS (intoLazyVStack/LazyHStackspacing) and silently dropped on Android.That gap matters more than it looks. Without it the only way to space a list is wrapping it in a
<column>, which collapses the entire list into a single lazy item — killing virtualization. Measured on a real chat log:directChildren=1,canScrollForward=false, andfirstVisibleItemScrollOffsetclimbing past 1000px inside one item.3. Programmatic scrolls left a collapsing top bar expanded
Both scroll paths now drive core's
ChromeScrollControllerafter moving the list. Skipped on the initial jump — opening a screen shouldn't animate the chrome shut.Compatibility — please read
Two user-visible behaviour changes for existing apps:
gapon a scroll-view now spaces on Android. Any app relying on the current no-op will see layouts shift. Arguably the fix, but it is a change.autoScrollTo()now scrolls. Anyone who called it and got nothing will now get scrolling.Also
auto_scroll_totaking precedence overscroll_anchor— previously moot, sinceauto_scroll_todid nothing.Testing status — partial, please review accordingly
auto_scroll_to(both platforms) and the Android gap fix: NOT yet exercised on device. The test app usesscroll-anchor="bottom"with a wrapped log, so neither path was hit. Reviewed against surrounding code, imports verified, but they want a real build before merge.🤖 Generated with Claude Code