Skip to content

Commit 96f4da7

Browse files
committed
patch @tanstack/virtual-core
There is a timing issue if the Virtualizer is enabled and disabled in rapid succession. This happens in our combobox when you see a list of items and quickly search for something which in turn filters the list and the options will become empty. The `scrollToIndex` checks if an element's DOM node is available (via the measurementsCache) but it also has an internal `setTimeout` where the same code is used, but it's not re-checking the measurementsCache cache. The measurementsCache is also cleared the moment the `enabled` prop becomes false. This means that there will be a split second where the `measurementsCache[x]` will be `undefined` even though it was not undefined moments ago. In this scenario, it's safe to just not scroll (yet), but instead the `@tanstack/virtual-core` is throwing an error via the `notUndefined` function. We unfortunately can't catch the error because it happens in a `setTimeout`... Instead of throwing, this patch ignores the result if it becomes `undefined`. This also means that we don't scroll to the item, but there is no item to scroll to in the first place.
1 parent b9c7abc commit 96f4da7

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
diff --git a/node_modules/@tanstack/virtual-core/dist/cjs/index.cjs b/node_modules/@tanstack/virtual-core/dist/cjs/index.cjs
2+
index dd4e77f..127987e 100644
3+
--- a/node_modules/@tanstack/virtual-core/dist/cjs/index.cjs
4+
+++ b/node_modules/@tanstack/virtual-core/dist/cjs/index.cjs
5+
@@ -665,9 +665,9 @@ class Virtualizer {
6+
this.options.getItemKey(index)
7+
);
8+
if (elementInDOM) {
9+
- const [latestOffset] = utils.notUndefined(
10+
- this.getOffsetForIndex(index, align)
11+
- );
12+
+ const result = this.getOffsetForIndex(index, align)
13+
+ if (!result) return
14+
+ const [latestOffset] = result
15+
if (!utils.approxEqual(latestOffset, this.getScrollOffset())) {
16+
this.scrollToIndex(index, { align, behavior });
17+
}
18+
diff --git a/node_modules/@tanstack/virtual-core/dist/esm/index.js b/node_modules/@tanstack/virtual-core/dist/esm/index.js
19+
index 8da519d..8c78af8 100644
20+
--- a/node_modules/@tanstack/virtual-core/dist/esm/index.js
21+
+++ b/node_modules/@tanstack/virtual-core/dist/esm/index.js
22+
@@ -663,9 +663,9 @@ class Virtualizer {
23+
this.options.getItemKey(index)
24+
);
25+
if (elementInDOM) {
26+
- const [latestOffset] = notUndefined(
27+
- this.getOffsetForIndex(index, align)
28+
- );
29+
+ const result = this.getOffsetForIndex(index, align)
30+
+ if (!result) return
31+
+ const [latestOffset] = result
32+
if (!approxEqual(latestOffset, this.getScrollOffset())) {
33+
this.scrollToIndex(index, { align, behavior });
34+
}
35+
diff --git a/node_modules/@tanstack/virtual-core/src/index.ts b/node_modules/@tanstack/virtual-core/src/index.ts
36+
index 3a0c446..4a9e792 100644
37+
--- a/node_modules/@tanstack/virtual-core/src/index.ts
38+
+++ b/node_modules/@tanstack/virtual-core/src/index.ts
39+
@@ -1003,9 +1003,9 @@ export class Virtualizer<
40+
)
41+
42+
if (elementInDOM) {
43+
- const [latestOffset] = notUndefined(
44+
- this.getOffsetForIndex(index, align),
45+
- )
46+
+ const result = this.getOffsetForIndex(index, align)
47+
+ if (!result) return
48+
+ const [latestOffset] = result
49+
50+
if (!approxEqual(latestOffset, this.getScrollOffset())) {
51+
this.scrollToIndex(index, { align, behavior })

0 commit comments

Comments
 (0)