virtua 0.52.7 → 0.52.8

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.
@@ -60,8 +60,7 @@ var UPDATE_SCROLL_END_EVENT = 8;
60
60
  var getScrollSize = (store) => {
61
61
  return max(store.$getTotalSize(), store.$getViewportSize());
62
62
  };
63
- var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItemOffset: getOffset, $getItemSize: getItemSize, $setItemSize: setItemSize, $isSizeEqual: isSizeEqual, $getTotalSize: getTotalSize, $getLength: getLength, $setLength: setLength, $estimateDefaultSize: estimateDefaultSize }, ssrCount = 0) => {
64
- let shouldAutoEstimateItemSize = !!estimateDefaultSize;
63
+ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItemOffset: getOffset, $getItemSize: getItemSize, $isSizeEqual: isSizeEqual, $getTotalSize: getTotalSize, $getLength: getLength, $setLength: setLength, $isEstimating: isEstimating, $resize: resize, $relayout: relayout }, ssrCount = 0) => {
65
64
  let isSSR = !!ssrCount;
66
65
  let stateVersion = 1;
67
66
  let viewportSize = 0;
@@ -74,7 +73,6 @@ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItem
74
73
  let _scrollMode = SCROLL_BY_NATIVE;
75
74
  let _frozenRange = null;
76
75
  let _prevRange = [0, isSSR ? max(ssrCount - 1, 0) : -1];
77
- let _totalMeasuredSize = 0;
78
76
  let _isViewportMeasured = false;
79
77
  const subscribers = new Set();
80
78
  const getRelativeScrollOffset = () => scrollOffset - startSpacerSize;
@@ -82,6 +80,18 @@ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItem
82
80
  const getItemOffset = (index) => {
83
81
  return getOffset(index) - pendingJump;
84
82
  };
83
+ const shouldKeep = (index) => {
84
+ if (_scrollMode === SCROLL_BY_SHIFT) {
85
+ return true;
86
+ }
87
+ if (_frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL) {
88
+ return index < _frozenRange[0];
89
+ }
90
+ const start = getRelativeScrollOffset();
91
+ const itemOffset = getItemOffset(index);
92
+ const itemSize = getItemSize(index);
93
+ return _scrollDirection !== SCROLL_DOWN && _scrollMode === SCROLL_BY_NATIVE ? itemOffset + itemSize <= start : itemOffset < start && itemOffset + itemSize < start + viewportSize;
94
+ };
85
95
  const applyJump = (j) => {
86
96
  if (j) {
87
97
  if (isIOSWebKit() && _scrollDirection !== SCROLL_IDLE || _frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL) {
@@ -107,7 +117,7 @@ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItem
107
117
  } else {
108
118
  let startOffset = max(0, getVisibleOffset());
109
119
  let endOffset = startOffset + viewportSize;
110
- if (!shouldAutoEstimateItemSize) {
120
+ if (!isEstimating()) {
111
121
  bufferSize = max(0, bufferSize);
112
122
  if (_scrollDirection !== SCROLL_DOWN) {
113
123
  startOffset -= bufferSize;
@@ -191,34 +201,7 @@ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItem
191
201
  if (!updated.length) {
192
202
  break;
193
203
  }
194
- applyJump(updated.reduce((acc, [index, size]) => {
195
- let shouldKeep;
196
- if (_scrollMode === SCROLL_BY_SHIFT) {
197
- shouldKeep = true;
198
- } else if (_frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL) {
199
- shouldKeep = index < _frozenRange[0];
200
- } else {
201
- const start = getRelativeScrollOffset();
202
- const itemOffset = getItemOffset(index);
203
- const itemSize = getItemSize(index);
204
- shouldKeep = _scrollDirection !== SCROLL_DOWN && _scrollMode === SCROLL_BY_NATIVE ? itemOffset + itemSize <= start : itemOffset < start && itemOffset + itemSize < start + viewportSize;
205
- }
206
- if (shouldKeep) {
207
- acc += size - getItemSize(index);
208
- }
209
- return acc;
210
- }, 0));
211
- for (const [index, size] of updated) {
212
- const prevSize = getItemSize(index);
213
- const isInitialMeasurement = setItemSize(index, size);
214
- if (shouldAutoEstimateItemSize) {
215
- _totalMeasuredSize += isInitialMeasurement ? size : size - prevSize;
216
- }
217
- }
218
- if (shouldAutoEstimateItemSize && viewportSize && _totalMeasuredSize > viewportSize) {
219
- applyJump(estimateDefaultSize(findIndex(getVisibleOffset())));
220
- shouldAutoEstimateItemSize = false;
221
- }
204
+ applyJump(resize(updated, shouldKeep, getVisibleOffset(), viewportSize));
222
205
  mutated = 1 + 2;
223
206
  shouldSync = true;
224
207
  break;
@@ -253,8 +236,11 @@ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItem
253
236
  break;
254
237
  }
255
238
  case 9: {
256
- applyJump(payload);
257
- mutated = 1 + 2;
239
+ const relayoutJump = relayout(payload, getVisibleOffset());
240
+ if (relayoutJump != null) {
241
+ applyJump(relayoutJump);
242
+ mutated = 1 + 2;
243
+ }
258
244
  break;
259
245
  }
260
246
  case 8: {
@@ -309,6 +295,8 @@ var findIndex = (getOffset, length, offset, low = 0, high = length - 1) => {
309
295
  var createListLayout = (length, itemSize, snapshot) => {
310
296
  let defaultItemSize = snapshot && snapshot[1] || itemSize || 40;
311
297
  let computedOffsetIndex = -1;
298
+ let _totalMeasuredSize = 0;
299
+ let shouldAutoEstimateItemSize = !itemSize;
312
300
  let prevStartIndex = 0;
313
301
  const restoredSizes = snapshot && snapshot[0];
314
302
  const sizes = restoredSizes ? fill(restoredSizes.slice(0, min(length, restoredSizes.length)), max(0, length - restoredSizes.length)) : fill([], length);
@@ -353,13 +341,39 @@ var createListLayout = (length, itemSize, snapshot) => {
353
341
  $findIndex: (offset) => findIndex(getOffset, length, offset),
354
342
  $getItemOffset: getOffset,
355
343
  $getItemSize: getSize,
356
- $setItemSize: (index, size) => {
357
- const isInitialMeasurement = sizes[index] === -1;
358
- sizes[index] = size;
359
- computedOffsetIndex = min(index, computedOffsetIndex);
360
- return isInitialMeasurement;
361
- },
362
344
  $isSizeEqual: (index, size = -1) => sizes[index] === size,
345
+ $resize: (resizes, shouldKeep, scrollOffset, viewportSize) => {
346
+ let jump = resizes.reduce((acc, [index, size]) => shouldKeep(index) ? acc + (size - getSize(index)) : acc, 0);
347
+ for (const [index, size] of resizes) {
348
+ _totalMeasuredSize += sizes[index] === -1 ? size : size - getSize(index);
349
+ sizes[index] = size;
350
+ computedOffsetIndex = min(index, computedOffsetIndex);
351
+ }
352
+ if (shouldAutoEstimateItemSize && viewportSize && _totalMeasuredSize > viewportSize) {
353
+ let measuredCountBeforeStart = 0;
354
+ const startIndex = findIndex(getOffset, length, scrollOffset + jump);
355
+ const measuredSizes = [];
356
+ sizes.forEach((s, i) => {
357
+ if (s !== -1) {
358
+ if (s) {
359
+ measuredSizes.push(s);
360
+ }
361
+ if (i < startIndex) {
362
+ measuredCountBeforeStart++;
363
+ }
364
+ }
365
+ });
366
+ computedOffsetIndex = -1;
367
+ sort(measuredSizes);
368
+ const len = measuredSizes.length;
369
+ const mid = len / 2 | 0;
370
+ const median = len % 2 === 0 ? (measuredSizes[mid - 1] + measuredSizes[mid]) / 2 : measuredSizes[mid];
371
+ const prevDefaultItemSize = defaultItemSize;
372
+ jump += ((defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
373
+ shouldAutoEstimateItemSize = false;
374
+ }
375
+ return jump;
376
+ },
363
377
  $getTotalSize: () => getOffset(length),
364
378
  $getLength: () => length,
365
379
  $setLength: (nextLength, isShift) => {
@@ -375,27 +389,7 @@ var createListLayout = (length, itemSize, snapshot) => {
375
389
  return (isShift ? sizes.splice(0, -diff) : sizes.splice(diff)).reduce((acc, removed) => acc - (removed === -1 ? defaultItemSize : removed), 0);
376
390
  }
377
391
  },
378
- $estimateDefaultSize: itemSize ? undefined : (startIndex) => {
379
- let measuredCountBeforeStart = 0;
380
- const measuredSizes = [];
381
- sizes.forEach((s, i) => {
382
- if (s !== -1) {
383
- if (s) {
384
- measuredSizes.push(s);
385
- }
386
- if (i < startIndex) {
387
- measuredCountBeforeStart++;
388
- }
389
- }
390
- });
391
- computedOffsetIndex = -1;
392
- sort(measuredSizes);
393
- const len = measuredSizes.length;
394
- const mid = len / 2 | 0;
395
- const median = len % 2 === 0 ? (measuredSizes[mid - 1] + measuredSizes[mid]) / 2 : measuredSizes[mid];
396
- const prevDefaultItemSize = defaultItemSize;
397
- return ((defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
398
- },
392
+ $isEstimating: () => shouldAutoEstimateItemSize,
399
393
  $snapshot: () => [sizes.slice(), defaultItemSize]
400
394
  };
401
395
  };
@@ -410,6 +404,8 @@ var createGridLayout = (axis, size, gap = 0) => {
410
404
  const isAuto = size === "auto";
411
405
  let defaultItemSize = (isUniform ? size : 40) + gap;
412
406
  let computedOffsetIndex = -1;
407
+ let _totalMeasuredSize = 0;
408
+ let shouldAutoEstimateItemSize = isAuto;
413
409
  let header = 0;
414
410
  let footer = 0;
415
411
  let currentSizes = null;
@@ -454,6 +450,7 @@ var createGridLayout = (axis, size, gap = 0) => {
454
450
  const find = (offset) => sizes.length ? findIndex(getOffset, length, offset) : defaultItemSize ? clamp(floor(offset / defaultItemSize), 0, length - 1) : 0;
455
451
  const getPinnedStart = () => min(header, length);
456
452
  const getTrailStart = () => max(length - footer, getPinnedStart());
453
+ const getItemSize = (index) => (sizes.length ? getSize(index) : defaultItemSize) - gap;
457
454
  return {
458
455
  $getRange: (startOffset, endOffset) => {
459
456
  const insetStart = getOffset(getPinnedStart());
@@ -463,17 +460,45 @@ var createGridLayout = (axis, size, gap = 0) => {
463
460
  },
464
461
  $findIndex: find,
465
462
  $getItemOffset: getOffset,
466
- $getItemSize: (index) => (sizes.length ? getSize(index) : defaultItemSize) - gap,
467
- $setItemSize: (index, size) => {
468
- if (!isMeasurable(index)) {
469
- return false;
463
+ $getItemSize: getItemSize,
464
+ $resize: (resizes, shouldKeep, scrollOffset, viewportSize) => {
465
+ let jump = resizes.reduce((acc, [index, size]) => isMeasurable(index) && shouldKeep(index) ? acc + (size - getItemSize(index)) : acc, 0);
466
+ for (const [index, size] of resizes) {
467
+ if (isMeasurable(index)) {
468
+ materialize();
469
+ _totalMeasuredSize += sizes[index] === -1 ? size : size - getItemSize(index);
470
+ setSize(index, size + gap);
471
+ }
470
472
  }
471
- materialize();
472
- const isInitialMeasurement = sizes[index] === -1;
473
- setSize(index, size + gap);
474
- return isInitialMeasurement;
473
+ if (shouldAutoEstimateItemSize && viewportSize && _totalMeasuredSize > viewportSize) {
474
+ let measuredCountBeforeStart = 0;
475
+ const startIndex = find(scrollOffset + jump);
476
+ const measuredSizes = [];
477
+ sizes.forEach((s, i) => {
478
+ if (s !== -1) {
479
+ if (s) {
480
+ measuredSizes.push(s);
481
+ }
482
+ if (i < startIndex) {
483
+ measuredCountBeforeStart++;
484
+ }
485
+ }
486
+ });
487
+ computedOffsetIndex = -1;
488
+ sort(measuredSizes);
489
+ const len = measuredSizes.length;
490
+ const mid = len / 2 | 0;
491
+ const median = len % 2 === 0 ? (measuredSizes[mid - 1] + measuredSizes[mid]) / 2 : measuredSizes[mid];
492
+ const prevDefaultItemSize = defaultItemSize;
493
+ jump += ((defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
494
+ shouldAutoEstimateItemSize = false;
495
+ }
496
+ return jump;
497
+ },
498
+ $isSizeEqual: (index, size = -1) => {
499
+ const cachedSize = sizes.length ? sizes[index] : -1;
500
+ return size === -1 ? isMeasurable(index) && cachedSize === -1 : cachedSize === size + gap;
475
501
  },
476
- $isSizeEqual: (index, size) => (sizes.length ? sizes[index] : -1) === size + gap,
477
502
  $getTotalSize: () => length ? getOffset(length) - gap : 0,
478
503
  $getLength: () => length,
479
504
  $setLength: (nextLength) => {
@@ -489,27 +514,7 @@ var createGridLayout = (axis, size, gap = 0) => {
489
514
  }
490
515
  return 0;
491
516
  },
492
- $estimateDefaultSize: isAuto ? (startIndex) => {
493
- let measuredCountBeforeStart = 0;
494
- const measuredSizes = [];
495
- sizes.forEach((s, i) => {
496
- if (s !== -1) {
497
- if (s) {
498
- measuredSizes.push(s);
499
- }
500
- if (i < startIndex) {
501
- measuredCountBeforeStart++;
502
- }
503
- }
504
- });
505
- computedOffsetIndex = -1;
506
- sort(measuredSizes);
507
- const len = measuredSizes.length;
508
- const mid = len / 2 | 0;
509
- const median = len % 2 === 0 ? (measuredSizes[mid - 1] + measuredSizes[mid]) / 2 : measuredSizes[mid];
510
- const prevDefaultItemSize = defaultItemSize;
511
- return ((defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
512
- } : undefined,
517
+ $isEstimating: () => shouldAutoEstimateItemSize,
513
518
  $isMeasurable: isMeasurable,
514
519
  $setPinned: (nextHeader = 0, nextFooter = 0) => {
515
520
  header = nextHeader;
@@ -518,7 +523,7 @@ var createGridLayout = (axis, size, gap = 0) => {
518
523
  $getPinnedStart: getPinnedStart,
519
524
  $getTrailStart: getTrailStart,
520
525
  $getSizes: (nextAxis, nextSize) => typeof nextSize === "number" ? isUniform ? nextSize : null : isUniform || isAuto || nextSize === "auto" ? null : nextAxis.map((item) => item != null ? item[nextSize] : null),
521
- $setAxis: (nextSizes, scrollOffset) => {
526
+ $relayout: (nextSizes, scrollOffset) => {
522
527
  if (nextSizes == null) {
523
528
  return;
524
529
  }
@@ -562,17 +567,6 @@ var createGridLayout = (axis, size, gap = 0) => {
562
567
 
563
568
  //#endregion
564
569
  //#region src/core/grid.ts
565
- var updateGridAxis = (store, layout, axis, sizes, header, footer) => {
566
- const length = getAxisLength(axis);
567
- layout.$setPinned(header, footer);
568
- if (length !== store.$getItemsLength()) {
569
- store.$update(5, [length]);
570
- }
571
- const jump = layout.$setAxis(sizes, store.$getScrollOffset() - store.$getItemOffset(0));
572
- if (jump != null) {
573
- store.$update(9, jump);
574
- }
575
- };
576
570
  var rowStatesCache = /*#__PURE__*/ new WeakMap();
577
571
  var createGridSpanIndex = (spans = EMPTY) => {
578
572
  const index = new Map();
@@ -1008,9 +1002,11 @@ var createScrollObserver = (store, viewport, scroller, isHorizontal, isRtl, onMo
1008
1002
  onMomentumJump();
1009
1003
  }
1010
1004
  stillMomentumScrolling = false;
1011
- const target = store.$getScrollOffset() + jump;
1012
- if (target <= 0 || target >= store.$getStartSpacerSize() + store.$getTotalSize() - store.$getViewportSize()) {
1013
- scrollTo(target);
1005
+ const from = store.$getScrollOffset();
1006
+ const to = from + jump;
1007
+ const end = store.$getStartSpacerSize() + store.$getTotalSize() - store.$getViewportSize();
1008
+ if (to <= 0 || to >= end || from >= end) {
1009
+ scrollTo(to);
1014
1010
  } else {
1015
1011
  scroller.scrollBy({
1016
1012
  [scrollToKey]: normalizeScrollOffset(jump),
@@ -1807,10 +1803,18 @@ var VGrid = (props) => {
1807
1803
  rowStore.$subscribe(8, notifyScrollEnd);
1808
1804
  colStore.$subscribe(8, notifyScrollEnd);
1809
1805
  createComputed(() => {
1810
- updateGridAxis(rowStore, rowLayout, props.rows, rowSizes(), props.headerRows, props.footerRows);
1811
- });
1812
- createComputed(() => {
1813
- updateGridAxis(colStore, colLayout, props.cols, colSizes(), props.headerCols, props.footerCols);
1806
+ rowLayout.$setPinned(props.headerRows, props.footerRows);
1807
+ colLayout.$setPinned(props.headerCols, props.footerCols);
1808
+ const rowLength = getAxisLength(props.rows);
1809
+ const colLength = getAxisLength(props.cols);
1810
+ if (rowLength !== rowStore.$getItemsLength()) {
1811
+ rowStore.$update(5, [rowLength]);
1812
+ }
1813
+ if (colLength !== colStore.$getItemsLength()) {
1814
+ colStore.$update(5, [colLength]);
1815
+ }
1816
+ rowStore.$update(9, rowSizes());
1817
+ colStore.$update(9, colSizes());
1814
1818
  });
1815
1819
  const rowCount = createMemo(() => stateVersion() && rowStore.$getItemsLength());
1816
1820
  const colCount = createMemo(() => stateVersion() && colStore.$getItemsLength());