@legendapp/list 3.0.0-beta.47 → 3.0.0-beta.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -236,6 +236,7 @@ interface InternalState$1 {
236
236
  dataChanged?: boolean;
237
237
  forceFullItemPositions?: boolean;
238
238
  }) => void;
239
+ userScrollAnchorResetKeys?: Set<string>;
239
240
  viewabilityConfigCallbackPairs: ViewabilityConfigCallbackPairs$1<any> | undefined;
240
241
  props: {
241
242
  alignItemsAtEnd: boolean;
package/index.js CHANGED
@@ -2080,7 +2080,7 @@ function getId(state, index) {
2080
2080
  }
2081
2081
 
2082
2082
  // src/core/addTotalSize.ts
2083
- function addTotalSize(ctx, key, add) {
2083
+ function addTotalSize(ctx, key, add, notifyTotalSize = true) {
2084
2084
  const state = ctx.state;
2085
2085
  const prevTotalSize = state.totalSize;
2086
2086
  let totalSize = state.totalSize;
@@ -2097,25 +2097,29 @@ function addTotalSize(ctx, key, add) {
2097
2097
  {
2098
2098
  state.pendingTotalSize = void 0;
2099
2099
  state.totalSize = totalSize;
2100
- set$(ctx, "totalSize", totalSize);
2100
+ if (notifyTotalSize) {
2101
+ set$(ctx, "totalSize", totalSize);
2102
+ }
2101
2103
  }
2104
+ } else if (notifyTotalSize && ctx.values.get("totalSize") !== totalSize) {
2105
+ set$(ctx, "totalSize", totalSize);
2102
2106
  }
2103
2107
  }
2104
2108
 
2105
2109
  // src/core/setSize.ts
2106
- function setSize(ctx, itemKey, size) {
2110
+ function setSize(ctx, itemKey, size, notifyTotalSize = true) {
2107
2111
  const state = ctx.state;
2108
2112
  const { sizes } = state;
2109
2113
  const previousSize = sizes.get(itemKey);
2110
2114
  const diff = previousSize !== void 0 ? size - previousSize : size;
2111
2115
  if (diff !== 0) {
2112
- addTotalSize(ctx, itemKey, diff);
2116
+ addTotalSize(ctx, itemKey, diff, notifyTotalSize);
2113
2117
  }
2114
2118
  sizes.set(itemKey, size);
2115
2119
  }
2116
2120
 
2117
2121
  // src/utils/getItemSize.ts
2118
- function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
2122
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, notifyTotalSize) {
2119
2123
  var _a3, _b, _c;
2120
2124
  const state = ctx.state;
2121
2125
  const {
@@ -2161,7 +2165,7 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
2161
2165
  if (size === void 0) {
2162
2166
  size = getEstimatedItemSize ? getEstimatedItemSize(data, index, itemType) : estimatedItemSize;
2163
2167
  }
2164
- setSize(ctx, key, size);
2168
+ setSize(ctx, key, size, notifyTotalSize);
2165
2169
  return size;
2166
2170
  }
2167
2171
  function getItemSizeAtIndex(ctx, index) {
@@ -2600,10 +2604,10 @@ function getMountedBufferedIndices(state) {
2600
2604
  function getMountedNoBufferIndices(state) {
2601
2605
  return getMountedIndicesInRange(state, state.startNoBuffer, state.endNoBuffer);
2602
2606
  }
2603
- function checkAllSizesKnown(state, indices = getMountedBufferedIndices(state)) {
2607
+ function checkAllSizesKnown(state, indices) {
2604
2608
  return indices.length > 0 && indices.every((index) => {
2605
2609
  const key = getId(state, index);
2606
- return state.sizesKnown.has(key);
2610
+ return key !== void 0 && state.sizesKnown.has(key);
2607
2611
  });
2608
2612
  }
2609
2613
 
@@ -3913,6 +3917,7 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
3913
3917
  const maxVisibleArea = scrollBottomBuffered + 1e3;
3914
3918
  const useAverageSize = !getEstimatedItemSize;
3915
3919
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_b = peek$(ctx, "scrollAdjustPending")) != null ? _b : 0) !== 0;
3920
+ const notifyTotalSizeWhileCachingSizes = false;
3916
3921
  let currentRowTop = 0;
3917
3922
  let column = 1;
3918
3923
  let maxSizeInRow = 0;
@@ -3940,7 +3945,15 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
3940
3945
  const prevIndex = startIndex - 1;
3941
3946
  const prevId = getId(state, prevIndex);
3942
3947
  const prevPosition = (_c = positions[prevIndex]) != null ? _c : 0;
3943
- const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
3948
+ const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(
3949
+ ctx,
3950
+ prevId,
3951
+ prevIndex,
3952
+ data[prevIndex],
3953
+ useAverageSize,
3954
+ preferCachedSize,
3955
+ notifyTotalSizeWhileCachingSizes
3956
+ );
3944
3957
  currentRowTop = prevPosition + prevSize;
3945
3958
  }
3946
3959
  }
@@ -3973,7 +3986,7 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
3973
3986
  maxSizeInRow = 0;
3974
3987
  }
3975
3988
  const knownSize = sizesKnown.get(id);
3976
- const size = knownSize !== void 0 ? knownSize : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
3989
+ const size = knownSize !== void 0 ? knownSize : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize, notifyTotalSizeWhileCachingSizes);
3977
3990
  if (IS_DEV && needsIndexByKey) {
3978
3991
  if (indexByKeyForChecking.has(id)) {
3979
3992
  console.error(
@@ -4229,7 +4242,7 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
4229
4242
  }
4230
4243
  function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
4231
4244
  let value = ctx.mapViewabilityAmountValues.get(containerId);
4232
- if (!value || value.key !== key) {
4245
+ if (!value || value.key !== key || value.index !== index) {
4233
4246
  value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
4234
4247
  }
4235
4248
  return value.isViewable;
@@ -4244,7 +4257,7 @@ var unstableBatchedUpdates = ReactDOM__namespace.unstable_batchedUpdates;
4244
4257
  var batchedUpdates = typeof unstableBatchedUpdates === "function" ? unstableBatchedUpdates : (fn) => fn();
4245
4258
 
4246
4259
  // src/utils/findAvailableContainers.ts
4247
- function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
4260
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers, protectedKeys) {
4248
4261
  const numContainers = peek$(ctx, "numContainers");
4249
4262
  const state = ctx.state;
4250
4263
  const { stickyContainerPool, containerItemTypes } = state;
@@ -4312,6 +4325,7 @@ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pen
4312
4325
  }
4313
4326
  const key = peek$(ctx, `containerItemKey${u}`);
4314
4327
  if (key === void 0) continue;
4328
+ if ((protectedKeys == null ? void 0 : protectedKeys.has(key)) && state.indexByKey.has(key)) continue;
4315
4329
  const index = state.indexByKey.get(key);
4316
4330
  const isOutOfView = index < startBuffered || index > endBuffered;
4317
4331
  if (isOutOfView) {
@@ -4447,7 +4461,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
4447
4461
  function calculateItemsInView(ctx, params = {}) {
4448
4462
  const state = ctx.state;
4449
4463
  batchedUpdates(() => {
4450
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
4464
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
4451
4465
  const {
4452
4466
  columns,
4453
4467
  columnSpans,
@@ -4549,17 +4563,31 @@ function calculateItemsInView(ctx, params = {}) {
4549
4563
  if (minIndexSizeChanged !== void 0) {
4550
4564
  state.minIndexSizeChanged = void 0;
4551
4565
  }
4566
+ let protectedContainerKeys;
4567
+ if (dataChanged && doMVCP && state.props.maintainVisibleContentPosition.data && state.didContainersLayout && state.idsInView.length > 0) {
4568
+ const shouldRestorePosition = state.props.maintainVisibleContentPosition.shouldRestorePosition;
4569
+ protectedContainerKeys = /* @__PURE__ */ new Set();
4570
+ for (const id of state.idsInView) {
4571
+ const index = indexByKey.get(id);
4572
+ if (index === void 0) continue;
4573
+ if (shouldRestorePosition && !shouldRestorePosition(data[index], index, data)) continue;
4574
+ protectedContainerKeys.add(id);
4575
+ }
4576
+ }
4577
+ const scrollBeforeMVCP = state.scroll;
4578
+ const scrollAdjustPendingBeforeMVCP = (_e = peek$(ctx, "scrollAdjustPending")) != null ? _e : 0;
4552
4579
  checkMVCP == null ? void 0 : checkMVCP();
4580
+ const didMVCPAdjustScroll = !!checkMVCP && (state.scroll !== scrollBeforeMVCP || ((_f = peek$(ctx, "scrollAdjustPending")) != null ? _f : 0) !== scrollAdjustPendingBeforeMVCP);
4553
4581
  let startNoBuffer = null;
4554
4582
  let startBuffered = null;
4555
4583
  let startBufferedId = null;
4556
4584
  let endNoBuffer = null;
4557
4585
  let endBuffered = null;
4558
- let loopStart = (_e = suppressInitialScrollSideEffects ? bootstrapInitialScrollState == null ? void 0 : bootstrapInitialScrollState.targetIndexSeed : void 0) != null ? _e : !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
4586
+ let loopStart = (_g = suppressInitialScrollSideEffects ? bootstrapInitialScrollState == null ? void 0 : bootstrapInitialScrollState.targetIndexSeed : void 0) != null ? _g : !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
4559
4587
  for (let i = loopStart; i >= 0; i--) {
4560
- const id = (_f = idCache[i]) != null ? _f : getId(state, i);
4588
+ const id = (_h = idCache[i]) != null ? _h : getId(state, i);
4561
4589
  const top = positions[i];
4562
- const size = (_g = sizes.get(id)) != null ? _g : getItemSize(ctx, id, i, data[i]);
4590
+ const size = (_i = sizes.get(id)) != null ? _i : getItemSize(ctx, id, i, data[i]);
4563
4591
  const bottom = top + size;
4564
4592
  if (bottom > scroll - scrollBufferTop) {
4565
4593
  loopStart = i;
@@ -4590,8 +4618,8 @@ function calculateItemsInView(ctx, params = {}) {
4590
4618
  let firstFullyOnScreenIndex;
4591
4619
  const dataLength = data.length;
4592
4620
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
4593
- const id = (_h = idCache[i]) != null ? _h : getId(state, i);
4594
- const size = (_i = sizes.get(id)) != null ? _i : getItemSize(ctx, id, i, data[i]);
4621
+ const id = (_j = idCache[i]) != null ? _j : getId(state, i);
4622
+ const size = (_k = sizes.get(id)) != null ? _k : getItemSize(ctx, id, i, data[i]);
4595
4623
  const top = positions[i];
4596
4624
  if (!foundEnd) {
4597
4625
  if (startNoBuffer === null && top + size > scroll) {
@@ -4630,7 +4658,7 @@ function calculateItemsInView(ctx, params = {}) {
4630
4658
  const firstVisibleAnchorIndex = firstFullyOnScreenIndex != null ? firstFullyOnScreenIndex : startNoBuffer;
4631
4659
  if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && endNoBuffer !== null) {
4632
4660
  for (let i = firstVisibleAnchorIndex; i <= endNoBuffer; i++) {
4633
- const id = (_j = idCache[i]) != null ? _j : getId(state, i);
4661
+ const id = (_l = idCache[i]) != null ? _l : getId(state, i);
4634
4662
  idsInView.push(id);
4635
4663
  }
4636
4664
  }
@@ -4663,7 +4691,7 @@ function calculateItemsInView(ctx, params = {}) {
4663
4691
  const needNewContainers = [];
4664
4692
  const needNewContainersSet = /* @__PURE__ */ new Set();
4665
4693
  for (let i = startBuffered; i <= endBuffered; i++) {
4666
- const id = (_k = idCache[i]) != null ? _k : getId(state, i);
4694
+ const id = (_m = idCache[i]) != null ? _m : getId(state, i);
4667
4695
  if (!containerItemKeys.has(id)) {
4668
4696
  needNewContainersSet.add(i);
4669
4697
  needNewContainers.push(i);
@@ -4672,7 +4700,7 @@ function calculateItemsInView(ctx, params = {}) {
4672
4700
  if (alwaysRenderArr.length > 0) {
4673
4701
  for (const index of alwaysRenderArr) {
4674
4702
  if (index < 0 || index >= dataLength) continue;
4675
- const id = (_l = idCache[index]) != null ? _l : getId(state, index);
4703
+ const id = (_n = idCache[index]) != null ? _n : getId(state, index);
4676
4704
  if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
4677
4705
  needNewContainersSet.add(index);
4678
4706
  needNewContainers.push(index);
@@ -4705,12 +4733,13 @@ function calculateItemsInView(ctx, params = {}) {
4705
4733
  endBuffered,
4706
4734
  pendingRemoval,
4707
4735
  requiredItemTypes,
4708
- needNewContainers
4736
+ needNewContainers,
4737
+ protectedContainerKeys
4709
4738
  );
4710
4739
  for (let idx = 0; idx < needNewContainers.length; idx++) {
4711
4740
  const i = needNewContainers[idx];
4712
4741
  const containerIndex = availableContainers[idx];
4713
- const id = (_m = idCache[i]) != null ? _m : getId(state, i);
4742
+ const id = (_o = idCache[i]) != null ? _o : getId(state, i);
4714
4743
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
4715
4744
  if (oldKey && oldKey !== id) {
4716
4745
  containerItemKeys.delete(oldKey);
@@ -4721,6 +4750,7 @@ function calculateItemsInView(ctx, params = {}) {
4721
4750
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
4722
4751
  }
4723
4752
  containerItemKeys.set(id, containerIndex);
4753
+ (_p = state.userScrollAnchorResetKeys) == null ? void 0 : _p.add(id);
4724
4754
  const containerSticky = `containerSticky${containerIndex}`;
4725
4755
  const isSticky = stickyIndicesSet.has(i);
4726
4756
  const isAlwaysRender = alwaysRenderSet.has(i);
@@ -4748,10 +4778,13 @@ function calculateItemsInView(ctx, params = {}) {
4748
4778
  }
4749
4779
  }
4750
4780
  }
4781
+ if (((_q = state.userScrollAnchorResetKeys) == null ? void 0 : _q.size) === 0) {
4782
+ state.userScrollAnchorResetKeys = void 0;
4783
+ }
4751
4784
  if (alwaysRenderArr.length > 0) {
4752
4785
  for (const index of alwaysRenderArr) {
4753
4786
  if (index < 0 || index >= dataLength) continue;
4754
- const id = (_n = idCache[index]) != null ? _n : getId(state, index);
4787
+ const id = (_r = idCache[index]) != null ? _r : getId(state, index);
4755
4788
  const containerIndex = containerItemKeys.get(id);
4756
4789
  if (containerIndex !== void 0) {
4757
4790
  state.stickyContainerPool.add(containerIndex);
@@ -4812,16 +4845,18 @@ function calculateItemsInView(ctx, params = {}) {
4812
4845
  handleInitialScrollLayoutReady(ctx);
4813
4846
  }
4814
4847
  if (viewabilityConfigCallbackPairs && startNoBuffer !== null && endNoBuffer !== null) {
4815
- updateViewableItems(
4816
- ctx.state,
4817
- ctx,
4818
- viewabilityConfigCallbackPairs,
4819
- scrollLength,
4820
- startNoBuffer,
4821
- endNoBuffer,
4822
- startBuffered != null ? startBuffered : startNoBuffer,
4823
- endBuffered != null ? endBuffered : endNoBuffer
4824
- );
4848
+ if (!didMVCPAdjustScroll) {
4849
+ updateViewableItems(
4850
+ ctx.state,
4851
+ ctx,
4852
+ viewabilityConfigCallbackPairs,
4853
+ scrollLength,
4854
+ startNoBuffer,
4855
+ endNoBuffer,
4856
+ startBuffered != null ? startBuffered : startNoBuffer,
4857
+ endBuffered != null ? endBuffered : endNoBuffer
4858
+ );
4859
+ }
4825
4860
  }
4826
4861
  if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
4827
4862
  const item = data[nextActiveStickyIndex];
@@ -5110,7 +5145,14 @@ function updateScroll(ctx, newScroll, forceUpdate) {
5110
5145
  (_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { doMVCP: scrollingTo !== void 0 });
5111
5146
  checkThresholds(ctx);
5112
5147
  };
5113
- if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
5148
+ if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust) {
5149
+ state.mvcpAnchorLock = void 0;
5150
+ state.pendingNativeMVCPAdjust = void 0;
5151
+ state.userScrollAnchorResetKeys = /* @__PURE__ */ new Set();
5152
+ if (state.queuedMVCPRecalculate !== void 0) {
5153
+ cancelAnimationFrame(state.queuedMVCPRecalculate);
5154
+ state.queuedMVCPRecalculate = void 0;
5155
+ }
5114
5156
  ReactDOM.flushSync(runCalculateItems);
5115
5157
  } else {
5116
5158
  runCalculateItems();
@@ -5293,6 +5335,20 @@ function maybeUpdateAnchoredEndSpace(ctx) {
5293
5335
  // src/core/updateItemSize.ts
5294
5336
  function runOrScheduleMVCPRecalculate(ctx) {
5295
5337
  const state = ctx.state;
5338
+ if (state.userScrollAnchorResetKeys !== void 0) {
5339
+ if (state.queuedMVCPRecalculate !== void 0) {
5340
+ return;
5341
+ }
5342
+ state.queuedMVCPRecalculate = requestAnimationFrame(() => {
5343
+ var _a3;
5344
+ state.queuedMVCPRecalculate = void 0;
5345
+ calculateItemsInView(ctx);
5346
+ if (((_a3 = state.userScrollAnchorResetKeys) == null ? void 0 : _a3.size) === 0) {
5347
+ state.userScrollAnchorResetKeys = void 0;
5348
+ }
5349
+ });
5350
+ return;
5351
+ }
5296
5352
  {
5297
5353
  if (!state.mvcpAnchorLock) {
5298
5354
  if (state.queuedMVCPRecalculate !== void 0) {
@@ -5314,6 +5370,8 @@ function runOrScheduleMVCPRecalculate(ctx) {
5314
5370
  function updateItemSize(ctx, itemKey, sizeObj) {
5315
5371
  var _a3;
5316
5372
  const state = ctx.state;
5373
+ const userScrollAnchorResetKeys = state.userScrollAnchorResetKeys;
5374
+ const didMeasureUserScrollAnchorResetItem = !!(userScrollAnchorResetKeys == null ? void 0 : userScrollAnchorResetKeys.delete(itemKey));
5317
5375
  const {
5318
5376
  didContainersLayout,
5319
5377
  sizesKnown,
@@ -5392,10 +5450,12 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5392
5450
  if (!cur || maxOtherAxisSize > cur) {
5393
5451
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
5394
5452
  }
5395
- if (didContainersLayout || checkAllSizesKnown(state)) {
5453
+ if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
5396
5454
  if (needsRecalculate) {
5397
5455
  state.scrollForNextCalculateItemsInView = void 0;
5398
5456
  runOrScheduleMVCPRecalculate(ctx);
5457
+ } else if (didMeasureUserScrollAnchorResetItem && (userScrollAnchorResetKeys == null ? void 0 : userScrollAnchorResetKeys.size) === 0) {
5458
+ state.userScrollAnchorResetKeys = void 0;
5399
5459
  }
5400
5460
  if (shouldMaintainScrollAtEnd) {
5401
5461
  if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onItemLayout) {
package/index.mjs CHANGED
@@ -2059,7 +2059,7 @@ function getId(state, index) {
2059
2059
  }
2060
2060
 
2061
2061
  // src/core/addTotalSize.ts
2062
- function addTotalSize(ctx, key, add) {
2062
+ function addTotalSize(ctx, key, add, notifyTotalSize = true) {
2063
2063
  const state = ctx.state;
2064
2064
  const prevTotalSize = state.totalSize;
2065
2065
  let totalSize = state.totalSize;
@@ -2076,25 +2076,29 @@ function addTotalSize(ctx, key, add) {
2076
2076
  {
2077
2077
  state.pendingTotalSize = void 0;
2078
2078
  state.totalSize = totalSize;
2079
- set$(ctx, "totalSize", totalSize);
2079
+ if (notifyTotalSize) {
2080
+ set$(ctx, "totalSize", totalSize);
2081
+ }
2080
2082
  }
2083
+ } else if (notifyTotalSize && ctx.values.get("totalSize") !== totalSize) {
2084
+ set$(ctx, "totalSize", totalSize);
2081
2085
  }
2082
2086
  }
2083
2087
 
2084
2088
  // src/core/setSize.ts
2085
- function setSize(ctx, itemKey, size) {
2089
+ function setSize(ctx, itemKey, size, notifyTotalSize = true) {
2086
2090
  const state = ctx.state;
2087
2091
  const { sizes } = state;
2088
2092
  const previousSize = sizes.get(itemKey);
2089
2093
  const diff = previousSize !== void 0 ? size - previousSize : size;
2090
2094
  if (diff !== 0) {
2091
- addTotalSize(ctx, itemKey, diff);
2095
+ addTotalSize(ctx, itemKey, diff, notifyTotalSize);
2092
2096
  }
2093
2097
  sizes.set(itemKey, size);
2094
2098
  }
2095
2099
 
2096
2100
  // src/utils/getItemSize.ts
2097
- function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
2101
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, notifyTotalSize) {
2098
2102
  var _a3, _b, _c;
2099
2103
  const state = ctx.state;
2100
2104
  const {
@@ -2140,7 +2144,7 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
2140
2144
  if (size === void 0) {
2141
2145
  size = getEstimatedItemSize ? getEstimatedItemSize(data, index, itemType) : estimatedItemSize;
2142
2146
  }
2143
- setSize(ctx, key, size);
2147
+ setSize(ctx, key, size, notifyTotalSize);
2144
2148
  return size;
2145
2149
  }
2146
2150
  function getItemSizeAtIndex(ctx, index) {
@@ -2579,10 +2583,10 @@ function getMountedBufferedIndices(state) {
2579
2583
  function getMountedNoBufferIndices(state) {
2580
2584
  return getMountedIndicesInRange(state, state.startNoBuffer, state.endNoBuffer);
2581
2585
  }
2582
- function checkAllSizesKnown(state, indices = getMountedBufferedIndices(state)) {
2586
+ function checkAllSizesKnown(state, indices) {
2583
2587
  return indices.length > 0 && indices.every((index) => {
2584
2588
  const key = getId(state, index);
2585
- return state.sizesKnown.has(key);
2589
+ return key !== void 0 && state.sizesKnown.has(key);
2586
2590
  });
2587
2591
  }
2588
2592
 
@@ -3892,6 +3896,7 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
3892
3896
  const maxVisibleArea = scrollBottomBuffered + 1e3;
3893
3897
  const useAverageSize = !getEstimatedItemSize;
3894
3898
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_b = peek$(ctx, "scrollAdjustPending")) != null ? _b : 0) !== 0;
3899
+ const notifyTotalSizeWhileCachingSizes = false;
3895
3900
  let currentRowTop = 0;
3896
3901
  let column = 1;
3897
3902
  let maxSizeInRow = 0;
@@ -3919,7 +3924,15 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
3919
3924
  const prevIndex = startIndex - 1;
3920
3925
  const prevId = getId(state, prevIndex);
3921
3926
  const prevPosition = (_c = positions[prevIndex]) != null ? _c : 0;
3922
- const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
3927
+ const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(
3928
+ ctx,
3929
+ prevId,
3930
+ prevIndex,
3931
+ data[prevIndex],
3932
+ useAverageSize,
3933
+ preferCachedSize,
3934
+ notifyTotalSizeWhileCachingSizes
3935
+ );
3923
3936
  currentRowTop = prevPosition + prevSize;
3924
3937
  }
3925
3938
  }
@@ -3952,7 +3965,7 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
3952
3965
  maxSizeInRow = 0;
3953
3966
  }
3954
3967
  const knownSize = sizesKnown.get(id);
3955
- const size = knownSize !== void 0 ? knownSize : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
3968
+ const size = knownSize !== void 0 ? knownSize : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize, notifyTotalSizeWhileCachingSizes);
3956
3969
  if (IS_DEV && needsIndexByKey) {
3957
3970
  if (indexByKeyForChecking.has(id)) {
3958
3971
  console.error(
@@ -4208,7 +4221,7 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
4208
4221
  }
4209
4222
  function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
4210
4223
  let value = ctx.mapViewabilityAmountValues.get(containerId);
4211
- if (!value || value.key !== key) {
4224
+ if (!value || value.key !== key || value.index !== index) {
4212
4225
  value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
4213
4226
  }
4214
4227
  return value.isViewable;
@@ -4223,7 +4236,7 @@ var unstableBatchedUpdates = ReactDOM.unstable_batchedUpdates;
4223
4236
  var batchedUpdates = typeof unstableBatchedUpdates === "function" ? unstableBatchedUpdates : (fn) => fn();
4224
4237
 
4225
4238
  // src/utils/findAvailableContainers.ts
4226
- function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
4239
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers, protectedKeys) {
4227
4240
  const numContainers = peek$(ctx, "numContainers");
4228
4241
  const state = ctx.state;
4229
4242
  const { stickyContainerPool, containerItemTypes } = state;
@@ -4291,6 +4304,7 @@ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pen
4291
4304
  }
4292
4305
  const key = peek$(ctx, `containerItemKey${u}`);
4293
4306
  if (key === void 0) continue;
4307
+ if ((protectedKeys == null ? void 0 : protectedKeys.has(key)) && state.indexByKey.has(key)) continue;
4294
4308
  const index = state.indexByKey.get(key);
4295
4309
  const isOutOfView = index < startBuffered || index > endBuffered;
4296
4310
  if (isOutOfView) {
@@ -4426,7 +4440,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
4426
4440
  function calculateItemsInView(ctx, params = {}) {
4427
4441
  const state = ctx.state;
4428
4442
  batchedUpdates(() => {
4429
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
4443
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
4430
4444
  const {
4431
4445
  columns,
4432
4446
  columnSpans,
@@ -4528,17 +4542,31 @@ function calculateItemsInView(ctx, params = {}) {
4528
4542
  if (minIndexSizeChanged !== void 0) {
4529
4543
  state.minIndexSizeChanged = void 0;
4530
4544
  }
4545
+ let protectedContainerKeys;
4546
+ if (dataChanged && doMVCP && state.props.maintainVisibleContentPosition.data && state.didContainersLayout && state.idsInView.length > 0) {
4547
+ const shouldRestorePosition = state.props.maintainVisibleContentPosition.shouldRestorePosition;
4548
+ protectedContainerKeys = /* @__PURE__ */ new Set();
4549
+ for (const id of state.idsInView) {
4550
+ const index = indexByKey.get(id);
4551
+ if (index === void 0) continue;
4552
+ if (shouldRestorePosition && !shouldRestorePosition(data[index], index, data)) continue;
4553
+ protectedContainerKeys.add(id);
4554
+ }
4555
+ }
4556
+ const scrollBeforeMVCP = state.scroll;
4557
+ const scrollAdjustPendingBeforeMVCP = (_e = peek$(ctx, "scrollAdjustPending")) != null ? _e : 0;
4531
4558
  checkMVCP == null ? void 0 : checkMVCP();
4559
+ const didMVCPAdjustScroll = !!checkMVCP && (state.scroll !== scrollBeforeMVCP || ((_f = peek$(ctx, "scrollAdjustPending")) != null ? _f : 0) !== scrollAdjustPendingBeforeMVCP);
4532
4560
  let startNoBuffer = null;
4533
4561
  let startBuffered = null;
4534
4562
  let startBufferedId = null;
4535
4563
  let endNoBuffer = null;
4536
4564
  let endBuffered = null;
4537
- let loopStart = (_e = suppressInitialScrollSideEffects ? bootstrapInitialScrollState == null ? void 0 : bootstrapInitialScrollState.targetIndexSeed : void 0) != null ? _e : !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
4565
+ let loopStart = (_g = suppressInitialScrollSideEffects ? bootstrapInitialScrollState == null ? void 0 : bootstrapInitialScrollState.targetIndexSeed : void 0) != null ? _g : !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
4538
4566
  for (let i = loopStart; i >= 0; i--) {
4539
- const id = (_f = idCache[i]) != null ? _f : getId(state, i);
4567
+ const id = (_h = idCache[i]) != null ? _h : getId(state, i);
4540
4568
  const top = positions[i];
4541
- const size = (_g = sizes.get(id)) != null ? _g : getItemSize(ctx, id, i, data[i]);
4569
+ const size = (_i = sizes.get(id)) != null ? _i : getItemSize(ctx, id, i, data[i]);
4542
4570
  const bottom = top + size;
4543
4571
  if (bottom > scroll - scrollBufferTop) {
4544
4572
  loopStart = i;
@@ -4569,8 +4597,8 @@ function calculateItemsInView(ctx, params = {}) {
4569
4597
  let firstFullyOnScreenIndex;
4570
4598
  const dataLength = data.length;
4571
4599
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
4572
- const id = (_h = idCache[i]) != null ? _h : getId(state, i);
4573
- const size = (_i = sizes.get(id)) != null ? _i : getItemSize(ctx, id, i, data[i]);
4600
+ const id = (_j = idCache[i]) != null ? _j : getId(state, i);
4601
+ const size = (_k = sizes.get(id)) != null ? _k : getItemSize(ctx, id, i, data[i]);
4574
4602
  const top = positions[i];
4575
4603
  if (!foundEnd) {
4576
4604
  if (startNoBuffer === null && top + size > scroll) {
@@ -4609,7 +4637,7 @@ function calculateItemsInView(ctx, params = {}) {
4609
4637
  const firstVisibleAnchorIndex = firstFullyOnScreenIndex != null ? firstFullyOnScreenIndex : startNoBuffer;
4610
4638
  if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && endNoBuffer !== null) {
4611
4639
  for (let i = firstVisibleAnchorIndex; i <= endNoBuffer; i++) {
4612
- const id = (_j = idCache[i]) != null ? _j : getId(state, i);
4640
+ const id = (_l = idCache[i]) != null ? _l : getId(state, i);
4613
4641
  idsInView.push(id);
4614
4642
  }
4615
4643
  }
@@ -4642,7 +4670,7 @@ function calculateItemsInView(ctx, params = {}) {
4642
4670
  const needNewContainers = [];
4643
4671
  const needNewContainersSet = /* @__PURE__ */ new Set();
4644
4672
  for (let i = startBuffered; i <= endBuffered; i++) {
4645
- const id = (_k = idCache[i]) != null ? _k : getId(state, i);
4673
+ const id = (_m = idCache[i]) != null ? _m : getId(state, i);
4646
4674
  if (!containerItemKeys.has(id)) {
4647
4675
  needNewContainersSet.add(i);
4648
4676
  needNewContainers.push(i);
@@ -4651,7 +4679,7 @@ function calculateItemsInView(ctx, params = {}) {
4651
4679
  if (alwaysRenderArr.length > 0) {
4652
4680
  for (const index of alwaysRenderArr) {
4653
4681
  if (index < 0 || index >= dataLength) continue;
4654
- const id = (_l = idCache[index]) != null ? _l : getId(state, index);
4682
+ const id = (_n = idCache[index]) != null ? _n : getId(state, index);
4655
4683
  if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
4656
4684
  needNewContainersSet.add(index);
4657
4685
  needNewContainers.push(index);
@@ -4684,12 +4712,13 @@ function calculateItemsInView(ctx, params = {}) {
4684
4712
  endBuffered,
4685
4713
  pendingRemoval,
4686
4714
  requiredItemTypes,
4687
- needNewContainers
4715
+ needNewContainers,
4716
+ protectedContainerKeys
4688
4717
  );
4689
4718
  for (let idx = 0; idx < needNewContainers.length; idx++) {
4690
4719
  const i = needNewContainers[idx];
4691
4720
  const containerIndex = availableContainers[idx];
4692
- const id = (_m = idCache[i]) != null ? _m : getId(state, i);
4721
+ const id = (_o = idCache[i]) != null ? _o : getId(state, i);
4693
4722
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
4694
4723
  if (oldKey && oldKey !== id) {
4695
4724
  containerItemKeys.delete(oldKey);
@@ -4700,6 +4729,7 @@ function calculateItemsInView(ctx, params = {}) {
4700
4729
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
4701
4730
  }
4702
4731
  containerItemKeys.set(id, containerIndex);
4732
+ (_p = state.userScrollAnchorResetKeys) == null ? void 0 : _p.add(id);
4703
4733
  const containerSticky = `containerSticky${containerIndex}`;
4704
4734
  const isSticky = stickyIndicesSet.has(i);
4705
4735
  const isAlwaysRender = alwaysRenderSet.has(i);
@@ -4727,10 +4757,13 @@ function calculateItemsInView(ctx, params = {}) {
4727
4757
  }
4728
4758
  }
4729
4759
  }
4760
+ if (((_q = state.userScrollAnchorResetKeys) == null ? void 0 : _q.size) === 0) {
4761
+ state.userScrollAnchorResetKeys = void 0;
4762
+ }
4730
4763
  if (alwaysRenderArr.length > 0) {
4731
4764
  for (const index of alwaysRenderArr) {
4732
4765
  if (index < 0 || index >= dataLength) continue;
4733
- const id = (_n = idCache[index]) != null ? _n : getId(state, index);
4766
+ const id = (_r = idCache[index]) != null ? _r : getId(state, index);
4734
4767
  const containerIndex = containerItemKeys.get(id);
4735
4768
  if (containerIndex !== void 0) {
4736
4769
  state.stickyContainerPool.add(containerIndex);
@@ -4791,16 +4824,18 @@ function calculateItemsInView(ctx, params = {}) {
4791
4824
  handleInitialScrollLayoutReady(ctx);
4792
4825
  }
4793
4826
  if (viewabilityConfigCallbackPairs && startNoBuffer !== null && endNoBuffer !== null) {
4794
- updateViewableItems(
4795
- ctx.state,
4796
- ctx,
4797
- viewabilityConfigCallbackPairs,
4798
- scrollLength,
4799
- startNoBuffer,
4800
- endNoBuffer,
4801
- startBuffered != null ? startBuffered : startNoBuffer,
4802
- endBuffered != null ? endBuffered : endNoBuffer
4803
- );
4827
+ if (!didMVCPAdjustScroll) {
4828
+ updateViewableItems(
4829
+ ctx.state,
4830
+ ctx,
4831
+ viewabilityConfigCallbackPairs,
4832
+ scrollLength,
4833
+ startNoBuffer,
4834
+ endNoBuffer,
4835
+ startBuffered != null ? startBuffered : startNoBuffer,
4836
+ endBuffered != null ? endBuffered : endNoBuffer
4837
+ );
4838
+ }
4804
4839
  }
4805
4840
  if (onStickyHeaderChange && stickyIndicesArr.length > 0 && nextActiveStickyIndex !== void 0 && nextActiveStickyIndex !== previousStickyIndex) {
4806
4841
  const item = data[nextActiveStickyIndex];
@@ -5089,7 +5124,14 @@ function updateScroll(ctx, newScroll, forceUpdate) {
5089
5124
  (_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, { doMVCP: scrollingTo !== void 0 });
5090
5125
  checkThresholds(ctx);
5091
5126
  };
5092
- if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
5127
+ if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust) {
5128
+ state.mvcpAnchorLock = void 0;
5129
+ state.pendingNativeMVCPAdjust = void 0;
5130
+ state.userScrollAnchorResetKeys = /* @__PURE__ */ new Set();
5131
+ if (state.queuedMVCPRecalculate !== void 0) {
5132
+ cancelAnimationFrame(state.queuedMVCPRecalculate);
5133
+ state.queuedMVCPRecalculate = void 0;
5134
+ }
5093
5135
  flushSync(runCalculateItems);
5094
5136
  } else {
5095
5137
  runCalculateItems();
@@ -5272,6 +5314,20 @@ function maybeUpdateAnchoredEndSpace(ctx) {
5272
5314
  // src/core/updateItemSize.ts
5273
5315
  function runOrScheduleMVCPRecalculate(ctx) {
5274
5316
  const state = ctx.state;
5317
+ if (state.userScrollAnchorResetKeys !== void 0) {
5318
+ if (state.queuedMVCPRecalculate !== void 0) {
5319
+ return;
5320
+ }
5321
+ state.queuedMVCPRecalculate = requestAnimationFrame(() => {
5322
+ var _a3;
5323
+ state.queuedMVCPRecalculate = void 0;
5324
+ calculateItemsInView(ctx);
5325
+ if (((_a3 = state.userScrollAnchorResetKeys) == null ? void 0 : _a3.size) === 0) {
5326
+ state.userScrollAnchorResetKeys = void 0;
5327
+ }
5328
+ });
5329
+ return;
5330
+ }
5275
5331
  {
5276
5332
  if (!state.mvcpAnchorLock) {
5277
5333
  if (state.queuedMVCPRecalculate !== void 0) {
@@ -5293,6 +5349,8 @@ function runOrScheduleMVCPRecalculate(ctx) {
5293
5349
  function updateItemSize(ctx, itemKey, sizeObj) {
5294
5350
  var _a3;
5295
5351
  const state = ctx.state;
5352
+ const userScrollAnchorResetKeys = state.userScrollAnchorResetKeys;
5353
+ const didMeasureUserScrollAnchorResetItem = !!(userScrollAnchorResetKeys == null ? void 0 : userScrollAnchorResetKeys.delete(itemKey));
5296
5354
  const {
5297
5355
  didContainersLayout,
5298
5356
  sizesKnown,
@@ -5371,10 +5429,12 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5371
5429
  if (!cur || maxOtherAxisSize > cur) {
5372
5430
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
5373
5431
  }
5374
- if (didContainersLayout || checkAllSizesKnown(state)) {
5432
+ if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
5375
5433
  if (needsRecalculate) {
5376
5434
  state.scrollForNextCalculateItemsInView = void 0;
5377
5435
  runOrScheduleMVCPRecalculate(ctx);
5436
+ } else if (didMeasureUserScrollAnchorResetItem && (userScrollAnchorResetKeys == null ? void 0 : userScrollAnchorResetKeys.size) === 0) {
5437
+ state.userScrollAnchorResetKeys = void 0;
5378
5438
  }
5379
5439
  if (shouldMaintainScrollAtEnd) {
5380
5440
  if (maintainScrollAtEnd == null ? void 0 : maintainScrollAtEnd.onItemLayout) {