@legendapp/list 1.0.14 → 1.0.16

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
@@ -120,6 +120,12 @@ function useArr$(signalNames) {
120
120
  const value = shim.useSyncExternalStore(subscribe, get);
121
121
  return value;
122
122
  }
123
+ function useSelector$(signalName, selector) {
124
+ const ctx = React2__namespace.useContext(ContextState);
125
+ const { subscribe, get } = React2__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
126
+ const value = shim.useSyncExternalStore(subscribe, () => selector(get()[0]));
127
+ return value;
128
+ }
123
129
 
124
130
  // src/DebugView.tsx
125
131
  var DebugRow = ({ children }) => {
@@ -167,7 +173,7 @@ var DebugView = React2__namespace.memo(function DebugView2({ state }) {
167
173
  },
168
174
  /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "TotalSize:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, totalSize.toFixed(2))),
169
175
  /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "ContentSize:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, contentSize.toFixed(2))),
170
- /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "At end:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, String(state.isAtBottom))),
176
+ /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "At end:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, String(state.isAtEnd))),
171
177
  /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null),
172
178
  /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "ScrollAdjust:"), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, scrollAdjust.toFixed(2))),
173
179
  /* @__PURE__ */ React2__namespace.createElement(DebugRow, null, /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, "TotalSizeReal: "), /* @__PURE__ */ React2__namespace.createElement(reactNative.Text, null, totalSizeWithScrollAdjust.toFixed(2))),
@@ -194,9 +200,6 @@ function warnDevOnce(id, text) {
194
200
  console.warn(`[legend-list] ${text}`);
195
201
  }
196
202
  }
197
- function roundSize(size) {
198
- return Math.floor(size * 8) / 8;
199
- }
200
203
  function isNullOrUndefined(value) {
201
204
  return value === null || value === void 0;
202
205
  }
@@ -308,6 +311,11 @@ function useRecyclingState(valueOrFun) {
308
311
  );
309
312
  return [refState.current.value, setState];
310
313
  }
314
+ function useIsLastItem() {
315
+ const { itemKey } = React2.useContext(ContextContainer);
316
+ const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
317
+ return isLast;
318
+ }
311
319
  var LeanViewComponent = React2__namespace.forwardRef((props, ref) => {
312
320
  return React2__namespace.createElement("RCTView", { ...props, ref });
313
321
  });
