@legendapp/list 3.3.9 → 3.3.11

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.js CHANGED
@@ -1014,6 +1014,7 @@ function supersedeInitialScroll(ctx) {
1014
1014
  function finishInitialScroll(ctx, options) {
1015
1015
  var _a3, _b, _c;
1016
1016
  const state = ctx.state;
1017
+ const freshDataTransitionEpoch = state.freshDataTransitionEpoch;
1017
1018
  if ((options == null ? void 0 : options.resolvedOffset) !== void 0) {
1018
1019
  syncInitialScrollOffset(state, options.resolvedOffset);
1019
1020
  } else if ((options == null ? void 0 : options.syncObservedOffset) && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset") {
@@ -1023,9 +1024,13 @@ function finishInitialScroll(ctx, options) {
1023
1024
  }
1024
1025
  }
1025
1026
  const complete = () => {
1026
- var _a4, _b2, _c2, _d, _e;
1027
- const shouldReleaseDeferredPublicOnScroll = Platform.OS === "web" && ((_a4 = state.initialScrollSession) == null ? void 0 : _a4.kind) === "bootstrap";
1028
- const finalScrollOffset = (_d = (_c2 = (_b2 = options == null ? void 0 : options.resolvedOffset) != null ? _b2 : state.scrollPending) != null ? _c2 : state.scroll) != null ? _d : 0;
1027
+ var _a4, _b2, _c2, _d, _e, _f;
1028
+ if (freshDataTransitionEpoch !== state.freshDataTransitionEpoch) {
1029
+ (_a4 = options == null ? void 0 : options.onFinished) == null ? void 0 : _a4.call(options);
1030
+ return;
1031
+ }
1032
+ const shouldReleaseDeferredPublicOnScroll = Platform.OS === "web" && ((_b2 = state.initialScrollSession) == null ? void 0 : _b2.kind) === "bootstrap";
1033
+ const finalScrollOffset = (_e = (_d = (_c2 = options == null ? void 0 : options.resolvedOffset) != null ? _c2 : state.scrollPending) != null ? _d : state.scroll) != null ? _e : 0;
1029
1034
  initialScrollWatchdog.clear(state);
1030
1035
  if ((options == null ? void 0 : options.preserveTarget) && state.initialScroll) {
1031
1036
  state.clearPreservedInitialScrollOnNextFinish = void 0;
@@ -1054,7 +1059,7 @@ function finishInitialScroll(ctx, options) {
1054
1059
  if (shouldReleaseDeferredPublicOnScroll) {
1055
1060
  releaseDeferredPublicOnScroll(ctx, finalScrollOffset);
1056
1061
  }
1057
- (_e = options == null ? void 0 : options.onFinished) == null ? void 0 : _e.call(options);
1062
+ (_f = options == null ? void 0 : options.onFinished) == null ? void 0 : _f.call(options);
1058
1063
  };
1059
1064
  if (options == null ? void 0 : options.waitForCompletionFrame) {
1060
1065
  requestAnimationFrame(complete);
@@ -1338,246 +1343,21 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
1338
1343
  return clampedOffset;
1339
1344
  }
1340
1345
 
1341
- // src/core/finishScrollTo.ts
1342
- function finishScrollTo(ctx) {
1343
- var _a3, _b;
1344
- const state = ctx.state;
1345
- if (state == null ? void 0 : state.scrollingTo) {
1346
- cancelScrollCompletionChecks(state);
1347
- const resolvePendingScroll = state.pendingScrollResolve;
1348
- state.pendingScrollResolve = void 0;
1349
- const scrollingTo = state.scrollingTo;
1350
- state.scrollHistory.length = 0;
1351
- state.scrollingTo = void 0;
1352
- state.scrollTargetPinnedRange = void 0;
1353
- if (state.pendingTotalSize !== void 0) {
1354
- addTotalSize(ctx, null, state.pendingTotalSize);
1355
- }
1356
- if (PlatformAdjustBreaksScroll) {
1357
- state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
1358
- }
1359
- if (scrollingTo.isInitialScroll || state.initialScroll) {
1360
- const isOffsetSession = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset";
1361
- const shouldPreserveResizeTarget = !!scrollingTo.isInitialScroll && !state.clearPreservedInitialScrollOnNextFinish && state.props.data.length > 0 && ((_b = state.initialScroll) == null ? void 0 : _b.viewPosition) === 1;
1362
- finishInitialScroll(ctx, {
1363
- onFinished: () => {
1364
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1365
- },
1366
- preserveTarget: isOffsetSession && state.props.data.length === 0 || shouldPreserveResizeTarget,
1367
- recalculateItems: true,
1368
- schedulePreservedTargetClear: shouldPreserveResizeTarget,
1369
- syncObservedOffset: isOffsetSession,
1370
- waitForCompletionFrame: !!scrollingTo.waitForInitialScrollCompletionFrame
1371
- });
1372
- return;
1373
- }
1374
- recalculateSettledScroll(ctx);
1375
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1376
- }
1377
- }
1378
-
1379
- // src/core/checkFinishedScroll.ts
1380
- var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
1381
- var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
1382
- var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
1383
- var SILENT_INITIAL_SCROLL_RETRY_DELAY_MS = 16;
1384
- var SILENT_INITIAL_SCROLL_TARGET_EPSILON = 1;
1385
- function checkFinishedScroll(ctx, options) {
1386
- const scrollingTo = ctx.state.scrollingTo;
1387
- if (options == null ? void 0 : options.onlyIfAligned) {
1388
- if (!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || scrollingTo.animated) {
1389
- return;
1390
- }
1391
- if (!getResolvedScrollCompletionState(ctx, scrollingTo).isAtResolvedTarget) {
1392
- return;
1393
- }
1394
- }
1395
- ctx.state.scheduledWork.frame(() => checkFinishedScrollFrame(ctx), "checkFinishedScrollFrame");
1396
- }
1397
- function hasScrollCompletionOwnership(state, options) {
1398
- const { clampedTargetOffset, scrollingTo } = options;
1399
- return !scrollingTo.isInitialScroll || state.hasScrolled || clampedTargetOffset <= INITIAL_SCROLL_COMPLETION_TARGET_EPSILON;
1400
- }
1401
- function isSilentInitialDispatch(state, scrollingTo) {
1402
- return !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled;
1403
- }
1404
- function getInitialScrollWatchdogTargetOffset(state) {
1405
- var _a3;
1406
- return (_a3 = initialScrollWatchdog.get(state)) == null ? void 0 : _a3.targetOffset;
1407
- }
1408
- function isNativeInitialNonZeroTarget(state) {
1409
- const targetOffset = getInitialScrollWatchdogTargetOffset(state);
1410
- return !state.didFinishInitialScroll && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
1411
- }
1412
- function shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) {
1413
- var _a3, _b;
1414
- if (!scrollingTo.isInitialScroll || scrollingTo.animated || !state.didContainersLayout) {
1415
- return false;
1416
- }
1417
- if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap") {
1418
- return false;
1419
- }
1420
- const targetOffset = (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset;
1421
- if (initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled) {
1422
- return false;
1423
- }
1424
- if (initialScrollWatchdog.isAtZeroTargetOffset(targetOffset) || Math.abs(state.scroll - targetOffset) > 1 || Math.abs(state.scrollPending - targetOffset) > 1) {
1425
- return false;
1426
- }
1427
- return !!scrollingTo.waitForInitialScrollCompletionFrame || isNativeInitialNonZeroTarget(state);
1428
- }
1429
- function shouldFinishInitialZeroTargetScroll(ctx) {
1430
- var _a3;
1431
- const { state } = ctx;
1432
- return !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) && state.props.data.length > 0 && getContentSize(ctx) <= state.scrollLength && state.scrollPending <= INITIAL_SCROLL_ZERO_TARGET_EPSILON;
1433
- }
1434
- function isEndAlignedLastItemTarget(ctx, scrollingTo) {
1435
- return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
1436
- }
1437
- function getCurrentTargetOffset(ctx, scrollingTo) {
1438
- var _a3;
1439
- const index = scrollingTo.index;
1440
- const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
1441
- const requestedTargetOffset = shouldRecomputeEndTarget && index !== void 0 ? calculateOffsetWithOffsetPosition(ctx, calculateOffsetForIndex(ctx, index), scrollingTo) : (_a3 = scrollingTo.targetOffset) != null ? _a3 : clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0), scrollingTo);
1442
- return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
1443
- }
1444
- function getResolvedScrollCompletionState(ctx, scrollingTo) {
1445
- const { state } = ctx;
1446
- const scroll = state.scrollPending;
1447
- const adjust = state.scrollAdjustHandler.getAdjust();
1448
- const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
1449
- const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
1450
- const diff1 = Math.abs(scroll - clampedTargetOffset);
1451
- const adjustedTargetOffset = clampedTargetOffset + adjust;
1452
- const diff2 = Math.abs(scroll - adjustedTargetOffset);
1453
- const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
1454
- return {
1455
- clampedTargetOffset,
1456
- isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
1457
- };
1458
- }
1459
- function checkFinishedScrollFrame(ctx) {
1460
- const scrollingTo = ctx.state.scrollingTo;
1461
- if (!scrollingTo) {
1462
- return;
1463
- }
1464
- const { state } = ctx;
1465
- const completionState = getResolvedScrollCompletionState(ctx, scrollingTo);
1466
- if (completionState.isAtResolvedTarget && hasScrollCompletionOwnership(state, {
1467
- clampedTargetOffset: completionState.clampedTargetOffset,
1468
- scrollingTo
1469
- })) {
1470
- finishScrollTo(ctx);
1471
- }
1472
- }
1473
- function scrollToFallbackOffset(ctx, offset) {
1474
- var _a3;
1475
- (_a3 = ctx.state.refScroller.current) == null ? void 0 : _a3.scrollTo({
1476
- animated: false,
1477
- x: ctx.state.props.horizontal ? offset : 0,
1478
- y: ctx.state.props.horizontal ? 0 : offset
1479
- });
1480
- }
1481
- function checkFinishedScrollFallback(ctx) {
1482
- const state = ctx.state;
1483
- if (state.scheduledWork.has("checkFinishedScrollFallback")) {
1484
- return;
1485
- }
1486
- const scrollingTo = state.scrollingTo;
1487
- const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
1488
- const silentInitialDispatch = isSilentInitialDispatch(state, scrollingTo);
1489
- const canFinishInitialWithoutNativeProgress = scrollingTo !== void 0 ? shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) : false;
1490
- const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget && !canFinishInitialWithoutNativeProgress || !state.didContainersLayout;
1491
- const initialDelay = shouldFinishInitialZeroTarget || canFinishInitialWithoutNativeProgress ? 0 : silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : slowTimeout ? 500 : 100;
1492
- let numChecks = 0;
1493
- const scheduleFallbackCheck = (delay) => {
1494
- state.scheduledWork.timeout(checkHasScrolled, delay, "checkFinishedScrollFallback");
1495
- };
1496
- const checkHasScrolled = () => {
1497
- var _a3, _b, _c, _d;
1498
- const isStillScrollingTo = state.scrollingTo;
1499
- if (isStillScrollingTo) {
1500
- numChecks++;
1501
- const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
1502
- const maxChecks = silentInitialDispatch ? 5 : isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
1503
- const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
1504
- const canFinishInitialScrollWithoutNativeProgress = shouldFinishInitialScrollWithoutNativeProgress(
1505
- state,
1506
- isStillScrollingTo
1507
- );
1508
- const completionState = getResolvedScrollCompletionState(ctx, isStillScrollingTo);
1509
- const canFinishAfterSilentNativeDispatch = Platform.OS === "android" && silentInitialDispatch && completionState.isAtResolvedTarget && numChecks >= 1;
1510
- const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
1511
- const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
1512
- const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
1513
- const shouldRetryUnalignedEndScroll = Platform.OS === "ios" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
1514
- if (shouldRetrySilentInitialNativeScroll) {
1515
- const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
1516
- const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
1517
- initialScrollCompletion.markSilentInitialScrollRetry(state);
1518
- scrollToFallbackOffset(ctx, jiggleOffset);
1519
- state.scheduledWork.frame(
1520
- () => scrollToFallbackOffset(ctx, targetOffset),
1521
- "checkFinishedScrollRetryFrame"
1522
- );
1523
- scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
1524
- } else if (shouldRetryUnalignedEndScroll) {
1525
- scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
1526
- scheduleFallbackCheck(100);
1527
- } else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
1528
- finishScrollTo(ctx);
1529
- } else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
1530
- const targetOffset = (_d = (_c = getInitialScrollWatchdogTargetOffset(state)) != null ? _c : isStillScrollingTo.targetOffset) != null ? _d : state.scrollPending;
1531
- scrollToFallbackOffset(ctx, targetOffset);
1532
- scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
1533
- } else {
1534
- scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
1535
- }
1536
- }
1537
- };
1538
- scheduleFallbackCheck(initialDelay);
1539
- }
1540
-
1541
- // src/core/doScrollTo.native.ts
1542
- function doScrollTo(ctx, params) {
1543
- const state = ctx.state;
1544
- const { animated, horizontal, isInitialScroll, offset } = params;
1545
- const isAnimated = !!animated;
1546
- const { refScroller } = state;
1547
- const scroller = refScroller.current;
1548
- if (!scroller) {
1549
- return;
1550
- }
1551
- const isHorizontal = !!horizontal;
1552
- const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
1553
- const nativeOffset = toNativeHorizontalOffset(state, offset, contentSize);
1554
- scroller.scrollTo({
1555
- animated: isAnimated,
1556
- x: isHorizontal ? nativeOffset : 0,
1557
- y: isHorizontal ? 0 : offset
1558
- });
1559
- if (isInitialScroll) {
1560
- initialScrollCompletion.markInitialScrollNativeDispatch(state);
1561
- }
1562
- if (isAnimated && Math.abs(state.scroll - offset) <= 1) {
1563
- checkFinishedScroll(ctx);
1564
- }
1565
- if (!isAnimated) {
1566
- state.scroll = offset;
1567
- checkFinishedScrollFallback(ctx);
1568
- }
1569
- }
1570
-
1571
1346
  // src/core/scrollRequestTracker.ts
