@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.js
CHANGED
|
@@ -68,10 +68,6 @@ function getStylePaddingEnd(props) {
|
|
|
68
68
|
}
|
|
69
69
|
return (isHorizontalRTLProps(props) ? props.stylePaddingLeft : props.stylePaddingRight) || 0;
|
|
70
70
|
}
|
|
71
|
-
function getLogicalHorizontalMaxOffset(state, contentWidth) {
|
|
72
|
-
var _a3;
|
|
73
|
-
return (_a3 = getHorizontalMaxOffset(state, contentWidth)) != null ? _a3 : 0;
|
|
74
|
-
}
|
|
75
71
|
function getHorizontalInsetEnd(state, inset) {
|
|
76
72
|
if (!inset) {
|
|
77
73
|
return 0;
|
|
@@ -457,6 +453,28 @@ var EDGE_POSITION_EPSILON = 1;
|
|
|
457
453
|
var ENABLE_DEVMODE = IS_DEV && false;
|
|
458
454
|
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
459
455
|
|
|
456
|
+
// src/core/cancelImperativeScroll.ts
|
|
457
|
+
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
458
|
+
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
459
|
+
scheduledWork.cancel("checkFinishedScrollRetryFrame");
|
|
460
|
+
scheduledWork.cancel("checkFinishedScrollFallback");
|
|
461
|
+
scheduledWork.cancel("platformScrollCompletion");
|
|
462
|
+
}
|
|
463
|
+
function settlePendingImperativeScroll(state) {
|
|
464
|
+
var _a3, _b;
|
|
465
|
+
const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
|
|
466
|
+
state.pendingScrollResolve = void 0;
|
|
467
|
+
state.pendingScrollToEnd = void 0;
|
|
468
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
469
|
+
}
|
|
470
|
+
function cancelImperativeScroll(state) {
|
|
471
|
+
cancelScrollCompletionChecks(state);
|
|
472
|
+
state.scheduledWork.cancel("imperativeScrollReady");
|
|
473
|
+
state.scrollingTo = void 0;
|
|
474
|
+
state.scrollTargetPinnedRange = void 0;
|
|
475
|
+
settlePendingImperativeScroll(state);
|
|
476
|
+
}
|
|
477
|
+
|
|
460
478
|
// src/core/deferredPublicOnScroll.ts
|
|
461
479
|
function withResolvedContentOffset(state, event, resolvedOffset) {
|
|
462
480
|
return {
|
|
@@ -711,6 +729,12 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
711
729
|
} = state;
|
|
712
730
|
const contentSize = getContentSize(ctx);
|
|
713
731
|
resetSharedEdgeGateIfOutsideHysteresis(ctx);
|
|
732
|
+
if (state.props.data.length === 0 && scrollLength > 0 && contentSize <= scrollLength) {
|
|
733
|
+
set$(ctx, "isAtEnd", true);
|
|
734
|
+
set$(ctx, "isNearEnd", true);
|
|
735
|
+
set$(ctx, "isWithinMaintainScrollAtEndThreshold", true);
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
714
738
|
if (contentSize > 0 && queuedInitialLayout) {
|
|
715
739
|
const insetEnd = getContentInsetEnd(ctx);
|
|
716
740
|
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
@@ -720,7 +744,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
720
744
|
set$(
|
|
721
745
|
ctx,
|
|
722
746
|
"isWithinMaintainScrollAtEndThreshold",
|
|
723
|
-
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength
|
|
747
|
+
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant"
|
|
724
748
|
);
|
|
725
749
|
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
|
|
726
750
|
if (!shouldSkipThresholdChecks) {
|
|
@@ -964,6 +988,24 @@ function clearPreservedInitialScrollTarget(state) {
|
|
|
964
988
|
state.initialScroll = void 0;
|
|
965
989
|
setInitialScrollSession(state);
|
|
966
990
|
}
|
|
991
|
+
function supersedeInitialScroll(ctx) {
|
|
992
|
+
var _a3, _b, _c;
|
|
993
|
+
const state = ctx.state;
|
|
994
|
+
const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
995
|
+
if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
|
|
996
|
+
if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
997
|
+
cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
|
|
998
|
+
}
|
|
999
|
+
if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
|
|
1000
|
+
cancelScrollCompletionChecks(state);
|
|
1001
|
+
state.scrollingTo = void 0;
|
|
1002
|
+
state.scrollTargetPinnedRange = void 0;
|
|
1003
|
+
}
|
|
1004
|
+
initialScrollCompletion.resetFlags(state);
|
|
1005
|
+
setInitialScrollSession(state, { bootstrap: null });
|
|
1006
|
+
finishInitialScroll(ctx);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
967
1009
|
function finishInitialScroll(ctx, options) {
|
|
968
1010
|
var _a3, _b, _c;
|
|
969
1011
|
const state = ctx.state;
|
|
@@ -1053,10 +1095,22 @@ function getAlignItemsAtEndPadding(ctx) {
|
|
|
1053
1095
|
return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
|
|
1054
1096
|
}
|
|
1055
1097
|
function updateContentMetricsState(ctx) {
|
|
1098
|
+
var _a3;
|
|
1099
|
+
const { state } = ctx;
|
|
1056
1100
|
const previousPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1057
1101
|
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1058
1102
|
if (previousPadding !== nextPadding) {
|
|
1059
|
-
|
|
1103
|
+
const isAnimatedMaintainActive = state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated";
|
|
1104
|
+
const isMaintainExpected = state.didContainersLayout && ((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.animated) && (isAnimatedMaintainActive || previousPadding > nextPadding && peek$(ctx, "isWithinMaintainScrollAtEndThreshold"));
|
|
1105
|
+
if (isMaintainExpected && !isAnimatedMaintainActive && !state.pendingMaintainScrollAtEnd) {
|
|
1106
|
+
state.scheduledWork.microtask(() => {
|
|
1107
|
+
if (!state.maintainingScrollAtEnd && !state.pendingMaintainScrollAtEnd) {
|
|
1108
|
+
set$(ctx, "alignItemsAtEndPadding", getAlignItemsAtEndPadding(ctx));
|
|
1109
|
+
}
|
|
1110
|
+
}, "alignItemsAtEndPaddingFallback");
|
|
1111
|
+
} else if (!isMaintainExpected) {
|
|
1112
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1113
|
+
}
|
|
1060
1114
|
}
|
|
1061
1115
|
}
|
|
1062
1116
|
|
|
@@ -1279,29 +1333,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
|
1279
1333
|
return clampedOffset;
|
|
1280
1334
|
}
|
|
1281
1335
|
|
|
1282
|
-
// src/core/cancelImperativeScroll.ts
|
|
1283
|
-
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
1284
|
-
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
1285
|
-
scheduledWork.cancel("checkFinishedScrollRetryFrame");
|
|
1286
|
-
scheduledWork.cancel("checkFinishedScrollFallback");
|
|
1287
|
-
scheduledWork.cancel("platformScrollCompletion");
|
|
1288
|
-
}
|
|
1289
|
-
function settlePendingImperativeScroll(state) {
|
|
1290
|
-
var _a3, _b;
|
|
1291
|
-
const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
|
|
1292
|
-
state.pendingScrollResolve = void 0;
|
|
1293
|
-
state.pendingScrollToEnd = void 0;
|
|
1294
|
-
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1295
|
-
}
|
|
1296
|
-
function cancelImperativeScroll(state) {
|
|
1297
|
-
cancelScrollCompletionChecks(state);
|
|
1298
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1299
|
-
state.runPendingScrollToEnd = void 0;
|
|
1300
|
-
state.scrollingTo = void 0;
|
|
1301
|
-
state.scrollTargetPinnedRange = void 0;
|
|
1302
|
-
settlePendingImperativeScroll(state);
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
1336
|
// src/core/finishScrollTo.ts
|
|
1306
1337
|
function finishScrollTo(ctx) {
|
|
1307
1338
|
var _a3, _b;
|
|
@@ -1532,81 +1563,55 @@ function doScrollTo(ctx, params) {
|
|
|
1532
1563
|
}
|
|
1533
1564
|
}
|
|
1534
1565
|
|
|
1535
|
-
// src/core/
|
|
1536
|
-
function
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
if (!state.maintainingScrollAtEnd) {
|
|
1557
|
-
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1558
|
-
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1559
|
-
const scrollAtRequest = state.scroll;
|
|
1560
|
-
state.maintainingScrollAtEnd = pendingState;
|
|
1561
|
-
requestAnimationFrame(() => {
|
|
1562
|
-
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1563
|
-
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1564
|
-
if (isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1565
|
-
state.maintainingScrollAtEnd = activeState;
|
|
1566
|
-
const scroller = refScroller.current;
|
|
1567
|
-
if (state.props.horizontal && isHorizontalRTL(state)) {
|
|
1568
|
-
const currentContentSize = getContentSize(ctx);
|
|
1569
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
1570
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
1571
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
1572
|
-
animated: maintainScrollAtEnd.animated,
|
|
1573
|
-
x: nativeOffset,
|
|
1574
|
-
y: 0
|
|
1575
|
-
});
|
|
1576
|
-
} else {
|
|
1577
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
1578
|
-
animated: maintainScrollAtEnd.animated
|
|
1579
|
-
});
|
|
1580
|
-
}
|
|
1581
|
-
setTimeout(
|
|
1582
|
-
() => {
|
|
1583
|
-
if (state.maintainingScrollAtEnd === activeState) {
|
|
1584
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1585
|
-
if (state.pendingMaintainScrollAtEnd) {
|
|
1586
|
-
doMaintainScrollAtEnd(ctx);
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
|
-
},
|
|
1590
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
1591
|
-
);
|
|
1592
|
-
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1593
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1594
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1566
|
+
// src/core/scrollRequestTracker.ts
|
|
1567
|
+
function getScrollRequestTracker(ctx) {
|
|
1568
|
+
if (!ctx.scrollRequestTracker) {
|
|
1569
|
+
let currentToken = 0;
|
|
1570
|
+
const start = (resolve) => {
|
|
1571
|
+
const state = ctx.state;
|
|
1572
|
+
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1573
|
+
const token = ++currentToken;
|
|
1574
|
+
settlePendingImperativeScroll(state);
|
|
1575
|
+
state.pendingScrollResolve = resolve;
|
|
1576
|
+
return token;
|
|
1577
|
+
};
|
|
1578
|
+
const runNow = (token, resolve, run) => {
|
|
1579
|
+
const state = ctx.state;
|
|
1580
|
+
if (token !== currentToken) {
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
const didStartScroll = run();
|
|
1584
|
+
if (!didStartScroll || !state.scrollingTo) {
|
|
1585
|
+
if (state.pendingScrollResolve === resolve) {
|
|
1586
|
+
state.pendingScrollResolve = void 0;
|
|
1595
1587
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1588
|
+
resolve();
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
ctx.scrollRequestTracker = {
|
|
1592
|
+
isCurrent: (token) => token === currentToken,
|
|
1593
|
+
runNow,
|
|
1594
|
+
runNowIfIdle: (run) => {
|
|
1595
|
+
const state = ctx.state;
|
|
1596
|
+
if (state.pendingScrollResolve || state.scrollingTo) {
|
|
1597
|
+
return Promise.resolve();
|
|
1598
|
+
}
|
|
1599
|
+
return new Promise((resolve) => {
|
|
1600
|
+
const token = start(resolve);
|
|
1601
|
+
runNow(token, resolve, run);
|
|
1602
|
+
});
|
|
1603
|
+
},
|
|
1604
|
+
start
|
|
1605
|
+
};
|
|
1601
1606
|
}
|
|
1602
|
-
|
|
1603
|
-
return false;
|
|
1607
|
+
return ctx.scrollRequestTracker;
|
|
1604
1608
|
}
|
|
1605
1609
|
|
|
1606
1610
|
// src/utils/requestAdjust.ts
|
|
1607
|
-
function requestAdjust(ctx, positionDiff,
|
|
1611
|
+
function requestAdjust(ctx, positionDiff, source) {
|
|
1608
1612
|
const state = ctx.state;
|
|
1609
1613
|
if (Math.abs(positionDiff) > 0.1) {
|
|
1614
|
+
const dataChanged = source === "data";
|
|
1610
1615
|
const needsScrollWorkaround = Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
|
|
1611
1616
|
const doit = () => {
|
|
1612
1617
|
if (needsScrollWorkaround) {
|
|
@@ -1623,7 +1628,7 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
1623
1628
|
const readyToRender = peek$(ctx, "readyToRender");
|
|
1624
1629
|
if (readyToRender) {
|
|
1625
1630
|
doit();
|
|
1626
|
-
if (Platform.OS !== "web") {
|
|
1631
|
+
if (Platform.OS !== "web" && source !== "item-size") {
|
|
1627
1632
|
const threshold = state.scroll - positionDiff / 2;
|
|
1628
1633
|
if (!state.ignoreScrollFromMVCP) {
|
|
1629
1634
|
state.ignoreScrollFromMVCP = {};
|
|
@@ -1656,6 +1661,87 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
|
1656
1661
|
}
|
|
1657
1662
|
}
|
|
1658
1663
|
|
|
1664
|
+
// src/core/doMaintainScrollAtEnd.ts
|
|
1665
|
+
function finishMaintainScrollAtEnd(ctx) {
|
|
1666
|
+
var _a3;
|
|
1667
|
+
const { state } = ctx;
|
|
1668
|
+
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1669
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1670
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1671
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1672
|
+
if (currentPadding !== nextPadding) {
|
|
1673
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1674
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1675
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1676
|
+
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1677
|
+
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
function doMaintainScrollAtEnd(ctx) {
|
|
1681
|
+
const state = ctx.state;
|
|
1682
|
+
const {
|
|
1683
|
+
didContainersLayout,
|
|
1684
|
+
didFinishInitialScroll,
|
|
1685
|
+
pendingNativeMVCPAdjust,
|
|
1686
|
+
props: { maintainScrollAtEnd }
|
|
1687
|
+
} = state;
|
|
1688
|
+
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1689
|
+
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1690
|
+
const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1691
|
+
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1692
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1693
|
+
return false;
|
|
1694
|
+
}
|
|
1695
|
+
if (pendingNativeMVCPAdjust) {
|
|
1696
|
+
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1697
|
+
return false;
|
|
1698
|
+
}
|
|
1699
|
+
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1700
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1701
|
+
const contentSize = getContentSize(ctx);
|
|
1702
|
+
if (contentSize < state.scrollLength) {
|
|
1703
|
+
state.scroll = 0;
|
|
1704
|
+
}
|
|
1705
|
+
if (!state.maintainingScrollAtEnd) {
|
|
1706
|
+
const pendingState = maintainScrollAtEnd.animated ? "pending-animated" : "pending-instant";
|
|
1707
|
+
const activeState = maintainScrollAtEnd.animated ? "animated" : "instant";
|
|
1708
|
+
const scrollAtRequest = state.scroll;
|
|
1709
|
+
state.maintainingScrollAtEnd = pendingState;
|
|
1710
|
+
requestAnimationFrame(() => {
|
|
1711
|
+
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1712
|
+
return;
|
|
1713
|
+
}
|
|
1714
|
+
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1715
|
+
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1716
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1717
|
+
state.maintainingScrollAtEnd = activeState;
|
|
1718
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1719
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1720
|
+
);
|
|
1721
|
+
void scrollPromise.then(() => {
|
|
1722
|
+
if (state.maintainingScrollAtEnd !== activeState) {
|
|
1723
|
+
return;
|
|
1724
|
+
}
|
|
1725
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
1726
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1727
|
+
doMaintainScrollAtEnd(ctx);
|
|
1728
|
+
} else {
|
|
1729
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1730
|
+
}
|
|
1731
|
+
});
|
|
1732
|
+
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1733
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1734
|
+
}
|
|
1735
|
+
});
|
|
1736
|
+
} else {
|
|
1737
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1738
|
+
}
|
|
1739
|
+
return true;
|
|
1740
|
+
}
|
|
1741
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1742
|
+
return false;
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1659
1745
|
// src/core/mvcp.ts
|
|
1660
1746
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
1661
1747
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -1729,7 +1815,7 @@ function settlePendingNativeMVCPAdjust(ctx, remainingAfterManual, nativeDelta) {
|
|
|
1729
1815
|
state.pendingNativeMVCPAdjust = void 0;
|
|
1730
1816
|
const remaining = remainingAfterManual - nativeDelta;
|
|
1731
1817
|
if (Math.abs(remaining) > MVCP_POSITION_EPSILON) {
|
|
1732
|
-
requestAdjust(ctx, remaining,
|
|
1818
|
+
requestAdjust(ctx, remaining, "data");
|
|
1733
1819
|
}
|
|
1734
1820
|
}
|
|
1735
1821
|
function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
@@ -1748,7 +1834,7 @@ function maybeApplyPredictedNativeMVCPAdjust(ctx) {
|
|
|
1748
1834
|
return;
|
|
1749
1835
|
}
|
|
1750
1836
|
pending.manualApplied = manualDesired;
|
|
1751
|
-
requestAdjust(ctx, manualDesired,
|
|
1837
|
+
requestAdjust(ctx, manualDesired, "data");
|
|
1752
1838
|
pending.furthestProgressTowardAmount = 0;
|
|
1753
1839
|
}
|
|
1754
1840
|
function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
@@ -1794,7 +1880,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
|
1794
1880
|
}
|
|
1795
1881
|
return false;
|
|
1796
1882
|
}
|
|
1797
|
-
function prepareMVCP(ctx, dataChanged) {
|
|
1883
|
+
function prepareMVCP(ctx, dataChanged, adjustmentSource) {
|
|
1798
1884
|
const state = ctx.state;
|
|
1799
1885
|
const { idsInView, positions, props } = state;
|
|
1800
1886
|
const {
|
|
@@ -1948,7 +2034,7 @@ function prepareMVCP(ctx, dataChanged) {
|
|
|
1948
2034
|
if (Math.abs(positionDiff) > MVCP_POSITION_EPSILON) {
|
|
1949
2035
|
const shouldSkipAdjustForMaintainedEnd = (state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated") && peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1950
2036
|
if (!shouldSkipAdjustForMaintainedEnd) {
|
|
1951
|
-
requestAdjust(ctx, positionDiff, dataChanged && mvcpData);
|
|
2037
|
+
requestAdjust(ctx, positionDiff, dataChanged && mvcpData ? "data" : adjustmentSource);
|
|
1952
2038
|
}
|
|
1953
2039
|
}
|
|
1954
2040
|
};
|
|
@@ -2046,6 +2132,10 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2046
2132
|
state.scrollTime = currentTime;
|
|
2047
2133
|
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
2048
2134
|
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
2135
|
+
const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
2136
|
+
if (didCancelMaintainScrollAtEnd) {
|
|
2137
|
+
finishMaintainScrollAtEnd(ctx);
|
|
2138
|
+
}
|
|
2049
2139
|
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
2050
2140
|
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
2051
2141
|
const scrollLength = state.scrollLength;
|
|
@@ -2054,7 +2144,7 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2054
2144
|
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
2055
2145
|
const lastCalculated = state.scrollLastCalculate;
|
|
2056
2146
|
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
2057
|
-
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2147
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
2058
2148
|
if (shouldUpdate) {
|
|
2059
2149
|
state.scrollLastCalculate = state.scroll;
|
|
2060
2150
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
@@ -2883,7 +2973,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2883
2973
|
}
|
|
2884
2974
|
}
|
|
2885
2975
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2886
|
-
var _a3, _b
|
|
2976
|
+
var _a3, _b;
|
|
2887
2977
|
const state = ctx.state;
|
|
2888
2978
|
const initialScroll = state.initialScroll;
|
|
2889
2979
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2897,19 +2987,15 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2897
2987
|
if (state.didFinishInitialScroll) {
|
|
2898
2988
|
schedulePreservedEndAnchorCorrection(ctx);
|
|
2899
2989
|
} else if (scrollingTo) {
|
|
2900
|
-
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2901
|
-
scrollingTo.offset = resolvedOffset;
|
|
2902
|
-
scrollingTo.targetOffset = resolvedOffset;
|
|
2903
2990
|
state.initialScroll = {
|
|
2904
2991
|
...initialScroll,
|
|
2905
2992
|
contentOffset: resolvedOffset
|
|
2906
2993
|
};
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2994
|
+
dispatchInitialScroll(ctx, {
|
|
2995
|
+
forceScroll: true,
|
|
2996
|
+
resolvedOffset,
|
|
2997
|
+
target: state.initialScroll
|
|
2911
2998
|
});
|
|
2912
|
-
requestAdjust(ctx, offsetDiff);
|
|
2913
2999
|
}
|
|
2914
3000
|
}
|
|
2915
3001
|
} else {
|
|
@@ -3951,6 +4037,9 @@ function setDidLayout(ctx) {
|
|
|
3951
4037
|
state.queuedInitialLayout = true;
|
|
3952
4038
|
checkAtBottom(ctx);
|
|
3953
4039
|
setInitialRenderState(ctx, { didLayout: true });
|
|
4040
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
4041
|
+
doMaintainScrollAtEnd(ctx);
|
|
4042
|
+
}
|
|
3954
4043
|
}
|
|
3955
4044
|
|
|
3956
4045
|
// src/core/calculateItemsInView.ts
|
|
@@ -4187,7 +4276,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4187
4276
|
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
|
|
4188
4277
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4189
4278
|
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4190
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4279
|
+
const { dataChanged, doMVCP, forceFullItemPositions, mvcpAdjustmentSource } = params;
|
|
4191
4280
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
4192
4281
|
const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
|
|
4193
4282
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
@@ -4288,7 +4377,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4288
4377
|
}
|
|
4289
4378
|
}
|
|
4290
4379
|
}
|
|
4291
|
-
const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged) : void 0;
|
|
4380
|
+
const checkMVCP = doMVCP && !suppressInitialScrollSideEffects ? prepareMVCP(ctx, dataChanged, mvcpAdjustmentSource) : void 0;
|
|
4292
4381
|
if (dataChanged) {
|
|
4293
4382
|
resetLayoutCachesForDataChange(state);
|
|
4294
4383
|
}
|
|
@@ -4702,12 +4791,15 @@ function runOrScheduleMVCPRecalculate(ctx) {
|
|
|
4702
4791
|
} else if (Platform.OS === "web") {
|
|
4703
4792
|
if (!state.mvcpAnchorLock) {
|
|
4704
4793
|
state.scheduledWork.cancel("mvcpRecalculate");
|
|
4705
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
4794
|
+
calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
|
|
4706
4795
|
} else if (!state.scheduledWork.has("mvcpRecalculate")) {
|
|
4707
|
-
state.scheduledWork.frame(
|
|
4796
|
+
state.scheduledWork.frame(
|
|
4797
|
+
() => calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" }),
|
|
4798
|
+
"mvcpRecalculate"
|
|
4799
|
+
);
|
|
4708
4800
|
}
|
|
4709
4801
|
} else {
|
|
4710
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
4802
|
+
calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
|
|
4711
4803
|
}
|
|
4712
4804
|
}
|
|
4713
4805
|
function updateOtherAxisSizeIfNeeded(ctx, sizeObj, horizontal) {
|
|
@@ -4833,7 +4925,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4833
4925
|
if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
|
|
4834
4926
|
needsRecalculate = true;
|
|
4835
4927
|
}
|
|
4836
|
-
if (prevSizeKnown
|
|
4928
|
+
if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
|
|
4837
4929
|
shouldMaintainScrollAtEnd = true;
|
|
4838
4930
|
}
|
|
4839
4931
|
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
@@ -5196,6 +5288,30 @@ function useContainerItemSignals(containerContext) {
|
|
|
5196
5288
|
itemKey
|
|
5197
5289
|
};
|
|
5198
5290
|
}
|
|
5291
|
+
function scheduleViewabilityConfigWarning(ctx, hookName, configId) {
|
|
5292
|
+
let cancelled = false;
|
|
5293
|
+
Promise.resolve().then(() => {
|
|
5294
|
+
var _a3;
|
|
5295
|
+
const viewabilityConfigCallbackPairs = (_a3 = ctx.state) == null ? void 0 : _a3.viewabilityConfigCallbackPairs;
|
|
5296
|
+
if (!cancelled && ctx.state) {
|
|
5297
|
+
if (!(viewabilityConfigCallbackPairs == null ? void 0 : viewabilityConfigCallbackPairs.length)) {
|
|
5298
|
+
warnDevOnce(
|
|
5299
|
+
`${hookName}-missing-viewability-config`,
|
|
5300
|
+
`${hookName} requires viewability to be configured on the owning LegendList. Add viewabilityConfig with a visibility threshold.`
|
|
5301
|
+
);
|
|
5302
|
+
} else if (hookName === "useViewability" && !viewabilityConfigCallbackPairs.some((pair) => pair.viewabilityConfig.id === (configId != null ? configId : ""))) {
|
|
5303
|
+
const configDescription = configId ? ` for configId "${configId}"` : "";
|
|
5304
|
+
warnDevOnce(
|
|
5305
|
+
`${hookName}-missing-viewability-config-${configId != null ? configId : "default"}`,
|
|
5306
|
+
`${hookName}${configDescription} requires a matching viewabilityConfig.id on the owning LegendList. Add an id to viewabilityConfig and pass the same id to useViewability.`
|
|
5307
|
+
);
|
|
5308
|
+
}
|
|
5309
|
+
}
|
|
5310
|
+
});
|
|
5311
|
+
return () => {
|
|
5312
|
+
cancelled = true;
|
|
5313
|
+
};
|
|
5314
|
+
}
|
|
5199
5315
|
function useAdaptiveRender() {
|
|
5200
5316
|
const [mode] = useArr$(["adaptiveRender"]);
|
|
5201
5317
|
return mode;
|
|
@@ -5235,7 +5351,9 @@ function useViewability(callback, configId) {
|
|
|
5235
5351
|
const { containerId } = containerContext;
|
|
5236
5352
|
const key = containerId + (configId != null ? configId : "");
|
|
5237
5353
|
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
5354
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewability", configId) : void 0;
|
|
5238
5355
|
return () => {
|
|
5356
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5239
5357
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
5240
5358
|
};
|
|
5241
5359
|
}, [ctx, callback, configId, containerContext]);
|
|
@@ -5259,7 +5377,9 @@ function useViewabilityAmount(callback) {
|
|
|
5259
5377
|
}
|
|
5260
5378
|
const { containerId } = containerContext;
|
|
5261
5379
|
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
5380
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewabilityAmount") : void 0;
|
|
5262
5381
|
return () => {
|
|
5382
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5263
5383
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
5264
5384
|
};
|
|
5265
5385
|
}, [ctx, callback, containerContext]);
|
|
@@ -5683,13 +5803,11 @@ var ContainerSlot = typedMemo(function ContainerSlot2(props) {
|
|
|
5683
5803
|
return /* @__PURE__ */ React2__namespace.createElement(ContainerSlotBase, { ...props });
|
|
5684
5804
|
});
|
|
5685
5805
|
function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
|
|
5686
|
-
const completedTransitionEpoch = React2.
|
|
5687
|
-
const isTransitionPending = completedTransitionEpoch
|
|
5806
|
+
const [completedTransitionEpoch, setCompletedTransitionEpoch] = React2.useState(transitionEpoch);
|
|
5807
|
+
const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
|
|
5688
5808
|
React2.useLayoutEffect(() => {
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
}
|
|
5692
|
-
}, [readyToRender, transitionEpoch]);
|
|
5809
|
+
setCompletedTransitionEpoch(transitionEpoch);
|
|
5810
|
+
}, [transitionEpoch]);
|
|
5693
5811
|
return readyToRender && !isTransitionPending;
|
|
5694
5812
|
}
|
|
5695
5813
|
|
|
@@ -6368,11 +6486,29 @@ var ScheduledWork = class {
|
|
|
6368
6486
|
constructor() {
|
|
6369
6487
|
this.work = /* @__PURE__ */ new Map();
|
|
6370
6488
|
}
|
|
6489
|
+
microtask(callback, key) {
|
|
6490
|
+
const pendingWork = this.work.get(key);
|
|
6491
|
+
if (pendingWork == null ? void 0 : pendingWork.callback) {
|
|
6492
|
+
pendingWork.callback = callback;
|
|
6493
|
+
} else {
|
|
6494
|
+
this.cancel(key);
|
|
6495
|
+
const work = { callback, cancel: () => {
|
|
6496
|
+
} };
|
|
6497
|
+
this.work.set(key, work);
|
|
6498
|
+
queueMicrotask(() => {
|
|
6499
|
+
var _a3;
|
|
6500
|
+
if (this.work.get(key) === work) {
|
|
6501
|
+
this.work.delete(key);
|
|
6502
|
+
(_a3 = work.callback) == null ? void 0 : _a3.call(work);
|
|
6503
|
+
}
|
|
6504
|
+
});
|
|
6505
|
+
}
|
|
6506
|
+
}
|
|
6371
6507
|
timeout(callback, delay, key) {
|
|
6372
6508
|
if (key) {
|
|
6373
6509
|
this.cancel(key);
|
|
6374
6510
|
}
|
|
6375
|
-
const work =
|
|
6511
|
+
const work = { cancel: () => clearTimeout(handle) };
|
|
6376
6512
|
const handle = setTimeout(() => {
|
|
6377
6513
|
const workKey = key != null ? key : handle;
|
|
6378
6514
|
if (this.work.get(workKey) === work) {
|
|
@@ -6380,14 +6516,13 @@ var ScheduledWork = class {
|
|
|
6380
6516
|
callback();
|
|
6381
6517
|
}
|
|
6382
6518
|
}, delay);
|
|
6383
|
-
work[0] = handle;
|
|
6384
6519
|
this.work.set(key != null ? key : handle, work);
|
|
6385
6520
|
}
|
|
6386
6521
|
frame(callback, key) {
|
|
6387
6522
|
this.cancel(key);
|
|
6388
|
-
const work =
|
|
6523
|
+
const work = { cancel: () => cancelAnimationFrame(handle) };
|
|
6389
6524
|
this.work.set(key, work);
|
|
6390
|
-
|
|
6525
|
+
const handle = requestAnimationFrame(() => {
|
|
6391
6526
|
if (this.work.get(key) === work) {
|
|
6392
6527
|
this.work.delete(key);
|
|
6393
6528
|
callback();
|
|
@@ -6396,21 +6531,21 @@ var ScheduledWork = class {
|
|
|
6396
6531
|
}
|
|
6397
6532
|
register(key, cancel) {
|
|
6398
6533
|
this.cancel(key);
|
|
6399
|
-
this.work.set(key,
|
|
6534
|
+
this.work.set(key, { cancel });
|
|
6400
6535
|
}
|
|
6401
6536
|
cancel(key) {
|
|
6402
6537
|
const work = this.work.get(key);
|
|
6403
6538
|
if (work) {
|
|
6404
6539
|
this.work.delete(key);
|
|
6405
|
-
work
|
|
6540
|
+
work.cancel();
|
|
6406
6541
|
}
|
|
6407
6542
|
}
|
|
6408
6543
|
has(key) {
|
|
6409
6544
|
return this.work.has(key);
|
|
6410
6545
|
}
|
|
6411
6546
|
dispose() {
|
|
6412
|
-
for (const
|
|
6413
|
-
cancel(
|
|
6547
|
+
for (const work of this.work.values()) {
|
|
6548
|
+
work.cancel();
|
|
6414
6549
|
}
|
|
6415
6550
|
this.work.clear();
|
|
6416
6551
|
}
|
|
@@ -6467,6 +6602,25 @@ var ScrollAdjustHandler = class {
|
|
|
6467
6602
|
}
|
|
6468
6603
|
};
|
|
6469
6604
|
|
|
6605
|
+
// src/core/scrollToEnd.ts
|
|
6606
|
+
function scrollToEnd(ctx, options) {
|
|
6607
|
+
const state = ctx.state;
|
|
6608
|
+
const data = state.props.data;
|
|
6609
|
+
const index = data.length - 1;
|
|
6610
|
+
if (index === -1) {
|
|
6611
|
+
return false;
|
|
6612
|
+
}
|
|
6613
|
+
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
6614
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
6615
|
+
scrollToIndex(ctx, {
|
|
6616
|
+
...options,
|
|
6617
|
+
index,
|
|
6618
|
+
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
6619
|
+
viewPosition: 1
|
|
6620
|
+
});
|
|
6621
|
+
return true;
|
|
6622
|
+
}
|
|
6623
|
+
|
|
6470
6624
|
// src/core/updateContentInsetEndAdjustment.ts
|
|
6471
6625
|
function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
|
|
6472
6626
|
const state = ctx.state;
|
|
@@ -6541,25 +6695,6 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
6541
6695
|
}
|
|
6542
6696
|
}
|
|
6543
6697
|
|
|
6544
|
-
// src/core/scrollToEnd.ts
|
|
6545
|
-
function scrollToEnd(ctx, options) {
|
|
6546
|
-
const state = ctx.state;
|
|
6547
|
-
const data = state.props.data;
|
|
6548
|
-
const index = data.length - 1;
|
|
6549
|
-
if (index === -1) {
|
|
6550
|
-
return false;
|
|
6551
|
-
}
|
|
6552
|
-
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
6553
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
6554
|
-
scrollToIndex(ctx, {
|
|
6555
|
-
...options,
|
|
6556
|
-
index,
|
|
6557
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
6558
|
-
viewPosition: 1
|
|
6559
|
-
});
|
|
6560
|
-
return true;
|
|
6561
|
-
}
|
|
6562
|
-
|
|
6563
6698
|
// src/utils/createImperativeHandle.ts
|
|
6564
6699
|
var DEFAULT_AVERAGE_ITEM_SIZE_TYPE = "default";
|
|
6565
6700
|
function getAverageItemSizes(state) {
|
|
@@ -6586,9 +6721,9 @@ function triggerMountedContainerLayouts(ctx) {
|
|
|
6586
6721
|
}
|
|
6587
6722
|
function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
6588
6723
|
const state = ctx.state;
|
|
6724
|
+
const scrollRequestTracker = getScrollRequestTracker(ctx);
|
|
6589
6725
|
const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
|
|
6590
6726
|
const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
|
|
6591
|
-
let imperativeScrollToken = 0;
|
|
6592
6727
|
const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.scheduledWork.has("mvcpRecalculate") || state.ignoreScrollFromMVCP !== void 0;
|
|
6593
6728
|
const isScrollToIndexReady = (targetIndex, allowEmpty = false) => {
|
|
6594
6729
|
var _a3;
|
|
@@ -6610,7 +6745,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6610
6745
|
const startedAt = Date.now();
|
|
6611
6746
|
let stableFrames = 0;
|
|
6612
6747
|
const check = () => {
|
|
6613
|
-
if (token
|
|
6748
|
+
if (!scrollRequestTracker.isCurrent(token)) {
|
|
6614
6749
|
return;
|
|
6615
6750
|
}
|
|
6616
6751
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
@@ -6628,40 +6763,23 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6628
6763
|
state.scheduledWork.frame(check, "imperativeScrollReady");
|
|
6629
6764
|
};
|
|
6630
6765
|
const runScrollRequest = (token, resolve, run, isReady = () => true) => {
|
|
6631
|
-
const runNow = () =>
|
|
6632
|
-
if (token !== imperativeScrollToken) {
|
|
6633
|
-
return;
|
|
6634
|
-
}
|
|
6635
|
-
const didStartScroll = run();
|
|
6636
|
-
if (!didStartScroll || !state.scrollingTo) {
|
|
6637
|
-
if (state.pendingScrollResolve === resolve) {
|
|
6638
|
-
state.pendingScrollResolve = void 0;
|
|
6639
|
-
}
|
|
6640
|
-
resolve();
|
|
6641
|
-
}
|
|
6642
|
-
};
|
|
6766
|
+
const runNow = () => scrollRequestTracker.runNow(token, resolve, run);
|
|
6643
6767
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
6644
6768
|
runWhenReady(token, runNow, isReady);
|
|
6645
6769
|
} else {
|
|
6646
6770
|
runNow();
|
|
6647
6771
|
}
|
|
6648
6772
|
};
|
|
6649
|
-
const startImperativeScroll = (resolve) => {
|
|
6650
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
6651
|
-
const token = ++imperativeScrollToken;
|
|
6652
|
-
settlePendingImperativeScroll(state);
|
|
6653
|
-
state.pendingScrollResolve = resolve;
|
|
6654
|
-
return token;
|
|
6655
|
-
};
|
|
6656
6773
|
const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
|
|
6657
|
-
const token =
|
|
6774
|
+
const token = scrollRequestTracker.start(resolve);
|
|
6775
|
+
supersedeInitialScroll(ctx);
|
|
6658
6776
|
runScrollRequest(token, resolve, run, isReady);
|
|
6659
6777
|
});
|
|
6660
6778
|
state.runPendingScrollToEnd = () => {
|
|
6661
6779
|
const pendingScroll = state.pendingScrollToEnd;
|
|
6662
6780
|
if (pendingScroll) {
|
|
6663
6781
|
state.pendingScrollToEnd = void 0;
|
|
6664
|
-
if (pendingScroll.token
|
|
6782
|
+
if (scrollRequestTracker.isCurrent(pendingScroll.token)) {
|
|
6665
6783
|
runScrollRequest(
|
|
6666
6784
|
pendingScroll.token,
|
|
6667
6785
|
pendingScroll.resolve,
|
|
@@ -6775,15 +6893,15 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
6775
6893
|
}),
|
|
6776
6894
|
scrollToEnd: (options) => new Promise((resolve) => {
|
|
6777
6895
|
var _a3;
|
|
6778
|
-
const token =
|
|
6896
|
+
const token = scrollRequestTracker.start(resolve);
|
|
6779
6897
|
state.pendingScrollToEnd = {
|
|
6780
6898
|
options,
|
|
6781
6899
|
resolve,
|
|
6782
6900
|
token
|
|
6783
6901
|
};
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6902
|
+
scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
|
|
6903
|
+
supersedeInitialScroll(ctx);
|
|
6904
|
+
if (!scheduleImperativeScrollCommit) {
|
|
6787
6905
|
(_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
|
|
6788
6906
|
}
|
|
6789
6907
|
}),
|
|
@@ -7155,6 +7273,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7155
7273
|
const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
|
|
7156
7274
|
const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
|
|
7157
7275
|
const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
|
|
7276
|
+
const shouldBottomAlignNumericInitialScrollIndex = typeof initialScrollIndexProp === "number" && !hasInitialScrollOffset && dataProp.length > 1 && initialScrollIndexProp >= dataProp.length - 1;
|
|
7158
7277
|
const initialScrollProp = initialScrollAtEnd ? {
|
|
7159
7278
|
index: Math.max(0, dataProp.length - 1),
|
|
7160
7279
|
preserveForBottomPadding: true,
|
|
@@ -7167,7 +7286,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7167
7286
|
viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
|
|
7168
7287
|
} : {
|
|
7169
7288
|
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
7170
|
-
|
|
7289
|
+
preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
|
|
7290
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? -stylePaddingEndState : 0,
|
|
7291
|
+
viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
|
|
7171
7292
|
} : initialScrollUsesOffsetOnly ? {
|
|
7172
7293
|
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
7173
7294
|
index: 0,
|
|
@@ -7273,6 +7394,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7273
7394
|
viewabilityConfigCallbackPairs: void 0
|
|
7274
7395
|
};
|
|
7275
7396
|
const internalState = ctx.state;
|
|
7397
|
+
ctx.scrollToEnd = (options) => scrollToEnd(ctx, options);
|
|
7276
7398
|
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
7277
7399
|
internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
|
|
7278
7400
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
|
|
@@ -7634,6 +7756,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7634
7756
|
onScroll: (event) => onScroll(ctx, event),
|
|
7635
7757
|
onScrollBeginDrag: (event) => {
|
|
7636
7758
|
var _a4, _b2;
|
|
7759
|
+
const maintainingScrollAtEnd = state.maintainingScrollAtEnd;
|
|
7760
|
+
if (maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant") {
|
|
7761
|
+
cancelImperativeScroll(state);
|
|
7762
|
+
}
|
|
7763
|
+
if (maintainingScrollAtEnd) {
|
|
7764
|
+
finishMaintainScrollAtEnd(ctx);
|
|
7765
|
+
}
|
|
7637
7766
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
7638
7767
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
7639
7768
|
},
|