Files
ThreadNet-Web/patches/@tanstack__virtual-core@3.17.6.patch
T

48 lines
2.7 KiB
Diff
Raw Normal View History

diff --git a/dist/esm/index.d.ts b/dist/esm/index.d.ts
index 387489bd25c9ebcf6afd97df5e741706fbdec65d..0e9961bb69b411824ba91f56694774e801d599c4 100644
--- a/dist/esm/index.d.ts
+++ b/dist/esm/index.d.ts
@@ -78,6 +78,12 @@ export interface VirtualizerOptions<TScrollElement extends Element | Window, TIt
initialMeasurementsCache?: Array<VirtualItem>;
lanes?: number;
anchorTo?: ScrollAnchor;
+ /**
+ * With `anchorTo: "end"`, reject an item as the scroll anchor (e.g. a transient
+ * placeholder/sentinel row whose key does not survive the update); anchoring
+ * steps inward to the nearest accepted item. Element-web patch, pending upstream.
+ */
+ isValidAnchorItem?: (item: VirtualItem) => boolean;
followOnAppend?: FollowOnAppend;
scrollEndThreshold?: number;
isScrollingResetDelay?: number;
diff --git a/dist/esm/index.js b/dist/esm/index.js
index 00fd4a4b0a0049193f8862c2604cb76013d605d5..37c058b25d30f42f82617d9cc4c2831bc0b13704 100644
--- a/dist/esm/index.js
+++ b/dist/esm/index.js
@@ -295,7 +295,24 @@ class Virtualizer {
const didEdgeKeysChange = didCountChange || prevCount > 0 && nextCount > 0 && (merged.getItemKey(0) !== prevFirstKey || merged.getItemKey(nextCount - 1) !== prevLastKey);
if (didEdgeKeysChange) {
edgeKeysChanged = true;
- const item = prevCount > 0 ? this.getVirtualItemForOffset(this.getScrollOffset()) ?? measurements[0] : null;
+ let item = prevCount > 0 ? this.getVirtualItemForOffset(this.getScrollOffset()) ?? measurements[0] : null;
+ // With anchorTo: "end" the scroll is re-pinned by the key of the item
+ // under the current offset. If the consumer rejects that item as an
+ // anchor via isValidAnchorItem — e.g. a transient placeholder/sentinel
+ // row (loading spinner, "load more", skeleton) whose key does not
+ // survive the update — re-pinning by its key would fail and the
+ // prepend would go uncompensated (the list jumps to the edge). Such
+ // rows only sit at the extreme edges, so step one index inward to the
+ // nearest accepted item, whose key persists across the update.
+ const isValidAnchorItem = merged.isValidAnchorItem;
+ if (item && isValidAnchorItem && !isValidAnchorItem(item)) {
+ const step = item.index === 0 ? 1 : -1;
+ let i = item.index;
+ while (i >= 0 && i < measurements.length && measurements[i] && !isValidAnchorItem(measurements[i])) {
+ i += step;
+ }
+ item = measurements[i] ?? item;
+ }
if (item) {
anchor = [item.key, this.getScrollOffset() - item.start];
}