@legendapp/list 3.3.5 → 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 +6 -0
- package/package.json +1 -1
- package/react-native.js +259 -147
- package/react-native.mjs +259 -147
- package/react-native.web.js +240 -129
- package/react-native.web.mjs +240 -129
- package/react.js +240 -129
- package/react.mjs +240 -129
- package/.DS_Store +0 -0
package/react.js
CHANGED
|
@@ -76,10 +76,6 @@ function getStylePaddingEnd(props) {
|
|
|
76
76
|
}
|
|
77
77
|
return (isHorizontalRTLProps(props) ? props.stylePaddingLeft : props.stylePaddingRight) || 0;
|
|
78
78
|
}
|
|
79
|
-
function getLogicalHorizontalMaxOffset(state, contentWidth) {
|
|
80
|
-
var _a3;
|
|
81
|
-
return (_a3 = getHorizontalMaxOffset(state, contentWidth)) != null ? _a3 : 0;
|
|
82
|
-
}
|
|
83
79
|
function getHorizontalInsetEnd(state, inset) {
|
|
84
80
|
if (!inset) {
|
|
85
81
|
return 0;
|
|
@@ -710,6 +706,12 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
710
706
|
} = state;
|
|
711
707
|
const contentSize = getContentSize(ctx);
|
|
712
708
|
resetSharedEdgeGateIfOutsideHysteresis(ctx);
|
|
709
|
+
if (state.props.data.length === 0 && scrollLength > 0 && contentSize <= scrollLength) {
|
|
710
|
+
set$(ctx, "isAtEnd", true);
|
|
711
|
+
set$(ctx, "isNearEnd", true);
|
|
712
|
+
set$(ctx, "isWithinMaintainScrollAtEndThreshold", true);
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
713
715
|
if (contentSize > 0 && queuedInitialLayout) {
|
|
714
716
|
const insetEnd = getContentInsetEnd(ctx);
|
|
715
717
|
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
@@ -719,7 +721,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
719
721
|
set$(
|
|
720
722
|
ctx,
|
|
721
723
|
"isWithinMaintainScrollAtEndThreshold",
|
|
722
|
-
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength
|
|
724
|
+
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant"
|
|
723
725
|
);
|
|
724
726
|
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
|
|
725
727
|
if (!shouldSkipThresholdChecks) {
|
|
@@ -1064,10 +1066,22 @@ function getAlignItemsAtEndPadding(ctx) {
|
|
|
1064
1066
|
return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
|
|
1065
1067
|
}
|
|
1066
1068
|
function updateContentMetricsState(ctx) {
|
|
1069
|
+
var _a3;
|
|
1070
|
+
const { state } = ctx;
|
|
1067
1071
|
const previousPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1068
1072
|
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1069
1073
|
if (previousPadding !== nextPadding) {
|
|
1070
|
-
|
|
1074
|
+
const isAnimatedMaintainActive = state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated";
|
|
1075
|
+
const isMaintainExpected = state.didContainersLayout && ((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.animated) && (isAnimatedMaintainActive || previousPadding > nextPadding && peek$(ctx, "isWithinMaintainScrollAtEndThreshold"));
|
|
1076
|
+
if (isMaintainExpected && !isAnimatedMaintainActive && !state.pendingMaintainScrollAtEnd) {
|
|
1077
|
+
state.scheduledWork.microtask(() => {
|
|
1078
|
+
if (!state.maintainingScrollAtEnd && !state.pendingMaintainScrollAtEnd) {
|
|
1079
|
+
set$(ctx, "alignItemsAtEndPadding", getAlignItemsAtEndPadding(ctx));
|
|
1080
|
+
}
|
|
1081
|
+
}, "alignItemsAtEndPaddingFallback");
|
|
1082
|
+
} else if (!isMaintainExpected) {
|
|
1083
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1084
|
+
}
|
|
1071
1085
|
}
|
|
1072
1086
|
}
|
|
1073
1087
|
|
|
@@ -1425,22 +1439,110 @@ function listenForScrollEnd(ctx, params) {
|
|
|
1425
1439
|
scheduledWork.register("platformScrollCompletion", cancel);
|
|
1426
1440
|
}
|
|
1427
1441
|
|
|
1442
|
+
// src/core/scrollRequestTracker.ts
|
|
1443
|
+
function getScrollRequestTracker(ctx) {
|
|
1444
|
+
if (!ctx.scrollRequestTracker) {
|
|
1445
|
+
let currentToken = 0;
|
|
1446
|
+
const start = (resolve) => {
|
|
1447
|
+
const state = ctx.state;
|
|
1448
|
+
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1449
|
+
const token = ++currentToken;
|
|
1450
|
+
settlePendingImperativeScroll(state);
|
|
1451
|
+
state.pendingScrollResolve = resolve;
|
|
1452
|
+
return token;
|
|
1453
|
+
};
|
|
1454
|
+
const runNow = (token, resolve, run) => {
|
|
1455
|
+
const state = ctx.state;
|
|
1456
|
+
if (token !== currentToken) {
|
|
1457
|
+
return;
|
|
1458
|
+
}
|
|
1459
|
+
const didStartScroll = run();
|
|
1460
|
+
if (!didStartScroll || !state.scrollingTo) {
|
|
1461
|
+
if (state.pendingScrollResolve === resolve) {
|
|
1462
|
+
state.pendingScrollResolve = void 0;
|
|
1463
|
+
}
|
|
1464
|
+
resolve();
|
|
1465
|
+
}
|
|
1466
|
+
};
|
|
1467
|
+
ctx.scrollRequestTracker = {
|
|
1468
|
+
isCurrent: (token) => token === currentToken,
|
|
1469
|
+
runNow,
|
|
1470
|
+
runNowIfIdle: (run) => {
|
|
1471
|
+
const state = ctx.state;
|
|
1472
|
+
if (state.pendingScrollResolve || state.scrollingTo) {
|
|
1473
|
+
return Promise.resolve();
|
|
1474
|
+
}
|
|
1475
|
+
return new Promise((resolve) => {
|
|
1476
|
+
const token = start(resolve);
|
|
1477
|
+
runNow(token, resolve, run);
|
|
1478
|
+
});
|
|
1479
|
+
},
|
|
1480
|
+
start
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1483
|
+
return ctx.scrollRequestTracker;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// src/utils/requestAdjust.ts
|
|
1487
|
+
function requestAdjust(ctx, positionDiff, source) {
|
|
1488
|
+
const state = ctx.state;
|
|
1489
|
+
if (Math.abs(positionDiff) > 0.1) {
|
|
1490
|
+
const doit = () => {
|
|
1491
|
+
{
|
|
1492
|
+
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1493
|
+
if (state.adjustingFromInitialMount) {
|
|
1494
|
+
state.adjustingFromInitialMount--;
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
state.scroll += positionDiff;
|
|
1499
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1500
|
+
const readyToRender = peek$(ctx, "readyToRender");
|
|
1501
|
+
if (readyToRender) {
|
|
1502
|
+
doit();
|
|
1503
|
+
} else {
|
|
1504
|
+
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
1505
|
+
requestAnimationFrame(doit);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1428
1510
|
// src/core/doMaintainScrollAtEnd.ts
|
|
1511
|
+
function finishMaintainScrollAtEnd(ctx) {
|
|
1512
|
+
var _a3;
|
|
1513
|
+
const { state } = ctx;
|
|
1514
|
+
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1515
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1516
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1517
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1518
|
+
if (currentPadding !== nextPadding) {
|
|
1519
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1520
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1521
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1522
|
+
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1523
|
+
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1429
1526
|
function doMaintainScrollAtEnd(ctx) {
|
|
1430
1527
|
const state = ctx.state;
|
|
1431
1528
|
const {
|
|
1432
1529
|
didContainersLayout,
|
|
1530
|
+
didFinishInitialScroll,
|
|
1433
1531
|
pendingNativeMVCPAdjust,
|
|
1434
|
-
refScroller,
|
|
1435
1532
|
props: { maintainScrollAtEnd }
|
|
1436
1533
|
} = state;
|
|
1437
1534
|
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1438
|
-
const
|
|
1535
|
+
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1536
|
+
const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1537
|
+
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1538
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1539
|
+
return false;
|
|
1540
|
+
}
|
|
1439
1541
|
if (pendingNativeMVCPAdjust) {
|
|
1440
1542
|
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1441
1543
|
return false;
|
|
1442
1544
|
}
|
|
1443
|
-
if (shouldMaintainScrollAtEnd) {
|
|
1545
|
+
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1444
1546
|
state.pendingMaintainScrollAtEnd = false;
|
|
1445
1547
|
const contentSize = getContentSize(ctx);
|
|
1446
1548
|
if (contentSize < state.scrollLength) {
|
|
@@ -1452,39 +1554,29 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1452
1554
|
const scrollAtRequest = state.scroll;
|
|
1453
1555
|
state.maintainingScrollAtEnd = pendingState;
|
|
1454
1556
|
requestAnimationFrame(() => {
|
|
1557
|
+
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1455
1560
|
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1456
1561
|
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1457
|
-
if (isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1562
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1458
1563
|
state.maintainingScrollAtEnd = activeState;
|
|
1459
|
-
const
|
|
1460
|
-
|
|
1461
|
-
const currentContentSize = getContentSize(ctx);
|
|
1462
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
1463
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
1464
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
1465
|
-
animated: maintainScrollAtEnd.animated,
|
|
1466
|
-
x: nativeOffset,
|
|
1467
|
-
y: 0
|
|
1468
|
-
});
|
|
1469
|
-
} else {
|
|
1470
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
1471
|
-
animated: maintainScrollAtEnd.animated
|
|
1472
|
-
});
|
|
1473
|
-
}
|
|
1474
|
-
setTimeout(
|
|
1475
|
-
() => {
|
|
1476
|
-
if (state.maintainingScrollAtEnd === activeState) {
|
|
1477
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1478
|
-
if (state.pendingMaintainScrollAtEnd) {
|
|
1479
|
-
doMaintainScrollAtEnd(ctx);
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
},
|
|
1483
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
1564
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1565
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1484
1566
|
);
|
|
1567
|
+
void scrollPromise.then(() => {
|
|
1568
|
+
if (state.maintainingScrollAtEnd !== activeState) {
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
1572
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1573
|
+
doMaintainScrollAtEnd(ctx);
|
|
1574
|
+
} else {
|
|
1575
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1485
1578
|
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1486
|
-
|
|
1487
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1579
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1488
1580
|
}
|
|
1489
1581
|
});
|
|
1490
1582
|
} else {
|
|
@@ -1492,34 +1584,10 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1492
1584
|
}
|
|
1493
1585
|
return true;
|
|
1494
1586
|
}
|
|
1495
|
-
|
|
1587
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1496
1588
|
return false;
|
|
1497
1589
|
}
|
|
1498
1590
|
|
|
1499
|
-
// src/utils/requestAdjust.ts
|
|
1500
|
-
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
1501
|
-
const state = ctx.state;
|
|
1502
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
1503
|
-
const doit = () => {
|
|
1504
|
-
{
|
|
1505
|
-
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1506
|
-
if (state.adjustingFromInitialMount) {
|
|
1507
|
-
state.adjustingFromInitialMount--;
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
};
|
|
1511
|
-
state.scroll += positionDiff;
|
|
1512
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1513
|
-
const readyToRender = peek$(ctx, "readyToRender");
|
|
1514
|
-
if (readyToRender) {
|
|
1515
|
-
doit();
|
|
1516
|
-
} else {
|
|
1517
|
-
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
1518
|
-
requestAnimationFrame(doit);
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
1591
|
// src/core/mvcp.ts
|
|
1524
1592
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
1525
1593
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -1656,7 +1724,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
|
1656
1724
|
}
|
|
1657
1725
|
return false;
|
|
1658
1726
|
}
|
|
1659
|
-
function prepareMVCP(ctx, dataChanged) {
|
|
1727
|
+
function prepareMVCP(ctx, dataChanged, adjustmentSource) {
|
|
1660
1728
|
const state = ctx.state;
|
|
1661
1729
|
const { idsInView, positions, props } = state;
|
|
1662
1730
|
const {
|
|
@@ -1908,6 +1976,10 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
1908
1976
|
state.scrollTime = currentTime;
|
|
1909
1977
|
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1910
1978
|
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
1979
|
+
const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
1980
|
+
if (didCancelMaintainScrollAtEnd) {
|
|
1981
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1982
|
+
}
|
|
1911
1983
|
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
1912
1984
|
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
1913
1985
|
const scrollLength = state.scrollLength;
|
|
@@ -1916,7 +1988,7 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
1916
1988
|
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
1917
1989
|
const lastCalculated = state.scrollLastCalculate;
|
|
1918
1990
|
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1919
|
-
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1991
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1920
1992
|
if (shouldUpdate) {
|
|
1921
1993
|
state.scrollLastCalculate = state.scroll;
|
|
1922
1994
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
@@ -2745,7 +2817,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2745
2817
|
}
|
|
2746
2818
|
}
|
|
2747
2819
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2748
|
-
var _a3, _b
|
|
2820
|
+
var _a3, _b;
|
|
2749
2821
|
const state = ctx.state;
|
|
2750
2822
|
const initialScroll = state.initialScroll;
|
|
2751
2823
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2759,19 +2831,15 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2759
2831
|
if (state.didFinishInitialScroll) {
|
|
2760
2832
|
schedulePreservedEndAnchorCorrection(ctx);
|
|
2761
2833
|
} else if (scrollingTo) {
|
|
2762
|
-
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2763
|
-
scrollingTo.offset = resolvedOffset;
|
|
2764
|
-
scrollingTo.targetOffset = resolvedOffset;
|
|
2765
2834
|
state.initialScroll = {
|
|
2766
2835
|
...initialScroll,
|
|
2767
2836
|
contentOffset: resolvedOffset
|
|
2768
2837
|
};
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2838
|
+
dispatchInitialScroll(ctx, {
|
|
2839
|
+
forceScroll: true,
|
|
2840
|
+
resolvedOffset,
|
|
2841
|
+
target: state.initialScroll
|
|
2773
2842
|
});
|
|
2774
|
-
requestAdjust(ctx, offsetDiff);
|
|
2775
2843
|
}
|
|
2776
2844
|
}
|
|
2777
2845
|
} else {
|
|
@@ -3998,6 +4066,9 @@ function setDidLayout(ctx) {
|
|
|
3998
4066
|
state.queuedInitialLayout = true;
|
|
3999
4067
|
checkAtBottom(ctx);
|
|
4000
4068
|
setInitialRenderState(ctx, { didLayout: true });
|
|
4069
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
4070
|
+
doMaintainScrollAtEnd(ctx);
|
|
4071
|
+
}
|
|
4001
4072
|
}
|
|
4002
4073
|
|
|
4003
4074
|
// src/core/calculateItemsInView.ts
|
|
@@ -4234,7 +4305,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4234
4305
|
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
|
|
4235
4306
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4236
4307
|
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4237
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4308
|
+
const { dataChanged, doMVCP, forceFullItemPositions, mvcpAdjustmentSource } = params;
|
|
4238
4309
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
4239
4310
|
const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
|
|
4240
4311
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
@@ -4738,9 +4809,12 @@ function runOrScheduleMVCPRecalculate(ctx) {
|
|
|
4738
4809
|
} else {
|
|
4739
4810
|
if (!state.mvcpAnchorLock) {
|
|
4740
4811
|
state.scheduledWork.cancel("mvcpRecalculate");
|
|
4741
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
4812
|
+
calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
|
|
4742
4813
|
} else if (!state.scheduledWork.has("mvcpRecalculate")) {
|
|
4743
|
-
state.scheduledWork.frame(
|
|
4814
|
+
state.scheduledWork.frame(
|
|
4815
|
+
() => calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" }),
|
|
4816
|
+
"mvcpRecalculate"
|
|
4817
|
+
);
|
|
4744
4818
|
}
|
|
4745
4819
|
}
|
|
4746
4820
|
}
|
|
@@ -5107,6 +5181,30 @@ function useContainerItemSignals(containerContext) {
|
|
|
5107
5181
|
itemKey
|
|
5108
5182
|
};
|
|
5109
5183
|
}
|
|
5184
|
+
function scheduleViewabilityConfigWarning(ctx, hookName, configId) {
|
|
5185
|
+
let cancelled = false;
|
|
5186
|
+
Promise.resolve().then(() => {
|
|
5187
|
+
var _a3;
|
|
5188
|
+
const viewabilityConfigCallbackPairs = (_a3 = ctx.state) == null ? void 0 : _a3.viewabilityConfigCallbackPairs;
|
|
5189
|
+
if (!cancelled && ctx.state) {
|
|
5190
|
+
if (!(viewabilityConfigCallbackPairs == null ? void 0 : viewabilityConfigCallbackPairs.length)) {
|
|
5191
|
+
warnDevOnce(
|
|
5192
|
+
`${hookName}-missing-viewability-config`,
|
|
5193
|
+
`${hookName} requires viewability to be configured on the owning LegendList. Add viewabilityConfig with a visibility threshold.`
|
|
5194
|
+
);
|
|
5195
|
+
} else if (hookName === "useViewability" && !viewabilityConfigCallbackPairs.some((pair) => pair.viewabilityConfig.id === (configId != null ? configId : ""))) {
|
|
5196
|
+
const configDescription = configId ? ` for configId "${configId}"` : "";
|
|
5197
|
+
warnDevOnce(
|
|
5198
|
+
`${hookName}-missing-viewability-config-${configId != null ? configId : "default"}`,
|
|
5199
|
+
`${hookName}${configDescription} requires a matching viewabilityConfig.id on the owning LegendList. Add an id to viewabilityConfig and pass the same id to useViewability.`
|
|
5200
|
+
);
|
|
5201
|
+
}
|
|
5202
|
+
}
|
|
5203
|
+
});
|
|
5204
|
+
return () => {
|
|
5205
|
+
cancelled = true;
|
|
5206
|
+
};
|
|
5207
|
+
}
|
|
5110
5208
|
function useAdaptiveRender() {
|
|
5111
5209
|
const [mode] = useArr$(["adaptiveRender"]);
|
|
5112
5210
|
return mode;
|
|
@@ -5146,7 +5244,9 @@ function useViewability(callback, configId) {
|
|
|
5146
5244
|
const { containerId } = containerContext;
|
|
5147
5245
|
const key = containerId + (configId != null ? configId : "");
|
|
5148
5246
|
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
5247
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewability", configId) : void 0;
|
|
5149
5248
|
return () => {
|
|
5249
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5150
5250
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
5151
5251
|
};
|
|
5152
5252
|
}, [ctx, callback, configId, containerContext]);
|
|
@@ -5170,7 +5270,9 @@ function useViewabilityAmount(callback) {
|
|
|
5170
5270
|
}
|
|
5171
5271
|
const { containerId } = containerContext;
|
|
5172
5272
|
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
5273
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewabilityAmount") : void 0;
|
|
5173
5274
|
return () => {
|
|
5275
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5174
5276
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
5175
5277
|
};
|
|
5176
5278
|
}, [ctx, callback, containerContext]);
|
|
@@ -7043,11 +7145,29 @@ var ScheduledWork = class {
|
|
|
7043
7145
|
constructor() {
|
|
7044
7146
|
this.work = /* @__PURE__ */ new Map();
|
|
7045
7147
|
}
|
|
7148
|
+
microtask(callback, key) {
|
|
7149
|
+
const pendingWork = this.work.get(key);
|
|
7150
|
+
if (pendingWork == null ? void 0 : pendingWork.callback) {
|
|
7151
|
+
pendingWork.callback = callback;
|
|
7152
|
+
} else {
|
|
7153
|
+
this.cancel(key);
|
|
7154
|
+
const work = { callback, cancel: () => {
|
|
7155
|
+
} };
|
|
7156
|
+
this.work.set(key, work);
|
|
7157
|
+
queueMicrotask(() => {
|
|
7158
|
+
var _a3;
|
|
7159
|
+
if (this.work.get(key) === work) {
|
|
7160
|
+
this.work.delete(key);
|
|
7161
|
+
(_a3 = work.callback) == null ? void 0 : _a3.call(work);
|
|
7162
|
+
}
|
|
7163
|
+
});
|
|
7164
|
+
}
|
|
7165
|
+
}
|
|
7046
7166
|
timeout(callback, delay, key) {
|
|
7047
7167
|
if (key) {
|
|
7048
7168
|
this.cancel(key);
|
|
7049
7169
|
}
|
|
7050
|
-
const work =
|
|
7170
|
+
const work = { cancel: () => clearTimeout(handle) };
|
|
7051
7171
|
const handle = setTimeout(() => {
|
|
7052
7172
|
const workKey = key != null ? key : handle;
|
|
7053
7173
|
if (this.work.get(workKey) === work) {
|
|
@@ -7055,14 +7175,13 @@ var ScheduledWork = class {
|
|
|
7055
7175
|
callback();
|
|
7056
7176
|
}
|
|
7057
7177
|
}, delay);
|
|
7058
|
-
work[0] = handle;
|
|
7059
7178
|
this.work.set(key != null ? key : handle, work);
|
|
7060
7179
|
}
|
|
7061
7180
|
frame(callback, key) {
|
|
7062
7181
|
this.cancel(key);
|
|
7063
|
-
const work =
|
|
7182
|
+
const work = { cancel: () => cancelAnimationFrame(handle) };
|
|
7064
7183
|
this.work.set(key, work);
|
|
7065
|
-
|
|
7184
|
+
const handle = requestAnimationFrame(() => {
|
|
7066
7185
|
if (this.work.get(key) === work) {
|
|
7067
7186
|
this.work.delete(key);
|
|
7068
7187
|
callback();
|
|
@@ -7071,22 +7190,21 @@ var ScheduledWork = class {
|
|
|
7071
7190
|
}
|
|
7072
7191
|
register(key, cancel) {
|
|
7073
7192
|
this.cancel(key);
|
|
7074
|
-
this.work.set(key,
|
|
7193
|
+
this.work.set(key, { cancel });
|
|
7075
7194
|
}
|
|
7076
7195
|
cancel(key) {
|
|
7077
7196
|
const work = this.work.get(key);
|
|
7078
7197
|
if (work) {
|
|
7079
7198
|
this.work.delete(key);
|
|
7080
|
-
|
|
7081
|
-
cancel(handle);
|
|
7199
|
+
work.cancel();
|
|
7082
7200
|
}
|
|
7083
7201
|
}
|
|
7084
7202
|
has(key) {
|
|
7085
7203
|
return this.work.has(key);
|
|
7086
7204
|
}
|
|
7087
7205
|
dispose() {
|
|
7088
|
-
for (const
|
|
7089
|
-
cancel(
|
|
7206
|
+
for (const work of this.work.values()) {
|
|
7207
|
+
work.cancel();
|
|
7090
7208
|
}
|
|
7091
7209
|
this.work.clear();
|
|
7092
7210
|
}
|
|
@@ -7143,6 +7261,25 @@ var ScrollAdjustHandler = class {
|
|
|
7143
7261
|
}
|
|
7144
7262
|
};
|
|
7145
7263
|
|
|
7264
|
+
// src/core/scrollToEnd.ts
|
|
7265
|
+
function scrollToEnd(ctx, options) {
|
|
7266
|
+
const state = ctx.state;
|
|
7267
|
+
const data = state.props.data;
|
|
7268
|
+
const index = data.length - 1;
|
|
7269
|
+
if (index === -1) {
|
|
7270
|
+
return false;
|
|
7271
|
+
}
|
|
7272
|
+
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
7273
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
7274
|
+
scrollToIndex(ctx, {
|
|
7275
|
+
...options,
|
|
7276
|
+
index,
|
|
7277
|
+
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
7278
|
+
viewPosition: 1
|
|
7279
|
+
});
|
|
7280
|
+
return true;
|
|
7281
|
+
}
|
|
7282
|
+
|
|
7146
7283
|
// src/core/updateContentInsetEndAdjustment.ts
|
|
7147
7284
|
function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
|
|
7148
7285
|
const state = ctx.state;
|
|
@@ -7205,25 +7342,6 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
7205
7342
|
}
|
|
7206
7343
|
}
|
|
7207
7344
|
|
|
7208
|
-
// src/core/scrollToEnd.ts
|
|
7209
|
-
function scrollToEnd(ctx, options) {
|
|
7210
|
-
const state = ctx.state;
|
|
7211
|
-
const data = state.props.data;
|
|
7212
|
-
const index = data.length - 1;
|
|
7213
|
-
if (index === -1) {
|
|
7214
|
-
return false;
|
|
7215
|
-
}
|
|
7216
|
-
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
7217
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
7218
|
-
scrollToIndex(ctx, {
|
|
7219
|
-
...options,
|
|
7220
|
-
index,
|
|
7221
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
7222
|
-
viewPosition: 1
|
|
7223
|
-
});
|
|
7224
|
-
return true;
|
|
7225
|
-
}
|
|
7226
|
-
|
|
7227
7345
|
// src/utils/createImperativeHandle.ts
|
|
7228
7346
|
var DEFAULT_AVERAGE_ITEM_SIZE_TYPE = "default";
|
|
7229
7347
|
function getAverageItemSizes(state) {
|
|
@@ -7246,9 +7364,9 @@ function triggerMountedContainerLayouts(ctx) {
|
|
|
7246
7364
|
}
|
|
7247
7365
|
function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
7248
7366
|
const state = ctx.state;
|
|
7367
|
+
const scrollRequestTracker = getScrollRequestTracker(ctx);
|
|
7249
7368
|
const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
|
|
7250
7369
|
const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
|
|
7251
|
-
let imperativeScrollToken = 0;
|
|
7252
7370
|
const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.scheduledWork.has("mvcpRecalculate") || state.ignoreScrollFromMVCP !== void 0;
|
|
7253
7371
|
const isScrollToIndexReady = (targetIndex, allowEmpty = false) => {
|
|
7254
7372
|
var _a3;
|
|
@@ -7270,7 +7388,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7270
7388
|
const startedAt = Date.now();
|
|
7271
7389
|
let stableFrames = 0;
|
|
7272
7390
|
const check = () => {
|
|
7273
|
-
if (token
|
|
7391
|
+
if (!scrollRequestTracker.isCurrent(token)) {
|
|
7274
7392
|
return;
|
|
7275
7393
|
}
|
|
7276
7394
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
@@ -7288,33 +7406,15 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7288
7406
|
state.scheduledWork.frame(check, "imperativeScrollReady");
|
|
7289
7407
|
};
|
|
7290
7408
|
const runScrollRequest = (token, resolve, run, isReady = () => true) => {
|
|
7291
|
-
const runNow = () =>
|
|
7292
|
-
if (token !== imperativeScrollToken) {
|
|
7293
|
-
return;
|
|
7294
|
-
}
|
|
7295
|
-
const didStartScroll = run();
|
|
7296
|
-
if (!didStartScroll || !state.scrollingTo) {
|
|
7297
|
-
if (state.pendingScrollResolve === resolve) {
|
|
7298
|
-
state.pendingScrollResolve = void 0;
|
|
7299
|
-
}
|
|
7300
|
-
resolve();
|
|
7301
|
-
}
|
|
7302
|
-
};
|
|
7409
|
+
const runNow = () => scrollRequestTracker.runNow(token, resolve, run);
|
|
7303
7410
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
7304
7411
|
runWhenReady(token, runNow, isReady);
|
|
7305
7412
|
} else {
|
|
7306
7413
|
runNow();
|
|
7307
7414
|
}
|
|
7308
7415
|
};
|
|
7309
|
-
const startImperativeScroll = (resolve) => {
|
|
7310
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
7311
|
-
const token = ++imperativeScrollToken;
|
|
7312
|
-
settlePendingImperativeScroll(state);
|
|
7313
|
-
state.pendingScrollResolve = resolve;
|
|
7314
|
-
return token;
|
|
7315
|
-
};
|
|
7316
7416
|
const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
|
|
7317
|
-
const token =
|
|
7417
|
+
const token = scrollRequestTracker.start(resolve);
|
|
7318
7418
|
supersedeInitialScroll(ctx);
|
|
7319
7419
|
runScrollRequest(token, resolve, run, isReady);
|
|
7320
7420
|
});
|
|
@@ -7322,7 +7422,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7322
7422
|
const pendingScroll = state.pendingScrollToEnd;
|
|
7323
7423
|
if (pendingScroll) {
|
|
7324
7424
|
state.pendingScrollToEnd = void 0;
|
|
7325
|
-
if (pendingScroll.token
|
|
7425
|
+
if (scrollRequestTracker.isCurrent(pendingScroll.token)) {
|
|
7326
7426
|
runScrollRequest(
|
|
7327
7427
|
pendingScroll.token,
|
|
7328
7428
|
pendingScroll.resolve,
|
|
@@ -7436,7 +7536,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7436
7536
|
}),
|
|
7437
7537
|
scrollToEnd: (options) => new Promise((resolve) => {
|
|
7438
7538
|
var _a3;
|
|
7439
|
-
const token =
|
|
7539
|
+
const token = scrollRequestTracker.start(resolve);
|
|
7440
7540
|
state.pendingScrollToEnd = {
|
|
7441
7541
|
options,
|
|
7442
7542
|
resolve,
|
|
@@ -7816,6 +7916,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7816
7916
|
const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
|
|
7817
7917
|
const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
|
|
7818
7918
|
const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
|
|
7919
|
+
const shouldBottomAlignNumericInitialScrollIndex = typeof initialScrollIndexProp === "number" && !hasInitialScrollOffset && dataProp.length > 1 && initialScrollIndexProp >= dataProp.length - 1;
|
|
7819
7920
|
const initialScrollProp = initialScrollAtEnd ? {
|
|
7820
7921
|
index: Math.max(0, dataProp.length - 1),
|
|
7821
7922
|
preserveForBottomPadding: true,
|
|
@@ -7828,7 +7929,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7828
7929
|
viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
|
|
7829
7930
|
} : {
|
|
7830
7931
|
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
7831
|
-
|
|
7932
|
+
preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
|
|
7933
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? -stylePaddingEndState : 0,
|
|
7934
|
+
viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
|
|
7832
7935
|
} : initialScrollUsesOffsetOnly ? {
|
|
7833
7936
|
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
7834
7937
|
index: 0,
|
|
@@ -7934,6 +8037,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7934
8037
|
viewabilityConfigCallbackPairs: void 0
|
|
7935
8038
|
};
|
|
7936
8039
|
const internalState = ctx.state;
|
|
8040
|
+
ctx.scrollToEnd = (options) => scrollToEnd(ctx, options);
|
|
7937
8041
|
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
7938
8042
|
internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
|
|
7939
8043
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
|
|
@@ -8287,6 +8391,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
8287
8391
|
onScroll: (event) => onScroll(ctx, event),
|
|
8288
8392
|
onScrollBeginDrag: (event) => {
|
|
8289
8393
|
var _a4, _b2;
|
|
8394
|
+
const maintainingScrollAtEnd = state.maintainingScrollAtEnd;
|
|
8395
|
+
if (maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant") {
|
|
8396
|
+
cancelImperativeScroll(state);
|
|
8397
|
+
}
|
|
8398
|
+
if (maintainingScrollAtEnd) {
|
|
8399
|
+
finishMaintainScrollAtEnd(ctx);
|
|
8400
|
+
}
|
|
8290
8401
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
8291
8402
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
8292
8403
|
},
|