@tanstack/solid-virtual 3.0.0-beta.29 → 3.0.0-beta.32

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];
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];
150
178
  cb(Math.max(0, offset - instance.options.scrollMargin));
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,388 +192,404 @@
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 adjustments = _ref.adjustments,
208
+ behavior = _ref.behavior,
209
+ sync = _ref.sync;
210
+ var toOffset = (sync ? offset : offset + instance.options.scrollMargin) + (adjustments != null ? adjustments : 0);
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 adjustments = _ref2.adjustments,
216
+ behavior = _ref2.behavior,
217
+ sync = _ref2.sync;
218
+ var toOffset = (sync ? offset : offset + instance.options.scrollMargin) + (adjustments != null ? adjustments : 0);
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.itemMeasurementsCache = {};
229
+ this.pendingMeasuredCacheIndexes = [];
230
+ this.scrollAdjustments = 0;
231
+ this.measureElementCache = {};
232
+ this.pendingScrollToIndexCallback = null;
233
+ this.getResizeObserver = function () {
234
+ var _ro = null;
235
+ return function () {
236
+ if (_ro) {
237
+ return _ro;
238
+ } else if (typeof ResizeObserver !== 'undefined') {
239
+ return _ro = new ResizeObserver(function (entries) {
240
+ entries.forEach(function (entry) {
241
+ _this._measureElement(entry.target, false);
226
242
  });
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
243
  });
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
- if (this.scrollOffset !== offset) {
303
- this.scrollOffset = offset;
304
- this.isScrolling = true;
305
- this.scrollAdjustments = 0;
306
- this.isScrollingTimeoutId = setTimeout(() => {
307
- this.isScrollingTimeoutId = null;
308
- this.isScrolling = false;
309
- this.notify();
310
- }, this.options.scrollingDelay);
311
- } else {
312
- this.isScrolling = false;
313
- this.scrollAdjustments = 0;
314
- }
315
- this.calculateRange();
316
- }));
317
- } else if (!this.isScrolling) {
318
- this.calculateRange();
244
+ } else {
245
+ return null;
319
246
  }
320
247
  };
