@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.js CHANGED
@@ -153,6 +153,7 @@ function StateProvider({ children }) {
153
153
  const [value] = React3__namespace.useState(() => ({
154
154
  animatedScrollY: createAnimatedValue(0),
155
155
  columnWrapperStyle: void 0,
156
+ containerLayoutTriggers: /* @__PURE__ */ new Map(),
156
157
  contextNum: contextNum++,
157
158
  listeners: /* @__PURE__ */ new Map(),
158
159
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
@@ -420,9 +421,6 @@ function roundSize(size) {
420
421
  function isNullOrUndefined(value) {
421
422
  return value === null || value === void 0;
422
423
  }
423
- function comparatorDefault(a, b) {
424
- return a - b;
425
- }
426
424
  function getPadding(s, type) {
427
425
  var _a3, _b, _c;
428
426
  const axisPadding = type === "Left" || type === "Right" ? s.paddingHorizontal : s.paddingVertical;
@@ -930,18 +928,6 @@ var Container = typedMemo(function Container2({
930
928
  [itemKey, data, extraData]
931
929
  );
932
930
  const { index, renderedItem } = renderedItemInfo || {};
933
- const contextValue = React3.useMemo(() => {
934
- ctx.viewRefs.set(id, ref);
935
- return {
936
- containerId: id,
937
- index,
938
- itemKey,
939
- triggerLayout: () => {
940
- forceLayoutRender((v) => v + 1);
941
- },
942
- value: data
943
- };
944
- }, [id, itemKey, index, data]);
945
931
  const onLayoutChange = React3.useCallback((rectangle) => {
946
932
  const {
947
933
  horizontal: currentHorizontal,
@@ -985,6 +971,27 @@ var Container = typedMemo(function Container2({
985
971
  doUpdate();
986
972
  }
987
973
  }, []);
974
+ const triggerLayout = React3.useCallback(() => {
975
+ forceLayoutRender((v) => v + 1);
976
+ }, []);
977
+ const contextValue = React3.useMemo(() => {
978
+ ctx.viewRefs.set(id, ref);
979
+ return {
980
+ containerId: id,
981
+ index,
982
+ itemKey,
983
+ triggerLayout,
984
+ value: data
985
+ };
986
+ }, [id, itemKey, index, data, triggerLayout]);
987
+ React3.useLayoutEffect(() => {
988
+ ctx.containerLayoutTriggers.set(id, triggerLayout);
989
+ return () => {
990
+ if (ctx.containerLayoutTriggers.get(id) === triggerLayout) {
991
+ ctx.containerLayoutTriggers.delete(id);
992
+ }
993
+ };
994
+ }, [ctx, id, triggerLayout]);
988
995
  const { onLayout } = useOnLayoutSync(
989
996
  {
990
997
  onLayoutChange,
@@ -2462,14 +2469,14 @@ function setSize(ctx, itemKey, size, notifyTotalSize = true) {
2462
2469
  }
2463
2470
 
2464
2471
  // src/utils/getItemSize.ts
2465
- function getKnownOrFixedSize(ctx, key, index, data) {
2466
- var _a3;
2472
+ function getKnownOrFixedSize(ctx, key, index, data, resolved) {
2473
+ var _a3, _b;
2467
2474
  const state = ctx.state;
2468
2475
  const { getFixedItemSize, getItemType } = state.props;
2469
2476
  let size = key ? state.sizesKnown.get(key) : void 0;
2470
2477
  if (size === void 0 && key && getFixedItemSize) {
2471
- const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
2472
- size = getFixedItemSize(data, index, itemType);
2478
+ const itemType = (_b = resolved == null ? void 0 : resolved.itemType) != null ? _b : getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
2479
+ size = (resolved == null ? void 0 : resolved.didResolveFixedItemSize) ? resolved.fixedItemSize : getFixedItemSize(data, index, itemType);
2473
2480
  if (size !== void 0) {
2474
2481
  state.sizesKnown.set(key, size);
2475
2482
  }
@@ -2488,8 +2495,8 @@ function areKnownOrFixedItemSizesAvailable(ctx, startIndex, endIndex) {
2488
2495
  }
2489
2496
  return true;
2490
2497
  }
2491
- function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, notifyTotalSize) {
2492
- var _a3, _b, _c;
2498
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, notifyTotalSize, resolved) {
2499
+ var _a3, _b, _c, _d;
2493
2500
  const state = ctx.state;
2494
2501
  const {
2495
2502
  sizes,
@@ -2508,14 +2515,14 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, no
2508
2515
  return renderedSize;
2509
2516
  }
2510
2517
  }
2511
- size = getKnownOrFixedSize(ctx, key, index, data);
2518
+ size = getKnownOrFixedSize(ctx, key, index, data, resolved);
2512
2519
  if (size !== void 0) {
2513
2520
  setSize(ctx, key, size, notifyTotalSize);
2514
2521
  return size;
2515
2522
  }
2516
- const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
2523
+ const itemType = (_b = resolved == null ? void 0 : resolved.itemType) != null ? _b : getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
2517
2524
  if (useAverageSize && !scrollingTo) {
2518
- const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
2525
+ const averageSizeForType = (_c = averageSizes[itemType]) == null ? void 0 : _c.avg;
2519
2526
  if (averageSizeForType !== void 0) {
2520
2527
  size = roundSize(averageSizeForType);
2521
2528
  }
@@ -2524,7 +2531,7 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize, no
2524
2531
  return renderedSize;
2525
2532
  }
2526
2533
  if (size === void 0 && useAverageSize && scrollingTo) {
2527
- const averageSizeForType = (_c = scrollingTo.averageSizeSnapshot) == null ? void 0 : _c[itemType];
2534
+ const averageSizeForType = (_d = scrollingTo.averageSizeSnapshot) == null ? void 0 : _d[itemType];
2528
2535
  if (averageSizeForType !== void 0) {
2529
2536
  size = roundSize(averageSizeForType);
2530
2537
  }
@@ -3085,8 +3092,8 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
3085
3092
  if ((options == null ? void 0 : options.markHasScrolled) !== false) {
3086
3093
  state.hasScrolled = true;
3087
3094
  }
3088
- state.lastBatchingAction = Date.now();
3089
3095
  const currentTime = Date.now();
3096
+ state.lastBatchingAction = currentTime;
3090
3097
  const adjust = scrollAdjustHandler.getAdjust();
3091
3098
  const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
3092
3099
  if (adjustChanged) {
@@ -3395,26 +3402,22 @@ function advanceCurrentInitialScrollSession(ctx, options) {
3395
3402
  }
3396
3403
 
3397
3404
  // src/utils/checkAllSizesKnown.ts
3398
- function isNullOrUndefined2(value) {
3399
- return value === null || value === void 0;
3400
- }
3401
- function getMountedIndicesInRange(state, start, end) {
3402
- if (!isNullOrUndefined2(end) && !isNullOrUndefined2(start) && start >= 0 && end >= 0) {
3403
- 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);
3405
+ function checkAllSizesKnown(state, start, end) {
3406
+ if (start == null || end == null || start < 0 || end < start) {
3407
+ return false;
3404
3408
  }
3405
- return [];
3406
- }
3407
- function getMountedBufferedIndices(state) {
3408
- return getMountedIndicesInRange(state, state.startBuffered, state.endBuffered);
3409
- }
3410
- function getMountedNoBufferIndices(state) {
3411
- return getMountedIndicesInRange(state, state.startNoBuffer, state.endNoBuffer);
3412
- }
3413
- function checkAllSizesKnown(state, indices) {
3414
- return indices.length > 0 && indices.every((index) => {
3415
- const key = getId(state, index);
3416
- return key !== void 0 && state.sizesKnown.has(key);
3417
- });
3409
+ let hasMountedIndex = false;
3410
+ for (const key of state.containerItemKeys.keys()) {
3411
+ const index = state.indexByKey.get(key);
3412
+ if (index !== void 0 && index >= start && index <= end) {
3413
+ hasMountedIndex = true;
3414
+ const id = getId(state, index);
3415
+ if (id === void 0 || !state.sizesKnown.has(id)) {
3416
+ return false;
3417
+ }
3418
+ }
3419
+ }
3420
+ return hasMountedIndex;
3418
3421
  }
3419
3422
 
3420
3423
  // src/core/bootstrapInitialScroll.ts
@@ -3915,8 +3918,7 @@ function evaluateBootstrapInitialScroll(ctx) {
3915
3918
  bootstrapInitialScroll.targetIndexSeed = void 0;
3916
3919
  }
3917
3920
  const resolvedOffset = resolveInitialScrollOffset(ctx, initialScroll);
3918
- const mountedBufferedIndices = getMountedBufferedIndices(state);
3919
- const areMountedBufferedIndicesMeasured = checkAllSizesKnown(state, mountedBufferedIndices);
3921
+ const areMountedBufferedIndicesMeasured = checkAllSizesKnown(state, state.startBuffered, state.endBuffered);
3920
3922
  const didResolvedOffsetChange = Math.abs(bootstrapInitialScroll.scroll - resolvedOffset) > 1;
3921
3923
  const { data } = state.props;
3922
3924
  const visibleIndices = getBootstrapRevealVisibleIndices({
@@ -4492,7 +4494,14 @@ function updateSnapToOffsets(ctx) {
4492
4494
  }
4493
4495
 
4494
4496
  // src/core/updateItemPositions.ts
4495
- function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP, optimizeForVisibleWindow = false } = {
4497
+ function updateItemPositions(ctx, dataChanged, {
4498
+ doMVCP,
4499
+ forceFullUpdate = false,
4500
+ optimizeForVisibleWindow = false,
4501
+ scrollBottomBuffered,
4502
+ scrollVelocity,
4503
+ startIndex
4504
+ } = {
4496
4505
  doMVCP: false,
4497
4506
  forceFullUpdate: false,
4498
4507
  optimizeForVisibleWindow: false,
@@ -4519,7 +4528,7 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
4519
4528
  const extraData = peek$(ctx, "extraData");
4520
4529
  const layoutConfig = overrideItemLayout ? { span: 1 } : void 0;
4521
4530
  const lastScrollDelta = state.lastScrollDelta;
4522
- const velocity = getScrollVelocity(state);
4531
+ const velocity = scrollVelocity != null ? scrollVelocity : getScrollVelocity(state);
4523
4532
  const shouldOptimize = !forceFullUpdate && !dataChanged && (optimizeForVisibleWindow || Math.abs(velocity) > 0 || state.scrollLength > 0 && lastScrollDelta > state.scrollLength);
4524
4533
  const maxVisibleArea = scrollBottomBuffered + 1e3;
4525
4534
  const useAverageSize = true;
@@ -4699,25 +4708,28 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
4699
4708
  const configId = viewabilityConfig.id;
4700
4709
  const viewabilityState = ensureViewabilityState(ctx, configId);
4701
4710
  const { viewableItems: previousViewableItems, start, end, startBuffered, endBuffered } = viewabilityState;
4702
- const viewabilityTokens = /* @__PURE__ */ new Map();
4711
+ let staleViewabilityAmountIds;
4703
4712
  for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
4704
- viewabilityTokens.set(
4713
+ const nextValue = computeViewability(
4714
+ state,
4715
+ ctx,
4716
+ viewabilityConfig,
4705
4717
  containerId,
4706
- computeViewability(
4707
- state,
4708
- ctx,
4709
- viewabilityConfig,
4710
- containerId,
4711
- value.key,
4712
- scrollSize,
4713
- value.item,
4714
- value.index
4715
- )
4718
+ value.key,
4719
+ scrollSize,
4720
+ value.item,
4721
+ value.index
4716
4722
  );
4723
+ if (nextValue.sizeVisible < 0) {
4724
+ staleViewabilityAmountIds != null ? staleViewabilityAmountIds : staleViewabilityAmountIds = [];
4725
+ staleViewabilityAmountIds.push(containerId);
4726
+ }
4717
4727
  }
4718
4728
  const changed = [];
4729
+ const previousViewableKeys = /* @__PURE__ */ new Set();
4719
4730
  if (previousViewableItems) {
4720
4731
  for (const viewToken of previousViewableItems) {
4732
+ previousViewableKeys.add(viewToken.key);
4721
4733
  const containerId = findContainerId(ctx, viewToken.key);
4722
4734
  if (!checkIsViewable(
4723
4735
  state,
@@ -4749,7 +4761,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
4749
4761
  key
4750
4762
  };
4751
4763
  viewableItems.push(viewToken);
4752
- if (!(previousViewableItems == null ? void 0 : previousViewableItems.find((v) => v.key === viewToken.key))) {
4764
+ if (!previousViewableKeys.has(viewToken.key)) {
4753
4765
  changed.push(viewToken);
4754
4766
  }
4755
4767
  }
@@ -4770,20 +4782,17 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
4770
4782
  onViewableItemsChanged({ changed, end, endBuffered, start, startBuffered, viewableItems });
4771
4783
  }
4772
4784
  }
4773
- for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
4774
- if (value.sizeVisible < 0) {
4775
- ctx.mapViewabilityAmountValues.delete(containerId);
4785
+ if (staleViewabilityAmountIds) {
4786
+ for (const containerId of staleViewabilityAmountIds) {
4787
+ const value = ctx.mapViewabilityAmountValues.get(containerId);
4788
+ if (value && value.sizeVisible < 0) {
4789
+ ctx.mapViewabilityAmountValues.delete(containerId);
4790
+ }
4776
4791
  }
4777
4792
  }
4778
4793
  }
4779
- function shallowEqual(prev, next) {
4780
- if (!prev) return false;
4781
- const keys = Object.keys(next);
4782
- for (let i = 0; i < keys.length; i++) {
4783
- const k = keys[i];
4784
- if (prev[k] !== next[k]) return false;
4785
- }
4786
- return true;
4794
+ function areViewabilityAmountTokensEqual(prev, next) {
4795
+ 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;
4787
4796
  }
4788
4797
  function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
4789
4798
  const { sizes, scroll: scrollState } = state;
@@ -4808,7 +4817,7 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
4808
4817
  sizeVisible: -1
4809
4818
  };
4810
4819
  const prev2 = ctx.mapViewabilityAmountValues.get(containerId);
4811
- if (!shallowEqual(prev2, value2)) {
4820
+ if (!areViewabilityAmountTokensEqual(prev2, value2)) {
4812
4821
  ctx.mapViewabilityAmountValues.set(containerId, value2);
4813
4822
  const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
4814
4823
  if (cb) {
@@ -4838,7 +4847,7 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
4838
4847
  sizeVisible
4839
4848
  };
4840
4849
  const prev = ctx.mapViewabilityAmountValues.get(containerId);
4841
- if (!shallowEqual(prev, value)) {
4850
+ if (!areViewabilityAmountTokensEqual(prev, value)) {
4842
4851
  ctx.mapViewabilityAmountValues.set(containerId, value);
4843
4852
  const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
4844
4853
  if (cb) {
@@ -4889,126 +4898,152 @@ function getExpandedContainerPoolSize(dataLength, numContainers) {
4889
4898
  }
4890
4899
 
4891
4900
  // src/utils/findAvailableContainers.ts
4892
- function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers, protectedKeys) {
4901
+ function findAvailableContainers(ctx, needNewContainers, startBuffered, endBuffered, pendingRemoval, getRequiredItemType, protectedKeys) {
4902
+ const numNeeded = needNewContainers.length;
4903
+ if (numNeeded === 0) {
4904
+ return [];
4905
+ }
4893
4906
  const numContainers = peek$(ctx, "numContainers");
4894
4907
  const state = ctx.state;
4895
4908
  const { stickyContainerPool, containerItemTypes } = state;
4896
4909
  const shouldAvoidAssignedContainerReuse = state.props.recycleItems && !!state.props.positionComponentInternal;
4897
- const result = [];
4898
- const availableContainers = [];
4899
- const pendingRemovalSet = new Set(pendingRemoval);
4910
+ const allocations = [];
4911
+ const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
4900
4912
  let pendingRemovalChanged = false;
4913
+ let nextNewContainerIndex = numContainers;
4914
+ const usedContainers = /* @__PURE__ */ new Set();
4915
+ let availableContainers;
4901
4916
  const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet;
4902
- const stickyHeaderItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyHeaderIndicesSet.has(index))) || [];
4903
4917
  const canReuseContainer = (containerIndex, requiredType) => {
4904
4918
  if (!requiredType) return true;
4905
4919
  const existingType = containerItemTypes.get(containerIndex);
4906
4920
  if (!existingType) return true;
4907
4921
  return existingType === requiredType;
4908
4922
  };
4909
- const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
4910
- let typeIndex = 0;
4911
- for (let i = 0; i < stickyHeaderItemIndices.length; i++) {
4912
- const requiredType = neededTypes[typeIndex];
4913
- let foundContainer = false;
4914
- for (const containerIndex of stickyContainerPool) {
4915
- const key = peek$(ctx, `containerItemKey${containerIndex}`);
4916
- const isPendingRemoval = pendingRemovalSet.has(containerIndex);
4917
- if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType) && !result.includes(containerIndex)) {
4918
- result.push(containerIndex);
4919
- if (isPendingRemoval && pendingRemovalSet.delete(containerIndex)) {
4920
- pendingRemovalChanged = true;
4921
- }
4922
- foundContainer = true;
4923
- if (requiredItemTypes) typeIndex++;
4924
- break;
4925
- }
4923
+ const pushAllocation = (itemIndex, itemType, containerIndex) => {
4924
+ allocations.push({
4925
+ containerIndex,
4926
+ itemIndex,
4927
+ itemType
4928
+ });
4929
+ usedContainers.add(containerIndex);
4930
+ if (pendingRemovalSet == null ? void 0 : pendingRemovalSet.delete(containerIndex)) {
4931
+ pendingRemovalChanged = true;
4926
4932
  }
4927
- if (!foundContainer) {
4928
- const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
4929
- result.push(newContainerIndex);
4933
+ };
4934
+ const pushNewContainer = (itemIndex, itemType, isSticky) => {
4935
+ const newContainerIndex = nextNewContainerIndex++;
4936
+ pushAllocation(itemIndex, itemType, newContainerIndex);
4937
+ if (isSticky) {
4930
4938
  stickyContainerPool.add(newContainerIndex);
4931
- if (requiredItemTypes) typeIndex++;
4932
4939
  }
4933
- }
4934
- for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
4935
- if (stickyContainerPool.has(u)) {
4936
- continue;
4937
- }
4938
- const key = peek$(ctx, `containerItemKey${u}`);
4939
- const requiredType = neededTypes[typeIndex];
4940
- const isPending = key !== void 0 && pendingRemovalSet.has(u);
4941
- const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
4942
- if (canUse) {
4943
- if (isPending) {
4944
- pendingRemovalSet.delete(u);
4945
- pendingRemovalChanged = true;
4946
- }
4947
- result.push(u);
4948
- if (requiredItemTypes) {
4949
- typeIndex++;
4950
- }
4940
+ return newContainerIndex;
4941
+ };
4942
+ const canUseContainer = (containerIndex, itemType) => {
4943
+ if (usedContainers.has(containerIndex) || stickyContainerPool.has(containerIndex)) {
4944
+ return false;
4951
4945
  }
4952
- }
4953
- if (!shouldAvoidAssignedContainerReuse) {
4954
- for (let u = 0; u < numContainers && result.length < numNeeded; u++) {
4955
- if (stickyContainerPool.has(u)) {
4956
- continue;
4957
- }
4958
- const key = peek$(ctx, `containerItemKey${u}`);
4959
- if (key === void 0) continue;
4960
- if ((protectedKeys == null ? void 0 : protectedKeys.has(key)) && state.indexByKey.has(key)) continue;
4961
- const index = state.indexByKey.get(key);
4962
- const isOutOfView = index < startBuffered || index > endBuffered;
4963
- if (isOutOfView) {
4964
- const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
4965
- if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
4966
- availableContainers.push({ distance, index: u });
4946
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
4947
+ const isPending = !!(pendingRemovalSet == null ? void 0 : pendingRemovalSet.has(containerIndex));
4948
+ return (key === void 0 || isPending) && canReuseContainer(containerIndex, itemType);
4949
+ };
4950
+ const findStickyContainer = (itemType) => {
4951
+ let foundContainer;
4952
+ for (const containerIndex of stickyContainerPool) {
4953
+ if (!usedContainers.has(containerIndex)) {
4954
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
4955
+ const isPendingRemoval = !!(pendingRemovalSet == null ? void 0 : pendingRemovalSet.has(containerIndex));
4956
+ if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, itemType)) {
4957
+ foundContainer = containerIndex;
4958
+ break;
4967
4959
  }
4968
4960
  }
4969
4961
  }
4970
- }
4971
- const remaining = numNeeded - result.length;
4972
- if (remaining > 0) {
4973
- if (availableContainers.length > 0) {
4974
- if (availableContainers.length > remaining) {
4975
- availableContainers.sort(comparatorByDistance);
4976
- availableContainers.length = remaining;
4962
+ return foundContainer;
4963
+ };
4964
+ const findUnassignedOrPendingContainer = (itemType) => {
4965
+ let foundContainer;
4966
+ for (let containerIndex = 0; containerIndex < numContainers && foundContainer === void 0; containerIndex++) {
4967
+ if (canUseContainer(containerIndex, itemType)) {
4968
+ foundContainer = containerIndex;
4977
4969
  }
4978
- for (const container of availableContainers) {
4979
- result.push(container.index);
4980
- if (requiredItemTypes) {
4981
- typeIndex++;
4970
+ }
4971
+ return foundContainer;
4972
+ };
4973
+ const getAvailableContainers = () => {
4974
+ if (!availableContainers) {
4975
+ availableContainers = [];
4976
+ if (!shouldAvoidAssignedContainerReuse) {
4977
+ for (let containerIndex = 0; containerIndex < numContainers; containerIndex++) {
4978
+ if (usedContainers.has(containerIndex) || stickyContainerPool.has(containerIndex)) {
4979
+ continue;
4980
+ }
4981
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
4982
+ if (key === void 0) continue;
4983
+ if ((protectedKeys == null ? void 0 : protectedKeys.has(key)) && state.indexByKey.has(key)) continue;
4984
+ const index = state.indexByKey.get(key);
4985
+ const isOutOfView = index < startBuffered || index > endBuffered;
4986
+ if (isOutOfView) {
4987
+ const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
4988
+ availableContainers.push({ distance, index: containerIndex });
4989
+ }
4982
4990
  }
4991
+ availableContainers.sort(comparatorByDistance);
4983
4992
  }
4984
4993
  }
4985
- const stillNeeded = numNeeded - result.length;
4986
- if (stillNeeded > 0) {
4987
- for (let i = 0; i < stillNeeded; i++) {
4988
- result.push(numContainers + i);
4994
+ return availableContainers;
4995
+ };
4996
+ const findAvailableContainer = (itemType) => {
4997
+ const containers = getAvailableContainers();
4998
+ let matchIndex = -1;
4999
+ for (let i = 0; i < containers.length && matchIndex === -1; i++) {
5000
+ const containerIndex = containers[i].index;
5001
+ if (!usedContainers.has(containerIndex) && canReuseContainer(containerIndex, itemType)) {
5002
+ matchIndex = i;
4989
5003
  }
4990
- if (IS_DEV && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
4991
- console.warn(
4992
- "[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.",
4993
- {
4994
- debugInfo: {
4995
- numContainers,
4996
- numContainersPooled: peek$(ctx, "numContainersPooled"),
4997
- numNeeded,
4998
- stillNeeded
4999
- }
5000
- }
5001
- );
5004
+ }
5005
+ return matchIndex === -1 ? void 0 : containers.splice(matchIndex, 1)[0].index;
5006
+ };
5007
+ for (const itemIndex of needNewContainers) {
5008
+ const itemType = getRequiredItemType == null ? void 0 : getRequiredItemType(itemIndex);
5009
+ const isSticky = stickyHeaderIndicesSet.has(itemIndex);
5010
+ let containerIndex;
5011
+ if (isSticky) {
5012
+ containerIndex = findStickyContainer(itemType);
5013
+ } else {
5014
+ containerIndex = findUnassignedOrPendingContainer(itemType);
5015
+ if (containerIndex === void 0) {
5016
+ containerIndex = findAvailableContainer(itemType);
5002
5017
  }
5003
5018
  }
5019
+ if (containerIndex !== void 0) {
5020
+ pushAllocation(itemIndex, itemType, containerIndex);
5021
+ } else {
5022
+ pushNewContainer(itemIndex, itemType, isSticky);
5023
+ }
5004
5024
  }
5005
5025
  if (pendingRemovalChanged) {
5006
5026
  pendingRemoval.length = 0;
5007
- for (const value of pendingRemovalSet) {
5008
- pendingRemoval.push(value);
5027
+ if (pendingRemovalSet) {
5028
+ for (const value of pendingRemovalSet) {
5029
+ pendingRemoval.push(value);
5030
+ }
5009
5031
  }
5010
5032
  }
5011
- return result.sort(comparatorDefault);
5033
+ if (IS_DEV && nextNewContainerIndex > peek$(ctx, "numContainersPooled")) {
5034
+ console.warn(
5035
+ "[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.",
5036
+ {
5037
+ debugInfo: {
5038
+ numContainers,
5039
+ numContainersPooled: peek$(ctx, "numContainersPooled"),
5040
+ numNeeded,
5041
+ stillNeeded: nextNewContainerIndex - numContainers
5042
+ }
5043
+ }
5044
+ );
5045
+ }
5046
+ return allocations;
5012
5047
  }
5013
5048
  function comparatorByDistance(a, b) {
5014
5049
  return b.distance - a.distance;
@@ -5034,21 +5069,28 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
5034
5069
  }
5035
5070
  return -1;
5036
5071
  }
5037
- function getActiveStickyIndices(ctx, stickyHeaderIndices) {
5072
+ function isStickyIndexActive(ctx, targetIndex) {
5038
5073
  const state = ctx.state;
5039
- return new Set(
5040
- 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))
5041
- );
5074
+ let isActive = false;
5075
+ for (const containerIndex of state.stickyContainerPool) {
5076
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
5077
+ const itemIndex = key ? state.indexByKey.get(key) : void 0;
5078
+ if (itemIndex === targetIndex) {
5079
+ isActive = true;
5080
+ break;
5081
+ }
5082
+ }
5083
+ return isActive;
5042
5084
  }
5043
- function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, needNewContainersSet, startBuffered, endBuffered) {
5085
+ function handleStickyActivation(ctx, stickyArray, currentStickyIdx, needNewContainers, needNewContainersSet, startBuffered, endBuffered) {
5044
5086
  var _a3;
5045
5087
  const state = ctx.state;
5046
- const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
5047
5088
  set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
5048
5089
  for (let offset = 0; offset <= 1; offset++) {
5049
5090
  const idx = currentStickyIdx - offset;
5050
- if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
5091
+ if (idx < 0) continue;
5051
5092
  const stickyIndex = stickyArray[idx];
5093
+ if (isStickyIndexActive(ctx, stickyIndex)) continue;
5052
5094
  const stickyId = (_a3 = state.idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
5053
5095
  if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered) && !needNewContainersSet.has(stickyIndex)) {
5054
5096
  needNewContainersSet.add(stickyIndex);
@@ -5090,10 +5132,86 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
5090
5132
  }
5091
5133
  }
5092
5134
  }
5135
+ function trackVisibleRange(range, i, top, size, scroll, scrollBottom) {
5136
+ let didPassVisibleEnd = false;
5137
+ if (range.startNoBuffer === null && top + size > scroll) {
5138
+ range.startNoBuffer = i;
5139
+ }
5140
+ if (range.firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
5141
+ range.firstFullyOnScreenIndex = i;
5142
+ }
5143
+ if (range.startNoBuffer !== null) {
5144
+ if (top <= scrollBottom) {
5145
+ range.endNoBuffer = i;
5146
+ } else {
5147
+ didPassVisibleEnd = true;
5148
+ }
5149
+ }
5150
+ return didPassVisibleEnd;
5151
+ }
5152
+ function getIdsInVisibleRange(state, range) {
5153
+ var _a3, _b;
5154
+ const idsInView = [];
5155
+ const firstVisibleAnchorIndex = (_a3 = range.firstFullyOnScreenIndex) != null ? _a3 : range.startNoBuffer;
5156
+ if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && range.endNoBuffer !== null) {
5157
+ for (let i = firstVisibleAnchorIndex; i <= range.endNoBuffer; i++) {
5158
+ const id = (_b = state.idCache[i]) != null ? _b : getId(state, i);
5159
+ idsInView.push(id);
5160
+ }
5161
+ }
5162
+ return idsInView;
5163
+ }
5164
+ function updateViewabilityForCachedRange(ctx, viewabilityConfigCallbackPairs, scrollLength, scroll, scrollBottom) {
5165
+ var _a3, _b;
5166
+ const state = ctx.state;
5167
+ const {
5168
+ endBuffered,
5169
+ idCache,
5170
+ positions,
5171
+ props: { data },
5172
+ sizes,
5173
+ startBuffered
5174
+ } = state;
5175
+ if (startBuffered === null || endBuffered === null || startBuffered < 0 || endBuffered < startBuffered) {
5176
+ return;
5177
+ }
5178
+ const visibleRange = {
5179
+ endNoBuffer: null,
5180
+ firstFullyOnScreenIndex: void 0,
5181
+ startNoBuffer: null
5182
+ };
5183
+ for (let i = startBuffered; i <= endBuffered && i < data.length; i++) {
5184
+ const id = (_a3 = idCache[i]) != null ? _a3 : getId(state, i);
5185
+ const size = (_b = sizes.get(id)) != null ? _b : getItemSize(ctx, id, i, data[i]);
5186
+ const top = positions[i];
5187
+ const didPassVisibleEnd = trackVisibleRange(visibleRange, i, top, size, scroll, scrollBottom);
5188
+ if (didPassVisibleEnd) {
5189
+ break;
5190
+ }
5191
+ }
5192
+ Object.assign(state, {
5193
+ endNoBuffer: visibleRange.endNoBuffer,
5194
+ firstFullyOnScreenIndex: visibleRange.firstFullyOnScreenIndex,
5195
+ idsInView: getIdsInVisibleRange(state, visibleRange),
5196
+ startNoBuffer: visibleRange.startNoBuffer
5197
+ });
5198
+ if (visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
5199
+ updateViewableItems(
5200
+ state,
5201
+ ctx,
5202
+ viewabilityConfigCallbackPairs,
5203
+ scrollLength,
5204
+ visibleRange.startNoBuffer,
5205
+ visibleRange.endNoBuffer,
5206
+ startBuffered,
5207
+ endBuffered
5208
+ );
5209
+ }
5210
+ }
5093
5211
  function calculateItemsInView(ctx, params = {}) {
5094
5212
  const state = ctx.state;
5095
5213
  batchedUpdates(() => {
5096
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
5214
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
5097
5215
  const {
5098
5216
  columns,
5099
5217
  containerItemKeys,
@@ -5194,6 +5312,15 @@ function calculateItemsInView(ctx, params = {}) {
5194
5312
  state.scrollForNextCalculateItemsInView = void 0;
5195
5313
  } else if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
5196
5314
  if (!isInMVCPActiveMode(state)) {
5315
+ if (viewabilityConfigCallbackPairs) {
5316
+ updateViewabilityForCachedRange(
5317
+ ctx,
5318
+ viewabilityConfigCallbackPairs,
5319
+ scrollLength,
5320
+ scroll,
5321
+ scrollBottom
5322
+ );
5323
+ }
5197
5324
  finishCalculateItemsInView == null ? void 0 : finishCalculateItemsInView();
5198
5325
  return;
5199
5326
  }
@@ -5210,6 +5337,7 @@ function calculateItemsInView(ctx, params = {}) {
5210
5337
  forceFullUpdate: !!forceFullItemPositions,
5211
5338
  optimizeForVisibleWindow,
5212
5339
  scrollBottomBuffered,
5340
+ scrollVelocity: speed,
5213
5341
  startIndex
5214
5342
  });
5215
5343
  totalSize = getContentSize(ctx);
@@ -5235,10 +5363,8 @@ function calculateItemsInView(ctx, params = {}) {
5235
5363
  updateScroll2(state.scroll);
5236
5364
  updateScrollRange();
5237
5365
  }
5238
- let startNoBuffer = null;
5239
5366
  let startBuffered = null;
5240
5367
  let startBufferedId = null;
5241
- let endNoBuffer = null;
5242
5368
  let endBuffered = null;
5243
5369
  let loopStart = (_f = suppressInitialScrollSideEffects ? bootstrapInitialScrollState == null ? void 0 : bootstrapInitialScrollState.targetIndexSeed : void 0) != null ? _f : !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
5244
5370
  for (let i = loopStart; i >= 0; i--) {
@@ -5272,19 +5398,18 @@ function calculateItemsInView(ctx, params = {}) {
5272
5398
  maxIndexRendered = Math.max(maxIndexRendered, index);
5273
5399
  }
5274
5400
  }
5275
- let firstFullyOnScreenIndex;
5401
+ const visibleRange = {
5402
+ endNoBuffer: null,
5403
+ firstFullyOnScreenIndex: void 0,
5404
+ startNoBuffer: null
5405
+ };
5276
5406
  const dataLength = data.length;
5277
5407
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
5278
5408
  const id = (_i = idCache[i]) != null ? _i : getId(state, i);
5279
5409
  const size = (_j = sizes.get(id)) != null ? _j : getItemSize(ctx, id, i, data[i]);
5280
5410
  const top = positions[i];
5281
5411
  if (!foundEnd) {
5282
- if (startNoBuffer === null && top + size > scroll) {
5283
- startNoBuffer = i;
5284
- }
5285
- if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10 && top <= scrollBottom) {
5286
- firstFullyOnScreenIndex = i;
5287
- }
5412
+ trackVisibleRange(visibleRange, i, top, size, scroll, scrollBottom);
5288
5413
  if (startBuffered === null && top + size > scrollTopBuffered) {
5289
5414
  startBuffered = i;
5290
5415
  startBufferedId = id;
@@ -5294,10 +5419,7 @@ function calculateItemsInView(ctx, params = {}) {
5294
5419
  nextTop = top;
5295
5420
  }
5296
5421
  }
5297
- if (startNoBuffer !== null) {
5298
- if (top <= scrollBottom) {
5299
- endNoBuffer = i;
5300
- }
5422
+ if (visibleRange.startNoBuffer !== null) {
5301
5423
  if (top <= scrollBottomBuffered) {
5302
5424
  endBuffered = i;
5303
5425
  if (scrollBottomBuffered > totalSize) {
@@ -5311,22 +5433,14 @@ function calculateItemsInView(ctx, params = {}) {
5311
5433
  }
5312
5434
  }
5313
5435
  }
5314
- const idsInView = [];
5315
- const firstVisibleAnchorIndex = firstFullyOnScreenIndex != null ? firstFullyOnScreenIndex : startNoBuffer;
5316
- if (firstVisibleAnchorIndex !== null && firstVisibleAnchorIndex !== void 0 && endNoBuffer !== null) {
5317
- for (let i = firstVisibleAnchorIndex; i <= endNoBuffer; i++) {
5318
- const id = (_k = idCache[i]) != null ? _k : getId(state, i);
5319
- idsInView.push(id);
5320
- }
5321
- }
5322
5436
  Object.assign(state, {
5323
5437
  endBuffered,
5324
- endNoBuffer,
5325
- firstFullyOnScreenIndex,
5326
- idsInView,
5438
+ endNoBuffer: visibleRange.endNoBuffer,
5439
+ firstFullyOnScreenIndex: visibleRange.firstFullyOnScreenIndex,
5440
+ idsInView: getIdsInVisibleRange(state, visibleRange),
5327
5441
  startBuffered,
5328
5442
  startBufferedId,
5329
- startNoBuffer
5443
+ startNoBuffer: visibleRange.startNoBuffer
5330
5444
  });
5331
5445
  if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
5332
5446
  state.scrollForNextCalculateItemsInView = isNullOrUndefined(nextTop) && isNullOrUndefined(nextBottom) ? void 0 : {
@@ -5348,7 +5462,7 @@ function calculateItemsInView(ctx, params = {}) {
5348
5462
  const needNewContainers = [];
5349
5463
  const needNewContainersSet = /* @__PURE__ */ new Set();
5350
5464
  for (let i = startBuffered; i <= endBuffered; i++) {
5351
- const id = (_l = idCache[i]) != null ? _l : getId(state, i);
5465
+ const id = (_k = idCache[i]) != null ? _k : getId(state, i);
5352
5466
  if (!containerItemKeys.has(id)) {
5353
5467
  needNewContainersSet.add(i);
5354
5468
  needNewContainers.push(i);
@@ -5357,7 +5471,7 @@ function calculateItemsInView(ctx, params = {}) {
5357
5471
  if (alwaysRenderArr.length > 0) {
5358
5472
  for (const index of alwaysRenderArr) {
5359
5473
  if (index < 0 || index >= dataLength) continue;
5360
- const id = (_m = idCache[index]) != null ? _m : getId(state, index);
5474
+ const id = (_l = idCache[index]) != null ? _l : getId(state, index);
5361
5475
  if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
5362
5476
  needNewContainersSet.add(index);
5363
5477
  needNewContainers.push(index);
@@ -5367,7 +5481,6 @@ function calculateItemsInView(ctx, params = {}) {
5367
5481
  if (stickyHeaderIndicesArr.length > 0) {
5368
5482
  handleStickyActivation(
5369
5483
  ctx,
5370
- stickyHeaderIndicesSet,
5371
5484
  stickyHeaderIndicesArr,
5372
5485
  currentStickyIdx,
5373
5486
  needNewContainers,
@@ -5379,35 +5492,34 @@ function calculateItemsInView(ctx, params = {}) {
5379
5492
  set$(ctx, "activeStickyIndex", -1);
5380
5493
  }
5381
5494
  if (needNewContainers.length > 0) {
5382
- const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
5495
+ const getRequiredItemType = getItemType ? (i) => {
5383
5496
  const itemType = getItemType(data[i], i);
5384
5497
  return itemType !== void 0 ? String(itemType) : "";
5385
- }) : void 0;
5386
- const availableContainers = findAvailableContainers(
5498
+ } : void 0;
5499
+ const availableContainerAllocations = findAvailableContainers(
5387
5500
  ctx,
5388
- needNewContainers.length,
5501
+ needNewContainers,
5389
5502
  startBuffered,
5390
5503
  endBuffered,
5391
5504
  pendingRemoval,
5392
- requiredItemTypes,
5393
- needNewContainers,
5505
+ getRequiredItemType,
5394
5506
  protectedContainerKeys
5395
5507
  );
5396
- for (let idx = 0; idx < needNewContainers.length; idx++) {
5397
- const i = needNewContainers[idx];
5398
- const containerIndex = availableContainers[idx];
5399
- const id = (_n = idCache[i]) != null ? _n : getId(state, i);
5508
+ for (const allocation of availableContainerAllocations) {
5509
+ const i = allocation.itemIndex;
5510
+ const containerIndex = allocation.containerIndex;
5511
+ const id = (_m = idCache[i]) != null ? _m : getId(state, i);
5400
5512
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
5401
5513
  if (oldKey && oldKey !== id) {
5402
5514
  containerItemKeys.delete(oldKey);
5403
5515
  }
5404
5516
  set$(ctx, `containerItemKey${containerIndex}`, id);
5405
5517
  set$(ctx, `containerItemData${containerIndex}`, data[i]);
5406
- if (requiredItemTypes) {
5407
- state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
5518
+ if (allocation.itemType !== void 0) {
5519
+ state.containerItemTypes.set(containerIndex, allocation.itemType);
5408
5520
  }
5409
5521
  containerItemKeys.set(id, containerIndex);
5410
- (_o = state.userScrollAnchorReset) == null ? void 0 : _o.keys.add(id);
5522
+ (_n = state.userScrollAnchorReset) == null ? void 0 : _n.keys.add(id);
5411
5523
  const containerSticky = `containerSticky${containerIndex}`;
5412
5524
  const isSticky = stickyHeaderIndicesSet.has(i);
5413
5525
  const isAlwaysRender = alwaysRenderSet.has(i);
@@ -5445,7 +5557,7 @@ function calculateItemsInView(ctx, params = {}) {
5445
5557
  if (alwaysRenderArr.length > 0) {
5446
5558
  for (const index of alwaysRenderArr) {
5447
5559
  if (index < 0 || index >= dataLength) continue;
5448
- const id = (_p = idCache[index]) != null ? _p : getId(state, index);
5560
+ const id = (_o = idCache[index]) != null ? _o : getId(state, index);
5449
5561
  const containerIndex = containerItemKeys.get(id);
5450
5562
  if (containerIndex !== void 0) {
5451
5563
  state.stickyContainerPool.add(containerIndex);
@@ -5464,10 +5576,11 @@ function calculateItemsInView(ctx, params = {}) {
5464
5576
  alwaysRenderSet
5465
5577
  );
5466
5578
  }
5579
+ const pendingRemovalSet = pendingRemoval.length > 0 ? new Set(pendingRemoval) : void 0;
5467
5580
  let didChangePositions = false;
5468
5581
  for (let i = 0; i < numContainers; i++) {
5469
5582
  const itemKey = peek$(ctx, `containerItemKey${i}`);
5470
- if (pendingRemoval.includes(i)) {
5583
+ if (pendingRemovalSet == null ? void 0 : pendingRemovalSet.has(i)) {
5471
5584
  if (itemKey !== void 0) {
5472
5585
  containerItemKeys.delete(itemKey);
5473
5586
  }
@@ -5498,24 +5611,24 @@ function calculateItemsInView(ctx, params = {}) {
5498
5611
  evaluateBootstrapInitialScroll(ctx);
5499
5612
  return;
5500
5613
  }
5501
- const mountedBufferedIndices = getMountedBufferedIndices(state);
5502
- const mountedNoBufferIndices = getMountedNoBufferIndices(state);
5503
- const readinessIndices = hasActiveInitialScroll(state) ? mountedBufferedIndices : mountedNoBufferIndices.length > 0 ? mountedNoBufferIndices : mountedBufferedIndices;
5504
- if (!queuedInitialLayout && readinessIndices.length > 0 && checkAllSizesKnown(state, readinessIndices)) {
5505
- setDidLayout(ctx);
5506
- handleInitialScrollLayoutReady(ctx);
5614
+ if (!queuedInitialLayout && !state.didContainersLayout) {
5615
+ const isInitialLayoutReady = hasActiveInitialScroll(state) ? checkAllSizesKnown(state, state.startBuffered, state.endBuffered) : checkAllSizesKnown(state, state.startNoBuffer, state.endNoBuffer) || checkAllSizesKnown(state, state.startBuffered, state.endBuffered);
5616
+ if (isInitialLayoutReady) {
5617
+ setDidLayout(ctx);
5618
+ handleInitialScrollLayoutReady(ctx);
5619
+ }
5507
5620
  }
5508
- if (viewabilityConfigCallbackPairs && startNoBuffer !== null && endNoBuffer !== null) {
5621
+ if (viewabilityConfigCallbackPairs && visibleRange.startNoBuffer !== null && visibleRange.endNoBuffer !== null) {
5509
5622
  if (!didMVCPAdjustScroll) {
5510
5623
  updateViewableItems(
5511
5624
  ctx.state,
5512
5625
  ctx,
5513
5626
  viewabilityConfigCallbackPairs,
5514
5627
  scrollLength,
5515
- startNoBuffer,
5516
- endNoBuffer,
5517
- startBuffered != null ? startBuffered : startNoBuffer,
5518
- endBuffered != null ? endBuffered : endNoBuffer
5628
+ visibleRange.startNoBuffer,
5629
+ visibleRange.endNoBuffer,
5630
+ startBuffered != null ? startBuffered : visibleRange.startNoBuffer,
5631
+ endBuffered != null ? endBuffered : visibleRange.endNoBuffer
5519
5632
  );
5520
5633
  }
5521
5634
  }
@@ -5974,6 +6087,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5974
6087
  } = state;
5975
6088
  if (!data) return;
5976
6089
  const index = state.indexByKey.get(itemKey);
6090
+ let resolvedMeasurementItem;
5977
6091
  if (getFixedItemSize) {
5978
6092
  if (index === void 0) {
5979
6093
  return;
@@ -5984,6 +6098,12 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5984
6098
  }
5985
6099
  const type = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
5986
6100
  const size2 = getFixedItemSize(itemData, index, type);
6101
+ resolvedMeasurementItem = {
6102
+ didResolveFixedItemSize: true,
6103
+ fixedItemSize: size2,
6104
+ itemData,
6105
+ itemType: type
6106
+ };
5987
6107
  if (size2 !== void 0 && size2 === sizesKnown.get(itemKey)) {
5988
6108
  updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
5989
6109
  return;
@@ -5993,7 +6113,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
5993
6113
  let shouldMaintainScrollAtEnd = false;
5994
6114
  let minIndexSizeChanged;
5995
6115
  const prevSizeKnown = state.sizesKnown.get(itemKey);
5996
- const diff = updateOneItemSize(ctx, itemKey, sizeObj);
6116
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem);
5997
6117
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
5998
6118
  if (diff !== 0) {
5999
6119
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -6018,7 +6138,7 @@ function updateItemSize(ctx, itemKey, sizeObj) {
6018
6138
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
6019
6139
  }
6020
6140
  updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal);
6021
- if (didContainersLayout || checkAllSizesKnown(state, getMountedBufferedIndices(state))) {
6141
+ if (didContainersLayout || checkAllSizesKnown(state, state.startBuffered, state.endBuffered)) {
6022
6142
  if (needsRecalculate) {
6023
6143
  state.scrollForNextCalculateItemsInView = void 0;
6024
6144
  runOrScheduleMVCPRecalculate(ctx);
@@ -6032,8 +6152,8 @@ function updateItemSize(ctx, itemKey, sizeObj) {
6032
6152
  }
6033
6153
  }
6034
6154
  }
6035
- function updateOneItemSize(ctx, itemKey, sizeObj) {
6036
- var _a3, _b;
6155
+ function updateOneItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
6156
+ var _a3, _b, _c;
6037
6157
  const state = ctx.state;
6038
6158
  const {
6039
6159
  indexByKey,
@@ -6043,20 +6163,25 @@ function updateOneItemSize(ctx, itemKey, sizeObj) {
6043
6163
  } = state;
6044
6164
  if (!data) return 0;
6045
6165
  const index = indexByKey.get(itemKey);
6046
- const itemData = data[index];
6047
- let itemType;
6048
- let fixedItemSize;
6049
- if (getFixedItemSize) {
6050
- itemType = getItemType ? (_a3 = getItemType(itemData, index)) != null ? _a3 : "" : "";
6166
+ const itemData = (_a3 = resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.itemData) != null ? _a3 : data[index];
6167
+ let itemType = resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.itemType;
6168
+ let fixedItemSize = resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.fixedItemSize;
6169
+ if (getFixedItemSize && !(resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.didResolveFixedItemSize)) {
6170
+ itemType = getItemType ? (_b = getItemType(itemData, index)) != null ? _b : "" : "";
6051
6171
  fixedItemSize = getFixedItemSize(itemData, index, itemType);
6052
6172
  }
6053
- const prevSize = getItemSize(ctx, itemKey, index, itemData);
6173
+ const resolvedItemSize = (resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.didResolveFixedItemSize) || itemType !== void 0 || fixedItemSize !== void 0 ? {
6174
+ didResolveFixedItemSize: resolvedMeasurementItem == null ? void 0 : resolvedMeasurementItem.didResolveFixedItemSize,
6175
+ fixedItemSize,
6176
+ itemType
6177
+ } : void 0;
6178
+ const prevSize = getItemSize(ctx, itemKey, index, itemData, void 0, void 0, void 0, resolvedItemSize);
6054
6179
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
6055
6180
  const prevSizeKnown = sizesKnown.get(itemKey);
6056
6181
  const size = Math.round(rawSize) ;
6057
6182
  sizesKnown.set(itemKey, size);
6058
6183
  if (fixedItemSize === void 0 && size > 0) {
6059
- itemType != null ? itemType : itemType = getItemType ? (_b = getItemType(itemData, index)) != null ? _b : "" : "";
6184
+ itemType != null ? itemType : itemType = getItemType ? (_c = getItemType(itemData, index)) != null ? _c : "" : "";
6060
6185
  let averages = averageSizes[itemType];
6061
6186
  if (!averages) {
6062
6187
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
@@ -6158,6 +6283,11 @@ function getAverageItemSizes(state) {
6158
6283
  }
6159
6284
  return averageItemSizes;
6160
6285
  }
6286
+ function triggerMountedContainerLayouts(ctx) {
6287
+ for (const triggerLayout of ctx.containerLayoutTriggers.values()) {
6288
+ triggerLayout();
6289
+ }
6290
+ }
6161
6291
  function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6162
6292
  const state = ctx.state;
6163
6293
  const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
@@ -6283,6 +6413,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6283
6413
  state.columns.length = 0;
6284
6414
  state.columnSpans.length = 0;
6285
6415
  }
6416
+ triggerMountedContainerLayouts(ctx);
6286
6417
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
6287
6418
  };
6288
6419
  return {
@@ -7085,7 +7216,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7085
7216
  viewabilityConfigCallbackPairs
7086
7217
  });
7087
7218
  state.viewabilityConfigCallbackPairs = viewability;
7088
- state.enableScrollForNextCalculateItemsInView = !viewability;
7219
+ state.enableScrollForNextCalculateItemsInView = true;
7089
7220
  if (viewability) {
7090
7221
  state.scrollForNextCalculateItemsInView = void 0;
7091
7222
  }