1572
1347
  function getScrollRequestTracker(ctx) {
1573
1348
  if (!ctx.scrollRequestTracker) {
1574
1349
  let currentToken = 0;
1575
- const start = (resolve) => {
1350
+ let waitingToken;
1351
+ const start = (resolve, isInternal = false) => {
1576
1352
  const state = ctx.state;
1353
+ if (!isInternal && (state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd)) {
1354
+ finishMaintainScrollAtEnd(ctx);
1355
+ }
1577
1356
  state.scheduledWork.cancel("imperativeScrollReady");
1578
1357
  const token = ++currentToken;
1579
1358
  settlePendingImperativeScroll(state);
1580
1359
  state.pendingScrollResolve = resolve;
1360
+ waitingToken = token;
1581
1361
  return token;
1582
1362
  };
1583
1363
  const runNow = (token, resolve, run) => {
@@ -1585,6 +1365,7 @@ function getScrollRequestTracker(ctx) {
1585
1365
  if (token !== currentToken) {
1586
1366
  return;
1587
1367
  }
1368
+ waitingToken = void 0;
1588
1369
  const didStartScroll = run();
1589
1370
  if (!didStartScroll || !state.scrollingTo) {
1590
1371
  if (state.pendingScrollResolve === resolve) {
@@ -1595,6 +1376,7 @@ function getScrollRequestTracker(ctx) {
1595
1376
  };
1596
1377
  ctx.scrollRequestTracker = {
1597
1378
  isCurrent: (token) => token === currentToken,
1379
+ isWaitingToRun: () => waitingToken === currentToken && !!ctx.state.pendingScrollResolve,
1598
1380
  runNow,
1599
1381
  runNowIfIdle: (run) => {
1600
1382
  const state = ctx.state;
@@ -1602,7 +1384,7 @@ function getScrollRequestTracker(ctx) {
1602
1384
  return Promise.resolve();
1603
1385
  }
1604
1386
  return new Promise((resolve) => {
1605
- const token = start(resolve);
1387
+ const token = start(resolve, true);
1606
1388
  runNow(token, resolve, run);
1607
1389
  });
1608
1390
  },
@@ -1666,96 +1448,15 @@ function requestAdjust(ctx, positionDiff, source) {
1666
1448
  }
1667
1449
  }
1668
1450
 
1669
- // src/core/doMaintainScrollAtEnd.ts
1670
- function finishMaintainScrollAtEnd(ctx) {
1671
- var _a3;
1672
- const { state } = ctx;
1673
- const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
1674
- const nextPadding = getAlignItemsAtEndPadding(ctx);
1675
- state.maintainingScrollAtEnd = void 0;
1676
- state.pendingMaintainScrollAtEnd = false;
1677
- if (currentPadding !== nextPadding) {
1678
- set$(ctx, "alignItemsAtEndPadding", nextPadding);
1679
- state.scrollForNextCalculateItemsInView = void 0;
1680
- (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
1681
- const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
1682
- requestAdjust(ctx, nextScroll - state.scroll);
1683
- }
1684
- }
1685
- function doMaintainScrollAtEnd(ctx) {
1686
- const state = ctx.state;
1687
- const {
1688
- didContainersLayout,
1689
- didFinishInitialScroll,
1690
- pendingNativeMVCPAdjust,
1691
- props: { maintainScrollAtEnd }
1692
- } = state;
1693
- const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1694
- const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
1695
- const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
1696
- if (shouldMaintainScrollAtEnd && !didContainersLayout) {
1697
- state.pendingMaintainScrollAtEnd = true;
1698
- return false;
1699
- }
1700
- if (pendingNativeMVCPAdjust) {
1701
- state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
1702
- return false;
1703
- }
1704
- if (shouldMaintainScrollAtEnd && didContainersLayout) {
1705
- state.pendingMaintainScrollAtEnd = false;
1706
- const contentSize = getContentSize(ctx);
1707
- if (contentSize < state.scrollLength) {
1708
- state.scroll = 0;
1709
- }
1710
- if (!state.maintainingScrollAtEnd) {
1711
- const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1712
- const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
1713
- const scrollAtRequest = state.scroll;
1714
- state.maintainingScrollAtEnd = pendingState;
1715
- requestAnimationFrame(() => {
1716
- if (state.maintainingScrollAtEnd !== pendingState) {
1717
- return;
1718
- }
1719
- const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1720
- const didScrollSinceRequest = state.scroll !== scrollAtRequest;
1721
- if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
1722
- state.maintainingScrollAtEnd = activeState;
1723
- const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
1724
- () => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
1725
- );
1726
- void scrollPromise.then(() => {
1727
- if (state.maintainingScrollAtEnd !== activeState) {
1728
- return;
1729
- }
1730
- if (state.pendingMaintainScrollAtEnd) {
1731
- state.maintainingScrollAtEnd = void 0;
1732
- doMaintainScrollAtEnd(ctx);
1733
- } else {
1734
- finishMaintainScrollAtEnd(ctx);
1735
- }
1736
- });
1737
- } else if (state.maintainingScrollAtEnd === pendingState) {
1738
- finishMaintainScrollAtEnd(ctx);
1739
- }
1740
- });
1741
- } else {
1742
- state.pendingMaintainScrollAtEnd = true;
1743
- }
1744
- return true;
1745
- }
1746
- finishMaintainScrollAtEnd(ctx);
1747
- return false;
1748
- }
1749
-
1750
- // src/core/mvcp.ts
1751
- var MVCP_POSITION_EPSILON = 0.1;
1752
- var MVCP_ANCHOR_LOCK_TTL_MS = 300;
1753
- var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
1754
- var NATIVE_END_CLAMP_EPSILON = 1;
1755
- function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
1756
- if (!enableMVCPAnchorLock) {
1757
- state.mvcpAnchorLock = void 0;
1758
- return void 0;
1451
+ // src/core/mvcp.ts
1452
+ var MVCP_POSITION_EPSILON = 0.1;
1453
+ var MVCP_ANCHOR_LOCK_TTL_MS = 300;
1454
+ var MVCP_ANCHOR_LOCK_QUIET_PASSES_TO_RELEASE = 2;
1455
+ var NATIVE_END_CLAMP_EPSILON = 1;
1456
+ function resolveAnchorLock(state, enableMVCPAnchorLock, mvcpData, now) {
1457
+ if (!enableMVCPAnchorLock) {
1458
+ state.mvcpAnchorLock = void 0;
1459
+ return void 0;
1759
1460
  }
1760
1461
  const lock = state.mvcpAnchorLock;
1761
1462
  if (!lock) {
@@ -2045,144 +1746,494 @@ function prepareMVCP(ctx, dataChanged, adjustmentSource) {
2045
1746
  };
2046
1747
  }
2047
1748
  }
2048
-
2049
- // src/platform/flushSync.native.ts
2050
- var flushSync = (fn) => {
2051
- fn();
2052
- };
2053
-
2054
- // src/utils/getScrollVelocity.ts
2055
- var MAX_SCROLL_VELOCITY_WINDOW_MS = 1e3;
2056
- var SCROLL_VELOCITY_HALF_LIFE_MS = 200;
2057
- var getScrollVelocity = (state) => {
2058
- const { scrollHistory } = state;
2059
- const newestIndex = scrollHistory.length - 1;
2060
- if (newestIndex < 1) {
2061
- return 0;
2062
- }
2063
- const newest = scrollHistory[newestIndex];
2064
- if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
2065
- return 0;
1749
+
1750
+ // src/platform/flushSync.native.ts
1751
+ var flushSync = (fn) => {
1752
+ fn();
1753
+ };
1754
+
1755
+ // src/utils/getScrollVelocity.ts
1756
+ var MAX_SCROLL_VELOCITY_WINDOW_MS = 1e3;
1757
+ var SCROLL_VELOCITY_HALF_LIFE_MS = 200;
1758
+ var getScrollVelocity = (state) => {
1759
+ const { scrollHistory } = state;
1760
+ const newestIndex = scrollHistory.length - 1;
1761
+ if (newestIndex < 1) {
1762
+ return 0;
1763
+ }
1764
+ const newest = scrollHistory[newestIndex];
1765
+ if (Date.now() - newest.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
1766
+ return 0;
1767
+ }
1768
+ let direction = 0;
1769
+ let weightedVelocity = 0;
1770
+ let totalWeight = 0;
1771
+ for (let i = newestIndex; i > 0; i--) {
1772
+ const current = scrollHistory[i];
1773
+ const previous = scrollHistory[i - 1];
1774
+ const scrollDiff = current.scroll - previous.scroll;
1775
+ const timeDiff = current.time - previous.time;
1776
+ const deltaSign = Math.sign(scrollDiff);
1777
+ if (deltaSign !== 0) {
1778
+ if (direction === 0) {
1779
+ direction = deltaSign;
1780
+ } else if (deltaSign !== direction) {
1781
+ break;
1782
+ }
1783
+ }
1784
+ if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
1785
+ break;
1786
+ }
1787
+ if (scrollDiff === 0 || timeDiff <= 0) {
1788
+ continue;
1789
+ }
1790
+ const age = newest.time - current.time;
1791
+ const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
1792
+ weightedVelocity += scrollDiff / timeDiff * weight;
1793
+ totalWeight += weight;
1794
+ }
1795
+ return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
1796
+ };
1797
+
1798
+ // src/utils/isInMVCPActiveMode.native.ts
1799
+ function isInMVCPActiveMode(state) {
1800
+ return state.dataChangeNeedsScrollUpdate;
1801
+ }
1802
+
1803
+ // src/core/updateScroll.ts
1804
+ function updateScroll(ctx, newScroll, forceUpdate, options) {
1805
+ var _a3;
1806
+ const state = ctx.state;
1807
+ const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
1808
+ const prevScroll = state.scroll;
1809
+ if ((options == null ? void 0 : options.markHasScrolled) !== false) {
1810
+ state.hasScrolled = true;
1811
+ }
1812
+ const currentTime = Date.now();
1813
+ state.lastBatchingAction = currentTime;
1814
+ const adjust = scrollAdjustHandler.getAdjust();
1815
+ const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1816
+ if (adjustChanged) {
1817
+ scrollHistory.length = 0;
1818
+ }
1819
+ state.lastScrollAdjustForHistory = adjust;
1820
+ if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
1821
+ if (!adjustChanged) {
1822
+ scrollHistory.push({ scroll: newScroll, time: currentTime });
1823
+ }
1824
+ }
1825
+ if (scrollHistory.length > 5) {
1826
+ scrollHistory.shift();
1827
+ }
1828
+ if (ignoreScrollFromMVCP && !scrollingTo) {
1829
+ const { lt, gt } = ignoreScrollFromMVCP;
1830
+ if (lt && newScroll < lt || gt && newScroll > gt) {
1831
+ state.ignoreScrollFromMVCPIgnored = true;
1832
+ return;
1833
+ }
1834
+ }
1835
+ state.scrollPrev = prevScroll;
1836
+ state.scrollPrevTime = state.scrollTime;
1837
+ state.scroll = newScroll;
1838
+ state.scrollTime = currentTime;
1839
+ const scrollDelta = Math.abs(newScroll - prevScroll);
1840
+ const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
1841
+ const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
1842
+ if (didCancelMaintainScrollAtEnd) {
1843
+ finishMaintainScrollAtEnd(ctx);
1844
+ }
1845
+ const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
1846
+ const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
1847
+ const scrollLength = state.scrollLength;
1848
+ const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
1849
+ const scrollVelocity = getScrollVelocity(state);
1850
+ updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
1851
+ const lastCalculated = state.scrollLastCalculate;
1852
+ const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
1853
+ const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
1854
+ if (shouldUpdate) {
1855
+ state.scrollLastCalculate = state.scroll;
1856
+ state.ignoreScrollFromMVCPIgnored = false;
1857
+ state.lastScrollDelta = scrollDelta;
1858
+ const runCalculateItems = () => {
1859
+ var _a4;
1860
+ const calculateItemsParams = {
1861
+ doMVCP: scrollingTo !== void 0,
1862
+ scrollVelocity
1863
+ };
1864
+ if (isLargeUserScrollJump) {
1865
+ calculateItemsParams.drawDistanceMode = "visible-first";
1866
+ }
1867
+ (_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
1868
+ checkThresholds(ctx, allowedEdge);
1869
+ };
1870
+ if (isLargeUserScrollJump) {
1871
+ state.mvcpAnchorLock = void 0;
1872
+ state.pendingNativeMVCPAdjust = void 0;
1873
+ state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
1874
+ state.scheduledWork.cancel("mvcpRecalculate");
1875
+ flushSync(runCalculateItems);
1876
+ scheduleFullDrawDistancePrewarm(ctx);
1877
+ } else {
1878
+ runCalculateItems();
1879
+ }
1880
+ const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
1881
+ if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
1882
+ state.pendingMaintainScrollAtEnd = false;
1883
+ doMaintainScrollAtEnd(ctx);
1884
+ }
1885
+ state.dataChangeNeedsScrollUpdate = false;
1886
+ state.lastScrollDelta = 0;
1887
+ }
1888
+ }
1889
+
1890
+ // src/core/doMaintainScrollAtEnd.ts
1891
+ function interruptMaintainScrollAtEnd(ctx) {
1892
+ var _a3;
1893
+ const { state } = ctx;
1894
+ const maintaining = state.maintainingScrollAtEnd;
1895
+ const cancelActiveScroll = !!(maintaining === "animated" || maintaining === "instant" || maintaining && ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isScrollToEnd));
1896
+ if (cancelActiveScroll) {
1897
+ cancelImperativeScroll(state);
1898
+ }
1899
+ if (maintaining || state.pendingMaintainScrollAtEnd) {
1900
+ finishMaintainScrollAtEnd(ctx);
1901
+ }
1902
+ return cancelActiveScroll;
1903
+ }
1904
+ function finishMaintainScrollAtEnd(ctx) {
1905
+ var _a3;
1906
+ const { state } = ctx;
1907
+ const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
1908
+ const nextPadding = getAlignItemsAtEndPadding(ctx);
1909
+ state.maintainingScrollAtEnd = void 0;
1910
+ state.pendingMaintainScrollAtEnd = false;
1911
+ if (currentPadding !== nextPadding) {
1912
+ set$(ctx, "alignItemsAtEndPadding", nextPadding);
1913
+ state.scrollForNextCalculateItemsInView = void 0;
1914
+ (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
1915
+ const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
1916
+ requestAdjust(ctx, nextScroll - state.scroll);
1917
+ }
1918
+ }
1919
+ function doMaintainScrollAtEnd(ctx) {
1920
+ var _a3, _b, _c, _d, _e;
1921
+ const state = ctx.state;
1922
+ const {
1923
+ didContainersLayout,
1924
+ didFinishInitialScroll,
1925
+ pendingNativeMVCPAdjust,
1926
+ props: { maintainScrollAtEnd }
1927
+ } = state;
1928
+ const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1929
+ const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
1930
+ const shouldMaintainScrollAtEnd = !!(!((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) && (!state.scrollingTo || state.scrollingTo.isScrollToEnd) && (isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain || ((_b = state.scrollingTo) == null ? void 0 : _b.isScrollToEnd)) && maintainScrollAtEnd && didFinishInitialScroll);
1931
+ if (shouldMaintainScrollAtEnd && !state.scrollingTo) {
1932
+ const scroller = state.refScroller.current;
1933
+ const nativeMax = (_c = scroller == null ? void 0 : scroller.getMaxScrollOffset) == null ? void 0 : _c.call(scroller);
1934
+ const observed = (_d = scroller == null ? void 0 : scroller.getCurrentScrollOffset) == null ? void 0 : _d.call(scroller);
1935
+ if (nativeMax !== void 0 && observed !== void 0 && nativeMax < state.scroll - 1 && Math.abs(observed - nativeMax) <= 1) {
1936
+ state.pendingMaintainScrollAtEnd = true;
1937
+ state.scrollPending = observed;
1938
+ updateScroll(ctx, observed, true, { markHasScrolled: false });
1939
+ }
1940
+ }
1941
+ if (shouldMaintainScrollAtEnd && !didContainersLayout) {
1942
+ state.pendingMaintainScrollAtEnd = true;
1943
+ return false;
1944
+ }
1945
+ if (pendingNativeMVCPAdjust) {
1946
+ state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
1947
+ return false;
1948
+ }
1949
+ if (shouldMaintainScrollAtEnd && (state.scrollingTo || state.pendingScrollResolve)) {
1950
+ state.pendingMaintainScrollAtEnd = true;
1951
+ (_e = state.maintainingScrollAtEnd) != null ? _e : state.maintainingScrollAtEnd = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1952
+ return false;
1953
+ }
1954
+ if (shouldMaintainScrollAtEnd && didContainersLayout) {
1955
+ state.pendingMaintainScrollAtEnd = false;
1956
+ const contentSize = getContentSize(ctx);
1957
+ if (contentSize < state.scrollLength) {
1958
+ state.scroll = 0;
1959
+ }
1960
+ if (!state.maintainingScrollAtEnd) {
1961
+ const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
1962
+ const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
1963
+ const scrollAtRequest = state.scroll;
1964
+ state.maintainingScrollAtEnd = pendingState;
1965
+ requestAnimationFrame(() => {
1966
+ if (state.maintainingScrollAtEnd !== pendingState) {
1967
+ return;
1968
+ }
1969
+ const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
1970
+ const didScrollSinceRequest = state.scroll !== scrollAtRequest;
1971
+ if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
1972
+ if (state.scrollingTo || state.pendingScrollResolve) {
1973
+ state.pendingMaintainScrollAtEnd = true;
1974
+ return;
1975
+ }
1976
+ state.maintainingScrollAtEnd = activeState;
1977
+ const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
1978
+ () => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
1979
+ );
1980
+ void scrollPromise.then(() => {
1981
+ if (state.maintainingScrollAtEnd !== activeState) {
1982
+ return;
1983
+ }
1984
+ if (state.pendingMaintainScrollAtEnd) {
1985
+ state.maintainingScrollAtEnd = void 0;
1986
+ doMaintainScrollAtEnd(ctx);
1987
+ } else {
1988
+ finishMaintainScrollAtEnd(ctx);
1989
+ }
1990
+ });
1991
+ } else if (state.maintainingScrollAtEnd === pendingState) {
1992
+ finishMaintainScrollAtEnd(ctx);
1993
+ }
1994
+ });
1995
+ } else {
1996
+ state.pendingMaintainScrollAtEnd = true;
1997
+ }
1998
+ return true;
1999
+ }
2000
+ finishMaintainScrollAtEnd(ctx);
2001
+ return false;
2002
+ }
2003
+
2004
+ // src/core/finishScrollTo.ts
2005
+ function finishScrollTo(ctx) {
2006
+ var _a3, _b, _c;
2007
+ const state = ctx.state;
2008
+ if (state == null ? void 0 : state.scrollingTo) {
2009
+ cancelScrollCompletionChecks(state);
2010
+ const resolvePendingScroll = ((_a3 = ctx.scrollRequestTracker) == null ? void 0 : _a3.isWaitingToRun()) ? void 0 : state.pendingScrollResolve;
2011
+ if (resolvePendingScroll) {
2012
+ state.pendingScrollResolve = void 0;
2013
+ }
2014
+ const scrollingTo = state.scrollingTo;
2015
+ state.scrollHistory.length = 0;
2016
+ state.scrollingTo = void 0;
2017
+ state.scrollTargetPinnedRange = void 0;
2018
+ if (state.pendingTotalSize !== void 0) {
2019
+ addTotalSize(ctx, null, state.pendingTotalSize);
2020
+ }
2021
+ if (PlatformAdjustBreaksScroll) {
2022
+ state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
2023
+ }
2024
+ if (scrollingTo.isInitialScroll || state.initialScroll) {
2025
+ const isOffsetSession = ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) === "offset";
2026
+ const shouldPreserveResizeTarget = !!scrollingTo.isInitialScroll && !state.clearPreservedInitialScrollOnNextFinish && state.props.data.length > 0 && ((_c = state.initialScroll) == null ? void 0 : _c.viewPosition) === 1;
2027
+ finishInitialScroll(ctx, {
2028
+ onFinished: () => {
2029
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
2030
+ },
2031
+ preserveTarget: isOffsetSession && state.props.data.length === 0 || shouldPreserveResizeTarget,
2032
+ recalculateItems: true,
2033
+ schedulePreservedTargetClear: shouldPreserveResizeTarget,
2034
+ syncObservedOffset: isOffsetSession,
2035
+ waitForCompletionFrame: !!scrollingTo.waitForInitialScrollCompletionFrame
2036
+ });
2037
+ return;
2038
+ }
2039
+ recalculateSettledScroll(ctx);
2040
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
2041
+ if (state.pendingMaintainScrollAtEnd) {
2042
+ state.maintainingScrollAtEnd = void 0;
2043
+ doMaintainScrollAtEnd(ctx);
2044
+ }
2045
+ }
2046
+ }
2047
+
2048
+ // src/core/checkFinishedScroll.ts
2049
+ var INITIAL_SCROLL_MAX_FALLBACK_CHECKS = 20;
2050
+ var INITIAL_SCROLL_COMPLETION_TARGET_EPSILON = 1;
2051
+ var INITIAL_SCROLL_ZERO_TARGET_EPSILON = 1;
2052
+ var SILENT_INITIAL_SCROLL_RETRY_DELAY_MS = 16;
2053
+ var SILENT_INITIAL_SCROLL_TARGET_EPSILON = 1;
2054
+ function checkFinishedScroll(ctx, options) {
2055
+ const scrollingTo = ctx.state.scrollingTo;
2056
+ if (options == null ? void 0 : options.onlyIfAligned) {
2057
+ if (!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || scrollingTo.animated) {
2058
+ return;
2059
+ }
2060
+ if (!getResolvedScrollCompletionState(ctx, scrollingTo).isAtResolvedTarget) {
2061
+ return;
2062
+ }
2063
+ }
2064
+ ctx.state.scheduledWork.frame(() => checkFinishedScrollFrame(ctx), "checkFinishedScrollFrame");
2065
+ }
2066
+ function hasScrollCompletionOwnership(state, options) {
2067
+ const { clampedTargetOffset, scrollingTo } = options;
2068
+ return !scrollingTo.isInitialScroll || state.hasScrolled || clampedTargetOffset <= INITIAL_SCROLL_COMPLETION_TARGET_EPSILON;
2069
+ }
2070
+ function isSilentInitialDispatch(state, scrollingTo) {
2071
+ return !!(scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled;
2072
+ }
2073
+ function getInitialScrollWatchdogTargetOffset(state) {
2074
+ var _a3;
2075
+ return (_a3 = initialScrollWatchdog.get(state)) == null ? void 0 : _a3.targetOffset;
2076
+ }
2077
+ function isNativeInitialNonZeroTarget(state) {
2078
+ const targetOffset = getInitialScrollWatchdogTargetOffset(state);
2079
+ return !state.didFinishInitialScroll && initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset);
2080
+ }
2081
+ function shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) {
2082
+ var _a3, _b;
2083
+ if (!scrollingTo.isInitialScroll || scrollingTo.animated || !state.didContainersLayout) {
2084
+ return false;
2085
+ }
2086
+ if (((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap") {
2087
+ return false;
2088
+ }
2089
+ const targetOffset = (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset;
2090
+ if (initialScrollWatchdog.hasNonZeroTargetOffset(targetOffset) && initialScrollCompletion.didDispatchNativeScroll(state) && !state.hasScrolled) {
2091
+ return false;
2092
+ }
2093
+ if (initialScrollWatchdog.isAtZeroTargetOffset(targetOffset) || Math.abs(state.scroll - targetOffset) > 1 || Math.abs(state.scrollPending - targetOffset) > 1) {
2094
+ return false;
2095
+ }
2096
+ return !!scrollingTo.waitForInitialScrollCompletionFrame || isNativeInitialNonZeroTarget(state);
2097
+ }
2098
+ function shouldFinishInitialZeroTargetScroll(ctx) {
2099
+ var _a3;
2100
+ const { state } = ctx;
2101
+ return !!((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) && state.props.data.length > 0 && getContentSize(ctx) <= state.scrollLength && state.scrollPending <= INITIAL_SCROLL_ZERO_TARGET_EPSILON;
2102
+ }
2103
+ function isEndAlignedLastItemTarget(ctx, scrollingTo) {
2104
+ return scrollingTo.index === ctx.state.props.data.length - 1 && scrollingTo.viewPosition === 1;
2105
+ }
2106
+ function getCurrentTargetOffset(ctx, scrollingTo) {
2107
+ var _a3;
2108
+ const index = scrollingTo.index;
2109
+ const shouldRecomputeEndTarget = isEndAlignedLastItemTarget(ctx, scrollingTo);
2110
+ const requestedTargetOffset = shouldRecomputeEndTarget && index !== void 0 ? calculateOffsetWithOffsetPosition(ctx, calculateOffsetForIndex(ctx, index), scrollingTo) : (_a3 = scrollingTo.targetOffset) != null ? _a3 : clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0), scrollingTo);
2111
+ return clampScrollOffset(ctx, requestedTargetOffset, scrollingTo);
2112
+ }
2113
+ function getResolvedScrollCompletionState(ctx, scrollingTo) {
2114
+ const { state } = ctx;
2115
+ const scroll = state.scrollPending;
2116
+ const adjust = state.scrollAdjustHandler.getAdjust();
2117
+ const clampedTargetOffset = getCurrentTargetOffset(ctx, scrollingTo);
2118
+ const maxOffset = clampScrollOffset(ctx, scroll, scrollingTo);
2119
+ const diff1 = Math.abs(scroll - clampedTargetOffset);
2120
+ const adjustedTargetOffset = clampedTargetOffset + adjust;
2121
+ const diff2 = Math.abs(scroll - adjustedTargetOffset);
2122
+ const canUseAdjustedCompletion = !scrollingTo.animated || Platform.OS === "ios";
2123
+ return {
2124
+ clampedTargetOffset,
2125
+ isAtResolvedTarget: Math.abs(scroll - maxOffset) < 1 && (diff1 < 1 || canUseAdjustedCompletion && diff2 < 1)
2126
+ };
2127
+ }
2128
+ function checkFinishedScrollFrame(ctx) {
2129
+ const scrollingTo = ctx.state.scrollingTo;
2130
+ if (!scrollingTo) {
2131
+ return;
2066
2132
  }
2067
- let direction = 0;
2068
- let weightedVelocity = 0;
2069
- let totalWeight = 0;
2070
- for (let i = newestIndex; i > 0; i--) {
2071
- const current = scrollHistory[i];
2072
- const previous = scrollHistory[i - 1];
2073
- const scrollDiff = current.scroll - previous.scroll;
2074
- const timeDiff = current.time - previous.time;
2075
- const deltaSign = Math.sign(scrollDiff);
2076
- if (deltaSign !== 0) {
2077
- if (direction === 0) {
2078
- direction = deltaSign;
2079
- } else if (deltaSign !== direction) {
2080
- break;
2081
- }
2082
- }
2083
- if (newest.time - previous.time > MAX_SCROLL_VELOCITY_WINDOW_MS) {
2084
- break;
2085
- }
2086
- if (scrollDiff === 0 || timeDiff <= 0) {
2087
- continue;
2088
- }
2089
- const age = newest.time - current.time;
2090
- const weight = Math.exp(-age / SCROLL_VELOCITY_HALF_LIFE_MS);
2091
- weightedVelocity += scrollDiff / timeDiff * weight;
2092
- totalWeight += weight;
2133
+ const { state } = ctx;
2134
+ const completionState = getResolvedScrollCompletionState(ctx, scrollingTo);
2135
+ if (completionState.isAtResolvedTarget && hasScrollCompletionOwnership(state, {
2136
+ clampedTargetOffset: completionState.clampedTargetOffset,
2137
+ scrollingTo
2138
+ })) {
2139
+ finishScrollTo(ctx);
2093
2140
  }
2094
- return totalWeight > 0 ? weightedVelocity / totalWeight : 0;
2095
- };
2096
-
2097
- // src/utils/isInMVCPActiveMode.native.ts
2098
- function isInMVCPActiveMode(state) {
2099
- return state.dataChangeNeedsScrollUpdate;
2100
2141
  }
2101
-
2102
- // src/core/updateScroll.ts
2103
- function updateScroll(ctx, newScroll, forceUpdate, options) {
2142
+ function scrollToFallbackOffset(ctx, offset) {
2104
2143
  var _a3;
2144
+ (_a3 = ctx.state.refScroller.current) == null ? void 0 : _a3.scrollTo({
2145
+ animated: false,
2146
+ x: ctx.state.props.horizontal ? offset : 0,
2147
+ y: ctx.state.props.horizontal ? 0 : offset
2148
+ });
2149
+ }
2150
+ function checkFinishedScrollFallback(ctx) {
2105
2151
  const state = ctx.state;
2106
- const { ignoreScrollFromMVCP, lastScrollAdjustForHistory, scrollAdjustHandler, scrollHistory, scrollingTo } = state;
2107
- const prevScroll = state.scroll;
2108
- if ((options == null ? void 0 : options.markHasScrolled) !== false) {
2109
- state.hasScrolled = true;
2110
- }
2111
- const currentTime = Date.now();
2112
- state.lastBatchingAction = currentTime;
2113
- const adjust = scrollAdjustHandler.getAdjust();
2114
- const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
2115
- if (adjustChanged) {
2116
- scrollHistory.length = 0;
2152
+ if (state.scheduledWork.has("checkFinishedScrollFallback")) {
2153
+ return;
2117
2154
  }
2118
- state.lastScrollAdjustForHistory = adjust;
2119
- if (scrollingTo === void 0 && !(scrollHistory.length === 0 && newScroll === state.scroll)) {
2120
- if (!adjustChanged) {
2121
- scrollHistory.push({ scroll: newScroll, time: currentTime });
2155
+ const scrollingTo = state.scrollingTo;
2156
+ const shouldFinishInitialZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
2157
+ const silentInitialDispatch = isSilentInitialDispatch(state, scrollingTo);
2158
+ const canFinishInitialWithoutNativeProgress = scrollingTo !== void 0 ? shouldFinishInitialScrollWithoutNativeProgress(state, scrollingTo) : false;
2159
+ const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) && !shouldFinishInitialZeroTarget && !canFinishInitialWithoutNativeProgress || !state.didContainersLayout;
2160
+ const initialDelay = shouldFinishInitialZeroTarget || canFinishInitialWithoutNativeProgress ? 0 : silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : slowTimeout ? 500 : 100;
2161
+ let numChecks = 0;
2162
+ const scheduleFallbackCheck = (delay) => {
2163
+ state.scheduledWork.timeout(checkHasScrolled, delay, "checkFinishedScrollFallback");
2164
+ };
2165
+ const checkHasScrolled = () => {
2166
+ var _a3, _b, _c, _d;
2167
+ const isStillScrollingTo = state.scrollingTo;
2168
+ if (isStillScrollingTo) {
2169
+ numChecks++;
2170
+ const isNativeInitialPending = isNativeInitialNonZeroTarget(state) && !state.hasScrolled;
2171
+ const maxChecks = silentInitialDispatch ? 5 : isNativeInitialPending ? INITIAL_SCROLL_MAX_FALLBACK_CHECKS : 5;
2172
+ const shouldFinishZeroTarget = shouldFinishInitialZeroTargetScroll(ctx);
2173
+ const canFinishInitialScrollWithoutNativeProgress = shouldFinishInitialScrollWithoutNativeProgress(
2174
+ state,
2175
+ isStillScrollingTo
2176
+ );
2177
+ const completionState = getResolvedScrollCompletionState(ctx, isStillScrollingTo);
2178
+ const canFinishAfterSilentNativeDispatch = Platform.OS === "android" && silentInitialDispatch && completionState.isAtResolvedTarget && numChecks >= 1;
2179
+ const shouldRetrySilentInitialNativeScroll = Platform.OS === "android" && canFinishAfterSilentNativeDispatch && !initialScrollCompletion.didRetrySilentInitialScroll(state);
2180
+ const shouldFinishAfterObservedScroll = state.hasScrolled && (!isStillScrollingTo.isInitialScroll || completionState.isAtResolvedTarget);
2181
+ const shouldRetryUnalignedInitialScroll = isStillScrollingTo.isInitialScroll && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
2182
+ const shouldRetryUnalignedEndScroll = Platform.OS !== "web" && !isStillScrollingTo.isInitialScroll && isEndAlignedLastItemTarget(ctx, isStillScrollingTo) && !completionState.isAtResolvedTarget && numChecks <= maxChecks;
2183
+ if (shouldRetrySilentInitialNativeScroll) {
2184
+ const targetOffset = (_b = (_a3 = getInitialScrollWatchdogTargetOffset(state)) != null ? _a3 : isStillScrollingTo.targetOffset) != null ? _b : 0;
2185
+ const jiggleOffset = targetOffset >= SILENT_INITIAL_SCROLL_TARGET_EPSILON ? targetOffset - SILENT_INITIAL_SCROLL_TARGET_EPSILON : targetOffset + SILENT_INITIAL_SCROLL_TARGET_EPSILON;
2186
+ initialScrollCompletion.markSilentInitialScrollRetry(state);
2187
+ scrollToFallbackOffset(ctx, jiggleOffset);
2188
+ state.scheduledWork.frame(
2189
+ () => scrollToFallbackOffset(ctx, targetOffset),
2190
+ "checkFinishedScrollRetryFrame"
2191
+ );
2192
+ scheduleFallbackCheck(SILENT_INITIAL_SCROLL_RETRY_DELAY_MS);
2193
+ } else if (shouldRetryUnalignedEndScroll) {
2194
+ scrollToFallbackOffset(ctx, completionState.clampedTargetOffset);
2195
+ scheduleFallbackCheck(100);
2196
+ } else if (shouldFinishZeroTarget || shouldFinishAfterObservedScroll || canFinishInitialScrollWithoutNativeProgress || canFinishAfterSilentNativeDispatch || numChecks > maxChecks) {
2197
+ finishScrollTo(ctx);
2198
+ } else if ((isNativeInitialPending || shouldRetryUnalignedInitialScroll) && numChecks <= maxChecks) {
2199
+ const targetOffset = (_d = (_c = getInitialScrollWatchdogTargetOffset(state)) != null ? _c : isStillScrollingTo.targetOffset) != null ? _d : state.scrollPending;
2200
+ scrollToFallbackOffset(ctx, targetOffset);
2201
+ scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
2202
+ } else {
2203
+ scheduleFallbackCheck(silentInitialDispatch ? SILENT_INITIAL_SCROLL_RETRY_DELAY_MS : 100);
2204
+ }
2122
2205
  }
2206
+ };
2207
+ scheduleFallbackCheck(initialDelay);
2208
+ }
2209
+
2210
+ // src/core/doScrollTo.native.ts
2211
+ function doScrollTo(ctx, params) {
2212
+ const state = ctx.state;
2213
+ const { animated, horizontal, isInitialScroll, offset } = params;
2214
+ const isAnimated = !!animated;
2215
+ const { refScroller } = state;
2216
+ const scroller = refScroller.current;
2217
+ if (!scroller) {
2218
+ return;
2123
2219
  }
2124
- if (scrollHistory.length > 5) {
2125
- scrollHistory.shift();
2126
- }
2127
- if (ignoreScrollFromMVCP && !scrollingTo) {
2128
- const { lt, gt } = ignoreScrollFromMVCP;
2129
- if (lt && newScroll < lt || gt && newScroll > gt) {
2130
- state.ignoreScrollFromMVCPIgnored = true;
2131
- return;
2132
- }
2220
+ const isHorizontal = !!horizontal;
2221
+ const contentSize = isHorizontal ? getContentSize(ctx) : void 0;
2222
+ const nativeOffset = toNativeHorizontalOffset(state, offset, contentSize);
2223
+ scroller.scrollTo({
2224
+ animated: isAnimated,
2225
+ x: isHorizontal ? nativeOffset : 0,
2226
+ y: isHorizontal ? 0 : offset
2227
+ });
2228
+ if (isInitialScroll) {
2229
+ initialScrollCompletion.markInitialScrollNativeDispatch(state);
2133
2230
  }
2134
- state.scrollPrev = prevScroll;
2135
- state.scrollPrevTime = state.scrollTime;
2136
- state.scroll = newScroll;
2137
- state.scrollTime = currentTime;
2138
- const scrollDelta = Math.abs(newScroll - prevScroll);
2139
- const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
2140
- const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
2141
- if (didCancelMaintainScrollAtEnd) {
2142
- finishMaintainScrollAtEnd(ctx);
2231
+ if (isAnimated && Math.abs(state.scroll - offset) <= 1) {
2232
+ checkFinishedScroll(ctx);
2143
2233
  }
2144
- const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
2145
- const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
2146
- const scrollLength = state.scrollLength;
2147
- const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
2148
- const scrollVelocity = getScrollVelocity(state);
2149
- updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
2150
- const lastCalculated = state.scrollLastCalculate;
2151
- const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
2152
- const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
2153
- if (shouldUpdate) {
2154
- state.scrollLastCalculate = state.scroll;
2155
- state.ignoreScrollFromMVCPIgnored = false;
2156
- state.lastScrollDelta = scrollDelta;
2157
- const runCalculateItems = () => {
2158
- var _a4;
2159
- const calculateItemsParams = {
2160
- doMVCP: scrollingTo !== void 0,
2161
- scrollVelocity
2162
- };
2163
- if (isLargeUserScrollJump) {
2164
- calculateItemsParams.drawDistanceMode = "visible-first";
2165
- }
2166
- (_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
2167
- checkThresholds(ctx, allowedEdge);
2168
- };
2169
- if (isLargeUserScrollJump) {
2170
- state.mvcpAnchorLock = void 0;
2171
- state.pendingNativeMVCPAdjust = void 0;
2172
- state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
2173
- state.scheduledWork.cancel("mvcpRecalculate");
2174
- flushSync(runCalculateItems);
2175
- scheduleFullDrawDistancePrewarm(ctx);
2176
- } else {
2177
- runCalculateItems();
2178
- }
2179
- const shouldMaintainScrollAtEndAfterPendingSettle = !!state.pendingMaintainScrollAtEnd || !!((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.onDataChange);
2180
- if (didResolvePendingNativeMVCPAdjust && shouldMaintainScrollAtEndAfterPendingSettle) {
2181
- state.pendingMaintainScrollAtEnd = false;
2182
- doMaintainScrollAtEnd(ctx);
2183
- }
2184
- state.dataChangeNeedsScrollUpdate = false;
2185
- state.lastScrollDelta = 0;
2234
+ if (!isAnimated) {
2235
+ state.scroll = offset;
2236
+ checkFinishedScrollFallback(ctx);
2186
2237
  }
2187
2238
  }
2188
2239
 
@@ -3191,6 +3242,11 @@ function handleInitialScrollDataChange(ctx, options) {
3191
3242
  const state = ctx.state;
3192
3243
  const previousInitialScrollDataLength = (_b = (_a3 = state.initialScrollSession) == null ? void 0 : _a3.previousDataLength) != null ? _b : 0;
3193
3244
  const shouldUseLatestInitialScroll = dataLength > 0 && (!state.hasHadNonEmptyData || didStartFreshData);
3245
+ if (didStartFreshData) {
3246
+ cancelImperativeScroll(state);
3247
+ state.maintainingScrollAtEnd = void 0;
3248
+ state.pendingMaintainScrollAtEnd = false;
3249
+ }
3194
3250
  if (dataLength > 0) {
3195
3251
  state.hasHadNonEmptyData = true;
3196
3252
  }
@@ -4735,6 +4791,7 @@ function maybeUpdateAnchoredEndSpace(ctx) {
4735
4791
  const nextAnchorIndex = anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex;
4736
4792
  let nextAnchorKey;
4737
4793
  let isReady = true;
4794
+ let canUpdateSize = true;
4738
4795
  let nextSize = 0;
4739
4796
  if (anchoredEndSpace) {
4740
4797
  const { anchorIndex, anchorMaxSize, anchorOffset = 0 } = anchoredEndSpace;
@@ -4756,25 +4813,30 @@ function maybeUpdateAnchoredEndSpace(ctx) {
4756
4813
  contentBelowAnchor = Math.max(0, contentBelowAnchor - ctx.scrollAxisGap);
4757
4814
  contentBelowAnchor += (ctx.values.get("footerSize") || 0) + getStylePaddingEnd(state.props);
4758
4815
  isReady = !hasUnknownTailSize;
4759
- nextSize = hasUnknownTailSize ? previousSize || 0 : Math.max(0, state.scrollLength - contentBelowAnchor - anchorOffset);
4816
+ const knownSizeBound = Math.max(0, state.scrollLength - contentBelowAnchor - anchorOffset);
4817
+ nextSize = hasUnknownTailSize ? Math.min(previousSize || 0, knownSizeBound) : knownSizeBound;
4760
4818
  } else if (anchorIndex >= 0) {
4761
4819
  isReady = false;
4820
+ canUpdateSize = false;
4762
4821
  }
4763
4822
  }
4764
4823
  const didSizeChange = previousSize !== nextSize && (previousSize !== void 0 || anchoredEndSpace !== void 0);
4765
4824
  const didEffectiveSizeChange = (previousSize || 0) !== nextSize;
4825
+ const canApplySizeChange = canUpdateSize && (isReady || previousSize !== void 0);
4766
4826
  const didReadyAnchorChange = previousReadyAnchorIndex !== nextAnchorIndex || previousReadyAnchorKey !== nextAnchorKey;
4767
- if (isReady && (didSizeChange || didReadyAnchorChange)) {
4827
+ const didBecomeReady = isReady && state.anchoredEndSpacePendingReady;
4828
+ state.anchoredEndSpacePendingReady = !isReady;
4829
+ if (canApplySizeChange && didSizeChange) {
4830
+ set$(ctx, "anchoredEndSpaceSize", nextSize);
4831
+ (_a3 = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onSizeChanged) == null ? void 0 : _a3.call(anchoredEndSpace, nextSize);
4832
+ }
4833
+ if (canApplySizeChange && didEffectiveSizeChange) {
4834
+ updateContentMetricsState(ctx);
4835
+ updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
4836
+ }
4837
+ if (isReady && (didSizeChange || didReadyAnchorChange || didBecomeReady)) {
4768
4838
  state.anchoredEndSpaceReadyAnchorIndex = nextAnchorIndex;
4769
4839
  state.anchoredEndSpaceReadyAnchorKey = nextAnchorKey;
4770
- if (didSizeChange) {
4771
- set$(ctx, "anchoredEndSpaceSize", nextSize);
4772
- (_a3 = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onSizeChanged) == null ? void 0 : _a3.call(anchoredEndSpace, nextSize);
4773
- }
4774
- if (didEffectiveSizeChange) {
4775
- updateContentMetricsState(ctx);
4776
- updateScroll(ctx, state.scroll, true, { markHasScrolled: false });
4777
- }
4778
4840
  (_b = anchoredEndSpace == null ? void 0 : anchoredEndSpace.onReady) == null ? void 0 : _b.call(anchoredEndSpace, { anchorIndex: nextAnchorIndex, anchorKey: nextAnchorKey, size: nextSize });
4779
4841
  }
4780
4842
  return nextSize;
@@ -6678,6 +6740,9 @@ function scrollToEnd(ctx, options) {
6678
6740
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
6679
6741
  viewPosition: 1
6680
6742
  });
6743
+ if (state.scrollingTo) {
6744
+ state.scrollingTo.isScrollToEnd = true;
6745
+ }
6681
6746
  return true;
6682
6747
  }
6683
6748
 
@@ -7411,6 +7476,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7411
7476
  endReachedSnapshot: void 0,
7412
7477
  firstFullyOnScreenIndex: -1,
7413
7478
  freshDataTransitionEpoch: 0,
7479
+ handledDataChangeEpoch: 0,
7480
+ handledFreshDataTransitionEpoch: 0,
7414
7481
  hasHadNonEmptyData: dataProp.length > 0,
7415
7482
  idCache: [],
7416
7483
  idsInView: [],
@@ -7495,6 +7562,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7495
7562
  if (shouldResetFreshDataLayout) {
7496
7563
  state.freshDataTransitionEpoch += 1;
7497
7564
  }
7565
+ const dataChangeEpoch = state.dataChangeEpoch;
7566
+ const freshDataTransitionEpoch = state.freshDataTransitionEpoch;
7498
7567
  const throttledOnScroll = useThrottledOnScroll(onScrollProp != null ? onScrollProp : noopOnScroll, scrollEventThrottle != null ? scrollEventThrottle : 0);
7499
7568
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? throttledOnScroll : onScrollProp;
7500
7569
  const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((_q = state.props.anchoredEndSpace) == null ? void 0 : _q.anchorIndex) !== (anchoredEndSpace == null ? void 0 : anchoredEndSpace.anchorIndex);
@@ -7622,7 +7691,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7622
7691
  useDevChecks(props);
7623
7692
  }
7624
7693
  React2.useLayoutEffect(() => {
7625
- if (shouldResetFreshDataLayout) {
7694
+ const didDataChange = state.handledDataChangeEpoch !== dataChangeEpoch;
7695
+ const didStartFreshData = state.handledFreshDataTransitionEpoch !== freshDataTransitionEpoch;
7696
+ state.handledDataChangeEpoch = dataChangeEpoch;
7697
+ state.handledFreshDataTransitionEpoch = freshDataTransitionEpoch;
7698
+ if (didStartFreshData) {
7626
7699
  resetInitialRenderState(ctx, {
7627
7700
  resetInitialScroll: !!initialScrollProp,
7628
7701
  resetLayout: true
@@ -7630,8 +7703,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7630
7703
  }
7631
7704
  handleInitialScrollDataChange(ctx, {
7632
7705
  dataLength: dataProp.length,
7633
- didDataChange: didDataChangeLocal,
7634
- didStartFreshData: shouldResetFreshDataLayout,
7706
+ didDataChange,
7707
+ didStartFreshData,
7635
7708
  initialScrollAtEnd,
7636
7709
  latestInitialScroll: initialScrollProp,
7637
7710
  latestInitialScrollSessionKind: initialScrollUsesOffsetOnly ? "offset" : "bootstrap",
@@ -7641,8 +7714,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7641
7714
  }, [
7642
7715
  dataProp.length,
7643
7716
  dataKey,
7644
- didDataChangeLocal,
7645
- shouldResetFreshDataLayout,
7717
+ dataChangeEpoch,
7718
+ freshDataTransitionEpoch,
7646
7719
  initialScrollAtEnd,
7647
7720
  stylePaddingEndState,
7648
7721
  usesBootstrapInitialScroll
@@ -7825,13 +7898,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
7825
7898
  onScroll: (event) => onScroll(ctx, event),
7826
7899
  onScrollBeginDrag: (event) => {
7827
7900
  var _a4, _b2;
7828
- const maintainingScrollAtEnd = state.maintainingScrollAtEnd;
7829
- if (maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant") {
7830
- cancelImperativeScroll(state);
7831
- }
7832
- if (maintainingScrollAtEnd) {
7833
- finishMaintainScrollAtEnd(ctx);
7834
- }
7901
+ interruptMaintainScrollAtEnd(ctx);
7835
7902
  prepareReachedEdgeForNextUserScroll(ctx);
7836
7903
  (_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
7837
7904
  },