@legendapp/list 3.0.4 → 3.0.5

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/react-native.js CHANGED
@@ -143,6 +143,7 @@ function StateProvider({ children }) {
143
143
  const [value] = React2__namespace.useState(() => ({
144
144
  animatedScrollY: createAnimatedValue(0),
145
145
  columnWrapperStyle: void 0,
146
+ containerLayoutTriggers: /* @__PURE__ */ new Map(),
146
147
  contextNum: contextNum++,
147
148
  listeners: /* @__PURE__ */ new Map(),
148
149
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
@@ -561,9 +562,6 @@ function roundSize(size) {
561
562
  function isNullOrUndefined(value) {
562
563
  return value === null || value === void 0;
563
564
  }
564
- function comparatorDefault(a, b) {
565
- return a - b;
566
- }
567
565
  function getPadding(s, type) {
568
566
  var _a3, _b, _c;
569
567
  const axisPadding = type === "Left" || type === "Right" ? s.paddingHorizontal : s.paddingVertical;
@@ -916,18 +914,6 @@ var Container = typedMemo(function Container2({
916
914
  [itemKey, data, extraData]
917
915
  );
918
916
  const { index, renderedItem } = renderedItemInfo || {};
919
- const contextValue = React2.useMemo(() => {
920
- ctx.viewRefs.set(id, ref);
921
- return {
922
- containerId: id,
923
- index,
924
- itemKey,
925
- triggerLayout: () => {
926
- forceLayoutRender((v) => v + 1);
927
- },
928
- value: data
929
- };
930
- }, [id, itemKey, index, data]);
931
917
  const onLayoutChange = React2.useCallback((rectangle) => {
932
918
  var _a3, _b;
933
919
  const {
@@ -977,6 +963,27 @@ var Container = typedMemo(function Container2({
977
963
  });
978
964
  }
979
965
  }, []);
966
+ const triggerLayout = React2.useCallback(() => {
967
+ forceLayoutRender((v) => v + 1);
968
+ }, []);
969
+ const contextValue = React2.useMemo(() => {
970
+ ctx.viewRefs.set(id, ref);
971
+ return {
972
+ containerId: id,
973
+ index,
974
+ itemKey,
975
+ triggerLayout,
976
+ value: data
977
+ };
978
+ }, [id, itemKey, index, data, triggerLayout]);
979
+ React2.useLayoutEffect(() => {
980
+ ctx.containerLayoutTriggers.set(id, triggerLayout);
981
+ return () => {
982
+ if (ctx.containerLayoutTriggers.get(id) === triggerLayout) {
983
+ ctx.containerLayoutTriggers.delete(id);
984
+ }
985
+ };
986
+ }, [ctx, id, triggerLayout]);
980
987
  const { onLayout } = useOnLayoutSync(
981
988
  {
982
989
  onLayoutChange,
@@ -1831,14 +1838,14 @@ function setSize(ctx, itemKey, size, notifyTotalSize = true) {
1831
1838
  }
1832
1839
 
1833
1840
  // src/utils/getItemSize.ts
1834
- function getKnownOrFixedSize(ctx, key, index, data) {
1835
- var _a3;
1841
+ function getKnownOrFixedSize(ctx, key, index, data, resolved) {
1842
+ var _a3, _b;
1836
1843
  const state = ctx.state;
1837
1844
  const { getFixedItemSize, getItemType } = state.props;
1838
1845
  let size = key ? state.sizesKnown.get(key) : void 0;
1839
1846
  if (size === void 0 && key && getFixedItemSize) {
1840
- const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1841
- size = getFixedItemSize(data, index, itemType);
1847
+ const itemType = (_b = resolved == null ? void 0 : resolved.itemType) != null ? _b : getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1848
+ size = (resolved == null ? void 0 : resolved.didResolveFixedItemSize) ? resolved.fixedItemSize : getFixedItemSize(data, index, itemType);
1842
1849
  if (size !== void 0) {
1843
1850
  state.sizesKnown.set(key, size);
1844
1851
  }
@@ -1857,8 +1864,8 @@ function areKnownOrFixedItemSizesAvailable(ctx, startIndex, endIndex) {
1857
1864
  }
1858
1865
  return true;
1859
1866
  }
1860
- function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, notifyTotalSize) {
1861
- var _a3, _b, _c;
1867
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, notifyTotalSize, resolved) {
1868
+ var _a3, _b, _c, _d;
1862
1869
  const state = ctx.state;
1863
1870
  const {
1864
1871
  sizes,
@@ -1877,14 +1884,14 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, no
1877
1884
  return renderedSize;
1878
1885
  }
1879
1886
  }
1880
- size = getKnownOrFixedSize(ctx, key, index, data);
1887
+ size = getKnownOrFixedSize(ctx, key, index, data, resolved);
1881
1888
  if (size !== void 0) {
1882
1889
  setSize(ctx, key, size, notifyTotalSize);
1883
1890
  return size;
1884
1891
  }
1885
- const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1892
+ const itemType = (_b = resolved == null ? void 0 : resolved.itemType) != null ? _b : getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1886
1893
  if (useAverageSize && !scrollingTo) {
1887
- const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
1894
+ const averageSizeForType = (_c = averageSizes[itemType]) == null ? void 0 : _c.avg;
1888
1895
  if (averageSizeForType !== void 0) {
1889
1896
  size = roundSize(averageSizeForType);
1890
1897
  }
@@ -1893,7 +1900,7 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, no
1893
1900
  return renderedSize;
1894
1901
  }
1895
1902
  if (size === void 0 && useAverageSize && scrollingTo) {
1896
- const averageSizeForType = (_c = scrollingTo.averageSizeSnapshot) == null ? void 0 : _c[itemType];
1903
+ const averageSizeForType = (_d = scrollingTo.averageSizeSnapshot) == null ? void 0 : _d[itemType];
1897
1904
  if (averageSizeForType !== void 0) {
1898
1905
  size = roundSize(averageSizeForType);
1899
1906
  }
@@ -2600,8 +2607,8 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
2600
2607
  if ((options == null ? void 0 : options.markHasScrolled) !== false) {
2601
2608
  state.hasScrolled = true;
2602
2609
  }
2603
- state.lastBatchingAction = Date.now();
2604
2610
  const currentTime = Date.now();
2611
+ state.lastBatchingAction = currentTime;
2605
2612
  const adjust = scrollAdjustHandler.getAdjust();
2606
2613
  const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
2607
2614
  if (adjustChanged) {
@@ -2910,26 +2917,22 @@ function advanceCurrentInitialScrollSession(ctx, options) {
2910
2917
  }
2911
2918
 
2912
2919
  // src/utils/checkAllSizesKnown.ts
2913
- function isNullOrUndefined2(value) {
2914
- return value === null || value === void 0;
2915
- }
2916
- function getMountedIndicesInRange(state, start, end) {
2917
- if (!isNullOrUndefined2(end) && !isNullOrUndefined2(start) && start >= 0 && end >= 0) {
2918
- return Array.from(state.containerItemKeys.keys()).map((key) => state.indexByKey.get(key)).filter((index) => index !== void 0 && index >= start && index <= end).sort((a, b) => a - b);
2920
+ function checkAllSizesKnown(state, start, end) {
2921
+ if (start == null || end == null || start < 0 || end < start) {
2922
+ return false;
2919
2923
  }
2920
- return [];
2921
- }
2922
- function getMountedBufferedIndices(state) {
2923
- return getMountedIndicesInRange(state, state.startBuffered, state.endBuffered);
2924
- }
2925
- function getMountedNoBufferIndices(state) {
2926
- return getMountedIndicesInRange(state, state.startNoBuffer, state.endNoBuffer);
2927
- }
2928
- function checkAllSizesKnown(state, indices) {
2929
- return indices.length > 0 && indices.every((index) => {
2930
- const key = getId(state, index);
2931
- return key !== void 0 && state.sizesKnown.has(key);
2932
- });
2924
+ let hasMountedIndex = false;
2925
+ for (const key of state.containerItemKeys.keys()) {
2926
+ const index = state.indexByKey.get(key);
2927
+ if (index !== void 0 && index >= start && index <= end) {
2928
+ hasMountedIndex = true;
2929
+ const id = getId(state, index);
2930
+ if (id === void 0 || !state.sizesKnown.has(id)) {
2931
+ return false;
2932
+ }
2933
+ }
2934
+ }
2935
+ return hasMountedIndex;
2933
2936
  }
2934
2937
 
2935
2938
  // src/core/bootstrapInitialScroll.ts
@@ -3430,8 +3433,7 @@ function evaluateBootstrapInitialScroll(ctx) {
3430
3433
  bootstrapInitialScroll.targetIndexSeed = void 0;
3431
3434
  }
3432
3435
  const resolvedOffset = resolveInitialScrollOffset(ctx, initialScroll);
3433
- const mountedBufferedIndices = getMountedBufferedIndices(state);
3434
- const areMountedBufferedIndicesMeasured = checkAllSizesKnown(state, mountedBufferedIndices);
3436
+ const areMountedBufferedIndicesMeasured = checkAllSizesKnown(state, state.startBuffered, state.endBuffered);
3435
3437
  const didResolvedOffsetChange = Math.abs(bootstrapInitialScroll.scroll - resolvedOffset) > 1;
3436
3438
  const { data } = state.props;
3437
3439
  const visibleIndices = getBootstrapRevealVisibleIndices({
@@ -3862,7 +3864,14 @@ function updateSnapToOffsets(ctx) {
3862
3864
  }
3863
3865
 
3864
3866
  // src/core/updateItemPositions.ts
3865
- function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP, optimizeForVisibleWindow = false } = {
3867
+ function updateItemPositions(ctx, dataChanged, {
3868
+ doMVCP,
3869
+ forceFullUpdate = false,
3870
+ optimizeForVisibleWindow = false,
3871
+ scrollBottomBuffered,
3872
+ scrollVelocity,
3873
+ startIndex
3874
+ } = {
3866
3875
  doMVCP: false,
3867
3876
  forceFullUpdate: false,
3868
3877
  optimizeForVisibleWindow: false,
@@ -3889,7 +3898,7 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
3889
3898
  const extraData = peek$(ctx, "extraData");
3890
3899
  const layoutConfig = overrideItemLayout ? { span: 1 } : void 0;
3891
3900
  const lastScrollDelta = state.lastScrollDelta;
3892
- const velocity = getScrollVelocity(state);
3901
+ const velocity = scrollVelocity != null ? scrollVelocity : getScrollVelocity(state);
3893
3902
  const shouldOptimize = !forceFullUpdate && !dataChanged && (optimizeForVisibleWindow || Math.abs(velocity) > 0 || Platform.OS === "web" && state.scrollLength > 0 && lastScrollDelta > state.scrollLength);
3894
3903
  const maxVisibleArea = scrollBottomBuffered + 1e3;
3895
3904
  const useAverageSize = true;
@@ -4069,25 +4078,28 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
4069
4078
  const configId = viewabilityConfig.id;
4070
4079
  const viewabilityState = ensureViewabilityState(ctx, configId);
4071
4080
  const { viewableItems: previousViewableItems, start, end, startBuffered, endBuffered } = viewabilityState;
4072
- const viewabilityTokens = /* @__PURE__ */ new Map();
4081
+ let staleViewabilityAmountIds;
4073
4082
  for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
4074
- viewabilityTokens.set(
4083
+ const nextValue = computeViewability(
4084
+ state,
4085
+ ctx,
4086
+ viewabilityConfig,
4075
4087
  containerId,
4076
- computeViewability(
4077
- state,
4078
- ctx,
4079
- viewabilityConfig,
4080
- containerId,
4081
- value.key,
4082
- scrollSize,
4083
- value.item,
4084
- value.index
4085
- )
4088
+ value.key,
4089
+ scrollSize,
4090
+ value.item,
4091
+ value.index
4086
4092
  );
4093
+ if (nextValue.sizeVisible < 0) {
4094
+ staleViewabilityAmountIds != null ? staleViewabilityAmountIds : staleViewabilityAmountIds = [];
4095
+ staleViewabilityAmountIds.push(containerId);
4096
+ }
4087
4097
  }
4088
4098
  const changed = [];
4099
+ const previousViewableKeys = /* @__PURE__ */ new Set();
4089
4100
  if (previousViewableItems) {
4090
4101
  for (const viewToken of previousViewableItems) {
4102
+ previousViewableKeys.add(viewToken.key);
4091
4103
  const containerId = findContainerId(ctx, viewToken.key);
4092
4104
  if (!checkIsViewable(
4093
4105
  state,
@@ -4119,7 +4131,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
4119
4131
  key
4120
4132
  };
4121
4133
  viewableItems.push(viewToken);
4122
- if (!(previousViewableItems == null ? void 0 : previousViewableItems.find((v) => v.key === viewToken.key))) {
4134
+ if (!previousViewableKeys.has(viewToken.key)) {
4123
4135
  changed.push(viewToken);
4124
4136
  }
4125
4137
  }
@@ -4140,20 +4152,17 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
4140
4152
  onViewableItemsChanged({ changed, end, endBuffered, start, startBuffered, viewableItems });
4141
4153
  }
4142
4154
  }
4143
- for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
4144
- if (value.sizeVisible < 0) {
4145
- ctx.mapViewabilityAmountValues.delete(containerId);
4155
+ if (staleViewabilityAmountIds) {
4156
+ for (const containerId of staleViewabilityAmountIds) {
4157
+ const value = ctx.mapViewabilityAmountValues.get(containerId);
4158
+ if (value && value.sizeVisible < 0) {
4159
+ ctx.mapViewabilityAmountValues.delete(containerId);
4160
+ }
4146
4161
  }
4147
4162
  }
4148
4163
  }
4149
- function shallowEqual(prev, next) {
4150
- if (!prev) return false;
4151
- const keys = Object.keys(next);
4152
- for (let i = 0; i < keys.length; i++) {
4153
- const k = keys[i];
4154
- if (prev[k] !== next[k]) return false;
4155
- }
4156
- return true;
4164
+ function areViewabilityAmountTokensEqual(prev, next) {
4165
+ return !!prev && prev.containerId === next.containerId && prev.index === next.index && prev.isViewable === next.isViewable && prev.item === next.item && prev.key === next.key && prev.percentOfScroller === next.percentOfScroller && prev.percentVisible === next.percentVisible && prev.scrollSize === next.scrollSize && prev.size === next.size && prev.sizeVisible === next.sizeVisible;
4157
4166
  }
4158
4167
  function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
4159
4168
  const { sizes, scroll: scrollState } = state;
@@ -4178,7 +4187,7 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
4178
4187
  sizeVisible: -1
4179
4188
  };
4180
4189
  const prev2 = ctx.mapViewabilityAmountValues.get(containerId);
4181
- if (!shallowEqual(prev2, value2)) {
4190
+ if (!areViewabilityAmountTokensEqual(prev2, value2)) {
4182
4191
  ctx.mapViewabilityAmountValues.set(containerId, value2);
4183
4192
  const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
4184
4193
  if (cb) {
@@ -4208,7 +4217,7 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
4208
4217
  sizeVisible
4209
4218
  };
4210
4219
  const prev = ctx.mapViewabilityAmountValues.get(containerId);
4211
- if (!shallowEqual(prev, value)) {
4220
+ if (!areViewabilityAmountTokensEqual(prev, value)) {
4212
4221
  ctx.mapViewabilityAmountValues.set(containerId, value);
4213
4222
  const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
4214
4223
  if (cb) {
@@ -4259,126 +4268,152 @@ function getExpandedContainerPoolSize(dataLength, numContainers) {
4259
4268
  }
4260
4269
 
4261
4270
  // src/utils/findAvailableContainers.ts
4262
- function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers, protectedKeys) {
4271
+ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffered, pendingRemoval, getRequiredItemType, protectedKeys) {
4272
+ const numNeeded = needNewContainers.length;
4273
+ if (numNeeded === 0) {
4274
+ return [];
4275
+ }
4263
4276
  const numContainers = peek$(ctx, "numContainers");
4264
4277
  const state = ctx.state;
4265
4278
  const { stickyContainerPool, containerItemTypes } = state;
4266
4279
  const shouldAvoidAssignedContainerReuse = state.props.recycleItems && !!state.props.positionComponentInternal;
4267
- const result = [];
4268
- const availableContainers = [];
4269
- const pendingRemovalSet = new Set(pendingRemoval);
4280
+ const allocations = [];
4281
+ const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
4270
4282
  let pendingRemovalChanged = false;
4283
+ let nextNewContainerIndex = numContainers;
4284
+ const usedContainers = /* @__PURE__ */ new Set();
4285
+ let availableContainers;
4271
4286
  const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet;
4272
- const stickyHeaderItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyHeaderIndicesSet.has(index))) || [];
4273
4287
  const canReuseContainer = (containerIndex, requiredType) => {
4274
4288
  if (!requiredType) return true;
4275
4289
  const existingType = containerItemTypes.get(containerIndex);
4276
4290
  if (!existingType) return true;
4277
4291
  return existingType === requiredType;
4278
4292
  };
4279
- const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
4280
- let typeIndex = 0;
4281
- for (let i = 0; i < stickyHeaderItemIndices.length; i++) {
4282
- const requiredType = neededTypes[typeIndex];
4283
- let foundContainer = false;
4284
- for (const containerIndex of stickyContainerPool) {
4285
- const key = peek$(ctx, `containerItemKey${containerIndex}`);
4286
- const isPendingRemoval = pendingRemovalSet.has(containerIndex);
4287
- if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType) && !result.includes(containerIndex)) {
4288
- result.push(containerIndex);
4289
- if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
4290
- pendingRemovalChanged = true;
4291
- }
4292
- foundContainer = true;
4293
- if (requiredItemTypes) typeIndex++;
4294
- break;
4295
- }
4293
+ const pushAllocation = (itemIndex, itemType, containerIndex) => {
4294
+ allocations.push({
4295
+ containerIndex,
4296
+ itemIndex,
4297
+ itemType
4298
+ });
4299
+ usedContainers.add(containerIndex);
4300
+ if (pendingRemovalSet == null ? void 0 : pendingRemovalSet.delete(containerIndex)) {
4301
+ pendingRemovalChanged = true;
4296
4302
  }
4297
- if (!foundContainer) {
4298
- const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
4299
- result.push(newContainerIndex);
4303
+ };
4304
+ const pushNewContainer = (itemIndex, itemType, isSticky) => {
4305
+ const newContainerIndex = nextNewContainerIndex++;
4306
+ pushAllocation(itemIndex, itemType, newContainerIndex);
4307
+ if (isSticky) {
4300
4308
  stickyContainerPool.add(newContainerIndex);
4301
- if (requiredItemTypes) typeIndex++;
4302
- }
4303
- }
4304
- for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
4305
- if (stickyContainerPool.has(u)) {
4306
- continue;
4307
4309
  }
4308
- const key = peek$(ctx, `containerItemKey${u}`);
4309
- const requiredType = neededTypes[typeIndex];
4310
- const isPending = key !== void 0 && pendingRemovalSet.has(u);
4311
- const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
4312
- if (canUse) {
4313
- if (isPending) {
4314
- pendingRemovalSet.delete(u);
4315
- pendingRemovalChanged = true;
4316
- }
4317
- result.push(u);
4318
- if (requiredItemTypes) {
4319
- typeIndex++;
4320
- }
4310
+ return newContainerIndex;
4311
+ };
4312
+ const canUseContainer = (containerIndex, itemType) => {
4313
+ if (usedContainers.has(containerIndex) || stickyContainerPool.has(containerIndex)) {
4314
+ return false;
4321
4315
  }
4322
- }
4323
- if (!shouldAvoidAssignedContainerReuse) {
4324
- for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
4325
- if (stickyContainerPool.has(u)) {
4326
- continue;
4327
- }
4328
- const key = peek$(ctx, `containerItemKey${u}`);
4329
- if (key === void 0) continue;
4330
- if ((protectedKeys == null ? void 0 : protectedKeys.has(key)) && state.indexByKey.has(key)) continue;
4331
- const index = state.indexByKey.get(key);
4332
- const isOutOfView = index < startBuffered || index > endBuffered;
4333
- if (isOutOfView) {
4334
- const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
4335
- if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
4336
- availableContainers.push({ distance, index: u });
4316
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
4317
+ const isPending = !!(pendingRemovalSet == null ? void 0 : pendingRemovalSet.has(containerIndex));
4318
+ return (key === void 0 || isPending) && canReuseContainer(containerIndex, itemType);
4319
+ };
4320
+ const findStickyContainer = (itemType) => {
4321
+ let foundContainer;
4322
+ for (const containerIndex of stickyContainerPool) {
4323
+ if (!usedContainers.has(containerIndex)) {
4324
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
4325
+ const isPendingRemoval = !!(pendingRemovalSet == null ? void 0 : pendingRemovalSet.has(containerIndex));
4326
+ if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, itemType)) {
4327
+ foundContainer = containerIndex;
4328
+ break;
4337
4329
  }
4338
4330
  }
4339
4331
  }
4340
- }
4341
- const remaining = numNeeded - result.length;
4342
- if (remaining > 0) {
4343
- if (availableContainers.length > 0) {
4344
- if (availableContainers.length > remaining) {
4345
- availableContainers.sort(comparatorByDistance);
4346
- availableContainers.length = remaining;
4332
+ return foundContainer;
4333
+ };
4334
+ const findUnassignedOrPendingContainer = (itemType) => {
4335
+ let foundContainer;
4336
+ for (let containerIndex = 0; containerIndex < numContainers && foundContainer === void 0; containerIndex++) {
4337
+ if (canUseContainer(containerIndex, itemType)) {
4338
+ foundContainer = containerIndex;
4347
4339
  }
4348
- for (const container of availableContainers) {
4349
- result.push(container.index);
4350
- if (requiredItemTypes) {
4351
- typeIndex++;
4340
+ }
4341
+ return foundContainer;
4342
+ };
4343
+ const getAvailableContainers = () => {
4344
+ if (!availableContainers) {
4345
+ availableContainers = [];
4346
+ if (!shouldAvoidAssignedContainerReuse) {
4347
+ for (let containerIndex = 0; containerIndex < numContainers; containerIndex++) {
4348
+ if (usedContainers.has(containerIndex) || stickyContainerPool.has(containerIndex)) {
4349
+ continue;
4350
+ }
4351
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
4352
+ if (key === void 0) continue;
4353
+ if ((protectedKeys == null ? void 0 : protectedKeys.has(key)) && state.indexByKey.has(key)) continue;
4354
+ const index = state.indexByKey.get(key);
4355
+ const isOutOfView = index < startBuffered || index > endBuffered;
4356
+ if (isOutOfView) {
4357
+ const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
4358
+ availableContainers.push({ distance, index: containerIndex });
4359
+ }
4352
4360
  }
4361
+ availableContainers.sort(comparatorByDistance);
4353
4362
  }
4354
4363
  }
4355
- const stillNeeded = numNeeded - result.length;
4356
- if (stillNeeded > 0) {
4357
- for (let i = 0; i < stillNeeded; i++) {
4358
- result.push(numContainers + i);
4364
+ return availableContainers;
4365
+ };
4366
+ const findAvailableContainer = (itemType) => {
4367
+ const containers = getAvailableContainers();
4368
+ let matchIndex = -1;
4369
+ for (let i = 0; i < containers.length && matchIndex === -1; i++) {
4370
+ const containerIndex = containers[i].index;
4371
+ if (!usedContainers.has(containerIndex) && canReuseContainer(containerIndex, itemType)) {
4372
+ matchIndex = i;
4359
4373
  }
4360
- if (IS_DEV && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
4361
- console.warn(
4362
- "[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize.",
4363
- {
4364
- debugInfo: {
4365
- numContainers,
4366
- numContainersPooled: peek$(ctx, "numContainersPooled"),
4367
- numNeeded,
4368
- stillNeeded
4369
- }
4370
- }
4371
- );
4374
+ }
4375
+ return matchIndex === -1 ? void 0 : containers.splice(matchIndex, 1)[0].index;
4376
+ };
4377
+ for (const itemIndex of needNewContainers) {
4378
+ const itemType = getRequiredItemType == null ? void 0 : getRequiredItemType(itemIndex);
4379
+ const isSticky = stickyHeaderIndicesSet.has(itemIndex);
4380
+ let containerIndex;
4381
+ if (isSticky) {
4382
+ containerIndex = findStickyContainer(itemType);
4383
+ } else {
4384
+ containerIndex = findUnassignedOrPendingContainer(itemType);
4385
+ if (containerIndex === void 0) {
4386
+ containerIndex = findAvailableContainer(itemType);
4372
4387
  }
4373
4388
  }
4389
+ if (containerIndex !== void 0) {
4390
+ pushAllocation(itemIndex, itemType, containerIndex);
4391
+ } else {
4392
+ pushNewContainer(itemIndex, itemType, isSticky);
4393
+ }
4374
4394
  }
4375
4395
  if (pendingRemovalChanged) {
4376
4396
  pendingRemoval.length = 0;
4377
- for (const value of pendingRemovalSet) {
4378
- pendingRemoval.push(value);
4397
+ if (pendingRemovalSet) {
4398
+ for (const value of pendingRemovalSet) {
4399
+ pendingRemoval.push(value);
4400
+ }
4379
4401
  }
4380
4402
  }
4381
- return result.sort(comparatorDefault);
4403
+ if (IS_DEV && nextNewContainerIndex > peek$(ctx, "numContainersPooled")) {
4404
+ console.warn(
4405
+ "[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize.",
4406
+ {
4407
+ debugInfo: {
4408
+ numContainers,
4409
+ numContainersPooled: peek$(ctx, "numContainersPooled"),
4410
+ numNeeded,
4411
+ stillNeeded: nextNewContainerIndex - numContainers
4412
+ }
4413
+ }
4414
+ );
4415
+ }
4416
+ return allocations;
4382
4417
  }
4383
4418
  function comparatorByDistance(a, b) {
4384
4419
  return b.distance - a.distance;
@@ -4404,21 +4439,28 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
4404
4439
  }
4405
4440
  return -1;
4406
4441
  }
4407
- function getActiveStickyIndices(ctx, stickyHeaderIndices) {
4442
+ function isStickyIndexActive(ctx, targetIndex) {
4408
4443
  const state = ctx.state;
4409
- return new Set(
4410
- Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyHeaderIndices.has(idx))
4411
- );
4444
+ let isActive = false;
4445
+ for (const containerIndex of state.stickyContainerPool) {
4446
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
4447
+ const itemIndex = key ? state.indexByKey.get(key) : void 0;
4448
+ if (itemIndex === targetIndex) {
4449
+ isActive = true;
4450
+ break;
4451
+ }
4452
+ }
4453
+ return isActive;
4412
4454
  }
4413
- function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, needNewContainersSet, startBuffered, endBuffered) {
4455
+ function handleStickyActivation(ctx, stickyArray, currentStickyIdx, needNewContainers, needNewContainersSet, startBuffered, endBuffered) {
4414
4456
  var _a3;
4415
4457
  const state = ctx.state;
4416
- const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
4417
4458
  set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
4418
4459
  for (let offset = 0; offset <= 1; offset++) {
4419
4460
  const idx = currentStickyIdx - offset;
4420
- if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
4461
+ if (idx < 0) continue;
4421
4462
  const stickyIndex = stickyArray[idx];
4463
+ if (isStickyIndexActive(ctx, stickyIndex)) continue;
4422
4464
  const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
4423
4465
  if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered) && !needNewContainersSet.has(stickyIndex)) {
4424
4466
  needNewContainersSet.add(stickyIndex);
@@ -4460,10 +4502,86 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
4460
4502
  }
4461
4503
  }
4462
4504
  }
4505
+ function trackVisibleRange(range, i, top, size, scroll, scrollBottom) {
4506
+ let didPassVisibleEnd = false;
4507
+ if (range.startNoBuffer === null && top + size > scroll) {
4508
+ range.startNoBuffer = i;
4509
+ }
4510
+ if (range.firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
4511
+ range.firstFullyOnScreenIndex = i;
4512
+ }
4513
+ if (range.startNoBuffer !== null) {
4514
+ if (top <= scrollBottom) {
4515
+ range.endNoBuffer = i;
4516
+ } else {
4517
+ didPassVisibleEnd = true;
4518
+ }
4519
+ }
4520
+ return didPassVisibleEnd;
4521
+ }
4522
+ function getIdsInVisibleRange(state, range) {
4523
+ var _a3, _b;
4524
+ const idsInView = [];
4525
+ const firstVisibleAnchorIndex = (_a3 = range.firstFullyOnScreenIndex) != null ? _a3 : range.startNoBuffer;
4526
+ if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && range.endNoBuffer !== null) {
4527
+ for (let i = firstVisibleAnchorIndex; i <= range.endNoBuffer; i++) {
4528
+ const id = (_b = state.idCache[i]) != null ? _b : getId(state, i);
4529
+ idsInView.push(id);
4530
+ }
4531
+ }
4532
+ return idsInView;
4533
+ }
4534
+ function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, scrollLength, scroll, scrollBottom) {
4535
+ var _a3, _b;
4536
+ const state = ctx.state;
4537
+ const {
4538
+ endBuffered,
4539
+ idCache,
4540
+ positions,
4541
+ props: { data },
4542
+ sizes,
4543
+ startBuffered
4544
+ } = state;
4545
+ if (startBuffered === null || endBuffered === null || startBuffered < 0 || endBuffered < startBuffered) {
4546
+ return;
4547
+ }
4548
+ const visibleRange = {
4549
+ endNoBuffer: null,
4550
+ firstFullyOnScreenIndex: void 0,
4551
+ startNoBuffer: null
4552
+ };
4553
+ for (let i = startBuffered; i <= endBuffered && i < data.length; i++) {
4554
+ const id = (_a3 = idCache[i]) != null ? _a3 : getId(state, i);
4555
+ const size = (_b = sizes.get(id)) != null ? _b : getItemSize(ctx, id, i, data[i]);
4556
+ const top = positions[i];
4557
+ const didPassVisibleEnd = trackVisibleRange(visibleRange, i, top, size, scroll, scrollBottom);
4558
+ if (didPassVisibleEnd) {
4559
+ break;
4560
+ }
4561
+ }
4562
+ Object.assign(state, {
4563
+ endNoBuffer: visibleRange.endNoBuffer,
4564
+ firstFullyOnScreenIndex: visibleRange.firstFullyOnScreenIndex,
4565
+ idsInView: getIdsInVisibleRange(state, visibleRange),
4566
+ startNoBuffer: visibleRange.startNoBuffer
4567
+ });
4568
+ if (visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
4569
+ updateViewableItems(
4570
+ state,
4571
+ ctx,
4572
+ viewabilityConfigCallbackPairs,
4573
+ scrollLength,
4574
+ visibleRange.startNoBuffer,
4575
+ visibleRange.endNoBuffer,
4576
+ startBuffered,
4577
+ endBuffered
4578
+ );
4579
+ }
4580
+ }
4463
4581
  function calculateItemsInView(ctx, params = {}) {
4464
4582
  const state = ctx.state;
4465
4583
  batchedUpdates(() => {
4466
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
4584
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
4467
4585
  const {
4468
4586
  columns,
4469
4587
  containerItemKeys,
@@ -4564,6 +4682,15 @@ function calculateItemsInView(ctx, params = {}) {
4564
4682
  state.scrollForNextCalculateItemsInView = void 0;
4565
4683
  } else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
4566
4684
  if (Platform.OS !== "web" || !isInMVCPActiveMode(state)) {
4685
+ if (viewabilityConfigCallbackPairs) {
4686
+ updateViewabilityForCachedRange(
4687
+ ctx,
4688
+ viewabilityConfigCallbackPairs,
4689
+ scrollLength,
4690
+ scroll,
4691
+ scrollBottom
4692
+ );
4693
+ }
4567
4694
  finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
4568
4695
  return;
4569
4696
  }
@@ -4580,6 +4707,7 @@ function calculateItemsInView(ctx, params = {}) {
4580
4707
  forceFullUpdate: !!forceFullItemPositions,
4581
4708
  optimizeForVisibleWindow,
4582
4709
  scrollBottomBuffered,
4710
+ scrollVelocity: speed,
4583
4711
  startIndex
4584
4712
  });
4585
4713
  totalSize = getContentSize(ctx);
@@ -4605,10 +4733,8 @@ function calculateItemsInView(ctx, params = {}) {
4605
4733
  updateScroll2(state.scroll);
4606
4734
  updateScrollRange();
4607
4735
  }
4608
- let startNoBuffer = null;
4609
4736
  let startBuffered = null;
4610
4737
  let startBufferedId = null;
4611
- let endNoBuffer = null;
4612
4738
  let endBuffered = null;
4613
4739
  let loopStart = (_f = suppressInitialScrollSideEffects ? bootstrapInitialScrollState == null ? void 0 : bootstrapInitialScrollState.targetIndexSeed : void 0) != null ? _f : !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
4614
4740
  for (let i = loopStart; i >= 0; i--) {
@@ -4642,19 +4768,18 @@ function calculateItemsInView(ctx, params = {}) {
4642
4768
  maxIndexRendered = Math.max(maxIndexRendered, index);
4643
4769
  }
4644
4770
  }
4645
- let firstFullyOnScreenIndex;
4771
+ const visibleRange = {
4772
+ endNoBuffer: null,
4773
+ firstFullyOnScreenIndex: void 0,
4774
+ startNoBuffer: null
4775
+ };
4646
4776
  const dataLength = data.length;
4647
4777
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
4648
4778
  const id = (_i = idCache[i]) != null ? _i : getId(state, i);
4649
4779
  const size = (_j = sizes.get(id)) != null ? _j : getItemSize(ctx, id, i, data[i]);
4650
4780
  const top = positions[i];
4651
4781
  if (!foundEnd) {
4652
- if (startNoBuffer === null && top + size > scroll) {
4653
- startNoBuffer = i;
4654
- }
4655
- if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
4656
- firstFullyOnScreenIndex = i;
4657
- }
4782
+ trackVisibleRange(visibleRange, i, top, size, scroll, scrollBottom);
4658
4783
  if (startBuffered === null && top + size > scrollTopBuffered) {
4659
4784
  startBuffered = i;
4660
4785
  startBufferedId = id;
@@ -4664,10 +4789,7 @@ function calculateItemsInView(ctx, params = {}) {
4664
4789
  nextTop = top;
4665
4790
  }
4666
4791
  }
4667
- if (startNoBuffer !== null) {
4668
- if (top <= scrollBottom) {
4669
- endNoBuffer = i;
4670
- }
4792
+ if (visibleRange.startNoBuffer !== null) {
4671
4793
  if (top <= scrollBottomBuffered) {
4672
4794
  endBuffered = i;
4673
4795
  if (scrollBottomBuffered > totalSize) {
@@ -4681,22 +4803,14 @@ function calculateItemsInView(ctx, params = {}) {
4681
4803
  }
4682
4804
  }
4683
4805
  }
4684
- const idsInView = [];
4685
- const firstVisibleAnchorIndex = firstFullyOnScreenIndex != null ? firstFullyOnScreenIndex : startNoBuffer;
4686
- if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && endNoBuffer !== null) {
4687
- for (let i = firstVisibleAnchorIndex; i <= endNoBuffer; i++) {
4688
- const id = (_k = idCache[i]) != null ? _k : getId(state, i);
4689
- idsInView.push(id);
4690
- }
4691
- }
4692
4806
  Object.assign(state, {
4693
4807
  endBuffered,
4694
- endNoBuffer,
4695
- firstFullyOnScreenIndex,
4696
- idsInView,
4808
+ endNoBuffer: visibleRange.endNoBuffer,
4809
+ firstFullyOnScreenIndex: visibleRange.firstFullyOnScreenIndex,
4810
+ idsInView: getIdsInVisibleRange(state, visibleRange),
4697
4811
  startBuffered,
4698
4812
  startBufferedId,
4699
- startNoBuffer
4813
+ startNoBuffer: visibleRange.startNoBuffer
4700
4814
  });
4701
4815
  if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
4702
4816
  state.scrollForNextCalculateItemsInView = isNullOrUndefined(nextTop) && isNullOrUndefined(nextBottom) ? void 0 : {
@@ -4718,7 +4832,7 @@ function calculateItemsInView(ctx, params = {}) {
4718
4832
  const needNewContainers = [];
4719
4833
  const needNewContainersSet = /* @__PURE__ */ new Set();
4720
4834
  for (let i = startBuffered; i <= endBuffered; i++) {
4721
- const id = (_l = idCache[i]) != null ? _l : getId(state, i);
4835
+ const id = (_k = idCache[i]) != null ? _k : getId(state, i);
4722
4836
  if (!containerItemKeys.has(id)) {
4723
4837
  needNewContainersSet.add(i);
4724
4838
  needNewContainers.push(i);
@@ -4727,7 +4841,7 @@ function calculateItemsInView(ctx, params = {}) {
4727
4841
  if (alwaysRenderArr.length > 0) {
4728
4842
  for (const index of alwaysRenderArr) {
4729
4843
  if (index < 0 || index >= dataLength) continue;
4730
- const id = (_m = idCache[index]) != null ? _m : getId(state, index);
4844
+ const id = (_l = idCache[index]) != null ? _l : getId(state, index);
4731
4845
  if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
4732
4846
  needNewContainersSet.add(index);
4733
4847
  needNewContainers.push(index);
@@ -4737,7 +4851,6 @@ function calculateItemsInView(ctx, params = {}) {
4737
4851
  if (stickyHeaderIndicesArr.length > 0) {
4738
4852
  handleStickyActivation(
4739
4853
  ctx,
4740
- stickyHeaderIndicesSet,
4741
4854
  stickyHeaderIndicesArr,
4742
4855
  currentStickyIdx,
4743
4856
  needNewContainers,
@@ -4749,35 +4862,34 @@ function calculateItemsInView(ctx, params = {}) {
4749
4862
  set$(ctx, "activeStickyIndex", -1);
4750
4863
  }
4751
4864
  if (needNewContainers.length > 0) {
4752
- const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
4865
+ const getRequiredItemType = getItemType ? (i) => {
4753
4866
  const itemType = getItemType(data[i], i);
4754
4867
  return itemType !== void 0 ? String(itemType) : "";
4755
- }) : void 0;
4756
- const availableContainers = findAvailableContainers(
4868
+ } : void 0;
4869
+ const availableContainerAllocations = findAvailableContainers(
4757
4870
  ctx,
4758
- needNewContainers.length,
4871
+ needNewContainers,
4759
4872
  startBuffered,
4760
4873
  endBuffered,
4761
4874
  pendingRemoval,
4762
- requiredItemTypes,
4763
- needNewContainers,
4875
+ getRequiredItemType,
4764
4876
  protectedContainerKeys
4765
4877
  );
4766
- for (let idx = 0; idx < needNewContainers.length; idx++) {
4767
- const i = needNewContainers[idx];
4768
- const containerIndex = availableContainers[idx];
4769
- const id = (_n = idCache[i]) != null ? _n : getId(state, i);
4878
+ for (const allocation of availableContainerAllocations) {
4879
+ const i = allocation.itemIndex;
4880
+ const containerIndex = allocation.containerIndex;
4881
+ const id = (_m = idCache[i]) != null ? _m : getId(state, i);
4770
4882
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
4771
4883
  if (oldKey && oldKey !== id) {
4772
4884
  containerItemKeys.delete(oldKey);
4773
4885
  }
4774
4886
  set$(ctx, `containerItemKey${containerIndex}`, id);
4775
4887
  set$(ctx, `containerItemData${containerIndex}`, data[i]);
4776
- if (requiredItemTypes) {
4777
- state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
4888
+ if (allocation.itemType !== void 0) {
4889
+ state.containerItemTypes.set(containerIndex, allocation.itemType);
4778
4890
  }
4779
4891
  containerItemKeys.set(id, containerIndex);
4780
- (_o = state.userScrollAnchorReset) == null ? void 0 : _o.keys.add(id);
4892
+ (_n = state.userScrollAnchorReset) == null ? void 0 : _n.keys.add(id);
4781
4893
  const containerSticky = `containerSticky${containerIndex}`;
4782
4894
  const isSticky = stickyHeaderIndicesSet.has(i);
4783
4895
  const isAlwaysRender = alwaysRenderSet.has(i);
@@ -4815,7 +4927,7 @@ function calculateItemsInView(ctx, params = {}) {
4815
4927
  if (alwaysRenderArr.length > 0) {
4816
4928
  for (const index of alwaysRenderArr) {
4817
4929
  if (index < 0 || index >= dataLength) continue;
4818
- const id = (_p = idCache[index]) != null ? _p : getId(state, index);
4930
+ const id = (_o = idCache[index]) != null ? _o : getId(state, index);
4819
4931
  const containerIndex = containerItemKeys.get(id);
4820
4932
  if (containerIndex !== void 0) {
4821
4933
  state.stickyContainerPool.add(containerIndex);
@@ -4834,10 +4946,11 @@ function calculateItemsInView(ctx, params = {}) {
4834
4946
  alwaysRenderSet
4835
4947
  );
4836
4948
  }
4949
+ const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
4837
4950
  let didChangePositions = false;
4838
4951
  for (let i = 0; i < numContainers; i++) {
4839
4952
  const itemKey = peek$(ctx, `containerItemKey${i}`);
4840
- if (pendingRemoval.includes(i)) {
4953
+ if (pendingRemovalSet == null ? void 0 : pendingRemovalSet.has(i)) {
4841
4954
  if (itemKey !== void 0) {
4842
4955
  containerItemKeys.delete(itemKey);
4843
4956
  }
@@ -4868,24 +4981,24 @@ function calculateItemsInView(ctx, params = {}) {
4868
4981
  evaluateBootstrapInitialScroll(ctx);
4869
4982
  return;
4870
4983
  }
4871
- const mountedBufferedIndices = getMountedBufferedIndices(state);
4872
- const mountedNoBufferIndices = getMountedNoBufferIndices(state);
4873
- const readinessIndices = hasActiveInitialScroll(state) ? mountedBufferedIndices : mountedNoBufferIndices.length > 0 ? mountedNoBufferIndices : mountedBufferedIndices;
4874
- if (!queuedInitialLayout && readinessIndices.length > 0 && checkAllSizesKnown(state, readinessIndices)) {
4875
- setDidLayout(ctx);
4876
- handleInitialScrollLayoutReady(ctx);
4984
+ if (!queuedInitialLayout && !state.didContainersLayout) {
4985
+ const isInitialLayoutReady = hasActiveInitialScroll(state) ? checkAllSizesKnown(state, state.startBuffered, state.endBuffered) : checkAllSizesKnown(state, state.startNoBuffer, state.endNoBuffer) || checkAllSizesKnown(state, state.startBuffered, state.endBuffered);
4986
+ if (isInitialLayoutReady) {
4987
+ setDidLayout(ctx);
4988
+ handleInitialScrollLayoutReady(ctx);
4989
+ }
4877
4990
  }
4878
- if (viewabilityConfigCallbackPairs && startNoBuffer !== null && endNoBuffer !== null) {
4991
+ if (viewabilityConfigCallbackPairs && visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
4879
4992
  if (!didMVCPAdjustScroll) {
4880
4993
  updateViewableItems(
4881
4994
  ctx.state,
4882
4995
  ctx,
4883
4996
  viewabilityConfigCallbackPairs,
4884
4997
  scrollLength,
4885
- startNoBuffer,
4886
- endNoBuffer,
4887
- startBuffered != null ? startBuffered : startNoBuffer,
4888
- endBuffered != null ? endBuffered : endNoBuffer
4998
+ visibleRange.startNoBuffer,
4999
+ visibleRange.endNoBuffer,
5000
+ startBuffered != null ? startBuffered : visibleRange.startNoBuffer,
5001
+ endBuffered != null ? endBuffered : visibleRange.endNoBuffer
4889
5002
  );
4890
5003
  }
4891
5004
  }
@@ -5346,6 +5459,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5346
5459
  } = state;
5347
5460
  if (!data) return;
5348
5461
  const index = state.indexByKey.get(itemKey);
5462
+ let resolvedMeasurementItem;
5349
5463
  if (getFixedItemSize) {
5350
5464
  if (index === void 0) {
5351
5465
  return;
@@ -5356,6 +5470,12 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5356
5470
  }
5357
5471
  const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
5358
5472
  const size2 = getFixedItemSize(itemData, index, type);
5473
+ resolvedMeasurementItem = {
5474
+ didResolveFixedItemSize: true,
5475
+ fixedItemSize: size2,
5476
+ itemData,
5477
+ itemType: type
5478
+ };
5359
5479
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
5360
5480
  updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5361
5481
  return;
@@ -5365,7 +5485,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5365
5485
  let shouldMaintainScrollAtEnd = false;
5366
5486
  let minIndexSizeChanged;
5367
5487
  const prevSizeKnown = state.sizesKnown.get(itemKey);
5368
- const diff = updateOneItemSize(ctx, itemKey, sizeObj);
5488
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem);
5369
5489
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
5370
5490
  if (diff !== 0) {
5371
5491
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -5390,7 +5510,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5390
5510
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
5391
5511
  }
5392
5512
  updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5393
- if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
5513
+ if (didContainersLayout || checkAllSizesKnown(state, state.startBuffered, state.endBuffered)) {
5394
5514
  if (needsRecalculate) {
5395
5515
  state.scrollForNextCalculateItemsInView = void 0;
5396
5516
  runOrScheduleMVCPRecalculate(ctx);
@@ -5404,8 +5524,8 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5404
5524
  }
5405
5525
  }
5406
5526
  }
5407
- function updateOneItemSize(ctx, itemKey, sizeObj) {
5408
- var _a3, _b;
5527
+ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
5528
+ var _a3, _b, _c;
5409
5529
  const state = ctx.state;
5410
5530
  const {
5411
5531
  indexByKey,
@@ -5415,14 +5535,19 @@ function updateOneItemSize(ctx, itemKey, sizeObj) {
5415
5535
  } = state;
5416
5536
  if (!data) return 0;
5417
5537
  const index = indexByKey.get(itemKey);
5418
- const itemData = data[index];
5419
- let itemType;
5420
- let fixedItemSize;
5421
- if (getFixedItemSize) {
5422
- itemType = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
5538
+ const itemData = (_a3 = resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.itemData) != null ? _a3 : data[index];
5539
+ let itemType = resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.itemType;
5540
+ let fixedItemSize = resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.fixedItemSize;
5541
+ if (getFixedItemSize && !(resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.didResolveFixedItemSize)) {
5542
+ itemType = getItemType ? (_b = getItemType(itemData, index)) != null ? _b : "" : "";
5423
5543
  fixedItemSize = getFixedItemSize(itemData, index, itemType);
5424
5544
  }
5425
- const prevSize = getItemSize(ctx, itemKey, index, itemData);
5545
+ const resolvedItemSize = (resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.didResolveFixedItemSize) || itemType !== void 0 || fixedItemSize !== void 0 ? {
5546
+ didResolveFixedItemSize: resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.didResolveFixedItemSize,
5547
+ fixedItemSize,
5548
+ itemType
5549
+ } : void 0;
5550
+ const prevSize = getItemSize(ctx, itemKey, index, itemData, void 0, void 0, void 0, resolvedItemSize);
5426
5551
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
5427
5552
  const prevSizeKnown = sizesKnown.get(itemKey);
5428
5553
  if (Platform.OS !== "web" && prevSizeKnown !== void 0 && isNativeLayoutNoise(rawSize - prevSizeKnown)) {
@@ -5431,7 +5556,7 @@ function updateOneItemSize(ctx, itemKey, sizeObj) {
5431
5556
  const size = Platform.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
5432
5557
  sizesKnown.set(itemKey, size);
5433
5558
  if (fixedItemSize === void 0 && size > 0) {
5434
- itemType != null ? itemType : itemType = getItemType ? (_b = getItemType(itemData, index)) != null ? _b : "" : "";
5559
+ itemType != null ? itemType : itemType = getItemType ? (_c = getItemType(itemData, index)) != null ? _c : "" : "";
5435
5560
  let averages = averageSizes[itemType];
5436
5561
  if (!averages) {
5437
5562
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
@@ -5546,6 +5671,11 @@ function getAverageItemSizes(state) {
5546
5671
  }
5547
5672
  return averageItemSizes;
5548
5673
  }
5674
+ function triggerMountedContainerLayouts(ctx) {
5675
+ for (const triggerLayout of ctx.containerLayoutTriggers.values()) {
5676
+ triggerLayout();
5677
+ }
5678
+ }
5549
5679
  function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
5550
5680
  const state = ctx.state;
5551
5681
  const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
@@ -5671,6 +5801,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
5671
5801
  state.columns.length = 0;
5672
5802
  state.columnSpans.length = 0;
5673
5803
  }
5804
+ triggerMountedContainerLayouts(ctx);
5674
5805
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
5675
5806
  };
5676
5807
  return {
@@ -6478,7 +6609,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
6478
6609
  viewabilityConfigCallbackPairs
6479
6610
  });
6480
6611
  state.viewabilityConfigCallbackPairs = viewability;
6481
- state.enableScrollForNextCalculateItemsInView = !viewability;
6612
+ state.enableScrollForNextCalculateItemsInView = true;
6482
6613
  if (viewability) {
6483
6614
  state.scrollForNextCalculateItemsInView = void 0;
6484
6615
  }