Skip to content

feat(core): implement built-in scroll-scaling for large lists#1172

Open
DivyamUp14 wants to merge 3 commits into
TanStack:mainfrom
DivyamUp14:feat/scroll-scaling
Open

feat(core): implement built-in scroll-scaling for large lists#1172
DivyamUp14 wants to merge 3 commits into
TanStack:mainfrom
DivyamUp14:feat/scroll-scaling

Conversation

@DivyamUp14
Copy link
Copy Markdown

@DivyamUp14 DivyamUp14 commented May 23, 2026

🎯 Changes

Fixes #616

Introduced native scroll-scaling in virtual-core to compress coordinates and bypass the browser's maximum scroll height limitation (~33.5 million pixels) for extremely large lists.

✅ 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).

Summary by CodeRabbit

  • New Features

    • Added scroll-scaling for very large virtualized lists
    • New option: maxScrollSize (default 33,000,000; Infinity disables scaling)
    • New property: scale exposes the active compression factor; scroll APIs work transparently while scaling
  • Documentation

    • Updated docs: capped physical container sizing, virtual vs. physical coordinate semantics, and how to recover real item sizes
  • Tests

    • Added tests for scaling activation, coordinate/reporting behavior, and scroll anchoring under scaling

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6c0a6df6-0a33-4158-b1ef-32e8a840faaa

📥 Commits

Reviewing files that changed from the base of the PR and between f40ad74 and db4a1a7.

📒 Files selected for processing (4)
  • .changeset/scroll-scaling.md
  • docs/api/virtualizer.md
  • packages/virtual-core/src/index.ts
  • packages/virtual-core/tests/index.test.ts

📝 Walkthrough

Walkthrough

Implements scroll-range scaling in Virtualizer: adds maxScrollSize (default 33_000_000) and public scale; converts between physical (DOM) and virtual coordinates for scroll reads/writes, adjusts reconciliation, returns scaled consumer item coordinates, updates total-size reporting, and adds tests and docs.

Changes

Scroll-Range Scaling Feature

Layer / File(s) Summary
Configuration and scale factor computation
packages/virtual-core/src/index.ts
Adds maxScrollSize?: number option (default 33_000_000), implements getScale() logic, and exposes public scale getter.
Scaled item coordinates and sizing APIs
packages/virtual-core/src/index.ts
Adds getTotalVirtualSize(); getTotalSize() now returns capped physical size (virtual / scale); getVirtualItems() returns original references when scale === 1 or scaled copies (start/size/end ÷ scale) when active; getMaxScrollOffset() maps physical DOM max to virtual space.
Scroll event reading and writing with coordinate conversion
packages/virtual-core/src/index.ts
Scroll handler converts physical DOM offsets to virtual coordinates (virtual = physical * scale), reconciliation tolerance is scale-aware, _scrollToOffset() downscales virtual offsets for DOM writes and records _intendedScrollOffset in physical space.
Comprehensive test coverage
packages/virtual-core/tests/index.test.ts
Adds Vitest cases validating scale activation and disabling, custom maxScrollSize, getVirtualItems() semantics and identity, offset conversions (observer and _scrollToOffset), and resize anchoring under scaling.
API documentation and release notes
docs/api/virtualizer.md, .changeset/scroll-scaling.md
Documents maxScrollSize, clarifies getTotalSize() and scrollOffset semantics during scaling, expands scale docs and usage, and updates release notes.

Sequence Diagram(s):

sequenceDiagram
  participant Browser
  participant Virtualizer
  participant ScrollFn
  Browser->>Virtualizer: scroll event physicalOffset
  Virtualizer->>Virtualizer: compute scale and virtualOffset
  Virtualizer->>Virtualizer: reconcile using scale-aware tolerance
  Virtualizer->>ScrollFn: call _scrollToOffset with physicalOffset = virtualOffset / scale
  ScrollFn->>Browser: perform DOM scroll
