@legendapp/list 3.3.5 → 3.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/react-native.mjs CHANGED
@@ -47,10 +47,6 @@ function getStylePaddingEnd(props) {
47
47
  }
48
48
  return (isHorizontalRTLProps(props) ? props.stylePaddingLeft : props.stylePaddingRight) || 0;
49
49
  }
50
- function getLogicalHorizontalMaxOffset(state, contentWidth) {
51
- var _a3;
52
- return (_a3 = getHorizontalMaxOffset(state, contentWidth)) != null ? _a3 : 0;
53
- }
54
50
  function getHorizontalInsetEnd(state, inset) {
55
51
  if (!inset) {
56
52
  return 0;
@@ -384,6 +380,7 @@ var IsNewArchitecture = f !== void 0 && f != null;
384
380
  // src/core/containerItemMetadata.ts
385
381
  function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
386
382
  return {
383
+ data: state.props.data,
387
384
  dataChangeEpoch: state.dataChangeEpoch,
388
385
  getFixedItemSize: state.props.getFixedItemSize,
389
386
  getItemType: state.props.getItemType,
@@ -392,25 +389,29 @@ function createContainerItemMetadata(state, itemIndex, itemData, itemType) {
392
389
  itemType
393
390
  };
394
391
  }
395
- function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
396
- var _a3, _b;
397
- const { getFixedItemSize, getItemType } = state.props;
392
+ function updateContainerItemMetadata(state, containerId, itemIndex, itemData, itemType) {
393
+ var _a3;
394
+ const { getItemType } = state.props;
398
395
  const previousMetadata = state.containerItemMetadata.get(containerId);
399
- let metadata;
400
396
  if ((previousMetadata == null ? void 0 : previousMetadata.dataChangeEpoch) === state.dataChangeEpoch && previousMetadata.getItemType === getItemType && previousMetadata.itemData === itemData && previousMetadata.itemIndex === itemIndex) {
401
- metadata = previousMetadata;
402
- } else {
403
- const itemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
404
- metadata = createContainerItemMetadata(state, itemIndex, itemData, itemType);
405
- state.containerItemMetadata.set(containerId, metadata);
397
+ return previousMetadata;
406
398
  }
399
+ const resolvedItemType = getItemType ? (_a3 = getItemType(itemData, itemIndex)) != null ? _a3 : "" : void 0;
400
+ const metadata = createContainerItemMetadata(state, itemIndex, itemData, resolvedItemType);
401
+ state.containerItemMetadata.set(containerId, metadata);
402
+ return metadata;
403
+ }
404
+ function resolveContainerItemMetadata(state, containerId, itemIndex, itemData) {
405
+ var _a3;
406
+ const { getFixedItemSize } = state.props;
407
+ const metadata = updateContainerItemMetadata(state, containerId, itemIndex, itemData);
407
408
  if (metadata.getFixedItemSize !== getFixedItemSize) {
408
409
  metadata.didResolveFixedItemSize = false;
409
410
  metadata.fixedItemSize = void 0;
410
411
  metadata.getFixedItemSize = getFixedItemSize;
411
412
  }
412
413
  if (getFixedItemSize && !metadata.didResolveFixedItemSize) {
413
- metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_b = metadata.itemType) != null ? _b : "");
414
+ metadata.fixedItemSize = getFixedItemSize(itemData, itemIndex, (_a3 = metadata.itemType) != null ? _a3 : "");
414
415
  metadata.didResolveFixedItemSize = true;
415
416
  }
416
417
  return metadata;
@@ -712,6 +713,12 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
712
713
  } = state;
713
714
  const contentSize = getContentSize(ctx);
714
715
  resetSharedEdgeGateIfOutsideHysteresis(ctx);
