@legendapp/list 3.3.4 → 3.3.6
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/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/react-native.js +308 -179
- package/react-native.mjs +308 -179
- package/react-native.web.js +304 -168
- package/react-native.web.mjs +304 -168
- package/react.js +304 -168
- package/react.mjs +304 -168
- package/.DS_Store +0 -0
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;
|
|
@@ -436,6 +432,28 @@ var EDGE_POSITION_EPSILON = 1;
|
|
|
436
432
|
var ENABLE_DEVMODE = IS_DEV && false;
|
|
437
433
|
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
438
434
|
|
|
435
|
+
// src/core/cancelImperativeScroll.ts
|
|
436
|
+
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
437
|
+
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
438
|
+
scheduledWork.cancel("checkFinishedScrollRetryFrame");
|
|
439
|
+
scheduledWork.cancel("checkFinishedScrollFallback");
|
|
440
|
+
scheduledWork.cancel("platformScrollCompletion");
|
|
441
|
+
}
|
|
442
|
+
function settlePendingImperativeScroll(state) {
|
|
443
|
+
var _a3, _b;
|
|
444
|
+
const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
|
|
445
|
+
state.pendingScrollResolve = void 0;
|
|
446
|
+
state.pendingScrollToEnd = void 0;
|
|
447
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
448
|
+
}
|
|
449
|
+
function cancelImperativeScroll(state) {
|
|
450
|
+
cancelScrollCompletionChecks(state);
|
|
451
|
+
state.scheduledWork.cancel("imperativeScrollReady");
|
|
452
|
+
state.scrollingTo = void 0;
|
|
453
|
+
state.scrollTargetPinnedRange = void 0;
|
|
454
|
+
settlePendingImperativeScroll(state);
|
|
455
|
+
}
|
|
456
|
+
|
|
439
457
|
// src/core/deferredPublicOnScroll.ts
|
|
440
458
|
function withResolvedContentOffset(state, event, resolvedOffset) {
|
|
441
459
|
return {
|
|
@@ -690,6 +708,12 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
690
708
|
} = state;
|
|
691
709
|
const contentSize = getContentSize(ctx);
|
|
692
710
|
resetSharedEdgeGateIfOutsideHysteresis(ctx);
|
|
711
|
+
if (state.props.data.length === 0 && scrollLength > 0 && contentSize <= scrollLength) {
|
|
712
|
+
set$(ctx, "isAtEnd", true);
|
|
713
|
+
set$(ctx, "isNearEnd", true);
|
|
714
|
+
set$(ctx, "isWithinMaintainScrollAtEndThreshold", true);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
693
717
|
if (contentSize > 0 && queuedInitialLayout) {
|
|
694
718
|
const insetEnd = getContentInsetEnd(ctx);
|
|
695
719
|
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
@@ -699,7 +723,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
699
723
|
set$(
|
|
700
724
|
ctx,
|
|
701
725
|
"isWithinMaintainScrollAtEndThreshold",
|
|
702
|
-
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength
|
|
726
|
+
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant"
|
|
703
727
|
);
|
|
704
728
|
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
|
|
705
729
|
if (!shouldSkipThresholdChecks) {
|
|
@@ -943,6 +967,24 @@ function clearPreservedInitialScrollTarget(state) {
|
|
|
943
967
|
state.initialScroll = void 0;
|
|
944
968
|
setInitialScrollSession(state);
|
|
945
969
|
}
|
|
970
|
+
function supersedeInitialScroll(ctx) {
|
|
971
|
+
var _a3, _b, _c;
|
|
972
|
+
const state = ctx.state;
|
|
973
|
+
const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
974
|
+
if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
|
|
975
|
+
if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
976
|
+
cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
|
|
977
|
+
}
|
|
978
|
+
if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
|
|
979
|
+
cancelScrollCompletionChecks(state);
|
|
980
|
+
state.scrollingTo = void 0;
|
|
981
|
+
state.scrollTargetPinnedRange = void 0;
|
|
982
|
+
}
|
|
983
|
+
initialScrollCompletion.resetFlags(state);
|
|
984
|
+
setInitialScrollSession(state, { bootstrap: null });
|
|
985
|
+
finishInitialScroll(ctx);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
946
988
|
function finishInitialScroll(ctx, options) {
|
|
947
989
|
var _a3, _b, _c;
|
|
948
990
|
const state = ctx.state;
|
|
@@ -1032,10 +1074,22 @@ function getAlignItemsAtEndPadding(ctx) {
|
|
|
1032
1074
|
return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
|
|
1033
1075
|
}
|
|
1034
1076
|
function updateContentMetricsState(ctx) {
|
|
1077
|
+
var _a3;
|
|
1078
|
+
const { state } = ctx;
|
|
1035
1079
|
const previousPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1036
1080
|
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1037
1081
|
if (previousPadding !== nextPadding) {
|
|
1038
|
-
|
|
1082
|
+
const isAnimatedMaintainActive = state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated";
|
|
1083
|
+
const isMaintainExpected = state.didContainersLayout && ((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.animated) && (isAnimatedMaintainActive || previousPadding > nextPadding && peek$(ctx, "isWithinMaintainScrollAtEndThreshold"));
|
|
1084
|
+
if (isMaintainExpected && !isAnimatedMaintainActive && !state.pendingMaintainScrollAtEnd) {
|
|
1085
|
+
state.scheduledWork.microtask(() => {
|
|
1086
|
+
if (!state.maintainingScrollAtEnd && !state.pendingMaintainScrollAtEnd) {
|
|
1087
|
+
set$(ctx, "alignItemsAtEndPadding", getAlignItemsAtEndPadding(ctx));
|
|
1088
|
+
}
|
|
1089
|
+
}, "alignItemsAtEndPaddingFallback");
|
|
1090
|
+
} else if (!isMaintainExpected) {
|
|
1091
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1092
|
+
}
|
|
1039
1093
|
}
|
|
1040
1094
|
}
|
|
1041
1095
|
|
|
@@ -1258,29 +1312,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
|
1258
1312
|
return clampedOffset;
|
|
1259
1313
|
}
|
|
1260
1314
|
|
|
1261
|
-
// src/core/cancelImperativeScroll.ts
|
|
1262
|
-
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
1263
|
-
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
1264
|
-
scheduledWork.cancel("checkFinishedScrollRetryFrame");
|
|
1265
|
-
scheduledWork.cancel("checkFinishedScrollFallback");
|
|
1266
|
-
scheduledWork.cancel("platformScrollCompletion");
|
|
1267
|
-
}
|
|
1268
|
-
function settlePendingImperativeScroll(state) {
|
|
1269
|
-
var _a3, _b;
|
|
1270
|
-
const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
|
|
1271
|
-
state.pendingScrollResolve = void 0;
|
|
1272
|
-
state.pendingScrollToEnd = void 0;
|
|
1273
|
-
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1274
|
-
}
|
|
1275
|
-
function cancelImperativeScroll(state) {
|
|
1276
|
-
cancelScrollCompletionChecks(state);
|
|
1277
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1278
|
-
state.runPendingScrollToEnd = void 0;
|
|
1279
|
-
state.scrollingTo = void 0;
|
|
1280
|
-
state.scrollTargetPinnedRange = void 0;
|
|
1281
|
-
settlePendingImperativeScroll(state);
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
1315
|
// src/core/finishScrollTo.ts
|
|
1285
1316
|
function finishScrollTo(ctx) {
|
|
1286
1317
|
var _a3, _b;
|
|
@@ -1511,81 +1542,55 @@ function doScrollTo(ctx, params) {
|
|
|
1511
1542
|
}
|
|
1512
1543
|
}
|
|
1513
1544
|
|
|
1514
|
-
// src/core/
|
|
1515
|
-
function
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
if (!state.maintainingScrollAtEnd) {
|
|
1536
|
-
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1537
|
-
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1538
|
-
const scrollAtRequest = state.scroll;
|
|
1539
|
-
state.maintainingScrollAtEnd = pendingState;
|
|
1540
|
-
requestAnimationFrame(() => {
|
|
1541
|
-
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1542
|
-
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1543
|
-
if (isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1544
|
-
state.maintainingScrollAtEnd = activeState;
|
|
1545
|
-
const scroller = refScroller.current;
|
|
1546
|
-
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
1547
|
-
const currentContentSize = getContentSize(ctx);
|
|
1548
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
1549
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
1550
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
1551
|
-
animated: maintainScrollAtEnd.animated,
|
|
1552
|
-
x: nativeOffset,
|
|
1553
|
-
y: 0
|
|
1554
|
-
});
|
|
1555
|
-
} else {
|
|
1556
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
1557
|
-
animated: maintainScrollAtEnd.animated
|
|
1558
|
-
});
|
|
1559
|
-
}
|
|
1560
|
-
setTimeout(
|
|
1561
|
-
() => {
|
|
1562
|
-
if (state.maintainingScrollAtEnd === activeState) {
|
|
1563
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1564
|
-
if (state.pendingMaintainScrollAtEnd) {
|
|
1565
|
-
doMaintainScrollAtEnd(ctx);
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
},
|
|
1569
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
1570
|
-
);
|
|
1571
|
-
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1572
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1573
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1545
|
+
// src/core/scrollRequestTracker.ts
|
|
1546
|
+
function getScrollRequestTracker(ctx) {
|
|
1547
|
+
if (!ctx.scrollRequestTracker) {
|
|
1548
|
+
let currentToken = 0;
|
|
1549
|
+
const start = (resolve) => {
|
|
1550
|
+
const state = ctx.state;
|
|
1551
|
+
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1552
|
+
const token = ++currentToken;
|
|
1553
|
+
settlePendingImperativeScroll(state);
|
|
1554
|
+
state.pendingScrollResolve = resolve;
|
|
1555
|
+
return token;
|
|
1556
|
+
};
|
|
1557
|
+
const runNow = (token, resolve, run) => {
|
|
1558
|
+
const state = ctx.state;
|
|
1559
|
+
if (token !== currentToken) {
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
const didStartScroll = run();
|
|
1563
|
+
if (!didStartScroll || !state.scrollingTo) {
|
|
1564
|
+
if (state.pendingScrollResolve === resolve) {
|
|
1565
|
+
state.pendingScrollResolve = void 0;
|
|
1574
1566
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1567
|
+
resolve();
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
ctx.scrollRequestTracker = {
|
|
1571
|
+
isCurrent: (token) => token === currentToken,
|
|
1572
|
+
runNow,
|
|
1573
|
+
runNowIfIdle: (run) => {
|
|
1574
|
+
const state = ctx.state;
|
|
1575
|
+
if (state.pendingScrollResolve || state.scrollingTo) {
|
|
1576
|
+
return Promise.resolve();
|
|
1577
|
+
}
|
|
1578
|
+
return new Promise((resolve) => {
|
|
1579
|
+
const token = start(resolve);
|
|
1580
|
+
runNow(token, resolve, run);
|
|
1581
|
+
});
|
|
1582
|
+
},
|
|
1583
|
+
start
|
|
1584
|
+
};
|
|
1580
1585
|
}
|
|
1581
|
-
|
|
1582
|
-
return false;
|
|
1586
|
+
return ctx.scrollRequestTracker;
|
|
1583
1587
|
}
|
|
1584
1588
|
|
|
1585
1589
|
// src/utils/requestAdjust.ts
|
|
1586
|
-
function requestAdjust(ctx, positionDiff,
|
|
1590
|
+
function requestAdjust(ctx, positionDiff, source) {
|
|
1587
1591
|
const state = ctx.state;
|
|
1588
1592
|
if (Math.abs(positionDiff) > 0.1) {
|
|
1593
|
+
const dataChanged = source === "data";
|
|
1589
1594
|
const needsScrollWorkaround = Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
|
|
1590
1595
|
const doit = () => {
|
|
1591
1596
|
if (needsScrollWorkaround) {
|
|
@@ -1602,7 +1607,7 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
1602
1607
|
const readyToRender = peek$(ctx, "readyToRender");
|
|
1603
1608
|
if (readyToRender) {
|
|
1604
1609
|
doit();
|
|
1605
|
-
if (Platform.OS !== "web") {
|
|
1610
|
+
if (Platform.OS !== "web" && source !== "item-size") {
|
|
1606
1611
|
const threshold = state.scroll - positionDiff / 2;
|
|
1607
1612
|
if (!state.ignoreScrollFromMVCP) {
|
|
1608
1613
|
state.ignoreScrollFromMVCP = {};
|
|
@@ -1635,6 +1640,87 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
1635
1640
|
}
|
|
1636
1641
|
}
|
|
1637
1642
|
|
|
1643
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1644
|
+
function finishMaintainScrollAtEnd(ctx) {
|
|
1645
|
+
var _a3;
|
|
1646
|
+
const { state } = ctx;
|
|
1647
|
+
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1648
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1649
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1650
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1651
|
+
if (currentPadding !== nextPadding) {
|
|
1652
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1653
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1654
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1655
|
+
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1656
|
+
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
1660
|
+
const state = ctx.state;
|
|
1661
|
+
const {
|
|
1662
|
+
didContainersLayout,
|
|
1663
|
+
didFinishInitialScroll,
|
|
1664
|
+
pendingNativeMVCPAdjust,
|
|
1665
|
+
props: { maintainScrollAtEnd }
|
|
1666
|
+
} = state;
|
|
1667
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1668
|
+
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1669
|
+
const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1670
|
+
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1671
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1672
|
+
return false;
|
|
1673
|
+
}
|
|
1674
|
+
if (pendingNativeMVCPAdjust) {
|
|
1675
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1676
|
+
return false;
|
|
1677
|
+
}
|
|
1678
|
+
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1679
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1680
|
+
const contentSize = getContentSize(ctx);
|
|
1681
|
+
if (contentSize < state.scrollLength) {
|
|
1682
|
+
state.scroll = 0;
|
|
1683
|
+
}
|
|
1684
|
+
if (!state.maintainingScrollAtEnd) {
|
|
1685
|
+
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1686
|
+
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1687
|
+
const scrollAtRequest = state.scroll;
|
|
1688
|
+
state.maintainingScrollAtEnd = pendingState;
|
|
1689
|
+
requestAnimationFrame(() => {
|
|
1690
|
+
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1691
|
+
return;
|
|
1692
|
+
}
|
|
1693
|
+
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1694
|
+
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1695
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1696
|
+
state.maintainingScrollAtEnd = activeState;
|
|
1697
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1698
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1699
|
+
);
|
|
1700
|
+
void scrollPromise.then(() => {
|
|
1701
|
+
if (state.maintainingScrollAtEnd !== activeState) {
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
1705
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1706
|
+
doMaintainScrollAtEnd(ctx);
|
|
1707
|
+
} else {
|
|
1708
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1709
|
+
}
|
|
1710
|
+
});
|
|
1711
|
+
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1712
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
} else {
|
|
1716
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1717
|
+
}
|
|
1718
|
+
return true;
|
|
1719
|
+
}
|
|
1720
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1721
|
+
return false;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1638
1724
|
// src/core/mvcp.ts
|
|
1639
1725
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
1640
1726
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -1708,7 +1794,7 @@ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
|
|
|
1708
1794
|
state.pendingNativeMVCPAdjust = void 0;
|
|
1709
1795
|
const remaining = remainingAfterManual - nativeDelta;
|
|
1710
1796
|
if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
|
|
1711
|
-
requestAdjust(ctx, remaining,
|
|
1797
|
+
requestAdjust(ctx, remaining, "data");
|
|
1712
1798
|
}
|
|
1713
1799
|
}
|
|
1714
1800
|
function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
@@ -1727,7 +1813,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
|
1727
1813
|
return;
|
|
1728
1814
|
}
|
|
1729
1815
|
pending.manualApplied = manualDesired;
|
|
1730
|
-
requestAdjust(ctx, manualDesired,
|
|
1816
|
+
requestAdjust(ctx, manualDesired, "data");
|
|
1731
1817
|
pending.furthestProgressTowardAmount = 0;
|
|
1732
1818
|
}
|
|
1733
1819
|
function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
@@ -1773,7 +1859,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
|
1773
1859
|
}
|
|
1774
1860
|
return false;
|
|
1775
1861
|
}
|
|
1776
|
-
function prepareMVCP(ctx, dataChanged) {
|
|
1862
|
+
function prepareMVCP(ctx, dataChanged, adjustmentSource) {
|
|
1777
1863
|
const state = ctx.state;
|
|
1778
1864
|
const { idsInView, positions, props } = state;
|
|
1779
1865
|
const {
|
|
@@ -1927,7 +2013,7 @@ function prepareMVCP(ctx, dataChanged) {
|
|
|
1927
2013
|
if (Math.abs(positionDiff) > MVCP_POSITION_EPSILON) {
|
|
1928
2014
|
const shouldSkipAdjustForMaintainedEnd = (state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated") && peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1929
2015
|
if (!shouldSkipAdjustForMaintainedEnd) {
|
|
1930
|
-
requestAdjust(ctx, positionDiff, dataChanged && mvcpData);
|
|
2016
|
+
requestAdjust(ctx, positionDiff, dataChanged && mvcpData ? "data" : adjustmentSource);
|
|
1931
2017
|
}
|
|
1932
2018
|
}
|
|
1933
2019
|
};
|
|
@@ -2025,6 +2111,10 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2025
2111
|
state.scrollTime = currentTime;
|
|
2026
2112
|
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
2027
2113
|
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
2114
|
+
const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
2115
|
+
if (didCancelMaintainScrollAtEnd) {
|
|
2116
|
+
finishMaintainScrollAtEnd(ctx);
|
|
2117
|
+
}
|
|
2028
2118
|
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
2029
2119
|
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
2030
2120
|
const scrollLength = state.scrollLength;
|
|
@@ -2033,7 +2123,7 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2033
2123
|
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
2034
2124
|
const lastCalculated = state.scrollLastCalculate;
|
|
2035
2125
|
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
2036
|
-
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2126
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2037
2127
|
if (shouldUpdate) {
|
|
2038
2128
|
state.scrollLastCalculate = state.scroll;
|
|
2039
2129
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
@@ -2862,7 +2952,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2862
2952
|
}
|
|
2863
2953
|
}
|
|
2864
2954
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2865
|
-
var _a3, _b
|
|
2955
|
+
var _a3, _b;
|
|
2866
2956
|
const state = ctx.state;
|
|
2867
2957
|
const initialScroll = state.initialScroll;
|
|
2868
2958
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2876,19 +2966,15 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2876
2966
|
if (state.didFinishInitialScroll) {
|
|
2877
2967
|
schedulePreservedEndAnchorCorrection(ctx);
|
|
2878
2968
|
} else if (scrollingTo) {
|
|
2879
|
-
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2880
|
-
scrollingTo.offset = resolvedOffset;
|
|
2881
|
-
scrollingTo.targetOffset = resolvedOffset;
|
|
2882
2969
|
state.initialScroll = {
|
|
2883
2970
|
...initialScroll,
|
|
2884
2971
|
contentOffset: resolvedOffset
|
|
2885
2972
|
};
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2973
|
+
dispatchInitialScroll(ctx, {
|
|
2974
|
+
forceScroll: true,
|
|
2975
|
+
resolvedOffset,
|
|
2976
|
+
target: state.initialScroll
|
|
2890
2977
|
});
|
|
2891
|
-
requestAdjust(ctx, offsetDiff);
|
|
2892
2978
|
}
|
|
2893
2979
|
}
|
|
2894
2980
|
} else {
|
|
@@ -3930,6 +4016,9 @@ function setDidLayout(ctx) {
|
|
|
3930
4016
|
state.queuedInitialLayout = true;
|
|
3931
4017
|
checkAtBottom(ctx);
|
|
3932
4018
|
setInitialRenderState(ctx, { didLayout: true });
|
|
4019
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
4020
|
+
doMaintainScrollAtEnd(ctx);
|
|
4021
|
+
}
|
|
3933
4022
|
}
|
|
3934
4023
|
|
|
3935
4024
|
// src/core/calculateItemsInView.ts
|
|
@@ -4166,7 +4255,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4166
4255
|
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
|
|
4167
4256
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4168
4257
|
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4169
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4258
|
+
const { dataChanged, doMVCP, forceFullItemPositions, mvcpAdjustmentSource } = params;
|
|
4170
4259
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
4171
4260
|
const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
|
|
4172
4261
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
@@ -4267,7 +4356,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4267
4356
|
}
|
|
4268
4357
|
}
|
|
4269
4358
|
}
|
|
4270
|
-
const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged) : void 0;
|
|
4359
|
+
const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged, mvcpAdjustmentSource) : void 0;
|
|
4271
4360
|
if (dataChanged) {
|
|
4272
4361
|
resetLayoutCachesForDataChange(state);
|
|
4273
4362
|
}
|
|
@@ -4681,12 +4770,15 @@ function runOrScheduleMVCPRecalculate(ctx) {
|
|
|
4681
4770
|
} else if (Platform.OS === "web") {
|
|
4682
4771
|
if (!state.mvcpAnchorLock) {
|
|
4683
4772
|
state.scheduledWork.cancel("mvcpRecalculate");
|
|
4684
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
4773
|
+
calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
|
|
4685
4774
|
} else if (!state.scheduledWork.has("mvcpRecalculate")) {
|
|
4686
|
-
state.scheduledWork.frame(
|
|
4775
|
+
state.scheduledWork.frame(
|
|
4776
|
+
() => calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" }),
|
|
4777
|
+
"mvcpRecalculate"
|
|
4778
|
+
);
|
|
4687
4779
|
}
|
|
4688
4780
|
} else {
|
|
4689
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
4781
|
+
calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
|
|
4690
4782
|
}
|
|
4691
4783
|
}
|
|
4692
4784
|
function updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal) {
|
|
@@ -4812,7 +4904,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4812
4904
|
if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
|
|
4813
4905
|
needsRecalculate = true;
|
|
4814
4906
|
}
|
|
4815
|
-
if (prevSizeKnown
|
|
4907
|
+
if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
|
|
4816
4908
|
shouldMaintainScrollAtEnd = true;
|
|
4817
4909
|
}
|
|
4818
4910
|
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
@@ -5175,6 +5267,30 @@ function useContainerItemSignals(containerContext) {
|
|
|
5175
5267
|
itemKey
|
|
5176
5268
|
};
|
|
5177
5269
|
}
|
|
5270
|
+
function scheduleViewabilityConfigWarning(ctx, hookName, configId) {
|
|
5271
|
+
let cancelled = false;
|
|
5272
|
+
Promise.resolve().then(() => {
|
|
5273
|
+
var _a3;
|
|
5274
|
+
const viewabilityConfigCallbackPairs = (_a3 = ctx.state) == null ? void 0 : _a3.viewabilityConfigCallbackPairs;
|
|
5275
|
+
if (!cancelled && ctx.state) {
|
|
5276
|
+
if (!(viewabilityConfigCallbackPairs == null ? void 0 : viewabilityConfigCallbackPairs.length)) {
|
|
5277
|
+
warnDevOnce(
|
|
5278
|
+
`${hookName}-missing-viewability-config`,
|
|
5279
|
+
`${hookName} requires viewability to be configured on the owning LegendList. Add viewabilityConfig with a visibility threshold.`
|
|
5280
|
+
);
|
|
5281
|
+
} else if (hookName === "useViewability" && !viewabilityConfigCallbackPairs.some((pair) => pair.viewabilityConfig.id === (configId != null ? configId : ""))) {
|
|
5282
|
+
const configDescription = configId ? ` for configId "${configId}"` : "";
|
|
5283
|
+
warnDevOnce(
|
|
5284
|
+
`${hookName}-missing-viewability-config-${configId != null ? configId : "default"}`,
|
|
5285
|
+
`${hookName}${configDescription} requires a matching viewabilityConfig.id on the owning LegendList. Add an id to viewabilityConfig and pass the same id to useViewability.`
|
|
5286
|
+
);
|
|
5287
|
+
}
|
|
5288
|
+
}
|
|
5289
|
+
});
|
|
5290
|
+
return () => {
|
|
5291
|
+
cancelled = true;
|
|
5292
|
+
};
|
|
5293
|
+
}
|
|
5178
5294
|
function useAdaptiveRender() {
|
|
5179
5295
|
const [mode] = useArr$(["adaptiveRender"]);
|
|
5180
5296
|
return mode;
|
|
@@ -5214,7 +5330,9 @@ function useViewability(callback, configId) {
|
|
|
5214
5330
|
const { containerId } = containerContext;
|
|
5215
5331
|
const key = containerId + (configId != null ? configId : "");
|
|
5216
5332
|
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
5333
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewability", configId) : void 0;
|
|
5217
5334
|
return () => {
|
|
5335
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5218
5336
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
5219
5337
|
};
|
|
5220
5338
|
}, [ctx, callback, configId, containerContext]);
|
|
@@ -5238,7 +5356,9 @@ function useViewabilityAmount(callback) {
|
|
|
5238
5356
|
}
|
|
5239
5357
|
const { containerId } = containerContext;
|
|
5240
5358
|
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
5359
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewabilityAmount") : void 0;
|
|
5241
5360
|
return () => {
|
|
5361
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5242
5362
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
5243
5363
|
};
|
|
5244
5364
|
}, [ctx, callback, containerContext]);
|
|
@@ -5662,13 +5782,11 @@ var ContainerSlot = typedMemo(function ContainerSlot2(props) {
|
|
|
5662
5782
|
return /* @__PURE__ */ React2.createElement(ContainerSlotBase, { ...props });
|
|
5663
5783
|
});
|
|
5664
5784
|
function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
|
|
5665
|
-
const completedTransitionEpoch =
|
|
5666
|
-
const isTransitionPending = completedTransitionEpoch
|
|
5785
|
+
const [completedTransitionEpoch, setCompletedTransitionEpoch] = useState(transitionEpoch);
|
|
5786
|
+
const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
|
|
5667
5787
|
useLayoutEffect(() => {
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
}
|
|
5671
|
-
}, [readyToRender, transitionEpoch]);
|
|
5788
|
+
setCompletedTransitionEpoch(transitionEpoch);
|
|
5789
|
+
}, [transitionEpoch]);
|
|
5672
5790
|
return readyToRender && !isTransitionPending;
|
|
5673
5791
|
}
|
|
5674
5792
|
|
|
@@ -6347,11 +6465,29 @@ var ScheduledWork = class {
|
|
|
6347
6465
|
constructor() {
|
|
6348
6466
|
this.work = /* @__PURE__ */ new Map();
|
|
6349
6467
|
}
|
|
6468
|
+
microtask(callback, key) {
|
|
6469
|
+
const pendingWork = this.work.get(key);
|
|
6470
|
+
if (pendingWork == null ? void 0 : pendingWork.callback) {
|
|
6471
|
+
pendingWork.callback = callback;
|
|
6472
|
+
} else {
|
|
6473
|
+
this.cancel(key);
|
|
6474
|
+
const work = { callback, cancel: () => {
|
|
6475
|
+
} };
|
|
6476
|
+
this.work.set(key, work);
|
|
6477
|
+
queueMicrotask(() => {
|
|
6478
|
+
var _a3;
|
|
6479
|
+
if (this.work.get(key) === work) {
|
|
6480
|
+
this.work.delete(key);
|
|
6481
|
+
(_a3 = work.callback) == null ? void 0 : _a3.call(work);
|
|
6482
|
+
}
|
|
6483
|
+
});
|
|
6484
|
+
}
|
|
6485
|
+
}
|
|
6350
6486
|
timeout(callback, delay, key) {
|
|
6351
6487
|
if (key) {
|
|
6352
6488
|
this.cancel(key);
|
|
6353
6489
|
}
|
|
6354
|
-
const work =
|
|
6490
|
+
const work = { cancel: () => clearTimeout(handle) };
|
|
6355
6491
|
const handle = setTimeout(() => {
|
|
6356
6492
|
const workKey = key != null ? key : handle;
|
|
6357
6493
|
if (this.work.get(workKey) === work) {
|
|
@@ -6359,14 +6495,13 @@ var ScheduledWork = class {
|
|
|
6359
6495
|
callback();
|
|
6360
6496
|
}
|
|
6361
6497
|
}, delay);
|
|
6362
|
-
work[0] = handle;
|
|
6363
6498
|
this.work.set(key != null ? key : handle, work);
|
|
6364
6499
|
}
|
|
6365
6500
|
frame(callback, key) {
|
|
6366
6501
|
this.cancel(key);
|
|
6367
|
-
const work =
|
|
6502
|
+
const work = { cancel: () => cancelAnimationFrame(handle) };
|
|
6368
6503
|
this.work.set(key, work);
|
|
6369
|
-
|
|
6504
|
+
const handle = requestAnimationFrame(() => {
|
|
6370
6505
|
if (this.work.get(key) === work) {
|
|
6371
6506
|
this.work.delete(key);
|
|
6372
6507
|
callback();
|
|
@@ -6375,21 +6510,21 @@ var ScheduledWork = class {
|
|
|
6375
6510
|
}
|
|
6376
6511
|
register(key, cancel) {
|
|
6377
6512
|
this.cancel(key);
|
|
6378
|
-
this.work.set(key,
|
|
6513
|
+
this.work.set(key, { cancel });
|
|
6379
6514
|
}
|
|
6380
6515
|
cancel(key) {
|
|
6381
6516
|
const work = this.work.get(key);
|
|
6382
6517
|
if (work) {
|
|
6383
6518
|
this.work.delete(key);
|
|
6384
|
-
work
|
|
6519
|
+
work.cancel();
|
|
6385
6520
|
}
|
|
6386
6521
|
}
|
|
6387
6522
|
has(key) {
|
|
6388
6523
|
return this.work.has(key);
|
|
6389
6524
|
}
|
|
6390
6525
|
dispose() {
|
|
6391
|
-
for (const
|
|
6392
|
-
cancel(
|
|
6526
|
+
for (const work of this.work.values()) {
|
|
6527
|
+
work.cancel();
|
|
6393
6528
|
}
|
|
6394
6529
|
this.work.clear();
|
|
6395
6530
|
}
|
|
@@ -6446,6 +6581,25 @@ var ScrollAdjustHandler = class {
|
|
|
6446
6581
|
}
|
|
6447
6582
|
};
|
|
6448
6583
|
|
|
6584
|
+
// src/core/scrollToEnd.ts
|
|
6585
|
+
function scrollToEnd(ctx, options) {
|
|
6586
|
+
const state = ctx.state;
|
|
6587
|
+
const data = state.props.data;
|
|
6588
|
+
const index = data.length - 1;
|
|
6589
|
+
if (index === -1) {
|
|
6590
|
+
return false;
|
|
6591
|
+
}
|
|
6592
|
+
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
6593
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
6594
|
+
scrollToIndex(ctx, {
|
|
6595
|
+
...options,
|
|
6596
|
+
index,
|
|
6597
|
+
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
6598
|
+
viewPosition: 1
|
|
6599
|
+
});
|
|
6600
|
+
return true;
|
|
6601
|
+
}
|
|
6602
|
+
|
|
6449
6603
|
// src/core/updateContentInsetEndAdjustment.ts
|
|
6450
6604
|
function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
|
|
6451
6605
|
const state = ctx.state;
|
|
@@ -6520,25 +6674,6 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
6520
6674
|
}
|
|
6521
6675
|
}
|
|
6522
6676
|
|
|
6523
|
-
// src/core/scrollToEnd.ts
|
|
6524
|
-
function scrollToEnd(ctx, options) {
|
|
6525
|
-
const state = ctx.state;
|
|
6526
|
-
const data = state.props.data;
|
|
6527
|
-
const index = data.length - 1;
|
|
6528
|
-
if (index === -1) {
|
|
6529
|
-
return false;
|
|
6530
|
-
}
|
|
6531
|
-
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
6532
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
6533
|
-
scrollToIndex(ctx, {
|
|
6534
|
-
...options,
|
|
6535
|
-
index,
|
|
6536
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
6537
|
-
viewPosition: 1
|
|
6538
|
-
});
|
|
6539
|
-
return true;
|
|
6540
|
-
}
|
|
6541
|
-
|
|
6542
6677
|
// src/utils/createImperativeHandle.ts
|
|
6543
6678
|
var DEFAULT_AVERAGE_ITEM_SIZE_TYPE = "default";
|
|
6544
6679
|
function getAverageItemSizes(state) {
|
|
@@ -6565,9 +6700,9 @@ function triggerMountedContainerLayouts(ctx) {
|
|
|
6565
6700
|
}
|
|
6566
6701
|
function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
6567
6702
|
const state = ctx.state;
|
|
6703
|
+
const scrollRequestTracker = getScrollRequestTracker(ctx);
|
|
6568
6704
|
const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
|
|
6569
6705
|
const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
|
|
6570
|
-
let imperativeScrollToken = 0;
|
|
6571
6706
|
const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.scheduledWork.has("mvcpRecalculate") || state.ignoreScrollFromMVCP !== void 0;
|
|
6572
6707
|
const isScrollToIndexReady = (targetIndex, allowEmpty = false) => {
|
|
6573
6708
|
var _a3;
|
|
@@ -6589,7 +6724,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6589
6724
|
const startedAt = Date.now();
|
|
6590
6725
|
let stableFrames = 0;
|
|
6591
6726
|
const check = () => {
|
|
6592
|
-
if (token
|
|
6727
|
+
if (!scrollRequestTracker.isCurrent(token)) {
|
|
6593
6728
|
return;
|
|
6594
6729
|
}
|
|
6595
6730
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
@@ -6607,40 +6742,23 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6607
6742
|
state.scheduledWork.frame(check, "imperativeScrollReady");
|
|
6608
6743
|
};
|
|
6609
6744
|
const runScrollRequest = (token, resolve, run, isReady = () => true) => {
|
|
6610
|
-
const runNow = () =>
|
|
6611
|
-
if (token !== imperativeScrollToken) {
|
|
6612
|
-
return;
|
|
6613
|
-
}
|
|
6614
|
-
const didStartScroll = run();
|
|
6615
|
-
if (!didStartScroll || !state.scrollingTo) {
|
|
6616
|
-
if (state.pendingScrollResolve === resolve) {
|
|
6617
|
-
state.pendingScrollResolve = void 0;
|
|
6618
|
-
}
|
|
6619
|
-
resolve();
|
|
6620
|
-
}
|
|
6621
|
-
};
|
|
6745
|
+
const runNow = () => scrollRequestTracker.runNow(token, resolve, run);
|
|
6622
6746
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
6623
6747
|
runWhenReady(token, runNow, isReady);
|
|
6624
6748
|
} else {
|
|
6625
6749
|
runNow();
|
|
6626
6750
|
}
|
|
6627
6751
|
};
|
|
6628
|
-
const startImperativeScroll = (resolve) => {
|
|
6629
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
6630
|
-
const token = ++imperativeScrollToken;
|
|
6631
|
-
settlePendingImperativeScroll(state);
|
|
6632
|
-
state.pendingScrollResolve = resolve;
|
|
6633
|
-
return token;
|
|
6634
|
-
};
|
|
6635
6752
|
const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
|
|
6636
|
-
const token =
|
|
6753
|
+
const token = scrollRequestTracker.start(resolve);
|
|
6754
|
+
supersedeInitialScroll(ctx);
|
|
6637
6755
|
runScrollRequest(token, resolve, run, isReady);
|
|
6638
6756
|
});
|
|
6639
6757
|
state.runPendingScrollToEnd = () => {
|
|
6640
6758
|
const pendingScroll = state.pendingScrollToEnd;
|
|
6641
6759
|
if (pendingScroll) {
|
|
6642
6760
|
state.pendingScrollToEnd = void 0;
|
|
6643
|
-
if (pendingScroll.token
|
|
6761
|
+
if (scrollRequestTracker.isCurrent(pendingScroll.token)) {
|
|
6644
6762
|
runScrollRequest(
|
|
6645
6763
|
pendingScroll.token,
|
|
6646
6764
|
pendingScroll.resolve,
|
|
@@ -6754,15 +6872,15 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6754
6872
|
}),
|
|
6755
6873
|
scrollToEnd: (options) => new Promise((resolve) => {
|
|
6756
6874
|
var _a3;
|
|
6757
|
-
const token =
|
|
6875
|
+
const token = scrollRequestTracker.start(resolve);
|
|
6758
6876
|
state.pendingScrollToEnd = {
|
|
6759
6877
|
options,
|
|
6760
6878
|
resolve,
|
|
6761
6879
|
token
|
|
6762
6880
|
};
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6881
|
+
scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
|
|
6882
|
+
supersedeInitialScroll(ctx);
|
|
6883
|
+
if (!scheduleImperativeScrollCommit) {
|
|
6766
6884
|
(_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
|
|
6767
6885
|
}
|
|
6768
6886
|
}),
|
|
@@ -7134,6 +7252,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7134
7252
|
const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
|
|
7135
7253
|
const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
|
|
7136
7254
|
const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
|
|
7255
|
+
const shouldBottomAlignNumericInitialScrollIndex = typeof initialScrollIndexProp === "number" && !hasInitialScrollOffset && dataProp.length > 1 && initialScrollIndexProp >= dataProp.length - 1;
|
|
7137
7256
|
const initialScrollProp = initialScrollAtEnd ? {
|
|
7138
7257
|
index: Math.max(0, dataProp.length - 1),
|
|
7139
7258
|
preserveForBottomPadding: true,
|
|
@@ -7146,7 +7265,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7146
7265
|
viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
|
|
7147
7266
|
} : {
|
|
7148
7267
|
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
7149
|
-
|
|
7268
|
+
preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
|
|
7269
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? -stylePaddingEndState : 0,
|
|
7270
|
+
viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
|
|
7150
7271
|
} : initialScrollUsesOffsetOnly ? {
|
|
7151
7272
|
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
7152
7273
|
index: 0,
|
|
@@ -7252,6 +7373,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7252
7373
|
viewabilityConfigCallbackPairs: void 0
|
|
7253
7374
|
};
|
|
7254
7375
|
const internalState = ctx.state;
|
|
7376
|
+
ctx.scrollToEnd = (options) => scrollToEnd(ctx, options);
|
|
7255
7377
|
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
7256
7378
|
internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
|
|
7257
7379
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
|
|
@@ -7613,6 +7735,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7613
7735
|
onScroll: (event) => onScroll(ctx, event),
|
|
7614
7736
|
onScrollBeginDrag: (event) => {
|
|
7615
7737
|
var _a4, _b2;
|
|
7738
|
+
const maintainingScrollAtEnd = state.maintainingScrollAtEnd;
|
|
7739
|
+
if (maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant") {
|
|
7740
|
+
cancelImperativeScroll(state);
|
|
7741
|
+
}
|
|
7742
|
+
if (maintainingScrollAtEnd) {
|
|
7743
|
+
finishMaintainScrollAtEnd(ctx);
|
|
7744
|
+
}
|
|
7616
7745
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
7617
7746
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
7618
7747
|
},
|