Loading

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • TanStack/virtual#1173: Modifies scrollToEnd/end-distance behavior in packages/virtual-core/src/index.ts, overlapping end/anchoring logic changes.
  • TanStack/virtual#1168: Adjusts scroll reconciliation and offset handling that interact with the scaling-aware reconciliation logic.

Suggested reviewers

  • piecyk

"A rabbit hops through bounds so tall,
Where pixels once would break and fall,
Now scaling makes the viewport free,
Infinite lists we finally see! 🐰"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: implementing built-in scroll-scaling for handling large lists.
Description check ✅ Passed The PR description follows the template structure, completes all checklist items, references the linked issue #616, and explains the core change addressing browser scroll height limitations.
Linked Issues check ✅ Passed The code changes comprehensively implement scroll-scaling to solve issue #616 by introducing maxScrollSize configuration, exposing scale factor, and converting coordinates across the virtual-core API.
Out of Scope Changes check ✅ Passed All changes directly relate to implementing scroll-scaling for large lists: core logic, documentation, tests, and changeset—no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/virtual-core/tests/index.test.ts

Parsing error: "parserOptions.project" has been provided for @typescript-eslint/parser.
The file was not found in any of the provided project(s): packages/virtual-core/tests/index.test.ts


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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/virtual-core/tests/index.test.ts (1)

2660-2677: ⚡ Quick win

The scale === 1 zero-overhead test doesn’t verify object identity yet.

This test currently checks size/scale only, so it won’t fail if getVirtualItems() starts cloning under scale === 1. Assert reference equality between returned items and getMeasurements() entries for visible indexes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/virtual-core/tests/index.test.ts` around lines 2660 - 2677, The test
currently only checks scale and total size but doesn't assert object identity;
update it to ensure getVirtualItems returns actual items (provide a non-null
scroll element in the Virtualizer config, e.g., a dummy element) when scale ===
1, call virtualizer.getMeasurements() and virtualizer.getVirtualItems(), then
for each virtual item assert strict reference equality with the corresponding
measurements entry (match by item.index) so the test fails if getVirtualItems
clones objects under scale === 1; keep existing getTotalSize and scale
assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/virtual-core/src/index.ts`:
- Around line 386-390: The getScale function can divide by invalid
options.maxScrollSize (0, negative, NaN, Infinity) causing invalid scale values;
update getScale to validate maxScrollSize before dividing (use Number.isFinite
and maxScrollSize > 0) and treat any invalid value as a safe fallback (e.g., 1
or a small positive clamp), keeping the existing behavior of returning
virtualTotal / max when valid; change references in getScale (and callers like
getTotalSize/offset conversion/anchoring logic) to rely on this validated result
so downstream math never sees Infinity/NaN/negative scale.

---

Nitpick comments:
In `@packages/virtual-core/tests/index.test.ts`:
- Around line 2660-2677: The test currently only checks scale and total size but
doesn't assert object identity; update it to ensure getVirtualItems returns
actual items (provide a non-null scroll element in the Virtualizer config, e.g.,
a dummy element) when scale === 1, call virtualizer.getMeasurements() and
virtualizer.getVirtualItems(), then for each virtual item assert strict
reference equality with the corresponding measurements entry (match by
item.index) so the test fails if getVirtualItems clones objects under scale ===
1; keep existing getTotalSize and scale assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2a8f8b85-a408-461b-b026-09188d95fa4e

📥 Commits

Reviewing files that changed from the base of the PR and between 949180b and bbfc4bf.

📒 Files selected for processing (4)
  • .changeset/scroll-scaling.md
  • docs/api/virtualizer.md
  • packages/virtual-core/src/index.ts
  • packages/virtual-core/tests/index.test.ts

Comment thread packages/virtual-core/src/index.ts
@DivyamUp14 DivyamUp14 force-pushed the feat/scroll-scaling branch from f40ad74 to db4a1a7 Compare May 26, 2026 11:30
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.

Reach browser max height pixels

1 participant