@@ -366,12 +374,12 @@ var Container = ({
366
374
  if (horizontal) {
367
375
  paddingStyles = {
368
376
  paddingRight: !lastItemKeys.includes(itemKey) ? columnGap || gap || void 0 : void 0,
369
- paddingVertical: (rowGap || gap || 0) / 2
377
+ paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
370
378
  };
371
379
  } else {
372
380
  paddingStyles = {
373
381
  paddingBottom: !lastItemKeys.includes(itemKey) ? rowGap || gap || void 0 : void 0,
374
- paddingHorizontal: (columnGap || gap || 0) / 2
382
+ paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
375
383
  };
376
384
  }
377
385
  }
@@ -379,7 +387,6 @@ var Container = ({
379
387
  flexDirection: ItemSeparatorComponent ? "row" : void 0,
380
388
  position: "absolute",
381
389
  top: otherAxisPos,
382
- bottom: numColumns > 1 ? null : 0,
383
390
  height: otherAxisSize,
384
391
  left: position.relativeCoordinate,
385
392
  ...paddingStyles || {}
@@ -402,17 +409,17 @@ var Container = ({
402
409
  const onLayout = (event) => {
403
410
  var _a, _b;
404
411
  if (!isNullOrUndefined(itemKey)) {
405
- const layout = event.nativeEvent.layout;
406
- let size = roundSize(layout[horizontal ? "width" : "height"]);
412
+ let layout = event.nativeEvent.layout;
413
+ const size = layout[horizontal ? "width" : "height"];
407
414
  const doUpdate = () => {
408
- refLastSize.current = size;
409
- updateItemSize(itemKey, size);
415
+ refLastSize.current = { width: layout.width, height: layout.height };
416
+ updateItemSize(itemKey, layout);
410
417
  };
411
418
  if (IsNewArchitecture || size > 0) {
412
419
  doUpdate();
413
420
  } else {
414
421
  (_b = (_a = ref.current) == null ? void 0 : _a.measure) == null ? void 0 : _b.call(_a, (x, y, width, height) => {
415
- size = roundSize(horizontal ? width : height);
422
+ layout = { width, height };
416
423
  doUpdate();
417
424
  });
418
425
  }
@@ -426,7 +433,7 @@ var Container = ({
426
433
  if (measured) {
427
434
  const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
428
435
  if (size) {
429
- updateItemSize(itemKey, size);
436
+ updateItemSize(itemKey, measured);
430
437
  }
431
438
  }
432
439
  }
@@ -451,7 +458,7 @@ var Container = ({
451
458
  }, [id, itemKey, index, data]);
452
459
  const contentFragment = /* @__PURE__ */ React2__namespace.default.createElement(React2__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React2__namespace.default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && !lastItemKeys.includes(itemKey) && /* @__PURE__ */ React2__namespace.default.createElement(ItemSeparatorComponent, { leadingItem: renderedItemInfo.item })));
453
460
  if (maintainVisibleContentPosition) {
454
- const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
461
+ const anchorStyle = horizontal ? position.type === "top" ? { position: "absolute", left: 0, top: 0, bottom: 0, flexDirection: "row", alignItems: "stretch" } : { position: "absolute", right: 0, top: 0, bottom: 0, flexDirection: "row", alignItems: "stretch" } : position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
455
462
  if (__DEV__ && ENABLE_DEVMODE) {
456
463
  anchorStyle.borderColor = position.type === "top" ? "red" : "blue";
457
464
  anchorStyle.borderWidth = 1;
@@ -500,7 +507,7 @@ var Containers = typedMemo(function Containers2({
500
507
  }) {
501
508
  const ctx = useStateContext();
502
509
  const columnWrapperStyle = ctx.columnWrapperStyle;
503
- const [numContainers] = useArr$(["numContainersPooled"]);
510
+ const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
504
511
  const animSize = useValue$(
505
512
  "totalSizeWithScrollAdjust",
506
513
  void 0,
@@ -508,6 +515,12 @@ var Containers = typedMemo(function Containers2({
508
515
  true
509
516
  );
510
517
  const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
518
+ const otherAxisSize = useValue$(
519
+ "otherAxisSize",
520
+ void 0,
521
+ /*useMicrotask*/
522
+ true
523
+ );
511
524
  const containers = [];
512
525
  for (let i = 0; i < numContainers; i++) {
513
526
  containers.push(
@@ -525,8 +538,8 @@ var Containers = typedMemo(function Containers2({
525
538
  )
526
539
  );
527
540
  }
528
- const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
529
- if (columnWrapperStyle) {
541
+ const style = horizontal ? { width: animSize, opacity: animOpacity, minHeight: otherAxisSize } : { height: animSize, opacity: animOpacity, minWidth: otherAxisSize };
542
+ if (columnWrapperStyle && numColumns > 1) {
530
543
  const { columnGap, rowGap, gap } = columnWrapperStyle;
531
544
  if (horizontal) {
532
545
  const my = (rowGap || gap || 0) / 2;
@@ -549,11 +562,14 @@ function ListHeaderComponentContainer({
549
562
  horizontal,
550
563
  waitForInitialLayout
551
564
  }) {
552
- const scrollAdjust = useValue$("scrollAdjust", (v) => v, true);
565
+ var _a;
566
+ const hasData = ((_a = peek$(ctx, "lastItemKeys")) == null ? void 0 : _a.length) > 0;
567
+ const scrollAdjust = useValue$("scrollAdjust", (v) => v != null ? v : 0, true);
553
568
  const animOpacity = waitForInitialLayout ? useValue$("containersDidLayout", (value) => value ? 1 : 0) : void 0;
554
569
  const additionalSize = {
555
570
  transform: [{ translateY: reactNative.Animated.multiply(scrollAdjust, -1) }],
556
- opacity: animOpacity
571
+ // Header should show if there's no data yet, but containersDidLayout will be false until it has some data
572
+ opacity: hasData ? animOpacity : 1
557
573
  };
558
574
  return /* @__PURE__ */ React2__namespace.createElement(
559
575
  reactNative.Animated.View,
@@ -650,9 +666,6 @@ var ListComponent = typedMemo(function ListComponent2({
650
666
  refScrollView,
651
667
  maintainVisibleContentPosition,
652
668
  renderScrollComponent,
653
- onRefresh,
654
- refreshing,
655
- progressViewOffset,
656
669
  ...rest
657
670
  }) {
658
671
  const ctx = useStateContext();
@@ -1026,6 +1039,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1026
1039
  onViewableItemsChanged,
1027
1040
  ...rest
1028
1041
  } = props;
1042
+ const refLoadStartTime = React2.useRef(Date.now());
1029
1043
  const callbacks = React2.useRef({
1030
1044
  onStartReached: rest.onStartReached,
1031
1045
  onEndReached: rest.onEndReached
@@ -1060,20 +1074,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1060
1074
  };
1061
1075
  const getItemSize = (key, index, data, useAverageSize = false) => {
1062
1076
  const state = refState.current;
1063
- const sizeKnown = state.sizesKnown.get(key);
1077
+ state.sizesKnown.get(key);
1064
1078
  const sizePrevious = state.sizes.get(key);
1065
1079
  let size;
1066
- const numColumns = peek$(ctx, "numColumns");
1067
- if (sizeKnown === void 0 && !getEstimatedItemSize && numColumns === 1 && useAverageSize) {
1068
- const itemType = "";
1069
- const average = state.averageSizes[itemType];
1070
- if (average) {
1071
- size = roundSize(average.avg);
1072
- if (size !== sizePrevious) {
1073
- addTotalSize(key, size - sizePrevious, 0);
1074
- }
1075
- }
1076
- }
1080
+ peek$(ctx, "numColumns");
1077
1081
  if (size === void 0 && sizePrevious !== void 0) {
1078
1082
  return sizePrevious;
1079
1083
  }
@@ -1094,7 +1098,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1094
1098
  if (canGetSize || getEstimatedItemSize) {
1095
1099
  const sizeFn = (index2) => {
1096
1100
  if (canGetSize) {
1097
- return getItemSize(getId(index2), index2, data[index2]);
1101
+ return getItemSize(getId(index2), index2, data[index2], true);
1098
1102
  }
1099
1103
  return getEstimatedItemSize(index2, data[index2]);
1100
1104
  };
@@ -1121,8 +1125,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1121
1125
  pendingAdjust: 0,
1122
1126
  isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
1123
1127
  isEndReached: false,
1124
- isAtBottom: false,
1125
- isAtTop: false,
1128
+ isAtEnd: false,
1129
+ isAtStart: false,
1126
1130
  data: dataProp,
1127
1131
  scrollLength: initialScrollLength,
1128
1132
  startBuffered: -1,
@@ -1207,6 +1211,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1207
1211
  index = 0;
1208
1212
  }
1209
1213
  const firstIndexOffset = calculateOffsetForIndex(index);
1214
+ const isLast = index === state.data.length - 1;
1215
+ if (isLast && viewPosition !== void 0) {
1216
+ viewPosition = 1;
1217
+ }
1210
1218
  let firstIndexScrollPostion = firstIndexOffset - viewOffset;
1211
1219
  const diff = Math.abs(state.scroll - firstIndexScrollPostion);
1212
1220
  const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
@@ -1222,14 +1230,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1222
1230
  state.minIndexSizeChanged = index;
1223
1231
  firstIndexScrollPostion = firstIndexOffset - viewOffset + state.scrollAdjustHandler.getAppliedAdjust();
1224
1232
  }
1225
- if (viewPosition) {
1226
- firstIndexScrollPostion -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
1227
- }
1228
- scrollTo(firstIndexScrollPostion, animated);
1233
+ scrollTo({ offset: firstIndexScrollPostion, animated, index, viewPosition, viewOffset });
1229
1234
  };
1230
1235
  const setDidLayout = () => {
1231
1236
  refState.current.queuedInitialLayout = true;
1232
1237
  checkAtBottom();
1238
+ const setIt = () => {
1239
+ set$(ctx, "containersDidLayout", true);
1240
+ if (props.onLoad) {
1241
+ props.onLoad({ elapsedTimeInMs: Date.now() - refLoadStartTime.current });
1242
+ }
1243
+ };
1233
1244
  if (initialScrollIndex) {
1234
1245
  queueMicrotask(() => {
1235
1246
  scrollToIndex({ index: initialScrollIndex, animated: false });
@@ -1237,13 +1248,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1237
1248
  if (!IsNewArchitecture) {
1238
1249
  scrollToIndex({ index: initialScrollIndex, animated: false });
1239
1250
  }
1240
- set$(ctx, "containersDidLayout", true);
1251
+ setIt();
1241
1252
  });
1242
1253
  });
1243
1254
  } else {
1244
- queueMicrotask(() => {
1245
- set$(ctx, "containersDidLayout", true);
1246
- });
1255
+ queueMicrotask(setIt);
1247
1256
  }
1248
1257
  };
1249
1258
  const addTotalSize = React2.useCallback((key, add, totalSizeBelowAnchor) => {
@@ -1329,7 +1338,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1329
1338
  };
1330
1339
  const disableScrollJumps = (timeout) => {
1331
1340
  const state = refState.current;
1332
- if (state.scrollingToOffset === void 0) {
1341
+ if (state.scrollingTo === void 0) {
1333
1342
  state.disableScrollJumpsFrom = state.scroll - state.scrollAdjustHandler.getAppliedAdjust();
1334
1343
  state.scrollHistory.length = 0;
1335
1344
  setTimeout(() => {
@@ -1375,10 +1384,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1375
1384
  });
1376
1385
  numMeasurements++;
1377
1386
  if (measured) {
1378
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
1379
1387
  updateItemSize(
1380
1388
  itemKey,
1381
- size,
1389
+ measured,
1382
1390
  /*fromFixGaps*/
1383
1391
  true
1384
1392
  );
@@ -1476,13 +1484,15 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1476
1484
  scrollBufferBottom = scrollBuffer * 0.1;
1477
1485
  }
1478
1486
  }
1487
+ const scrollTopBuffered = scroll - scrollBufferTop;
1488
+ const scrollBottom = scroll + scrollLength;
1489
+ const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1479
1490
  if (state.scrollForNextCalculateItemsInView) {
1480
1491
  const { top: top2, bottom } = state.scrollForNextCalculateItemsInView;
1481
- if (scroll > top2 && scroll < bottom) {
1492
+ if (scrollTopBuffered > top2 && scrollBottomBuffered < bottom) {
1482
1493
  return;
1483
1494
  }
1484
1495
  }
1485
- const scrollBottom = scroll + scrollLength;
1486
1496
  let startNoBuffer = null;
1487
1497
  let startBuffered = null;
1488
1498
  let startBufferedId = null;
@@ -1562,7 +1572,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1562
1572
  if (startNoBuffer === null && top + size > scroll) {
1563
1573
  startNoBuffer = i;
1564
1574
  }
1565
- if (startBuffered === null && top + size > scroll - scrollBufferTop) {
1575
+ if (startBuffered === null && top + size > scrollTopBuffered) {
1566
1576
  startBuffered = i;
1567
1577
  startBufferedId = id;
1568
1578
  nextTop = top;
@@ -1571,7 +1581,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1571
1581
  if (top <= scrollBottom) {
1572
1582
  endNoBuffer = i;
1573
1583
  }
1574
- if (top <= scrollBottom + scrollBufferBottom) {
1584
+ if (top <= scrollBottomBuffered) {
1575
1585
  endBuffered = i;
1576
1586
  nextBottom = top + maxSizeInRow - scrollLength;
1577
1587
  } else {
@@ -1731,18 +1741,26 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1731
1741
  const finishScrollTo = () => {
1732
1742
  const state = refState.current;
1733
1743
  if (state) {
1734
- state.scrollingToOffset = void 0;
1744
+ state.scrollingTo = void 0;
1735
1745
  state.scrollAdjustHandler.setDisableAdjust(false);
1736
1746
  state.scrollHistory.length = 0;
1737
1747
  calculateItemsInView();
1738
1748
  }
1739
1749
  };
1740
- const scrollTo = (offset, animated) => {
1750
+ const scrollTo = (params = {}) => {
1741
1751
  var _a;
1742
1752
  const state = refState.current;
1753
+ const { animated, index, viewPosition, viewOffset } = params;
1754
+ let { offset } = params;
1755
+ if (viewOffset) {
1756
+ offset -= viewOffset;
1757
+ }
1758
+ if (viewPosition !== void 0 && index !== void 0) {
1759
+ offset -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
1760
+ }
1743
1761
  state.scrollAdjustHandler.setDisableAdjust(true);
1744
1762
  state.scrollHistory.length = 0;
1745
- state.scrollingToOffset = offset;
1763
+ state.scrollingTo = params;
1746
1764
  (_a = refScroller.current) == null ? void 0 : _a.scrollTo({
1747
1765
  x: horizontal ? offset : 0,
1748
1766
  y: horizontal ? 0 : offset,
@@ -1754,7 +1772,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1754
1772
  };
1755
1773
  const doMaintainScrollAtEnd = (animated) => {
1756
1774
  const state = refState.current;
1757
- if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
1775
+ if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
1758
1776
  const paddingTop = peek$(ctx, "alignItemsPaddingTop");
1759
1777
  if (paddingTop > 0) {
1760
1778
  state.scroll = 0;
@@ -1803,9 +1821,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1803
1821
  const contentSize = getContentSize(ctx);
1804
1822
  if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
1805
1823
  const distanceFromEnd = contentSize - scroll - scrollLength;
1806
- const distanceFromEndAbs = Math.abs(distanceFromEnd);
1807
1824
  const isContentLess = contentSize < scrollLength;
1808
- refState.current.isAtBottom = isContentLess || distanceFromEndAbs < scrollLength * maintainScrollAtEndThreshold;
1825
+ refState.current.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1809
1826
  refState.current.isEndReached = checkThreshold(
1810
1827
  distanceFromEnd,
1811
1828
  isContentLess,
@@ -1828,7 +1845,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1828
1845
  }
1829
1846
  const { scrollLength, scroll } = refState.current;
1830
1847
  const distanceFromTop = scroll;
1831
- refState.current.isAtTop = distanceFromTop <= 0;
1848
+ refState.current.isAtStart = distanceFromTop <= 0;
1832
1849
  refState.current.isStartReached = checkThreshold(
1833
1850
  distanceFromTop,
1834
1851
  false,
@@ -1860,8 +1877,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1860
1877
  for (let i = 0; i < numContainers; i++) {
1861
1878
  const itemKey = peek$(ctx, `containerItemKey${i}`);
1862
1879
  if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
1863
- set$(ctx, `containerItemKey${i}`, null);
1864
- set$(ctx, `containerItemData${i}`, null);
1880
+ set$(ctx, `containerItemKey${i}`, void 0);
1881
+ set$(ctx, `containerItemData${i}`, void 0);
1865
1882
  set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
1866
1883
  set$(ctx, `containerColumn${i}`, -1);
1867
1884
  }
@@ -1923,7 +1940,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1923
1940
  };
1924
1941
  state.anchorElement = newAnchorElement;
1925
1942
  (_b = state.belowAnchorElementPositions) == null ? void 0 : _b.clear();
1926
- scrollTo(0, false);
1943
+ scrollTo({ offset: 0, animated: false });
1927
1944
  setTimeout(() => {
1928
1945
  calculateItemsInView(
1929
1946
  /*reset*/
@@ -1941,7 +1958,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1941
1958
  } else {
1942
1959
  state.startBufferedId = void 0;
1943
1960
  }
1944
- scrollTo(0, false);
1961
+ scrollTo({ offset: 0, animated: false });
1945
1962
  setTimeout(() => {
1946
1963
  calculateItemsInView(
1947
1964
  /*reset*/
@@ -2049,7 +2066,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2049
2066
  const paddingDiff = stylePaddingTopState - prevPaddingTop;
2050
2067
  if (paddingDiff && prevPaddingTop !== void 0 && reactNative.Platform.OS === "ios") {
2051
2068
  queueMicrotask(() => {
2052
- scrollTo(refState.current.scroll + paddingDiff, false);
2069
+ scrollTo({ offset: refState.current.scroll + paddingDiff, animated: false });
2053
2070
  });
2054
2071
  }
2055
2072
  };
@@ -2084,7 +2101,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2084
2101
  refState.current.renderItem = renderItem;
2085
2102
  React2.useEffect(initalizeStateVars, [memoizedLastItemKeys.join(","), numColumnsProp, stylePaddingTopState]);
2086
2103
  const getRenderedItem = React2.useCallback((key) => {
2087
- var _a, _b;
2088
2104
  const state = refState.current;
2089
2105
  if (!state) {
2090
2106
  return null;
@@ -2094,11 +2110,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2094
2110
  if (index === void 0) {
2095
2111
  return null;
2096
2112
  }
2097
- const renderedItem = (_b = (_a = refState.current).renderItem) == null ? void 0 : _b.call(_a, {
2098
- item: data[index],
2099
- index,
2100
- extraData: peek$(ctx, "extraData")
2101
- });
2113
+ const renderItemProp = refState.current.renderItem;
2114
+ let renderedItem = null;
2115
+ if (renderItemProp) {
2116
+ const itemProps = {
2117
+ item: data[index],
2118
+ index,
2119
+ extraData: peek$(ctx, "extraData")
2120
+ };
2121
+ renderedItem = isFunction(renderItemProp) ? renderItemProp(itemProps) : React2__namespace.createElement(renderItemProp, itemProps);
2122
+ }
2102
2123
  return { index, item: data[index], renderedItem };
2103
2124
  }, []);
2104
2125
  const doInitialAllocateContainers = () => {
@@ -2142,120 +2163,130 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2142
2163
  useInit(() => {
2143
2164
  doInitialAllocateContainers();
2144
2165
  });
2145
- const updateItemSize = React2.useCallback((itemKey, size, fromFixGaps) => {
2146
- const state = refState.current;
2147
- const {
2148
- sizes,
2149
- indexByKey,
2150
- sizesKnown,
2151
- data,
2152
- rowHeights,
2153
- startBuffered,
2154
- endBuffered,
2155
- averageSizes,
2156
- queuedInitialLayout
2157
- } = state;
2158
- if (!data) {
2159
- return;
2160
- }
2161
- const index = indexByKey.get(itemKey);
2162
- const numColumns = peek$(ctx, "numColumns");
2163
- state.scrollForNextCalculateItemsInView = void 0;
2164
- state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
2165
- const prevSize = getItemSize(itemKey, index, data);
2166
- const prevSizeKnown = sizesKnown.get(itemKey);
2167
- let needsCalculate = false;
2168
- let needsUpdateContainersDidLayout = false;
2169
- sizesKnown.set(itemKey, size);
2170
- const itemType = "";
2171
- let averages = averageSizes[itemType];
2172
- if (!averages) {
2173
- averages = averageSizes[itemType] = {
2174
- num: 0,
2175
- avg: 0
2176
- };
2177
- }
2178
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2179
- averages.num++;
2180
- if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2181
- let diff;
2182
- needsCalculate = true;
2183
- if (numColumns > 1) {
2184
- const rowNumber = Math.floor(index / numColumnsProp);
2185
- const prevSizeInRow = getRowHeight(rowNumber);
2186
- sizes.set(itemKey, size);
2187
- rowHeights.delete(rowNumber);
2188
- const sizeInRow = getRowHeight(rowNumber);
2189
- diff = sizeInRow - prevSizeInRow;
2190
- } else {
2191
- sizes.set(itemKey, size);
2192
- diff = size - prevSize;
2166
+ const updateItemSize = React2.useCallback(
2167
+ (itemKey, sizeObj, fromFixGaps) => {
2168
+ const state = refState.current;
2169
+ const {
2170
+ sizes,
2171
+ indexByKey,
2172
+ sizesKnown,
2173
+ data,
2174
+ rowHeights,
2175
+ startBuffered,
2176
+ endBuffered,
2177
+ averageSizes,
2178
+ queuedInitialLayout
2179
+ } = state;
2180
+ if (!data) {
2181
+ return;
2182
+ }
2183
+ const index = indexByKey.get(itemKey);
2184
+ const numColumns = peek$(ctx, "numColumns");
2185
+ state.scrollForNextCalculateItemsInView = void 0;
2186
+ state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
2187
+ const prevSize = getItemSize(itemKey, index, data);
2188
+ const prevSizeKnown = sizesKnown.get(itemKey);
2189
+ let needsCalculate = false;
2190
+ let needsUpdateContainersDidLayout = false;
2191
+ const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
2192
+ sizesKnown.set(itemKey, size);
2193
+ const itemType = "";
2194
+ let averages = averageSizes[itemType];
2195
+ if (!averages) {
2196
+ averages = averageSizes[itemType] = {
2197
+ num: 0,
2198
+ avg: 0
2199
+ };
2193
2200
  }
2194
- if (__DEV__ && suggestEstimatedItemSize) {
2195
- if (state.timeoutSizeMessage) {
2196
- clearTimeout(state.timeoutSizeMessage);
2201
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2202
+ averages.num++;
2203
+ if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2204
+ let diff;
2205
+ needsCalculate = true;
2206
+ if (numColumns > 1) {
2207
+ const rowNumber = Math.floor(index / numColumnsProp);
2208
+ const prevSizeInRow = getRowHeight(rowNumber);
2209
+ sizes.set(itemKey, size);
2210
+ rowHeights.delete(rowNumber);
2211
+ const sizeInRow = getRowHeight(rowNumber);
2212
+ diff = sizeInRow - prevSizeInRow;
2213
+ } else {
2214
+ sizes.set(itemKey, size);
2215
+ diff = size - prevSize;
2216
+ }
2217
+ if (__DEV__ && suggestEstimatedItemSize) {
2218
+ if (state.timeoutSizeMessage) {
2219
+ clearTimeout(state.timeoutSizeMessage);
2220
+ }
2221
+ state.timeoutSizeMessage = setTimeout(() => {
2222
+ state.timeoutSizeMessage = void 0;
2223
+ const num = sizesKnown.size;
2224
+ const avg = state.averageSizes[""].avg;
2225
+ console.warn(
2226
+ `[legend-list] estimatedItemSize or getEstimatedItemSize are not defined. Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
2227
+ );
2228
+ }, 1e3);
2229
+ }
2230
+ state.scrollForNextCalculateItemsInView = void 0;
2231
+ addTotalSize(itemKey, diff, 0);
2232
+ if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
2233
+ doMaintainScrollAtEnd(false);
2234
+ }
2235
+ if (onItemSizeChanged) {
2236
+ onItemSizeChanged({
2237
+ size,
2238
+ previous: prevSize,
2239
+ index,
2240
+ itemKey,
2241
+ itemData: data[index]
2242
+ });
2197
2243
  }
2198
- state.timeoutSizeMessage = setTimeout(() => {
2199
- state.timeoutSizeMessage = void 0;
2200
- const num = sizesKnown.size;
2201
- const avg = state.averageSizes[""].avg;
2202
- console.warn(
2203
- `[legend-list] estimatedItemSize or getEstimatedItemSize are not defined. Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
2204
- );
2205
- }, 1e3);
2206
2244
  }
2207
- state.scrollForNextCalculateItemsInView = void 0;
2208
- addTotalSize(itemKey, diff, 0);
2209
- if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
2210
- doMaintainScrollAtEnd(false);
2211
- }
2212
- if (onItemSizeChanged) {
2213
- onItemSizeChanged({
2214
- size,
2215
- previous: prevSize,
2216
- index,
2217
- itemKey,
2218
- itemData: data[index]
2219
- });
2245
+ if (!queuedInitialLayout && checkAllSizesKnown()) {
2246
+ needsUpdateContainersDidLayout = true;
2220
2247
  }
2221
- }
2222
- if (!queuedInitialLayout && checkAllSizesKnown()) {
2223
- needsUpdateContainersDidLayout = true;
2224
- }
2225
- let isInView = index >= startBuffered && index <= endBuffered;
2226
- if (!isInView) {
2227
- const numContainers = ctx.values.get("numContainers");
2228
- for (let i = 0; i < numContainers; i++) {
2229
- if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
2230
- isInView = true;
2231
- break;
2248
+ let isInView = index >= startBuffered && index <= endBuffered;
2249
+ if (!isInView) {
2250
+ const numContainers = ctx.values.get("numContainers");
2251
+ for (let i = 0; i < numContainers; i++) {
2252
+ if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
2253
+ isInView = true;
2254
+ break;
2255
+ }
2232
2256
  }
2233
2257
  }
2234
- }
2235
- if (needsUpdateContainersDidLayout || !fromFixGaps && needsCalculate && (isInView || !queuedInitialLayout)) {
2236
- const scrollVelocity = state.scrollVelocity;
2237
- let didCalculate = false;
2238
- if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1 || state.scrollingToOffset !== void 0) && (!waitForInitialLayout || needsUpdateContainersDidLayout || queuedInitialLayout)) {
2239
- if (Date.now() - state.lastBatchingAction < 500) {
2240
- if (!state.queuedCalculateItemsInView) {
2241
- state.queuedCalculateItemsInView = requestAnimationFrame(() => {
2242
- state.queuedCalculateItemsInView = void 0;
2243
- calculateItemsInView();
2244
- });
2258
+ if (needsUpdateContainersDidLayout || !fromFixGaps && needsCalculate && (isInView || !queuedInitialLayout)) {
2259
+ const scrollVelocity = state.scrollVelocity;
2260
+ let didCalculate = false;
2261
+ if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1 || state.scrollingTo !== void 0) && (!waitForInitialLayout || needsUpdateContainersDidLayout || queuedInitialLayout)) {
2262
+ if (Date.now() - state.lastBatchingAction < 500) {
2263
+ if (!state.queuedCalculateItemsInView) {
2264
+ state.queuedCalculateItemsInView = requestAnimationFrame(() => {
2265
+ state.queuedCalculateItemsInView = void 0;
2266
+ calculateItemsInView();
2267
+ });
2268
+ }
2269
+ } else {
2270
+ calculateItemsInView();
2271
+ didCalculate = true;
2245
2272
  }
2246
- } else {
2247
- calculateItemsInView();
2248
- didCalculate = true;
2273
+ }
2274
+ if (!didCalculate && !needsUpdateContainersDidLayout && IsNewArchitecture) {
2275
+ fixGaps();
2249
2276
  }
2250
2277
  }
2251
- if (!didCalculate && !needsUpdateContainersDidLayout && IsNewArchitecture) {
2252
- fixGaps();
2278
+ if (state.needsOtherAxisSize) {
2279
+ const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
2280
+ const cur = peek$(ctx, "otherAxisSize");
2281
+ if (!cur || otherAxisSize > cur) {
2282
+ set$(ctx, "otherAxisSize", otherAxisSize);
2283
+ }
2253
2284
  }
2254
- }
2255
- }, []);
2256
- const onLayout = React2.useCallback((event) => {
2285
+ },
2286
+ []
2287
+ );
2288
+ const handleLayout = React2.useCallback((scrollLength) => {
2257
2289
  const state = refState.current;
2258
- const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
2259
2290
  const didChange = scrollLength !== state.scrollLength;
2260
2291
  state.scrollLength = scrollLength;
2261
2292
  state.lastBatchingAction = Date.now();
@@ -2268,20 +2299,36 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2268
2299
  if (didChange) {
2269
2300
  calculateItemsInView();
2270
2301
  }
2271
- if (__DEV__) {
2272
- const isWidthZero = event.nativeEvent.layout.width === 0;
2273
- const isHeightZero = event.nativeEvent.layout.height === 0;
2274
- if (isWidthZero || isHeightZero) {
2275
- warnDevOnce(
2276
- "height0",
2277
- `[legend-list] List ${isWidthZero ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
2278
- );
2279
- }
2302
+ }, []);
2303
+ const onLayout = React2.useCallback((event) => {
2304
+ const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
2305
+ handleLayout(scrollLength);
2306
+ const otherAxisSize = event.nativeEvent.layout[horizontal ? "height" : "width"];
2307
+ if (refState.current) {
2308
+ refState.current.needsOtherAxisSize = otherAxisSize - (stylePaddingTopState || 0) < 10;
2309
+ }
2310
+ if (__DEV__ && scrollLength === 0) {
2311
+ warnDevOnce(
2312
+ "height0",
2313
+ `List ${horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
2314
+ );
2280
2315
  }
2281
2316
  if (onLayoutProp) {
2282
2317
  onLayoutProp(event);
2283
2318
  }
2284
2319
  }, []);
2320
+ if (IsNewArchitecture) {
2321
+ React2.useLayoutEffect(() => {
2322
+ var _a, _b;
2323
+ const measured = (_b = (_a = refScroller.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
2324
+ if (measured) {
2325
+ const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
2326
+ if (size) {
2327
+ handleLayout(size);
2328
+ }
2329
+ }
2330
+ }, []);
2331
+ }
2285
2332
  const handleScroll = React2.useCallback(
2286
2333
  (event) => {
2287
2334
  var _a, _b, _c, _d;
@@ -2301,8 +2348,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2301
2348
  );
2302
2349
  const updateScroll = React2.useCallback((newScroll) => {
2303
2350
  const state = refState.current;
2304
- const scrollingToOffset = state.scrollingToOffset;
2305
- if (scrollingToOffset !== void 0 && Math.abs(newScroll - scrollingToOffset) < 10) {
2351
+ const scrollingTo = state.scrollingTo;
2352
+ if (scrollingTo !== void 0 && Math.abs(newScroll - scrollingTo.offset) < 10) {
2306
2353
  finishScrollTo();
2307
2354
  }
2308
2355
  if (state.disableScrollJumpsFrom !== void 0) {
@@ -2315,7 +2362,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2315
2362
  state.hasScrolled = true;
2316
2363
  state.lastBatchingAction = Date.now();
2317
2364
  const currentTime = performance.now();
2318
- if (scrollingToOffset === void 0 && !(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
2365
+ if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
2319
2366
  state.scrollHistory.push({ scroll: newScroll, time: currentTime });
2320
2367
  }
2321
2368
  if (state.scrollHistory.length > 5) {
@@ -2381,8 +2428,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2381
2428
  contentLength: state.totalSize,
2382
2429
  end: state.endNoBuffer,
2383
2430
  endBuffered: state.endBuffered,
2384
- isAtEnd: state.isAtBottom,
2385
- isAtStart: state.isAtTop,
2431
+ isAtEnd: state.isAtEnd,
2432
+ isAtStart: state.isAtStart,
2386
2433
  scroll: state.scroll,
2387
2434
  scrollLength: state.scrollLength,
2388
2435
  start: state.startNoBuffer,
@@ -2405,10 +2452,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2405
2452
  scrollToIndex({ index, ...props2 });
2406
2453
  }
2407
2454
  },
2408
- scrollToOffset: ({ offset, animated }) => {
2409
- scrollTo(offset, animated);
2410
- },
2411
- scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
2455
+ scrollToOffset: (params) => scrollTo(params),
2456
+ scrollToEnd: (options) => {
2457
+ const { data } = refState.current;
2458
+ const index = data.length - 1;
2459
+ if (index !== -1) {
2460
+ scrollToIndex({ index, ...options });
2461
+ }
2462
+ }
2412
2463
  };
2413
2464
  },
2414
2465
  []
@@ -2418,7 +2469,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2418
2469
  var _a;
2419
2470
  if (initialContentOffset) {
2420
2471
  (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler.setDisableAdjust(true);
2421
- scrollTo(initialContentOffset, false);
2472
+ scrollTo({ offset: initialContentOffset, animated: false });
2422
2473
  setTimeout(() => {
2423
2474
  var _a2;
2424
2475
  (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(false);
@@ -2438,11 +2489,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2438
2489
  handleScroll,
2439
2490
  onMomentumScrollEnd: (event) => {
2440
2491
  var _a;
2441
- const scrollingToOffset = (_a = refState.current) == null ? void 0 : _a.scrollingToOffset;
2442
- if (scrollingToOffset !== void 0) {
2492
+ const scrollingTo = (_a = refState.current) == null ? void 0 : _a.scrollingTo;
2493
+ if (scrollingTo !== void 0) {
2443
2494
  requestAnimationFrame(() => {
2444
- scrollTo(scrollingToOffset, false);
2445
- refState.current.scrollingToOffset = void 0;
2495
+ scrollTo({ ...scrollingTo, animated: false });
2496
+ refState.current.scrollingTo = void 0;
2446
2497
  requestAnimationFrame(() => {
2447
2498
  refState.current.scrollAdjustHandler.setDisableAdjust(false);
2448
2499
  });
@@ -2465,12 +2516,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2465
2516
  maintainVisibleContentPosition,
2466
2517
  scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
2467
2518
  waitForInitialLayout,
2468
- refreshControl: refreshControl != null ? refreshControl : onRefresh && /* @__PURE__ */ React2__namespace.createElement(
2519
+ refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControl, {
2520
+ progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
2521
+ }) : refreshControl : onRefresh && /* @__PURE__ */ React2__namespace.createElement(
2469
2522
  reactNative.RefreshControl,
2470
2523
  {
2471
2524
  refreshing: !!refreshing,
2472
2525
  onRefresh,
2473
- progressViewOffset
2526
+ progressViewOffset: (progressViewOffset || 0) + stylePaddingTopState
2474
2527
  }
2475
2528
  ),
2476
2529
  style,
@@ -2480,6 +2533,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2480
2533
  });
2481
2534
 
2482
2535
  exports.LegendList = LegendList;
2536
+ exports.useIsLastItem = useIsLastItem;
2483
2537
  exports.useRecyclingEffect = useRecyclingEffect;
2484
2538
  exports.useRecyclingState = useRecyclingState;
2485
2539
  exports.useViewability = useViewability;