@legendapp/list 3.3.6 → 3.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2931,6 +2931,7 @@ function abortBootstrapInitialScroll(ctx) {
2931
2931
  // src/core/containerItemMetadata.ts
2932
2932
  function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
2933
2933
  return {
2934
+ data: state.props.data,
2934
2935
  dataChangeEpoch: state.dataChangeEpoch,
2935
2936
  getFixedItemSize: state.props.getFixedItemSize,
2936
2937
  getItemType: state.props.getItemType,
@@ -2939,25 +2940,29 @@ function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
2939
2940
  itemType
2940
2941
  };
2941
2942
  }
2942
- function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
2943
- var _a3, _b;
2944
- const { getFixedItemSize, getItemType } = state.props;
2943
+ function updateContainerItemMetadata(state, containerId, itemIndex, itemData, itemType) {
2944
+ var _a3;
2945
+ const { getItemType } = state.props;
2945
2946
  const previousMetadata = state.containerItemMetadata.get(containerId);
2946
- let metadata;
2947
2947
  if ((previousMetadata == null ? void 0 : previousMetadata.dataChangeEpoch) === state.dataChangeEpoch && previousMetadata.getItemType === getItemType && previousMetadata.itemData === itemData && previousMetadata.itemIndex === itemIndex) {
2948
- metadata = previousMetadata;
2949
- } else {
2950
- const itemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
2951
- metadata = createContainerItemMetadata(state, itemIndex, itemData, itemType);
2952
- state.containerItemMetadata.set(containerId, metadata);
2948
+ return previousMetadata;
2953
2949
  }
2950
+ const resolvedItemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
2951
+ const metadata = createContainerItemMetadata(state, itemIndex, itemData, resolvedItemType);
2952
+ state.containerItemMetadata.set(containerId, metadata);
2953
+ return metadata;
2954
+ }
2955
+ function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
2956
+ var _a3;
2957
+ const { getFixedItemSize } = state.props;
2958
+ const metadata = updateContainerItemMetadata(state, containerId, itemIndex, itemData);
2954
2959
  if (metadata.getFixedItemSize !== getFixedItemSize) {
2955
2960
  metadata.didResolveFixedItemSize = false;
2956
2961
  metadata.fixedItemSize = void 0;
2957
2962
  metadata.getFixedItemSize = getFixedItemSize;
2958
2963
  }
2959
2964
  if (getFixedItemSize && !metadata.didResolveFixedItemSize) {
2960
- metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_b = metadata.itemType) != null ? _b : "");
2965
+ metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_a3 = metadata.itemType) != null ? _a3 : "");
2961
2966
  metadata.didResolveFixedItemSize = true;
2962
2967
  }
2963
2968
  return metadata;
@@ -3302,6 +3307,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3302
3307
  return { didChangePosition: false, didRefreshData: false };
3303
3308
  }
3304
3309
  const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
3310
+ const metadata = updateContainerItemMetadata(state, containerIndex, itemIndex, item);
3305
3311
  const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3306
3312
  let didChangePosition = false;
3307
3313
  let didRefreshData = false;
@@ -3312,7 +3318,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3312
3318
  return { didChangePosition: false, didRefreshData: false };
3313
3319
  }
3314
3320
  const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
3315
- const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
3321
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item, void 0, void 0, void 0, metadata);
3316
3322
  const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3317
3323
  const column = columns[itemIndex] || 1;
3318
3324
  const span = columnSpans[itemIndex] || 1;
