Skip to content

fix(virtual-list): keep the focus snap when a scroll request echoes it - #152

Merged
RuudBurger merged 1 commit into
mainfrom
ruud/virtuallist-rest-offset
Oct 15, 2026
Merged

RuudBurger merged 1 commit into
mainfrom
ruud/virtuallist-rest-offset

Conversation

@RuudBurger

Copy link
Copy Markdown
Member

Home rows rested at different tops going Up than going Down in the Plex app (row 8 at 496, row 6 at 532, row 2 at 496, all 520 on the way down). 24 px of drift, 12 px where the app's preview expansion is partial.

What happens: on every Lightning focus move the app calls scrollToIndex for the row that VirtualList just scrolled to itself, 15-30 ms later with the same target (ScrollIntoViewHelper in the app runs on Lightning because IS_WEB is true there). scrollToOffset drops the focus anchor before the duplicate-target guard turns the call into a no-op, so keepFocusedItemSnapped switches off, and scrollToIndex also stores a fixed index intent that re-applies a stale offset on the next maxScroll change. When the scroll animation ends the batched sizes drain, a row above the focused one resizes (928 to 904 px for the preview row), the focused cell's offset moves and nothing resnaps.

Fix: scrollToOffset keeps the anchor when the requested offset is within 1 px of where the anchor already snaps the list, and scrollToIndex doesn't set the stale index intent in that case. Any other target still releases the anchor. The app doesn't need to change.

Verified: unit test (useScrollHandler.spec.tsx, uses createTestRenderer) fails without the fix and also without only the anchor half, plus a test that a scrollToIndex to another row still releases the anchor. In the app (headless Chrome, patched dist on top of the stable ref handle fix): a settled Down/Up sweep rests all rows at 520 both ways, baseline had 8@496 6@532 3@496 1@532 on the way up. One animated 24 px resnap after the drain, no fight with the intent. Haven't re-run the timed 700/150 ms repro with the fix, only the settled sweep.

@RuudBurger
RuudBurger merged commit fbe68d4 into main Oct 15, 2026
1 check passed
@RuudBurger
RuudBurger deleted the ruud/virtuallist-rest-offset branch October 15, 2026 16:12
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