@tanstack/virtual-core 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.
@@ -8,6 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ import { extends as _extends } from './_virtual/_rollupPluginBabelHelpers.mjs';
11
12
  import { memo } from './utils.mjs';
12
13
  export { memo } from './utils.mjs';
13
14
 
@@ -15,30 +16,32 @@ export { memo } from './utils.mjs';
15
16
 
16
17
  //
17
18
 
18
- const defaultKeyExtractor = index => index;
19
- const defaultRangeExtractor = range => {
20
- const start = Math.max(range.startIndex - range.overscan, 0);
21
- const end = Math.min(range.endIndex + range.overscan, range.count - 1);
22
- const arr = [];
23
- for (let i = start; i <= end; i++) {
24
- arr.push(i);
19
+ var defaultKeyExtractor = function defaultKeyExtractor(index) {
20
+ return index;
21
+ };
22
+ var defaultRangeExtractor = function defaultRangeExtractor(range) {
23
+ var start = Math.max(range.startIndex - range.overscan, 0);
24
+ var end = Math.min(range.endIndex + range.overscan, range.count - 1);
25
+ var arr = [];
26
+ for (var _i = start; _i <= end; _i++) {
27
+ arr.push(_i);
25
28
  }
26
29
  return arr;
27
30
  };
28
- const memoRectCallback = (instance, cb) => {
29
- let prev = {
31
+ var memoRectCallback = function memoRectCallback(instance, cb) {
32
+ var prev = {
30
33
  height: -1,
31
34
  width: -1
32
35
  };
33
- return rect => {
36
+ return function (rect) {
34
37
  if (instance.options.horizontal ? rect.width !== prev.width : rect.height !== prev.height) {
35
38
  cb(rect);
36
39
  }
37
40
  prev = rect;
38
41
  };
39
42
  };
40
- const observeElementRect = (instance, cb) => {
41
- const observer = new ResizeObserver(entries => {
43
+ var observeElementRect = function observeElementRect(instance, cb) {
44
+ var observer = new ResizeObserver(function (entries) {
42
45
  var _entries$, _entries$2;
43
46
  cb({
44
47
  width: (_entries$ = entries[0]) == null ? void 0 : _entries$.contentRect.width,
@@ -50,16 +53,18 @@ const observeElementRect = (instance, cb) => {
50
53
  }
51
54
  cb(instance.scrollElement.getBoundingClientRect());
52
55
  observer.observe(instance.scrollElement);
53
- return () => {
56
+ return function () {
54
57
  observer.unobserve(instance.scrollElement);
55
58
  };
56
59
  };
57
- const observeWindowRect = (instance, cb) => {
58
- const memoizedCallback = memoRectCallback(instance, cb);
59
- const onResize = () => memoizedCallback({
60
- width: instance.scrollElement.innerWidth,
61
- height: instance.scrollElement.innerHeight
62
- });
60
+ var observeWindowRect = function observeWindowRect(instance, cb) {
61
+ var memoizedCallback = memoRectCallback(instance, cb);
62
+ var onResize = function onResize() {
63
+ return memoizedCallback({
64
+ width: instance.scrollElement.innerWidth,
65
+ height: instance.scrollElement.innerHeight
66
+ });
67
+ };
63
68
  if (!instance.scrollElement) {
64
69
  return;
65
70
  }
@@ -68,32 +73,32 @@ const observeWindowRect = (instance, cb) => {
68
73
  capture: false,
69
74
  passive: true
70
75
  });
71
- return () => {
76
+ return function () {
72
77
  instance.scrollElement.removeEventListener('resize', onResize);
73
78
  };
74
79
  };
75
- const scrollProps = {
80
+ var scrollProps = {
76
81
  element: ['scrollLeft', 'scrollTop'],
77
82
  window: ['scrollX', 'scrollY']
78
83
  };
79
- const createOffsetObserver = mode => {
80
- return (instance, cb) => {
84
+ var createOffsetObserver = function createOffsetObserver(mode) {
85
+ return function (instance, cb) {
81
86
  if (!instance.scrollElement) {
82
87
  return;
83
88
  }
84
- const propX = scrollProps[mode][0];
85
- const propY = scrollProps[mode][1];
86
- let prevX = instance.scrollElement[propX];
87
- let prevY = instance.scrollElement[propY];
88
- const scroll = () => {
89
- const offset = instance.scrollElement[instance.options.horizontal ? propX : propY];
90
- cb(Math.max(0, offset - instance.options.scrollMargin));
89
+ var propX = scrollProps[mode][0];
90
+ var propY = scrollProps[mode][1];
91
+ var prevX = instance.scrollElement[propX];
92
+ var prevY = instance.scrollElement[propY];
93
+ var scroll = function scroll() {
94
+ var offset = instance.scrollElement[instance.options.horizontal ? propX : propY];
95
+ cb(offset);
91
96
  };
92
97
  scroll();
93
- const onScroll = e => {
94
- const target = e.currentTarget;
95
- const scrollX = target[propX];
96
- const scrollY = target[propY];
98
+ var onScroll = function onScroll(e) {
99
+ var target = e.currentTarget;
100
+ var scrollX = target[propX];
101
+ var scrollY = target[propY];
97
102
  if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) {
98
103
  scroll();
99
104
  }
@@ -104,390 +109,407 @@ const createOffsetObserver = mode => {
104
109
  capture: false,
105
110
  passive: true
106
111
  });
107
- return () => {
112
+ return function () {
108
113
  instance.scrollElement.removeEventListener('scroll', onScroll);
109
114
  };
110
115
  };
111
116
  };
112
- const observeElementOffset = createOffsetObserver('element');
113
- const observeWindowOffset = createOffsetObserver('window');
114
- const measureElement = (element, instance) => {
117
+ var observeElementOffset = createOffsetObserver('element');
118
+ var observeWindowOffset = createOffsetObserver('window');
119
+ var measureElement = function measureElement(element, instance) {
115
120
  return Math.round(element.getBoundingClientRect()[instance.options.horizontal ? 'width' : 'height']);
116
121
  };
117
- const windowScroll = (offset, _ref, instance) => {
118
- var _instance$scrollEleme;
119
- let {
120
- adjustments,
121
- behavior,
122
- sync
123
- } = _ref;
124
- const toOffset = (sync ? offset : offset + instance.options.scrollMargin) + (adjustments ?? 0);
125
- (_instance$scrollEleme = instance.scrollElement) == null ? void 0 : _instance$scrollEleme.scrollTo == null ? void 0 : _instance$scrollEleme.scrollTo({
126
- [instance.options.horizontal ? 'left' : 'top']: toOffset,
127
- behavior
128
- });
122
+ var windowScroll = function windowScroll(offset, _ref, instance) {
123
+ var _instance$scrollEleme, _instance$scrollEleme2;
124
+ var _ref$adjustments = _ref.adjustments,
125
+ adjustments = _ref$adjustments === void 0 ? 0 : _ref$adjustments,
126
+ behavior = _ref.behavior;
127
+ var toOffset = offset + adjustments;
128
+ (_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));
129
129
  };
130
- const elementScroll = (offset, _ref2, instance) => {
131
- var _instance$scrollEleme2;
132
- let {
133
- adjustments,
134
- behavior,
135
- sync
136
- } = _ref2;
137
- const toOffset = (sync ? offset : offset + instance.options.scrollMargin) + (adjustments ?? 0);
138
- (_instance$scrollEleme2 = instance.scrollElement) == null ? void 0 : _instance$scrollEleme2.scrollTo == null ? void 0 : _instance$scrollEleme2.scrollTo({
139
- [instance.options.horizontal ? 'left' : 'top']: toOffset,
140
- behavior
141
- });
130
+ var elementScroll = function elementScroll(offset, _ref2, instance) {
131
+ var _instance$scrollEleme3, _instance$scrollEleme4;
132
+ var _ref2$adjustments = _ref2.adjustments,
133
+ adjustments = _ref2$adjustments === void 0 ? 0 : _ref2$adjustments,
134
+ behavior = _ref2.behavior;
135
+ var toOffset = offset + adjustments;
136
+ (_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));
142
137
  };
143
- class Virtualizer {
144
- constructor(_opts) {
145
- var _this = this;
146
- this.unsubs = [];
147
- this.scrollElement = null;
148
- this.isScrolling = false;
149
- this.isScrollingTimeoutId = null;
150
- this.measurementsCache = [];
151
- this.itemMeasurementsCache = {};
152
- this.pendingMeasuredCacheIndexes = [];
153
- this.scrollAdjustments = 0;
154
- this.measureElementCache = {};
155
- this.pendingScrollToIndexCallback = null;
156
- this.getResizeObserver = (() => {
157
- let _ro = null;
158
- return () => {
159
- if (_ro) {
160
- return _ro;
161
- } else if (typeof ResizeObserver !== 'undefined') {
162
- return _ro = new ResizeObserver(entries => {
163
- entries.forEach(entry => {
164
- this._measureElement(entry.target, false);
165
- });
138
+ var Virtualizer = function Virtualizer(_opts) {
139
+ var _this = this;
140
+ this.unsubs = [];
141
+ this.scrollElement = null;
142
+ this.isScrolling = false;
143
+ this.isScrollingTimeoutId = null;
144
+ this.measurementsCache = [];
145
+ this.itemSizeCache = {};
146
+ this.pendingMeasuredCacheIndexes = [];
147
+ this.scrollDirection = null;
148
+ this.scrollAdjustments = 0;
149
+ this.measureElementCache = {};
150
+ this.pendingScrollToIndexCallback = null;
151
+ this.getResizeObserver = function () {
152
+ var _ro = null;
153
+ return function () {
154
+ if (_ro) {
155
+ return _ro;
156
+ } else if (typeof ResizeObserver !== 'undefined') {
157
+ return _ro = new ResizeObserver(function (entries) {
158
+ entries.forEach(function (entry) {
159
+ _this._measureElement(entry.target, false);
166
160
  });
167
- } else {
168
- return null;
169
- }
170
- };
171
- })();
172
- this.range = {
173
- startIndex: 0,
174
- endIndex: 0
175
- };
176
- this.setOptions = opts => {
177
- Object.entries(opts).forEach(_ref3 => {
178
- let [key, value] = _ref3;
179
- if (typeof value === 'undefined') delete opts[key];
180
- });
181
- this.options = {
182
- debug: false,
183
- initialOffset: 0,
184
- overscan: 1,
185
- paddingStart: 0,
186
- paddingEnd: 0,
187
- scrollPaddingStart: 0,
188
- scrollPaddingEnd: 0,
189
- horizontal: false,
190
- getItemKey: defaultKeyExtractor,
191
- rangeExtractor: defaultRangeExtractor,
192
- onChange: () => {},
193
- measureElement,
194
- initialRect: {
195
- width: 0,
196
- height: 0
197
- },
198
- scrollMargin: 0,
199
- scrollingDelay: 150,
200
- indexAttribute: 'data-index',
201
- ...opts
202
- };
203
- };
204
- this.notify = () => {
205
- var _this$options$onChang, _this$options;
206
- (_this$options$onChang = (_this$options = this.options).onChange) == null ? void 0 : _this$options$onChang.call(_this$options, this);
207
- };
208
- this.cleanup = () => {
209
- this.unsubs.filter(Boolean).forEach(d => d());
210
- this.unsubs = [];
211
- this.scrollElement = null;
212
- };
213
- this._didMount = () => {
214
- const ro = this.getResizeObserver();
215
- Object.values(this.measureElementCache).forEach(node => ro == null ? void 0 : ro.observe(node));
216
- return () => {
217
- ro == null ? void 0 : ro.disconnect();
218
- this.cleanup();
219
- };
220
- };
221
- this._willUpdate = () => {
222
- var _this$pendingScrollTo;
223
- (_this$pendingScrollTo = this.pendingScrollToIndexCallback) == null ? void 0 : _this$pendingScrollTo.call(this);
224
- const scrollElement = this.options.getScrollElement();
225
- if (this.scrollElement !== scrollElement) {
226
- this.cleanup();
227
- this.scrollElement = scrollElement;
228
- this._scrollToOffset(this.scrollOffset, {
229
- adjustments: undefined,
230
- behavior: undefined,
231
- sync: true
232
161
  });
233
- this.unsubs.push(this.options.observeElementRect(this, rect => {
234
- this.scrollRect = rect;
235
- this.calculateRange();
236
- }));
237
- this.unsubs.push(this.options.observeElementOffset(this, offset => {
238
- if (this.isScrollingTimeoutId !== null) {
239
- clearTimeout(this.isScrollingTimeoutId);
240
- this.isScrollingTimeoutId = null;
241
- }
242
- const onIsScrollingChange = isScrolling => {
243
- if (this.isScrolling !== isScrolling) {
244
- this.isScrolling = isScrolling;
245
- this.notify();
246
- }
247
- };
248
- this.scrollAdjustments = 0;
249
- if (this.scrollOffset !== offset) {
250
- this.scrollOffset = offset;
251
- onIsScrollingChange(true);
252
- }
253
- this.calculateRange();
254
- this.isScrollingTimeoutId = setTimeout(() => {
255
- this.isScrollingTimeoutId = null;
256
- onIsScrollingChange(false);
257
- }, this.options.scrollingDelay);
258
- }));
259
- } else if (!this.isScrolling) {
260
- this.calculateRange();
162
+ } else {
163
+ return null;
261
164
  }
262
165
  };
263
- this.getSize = () => {
264
- return this.scrollRect[this.options.horizontal ? 'width' : 'height'];
265
- };
266
- this.getMeasurements = memo(() => [this.options.count, this.options.paddingStart, this.options.getItemKey, this.itemMeasurementsCache], (count, paddingStart, getItemKey, measurementsCache) => {
267
- const min = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;
268
- this.pendingMeasuredCacheIndexes = [];
269
- const measurements = this.measurementsCache.slice(0, min);
270
- for (let i = min; i < count; i++) {
271
- const key = getItemKey(i);
272
- const measuredSize = measurementsCache[key];
273
- const start = measurements[i - 1] ? measurements[i - 1].end : paddingStart;
274
- const size = typeof measuredSize === 'number' ? measuredSize : this.options.estimateSize(i);
275
- const end = start + size;
276
- measurements[i] = {
277
- index: i,
278
- start,
279
- size,
280
- end,
281
- key
282
- };
283
- }
284
- this.measurementsCache = measurements;
285
- return measurements;
286
- }, {
287
- key: process.env.NODE_ENV !== 'production' && 'getMeasurements',
288
- debug: () => this.options.debug
166
+ }();
167
+ this.range = {
168
+ startIndex: 0,
169
+ endIndex: 0
170
+ };
171
+ this.setOptions = function (opts) {
172
+ Object.entries(opts).forEach(function (_ref3) {
173
+ var key = _ref3[0],
174
+ value = _ref3[1];
175
+ if (typeof value === 'undefined') delete opts[key];
289
176
  });
290
- this.calculateRange = memo(() => [this.getMeasurements(), this.getSize(), this.scrollOffset], (measurements, outerSize, scrollOffset) => {
291
- const range = calculateRange({
292
- measurements,
293
- outerSize,
294
- scrollOffset
295
- });
296
- if (range.startIndex !== this.range.startIndex || range.endIndex !== this.range.endIndex) {
297
- this.range = range;
298
- this.notify();
299
- }
300
- return this.range;
301
- }, {
302
- key: process.env.NODE_ENV !== 'production' && 'calculateRange',
303
- debug: () => this.options.debug
177
+ _this.options = _extends({
178
+ debug: false,
179
+ initialOffset: 0,
180
+ overscan: 1,
181
+ paddingStart: 0,
182
+ paddingEnd: 0,
183
+ scrollPaddingStart: 0,
184
+ scrollPaddingEnd: 0,
185
+ horizontal: false,
186
+ getItemKey: defaultKeyExtractor,
187
+ rangeExtractor: defaultRangeExtractor,
188
+ onChange: function onChange() {},
189
+ measureElement: measureElement,
190
+ initialRect: {
191
+ width: 0,
192
+ height: 0
193
+ },
194
+ scrollMargin: 0,
195
+ scrollingDelay: 150,
196
+ indexAttribute: 'data-index',
197
+ initialMeasurementsCache: []
198
+ }, opts);
199
+ };
200
+ this.notify = function () {
201
+ _this.options.onChange == null ? void 0 : _this.options.onChange(_this);
202
+ };
203
+ this.cleanup = function () {
204
+ _this.unsubs.filter(Boolean).forEach(function (d) {
205
+ return d();
304
206
  });
305
- this.getIndexes = memo(() => [this.options.rangeExtractor, this.range, this.options.overscan, this.options.count], (rangeExtractor, range, overscan, count) => {
306
- return rangeExtractor({
307
- ...range,
308
- overscan,
309
- count: count
310
- });
311
- }, {
312
- key: process.env.NODE_ENV !== 'production' && 'getIndexes',
313
- debug: () => this.options.debug
207
+ _this.unsubs = [];
208
+ _this.scrollElement = null;
209
+ };
210
+ this._didMount = function () {
211
+ var ro = _this.getResizeObserver();
212
+ Object.values(_this.measureElementCache).forEach(function (node) {
213
+ return ro == null ? void 0 : ro.observe(node);
314
214
  });
315
- this.indexFromElement = node => {
316
- const attributeName = this.options.indexAttribute;
317
- const indexStr = node.getAttribute(attributeName);
318
- if (!indexStr) {
319
- console.warn(`Missing attribute name '${attributeName}={index}' on measured element.`);
320
- return -1;
321
- }
322
- return parseInt(indexStr, 10);
215
+ return function () {
216
+ ro == null ? void 0 : ro.disconnect();
217
+ _this.cleanup();
323
218
  };
324
- this._measureElement = (node, _sync) => {
325
- const index = this.indexFromElement(node);
326
- const item = this.measurementsCache[index];
327
- if (!item) {
328
- return;
329
- }
330
- const prevNode = this.measureElementCache[item.key];
331
- const ro = this.getResizeObserver();
332
- if (!node.isConnected) {
333
- if (prevNode) {
334
- ro == null ? void 0 : ro.unobserve(prevNode);
335
- delete this.measureElementCache[item.key];
219
+ };
220
+ this._willUpdate = function () {
221
+ _this.pendingScrollToIndexCallback == null ? void 0 : _this.pendingScrollToIndexCallback();
222
+ var scrollElement = _this.options.getScrollElement();
223
+ if (_this.scrollElement !== scrollElement) {
224
+ _this.cleanup();
225
+ _this.scrollElement = scrollElement;
226
+ _this._scrollToOffset(_this.scrollOffset, {
227
+ adjustments: undefined,
228
+ behavior: undefined
229
+ });
230
+ _this.unsubs.push(_this.options.observeElementRect(_this, function (rect) {
231
+ _this.scrollRect = rect;
232
+ _this.calculateRange();
233
+ }));
234
+ _this.unsubs.push(_this.options.observeElementOffset(_this, function (offset) {
235
+ _this.scrollAdjustments = 0;
236
+ if (_this.scrollOffset === offset) {
237
+ return;
336
238
  }
337
- return;
338
- }
339
- if (!prevNode || prevNode !== node) {
340
- if (prevNode) {
341
- ro == null ? void 0 : ro.unobserve(prevNode);
239
+ if (_this.isScrollingTimeoutId !== null) {
240
+ clearTimeout(_this.isScrollingTimeoutId);
241
+ _this.isScrollingTimeoutId = null;
342
242
  }
343
- this.measureElementCache[item.key] = node;
344
- ro == null ? void 0 : ro.observe(node);
345
- }
346
- const measuredItemSize = this.options.measureElement(node, this);
347
- const itemSize = this.itemMeasurementsCache[item.key] ?? item.size;
348
- const delta = measuredItemSize - itemSize;
349
- if (delta !== 0) {
350
- if (item.start < this.scrollOffset && this.isScrolling) {
351
- if (process.env.NODE_ENV !== 'production' && this.options.debug) {
352
- console.info('correction', delta);
243
+ var onIsScrollingChange = function onIsScrollingChange(isScrolling) {
244
+ if (_this.isScrolling !== isScrolling) {
245
+ _this.isScrolling = isScrolling;
246
+ _this.notify();
353
247
  }
354
- this._scrollToOffset(this.scrollOffset, {
355
- adjustments: this.scrollAdjustments += delta,
356
- behavior: undefined,
357
- sync: false
358
- });
359
- }
360
- this.pendingMeasuredCacheIndexes.push(index);
361
- this.itemMeasurementsCache = {
362
- ...this.itemMeasurementsCache,
363
- [item.key]: measuredItemSize
364
248
  };
365
- this.notify();
366
- }
367
- };
368
- this.measureElement = node => {
369
- if (!node) {
370
- return;
249
+ _this.scrollDirection = _this.scrollOffset < offset ? 'forward' : 'backward';
250
+ _this.scrollOffset = offset;
251
+ _this.calculateRange();
252
+ onIsScrollingChange(true);
253
+ _this.isScrollingTimeoutId = setTimeout(function () {
254
+ _this.isScrollingTimeoutId = null;
255
+ _this.scrollDirection = null;
256
+ onIsScrollingChange(false);
257
+ }, _this.options.scrollingDelay);
258
+ }));
259
+ } else if (!_this.isScrolling) {
260
+ _this.calculateRange();
261
+ }
262
+ };
263
+ this.getSize = function () {
264
+ return _this.scrollRect[_this.options.horizontal ? 'width' : 'height'];
265
+ };
266
+ this.getMeasurements = memo(function () {
267
+ return [_this.options.count, _this.options.paddingStart, _this.options.scrollMargin, _this.options.getItemKey, _this.itemSizeCache];
268
+ }, function (count, paddingStart, scrollMargin, getItemKey, itemSizeCache) {
269
+ var min = _this.pendingMeasuredCacheIndexes.length > 0 ? Math.min.apply(Math, _this.pendingMeasuredCacheIndexes) : 0;
270
+ _this.pendingMeasuredCacheIndexes = [];
271
+ var measurements = _this.measurementsCache.slice(0, min);
272
+ for (var _i2 = min; _i2 < count; _i2++) {
273
+ var key = getItemKey(_i2);
274
+ var measuredSize = itemSizeCache[key];
275
+ var start = measurements[_i2 - 1] ? measurements[_i2 - 1].end : paddingStart + scrollMargin;
276
+ var size = typeof measuredSize === 'number' ? measuredSize : _this.options.estimateSize(_i2);
277
+ var end = start + size;
278
+ measurements[_i2] = {
279
+ index: _i2,
280
+ start: start,
281
+ size: size,
282
+ end: end,
283
+ key: key
284
+ };
285
+ }
286
+ _this.measurementsCache = measurements;
287
+ return measurements;
288
+ }, {
289
+ key: process.env.NODE_ENV !== 'production' && 'getMeasurements',
290
+ debug: function debug() {
291
+ return _this.options.debug;
292
+ }
293
+ });
294
+ this.calculateRange = memo(function () {
295
+ return [_this.getMeasurements(), _this.getSize(), _this.scrollOffset];
296
+ }, function (measurements, outerSize, scrollOffset) {
297
+ var range = calculateRange({
298
+ measurements: measurements,
299
+ outerSize: outerSize,
300
+ scrollOffset: scrollOffset
301
+ });
302
+ if (range.startIndex !== _this.range.startIndex || range.endIndex !== _this.range.endIndex) {
303
+ _this.range = range;
304
+ _this.notify();
305
+ }
306
+ return _this.range;
307
+ }, {
308
+ key: process.env.NODE_ENV !== 'production' && 'calculateRange',
309
+ debug: function debug() {
310
+ return _this.options.debug;
311
+ }
312
+ });
313
+ this.getIndexes = memo(function () {
314
+ return [_this.options.rangeExtractor, _this.range, _this.options.overscan, _this.options.count];
315
+ }, function (rangeExtractor, range, overscan, count) {
316
+ return rangeExtractor(_extends({}, range, {
317
+ overscan: overscan,
318
+ count: count
319
+ }));
320
+ }, {
321
+ key: process.env.NODE_ENV !== 'production' && 'getIndexes',
322
+ debug: function debug() {
323
+ return _this.options.debug;
324
+ }
325
+ });
326
+ this.indexFromElement = function (node) {
327
+ var attributeName = _this.options.indexAttribute;
328
+ var indexStr = node.getAttribute(attributeName);
329
+ if (!indexStr) {
330
+ console.warn("Missing attribute name '" + attributeName + "={index}' on measured element.");
331
+ return -1;
332
+ }
333
+ return parseInt(indexStr, 10);
334
+ };
335
+ this._measureElement = function (node, _sync) {
336
+ var _this$itemSizeCache$i;
337
+ var index = _this.indexFromElement(node);
338
+ var item = _this.measurementsCache[index];
339
+ if (!item) {
340
+ return;
341
+ }
342
+ var prevNode = _this.measureElementCache[item.key];
343
+ var ro = _this.getResizeObserver();
344
+ if (!node.isConnected) {
345
+ if (prevNode) {
346
+ ro == null ? void 0 : ro.unobserve(prevNode);
347
+ delete _this.measureElementCache[item.key];
371
348
  }
372
- this._measureElement(node, true);
373
- };
374
- this.getVirtualItems = memo(() => [this.getIndexes(), this.getMeasurements()], (indexes, measurements) => {
375
- const virtualItems = [];
376
- for (let k = 0, len = indexes.length; k < len; k++) {
377
- const i = indexes[k];
378
- const measurement = measurements[i];
379
- virtualItems.push(measurement);
349
+ return;
350
+ }
351
+ if (!prevNode || prevNode !== node) {
352
+ if (prevNode) {
353
+ ro == null ? void 0 : ro.unobserve(prevNode);
380
354
  }
381
- return virtualItems;
382
- }, {
383
- key: process.env.NODE_ENV !== 'production' && 'getIndexes',
384
- debug: () => this.options.debug
385
- });
386
- this.scrollToOffset = function (toOffset, _temp) {
387
- let {
388
- align = 'start',
389
- behavior
390
- } = _temp === void 0 ? {} : _temp;
391
- const offset = _this.scrollOffset;
392
- const size = _this.getSize();
393
- if (align === 'auto') {
394
- if (toOffset <= offset) {
395
- align = 'start';
396
- } else if (toOffset >= offset + size) {
397
- align = 'end';
398
- } else {
399
- align = 'start';
355
+ _this.measureElementCache[item.key] = node;
356
+ ro == null ? void 0 : ro.observe(node);
357
+ }
358
+ var measuredItemSize = _this.options.measureElement(node, _this);
359
+ var itemSize = (_this$itemSizeCache$i = _this.itemSizeCache[item.key]) != null ? _this$itemSizeCache$i : item.size;
360
+ var delta = measuredItemSize - itemSize;
361
+ if (delta !== 0) {
362
+ var _extends2;
363
+ if (item.start < _this.scrollOffset && _this.isScrolling && _this.scrollDirection === 'backward') {
364
+ if (process.env.NODE_ENV !== 'production' && _this.options.debug) {
365
+ console.info('correction', delta);
400
366
  }
367
+ _this._scrollToOffset(_this.scrollOffset, {
368
+ adjustments: _this.scrollAdjustments += delta,
369
+ behavior: undefined
370
+ });
401
371
  }
402
- const options = {
403
- adjustments: undefined,
404
- behavior,
405
- sync: false
406
- };
407
- if (align === 'start') {
408
- _this._scrollToOffset(toOffset, options);
409
- } else if (align === 'end') {
410
- _this._scrollToOffset(toOffset - size, options);
411
- } else if (align === 'center') {
412
- _this._scrollToOffset(toOffset - size / 2, options);
372
+ _this.pendingMeasuredCacheIndexes.push(index);
373
+ _this.itemSizeCache = _extends({}, _this.itemSizeCache, (_extends2 = {}, _extends2[item.key] = measuredItemSize, _extends2));
374
+ _this.notify();
375
+ }
376
+ };
377
+ this.measureElement = function (node) {
378
+ if (!node) {
379
+ return;
380
+ }
381
+ _this._measureElement(node, true);
382
+ };
383
+ this.getVirtualItems = memo(function () {
384
+ return [_this.getIndexes(), _this.getMeasurements()];
385
+ }, function (indexes, measurements) {
386
+ var virtualItems = [];
387
+ for (var k = 0, len = indexes.length; k < len; k++) {
388
+ var _i3 = indexes[k];
389
+ var measurement = measurements[_i3];
390
+ virtualItems.push(measurement);
391
+ }
392
+ return virtualItems;
393
+ }, {
394
+ key: process.env.NODE_ENV !== 'production' && 'getIndexes',
395
+ debug: function debug() {
396
+ return _this.options.debug;
397
+ }
398
+ });
399
+ this.getOffsetForAlignment = function (toOffset, align) {
400
+ var offset = _this.scrollOffset;
401
+ var size = _this.getSize();
402
+ if (align === 'auto') {
403
+ if (toOffset <= offset) {
404
+ align = 'start';
405
+ } else if (toOffset >= offset + size) {
406
+ align = 'end';
407
+ } else {
408
+ align = 'start';
413
409
  }
410
+ }
411
+ if (align === 'start') {
412
+ return toOffset;
413
+ } else if (align === 'end') {
414
+ return toOffset - size;
415
+ } else if (align === 'center') {
416
+ return toOffset - size / 2;
417
+ }
418
+ return toOffset;
419
+ };
420
+ this.scrollToOffset = function (toOffset, _temp) {
421
+ var _ref4 = _temp === void 0 ? {} : _temp,
422
+ _ref4$align = _ref4.align,
423
+ align = _ref4$align === void 0 ? 'start' : _ref4$align,
424
+ behavior = _ref4.behavior;
425
+ var options = {
426
+ adjustments: undefined,
427
+ behavior: behavior,
428
+ sync: false
414
429
  };
415
- this.scrollToIndex = function (index, _temp2) {
416
- let {
417
- align = 'auto',
418
- ...rest
419
- } = _temp2 === void 0 ? {} : _temp2;
420
- _this.pendingScrollToIndexCallback = null;
421
- const measurements = _this.getMeasurements();
422
- const offset = _this.scrollOffset;
423
- const size = _this.getSize();
424
- const {
425
- count
426
- } = _this.options;
427
- const measurement = measurements[Math.max(0, Math.min(index, count - 1))];
428
- if (!measurement) {
430
+ _this._scrollToOffset(_this.getOffsetForAlignment(toOffset, align), options);
431
+ };
432
+ this.scrollToIndex = function (index, _temp2) {
433
+ var _ref5 = _temp2 === void 0 ? {} : _temp2,
434
+ _ref5$align = _ref5.align,
435
+ align = _ref5$align === void 0 ? 'auto' : _ref5$align,
436
+ behavior = _ref5.behavior;
437
+ _this.pendingScrollToIndexCallback = null;
438
+ var offset = _this.scrollOffset;
439
+ var size = _this.getSize();
440
+ var count = _this.options.count;
441
+ var measurements = _this.getMeasurements();
442
+ var measurement = measurements[Math.max(0, Math.min(index, count - 1))];
443
+ if (!measurement) {
444
+ throw new Error("VirtualItem not found for index = " + index);
445
+ }
446
+ if (align === 'auto') {
447
+ if (measurement.end >= offset + size - _this.options.scrollPaddingEnd) {
448
+ align = 'end';
449
+ } else if (measurement.start <= offset + _this.options.scrollPaddingStart) {
450
+ align = 'start';
451
+ } else {
429
452
  return;
430
453
  }
431
- if (align === 'auto') {
432
- if (measurement.end >= offset + size - _this.options.scrollPaddingEnd) {
433
- align = 'end';
434
- } else if (measurement.start <= offset + _this.options.scrollPaddingStart) {
435
- align = 'start';
436
- } else {
437
- return;
438
- }
439
- }
440
- const toOffset = align === 'end' ? measurement.end + _this.options.scrollPaddingEnd : measurement.start - _this.options.scrollPaddingStart;
441
- _this.scrollToOffset(toOffset, {
442
- align,
443
- ...rest
444
- });
445
- const isDynamic = Object.keys(_this.measureElementCache).length > 0;
446
- if (isDynamic) {
447
- const didSeen = () => typeof _this.itemMeasurementsCache[_this.options.getItemKey(index)] === 'number';
448
- if (!didSeen()) {
449
- _this.pendingScrollToIndexCallback = () => {
450
- if (didSeen()) {
451
- _this.pendingScrollToIndexCallback = null;
452
- _this.scrollToIndex(index, {
453
- align,
454
- ...rest
455
- });
456
- }
457
- };
458
- }
459
- }
460
- };
461
- this.getTotalSize = () => {
462
- var _this$getMeasurements;
463
- return (((_this$getMeasurements = this.getMeasurements()[this.options.count - 1]) == null ? void 0 : _this$getMeasurements.end) || this.options.paddingStart) + this.options.paddingEnd;
464
- };
465
- this._scrollToOffset = (offset, _ref4) => {
466
- let {
467
- adjustments,
468
- behavior,
469
- sync
470
- } = _ref4;
471
- this.options.scrollToFn(offset, {
472
- behavior,
473
- sync,
474
- adjustments
475
- }, this);
454
+ }
455
+ var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(measurement) {
456
+ var toOffset = align === 'end' ? measurement.end + _this.options.scrollPaddingEnd : measurement.start - _this.options.scrollPaddingStart;
457
+ return _this.getOffsetForAlignment(toOffset, align);
476
458
  };
477
- this.measure = () => {
478
- this.itemMeasurementsCache = {};
479
- this.notify();
459
+ var toOffset = getOffsetForIndexAndAlignment(measurement);
460
+ if (toOffset === offset) {
461
+ return;
462
+ }
463
+ var options = {
464
+ adjustments: undefined,
465
+ behavior: behavior
480
466
  };
481
- this.setOptions(_opts);
482
- this.scrollRect = this.options.initialRect;
483
- this.scrollOffset = this.options.initialOffset;
484
- this.calculateRange();
485
- }
486
- }
487
- const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
467
+ _this._scrollToOffset(toOffset, options);
468
+ var isDynamic = Object.keys(_this.measureElementCache).length > 0;
469
+ if (isDynamic) {
470
+ _this.pendingScrollToIndexCallback = function () {
471
+ _this.scrollToIndex(index, {
472
+ align: align,
473
+ behavior: behavior
474
+ });
475
+ };
476
+ }
477
+ };
478
+ this.scrollBy = function (adjustments, options) {
479
+ _this._scrollToOffset(_this.scrollOffset, {
480
+ adjustments: adjustments,
481
+ behavior: options == null ? void 0 : options.behavior
482
+ });
483
+ };
484
+ this.getTotalSize = function () {
485
+ var _this$getMeasurements;
486
+ return (((_this$getMeasurements = _this.getMeasurements()[_this.options.count - 1]) == null ? void 0 : _this$getMeasurements.end) || _this.options.paddingStart) - _this.options.scrollMargin + _this.options.paddingEnd;
487
+ };
488
+ this._scrollToOffset = function (offset, _ref6) {
489
+ var adjustments = _ref6.adjustments,
490
+ behavior = _ref6.behavior;
491
+ _this.options.scrollToFn(offset, {
492
+ behavior: behavior,
493
+ adjustments: adjustments
494
+ }, _this);
495
+ };
496
+ this.measure = function () {
497
+ _this.itemSizeCache = {};
498
+ _this.notify();
499
+ };
500
+ this.setOptions(_opts);
501
+ this.scrollRect = this.options.initialRect;
502
+ this.scrollOffset = this.options.initialOffset;
503
+ this.measurementsCache = this.options.initialMeasurementsCache;
504
+ this.measurementsCache.forEach(function (item) {
505
+ _this.itemSizeCache[item.key] = item.size;
506
+ });
507
+ this.calculateRange();
508
+ };
509
+ var findNearestBinarySearch = function findNearestBinarySearch(low, high, getCurrentValue, value) {
488
510
  while (low <= high) {
489
- const middle = (low + high) / 2 | 0;
490
- const currentValue = getCurrentValue(middle);
511
+ var middle = (low + high) / 2 | 0;
512
+ var currentValue = getCurrentValue(middle);
491
513
  if (currentValue < value) {
492
514
  low = middle + 1;
493
515
  } else if (currentValue > value) {
@@ -502,22 +524,22 @@ const findNearestBinarySearch = (low, high, getCurrentValue, value) => {
502
524
  return 0;
503
525
  }
504
526
  };
505
- function calculateRange(_ref5) {
506
- let {
507
- measurements,
508
- outerSize,
509
- scrollOffset
510
- } = _ref5;
511
- const count = measurements.length - 1;
512
- const getOffset = index => measurements[index].start;
513
- const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset);
514
- let endIndex = startIndex;
527
+ function calculateRange(_ref7) {
528
+ var measurements = _ref7.measurements,
529
+ outerSize = _ref7.outerSize,
530
+ scrollOffset = _ref7.scrollOffset;
531
+ var count = measurements.length - 1;
532
+ var getOffset = function getOffset(index) {
533
+ return measurements[index].start;
534
+ };
535
+ var startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset);
536
+ var endIndex = startIndex;
515
537
  while (endIndex < count && measurements[endIndex].end < scrollOffset + outerSize) {
516
538
  endIndex++;
517
539
  }
518
540
  return {
519
- startIndex,
520
- endIndex
541
+ startIndex: startIndex,
542
+ endIndex: endIndex
521
543
  };
522
544
  }
523
545