@@ -4598,18 +4604,22 @@ function calculateItemsInView(ctx, params = {}) {
4598
4604
  if (oldKey && oldKey !== id) {
4599
4605
  containerItemKeys.delete(oldKey);
4600
4606
  }
4607
+ state.containerItemMetadata.set(
4608
+ containerIndex,
4609
+ createContainerItemMetadata(state, i, data[i], allocation.itemType)
4610
+ );
4601
4611
  if (oldKey !== id) {
4602
4612
  changedContainerIds != null ? changedContainerIds : changedContainerIds = /* @__PURE__ */ new Set();
4603
4613
  changedContainerIds.add(containerIndex);
4604
4614
  state.containerItemGenerations[containerIndex] = ((_p = state.containerItemGenerations[containerIndex]) != null ? _p : 0) + 1;
4615
+ if (state.props.hideItemsUntilMeasured) {
4616
+ const isLayoutReady = state.sizesKnown.has(id) || resolveContainerItemMetadata(state, containerIndex, i, data[i]).fixedItemSize !== void 0;
4617
+ set$(ctx, `containerLayoutReady${containerIndex}`, isLayoutReady);
4618
+ }
4605
4619
  }
4606
4620
  set$(ctx, `containerItemKey${containerIndex}`, id);
4607
4621
  set$(ctx, `containerItemIndex${containerIndex}`, i);
4608
4622
  set$(ctx, `containerItemData${containerIndex}`, data[i]);
4609
- state.containerItemMetadata.set(
4610
- containerIndex,
4611
- createContainerItemMetadata(state, i, data[i], allocation.itemType)
4612
- );
4613
4623
  containerItemKeys.set(id, containerIndex);
4614
4624
  (_q = state.userScrollAnchorReset) == null ? void 0 : _q.keys.add(id);
4615
4625
  const containerSticky = `containerSticky${containerIndex}`;
@@ -5672,7 +5682,7 @@ var Container = typedMemo(function Container2({
5672
5682
  ]
5673
5683
  );
5674
5684
  const renderedItemInfo = useMemo(
5675
- () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
5685
+ () => itemKey !== void 0 ? getRenderedItem2(itemKey, id) : null,
5676
5686
  [itemKey, data, extraData]
5677
5687
  );
5678
5688
  const { renderedItem } = renderedItemInfo || {};
@@ -6923,6 +6933,16 @@ function checkStructuralDataChange(state, dataProp, previousData) {
6923
6933
  return false;
6924
6934
  }
6925
6935
 
6936
+ // src/core/containerLayoutReady.ts
6937
+ var CONTAINER_LAYOUT_READY_PREFIX = "containerLayoutReady";
6938
+ function resetContainerLayoutReady(ctx) {
6939
+ for (const signalName of ctx.values.keys()) {
6940
+ if (signalName.startsWith(CONTAINER_LAYOUT_READY_PREFIX)) {
6941
+ set$(ctx, signalName, void 0);
6942
+ }
6943
+ }
6944
+ }
6945
+
6926
6946
  // src/core/doInitialAllocateContainers.ts
6927
6947
  function doInitialAllocateContainers(ctx) {
6928
6948
  var _a3, _b;
@@ -7617,34 +7637,37 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
7617
7637
  }
7618
7638
 
7619
7639
  // src/utils/getRenderedItem.ts
7620
- function getRenderedItem(ctx, key) {
7621
- var _a3;
7640
+ function getRenderedItem(ctx, key, containerId) {
7641
+ var _a3, _b, _c;
7622
7642
  const state = ctx.state;
7623
7643
  if (!state) {
7624
7644
  return null;
7625
7645
  }
7646
+ const metadata = state.containerItemMetadata.get(containerId);
7647
+ const useAssignedGeneration = metadata && metadata.dataChangeEpoch !== state.dataChangeEpoch;
7626
7648
  const {
7627
7649
  indexByKey,
7628
- props: { data, getItemType, renderItem }
7650
+ props: { data: currentData, getItemType, renderItem }
7629
7651
  } = state;
7630
- const index = indexByKey.get(key);
7652
+ const data = useAssignedGeneration ? metadata.data : currentData;
7653
+ const index = (_a3 = metadata == null ? void 0 : metadata.itemIndex) != null ? _a3 : indexByKey.get(key);
7631
7654
  if (index === void 0) {
7632
7655
  return null;
7633
7656
  }
7634
7657
  let renderedItem = null;
7635
7658
  const extraData = peek$(ctx, "extraData");
7636
- const item = data[index];
7659
+ const item = useAssignedGeneration ? metadata.itemData : data[index];
7637
7660
  if (renderItem && !isNullOrUndefined(item)) {
7638
7661
  const itemProps = {
7639
7662
  data,
7640
7663
  extraData,
7641
7664
  index,
7642
7665
  item,
7643
- type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
7666
+ type: useAssignedGeneration ? (_b = metadata.itemType) != null ? _b : "" : getItemType ? (_c = getItemType(item, index)) != null ? _c : "" : ""
7644
7667
  };
7645
7668
  renderedItem = renderItem(itemProps);
7646
7669
  }
7647
- return { index, item: data[index], renderedItem };
7670
+ return { index, item, renderedItem };
7648
7671
  }
7649
7672
 
7650
7673
  // src/utils/normalizeMaintainScrollAtEnd.ts
@@ -7810,6 +7833,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7810
7833
  initialScrollIndex: initialScrollIndexProp,
7811
7834
  initialScrollOffset: initialScrollOffsetProp,
7812
7835
  experimental_adaptiveRender,
7836
+ experimental_hideItemsUntilMeasured,
7813
7837
  itemsAreEqual,
7814
7838
  keyExtractor: keyExtractorProp,
7815
7839
  ListEmptyComponent,
@@ -8030,6 +8054,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8030
8054
  const state = refState.current;
8031
8055
  const isFirstLocal = state.isFirst;
8032
8056
  const previousAdaptiveRender = state.props.adaptiveRender;
8057
+ const previousHideItemsUntilMeasured = state.props.hideItemsUntilMeasured;
8033
8058
  const previousNumColumnsProp = state.props.numColumns;
8034
8059
  const didScrollAxisGapChange = !isFirstLocal && ctx.scrollAxisGap !== nextScrollAxisGap;
8035
8060
  ctx.scrollAxisGap = nextScrollAxisGap;
@@ -8075,6 +8100,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8075
8100
  estimatedItemSize,
8076
8101
  getFixedItemSize: useWrapIfItem(getFixedItemSize),
8077
8102
  getItemType: useWrapIfItem(getItemType),
8103
+ hideItemsUntilMeasured: experimental_hideItemsUntilMeasured,
8078
8104
  horizontal: !!horizontal,
8079
8105
  itemsAreEqual,
8080
8106
  keyExtractor: useWrapIfItem(keyExtractor),
@@ -8112,6 +8138,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8112
8138
  if (!isFirstLocal && previousAdaptiveRender && !experimental_adaptiveRender) {
8113
8139
  resetAdaptiveRender(ctx);
8114
8140
  }
8141
+ if (!isFirstLocal && previousHideItemsUntilMeasured && !experimental_hideItemsUntilMeasured) {
8142
+ resetContainerLayoutReady(ctx);
8143
+ }
8115
8144
  const memoizedLastItemKeys = useMemo(() => {
8116
8145
  if (!dataProp.length) return [];
8117
8146
  return Array.from(
@@ -8360,7 +8389,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8360
8389
  }, [ctx, usesBootstrapInitialScroll]);
8361
8390
  const fns = useMemo(
8362
8391
  () => ({
8363
- getRenderedItem: (key) => getRenderedItem(ctx, key),
8392
+ getRenderedItem: (key, containerId) => getRenderedItem(ctx, key, containerId),
8364
8393
  onMomentumScrollEnd: (event) => {
8365
8394
  checkFinishedScrollFallback(ctx);
8366
8395
  if (state.props.onMomentumScrollEnd) {
package/react.d.ts CHANGED
@@ -31,7 +31,7 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
31
31
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
32
32
  }
33
33
 
34
- type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "containerLayoutEpoch" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemIndex${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
34
+ type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "containerLayoutEpoch" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemIndex${number}` | `containerItemKey${number}` | `containerLayoutReady${number}` | `containerPosition${number}` | `containerSticky${number}`;
35
35
  type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
36
36
  type ListenerTypeValueMap = {
37
37
  activeStickyIndex: number;
@@ -70,6 +70,8 @@ type ListenerTypeValueMap = {
70
70
  adaptiveRender: "normal" | "light";
71
71
  } & {
72
72
  [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
73
+ } & {
74
+ [K in ListenerType as K extends `containerLayoutReady${number}` ? K : never]: boolean;
73
75
  } & {
74
76
  [K in ListenerType as K extends `containerItemData${number}` ? K : never]: any;
75
77
  } & {
@@ -371,6 +373,20 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
371
373
  * Configures the adaptive render signal. Items can use this to render a lighter version while scrolling quickly.
372
374
  */
373
375
  experimental_adaptiveRender?: AdaptiveRenderConfig;
376
+ /**
377
+ * Keeps a newly recycled item laid out but invisible until its size has been measured, so it is never painted at
378
+ * the estimated position it was recycled to. Only applies on the new architecture.
379
+ *
380
+ * This trades a possible flash at the wrong position for an extra render and native commit per recycled row, so it
381
+ * is worth enabling only for lists with dynamically sized items whose estimates are visibly wrong. Items with a
382
+ * size from `getFixedItemSize`, or with an already measured size, are exact and render immediately either way.
383
+ *
384
+ * Sticky headers are intentionally excluded. They are painted from a scroll-driven interpolation rather than the
385
+ * committed position, so hiding them would blink a header out mid-scroll without preventing a flash.
386
+ *
387
+ * @default false
388
+ */
389
+ experimental_hideItemsUntilMeasured?: boolean;
374
390
  /**
375
391
  * Function to call when the user pulls to refresh.
376
392
  */
package/react.js CHANGED
@@ -2952,6 +2952,7 @@ function abortBootstrapInitialScroll(ctx) {
2952
2952
  // src/core/containerItemMetadata.ts
2953
2953
  function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
2954
2954
  return {
2955
+ data: state.props.data,
2955
2956
  dataChangeEpoch: state.dataChangeEpoch,
2956
2957
  getFixedItemSize: state.props.getFixedItemSize,
2957
2958
  getItemType: state.props.getItemType,
@@ -2960,25 +2961,29 @@ function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
2960
2961
  itemType
2961
2962
  };
2962
2963
  }
2963
- function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
2964
- var _a3, _b;
2965
- const { getFixedItemSize, getItemType } = state.props;
2964
+ function updateContainerItemMetadata(state, containerId, itemIndex, itemData, itemType) {
2965
+ var _a3;
2966
+ const { getItemType } = state.props;
2966
2967
  const previousMetadata = state.containerItemMetadata.get(containerId);
2967
- let metadata;
2968
2968
  if ((previousMetadata == null ? void 0 : previousMetadata.dataChangeEpoch) === state.dataChangeEpoch && previousMetadata.getItemType === getItemType && previousMetadata.itemData === itemData && previousMetadata.itemIndex === itemIndex) {
2969
- metadata = previousMetadata;
2970
- } else {
2971
- const itemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
2972
- metadata = createContainerItemMetadata(state, itemIndex, itemData, itemType);
2973
- state.containerItemMetadata.set(containerId, metadata);
2969
+ return previousMetadata;
2974
2970
  }
2971
+ const resolvedItemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
2972
+ const metadata = createContainerItemMetadata(state, itemIndex, itemData, resolvedItemType);
2973
+ state.containerItemMetadata.set(containerId, metadata);
2974
+ return metadata;
2975
+ }
2976
+ function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
2977
+ var _a3;
2978
+ const { getFixedItemSize } = state.props;
2979
+ const metadata = updateContainerItemMetadata(state, containerId, itemIndex, itemData);
2975
2980
  if (metadata.getFixedItemSize !== getFixedItemSize) {
2976
2981
  metadata.didResolveFixedItemSize = false;
2977
2982
  metadata.fixedItemSize = void 0;
2978
2983
  metadata.getFixedItemSize = getFixedItemSize;
2979
2984
  }
2980
2985
  if (getFixedItemSize && !metadata.didResolveFixedItemSize) {
2981
- metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_b = metadata.itemType) != null ? _b : "");
2986
+ metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_a3 = metadata.itemType) != null ? _a3 : "");
2982
2987
  metadata.didResolveFixedItemSize = true;
2983
2988
  }
2984
2989
  return metadata;
@@ -3323,6 +3328,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3323
3328
  return { didChangePosition: false, didRefreshData: false };
3324
3329
  }
3325
3330
  const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
3331
+ const metadata = updateContainerItemMetadata(state, containerIndex, itemIndex, item);
3326
3332
  const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3327
3333
  let didChangePosition = false;
3328
3334
  let didRefreshData = false;
@@ -3333,7 +3339,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3333
3339
  return { didChangePosition: false, didRefreshData: false };
3334
3340
  }
3335
3341
  const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
3336
- const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
3342
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item, void 0, void 0, void 0, metadata);
3337
3343
  const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3338
3344
  const column = columns[itemIndex] || 1;
3339
3345
  const span = columnSpans[itemIndex] || 1;
@@ -4619,18 +4625,22 @@ function calculateItemsInView(ctx, params = {}) {
4619
4625
  if (oldKey && oldKey !== id) {
4620
4626
  containerItemKeys.delete(oldKey);
4621
4627
  }
4628
+ state.containerItemMetadata.set(
4629
+ containerIndex,
4630
+ createContainerItemMetadata(state, i, data[i], allocation.itemType)
4631
+ );
4622
4632
  if (oldKey !== id) {
4623
4633
  changedContainerIds != null ? changedContainerIds : changedContainerIds = /* @__PURE__ */ new Set();
4624
4634
  changedContainerIds.add(containerIndex);
4625
4635
  state.containerItemGenerations[containerIndex] = ((_p = state.containerItemGenerations[containerIndex]) != null ? _p : 0) + 1;
4636
+ if (state.props.hideItemsUntilMeasured) {
4637
+ const isLayoutReady = state.sizesKnown.has(id) || resolveContainerItemMetadata(state, containerIndex, i, data[i]).fixedItemSize !== void 0;
4638
+ set$(ctx, `containerLayoutReady${containerIndex}`, isLayoutReady);
4639
+ }
4626
4640
  }
4627
4641
  set$(ctx, `containerItemKey${containerIndex}`, id);
4628
4642
  set$(ctx, `containerItemIndex${containerIndex}`, i);
4629
4643
  set$(ctx, `containerItemData${containerIndex}`, data[i]);
4630
- state.containerItemMetadata.set(
4631
- containerIndex,
4632
- createContainerItemMetadata(state, i, data[i], allocation.itemType)
4633
- );
4634
4644
  containerItemKeys.set(id, containerIndex);
4635
4645
  (_q = state.userScrollAnchorReset) == null ? void 0 : _q.keys.add(id);
4636
4646
  const containerSticky = `containerSticky${containerIndex}`;
@@ -5693,7 +5703,7 @@ var Container = typedMemo(function Container2({
5693
5703
  ]
5694
5704
  );
5695
5705
  const renderedItemInfo = React3.useMemo(
5696
- () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
5706
+ () => itemKey !== void 0 ? getRenderedItem2(itemKey, id) : null,
5697
5707
  [itemKey, data, extraData]
5698
5708
  );
5699
5709
  const { renderedItem } = renderedItemInfo || {};
@@ -6944,6 +6954,16 @@ function checkStructuralDataChange(state, dataProp, previousData) {
6944
6954
  return false;
6945
6955
  }
6946
6956
 
6957
+ // src/core/containerLayoutReady.ts
6958
+ var CONTAINER_LAYOUT_READY_PREFIX = "containerLayoutReady";
6959
+ function resetContainerLayoutReady(ctx) {
6960
+ for (const signalName of ctx.values.keys()) {
6961
+ if (signalName.startsWith(CONTAINER_LAYOUT_READY_PREFIX)) {
6962
+ set$(ctx, signalName, void 0);
6963
+ }
6964
+ }
6965
+ }
6966
+
6947
6967
  // src/core/doInitialAllocateContainers.ts
6948
6968
  function doInitialAllocateContainers(ctx) {
6949
6969
  var _a3, _b;
@@ -7638,34 +7658,37 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
7638
7658
  }
7639
7659
 
7640
7660
  // src/utils/getRenderedItem.ts
7641
- function getRenderedItem(ctx, key) {
7642
- var _a3;
7661
+ function getRenderedItem(ctx, key, containerId) {
7662
+ var _a3, _b, _c;
7643
7663
  const state = ctx.state;
7644
7664
  if (!state) {
7645
7665
  return null;
7646
7666
  }
7667
+ const metadata = state.containerItemMetadata.get(containerId);
7668
+ const useAssignedGeneration = metadata && metadata.dataChangeEpoch !== state.dataChangeEpoch;
7647
7669
  const {
7648
7670
  indexByKey,
7649
- props: { data, getItemType, renderItem }
7671
+ props: { data: currentData, getItemType, renderItem }
7650
7672
  } = state;
7651
- const index = indexByKey.get(key);
7673
+ const data = useAssignedGeneration ? metadata.data : currentData;
7674
+ const index = (_a3 = metadata == null ? void 0 : metadata.itemIndex) != null ? _a3 : indexByKey.get(key);
7652
7675
  if (index === void 0) {
7653
7676
  return null;
7654
7677
  }
7655
7678
  let renderedItem = null;
7656
7679
  const extraData = peek$(ctx, "extraData");
7657
- const item = data[index];
7680
+ const item = useAssignedGeneration ? metadata.itemData : data[index];
7658
7681
  if (renderItem && !isNullOrUndefined(item)) {
7659
7682
  const itemProps = {
7660
7683
  data,
7661
7684
  extraData,
7662
7685
  index,
7663
7686
  item,
7664
- type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
7687
+ type: useAssignedGeneration ? (_b = metadata.itemType) != null ? _b : "" : getItemType ? (_c = getItemType(item, index)) != null ? _c : "" : ""
7665
7688
  };
7666
7689
  renderedItem = renderItem(itemProps);
7667
7690
  }
7668
- return { index, item: data[index], renderedItem };
7691
+ return { index, item, renderedItem };
7669
7692
  }
7670
7693
 
7671
7694
  // src/utils/normalizeMaintainScrollAtEnd.ts
@@ -7831,6 +7854,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7831
7854
  initialScrollIndex: initialScrollIndexProp,
7832
7855
  initialScrollOffset: initialScrollOffsetProp,
7833
7856
  experimental_adaptiveRender,
7857
+ experimental_hideItemsUntilMeasured,
7834
7858
  itemsAreEqual,
7835
7859
  keyExtractor: keyExtractorProp,
7836
7860
  ListEmptyComponent,
@@ -8051,6 +8075,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8051
8075
  const state = refState.current;
8052
8076
  const isFirstLocal = state.isFirst;
8053
8077
  const previousAdaptiveRender = state.props.adaptiveRender;
8078
+ const previousHideItemsUntilMeasured = state.props.hideItemsUntilMeasured;
8054
8079
  const previousNumColumnsProp = state.props.numColumns;
8055
8080
  const didScrollAxisGapChange = !isFirstLocal && ctx.scrollAxisGap !== nextScrollAxisGap;
8056
8081
  ctx.scrollAxisGap = nextScrollAxisGap;
@@ -8096,6 +8121,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8096
8121
  estimatedItemSize,
8097
8122
  getFixedItemSize: useWrapIfItem(getFixedItemSize),
8098
8123
  getItemType: useWrapIfItem(getItemType),
8124
+ hideItemsUntilMeasured: experimental_hideItemsUntilMeasured,
8099
8125
  horizontal: !!horizontal,
8100
8126
  itemsAreEqual,
8101
8127
  keyExtractor: useWrapIfItem(keyExtractor),
@@ -8133,6 +8159,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8133
8159
  if (!isFirstLocal && previousAdaptiveRender && !experimental_adaptiveRender) {
8134
8160
  resetAdaptiveRender(ctx);
8135
8161
  }
8162
+ if (!isFirstLocal && previousHideItemsUntilMeasured && !experimental_hideItemsUntilMeasured) {
8163
+ resetContainerLayoutReady(ctx);
8164
+ }
8136
8165
  const memoizedLastItemKeys = React3.useMemo(() => {
8137
8166
  if (!dataProp.length) return [];
8138
8167
  return Array.from(
@@ -8381,7 +8410,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8381
8410
  }, [ctx, usesBootstrapInitialScroll]);
8382
8411
  const fns = React3.useMemo(
8383
8412
  () => ({
8384
- getRenderedItem: (key) => getRenderedItem(ctx, key),
8413
+ getRenderedItem: (key, containerId) => getRenderedItem(ctx, key, containerId),
8385
8414
  onMomentumScrollEnd: (event) => {
8386
8415
  checkFinishedScrollFallback(ctx);
8387
8416
  if (state.props.onMomentumScrollEnd) {
package/react.mjs CHANGED
@@ -2931,6 +2931,7 @@ function abortBootstrapInitialScroll(ctx) {
2931
2931
  // src/core/containerItemMetadata.ts
2932
2932
  function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
2933
2933
  return {
2934
+ data: state.props.data,
2934
2935
  dataChangeEpoch: state.dataChangeEpoch,
2935
2936
  getFixedItemSize: state.props.getFixedItemSize,
2936
2937
  getItemType: state.props.getItemType,
@@ -2939,25 +2940,29 @@ function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
2939
2940
  itemType
2940
2941
  };
2941
2942
  }
2942
- function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
2943
- var _a3, _b;
2944
- const { getFixedItemSize, getItemType } = state.props;
2943
+ function updateContainerItemMetadata(state, containerId, itemIndex, itemData, itemType) {
2944
+ var _a3;
2945
+ const { getItemType } = state.props;
2945
2946
  const previousMetadata = state.containerItemMetadata.get(containerId);
2946
- let metadata;
2947
2947
  if ((previousMetadata == null ? void 0 : previousMetadata.dataChangeEpoch) === state.dataChangeEpoch && previousMetadata.getItemType === getItemType && previousMetadata.itemData === itemData && previousMetadata.itemIndex === itemIndex) {
2948
- metadata = previousMetadata;
2949
- } else {
2950
- const itemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
2951
- metadata = createContainerItemMetadata(state, itemIndex, itemData, itemType);
2952
- state.containerItemMetadata.set(containerId, metadata);
2948
+ return previousMetadata;
2953
2949
  }
2950
+ const resolvedItemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
2951
+ const metadata = createContainerItemMetadata(state, itemIndex, itemData, resolvedItemType);
2952
+ state.containerItemMetadata.set(containerId, metadata);
2953
+ return metadata;
2954
+ }
2955
+ function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
2956
+ var _a3;
2957
+ const { getFixedItemSize } = state.props;
2958
+ const metadata = updateContainerItemMetadata(state, containerId, itemIndex, itemData);
2954
2959
  if (metadata.getFixedItemSize !== getFixedItemSize) {
2955
2960
  metadata.didResolveFixedItemSize = false;
2956
2961
  metadata.fixedItemSize = void 0;
2957
2962
  metadata.getFixedItemSize = getFixedItemSize;
2958
2963
  }
2959
2964
  if (getFixedItemSize && !metadata.didResolveFixedItemSize) {
2960
- metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_b = metadata.itemType) != null ? _b : "");
2965
+ metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_a3 = metadata.itemType) != null ? _a3 : "");
2961
2966
  metadata.didResolveFixedItemSize = true;
2962
2967
  }
2963
2968
  return metadata;
@@ -3302,6 +3307,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3302
3307
  return { didChangePosition: false, didRefreshData: false };
3303
3308
  }
3304
3309
  const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
3310
+ const metadata = updateContainerItemMetadata(state, containerIndex, itemIndex, item);
3305
3311
  const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3306
3312
  let didChangePosition = false;
3307
3313
  let didRefreshData = false;
@@ -3312,7 +3318,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3312
3318
  return { didChangePosition: false, didRefreshData: false };
3313
3319
  }
3314
3320
  const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
3315
- const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
3321
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item, void 0, void 0, void 0, metadata);
3316
3322
  const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3317
3323
  const column = columns[itemIndex] || 1;
3318
3324
  const span = columnSpans[itemIndex] || 1;
@@ -4598,18 +4604,22 @@ function calculateItemsInView(ctx, params = {}) {
4598
4604
  if (oldKey && oldKey !== id) {
4599
4605
  containerItemKeys.delete(oldKey);
4600
4606
  }
4607
+ state.containerItemMetadata.set(
4608
+ containerIndex,
4609
+ createContainerItemMetadata(state, i, data[i], allocation.itemType)
4610
+ );
4601
4611
  if (oldKey !== id) {
4602
4612
  changedContainerIds != null ? changedContainerIds : changedContainerIds = /* @__PURE__ */ new Set();
4603
4613
  changedContainerIds.add(containerIndex);
4604
4614
  state.containerItemGenerations[containerIndex] = ((_p = state.containerItemGenerations[containerIndex]) != null ? _p : 0) + 1;
4615
+ if (state.props.hideItemsUntilMeasured) {
4616
+ const isLayoutReady = state.sizesKnown.has(id) || resolveContainerItemMetadata(state, containerIndex, i, data[i]).fixedItemSize !== void 0;
4617
+ set$(ctx, `containerLayoutReady${containerIndex}`, isLayoutReady);
4618
+ }
4605
4619
  }
4606
4620
  set$(ctx, `containerItemKey${containerIndex}`, id);
4607
4621
  set$(ctx, `containerItemIndex${containerIndex}`, i);
4608
4622
  set$(ctx, `containerItemData${containerIndex}`, data[i]);
4609
- state.containerItemMetadata.set(
4610
- containerIndex,
4611
- createContainerItemMetadata(state, i, data[i], allocation.itemType)
4612
- );
4613
4623
  containerItemKeys.set(id, containerIndex);
4614
4624
  (_q = state.userScrollAnchorReset) == null ? void 0 : _q.keys.add(id);
4615
4625
  const containerSticky = `containerSticky${containerIndex}`;
@@ -5672,7 +5682,7 @@ var Container = typedMemo(function Container2({
5672
5682
  ]
5673
5683
  );
5674
5684
  const renderedItemInfo = useMemo(
5675
- () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
5685
+ () => itemKey !== void 0 ? getRenderedItem2(itemKey, id) : null,
5676
5686
  [itemKey, data, extraData]
5677
5687
  );
5678
5688
  const { renderedItem } = renderedItemInfo || {};
@@ -6923,6 +6933,16 @@ function checkStructuralDataChange(state, dataProp, previousData) {
6923
6933
  return false;
6924
6934
  }
6925
6935
 
6936
+ // src/core/containerLayoutReady.ts
6937
+ var CONTAINER_LAYOUT_READY_PREFIX = "containerLayoutReady";
6938
+ function resetContainerLayoutReady(ctx) {
6939
+ for (const signalName of ctx.values.keys()) {
6940
+ if (signalName.startsWith(CONTAINER_LAYOUT_READY_PREFIX)) {
6941
+ set$(ctx, signalName, void 0);
6942
+ }
6943
+ }
6944
+ }
6945
+
6926
6946
  // src/core/doInitialAllocateContainers.ts
6927
6947
  function doInitialAllocateContainers(ctx) {
6928
6948
  var _a3, _b;
@@ -7617,34 +7637,37 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
7617
7637
  }
7618
7638
 
7619
7639
  // src/utils/getRenderedItem.ts
7620
- function getRenderedItem(ctx, key) {
7621
- var _a3;
7640
+ function getRenderedItem(ctx, key, containerId) {
7641
+ var _a3, _b, _c;
7622
7642
  const state = ctx.state;
7623
7643
  if (!state) {
7624
7644
  return null;
7625
7645
  }
7646
+ const metadata = state.containerItemMetadata.get(containerId);
7647
+ const useAssignedGeneration = metadata && metadata.dataChangeEpoch !== state.dataChangeEpoch;
7626
7648
  const {
7627
7649
  indexByKey,
7628
- props: { data, getItemType, renderItem }
7650
+ props: { data: currentData, getItemType, renderItem }
7629
7651
  } = state;
7630
- const index = indexByKey.get(key);
7652
+ const data = useAssignedGeneration ? metadata.data : currentData;
7653
+ const index = (_a3 = metadata == null ? void 0 : metadata.itemIndex) != null ? _a3 : indexByKey.get(key);
7631
7654
  if (index === void 0) {
7632
7655
  return null;
7633
7656
  }
7634
7657
  let renderedItem = null;
7635
7658
  const extraData = peek$(ctx, "extraData");
7636
- const item = data[index];
7659
+ const item = useAssignedGeneration ? metadata.itemData : data[index];
7637
7660
  if (renderItem && !isNullOrUndefined(item)) {
7638
7661
  const itemProps = {
7639
7662
  data,
7640
7663
  extraData,
7641
7664
  index,
7642
7665
  item,
7643
- type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
7666
+ type: useAssignedGeneration ? (_b = metadata.itemType) != null ? _b : "" : getItemType ? (_c = getItemType(item, index)) != null ? _c : "" : ""
7644
7667
  };
7645
7668
  renderedItem = renderItem(itemProps);
7646
7669
  }
7647
- return { index, item: data[index], renderedItem };
7670
+ return { index, item, renderedItem };
7648
7671
  }
7649
7672
 
7650
7673
  // src/utils/normalizeMaintainScrollAtEnd.ts
@@ -7810,6 +7833,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7810
7833
  initialScrollIndex: initialScrollIndexProp,
7811
7834
  initialScrollOffset: initialScrollOffsetProp,
7812
7835
  experimental_adaptiveRender,
7836
+ experimental_hideItemsUntilMeasured,
7813
7837
  itemsAreEqual,
7814
7838
  keyExtractor: keyExtractorProp,
7815
7839
  ListEmptyComponent,
@@ -8030,6 +8054,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8030
8054
  const state = refState.current;
8031
8055
  const isFirstLocal = state.isFirst;
8032
8056
  const previousAdaptiveRender = state.props.adaptiveRender;
8057
+ const previousHideItemsUntilMeasured = state.props.hideItemsUntilMeasured;
8033
8058
  const previousNumColumnsProp = state.props.numColumns;
8034
8059
  const didScrollAxisGapChange = !isFirstLocal && ctx.scrollAxisGap !== nextScrollAxisGap;
8035
8060
  ctx.scrollAxisGap = nextScrollAxisGap;
@@ -8075,6 +8100,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8075
8100
  estimatedItemSize,
8076
8101
  getFixedItemSize: useWrapIfItem(getFixedItemSize),
8077
8102
  getItemType: useWrapIfItem(getItemType),
8103
+ hideItemsUntilMeasured: experimental_hideItemsUntilMeasured,
8078
8104
  horizontal: !!horizontal,
8079
8105
  itemsAreEqual,
8080
8106
  keyExtractor: useWrapIfItem(keyExtractor),
@@ -8112,6 +8138,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8112
8138
  if (!isFirstLocal && previousAdaptiveRender && !experimental_adaptiveRender) {
8113
8139
  resetAdaptiveRender(ctx);
8114
8140
  }
8141
+ if (!isFirstLocal && previousHideItemsUntilMeasured && !experimental_hideItemsUntilMeasured) {
8142
+ resetContainerLayoutReady(ctx);
8143
+ }
8115
8144
  const memoizedLastItemKeys = useMemo(() => {
8116
8145
  if (!dataProp.length) return [];
8117
8146
  return Array.from(
@@ -8360,7 +8389,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
8360
8389
  }, [ctx, usesBootstrapInitialScroll]);
8361
8390
  const fns = useMemo(
8362
8391
  () => ({
8363
- getRenderedItem: (key) => getRenderedItem(ctx, key),
8392
+ getRenderedItem: (key, containerId) => getRenderedItem(ctx, key, containerId),
8364
8393
  onMomentumScrollEnd: (event) => {
8365
8394
  checkFinishedScrollFallback(ctx);
8366
8395
  if (state.props.onMomentumScrollEnd) {