Skip to content

fix(virtual-core): viewport drifts when above-viewport rows resize over multiple frames#1212

Merged
piecyk merged 1 commit into
TanStack:mainfrom
mds-ant:fix/resize-adjust-scrolloffset-sync
Jun 30, 2026
Merged

fix(virtual-core): viewport drifts when above-viewport rows resize over multiple frames#1212
piecyk merged 1 commit into
TanStack:mainfrom
mds-ant:fix/resize-adjust-scrolloffset-sync

Conversation

@mds-ant

@mds-ant mds-ant commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

🎯 Changes

Folding adjustments eagerly into scrollOffset means the browser's scroll event for an adjustment write now arrives at exactly the offset we already hold, and the direction computation classified that equality as 'backward'. With isScrolling held for isScrollingResetDelay after the event, the default shouldAdjustScrollPositionOnItemSizeChange then skipped every above-viewport re-measure compensation until the reset — so multi-frame reflows (a side pane's width animation re-wrapping rows while the user is scrolled up) drifted the viewport, with only ~1 frame in 9 compensated.

An event at the held offset carries no directional information, so keep the previous direction for it instead of computing the comparison. Real gestures still latch normally (their read-backs never equal the held offset, which moves with each event), an equality read-back during a real backward gesture correctly stays 'backward', and the isScrolling === false reset emission still clears the direction.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

This PR was assisted by Claude Code.

Summary by CodeRabbit

  • Bug Fixes
    • Improved scroll direction handling so the app no longer misreads its own scroll adjustment read-backs as user scrolling.
    • Prevents viewport drift and skipped compensation during multi-frame reflows, especially after content changes above the viewport.
    • Real scroll gestures still update direction normally, and direction now stays unchanged when the offset hasn’t actually moved.

…er multiple frames

Folding adjustments eagerly into `scrollOffset` means the browser's
scroll event for an adjustment write now arrives at exactly the offset
we already hold, and the direction computation classified that equality
as `'backward'`. With `isScrolling` held for `isScrollingResetDelay`
after the event, the default `shouldAdjustScrollPositionOnItemSizeChange`
then skipped every above-viewport re-measure compensation until the
reset — so multi-frame reflows (a side pane's width animation
re-wrapping rows while the user is scrolled up) drifted the viewport,
with only ~1 frame in 9 compensated.

An event at the held offset carries no directional information, so keep
the previous direction for it instead of computing the comparison. Real
gestures still latch normally (their read-backs never equal the held
offset, which moves with each event), an equality read-back during a
real backward gesture correctly stays `'backward'`, and the
`isScrolling === false` reset emission still clears the direction.
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main fix: preventing viewport drift from scroll-direction misclassification during multi-frame row resizes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description matches the required template and includes the changes, checklist items, and release impact section.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mds-ant

mds-ant commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@piecyk, this is a follow-up to #1209.

@nx-cloud

nx-cloud Bot commented Jun 30, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 0756722

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 2m 33s View ↗
nx run-many --target=build --exclude=examples/** ✅ Succeeded 17s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-30 14:07:46 UTC

@pkg-pr-new

pkg-pr-new Bot commented Jun 30, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-virtual

npm i https://pkg.pr.new/@tanstack/angular-virtual@1212

@tanstack/lit-virtual

npm i https://pkg.pr.new/@tanstack/lit-virtual@1212

@tanstack/react-virtual

npm i https://pkg.pr.new/@tanstack/react-virtual@1212

@tanstack/solid-virtual

npm i https://pkg.pr.new/@tanstack/solid-virtual@1212

@tanstack/svelte-virtual

npm i https://pkg.pr.new/@tanstack/svelte-virtual@1212

@tanstack/virtual-core

npm i https://pkg.pr.new/@tanstack/virtual-core@1212

@tanstack/vue-virtual

npm i https://pkg.pr.new/@tanstack/vue-virtual@1212

commit: 0756722

@piecyk piecyk merged commit bc8643b into TanStack:main Jun 30, 2026
9 of 10 checks passed
@github-actions github-actions Bot mentioned this pull request Jun 30, 2026
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.

2 participants