@legendapp/list 1.0.0-beta.16 → 1.0.0-beta.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -78,6 +78,14 @@ function set$(ctx, signalName, value) {
78
78
  }
79
79
  }
80
80
  }
81
+ function getContentSize(ctx) {
82
+ const { values } = ctx;
83
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
84
+ const headerSize = values.get("headerSize") || 0;
85
+ const footerSize = values.get("footerSize") || 0;
86
+ const totalSize = values.get("totalSize") || 0;
87
+ return headerSize + footerSize + totalSize + stylePaddingTop;
88
+ }
81
89
  var symbolFirst = Symbol();
82
90
  function useInit(cb) {
83
91
  const refValue = React6.useRef(symbolFirst);
@@ -164,7 +172,9 @@ function useRecyclingState(valueOrFun) {
164
172
  return stateInfo;
165
173
  }
166
174
  var DebugView = React6.memo(function DebugView2({ state }) {
167
- const paddingTop = use$("paddingTop");
175
+ const ctx = useStateContext();
176
+ const totalSize = use$("totalSize");
177
+ const contentSize = getContentSize(ctx);
168
178
  const [, forceUpdate] = React6.useReducer((x) => x + 1, 0);
169
179
  useInterval(() => {
170
180
  forceUpdate();
@@ -182,7 +192,8 @@ var DebugView = React6.memo(function DebugView2({ state }) {
182
192
  backgroundColor: "#FFFFFFCC"
183
193
  }
184
194
  },
185
- /* @__PURE__ */ React6__namespace.createElement(reactNative.Text, null, "PaddingTop: ", paddingTop),
195
+ /* @__PURE__ */ React6__namespace.createElement(reactNative.Text, null, "TotalSize: ", totalSize),
196
+ /* @__PURE__ */ React6__namespace.createElement(reactNative.Text, null, "ContentSize: ", contentSize),
186
197
  /* @__PURE__ */ React6__namespace.createElement(reactNative.Text, null, "At end: ", String(state.isAtBottom))
187
198
  );
188
199
  });
@@ -224,13 +235,17 @@ var Container = ({
224
235
  const position = use$(`containerPosition${id}`) || ANCHORED_POSITION_OUT_OF_VIEW;
225
236
  const column = use$(`containerColumn${id}`) || 0;
226
237
  const numColumns = use$("numColumns");
238
+ const lastItemKeys = use$("lastItemKeys");
239
+ const itemKey = use$(`containerItemKey${id}`);
240
+ const data = use$(`containerItemData${id}`);
241
+ const extraData = use$("extraData");
227
242
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
228
243
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
229
244
  let verticalPaddingStyles;
230
245
  if (columnWrapperStyle && !horizontal && numColumns > 1) {
231
246
  const { columnGap, rowGap, gap } = columnWrapperStyle;
232
247
  verticalPaddingStyles = {
233
- paddingVertical: rowGap || gap || void 0,
248
+ paddingBottom: !lastItemKeys.has(itemKey) ? rowGap || gap || void 0 : void 0,
234
249
  // Apply horizontal padding based on column position (first, middle, or last)
235
250
  paddingLeft: column > 1 ? (columnGap || gap || 0) / 2 : void 0,
236
251
  paddingRight: column < numColumns ? (columnGap || gap || 0) / 2 : void 0
@@ -251,12 +266,8 @@ var Container = ({
251
266
  top: position.relativeCoordinate,
252
267
  ...verticalPaddingStyles || {}
253
268
  };
254
- const lastItemKey = use$("lastItemKey");
255
- const itemKey = use$(`containerItemKey${id}`);
256
- const data = use$(`containerItemData${id}`);
257
- const extraData = use$("extraData");
258
269
  const renderedItemInfo = React6.useMemo(
259
- () => itemKey !== void 0 && getRenderedItem(itemKey),
270
+ () => itemKey !== void 0 ? getRenderedItem(itemKey) : null,
260
271
  [itemKey, data, extraData]
261
272
  );
262
273
  const { index, renderedItem } = renderedItemInfo || {};
@@ -265,7 +276,7 @@ var Container = ({
265
276
  const layout = event.nativeEvent.layout;
266
277
  const size = Math.floor(layout[horizontal ? "width" : "height"] * 8) / 8;
267
278
  if (size === 0) {
268
- if (layout.y !== POSITION_OUT_OF_VIEW && layout.y !== POSITION_OUT_OF_VIEW) {
279
+ if (layout.x !== POSITION_OUT_OF_VIEW && layout.y !== POSITION_OUT_OF_VIEW) {
269
280
  console.log(
270
281
  "[WARN] Container 0 height reported, possible bug in LegendList",
271
282
  id,
@@ -297,7 +308,7 @@ var Container = ({
297
308
  () => ({ containerId: id, itemKey, index, value: data }),
298
309
  [id, itemKey, index, data]
299
310
  );
300
- const contentFragment = /* @__PURE__ */ React6__namespace.default.createElement(React6__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React6__namespace.default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent));
311
+ const contentFragment = /* @__PURE__ */ React6__namespace.default.createElement(React6__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React6__namespace.default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && !lastItemKeys.has(itemKey) && /* @__PURE__ */ React6__namespace.default.createElement(ItemSeparatorComponent, { leadingItem: renderedItemInfo.item })));
301
312
  if (maintainVisibleContentPosition) {
302
313
  const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
303
314
  if (ENABLE_DEVMODE) {
@@ -308,6 +319,8 @@ var Container = ({
308
319
  }
309
320
  return /* @__PURE__ */ React6__namespace.default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
310
321
  };
322
+ var typedForwardRef = React6.forwardRef;
323
+ var typedMemo = React6.memo;
311
324
  var useAnimatedValue = (initialValue) => {
312
325
  return React6.useRef(new reactNative.Animated.Value(initialValue)).current;
313
326
  };
@@ -336,7 +349,7 @@ function useValue$(key, getValue, useMicrotask) {
336
349
  }
337
350
 
338
351
  // src/Containers.tsx
339
- var Containers = React6__namespace.memo(function Containers2({
352
+ var Containers = typedMemo(function Containers2({
340
353
  horizontal,
341
354
  recycleItems,
342
355
  ItemSeparatorComponent,
@@ -346,7 +359,7 @@ var Containers = React6__namespace.memo(function Containers2({
346
359
  }) {
347
360
  const numContainers = use$("numContainersPooled");
348
361
  const animSize = useValue$(
349
- "totalSize",
362
+ "totalSizeWithScrollAdjust",
350
363
  void 0,
351
364
  /*useMicrotask*/
352
365
  true
@@ -355,7 +368,7 @@ var Containers = React6__namespace.memo(function Containers2({
355
368
  const containers = [];
356
369
  for (let i = 0; i < numContainers; i++) {
357
370
  containers.push(
358
- /* @__PURE__ */ React6__namespace.createElement(
371
+ /* @__PURE__ */ React.createElement(
359
372
  Container,
360
373
  {
361
374
  id: i,
@@ -370,7 +383,7 @@ var Containers = React6__namespace.memo(function Containers2({
370
383
  );
371
384
  }
372
385
  const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
373
- return /* @__PURE__ */ React6__namespace.createElement(reactNative.Animated.View, { style }, containers);
386
+ return /* @__PURE__ */ React.createElement(reactNative.Animated.View, { style }, containers);
374
387
  });
375
388
 
376
389
  // src/ListComponent.tsx
@@ -434,7 +447,7 @@ var PaddingAndAdjustDevMode = () => {
434
447
  }
435
448
  ));
436
449
  };
437
- var ListComponent = React6__namespace.memo(function ListComponent2({
450
+ var ListComponent = typedMemo(function ListComponent2({
438
451
  style,
439
452
  contentContainerStyle,
440
453
  horizontal,
@@ -455,6 +468,9 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
455
468
  refScrollView,
456
469
  maintainVisibleContentPosition,
457
470
  renderScrollComponent,
471
+ onRefresh,
472
+ refreshing,
473
+ progressViewOffset,
458
474
  ...rest
459
475
  }) {
460
476
  const ctx = useStateContext();
@@ -482,15 +498,12 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
482
498
  },
483
499
  ENABLE_DEVMODE ? /* @__PURE__ */ React6__namespace.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React6__namespace.createElement(PaddingAndAdjust, null),
484
500
  ListHeaderComponent && /* @__PURE__ */ React6__namespace.createElement(
485
- reactNative.Animated.View,
501
+ reactNative.View,
486
502
  {
487
503
  style: ListHeaderComponentStyle,
488
504
  onLayout: (event) => {
489
505
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
490
- const prevSize = peek$(ctx, "headerSize") || 0;
491
- if (size !== prevSize) {
492
- set$(ctx, "headerSize", size);
493
- }
506
+ set$(ctx, "headerSize", size);
494
507
  }
495
508
  },
496
509
  getComponent(ListHeaderComponent)
@@ -503,11 +516,21 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
503
516
  recycleItems,
504
517
  waitForInitialLayout,
505
518
  getRenderedItem,
506
- ItemSeparatorComponent: ItemSeparatorComponent && getComponent(ItemSeparatorComponent),
519
+ ItemSeparatorComponent,
507
520
  updateItemSize
508
521
  }
509
522
  ),
510
- ListFooterComponent && /* @__PURE__ */ React6__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
523
+ ListFooterComponent && /* @__PURE__ */ React6__namespace.createElement(
524
+ reactNative.View,
525
+ {
526
+ style: ListFooterComponentStyle,
527
+ onLayout: (event) => {
528
+ const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
529
+ set$(ctx, "footerSize", size);
530
+ }
531
+ },
532
+ getComponent(ListFooterComponent)
533
+ )
511
534
  );
512
535
  });
513
536
 
@@ -552,7 +575,6 @@ var ScrollAdjustHandler = class {
552
575
  return false;
553
576
  }
554
577
  };
555
- var typedForwardRef = React6.forwardRef;
556
578
  var useCombinedRef = (...refs) => {
557
579
  const callback = React6.useCallback((element) => {
558
580
  for (const ref of refs) {
@@ -752,6 +774,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
752
774
  waitForInitialLayout = true,
753
775
  extraData,
754
776
  onLayout: onLayoutProp,
777
+ onRefresh,
778
+ refreshing,
779
+ progressViewOffset,
755
780
  ...rest
756
781
  } = props;
757
782
  const { style, contentContainerStyle } = props;
@@ -817,13 +842,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
817
842
  positions: /* @__PURE__ */ new Map(),
818
843
  columns: /* @__PURE__ */ new Map(),
819
844
  pendingAdjust: 0,
820
- waitingForMicrotask: false,
821
845
  isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
822
846
  isEndReached: false,
823
847
  isAtBottom: false,
824
848
  isAtTop: false,
825
849
  data: dataProp,
826
- idsInFirstRender: void 0,
827
850
  hasScrolled: false,
828
851
  scrollLength: initialScrollLength,
829
852
  startBuffered: 0,
@@ -850,11 +873,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
850
873
  belowAnchorElementPositions: void 0,
851
874
  rowHeights: /* @__PURE__ */ new Map(),
852
875
  startReachedBlockedByTimer: false,
876
+ endReachedBlockedByTimer: false,
853
877
  scrollForNextCalculateItemsInView: void 0,
854
878
  enableScrollForNextCalculateItemsInView: true,
855
- minIndexSizeChanged: 0
879
+ minIndexSizeChanged: 0,
880
+ numPendingInitialLayout: 0
856
881
  };
857
- refState.current.idsInFirstRender = new Set(dataProp.map((_, i) => getId(i)));
858
882
  if (maintainVisibleContentPosition) {
859
883
  if (initialScrollIndex) {
860
884
  refState.current.anchorElement = {
@@ -874,6 +898,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
874
898
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
875
899
  set$(ctx, "extraData", extraData);
876
900
  }
901
+ const didDataChange = refState.current.data !== dataProp;
902
+ refState.current.data = dataProp;
877
903
  const getAnchorElementIndex = () => {
878
904
  const state = refState.current;
879
905
  if (state.anchorElement) {
@@ -915,7 +941,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
915
941
  });
916
942
  }
917
943
  }
918
- set$(ctx, "totalSize", resultSize);
944
+ set$(ctx, "totalSize", state.totalSize);
945
+ set$(ctx, "totalSizeWithScrollAdjust", resultSize);
919
946
  if (alignItemsAtEnd) {
920
947
  doUpdatePaddingTop();
921
948
  }
@@ -985,10 +1012,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
985
1012
  columns,
986
1013
  scrollAdjustHandler
987
1014
  } = state;
988
- if (state.waitingForMicrotask) {
989
- state.waitingForMicrotask = false;
990
- }
991
- if (!data) {
1015
+ if (!data || scrollLength === 0) {
992
1016
  return;
993
1017
  }
994
1018
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
@@ -1221,7 +1245,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1221
1245
  }
1222
1246
  }
1223
1247
  }
1224
- set$(ctx, "containersDidLayout", true);
1248
+ if (state.numPendingInitialLayout === 0) {
1249
+ state.numPendingInitialLayout = state.endBuffered - state.startBuffered + 1;
1250
+ }
1225
1251
  if (state.viewabilityConfigCallbackPairs) {
1226
1252
  updateViewableItems(
1227
1253
  state,
@@ -1236,9 +1262,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1236
1262
  }, []);
1237
1263
  const doUpdatePaddingTop = () => {
1238
1264
  if (alignItemsAtEnd) {
1239
- const { scrollLength, totalSize } = refState.current;
1240
- const listPaddingTop = peek$(ctx, "stylePaddingTop") || 0;
1241
- const paddingTop = Math.max(0, Math.floor(scrollLength - totalSize - listPaddingTop));
1265
+ const { scrollLength } = refState.current;
1266
+ const contentSize = getContentSize(ctx);
1267
+ const paddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
1242
1268
  set$(ctx, "paddingTop", paddingTop);
1243
1269
  }
1244
1270
  };
@@ -1258,29 +1284,48 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1258
1284
  return true;
1259
1285
  }
1260
1286
  };
1287
+ const checkThreshold = (distance, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
1288
+ const distanceAbs = Math.abs(distance);
1289
+ const isAtThreshold = distanceAbs < threshold;
1290
+ if (!isReached && !isBlockedByTimer) {
1291
+ if (isAtThreshold) {
1292
+ onReached == null ? void 0 : onReached(distance);
1293
+ blockTimer == null ? void 0 : blockTimer(true);
1294
+ setTimeout(() => {
1295
+ blockTimer == null ? void 0 : blockTimer(false);
1296
+ }, 700);
1297
+ return true;
1298
+ }
1299
+ } else {
1300
+ if (distance >= 1.3 * threshold) {
1301
+ return false;
1302
+ }
1303
+ }
1304
+ return isReached;
1305
+ };
1261
1306
  const checkAtBottom = () => {
1262
1307
  if (!refState.current) {
1263
1308
  return;
1264
1309
  }
1265
- const { scrollLength, scroll, totalSize, hasScrolled } = refState.current;
1266
- if (totalSize > 0 && hasScrolled) {
1267
- const distanceFromEnd = Math.abs(
1268
- totalSize - scroll - scrollLength + (peek$(ctx, "paddingTop") || 0)
1269
- );
1270
- if (refState.current) {
1271
- refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1272
- }
1273
- if (!refState.current.isEndReached) {
1274
- if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
1275
- refState.current.isEndReached = true;
1276
- const { onEndReached } = callbacks.current;
1277
- onEndReached == null ? void 0 : onEndReached({ distanceFromEnd });
1278
- }
1279
- } else {
1280
- if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
1281
- refState.current.isEndReached = false;
1310
+ const { scrollLength, scroll, hasScrolled } = refState.current;
1311
+ const contentSize = getContentSize(ctx);
1312
+ if (contentSize > 0 && hasScrolled) {
1313
+ const distanceFromEnd = contentSize - scroll - scrollLength;
1314
+ const distanceFromEndAbs = Math.abs(distanceFromEnd);
1315
+ refState.current.isAtBottom = distanceFromEndAbs < scrollLength * maintainScrollAtEndThreshold;
1316
+ refState.current.isEndReached = checkThreshold(
1317
+ distanceFromEnd,
1318
+ onEndReachedThreshold * scrollLength,
1319
+ refState.current.isEndReached,
1320
+ refState.current.endReachedBlockedByTimer,
1321
+ (distance) => {
1322
+ var _a2, _b2;
1323
+ return (_b2 = (_a2 = callbacks.current).onEndReached) == null ? void 0 : _b2.call(_a2, { distanceFromEnd: distance });
1324
+ },
1325
+ (block) => {
1326
+ refState.current.endReachedBlockedByTimer = block;
1282
1327
  }
1283
- }
1328
+ );
1284
1329
  }
1285
1330
  };
1286
1331
  const checkAtTop = () => {
@@ -1289,22 +1334,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1289
1334
  }
1290
1335
  const { scrollLength, scroll } = refState.current;
1291
1336
  const distanceFromTop = scroll;
1292
- refState.current.isAtTop = distanceFromTop < 0;
1293
- if (!refState.current.isStartReached && !refState.current.startReachedBlockedByTimer) {
1294
- if (distanceFromTop < onStartReachedThreshold * scrollLength) {
1295
- refState.current.isStartReached = true;
1296
- const { onStartReached } = callbacks.current;
1297
- onStartReached == null ? void 0 : onStartReached({ distanceFromStart: scroll });
1298
- refState.current.startReachedBlockedByTimer = true;
1299
- setTimeout(() => {
1300
- refState.current.startReachedBlockedByTimer = false;
1301
- }, 700);
1302
- }
1303
- } else {
1304
- if (distanceFromTop >= 1.3 * onStartReachedThreshold * scrollLength) {
1305
- refState.current.isStartReached = false;
1337
+ const distanceFromTopAbs = Math.abs(distanceFromTop);
1338
+ refState.current.isAtTop = distanceFromTopAbs < 0;
1339
+ refState.current.isStartReached = checkThreshold(
1340
+ distanceFromTop,
1341
+ onStartReachedThreshold * scrollLength,
1342
+ refState.current.isStartReached,
1343
+ refState.current.startReachedBlockedByTimer,
1344
+ (distance) => {
1345
+ var _a2, _b2;
1346
+ return (_b2 = (_a2 = callbacks.current).onStartReached) == null ? void 0 : _b2.call(_a2, { distanceFromStart: distance });
1347
+ },
1348
+ (block) => {
1349
+ refState.current.startReachedBlockedByTimer = block;
1306
1350
  }
1307
- }
1351
+ );
1308
1352
  };
1309
1353
  const checkResetContainers = (isFirst2) => {
1310
1354
  const state = refState.current;
@@ -1415,12 +1459,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1415
1459
  addTotalSize(null, totalSize, totalSizeBelowIndex);
1416
1460
  };
1417
1461
  const isFirst = !refState.current.renderItem;
1418
- if (isFirst || dataProp !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1419
- if (!keyExtractorProp && !isFirst && dataProp !== refState.current.data) {
1462
+ if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
1463
+ if (!keyExtractorProp && !isFirst && didDataChange) {
1420
1464
  refState.current.sizes.clear();
1421
1465
  refState.current.positions.clear();
1422
1466
  }
1423
- refState.current.data = dataProp;
1424
1467
  calcTotalSizesAndPositions({ forgetPositions: false });
1425
1468
  }
1426
1469
  React6.useEffect(() => {
@@ -1433,17 +1476,22 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1433
1476
  set$(ctx, "extraData", extraData);
1434
1477
  }, [extraData]);
1435
1478
  refState.current.renderItem = renderItem;
1436
- const lastItemKey = dataProp.length > 0 ? getId(dataProp.length - 1) : void 0;
1479
+ const memoizedLastItemKeys = React6.useMemo(() => {
1480
+ if (!dataProp.length) return [];
1481
+ return new Set(
1482
+ Array.from({ length: Math.min(numColumnsProp, dataProp.length) }, (_, i) => getId(dataProp.length - 1 - i))
1483
+ );
1484
+ }, [dataProp.length, numColumnsProp, dataProp.slice(-numColumnsProp).toString()]);
1437
1485
  const stylePaddingTop = (_d = (_c = (_a = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _a.paddingTop) != null ? _c : (_b = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _b.paddingTop) != null ? _d : 0;
1438
1486
  const initalizeStateVars = () => {
1439
- set$(ctx, "lastItemKey", lastItemKey);
1487
+ set$(ctx, "lastItemKeys", memoizedLastItemKeys);
1440
1488
  set$(ctx, "numColumns", numColumnsProp);
1441
1489
  set$(ctx, "stylePaddingTop", stylePaddingTop);
1442
1490
  };
1443
1491
  if (isFirst) {
1444
1492
  initalizeStateVars();
1445
1493
  }
1446
- React6.useEffect(initalizeStateVars, [lastItemKey, numColumnsProp, stylePaddingTop]);
1494
+ React6.useEffect(initalizeStateVars, [memoizedLastItemKeys, numColumnsProp, stylePaddingTop]);
1447
1495
  const getRenderedItem = React6.useCallback((key) => {
1448
1496
  var _a2, _b2;
1449
1497
  const state = refState.current;
@@ -1475,34 +1523,40 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1475
1523
  useRecyclingEffect: useRecyclingEffect2,
1476
1524
  useRecyclingState: useRecyclingState2
1477
1525
  });
1478
- return { index, renderedItem };
1526
+ return { index, item: data[index], renderedItem };
1479
1527
  }, []);
1480
- useInit(() => {
1528
+ const doInitialAllocateContainers = () => {
1481
1529
  var _a2;
1482
1530
  const state = refState.current;
1483
- const viewability = setupViewability(props);
1484
- state.viewabilityConfigCallbackPairs = viewability;
1485
- state.enableScrollForNextCalculateItemsInView = !viewability;
1486
1531
  const scrollLength = state.scrollLength;
1487
- const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, dataProp[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
1488
- const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
1489
- for (let i = 0; i < numContainers; i++) {
1490
- set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1491
- set$(ctx, `containerColumn${i}`, -1);
1492
- }
1493
- set$(ctx, "numContainers", numContainers);
1494
- set$(ctx, "numContainersPooled", numContainers * 2);
1495
- if (initialScrollIndex) {
1496
- requestAnimationFrame(() => {
1532
+ if (scrollLength > 0 && !peek$(ctx, "numContainers")) {
1533
+ const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, dataProp[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
1534
+ const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
1535
+ for (let i = 0; i < numContainers; i++) {
1536
+ set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1537
+ set$(ctx, `containerColumn${i}`, -1);
1538
+ }
1539
+ set$(ctx, "numContainers", numContainers);
1540
+ set$(ctx, "numContainersPooled", numContainers * 2);
1541
+ if (initialScrollIndex) {
1542
+ requestAnimationFrame(() => {
1543
+ calculateItemsInView(state.scrollVelocity);
1544
+ });
1545
+ } else {
1497
1546
  calculateItemsInView(state.scrollVelocity);
1498
- });
1499
- } else {
1500
- calculateItemsInView(state.scrollVelocity);
1547
+ }
1501
1548
  }
1549
+ };
1550
+ useInit(() => {
1551
+ const state = refState.current;
1552
+ const viewability = setupViewability(props);
1553
+ state.viewabilityConfigCallbackPairs = viewability;
1554
+ state.enableScrollForNextCalculateItemsInView = !viewability;
1555
+ doInitialAllocateContainers();
1502
1556
  });
1503
1557
  const updateItemSize = React6.useCallback((containerId, itemKey, size) => {
1504
1558
  const state = refState.current;
1505
- const { sizes, indexByKey, columns, sizesLaidOut, data, rowHeights } = state;
1559
+ const { sizes, indexByKey, sizesLaidOut, data, rowHeights } = state;
1506
1560
  if (!data) {
1507
1561
  return;
1508
1562
  }
@@ -1510,8 +1564,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1510
1564
  const numColumns = peek$(ctx, "numColumns");
1511
1565
  state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
1512
1566
  const prevSize = getItemSize(itemKey, index, data);
1567
+ let needsCalculate = false;
1568
+ if (state.numPendingInitialLayout > 0) {
1569
+ state.numPendingInitialLayout--;
1570
+ if (state.numPendingInitialLayout === 0) {
1571
+ needsCalculate = true;
1572
+ state.numPendingInitialLayout = -1;
1573
+ queueMicrotask(() => {
1574
+ set$(ctx, "containersDidLayout", true);
1575
+ });
1576
+ }
1577
+ }
1513
1578
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1514
1579
  let diff;
1580
+ needsCalculate = true;
1515
1581
  if (numColumns > 1) {
1516
1582
  const rowNumber = Math.floor(index / numColumnsProp);
1517
1583
  const prevSizeInRow = getRowHeight(rowNumber);
@@ -1545,22 +1611,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1545
1611
  refState.current.scrollForNextCalculateItemsInView = void 0;
1546
1612
  addTotalSize(itemKey, diff, 0);
1547
1613
  doMaintainScrollAtEnd(true);
1548
- const scrollVelocity = state.scrollVelocity;
1549
- if (!state.waitingForMicrotask && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1550
- if (!peek$(ctx, "containersDidLayout")) {
1551
- state.waitingForMicrotask = true;
1552
- queueMicrotask(() => {
1553
- if (state.waitingForMicrotask) {
1554
- state.waitingForMicrotask = false;
1555
- calculateItemsInView(state.scrollVelocity);
1556
- }
1557
- });
1558
- } else {
1559
- calculateItemsInView(state.scrollVelocity);
1560
- }
1561
- }
1562
1614
  if (onItemSizeChanged) {
1563
- onItemSizeChanged({ size, previous: prevSize, index, itemKey, itemData: data[index] });
1615
+ onItemSizeChanged({
1616
+ size,
1617
+ previous: prevSize,
1618
+ index,
1619
+ itemKey,
1620
+ itemData: data[index]
1621
+ });
1622
+ }
1623
+ }
1624
+ if (needsCalculate) {
1625
+ const scrollVelocity = state.scrollVelocity;
1626
+ if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1) && (!waitForInitialLayout || state.numPendingInitialLayout < 0)) {
1627
+ calculateItemsInView(state.scrollVelocity);
1564
1628
  }
1565
1629
  }
1566
1630
  }, []);
@@ -1572,7 +1636,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1572
1636
  const onLayout = React6.useCallback((event) => {
1573
1637
  const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
1574
1638
  const didChange = scrollLength !== refState.current.scrollLength;
1639
+ refState.current.scrollLength;
1575
1640
  refState.current.scrollLength = scrollLength;
1641
+ doInitialAllocateContainers();
1576
1642
  doMaintainScrollAtEnd(false);
1577
1643
  doUpdatePaddingTop();
1578
1644
  checkAtBottom();
@@ -1692,7 +1758,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1692
1758
  scrollToIndex({ index, animated });
1693
1759
  }
1694
1760
  },
1695
- scrollToEnd: () => refScroller.current.scrollToEnd()
1761
+ scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
1696
1762
  };
1697
1763
  },
1698
1764
  []
@@ -1725,6 +1791,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1725
1791
  maintainVisibleContentPosition,
1726
1792
  scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : reactNative.Platform.OS === "web" ? 16 : void 0,
1727
1793
  waitForInitialLayout,
1794
+ refreshControl: props.refreshControl == null ? /* @__PURE__ */ React6__namespace.createElement(
1795
+ reactNative.RefreshControl,
1796
+ {
1797
+ refreshing: !!refreshing,
1798
+ onRefresh,
1799
+ progressViewOffset
1800
+ }
1801
+ ) : props.refreshControl,
1728
1802
  style
1729
1803
  }
1730
1804
  ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React6__namespace.createElement(DebugView, { state: refState.current }));