@tanstack/solid-virtual 3.0.0-beta.30 → 3.0.0-beta.33

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.
@@ -14,6 +14,31 @@
14
14
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SolidVirtual = {}, global.Solid, global.SolidStore));
15
15
  })(this, (function (exports, solidJs, store) { 'use strict';
16
16
 
17
+ /**
18
+ * virtual-core
19
+ *
20
+ * Copyright (c) TanStack
21
+ *
22
+ * This source code is licensed under the MIT license found in the
23
+ * LICENSE.md file in the root directory of this source tree.
24
+ *
25
+ * @license MIT
26
+ */
27
+ function _extends() {
28
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
29
+ for (var i = 1; i < arguments.length; i++) {
30
+ var source = arguments[i];
31
+ for (var key in source) {
32
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
33
+ target[key] = source[key];
34
+ }
35
+ }
36
+ }
37
+ return target;
38
+ };
39
+ return _extends.apply(this, arguments);
40
+ }
41
+
17
42
  /**
18
43
  * virtual-core
19
44
  *
@@ -25,36 +50,35 @@
25
50
  * @license MIT
26
51
  */
27
52
  function memo(getDeps, fn, opts) {
28
- let deps = [];
29
- let result;
30
- return () => {
31
- let depTime;
53
+ var deps = [];
54
+ var result;
55
+ return function () {
56
+ var depTime;
32
57
  if (opts.key && opts.debug != null && opts.debug()) depTime = Date.now();
33
- const newDeps = getDeps();
34
- const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);
58
+ var newDeps = getDeps();
59
+ var depsChanged = newDeps.length !== deps.length || newDeps.some(function (dep, index) {
60
+ return deps[index] !== dep;
61
+ });
35
62
  if (!depsChanged) {
36
63
  return result;
37
64
  }
38
65
  deps = newDeps;
39
- let resultTime;
66
+ var resultTime;
40
67
  if (opts.key && opts.debug != null && opts.debug()) resultTime = Date.now();
41
- result = fn(...newDeps);
68
+ result = fn.apply(void 0, newDeps);
42
69
  opts == null ? void 0 : opts.onChange == null ? void 0 : opts.onChange(result);
43
70
  if (opts.key && opts.debug != null && opts.debug()) {
44
- const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
45
- const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
46
- const resultFpsPercentage = resultEndTime / 16;
47
- const pad = (str, num) => {
71
+ var depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
72
+ var resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
73
+ var resultFpsPercentage = resultEndTime / 16;
74
+ var pad = function pad(str, num) {
48
75
  str = String(str);
49
76
  while (str.length < num) {
50
77
  str = ' ' + str;
51
78
  }
52
79
  return str;
53
80
  };
54
- console.info(`%c ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`, `
55
- font-size: .6rem;
56
- font-weight: bold;
57
- color: hsl(${Math.max(0, Math.min(120 - 120 * resultFpsPercentage, 120))}deg 100% 31%);`, opts == null ? void 0 : opts.key);
81
+ console.info("%c\u23F1 " + pad(resultEndTime, 5) + " /" + pad(depEndTime, 5) + " ms", "\n font-size: .6rem;\n font-weight: bold;\n color: hsl(" + Math.max(0, Math.min(120 - 120 * resultFpsPercentage, 120)) + "deg 100% 31%);", opts == null ? void 0 : opts.key);
58
82
  }
59
83
  return result;
60
84
  };
@@ -75,30 +99,32 @@
75
99
 
76
100
  //
77
101
 
78
- const defaultKeyExtractor = index => index;
79
- const defaultRangeExtractor = range => {
80
- const start = Math.max(range.startIndex - range.overscan, 0);
81
- const end = Math.min(range.endIndex + range.overscan, range.count - 1);
82
- const arr = [];
83
- for (let i = start; i <= end; i++) {
84
- arr.push(i);
102
+ var defaultKeyExtractor = function defaultKeyExtractor(index) {
103
+ return index;
104
+ };
105
+ var defaultRangeExtractor = function defaultRangeExtractor(range) {
106
+ var start = Math.max(range.startIndex - range.overscan, 0);
107
+ var end = Math.min(range.endIndex + range.overscan, range.count - 1);
108
+ var arr = [];
109
+ for (var _i = start; _i <= end; _i++) {
110
+ arr.push(_i);
85
111
  }
86
112
  return arr;
87
113
  };
88
- const memoRectCallback = (instance, cb) => {
89
- let prev = {
114
+ var memoRectCallback = function memoRectCallback(instance, cb) {
115
+ var prev = {
90
116
  height: -1,
91
117
  width: -1
92
118
  };
93
- return rect => {
119
+ return function (rect) {
94
120
  if (instance.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) {
95
121
  cb(rect);
96
122
  }
97
123
  prev = rect;
98
124
  };
99
125
  };
100
- const observeElementRect = (instance, cb) => {
101
- const observer = new ResizeObserver(entries => {
126
+ var observeElementRect = function observeElementRect(instance, cb) {
127
+ var observer = new ResizeObserver(function (entries) {
102
128
  var _entries$, _entries$2;
103
129
  cb({
104
130
  width: (_entries$ = entries[0]) == null ? void 0 : _entries$.contentRect.width,
@@ -110,16 +136,18 @@
110
136
  }
111
137
  cb(instance.scrollElement.getBoundingClientRect());
112
138
  observer.observe(instance.scrollElement);
113
- return () => {
139
+ return function () {
114
140
  observer.unobserve(instance.scrollElement);
115
141
  };
116
142
  };
117
- const observeWindowRect = (instance, cb) => {
118
- const memoizedCallback = memoRectCallback(instance, cb);
119
- const onResize = () => memoizedCallback({
120
- width: instance.scrollElement.innerWidth,
121
- height: instance.scrollElement.innerHeight
122
- });
143
+ var observeWindowRect = function observeWindowRect(instance, cb) {
144
+ var memoizedCallback = memoRectCallback(instance, cb);
145
+ var onResize = function onResize() {
146
+ return memoizedCallback({
147
+ width: instance.scrollElement.innerWidth,
148
+ height: instance.scrollElement.innerHeight
149
+ });
150
+ };
123
151
  if (!instance.scrollElement) {
124
152
  return;
125
153
  }
@@ -128,32 +156,32 @@
128
156
  capture: false,
129
157
  passive: true
130
158
  });
131
- return () => {
159
+ return function () {
132
160
  instance.scrollElement.removeEventListener('resize', onResize);
133
161
  };
134
162
  };
135
- const scrollProps = {
163
+ var scrollProps = {
136
164
  element: ['scrollLeft', 'scrollTop'],
137
165
  window: ['scrollX', 'scrollY']
138
166
  };
139
- const createOffsetObserver = mode => {
140
- return (instance, cb) => {
167
+ var createOffsetObserver = function createOffsetObserver(mode) {
168
+ return function (instance, cb) {
141
169
  if (!instance.scrollElement) {
142
170
  return;
143
171
  }
144
- const propX = scrollProps[mode][0];
145
- const propY = scrollProps[mode][1];
146
- let prevX = instance.scrollElement[propX];
147
- let prevY = instance.scrollElement[propY];
148
- const scroll = () => {
149
- const offset = instance.scrollElement[instance.options.horizontal ? propX : propY];
150
- cb(Math.max(0, offset - instance.options.scrollMargin));
172
+ var propX = scrollProps[mode][0];
173
+ var propY = scrollProps[mode][1];
174
+ var prevX = instance.scrollElement[propX];
175
+ var prevY = instance.scrollElement[propY];
176
+ var scroll = function scroll() {
177
+ var offset = instance.scrollElement[instance.options.horizontal ? propX : propY];
178
+ cb(offset);
151
179
  };
152
180
  scroll();
153
- const onScroll = e => {
154
- const target = e.currentTarget;
155
- const scrollX = target[propX];
156
- const scrollY = target[propY];
181
+ var onScroll = function onScroll(e) {
182
+ var target = e.currentTarget;
183
+ var scrollX = target[propX];
184
+ var scrollY = target[propY];
157
185
  if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) {
158
186
  scroll();
159
187
  }
@@ -164,390 +192,407 @@
164
192
  capture: false,
165
193
  passive: true
166
194
  });
167
- return () => {
195
+ return function () {
168
196
  instance.scrollElement.removeEventListener('scroll', onScroll);
169
197
  };
170
198
  };
171
199
  };
172
- const observeElementOffset = createOffsetObserver('element');
173
- const observeWindowOffset = createOffsetObserver('window');
174
- const measureElement = (element, instance) => {
200
+ var observeElementOffset = createOffsetObserver('element');
201
+ var observeWindowOffset = createOffsetObserver('window');
202
+ var measureElement = function measureElement(element, instance) {
175
203
  return Math.round(element.getBoundingClientRect()[instance.options.horizontal ? 'width' : 'height']);
176
204
  };
177
- const windowScroll = (offset, _ref, instance) => {
178
- var _instance$scrollEleme;
179
- let {
180
- adjustments,
181
- behavior,
182
- sync
183
- } = _ref;
184
- const toOffset = (sync ? offset : offset + instance.options.scrollMargin) + (adjustments ?? 0);
185
- (_instance$scrollEleme = instance.scrollElement) == null ? void 0 : _instance$scrollEleme.scrollTo == null ? void 0 : _instance$scrollEleme.scrollTo({
186
- [instance.options.horizontal ? 'left' : 'top']: toOffset,
187
- behavior
188
- });
205
+ var windowScroll = function windowScroll(offset, _ref, instance) {
206
+ var _instance$scrollEleme, _instance$scrollEleme2;
207
+ var _ref$adjustments = _ref.adjustments,
208
+ adjustments = _ref$adjustments === void 0 ? 0 : _ref$adjustments,
209
+ behavior = _ref.behavior;
210
+ var toOffset = offset + adjustments;
211
+ (_instance$scrollEleme = instance.scrollElement) == null ? void 0 : _instance$scrollEleme.scrollTo == null ? void 0 : _instance$scrollEleme.scrollTo((_instance$scrollEleme2 = {}, _instance$scrollEleme2[instance.options.horizontal ? 'left' : 'top'] = toOffset, _instance$scrollEleme2.behavior = behavior, _instance$scrollEleme2));
189
212
  };
190
- const elementScroll = (offset, _ref2, instance) => {
191
- var _instance$scrollEleme2;
192
- let {
193
- adjustments,
194
- behavior,
195
- sync
196
- } = _ref2;
197
- const toOffset = (sync ? offset : offset + instance.options.scrollMargin) + (adjustments ?? 0);
198
- (_instance$scrollEleme2 = instance.scrollElement) == null ? void 0 : _instance$scrollEleme2.scrollTo == null ? void 0 : _instance$scrollEleme2.scrollTo({
199
- [instance.options.horizontal ? 'left' : 'top']: toOffset,
200
- behavior
201
- });
213
+ var elementScroll = function elementScroll(offset, _ref2, instance) {
214
+ var _instance$scrollEleme3, _instance$scrollEleme4;
215
+ var _ref2$adjustments = _ref2.adjustments,
216
+ adjustments = _ref2$adjustments === void 0 ? 0 : _ref2$adjustments,
217
+ behavior = _ref2.behavior;
218
+ var toOffset = offset + adjustments;
219
+ (_instance$scrollEleme3 = instance.scrollElement) == null ? void 0 : _instance$scrollEleme3.scrollTo == null ? void 0 : _instance$scrollEleme3.scrollTo((_instance$scrollEleme4 = {}, _instance$scrollEleme4[instance.options.horizontal ? 'left' : 'top'] = toOffset, _instance$scrollEleme4.behavior = behavior, _instance$scrollEleme4));
202
220
  };
203
- class Virtualizer {
204
- constructor(_opts) {
205
- var _this = this;
206
- this.unsubs = [];
207
- this.scrollElement = null;
208
- this.isScrolling = false;
209
- this.isScrollingTimeoutId = null;
210
- this.measurementsCache = [];
211
- this.itemMeasurementsCache = {};
212
- this.pendingMeasuredCacheIndexes = [];
213
- this.scrollAdjustments = 0;
214
- this.measureElementCache = {};
215
- this.pendingScrollToIndexCallback = null;
216
- this.getResizeObserver = (() => {
217
- let _ro = null;
218
- return () => {
219
- if (_ro) {
220
- return _ro;
221
- } else if (typeof ResizeObserver !== 'undefined') {
222
- return _ro = new ResizeObserver(entries => {
223
- entries.forEach(entry => {
224
- this._measureElement(entry.target, false);
225
- });
221
+ var Virtualizer = function Virtualizer(_opts) {
222
+ var _this = this;
223
+ this.unsubs = [];
224
+ this.scrollElement = null;
225
+ this.isScrolling = false;
226
+ this.isScrollingTimeoutId = null;
227
+ this.measurementsCache = [];
228
+ this.itemSizeCache = {};
229
+ this.pendingMeasuredCacheIndexes = [];
230
+ this.scrollDirection = null;
231
+ this.scrollAdjustments = 0;
232
+ this.measureElementCache = {};
233
+ this.pendingScrollToIndexCallback = null;
234
+ this.getResizeObserver = function () {
235
+ var _ro = null;
236
+ return function () {
237
+ if (_ro) {
238
+ return _ro;
239
+ } else if (typeof ResizeObserver !== 'undefined') {
240
+ return _ro = new ResizeObserver(function (entries) {
241
+ entries.forEach(function (entry) {
242
+ _this._measureElement(entry.target, false);
226
243
  });
227
- } else {
228
- return null;
229
- }
230
- };
231
- })();
232
- this.range = {
233
- startIndex: 0,
234
- endIndex: 0
235
- };
236
- this.setOptions = opts => {
237
- Object.entries(opts).forEach(_ref3 => {
238
- let [key, value] = _ref3;
239
- if (typeof value === 'undefined') delete opts[key];
240
- });
241
- this.options = {
242
- debug: false,
243
- initialOffset: 0,
244
- overscan: 1,
245
- paddingStart: 0,
246
- paddingEnd: 0,
247
- scrollPaddingStart: 0,
248
- scrollPaddingEnd: 0,
249
- horizontal: false,
250
- getItemKey: defaultKeyExtractor,
251
- rangeExtractor: defaultRangeExtractor,
252
- onChange: () => {},
253
- measureElement,
254
- initialRect: {
255
- width: 0,
256
- height: 0
257
- },
258
- scrollMargin: 0,
259
- scrollingDelay: 150,
260
- indexAttribute: 'data-index',
261
- ...opts
262
- };
263
- };
264
- this.notify = () => {
265
- var _this$options$onChang, _this$options;
266
- (_this$options$onChang = (_this$options = this.options).onChange) == null ? void 0 : _this$options$onChang.call(_this$options, this);
267
- };
268
- this.cleanup = () => {
269
- this.unsubs.filter(Boolean).forEach(d => d());
270
- this.unsubs = [];
271
- this.scrollElement = null;
272
- };
273
- this._didMount = () => {
274
- const ro = this.getResizeObserver();
275
- Object.values(this.measureElementCache).forEach(node => ro == null ? void 0 : ro.observe(node));
276
- return () => {
277
- ro == null ? void 0 : ro.disconnect();
278
- this.cleanup();
279
- };
280
- };
281
- this._willUpdate = () => {
282
- var _this$pendingScrollTo;
283
- (_this$pendingScrollTo = this.pendingScrollToIndexCallback) == null ? void 0 : _this$pendingScrollTo.call(this);
284
- const scrollElement = this.options.getScrollElement();
285
- if (this.scrollElement !== scrollElement) {
286
- this.cleanup();
287
- this.scrollElement = scrollElement;
288
- this._scrollToOffset(this.scrollOffset, {
289
- adjustments: undefined,
290
- behavior: undefined,
291
- sync: true
292
244
  });
293
- this.unsubs.push(this.options.observeElementRect(this, rect => {
294
- this.scrollRect = rect;
295
- this.calculateRange();
296
- }));
297
- this.unsubs.push(this.options.observeElementOffset(this, offset => {
298
- if (this.isScrollingTimeoutId !== null) {
299
- clearTimeout(this.isScrollingTimeoutId);
300
- this.isScrollingTimeoutId = null;
301
- }
302
- const onIsScrollingChange = isScrolling => {
303
- if (this.isScrolling !== isScrolling) {
304
- this.isScrolling = isScrolling;
305
- this.notify();
306
- }
307
- };
308
- this.scrollAdjustments = 0;
309
- if (this.scrollOffset !== offset) {
310
- this.scrollOffset = offset;
311
- onIsScrollingChange(true);
312
- }
313
- this.calculateRange();
314
- this.isScrollingTimeoutId = setTimeout(() => {
315
- this.isScrollingTimeoutId = null;
316
- onIsScrollingChange(false);
317
- }, this.options.scrollingDelay);
318
- }));
319
- } else if (!this.isScrolling) {
320
- this.calculateRange();
245
+ } else {
246
+ return null;
321
247
  }
322
248
  };
323
- this.getSize = () => {
324
- return this.scrollRect[this.options.horizontal ? 'width' : 'height'];
325
- };
326
- this.getMeasurements = memo(() => [this.options.count, this.options.paddingStart, this.options.getItemKey, this.itemMeasurementsCache], (count, paddingStart, getItemKey, measurementsCache) => {
327
- const min = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
328
- this.pendingMeasuredCacheIndexes = [];
329
- const measurements = this.measurementsCache.slice(0, min);
330
- for (let i = min; i < count; i++) {
331
- const key = getItemKey(i);
332
- const measuredSize = measurementsCache[key];
333
- const start = measurements[i - 1] ? measurements[i - 1].end : paddingStart;
334
- const size = typeof measuredSize === 'number' ? measuredSize : this.options.estimateSize(i);
335
- const end = start + size;
336
- measurements[i] = {
337
- index: i,
338
- start,
339
- size,
340
- end,
341
- key
342
- };
343
- }
344
- this.measurementsCache = measurements;
345
- return measurements;
346
- }, {
347
- key: 'getMeasurements',
348
- debug: () => this.options.debug
249
+ }();
250
+ this.range = {
251
+ startIndex: 0,
252
+ endIndex: 0
253
+ };
254
+ this.setOptions = function (opts) {
255
+ Object.entries(opts).forEach(function (_ref3) {
256
+ var key = _ref3[0],
257
+ value = _ref3[1];
258
+ if (typeof value === 'undefined') delete opts[key];
349
259
  });
350
- this.calculateRange = memo(() => [this.getMeasurements(), this.getSize(), this.scrollOffset], (measurements, outerSize, scrollOffset) => {
351
- const range = calculateRange({
352
- measurements,
353
- outerSize,
354
- scrollOffset
355
- });
356
- if (range.startIndex !== this.range.startIndex || range.endIndex !== this.range.endIndex) {
357
- this.range = range;
358
- this.notify();
359
- }
360
- return this.range;
361
- }, {
362
- key: 'calculateRange',
363
- debug: () => this.options.debug
260
+ _this.options = _extends({
261
+ debug: false,
262
+ initialOffset: 0,
263
+ overscan: 1,
264
+ paddingStart: 0,
265
+ paddingEnd: 0,
266
+ scrollPaddingStart: 0,
267
+ scrollPaddingEnd: 0,
268
+ horizontal: false,
269
+ getItemKey: defaultKeyExtractor,
270
+ rangeExtractor: defaultRangeExtractor,
271
+ onChange: function onChange() {},
272
+ measureElement: measureElement,
273
+ initialRect: {
274
+ width: 0,
275
+ height: 0
276
+ },
277
+ scrollMargin: 0,
278
+ scrollingDelay: 150,
279
+ indexAttribute: 'data-index',
280
+ initialMeasurementsCache: []
281
+ }, opts);
282
+ };
283
+ this.notify = function () {
284
+ _this.options.onChange == null ? void 0 : _this.options.onChange(_this);
285
+ };
286
+ this.cleanup = function () {
287
+ _this.unsubs.filter(Boolean).forEach(function (d) {
288
+ return d();
364
289
  });
365
- this.getIndexes = memo(() => [this.options.rangeExtractor, this.range, this.options.overscan, this.options.count], (rangeExtractor, range, overscan, count) => {
366
- return rangeExtractor({
367
- ...range,
368
- overscan,
369
- count: count
370
- });
371
- }, {
372
- key: 'getIndexes',
373
- debug: () => this.options.debug
290
+ _this.unsubs = [];
291
+ _this.scrollElement = null;
292
+ };
293
+ this._didMount = function () {
294
+ var ro = _this.getResizeObserver();
295
+ Object.values(_this.measureElementCache).forEach(function (node) {
296
+ return ro == null ? void 0 : ro.observe(node);
374
297
  });
375
- this.indexFromElement = node => {
376
- const attributeName = this.options.indexAttribute;
377
- const indexStr = node.getAttribute(attributeName);
378
- if (!indexStr) {
379
- console.warn(`Missing attribute name '${attributeName}={index}' on measured element.`);
380
- return -1;
381
- }
382
- return parseInt(indexStr, 10);
298
+ return function () {
299
+ ro == null ? void 0 : ro.disconnect();
300
+ _this.cleanup();
383
301
  };
384
- this._measureElement = (node, _sync) => {
385
- const index = this.indexFromElement(node);
386
- const item = this.measurementsCache[index];
387
- if (!item) {
388
- return;
389
- }
390
- const prevNode = this.measureElementCache[item.key];
391
- const ro = this.getResizeObserver();
392
- if (!node.isConnected) {
393
- if (prevNode) {
394
- ro == null ? void 0 : ro.unobserve(prevNode);
395
- delete this.measureElementCache[item.key];
302
+ };
303
+ this._willUpdate = function () {
304
+ _this.pendingScrollToIndexCallback == null ? void 0 : _this.pendingScrollToIndexCallback();
305
+ var scrollElement = _this.options.getScrollElement();
306
+ if (_this.scrollElement !== scrollElement) {
307
+ _this.cleanup();
308
+ _this.scrollElement = scrollElement;
309
+ _this._scrollToOffset(_this.scrollOffset, {
310
+ adjustments: undefined,
311
+ behavior: undefined
312
+ });
313
+ _this.unsubs.push(_this.options.observeElementRect(_this, function (rect) {
314
+ _this.scrollRect = rect;
315
+ _this.calculateRange();
316
+ }));
317
+ _this.unsubs.push(_this.options.observeElementOffset(_this, function (offset) {
318
+ _this.scrollAdjustments = 0;
319
+ if (_this.scrollOffset === offset) {
320
+ return;
396
321
  }
397
- return;
398
- }
399
- if (!prevNode || prevNode !== node) {
400
- if (prevNode) {
401
- ro == null ? void 0 : ro.unobserve(prevNode);
322
+ if (_this.isScrollingTimeoutId !== null) {
323
+ clearTimeout(_this.isScrollingTimeoutId);
324
+ _this.isScrollingTimeoutId = null;
402
325
  }
403
- this.measureElementCache[item.key] = node;
404
- ro == null ? void 0 : ro.observe(node);
405
- }
406
- const measuredItemSize = this.options.measureElement(node, this);
407
- const itemSize = this.itemMeasurementsCache[item.key] ?? item.size;
408
- const delta = measuredItemSize - itemSize;
409
- if (delta !== 0) {
410
- if (item.start < this.scrollOffset && this.isScrolling) {
411
- if (this.options.debug) {
412
- console.info('correction', delta);
326
+ var onIsScrollingChange = function onIsScrollingChange(isScrolling) {
327
+ if (_this.isScrolling !== isScrolling) {
328
+ _this.isScrolling = isScrolling;
329
+ _this.notify();
413
330
  }
414
- this._scrollToOffset(this.scrollOffset, {
415
- adjustments: this.scrollAdjustments += delta,
416
- behavior: undefined,
417
- sync: false
418
- });
419
- }
420
- this.pendingMeasuredCacheIndexes.push(index);
421
- this.itemMeasurementsCache = {
422
- ...this.itemMeasurementsCache,
423
- [item.key]: measuredItemSize
424
331
  };
425
- this.notify();
426
- }
427
- };
428
- this.measureElement = node => {
429
- if (!node) {
430
- return;
332
+ _this.scrollDirection = _this.scrollOffset < offset ? 'forward' : 'backward';
333
+ _this.scrollOffset = offset;
334
+ _this.calculateRange();
335
+ onIsScrollingChange(true);
336
+ _this.isScrollingTimeoutId = setTimeout(function () {
337
+ _this.isScrollingTimeoutId = null;
338
+ _this.scrollDirection = null;
339
+ onIsScrollingChange(false);
340
+ }, _this.options.scrollingDelay);
341
+ }));
342
+ } else if (!_this.isScrolling) {
343
+ _this.calculateRange();
344
+ }
345
+ };
346
+ this.getSize = function () {
347
+ return _this.scrollRect[_this.options.horizontal ? 'width' : 'height'];
348
+ };
349
+ this.getMeasurements = memo(function () {
350
+ return [_this.options.count, _this.options.paddingStart, _this.options.scrollMargin, _this.options.getItemKey, _this.itemSizeCache];
351
+ }, function (count, paddingStart, scrollMargin, getItemKey, itemSizeCache) {
352
+ var min = _this.pendingMeasuredCacheIndexes.length > 0 ? Math.min.apply(Math, _this.pendingMeasuredCacheIndexes) : 0;
353
+ _this.pendingMeasuredCacheIndexes = [];
354
+ var measurements = _this.measurementsCache.slice(0, min);
355
+ for (var _i2 = min; _i2 < count; _i2++) {
356
+ var key = getItemKey(_i2);
357
+ var measuredSize = itemSizeCache[key];
358
+ var start = measurements[_i2 - 1] ? measurements[_i2 - 1].end : paddingStart + scrollMargin;
359
+ var size = typeof measuredSize === 'number' ? measuredSize : _this.options.estimateSize(_i2);
360
+ var end = start + size;
361
+ measurements[_i2] = {
362
+ index: _i2,
363
+ start: start,
364
+ size: size,
365
+ end: end,
366
+ key: key
367
+ };
368
+ }
369
+ _this.measurementsCache = measurements;
370
+ return measurements;
371
+ }, {
372
+ key: 'getMeasurements',
373
+ debug: function debug() {
374
+ return _this.options.debug;
375
+ }
376
+ });
377
+ this.calculateRange = memo(function () {
378
+ return [_this.getMeasurements(), _this.getSize(), _this.scrollOffset];
379
+ }, function (measurements, outerSize, scrollOffset) {
380
+ var range = calculateRange({
381
+ measurements: measurements,
382
+ outerSize: outerSize,
383
+ scrollOffset: scrollOffset
384
+ });
385
+ if (range.startIndex !== _this.range.startIndex || range.endIndex !== _this.range.endIndex) {
386
+ _this.range = range;
387
+ _this.notify();
388
+ }
389
+ return _this.range;
390
+ }, {
391
+ key: 'calculateRange',
392
+ debug: function debug() {
393
+ return _this.options.debug;
394
+ }
395
+ });
396
+ this.getIndexes = memo(function () {
397
+ return [_this.options.rangeExtractor, _this.range, _this.options.overscan, _this.options.count];
398
+ }, function (rangeExtractor, range, overscan, count) {
399
+ return rangeExtractor(_extends({}, range, {
400
+ overscan: overscan,
401
+ count: count
402
+ }));
403
+ }, {
404
+ key: 'getIndexes',
405
+ debug: function debug() {
406
+ return _this.options.debug;
407
+ }
408
+ });
409
+ this.indexFromElement = function (node) {
410
+ var attributeName = _this.options.indexAttribute;
411
+ var indexStr = node.getAttribute(attributeName);
412
+ if (!indexStr) {
413
+ console.warn("Missing attribute name '" + attributeName + "={index}' on measured element.");
414
+ return -1;
415
+ }
416
+ return parseInt(indexStr, 10);
417
+ };
418
+ this._measureElement = function (node, _sync) {
419
+ var _this$itemSizeCache$i;
420
+ var index = _this.indexFromElement(node);
421
+ var item = _this.measurementsCache[index];
422
+ if (!item) {
423
+ return;
424
+ }
425
+ var prevNode = _this.measureElementCache[item.key];
426
+ var ro = _this.getResizeObserver();
427
+ if (!node.isConnected) {
428
+ if (prevNode) {
429
+ ro == null ? void 0 : ro.unobserve(prevNode);
430
+ delete _this.measureElementCache[item.key];
431
431
  }
432
- this._measureElement(node, true);
433
- };
434
- this.getVirtualItems = memo(() => [this.getIndexes(), this.getMeasurements()], (indexes, measurements) => {
435
- const virtualItems = [];
436
- for (let k = 0, len = indexes.length; k < len; k++) {
437
- const i = indexes[k];
438
- const measurement = measurements[i];
439
- virtualItems.push(measurement);
432
+ return;
433
+ }
434
+ if (!prevNode || prevNode !== node) {
435
+ if (prevNode) {
436
+ ro == null ? void 0 : ro.unobserve(prevNode);
440
437
  }
441
- return virtualItems;
442
- }, {
443
- key: 'getIndexes',
444
- debug: () => this.options.debug
445
- });
446
- this.scrollToOffset = function (toOffset, _temp) {
447
- let {
448
- align = 'start',
449
- behavior
450
- } = _temp === void 0 ? {} : _temp;
451
- const offset = _this.scrollOffset;
452
- const size = _this.getSize();
453
- if (align === 'auto') {
454
- if (toOffset <= offset) {
455
- align = 'start';
456
- } else if (toOffset >= offset + size) {
457
- align = 'end';
458
- } else {
459
- align = 'start';
438
+ _this.measureElementCache[item.key] = node;
439
+ ro == null ? void 0 : ro.observe(node);
440
+ }
441
+ var measuredItemSize = _this.options.measureElement(node, _this);
442
+ var itemSize = (_this$itemSizeCache$i = _this.itemSizeCache[item.key]) != null ? _this$itemSizeCache$i : item.size;
443
+ var delta = measuredItemSize - itemSize;
444
+ if (delta !== 0) {
445
+ var _extends2;
446
+ if (item.start < _this.scrollOffset && _this.isScrolling && _this.scrollDirection === 'backward') {
447
+ if (_this.options.debug) {
448
+ console.info('correction', delta);
460
449
  }
450
+ _this._scrollToOffset(_this.scrollOffset, {
451
+ adjustments: _this.scrollAdjustments += delta,
452
+ behavior: undefined
453
+ });
461
454
  }
462
- const options = {
463
- adjustments: undefined,
464
- behavior,
465
- sync: false
466
- };
467
- if (align === 'start') {
468
- _this._scrollToOffset(toOffset, options);
469
- } else if (align === 'end') {
470
- _this._scrollToOffset(toOffset - size, options);
471
- } else if (align === 'center') {
472
- _this._scrollToOffset(toOffset - size / 2, options);
455
+ _this.pendingMeasuredCacheIndexes.push(index);
456
+ _this.itemSizeCache = _extends({}, _this.itemSizeCache, (_extends2 = {}, _extends2[item.key] = measuredItemSize, _extends2));
457
+ _this.notify();
458
+ }
459
+ };
460
+ this.measureElement = function (node) {
461
+ if (!node) {
462
+ return;
463
+ }
464
+ _this._measureElement(node, true);
465
+ };
466
+ this.getVirtualItems = memo(function () {
467
+ return [_this.getIndexes(), _this.getMeasurements()];
468
+ }, function (indexes, measurements) {
469
+ var virtualItems = [];
470
+ for (var k = 0, len = indexes.length; k < len; k++) {
471
+ var _i3 = indexes[k];
472
+ var measurement = measurements[_i3];
473
+ virtualItems.push(measurement);
474
+ }
475
+ return virtualItems;
476
+ }, {
477
+ key: 'getIndexes',
478
+ debug: function debug() {
479
+ return _this.options.debug;
480
+ }
481
+ });
482
+ this.getOffsetForAlignment = function (toOffset, align) {
483
+ var offset = _this.scrollOffset;
484
+ var size = _this.getSize();
485
+ if (align === 'auto') {
486
+ if (toOffset <= offset) {
487
+ align = 'start';
488
+ } else if (toOffset >= offset + size) {
489
+ align = 'end';
490
+ } else {
491
+ align = 'start';
473
492
  }
493
+ }
494
+ if (align === 'start') {
495
+ return toOffset;
496
+ } else if (align === 'end') {
497
+ return toOffset - size;
498
+ } else if (align === 'center') {
499
+ return toOffset - size / 2;
500
+ }
501
+ return toOffset;
502
+ };
503
+ this.scrollToOffset = function (toOffset, _temp) {
504
+ var _ref4 = _temp === void 0 ? {} : _temp,
505
+ _ref4$align = _ref4.align,
506
+ align = _ref4$align === void 0 ? 'start' : _ref4$align,
507
+ behavior = _ref4.behavior;
508
+ var options = {
509
+ adjustments: undefined,
510
+ behavior: behavior,
511
+ sync: false
474
512
  };
475
- this.scrollToIndex = function (index, _temp2) {
476
- let {
477
- align = 'auto',
478
- ...rest
479
- } = _temp2 === void 0 ? {} : _temp2;
480
- _this.pendingScrollToIndexCallback = null;
481
- const measurements = _this.getMeasurements();
482
- const offset = _this.scrollOffset;
483
- const size = _this.getSize();
484
- const {
485
- count
486
- } = _this.options;
487
- const measurement = measurements[Math.max(0, Math.min(index, count - 1))];
488
- if (!measurement) {
513
+ _this._scrollToOffset(_this.getOffsetForAlignment(toOffset, align), options);
514
+ };
515
+ this.scrollToIndex = function (index, _temp2) {
516
+ var _ref5 = _temp2 === void 0 ? {} : _temp2,
517
+ _ref5$align = _ref5.align,
518
+ align = _ref5$align === void 0 ? 'auto' : _ref5$align,
519
+ behavior = _ref5.behavior;
520
+ _this.pendingScrollToIndexCallback = null;
521
+ var offset = _this.scrollOffset;
522
+ var size = _this.getSize();
523
+ var count = _this.options.count;
524
+ var measurements = _this.getMeasurements();
525
+ var measurement = measurements[Math.max(0, Math.min(index, count - 1))];
526
+ if (!measurement) {
527
+ throw new Error("VirtualItem not found for index = " + index);
528
+ }
529
+ if (align === 'auto') {
530
+ if (measurement.end >= offset + size - _this.options.scrollPaddingEnd) {
531
+ align = 'end';
532
+ } else if (measurement.start <= offset + _this.options.scrollPaddingStart) {
533
+ align = 'start';
534
+ } else {
489
535
  return;
490
536
  }
491
- if (align === 'auto') {
492
- if (measurement.end >= offset + size - _this.options.scrollPaddingEnd) {
493
- align = 'end';
494
- } else if (measurement.start <= offset + _this.options.scrollPaddingStart) {
495
- align = 'start';
496
- } else {
497
- return;
498
- }
499
- }
500
- const toOffset = align === 'end' ? measurement.end + _this.options.scrollPaddingEnd : measurement.start - _this.options.scrollPaddingStart;
501
- _this.scrollToOffset(toOffset, {
502
- align,
503
- ...rest
504
- });
505
- const isDynamic = Object.keys(_this.measureElementCache).length > 0;
506
- if (isDynamic) {
507
- const didSeen = () => typeof _this.itemMeasurementsCache[_this.options.getItemKey(index)] === 'number';
508
- if (!didSeen()) {
509
- _this.pendingScrollToIndexCallback = () => {
510
- if (didSeen()) {
511
- _this.pendingScrollToIndexCallback = null;
512
- _this.scrollToIndex(index, {
513
- align,
514
- ...rest
515
- });
516
- }
517
- };
518
- }
519
- }
520
- };
521
- this.getTotalSize = () => {
522
- var _this$getMeasurements;
523
- return (((_this$getMeasurements = this.getMeasurements()[this.options.count - 1]) == null ? void 0 : _this$getMeasurements.end) || this.options.paddingStart) + this.options.paddingEnd;
524
- };
525
- this._scrollToOffset = (offset, _ref4) => {
526
- let {
527
- adjustments,
528
- behavior,
529
- sync
530
- } = _ref4;
531
- this.options.scrollToFn(offset, {
532
- behavior,
533
- sync,
534
- adjustments
535
- }, this);
537
+ }
538
+ var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(measurement) {
539
+ var toOffset = align === 'end' ? measurement.end + _this.options.scrollPaddingEnd : measurement.start - _this.options.scrollPaddingStart;
540
+ return _this.getOffsetForAlignment(toOffset, align);
536
541
  };
537
- this.measure = () => {
538
- this.itemMeasurementsCache = {};
539
- this.notify();
542
+ var toOffset = getOffsetForIndexAndAlignment(measurement);
543
+ if (toOffset === offset) {
544
+ return;
545
+ }
546
+ var options = {
547
+ adjustments: undefined,
548
+ behavior: behavior
540
549
  };
541
- this.setOptions(_opts);
542
- this.scrollRect = this.options.initialRect;
543
- this.scrollOffset = this.options.initialOffset;
544
- this.calculateRange();
545
- }
546
- }
547
- const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
550
+ _this._scrollToOffset(toOffset, options);
551
+ var isDynamic = Object.keys(_this.measureElementCache).length > 0;
552
+ if (isDynamic) {
553
+ _this.pendingScrollToIndexCallback = function () {
554
+ _this.scrollToIndex(index, {
555
+ align: align,
556
+ behavior: behavior
557
+ });
558
+ };
559
+ }
560
+ };
561
+ this.scrollBy = function (adjustments, options) {
562
+ _this._scrollToOffset(_this.scrollOffset, {
563
+ adjustments: adjustments,
564
+ behavior: options == null ? void 0 : options.behavior
565
+ });
566
+ };
567
+ this.getTotalSize = function () {
568
+ var _this$getMeasurements;
569
+ return (((_this$getMeasurements = _this.getMeasurements()[_this.options.count - 1]) == null ? void 0 : _this$getMeasurements.end) || _this.options.paddingStart) - _this.options.scrollMargin + _this.options.paddingEnd;
570
+ };
571
+ this._scrollToOffset = function (offset, _ref6) {
572
+ var adjustments = _ref6.adjustments,
573
+ behavior = _ref6.behavior;
574
+ _this.options.scrollToFn(offset, {
575
+ behavior: behavior,
576
+ adjustments: adjustments
577
+ }, _this);
578
+ };
579
+ this.measure = function () {
580
+ _this.itemSizeCache = {};
581
+ _this.notify();
582
+ };
583
+ this.setOptions(_opts);
584
+ this.scrollRect = this.options.initialRect;
585
+ this.scrollOffset = this.options.initialOffset;
586
+ this.measurementsCache = this.options.initialMeasurementsCache;
587
+ this.measurementsCache.forEach(function (item) {
588
+ _this.itemSizeCache[item.key] = item.size;
589
+ });
590
+ this.calculateRange();
591
+ };
592
+ var findNearestBinarySearch = function findNearestBinarySearch(low, high, getCurrentValue, value) {
548
593
  while (low <= high) {
549
- const middle = (low + high) / 2 | 0;
550
- const currentValue = getCurrentValue(middle);
594
+ var middle = (low + high) / 2 | 0;
595
+ var currentValue = getCurrentValue(middle);
551
596
  if (currentValue < value) {
552
597
  low = middle + 1;
553
598
  } else if (currentValue > value) {
@@ -562,52 +607,60 @@
562
607
  return 0;
563
608
  }
564
609
  };
565
- function calculateRange(_ref5) {
566
- let {
567
- measurements,
568
- outerSize,
569
- scrollOffset
570
- } = _ref5;
571
- const count = measurements.length - 1;
572
- const getOffset = index => measurements[index].start;
573
- const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset);
574
- let endIndex = startIndex;
610
+ function calculateRange(_ref7) {
611
+ var measurements = _ref7.measurements,
612
+ outerSize = _ref7.outerSize,
613
+ scrollOffset = _ref7.scrollOffset;
614
+ var count = measurements.length - 1;
615
+ var getOffset = function getOffset(index) {
616
+ return measurements[index].start;
617
+ };
618
+ var startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset);
619
+ var endIndex = startIndex;
575
620
  while (endIndex < count && measurements[endIndex].end < scrollOffset + outerSize) {
576
621
  endIndex++;
577
622
  }
578
623
  return {
579
- startIndex,
580
- endIndex
624
+ startIndex: startIndex,
625
+ endIndex: endIndex
581
626
  };
582
627
  }
583
628
 
584
629
  function createVirtualizerBase(options) {
585
- const resolvedOptions = solidJs.mergeProps(options);
586
- const instance = new Virtualizer(resolvedOptions);
587
- const [virtualItems, setVirtualItems] = store.createStore(instance.getVirtualItems());
588
- const [totalSize, setTotalSize] = solidJs.createSignal(instance.getTotalSize());
589
- const handler = {
590
- get(target, prop) {
630
+ var resolvedOptions = solidJs.mergeProps(options);
631
+ var instance = new Virtualizer(resolvedOptions);
632
+ var _createStore = store.createStore(instance.getVirtualItems()),
633
+ virtualItems = _createStore[0],
634
+ setVirtualItems = _createStore[1];
635
+ var _createSignal = solidJs.createSignal(instance.getTotalSize()),
636
+ totalSize = _createSignal[0],
637
+ setTotalSize = _createSignal[1];
638
+ var handler = {
639
+ get: function get(target, prop) {
591
640
  switch (prop) {
592
641
  case 'getVirtualItems':
593
- return () => virtualItems;
642
+ return function () {
643
+ return virtualItems;
644
+ };
594
645
  case 'getTotalSize':
595
- return () => totalSize();
646
+ return function () {
647
+ return totalSize();
648
+ };
596
649
  default:
597
650
  return Reflect.get(target, prop);
598
651
  }
599
652
  }
600
653
  };
601
- const virtualizer = new Proxy(instance, handler);
654
+ var virtualizer = new Proxy(instance, handler);
602
655
  virtualizer.setOptions(resolvedOptions);
603
- solidJs.onMount(() => {
604
- const cleanup = virtualizer._didMount();
656
+ solidJs.onMount(function () {
657
+ var cleanup = virtualizer._didMount();
605
658
  virtualizer._willUpdate();
606
659
  solidJs.onCleanup(cleanup);
607
660
  });
608
- solidJs.createComputed(() => {
661
+ solidJs.createComputed(function () {
609
662
  virtualizer.setOptions(solidJs.mergeProps(resolvedOptions, options, {
610
- onChange: instance => {
663
+ onChange: function onChange(instance) {
611
664
  instance._willUpdate();
612
665
  setVirtualItems(store.reconcile(instance.getVirtualItems(), {
613
666
  key: 'index'
@@ -629,7 +682,9 @@
629
682
  }
630
683
  function createWindowVirtualizer(options) {
631
684
  return createVirtualizerBase(solidJs.mergeProps({
632
- getScrollElement: () => typeof window !== 'undefined' ? window : null,
685
+ getScrollElement: function getScrollElement() {
686
+ return typeof window !== 'undefined' ? window : null;
687
+ },
633
688
  observeElementRect: observeWindowRect,
634
689
  observeElementOffset: observeWindowOffset,
635
690
  scrollToFn: windowScroll