@legendapp/list 3.0.0-beta.32 → 3.0.0-beta.34

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.
Files changed (54) hide show
  1. package/README.md +7 -1
  2. package/animated.d.ts +605 -6
  3. package/animated.js +2 -2
  4. package/animated.mjs +1 -1
  5. package/index.d.ts +503 -118
  6. package/index.js +607 -275
  7. package/index.mjs +607 -275
  8. package/index.native.js +348 -189
  9. package/index.native.mjs +347 -188
  10. package/keyboard-controller.d.ts +616 -6
  11. package/keyboard-controller.js +2 -2
  12. package/keyboard-controller.mjs +1 -1
  13. package/keyboard.d.ts +204 -8
  14. package/keyboard.js +68 -53
  15. package/keyboard.mjs +71 -55
  16. package/{index.d.mts → list-react-native.d.ts} +138 -42
  17. package/list-react-native.js +4348 -0
  18. package/list-react-native.mjs +4318 -0
  19. package/{index.native.d.mts → list-react.d.ts} +195 -42
  20. package/list-react.js +4709 -0
  21. package/list-react.mjs +4679 -0
  22. package/package.json +52 -1
  23. package/reanimated.d.ts +605 -7
  24. package/reanimated.js +180 -12
  25. package/reanimated.mjs +177 -9
  26. package/section-list.d.ts +615 -14
  27. package/section-list.js +6 -6
  28. package/section-list.mjs +1 -1
  29. package/animated.d.mts +0 -9
  30. package/animated.native.d.mts +0 -9
  31. package/animated.native.d.ts +0 -9
  32. package/animated.native.js +0 -9
  33. package/animated.native.mjs +0 -7
  34. package/index.native.d.ts +0 -817
  35. package/keyboard-controller.d.mts +0 -12
  36. package/keyboard-controller.native.d.mts +0 -12
  37. package/keyboard-controller.native.d.ts +0 -12
  38. package/keyboard-controller.native.js +0 -69
  39. package/keyboard-controller.native.mjs +0 -48
  40. package/keyboard.d.mts +0 -13
  41. package/keyboard.native.d.mts +0 -13
  42. package/keyboard.native.d.ts +0 -13
  43. package/keyboard.native.js +0 -399
  44. package/keyboard.native.mjs +0 -377
  45. package/reanimated.d.mts +0 -18
  46. package/reanimated.native.d.mts +0 -18
  47. package/reanimated.native.d.ts +0 -18
  48. package/reanimated.native.js +0 -89
  49. package/reanimated.native.mjs +0 -65
  50. package/section-list.d.mts +0 -112
  51. package/section-list.native.d.mts +0 -112
  52. package/section-list.native.d.ts +0 -112
  53. package/section-list.native.js +0 -293
  54. package/section-list.native.mjs +0 -271
package/index.native.mjs CHANGED
@@ -218,7 +218,7 @@ var _a;
218
218
  var envMode = typeof process !== "undefined" && typeof process.env === "object" && process.env ? (_a = process.env.NODE_ENV) != null ? _a : process.env.MODE : void 0;
219
219
  var processDev = typeof envMode === "string" ? envMode.toLowerCase() !== "production" : void 0;
220
220
  var _a2;
221
- var IS_DEV = (_a2 = metroDev != null ? metroDev : processDev) != null ? _a2 : false;
221
+ var IS_DEV = (_a2 = processDev != null ? processDev : metroDev) != null ? _a2 : false;
222
222
 
223
223
  // src/constants.ts
224
224
  var POSITION_OUT_OF_VIEW = -1e7;
