virtua 0.49.2 → 0.50.0
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/README.md +39 -5
- package/lib/angular/ListItem.d.ts +1 -0
- package/lib/angular/VList.d.ts +85 -0
- package/lib/angular/Virtualizer.d.ts +141 -0
- package/lib/angular/WindowVirtualizer.d.ts +103 -0
- package/lib/angular/index.d.ts +6 -0
- package/lib/angular/index.js +1148 -0
- package/lib/angular/index.js.map +1 -0
- package/lib/angular/utils.d.ts +19 -0
- package/lib/core/index.cjs +237 -233
- package/lib/core/index.cjs.map +1 -1
- package/lib/core/index.d.ts +6 -6
- package/lib/core/index.js +272 -272
- package/lib/core/index.js.map +1 -1
- package/lib/index.cjs +529 -499
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +321 -315
- package/lib/index.js.map +1 -1
- package/lib/react/VGrid.d.ts +2 -2
- package/lib/react/VList.d.ts +3 -3
- package/lib/react/Virtualizer.d.ts +3 -3
- package/lib/react/WindowVirtualizer.d.ts +3 -3
- package/lib/react/index.d.ts +9 -9
- package/lib/react/types.d.ts +1 -1
- package/lib/solid/VList.d.ts +3 -6
- package/lib/solid/Virtualizer.d.ts +2 -5
- package/lib/solid/WindowVirtualizer.d.ts +2 -5
- package/lib/solid/index.cjs +331 -323
- package/lib/solid/index.cjs.map +1 -1
- package/lib/solid/index.d.ts +7 -7
- package/lib/solid/index.js +249 -257
- package/lib/solid/index.js.map +1 -1
- package/lib/solid/index.jsx +1224 -1566
- package/lib/solid/index.jsx.map +1 -1
- package/lib/solid/types.d.ts +1 -1
- package/lib/svelte/ListItem.svelte +12 -2
- package/lib/svelte/VList.svelte +2 -0
- package/lib/svelte/VList.type.d.ts +3 -3
- package/lib/svelte/Virtualizer.svelte +2 -0
- package/lib/svelte/Virtualizer.type.d.ts +8 -3
- package/lib/svelte/WindowVirtualizer.type.d.ts +2 -2
- package/lib/svelte/index.d.ts +6 -6
- package/lib/svelte/index.js +4 -4
- package/lib/svelte/types.d.ts +1 -1
- package/lib/svelte/utils.d.ts +7 -0
- package/lib/svelte/utils.js +11 -11
- package/lib/svelte/utils.js.map +1 -1
- package/lib/vue/VList.d.ts +2 -3
- package/lib/vue/Virtualizer.d.ts +3 -4
- package/lib/vue/WindowVirtualizer.d.ts +2 -3
- package/lib/vue/index.cjs +327 -317
- package/lib/vue/index.cjs.map +1 -1
- package/lib/vue/index.d.ts +6 -6
- package/lib/vue/index.js +284 -284
- package/lib/vue/index.js.map +1 -1
- package/lib/vue/utils.d.ts +1 -1
- package/package.json +40 -17
- package/lib/svelte/index.js.map +0 -1
package/lib/solid/index.jsx
CHANGED
|
@@ -1,1622 +1,1280 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Dynamic } from
|
|
1
|
+
import { For, createComputed, createEffect, createMemo, createSignal, mergeProps, on, onCleanup, onMount, splitProps, untrack } from "solid-js";
|
|
2
|
+
import { Dynamic } from "solid-js/web";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
const clamp = (value, minValue, maxValue) => min(maxValue, max(minValue, value));
|
|
12
|
-
/**
|
|
13
|
-
* @internal
|
|
14
|
-
*/
|
|
15
|
-
const sort = (arr) => {
|
|
16
|
-
return [...arr].sort((a, b) => a - b);
|
|
4
|
+
//#region src/core/utils.ts
|
|
5
|
+
var NULL = null;
|
|
6
|
+
var { min, max, abs, floor } = Math;
|
|
7
|
+
var clamp = (value, minValue, maxValue) => min(maxValue, max(minValue, value));
|
|
8
|
+
var sort = (arr) => {
|
|
9
|
+
return [...arr].sort((a, b) => a - b);
|
|
17
10
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
const microtask = typeof queueMicrotask === "function"
|
|
22
|
-
? queueMicrotask
|
|
23
|
-
: (fn) => {
|
|
24
|
-
Promise.resolve().then(fn);
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* @internal
|
|
28
|
-
*/
|
|
29
|
-
const createPromise = () => {
|
|
30
|
-
let resolve;
|
|
31
|
-
const promise = new Promise((res) => {
|
|
32
|
-
resolve = res;
|
|
33
|
-
});
|
|
34
|
-
return [promise, resolve];
|
|
11
|
+
var microtask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
|
|
12
|
+
Promise.resolve().then(fn);
|
|
35
13
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
14
|
+
var createPromise = () => {
|
|
15
|
+
let resolve;
|
|
16
|
+
const promise = new Promise((res) => {
|
|
17
|
+
resolve = res;
|
|
18
|
+
});
|
|
19
|
+
return [promise, resolve];
|
|
20
|
+
};
|
|
21
|
+
var once = (fn) => {
|
|
22
|
+
let cache;
|
|
23
|
+
return () => {
|
|
24
|
+
if (fn) {
|
|
25
|
+
cache = fn();
|
|
26
|
+
fn = undefined;
|
|
27
|
+
}
|
|
28
|
+
return cache;
|
|
29
|
+
};
|
|
48
30
|
};
|
|
49
31
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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;
|
|
58
41
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const getItemSize = (cache, index) => {
|
|
63
|
-
const size = cache._sizes[index];
|
|
64
|
-
return size === UNCACHED ? cache._defaultItemSize : size;
|
|
42
|
+
var getItemSize = (cache, index) => {
|
|
43
|
+
const size = cache._sizes[index];
|
|
44
|
+
return size === -1 ? cache._defaultItemSize : size;
|
|
65
45
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
cache._sizes[index] = size;
|
|
72
|
-
// mark as dirty
|
|
73
|
-
cache._computedOffsetIndex = min(index, cache._computedOffsetIndex);
|
|
74
|
-
return isInitialMeasurement;
|
|
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;
|
|
75
51
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
while (i < index) {
|
|
94
|
-
top += getItemSize(cache, i);
|
|
95
|
-
cache._offsets[++i] = top;
|
|
96
|
-
}
|
|
97
|
-
// mark as measured
|
|
98
|
-
cache._computedOffsetIndex = index;
|
|
99
|
-
return top;
|
|
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;
|
|
100
69
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
low = mid + 1;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
high = mid - 1;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return clamp(found, 0, cache._length - 1);
|
|
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);
|
|
120
82
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const end = findIndex(cache, endOffset, prevStartIndex);
|
|
131
|
-
return [findIndex(cache, startOffset, prevStartIndex, end), end];
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// search backward
|
|
135
|
-
// start <= end, start <= prevStartIndex
|
|
136
|
-
const start = findIndex(cache, startOffset, undefined, prevStartIndex);
|
|
137
|
-
return [start, findIndex(cache, endOffset, start)];
|
|
138
|
-
}
|
|
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
|
+
}
|
|
139
92
|
};
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const sorted = sort(measuredSizes);
|
|
159
|
-
const len = sorted.length;
|
|
160
|
-
const mid = (len / 2) | 0;
|
|
161
|
-
const median = len % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
162
|
-
const prevDefaultItemSize = cache._defaultItemSize;
|
|
163
|
-
// Calculate diff of unmeasured items before start
|
|
164
|
-
return (((cache._defaultItemSize = median) - prevDefaultItemSize) *
|
|
165
|
-
max(startIndex - measuredCountBeforeStart, 0));
|
|
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);
|
|
166
111
|
};
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
fill(sizes.slice(0, min(length, sizes.length)), max(0, length - sizes.length))
|
|
176
|
-
: fill([], length),
|
|
177
|
-
_length: length,
|
|
178
|
-
_computedOffsetIndex: -1,
|
|
179
|
-
_offsets: fill([], length + 1),
|
|
180
|
-
};
|
|
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
|
+
};
|
|
181
120
|
};
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
*/
|
|
185
|
-
const takeCacheSnapshot = (cache) => {
|
|
186
|
-
return [cache._sizes.slice(), cache._defaultItemSize];
|
|
121
|
+
var takeCacheSnapshot = (cache) => {
|
|
122
|
+
return [cache._sizes.slice(), cache._defaultItemSize];
|
|
187
123
|
};
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
fill(cache._offsets, diff);
|
|
201
|
-
fill(cache._sizes, diff, isShift);
|
|
202
|
-
return cache._defaultItemSize * diff;
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
// Removed
|
|
206
|
-
cache._offsets.splice(diff);
|
|
207
|
-
return (isShift ? cache._sizes.splice(0, -diff) : cache._sizes.splice(diff)).reduce((acc, removed) => acc - (removed === UNCACHED ? cache._defaultItemSize : removed), 0);
|
|
208
|
-
}
|
|
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
|
+
}
|
|
209
136
|
};
|
|
210
137
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
*/
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const getCurrentDocument = (node) => node.ownerDocument;
|
|
223
|
-
/**
|
|
224
|
-
* @internal
|
|
225
|
-
*/
|
|
226
|
-
const getCurrentWindow = (doc) => doc.defaultView;
|
|
227
|
-
/**
|
|
228
|
-
* Currently, all browsers on iOS/iPadOS are WebKit, including WebView.
|
|
229
|
-
* @internal
|
|
230
|
-
*/
|
|
231
|
-
const isIOSWebKit = /*#__PURE__*/ once(() => {
|
|
232
|
-
if (/iP(hone|od|ad)/.test(navigator.userAgent)) {
|
|
233
|
-
return true;
|
|
234
|
-
}
|
|
235
|
-
// Modern iPad detection (iPadOS 13+)
|
|
236
|
-
// iPadOS 13+ reports the same userAgent/platform information as macOS, to enable desktop sites.
|
|
237
|
-
// So we treat devices that have macOS like information but with touch support as iPadOS.
|
|
238
|
-
// https://stackoverflow.com/questions/57776001/how-to-detect-ipad-pro-as-ipad-using-javascript
|
|
239
|
-
return navigator.platform === "MacIntel" && navigator.maxTouchPoints > 0;
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/core/environment.ts
|
|
140
|
+
var isBrowser = typeof window !== "undefined";
|
|
141
|
+
var getDocumentElement = (doc) => doc.documentElement;
|
|
142
|
+
var getCurrentDocument = (node) => node.ownerDocument;
|
|
143
|
+
var getCurrentWindow = (doc) => doc.defaultView;
|
|
144
|
+
var isIOSWebKit = /*#__PURE__*/ once(() => {
|
|
145
|
+
if (/iP(hone|od|ad)/.test(navigator.userAgent)) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
return navigator.platform === "MacIntel" && navigator.maxTouchPoints > 0;
|
|
240
149
|
});
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
*/
|
|
244
|
-
const isSmoothScrollSupported = /*#__PURE__*/ once(() => {
|
|
245
|
-
return "scrollBehavior" in getDocumentElement(document).style;
|
|
150
|
+
var isSmoothScrollSupported = /*#__PURE__*/ once(() => {
|
|
151
|
+
return "scrollBehavior" in getDocumentElement(document).style;
|
|
246
152
|
});
|
|
247
153
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
/** @internal */
|
|
272
|
-
const UPDATE_VIRTUAL_STATE = 0b0001;
|
|
273
|
-
/** @internal */
|
|
274
|
-
const UPDATE_SIZE_EVENT = 0b0010;
|
|
275
|
-
/** @internal */
|
|
276
|
-
const UPDATE_SCROLL_EVENT = 0b0100;
|
|
277
|
-
/** @internal */
|
|
278
|
-
const UPDATE_SCROLL_END_EVENT = 0b1000;
|
|
279
|
-
/**
|
|
280
|
-
* @internal
|
|
281
|
-
*/
|
|
282
|
-
const getScrollSize = (store) => {
|
|
283
|
-
return max(store.$getTotalSize(), store.$getViewportSize());
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/core/store.ts
|
|
156
|
+
var MAX_INT_32 = 2147483647;
|
|
157
|
+
var SCROLL_IDLE = 0;
|
|
158
|
+
var SCROLL_DOWN = 1;
|
|
159
|
+
var SCROLL_UP = 2;
|
|
160
|
+
var SCROLL_BY_NATIVE = 0;
|
|
161
|
+
var SCROLL_BY_MANUAL_SCROLL = 1;
|
|
162
|
+
var SCROLL_BY_SHIFT = 2;
|
|
163
|
+
var ACTION_SCROLL = 1;
|
|
164
|
+
var ACTION_SCROLL_END = 2;
|
|
165
|
+
var ACTION_ITEM_RESIZE = 3;
|
|
166
|
+
var ACTION_VIEWPORT_RESIZE = 4;
|
|
167
|
+
var ACTION_ITEMS_LENGTH_CHANGE = 5;
|
|
168
|
+
var ACTION_START_OFFSET_CHANGE = 6;
|
|
169
|
+
var ACTION_MANUAL_SCROLL = 7;
|
|
170
|
+
var ACTION_BEFORE_MANUAL_SMOOTH_SCROLL = 8;
|
|
171
|
+
var UPDATE_VIRTUAL_STATE = 1;
|
|
172
|
+
var UPDATE_SIZE_EVENT = 2;
|
|
173
|
+
var UPDATE_SCROLL_EVENT = 4;
|
|
174
|
+
var UPDATE_SCROLL_END_EVENT = 8;
|
|
175
|
+
var getScrollSize = (store) => {
|
|
176
|
+
return max(store.$getTotalSize(), store.$getViewportSize());
|
|
284
177
|
};
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
const isInitialMeasurement = setItemSize(cache, index, size);
|
|
516
|
-
if (shouldAutoEstimateItemSize) {
|
|
517
|
-
_totalMeasuredSize += isInitialMeasurement
|
|
518
|
-
? size
|
|
519
|
-
: size - prevSize;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
// Estimate initial item size from measured sizes
|
|
523
|
-
if (shouldAutoEstimateItemSize &&
|
|
524
|
-
viewportSize &&
|
|
525
|
-
// If the total size is lower than the viewport, the item may be a empty state
|
|
526
|
-
_totalMeasuredSize > viewportSize) {
|
|
527
|
-
applyJump(estimateDefaultItemSize(cache, findIndex(cache, getVisibleOffset())));
|
|
528
|
-
shouldAutoEstimateItemSize = false;
|
|
529
|
-
}
|
|
530
|
-
mutated = UPDATE_VIRTUAL_STATE + UPDATE_SIZE_EVENT;
|
|
531
|
-
// Synchronous update is necessary in current design to minimize visible glitch in concurrent rendering.
|
|
532
|
-
// However this seems to be the main cause of the errors from ResizeObserver.
|
|
533
|
-
// https://github.com/inokawa/virtua/issues/470
|
|
534
|
-
//
|
|
535
|
-
// And in React, synchronous update with flushSync after asynchronous update will overtake the asynchronous one.
|
|
536
|
-
// If items resize happens just after scroll, race condition can occur depending on implementation.
|
|
537
|
-
shouldSync = true;
|
|
538
|
-
break;
|
|
539
|
-
}
|
|
540
|
-
case ACTION_VIEWPORT_RESIZE: {
|
|
541
|
-
if (viewportSize !== payload) {
|
|
542
|
-
if (!viewportSize) {
|
|
543
|
-
_isViewportMeasured = shouldSync = true;
|
|
544
|
-
}
|
|
545
|
-
viewportSize = payload;
|
|
546
|
-
mutated = UPDATE_VIRTUAL_STATE + UPDATE_SIZE_EVENT;
|
|
547
|
-
}
|
|
548
|
-
break;
|
|
549
|
-
}
|
|
550
|
-
case ACTION_ITEMS_LENGTH_CHANGE: {
|
|
551
|
-
if (payload[1]) {
|
|
552
|
-
applyJump(updateCacheLength(cache, payload[0], true));
|
|
553
|
-
_scrollMode = SCROLL_BY_SHIFT;
|
|
554
|
-
mutated = UPDATE_VIRTUAL_STATE;
|
|
555
|
-
}
|
|
556
|
-
else {
|
|
557
|
-
updateCacheLength(cache, payload[0]);
|
|
558
|
-
// https://github.com/inokawa/virtua/issues/552
|
|
559
|
-
// https://github.com/inokawa/virtua/issues/557
|
|
560
|
-
mutated = UPDATE_VIRTUAL_STATE;
|
|
561
|
-
}
|
|
562
|
-
break;
|
|
563
|
-
}
|
|
564
|
-
case ACTION_START_OFFSET_CHANGE: {
|
|
565
|
-
startSpacerSize = payload;
|
|
566
|
-
break;
|
|
567
|
-
}
|
|
568
|
-
case ACTION_MANUAL_SCROLL: {
|
|
569
|
-
_scrollMode = SCROLL_BY_MANUAL_SCROLL;
|
|
570
|
-
break;
|
|
571
|
-
}
|
|
572
|
-
case ACTION_BEFORE_MANUAL_SMOOTH_SCROLL: {
|
|
573
|
-
_frozenRange = getRange(payload, payload + viewportSize);
|
|
574
|
-
mutated = UPDATE_VIRTUAL_STATE;
|
|
575
|
-
break;
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
if (mutated) {
|
|
579
|
-
stateVersion = (stateVersion & MAX_INT_32) + 1;
|
|
580
|
-
if (shouldFlushPendingJump && pendingJump) {
|
|
581
|
-
jump += pendingJump;
|
|
582
|
-
pendingJump = 0;
|
|
583
|
-
}
|
|
584
|
-
subscribers.forEach(([target, cb]) => {
|
|
585
|
-
// Early return to skip React's computation
|
|
586
|
-
if (!(mutated & target)) {
|
|
587
|
-
return;
|
|
588
|
-
}
|
|
589
|
-
// https://github.com/facebook/react/issues/25191
|
|
590
|
-
// https://github.com/facebook/react/blob/a5fc797db14c6e05d4d5c4dbb22a0dd70d41f5d5/packages/react-reconciler/src/ReactFiberWorkLoop.js#L1443-L1447
|
|
591
|
-
cb(shouldSync);
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
},
|
|
595
|
-
};
|
|
178
|
+
var createVirtualStore = (elementsCount, itemSize = 40, ssrCount = 0, cacheSnapshot, shouldAutoEstimateItemSize = false) => {
|
|
179
|
+
let isSSR = !!ssrCount;
|
|
180
|
+
let stateVersion = 1;
|
|
181
|
+
let viewportSize = 0;
|
|
182
|
+
let startSpacerSize = 0;
|
|
183
|
+
let scrollOffset = 0;
|
|
184
|
+
let jump = 0;
|
|
185
|
+
let pendingJump = 0;
|
|
186
|
+
let _flushedJump = 0;
|
|
187
|
+
let _scrollDirection = SCROLL_IDLE;
|
|
188
|
+
let _scrollMode = SCROLL_BY_NATIVE;
|
|
189
|
+
let _frozenRange = null;
|
|
190
|
+
let _prevRange = [0, isSSR ? max(ssrCount - 1, 0) : -1];
|
|
191
|
+
let _totalMeasuredSize = 0;
|
|
192
|
+
let _isViewportMeasured = false;
|
|
193
|
+
const cache = initCache(elementsCount, cacheSnapshot ? cacheSnapshot[1] : itemSize, cacheSnapshot && cacheSnapshot[0]);
|
|
194
|
+
const subscribers = new Set();
|
|
195
|
+
const getRelativeScrollOffset = () => scrollOffset - startSpacerSize;
|
|
196
|
+
const getVisibleOffset = () => getRelativeScrollOffset() + pendingJump + jump;
|
|
197
|
+
const getRange = (startOffset, endOffset) => {
|
|
198
|
+
return computeRange(cache, startOffset, endOffset, _prevRange[0]);
|
|
199
|
+
};
|
|
200
|
+
const getTotalSize = () => getItemOffset(cache, cache._length);
|
|
201
|
+
const getItemOffset$1 = (index, fromEnd) => {
|
|
202
|
+
const offset = getItemOffset(cache, index) - pendingJump;
|
|
203
|
+
if (fromEnd) {
|
|
204
|
+
return getTotalSize() - offset - getItemSize$1(index);
|
|
205
|
+
}
|
|
206
|
+
return offset;
|
|
207
|
+
};
|
|
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
|
+
const applyJump = (j) => {
|
|
215
|
+
if (j) {
|
|
216
|
+
if (isIOSWebKit() && _scrollDirection !== SCROLL_IDLE || _frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL) {
|
|
217
|
+
pendingJump += j;
|
|
218
|
+
} else {
|
|
219
|
+
jump += j;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
return {
|
|
224
|
+
$dispose: () => {
|
|
225
|
+
subscribers.clear();
|
|
226
|
+
},
|
|
227
|
+
$getStateVersion: () => stateVersion,
|
|
228
|
+
$getCacheSnapshot: () => {
|
|
229
|
+
return takeCacheSnapshot(cache);
|
|
230
|
+
},
|
|
231
|
+
$getRange: (bufferSize = 200) => {
|
|
232
|
+
if (!_isViewportMeasured || isSSR) {
|
|
233
|
+
return _prevRange;
|
|
234
|
+
}
|
|
235
|
+
let startIndex;
|
|
236
|
+
let endIndex;
|
|
237
|
+
if (_flushedJump) {
|
|
238
|
+
[startIndex, endIndex] = _prevRange;
|
|
239
|
+
} else {
|
|
240
|
+
let startOffset = max(0, getVisibleOffset());
|
|
241
|
+
let endOffset = startOffset + viewportSize;
|
|
242
|
+
if (!shouldAutoEstimateItemSize) {
|
|
243
|
+
bufferSize = max(0, bufferSize);
|
|
244
|
+
if (_scrollDirection !== SCROLL_DOWN) {
|
|
245
|
+
startOffset -= bufferSize;
|
|
246
|
+
}
|
|
247
|
+
if (_scrollDirection !== SCROLL_UP) {
|
|
248
|
+
endOffset += bufferSize;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
[startIndex, endIndex] = _prevRange = getRange(max(0, startOffset), max(0, endOffset));
|
|
252
|
+
if (_frozenRange) {
|
|
253
|
+
startIndex = min(startIndex, _frozenRange[0]);
|
|
254
|
+
endIndex = max(endIndex, _frozenRange[1]);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return [max(startIndex, 0), min(endIndex, cache._length - 1)];
|
|
258
|
+
},
|
|
259
|
+
$findItemIndex: (offset) => findIndex(cache, offset - startSpacerSize),
|
|
260
|
+
$isUnmeasuredItem: isSizeEqual,
|
|
261
|
+
$getItemOffset: getItemOffset$1,
|
|
262
|
+
$getItemSize: getItemSize$1,
|
|
263
|
+
$getItemsLength: () => cache._length,
|
|
264
|
+
$getScrollOffset: () => scrollOffset,
|
|
265
|
+
$isScrolling: () => _scrollDirection !== SCROLL_IDLE,
|
|
266
|
+
$getViewportSize: () => viewportSize,
|
|
267
|
+
$getStartSpacerSize: () => startSpacerSize,
|
|
268
|
+
$getTotalSize: getTotalSize,
|
|
269
|
+
_flushJump: () => {
|
|
270
|
+
_flushedJump = jump;
|
|
271
|
+
jump = 0;
|
|
272
|
+
return [_flushedJump, _scrollMode === SCROLL_BY_SHIFT];
|
|
273
|
+
},
|
|
274
|
+
$subscribe: (target, cb) => {
|
|
275
|
+
const sub = [target, cb];
|
|
276
|
+
subscribers.add(sub);
|
|
277
|
+
return () => {
|
|
278
|
+
subscribers.delete(sub);
|
|
279
|
+
};
|
|
280
|
+
},
|
|
281
|
+
$update: (type, payload) => {
|
|
282
|
+
let shouldFlushPendingJump;
|
|
283
|
+
let shouldSync;
|
|
284
|
+
let mutated = 0;
|
|
285
|
+
switch (type) {
|
|
286
|
+
case 1: {
|
|
287
|
+
if (payload === scrollOffset && _scrollMode === SCROLL_BY_NATIVE) {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
const flushedJump = _flushedJump;
|
|
291
|
+
_flushedJump = 0;
|
|
292
|
+
const delta = payload - scrollOffset;
|
|
293
|
+
const distance = abs(delta);
|
|
294
|
+
const isJustJumped = flushedJump && distance < abs(flushedJump) + 1;
|
|
295
|
+
if (!isJustJumped && _scrollMode === SCROLL_BY_NATIVE) {
|
|
296
|
+
_scrollDirection = delta < 0 ? SCROLL_UP : SCROLL_DOWN;
|
|
297
|
+
}
|
|
298
|
+
if (isSSR) {
|
|
299
|
+
isSSR = false;
|
|
300
|
+
}
|
|
301
|
+
scrollOffset = payload;
|
|
302
|
+
mutated = 4;
|
|
303
|
+
const relativeOffset = getRelativeScrollOffset();
|
|
304
|
+
if (relativeOffset >= -viewportSize && relativeOffset <= getTotalSize()) {
|
|
305
|
+
mutated += 1;
|
|
306
|
+
shouldSync = distance > viewportSize;
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
case 2: {
|
|
311
|
+
mutated = 8;
|
|
312
|
+
if (_scrollDirection !== SCROLL_IDLE) {
|
|
313
|
+
shouldFlushPendingJump = true;
|
|
314
|
+
mutated += 1;
|
|
315
|
+
}
|
|
316
|
+
_scrollDirection = SCROLL_IDLE;
|
|
317
|
+
_scrollMode = SCROLL_BY_NATIVE;
|
|
318
|
+
_frozenRange = null;
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
case 3: {
|
|
322
|
+
const updated = payload.filter(([index, size]) => !isSizeEqual(index, size));
|
|
323
|
+
if (!updated.length) {
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
applyJump(updated.reduce((acc, [index, size]) => {
|
|
327
|
+
let shouldKeep;
|
|
328
|
+
if (_scrollMode === SCROLL_BY_SHIFT) {
|
|
329
|
+
shouldKeep = true;
|
|
330
|
+
} else if (_frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL) {
|
|
331
|
+
shouldKeep = index < _frozenRange[0];
|
|
332
|
+
} else {
|
|
333
|
+
const start = getRelativeScrollOffset();
|
|
334
|
+
const itemOffset = getItemOffset$1(index);
|
|
335
|
+
const itemSize = getItemSize$1(index);
|
|
336
|
+
shouldKeep = _scrollDirection !== SCROLL_DOWN && _scrollMode === SCROLL_BY_NATIVE ? itemOffset + itemSize <= start : itemOffset < start && itemOffset + itemSize < start + viewportSize;
|
|
337
|
+
}
|
|
338
|
+
if (shouldKeep) {
|
|
339
|
+
acc += size - getItemSize$1(index);
|
|
340
|
+
}
|
|
341
|
+
return acc;
|
|
342
|
+
}, 0));
|
|
343
|
+
for (const [index, size] of updated) {
|
|
344
|
+
const prevSize = getItemSize$1(index);
|
|
345
|
+
const isInitialMeasurement = setItemSize(cache, index, size);
|
|
346
|
+
if (shouldAutoEstimateItemSize) {
|
|
347
|
+
_totalMeasuredSize += isInitialMeasurement ? size : size - prevSize;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (shouldAutoEstimateItemSize && viewportSize && _totalMeasuredSize > viewportSize) {
|
|
351
|
+
applyJump(estimateDefaultItemSize(cache, findIndex(cache, getVisibleOffset())));
|
|
352
|
+
shouldAutoEstimateItemSize = false;
|
|
353
|
+
}
|
|
354
|
+
mutated = 1 + 2;
|
|
355
|
+
shouldSync = true;
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
case 4: {
|
|
359
|
+
if (viewportSize !== payload) {
|
|
360
|
+
if (!viewportSize) {
|
|
361
|
+
_isViewportMeasured = shouldSync = true;
|
|
362
|
+
}
|
|
363
|
+
viewportSize = payload;
|
|
364
|
+
mutated = 1 + 2;
|
|
365
|
+
}
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
case 5: {
|
|
369
|
+
if (payload[1]) {
|
|
370
|
+
applyJump(updateCacheLength(cache, payload[0], true));
|
|
371
|
+
_scrollMode = SCROLL_BY_SHIFT;
|
|
372
|
+
mutated = 1;
|
|
373
|
+
} else {
|
|
374
|
+
updateCacheLength(cache, payload[0]);
|
|
375
|
+
mutated = 1;
|
|
376
|
+
}
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
case 6: {
|
|
380
|
+
startSpacerSize = payload;
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
case 7: {
|
|
384
|
+
_scrollMode = SCROLL_BY_MANUAL_SCROLL;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case 8: {
|
|
388
|
+
_frozenRange = getRange(payload, payload + viewportSize);
|
|
389
|
+
mutated = 1;
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (mutated) {
|
|
394
|
+
stateVersion = (stateVersion & MAX_INT_32) + 1;
|
|
395
|
+
if (shouldFlushPendingJump && pendingJump) {
|
|
396
|
+
jump += pendingJump;
|
|
397
|
+
pendingJump = 0;
|
|
398
|
+
}
|
|
399
|
+
subscribers.forEach(([target, cb]) => {
|
|
400
|
+
if (!(mutated & target)) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
cb(shouldSync);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
};
|
|
596
408
|
};
|
|
597
409
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
410
|
+
//#endregion
|
|
411
|
+
//#region src/core/scroller.ts
|
|
412
|
+
var timeout = setTimeout;
|
|
413
|
+
var debounce = (fn, ms) => {
|
|
414
|
+
let id;
|
|
415
|
+
const cancel = () => {
|
|
416
|
+
if (id != null) {
|
|
417
|
+
clearTimeout(id);
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
const debouncedFn = () => {
|
|
421
|
+
cancel();
|
|
422
|
+
id = timeout(() => {
|
|
423
|
+
id = null;
|
|
424
|
+
fn();
|
|
425
|
+
}, ms);
|
|
426
|
+
};
|
|
427
|
+
debouncedFn._cancel = cancel;
|
|
428
|
+
return debouncedFn;
|
|
615
429
|
};
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
* - direction: rtl https://github.com/othree/jquery.rtl-scroll-type
|
|
619
|
-
* - writing-mode https://people.igalia.com/fwang/scrollable-elements-in-non-default-writing-modes/
|
|
620
|
-
* - flex-direction: column-reverse/row-reverse
|
|
621
|
-
*
|
|
622
|
-
* top/left bottom/right
|
|
623
|
-
* 0 100 spec compliant bottom/right overflow, or possibly top/left overflow in Chrome earlier than v85
|
|
624
|
-
* -100 0 spec compliant top/left overflow
|
|
625
|
-
* https://drafts.csswg.org/cssom-view/#scroll-an-element
|
|
626
|
-
*/
|
|
627
|
-
const normalizeScrollOffset = (offset, isNegative) => {
|
|
628
|
-
return isNegative ? -offset : offset;
|
|
430
|
+
var normalizeScrollOffset = (offset, isNegative) => {
|
|
431
|
+
return isNegative ? -offset : offset;
|
|
629
432
|
};
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
viewport.removeEventListener("touchstart", onTouchStart);
|
|
699
|
-
viewport.removeEventListener("touchend", onTouchEnd);
|
|
700
|
-
onScrollEnd._cancel();
|
|
701
|
-
},
|
|
702
|
-
_fixScrollJump: () => {
|
|
703
|
-
const [jump, shift] = store._flushJump();
|
|
704
|
-
if (!jump)
|
|
705
|
-
return;
|
|
706
|
-
updateScrollOffset(jump, shift, stillMomentumScrolling);
|
|
707
|
-
stillMomentumScrolling = false;
|
|
708
|
-
if (shift && store.$getViewportSize() > store.$getTotalSize()) {
|
|
709
|
-
// In this case applying jump may not cause scroll.
|
|
710
|
-
// Current logic expects scroll event occurs after applying jump so we dispatch it manually.
|
|
711
|
-
store.$update(ACTION_SCROLL, getScrollOffset());
|
|
712
|
-
}
|
|
713
|
-
},
|
|
714
|
-
};
|
|
433
|
+
var createScrollObserver = (store, viewport, isHorizontal, getScrollOffset, updateScrollOffset, getStartOffset) => {
|
|
434
|
+
const now = Date.now;
|
|
435
|
+
let lastScrollTime = 0;
|
|
436
|
+
let wheeling = false;
|
|
437
|
+
let touching = false;
|
|
438
|
+
let justTouchEnded = false;
|
|
439
|
+
let stillMomentumScrolling = false;
|
|
440
|
+
const onScrollEnd = debounce(() => {
|
|
441
|
+
if (wheeling || touching) {
|
|
442
|
+
wheeling = false;
|
|
443
|
+
onScrollEnd();
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
justTouchEnded = false;
|
|
447
|
+
store.$update(2);
|
|
448
|
+
}, 150);
|
|
449
|
+
const onScroll = () => {
|
|
450
|
+
lastScrollTime = now();
|
|
451
|
+
if (justTouchEnded) {
|
|
452
|
+
stillMomentumScrolling = true;
|
|
453
|
+
}
|
|
454
|
+
if (getStartOffset) {
|
|
455
|
+
store.$update(6, getStartOffset());
|
|
456
|
+
}
|
|
457
|
+
store.$update(1, getScrollOffset());
|
|
458
|
+
onScrollEnd();
|
|
459
|
+
};
|
|
460
|
+
const onWheel = ((e) => {
|
|
461
|
+
if (wheeling || !store.$isScrolling() || e.ctrlKey) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const timeDelta = now() - lastScrollTime;
|
|
465
|
+
if (150 > timeDelta && 50 < timeDelta && (isHorizontal ? e.deltaX : e.deltaY)) {
|
|
466
|
+
wheeling = true;
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
const onTouchStart = () => {
|
|
470
|
+
touching = true;
|
|
471
|
+
justTouchEnded = stillMomentumScrolling = false;
|
|
472
|
+
};
|
|
473
|
+
const onTouchEnd = () => {
|
|
474
|
+
touching = false;
|
|
475
|
+
if (isIOSWebKit()) {
|
|
476
|
+
justTouchEnded = true;
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
viewport.addEventListener("scroll", onScroll);
|
|
480
|
+
viewport.addEventListener("wheel", onWheel, { passive: true });
|
|
481
|
+
viewport.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
482
|
+
viewport.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
483
|
+
return {
|
|
484
|
+
_dispose: () => {
|
|
485
|
+
viewport.removeEventListener("scroll", onScroll);
|
|
486
|
+
viewport.removeEventListener("wheel", onWheel);
|
|
487
|
+
viewport.removeEventListener("touchstart", onTouchStart);
|
|
488
|
+
viewport.removeEventListener("touchend", onTouchEnd);
|
|
489
|
+
onScrollEnd._cancel();
|
|
490
|
+
},
|
|
491
|
+
_fixScrollJump: () => {
|
|
492
|
+
const [jump, shift] = store._flushJump();
|
|
493
|
+
if (!jump) return;
|
|
494
|
+
updateScrollOffset(jump, shift, stillMomentumScrolling);
|
|
495
|
+
stillMomentumScrolling = false;
|
|
496
|
+
if (shift && store.$getViewportSize() > store.$getTotalSize()) {
|
|
497
|
+
store.$update(1, getScrollOffset());
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
};
|
|
715
501
|
};
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
scroll(getTargetOffset(), smooth);
|
|
781
|
-
});
|
|
782
|
-
}
|
|
783
|
-
else {
|
|
784
|
-
while (true) {
|
|
785
|
-
const [promise, unsubscribe] = waitForMeasurement();
|
|
786
|
-
try {
|
|
787
|
-
store.$update(ACTION_MANUAL_SCROLL);
|
|
788
|
-
scroll(getTargetOffset());
|
|
789
|
-
if (!(await promise)) {
|
|
790
|
-
// canceled or finished
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
finally {
|
|
795
|
-
unsubscribe();
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
},
|
|
800
|
-
() => {
|
|
801
|
-
cancelScroll && cancelScroll();
|
|
802
|
-
},
|
|
803
|
-
];
|
|
502
|
+
var createScrollScheduler = (store, initialized, scroll) => {
|
|
503
|
+
let cancelScroll;
|
|
504
|
+
return [async (getTargetOffset, smooth) => {
|
|
505
|
+
if (!await initialized()) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (cancelScroll) {
|
|
509
|
+
cancelScroll();
|
|
510
|
+
}
|
|
511
|
+
const waitForMeasurement = () => {
|
|
512
|
+
const [promise, resolve] = createPromise();
|
|
513
|
+
cancelScroll = () => {
|
|
514
|
+
resolve(false);
|
|
515
|
+
};
|
|
516
|
+
if (store.$getViewportSize()) {
|
|
517
|
+
timeout(cancelScroll, 150);
|
|
518
|
+
}
|
|
519
|
+
return [promise, store.$subscribe(2, () => {
|
|
520
|
+
resolve(true);
|
|
521
|
+
})];
|
|
522
|
+
};
|
|
523
|
+
if (smooth && isSmoothScrollSupported()) {
|
|
524
|
+
store.$update(8, getTargetOffset());
|
|
525
|
+
microtask(async () => {
|
|
526
|
+
while (true) {
|
|
527
|
+
let done = true;
|
|
528
|
+
for (let [i, end] = store.$getRange(); i <= end; i++) {
|
|
529
|
+
if (store.$isUnmeasuredItem(i)) {
|
|
530
|
+
done = false;
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (done) {
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
const [promise, unsubscribe] = waitForMeasurement();
|
|
538
|
+
try {
|
|
539
|
+
if (!await promise) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
} finally {
|
|
543
|
+
unsubscribe();
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
store.$update(7);
|
|
547
|
+
scroll(getTargetOffset(), smooth);
|
|
548
|
+
});
|
|
549
|
+
} else {
|
|
550
|
+
while (true) {
|
|
551
|
+
const [promise, unsubscribe] = waitForMeasurement();
|
|
552
|
+
try {
|
|
553
|
+
store.$update(7);
|
|
554
|
+
scroll(getTargetOffset());
|
|
555
|
+
if (!await promise) {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
} finally {
|
|
559
|
+
unsubscribe();
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}, () => {
|
|
564
|
+
cancelScroll && cancelScroll();
|
|
565
|
+
}];
|
|
804
566
|
};
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
scrollOffset + store.$getViewportSize()) {
|
|
880
|
-
align = "end";
|
|
881
|
-
}
|
|
882
|
-
else {
|
|
883
|
-
// already completely visible
|
|
884
|
-
return;
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
scheduleScroll(() => {
|
|
888
|
-
return (offset +
|
|
889
|
-
store.$getStartSpacerSize() +
|
|
890
|
-
store.$getItemOffset(index) +
|
|
891
|
-
(align === "end"
|
|
892
|
-
? store.$getItemSize(index) - store.$getViewportSize()
|
|
893
|
-
: align === "center"
|
|
894
|
-
? (store.$getItemSize(index) - store.$getViewportSize()) / 2
|
|
895
|
-
: 0));
|
|
896
|
-
}, smooth);
|
|
897
|
-
},
|
|
898
|
-
$fixScrollJump: () => {
|
|
899
|
-
scrollObserver && scrollObserver._fixScrollJump();
|
|
900
|
-
},
|
|
901
|
-
};
|
|
567
|
+
var createScroller = (store, isHorizontal) => {
|
|
568
|
+
let viewportElement;
|
|
569
|
+
let scrollObserver;
|
|
570
|
+
let initialized = createPromise();
|
|
571
|
+
let isNegative = false;
|
|
572
|
+
const scrollOffsetKey = isHorizontal ? "scrollLeft" : "scrollTop";
|
|
573
|
+
const overflowKey = isHorizontal ? "overflowX" : "overflowY";
|
|
574
|
+
const [scheduleScroll, cancelScroll] = createScrollScheduler(store, () => initialized[0], (offset, smooth) => {
|
|
575
|
+
offset = normalizeScrollOffset(offset, isNegative);
|
|
576
|
+
if (smooth) {
|
|
577
|
+
viewportElement.scrollTo({
|
|
578
|
+
[isHorizontal ? "left" : "top"]: offset,
|
|
579
|
+
behavior: "smooth"
|
|
580
|
+
});
|
|
581
|
+
} else {
|
|
582
|
+
viewportElement[scrollOffsetKey] = offset;
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
return {
|
|
586
|
+
$observe(_, viewport) {
|
|
587
|
+
viewportElement = viewport;
|
|
588
|
+
if (isHorizontal) {
|
|
589
|
+
isNegative = getComputedStyle(viewport).direction === "rtl";
|
|
590
|
+
}
|
|
591
|
+
scrollObserver = createScrollObserver(store, viewport, isHorizontal, () => normalizeScrollOffset(viewport[scrollOffsetKey], isNegative), (jump, shift, isMomentumScrolling) => {
|
|
592
|
+
if (isMomentumScrolling) {
|
|
593
|
+
const style = viewport.style;
|
|
594
|
+
const prev = style[overflowKey];
|
|
595
|
+
style[overflowKey] = "hidden";
|
|
596
|
+
timeout(() => {
|
|
597
|
+
style[overflowKey] = prev;
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
viewport[scrollOffsetKey] = normalizeScrollOffset(store.$getScrollOffset() + jump, isNegative);
|
|
601
|
+
if (shift) {
|
|
602
|
+
cancelScroll();
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
initialized[1](true);
|
|
606
|
+
},
|
|
607
|
+
$dispose() {
|
|
608
|
+
scrollObserver && scrollObserver._dispose();
|
|
609
|
+
initialized[1](false);
|
|
610
|
+
initialized = createPromise();
|
|
611
|
+
},
|
|
612
|
+
$isNegative: () => isNegative,
|
|
613
|
+
$scrollTo(offset) {
|
|
614
|
+
scheduleScroll(() => offset);
|
|
615
|
+
},
|
|
616
|
+
$scrollBy(offset) {
|
|
617
|
+
offset += store.$getScrollOffset();
|
|
618
|
+
scheduleScroll(() => offset);
|
|
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);
|
|
636
|
+
},
|
|
637
|
+
$fixScrollJump: () => {
|
|
638
|
+
scrollObserver && scrollObserver._fixScrollJump();
|
|
639
|
+
}
|
|
640
|
+
};
|
|
902
641
|
};
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
return;
|
|
982
|
-
index = clamp(index, 0, store.$getItemsLength() - 1);
|
|
983
|
-
if (align === "nearest") {
|
|
984
|
-
const itemOffset = store.$getItemOffset(index);
|
|
985
|
-
const scrollOffset = store.$getScrollOffset();
|
|
986
|
-
if (itemOffset < scrollOffset) {
|
|
987
|
-
align = "start";
|
|
988
|
-
}
|
|
989
|
-
else if (itemOffset + store.$getItemSize(index) >
|
|
990
|
-
scrollOffset + store.$getViewportSize()) {
|
|
991
|
-
align = "end";
|
|
992
|
-
}
|
|
993
|
-
else {
|
|
994
|
-
return;
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
const document = getCurrentDocument(containerElement);
|
|
998
|
-
const window = getCurrentWindow(document);
|
|
999
|
-
const html = getDocumentElement(document);
|
|
1000
|
-
const getScrollbarSize = () => store.$getViewportSize() -
|
|
1001
|
-
(isHorizontal ? html.clientWidth : html.clientHeight);
|
|
1002
|
-
scheduleScroll(() => {
|
|
1003
|
-
return (offset +
|
|
1004
|
-
// Calculate target scroll position including container's offset from document
|
|
1005
|
-
calcOffsetToViewport(containerElement, document.body, window, isHorizontal) +
|
|
1006
|
-
// store._getStartSpacerSize() +
|
|
1007
|
-
store.$getItemOffset(index) +
|
|
1008
|
-
(align === "end"
|
|
1009
|
-
? store.$getItemSize(index) -
|
|
1010
|
-
(store.$getViewportSize() - getScrollbarSize())
|
|
1011
|
-
: align === "center"
|
|
1012
|
-
? (store.$getItemSize(index) -
|
|
1013
|
-
(store.$getViewportSize() - getScrollbarSize())) /
|
|
1014
|
-
2
|
|
1015
|
-
: 0));
|
|
1016
|
-
}, smooth);
|
|
1017
|
-
},
|
|
1018
|
-
};
|
|
642
|
+
var createWindowScroller = (store, isHorizontal) => {
|
|
643
|
+
let containerElement;
|
|
644
|
+
let scrollObserver;
|
|
645
|
+
let initialized = createPromise();
|
|
646
|
+
let isNegative = false;
|
|
647
|
+
const scrollToKey = isHorizontal ? "left" : "top";
|
|
648
|
+
const [scheduleScroll] = createScrollScheduler(store, () => initialized[0], (offset, smooth) => {
|
|
649
|
+
offset = normalizeScrollOffset(offset, isNegative);
|
|
650
|
+
const window = getCurrentWindow(getCurrentDocument(containerElement));
|
|
651
|
+
if (smooth) {
|
|
652
|
+
window.scroll({
|
|
653
|
+
[scrollToKey]: offset,
|
|
654
|
+
behavior: "smooth"
|
|
655
|
+
});
|
|
656
|
+
} else {
|
|
657
|
+
window.scroll({ [scrollToKey]: offset });
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
const calcOffsetToViewport = (node, viewport, window, isHorizontal, offset = 0) => {
|
|
661
|
+
const offsetKey = isHorizontal ? "offsetLeft" : "offsetTop";
|
|
662
|
+
const offsetSum = offset + (isHorizontal && isNegative ? window.innerWidth - node[offsetKey] - node.offsetWidth : node[offsetKey]);
|
|
663
|
+
const parent = node.offsetParent;
|
|
664
|
+
if (node === viewport || !parent) {
|
|
665
|
+
return offsetSum;
|
|
666
|
+
}
|
|
667
|
+
return calcOffsetToViewport(parent, viewport, window, isHorizontal, offsetSum);
|
|
668
|
+
};
|
|
669
|
+
return {
|
|
670
|
+
$observe(container) {
|
|
671
|
+
containerElement = container;
|
|
672
|
+
const scrollOffsetKey = isHorizontal ? "scrollX" : "scrollY";
|
|
673
|
+
const document = getCurrentDocument(container);
|
|
674
|
+
const window = getCurrentWindow(document);
|
|
675
|
+
if (isHorizontal) {
|
|
676
|
+
isNegative = getComputedStyle(getDocumentElement(document)).direction === "rtl";
|
|
677
|
+
}
|
|
678
|
+
scrollObserver = createScrollObserver(store, window, isHorizontal, () => normalizeScrollOffset(window[scrollOffsetKey], isNegative), (jump, shift) => {
|
|
679
|
+
if (shift) {
|
|
680
|
+
window.scroll({ [scrollToKey]: normalizeScrollOffset(store.$getScrollOffset() + jump, isNegative) });
|
|
681
|
+
} else {
|
|
682
|
+
window.scrollBy({ [scrollToKey]: normalizeScrollOffset(jump, isNegative) });
|
|
683
|
+
}
|
|
684
|
+
}, () => calcOffsetToViewport(container, document.body, window, isHorizontal));
|
|
685
|
+
initialized[1](true);
|
|
686
|
+
},
|
|
687
|
+
$dispose() {
|
|
688
|
+
scrollObserver && scrollObserver._dispose();
|
|
689
|
+
containerElement = undefined;
|
|
690
|
+
initialized[1](false);
|
|
691
|
+
initialized = createPromise();
|
|
692
|
+
},
|
|
693
|
+
$isNegative: () => isNegative,
|
|
694
|
+
$fixScrollJump: () => {
|
|
695
|
+
scrollObserver && scrollObserver._fixScrollJump();
|
|
696
|
+
},
|
|
697
|
+
$scrollToIndex(index, { align, smooth, offset = 0 } = {}) {
|
|
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
|
+
}
|
|
711
|
+
const document = getCurrentDocument(containerElement);
|
|
712
|
+
const window = getCurrentWindow(document);
|
|
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
|
+
};
|
|
1019
720
|
};
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
colScroller.$fixScrollJump();
|
|
1063
|
-
},
|
|
1064
|
-
};
|
|
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
|
+
};
|
|
1065
763
|
};
|
|
1066
764
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
},
|
|
1083
|
-
};
|
|
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);
|
|
772
|
+
},
|
|
773
|
+
_unobserve(e) {
|
|
774
|
+
ro.unobserve(e);
|
|
775
|
+
},
|
|
776
|
+
_dispose() {
|
|
777
|
+
ro && ro.disconnect();
|
|
778
|
+
}
|
|
779
|
+
};
|
|
1084
780
|
};
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
const
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
mountedIndexes.delete(el);
|
|
1121
|
-
resizeObserver._unobserve(el);
|
|
1122
|
-
};
|
|
1123
|
-
},
|
|
1124
|
-
$dispose: resizeObserver._dispose,
|
|
1125
|
-
};
|
|
781
|
+
var createResizer = (store, isHorizontal) => {
|
|
782
|
+
let viewportElement;
|
|
783
|
+
const sizeKey = isHorizontal ? "width" : "height";
|
|
784
|
+
const mountedIndexes = new WeakMap();
|
|
785
|
+
const resizeObserver = createResizeObserver((entries) => {
|
|
786
|
+
const resizes = [];
|
|
787
|
+
for (const { target, contentRect } of entries) {
|
|
788
|
+
if (!target.offsetParent) continue;
|
|
789
|
+
if (target === viewportElement) {
|
|
790
|
+
store.$update(4, contentRect[sizeKey]);
|
|
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);
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
return {
|
|
803
|
+
$observeRoot(viewport) {
|
|
804
|
+
resizeObserver._observe(viewportElement = viewport);
|
|
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
|
+
};
|
|
1126
816
|
};
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
const
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
},
|
|
1171
|
-
$dispose() {
|
|
1172
|
-
cleanupOnWindowResize && cleanupOnWindowResize();
|
|
1173
|
-
resizeObserver._dispose();
|
|
1174
|
-
},
|
|
1175
|
-
};
|
|
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);
|
|
832
|
+
}
|
|
833
|
+
});
|
|
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
|
+
};
|
|
1176
860
|
};
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
const
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
sizeCache.delete(getKey(r, c));
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
rowStore.$update(ACTION_ITEM_RESIZE, rows);
|
|
1291
|
-
},
|
|
1292
|
-
$dispose: resizeObserver._dispose,
|
|
1293
|
-
};
|
|
861
|
+
var createGridResizer = (rowStore, colStore) => {
|
|
862
|
+
let viewportElement;
|
|
863
|
+
const mountedIndexes = new WeakMap();
|
|
864
|
+
const maybeCachedRowIndexes = new Set();
|
|
865
|
+
const maybeCachedColIndexes = new Set();
|
|
866
|
+
const sizeCache = new Map();
|
|
867
|
+
const getKey = (rowIndex, colIndex) => `${rowIndex}-${colIndex}`;
|
|
868
|
+
const resizeObserver = createResizeObserver((entries) => {
|
|
869
|
+
const resizedRows = new Set();
|
|
870
|
+
const resizedCols = new Set();
|
|
871
|
+
for (const { target, contentRect: { width, height } } of entries) {
|
|
872
|
+
if (!target.offsetParent) continue;
|
|
873
|
+
if (target === viewportElement) {
|
|
874
|
+
rowStore.$update(4, height);
|
|
875
|
+
colStore.$update(4, width);
|
|
876
|
+
} else {
|
|
877
|
+
const cell = mountedIndexes.get(target);
|
|
878
|
+
if (cell) {
|
|
879
|
+
const [rowIndex, colIndex] = cell;
|
|
880
|
+
const key = getKey(rowIndex, colIndex);
|
|
881
|
+
const prevSize = sizeCache.get(key);
|
|
882
|
+
let rowResized;
|
|
883
|
+
let colResized;
|
|
884
|
+
if (!prevSize) {
|
|
885
|
+
rowResized = colResized = true;
|
|
886
|
+
} else {
|
|
887
|
+
if (prevSize[0] !== height) {
|
|
888
|
+
rowResized = true;
|
|
889
|
+
}
|
|
890
|
+
if (prevSize[1] !== width) {
|
|
891
|
+
colResized = true;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
if (rowResized) {
|
|
895
|
+
resizedRows.add(rowIndex);
|
|
896
|
+
}
|
|
897
|
+
if (colResized) {
|
|
898
|
+
resizedCols.add(colIndex);
|
|
899
|
+
}
|
|
900
|
+
if (rowResized || colResized) {
|
|
901
|
+
sizeCache.set(key, [height, width]);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (resizedRows.size) {
|
|
907
|
+
const heightResizes = [];
|
|
908
|
+
resizedRows.forEach((rowIndex) => {
|
|
909
|
+
let maxHeight = 0;
|
|
910
|
+
maybeCachedColIndexes.forEach((colIndex) => {
|
|
911
|
+
const size = sizeCache.get(getKey(rowIndex, colIndex));
|
|
912
|
+
if (size) {
|
|
913
|
+
maxHeight = max(maxHeight, size[0]);
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
if (maxHeight) {
|
|
917
|
+
heightResizes.push([rowIndex, maxHeight]);
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
rowStore.$update(3, heightResizes);
|
|
921
|
+
}
|
|
922
|
+
if (resizedCols.size) {
|
|
923
|
+
const widthResizes = [];
|
|
924
|
+
resizedCols.forEach((colIndex) => {
|
|
925
|
+
let maxWidth = 0;
|
|
926
|
+
maybeCachedRowIndexes.forEach((rowIndex) => {
|
|
927
|
+
const size = sizeCache.get(getKey(rowIndex, colIndex));
|
|
928
|
+
if (size) {
|
|
929
|
+
maxWidth = max(maxWidth, size[1]);
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
if (maxWidth) {
|
|
933
|
+
widthResizes.push([colIndex, maxWidth]);
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
colStore.$update(3, widthResizes);
|
|
937
|
+
}
|
|
938
|
+
});
|
|
939
|
+
return {
|
|
940
|
+
$observeRoot(viewport) {
|
|
941
|
+
resizeObserver._observe(viewportElement = viewport);
|
|
942
|
+
},
|
|
943
|
+
$observeItem(el, rowIndex, colIndex) {
|
|
944
|
+
mountedIndexes.set(el, [rowIndex, colIndex]);
|
|
945
|
+
maybeCachedRowIndexes.add(rowIndex);
|
|
946
|
+
maybeCachedColIndexes.add(colIndex);
|
|
947
|
+
resizeObserver._observe(el);
|
|
948
|
+
return () => {
|
|
949
|
+
mountedIndexes.delete(el);
|
|
950
|
+
resizeObserver._unobserve(el);
|
|
951
|
+
};
|
|
952
|
+
},
|
|
953
|
+
$resizeCols(cols) {
|
|
954
|
+
for (const [c] of cols) {
|
|
955
|
+
for (let r = 0; r < rowStore.$getItemsLength(); r++) {
|
|
956
|
+
sizeCache.delete(getKey(r, c));
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
colStore.$update(3, cols);
|
|
960
|
+
},
|
|
961
|
+
$resizeRows(rows) {
|
|
962
|
+
for (const [r] of rows) {
|
|
963
|
+
for (let c = 0; c < colStore.$getItemsLength(); c++) {
|
|
964
|
+
sizeCache.delete(getKey(r, c));
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
rowStore.$update(3, rows);
|
|
968
|
+
},
|
|
969
|
+
$dispose: resizeObserver._dispose
|
|
970
|
+
};
|
|
1294
971
|
};
|
|
1295
972
|
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
return style;
|
|
1322
|
-
});
|
|
1323
|
-
return (<Dynamic component={props._as} index={props._index} ref={elementRef} style={style()}>
|
|
973
|
+
//#endregion
|
|
974
|
+
//#region src/solid/ListItem.tsx
|
|
975
|
+
var ListItem = (props) => {
|
|
976
|
+
let elementRef;
|
|
977
|
+
props = mergeProps({ _as: "div" }, props);
|
|
978
|
+
createEffect(() => {
|
|
979
|
+
if (!elementRef) return;
|
|
980
|
+
onCleanup(props._resizer(elementRef, props._index));
|
|
981
|
+
});
|
|
982
|
+
const style = createMemo(() => {
|
|
983
|
+
const isHorizontal = props._isHorizontal;
|
|
984
|
+
const style = {
|
|
985
|
+
contain: "layout style",
|
|
986
|
+
position: "absolute",
|
|
987
|
+
[isHorizontal ? "height" : "width"]: "100%",
|
|
988
|
+
[isHorizontal ? "top" : "left"]: "0px",
|
|
989
|
+
[isHorizontal ? "left" : "top"]: props._offset + "px",
|
|
990
|
+
visibility: props._hide ? "hidden" : undefined
|
|
991
|
+
};
|
|
992
|
+
if (isHorizontal) {
|
|
993
|
+
style.display = "inline-flex";
|
|
994
|
+
}
|
|
995
|
+
return style;
|
|
996
|
+
});
|
|
997
|
+
return <Dynamic component={props._as} index={props._index} ref={elementRef} style={style()}>
|
|
1324
998
|
{props._children}
|
|
1325
|
-
</Dynamic
|
|
999
|
+
</Dynamic>;
|
|
1326
1000
|
};
|
|
1327
1001
|
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
return prev[0] === next[0] && prev[1] === next[1];
|
|
1002
|
+
//#endregion
|
|
1003
|
+
//#region src/solid/utils.ts
|
|
1004
|
+
var isSameRange = (prev, next) => {
|
|
1005
|
+
return prev[0] === next[0] && prev[1] === next[1];
|
|
1333
1006
|
};
|
|
1334
1007
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
const
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
"pointer-events": isScrolling() ? "none" : undefined,
|
|
1462
|
-
}}>
|
|
1008
|
+
//#endregion
|
|
1009
|
+
//#region src/solid/Virtualizer.tsx
|
|
1010
|
+
var Virtualizer = (props) => {
|
|
1011
|
+
let containerRef;
|
|
1012
|
+
const { itemSize, horizontal = false, cache } = props;
|
|
1013
|
+
props = mergeProps({ as: "div" }, props);
|
|
1014
|
+
const store = createVirtualStore(props.data.length, itemSize, undefined, cache, !itemSize);
|
|
1015
|
+
const resizer = createResizer(store, horizontal);
|
|
1016
|
+
const scroller = createScroller(store, horizontal);
|
|
1017
|
+
const [stateVersion, setRerender] = createSignal(store.$getStateVersion());
|
|
1018
|
+
store.$subscribe(1, () => {
|
|
1019
|
+
setRerender(store.$getStateVersion());
|
|
1020
|
+
});
|
|
1021
|
+
store.$subscribe(4, () => {
|
|
1022
|
+
props.onScroll?.(store.$getScrollOffset());
|
|
1023
|
+
});
|
|
1024
|
+
store.$subscribe(8, () => {
|
|
1025
|
+
props.onScrollEnd?.();
|
|
1026
|
+
});
|
|
1027
|
+
const range = createMemo((prev) => {
|
|
1028
|
+
stateVersion();
|
|
1029
|
+
const next = store.$getRange(props.bufferSize);
|
|
1030
|
+
if (prev && isSameRange(prev, next)) {
|
|
1031
|
+
return prev;
|
|
1032
|
+
}
|
|
1033
|
+
return next;
|
|
1034
|
+
});
|
|
1035
|
+
const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
|
|
1036
|
+
const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
|
|
1037
|
+
const isNegative = createMemo(() => stateVersion() && scroller.$isNegative());
|
|
1038
|
+
onMount(() => {
|
|
1039
|
+
if (props.ref) {
|
|
1040
|
+
props.ref({
|
|
1041
|
+
get cache() {
|
|
1042
|
+
return store.$getCacheSnapshot();
|
|
1043
|
+
},
|
|
1044
|
+
get scrollOffset() {
|
|
1045
|
+
return store.$getScrollOffset();
|
|
1046
|
+
},
|
|
1047
|
+
get scrollSize() {
|
|
1048
|
+
return getScrollSize(store);
|
|
1049
|
+
},
|
|
1050
|
+
get viewportSize() {
|
|
1051
|
+
return store.$getViewportSize();
|
|
1052
|
+
},
|
|
1053
|
+
findItemIndex: store.$findItemIndex,
|
|
1054
|
+
getItemOffset: store.$getItemOffset,
|
|
1055
|
+
getItemSize: store.$getItemSize,
|
|
1056
|
+
scrollToIndex: scroller.$scrollToIndex,
|
|
1057
|
+
scrollTo: scroller.$scrollTo,
|
|
1058
|
+
scrollBy: scroller.$scrollBy
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
const container = containerRef;
|
|
1062
|
+
const scrollable = props.scrollRef || container.parentElement;
|
|
1063
|
+
resizer.$observeRoot(scrollable);
|
|
1064
|
+
scroller.$observe(container, scrollable);
|
|
1065
|
+
onCleanup(() => {
|
|
1066
|
+
if (props.ref) {
|
|
1067
|
+
props.ref();
|
|
1068
|
+
}
|
|
1069
|
+
store.$dispose();
|
|
1070
|
+
resizer.$dispose();
|
|
1071
|
+
scroller.$dispose();
|
|
1072
|
+
});
|
|
1073
|
+
});
|
|
1074
|
+
createComputed(on(() => props.startMargin || 0, (value) => {
|
|
1075
|
+
if (value !== store.$getStartSpacerSize()) {
|
|
1076
|
+
store.$update(6, value);
|
|
1077
|
+
}
|
|
1078
|
+
}));
|
|
1079
|
+
createEffect(on(stateVersion, () => {
|
|
1080
|
+
scroller.$fixScrollJump();
|
|
1081
|
+
}));
|
|
1082
|
+
const dataSlice = createMemo(() => {
|
|
1083
|
+
const count = props.data.length;
|
|
1084
|
+
untrack(() => {
|
|
1085
|
+
if (count !== store.$getItemsLength()) {
|
|
1086
|
+
store.$update(5, [count, props.shift]);
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
const items = [];
|
|
1090
|
+
const indexes = [];
|
|
1091
|
+
if (props.keepMounted) {
|
|
1092
|
+
const mounted = new Set(props.keepMounted);
|
|
1093
|
+
for (let [i, j] = range(); i <= j; i++) {
|
|
1094
|
+
mounted.add(i);
|
|
1095
|
+
}
|
|
1096
|
+
sort([...mounted]).forEach((index) => {
|
|
1097
|
+
items.push(props.data[index]);
|
|
1098
|
+
indexes.push(index);
|
|
1099
|
+
});
|
|
1100
|
+
} else {
|
|
1101
|
+
for (let [i, j] = range(); i <= j; i++) {
|
|
1102
|
+
items.push(props.data[i]);
|
|
1103
|
+
indexes.push(i);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return {
|
|
1107
|
+
_items: items,
|
|
1108
|
+
_indexes: indexes
|
|
1109
|
+
};
|
|
1110
|
+
});
|
|
1111
|
+
const renderItem = (data, index) => {
|
|
1112
|
+
const offset = createMemo(() => {
|
|
1113
|
+
stateVersion();
|
|
1114
|
+
return store.$getItemOffset(index(), isNegative());
|
|
1115
|
+
});
|
|
1116
|
+
const hide = createMemo(() => {
|
|
1117
|
+
stateVersion();
|
|
1118
|
+
return store.$isUnmeasuredItem(index());
|
|
1119
|
+
});
|
|
1120
|
+
const children = createMemo(() => {
|
|
1121
|
+
return untrack(() => props.children(data, index));
|
|
1122
|
+
});
|
|
1123
|
+
return <ListItem _as={props.item} _index={index()} _resizer={resizer.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} />;
|
|
1124
|
+
};
|
|
1125
|
+
return <Dynamic component={props.as} ref={containerRef} style={{
|
|
1126
|
+
contain: "size style",
|
|
1127
|
+
"overflow-anchor": "none",
|
|
1128
|
+
flex: "none",
|
|
1129
|
+
position: "relative",
|
|
1130
|
+
width: horizontal ? totalSize() + "px" : "100%",
|
|
1131
|
+
height: horizontal ? "100%" : totalSize() + "px",
|
|
1132
|
+
"pointer-events": isScrolling() ? "none" : undefined
|
|
1133
|
+
}}>
|
|
1463
1134
|
<For each={dataSlice()._items}>
|
|
1464
1135
|
{(data, index) => {
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
}}
|
|
1136
|
+
const itemIndex = createMemo(() => dataSlice()._indexes[index()]);
|
|
1137
|
+
return renderItem(data, itemIndex);
|
|
1138
|
+
}}
|
|
1469
1139
|
</For>
|
|
1470
|
-
</Dynamic
|
|
1140
|
+
</Dynamic>;
|
|
1471
1141
|
};
|
|
1472
1142
|
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
width: "100%",
|
|
1500
|
-
height: "100%",
|
|
1501
|
-
...local.style,
|
|
1502
|
-
}}>
|
|
1143
|
+
//#endregion
|
|
1144
|
+
//#region src/solid/VList.tsx
|
|
1145
|
+
var VList = (props) => {
|
|
1146
|
+
const [local, others] = splitProps(props, [
|
|
1147
|
+
"ref",
|
|
1148
|
+
"data",
|
|
1149
|
+
"children",
|
|
1150
|
+
"bufferSize",
|
|
1151
|
+
"itemSize",
|
|
1152
|
+
"shift",
|
|
1153
|
+
"horizontal",
|
|
1154
|
+
"keepMounted",
|
|
1155
|
+
"cache",
|
|
1156
|
+
"item",
|
|
1157
|
+
"onScroll",
|
|
1158
|
+
"onScrollEnd",
|
|
1159
|
+
"style"
|
|
1160
|
+
]);
|
|
1161
|
+
return <div {...others} style={{
|
|
1162
|
+
display: local.horizontal ? "inline-block" : "block",
|
|
1163
|
+
[local.horizontal ? "overflow-x" : "overflow-y"]: "auto",
|
|
1164
|
+
contain: "strict",
|
|
1165
|
+
width: "100%",
|
|
1166
|
+
height: "100%",
|
|
1167
|
+
...local.style
|
|
1168
|
+
}}>
|
|
1503
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}>
|
|
1504
1170
|
{local.children}
|
|
1505
1171
|
</Virtualizer>
|
|
1506
|
-
</div
|
|
1172
|
+
</div>;
|
|
1507
1173
|
};
|
|
1508
1174
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
const
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
position: "relative",
|
|
1593
|
-
width: horizontal ? totalSize() + "px" : "100%",
|
|
1594
|
-
height: horizontal ? "100%" : totalSize() + "px",
|
|
1595
|
-
"pointer-events": isScrolling() ? "none" : undefined,
|
|
1596
|
-
}}>
|
|
1175
|
+
//#endregion
|
|
1176
|
+
//#region src/solid/WindowVirtualizer.tsx
|
|
1177
|
+
var WindowVirtualizer = (props) => {
|
|
1178
|
+
let containerRef;
|
|
1179
|
+
const { ref: _ref, data: _data, children: _children, itemSize, shift: _shift, horizontal = false, cache, onScrollEnd: _onScrollEnd } = props;
|
|
1180
|
+
const store = createVirtualStore(props.data.length, itemSize, undefined, cache, !itemSize);
|
|
1181
|
+
const resizer = createWindowResizer(store, horizontal);
|
|
1182
|
+
const scroller = createWindowScroller(store, horizontal);
|
|
1183
|
+
const [stateVersion, setRerender] = createSignal(store.$getStateVersion());
|
|
1184
|
+
store.$subscribe(1, () => {
|
|
1185
|
+
setRerender(store.$getStateVersion());
|
|
1186
|
+
});
|
|
1187
|
+
store.$subscribe(4, () => {
|
|
1188
|
+
props.onScroll?.();
|
|
1189
|
+
});
|
|
1190
|
+
store.$subscribe(8, () => {
|
|
1191
|
+
props.onScrollEnd?.();
|
|
1192
|
+
});
|
|
1193
|
+
const range = createMemo((prev) => {
|
|
1194
|
+
stateVersion();
|
|
1195
|
+
const next = store.$getRange(props.bufferSize);
|
|
1196
|
+
if (prev && isSameRange(prev, next)) {
|
|
1197
|
+
return prev;
|
|
1198
|
+
}
|
|
1199
|
+
return next;
|
|
1200
|
+
});
|
|
1201
|
+
const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());
|
|
1202
|
+
const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());
|
|
1203
|
+
const isNegative = createMemo(() => stateVersion() && scroller.$isNegative());
|
|
1204
|
+
onMount(() => {
|
|
1205
|
+
if (props.ref) {
|
|
1206
|
+
props.ref({
|
|
1207
|
+
get cache() {
|
|
1208
|
+
return store.$getCacheSnapshot();
|
|
1209
|
+
},
|
|
1210
|
+
get scrollOffset() {
|
|
1211
|
+
return store.$getScrollOffset();
|
|
1212
|
+
},
|
|
1213
|
+
get viewportSize() {
|
|
1214
|
+
return store.$getViewportSize();
|
|
1215
|
+
},
|
|
1216
|
+
findItemIndex: store.$findItemIndex,
|
|
1217
|
+
getItemOffset: store.$getItemOffset,
|
|
1218
|
+
getItemSize: store.$getItemSize,
|
|
1219
|
+
scrollToIndex: scroller.$scrollToIndex
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1222
|
+
resizer.$observeRoot(containerRef);
|
|
1223
|
+
scroller.$observe(containerRef);
|
|
1224
|
+
onCleanup(() => {
|
|
1225
|
+
if (props.ref) {
|
|
1226
|
+
props.ref();
|
|
1227
|
+
}
|
|
1228
|
+
store.$dispose();
|
|
1229
|
+
resizer.$dispose();
|
|
1230
|
+
scroller.$dispose();
|
|
1231
|
+
});
|
|
1232
|
+
});
|
|
1233
|
+
createEffect(on(stateVersion, () => {
|
|
1234
|
+
scroller.$fixScrollJump();
|
|
1235
|
+
}));
|
|
1236
|
+
const dataSlice = createMemo(() => {
|
|
1237
|
+
const count = props.data.length;
|
|
1238
|
+
untrack(() => {
|
|
1239
|
+
if (count !== store.$getItemsLength()) {
|
|
1240
|
+
store.$update(5, [count, props.shift]);
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
const items = [];
|
|
1244
|
+
for (let [i, j] = range(); i <= j; i++) {
|
|
1245
|
+
items.push(props.data[i]);
|
|
1246
|
+
}
|
|
1247
|
+
return items;
|
|
1248
|
+
});
|
|
1249
|
+
return <div ref={containerRef} style={{
|
|
1250
|
+
contain: "size style",
|
|
1251
|
+
"overflow-anchor": "none",
|
|
1252
|
+
flex: "none",
|
|
1253
|
+
position: "relative",
|
|
1254
|
+
width: horizontal ? totalSize() + "px" : "100%",
|
|
1255
|
+
height: horizontal ? "100%" : totalSize() + "px",
|
|
1256
|
+
"pointer-events": isScrolling() ? "none" : undefined
|
|
1257
|
+
}}>
|
|
1597
1258
|
<For each={dataSlice()}>
|
|
1598
1259
|
{(data, index) => {
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1260
|
+
const itemIndex = createMemo(() => range()[0] + index());
|
|
1261
|
+
const offset = createMemo(() => {
|
|
1262
|
+
stateVersion();
|
|
1263
|
+
return store.$getItemOffset(itemIndex(), isNegative());
|
|
1264
|
+
});
|
|
1265
|
+
const hide = createMemo(() => {
|
|
1266
|
+
stateVersion();
|
|
1267
|
+
return store.$isUnmeasuredItem(itemIndex());
|
|
1268
|
+
});
|
|
1269
|
+
const children = createMemo(() => {
|
|
1270
|
+
return untrack(() => props.children(data, itemIndex));
|
|
1271
|
+
});
|
|
1272
|
+
return <ListItem _index={itemIndex()} _resizer={resizer.$observeItem} _offset={offset()} _hide={hide()} _children={children()} _isHorizontal={horizontal} />;
|
|
1273
|
+
}}
|
|
1613
1274
|
</For>
|
|
1614
|
-
</div
|
|
1275
|
+
</div>;
|
|
1615
1276
|
};
|
|
1616
1277
|
|
|
1617
|
-
|
|
1618
|
-
* @module solid
|
|
1619
|
-
*/
|
|
1620
|
-
|
|
1278
|
+
//#endregion
|
|
1621
1279
|
export { VList, Virtualizer, WindowVirtualizer };
|
|
1622
|
-
//# sourceMappingURL=index.jsx.map
|
|
1280
|
+
//# sourceMappingURL=index.jsx.map
|