virtua 0.50.2 → 0.50.4
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.
- package/lib/angular/VList.d.ts +7 -7
- package/lib/angular/Virtualizer.d.ts +11 -11
- package/lib/angular/WindowVirtualizer.d.ts +13 -9
- package/lib/angular/index.js +440 -434
- package/lib/angular/index.js.map +1 -1
- package/lib/core/index.cjs +342 -335
- package/lib/core/index.cjs.map +1 -1
- package/lib/core/index.d.ts +5 -2
- package/lib/core/index.js +326 -318
- package/lib/core/index.js.map +1 -1
- package/lib/core/layouts/types.d.ts +1 -0
- package/lib/core/observer.d.ts +1 -0
- package/lib/core/scroll-to.d.ts +1 -0
- package/lib/core/types.d.ts +1 -5
- package/lib/index.cjs +534 -532
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +496 -494
- package/lib/index.js.map +1 -1
- package/lib/solid/VList.d.ts +1 -1
- package/lib/solid/Virtualizer.d.ts +4 -0
- package/lib/solid/WindowVirtualizer.d.ts +4 -0
- package/lib/solid/index.cjs +366 -378
- package/lib/solid/index.cjs.map +1 -1
- package/lib/solid/index.js +373 -386
- package/lib/solid/index.js.map +1 -1
- package/lib/solid/index.jsx +383 -368
- package/lib/solid/index.jsx.map +1 -1
- package/lib/svelte/ListItem.svelte +2 -2
- package/lib/svelte/Virtualizer.svelte +22 -32
- package/lib/svelte/WindowVirtualizer.svelte +22 -21
- package/lib/svelte/WindowVirtualizer.type.d.ts +4 -0
- package/lib/svelte/utils.js.map +1 -1
- package/lib/vue/WindowVirtualizer.d.ts +4 -0
- package/lib/vue/index.cjs +366 -385
- package/lib/vue/index.cjs.map +1 -1
- package/lib/vue/index.js +342 -361
- package/lib/vue/index.js.map +1 -1
- package/package.json +30 -29
- /package/lib/core/{resizer.d.ts → driver.d.ts} +0 -0
- /package/lib/core/{scroller.d.ts → layouts/list.d.ts} +0 -0
package/lib/solid/index.jsx
CHANGED
|
@@ -8,6 +8,7 @@ var clamp = (value, minValue, maxValue) => min(maxValue, max(minValue, value));
|
|
|
8
8
|
var sort = (arr) => {
|
|
9
9
|
return [...arr].sort((a, b) => a - b);
|
|
10
10
|
};
|
|
11
|
+
var timeout = setTimeout;
|
|
11
12
|
var microtask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
|
|
12
13
|
Promise.resolve().then(fn);
|
|
13
14
|
};
|
|
@@ -29,112 +30,6 @@ var once = (fn) => {
|
|
|
29
30
|
};
|
|
30
31
|
};
|
|
31
32
|
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/core/cache.ts
|
|
34
|
-
var UNCACHED = -1;
|
|
35
|
-
var fill = (array, length, prepend) => {
|
|
36
|
-
const key = prepend ? "unshift" : "push";
|
|
37
|
-
for (let i = 0; i < length; i++) {
|
|
38
|
-
array[key](-1);
|
|
39
|
-
}
|
|
40
|
-
return array;
|
|
41
|
-
};
|
|
42
|
-
var getItemSize = (cache, index) => {
|
|
43
|
-
const size = cache._sizes[index];
|
|
44
|
-
return size === -1 ? cache._defaultItemSize : size;
|
|
45
|
-
};
|
|
46
|
-
var setItemSize = (cache, index, size) => {
|
|
47
|
-
const isInitialMeasurement = cache._sizes[index] === -1;
|
|
48
|
-
cache._sizes[index] = size;
|
|
49
|
-
cache._computedOffsetIndex = min(index, cache._computedOffsetIndex);
|
|
50
|
-
return isInitialMeasurement;
|
|
51
|
-
};
|
|
52
|
-
var getItemOffset = (cache, index) => {
|
|
53
|
-
if (!cache._length) return 0;
|
|
54
|
-
if (cache._computedOffsetIndex >= index) {
|
|
55
|
-
return cache._offsets[index];
|
|
56
|
-
}
|
|
57
|
-
if (cache._computedOffsetIndex < 0) {
|
|
58
|
-
cache._offsets[0] = 0;
|
|
59
|
-
cache._computedOffsetIndex = 0;
|
|
60
|
-
}
|
|
61
|
-
let i = cache._computedOffsetIndex;
|
|
62
|
-
let top = cache._offsets[i];
|
|
63
|
-
while (i < index) {
|
|
64
|
-
top += getItemSize(cache, i);
|
|
65
|
-
cache._offsets[++i] = top;
|
|
66
|
-
}
|
|
67
|
-
cache._computedOffsetIndex = index;
|
|
68
|
-
return top;
|
|
69
|
-
};
|
|
70
|
-
var findIndex = (cache, offset, low = 0, high = cache._length - 1) => {
|
|
71
|
-
let found = low;
|
|
72
|
-
while (low <= high) {
|
|
73
|
-
const mid = floor((low + high) / 2);
|
|
74
|
-
if (getItemOffset(cache, mid) <= offset) {
|
|
75
|
-
found = mid;
|
|
76
|
-
low = mid + 1;
|
|
77
|
-
} else {
|
|
78
|
-
high = mid - 1;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return clamp(found, 0, cache._length - 1);
|
|
82
|
-
};
|
|
83
|
-
var computeRange = (cache, startOffset, endOffset, prevStartIndex) => {
|
|
84
|
-
prevStartIndex = min(prevStartIndex, cache._length - 1);
|
|
85
|
-
if (getItemOffset(cache, prevStartIndex) <= startOffset) {
|
|
86
|
-
const end = findIndex(cache, endOffset, prevStartIndex);
|
|
87
|
-
return [findIndex(cache, startOffset, prevStartIndex, end), end];
|
|
88
|
-
} else {
|
|
89
|
-
const start = findIndex(cache, startOffset, undefined, prevStartIndex);
|
|
90
|
-
return [start, findIndex(cache, endOffset, start)];
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
var estimateDefaultItemSize = (cache, startIndex) => {
|
|
94
|
-
let measuredCountBeforeStart = 0;
|
|
95
|
-
const measuredSizes = [];
|
|
96
|
-
cache._sizes.forEach((s, i) => {
|
|
97
|
-
if (s !== -1) {
|
|
98
|
-
measuredSizes.push(s);
|
|
99
|
-
if (i < startIndex) {
|
|
100
|
-
measuredCountBeforeStart++;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
cache._computedOffsetIndex = -1;
|
|
105
|
-
const sorted = sort(measuredSizes);
|
|
106
|
-
const len = sorted.length;
|
|
107
|
-
const mid = len / 2 | 0;
|
|
108
|
-
const median = len % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
109
|
-
const prevDefaultItemSize = cache._defaultItemSize;
|
|
110
|
-
return ((cache._defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
|
|
111
|
-
};
|
|
112
|
-
var initCache = (length, itemSize, sizes) => {
|
|
113
|
-
return {
|
|
114
|
-
_defaultItemSize: itemSize,
|
|
115
|
-
_sizes: sizes ? fill(sizes.slice(0, min(length, sizes.length)), max(0, length - sizes.length)) : fill([], length),
|
|
116
|
-
_length: length,
|
|
117
|
-
_computedOffsetIndex: -1,
|
|
118
|
-
_offsets: fill([], length + 1)
|
|
119
|
-
};
|
|
120
|
-
};
|
|
121
|
-
var takeCacheSnapshot = (cache) => {
|
|
122
|
-
return [cache._sizes.slice(), cache._defaultItemSize];
|
|
123
|
-
};
|
|
124
|
-
var updateCacheLength = (cache, length, isShift) => {
|
|
125
|
-
const diff = length - cache._length;
|
|
126
|
-
cache._computedOffsetIndex = isShift ? -1 : min(length - 1, cache._computedOffsetIndex);
|
|
127
|
-
cache._length = length;
|
|
128
|
-
if (diff > 0) {
|
|
129
|
-
fill(cache._offsets, diff);
|
|
130
|
-
fill(cache._sizes, diff, isShift);
|
|
131
|
-
return cache._defaultItemSize * diff;
|
|
132
|
-
} else {
|
|
133
|
-
cache._offsets.splice(diff);
|
|
134
|
-
return (isShift ? cache._sizes.splice(0, -diff) : cache._sizes.splice(diff)).reduce((acc, removed) => acc - (removed === -1 ? cache._defaultItemSize : removed), 0);
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
|
|
138
33
|
//#endregion
|
|
139
34
|
//#region src/core/environment.ts
|
|
140
35
|
var isBrowser = typeof window !== "undefined";
|
|
@@ -175,7 +70,8 @@ var UPDATE_SCROLL_END_EVENT = 8;
|
|
|
175
70
|
var getScrollSize = (store) => {
|
|
176
71
|
return max(store.$getTotalSize(), store.$getViewportSize());
|
|
177
72
|
};
|
|
178
|
-
var createVirtualStore = (
|
|
73
|
+
var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItemOffset: getOffset, $getItemSize: getItemSize, $setItemSize: setItemSize, $isSizeEqual: isSizeEqual, $getTotalSize: getTotalSize, $getLength: getLength, $setLength: setLength, $estimateDefaultSize: estimateDefaultSize }, ssrCount = 0) => {
|
|
74
|
+
let shouldAutoEstimateItemSize = !!estimateDefaultSize;
|
|
179
75
|
let isSSR = !!ssrCount;
|
|
180
76
|
let stateVersion = 1;
|
|
181
77
|
let viewportSize = 0;
|
|
@@ -190,27 +86,16 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
|
|
|
190
86
|
let _prevRange = [0, isSSR ? max(ssrCount - 1, 0) : -1];
|
|
191
87
|
let _totalMeasuredSize = 0;
|
|
192
88
|
let _isViewportMeasured = false;
|
|
193
|
-
const cache = initCache(elementsCount, cacheSnapshot ? cacheSnapshot[1] : itemSize, cacheSnapshot && cacheSnapshot[0]);
|
|
194
89
|
const subscribers = new Set();
|
|
195
90
|
const getRelativeScrollOffset = () => scrollOffset - startSpacerSize;
|
|
196
91
|
const getVisibleOffset = () => getRelativeScrollOffset() + pendingJump + jump;
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
};
|
|
200
|
-
const getTotalSize = () => getItemOffset(cache, cache._length);
|
|
201
|
-
const getItemOffset$1 = (index, fromEnd) => {
|
|
202
|
-
const offset = getItemOffset(cache, index) - pendingJump;
|
|
92
|
+
const getItemOffset = (index, fromEnd) => {
|
|
93
|
+
const offset = getOffset(index) - pendingJump;
|
|
203
94
|
if (fromEnd) {
|
|
204
|
-
return getTotalSize() - offset - getItemSize
|
|
95
|
+
return getTotalSize() - offset - getItemSize(index);
|
|
205
96
|
}
|
|
206
97
|
return offset;
|
|
207
98
|
};
|
|
208
|
-
const getItemSize$1 = (index) => {
|
|
209
|
-
return getItemSize(cache, index);
|
|
210
|
-
};
|
|
211
|
-
const isSizeEqual = (index, value = -1) => {
|
|
212
|
-
return cache._sizes[index] === value;
|
|
213
|
-
};
|
|
214
99
|
const applyJump = (j) => {
|
|
215
100
|
if (j) {
|
|
216
101
|
if (isIOSWebKit() && _scrollDirection !== SCROLL_IDLE || _frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL) {
|
|
@@ -225,9 +110,6 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
|
|
|
225
110
|
subscribers.clear();
|
|
226
111
|
},
|
|
227
112
|
$getStateVersion: () => stateVersion,
|
|
228
|
-
$getCacheSnapshot: () => {
|
|
229
|
-
return takeCacheSnapshot(cache);
|
|
230
|
-
},
|
|
231
113
|
$getRange: (bufferSize = 200) => {
|
|
232
114
|
if (!_isViewportMeasured || isSSR) {
|
|
233
115
|
return _prevRange;
|
|
@@ -254,13 +136,13 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
|
|
|
254
136
|
endIndex = max(endIndex, _frozenRange[1]);
|
|
255
137
|
}
|
|
256
138
|
}
|
|
257
|
-
return [max(startIndex, 0), min(endIndex,
|
|
139
|
+
return [max(startIndex, 0), min(endIndex, getLength() - 1)];
|
|
258
140
|
},
|
|
259
|
-
$findItemIndex: (offset) => findIndex(
|
|
141
|
+
$findItemIndex: (offset) => findIndex(offset - startSpacerSize),
|
|
260
142
|
$isUnmeasuredItem: isSizeEqual,
|
|
261
|
-
$getItemOffset: getItemOffset
|
|
262
|
-
$getItemSize: getItemSize
|
|
263
|
-
$getItemsLength:
|
|
143
|
+
$getItemOffset: getItemOffset,
|
|
144
|
+
$getItemSize: getItemSize,
|
|
145
|
+
$getItemsLength: getLength,
|
|
264
146
|
$getScrollOffset: () => scrollOffset,
|
|
265
147
|
$isScrolling: () => _scrollDirection !== SCROLL_IDLE,
|
|
266
148
|
$getViewportSize: () => viewportSize,
|
|
@@ -331,24 +213,24 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
|
|
|
331
213
|
shouldKeep = index < _frozenRange[0];
|
|
332
214
|
} else {
|
|
333
215
|
const start = getRelativeScrollOffset();
|
|
334
|
-
const itemOffset = getItemOffset
|
|
335
|
-
const itemSize = getItemSize
|
|
216
|
+
const itemOffset = getItemOffset(index);
|
|
217
|
+
const itemSize = getItemSize(index);
|
|
336
218
|
shouldKeep = _scrollDirection !== SCROLL_DOWN && _scrollMode === SCROLL_BY_NATIVE ? itemOffset + itemSize <= start : itemOffset < start && itemOffset + itemSize < start + viewportSize;
|
|
337
219
|
}
|
|
338
220
|
if (shouldKeep) {
|
|
339
|
-
acc += size - getItemSize
|
|
221
|
+
acc += size - getItemSize(index);
|
|
340
222
|
}
|
|
341
223
|
return acc;
|
|
342
224
|
}, 0));
|
|
343
225
|
for (const [index, size] of updated) {
|
|
344
|
-
const prevSize = getItemSize
|
|
345
|
-
const isInitialMeasurement = setItemSize(
|
|
226
|
+
const prevSize = getItemSize(index);
|
|
227
|
+
const isInitialMeasurement = setItemSize(index, size);
|
|
346
228
|
if (shouldAutoEstimateItemSize) {
|
|
347
229
|
_totalMeasuredSize += isInitialMeasurement ? size : size - prevSize;
|
|
348
230
|
}
|
|
349
231
|
}
|
|
350
232
|
if (shouldAutoEstimateItemSize && viewportSize && _totalMeasuredSize > viewportSize) {
|
|
351
|
-
applyJump(
|
|
233
|
+
applyJump(estimateDefaultSize(findIndex(getVisibleOffset())));
|
|
352
234
|
shouldAutoEstimateItemSize = false;
|
|
353
235
|
}
|
|
354
236
|
mutated = 1 + 2;
|
|
@@ -367,11 +249,11 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
|
|
|
367
249
|
}
|
|
368
250
|
case 5: {
|
|
369
251
|
if (payload[1]) {
|
|
370
|
-
applyJump(
|
|
252
|
+
applyJump(setLength(payload[0], true));
|
|
371
253
|
_scrollMode = SCROLL_BY_SHIFT;
|
|
372
254
|
mutated = 1;
|
|
373
255
|
} else {
|
|
374
|
-
|
|
256
|
+
setLength(payload[0]);
|
|
375
257
|
mutated = 1;
|
|
376
258
|
}
|
|
377
259
|
break;
|
|
@@ -408,8 +290,139 @@ var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnaps
|
|
|
408
290
|
};
|
|
409
291
|
|
|
410
292
|
//#endregion
|
|
411
|
-
//#region src/core/
|
|
412
|
-
var
|
|
293
|
+
//#region src/core/cache.ts
|
|
294
|
+
var UNCACHED = -1;
|
|
295
|
+
var findIndex = (getOffset, length, offset, low = 0, high = length - 1) => {
|
|
296
|
+
let found = low;
|
|
297
|
+
while (low <= high) {
|
|
298
|
+
const mid = floor((low + high) / 2);
|
|
299
|
+
if (getOffset(mid) <= offset) {
|
|
300
|
+
found = mid;
|
|
301
|
+
low = mid + 1;
|
|
302
|
+
} else {
|
|
303
|
+
high = mid - 1;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return clamp(found, 0, length - 1);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/core/layouts/list.ts
|
|
311
|
+
var fill = (array, length, prepend) => {
|
|
312
|
+
const key = prepend ? "unshift" : "push";
|
|
313
|
+
for (let i = 0; i < length; i++) {
|
|
314
|
+
array[key](-1);
|
|
315
|
+
}
|
|
316
|
+
return array;
|
|
317
|
+
};
|
|
318
|
+
var createListLayout = (length, itemSize, snapshot) => {
|
|
319
|
+
let defaultItemSize = snapshot && snapshot[1] || itemSize || 40;
|
|
320
|
+
let computedOffsetIndex = -1;
|
|
321
|
+
let prevStartIndex = 0;
|
|
322
|
+
const restoredSizes = snapshot && snapshot[0];
|
|
323
|
+
const sizes = restoredSizes ? fill(restoredSizes.slice(0, min(length, restoredSizes.length)), max(0, length - restoredSizes.length)) : fill([], length);
|
|
324
|
+
const offsets = fill([], length + 1);
|
|
325
|
+
const getSize = (index) => {
|
|
326
|
+
const size = sizes[index];
|
|
327
|
+
return size === -1 ? defaultItemSize : size;
|
|
328
|
+
};
|
|
329
|
+
const getOffset = (index) => {
|
|
330
|
+
if (!length) return 0;
|
|
331
|
+
if (computedOffsetIndex >= index) {
|
|
332
|
+
return offsets[index];
|
|
333
|
+
}
|
|
334
|
+
if (computedOffsetIndex < 0) {
|
|
335
|
+
offsets[0] = 0;
|
|
336
|
+
computedOffsetIndex = 0;
|
|
337
|
+
}
|
|
338
|
+
let i = computedOffsetIndex;
|
|
339
|
+
let top = offsets[i];
|
|
340
|
+
while (i < index) {
|
|
341
|
+
top += getSize(i);
|
|
342
|
+
offsets[++i] = top;
|
|
343
|
+
}
|
|
344
|
+
computedOffsetIndex = index;
|
|
345
|
+
return top;
|
|
346
|
+
};
|
|
347
|
+
return {
|
|
348
|
+
$getRange: (startOffset, endOffset) => {
|
|
349
|
+
prevStartIndex = min(prevStartIndex, length - 1);
|
|
350
|
+
let start;
|
|
351
|
+
let end;
|
|
352
|
+
if (getOffset(prevStartIndex) <= startOffset) {
|
|
353
|
+
end = findIndex(getOffset, length, endOffset, prevStartIndex);
|
|
354
|
+
start = findIndex(getOffset, length, startOffset, prevStartIndex, end);
|
|
355
|
+
} else {
|
|
356
|
+
start = findIndex(getOffset, length, startOffset, undefined, prevStartIndex);
|
|
357
|
+
end = findIndex(getOffset, length, endOffset, start);
|
|
358
|
+
}
|
|
359
|
+
prevStartIndex = start;
|
|
360
|
+
return [start, end];
|
|
361
|
+
},
|
|
362
|
+
$findIndex: (offset) => findIndex(getOffset, length, offset),
|
|
363
|
+
$getItemOffset: getOffset,
|
|
364
|
+
$getItemSize: getSize,
|
|
365
|
+
$setItemSize: (index, size) => {
|
|
366
|
+
const isInitialMeasurement = sizes[index] === -1;
|
|
367
|
+
sizes[index] = size;
|
|
368
|
+
computedOffsetIndex = min(index, computedOffsetIndex);
|
|
369
|
+
return isInitialMeasurement;
|
|
370
|
+
},
|
|
371
|
+
$isSizeEqual: (index, size = -1) => sizes[index] === size,
|
|
372
|
+
$getTotalSize: () => getOffset(length),
|
|
373
|
+
$getLength: () => length,
|
|
374
|
+
$setLength: (nextLength, isShift) => {
|
|
375
|
+
const diff = nextLength - length;
|
|
376
|
+
computedOffsetIndex = isShift ? -1 : min(nextLength - 1, computedOffsetIndex);
|
|
377
|
+
length = nextLength;
|
|
378
|
+
if (diff > 0) {
|
|
379
|
+
fill(offsets, diff);
|
|
380
|
+
fill(sizes, diff, isShift);
|
|
381
|
+
return defaultItemSize * diff;
|
|
382
|
+
} else {
|
|
383
|
+
offsets.splice(diff);
|
|
384
|
+
return (isShift ? sizes.splice(0, -diff) : sizes.splice(diff)).reduce((acc, removed) => acc - (removed === -1 ? defaultItemSize : removed), 0);
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
$estimateDefaultSize: itemSize ? undefined : (startIndex) => {
|
|
388
|
+
let measuredCountBeforeStart = 0;
|
|
389
|
+
const measuredSizes = [];
|
|
390
|
+
sizes.forEach((s, i) => {
|
|
391
|
+
if (s !== -1) {
|
|
392
|
+
measuredSizes.push(s);
|
|
393
|
+
if (i < startIndex) {
|
|
394
|
+
measuredCountBeforeStart++;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
computedOffsetIndex = -1;
|
|
399
|
+
const sorted = sort(measuredSizes);
|
|
400
|
+
const len = sorted.length;
|
|
401
|
+
const mid = len / 2 | 0;
|
|
402
|
+
const median = len % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
403
|
+
const prevDefaultItemSize = defaultItemSize;
|
|
404
|
+
return ((defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
|
|
405
|
+
},
|
|
406
|
+
$snapshot: () => [sizes.slice(), defaultItemSize]
|
|
407
|
+
};
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
//#endregion
|
|
411
|
+
//#region src/core/observer.ts
|
|
412
|
+
var createResizeObserver = (cb) => {
|
|
413
|
+
let ro;
|
|
414
|
+
return {
|
|
415
|
+
_observe(e) {
|
|
416
|
+
(ro || (ro = new (getCurrentWindow(getCurrentDocument(e))).ResizeObserver(cb))).observe(e);
|
|
417
|
+
},
|
|
418
|
+
_unobserve(e) {
|
|
419
|
+
ro.unobserve(e);
|
|
420
|
+
},
|
|
421
|
+
_dispose() {
|
|
422
|
+
ro && ro.disconnect();
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
};
|
|
413
426
|
var debounce = (fn, ms) => {
|
|
414
427
|
let id;
|
|
415
428
|
const cancel = () => {
|
|
@@ -499,6 +512,9 @@ var createScrollObserver = (store, viewport, isHorizontal, getScrollOffset, upda
|
|
|
499
512
|
}
|
|
500
513
|
};
|
|
501
514
|
};
|
|
515
|
+
|
|
516
|
+
//#endregion
|
|
517
|
+
//#region src/core/driver.ts
|
|
502
518
|
var createScrollScheduler = (store, initialized, scroll) => {
|
|
503
519
|
let cancelScroll;
|
|
504
520
|
return [async (getTargetOffset, smooth) => {
|
|
@@ -564,7 +580,7 @@ var createScrollScheduler = (store, initialized, scroll) => {
|
|
|
564
580
|
cancelScroll && cancelScroll();
|
|
565
581
|
}];
|
|
566
582
|
};
|
|
567
|
-
var
|
|
583
|
+
var createContainerDriver = (store, isHorizontal) => {
|
|
568
584
|
let viewportElement;
|
|
569
585
|
let scrollObserver;
|
|
570
586
|
let initialized = createPromise();
|
|
@@ -582,9 +598,28 @@ var createScroller = (store, isHorizontal) => {
|
|
|
582
598
|
viewportElement[scrollOffsetKey] = offset;
|
|
583
599
|
}
|
|
584
600
|
});
|
|
601
|
+
const sizeKey = isHorizontal ? "width" : "height";
|
|
602
|
+
const mountedIndexes = new WeakMap();
|
|
603
|
+
const resizeObserver = createResizeObserver((entries) => {
|
|
604
|
+
const resizes = [];
|
|
605
|
+
for (const { target, contentRect } of entries) {
|
|
606
|
+
if (!target.offsetParent) continue;
|
|
607
|
+
if (target === viewportElement) {
|
|
608
|
+
store.$update(4, contentRect[sizeKey]);
|
|
609
|
+
} else {
|
|
610
|
+
const index = mountedIndexes.get(target);
|
|
611
|
+
if (index != null) {
|
|
612
|
+
resizes.push([index, contentRect[sizeKey]]);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (resizes.length) {
|
|
617
|
+
store.$update(3, resizes);
|
|
618
|
+
}
|
|
619
|
+
});
|
|
585
620
|
return {
|
|
586
|
-
$observe(
|
|
587
|
-
viewportElement = viewport;
|
|
621
|
+
$observe(containerElement, viewport = containerElement.parentElement) {
|
|
622
|
+
resizeObserver._observe(viewportElement = viewport);
|
|
588
623
|
if (isHorizontal) {
|
|
589
624
|
isNegative = getComputedStyle(viewport).direction === "rtl";
|
|
590
625
|
}
|
|
@@ -605,43 +640,32 @@ var createScroller = (store, isHorizontal) => {
|
|
|
605
640
|
initialized[1](true);
|
|
606
641
|
},
|
|
607
642
|
$dispose() {
|
|
643
|
+
resizeObserver._dispose();
|
|
608
644
|
scrollObserver && scrollObserver._dispose();
|
|
609
645
|
initialized[1](false);
|
|
610
646
|
initialized = createPromise();
|
|
611
647
|
},
|
|
612
|
-
$
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
},
|
|
620
|
-
$scrollToIndex(index, { align, smooth, offset = 0 } = {}) {
|
|
621
|
-
index = clamp(index, 0, store.$getItemsLength() - 1);
|
|
622
|
-
if (align === "nearest") {
|
|
623
|
-
const itemOffset = store.$getItemOffset(index);
|
|
624
|
-
const scrollOffset = store.$getScrollOffset();
|
|
625
|
-
if (itemOffset < scrollOffset) {
|
|
626
|
-
align = "start";
|
|
627
|
-
} else if (itemOffset + store.$getItemSize(index) > scrollOffset + store.$getViewportSize()) {
|
|
628
|
-
align = "end";
|
|
629
|
-
} else {
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
scheduleScroll(() => {
|
|
634
|
-
return offset + store.$getStartSpacerSize() + store.$getItemOffset(index) + (align === "end" ? store.$getItemSize(index) - store.$getViewportSize() : align === "center" ? (store.$getItemSize(index) - store.$getViewportSize()) / 2 : 0);
|
|
635
|
-
}, smooth);
|
|
648
|
+
$observeItem(el, index) {
|
|
649
|
+
mountedIndexes.set(el, index);
|
|
650
|
+
resizeObserver._observe(el);
|
|
651
|
+
return () => {
|
|
652
|
+
mountedIndexes.delete(el);
|
|
653
|
+
resizeObserver._unobserve(el);
|
|
654
|
+
};
|
|
636
655
|
},
|
|
637
|
-
$
|
|
656
|
+
$isNegative: () => isNegative,
|
|
657
|
+
$scheduleScroll: scheduleScroll,
|
|
658
|
+
$fixScrollJump() {
|
|
638
659
|
scrollObserver && scrollObserver._fixScrollJump();
|
|
639
|
-
}
|
|
660
|
+
},
|
|
661
|
+
$getBaseOffset: store.$getStartSpacerSize,
|
|
662
|
+
$getScrollbarSize: () => 0
|
|
640
663
|
};
|
|
641
664
|
};
|
|
642
|
-
var
|
|
665
|
+
var createWindowDriver = (store, isHorizontal) => {
|
|
643
666
|
let containerElement;
|
|
644
667
|
let scrollObserver;
|
|
668
|
+
let cleanupOnWindowResize;
|
|
645
669
|
let initialized = createPromise();
|
|
646
670
|
let isNegative = false;
|
|
647
671
|
const scrollToKey = isHorizontal ? "left" : "top";
|
|
@@ -657,6 +681,21 @@ var createWindowScroller = (store, isHorizontal) => {
|
|
|
657
681
|
window.scroll({ [scrollToKey]: offset });
|
|
658
682
|
}
|
|
659
683
|
});
|
|
684
|
+
const sizeKey = isHorizontal ? "width" : "height";
|
|
685
|
+
const mountedIndexes = new WeakMap();
|
|
686
|
+
const resizeObserver = createResizeObserver((entries) => {
|
|
687
|
+
const resizes = [];
|
|
688
|
+
for (const { target, contentRect } of entries) {
|
|
689
|
+
if (!target.offsetParent) continue;
|
|
690
|
+
const index = mountedIndexes.get(target);
|
|
691
|
+
if (index != null) {
|
|
692
|
+
resizes.push([index, contentRect[sizeKey]]);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
if (resizes.length) {
|
|
696
|
+
store.$update(3, resizes);
|
|
697
|
+
}
|
|
698
|
+
});
|
|
660
699
|
const calcOffsetToViewport = (node, viewport, window, isHorizontal, offset = 0) => {
|
|
661
700
|
const offsetKey = isHorizontal ? "offsetLeft" : "offsetTop";
|
|
662
701
|
const offsetSum = offset + (isHorizontal && isNegative ? window.innerWidth - node[offsetKey] - node.offsetWidth : node[offsetKey]);
|
|
@@ -672,6 +711,14 @@ var createWindowScroller = (store, isHorizontal) => {
|
|
|
672
711
|
const scrollOffsetKey = isHorizontal ? "scrollX" : "scrollY";
|
|
673
712
|
const document = getCurrentDocument(container);
|
|
674
713
|
const window = getCurrentWindow(document);
|
|
714
|
+
const onWindowResize = () => {
|
|
715
|
+
store.$update(4, window[isHorizontal ? "innerWidth" : "innerHeight"]);
|
|
716
|
+
};
|
|
717
|
+
window.addEventListener("resize", onWindowResize);
|
|
718
|
+
microtask(onWindowResize);
|
|
719
|
+
cleanupOnWindowResize = () => {
|
|
720
|
+
window.removeEventListener("resize", onWindowResize);
|
|
721
|
+
};
|
|
675
722
|
if (isHorizontal) {
|
|
676
723
|
isNegative = getComputedStyle(getDocumentElement(document)).direction === "rtl";
|
|
677
724
|
}
|
|
@@ -685,181 +732,56 @@ var createWindowScroller = (store, isHorizontal) => {
|
|
|
685
732
|
initialized[1](true);
|
|
686
733
|
},
|
|
687
734
|
$dispose() {
|
|
735
|
+
cleanupOnWindowResize && cleanupOnWindowResize();
|
|
736
|
+
resizeObserver._dispose();
|
|
688
737
|
scrollObserver && scrollObserver._dispose();
|
|
689
738
|
containerElement = undefined;
|
|
690
739
|
initialized[1](false);
|
|
691
740
|
initialized = createPromise();
|
|
692
741
|
},
|
|
742
|
+
$observeItem(el, index) {
|
|
743
|
+
mountedIndexes.set(el, index);
|
|
744
|
+
resizeObserver._observe(el);
|
|
745
|
+
return () => {
|
|
746
|
+
mountedIndexes.delete(el);
|
|
747
|
+
resizeObserver._unobserve(el);
|
|
748
|
+
};
|
|
749
|
+
},
|
|
693
750
|
$isNegative: () => isNegative,
|
|
694
|
-
$
|
|
751
|
+
$scheduleScroll: scheduleScroll,
|
|
752
|
+
$fixScrollJump() {
|
|
695
753
|
scrollObserver && scrollObserver._fixScrollJump();
|
|
696
754
|
},
|
|
697
|
-
$
|
|
698
|
-
if (!containerElement) return;
|
|
699
|
-
index = clamp(index, 0, store.$getItemsLength() - 1);
|
|
700
|
-
if (align === "nearest") {
|
|
701
|
-
const itemOffset = store.$getItemOffset(index);
|
|
702
|
-
const scrollOffset = store.$getScrollOffset();
|
|
703
|
-
if (itemOffset < scrollOffset) {
|
|
704
|
-
align = "start";
|
|
705
|
-
} else if (itemOffset + store.$getItemSize(index) > scrollOffset + store.$getViewportSize()) {
|
|
706
|
-
align = "end";
|
|
707
|
-
} else {
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
755
|
+
$getBaseOffset() {
|
|
711
756
|
const document = getCurrentDocument(containerElement);
|
|
712
|
-
|
|
713
|
-
const html = getDocumentElement(document);
|
|
714
|
-
const getScrollbarSize = () => store.$getViewportSize() - (isHorizontal ? html.clientWidth : html.clientHeight);
|
|
715
|
-
scheduleScroll(() => {
|
|
716
|
-
return offset + calcOffsetToViewport(containerElement, document.body, window, isHorizontal) + store.$getItemOffset(index) + (align === "end" ? store.$getItemSize(index) - (store.$getViewportSize() - getScrollbarSize()) : align === "center" ? (store.$getItemSize(index) - (store.$getViewportSize() - getScrollbarSize())) / 2 : 0);
|
|
717
|
-
}, smooth);
|
|
718
|
-
}
|
|
719
|
-
};
|
|
720
|
-
};
|
|
721
|
-
var createGridScroller = (rowStore, colStore) => {
|
|
722
|
-
const rowScroller = createScroller(rowStore, false);
|
|
723
|
-
const colScroller = createScroller(colStore, true);
|
|
724
|
-
return {
|
|
725
|
-
$observe(container, viewport) {
|
|
726
|
-
rowScroller.$observe(container, viewport);
|
|
727
|
-
colScroller.$observe(container, viewport);
|
|
728
|
-
},
|
|
729
|
-
$dispose() {
|
|
730
|
-
rowScroller.$dispose();
|
|
731
|
-
colScroller.$dispose();
|
|
732
|
-
},
|
|
733
|
-
$isNegative: colScroller.$isNegative,
|
|
734
|
-
$scrollTo(row, col) {
|
|
735
|
-
if (row != null) {
|
|
736
|
-
rowScroller.$scrollTo(row);
|
|
737
|
-
}
|
|
738
|
-
if (col != null) {
|
|
739
|
-
colScroller.$scrollTo(col);
|
|
740
|
-
}
|
|
741
|
-
},
|
|
742
|
-
$scrollBy(row, col) {
|
|
743
|
-
if (row != null) {
|
|
744
|
-
rowScroller.$scrollBy(row);
|
|
745
|
-
}
|
|
746
|
-
if (col != null) {
|
|
747
|
-
colScroller.$scrollBy(col);
|
|
748
|
-
}
|
|
749
|
-
},
|
|
750
|
-
$scrollToIndex(row, col) {
|
|
751
|
-
if (row != null) {
|
|
752
|
-
rowScroller.$scrollToIndex(row);
|
|
753
|
-
}
|
|
754
|
-
if (col != null) {
|
|
755
|
-
colScroller.$scrollToIndex(col);
|
|
756
|
-
}
|
|
757
|
-
},
|
|
758
|
-
$fixScrollJump() {
|
|
759
|
-
rowScroller.$fixScrollJump();
|
|
760
|
-
colScroller.$fixScrollJump();
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
};
|
|
764
|
-
|
|
765
|
-
//#endregion
|
|
766
|
-
//#region src/core/resizer.ts
|
|
767
|
-
var createResizeObserver = (cb) => {
|
|
768
|
-
let ro;
|
|
769
|
-
return {
|
|
770
|
-
_observe(e) {
|
|
771
|
-
(ro || (ro = new (getCurrentWindow(getCurrentDocument(e))).ResizeObserver(cb))).observe(e);
|
|
757
|
+
return calcOffsetToViewport(containerElement, document.body, getCurrentWindow(document), isHorizontal);
|
|
772
758
|
},
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
_dispose() {
|
|
777
|
-
ro && ro.disconnect();
|
|
759
|
+
$getScrollbarSize() {
|
|
760
|
+
const html = getDocumentElement(getCurrentDocument(containerElement));
|
|
761
|
+
return store.$getViewportSize() - (isHorizontal ? html.clientWidth : html.clientHeight);
|
|
778
762
|
}
|
|
779
763
|
};
|
|
780
764
|
};
|
|
781
|
-
var
|
|
765
|
+
var createContainerGridDriver = (rowStore, colStore) => {
|
|
782
766
|
let viewportElement;
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
} else {
|
|
792
|
-
const index = mountedIndexes.get(target);
|
|
793
|
-
if (index != null) {
|
|
794
|
-
resizes.push([index, contentRect[sizeKey]]);
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
if (resizes.length) {
|
|
799
|
-
store.$update(3, resizes);
|
|
767
|
+
let rowScrollObserver;
|
|
768
|
+
let colScrollObserver;
|
|
769
|
+
let initialized = createPromise();
|
|
770
|
+
let isNegative = false;
|
|
771
|
+
const [scheduleScrollX, cancelScrollX] = createScrollScheduler(colStore, () => initialized[0], (offset, smooth) => {
|
|
772
|
+
const opts = { left: normalizeScrollOffset(offset, isNegative) };
|
|
773
|
+
if (smooth) {
|
|
774
|
+
opts.behavior = "smooth";
|
|
800
775
|
}
|
|
776
|
+
viewportElement.scrollTo(opts);
|
|
801
777
|
});
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
$observeItem: (el, i) => {
|
|
807
|
-
mountedIndexes.set(el, i);
|
|
808
|
-
resizeObserver._observe(el);
|
|
809
|
-
return () => {
|
|
810
|
-
mountedIndexes.delete(el);
|
|
811
|
-
resizeObserver._unobserve(el);
|
|
812
|
-
};
|
|
813
|
-
},
|
|
814
|
-
$dispose: resizeObserver._dispose
|
|
815
|
-
};
|
|
816
|
-
};
|
|
817
|
-
var createWindowResizer = (store, isHorizontal) => {
|
|
818
|
-
const sizeKey = isHorizontal ? "width" : "height";
|
|
819
|
-
const windowSizeKey = isHorizontal ? "innerWidth" : "innerHeight";
|
|
820
|
-
const mountedIndexes = new WeakMap();
|
|
821
|
-
const resizeObserver = createResizeObserver((entries) => {
|
|
822
|
-
const resizes = [];
|
|
823
|
-
for (const { target, contentRect } of entries) {
|
|
824
|
-
if (!target.offsetParent) continue;
|
|
825
|
-
const index = mountedIndexes.get(target);
|
|
826
|
-
if (index != null) {
|
|
827
|
-
resizes.push([index, contentRect[sizeKey]]);
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
if (resizes.length) {
|
|
831
|
-
store.$update(3, resizes);
|
|
778
|
+
const [scheduleScrollY, cancelScrollY] = createScrollScheduler(rowStore, () => initialized[0], (offset, smooth) => {
|
|
779
|
+
const opts = { top: offset };
|
|
780
|
+
if (smooth) {
|
|
781
|
+
opts.behavior = "smooth";
|
|
832
782
|
}
|
|
783
|
+
viewportElement.scrollTo(opts);
|
|
833
784
|
});
|
|
834
|
-
let cleanupOnWindowResize;
|
|
835
|
-
return {
|
|
836
|
-
$observeRoot(container) {
|
|
837
|
-
const window = getCurrentWindow(getCurrentDocument(container));
|
|
838
|
-
const onWindowResize = () => {
|
|
839
|
-
store.$update(4, window[windowSizeKey]);
|
|
840
|
-
};
|
|
841
|
-
window.addEventListener("resize", onWindowResize);
|
|
842
|
-
microtask(onWindowResize);
|
|
843
|
-
cleanupOnWindowResize = () => {
|
|
844
|
-
window.removeEventListener("resize", onWindowResize);
|
|
845
|
-
};
|
|
846
|
-
},
|
|
847
|
-
$observeItem: (el, i) => {
|
|
848
|
-
mountedIndexes.set(el, i);
|
|
849
|
-
resizeObserver._observe(el);
|
|
850
|
-
return () => {
|
|
851
|
-
mountedIndexes.delete(el);
|
|
852
|
-
resizeObserver._unobserve(el);
|
|
853
|
-
};
|
|
854
|
-
},
|
|
855
|
-
$dispose() {
|
|
856
|
-
cleanupOnWindowResize && cleanupOnWindowResize();
|
|
857
|
-
resizeObserver._dispose();
|
|
858
|
-
}
|
|
859
|
-
};
|
|
860
|
-
};
|
|
861
|
-
var createGridResizer = (rowStore, colStore) => {
|
|
862
|
-
let viewportElement;
|
|
863
785
|
const mountedIndexes = new WeakMap();
|
|
864
786
|
const maybeCachedRowIndexes = new Set();
|
|
865
787
|
const maybeCachedColIndexes = new Set();
|
|
@@ -936,9 +858,40 @@ var createGridResizer = (rowStore, colStore) => {
|
|
|
936
858
|
colStore.$update(3, widthResizes);
|
|
937
859
|
}
|
|
938
860
|
});
|
|
861
|
+
const observeAxisScroll = (store, isHorizontal, cancelScroll) => {
|
|
862
|
+
const viewport = viewportElement;
|
|
863
|
+
const scrollOffsetKey = isHorizontal ? "scrollLeft" : "scrollTop";
|
|
864
|
+
const overflowKey = isHorizontal ? "overflowX" : "overflowY";
|
|
865
|
+
const negative = isHorizontal && isNegative;
|
|
866
|
+
return createScrollObserver(store, viewport, isHorizontal, () => normalizeScrollOffset(viewport[scrollOffsetKey], negative), (jump, shift, isMomentumScrolling) => {
|
|
867
|
+
if (isMomentumScrolling) {
|
|
868
|
+
const style = viewport.style;
|
|
869
|
+
const prev = style[overflowKey];
|
|
870
|
+
style[overflowKey] = "hidden";
|
|
871
|
+
timeout(() => {
|
|
872
|
+
style[overflowKey] = prev;
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
viewport[scrollOffsetKey] = normalizeScrollOffset(store.$getScrollOffset() + jump, negative);
|
|
876
|
+
if (shift) {
|
|
877
|
+
cancelScroll();
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
};
|
|
939
881
|
return {
|
|
940
|
-
$
|
|
882
|
+
$observe(containerElement, viewport = containerElement.parentElement) {
|
|
941
883
|
resizeObserver._observe(viewportElement = viewport);
|
|
884
|
+
isNegative = getComputedStyle(viewport).direction === "rtl";
|
|
885
|
+
rowScrollObserver = observeAxisScroll(rowStore, false, cancelScrollY);
|
|
886
|
+
colScrollObserver = observeAxisScroll(colStore, true, cancelScrollX);
|
|
887
|
+
initialized[1](true);
|
|
888
|
+
},
|
|
889
|
+
$dispose() {
|
|
890
|
+
resizeObserver._dispose();
|
|
891
|
+
rowScrollObserver && rowScrollObserver._dispose();
|
|
892
|
+
colScrollObserver && colScrollObserver._dispose();
|
|
893
|
+
initialized[1](false);
|
|
894
|
+
initialized = createPromise();
|
|
942
895
|
},
|
|
943
896
|
$observeItem(el, rowIndex, colIndex) {
|
|
944
897
|
mountedIndexes.set(el, [rowIndex, colIndex]);
|
|
@@ -950,6 +903,14 @@ var createGridResizer = (rowStore, colStore) => {
|
|
|
950
903
|
resizeObserver._unobserve(el);
|
|
951
904
|
};
|
|
952
905
|
},
|
|
906
|
+
$resizeRows(rows) {
|
|
907
|
+
for (const [r] of rows) {
|
|
908
|
+
for (let c = 0; c < colStore.$getItemsLength(); c++) {
|
|
909
|
+
sizeCache.delete(getKey(r, c));
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
rowStore.$update(3, rows);
|
|
913
|
+
},
|
|
953
914
|
$resizeCols(cols) {
|
|
954
915
|
for (const [c] of cols) {
|
|
955
916
|
for (let r = 0; r < rowStore.$getItemsLength(); r++) {
|
|
@@ -958,18 +919,71 @@ var createGridResizer = (rowStore, colStore) => {
|
|
|
958
919
|
}
|
|
959
920
|
colStore.$update(3, cols);
|
|
960
921
|
},
|
|
961
|
-
$
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
rowStore.$update(3, rows);
|
|
922
|
+
$isNegative: () => isNegative,
|
|
923
|
+
$scheduleScrollX: scheduleScrollX,
|
|
924
|
+
$scheduleScrollY: scheduleScrollY,
|
|
925
|
+
$fixScrollJump() {
|
|
926
|
+
rowScrollObserver && rowScrollObserver._fixScrollJump();
|
|
927
|
+
colScrollObserver && colScrollObserver._fixScrollJump();
|
|
968
928
|
},
|
|
969
|
-
$
|
|
929
|
+
$getBaseOffset: (isHorizontal) => (isHorizontal ? colStore : rowStore).$getStartSpacerSize()
|
|
970
930
|
};
|
|
971
931
|
};
|
|
972
932
|
|
|
933
|
+
//#endregion
|
|
934
|
+
//#region src/core/scroll-to.ts
|
|
935
|
+
var scrollTo = (driver, offset) => {
|
|
936
|
+
driver.$scheduleScroll(() => offset);
|
|
937
|
+
};
|
|
938
|
+
var scrollBy = (driver, store, offset) => {
|
|
939
|
+
scrollTo(driver, offset + store.$getScrollOffset());
|
|
940
|
+
};
|
|
941
|
+
var scrollToIndex = (driver, store, index, { align, smooth, offset = 0 } = {}) => {
|
|
942
|
+
index = clamp(index, 0, store.$getItemsLength() - 1);
|
|
943
|
+
if (align === "nearest") {
|
|
944
|
+
const itemOffset = store.$getItemOffset(index);
|
|
945
|
+
const scrollOffset = store.$getScrollOffset();
|
|
946
|
+
if (itemOffset < scrollOffset) {
|
|
947
|
+
align = "start";
|
|
948
|
+
} else if (itemOffset + store.$getItemSize(index) > scrollOffset + store.$getViewportSize()) {
|
|
949
|
+
align = "end";
|
|
950
|
+
} else {
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
driver.$scheduleScroll(() => {
|
|
955
|
+
return offset + driver.$getBaseOffset() + store.$getItemOffset(index) + (align === "end" ? store.$getItemSize(index) - (store.$getViewportSize() - driver.$getScrollbarSize()) : align === "center" ? (store.$getItemSize(index) - (store.$getViewportSize() - driver.$getScrollbarSize())) / 2 : 0);
|
|
956
|
+
}, smooth);
|
|
957
|
+
};
|
|
958
|
+
var gridScrollTo = (driver, row, col) => {
|
|
959
|
+
if (row != null) {
|
|
960
|
+
driver.$scheduleScrollY(() => row);
|
|
961
|
+
}
|
|
962
|
+
if (col != null) {
|
|
963
|
+
driver.$scheduleScrollX(() => col);
|
|
964
|
+
}
|
|
965
|
+
};
|
|
966
|
+
var gridScrollBy = (driver, rowStore, colStore, row, col) => {
|
|
967
|
+
if (row != null) {
|
|
968
|
+
const target = row + rowStore.$getScrollOffset();
|
|
969
|
+
driver.$scheduleScrollY(() => target);
|
|
970
|
+
}
|
|
971
|
+
if (col != null) {
|
|
972
|
+
const target = col + colStore.$getScrollOffset();
|
|
973
|
+
driver.$scheduleScrollX(() => target);
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
var gridScrollToIndex = (driver, rowStore, colStore, row, col) => {
|
|
977
|
+
if (row != null) {
|
|
978
|
+
const index = clamp(row, 0, rowStore.$getItemsLength() - 1);
|
|
979
|
+
driver.$scheduleScrollY(() => driver.$getBaseOffset(false) + rowStore.$getItemOffset(index));
|
|
980
|
+
}
|
|
981
|
+
if (col != null) {
|
|
982
|
+
const index = clamp(col, 0, colStore.$getItemsLength() - 1);
|
|
983
|
+
driver.$scheduleScrollX(() => driver.$getBaseOffset(true) + colStore.$getItemOffset(index));
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
|
|
973
987
|
//#endregion
|
|
974
988
|
//#region src/solid/ListItem.tsx
|
|
975
989
|
var ListItem = (props) => {
|
|
@@ -981,13 +995,15 @@ var ListItem = (props) => {
|
|
|
981
995
|
});
|
|
982
996
|
const style = createMemo(() => {
|
|
983
997
|
const isHorizontal = props._isHorizontal;
|
|
998
|
+
const hide = props._hide;
|
|
999
|
+
const isSSR = props._isSSR;
|
|
984
1000
|
const style = {
|
|
985
1001
|
contain: "layout style",
|
|
986
|
-
position: "absolute",
|
|
1002
|
+
position: hide && isSSR ? undefined : "absolute",
|
|
987
1003
|
[isHorizontal ? "height" : "width"]: "100%",
|
|
988
1004
|
[isHorizontal ? "top" : "left"]: "0px",
|
|
989
1005
|
[isHorizontal ? "left" : "top"]: props._offset + "px",
|
|
990
|
-
visibility:
|
|
1006
|
+
visibility: !hide || isSSR ? undefined : "hidden"
|
|
991
1007
|
};
|
|
992
1008
|
if (isHorizontal) {
|
|
993
1009
|
style.display = "inline-flex";
|
|
@@ -1009,11 +1025,12 @@ var isSameRange = (prev, next) => {
|
|
|
1009
1025
|
//#region src/solid/Virtualizer.tsx
|
|
1010
1026
|
var Virtualizer = (props) => {
|
|
1011
1027
|
let containerRef;
|
|
1012
|
-
const { itemSize, horizontal = false, cache } = props;
|
|
1028
|
+
const { itemSize, horizontal = false, cache, ssrCount } = props;
|
|
1013
1029
|
props = mergeProps({ as: "div" }, props);
|
|
1014
|
-
const
|
|
1015
|
-
const
|
|
1016
|
-
const
|
|
1030
|
+
const [isSSR, setIsSSR] = createSignal(!!ssrCount);
|
|
1031
|
+
const layout = createListLayout(props.data.length, itemSize, cache);
|
|
1032
|
+
const store = createVirtualStore(layout, ssrCount);
|
|
1033
|
+
const driver = createContainerDriver(store, horizontal);
|
|
1017
1034
|
const [stateVersion, setRerender] = createSignal(store.$getStateVersion());
|
|
1018
1035
|
store.$subscribe(1, () => {
|
|
1019
1036
|
setRerender(store.$getStateVersion());
|
|
@@ -1034,12 +1051,13 @@ var Virtualizer = (props) => {
|
|
|
1034
1051
|
});
|
|
1035
1052
|
const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
|
|
1036
1053
|
const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
|
|
1037
|
-
const isNegative = createMemo(() => stateVersion() &&
|
|
1054
|
+
const isNegative = createMemo(() => stateVersion() && driver.$isNegative());
|
|
1038
1055
|
onMount(() => {
|
|
1056
|
+
setIsSSR(false);
|
|
1039
1057
|
if (props.ref) {
|
|
1040
1058
|
props.ref({
|
|
1041
1059
|
get cache() {
|
|
1042
|
-
return
|
|
1060
|
+
return layout.$snapshot();
|
|
1043
1061
|
},
|
|
1044
1062
|
get scrollOffset() {
|
|
1045
1063
|
return store.$getScrollOffset();
|
|
@@ -1053,22 +1071,18 @@ var Virtualizer = (props) => {
|
|
|
1053
1071
|
findItemIndex: store.$findItemIndex,
|
|
1054
1072
|
getItemOffset: store.$getItemOffset,
|
|
1055
1073
|
getItemSize: store.$getItemSize,
|
|
1056
|
-
scrollToIndex:
|
|
1057
|
-
scrollTo:
|
|
1058
|
-
scrollBy:
|
|
1074
|
+
scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts),
|
|
1075
|
+
scrollTo: (offset) => scrollTo(driver, offset),
|
|
1076
|
+
scrollBy: (offset) => scrollBy(driver, store, offset)
|
|
1059
1077
|
});
|
|
1060
1078
|
}
|
|
1061
|
-
|
|
1062
|
-
const scrollable = props.scrollRef || container.parentElement;
|
|
1063
|
-
resizer.$observeRoot(scrollable);
|
|
1064
|
-
scroller.$observe(container, scrollable);
|
|
1079
|
+
driver.$observe(containerRef, props.scrollRef);
|
|
1065
1080
|
onCleanup(() => {
|
|
1066
1081
|
if (props.ref) {
|
|
1067
1082
|
props.ref();
|
|
1068
1083
|
}
|
|
1069
1084
|
store.$dispose();
|
|
1070
|
-
|
|
1071
|
-
scroller.$dispose();
|
|
1085
|
+
driver.$dispose();
|
|
1072
1086
|
});
|
|
1073
1087
|
});
|
|
1074
1088
|
createComputed(on(() => props.startMargin || 0, (value) => {
|
|
@@ -1077,7 +1091,7 @@ var Virtualizer = (props) => {
|
|
|
1077
1091
|
}
|
|
1078
1092
|
}));
|
|
1079
1093
|
createEffect(on(stateVersion, () => {
|
|
1080
|
-
|
|
1094
|
+
driver.$fixScrollJump();
|
|
1081
1095
|
}));
|
|
1082
1096
|
const dataSlice = createMemo(() => {
|
|
1083
1097
|
const count = props.data.length;
|
|
@@ -1120,7 +1134,7 @@ var Virtualizer = (props) => {
|
|
|
1120
1134
|
const children = createMemo(() => {
|
|
1121
1135
|
return untrack(() => props.children(data, index));
|
|
1122
1136
|
});
|
|
1123
|
-
return <ListItem _as={props.item} _index={index()} _resizer={
|
|
1137
|
+
return <ListItem _as={props.item} _index={index()} _resizer={driver.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} _isSSR={isSSR()} />;
|
|
1124
1138
|
};
|
|
1125
1139
|
return <Dynamic component={props.as} ref={containerRef} style={{
|
|
1126
1140
|
contain: "size style",
|
|
@@ -1149,6 +1163,7 @@ var VList = (props) => {
|
|
|
1149
1163
|
"children",
|
|
1150
1164
|
"bufferSize",
|
|
1151
1165
|
"itemSize",
|
|
1166
|
+
"ssrCount",
|
|
1152
1167
|
"shift",
|
|
1153
1168
|
"horizontal",
|
|
1154
1169
|
"keepMounted",
|
|
@@ -1166,7 +1181,7 @@ var VList = (props) => {
|
|
|
1166
1181
|
height: "100%",
|
|
1167
1182
|
...local.style
|
|
1168
1183
|
}}>
|
|
1169
|
-
<Virtualizer ref={local.ref} data={local.data} bufferSize={local.bufferSize} itemSize={local.itemSize} shift={local.shift} horizontal={local.horizontal} keepMounted={local.keepMounted} cache={local.cache} item={local.item} onScroll={local.onScroll} onScrollEnd={local.onScrollEnd}>
|
|
1184
|
+
<Virtualizer ref={local.ref} data={local.data} bufferSize={local.bufferSize} itemSize={local.itemSize} ssrCount={local.ssrCount} shift={local.shift} horizontal={local.horizontal} keepMounted={local.keepMounted} cache={local.cache} item={local.item} onScroll={local.onScroll} onScrollEnd={local.onScrollEnd}>
|
|
1170
1185
|
{local.children}
|
|
1171
1186
|
</Virtualizer>
|
|
1172
1187
|
</div>;
|
|
@@ -1176,10 +1191,11 @@ var VList = (props) => {
|
|
|
1176
1191
|
//#region src/solid/WindowVirtualizer.tsx
|
|
1177
1192
|
var WindowVirtualizer = (props) => {
|
|
1178
1193
|
let containerRef;
|
|
1179
|
-
const { ref: _ref, data: _data, children: _children, itemSize, shift: _shift, horizontal = false, cache, onScrollEnd: _onScrollEnd } = props;
|
|
1180
|
-
const
|
|
1181
|
-
const
|
|
1182
|
-
const
|
|
1194
|
+
const { ref: _ref, data: _data, children: _children, itemSize, ssrCount, shift: _shift, horizontal = false, cache, onScrollEnd: _onScrollEnd } = props;
|
|
1195
|
+
const [isSSR, setIsSSR] = createSignal(!!ssrCount);
|
|
1196
|
+
const layout = createListLayout(props.data.length, itemSize, cache);
|
|
1197
|
+
const store = createVirtualStore(layout, ssrCount);
|
|
1198
|
+
const driver = createWindowDriver(store, horizontal);
|
|
1183
1199
|
const [stateVersion, setRerender] = createSignal(store.$getStateVersion());
|
|
1184
1200
|
store.$subscribe(1, () => {
|
|
1185
1201
|
setRerender(store.$getStateVersion());
|
|
@@ -1200,12 +1216,13 @@ var WindowVirtualizer = (props) => {
|
|
|
1200
1216
|
});
|
|
1201
1217
|
const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
|
|
1202
1218
|
const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
|
|
1203
|
-
const isNegative = createMemo(() => stateVersion() &&
|
|
1219
|
+
const isNegative = createMemo(() => stateVersion() && driver.$isNegative());
|
|
1204
1220
|
onMount(() => {
|
|
1221
|
+
setIsSSR(false);
|
|
1205
1222
|
if (props.ref) {
|
|
1206
1223
|
props.ref({
|
|
1207
1224
|
get cache() {
|
|
1208
|
-
return
|
|
1225
|
+
return layout.$snapshot();
|
|
1209
1226
|
},
|
|
1210
1227
|
get scrollOffset() {
|
|
1211
1228
|
return store.$getScrollOffset();
|
|
@@ -1216,22 +1233,20 @@ var WindowVirtualizer = (props) => {
|
|
|
1216
1233
|
findItemIndex: store.$findItemIndex,
|
|
1217
1234
|
getItemOffset: store.$getItemOffset,
|
|
1218
1235
|
getItemSize: store.$getItemSize,
|
|
1219
|
-
scrollToIndex:
|
|
1236
|
+
scrollToIndex: (index, opts) => scrollToIndex(driver, store, index, opts)
|
|
1220
1237
|
});
|
|
1221
1238
|
}
|
|
1222
|
-
|
|
1223
|
-
scroller.$observe(containerRef);
|
|
1239
|
+
driver.$observe(containerRef);
|
|
1224
1240
|
onCleanup(() => {
|
|
1225
1241
|
if (props.ref) {
|
|
1226
1242
|
props.ref();
|
|
1227
1243
|
}
|
|
1228
1244
|
store.$dispose();
|
|
1229
|
-
|
|
1230
|
-
scroller.$dispose();
|
|
1245
|
+
driver.$dispose();
|
|
1231
1246
|
});
|
|
1232
1247
|
});
|
|
1233
1248
|
createEffect(on(stateVersion, () => {
|
|
1234
|
-
|
|
1249
|
+
driver.$fixScrollJump();
|
|
1235
1250
|
}));
|
|
1236
1251
|
const dataSlice = createMemo(() => {
|
|
1237
1252
|
const count = props.data.length;
|
|
@@ -1269,7 +1284,7 @@ var WindowVirtualizer = (props) => {
|
|
|
1269
1284
|
const children = createMemo(() => {
|
|
1270
1285
|
return untrack(() => props.children(data, itemIndex));
|
|
1271
1286
|
});
|
|
1272
|
-
return <ListItem _index={itemIndex()} _resizer={
|
|
1287
|
+
return <ListItem _index={itemIndex()} _resizer={driver.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} _isSSR={isSSR()} />;
|
|
1273
1288
|
}}
|
|
1274
1289
|
</For>
|
|
1275
1290
|
</div>;
|