321
- this.getSize = () => {
322
- return this.scrollRect[this.options.horizontal ? 'width' : 'height'];
323
- };
324
- this.getMeasurements = memo(() => [this.options.count, this.options.paddingStart, this.options.getItemKey, this.itemMeasurementsCache], (count, paddingStart, getItemKey, measurementsCache) => {
325
- const min = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
326
- this.pendingMeasuredCacheIndexes = [];
327
- const measurements = this.measurementsCache.slice(0, min);
328
- for (let i = min; i < count; i++) {
329
- const key = getItemKey(i);
330
- const measuredSize = measurementsCache[key];
331
- const start = measurements[i - 1] ? measurements[i - 1].end : paddingStart;
332
- const size = typeof measuredSize === 'number' ? measuredSize : this.options.estimateSize(i);
333
- const end = start + size;
334
- measurements[i] = {
335
- index: i,
336
- start,
337
- size,
338
- end,
339
- key
340
- };
341
- }
342
- this.measurementsCache = measurements;
343
- return measurements;
344
- }, {
345
- key: 'getMeasurements',
346
- debug: () => this.options.debug
248
+ }();
249
+ this.range = {
250
+ startIndex: 0,
251
+ endIndex: 0
252
+ };
253
+ this.setOptions = function (opts) {
254
+ Object.entries(opts).forEach(function (_ref3) {
255
+ var key = _ref3[0],
256
+ value = _ref3[1];
257
+ if (typeof value === 'undefined') delete opts[key];
347
258
  });
348
- this.calculateRange = memo(() => [this.getMeasurements(), this.getSize(), this.scrollOffset], (measurements, outerSize, scrollOffset) => {
349
- const range = calculateRange({
350
- measurements,
351
- outerSize,
352
- scrollOffset
353
- });
354
- if (range.startIndex !== this.range.startIndex || range.endIndex !== this.range.endIndex) {
355
- this.range = range;
356
- this.notify();
357
- }
358
- return this.range;
359
- }, {
360
- key: 'calculateRange',
361
- debug: () => this.options.debug
259
+ _this.options = _extends({
260
+ debug: false,
261
+ initialOffset: 0,
262
+ overscan: 1,
263
+ paddingStart: 0,
264
+ paddingEnd: 0,
265
+ scrollPaddingStart: 0,
266
+ scrollPaddingEnd: 0,
267
+ horizontal: false,
268
+ getItemKey: defaultKeyExtractor,
269
+ rangeExtractor: defaultRangeExtractor,
270
+ onChange: function onChange() {},
271
+ measureElement: measureElement,
272
+ initialRect: {
273
+ width: 0,
274
+ height: 0
275
+ },
276
+ scrollMargin: 0,
277
+ scrollingDelay: 150,
278
+ indexAttribute: 'data-index'
279
+ }, opts);
280
+ };
281
+ this.notify = function () {
282
+ _this.options.onChange == null ? void 0 : _this.options.onChange(_this);
283
+ };
284
+ this.cleanup = function () {
285
+ _this.unsubs.filter(Boolean).forEach(function (d) {
286
+ return d();
362
287
  });
363
- this.getIndexes = memo(() => [this.options.rangeExtractor, this.range, this.options.overscan, this.options.count], (rangeExtractor, range, overscan, count) => {
364
- return rangeExtractor({
365
- ...range,
366
- overscan,
367
- count: count
368
- });
369
- }, {
370
- key: 'getIndexes',
371
- debug: () => this.options.debug
288
+ _this.unsubs = [];
289
+ _this.scrollElement = null;
290
+ };
291
+ this._didMount = function () {
292
+ var ro = _this.getResizeObserver();
293
+ Object.values(_this.measureElementCache).forEach(function (node) {
294
+ return ro == null ? void 0 : ro.observe(node);
372
295
  });
373
- this.indexFromElement = node => {
374
- const attributeName = this.options.indexAttribute;
375
- const indexStr = node.getAttribute(attributeName);
376
- if (!indexStr) {
377
- console.warn(`Missing attribute name '${attributeName}={index}' on measured element.`);
378
- return -1;
379
- }
380
- return parseInt(indexStr, 10);
296
+ return function () {
297
+ ro == null ? void 0 : ro.disconnect();
298
+ _this.cleanup();
381
299
  };
382
- this._measureElement = (node, _sync) => {
383
- const index = this.indexFromElement(node);
384
- const item = this.measurementsCache[index];
385
- if (!item) {
386
- return;
387
- }
388
- const prevNode = this.measureElementCache[item.key];
389
- const ro = this.getResizeObserver();
390
- if (!node.isConnected) {
391
- if (prevNode) {
392
- ro == null ? void 0 : ro.unobserve(prevNode);
393
- delete this.measureElementCache[item.key];
394
- }
395
- return;
396
- }
397
- if (!prevNode || prevNode !== node) {
398
- if (prevNode) {
399
- ro == null ? void 0 : ro.unobserve(prevNode);
300
+ };
301
+ this._willUpdate = function () {
302
+ _this.pendingScrollToIndexCallback == null ? void 0 : _this.pendingScrollToIndexCallback();
303
+ var scrollElement = _this.options.getScrollElement();
304
+ if (_this.scrollElement !== scrollElement) {
305
+ _this.cleanup();
306
+ _this.scrollElement = scrollElement;
307
+ _this._scrollToOffset(_this.scrollOffset, {
308
+ adjustments: undefined,
309
+ behavior: undefined,
310
+ sync: true
311
+ });
312
+ _this.unsubs.push(_this.options.observeElementRect(_this, function (rect) {
313
+ _this.scrollRect = rect;
314
+ _this.calculateRange();
315
+ }));
316
+ _this.unsubs.push(_this.options.observeElementOffset(_this, function (offset) {
317
+ if (_this.isScrollingTimeoutId !== null) {
318
+ clearTimeout(_this.isScrollingTimeoutId);
319
+ _this.isScrollingTimeoutId = null;
400
320
  }
401
- this.measureElementCache[item.key] = node;
402
- ro == null ? void 0 : ro.observe(node);
403
- }
404
- const measuredItemSize = this.options.measureElement(node, this);
405
- const itemSize = this.itemMeasurementsCache[item.key] ?? item.size;
406
- const delta = measuredItemSize - itemSize;
407
- if (delta !== 0) {
408
- if (item.start < this.scrollOffset && this.isScrolling) {
409
- if (this.options.debug) {
410
- console.info('correction', delta);
321
+ var onIsScrollingChange = function onIsScrollingChange(isScrolling) {
322
+ if (_this.isScrolling !== isScrolling) {
323
+ _this.isScrolling = isScrolling;
324
+ _this.notify();
411
325
  }
412
- this._scrollToOffset(this.scrollOffset, {
413
- adjustments: this.scrollAdjustments += delta,
414
- behavior: undefined,
415
- sync: false
416
- });
417
- }
418
- this.pendingMeasuredCacheIndexes.push(index);
419
- this.itemMeasurementsCache = {
420
- ...this.itemMeasurementsCache,
421
- [item.key]: measuredItemSize
422
326
  };
423
- this.notify();
424
- }
425
- };
426
- this.measureElement = node => {
427
- if (!node) {
428
- return;
429
- }
430
- this._measureElement(node, true);
431
- };
432
- this.getVirtualItems = memo(() => [this.getIndexes(), this.getMeasurements()], (indexes, measurements) => {
433
- const virtualItems = [];
434
- for (let k = 0, len = indexes.length; k < len; k++) {
435
- const i = indexes[k];
436
- const measurement = measurements[i];
437
- virtualItems.push(measurement);
438
- }
439
- return virtualItems;
440
- }, {
441
- key: 'getIndexes',
442
- debug: () => this.options.debug
443
- });
444
- this.scrollToOffset = function (toOffset, _temp) {
445
- let {
446
- align = 'start',
447
- behavior
448
- } = _temp === void 0 ? {} : _temp;
449
- const offset = _this.scrollOffset;
450
- const size = _this.getSize();
451
- if (align === 'auto') {
452
- if (toOffset <= offset) {
453
- align = 'start';
454
- } else if (toOffset >= offset + size) {
455
- align = 'end';
456
- } else {
457
- align = 'start';
327
+ _this.scrollAdjustments = 0;
328
+ if (_this.scrollOffset !== offset) {
329
+ _this.scrollOffset = offset;
330
+ onIsScrollingChange(true);
458
331
  }
459
- }
460
- const options = {
461
- adjustments: undefined,
462
- behavior,
463
- sync: false
332
+ _this.calculateRange();
333
+ _this.isScrollingTimeoutId = setTimeout(function () {
334
+ _this.isScrollingTimeoutId = null;
335
+ onIsScrollingChange(false);
336
+ }, _this.options.scrollingDelay);
337
+ }));
338
+ } else if (!_this.isScrolling) {
339
+ _this.calculateRange();
340
+ }
341
+ };
342
+ this.getSize = function () {
343
+ return _this.scrollRect[_this.options.horizontal ? 'width' : 'height'];
344
+ };
345
+ this.getMeasurements = memo(function () {
346
+ return [_this.options.count, _this.options.paddingStart, _this.options.getItemKey, _this.itemMeasurementsCache];
347
+ }, function (count, paddingStart, getItemKey, measurementsCache) {
348
+ var min = _this.pendingMeasuredCacheIndexes.length > 0 ? Math.min.apply(Math, _this.pendingMeasuredCacheIndexes) : 0;
349
+ _this.pendingMeasuredCacheIndexes = [];
350
+ var measurements = _this.measurementsCache.slice(0, min);
351
+ for (var _i2 = min; _i2 < count; _i2++) {
352
+ var key = getItemKey(_i2);
353
+ var measuredSize = measurementsCache[key];
354
+ var start = measurements[_i2 - 1] ? measurements[_i2 - 1].end : paddingStart;
355
+ var size = typeof measuredSize === 'number' ? measuredSize : _this.options.estimateSize(_i2);
356
+ var end = start + size;
357
+ measurements[_i2] = {
358
+ index: _i2,
359
+ start: start,
360
+ size: size,
361
+ end: end,
362
+ key: key
464
363
  };
465
- if (align === 'start') {
466
- _this._scrollToOffset(toOffset, options);
467
- } else if (align === 'end') {
468
- _this._scrollToOffset(toOffset - size, options);
469
- } else if (align === 'center') {
470
- _this._scrollToOffset(toOffset - size / 2, options);
364
+ }
365
+ _this.measurementsCache = measurements;
366
+ return measurements;
367
+ }, {
368
+ key: 'getMeasurements',
369
+ debug: function debug() {
370
+ return _this.options.debug;
371
+ }
372
+ });
373
+ this.calculateRange = memo(function () {
374
+ return [_this.getMeasurements(), _this.getSize(), _this.scrollOffset];
375
+ }, function (measurements, outerSize, scrollOffset) {
376
+ var range = calculateRange({
377
+ measurements: measurements,
378
+ outerSize: outerSize,
379
+ scrollOffset: scrollOffset
380
+ });
381
+ if (range.startIndex !== _this.range.startIndex || range.endIndex !== _this.range.endIndex) {
382
+ _this.range = range;
383
+ _this.notify();
384
+ }
385
+ return _this.range;
386
+ }, {
387
+ key: 'calculateRange',
388
+ debug: function debug() {
389
+ return _this.options.debug;
390
+ }
391
+ });
392
+ this.getIndexes = memo(function () {
393
+ return [_this.options.rangeExtractor, _this.range, _this.options.overscan, _this.options.count];
394
+ }, function (rangeExtractor, range, overscan, count) {
395
+ return rangeExtractor(_extends({}, range, {
396
+ overscan: overscan,
397
+ count: count
398
+ }));
399
+ }, {
400
+ key: 'getIndexes',
401
+ debug: function debug() {
402
+ return _this.options.debug;
403
+ }
404
+ });
405
+ this.indexFromElement = function (node) {
406
+ var attributeName = _this.options.indexAttribute;
407
+ var indexStr = node.getAttribute(attributeName);
408
+ if (!indexStr) {
409
+ console.warn("Missing attribute name '" + attributeName + "={index}' on measured element.");
410
+ return -1;
411
+ }
412
+ return parseInt(indexStr, 10);
413
+ };
414
+ this._measureElement = function (node, _sync) {
415
+ var _this$itemMeasurement;
416
+ var index = _this.indexFromElement(node);
417
+ var item = _this.measurementsCache[index];
418
+ if (!item) {
419
+ return;
420
+ }
421
+ var prevNode = _this.measureElementCache[item.key];
422
+ var ro = _this.getResizeObserver();
423
+ if (!node.isConnected) {
424
+ if (prevNode) {
425
+ ro == null ? void 0 : ro.unobserve(prevNode);
426
+ delete _this.measureElementCache[item.key];
471
427
  }
472
- };
473
- this.scrollToIndex = function (index, _temp2) {
474
- let {
475
- align = 'auto',
476
- ...rest
477
- } = _temp2 === void 0 ? {} : _temp2;
478
- _this.pendingScrollToIndexCallback = null;
479
- const measurements = _this.getMeasurements();
480
- const offset = _this.scrollOffset;
481
- const size = _this.getSize();
482
- const {
483
- count
484
- } = _this.options;
485
- const measurement = measurements[Math.max(0, Math.min(index, count - 1))];
486
- if (!measurement) {
487
- return;
428
+ return;
429
+ }
430
+ if (!prevNode || prevNode !== node) {
431
+ if (prevNode) {
432
+ ro == null ? void 0 : ro.unobserve(prevNode);
488
433
  }
489
- if (align === 'auto') {
490
- if (measurement.end >= offset + size - _this.options.scrollPaddingEnd) {
491
- align = 'end';
492
- } else if (measurement.start <= offset + _this.options.scrollPaddingStart) {
493
- align = 'start';
494
- } else {
495
- return;
434
+ _this.measureElementCache[item.key] = node;
435
+ ro == null ? void 0 : ro.observe(node);
436
+ }
437
+ var measuredItemSize = _this.options.measureElement(node, _this);
438
+ var itemSize = (_this$itemMeasurement = _this.itemMeasurementsCache[item.key]) != null ? _this$itemMeasurement : item.size;
439
+ var delta = measuredItemSize - itemSize;
440
+ if (delta !== 0) {
441
+ var _extends2;
442
+ if (item.start < _this.scrollOffset && _this.isScrolling) {
443
+ if (_this.options.debug) {
444
+ console.info('correction', delta);
496
445
  }
446
+ _this._scrollToOffset(_this.scrollOffset, {
447
+ adjustments: _this.scrollAdjustments += delta,
448
+ behavior: undefined,
449
+ sync: false
450
+ });
497
451
  }
498
- const toOffset = align === 'end' ? measurement.end + _this.options.scrollPaddingEnd : measurement.start - _this.options.scrollPaddingStart;
499
- _this.scrollToOffset(toOffset, {
500
- align,
501
- ...rest
502
- });
503
- const isDynamic = Object.keys(_this.measureElementCache).length > 0;
504
- if (isDynamic) {
505
- const didSeen = () => typeof _this.itemMeasurementsCache[_this.options.getItemKey(index)] === 'number';
506
- if (!didSeen()) {
507
- _this.pendingScrollToIndexCallback = () => {
508
- if (didSeen()) {
509
- _this.pendingScrollToIndexCallback = null;
510
- _this.scrollToIndex(index, {
511
- align,
512
- ...rest
513
- });
514
- }
515
- };
516
- }
452
+ _this.pendingMeasuredCacheIndexes.push(index);
453
+ _this.itemMeasurementsCache = _extends({}, _this.itemMeasurementsCache, (_extends2 = {}, _extends2[item.key] = measuredItemSize, _extends2));
454
+ _this.notify();
455
+ }
456
+ };
457
+ this.measureElement = function (node) {
458
+ if (!node) {
459
+ return;
460
+ }
461
+ _this._measureElement(node, true);
462
+ };
463
+ this.getVirtualItems = memo(function () {
464
+ return [_this.getIndexes(), _this.getMeasurements()];
465
+ }, function (indexes, measurements) {
466
+ var virtualItems = [];
467
+ for (var k = 0, len = indexes.length; k < len; k++) {
468
+ var _i3 = indexes[k];
469
+ var measurement = measurements[_i3];
470
+ virtualItems.push(measurement);
471
+ }
472
+ return virtualItems;
473
+ }, {
474
+ key: 'getIndexes',
475
+ debug: function debug() {
476
+ return _this.options.debug;
477
+ }
478
+ });
479
+ this.getOffsetForAlignment = function (toOffset, align) {
480
+ var offset = _this.scrollOffset;
481
+ var size = _this.getSize();
482
+ if (align === 'auto') {
483
+ if (toOffset <= offset) {
484
+ align = 'start';
485
+ } else if (toOffset >= offset + size) {
486
+ align = 'end';
487
+ } else {
488
+ align = 'start';
517
489
  }
490
+ }
491
+ if (align === 'start') {
492
+ return toOffset;
493
+ } else if (align === 'end') {
494
+ return toOffset - size;
495
+ } else if (align === 'center') {
496
+ return toOffset - size / 2;
497
+ }
498
+ return toOffset;
499
+ };
500
+ this.scrollToOffset = function (toOffset, _temp) {
501
+ var _ref4 = _temp === void 0 ? {} : _temp,
502
+ _ref4$align = _ref4.align,
503
+ align = _ref4$align === void 0 ? 'start' : _ref4$align,
504
+ behavior = _ref4.behavior;
505
+ var options = {
506
+ adjustments: undefined,
507
+ behavior: behavior,
508
+ sync: false
518
509
  };
519
- this.getTotalSize = () => {
520
- var _this$getMeasurements;
521
- return (((_this$getMeasurements = this.getMeasurements()[this.options.count - 1]) == null ? void 0 : _this$getMeasurements.end) || this.options.paddingStart) + this.options.paddingEnd;
522
- };
523
- this._scrollToOffset = (offset, _ref4) => {
524
- let {
525
- adjustments,
526
- behavior,
527
- sync
528
- } = _ref4;
529
- this.options.scrollToFn(offset, {
530
- behavior,
531
- sync,
532
- adjustments
533
- }, this);
510
+ _this._scrollToOffset(_this.getOffsetForAlignment(toOffset, align), options);
511
+ };
512
+ this.scrollToIndex = function (index, _temp2) {
513
+ var _ref5 = _temp2 === void 0 ? {} : _temp2,
514
+ _ref5$align = _ref5.align,
515
+ align = _ref5$align === void 0 ? 'auto' : _ref5$align,
516
+ behavior = _ref5.behavior;
517
+ _this.pendingScrollToIndexCallback = null;
518
+ var offset = _this.scrollOffset;
519
+ var size = _this.getSize();
520
+ var count = _this.options.count;
521
+ var measurements = _this.getMeasurements();
522
+ var measurement = measurements[Math.max(0, Math.min(index, count - 1))];
523
+ if (!measurement) {
524
+ throw new Error("VirtualItem not found for index = " + index);
525
+ }
526
+ if (align === 'auto') {
527
+ if (measurement.end >= offset + size - _this.options.scrollPaddingEnd) {
528
+ align = 'end';
529
+ } else if (measurement.start <= offset + _this.options.scrollPaddingStart) {
530
+ align = 'start';
531
+ } else {
532
+ return;
533
+ }
534
+ }
535
+ var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(measurement) {
536
+ var toOffset = align === 'end' ? measurement.end + _this.options.scrollPaddingEnd : measurement.start - _this.options.scrollPaddingStart;
537
+ return _this.getOffsetForAlignment(toOffset, align);
534
538
  };
535
- this.measure = () => {
536
- this.itemMeasurementsCache = {};
537
- this.notify();
539
+ var toOffset = getOffsetForIndexAndAlignment(measurement);
540
+ if (toOffset === offset) {
541
+ return;
542
+ }
543
+ var options = {
544
+ adjustments: undefined,
545
+ behavior: behavior,
546
+ sync: false
538
547
  };
539
- this.setOptions(_opts);
540
- this.scrollRect = this.options.initialRect;
541
- this.scrollOffset = this.options.initialOffset;
542
- this.calculateRange();
543
- }
544
- }
545
- const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
548
+ _this._scrollToOffset(toOffset, options);
549
+ var isDynamic = Object.keys(_this.measureElementCache).length > 0;
550
+ if (isDynamic) {
551
+ _this.pendingScrollToIndexCallback = function () {
552
+ _this.scrollToIndex(index, {
553
+ align: align,
554
+ behavior: behavior
555
+ });
556
+ };
557
+ }
558
+ };
559
+ this.scrollBy = function (adjustments, options) {
560
+ _this._scrollToOffset(_this.scrollOffset, {
561
+ adjustments: adjustments,
562
+ behavior: options == null ? void 0 : options.behavior,
563
+ sync: false
564
+ });
565
+ };
566
+ this.getTotalSize = function () {
567
+ var _this$getMeasurements;
568
+ return (((_this$getMeasurements = _this.getMeasurements()[_this.options.count - 1]) == null ? void 0 : _this$getMeasurements.end) || _this.options.paddingStart) + _this.options.paddingEnd;
569
+ };
570
+ this._scrollToOffset = function (offset, _ref6) {
571
+ var adjustments = _ref6.adjustments,
572
+ behavior = _ref6.behavior,
573
+ sync = _ref6.sync;
574
+ _this.options.scrollToFn(offset, {
575
+ behavior: behavior,
576
+ sync: sync,
577
+ adjustments: adjustments
578
+ }, _this);
579
+ };
580
+ this.measure = function () {
581
+ _this.itemMeasurementsCache = {};
582
+ _this.notify();
583
+ };
584
+ this.setOptions(_opts);
585
+ this.scrollRect = this.options.initialRect;
586
+ this.scrollOffset = this.options.initialOffset;
587
+ this.calculateRange();
588
+ };
589
+ var findNearestBinarySearch = function findNearestBinarySearch(low, high, getCurrentValue, value) {
546
590
  while (low <= high) {
547
- const middle = (low + high) / 2 | 0;
548
- const currentValue = getCurrentValue(middle);
591
+ var middle = (low + high) / 2 | 0;
592
+ var currentValue = getCurrentValue(middle);
549
593
  if (currentValue < value) {
550
594
  low = middle + 1;
551
595
  } else if (currentValue > value) {
@@ -560,52 +604,60 @@
560
604
  return 0;
561
605
  }
562
606
  };
563
- function calculateRange(_ref5) {
564
- let {
565
- measurements,
566
- outerSize,
567
- scrollOffset
568
- } = _ref5;
569
- const count = measurements.length - 1;
570
- const getOffset = index => measurements[index].start;
571
- const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset);
572
- let endIndex = startIndex;
607
+ function calculateRange(_ref7) {
608
+ var measurements = _ref7.measurements,
609
+ outerSize = _ref7.outerSize,
610
+ scrollOffset = _ref7.scrollOffset;
611
+ var count = measurements.length - 1;
612
+ var getOffset = function getOffset(index) {
613
+ return measurements[index].start;
614
+ };
615
+ var startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset);
616
+ var endIndex = startIndex;
573
617
  while (endIndex < count && measurements[endIndex].end < scrollOffset + outerSize) {
574
618
  endIndex++;
575
619
  }
576
620
  return {
577
- startIndex,
578
- endIndex
621
+ startIndex: startIndex,
622
+ endIndex: endIndex
579
623
  };
580
624
  }
581
625
 
582
626
  function createVirtualizerBase(options) {
583
- const resolvedOptions = solidJs.mergeProps(options);
584
- const instance = new Virtualizer(resolvedOptions);
585
- const [virtualItems, setVirtualItems] = store.createStore(instance.getVirtualItems());
586
- const [totalSize, setTotalSize] = solidJs.createSignal(instance.getTotalSize());
587
- const handler = {
588
- get(target, prop) {
627
+ var resolvedOptions = solidJs.mergeProps(options);
628
+ var instance = new Virtualizer(resolvedOptions);
629
+ var _createStore = store.createStore(instance.getVirtualItems()),
630
+ virtualItems = _createStore[0],
631
+ setVirtualItems = _createStore[1];
632
+ var _createSignal = solidJs.createSignal(instance.getTotalSize()),
633
+ totalSize = _createSignal[0],
634
+ setTotalSize = _createSignal[1];
635
+ var handler = {
636
+ get: function get(target, prop) {
589
637
  switch (prop) {
590
638
  case 'getVirtualItems':
591
- return () => virtualItems;
639
+ return function () {
640
+ return virtualItems;
641
+ };
592
642
  case 'getTotalSize':
593
- return () => totalSize();
643
+ return function () {
644
+ return totalSize();
645
+ };
594
646
  default:
595
647
  return Reflect.get(target, prop);
596
648
  }
597
649
  }
598
650
  };
599
- const virtualizer = new Proxy(instance, handler);
651
+ var virtualizer = new Proxy(instance, handler);
600
652
  virtualizer.setOptions(resolvedOptions);
601
- solidJs.onMount(() => {
602
- const cleanup = virtualizer._didMount();
653
+ solidJs.onMount(function () {
654
+ var cleanup = virtualizer._didMount();
603
655
  virtualizer._willUpdate();
604
656
  solidJs.onCleanup(cleanup);
605
657
  });
606
- solidJs.createComputed(() => {
658
+ solidJs.createComputed(function () {
607
659
  virtualizer.setOptions(solidJs.mergeProps(resolvedOptions, options, {
608
- onChange: instance => {
660
+ onChange: function onChange(instance) {
609
661
  instance._willUpdate();
610
662
  setVirtualItems(store.reconcile(instance.getVirtualItems(), {
611
663
  key: 'index'
@@ -627,7 +679,9 @@
627
679
  }
628
680
  function createWindowVirtualizer(options) {
629
681
  return createVirtualizerBase(solidJs.mergeProps({
630
- getScrollElement: () => typeof window !== 'undefined' ? window : null,
682
+ getScrollElement: function getScrollElement() {
683
+ return typeof window !== 'undefined' ? window : null;
684
+ },
631
685
  observeElementRect: observeWindowRect,
632
686
  observeElementOffset: observeWindowOffset,
633
687
  scrollToFn: windowScroll