Skip to content

fix(react-virtual): grow size container before scroll sync on end-anchored prepend - #1237

Merged
piecyk merged 2 commits into
TanStack:mainfrom
piecyk:fix/direct-dom-prepend-scroll-clamp
Jul 20, 2026
Merged

fix(react-virtual): grow size container before scroll sync on end-anchored prepend#1237
piecyk merged 2 commits into
TanStack:mainfrom
piecyk:fix/direct-dom-prepend-scroll-clamp

Conversation

@piecyk

@piecykpiecyk commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes a whitespace gap at the top of the list after an end-anchored prepend (e.g. "load older messages" in a chat pinned to the bottom) when using directDomUpdates mode.

Root cause

On a prepend, setOptions grows the total size and bumps scrollOffset to the new bottom in the same render pass. The scroll position is then synced in the _willUpdate layout effect — but the size container's height is written by the separateapplyDirectStyles layout effect that runs after it. So _willUpdate writes scrollTop to the new bottom while the container is still at its old, shorter height, and the browser clamps the write to the stale scrollHeight. The list is left with a gap at the top until the next scroll re-reconciles.

It only bites when at-end (that's the only time the new scroll target exceeds the stale scrollHeight), and only in directDomUpdates mode — React-rendered sizers receive their height during render, so they're already tall by the layout-effect phase.

Fix

Grow the size container to the new total before_willUpdate syncs the scroll position. Item positions are still written afterwards by applyDirectStyles. The size write is extracted into a small applyContainerSize helper (idempotent, guarded by lastSize) reused by both call sites.

Testing

  • @tanstack/react-virtual: 7/7 pass; tsc --noEmit clean.
  • Verified manually in the React chat example: scroll to bottom → "Load older" no longer leaves a gap; the list stays pinned to the bottom.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed a scrolling issue when items are prepended to the end-anchored list.
    • Prevented temporary whitespace caused by scroll position being clamped to an outdated list size.
    • Improved direct DOM updates so container dimensions are refreshed before scroll synchronization.

piecykand others added 2 commits July 20, 2026 13:19
…hored prepend
In directDomUpdates mode the size container's height was written by the
applyDirectStyles layout effect, which runs *after* the _willUpdate effect
syncs the scroll position. On an end-anchored prepend, _willUpdate writes
scrollTop to the new bottom while the container is still at its old, shorter
height, so the browser clamps the write to the stale scrollHeight and the list
is left with a gap at the top until the next scroll.
Grow the container to the new total size before _willUpdate runs. React-rendered
sizers are unaffected — they receive their height during render.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nx-cloud

nx-cloudBot commented Jul 20, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit b8c2cb3

CommandStatusDurationResult
nx affected --targets=test:sherif,test:knip,tes...✅ Succeeded39sView ↗
nx run-many --target=build --exclude=examples/**✅ Succeeded20sView ↗

☁️ Nx Cloud last updated this comment at 2026-07-20 11:22:24 UTC

@pkg-pr-new

Copy link
Copy Markdown
More templates

@tanstack/angular-virtual

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

@tanstack/lit-virtual

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

@tanstack/marko-virtual

npm i https://pkg.pr.new/@tanstack/marko-virtual@1237

@tanstack/react-virtual

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

@tanstack/solid-virtual

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

@tanstack/svelte-virtual

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

@tanstack/virtual-core

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

@tanstack/vue-virtual

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

commit: b8c2cb3

@coderabbitai

coderabbitaiBot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The direct DOM update path now applies the virtualization container’s total size separately and before item positioning or _willUpdate scroll synchronization, preventing stale scroll extents during end-anchored prepends. A patch changeset documents the fix.

Changes

Direct DOM scroll synchronization

Layer / File(s)Summary
Container sizing and item positioning
packages/react-virtual/src/index.tsx
Adds an idempotent applyContainerSize helper and invokes it before writing direct item positions.
Pre-scroll synchronization sizing
packages/react-virtual/src/index.tsx, .changeset/fix-direct-dom-prepend-scroll-clamp.md
Applies the container size before _willUpdate synchronizes scroll position and documents the patch release.参考

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers:tannerlinsley

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly matches the main change: fixing scroll sync by growing the size container first for end-anchored prepends.
Description check✅ PassedThe description covers the summary, root cause, fix, and testing, but omits the template's checklist and release-impact sections.
✨ 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.

@piecyk
piecyk merged commit aa536e7 into TanStack:mainJul 20, 2026
10 checks passed
@github-actionsgithub-actionsBot mentioned this pull request Jul 20, 2026
Sign up for freeto 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

@piecyk