@humanspeak/svelte-virtual-list 0.3.11 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -647,8 +647,15 @@
|
|
|
647
647
|
lastMeasuredIndex,
|
|
648
648
|
heightManager.averageHeight,
|
|
649
649
|
(result) => {
|
|
650
|
-
//
|
|
651
|
-
|
|
650
|
+
// Only update the estimated item height from statistically meaningful
|
|
651
|
+
// samples. With _measuredCount === 0 (browser path), the formula
|
|
652
|
+
// _totalHeight = _itemLength × _itemHeight means a single expanded
|
|
653
|
+
// accordion item (e.g., 117px) would balloon _totalHeight from
|
|
654
|
+
// 49,000 to 117,000px — a visible flash. Requiring ≥ 2 valid
|
|
655
|
+
// measurements prevents single-item outliers from swinging the estimate.
|
|
656
|
+
if (result.newValidCount !== 1) {
|
|
657
|
+
heightManager.itemHeight = result.newHeight
|
|
658
|
+
}
|
|
652
659
|
lastMeasuredIndex = result.newLastMeasuredIndex
|
|
653
660
|
|
|
654
661
|
// Update manager totals/cache before any scroll correction logic relies on them
|
|
@@ -697,7 +704,7 @@
|
|
|
697
704
|
})
|
|
698
705
|
heightManager.endDynamicUpdate()
|
|
699
706
|
},
|
|
700
|
-
lastMeasuredIndex < 0 ? 0 : 100, // debounceTime (no debounce on first pass)
|
|
707
|
+
lastMeasuredIndex < 0 || dirtyItems.size > 0 ? 0 : 100, // debounceTime (no debounce on first pass or when dirty items exist)
|
|
701
708
|
dirtyItems, // Pass dirty items for processing
|
|
702
709
|
0, // Don't pass ReactiveListManager state - let each system manage its own totals
|
|
703
710
|
0, // Don't pass ReactiveListManager state - let each system manage its own totals
|
|
@@ -1616,6 +1623,7 @@
|
|
|
1616
1623
|
class={viewportClass ?? 'virtual-list-viewport'}
|
|
1617
1624
|
bind:this={heightManager.viewportElement}
|
|
1618
1625
|
onscroll={handleScroll}
|
|
1626
|
+
style:overflow-anchor="none"
|
|
1619
1627
|
>
|
|
1620
1628
|
<!-- Content provides full scrollable height -->
|
|
1621
1629
|
<div
|
|
@@ -126,20 +126,24 @@ export declare class ReactiveListManager {
|
|
|
126
126
|
*/
|
|
127
127
|
get isDynamicUpdateInProgress(): boolean;
|
|
128
128
|
/**
|
|
129
|
-
* Begin a dynamic update. Handles nested calls: the first call
|
|
130
|
-
* subsequent calls just increment depth. Safe to call when not wired; styles
|
|
131
|
-
* when both container and viewport are ready.
|
|
129
|
+
* Begin a dynamic update. Handles nested calls: the first call ensures UA scroll anchoring
|
|
130
|
+
* is disabled, subsequent calls just increment depth. Safe to call when not wired; styles
|
|
131
|
+
* are only set when both container and viewport are ready.
|
|
132
|
+
*
|
|
133
|
+
* Note: overflow-anchor is kept permanently as 'none' to prevent browser scroll anchoring
|
|
134
|
+
* from interfering with the virtual list's own scroll correction logic.
|
|
132
135
|
*/
|
|
133
136
|
startDynamicUpdate(): void;
|
|
134
137
|
/**
|
|
135
138
|
* End a dynamic update started by `startDynamicUpdate`. Handles nesting: only the final
|
|
136
|
-
* corresponding end call
|
|
139
|
+
* corresponding end call completes the update. overflow-anchor remains 'none' permanently.
|
|
140
|
+
* Guards against underflow.
|
|
137
141
|
*/
|
|
138
142
|
endDynamicUpdate(): void;
|
|
139
143
|
/**
|
|
140
|
-
* Run a dynamic update with UA scroll anchoring disabled
|
|
141
|
-
* Accepts a sync or async function and ensures `overflow-anchor`
|
|
142
|
-
*
|
|
144
|
+
* Run a dynamic update with UA scroll anchoring disabled.
|
|
145
|
+
* Accepts a sync or async function and ensures `overflow-anchor` stays 'none'
|
|
146
|
+
* throughout. If the manager isn't ready yet, it simply executes `fn`.
|
|
143
147
|
*/
|
|
144
148
|
runDynamicUpdate<T>(fn: () => T | Promise<T>): Promise<T>;
|
|
145
149
|
/**
|
|
@@ -241,9 +241,12 @@ export class ReactiveListManager {
|
|
|
241
241
|
return this._dynamicUpdateDepth > 0;
|
|
242
242
|
}
|
|
243
243
|
/**
|
|
244
|
-
* Begin a dynamic update. Handles nested calls: the first call
|
|
245
|
-
* subsequent calls just increment depth. Safe to call when not wired; styles
|
|
246
|
-
* when both container and viewport are ready.
|
|
244
|
+
* Begin a dynamic update. Handles nested calls: the first call ensures UA scroll anchoring
|
|
245
|
+
* is disabled, subsequent calls just increment depth. Safe to call when not wired; styles
|
|
246
|
+
* are only set when both container and viewport are ready.
|
|
247
|
+
*
|
|
248
|
+
* Note: overflow-anchor is kept permanently as 'none' to prevent browser scroll anchoring
|
|
249
|
+
* from interfering with the virtual list's own scroll correction logic.
|
|
247
250
|
*/
|
|
248
251
|
startDynamicUpdate() {
|
|
249
252
|
const isOuter = this._dynamicUpdateDepth === 0;
|
|
@@ -257,7 +260,8 @@ export class ReactiveListManager {
|
|
|
257
260
|
}
|
|
258
261
|
/**
|
|
259
262
|
* End a dynamic update started by `startDynamicUpdate`. Handles nesting: only the final
|
|
260
|
-
* corresponding end call
|
|
263
|
+
* corresponding end call completes the update. overflow-anchor remains 'none' permanently.
|
|
264
|
+
* Guards against underflow.
|
|
261
265
|
*/
|
|
262
266
|
endDynamicUpdate() {
|
|
263
267
|
if (this._dynamicUpdateDepth <= 0) {
|
|
@@ -266,16 +270,16 @@ export class ReactiveListManager {
|
|
|
266
270
|
this._dynamicUpdateDepth -= 1;
|
|
267
271
|
if (this._dynamicUpdateDepth === 0) {
|
|
268
272
|
if (this._isReady && this._viewportElement) {
|
|
269
|
-
this._viewportElement.style.setProperty('overflow-anchor', '
|
|
273
|
+
this._viewportElement.style.setProperty('overflow-anchor', 'none');
|
|
270
274
|
}
|
|
271
275
|
this._dynamicUpdateInProgress = false;
|
|
272
276
|
this._scheduler.unblock();
|
|
273
277
|
}
|
|
274
278
|
}
|
|
275
279
|
/**
|
|
276
|
-
* Run a dynamic update with UA scroll anchoring disabled
|
|
277
|
-
* Accepts a sync or async function and ensures `overflow-anchor`
|
|
278
|
-
*
|
|
280
|
+
* Run a dynamic update with UA scroll anchoring disabled.
|
|
281
|
+
* Accepts a sync or async function and ensures `overflow-anchor` stays 'none'
|
|
282
|
+
* throughout. If the manager isn't ready yet, it simply executes `fn`.
|
|
279
283
|
*/
|
|
280
284
|
async runDynamicUpdate(fn) {
|
|
281
285
|
this.startDynamicUpdate();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@humanspeak/svelte-virtual-list",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.13",
|
|
4
4
|
"description": "A lightweight, high-performance virtual list component for Svelte 5 that renders large datasets with minimal memory usage. Features include dynamic height support, smooth scrolling, TypeScript support, and efficient DOM recycling. Ideal for infinite scrolling lists, data tables, chat interfaces, and any application requiring the rendering of thousands of items without compromising performance. Zero dependencies and fully customizable.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svelte",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"@eslint/compat": "^2.0.2",
|
|
63
63
|
"@eslint/js": "^10.0.1",
|
|
64
64
|
"@faker-js/faker": "^10.3.0",
|
|
65
|
+
"@playwright/cli": "^0.1.1",
|
|
65
66
|
"@playwright/test": "^1.58.2",
|
|
66
67
|
"@sveltejs/adapter-auto": "^7.0.1",
|
|
67
68
|
"@sveltejs/kit": "^2.52.0",
|
|
@@ -72,8 +73,8 @@
|
|
|
72
73
|
"@testing-library/svelte": "^5.3.1",
|
|
73
74
|
"@testing-library/user-event": "^14.6.1",
|
|
74
75
|
"@types/node": "^25.2.3",
|
|
75
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
76
|
-
"@typescript-eslint/parser": "^8.
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
77
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
77
78
|
"@vitest/coverage-v8": "^4.0.18",
|
|
78
79
|
"concurrently": "^9.2.1",
|
|
79
80
|
"eslint": "^10.0.0",
|
|
@@ -95,7 +96,7 @@
|
|
|
95
96
|
"tailwindcss": "^4.1.18",
|
|
96
97
|
"tw-animate-css": "^1.4.0",
|
|
97
98
|
"typescript": "^5.9.3",
|
|
98
|
-
"typescript-eslint": "^8.
|
|
99
|
+
"typescript-eslint": "^8.56.0",
|
|
99
100
|
"vite": "^7.3.1",
|
|
100
101
|
"vitest": "^4.0.18"
|
|
101
102
|
},
|