@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-native.web.mjs
CHANGED
|
@@ -55,10 +55,6 @@ function getStylePaddingEnd(props) {
|
|
|
55
55
|
}
|
|
56
56
|
return (isHorizontalRTLProps(props) ? props.stylePaddingLeft : props.stylePaddingRight) || 0;
|
|
57
57
|
}
|
|
58
|
-
function getLogicalHorizontalMaxOffset(state, contentWidth) {
|
|
59
|
-
var _a3;
|
|
60
|
-
return (_a3 = getHorizontalMaxOffset(state, contentWidth)) != null ? _a3 : 0;
|
|
61
|
-
}
|
|
62
58
|
function getHorizontalInsetEnd(state, inset) {
|
|
63
59
|
if (!inset) {
|
|
64
60
|
return 0;
|
|
@@ -689,6 +685,12 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
689
685
|
} = state;
|
|
690
686
|
const contentSize = getContentSize(ctx);
|
|
691
687
|
resetSharedEdgeGateIfOutsideHysteresis(ctx);
|
|
688
|
+
if (state.props.data.length === 0 && scrollLength > 0 && contentSize <= scrollLength) {
|
|
689
|
+
set$(ctx, "isAtEnd", true);
|
|
690
|
+
set$(ctx, "isNearEnd", true);
|
|
691
|
+
set$(ctx, "isWithinMaintainScrollAtEndThreshold", true);
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
692
694
|
if (contentSize > 0 && queuedInitialLayout) {
|
|
693
695
|
const insetEnd = getContentInsetEnd(ctx);
|
|
694
696
|
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
@@ -698,7 +700,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
698
700
|
set$(
|
|
699
701
|
ctx,
|
|
700
702
|
"isWithinMaintainScrollAtEndThreshold",
|
|
701
|
-
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength
|
|
703
|
+
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant"
|
|
702
704
|
);
|
|
703
705
|
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
|
|
704
706
|
if (!shouldSkipThresholdChecks) {
|
|
@@ -1043,10 +1045,22 @@ function getAlignItemsAtEndPadding(ctx) {
|
|
|
1043
1045
|
return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
|
|
1044
1046
|
}
|
|
1045
1047
|
function updateContentMetricsState(ctx) {
|
|
1048
|
+
var _a3;
|
|
1049
|
+
const { state } = ctx;
|
|
1046
1050
|
const previousPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1047
1051
|
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1048
1052
|
if (previousPadding !== nextPadding) {
|
|
1049
|
-
|
|
1053
|
+
const isAnimatedMaintainActive = state.maintainingScrollAtEnd === "pending-animated" || state.maintainingScrollAtEnd === "animated";
|
|
1054
|
+
const isMaintainExpected = state.didContainersLayout && ((_a3 = state.props.maintainScrollAtEnd) == null ? void 0 : _a3.animated) && (isAnimatedMaintainActive || previousPadding > nextPadding && peek$(ctx, "isWithinMaintainScrollAtEndThreshold"));
|
|
1055
|
+
if (isMaintainExpected && !isAnimatedMaintainActive && !state.pendingMaintainScrollAtEnd) {
|
|
1056
|
+
state.scheduledWork.microtask(() => {
|
|
1057
|
+
if (!state.maintainingScrollAtEnd && !state.pendingMaintainScrollAtEnd) {
|
|
1058
|
+
set$(ctx, "alignItemsAtEndPadding", getAlignItemsAtEndPadding(ctx));
|
|
1059
|
+
}
|
|
1060
|
+
}, "alignItemsAtEndPaddingFallback");
|
|
1061
|
+
} else if (!isMaintainExpected) {
|
|
1062
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1063
|
+
}
|
|
1050
1064
|
}
|
|
1051
1065
|
}
|
|
1052
1066
|
|
|
@@ -1404,22 +1418,110 @@ function listenForScrollEnd(ctx, params) {
|
|
|
1404
1418
|
scheduledWork.register("platformScrollCompletion", cancel);
|
|
1405
1419
|
}
|
|
1406
1420
|
|
|
1421
|
+
// src/core/scrollRequestTracker.ts
|
|
1422
|
+
function getScrollRequestTracker(ctx) {
|
|
1423
|
+
if (!ctx.scrollRequestTracker) {
|
|
1424
|
+
let currentToken = 0;
|
|
1425
|
+
const start = (resolve) => {
|
|
1426
|
+
const state = ctx.state;
|
|
1427
|
+
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1428
|
+
const token = ++currentToken;
|
|
1429
|
+
settlePendingImperativeScroll(state);
|
|
1430
|
+
state.pendingScrollResolve = resolve;
|
|
1431
|
+
return token;
|
|
1432
|
+
};
|
|
1433
|
+
const runNow = (token, resolve, run) => {
|
|
1434
|
+
const state = ctx.state;
|
|
1435
|
+
if (token !== currentToken) {
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
const didStartScroll = run();
|
|
1439
|
+
if (!didStartScroll || !state.scrollingTo) {
|
|
1440
|
+
if (state.pendingScrollResolve === resolve) {
|
|
1441
|
+
state.pendingScrollResolve = void 0;
|
|
1442
|
+
}
|
|
1443
|
+
resolve();
|
|
1444
|
+
}
|
|
1445
|
+
};
|
|
1446
|
+
ctx.scrollRequestTracker = {
|
|
1447
|
+
isCurrent: (token) => token === currentToken,
|
|
1448
|
+
runNow,
|
|
1449
|
+
runNowIfIdle: (run) => {
|
|
1450
|
+
const state = ctx.state;
|
|
1451
|
+
if (state.pendingScrollResolve || state.scrollingTo) {
|
|
1452
|
+
return Promise.resolve();
|
|
1453
|
+
}
|
|
1454
|
+
return new Promise((resolve) => {
|
|
1455
|
+
const token = start(resolve);
|
|
1456
|
+
runNow(token, resolve, run);
|
|
1457
|
+
});
|
|
1458
|
+
},
|
|
1459
|
+
start
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
return ctx.scrollRequestTracker;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
// src/utils/requestAdjust.ts
|
|
1466
|
+
function requestAdjust(ctx, positionDiff, source) {
|
|
1467
|
+
const state = ctx.state;
|
|
1468
|
+
if (Math.abs(positionDiff) > 0.1) {
|
|
1469
|
+
const doit = () => {
|
|
1470
|
+
{
|
|
1471
|
+
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1472
|
+
if (state.adjustingFromInitialMount) {
|
|
1473
|
+
state.adjustingFromInitialMount--;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
};
|
|
1477
|
+
state.scroll += positionDiff;
|
|
1478
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1479
|
+
const readyToRender = peek$(ctx, "readyToRender");
|
|
1480
|
+
if (readyToRender) {
|
|
1481
|
+
doit();
|
|
1482
|
+
} else {
|
|
1483
|
+
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
1484
|
+
requestAnimationFrame(doit);
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1407
1489
|
// src/core/doMaintainScrollAtEnd.ts
|
|
1490
|
+
function finishMaintainScrollAtEnd(ctx) {
|
|
1491
|
+
var _a3;
|
|
1492
|
+
const { state } = ctx;
|
|
1493
|
+
const currentPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1494
|
+
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1495
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1496
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1497
|
+
if (currentPadding !== nextPadding) {
|
|
1498
|
+
set$(ctx, "alignItemsAtEndPadding", nextPadding);
|
|
1499
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
1500
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { forceFullItemPositions: true });
|
|
1501
|
+
const nextScroll = clampScrollOffset(ctx, state.scroll + nextPadding - currentPadding);
|
|
1502
|
+
requestAdjust(ctx, nextScroll - state.scroll);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1408
1505
|
function doMaintainScrollAtEnd(ctx) {
|
|
1409
1506
|
const state = ctx.state;
|
|
1410
1507
|
const {
|
|
1411
1508
|
didContainersLayout,
|
|
1509
|
+
didFinishInitialScroll,
|
|
1412
1510
|
pendingNativeMVCPAdjust,
|
|
1413
|
-
refScroller,
|
|
1414
1511
|
props: { maintainScrollAtEnd }
|
|
1415
1512
|
} = state;
|
|
1416
1513
|
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1417
|
-
const
|
|
1514
|
+
const isReplayingPendingMaintain = !!state.pendingMaintainScrollAtEnd;
|
|
1515
|
+
const shouldMaintainScrollAtEnd = !!((isWithinMaintainScrollAtEndThreshold || isReplayingPendingMaintain) && maintainScrollAtEnd && didFinishInitialScroll);
|
|
1516
|
+
if (shouldMaintainScrollAtEnd && !didContainersLayout) {
|
|
1517
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1518
|
+
return false;
|
|
1519
|
+
}
|
|
1418
1520
|
if (pendingNativeMVCPAdjust) {
|
|
1419
1521
|
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1420
1522
|
return false;
|
|
1421
1523
|
}
|
|
1422
|
-
if (shouldMaintainScrollAtEnd) {
|
|
1524
|
+
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1423
1525
|
state.pendingMaintainScrollAtEnd = false;
|
|
1424
1526
|
const contentSize = getContentSize(ctx);
|
|
1425
1527
|
if (contentSize < state.scrollLength) {
|
|
@@ -1431,39 +1533,29 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1431
1533
|
const scrollAtRequest = state.scroll;
|
|
1432
1534
|
state.maintainingScrollAtEnd = pendingState;
|
|
1433
1535
|
requestAnimationFrame(() => {
|
|
1536
|
+
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1434
1539
|
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1435
1540
|
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1436
|
-
if (isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1541
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1437
1542
|
state.maintainingScrollAtEnd = activeState;
|
|
1438
|
-
const
|
|
1439
|
-
|
|
1440
|
-
const currentContentSize = getContentSize(ctx);
|
|
1441
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
1442
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
1443
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
1444
|
-
animated: maintainScrollAtEnd.animated,
|
|
1445
|
-
x: nativeOffset,
|
|
1446
|
-
y: 0
|
|
1447
|
-
});
|
|
1448
|
-
} else {
|
|
1449
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
1450
|
-
animated: maintainScrollAtEnd.animated
|
|
1451
|
-
});
|
|
1452
|
-
}
|
|
1453
|
-
setTimeout(
|
|
1454
|
-
() => {
|
|
1455
|
-
if (state.maintainingScrollAtEnd === activeState) {
|
|
1456
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1457
|
-
if (state.pendingMaintainScrollAtEnd) {
|
|
1458
|
-
doMaintainScrollAtEnd(ctx);
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
},
|
|
1462
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
1543
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1544
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1463
1545
|
);
|
|
1546
|
+
void scrollPromise.then(() => {
|
|
1547
|
+
if (state.maintainingScrollAtEnd !== activeState) {
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
1551
|
+
state.maintainingScrollAtEnd = void 0;
|
|
1552
|
+
doMaintainScrollAtEnd(ctx);
|
|
1553
|
+
} else {
|
|
1554
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1555
|
+
}
|
|
1556
|
+
});
|
|
1464
1557
|
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1465
|
-
|
|
1466
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1558
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1467
1559
|
}
|
|
1468
1560
|
});
|
|
1469
1561
|
} else {
|
|
@@ -1471,34 +1563,10 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1471
1563
|
}
|
|
1472
1564
|
return true;
|
|
1473
1565
|
}
|
|
1474
|
-
|
|
1566
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1475
1567
|
return false;
|
|
1476
1568
|
}
|
|
1477
1569
|
|
|
1478
|
-
// src/utils/requestAdjust.ts
|
|
1479
|
-
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
1480
|
-
const state = ctx.state;
|
|
1481
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
1482
|
-
const doit = () => {
|
|
1483
|
-
{
|
|
1484
|
-
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1485
|
-
if (state.adjustingFromInitialMount) {
|
|
1486
|
-
state.adjustingFromInitialMount--;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
};
|
|
1490
|
-
state.scroll += positionDiff;
|
|
1491
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1492
|
-
const readyToRender = peek$(ctx, "readyToRender");
|
|
1493
|
-
if (readyToRender) {
|
|
1494
|
-
doit();
|
|
1495
|
-
} else {
|
|
1496
|
-
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
1497
|
-
requestAnimationFrame(doit);
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
1570
|
// src/core/mvcp.ts
|
|
1503
1571
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
1504
1572
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -1635,7 +1703,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
|
1635
1703
|
}
|
|
1636
1704
|
return false;
|
|
1637
1705
|
}
|
|
1638
|
-
function prepareMVCP(ctx, dataChanged) {
|
|
1706
|
+
function prepareMVCP(ctx, dataChanged, adjustmentSource) {
|
|
1639
1707
|
const state = ctx.state;
|
|
1640
1708
|
const { idsInView, positions, props } = state;
|
|
1641
1709
|
const {
|
|
@@ -1887,6 +1955,10 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
1887
1955
|
state.scrollTime = currentTime;
|
|
1888
1956
|
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1889
1957
|
const isUserScrollEvent = !!(options == null ? void 0 : options.fromNativeScrollEvent) && scrollDelta > 0.1 && !adjustChanged && scrollingTo === void 0 && !state.pendingNativeMVCPAdjust;
|
|
1958
|
+
const didCancelMaintainScrollAtEnd = isUserScrollEvent && newScroll < prevScroll && !!(state.maintainingScrollAtEnd || state.pendingMaintainScrollAtEnd);
|
|
1959
|
+
if (didCancelMaintainScrollAtEnd) {
|
|
1960
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1961
|
+
}
|
|
1890
1962
|
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
1891
1963
|
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
1892
1964
|
const scrollLength = state.scrollLength;
|
|
@@ -1895,7 +1967,7 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
1895
1967
|
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
1896
1968
|
const lastCalculated = state.scrollLastCalculate;
|
|
1897
1969
|
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1898
|
-
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1970
|
+
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || didCancelMaintainScrollAtEnd || allowedEdge !== void 0 || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
1899
1971
|
if (shouldUpdate) {
|
|
1900
1972
|
state.scrollLastCalculate = state.scroll;
|
|
1901
1973
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
@@ -2724,7 +2796,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2724
2796
|
}
|
|
2725
2797
|
}
|
|
2726
2798
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2727
|
-
var _a3, _b
|
|
2799
|
+
var _a3, _b;
|
|
2728
2800
|
const state = ctx.state;
|
|
2729
2801
|
const initialScroll = state.initialScroll;
|
|
2730
2802
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2738,19 +2810,15 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2738
2810
|
if (state.didFinishInitialScroll) {
|
|
2739
2811
|
schedulePreservedEndAnchorCorrection(ctx);
|
|
2740
2812
|
} else if (scrollingTo) {
|
|
2741
|
-
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2742
|
-
scrollingTo.offset = resolvedOffset;
|
|
2743
|
-
scrollingTo.targetOffset = resolvedOffset;
|
|
2744
2813
|
state.initialScroll = {
|
|
2745
2814
|
...initialScroll,
|
|
2746
2815
|
contentOffset: resolvedOffset
|
|
2747
2816
|
};
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2817
|
+
dispatchInitialScroll(ctx, {
|
|
2818
|
+
forceScroll: true,
|
|
2819
|
+
resolvedOffset,
|
|
2820
|
+
target: state.initialScroll
|
|
2752
2821
|
});
|
|
2753
|
-
requestAdjust(ctx, offsetDiff);
|
|
2754
2822
|
}
|
|
2755
2823
|
}
|
|
2756
2824
|
} else {
|
|
@@ -3977,6 +4045,9 @@ function setDidLayout(ctx) {
|
|
|
3977
4045
|
state.queuedInitialLayout = true;
|
|
3978
4046
|
checkAtBottom(ctx);
|
|
3979
4047
|
setInitialRenderState(ctx, { didLayout: true });
|
|
4048
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
4049
|
+
doMaintainScrollAtEnd(ctx);
|
|
4050
|
+
}
|
|
3980
4051
|
}
|
|
3981
4052
|
|
|
3982
4053
|
// src/core/calculateItemsInView.ts
|
|
@@ -4213,7 +4284,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4213
4284
|
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
|
|
4214
4285
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4215
4286
|
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4216
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4287
|
+
const { dataChanged, doMVCP, forceFullItemPositions, mvcpAdjustmentSource } = params;
|
|
4217
4288
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
4218
4289
|
const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
|
|
4219
4290
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
@@ -4717,9 +4788,12 @@ function runOrScheduleMVCPRecalculate(ctx) {
|
|
|
4717
4788
|
} else {
|
|
4718
4789
|
if (!state.mvcpAnchorLock) {
|
|
4719
4790
|
state.scheduledWork.cancel("mvcpRecalculate");
|
|
4720
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
4791
|
+
calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
|
|
4721
4792
|
} else if (!state.scheduledWork.has("mvcpRecalculate")) {
|
|
4722
|
-
state.scheduledWork.frame(
|
|
4793
|
+
state.scheduledWork.frame(
|
|
4794
|
+
() => calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" }),
|
|
4795
|
+
"mvcpRecalculate"
|
|
4796
|
+
);
|
|
4723
4797
|
}
|
|
4724
4798
|
}
|
|
4725
4799
|
}
|
|
@@ -5086,6 +5160,30 @@ function useContainerItemSignals(containerContext) {
|
|
|
5086
5160
|
itemKey
|
|
5087
5161
|
};
|
|
5088
5162
|
}
|
|
5163
|
+
function scheduleViewabilityConfigWarning(ctx, hookName, configId) {
|
|
5164
|
+
let cancelled = false;
|
|
5165
|
+
Promise.resolve().then(() => {
|
|
5166
|
+
var _a3;
|
|
5167
|
+
const viewabilityConfigCallbackPairs = (_a3 = ctx.state) == null ? void 0 : _a3.viewabilityConfigCallbackPairs;
|
|
5168
|
+
if (!cancelled && ctx.state) {
|
|
5169
|
+
if (!(viewabilityConfigCallbackPairs == null ? void 0 : viewabilityConfigCallbackPairs.length)) {
|
|
5170
|
+
warnDevOnce(
|
|
5171
|
+
`${hookName}-missing-viewability-config`,
|
|
5172
|
+
`${hookName} requires viewability to be configured on the owning LegendList. Add viewabilityConfig with a visibility threshold.`
|
|
5173
|
+
);
|
|
5174
|
+
} else if (hookName === "useViewability" && !viewabilityConfigCallbackPairs.some((pair) => pair.viewabilityConfig.id === (configId != null ? configId : ""))) {
|
|
5175
|
+
const configDescription = configId ? ` for configId "${configId}"` : "";
|
|
5176
|
+
warnDevOnce(
|
|
5177
|
+
`${hookName}-missing-viewability-config-${configId != null ? configId : "default"}`,
|
|
5178
|
+
`${hookName}${configDescription} requires a matching viewabilityConfig.id on the owning LegendList. Add an id to viewabilityConfig and pass the same id to useViewability.`
|
|
5179
|
+
);
|
|
5180
|
+
}
|
|
5181
|
+
}
|
|
5182
|
+
});
|
|
5183
|
+
return () => {
|
|
5184
|
+
cancelled = true;
|
|
5185
|
+
};
|
|
5186
|
+
}
|
|
5089
5187
|
function useAdaptiveRender() {
|
|
5090
5188
|
const [mode] = useArr$(["adaptiveRender"]);
|
|
5091
5189
|
return mode;
|
|
@@ -5125,7 +5223,9 @@ function useViewability(callback, configId) {
|
|
|
5125
5223
|
const { containerId } = containerContext;
|
|
5126
5224
|
const key = containerId + (configId != null ? configId : "");
|
|
5127
5225
|
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
5226
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewability", configId) : void 0;
|
|
5128
5227
|
return () => {
|
|
5228
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5129
5229
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
5130
5230
|
};
|
|
5131
5231
|
}, [ctx, callback, configId, containerContext]);
|
|
@@ -5149,7 +5249,9 @@ function useViewabilityAmount(callback) {
|
|
|
5149
5249
|
}
|
|
5150
5250
|
const { containerId } = containerContext;
|
|
5151
5251
|
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
5252
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewabilityAmount") : void 0;
|
|
5152
5253
|
return () => {
|
|
5254
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5153
5255
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
5154
5256
|
};
|
|
5155
5257
|
}, [ctx, callback, containerContext]);
|
|
@@ -7022,11 +7124,29 @@ var ScheduledWork = class {
|
|
|
7022
7124
|
constructor() {
|
|
7023
7125
|
this.work = /* @__PURE__ */ new Map();
|
|
7024
7126
|
}
|
|
7127
|
+
microtask(callback, key) {
|
|
7128
|
+
const pendingWork = this.work.get(key);
|
|
7129
|
+
if (pendingWork == null ? void 0 : pendingWork.callback) {
|
|
7130
|
+
pendingWork.callback = callback;
|
|
7131
|
+
} else {
|
|
7132
|
+
this.cancel(key);
|
|
7133
|
+
const work = { callback, cancel: () => {
|
|
7134
|
+
} };
|
|
7135
|
+
this.work.set(key, work);
|
|
7136
|
+
queueMicrotask(() => {
|
|
7137
|
+
var _a3;
|
|
7138
|
+
if (this.work.get(key) === work) {
|
|
7139
|
+
this.work.delete(key);
|
|
7140
|
+
(_a3 = work.callback) == null ? void 0 : _a3.call(work);
|
|
7141
|
+
}
|
|
7142
|
+
});
|
|
7143
|
+
}
|
|
7144
|
+
}
|
|
7025
7145
|
timeout(callback, delay, key) {
|
|
7026
7146
|
if (key) {
|
|
7027
7147
|
this.cancel(key);
|
|
7028
7148
|
}
|
|
7029
|
-
const work =
|
|
7149
|
+
const work = { cancel: () => clearTimeout(handle) };
|
|
7030
7150
|
const handle = setTimeout(() => {
|
|
7031
7151
|
const workKey = key != null ? key : handle;
|
|
7032
7152
|
if (this.work.get(workKey) === work) {
|
|
@@ -7034,14 +7154,13 @@ var ScheduledWork = class {
|
|
|
7034
7154
|
callback();
|
|
7035
7155
|
}
|
|
7036
7156
|
}, delay);
|
|
7037
|
-
work[0] = handle;
|
|
7038
7157
|
this.work.set(key != null ? key : handle, work);
|
|
7039
7158
|
}
|
|
7040
7159
|
frame(callback, key) {
|
|
7041
7160
|
this.cancel(key);
|
|
7042
|
-
const work =
|
|
7161
|
+
const work = { cancel: () => cancelAnimationFrame(handle) };
|
|
7043
7162
|
this.work.set(key, work);
|
|
7044
|
-
|
|
7163
|
+
const handle = requestAnimationFrame(() => {
|
|
7045
7164
|
if (this.work.get(key) === work) {
|
|
7046
7165
|
this.work.delete(key);
|
|
7047
7166
|
callback();
|
|
@@ -7050,22 +7169,21 @@ var ScheduledWork = class {
|
|
|
7050
7169
|
}
|
|
7051
7170
|
register(key, cancel) {
|
|
7052
7171
|
this.cancel(key);
|
|
7053
|
-
this.work.set(key,
|
|
7172
|
+
this.work.set(key, { cancel });
|
|
7054
7173
|
}
|
|
7055
7174
|
cancel(key) {
|
|
7056
7175
|
const work = this.work.get(key);
|
|
7057
7176
|
if (work) {
|
|
7058
7177
|
this.work.delete(key);
|
|
7059
|
-
|
|
7060
|
-
cancel(handle);
|
|
7178
|
+
work.cancel();
|
|
7061
7179
|
}
|
|
7062
7180
|
}
|
|
7063
7181
|
has(key) {
|
|
7064
7182
|
return this.work.has(key);
|
|
7065
7183
|
}
|
|
7066
7184
|
dispose() {
|
|
7067
|
-
for (const
|
|
7068
|
-
cancel(
|
|
7185
|
+
for (const work of this.work.values()) {
|
|
7186
|
+
work.cancel();
|
|
7069
7187
|
}
|
|
7070
7188
|
this.work.clear();
|
|
7071
7189
|
}
|
|
@@ -7122,6 +7240,25 @@ var ScrollAdjustHandler = class {
|
|
|
7122
7240
|
}
|
|
7123
7241
|
};
|
|
7124
7242
|
|
|
7243
|
+
// src/core/scrollToEnd.ts
|
|
7244
|
+
function scrollToEnd(ctx, options) {
|
|
7245
|
+
const state = ctx.state;
|
|
7246
|
+
const data = state.props.data;
|
|
7247
|
+
const index = data.length - 1;
|
|
7248
|
+
if (index === -1) {
|
|
7249
|
+
return false;
|
|
7250
|
+
}
|
|
7251
|
+
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
7252
|
+
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
7253
|
+
scrollToIndex(ctx, {
|
|
7254
|
+
...options,
|
|
7255
|
+
index,
|
|
7256
|
+
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
7257
|
+
viewPosition: 1
|
|
7258
|
+
});
|
|
7259
|
+
return true;
|
|
7260
|
+
}
|
|
7261
|
+
|
|
7125
7262
|
// src/core/updateContentInsetEndAdjustment.ts
|
|
7126
7263
|
function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
|
|
7127
7264
|
const state = ctx.state;
|
|
@@ -7184,25 +7321,6 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
7184
7321
|
}
|
|
7185
7322
|
}
|
|
7186
7323
|
|
|
7187
|
-
// src/core/scrollToEnd.ts
|
|
7188
|
-
function scrollToEnd(ctx, options) {
|
|
7189
|
-
const state = ctx.state;
|
|
7190
|
-
const data = state.props.data;
|
|
7191
|
-
const index = data.length - 1;
|
|
7192
|
-
if (index === -1) {
|
|
7193
|
-
return false;
|
|
7194
|
-
}
|
|
7195
|
-
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
7196
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
7197
|
-
scrollToIndex(ctx, {
|
|
7198
|
-
...options,
|
|
7199
|
-
index,
|
|
7200
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
7201
|
-
viewPosition: 1
|
|
7202
|
-
});
|
|
7203
|
-
return true;
|
|
7204
|
-
}
|
|
7205
|
-
|
|
7206
7324
|
// src/utils/createImperativeHandle.ts
|
|
7207
7325
|
var DEFAULT_AVERAGE_ITEM_SIZE_TYPE = "default";
|
|
7208
7326
|
function getAverageItemSizes(state) {
|
|
@@ -7225,9 +7343,9 @@ function triggerMountedContainerLayouts(ctx) {
|
|
|
7225
7343
|
}
|
|
7226
7344
|
function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
7227
7345
|
const state = ctx.state;
|
|
7346
|
+
const scrollRequestTracker = getScrollRequestTracker(ctx);
|
|
7228
7347
|
const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
|
|
7229
7348
|
const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
|
|
7230
|
-
let imperativeScrollToken = 0;
|
|
7231
7349
|
const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.scheduledWork.has("mvcpRecalculate") || state.ignoreScrollFromMVCP !== void 0;
|
|
7232
7350
|
const isScrollToIndexReady = (targetIndex, allowEmpty = false) => {
|
|
7233
7351
|
var _a3;
|
|
@@ -7249,7 +7367,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7249
7367
|
const startedAt = Date.now();
|
|
7250
7368
|
let stableFrames = 0;
|
|
7251
7369
|
const check = () => {
|
|
7252
|
-
if (token
|
|
7370
|
+
if (!scrollRequestTracker.isCurrent(token)) {
|
|
7253
7371
|
return;
|
|
7254
7372
|
}
|
|
7255
7373
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
@@ -7267,33 +7385,15 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7267
7385
|
state.scheduledWork.frame(check, "imperativeScrollReady");
|
|
7268
7386
|
};
|
|
7269
7387
|
const runScrollRequest = (token, resolve, run, isReady = () => true) => {
|
|
7270
|
-
const runNow = () =>
|
|
7271
|
-
if (token !== imperativeScrollToken) {
|
|
7272
|
-
return;
|
|
7273
|
-
}
|
|
7274
|
-
const didStartScroll = run();
|
|
7275
|
-
if (!didStartScroll || !state.scrollingTo) {
|
|
7276
|
-
if (state.pendingScrollResolve === resolve) {
|
|
7277
|
-
state.pendingScrollResolve = void 0;
|
|
7278
|
-
}
|
|
7279
|
-
resolve();
|
|
7280
|
-
}
|
|
7281
|
-
};
|
|
7388
|
+
const runNow = () => scrollRequestTracker.runNow(token, resolve, run);
|
|
7282
7389
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
7283
7390
|
runWhenReady(token, runNow, isReady);
|
|
7284
7391
|
} else {
|
|
7285
7392
|
runNow();
|
|
7286
7393
|
}
|
|
7287
7394
|
};
|
|
7288
|
-
const startImperativeScroll = (resolve) => {
|
|
7289
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
7290
|
-
const token = ++imperativeScrollToken;
|
|
7291
|
-
settlePendingImperativeScroll(state);
|
|
7292
|
-
state.pendingScrollResolve = resolve;
|
|
7293
|
-
return token;
|
|
7294
|
-
};
|
|
7295
7395
|
const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
|
|
7296
|
-
const token =
|
|
7396
|
+
const token = scrollRequestTracker.start(resolve);
|
|
7297
7397
|
supersedeInitialScroll(ctx);
|
|
7298
7398
|
runScrollRequest(token, resolve, run, isReady);
|
|
7299
7399
|
});
|
|
@@ -7301,7 +7401,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7301
7401
|
const pendingScroll = state.pendingScrollToEnd;
|
|
7302
7402
|
if (pendingScroll) {
|
|
7303
7403
|
state.pendingScrollToEnd = void 0;
|
|
7304
|
-
if (pendingScroll.token
|
|
7404
|
+
if (scrollRequestTracker.isCurrent(pendingScroll.token)) {
|
|
7305
7405
|
runScrollRequest(
|
|
7306
7406
|
pendingScroll.token,
|
|
7307
7407
|
pendingScroll.resolve,
|
|
@@ -7415,7 +7515,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7415
7515
|
}),
|
|
7416
7516
|
scrollToEnd: (options) => new Promise((resolve) => {
|
|
7417
7517
|
var _a3;
|
|
7418
|
-
const token =
|
|
7518
|
+
const token = scrollRequestTracker.start(resolve);
|
|
7419
7519
|
state.pendingScrollToEnd = {
|
|
7420
7520
|
options,
|
|
7421
7521
|
resolve,
|
|
@@ -7795,6 +7895,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7795
7895
|
const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
|
|
7796
7896
|
const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
|
|
7797
7897
|
const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
|
|
7898
|
+
const shouldBottomAlignNumericInitialScrollIndex = typeof initialScrollIndexProp === "number" && !hasInitialScrollOffset && dataProp.length > 1 && initialScrollIndexProp >= dataProp.length - 1;
|
|
7798
7899
|
const initialScrollProp = initialScrollAtEnd ? {
|
|
7799
7900
|
index: Math.max(0, dataProp.length - 1),
|
|
7800
7901
|
preserveForBottomPadding: true,
|
|
@@ -7807,7 +7908,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7807
7908
|
viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
|
|
7808
7909
|
} : {
|
|
7809
7910
|
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
7810
|
-
|
|
7911
|
+
preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
|
|
7912
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? -stylePaddingEndState : 0,
|
|
7913
|
+
viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
|
|
7811
7914
|
} : initialScrollUsesOffsetOnly ? {
|
|
7812
7915
|
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
7813
7916
|
index: 0,
|
|
@@ -7913,6 +8016,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7913
8016
|
viewabilityConfigCallbackPairs: void 0
|
|
7914
8017
|
};
|
|
7915
8018
|
const internalState = ctx.state;
|
|
8019
|
+
ctx.scrollToEnd = (options) => scrollToEnd(ctx, options);
|
|
7916
8020
|
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
7917
8021
|
internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
|
|
7918
8022
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
|
|
@@ -8266,6 +8370,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
8266
8370
|
onScroll: (event) => onScroll(ctx, event),
|
|
8267
8371
|
onScrollBeginDrag: (event) => {
|
|
8268
8372
|
var _a4, _b2;
|
|
8373
|
+
const maintainingScrollAtEnd = state.maintainingScrollAtEnd;
|
|
8374
|
+
if (maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant") {
|
|
8375
|
+
cancelImperativeScroll(state);
|
|
8376
|
+
}
|
|
8377
|
+
if (maintainingScrollAtEnd) {
|
|
8378
|
+
finishMaintainScrollAtEnd(ctx);
|
|
8379
|
+
}
|
|
8269
8380
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
8270
8381
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
8271
8382
|
},
|