diff --git a/examples/angular/dynamic/package.json b/examples/angular/dynamic/package.json index 047657530..5a7571184 100644 --- a/examples/angular/dynamic/package.json +++ b/examples/angular/dynamic/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 914b00561..ac586f423 100644 --- a/examples/angular/fixed/package.json +++ b/examples/angular/fixed/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 c32caa7e5..730f587aa 100644 --- a/examples/angular/infinite-scroll/package.json +++ b/examples/angular/infinite-scroll/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", "@tanstack/angular-query-experimental": "5.80.7", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 fed86557a..176730a46 100644 --- a/examples/angular/padding/package.json +++ b/examples/angular/padding/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 47395de09..6f85a2bca 100644 --- a/examples/angular/smooth-scroll/package.json +++ b/examples/angular/smooth-scroll/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 700ab4ca7..f0d1190a0 100644 --- a/examples/angular/sticky/package.json +++ b/examples/angular/sticky/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", "@faker-js/faker": "^8.4.1", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 e383a2754..99392a977 100644 --- a/examples/angular/table/package.json +++ b/examples/angular/table/package.json @@ -19,7 +19,7 @@ "@angular/router": "^18.1.0", "@faker-js/faker": "^8.4.1", "@tanstack/angular-table": "8.21.3", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 b7c5398fe..fbeda0e12 100644 --- a/examples/angular/variable/package.json +++ b/examples/angular/variable/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 976e6a2da..710c4cb40 100644 --- a/examples/angular/window/package.json +++ b/examples/angular/window/package.json @@ -17,7 +17,7 @@ "@angular/platform-browser": "^18.1.0", "@angular/platform-browser-dynamic": "^18.1.0", "@angular/router": "^18.1.0", - "@tanstack/angular-virtual": "^4.0.10", + "@tanstack/angular-virtual": "^4.0.11", "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 95bf69f48..648ba210a 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.23", - "@tanstack/virtual-core": "^3.13.22", + "@tanstack/lit-virtual": "^3.13.24", + "@tanstack/virtual-core": "^3.13.23", "lit": "^3.3.0" }, "devDependencies": { diff --git a/examples/lit/fixed/package.json b/examples/lit/fixed/package.json index be99beebe..b19a41370 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.23", - "@tanstack/virtual-core": "^3.13.22", + "@tanstack/lit-virtual": "^3.13.24", + "@tanstack/virtual-core": "^3.13.23", "lit": "^3.3.0" }, "devDependencies": { diff --git a/examples/react/dynamic/package.json b/examples/react/dynamic/package.json index a0952ffee..397a840bb 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.22", + "@tanstack/react-virtual": "^3.13.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/fixed/package.json b/examples/react/fixed/package.json index 9288d9988..c4ab6c483 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.22", + "@tanstack/react-virtual": "^3.13.23", "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 92f4ae7ff..b39fcff96 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.22", + "@tanstack/react-virtual": "^3.13.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/padding/package.json b/examples/react/padding/package.json index 67321e730..e3bc979e4 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.22", + "@tanstack/react-virtual": "^3.13.23", "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 c67488dc9..4e216c208 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.22", + "@tanstack/react-virtual": "^3.13.23", "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 38882c385..326ce52f6 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.22", + "@tanstack/react-virtual": "^3.13.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/sticky/package.json b/examples/react/sticky/package.json index b3a54c40b..a12958a0b 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.22", + "@tanstack/react-virtual": "^3.13.23", "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 bfdb6db34..3c54b5b76 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.22", + "@tanstack/react-virtual": "^3.13.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/variable/package.json b/examples/react/variable/package.json index 94ebfbeb9..6a5ec6c7c 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.22", + "@tanstack/react-virtual": "^3.13.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/react/window/package.json b/examples/react/window/package.json index 908176435..6ae5a8da6 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.22", + "@tanstack/react-virtual": "^3.13.23", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/examples/svelte/dynamic/package.json b/examples/svelte/dynamic/package.json index a174d7edf..2840879b6 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.22" + "@tanstack/svelte-virtual": "^3.13.23" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/fixed/package.json b/examples/svelte/fixed/package.json index 09dafe1e5..fc7e4b6d7 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.22" + "@tanstack/svelte-virtual": "^3.13.23" }, "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 fc06c7fdd..7df898cb7 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.22" + "@tanstack/svelte-virtual": "^3.13.23" }, "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 aa80ea584..2f86c2069 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.22" + "@tanstack/svelte-virtual": "^3.13.23" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/svelte/sticky/package.json b/examples/svelte/sticky/package.json index eeebf32f0..e36c1fca0 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.22", + "@tanstack/svelte-virtual": "^3.13.23", "lodash": "^4.17.21" }, "devDependencies": { diff --git a/examples/svelte/table/package.json b/examples/svelte/table/package.json index fdd56194a..8a44982b9 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.22" + "@tanstack/svelte-virtual": "^3.13.23" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.2", diff --git a/examples/vue/dynamic/package.json b/examples/vue/dynamic/package.json index 171247a36..762adaee3 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.22", + "@tanstack/vue-virtual": "^3.13.23", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/dynamic/src/components/ColumnVirtualizerDynamic.vue b/examples/vue/dynamic/src/components/ColumnVirtualizerDynamic.vue index 2006d1fa6..36d359a30 100644 --- a/examples/vue/dynamic/src/components/ColumnVirtualizerDynamic.vue +++ b/examples/vue/dynamic/src/components/ColumnVirtualizerDynamic.vue @@ -15,7 +15,7 @@ v-for="virtualColumn in virtualColumns" :key="virtualColumn.key" :data-index="virtualColumn.index" - :ref="measureElement" + ref="virtualItemEls" :class="virtualColumn.index % 2 ? 'ListItemOdd' : 'ListItemEven'" :style="{ position: 'absolute', @@ -35,7 +35,7 @@ diff --git a/examples/vue/dynamic/src/components/GridVirtualizerDynamic.vue b/examples/vue/dynamic/src/components/GridVirtualizerDynamic.vue index 98245e346..d11973a9d 100644 --- a/examples/vue/dynamic/src/components/GridVirtualizerDynamic.vue +++ b/examples/vue/dynamic/src/components/GridVirtualizerDynamic.vue @@ -9,7 +9,7 @@ diff --git a/examples/vue/dynamic/src/components/RowVirtualizerDynamicWindow.vue b/examples/vue/dynamic/src/components/RowVirtualizerDynamicWindow.vue index cb95e1474..f0cdc28ca 100644 --- a/examples/vue/dynamic/src/components/RowVirtualizerDynamicWindow.vue +++ b/examples/vue/dynamic/src/components/RowVirtualizerDynamicWindow.vue @@ -22,7 +22,7 @@ v-for="virtualRow in virtualRows" :key="virtualRow.key" :data-index="virtualRow.index" - :ref="measureElement" + ref="virtualItemEls" :class="virtualRow.index % 2 ? 'ListItemOdd' : 'ListItemEven'" >
@@ -36,7 +36,7 @@ diff --git a/examples/vue/fixed/package.json b/examples/vue/fixed/package.json index 6623a8e2a..fab980cc0 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.22", + "@tanstack/vue-virtual": "^3.13.23", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/infinite-scroll/package.json b/examples/vue/infinite-scroll/package.json index 82505b674..861684e63 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.22", + "@tanstack/vue-virtual": "^3.13.23", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/padding/package.json b/examples/vue/padding/package.json index 8ed7048c7..3a539e1fe 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.22", + "@tanstack/vue-virtual": "^3.13.23", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/scroll-padding/package.json b/examples/vue/scroll-padding/package.json index 46a7d31ff..fe09ce10d 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.22", + "@tanstack/vue-virtual": "^3.13.23", "@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 f88099691..7238c2b8c 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.22", + "@tanstack/vue-virtual": "^3.13.23", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/sticky/package.json b/examples/vue/sticky/package.json index 5d8c59eba..016ae66c9 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.22", + "@tanstack/vue-virtual": "^3.13.23", "lodash": "^4.17.21", "vue": "^3.5.16" }, diff --git a/examples/vue/table/package.json b/examples/vue/table/package.json index 2a7872a98..5df010c8e 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.22", + "@tanstack/vue-virtual": "^3.13.23", "vue": "^3.5.16" }, "devDependencies": { diff --git a/examples/vue/variable/package.json b/examples/vue/variable/package.json index 8b1f5d1e1..b9c90231d 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.22", + "@tanstack/vue-virtual": "^3.13.23", "vue": "^3.5.16" }, "devDependencies": { diff --git a/packages/angular-virtual/CHANGELOG.md b/packages/angular-virtual/CHANGELOG.md index 1c725d22b..93aab437d 100644 --- a/packages/angular-virtual/CHANGELOG.md +++ b/packages/angular-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/angular-virtual +## 4.0.11 + +### Patch Changes + +- Updated dependencies [[`7ece2d5`](https://github.com/TanStack/virtual/commit/7ece2d5d4249b7e703c68ac497ae5545c54e7c67)]: + - @tanstack/virtual-core@3.13.23 + ## 4.0.10 ### Patch Changes diff --git a/packages/angular-virtual/package.json b/packages/angular-virtual/package.json index ba55cc7df..96f38aeb1 100644 --- a/packages/angular-virtual/package.json +++ b/packages/angular-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/angular-virtual", - "version": "4.0.10", + "version": "4.0.11", "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 69ef1c2b7..48c9f51c8 100644 --- a/packages/lit-virtual/CHANGELOG.md +++ b/packages/lit-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/lit-virtual +## 3.13.24 + +### Patch Changes + +- Updated dependencies [[`7ece2d5`](https://github.com/TanStack/virtual/commit/7ece2d5d4249b7e703c68ac497ae5545c54e7c67)]: + - @tanstack/virtual-core@3.13.23 + ## 3.13.23 ### Patch Changes diff --git a/packages/lit-virtual/package.json b/packages/lit-virtual/package.json index fdbb398eb..a6970e5d2 100644 --- a/packages/lit-virtual/package.json +++ b/packages/lit-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/lit-virtual", - "version": "3.13.23", + "version": "3.13.24", "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 49ecc5210..879ae10e5 100644 --- a/packages/react-virtual/CHANGELOG.md +++ b/packages/react-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/react-virtual +## 3.13.23 + +### Patch Changes + +- Updated dependencies [[`7ece2d5`](https://github.com/TanStack/virtual/commit/7ece2d5d4249b7e703c68ac497ae5545c54e7c67)]: + - @tanstack/virtual-core@3.13.23 + ## 3.13.22 ### Patch Changes diff --git a/packages/react-virtual/e2e/app/stale-index/index.html b/packages/react-virtual/e2e/app/stale-index/index.html new file mode 100644 index 000000000..56f418f61 --- /dev/null +++ b/packages/react-virtual/e2e/app/stale-index/index.html @@ -0,0 +1,10 @@ + + + + + + +
+ + + diff --git a/packages/react-virtual/e2e/app/stale-index/main.tsx b/packages/react-virtual/e2e/app/stale-index/main.tsx new file mode 100644 index 000000000..13fe85e19 --- /dev/null +++ b/packages/react-virtual/e2e/app/stale-index/main.tsx @@ -0,0 +1,95 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import { useVirtualizer } from '@tanstack/react-virtual' + +/** + * Regression test app for stale index bug: + * When items are removed from the end of the list, the ResizeObserver may fire + * for a disconnected node whose data-index >= the new count. If getItemKey + * indexes into the items array, this causes an out-of-bounds error. + */ + +interface Item { + id: string + label: string +} + +function makeItems(count: number): Array { + return Array.from({ length: count }, (_, i) => ({ + id: `item-${i}`, + label: `Row ${i}`, + })) +} + +const App = () => { + const parentRef = React.useRef(null) + const [items, setItems] = React.useState(() => makeItems(20)) + const [error, setError] = React.useState(null) + + const rowVirtualizer = useVirtualizer({ + count: items.length, + getScrollElement: () => parentRef.current, + estimateSize: () => 50, + getItemKey: (index) => { + if (index < 0 || index >= items.length) { + const msg = `getItemKey called with stale index ${index} (count=${items.length})` + setError(msg) + throw new Error(msg) + } + return items[index].id + }, + }) + + const removeLastFive = () => { + setItems((prev) => prev.slice(0, Math.max(0, prev.length - 5))) + } + + return ( +
+ +
Count: {items.length}
+ {error &&
{error}
} +
+
+ {rowVirtualizer.getVirtualItems().map((v) => { + const item = items[v.index] + return ( +
+ {item.label} +
+ ) + })} +
+
+
+ ) +} + +ReactDOM.createRoot(document.getElementById('root')!).render() diff --git a/packages/react-virtual/e2e/app/test/stale-index.spec.ts b/packages/react-virtual/e2e/app/test/stale-index.spec.ts new file mode 100644 index 000000000..fcf7d93e8 --- /dev/null +++ b/packages/react-virtual/e2e/app/test/stale-index.spec.ts @@ -0,0 +1,38 @@ +import { expect, test } from '@playwright/test' + +test('does not call getItemKey with stale index after removing items', async ({ + page, +}) => { + await page.goto('/stale-index/') + + // Verify initial state + await expect(page.locator('[data-testid="item-count"]')).toHaveText( + 'Count: 20', + ) + + // Scroll to the bottom so the last items are rendered and observed by ResizeObserver + const container = page.locator('[data-testid="scroll-container"]') + await container.evaluate((el) => (el.scrollTop = el.scrollHeight)) + await page.waitForTimeout(100) + + // Remove 5 items from the end — the RO may still fire for the now-disconnected nodes + await page.click('[data-testid="remove-items"]') + await expect(page.locator('[data-testid="item-count"]')).toHaveText( + 'Count: 15', + ) + + // Wait for any pending ResizeObserver callbacks + await page.waitForTimeout(200) + + // No error should have been thrown + await expect(page.locator('[data-testid="error"]')).not.toBeVisible() + + // Remove 5 more to stress it + await page.click('[data-testid="remove-items"]') + await expect(page.locator('[data-testid="item-count"]')).toHaveText( + 'Count: 10', + ) + await page.waitForTimeout(200) + + await expect(page.locator('[data-testid="error"]')).not.toBeVisible() +}) diff --git a/packages/react-virtual/e2e/app/vite.config.ts b/packages/react-virtual/e2e/app/vite.config.ts index 005ecd9c0..64183e497 100644 --- a/packages/react-virtual/e2e/app/vite.config.ts +++ b/packages/react-virtual/e2e/app/vite.config.ts @@ -14,6 +14,7 @@ export default defineConfig({ 'measure-element/index.html', ), 'smooth-scroll': path.resolve(__dirname, 'smooth-scroll/index.html'), + 'stale-index': path.resolve(__dirname, 'stale-index/index.html'), }, }, }, diff --git a/packages/react-virtual/package.json b/packages/react-virtual/package.json index 2dd94fcf1..e96b17690 100644 --- a/packages/react-virtual/package.json +++ b/packages/react-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-virtual", - "version": "3.13.22", + "version": "3.13.23", "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 bb3ece8e7..a9a3383ea 100644 --- a/packages/solid-virtual/CHANGELOG.md +++ b/packages/solid-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/solid-virtual +## 3.13.23 + +### Patch Changes + +- Updated dependencies [[`7ece2d5`](https://github.com/TanStack/virtual/commit/7ece2d5d4249b7e703c68ac497ae5545c54e7c67)]: + - @tanstack/virtual-core@3.13.23 + ## 3.13.22 ### Patch Changes diff --git a/packages/solid-virtual/package.json b/packages/solid-virtual/package.json index c443b9ac2..2adcb7a96 100644 --- a/packages/solid-virtual/package.json +++ b/packages/solid-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-virtual", - "version": "3.13.22", + "version": "3.13.23", "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 579fe469b..b13e4cdbd 100644 --- a/packages/svelte-virtual/CHANGELOG.md +++ b/packages/svelte-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/svelte-virtual +## 3.13.23 + +### Patch Changes + +- Updated dependencies [[`7ece2d5`](https://github.com/TanStack/virtual/commit/7ece2d5d4249b7e703c68ac497ae5545c54e7c67)]: + - @tanstack/virtual-core@3.13.23 + ## 3.13.22 ### Patch Changes diff --git a/packages/svelte-virtual/package.json b/packages/svelte-virtual/package.json index 08e8ea0b1..dbd098a9f 100644 --- a/packages/svelte-virtual/package.json +++ b/packages/svelte-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-virtual", - "version": "3.13.22", + "version": "3.13.23", "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 e171a211d..b027b9874 100644 --- a/packages/virtual-core/CHANGELOG.md +++ b/packages/virtual-core/CHANGELOG.md @@ -1,5 +1,11 @@ # @tanstack/virtual-core +## 3.13.23 + +### Patch Changes + +- fix(virtual-core): remove incorrect elementsCache cleanup using getItemKey ([#1148](https://github.com/TanStack/virtual/pull/1148)) + ## 3.13.22 ### Patch Changes diff --git a/packages/virtual-core/package.json b/packages/virtual-core/package.json index b0104ca28..0f81f175b 100644 --- a/packages/virtual-core/package.json +++ b/packages/virtual-core/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/virtual-core", - "version": "3.13.22", + "version": "3.13.23", "description": "Headless UI for virtualizing scrollable elements in TS/JS + Frameworks", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/virtual-core/src/index.ts b/packages/virtual-core/src/index.ts index 8cd53a814..64e9bd6d5 100644 --- a/packages/virtual-core/src/index.ts +++ b/packages/virtual-core/src/index.ts @@ -414,7 +414,6 @@ export class Virtualizer< if (!node.isConnected) { this.observer.unobserve(node) - this.elementsCache.delete(this.options.getItemKey(index)) return } diff --git a/packages/vue-virtual/CHANGELOG.md b/packages/vue-virtual/CHANGELOG.md index 7be5b460c..7f637dcce 100644 --- a/packages/vue-virtual/CHANGELOG.md +++ b/packages/vue-virtual/CHANGELOG.md @@ -1,5 +1,12 @@ # @tanstack/vue-virtual +## 3.13.23 + +### Patch Changes + +- Updated dependencies [[`7ece2d5`](https://github.com/TanStack/virtual/commit/7ece2d5d4249b7e703c68ac497ae5545c54e7c67)]: + - @tanstack/virtual-core@3.13.23 + ## 3.13.22 ### Patch Changes diff --git a/packages/vue-virtual/package.json b/packages/vue-virtual/package.json index 65ef11cdd..2b330adf4 100644 --- a/packages/vue-virtual/package.json +++ b/packages/vue-virtual/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/vue-virtual", - "version": "3.13.22", + "version": "3.13.23", "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 3a55d917a..477433eb1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,7 +102,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -154,7 +154,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -209,7 +209,7 @@ importers: specifier: 5.80.7 version: 5.80.7(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -261,7 +261,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -313,7 +313,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -368,7 +368,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -426,7 +426,7 @@ importers: specifier: 8.21.3 version: 8.21.3(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)) '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -478,7 +478,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -530,7 +530,7 @@ importers: specifier: ^18.1.0 version: 18.2.14(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@18.2.14(@angular/animations@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@18.2.14(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@18.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@tanstack/angular-virtual': - specifier: ^4.0.10 + specifier: ^4.0.11 version: link:../../../packages/angular-virtual rxjs: specifier: ^7.8.2 @@ -561,10 +561,10 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/lit-virtual': - specifier: ^3.13.23 + specifier: ^3.13.24 version: link:../../../packages/lit-virtual '@tanstack/virtual-core': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/virtual-core lit: specifier: ^3.3.0 @@ -586,10 +586,10 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/lit-virtual': - specifier: ^3.13.23 + specifier: ^3.13.24 version: link:../../../packages/lit-virtual '@tanstack/virtual-core': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/virtual-core lit: specifier: ^3.3.0 @@ -611,7 +611,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -642,7 +642,7 @@ importers: examples/react/fixed: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -676,7 +676,7 @@ importers: specifier: ^5.80.7 version: 5.90.5(react@18.3.1) '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -701,7 +701,7 @@ importers: examples/react/padding: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -729,7 +729,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.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -754,7 +754,7 @@ importers: examples/react/smooth-scroll: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -782,7 +782,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual lodash: specifier: ^4.17.21 @@ -819,7 +819,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.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -844,7 +844,7 @@ importers: examples/react/variable: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -869,7 +869,7 @@ importers: examples/react/window: dependencies: '@tanstack/react-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/react-virtual react: specifier: ^18.3.1 @@ -903,7 +903,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -931,7 +931,7 @@ importers: examples/svelte/fixed: dependencies: '@tanstack/svelte-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -962,7 +962,7 @@ importers: specifier: ^5.80.7 version: 5.90.2(svelte@4.2.20) '@tanstack/svelte-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -993,7 +993,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1024,7 +1024,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/svelte-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/svelte-virtual lodash: specifier: ^4.17.21 @@ -1061,7 +1061,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(svelte@4.2.20) '@tanstack/svelte-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/svelte-virtual devDependencies: '@sveltejs/vite-plugin-svelte': @@ -1092,7 +1092,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1117,7 +1117,7 @@ importers: examples/vue/fixed: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1145,7 +1145,7 @@ importers: specifier: ^5.80.7 version: 5.90.5(vue@3.5.22(typescript@5.4.5)) '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1170,7 +1170,7 @@ importers: examples/vue/padding: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1195,7 +1195,7 @@ importers: examples/vue/scroll-padding: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual '@vueuse/core': specifier: ^12.8.2 @@ -1223,7 +1223,7 @@ importers: examples/vue/smooth-scroll: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1251,7 +1251,7 @@ importers: specifier: ^8.4.1 version: 8.4.1 '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual lodash: specifier: ^4.17.21 @@ -1288,7 +1288,7 @@ importers: specifier: ^8.21.3 version: 8.21.3(vue@3.5.22(typescript@5.4.5)) '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16 @@ -1313,7 +1313,7 @@ importers: examples/vue/variable: dependencies: '@tanstack/vue-virtual': - specifier: ^3.13.22 + specifier: ^3.13.23 version: link:../../../packages/vue-virtual vue: specifier: ^3.5.16