diff --git a/.changeset/feat-core-ios-scroll-handling.md b/.changeset/feat-core-ios-scroll-handling.md deleted file mode 100644 index e95af692..00000000 --- a/.changeset/feat-core-ios-scroll-handling.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -iOS Safari momentum-scroll handling. Writing `scrollTop` while a finger -is on the screen, during momentum decay, or while the page is in the -elastic-overscroll bounce zone all cancel the in-flight scroll in iOS -WebKit. The virtualizer previously had no iOS-specific handling, which -manifested as the recurring "scroll abruptly stops when content above -resizes" complaints on Safari mobile. - -Adds three layers of protection, default-on, all transparent to -consumers: - -- **Touch event distinction.** A touchstart→touchend window plus a - 150 ms grace timer for the early-momentum phase. Scroll-position - adjustments triggered during any of these states accumulate into a - `_iosDeferredAdjustment` field instead of writing `scrollTop`. -- **Subpixel reconciliation.** When the browser reports back a rounded - `scrollTop` within 1.5 px of a value we just wrote, the virtualizer - prefers the intended value rather than treating the round-trip as a - user scroll. -- **Elastic-overscroll clamp.** The deferred-adjustment flush is skipped - when `scrollTop` is outside `[0, scrollHeight - clientHeight]`, - preventing a snap-back jolt at end-of-bounce. The next in-bounds - scroll event retries. - -Non-iOS code paths are unchanged. iOS detection is SSR-safe and cached -after first call. Bundle cost is ~370 B gzip in the consumer-minified -production build — kept default-on because iOS Safari is a large share -of mobile traffic for the apps that use virtualization heavily. diff --git a/.changeset/feat-core-scroll-to-index-smooth.md b/.changeset/feat-core-scroll-to-index-smooth.md deleted file mode 100644 index 58ec12f1..00000000 --- a/.changeset/feat-core-scroll-to-index-smooth.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@tanstack/virtual-core': patch ---- - -`scrollToIndex(N, { behavior: 'smooth' })` on a dynamic-height list no -longer snaps to `behavior: 'auto'` the moment a measurement shifts the -computed target offset. While the scroll is still more than a viewport -away from the new target, smooth scroll continues with the updated -endpoint; only on the final approach do we fall back to 'auto' for -precise landing. The user-visible effect is one continuous smooth -motion that subtly adjusts its endpoint as measurements arrive, -instead of the prior animation-then-snap pattern. - -Also: once `reconcileScroll` reaches its stable-frames threshold, it -writes the exact target offset one final time. This is a no-op when -`scrollTop` already equals the target (the common case) but corrects -the rare subpixel-rounding case where smooth scroll undershoots by -less than 1 px. diff --git a/.changeset/feat-core-scroll-up-jank-default.md b/.changeset/feat-core-scroll-up-jank-default.md deleted file mode 100644 index bd487934..00000000 --- a/.changeset/feat-core-scroll-up-jank-default.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -Skip the scroll-position adjustment while the user is scrolling backward -by default. When an above-viewport item resizes during backward scroll -(images load, content reflows, etc.) the prior behavior wrote `scrollTop` -to keep the visible window stable — but on backward scroll that write -fights the user's direction and produces visible "items jump up while I -scroll up" jank. This was the largest single complaint cluster in the -issue tracker (multiple recurring threads spanning years; users had -independently rediscovered the same workaround at least five times). - -Forward-scroll and idle (mount-time) adjustments still fire as before -to preserve visual stability of the visible window. Consumers who want -the old behavior — adjusting on every above-viewport resize regardless -of direction — can supply `shouldAdjustScrollPositionOnItemSizeChange` -which is checked before the default branch. diff --git a/.changeset/feat-core-take-snapshot.md b/.changeset/feat-core-take-snapshot.md deleted file mode 100644 index c185d871..00000000 --- a/.changeset/feat-core-take-snapshot.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -Add `takeSnapshot()` instance method for scroll-restoration round-trips. -Returns the currently-measured items as plain `VirtualItem` objects; -pair with the current `scrollOffset` to persist scroll position across -remounts (route navigation, list-view modals, etc.). The result feeds -back through the existing `initialMeasurementsCache` option: - -```tsx -const snapshot = virtualizer.takeSnapshot() -const offset = virtualizer.scrollOffset -// later, on remount: -useVirtualizer({ - // … - initialMeasurementsCache: snapshot, - initialOffset: offset, -}) -``` - -Closes the gap to virtua's `takeCacheSnapshot()` and react-virtuoso's -`getState`. Only items actually rendered (and thus measured) are -included; unmeasured items fall back to `estimateSize` on restore. diff --git a/.changeset/fix-core-elementscache-stale-index.md b/.changeset/fix-core-elementscache-stale-index.md deleted file mode 100644 index 1edd76ec..00000000 --- a/.changeset/fix-core-elementscache-stale-index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@tanstack/virtual-core': patch ---- - -Don't call `getItemKey` with a possibly-stale index when cleaning up -`elementsCache` for a disconnected node. The cleanup now finds the -matching entry by node identity, so removing items from the end of -the list while a `ResizeObserver` still has the now-detached node -queued no longer throws (regression of #1148). diff --git a/.changeset/fix-core-measure-and-ios-flush.md b/.changeset/fix-core-measure-and-ios-flush.md deleted file mode 100644 index a6009e1d..00000000 --- a/.changeset/fix-core-measure-and-ios-flush.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@tanstack/virtual-core': patch ---- - -Two correctness fixes in the new code: - -- `measure()` now resets `pendingMin` so a prior `resizeItem()` that left - it non-null can't preserve stale `measurementsCache` entries before that - index. The next rebuild is guaranteed to start at 0. -- The iOS deferred-adjustment flush now rolls its accumulated delta into - `scrollAdjustments`. Without this, a resize landing between the flush - and the resulting scroll event would compute the next correction from - the stale pre-flush offset. diff --git a/.changeset/perf-core-mount-and-measure-storm.md b/.changeset/perf-core-mount-and-measure-storm.md deleted file mode 100644 index 7aafb574..00000000 --- a/.changeset/perf-core-mount-and-measure-storm.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -'@tanstack/virtual-core': minor ---- - -Mount-time, measurement, and memory rewrite for huge lists. The hot path -through `getMeasurements()` no longer allocates a `VirtualItem` object per -index for single-lane lists; instead it fills a `Float64Array` of -start/size pairs and materializes `VirtualItem` objects lazily through a -`Proxy`-backed view when consumers index into them. Internal hot paths -(`calculateRange`, `getVirtualItemForOffset`, `getTotalSize`, `resizeItem`) -read directly from the typed-array storage to avoid the Proxy. - -Also collapses a chain of smaller hotspots discovered in an audit pass: -the per-resize `Map` clone in `resizeItem`, the `Object.entries+delete` -deopt in `setOptions`, the `Math.min(...pendingMeasuredCacheIndexes)` -spread, the `defaultRangeExtractor` `push` growth pattern, the eager -`measurementsCache` reference invalidation, and the leaked `elementsCache` -entries when a `ResizeObserver` fires for a node React already replaced. - -Headline impact (measured against actual `Virtualizer` instances with -vitest bench): - -- Cold mount @ 100k items: ~2.5 ms → ~0.5 ms (4.7×) -- Cold mount @ 500k items: ~14 ms → ~2.7 ms (5.2×) -- `resizeItem` storm of 10,000 measurements + final `getMeasurements`: - ~1.9 s → ~1.3 ms (≈1382×) — this was the dominant `Map`-clone bug -- `setOptions` × 10,000 calls (React-render-storm proxy): ~14 ms → ~1.3 ms - (11×) - -The lanes>1 path keeps the previous eager allocation (lane assignment is -order-dependent and harder to defer cleanly); behavior is unchanged -there. - -No public API change. `measurementsCache` is still an -`Array`-shaped value supporting `[i]`, `.length`, iteration, -etc. Internal consumers that previously read fields off `VirtualItem` -objects continue to do so transparently. diff --git a/.changeset/perf-react-virtual-rerender-alloc.md b/.changeset/perf-react-virtual-rerender-alloc.md deleted file mode 100644 index fd012e50..00000000 --- a/.changeset/perf-react-virtual-rerender-alloc.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@tanstack/react-virtual': patch ---- - -Replace the `useReducer(() => ({}), {})` force-rerender pattern with an -incrementing number counter. Same semantics (every dispatch changes the -reducer state, forcing a render); zero per-dispatch object allocation. -Trivial individual cost, but eliminates one steady-state GC source on -scroll-heavy apps. diff --git a/benchmarks/CHANGELOG.md b/benchmarks/CHANGELOG.md new file mode 100644 index 00000000..1a027e3f --- /dev/null +++ b/benchmarks/CHANGELOG.md @@ -0,0 +1,8 @@ +# @tanstack/virtual-benchmarks + +## 0.0.1 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/react-virtual@3.13.25 diff --git a/benchmarks/package.json b/benchmarks/package.json index 96638d6c..efc24d01 100644 --- a/benchmarks/package.json +++ b/benchmarks/package.json @@ -1,7 +1,7 @@ { "name": "@tanstack/virtual-benchmarks", "private": true, - "version": "0.0.0", + "version": "0.0.1", "type": "module", "scripts": { "dev": "vite", diff --git a/examples/angular/dynamic/package.json b/examples/angular/dynamic/package.json index 802f61bb..85db0193 100644 --- a/examples/angular/dynamic/package.json +++ b/examples/angular/dynamic/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/fixed/package.json b/examples/angular/fixed/package.json index 1dbca676..3f0f0bb9 100644 --- a/examples/angular/fixed/package.json +++ b/examples/angular/fixed/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/infinite-scroll/package.json b/examples/angular/infinite-scroll/package.json index ede25efd..e5b8b9b6 100644 --- a/examples/angular/infinite-scroll/package.json +++ b/examples/angular/infinite-scroll/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@tanstack/angular-query-experimental": "5.80.7", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/padding/package.json b/examples/angular/padding/package.json index a8cb1b74..dd82276a 100644 --- a/examples/angular/padding/package.json +++ b/examples/angular/padding/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/smooth-scroll/package.json b/examples/angular/smooth-scroll/package.json index 1b033a33..c03af429 100644 --- a/examples/angular/smooth-scroll/package.json +++ b/examples/angular/smooth-scroll/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/sticky/package.json b/examples/angular/sticky/package.json index 642e5f3f..ac48a8fb 100644 --- a/examples/angular/sticky/package.json +++ b/examples/angular/sticky/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/table/package.json b/examples/angular/table/package.json index 6d53b35e..bcb63c2e 100644 --- a/examples/angular/table/package.json +++ b/examples/angular/table/package.json @@ -19,7 +19,7 @@ "@angular/router": "^19.0.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-table": "8.21.3", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/variable/package.json b/examples/angular/variable/package.json index 3440f6ba..75cd2c3d 100644 --- a/examples/angular/variable/package.json +++ b/examples/angular/variable/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/angular/window/package.json b/examples/angular/window/package.json index 7a71f362..86f339ba 100644 --- a/examples/angular/window/package.json +++ b/examples/angular/window/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", - "@tanstack/angular-virtual": "^5.0.0", + "@tanstack/angular-virtual": "^5.0.1", "rxjs": "^7.8.2", "tslib": "^2.8.1", "zone.js": "0.15.1" diff --git a/examples/lit/dynamic/package.json b/examples/lit/dynamic/package.json index 26e226a7..485af5b0 100644 --- a/examples/lit/dynamic/package.json +++ b/examples/lit/dynamic/package.json @@ -9,8 +9,8 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/lit-virtual": "^3.13.25", - "@tanstack/virtual-core": "^3.14.0", + "@tanstack/lit-virtual": "^3.13.26", + "@tanstack/virtual-core": "^3.15.0", "lit": "^3.3.0" }, "devDependencies": { diff --git a/examples/lit/fixed/package.json b/examples/lit/fixed/package.json index 3dea5024..ab3f8504 100644 --- a/examples/lit/fixed/package.json +++ b/examples/lit/fixed/package.json @@ -9,8 +9,8 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/lit-virtual": "^3.13.25", - "@tanstack/virtual-core": "^3.14.0", + "@tanstack/lit-virtual": "^3.13.26", + "@tanstack/virtual-core": "^3.15.0", "lit": "^3.3.0" }, "devDependencies": { diff --git a/examples/react/dynamic/package.json b/examples/react/dynamic/package.json index c2f8ab1b..87ded409 100644 --- a/examples/react/dynamic/package.json +++ b/examples/react/dynamic/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/fixed/package.json b/examples/react/fixed/package.json index 65287182..af92e2f5 100644 --- a/examples/react/fixed/package.json +++ b/examples/react/fixed/package.json @@ -8,7 +8,7 @@ "serve": "vite preview" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/infinite-scroll/package.json b/examples/react/infinite-scroll/package.json index 2f541b45..427a2111 100644 --- a/examples/react/infinite-scroll/package.json +++ b/examples/react/infinite-scroll/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@tanstack/react-query": "^5.80.7", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/padding/package.json b/examples/react/padding/package.json index a9e4b904..4a27b3dc 100644 --- a/examples/react/padding/package.json +++ b/examples/react/padding/package.json @@ -9,7 +9,7 @@ "start": "vite" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/scroll-padding/package.json b/examples/react/scroll-padding/package.json index cfa93d19..fcce013b 100644 --- a/examples/react/scroll-padding/package.json +++ b/examples/react/scroll-padding/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@react-hookz/web": "^25.1.1", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/smooth-scroll/package.json b/examples/react/smooth-scroll/package.json index eb9ca321..c56afcf2 100644 --- a/examples/react/smooth-scroll/package.json +++ b/examples/react/smooth-scroll/package.json @@ -9,7 +9,7 @@ "start": "vite" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/sticky/package.json b/examples/react/sticky/package.json index b8c14583..41e7267d 100644 --- a/examples/react/sticky/package.json +++ b/examples/react/sticky/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "lodash": "^4.17.21", "react": "^18.3.1", "react-dom": "^18.3.1" diff --git a/examples/react/table/package.json b/examples/react/table/package.json index 7a451f38..925d5e94 100644 --- a/examples/react/table/package.json +++ b/examples/react/table/package.json @@ -11,7 +11,7 @@ "dependencies": { "@faker-js/faker": "^8.4.1", "@tanstack/react-table": "^8.21.3", - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/variable/package.json b/examples/react/variable/package.json index 78feb040..46ba91a9 100644 --- a/examples/react/variable/package.json +++ b/examples/react/variable/package.json @@ -9,7 +9,7 @@ "start": "vite" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/window/package.json b/examples/react/window/package.json index e74ee518..c1a78d43 100644 --- a/examples/react/window/package.json +++ b/examples/react/window/package.json @@ -8,7 +8,7 @@ "serve": "vite preview" }, "dependencies": { - "@tanstack/react-virtual": "^3.13.24", + "@tanstack/react-virtual": "^3.13.25", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/svelte/dynamic/package.json b/examples/svelte/dynamic/package.json index 9e2c27e7..ffe7ade4 100644 --- a/examples/svelte/dynamic/package.json +++ b/examples/svelte/dynamic/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/fixed/package.json b/examples/svelte/fixed/package.json index 59fe40d8..06e644ce 100644 --- a/examples/svelte/fixed/package.json +++ b/examples/svelte/fixed/package.json @@ -9,7 +9,7 @@ "check": "svelte-check --tsconfig ./tsconfig.json" }, "dependencies": { - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/infinite-scroll/package.json b/examples/svelte/infinite-scroll/package.json index 8970550f..57130e71 100644 --- a/examples/svelte/infinite-scroll/package.json +++ b/examples/svelte/infinite-scroll/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@tanstack/svelte-query": "^5.80.7", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/smooth-scroll/package.json b/examples/svelte/smooth-scroll/package.json index 2b4689b3..d6766b75 100644 --- a/examples/svelte/smooth-scroll/package.json +++ b/examples/svelte/smooth-scroll/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/sticky/package.json b/examples/svelte/sticky/package.json index 742c8c9e..c82393be 100644 --- a/examples/svelte/sticky/package.json +++ b/examples/svelte/sticky/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/svelte-virtual": "^3.13.24", + "@tanstack/svelte-virtual": "^3.13.25", "lodash": "^4.17.21" }, "devDependencies": { diff --git a/examples/svelte/table/package.json b/examples/svelte/table/package.json index ce43eb5e..e13197b1 100644 --- a/examples/svelte/table/package.json +++ b/examples/svelte/table/package.json @@ -11,7 +11,7 @@ "dependencies": { "@faker-js/faker": "^8.4.1", "@tanstack/svelte-table": "^8.21.3", - "@tanstack/svelte-virtual": "^3.13.24" + "@tanstack/svelte-virtual": "^3.13.25" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/vue/dynamic/package.json b/examples/vue/dynamic/package.json index b208d1fd..cf72a3b1 100644 --- a/examples/vue/dynamic/package.json +++ b/examples/vue/dynamic/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/fixed/package.json b/examples/vue/fixed/package.json index 98116db2..d0abefcd 100644 --- a/examples/vue/fixed/package.json +++ b/examples/vue/fixed/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/infinite-scroll/package.json b/examples/vue/infinite-scroll/package.json index 1c799f0b..8c1f5fb6 100644 --- a/examples/vue/infinite-scroll/package.json +++ b/examples/vue/infinite-scroll/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@tanstack/vue-query": "^5.80.7", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/padding/package.json b/examples/vue/padding/package.json index 44c96827..c55fe2ef 100644 --- a/examples/vue/padding/package.json +++ b/examples/vue/padding/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/scroll-padding/package.json b/examples/vue/scroll-padding/package.json index 82811330..585f8031 100644 --- a/examples/vue/scroll-padding/package.json +++ b/examples/vue/scroll-padding/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "@vueuse/core": "^12.8.2", "vue": "^3.5.16" }, diff --git a/examples/vue/smooth-scroll/package.json b/examples/vue/smooth-scroll/package.json index 2d9e16c1..d67a8bbf 100644 --- a/examples/vue/smooth-scroll/package.json +++ b/examples/vue/smooth-scroll/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/sticky/package.json b/examples/vue/sticky/package.json index 37a46bf1..3c0013d1 100644 --- a/examples/vue/sticky/package.json +++ b/examples/vue/sticky/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@faker-js/faker": "^8.4.1", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "lodash": "^4.17.21", "vue": "^3.5.16" }, diff --git a/examples/vue/table/package.json b/examples/vue/table/package.json index 1b097983..0776776b 100644 --- a/examples/vue/table/package.json +++ b/examples/vue/table/package.json @@ -10,7 +10,7 @@ "dependencies": { "@faker-js/faker": "^8.4.1", "@tanstack/vue-table": "^8.21.3", - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/variable/package.json b/examples/vue/variable/package.json index 3539f7c9..4f562002 100644 --- a/examples/vue/variable/package.json +++ b/examples/vue/variable/package.json @@ -8,7 +8,7 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/vue-virtual": "^3.13.24", + "@tanstack/vue-virtual": "^3.13.25", "vue": "^3.5.16" }, "devDependencies": { diff --git a/packages/angular-virtual/CHANGELOG.md b/packages/angular-virtual/CHANGELOG.md index 397ff67d..6468d502 100644 --- a/packages/angular-virtual/CHANGELOG.md +++ b/packages/angular-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/angular-virtual +## 5.0.1 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 5.0.0 ### Major Changes diff --git a/packages/angular-virtual/package.json b/packages/angular-virtual/package.json index fecdc71f..8273490e 100644 --- a/packages/angular-virtual/package.json +++ b/packages/angular-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/angular-virtual", - "version": "5.0.0", + "version": "5.0.1", "description": "Headless UI for virtualizing scrollable elements in Angular", "author": "Garrett Darnell", "license": "MIT", diff --git a/packages/lit-virtual/CHANGELOG.md b/packages/lit-virtual/CHANGELOG.md index cdf1fac8..2a20701d 100644 --- a/packages/lit-virtual/CHANGELOG.md +++ b/packages/lit-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/lit-virtual +## 3.13.26 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.25 ### Patch Changes diff --git a/packages/lit-virtual/package.json b/packages/lit-virtual/package.json index b1afa120..825e3290 100644 --- a/packages/lit-virtual/package.json +++ b/packages/lit-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/lit-virtual", - "version": "3.13.25", + "version": "3.13.26", "description": "Headless UI for virtualizing scrollable elements in Lit", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/react-virtual/CHANGELOG.md b/packages/react-virtual/CHANGELOG.md index 3cb1d2a4..1fb8189c 100644 --- a/packages/react-virtual/CHANGELOG.md +++ b/packages/react-virtual/CHANGELOG.md @@ -1,5 +1,17 @@ # @tanstack/react-virtual +## 3.13.25 + +### Patch Changes + +- Replace the `useReducer(() => ({}), {})` force-rerender pattern with an ([#1168](https://github.com/TanStack/virtual/pull/1168)) + incrementing number counter. Same semantics (every dispatch changes the + reducer state, forcing a render); zero per-dispatch object allocation. + Trivial individual cost, but eliminates one steady-state GC source on + scroll-heavy apps. +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/react-virtual/package.json b/packages/react-virtual/package.json index 096f654a..0e867e07 100644 --- a/packages/react-virtual/package.json +++ b/packages/react-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in React", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/solid-virtual/CHANGELOG.md b/packages/solid-virtual/CHANGELOG.md index 676902a2..866442c9 100644 --- a/packages/solid-virtual/CHANGELOG.md +++ b/packages/solid-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/solid-virtual +## 3.13.25 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/solid-virtual/package.json b/packages/solid-virtual/package.json index ba884dfe..75b8351b 100644 --- a/packages/solid-virtual/package.json +++ b/packages/solid-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in Solid", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/svelte-virtual/CHANGELOG.md b/packages/svelte-virtual/CHANGELOG.md index a81b06b4..7b05ae82 100644 --- a/packages/svelte-virtual/CHANGELOG.md +++ b/packages/svelte-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/svelte-virtual +## 3.13.25 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/svelte-virtual/package.json b/packages/svelte-virtual/package.json index f6fdefb7..993bb06e 100644 --- a/packages/svelte-virtual/package.json +++ b/packages/svelte-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in Svelte", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/virtual-core/CHANGELOG.md b/packages/virtual-core/CHANGELOG.md index dafdafe4..f812e332 100644 --- a/packages/virtual-core/CHANGELOG.md +++ b/packages/virtual-core/CHANGELOG.md @@ -1,5 +1,137 @@ # @tanstack/virtual-core +## 3.15.0 + +### Minor Changes + +- iOS Safari momentum-scroll handling. Writing `scrollTop` while a finger ([#1168](https://github.com/TanStack/virtual/pull/1168)) + is on the screen, during momentum decay, or while the page is in the + elastic-overscroll bounce zone all cancel the in-flight scroll in iOS + WebKit. The virtualizer previously had no iOS-specific handling, which + manifested as the recurring "scroll abruptly stops when content above + resizes" complaints on Safari mobile. + + Adds three layers of protection, default-on, all transparent to + consumers: + - **Touch event distinction.** A touchstart→touchend window plus a + 150 ms grace timer for the early-momentum phase. Scroll-position + adjustments triggered during any of these states accumulate into a + `_iosDeferredAdjustment` field instead of writing `scrollTop`. + - **Subpixel reconciliation.** When the browser reports back a rounded + `scrollTop` within 1.5 px of a value we just wrote, the virtualizer + prefers the intended value rather than treating the round-trip as a + user scroll. + - **Elastic-overscroll clamp.** The deferred-adjustment flush is skipped + when `scrollTop` is outside `[0, scrollHeight - clientHeight]`, + preventing a snap-back jolt at end-of-bounce. The next in-bounds + scroll event retries. + + Non-iOS code paths are unchanged. iOS detection is SSR-safe and cached + after first call. Bundle cost is ~370 B gzip in the consumer-minified + production build — kept default-on because iOS Safari is a large share + of mobile traffic for the apps that use virtualization heavily. + +- Skip the scroll-position adjustment while the user is scrolling backward ([#1168](https://github.com/TanStack/virtual/pull/1168)) + by default. When an above-viewport item resizes during backward scroll + (images load, content reflows, etc.) the prior behavior wrote `scrollTop` + to keep the visible window stable — but on backward scroll that write + fights the user's direction and produces visible "items jump up while I + scroll up" jank. This was the largest single complaint cluster in the + issue tracker (multiple recurring threads spanning years; users had + independently rediscovered the same workaround at least five times). + + Forward-scroll and idle (mount-time) adjustments still fire as before + to preserve visual stability of the visible window. Consumers who want + the old behavior — adjusting on every above-viewport resize regardless + of direction — can supply `shouldAdjustScrollPositionOnItemSizeChange` + which is checked before the default branch. + +- Add `takeSnapshot()` instance method for scroll-restoration round-trips. ([#1168](https://github.com/TanStack/virtual/pull/1168)) + Returns the currently-measured items as plain `VirtualItem` objects; + pair with the current `scrollOffset` to persist scroll position across + remounts (route navigation, list-view modals, etc.). The result feeds + back through the existing `initialMeasurementsCache` option: + + ```tsx + const snapshot = virtualizer.takeSnapshot() + const offset = virtualizer.scrollOffset + // later, on remount: + useVirtualizer({ + // … + initialMeasurementsCache: snapshot, + initialOffset: offset, + }) + ``` + + Closes the gap to virtua's `takeCacheSnapshot()` and react-virtuoso's + `getState`. Only items actually rendered (and thus measured) are + included; unmeasured items fall back to `estimateSize` on restore. + +- Mount-time, measurement, and memory rewrite for huge lists. The hot path ([#1168](https://github.com/TanStack/virtual/pull/1168)) + through `getMeasurements()` no longer allocates a `VirtualItem` object per + index for single-lane lists; instead it fills a `Float64Array` of + start/size pairs and materializes `VirtualItem` objects lazily through a + `Proxy`-backed view when consumers index into them. Internal hot paths + (`calculateRange`, `getVirtualItemForOffset`, `getTotalSize`, `resizeItem`) + read directly from the typed-array storage to avoid the Proxy. + + Also collapses a chain of smaller hotspots discovered in an audit pass: + the per-resize `Map` clone in `resizeItem`, the `Object.entries+delete` + deopt in `setOptions`, the `Math.min(...pendingMeasuredCacheIndexes)` + spread, the `defaultRangeExtractor` `push` growth pattern, the eager + `measurementsCache` reference invalidation, and the leaked `elementsCache` + entries when a `ResizeObserver` fires for a node React already replaced. + + Headline impact (measured against actual `Virtualizer` instances with + vitest bench): + - Cold mount @ 100k items: ~2.5 ms → ~0.5 ms (4.7×) + - Cold mount @ 500k items: ~14 ms → ~2.7 ms (5.2×) + - `resizeItem` storm of 10,000 measurements + final `getMeasurements`: + ~1.9 s → ~1.3 ms (≈1382×) — this was the dominant `Map`-clone bug + - `setOptions` × 10,000 calls (React-render-storm proxy): ~14 ms → ~1.3 ms + (11×) + + The lanes>1 path keeps the previous eager allocation (lane assignment is + order-dependent and harder to defer cleanly); behavior is unchanged + there. + + No public API change. `measurementsCache` is still an + `Array`-shaped value supporting `[i]`, `.length`, iteration, + etc. Internal consumers that previously read fields off `VirtualItem` + objects continue to do so transparently. + +### Patch Changes + +- `scrollToIndex(N, { behavior: 'smooth' })` on a dynamic-height list no ([#1168](https://github.com/TanStack/virtual/pull/1168)) + longer snaps to `behavior: 'auto'` the moment a measurement shifts the + computed target offset. While the scroll is still more than a viewport + away from the new target, smooth scroll continues with the updated + endpoint; only on the final approach do we fall back to 'auto' for + precise landing. The user-visible effect is one continuous smooth + motion that subtly adjusts its endpoint as measurements arrive, + instead of the prior animation-then-snap pattern. + + Also: once `reconcileScroll` reaches its stable-frames threshold, it + writes the exact target offset one final time. This is a no-op when + `scrollTop` already equals the target (the common case) but corrects + the rare subpixel-rounding case where smooth scroll undershoots by + less than 1 px. + +- Don't call `getItemKey` with a possibly-stale index when cleaning up ([#1168](https://github.com/TanStack/virtual/pull/1168)) + `elementsCache` for a disconnected node. The cleanup now finds the + matching entry by node identity, so removing items from the end of + the list while a `ResizeObserver` still has the now-detached node + queued no longer throws (regression of #1148). + +- Two correctness fixes in the new code: ([#1168](https://github.com/TanStack/virtual/pull/1168)) + - `measure()` now resets `pendingMin` so a prior `resizeItem()` that left + it non-null can't preserve stale `measurementsCache` entries before that + index. The next rebuild is guaranteed to start at 0. + - The iOS deferred-adjustment flush now rolls its accumulated delta into + `scrollAdjustments`. Without this, a resize landing between the flush + and the resulting scroll event would compute the next correction from + the stale pre-flush offset. + ## 3.14.0 ### Minor Changes diff --git a/packages/virtual-core/package.json b/packages/virtual-core/package.json index 98e97e4e..603a65c7 100644 --- a/packages/virtual-core/package.json +++ b/packages/virtual-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/virtual-core", - "version": "3.14.0", + "version": "3.15.0", "description": "Headless UI for virtualizing scrollable elements in TS/JS + Frameworks", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/vue-virtual/CHANGELOG.md b/packages/vue-virtual/CHANGELOG.md index 526efddc..5a0a8b22 100644 --- a/packages/vue-virtual/CHANGELOG.md +++ b/packages/vue-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/vue-virtual +## 3.13.25 + +### Patch Changes + +- Updated dependencies [[`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2), [`99355ad`](https://github.com/TanStack/virtual/commit/99355ad1eceee6270efaa26e51f535d8d7c31ac2)]: + - @tanstack/virtual-core@3.15.0 + ## 3.13.24 ### Patch Changes diff --git a/packages/vue-virtual/package.json b/packages/vue-virtual/package.json index f57a1b39..060f17da 100644 --- a/packages/vue-virtual/package.json +++ b/packages/vue-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/vue-virtual", - "version": "3.13.24", + "version": "3.13.25", "description": "Headless UI for virtualizing scrollable elements in Vue", "author": "Tanner Linsley", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e19d5ffe..415ad769 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -142,7 +142,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -194,7 +194,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -249,7 +249,7 @@ importers: specifier: 5.80.7 version: 5.80.7(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -301,7 +301,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -353,7 +353,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -408,7 +408,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -466,7 +466,7 @@ importers: specifier: 8.21.3 version: 8.21.3(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -518,7 +518,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -570,7 +570,7 @@ importers: specifier: ^19.0.0 version: 19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.20(@angular/animations@19.2.20(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.20(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.20(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^5.0.0 + specifier: ^5.0.1 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -601,10 +601,10 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/lit-virtual': - specifier: ^3.13.25 + specifier: ^3.13.26 version: link:../../../packages/lit-virtual '@tanstack/virtual-core': - specifier: ^3.14.0 + specifier: ^3.15.0 version: link:../../../packages/virtual-core lit: specifier: ^3.3.0 @@ -626,10 +626,10 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/lit-virtual': - specifier: ^3.13.25 + specifier: ^3.13.26 version: link:../../../packages/lit-virtual '@tanstack/virtual-core': - specifier: ^3.14.0 + specifier: ^3.15.0 version: link:../../../packages/virtual-core lit: specifier: ^3.3.0 @@ -651,7 +651,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -682,7 +682,7 @@ importers: examples/react/fixed: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -716,7 +716,7 @@ importers: specifier: ^5.80.7 version: 5.90.5(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -741,7 +741,7 @@ importers: examples/react/padding: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -769,7 +769,7 @@ importers: specifier: ^25.1.1 version: 25.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -794,7 +794,7 @@ importers: examples/react/smooth-scroll: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -822,7 +822,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual lodash: specifier: ^4.17.21 @@ -859,7 +859,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -884,7 +884,7 @@ importers: examples/react/variable: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -909,7 +909,7 @@ importers: examples/react/window: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -943,7 +943,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -971,7 +971,7 @@ importers: examples/svelte/fixed: dependencies: '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1002,7 +1002,7 @@ importers: specifier: ^5.80.7 version: 5.90.2(svelte@4.2.20) '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1033,7 +1033,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1064,7 +1064,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual lodash: specifier: ^4.17.21 @@ -1101,7 +1101,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(svelte@4.2.20) '@tanstack/svelte-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1132,7 +1132,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1157,7 +1157,7 @@ importers: examples/vue/fixed: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1185,7 +1185,7 @@ importers: specifier: ^5.80.7 version: 5.90.5(vue@3.5.22(typescript@5.6.3)) '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1210,7 +1210,7 @@ importers: examples/vue/padding: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1235,7 +1235,7 @@ importers: examples/vue/scroll-padding: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual '@vueuse/core': specifier: ^12.8.2 @@ -1263,7 +1263,7 @@ importers: examples/vue/smooth-scroll: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1291,7 +1291,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual lodash: specifier: ^4.17.21 @@ -1328,7 +1328,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(vue@3.5.22(typescript@5.6.3)) '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1353,7 +1353,7 @@ importers: examples/vue/variable: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.24 + specifier: ^3.13.25 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16