716
+ if (state.props.data.length === 0 && scrollLength > 0 && contentSize <= scrollLength) {
717
+ set$(ctx, "isAtEnd", true);
718
+ set$(ctx, "isNearEnd", true);
719
+ set$(ctx, "isWithinMaintainScrollAtEndThreshold", true);
720
+ return;
721
+ }
715
722
  if (contentSize > 0 && queuedInitialLayout) {
716
723
  const insetEnd = getContentInsetEnd(ctx);
717
724
  const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
@@ -721,7 +728,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
721
728
  set$(
722
729
  ctx,
723
730
  "isWithinMaintainScrollAtEndThreshold",
724
- isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength
731
+ isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant"
725
732
  );
726
733
  const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
727
734
  if (!shouldSkipThresholdChecks) {
@@ -1072,10 +1079,22 @@ function getAlignItemsAtEndPadding(ctx) {
1072
1079
  return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
1073
1080
  }
1074
1081
  function updateContentMetricsState(ctx) {
1082
+ var _a3;
1083
+ const { state } = ctx;
1075
1084
  const previousPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
1076
1085
  const nextPadding = getAlignItemsAtEndPadding(ctx);
1077
1086
  if (previousPadding !== nextPadding) {
1078
- set$(ctx, "alignItemsAtEndPadding", nextPadding);
1087
+ const isAnimatedMaintainActive = state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated";
1088
+ const isMaintainExpected = state.didContainersLayout && ((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.animated) && (isAnimatedMaintainActive || previousPadding > nextPadding && peek$(ctx, "isWithinMaintainScrollAtEndThreshold"));
1089
+ if (isMaintainExpected && !isAnimatedMaintainActive && !state.pendingMaintainScrollAtEnd) {
1090
+ state.scheduledWork.microtask(() => {
1091
+ if (!state.maintainingScrollAtEnd && !state.pendingMaintainScrollAtEnd) {
1092
+ set$(ctx, "alignItemsAtEndPadding", getAlignItemsAtEndPadding(ctx));
1093
+ }
1094
+ }, "alignItemsAtEndPaddingFallback");
1095
+ } else if (!isMaintainExpected) {
1096
+ set$(ctx, "alignItemsAtEndPadding", nextPadding);
1097
+ }
1079
1098
  }
1080
1099
  }
1081
1100
 
@@ -1528,81 +1547,55 @@ function doScrollTo(ctx, params) {
1528
1547
  }
1529
1548
  }
1530
1549
 
1531
- // src/core/doMaintainScrollAtEnd.ts
1532
- function doMaintainScrollAtEnd(ctx) {
1533
- const state = ctx.state;
1534
- const {
1535
- didContainersLayout,
1536
- pendingNativeMVCPAdjust,
1537
- refScroller,
1538
- props: { maintainScrollAtEnd }
1539
- } = state;
1540
- const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1541
- const shouldMaintainScrollAtEnd = !!(isWithinMaintainScrollAtEndThreshold && maintainScrollAtEnd && didContainersLayout);
1542
- if (pendingNativeMVCPAdjust) {
1543
- state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
1544
- return false;
1545
- }
1546
- if (shouldMaintainScrollAtEnd) {
1547
- state.pendingMaintainScrollAtEnd = false;
1548
- const contentSize = getContentSize(ctx);
1549
- if (contentSize < state.scrollLength) {
1550
- state.scroll = 0;
1551
- }
1552
- if (!state.maintainingScrollAtEnd) {
1553
- const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1554
- const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
1555
- const scrollAtRequest = state.scroll;
1556
- state.maintainingScrollAtEnd = pendingState;
1557
- requestAnimationFrame(() => {
1558
- const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1559
- const didScrollSinceRequest = state.scroll !== scrollAtRequest;
1560
- if (isStillWithinThreshold || !didScrollSinceRequest) {
1561
- state.maintainingScrollAtEnd = activeState;
1562
- const scroller = refScroller.current;
1563
- if (state.props.horizontal && isHorizontalRTL(state)) {
1564
- const currentContentSize = getContentSize(ctx);
1565
- const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
1566
- const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
1567
- scroller == null ? void 0 : scroller.scrollTo({
1568
- animated: maintainScrollAtEnd.animated,
1569
- x: nativeOffset,
1570
- y: 0
1571
- });
1572
- } else {
1573
- scroller == null ? void 0 : scroller.scrollToEnd({
1574
- animated: maintainScrollAtEnd.animated
1575
- });
1576
- }
1577
- setTimeout(
1578
- () => {
1579
- if (state.maintainingScrollAtEnd === activeState) {
1580
- state.maintainingScrollAtEnd = void 0;
1581
- if (state.pendingMaintainScrollAtEnd) {
1582
- doMaintainScrollAtEnd(ctx);
1583
- }
1584
- }
1585
- },
1586
- maintainScrollAtEnd.animated ? 500 : 0
1587
- );
1588
- } else if (state.maintainingScrollAtEnd === pendingState) {
1589
- state.maintainingScrollAtEnd = void 0;
1590
- state.pendingMaintainScrollAtEnd = false;
1550
+ // src/core/scrollRequestTracker.ts
1551
+ function getScrollRequestTracker(ctx) {
1552
+ if (!ctx.scrollRequestTracker) {
1553
+ let currentToken = 0;
1554
+ const start = (resolve) => {
1555
+ const state = ctx.state;
1556
+ state.scheduledWork.cancel("imperativeScrollReady");
1557
+ const token = ++currentToken;
1558
+ settlePendingImperativeScroll(state);
1559
+ state.pendingScrollResolve = resolve;
1560
+ return token;
1561
+ };
1562
+ const runNow = (token, resolve, run) => {
1563
+ const state = ctx.state;
1564
+ if (token !== currentToken) {
1565
+ return;
1566
+ }
1567
+ const didStartScroll = run();
1568
+ if (!didStartScroll || !state.scrollingTo) {
1569
+ if (state.pendingScrollResolve === resolve) {
1570
+ state.pendingScrollResolve = void 0;
1591
1571
  }
1592
- });
1593
- } else {
1594
- state.pendingMaintainScrollAtEnd = true;
1595
- }
1596
- return true;
1572
+ resolve();
1573
+ }
1574
+ };
1575
+ ctx.scrollRequestTracker = {
1576
+ isCurrent: (token) => token === currentToken,
1577
+ runNow,
1578
+ runNowIfIdle: (run) => {
1579
+ const state = ctx.state;
1580
+ if (state.pendingScrollResolve || state.scrollingTo) {
1581
+ return Promise.resolve();
1582
+ }
1583
+ return new Promise((resolve) => {
1584
+ const token = start(resolve);
1585
+ runNow(token, resolve, run);
1586
+ });
1587
+ },
1588
+ start
1589
+ };
1597
1590
  }
1598
- state.pendingMaintainScrollAtEnd = false;
1599
- return false;
1591
+ return ctx.scrollRequestTracker;
1600
1592
  }
1601
1593
 
1602
1594
  // src/utils/requestAdjust.ts
1603
- function requestAdjust(ctx, positionDiff, dataChanged) {
1595
+ function requestAdjust(ctx, positionDiff, source) {
1604
1596
  const state = ctx.state;
1605
1597
  if (Math.abs(positionDiff) > 0.1) {
1598
+ const dataChanged = source === "data";
1606
1599
  const needsScrollWorkaround = Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
1607
1600
  const doit = () => {
1608
1601
  if (needsScrollWorkaround) {
@@ -1619,7 +1612,7 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
1619
1612
  const readyToRender = peek$(ctx, "readyToRender");
1620
1613
  if (readyToRender) {
1621
1614
  doit();
1622
- if (Platform.OS !== "web") {
1615
+ if (Platform.OS !== "web" && source !== "item-size") {
1623
1616
  const threshold = state.scroll - positionDiff / 2;
1624
1617
  if (!state.ignoreScrollFromMVCP) {
1625
1618
  state.ignoreScrollFromMVCP = {};
@@ -1652,6 +1645,87 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
1652
1645
  }
1653
1646
  }
1654
1647
 
1648
+ // src/core/doMaintainScrollAtEnd.ts
1649
+ function finishMaintainScrollAtEnd(ctx) {
1650
+ var _a3;
1651
+ const { state } = ctx;
1652
+ const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
1653
+ const nextPadding = getAlignItemsAtEndPadding(ctx);
1654
+ state.maintainingScrollAtEnd = void 0;
1655
+ state.pendingMaintainScrollAtEnd = false;
1656
+ if (currentPadding !== nextPadding) {
1657
+ set$(ctx, "alignItemsAtEndPadding", nextPadding);
1658
+ state.scrollForNextCalculateItemsInView = void 0;
1659
+ (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
1660
+ const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
1661
+ requestAdjust(ctx, nextScroll - state.scroll);
1662
+ }
1663
+ }
1664
+ function doMaintainScrollAtEnd(ctx) {
1665
+ const state = ctx.state;
1666
+ const {
1667
+ didContainersLayout,
1668
+ didFinishInitialScroll,
1669
+ pendingNativeMVCPAdjust,
1670
+ props: { maintainScrollAtEnd }
1671
+ } = state;
1672
+ const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1673
+ const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
1674
+ const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
1675
+ if (shouldMaintainScrollAtEnd && !didContainersLayout) {
1676
+ state.pendingMaintainScrollAtEnd = true;
1677
+ return false;
1678
+ }
1679
+ if (pendingNativeMVCPAdjust) {
1680
+ state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
1681
+ return false;
1682
+ }
1683
+ if (shouldMaintainScrollAtEnd && didContainersLayout) {
1684
+ state.pendingMaintainScrollAtEnd = false;
1685
+ const contentSize = getContentSize(ctx);
1686
+ if (contentSize < state.scrollLength) {
1687
+ state.scroll = 0;
1688
+ }
1689
+ if (!state.maintainingScrollAtEnd) {
1690
+ const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1691
+ const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
1692
+ const scrollAtRequest = state.scroll;
1693
+ state.maintainingScrollAtEnd = pendingState;
1694
+ requestAnimationFrame(() => {
1695
+ if (state.maintainingScrollAtEnd !== pendingState) {
1696
+ return;
1697
+ }
1698
+ const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1699
+ const didScrollSinceRequest = state.scroll !== scrollAtRequest;
1700
+ if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
1701
+ state.maintainingScrollAtEnd = activeState;
1702
+ const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
1703
+ () => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
1704
+ );
1705
+ void scrollPromise.then(() => {
1706
+ if (state.maintainingScrollAtEnd !== activeState) {
1707
+ return;
1708
+ }
1709
+ if (state.pendingMaintainScrollAtEnd) {
1710
+ state.maintainingScrollAtEnd = void 0;
1711
+ doMaintainScrollAtEnd(ctx);
1712
+ } else {
1713
+ finishMaintainScrollAtEnd(ctx);
1714
+ }
1715
+ });
1716
+ } else if (state.maintainingScrollAtEnd === pendingState) {
1717
+ finishMaintainScrollAtEnd(ctx);
1718
+ }
1719
+ });
1720
+ } else {
1721
+ state.pendingMaintainScrollAtEnd = true;
1722
+ }
1723
+ return true;
1724
+ }
1725
+ finishMaintainScrollAtEnd(ctx);
1726
+ return false;
1727
+ }
1728
+
1655
1729
  // src/core/mvcp.ts
1656
1730
  var MVCP_POSITION_EPSILON = 0.1;
1657
1731
  var MVCP_ANCHOR_LOCK_TTL_MS = 300;
@@ -1725,7 +1799,7 @@ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
1725
1799
  state.pendingNativeMVCPAdjust = void 0;
1726
1800
  const remaining = remainingAfterManual - nativeDelta;
1727
1801
  if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
1728
- requestAdjust(ctx, remaining, true);
1802
+ requestAdjust(ctx, remaining, "data");
1729
1803
  }
1730
1804
  }
1731
1805
  function maybeApplyPredictedNativeMVCPAdjust(ctx) {
@@ -1744,7 +1818,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
1744
1818
  return;
1745
1819
  }
1746
1820
  pending.manualApplied = manualDesired;
1747
- requestAdjust(ctx, manualDesired, true);
1821
+ requestAdjust(ctx, manualDesired, "data");
1748
1822
  pending.furthestProgressTowardAmount = 0;
1749
1823
  }
1750
1824
  function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
@@ -1790,7 +1864,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
1790
1864
  }
1791
1865
  return false;
1792
1866
  }
1793
- function prepareMVCP(ctx, dataChanged) {
1867
+ function prepareMVCP(ctx, dataChanged, adjustmentSource) {
1794
1868
  const state = ctx.state;
1795
1869
  const { idsInView, positions, props } = state;
1796
1870
  const {
@@ -1944,7 +2018,7 @@ function prepareMVCP(ctx, dataChanged) {
1944
2018
  if (Math.abs(positionDiff) > MVCP_POSITION_EPSILON) {
1945
2019
  const shouldSkipAdjustForMaintainedEnd = (state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated") && peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1946
2020
  if (!shouldSkipAdjustForMaintainedEnd) {
1947
- requestAdjust(ctx, positionDiff, dataChanged && mvcpData);
2021
+ requestAdjust(ctx, positionDiff, dataChanged && mvcpData ? "data" : adjustmentSource);
1948
2022
  }
1949
2023
  }
1950
2024
  };
@@ -2042,6 +2116,10 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
2042
2116
  state.scrollTime = currentTime;
2043
2117
  const scrollDelta = Math.abs(newScroll - prevScroll);
2044
2118
  const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
2119
+ const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
2120
+ if (didCancelMaintainScrollAtEnd) {
2121
+ finishMaintainScrollAtEnd(ctx);
2122
+ }
2045
2123
  const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
2046
2124
  const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
2047
2125
  const scrollLength = state.scrollLength;
@@ -2050,7 +2128,7 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
2050
2128
  updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
2051
2129
  const lastCalculated = state.scrollLastCalculate;
2052
2130
  const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
2053
- const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
2131
+ const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
2054
2132
  if (shouldUpdate) {
2055
2133
  state.scrollLastCalculate = state.scroll;
2056
2134
  state.ignoreScrollFromMVCPIgnored = false;
@@ -2879,7 +2957,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
2879
2957
  }
2880
2958
  }
2881
2959
  function handleBootstrapInitialScrollLayoutChange(ctx) {
2882
- var _a3, _b, _c;
2960
+ var _a3, _b;
2883
2961
  const state = ctx.state;
2884
2962
  const initialScroll = state.initialScroll;
2885
2963
  const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
@@ -2893,19 +2971,15 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
2893
2971
  if (state.didFinishInitialScroll) {
2894
2972
  schedulePreservedEndAnchorCorrection(ctx);
2895
2973
  } else if (scrollingTo) {
2896
- const existingWatchdog = initialScrollWatchdog.get(state);
2897
- scrollingTo.offset = resolvedOffset;
2898
- scrollingTo.targetOffset = resolvedOffset;
2899
2974
  state.initialScroll = {
2900
2975
  ...initialScroll,
2901
2976
  contentOffset: resolvedOffset
2902
2977
  };
2903
- state.hasScrolled = false;
2904
- initialScrollWatchdog.set(state, {
2905
- startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
2906
- targetOffset: resolvedOffset
2978
+ dispatchInitialScroll(ctx, {
2979
+ forceScroll: true,
2980
+ resolvedOffset,
2981
+ target: state.initialScroll
2907
2982
  });
2908
- requestAdjust(ctx, offsetDiff);
2909
2983
  }
2910
2984
  }
2911
2985
  } else {
@@ -3204,6 +3278,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3204
3278
  return { didChangePosition: false, didRefreshData: false };
3205
3279
  }
3206
3280
  const itemKey = (_a3 = state.idCache[itemIndex]) != null ? _a3 : getId(state, itemIndex);
3281
+ const metadata = updateContainerItemMetadata(state, containerIndex, itemIndex, item);
3207
3282
  const updateLayout = (_b = options == null ? void 0 : options.updateLayout) != null ? _b : true;
3208
3283
  let didChangePosition = false;
3209
3284
  let didRefreshData = false;
@@ -3214,7 +3289,7 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3214
3289
  return { didChangePosition: false, didRefreshData: false };
3215
3290
  }
3216
3291
  const logicalPosition = (positionValue || 0) - ((_c = options == null ? void 0 : options.scrollAdjustPending) != null ? _c : 0);
3217
- const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item);
3292
+ const itemSize = (_d = state.sizes.get(itemKey)) != null ? _d : getItemSize(ctx, itemKey, itemIndex, item, void 0, void 0, void 0, metadata);
3218
3293
  const position = toPhysicalHorizontalItemPosition(state, logicalPosition, itemSize, peek$(ctx, "totalSize"));
3219
3294
  const column = columns[itemIndex] || 1;
3220
3295
  const span = columnSpans[itemIndex] || 1;
@@ -3947,6 +4022,9 @@ function setDidLayout(ctx) {
3947
4022
  state.queuedInitialLayout = true;
3948
4023
  checkAtBottom(ctx);
3949
4024
  setInitialRenderState(ctx, { didLayout: true });
4025
+ if (state.pendingMaintainScrollAtEnd) {
4026
+ doMaintainScrollAtEnd(ctx);
4027
+ }
3950
4028
  }
3951
4029
 
3952
4030
  // src/core/calculateItemsInView.ts
@@ -4183,7 +4261,7 @@ function calculateItemsInView(ctx, params = {}) {
4183
4261
  const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
4184
4262
  const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
4185
4263
  const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
4186
- const { dataChanged, doMVCP, forceFullItemPositions } = params;
4264
+ const { dataChanged, doMVCP, forceFullItemPositions, mvcpAdjustmentSource } = params;
4187
4265
  const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
4188
4266
  const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
4189
4267
  const prevNumContainers = peek$(ctx, "numContainers");
@@ -4284,7 +4362,7 @@ function calculateItemsInView(ctx, params = {}) {
4284
4362
  }
4285
4363
  }
4286
4364
  }
4287
- const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged) : void 0;
4365
+ const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged, mvcpAdjustmentSource) : void 0;
4288
4366
  if (dataChanged) {
4289
4367
  resetLayoutCachesForDataChange(state);
4290
4368
  }
@@ -4502,13 +4580,13 @@ function calculateItemsInView(ctx, params = {}) {
4502
4580
  changedContainerIds.add(containerIndex);
4503
4581
  state.containerItemGenerations[containerIndex] = ((_p = state.containerItemGenerations[containerIndex]) != null ? _p : 0) + 1;
4504
4582
  }
4505
- set$(ctx, `containerItemKey${containerIndex}`, id);
4506
- set$(ctx, `containerItemIndex${containerIndex}`, i);
4507
- set$(ctx, `containerItemData${containerIndex}`, data[i]);
4508
4583
  state.containerItemMetadata.set(
4509
4584
  containerIndex,
4510
4585
  createContainerItemMetadata(state, i, data[i], allocation.itemType)
4511
4586
  );
4587
+ set$(ctx, `containerItemKey${containerIndex}`, id);
4588
+ set$(ctx, `containerItemIndex${containerIndex}`, i);
4589
+ set$(ctx, `containerItemData${containerIndex}`, data[i]);
4512
4590
  containerItemKeys.set(id, containerIndex);
4513
4591
  (_q = state.userScrollAnchorReset) == null ? void 0 : _q.keys.add(id);
4514
4592
  const containerSticky = `containerSticky${containerIndex}`;
@@ -4698,12 +4776,15 @@ function runOrScheduleMVCPRecalculate(ctx) {
4698
4776
  } else if (Platform.OS === "web") {
4699
4777
  if (!state.mvcpAnchorLock) {
4700
4778
  state.scheduledWork.cancel("mvcpRecalculate");
4701
- calculateItemsInView(ctx, { doMVCP: true });
4779
+ calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
4702
4780
  } else if (!state.scheduledWork.has("mvcpRecalculate")) {
4703
- state.scheduledWork.frame(() => calculateItemsInView(ctx, { doMVCP: true }), "mvcpRecalculate");
4781
+ state.scheduledWork.frame(
4782
+ () => calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" }),
4783
+ "mvcpRecalculate"
4784
+ );
4704
4785
  }
4705
4786
  } else {
4706
- calculateItemsInView(ctx, { doMVCP: true });
4787
+ calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
4707
4788
  }
4708
4789
  }
4709
4790
  function updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal) {
@@ -5192,6 +5273,30 @@ function useContainerItemSignals(containerContext) {
5192
5273
  itemKey
5193
5274
  };
5194
5275
  }
5276
+ function scheduleViewabilityConfigWarning(ctx, hookName, configId) {
5277
+ let cancelled = false;
5278
+ Promise.resolve().then(() => {
5279
+ var _a3;
5280
+ const viewabilityConfigCallbackPairs = (_a3 = ctx.state) == null ? void 0 : _a3.viewabilityConfigCallbackPairs;
5281
+ if (!cancelled && ctx.state) {
5282
+ if (!(viewabilityConfigCallbackPairs == null ? void 0 : viewabilityConfigCallbackPairs.length)) {
5283
+ warnDevOnce(
5284
+ `${hookName}-missing-viewability-config`,
5285
+ `${hookName} requires viewability to be configured on the owning LegendList. Add viewabilityConfig with a visibility threshold.`
5286
+ );
5287
+ } else if (hookName === "useViewability" && !viewabilityConfigCallbackPairs.some((pair) => pair.viewabilityConfig.id === (configId != null ? configId : ""))) {
5288
+ const configDescription = configId ? ` for configId "${configId}"` : "";
5289
+ warnDevOnce(
5290
+ `${hookName}-missing-viewability-config-${configId != null ? configId : "default"}`,
5291
+ `${hookName}${configDescription} requires a matching viewabilityConfig.id on the owning LegendList. Add an id to viewabilityConfig and pass the same id to useViewability.`
5292
+ );
5293
+ }
5294
+ }
5295
+ });
5296
+ return () => {
5297
+ cancelled = true;
5298
+ };
5299
+ }
5195
5300
  function useAdaptiveRender() {
5196
5301
  const [mode] = useArr$(["adaptiveRender"]);
5197
5302
  return mode;
@@ -5231,7 +5336,9 @@ function useViewability(callback, configId) {
5231
5336
  const { containerId } = containerContext;
5232
5337
  const key = containerId + (configId != null ? configId : "");
5233
5338
  ctx.mapViewabilityCallbacks.set(key, callback);
5339
+ const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewability", configId) : void 0;
5234
5340
  return () => {
5341
+ cancelConfigWarning == null ? void 0 : cancelConfigWarning();
5235
5342
  ctx.mapViewabilityCallbacks.delete(key);
5236
5343
  };
5237
5344
  }, [ctx, callback, configId, containerContext]);
@@ -5255,7 +5362,9 @@ function useViewabilityAmount(callback) {
5255
5362
  }
5256
5363
  const { containerId } = containerContext;
5257
5364
  ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
5365
+ const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewabilityAmount") : void 0;
5258
5366
  return () => {
5367
+ cancelConfigWarning == null ? void 0 : cancelConfigWarning();
5259
5368
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
5260
5369
  };
5261
5370
  }, [ctx, callback, containerContext]);
@@ -5620,7 +5729,7 @@ var Container = typedMemo(function Container2({
5620
5729
  ]
5621
5730
  );
5622
5731
  const renderedItemInfo = useMemo(
5623
- () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
5732
+ () => itemKey !== void 0 ? getRenderedItem2(itemKey, id) : null,
5624
5733
  [itemKey, data, extraData]
5625
5734
  );
5626
5735
  const { renderedItem } = renderedItemInfo || {};
@@ -6362,11 +6471,29 @@ var ScheduledWork = class {
6362
6471
  constructor() {
6363
6472
  this.work = /* @__PURE__ */ new Map();
6364
6473
  }
6474
+ microtask(callback, key) {
6475
+ const pendingWork = this.work.get(key);
6476
+ if (pendingWork == null ? void 0 : pendingWork.callback) {
6477
+ pendingWork.callback = callback;
6478
+ } else {
6479
+ this.cancel(key);
6480
+ const work = { callback, cancel: () => {
6481
+ } };
6482
+ this.work.set(key, work);
6483
+ queueMicrotask(() => {
6484
+ var _a3;
6485
+ if (this.work.get(key) === work) {
6486
+ this.work.delete(key);
6487
+ (_a3 = work.callback) == null ? void 0 : _a3.call(work);
6488
+ }
6489
+ });
6490
+ }
6491
+ }
6365
6492
  timeout(callback, delay, key) {
6366
6493
  if (key) {
6367
6494
  this.cancel(key);
6368
6495
  }
6369
- const work = [void 0, clearTimeout];
6496
+ const work = { cancel: () => clearTimeout(handle) };
6370
6497
  const handle = setTimeout(() => {
6371
6498
  const workKey = key != null ? key : handle;
6372
6499
  if (this.work.get(workKey) === work) {
@@ -6374,14 +6501,13 @@ var ScheduledWork = class {
6374
6501
  callback();
6375
6502
  }
6376
6503
  }, delay);
6377
- work[0] = handle;
6378
6504
  this.work.set(key != null ? key : handle, work);
6379
6505
  }
6380
6506
  frame(callback, key) {
6381
6507
  this.cancel(key);
6382
- const work = [void 0, cancelAnimationFrame];
6508
+ const work = { cancel: () => cancelAnimationFrame(handle) };
6383
6509
  this.work.set(key, work);
6384
- work[0] = requestAnimationFrame(() => {
6510
+ const handle = requestAnimationFrame(() => {
6385
6511
  if (this.work.get(key) === work) {
6386
6512
  this.work.delete(key);
6387
6513
  callback();
@@ -6390,22 +6516,21 @@ var ScheduledWork = class {
6390
6516
  }
6391
6517
  register(key, cancel) {
6392
6518
  this.cancel(key);
6393
- this.work.set(key, [void 0, cancel]);
6519
+ this.work.set(key, { cancel });
6394
6520
  }
6395
6521
  cancel(key) {
6396
6522
  const work = this.work.get(key);
6397
6523
  if (work) {
6398
6524
  this.work.delete(key);
6399
- const [handle, cancel] = work;
6400
- cancel(handle);
6525
+ work.cancel();
6401
6526
  }
6402
6527
  }
6403
6528
  has(key) {
6404
6529
  return this.work.has(key);
6405
6530
  }
6406
6531
  dispose() {
6407
- for (const [handle, cancel] of this.work.values()) {
6408
- cancel(handle);
6532
+ for (const work of this.work.values()) {
6533
+ work.cancel();
6409
6534
  }
6410
6535
  this.work.clear();
6411
6536
  }
@@ -6462,6 +6587,25 @@ var ScrollAdjustHandler = class {
6462
6587
  }
6463
6588
  };
6464
6589
 
6590
+ // src/core/scrollToEnd.ts
6591
+ function scrollToEnd(ctx, options) {
6592
+ const state = ctx.state;
6593
+ const data = state.props.data;
6594
+ const index = data.length - 1;
6595
+ if (index === -1) {
6596
+ return false;
6597
+ }
6598
+ const paddingBottom = state.props.stylePaddingBottom || 0;
6599
+ const footerSize = peek$(ctx, "footerSize") || 0;
6600
+ scrollToIndex(ctx, {
6601
+ ...options,
6602
+ index,
6603
+ viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
6604
+ viewPosition: 1
6605
+ });
6606
+ return true;
6607
+ }
6608
+
6465
6609
  // src/core/updateContentInsetEndAdjustment.ts
6466
6610
  function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
6467
6611
  const state = ctx.state;
@@ -6536,25 +6680,6 @@ function createColumnWrapperStyle(contentContainerStyle) {
6536
6680
  }
6537
6681
  }
6538
6682
 
6539
- // src/core/scrollToEnd.ts
6540
- function scrollToEnd(ctx, options) {
6541
- const state = ctx.state;
6542
- const data = state.props.data;
6543
- const index = data.length - 1;
6544
- if (index === -1) {
6545
- return false;
6546
- }
6547
- const paddingBottom = state.props.stylePaddingBottom || 0;
6548
- const footerSize = peek$(ctx, "footerSize") || 0;
6549
- scrollToIndex(ctx, {
6550
- ...options,
6551
- index,
6552
- viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
6553
- viewPosition: 1
6554
- });
6555
- return true;
6556
- }
6557
-
6558
6683
  // src/utils/createImperativeHandle.ts
6559
6684
  var DEFAULT_AVERAGE_ITEM_SIZE_TYPE = "default";
6560
6685
  function getAverageItemSizes(state) {
@@ -6581,9 +6706,9 @@ function triggerMountedContainerLayouts(ctx) {
6581
6706
  }
6582
6707
  function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6583
6708
  const state = ctx.state;
6709
+ const scrollRequestTracker = getScrollRequestTracker(ctx);
6584
6710
  const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
6585
6711
  const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
6586
- let imperativeScrollToken = 0;
6587
6712
  const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.scheduledWork.has("mvcpRecalculate") || state.ignoreScrollFromMVCP !== void 0;
6588
6713
  const isScrollToIndexReady = (targetIndex, allowEmpty = false) => {
6589
6714
  var _a3;
@@ -6605,7 +6730,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6605
6730
  const startedAt = Date.now();
6606
6731
  let stableFrames = 0;
6607
6732
  const check = () => {
6608
- if (token !== imperativeScrollToken) {
6733
+ if (!scrollRequestTracker.isCurrent(token)) {
6609
6734
  return;
6610
6735
  }
6611
6736
  if (isSettlingAfterDataChange() || !isReady()) {
@@ -6623,33 +6748,15 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6623
6748
  state.scheduledWork.frame(check, "imperativeScrollReady");
6624
6749
  };
6625
6750
  const runScrollRequest = (token, resolve, run, isReady = () => true) => {
6626
- const runNow = () => {
6627
- if (token !== imperativeScrollToken) {
6628
- return;
6629
- }
6630
- const didStartScroll = run();
6631
- if (!didStartScroll || !state.scrollingTo) {
6632
- if (state.pendingScrollResolve === resolve) {
6633
- state.pendingScrollResolve = void 0;
6634
- }
6635
- resolve();
6636
- }
6637
- };
6751
+ const runNow = () => scrollRequestTracker.runNow(token, resolve, run);
6638
6752
  if (isSettlingAfterDataChange() || !isReady()) {
6639
6753
  runWhenReady(token, runNow, isReady);
6640
6754
  } else {
6641
6755
  runNow();
6642
6756
  }
6643
6757
  };
6644
- const startImperativeScroll = (resolve) => {
6645
- state.scheduledWork.cancel("imperativeScrollReady");
6646
- const token = ++imperativeScrollToken;
6647
- settlePendingImperativeScroll(state);
6648
- state.pendingScrollResolve = resolve;
6649
- return token;
6650
- };
6651
6758
  const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
6652
- const token = startImperativeScroll(resolve);
6759
+ const token = scrollRequestTracker.start(resolve);
6653
6760
  supersedeInitialScroll(ctx);
6654
6761
  runScrollRequest(token, resolve, run, isReady);
6655
6762
  });
@@ -6657,7 +6764,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6657
6764
  const pendingScroll = state.pendingScrollToEnd;
6658
6765
  if (pendingScroll) {
6659
6766
  state.pendingScrollToEnd = void 0;
6660
- if (pendingScroll.token === imperativeScrollToken) {
6767
+ if (scrollRequestTracker.isCurrent(pendingScroll.token)) {
6661
6768
  runScrollRequest(
6662
6769
  pendingScroll.token,
6663
6770
  pendingScroll.resolve,
@@ -6771,7 +6878,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6771
6878
  }),
6772
6879
  scrollToEnd: (options) => new Promise((resolve) => {
6773
6880
  var _a3;
6774
- const token = startImperativeScroll(resolve);
6881
+ const token = scrollRequestTracker.start(resolve);
6775
6882
  state.pendingScrollToEnd = {
6776
6883
  options,
6777
6884
  resolve,
@@ -6873,34 +6980,37 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
6873
6980
  }
6874
6981
 
6875
6982
  // src/utils/getRenderedItem.ts
6876
- function getRenderedItem(ctx, key) {
6877
- var _a3;
6983
+ function getRenderedItem(ctx, key, containerId) {
6984
+ var _a3, _b, _c;
6878
6985
  const state = ctx.state;
6879
6986
  if (!state) {
6880
6987
  return null;
6881
6988
  }
6989
+ const metadata = state.containerItemMetadata.get(containerId);
6990
+ const useAssignedGeneration = metadata && metadata.dataChangeEpoch !== state.dataChangeEpoch;
6882
6991
  const {
6883
6992
  indexByKey,
6884
- props: { data, getItemType, renderItem }
6993
+ props: { data: currentData, getItemType, renderItem }
6885
6994
  } = state;
6886
- const index = indexByKey.get(key);
6995
+ const data = useAssignedGeneration ? metadata.data : currentData;
6996
+ const index = (_a3 = metadata == null ? void 0 : metadata.itemIndex) != null ? _a3 : indexByKey.get(key);
6887
6997
  if (index === void 0) {
6888
6998
  return null;
6889
6999
  }
6890
7000
  let renderedItem = null;
6891
7001
  const extraData = peek$(ctx, "extraData");
6892
- const item = data[index];
7002
+ const item = useAssignedGeneration ? metadata.itemData : data[index];
6893
7003
  if (renderItem && !isNullOrUndefined(item)) {
6894
7004
  const itemProps = {
6895
7005
  data,
6896
7006
  extraData,
6897
7007
  index,
6898
7008
  item,
6899
- type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
7009
+ type: useAssignedGeneration ? (_b = metadata.itemType) != null ? _b : "" : getItemType ? (_c = getItemType(item, index)) != null ? _c : "" : ""
6900
7010
  };
6901
7011
  renderedItem = renderItem(itemProps);
6902
7012
  }
6903
- return { index, item: data[index], renderedItem };
7013
+ return { index, item, renderedItem };
6904
7014
  }
6905
7015
 
6906
7016
  // src/utils/normalizeMaintainScrollAtEnd.ts
@@ -7151,6 +7261,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7151
7261
  const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
7152
7262
  const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
7153
7263
  const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
7264
+ const shouldBottomAlignNumericInitialScrollIndex = typeof initialScrollIndexProp === "number" && !hasInitialScrollOffset && dataProp.length > 1 && initialScrollIndexProp >= dataProp.length - 1;
7154
7265
  const initialScrollProp = initialScrollAtEnd ? {
7155
7266
  index: Math.max(0, dataProp.length - 1),
7156
7267
  preserveForBottomPadding: true,
@@ -7163,7 +7274,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7163
7274
  viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
7164
7275
  } : {
7165
7276
  index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
7166
- viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0
7277
+ preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
7278
+ viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? -stylePaddingEndState : 0,
7279
+ viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
7167
7280
  } : initialScrollUsesOffsetOnly ? {
7168
7281
  contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
7169
7282
  index: 0,
@@ -7269,6 +7382,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7269
7382
  viewabilityConfigCallbackPairs: void 0
7270
7383
  };
7271
7384
  const internalState = ctx.state;
7385
+ ctx.scrollToEnd = (options) => scrollToEnd(ctx, options);
7272
7386
  internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
7273
7387
  internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
7274
7388
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
@@ -7620,7 +7734,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7620
7734
  }, [ctx, usesBootstrapInitialScroll]);
7621
7735
  const fns = useMemo(
7622
7736
  () => ({
7623
- getRenderedItem: (key) => getRenderedItem(ctx, key),
7737
+ getRenderedItem: (key, containerId) => getRenderedItem(ctx, key, containerId),
7624
7738
  onMomentumScrollEnd: (event) => {
7625
7739
  checkFinishedScrollFallback(ctx);
7626
7740
  if (state.props.onMomentumScrollEnd) {
@@ -7630,6 +7744,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7630
7744
  onScroll: (event) => onScroll(ctx, event),
7631
7745
  onScrollBeginDrag: (event) => {
7632
7746
  var _a4, _b2;
7747
+ const maintainingScrollAtEnd = state.maintainingScrollAtEnd;
7748
+ if (maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant") {
7749
+ cancelImperativeScroll(state);
7750
+ }
7751
+ if (maintainingScrollAtEnd) {
7752
+ finishMaintainScrollAtEnd(ctx);
7753
+ }
7633
7754
  prepareReachedEdgeForNextUserScroll(ctx);
7634
7755
  (_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
7635
7756
  },