@@ -291,7 +291,7 @@ function useValue$(key, params) {
291
291
  useMemo(() => {
292
292
  let prevValue;
293
293
  let didQueueTask = false;
294
- listen$(ctx, key, (v) => {
294
+ listen$(ctx, key, () => {
295
295
  const newValue = getNewValue();
296
296
  if (delay !== void 0) {
297
297
  const fn = () => {
@@ -320,7 +320,6 @@ function useValue$(key, params) {
320
320
  }, []);
321
321
  return animValue;
322
322
  }
323
- var typedForwardRef = forwardRef;
324
323
  var typedMemo = memo;
325
324
  var getComponent = (Component) => {
326
325
  if (React2.isValidElement(Component)) {
@@ -395,10 +394,7 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
395
394
  const stickyPosition = animatedScrollY.interpolate({
396
395
  extrapolateLeft: "clamp",
397
396
  extrapolateRight: "extend",
398
- inputRange: [
399
- stickyStart,
400
- stickyStart + 5e3
401
- ],
397
+ inputRange: [stickyStart, stickyStart + 5e3],
402
398
  outputRange: [position, position + 5e3]
403
399
  });
404
400
  return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
@@ -616,6 +612,8 @@ function useOnLayoutSync({
616
612
  }
617
613
  var Platform2 = Platform;
618
614
  var PlatformAdjustBreaksScroll = Platform2.OS === "android";
615
+ var typedForwardRef = forwardRef;
616
+ var typedMemo2 = memo;
619
617
 
620
618
  // src/utils/isInMVCPActiveMode.native.ts
621
619
  function isInMVCPActiveMode(state) {
@@ -623,7 +621,7 @@ function isInMVCPActiveMode(state) {
623
621
  }
624
622
 
625
623
  // src/components/Container.tsx
626
- var Container = typedMemo(function Container2({
624
+ var Container = typedMemo2(function Container2({
627
625
  id,
628
626
  recycleItems,
629
627
  horizontal,
@@ -634,6 +632,8 @@ var Container = typedMemo(function Container2({
634
632
  }) {
635
633
  const ctx = useStateContext();
636
634
  const { columnWrapperStyle, animatedScrollY } = ctx;
635
+ const positionComponentInternal = ctx.state.props.positionComponentInternal;
636
+ const stickyPositionComponentInternal = ctx.state.props.stickyPositionComponentInternal;
637
637
  const [column = 0, span = 1, data, itemKey, numColumns = 1, extraData, isSticky] = useArr$([
638
638
  `containerColumn${id}`,
639
639
  `containerSpan${id}`,
@@ -786,7 +786,7 @@ var Container = typedMemo(function Container2({
786
786
  }
787
787
  }, [itemKey]);
788
788
  }
789
- const PositionComponent = isSticky ? PositionViewSticky : PositionView;
789
+ const PositionComponent = isSticky ? stickyPositionComponentInternal ? stickyPositionComponentInternal : PositionViewSticky : positionComponentInternal ? positionComponentInternal : PositionView;
790
790
  return /* @__PURE__ */ React2.createElement(
791
791
  PositionComponent,
792
792
  {
@@ -897,7 +897,7 @@ var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
897
897
  };
898
898
 
899
899
  // src/components/ListComponent.tsx
900
- var ListComponent = typedMemo(function ListComponent2({
900
+ var ListComponent = typedMemo2(function ListComponent2({
901
901
  canRender,
902
902
  style,
903
903
  contentContainerStyle,
@@ -923,12 +923,15 @@ var ListComponent = typedMemo(function ListComponent2({
923
923
  snapToIndices,
924
924
  stickyHeaderConfig,
925
925
  stickyHeaderIndices,
926
+ useWindowScroll = false,
926
927
  ...rest
927
928
  }) {
928
929
  const ctx = useStateContext();
929
930
  const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
930
931
  const ScrollComponent = renderScrollComponent ? useMemo(
931
- () => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
932
+ () => React2.forwardRef(
933
+ (props, ref) => renderScrollComponent({ ...props, ref })
934
+ ),
932
935
  [renderScrollComponent]
933
936
  ) : ListComponentScrollView;
934
937
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
@@ -944,6 +947,7 @@ var ListComponent = typedMemo(function ListComponent2({
944
947
  SnapOrScroll,
945
948
  {
946
949
  ...rest,
950
+ ...ScrollComponent === ListComponentScrollView ? { useWindowScroll } : {},
947
951
  contentContainerStyle: [
948
952
  contentContainerStyle,
949
953
  horizontal ? {
@@ -989,24 +993,12 @@ var ListComponent = typedMemo(function ListComponent2({
989
993
  );
990
994
  });
991
995
 
992
- // src/utils/getId.ts
993
- function getId(state, index) {
994
- const { data, keyExtractor } = state.props;
995
- if (!data) {
996
- return "";
997
- }
998
- const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
999
- const id = ret;
1000
- state.idCache[index] = id;
1001
- return id;
1002
- }
1003
-
1004
996
  // src/core/calculateOffsetForIndex.ts
1005
997
  function calculateOffsetForIndex(ctx, index) {
1006
998
  const state = ctx.state;
1007
999
  let position = 0;
1008
1000
  if (index !== void 0) {
1009
- position = state.positions.get(getId(state, index)) || 0;
1001
+ position = state.positions[index] || 0;
1010
1002
  const paddingTop = peek$(ctx, "stylePaddingTop");
1011
1003
  if (paddingTop) {
1012
1004
  position += paddingTop;
@@ -1019,6 +1011,18 @@ function calculateOffsetForIndex(ctx, index) {
1019
1011
  return position;
1020
1012
  }
1021
1013
 
1014
+ // src/utils/getId.ts
1015
+ function getId(state, index) {
1016
+ const { data, keyExtractor } = state.props;
1017
+ if (!data) {
1018
+ return "";
1019
+ }
1020
+ const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
1021
+ const id = ret;
1022
+ state.idCache[index] = id;
1023
+ return id;
1024
+ }
1025
+
1022
1026
  // src/core/addTotalSize.ts
1023
1027
  function addTotalSize(ctx, key, add) {
1024
1028
  const state = ctx.state;
@@ -1072,13 +1076,13 @@ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
1072
1076
  return sizeKnown;
1073
1077
  }
1074
1078
  let size;
1075
- const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1076
1079
  if (preferCachedSize) {
1077
1080
  const cachedSize = sizes.get(key);
1078
1081
  if (cachedSize !== void 0) {
1079
1082
  return cachedSize;
1080
1083
  }
1081
1084
  }
1085
+ const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1082
1086
  if (getFixedItemSize) {
1083
1087
  size = getFixedItemSize(data, index, itemType);
1084
1088
  if (size !== void 0) {
@@ -1121,12 +1125,15 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1121
1125
  }
1122
1126
 
1123
1127
  // src/core/clampScrollOffset.ts
1124
- function clampScrollOffset(ctx, offset) {
1128
+ function clampScrollOffset(ctx, offset, scrollTarget) {
1125
1129
  const state = ctx.state;
1126
1130
  const contentSize = getContentSize(ctx);
1127
1131
  let clampedOffset = offset;
1128
1132
  if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength) && (Platform2.OS !== "android" || state.lastLayout)) {
1129
- const maxOffset = Math.max(0, contentSize - state.scrollLength);
1133
+ const baseMaxOffset = Math.max(0, contentSize - state.scrollLength);
1134
+ const viewOffset = scrollTarget == null ? void 0 : scrollTarget.viewOffset;
1135
+ const extraEndOffset = typeof viewOffset === "number" && viewOffset < 0 ? -viewOffset : 0;
1136
+ const maxOffset = baseMaxOffset + extraEndOffset;
1130
1137
  clampedOffset = Math.min(offset, maxOffset);
1131
1138
  }
1132
1139
  clampedOffset = Math.max(0, clampedOffset);
@@ -1219,37 +1226,54 @@ function checkAtBottom(ctx) {
1219
1226
 
1220
1227
  // src/utils/checkAtTop.ts
1221
1228
  function checkAtTop(ctx) {
1222
- var _a3;
1223
1229
  const state = ctx == null ? void 0 : ctx.state;
1224
- if (!state || state.initialScroll) {
1230
+ if (!state || state.initialScroll || state.scrollingTo) {
1225
1231
  return;
1226
1232
  }
1227
1233
  const {
1228
- scrollLength,
1234
+ dataChangeEpoch,
1235
+ isStartReached,
1236
+ props: { data, onStartReachedThreshold },
1229
1237
  scroll,
1230
- props: { onStartReachedThreshold }
1238
+ scrollLength,
1239
+ startReachedSnapshot,
1240
+ startReachedSnapshotDataChangeEpoch,
1241
+ totalSize
1231
1242
  } = state;
1232
- const distanceFromTop = scroll;
1233
- state.isAtStart = distanceFromTop <= 0;
1243
+ const dataLength = data.length;
1244
+ const threshold = onStartReachedThreshold * scrollLength;
1245
+ const dataChanged = startReachedSnapshotDataChangeEpoch !== dataChangeEpoch;
1246
+ const withinThreshold = threshold > 0 && Math.abs(scroll) <= threshold;
1247
+ const allowReentryOnDataChange = !!isStartReached && withinThreshold && !!dataChanged && !isInMVCPActiveMode(state);
1248
+ if (isStartReached && threshold > 0 && scroll > threshold && startReachedSnapshot && (dataChanged || startReachedSnapshot.contentSize !== totalSize || startReachedSnapshot.dataLength !== dataLength)) {
1249
+ state.isStartReached = false;
1250
+ state.startReachedSnapshot = void 0;
1251
+ state.startReachedSnapshotDataChangeEpoch = void 0;
1252
+ }
1253
+ state.isAtStart = scroll <= 0;
1254
+ if (isStartReached && withinThreshold && dataChanged && !allowReentryOnDataChange) {
1255
+ return;
1256
+ }
1234
1257
  state.isStartReached = checkThreshold(
1235
- distanceFromTop,
1258
+ scroll,
1236
1259
  false,
1237
- onStartReachedThreshold * scrollLength,
1260
+ threshold,
1238
1261
  state.isStartReached,
1239
- state.startReachedSnapshot,
1262
+ allowReentryOnDataChange ? void 0 : startReachedSnapshot,
1240
1263
  {
1241
- contentSize: state.totalSize,
1242
- dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
1264
+ contentSize: totalSize,
1265
+ dataLength,
1243
1266
  scrollPosition: scroll
1244
1267
  },
1245
1268
  (distance) => {
1246
- var _a4, _b;
1247
- return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
1269
+ var _a3, _b;
1270
+ return (_b = (_a3 = state.props).onStartReached) == null ? void 0 : _b.call(_a3, { distanceFromStart: distance });
1248
1271
  },
1249
1272
  (snapshot) => {
1250
1273
  state.startReachedSnapshot = snapshot;
1274
+ state.startReachedSnapshotDataChangeEpoch = snapshot ? dataChangeEpoch : void 0;
1251
1275
  },
1252
- false
1276
+ allowReentryOnDataChange
1253
1277
  );
1254
1278
  }
1255
1279
 
@@ -1265,14 +1289,22 @@ function setInitialRenderState(ctx, {
1265
1289
  didInitialScroll
1266
1290
  }) {
1267
1291
  const { state } = ctx;
1292
+ const {
1293
+ loadStartTime,
1294
+ props: { onLoad }
1295
+ } = state;
1268
1296
  if (didLayout) {
1269
1297
  state.didContainersLayout = true;
1270
1298
  }
1271
1299
  if (didInitialScroll) {
1272
1300
  state.didFinishInitialScroll = true;
1273
1301
  }
1274
- if (state.didContainersLayout && state.didFinishInitialScroll) {
1302
+ const isReadyToRender = Boolean(state.didContainersLayout && state.didFinishInitialScroll);
1303
+ if (isReadyToRender && !peek$(ctx, "readyToRender")) {
1275
1304
  set$(ctx, "readyToRender", true);
1305
+ if (onLoad) {
1306
+ onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1307
+ }
1276
1308
  }
1277
1309
  }
1278
1310
 
@@ -1281,6 +1313,8 @@ function finishScrollTo(ctx) {
1281
1313
  var _a3, _b;
1282
1314
  const state = ctx.state;
1283
1315
  if (state == null ? void 0 : state.scrollingTo) {
1316
+ const resolvePendingScroll = state.pendingScrollResolve;
1317
+ state.pendingScrollResolve = void 0;
1284
1318
  const scrollingTo = state.scrollingTo;
1285
1319
  state.scrollHistory.length = 0;
1286
1320
  state.initialScroll = void 0;
@@ -1297,6 +1331,7 @@ function finishScrollTo(ctx) {
1297
1331
  }
1298
1332
  setInitialRenderState(ctx, { didInitialScroll: true });
1299
1333
  checkThresholds(ctx);
1334
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1300
1335
  }
1301
1336
  }
1302
1337
 
@@ -1311,8 +1346,12 @@ function checkFinishedScrollFrame(ctx) {
1311
1346
  state.animFrameCheckFinishedScroll = void 0;
1312
1347
  const scroll = state.scrollPending;
1313
1348
  const adjust = state.scrollAdjustHandler.getAdjust();
1314
- const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1315
- const maxOffset = clampScrollOffset(ctx, scroll);
1349
+ const clampedTargetOffset = clampScrollOffset(
1350
+ ctx,
1351
+ scrollingTo.offset - (scrollingTo.viewOffset || 0),
1352
+ scrollingTo
1353
+ );
1354
+ const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
1316
1355
  const diff1 = Math.abs(scroll - clampedTargetOffset);
1317
1356
  const diff2 = Math.abs(diff1 - adjust);
1318
1357
  const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
@@ -1349,16 +1388,20 @@ function checkFinishedScrollFallback(ctx) {
1349
1388
 
1350
1389
  // src/core/doScrollTo.native.ts
1351
1390
  function doScrollTo(ctx, params) {
1352
- var _a3;
1353
1391
  const state = ctx.state;
1354
1392
  const { animated, horizontal, offset } = params;
1393
+ const isAnimated = !!animated;
1355
1394
  const { refScroller } = state;
1356
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1357
- animated: !!animated,
1395
+ const scroller = refScroller.current;
1396
+ if (!scroller) {
1397
+ return;
1398
+ }
1399
+ scroller.scrollTo({
1400
+ animated: isAnimated,
1358
1401
  x: horizontal ? offset : 0,
1359
1402
  y: horizontal ? 0 : offset
1360
1403
  });
1361
- if (!animated) {
1404
+ if (!isAnimated) {
1362
1405
  state.scroll = offset;
1363
1406
  checkFinishedScrollFallback(ctx);
1364
1407
  }
@@ -1379,7 +1422,7 @@ function scrollTo(ctx, params) {
1379
1422
  clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
1380
1423
  }
1381
1424
  let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
1382
- offset = clampScrollOffset(ctx, offset);
1425
+ offset = clampScrollOffset(ctx, offset, scrollTarget);
1383
1426
  state.scrollHistory.length = 0;
1384
1427
  if (!noScrollingTo) {
1385
1428
  state.scrollingTo = scrollTarget;
@@ -1400,7 +1443,7 @@ var flushSync = (fn) => {
1400
1443
  // src/core/updateScroll.ts
1401
1444
  function updateScroll(ctx, newScroll, forceUpdate) {
1402
1445
  const state = ctx.state;
1403
- const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
1446
+ const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
1404
1447
  const prevScroll = state.scroll;
1405
1448
  state.hasScrolled = true;
1406
1449
  state.lastBatchingAction = Date.now();
@@ -1408,22 +1451,17 @@ function updateScroll(ctx, newScroll, forceUpdate) {
1408
1451
  const adjust = scrollAdjustHandler.getAdjust();
1409
1452
  const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1410
1453
  if (adjustChanged) {
1411
- state.scrollHistory.length = 0;
1454
+ scrollHistory.length = 0;
1412
1455
  }
1413
1456
  state.lastScrollAdjustForHistory = adjust;
1414
- if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
1457
+ if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
1415
1458
  if (!adjustChanged) {
1416
- state.scrollHistory.push({ scroll: newScroll, time: currentTime });
1459
+ scrollHistory.push({ scroll: newScroll, time: currentTime });
1417
1460
  }
1418
1461
  }
1419
- if (state.scrollHistory.length > 5) {
1420
- state.scrollHistory.shift();
1462
+ if (scrollHistory.length > 5) {
1463
+ scrollHistory.shift();
1421
1464
  }
1422
- state.scrollPrev = prevScroll;
1423
- state.scrollPrevTime = state.scrollTime;
1424
- state.scroll = newScroll;
1425
- state.scrollTime = currentTime;
1426
- const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
1427
1465
  if (ignoreScrollFromMVCP && !scrollingTo) {
1428
1466
  const { lt, gt } = ignoreScrollFromMVCP;
1429
1467
  if (lt && newScroll < lt || gt && newScroll > gt) {
@@ -1431,6 +1469,10 @@ function updateScroll(ctx, newScroll, forceUpdate) {
1431
1469
  return;
1432
1470
  }
1433
1471
  }
1472
+ state.scrollPrev = prevScroll;
1473
+ state.scrollPrevTime = state.scrollTime;
1474
+ state.scroll = newScroll;
1475
+ state.scrollTime = currentTime;
1434
1476
  const scrollDelta = Math.abs(newScroll - prevScroll);
1435
1477
  const scrollLength = state.scrollLength;
1436
1478
  const lastCalculated = state.scrollLastCalculate;
@@ -1516,14 +1558,14 @@ var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1516
1558
  function ensureInitialAnchor(ctx) {
1517
1559
  var _a3, _b, _c, _d, _e;
1518
1560
  const state = ctx.state;
1519
- const { initialAnchor, didContainersLayout, positions, scroll, scrollLength } = state;
1561
+ const { initialAnchor, didContainersLayout, scroll, scrollLength } = state;
1520
1562
  const anchor = initialAnchor;
1521
1563
  const item = state.props.data[anchor.index];
1522
1564
  if (!didContainersLayout) {
1523
1565
  return;
1524
1566
  }
1525
1567
  const id = getId(state, anchor.index);
1526
- if (positions.get(id) === void 0) {
1568
+ if (state.positions[anchor.index] === void 0) {
1527
1569
  return;
1528
1570
  }
1529
1571
  const size = getItemSize(ctx, id, anchor.index, item, true, true);
@@ -1532,7 +1574,7 @@ function ensureInitialAnchor(ctx) {
1532
1574
  }
1533
1575
  const availableSpace = Math.max(0, scrollLength - size);
1534
1576
  const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1535
- const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset);
1577
+ const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset, anchor);
1536
1578
  const delta = clampedDesiredOffset - scroll;
1537
1579
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1538
1580
  const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
@@ -1619,6 +1661,7 @@ function prepareMVCP(ctx, dataChanged) {
1619
1661
  const idsInViewWithPositions = [];
1620
1662
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1621
1663
  const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1664
+ const isEndAnchoredScrollTarget = scrollTarget !== void 0 && state.props.data.length > 0 && scrollTarget >= state.props.data.length - 1 && (scrollingToViewPosition != null ? scrollingToViewPosition : 0) > 0;
1622
1665
  const shouldMVCP = dataChanged ? mvcpData : mvcpScroll;
1623
1666
  const indexByKey = state.indexByKey;
1624
1667
  if (shouldMVCP) {
@@ -1638,12 +1681,18 @@ function prepareMVCP(ctx, dataChanged) {
1638
1681
  const id = idsInView[i];
1639
1682
  const index = indexByKey.get(id);
1640
1683
  if (index !== void 0) {
1641
- idsInViewWithPositions.push({ id, position: positions.get(id) });
1684
+ const position = positions[index];
1685
+ if (position !== void 0) {
1686
+ idsInViewWithPositions.push({ id, position });
1687
+ }
1642
1688
  }
1643
1689
  }
1644
1690
  }
1645
1691
  if (targetId !== void 0 && prevPosition === void 0) {
1646
- prevPosition = positions.get(targetId);
1692
+ const targetIndex = indexByKey.get(targetId);
1693
+ if (targetIndex !== void 0) {
1694
+ prevPosition = positions[targetIndex];
1695
+ }
1647
1696
  }
1648
1697
  return () => {
1649
1698
  let positionDiff = 0;
@@ -1662,7 +1711,13 @@ function prepareMVCP(ctx, dataChanged) {
1662
1711
  }
1663
1712
  }
1664
1713
  }
1665
- const shouldUseFallbackVisibleAnchor = dataChanged && mvcpData && scrollTarget === void 0 && (targetId === void 0 || positions.get(targetId) === void 0 || skipTargetAnchor);
1714
+ const shouldUseFallbackVisibleAnchor = dataChanged && mvcpData && scrollTarget === void 0 && (() => {
1715
+ if (targetId === void 0 || skipTargetAnchor) {
1716
+ return true;
1717
+ }
1718
+ const targetIndex = indexByKey.get(targetId);
1719
+ return targetIndex === void 0 || positions[targetIndex] === void 0;
1720
+ })();
1666
1721
  if (shouldUseFallbackVisibleAnchor) {
1667
1722
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1668
1723
  const { id, position } = idsInViewWithPositions[i];
@@ -1673,7 +1728,7 @@ function prepareMVCP(ctx, dataChanged) {
1673
1728
  continue;
1674
1729
  }
1675
1730
  }
1676
- const newPosition = positions.get(id);
1731
+ const newPosition = index !== void 0 ? positions[index] : void 0;
1677
1732
  if (newPosition !== void 0) {
1678
1733
  positionDiff = newPosition - position;
1679
1734
  anchorIdForLock = id;
@@ -1683,11 +1738,12 @@ function prepareMVCP(ctx, dataChanged) {
1683
1738
  }
1684
1739
  }
1685
1740
  if (!skipTargetAnchor && targetId !== void 0 && prevPosition !== void 0) {
1686
- const newPosition = positions.get(targetId);
1741
+ const targetIndex = indexByKey.get(targetId);
1742
+ const newPosition = targetIndex !== void 0 ? positions[targetIndex] : void 0;
1687
1743
  if (newPosition !== void 0) {
1688
1744
  const totalSize = getContentSize(ctx);
1689
1745
  let diff = newPosition - prevPosition;
1690
- if (diff !== 0 && state.scroll + state.scrollLength > totalSize) {
1746
+ if (diff !== 0 && isEndAnchoredScrollTarget && state.scroll + state.scrollLength > totalSize) {
1691
1747
  if (diff > 0) {
1692
1748
  diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
1693
1749
  } else {
@@ -1730,17 +1786,15 @@ function prepareColumnStartState(ctx, startIndex, useAverageSize) {
1730
1786
  const state = ctx.state;
1731
1787
  const numColumns = peek$(ctx, "numColumns");
1732
1788
  let rowStartIndex = startIndex;
1733
- const columnAtStart = state.columns.get(state.idCache[startIndex]);
1789
+ const columnAtStart = state.columns[startIndex];
1734
1790
  if (columnAtStart !== 1) {
1735
1791
  rowStartIndex = findRowStartIndex(state, numColumns, startIndex);
1736
1792
  }
1737
1793
  let currentRowTop = 0;
1738
- const curId = state.idCache[rowStartIndex];
1739
- const column = state.columns.get(curId);
1794
+ const column = state.columns[rowStartIndex];
1740
1795
  if (rowStartIndex > 0) {
1741
1796
  const prevIndex = rowStartIndex - 1;
1742
- const prevId = state.idCache[prevIndex];
1743
- const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1797
+ const prevPosition = (_a3 = state.positions[prevIndex]) != null ? _a3 : 0;
1744
1798
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1745
1799
  const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
1746
1800
  currentRowTop = prevPosition + prevRowHeight;
@@ -1757,7 +1811,7 @@ function findRowStartIndex(state, numColumns, index) {
1757
1811
  }
1758
1812
  let rowStart = Math.max(0, index);
1759
1813
  while (rowStart > 0) {
1760
- const columnForIndex = state.columns.get(state.idCache[rowStart]);
1814
+ const columnForIndex = state.columns[rowStart];
1761
1815
  if (columnForIndex === 1) {
1762
1816
  break;
1763
1817
  }
@@ -1790,7 +1844,7 @@ function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
1790
1844
 
1791
1845
  // src/core/updateTotalSize.ts
1792
1846
  function updateTotalSize(ctx) {
1793
- var _a3, _b, _c;
1847
+ var _a3, _b;
1794
1848
  const state = ctx.state;
1795
1849
  const {
1796
1850
  positions,
@@ -1800,36 +1854,34 @@ function updateTotalSize(ctx) {
1800
1854
  if (data.length === 0) {
1801
1855
  addTotalSize(ctx, null, 0);
1802
1856
  } else {
1803
- const lastId = getId(state, data.length - 1);
1804
- if (lastId !== void 0) {
1805
- const lastPosition = positions.get(lastId);
1806
- if (lastPosition !== void 0) {
1807
- if (numColumns > 1) {
1808
- let rowStart = data.length - 1;
1809
- while (rowStart > 0) {
1810
- const rowId = (_b = state.idCache[rowStart]) != null ? _b : getId(state, rowStart);
1811
- const column = state.columns.get(rowId);
1812
- if (column === 1 || column === void 0) {
1813
- break;
1814
- }
1815
- rowStart -= 1;
1816
- }
1817
- let maxSize = 0;
1818
- for (let i = rowStart; i < data.length; i++) {
1819
- const rowId = (_c = state.idCache[i]) != null ? _c : getId(state, i);
1820
- const size = getItemSize(ctx, rowId, i, data[i]);
1821
- if (size > maxSize) {
1822
- maxSize = size;
1823
- }
1857
+ const lastIndex = data.length - 1;
1858
+ const lastId = getId(state, lastIndex);
1859
+ const lastPosition = positions[lastIndex];
1860
+ if (lastId !== void 0 && lastPosition !== void 0) {
1861
+ if (numColumns > 1) {
1862
+ let rowStart = lastIndex;
1863
+ while (rowStart > 0) {
1864
+ const column = state.columns[rowStart];
1865
+ if (column === 1 || column === void 0) {
1866
+ break;
1824
1867
  }
1825
- addTotalSize(ctx, null, lastPosition + maxSize);
1826
- } else {
1827
- const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
1828
- if (lastSize !== void 0) {
1829
- const totalSize = lastPosition + lastSize;
1830
- addTotalSize(ctx, null, totalSize);
1868
+ rowStart -= 1;
1869
+ }
1870
+ let maxSize = 0;
1871
+ for (let i = rowStart; i <= lastIndex; i++) {
1872
+ const rowId = (_b = state.idCache[i]) != null ? _b : getId(state, i);
1873
+ const size = getItemSize(ctx, rowId, i, data[i]);
1874
+ if (size > maxSize) {
1875
+ maxSize = size;
1831
1876
  }
1832
1877
  }
1878
+ addTotalSize(ctx, null, lastPosition + maxSize);
1879
+ } else {
1880
+ const lastSize = getItemSize(ctx, lastId, lastIndex, data[lastIndex]);
1881
+ if (lastSize !== void 0) {
1882
+ const totalSize = lastPosition + lastSize;
1883
+ addTotalSize(ctx, null, totalSize);
1884
+ }
1833
1885
  }
1834
1886
  }
1835
1887
  }
@@ -1878,14 +1930,13 @@ var getScrollVelocity = (state) => {
1878
1930
  function updateSnapToOffsets(ctx) {
1879
1931
  const state = ctx.state;
1880
1932
  const {
1881
- positions,
1882
1933
  props: { snapToIndices }
1883
1934
  } = state;
1884
1935
  const snapToOffsets = Array(snapToIndices.length);
1885
1936
  for (let i = 0; i < snapToIndices.length; i++) {
1886
1937
  const idx = snapToIndices[i];
1887
- const key = getId(state, idx);
1888
- snapToOffsets[i] = positions.get(key);
1938
+ getId(state, idx);
1939
+ snapToOffsets[i] = state.positions[idx];
1889
1940
  }
1890
1941
  set$(ctx, "snapToOffsets", snapToOffsets);
1891
1942
  }
@@ -1897,8 +1948,9 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
1897
1948
  scrollBottomBuffered: -1,
1898
1949
  startIndex: 0
1899
1950
  }) {
1900
- var _a3, _b, _c, _d, _e, _f;
1951
+ var _a3, _b, _c, _d, _e;
1901
1952
  const state = ctx.state;
1953
+ const hasPositionListeners = ctx.positionListeners.size > 0;
1902
1954
  const {
1903
1955
  columns,
1904
1956
  columnSpans,
@@ -1925,7 +1977,15 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
1925
1977
  let column = 1;
1926
1978
  let maxSizeInRow = 0;
1927
1979
  if (dataChanged) {
1928
- columnSpans.clear();
1980
+ columnSpans.length = 0;
1981
+ }
1982
+ if (!hasColumns) {
1983
+ if (columns.length) {
1984
+ columns.length = 0;
1985
+ }
1986
+ if (columnSpans.length) {
1987
+ columnSpans.length = 0;
1988
+ }
1929
1989
  }
1930
1990
  if (startIndex > 0) {
1931
1991
  if (hasColumns) {
@@ -1939,12 +1999,13 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
1939
1999
  } else if (startIndex < dataLength) {
1940
2000
  const prevIndex = startIndex - 1;
1941
2001
  const prevId = getId(state, prevIndex);
1942
- const prevPosition = (_c = positions.get(prevId)) != null ? _c : 0;
2002
+ const prevPosition = (_c = positions[prevIndex]) != null ? _c : 0;
1943
2003
  const prevSize = (_d = sizesKnown.get(prevId)) != null ? _d : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1944
2004
  currentRowTop = prevPosition + prevSize;
1945
2005
  }
1946
2006
  }
1947
2007
  const needsIndexByKey = dataChanged || indexByKey.size === 0;
2008
+ const canOverrideSpan = hasColumns && !!overrideItemLayout && !!layoutConfig;
1948
2009
  let didBreakEarly = false;
1949
2010
  let breakAt;
1950
2011
  for (let i = startIndex; i < dataLength; i++) {
@@ -1958,7 +2019,7 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
1958
2019
  }
1959
2020
  const id = (_e = idCache[i]) != null ? _e : getId(state, i);
1960
2021
  let span = 1;
1961
- if (hasColumns && overrideItemLayout && layoutConfig) {
2022
+ if (canOverrideSpan) {
1962
2023
  layoutConfig.span = 1;
1963
2024
  overrideItemLayout(layoutConfig, data[i], i, numColumns, extraData);
1964
2025
  const requestedSpan = layoutConfig.span;
@@ -1971,7 +2032,8 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
1971
2032
  column = 1;
1972
2033
  maxSizeInRow = 0;
1973
2034
  }
1974
- const size = (_f = sizesKnown.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
2035
+ const knownSize = sizesKnown.get(id);
2036
+ const size = knownSize !== void 0 ? knownSize : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
1975
2037
  if (IS_DEV && needsIndexByKey) {
1976
2038
  if (indexByKeyForChecking.has(id)) {
1977
2039
  console.error(
@@ -1980,16 +2042,20 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
1980
2042
  }
1981
2043
  indexByKeyForChecking.set(id, i);
1982
2044
  }
1983
- if (currentRowTop !== positions.get(id)) {
1984
- positions.set(id, currentRowTop);
1985
- notifyPosition$(ctx, id, currentRowTop);
2045
+ if (currentRowTop !== positions[i]) {
2046
+ positions[i] = currentRowTop;
2047
+ if (hasPositionListeners) {
2048
+ notifyPosition$(ctx, id, currentRowTop);
2049
+ }
1986
2050
  }
1987
2051
  if (needsIndexByKey) {
1988
2052
  indexByKey.set(id, i);
1989
2053
  }
1990
- columns.set(id, column);
1991
- columnSpans.set(id, span);
1992
- if (hasColumns) {
2054
+ if (!hasColumns) {
2055
+ currentRowTop += size;
2056
+ } else {
2057
+ columns[i] = column;
2058
+ columnSpans[i] = span;
1993
2059
  if (size > maxSizeInRow) {
1994
2060
  maxSizeInRow = size;
1995
2061
  }
@@ -1999,8 +2065,6 @@ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffere
1999
2065
  column = 1;
2000
2066
  maxSizeInRow = 0;
2001
2067
  }
2002
- } else {
2003
- currentRowTop += size;
2004
2068
  }
2005
2069
  }
2006
2070
  if (!didBreakEarly) {
@@ -2152,14 +2216,38 @@ function shallowEqual(prev, next) {
2152
2216
  return true;
2153
2217
  }
2154
2218
  function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
2155
- const { sizes, positions, scroll: scrollState } = state;
2219
+ const { sizes, scroll: scrollState } = state;
2156
2220
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2157
2221
  const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
2158
2222
  const viewAreaMode = viewAreaCoveragePercentThreshold != null;
2159
2223
  const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
2160
2224
  const scroll = scrollState - topPad;
2161
- const top = positions.get(key) - scroll;
2225
+ const position = state.positions[index];
2162
2226
  const size = sizes.get(key) || 0;
2227
+ if (position === void 0) {
2228
+ const value2 = {
2229
+ containerId,
2230
+ index,
2231
+ isViewable: false,
2232
+ item,
2233
+ key,
2234
+ percentOfScroller: 0,
2235
+ percentVisible: 0,
2236
+ scrollSize,
2237
+ size,
2238
+ sizeVisible: -1
2239
+ };
2240
+ const prev2 = ctx.mapViewabilityAmountValues.get(containerId);
2241
+ if (!shallowEqual(prev2, value2)) {
2242
+ ctx.mapViewabilityAmountValues.set(containerId, value2);
2243
+ const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
2244
+ if (cb) {
2245
+ cb(value2);
2246
+ }
2247
+ }
2248
+ return value2;
2249
+ }
2250
+ const top = position - scroll;
2163
2251
  const bottom = top + size;
2164
2252
  const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
2165
2253
  const sizeVisible = isEntirelyVisible ? size : Math.min(bottom, scrollSize) - Math.max(top, 0);
@@ -2372,37 +2460,24 @@ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPositi
2372
2460
  // src/utils/setDidLayout.ts
2373
2461
  function setDidLayout(ctx) {
2374
2462
  const state = ctx.state;
2375
- const {
2376
- loadStartTime,
2377
- initialScroll,
2378
- props: { onLoad }
2379
- } = state;
2463
+ const { initialScroll } = state;
2380
2464
  state.queuedInitialLayout = true;
2381
2465
  checkAtBottom(ctx);
2382
- const setIt = () => {
2383
- setInitialRenderState(ctx, { didLayout: true });
2384
- if (onLoad) {
2385
- onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
2386
- }
2387
- };
2388
2466
  if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
2389
2467
  const target = initialScroll;
2390
2468
  const runScroll = () => scrollToIndex(ctx, { ...target, animated: false });
2391
2469
  runScroll();
2392
2470
  requestAnimationFrame(runScroll);
2393
2471
  }
2394
- setIt();
2472
+ setInitialRenderState(ctx, { didLayout: true });
2395
2473
  }
2396
2474
 
2397
2475
  // src/core/calculateItemsInView.ts
2398
2476
  function findCurrentStickyIndex(stickyArray, scroll, state) {
2399
- var _a3;
2400
- const idCache = state.idCache;
2401
2477
  const positions = state.positions;
2402
2478
  for (let i = stickyArray.length - 1; i >= 0; i--) {
2403
2479
  const stickyIndex = stickyArray[i];
2404
- const stickyId = (_a3 = idCache[stickyIndex]) != null ? _a3 : getId(state, stickyIndex);
2405
- const stickyPos = stickyId ? positions.get(stickyId) : void 0;
2480
+ const stickyPos = positions[stickyIndex];
2406
2481
  if (stickyPos !== void 0 && scroll >= stickyPos) {
2407
2482
  return i;
2408
2483
  }
@@ -2432,7 +2507,7 @@ function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentSt
2432
2507
  }
2433
2508
  }
2434
2509
  function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentStickyIdx, pendingRemoval, alwaysRenderIndicesSet) {
2435
- var _a3, _b, _c;
2510
+ var _a3, _b;
2436
2511
  const state = ctx.state;
2437
2512
  for (const containerIndex of state.stickyContainerPool) {
2438
2513
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
@@ -2450,14 +2525,13 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
2450
2525
  const nextIndex = stickyArray[arrayIdx + 1];
2451
2526
  let shouldRecycle = false;
2452
2527
  if (nextIndex) {
2453
- const nextId = (_a3 = state.idCache[nextIndex]) != null ? _a3 : getId(state, nextIndex);
2454
- const nextPos = nextId ? state.positions.get(nextId) : void 0;
2528
+ const nextPos = state.positions[nextIndex];
2455
2529
  shouldRecycle = nextPos !== void 0 && scroll > nextPos + drawDistance * 2;
2456
2530
  } else {
2457
- const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2531
+ const currentId = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
2458
2532
  if (currentId) {
2459
- const currentPos = state.positions.get(currentId);
2460
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2533
+ const currentPos = state.positions[itemIndex];
2534
+ const currentSize = (_b = state.sizes.get(currentId)) != null ? _b : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2461
2535
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + drawDistance * 3;
2462
2536
  }
2463
2537
  }
@@ -2469,7 +2543,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
2469
2543
  function calculateItemsInView(ctx, params = {}) {
2470
2544
  const state = ctx.state;
2471
2545
  unstable_batchedUpdates(() => {
2472
- var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
2546
+ var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2473
2547
  const {
2474
2548
  columns,
2475
2549
  columnSpans,
@@ -2564,7 +2638,9 @@ function calculateItemsInView(ctx, params = {}) {
2564
2638
  if (dataChanged) {
2565
2639
  indexByKey.clear();
2566
2640
  idCache.length = 0;
2567
- positions.clear();
2641
+ positions.length = 0;
2642
+ columns.length = 0;
2643
+ columnSpans.length = 0;
2568
2644
  }
2569
2645
  const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2570
2646
  updateItemPositions(ctx, dataChanged, {
@@ -2585,7 +2661,7 @@ function calculateItemsInView(ctx, params = {}) {
2585
2661
  let loopStart = !dataChanged && startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
2586
2662
  for (let i = loopStart; i >= 0; i--) {
2587
2663
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2588
- const top = positions.get(id);
2664
+ const top = positions[i];
2589
2665
  const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
2590
2666
  const bottom = top + size;
2591
2667
  if (bottom > scroll - scrollBufferTop) {
@@ -2596,8 +2672,7 @@ function calculateItemsInView(ctx, params = {}) {
2596
2672
  }
2597
2673
  if (numColumns > 1) {
2598
2674
  while (loopStart > 0) {
2599
- const loopId = (_e = idCache[loopStart]) != null ? _e : getId(state, loopStart);
2600
- const loopColumn = columns.get(loopId);
2675
+ const loopColumn = columns[loopStart];
2601
2676
  if (loopColumn === 1 || loopColumn === void 0) {
2602
2677
  break;
2603
2678
  }
@@ -2618,9 +2693,9 @@ function calculateItemsInView(ctx, params = {}) {
2618
2693
  let firstFullyOnScreenIndex;
2619
2694
  const dataLength = data.length;
2620
2695
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2621
- const id = (_f = idCache[i]) != null ? _f : getId(state, i);
2622
- const size = (_g = sizes.get(id)) != null ? _g : getItemSize(ctx, id, i, data[i]);
2623
- const top = positions.get(id);
2696
+ const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2697
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
2698
+ const top = positions[i];
2624
2699
  if (!foundEnd) {
2625
2700
  if (startNoBuffer === null && top + size > scroll) {
2626
2701
  startNoBuffer = i;
@@ -2656,7 +2731,7 @@ function calculateItemsInView(ctx, params = {}) {
2656
2731
  }
2657
2732
  const idsInView = [];
2658
2733
  for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
2659
- const id = (_h = idCache[i]) != null ? _h : getId(state, i);
2734
+ const id = (_g = idCache[i]) != null ? _g : getId(state, i);
2660
2735
  idsInView.push(id);
2661
2736
  }
2662
2737
  Object.assign(state, {
@@ -2688,7 +2763,7 @@ function calculateItemsInView(ctx, params = {}) {
2688
2763
  const needNewContainers = [];
2689
2764
  const needNewContainersSet = /* @__PURE__ */ new Set();
2690
2765
  for (let i = startBuffered; i <= endBuffered; i++) {
2691
- const id = (_i = idCache[i]) != null ? _i : getId(state, i);
2766
+ const id = (_h = idCache[i]) != null ? _h : getId(state, i);
2692
2767
  if (!containerItemKeys.has(id)) {
2693
2768
  needNewContainersSet.add(i);
2694
2769
  needNewContainers.push(i);
@@ -2697,7 +2772,7 @@ function calculateItemsInView(ctx, params = {}) {
2697
2772
  if (alwaysRenderArr.length > 0) {
2698
2773
  for (const index of alwaysRenderArr) {
2699
2774
  if (index < 0 || index >= dataLength) continue;
2700
- const id = (_j = idCache[index]) != null ? _j : getId(state, index);
2775
+ const id = (_i = idCache[index]) != null ? _i : getId(state, index);
2701
2776
  if (id && !containerItemKeys.has(id) && !needNewContainersSet.has(index)) {
2702
2777
  needNewContainersSet.add(index);
2703
2778
  needNewContainers.push(index);
@@ -2735,7 +2810,7 @@ function calculateItemsInView(ctx, params = {}) {
2735
2810
  for (let idx = 0; idx < needNewContainers.length; idx++) {
2736
2811
  const i = needNewContainers[idx];
2737
2812
  const containerIndex = availableContainers[idx];
2738
- const id = (_k = idCache[i]) != null ? _k : getId(state, i);
2813
+ const id = (_j = idCache[i]) != null ? _j : getId(state, i);
2739
2814
  const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
2740
2815
  if (oldKey && oldKey !== id) {
2741
2816
  containerItemKeys.delete(oldKey);
@@ -2776,7 +2851,7 @@ function calculateItemsInView(ctx, params = {}) {
2776
2851
  if (alwaysRenderArr.length > 0) {
2777
2852
  for (const index of alwaysRenderArr) {
2778
2853
  if (index < 0 || index >= dataLength) continue;
2779
- const id = (_l = idCache[index]) != null ? _l : getId(state, index);
2854
+ const id = (_k = idCache[index]) != null ? _k : getId(state, index);
2780
2855
  const containerIndex = containerItemKeys.get(id);
2781
2856
  if (containerIndex !== void 0) {
2782
2857
  state.stickyContainerPool.add(containerIndex);
@@ -2816,14 +2891,13 @@ function calculateItemsInView(ctx, params = {}) {
2816
2891
  const itemIndex = indexByKey.get(itemKey);
2817
2892
  const item = data[itemIndex];
2818
2893
  if (item !== void 0) {
2819
- const id = (_m = idCache[itemIndex]) != null ? _m : getId(state, itemIndex);
2820
- const positionValue = positions.get(id);
2894
+ const positionValue = positions[itemIndex];
2821
2895
  if (positionValue === void 0) {
2822
2896
  set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
2823
2897
  } else {
2824
2898
  const position = (positionValue || 0) - scrollAdjustPending;
2825
- const column = columns.get(id) || 1;
2826
- const span = columnSpans.get(id) || 1;
2899
+ const column = columns[itemIndex] || 1;
2900
+ const span = columnSpans[itemIndex] || 1;
2827
2901
  const prevPos = peek$(ctx, `containerPosition${i}`);
2828
2902
  const prevColumn = peek$(ctx, `containerColumn${i}`);
2829
2903
  const prevSpan = peek$(ctx, `containerSpan${i}`);
@@ -3116,7 +3190,7 @@ function onScroll(ctx, event) {
3116
3190
  }
3117
3191
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
3118
3192
  if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
3119
- const maxOffset = clampScrollOffset(ctx, newScroll);
3193
+ const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
3120
3194
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
3121
3195
  newScroll = maxOffset;
3122
3196
  scrollTo(ctx, {
@@ -3169,7 +3243,7 @@ var ScrollAdjustHandler = class {
3169
3243
  if ((scrollTarget == null ? void 0 : scrollTarget.index) !== void 0) {
3170
3244
  const currentOffset = calculateOffsetForIndex(this.ctx, scrollTarget.index);
3171
3245
  targetScroll = calculateOffsetWithOffsetPosition(this.ctx, currentOffset, scrollTarget);
3172
- targetScroll = clampScrollOffset(this.ctx, targetScroll);
3246
+ targetScroll = clampScrollOffset(this.ctx, targetScroll, scrollTarget);
3173
3247
  } else {
3174
3248
  targetScroll = clampScrollOffset(this.ctx, state.scroll + pending);
3175
3249
  }
@@ -3370,8 +3444,9 @@ function getWindowSize() {
3370
3444
  }
3371
3445
  var StyleSheet = StyleSheet$1;
3372
3446
  function useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, onScroll2) {
3447
+ const shouldUseRnAnimatedEngine = !ctx.state.props.stickyPositionComponentInternal;
3373
3448
  return useMemo(() => {
3374
- if (stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.length) {
3449
+ if ((stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.length) && shouldUseRnAnimatedEngine) {
3375
3450
  const { animatedScrollY } = ctx;
3376
3451
  return Animated.event(
3377
3452
  [
@@ -3388,7 +3463,7 @@ function useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, onScroll2)
3388
3463
  );
3389
3464
  }
3390
3465
  return onScroll2;
3391
- }, [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(","), horizontal]);
3466
+ }, [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(","), horizontal, shouldUseRnAnimatedEngine]);
3392
3467
  }
3393
3468
 
3394
3469
  // src/utils/createColumnWrapperStyle.ts
@@ -3409,6 +3484,18 @@ function createColumnWrapperStyle(contentContainerStyle) {
3409
3484
  // src/utils/createImperativeHandle.ts
3410
3485
  function createImperativeHandle(ctx) {
3411
3486
  const state = ctx.state;
3487
+ const runScrollWithPromise = (run) => new Promise((resolve) => {
3488
+ var _a3;
3489
+ (_a3 = state.pendingScrollResolve) == null ? void 0 : _a3.call(state);
3490
+ state.pendingScrollResolve = resolve;
3491
+ const didStartScroll = run();
3492
+ if (!didStartScroll || !state.scrollingTo) {
3493
+ if (state.pendingScrollResolve === resolve) {
3494
+ state.pendingScrollResolve = void 0;
3495
+ }
3496
+ resolve();
3497
+ }
3498
+ });
3412
3499
  const scrollIndexIntoView = (options) => {
3413
3500
  if (state) {
3414
3501
  const { index, ...rest } = options;
@@ -3420,11 +3507,36 @@ function createImperativeHandle(ctx) {
3420
3507
  index,
3421
3508
  viewPosition
3422
3509
  });
3510
+ return true;
3423
3511
  }
3424
3512
  }
3513
+ return false;
3425
3514
  };
3426
3515
  const refScroller = state.refScroller;
3516
+ const clearCaches = (options) => {
3517
+ var _a3, _b;
3518
+ const mode = (_a3 = options == null ? void 0 : options.mode) != null ? _a3 : "sizes";
3519
+ state.sizes.clear();
3520
+ state.sizesKnown.clear();
3521
+ for (const key in state.averageSizes) {
3522
+ delete state.averageSizes[key];
3523
+ }
3524
+ state.minIndexSizeChanged = 0;
3525
+ state.scrollForNextCalculateItemsInView = void 0;
3526
+ state.pendingTotalSize = void 0;
3527
+ state.totalSize = 0;
3528
+ set$(ctx, "totalSize", 0);
3529
+ if (mode === "full") {
3530
+ state.indexByKey.clear();
3531
+ state.idCache.length = 0;
3532
+ state.positions.length = 0;
3533
+ state.columns.length = 0;
3534
+ state.columnSpans.length = 0;
3535
+ }
3536
+ (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
3537
+ };
3427
3538
  return {
3539
+ clearCaches,
3428
3540
  flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
3429
3541
  getNativeScrollRef: () => refScroller.current,
3430
3542
  getScrollableNode: () => refScroller.current.getScrollableNode(),
@@ -3443,8 +3555,11 @@ function createImperativeHandle(ctx) {
3443
3555
  isAtStart: state.isAtStart,
3444
3556
  listen: (signalName, cb) => listen$(ctx, signalName, cb),
3445
3557
  listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
3446
- positionAtIndex: (index) => state.positions.get(getId(state, index)),
3447
- positions: state.positions,
3558
+ positionAtIndex: (index) => state.positions[index],
3559
+ positionByKey: (key) => {
3560
+ const index = state.indexByKey.get(key);
3561
+ return index === void 0 ? void 0 : state.positions[index];
3562
+ },
3448
3563
  scroll: state.scroll,
3449
3564
  scrollLength: state.scrollLength,
3450
3565
  scrollVelocity: getScrollVelocity(state),
@@ -3457,15 +3572,17 @@ function createImperativeHandle(ctx) {
3457
3572
  state.contentInsetOverride = inset != null ? inset : void 0;
3458
3573
  updateScroll(ctx, state.scroll, true);
3459
3574
  },
3460
- scrollIndexIntoView,
3461
- scrollItemIntoView: ({ item, ...props }) => {
3575
+ scrollIndexIntoView: (options) => runScrollWithPromise(() => scrollIndexIntoView(options)),
3576
+ scrollItemIntoView: ({ item, ...props }) => runScrollWithPromise(() => {
3462
3577
  const data = state.props.data;
3463
3578
  const index = data.indexOf(item);
3464
3579
  if (index !== -1) {
3465
3580
  scrollIndexIntoView({ index, ...props });
3581
+ return true;
3466
3582
  }
3467
- },
3468
- scrollToEnd: (options) => {
3583
+ return false;
3584
+ }),
3585
+ scrollToEnd: (options) => runScrollWithPromise(() => {
3469
3586
  const data = state.props.data;
3470
3587
  const stylePaddingBottom = state.props.stylePaddingBottom;
3471
3588
  const index = data.length - 1;
@@ -3478,17 +3595,27 @@ function createImperativeHandle(ctx) {
3478
3595
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
3479
3596
  viewPosition: 1
3480
3597
  });
3598
+ return true;
3481
3599
  }
3482
- },
3483
- scrollToIndex: (params) => scrollToIndex(ctx, params),
3484
- scrollToItem: ({ item, ...props }) => {
3600
+ return false;
3601
+ }),
3602
+ scrollToIndex: (params) => runScrollWithPromise(() => {
3603
+ scrollToIndex(ctx, params);
3604
+ return true;
3605
+ }),
3606
+ scrollToItem: ({ item, ...props }) => runScrollWithPromise(() => {
3485
3607
  const data = state.props.data;
3486
3608
  const index = data.indexOf(item);
3487
3609
  if (index !== -1) {
3488
3610
  scrollToIndex(ctx, { index, ...props });
3611
+ return true;
3489
3612
  }
3490
- },
3491
- scrollToOffset: (params) => scrollTo(ctx, params),
3613
+ return false;
3614
+ }),
3615
+ scrollToOffset: (params) => runScrollWithPromise(() => {
3616
+ scrollTo(ctx, params);
3617
+ return true;
3618
+ }),
3492
3619
  setScrollProcessingEnabled: (enabled) => {
3493
3620
  state.scrollProcessingEnabled = enabled;
3494
3621
  },
@@ -3585,8 +3712,8 @@ function normalizeMaintainVisibleContentPosition(value) {
3585
3712
  if (value && typeof value === "object") {
3586
3713
  return {
3587
3714
  data: (_a3 = value.data) != null ? _a3 : false,
3588
- size: (_b = value.size) != null ? _b : true,
3589
- shouldRestorePosition: value.shouldRestorePosition
3715
+ shouldRestorePosition: value.shouldRestorePosition,
3716
+ size: (_b = value.size) != null ? _b : true
3590
3717
  };
3591
3718
  }
3592
3719
  if (value === false) {
@@ -3658,7 +3785,7 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
3658
3785
  }
3659
3786
 
3660
3787
  // src/components/LegendList.tsx
3661
- var LegendList = typedMemo(
3788
+ var LegendList = typedMemo2(
3662
3789
  // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
3663
3790
  typedForwardRef(function LegendList2(props, forwardedRef) {
3664
3791
  const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
@@ -3725,6 +3852,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3725
3852
  refreshControl,
3726
3853
  refreshing,
3727
3854
  refScrollView,
3855
+ renderScrollComponent,
3728
3856
  renderItem,
3729
3857
  scrollEventThrottle,
3730
3858
  snapToIndices,
@@ -3733,13 +3861,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3733
3861
  // TODOV3: Remove from v3 release
3734
3862
  style: styleProp,
3735
3863
  suggestEstimatedItemSize,
3864
+ useWindowScroll = false,
3736
3865
  viewabilityConfig,
3737
3866
  viewabilityConfigCallbackPairs,
3738
3867
  waitForInitialLayout = true,
3739
3868
  ...rest
3740
3869
  } = props;
3741
3870
  const animatedPropsInternal = props.animatedPropsInternal;
3742
- const { childrenMode } = rest;
3871
+ const positionComponentInternal = props.positionComponentInternal;
3872
+ const stickyPositionComponentInternal = props.stickyPositionComponentInternal;
3873
+ const {
3874
+ childrenMode,
3875
+ positionComponentInternal: _positionComponentInternal,
3876
+ stickyPositionComponentInternal: _stickyPositionComponentInternal,
3877
+ ...restProps
3878
+ } = rest;
3743
3879
  const contentContainerStyleBase = StyleSheet.flatten(contentContainerStyleProp);
3744
3880
  const shouldFlexGrow = alignItemsAtEnd && (horizontal ? (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minWidth) == null : (contentContainerStyleBase == null ? void 0 : contentContainerStyleBase.minHeight) == null);
3745
3881
  const contentContainerStyle = {
@@ -3791,6 +3927,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3791
3927
  "stickyIndices has been renamed to stickyHeaderIndices. Please update your props to use stickyHeaderIndices."
3792
3928
  );
3793
3929
  }
3930
+ if (IS_DEV && useWindowScroll && renderScrollComponent) {
3931
+ warnDevOnce(
3932
+ "useWindowScrollRenderScrollComponent",
3933
+ "useWindowScroll is not supported when renderScrollComponent is provided."
3934
+ );
3935
+ }
3936
+ const useWindowScrollResolved = Platform2.OS === "web" && !!useWindowScroll && !renderScrollComponent;
3794
3937
  const refState = useRef();
3795
3938
  const hasOverrideItemLayout = !!overrideItemLayout;
3796
3939
  const prevHasOverrideItemLayout = useRef(hasOverrideItemLayout);
@@ -3800,11 +3943,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3800
3943
  ctx.state = {
3801
3944
  activeStickyIndex: -1,
3802
3945
  averageSizes: {},
3803
- columnSpans: /* @__PURE__ */ new Map(),
3804
- columns: /* @__PURE__ */ new Map(),
3946
+ columnSpans: [],
3947
+ columns: [],
3805
3948
  containerItemKeys: /* @__PURE__ */ new Map(),
3806
3949
  containerItemTypes: /* @__PURE__ */ new Map(),
3807
3950
  contentInsetOverride: void 0,
3951
+ dataChangeEpoch: 0,
3808
3952
  dataChangeNeedsScrollUpdate: false,
3809
3953
  didColumnsChange: false,
3810
3954
  didDataChange: false,
@@ -3836,10 +3980,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3836
3980
  minIndexSizeChanged: 0,
3837
3981
  nativeContentInset: void 0,
3838
3982
  nativeMarginTop: 0,
3839
- positions: /* @__PURE__ */ new Map(),
3983
+ positions: [],
3840
3984
  props: {},
3841
3985
  queuedCalculateItemsInView: 0,
3842
- refScroller: void 0,
3986
+ refScroller: { current: null },
3843
3987
  scroll: 0,
3844
3988
  scrollAdjustHandler: new ScrollAdjustHandler(ctx),
3845
3989
  scrollForNextCalculateItemsInView: void 0,
@@ -3855,6 +3999,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3855
3999
  startBuffered: -1,
3856
4000
  startNoBuffer: -1,
3857
4001
  startReachedSnapshot: void 0,
4002
+ startReachedSnapshotDataChangeEpoch: void 0,
3858
4003
  stickyContainerPool: /* @__PURE__ */ new Set(),
3859
4004
  stickyContainers: /* @__PURE__ */ new Map(),
3860
4005
  timeoutSizeMessage: 0,
@@ -3874,6 +4019,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3874
4019
  state.didColumnsChange = numColumnsProp !== state.props.numColumns;
3875
4020
  const didDataChangeLocal = state.props.dataVersion !== dataVersion || state.props.data !== dataProp && checkActualChange(state, dataProp, state.props.data);
3876
4021
  if (didDataChangeLocal) {
4022
+ state.dataChangeEpoch += 1;
3877
4023
  state.dataChangeNeedsScrollUpdate = true;
3878
4024
  state.didDataChange = true;
3879
4025
  state.previousData = state.props.data;
@@ -3910,14 +4056,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3910
4056
  onStartReachedThreshold,
3911
4057
  onStickyHeaderChange,
3912
4058
  overrideItemLayout,
4059
+ positionComponentInternal,
3913
4060
  recycleItems: !!recycleItems,
3914
4061
  renderItem,
3915
4062
  snapToIndices,
3916
4063
  stickyIndicesArr: stickyHeaderIndices != null ? stickyHeaderIndices : [],
3917
4064
  stickyIndicesSet: useMemo(() => new Set(stickyHeaderIndices != null ? stickyHeaderIndices : []), [stickyHeaderIndices == null ? void 0 : stickyHeaderIndices.join(",")]),
4065
+ stickyPositionComponentInternal,
3918
4066
  stylePaddingBottom: stylePaddingBottomState,
3919
4067
  stylePaddingTop: stylePaddingTopState,
3920
- suggestEstimatedItemSize: !!suggestEstimatedItemSize
4068
+ suggestEstimatedItemSize: !!suggestEstimatedItemSize,
4069
+ useWindowScroll: useWindowScrollResolved
3921
4070
  };
3922
4071
  state.refScroller = refScroller;
3923
4072
  const memoizedLastItemKeys = useMemo(() => {
@@ -3968,7 +4117,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3968
4117
  } else {
3969
4118
  const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
3970
4119
  const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
3971
- const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
4120
+ const clampedOffset = clampScrollOffset(ctx, resolvedOffset, initialScroll);
3972
4121
  const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3973
4122
  refState.current.initialScroll = updatedInitialScroll;
3974
4123
  state.initialScroll = updatedInitialScroll;
@@ -3991,7 +4140,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3991
4140
  "Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
3992
4141
  );
3993
4142
  refState.current.sizes.clear();
3994
- refState.current.positions.clear();
4143
+ refState.current.positions.length = 0;
3995
4144
  refState.current.totalSize = 0;
3996
4145
  set$(ctx, "totalSize", 0);
3997
4146
  }
@@ -4124,7 +4273,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4124
4273
  return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
4125
4274
  ListComponent,
4126
4275
  {
4127
- ...rest,
4276
+ ...restProps,
4128
4277
  alignItemsAtEnd,
4129
4278
  canRender,
4130
4279
  contentContainerStyle,
@@ -4150,15 +4299,25 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4150
4299
  }
4151
4300
  ),
4152
4301
  refScrollView: combinedRef,
4302
+ renderScrollComponent,
4153
4303
  scrollAdjustHandler: (_d = refState.current) == null ? void 0 : _d.scrollAdjustHandler,
4154
4304
  scrollEventThrottle: 0,
4155
4305
  snapToIndices,
4156
4306
  stickyHeaderIndices,
4157
4307
  style,
4158
4308
  updateItemSize: fns.updateItemSize,
4309
+ useWindowScroll: useWindowScrollResolved,
4159
4310
  waitForInitialLayout
4160
4311
  }
4161
4312
  ), IS_DEV && ENABLE_DEBUG_VIEW);
4162
4313
  });
4163
4314
 
4164
- export { LegendList, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
4315
+ // src/index.ts
4316
+ var LegendList3 = LegendList;
4317
+ if (IS_DEV) {
4318
+ console.warn(
4319
+ "[legend-list] Legend List 3.0 deprecates the root import (@legendapp/list) because it now supports both react and react-native. The root import is fully functional, but please switch to platform-specific imports for strict platform types:\n - React Native: @legendapp/list/react-native\n - React: @legendapp/list/react\nSee README for details."
4320
+ );
4321
+ }
4322
+
4323
+ export { LegendList3 as LegendList, typedForwardRef, typedMemo2 as typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };