@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.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;
|
|
@@ -413,6 +409,28 @@ var EDGE_POSITION_EPSILON = 1;
|
|
|
413
409
|
var ENABLE_DEVMODE = IS_DEV && false;
|
|
414
410
|
var ENABLE_DEBUG_VIEW = IS_DEV && false;
|
|
415
411
|
|
|
412
|
+
// src/core/cancelImperativeScroll.ts
|
|
413
|
+
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
414
|
+
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
415
|
+
scheduledWork.cancel("checkFinishedScrollRetryFrame");
|
|
416
|
+
scheduledWork.cancel("checkFinishedScrollFallback");
|
|
417
|
+
scheduledWork.cancel("platformScrollCompletion");
|
|
418
|
+
}
|
|
419
|
+
function settlePendingImperativeScroll(state) {
|
|
420
|
+
var _a3, _b;
|
|
421
|
+
const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
|
|
422
|
+
state.pendingScrollResolve = void 0;
|
|
423
|
+
state.pendingScrollToEnd = void 0;
|
|
424
|
+
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
425
|
+
}
|
|
426
|
+
function cancelImperativeScroll(state) {
|
|
427
|
+
cancelScrollCompletionChecks(state);
|
|
428
|
+
state.scheduledWork.cancel("imperativeScrollReady");
|
|
429
|
+
state.scrollingTo = void 0;
|
|
430
|
+
state.scrollTargetPinnedRange = void 0;
|
|
431
|
+
settlePendingImperativeScroll(state);
|
|
432
|
+
}
|
|
433
|
+
|
|
416
434
|
// src/core/deferredPublicOnScroll.ts
|
|
417
435
|
function withResolvedContentOffset(state, event, resolvedOffset) {
|
|
418
436
|
return {
|
|
@@ -667,6 +685,12 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
667
685
|
} = state;
|
|
668
686
|
const contentSize = getContentSize(ctx);
|
|
669
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
|
+
}
|
|
670
694
|
if (contentSize > 0 && queuedInitialLayout) {
|
|
671
695
|
const insetEnd = getContentInsetEnd(ctx);
|
|
672
696
|
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
@@ -676,7 +700,7 @@ function checkAtBottom(ctx, allowedEdge, allowGateCreatedInCurrentCheck) {
|
|
|
676
700
|
set$(
|
|
677
701
|
ctx,
|
|
678
702
|
"isWithinMaintainScrollAtEndThreshold",
|
|
679
|
-
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength
|
|
703
|
+
isContentLess || distanceFromEnd <= maintainScrollAtEndThreshold * scrollLength || state.pendingMaintainScrollAtEnd || maintainingScrollAtEnd === "animated" || maintainingScrollAtEnd === "instant"
|
|
680
704
|
);
|
|
681
705
|
const shouldSkipThresholdChecks = hasActiveInitialScroll(state) || maintainingScrollAtEnd;
|
|
682
706
|
if (!shouldSkipThresholdChecks) {
|
|
@@ -914,6 +938,24 @@ function clearPreservedInitialScrollTarget(state) {
|
|
|
914
938
|
state.initialScroll = void 0;
|
|
915
939
|
setInitialScrollSession(state);
|
|
916
940
|
}
|
|
941
|
+
function supersedeInitialScroll(ctx) {
|
|
942
|
+
var _a3, _b, _c;
|
|
943
|
+
const state = ctx.state;
|
|
944
|
+
const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
945
|
+
if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
|
|
946
|
+
if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
947
|
+
cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
|
|
948
|
+
}
|
|
949
|
+
if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
|
|
950
|
+
cancelScrollCompletionChecks(state);
|
|
951
|
+
state.scrollingTo = void 0;
|
|
952
|
+
state.scrollTargetPinnedRange = void 0;
|
|
953
|
+
}
|
|
954
|
+
initialScrollCompletion.resetFlags(state);
|
|
955
|
+
setInitialScrollSession(state, { bootstrap: null });
|
|
956
|
+
finishInitialScroll(ctx);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
917
959
|
function finishInitialScroll(ctx, options) {
|
|
918
960
|
var _a3, _b, _c;
|
|
919
961
|
const state = ctx.state;
|
|
@@ -1003,10 +1045,22 @@ function getAlignItemsAtEndPadding(ctx) {
|
|
|
1003
1045
|
return shouldPad ? Math.max(0, state.scrollLength - getRawContentLength(ctx) - getContentInsetEnd(ctx)) : 0;
|
|
1004
1046
|
}
|
|
1005
1047
|
function updateContentMetricsState(ctx) {
|
|
1048
|
+
var _a3;
|
|
1049
|
+
const { state } = ctx;
|
|
1006
1050
|
const previousPadding = peek$(ctx, "alignItemsAtEndPadding") || 0;
|
|
1007
1051
|
const nextPadding = getAlignItemsAtEndPadding(ctx);
|
|
1008
1052
|
if (previousPadding !== nextPadding) {
|
|
1009
|
-
|
|
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
|
+
}
|
|
1010
1064
|
}
|
|
1011
1065
|
}
|
|
1012
1066
|
|
|
@@ -1227,29 +1281,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
|
|
|
1227
1281
|
return clampedOffset;
|
|
1228
1282
|
}
|
|
1229
1283
|
|
|
1230
|
-
// src/core/cancelImperativeScroll.ts
|
|
1231
|
-
function cancelScrollCompletionChecks({ scheduledWork }) {
|
|
1232
|
-
scheduledWork.cancel("checkFinishedScrollFrame");
|
|
1233
|
-
scheduledWork.cancel("checkFinishedScrollRetryFrame");
|
|
1234
|
-
scheduledWork.cancel("checkFinishedScrollFallback");
|
|
1235
|
-
scheduledWork.cancel("platformScrollCompletion");
|
|
1236
|
-
}
|
|
1237
|
-
function settlePendingImperativeScroll(state) {
|
|
1238
|
-
var _a3, _b;
|
|
1239
|
-
const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
|
|
1240
|
-
state.pendingScrollResolve = void 0;
|
|
1241
|
-
state.pendingScrollToEnd = void 0;
|
|
1242
|
-
resolvePendingScroll == null ? void 0 : resolvePendingScroll();
|
|
1243
|
-
}
|
|
1244
|
-
function cancelImperativeScroll(state) {
|
|
1245
|
-
cancelScrollCompletionChecks(state);
|
|
1246
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
1247
|
-
state.runPendingScrollToEnd = void 0;
|
|
1248
|
-
state.scrollingTo = void 0;
|
|
1249
|
-
state.scrollTargetPinnedRange = void 0;
|
|
1250
|
-
settlePendingImperativeScroll(state);
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
1284
|
// src/core/finishScrollTo.ts
|
|
1254
1285
|
function finishScrollTo(ctx) {
|
|
1255
1286
|
var _a3, _b;
|
|
@@ -1387,22 +1418,110 @@ function listenForScrollEnd(ctx, params) {
|
|
|
1387
1418
|
scheduledWork.register("platformScrollCompletion", cancel);
|
|
1388
1419
|
}
|
|
1389
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
|
+
|
|
1390
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
|
+
}
|
|
1391
1505
|
function doMaintainScrollAtEnd(ctx) {
|
|
1392
1506
|
const state = ctx.state;
|
|
1393
1507
|
const {
|
|
1394
1508
|
didContainersLayout,
|
|
1509
|
+
didFinishInitialScroll,
|
|
1395
1510
|
pendingNativeMVCPAdjust,
|
|
1396
|
-
refScroller,
|
|
1397
1511
|
props: { maintainScrollAtEnd }
|
|
1398
1512
|
} = state;
|
|
1399
1513
|
const isWithinMaintainScrollAtEndThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1400
|
-
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
|
+
}
|
|
1401
1520
|
if (pendingNativeMVCPAdjust) {
|
|
1402
1521
|
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1403
1522
|
return false;
|
|
1404
1523
|
}
|
|
1405
|
-
if (shouldMaintainScrollAtEnd) {
|
|
1524
|
+
if (shouldMaintainScrollAtEnd && didContainersLayout) {
|
|
1406
1525
|
state.pendingMaintainScrollAtEnd = false;
|
|
1407
1526
|
const contentSize = getContentSize(ctx);
|
|
1408
1527
|
if (contentSize < state.scrollLength) {
|
|
@@ -1414,39 +1533,29 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1414
1533
|
const scrollAtRequest = state.scroll;
|
|
1415
1534
|
state.maintainingScrollAtEnd = pendingState;
|
|
1416
1535
|
requestAnimationFrame(() => {
|
|
1536
|
+
if (state.maintainingScrollAtEnd !== pendingState) {
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1417
1539
|
const isStillWithinThreshold = peek$(ctx, "isWithinMaintainScrollAtEndThreshold");
|
|
1418
1540
|
const didScrollSinceRequest = state.scroll !== scrollAtRequest;
|
|
1419
|
-
if (isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1541
|
+
if (isReplayingPendingMaintain || isStillWithinThreshold || !didScrollSinceRequest) {
|
|
1420
1542
|
state.maintainingScrollAtEnd = activeState;
|
|
1421
|
-
const
|
|
1422
|
-
|
|
1423
|
-
const currentContentSize = getContentSize(ctx);
|
|
1424
|
-
const logicalEndOffset = getLogicalHorizontalMaxOffset(state, currentContentSize);
|
|
1425
|
-
const nativeOffset = toNativeHorizontalOffset(state, logicalEndOffset, currentContentSize);
|
|
1426
|
-
scroller == null ? void 0 : scroller.scrollTo({
|
|
1427
|
-
animated: maintainScrollAtEnd.animated,
|
|
1428
|
-
x: nativeOffset,
|
|
1429
|
-
y: 0
|
|
1430
|
-
});
|
|
1431
|
-
} else {
|
|
1432
|
-
scroller == null ? void 0 : scroller.scrollToEnd({
|
|
1433
|
-
animated: maintainScrollAtEnd.animated
|
|
1434
|
-
});
|
|
1435
|
-
}
|
|
1436
|
-
setTimeout(
|
|
1437
|
-
() => {
|
|
1438
|
-
if (state.maintainingScrollAtEnd === activeState) {
|
|
1439
|
-
state.maintainingScrollAtEnd = void 0;
|
|
1440
|
-
if (state.pendingMaintainScrollAtEnd) {
|
|
1441
|
-
doMaintainScrollAtEnd(ctx);
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
},
|
|
1445
|
-
maintainScrollAtEnd.animated ? 500 : 0
|
|
1543
|
+
const scrollPromise = getScrollRequestTracker(ctx).runNowIfIdle(
|
|
1544
|
+
() => ctx.scrollToEnd({ animated: maintainScrollAtEnd.animated })
|
|
1446
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
|
+
});
|
|
1447
1557
|
} else if (state.maintainingScrollAtEnd === pendingState) {
|
|
1448
|
-
|
|
1449
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1558
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1450
1559
|
}
|
|
1451
1560
|
});
|
|
1452
1561
|
} else {
|
|
@@ -1454,34 +1563,10 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1454
1563
|
}
|
|
1455
1564
|
return true;
|
|
1456
1565
|
}
|
|
1457
|
-
|
|
1566
|
+
finishMaintainScrollAtEnd(ctx);
|
|
1458
1567
|
return false;
|
|
1459
1568
|
}
|
|
1460
1569
|
|
|
1461
|
-
// src/utils/requestAdjust.ts
|
|
1462
|
-
function requestAdjust(ctx, positionDiff, dataChanged) {
|
|
1463
|
-
const state = ctx.state;
|
|
1464
|
-
if (Math.abs(positionDiff) > 0.1) {
|
|
1465
|
-
const doit = () => {
|
|
1466
|
-
{
|
|
1467
|
-
state.scrollAdjustHandler.requestAdjust(positionDiff);
|
|
1468
|
-
if (state.adjustingFromInitialMount) {
|
|
1469
|
-
state.adjustingFromInitialMount--;
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
};
|
|
1473
|
-
state.scroll += positionDiff;
|
|
1474
|
-
state.scrollForNextCalculateItemsInView = void 0;
|
|
1475
|
-
const readyToRender = peek$(ctx, "readyToRender");
|
|
1476
|
-
if (readyToRender) {
|
|
1477
|
-
doit();
|
|
1478
|
-
} else {
|
|
1479
|
-
state.adjustingFromInitialMount = (state.adjustingFromInitialMount || 0) + 1;
|
|
1480
|
-
requestAnimationFrame(doit);
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
1570
|
// src/core/mvcp.ts
|
|
1486
1571
|
var MVCP_POSITION_EPSILON = 0.1;
|
|
1487
1572
|
var MVCP_ANCHOR_LOCK_TTL_MS = 300;
|
|
@@ -1618,7 +1703,7 @@ function resolvePendingNativeMVCPAdjust(ctx, newScroll) {
|
|
|
1618
1703
|
}
|
|
1619
1704
|
return false;
|
|
1620
1705
|
}
|
|
1621
|
-
function prepareMVCP(ctx, dataChanged) {
|
|
1706
|
+
function prepareMVCP(ctx, dataChanged, adjustmentSource) {
|
|
1622
1707
|
const state = ctx.state;
|
|
1623
1708
|
const { idsInView, positions, props } = state;
|
|
1624
1709
|
const {
|
|
@@ -1870,6 +1955,10 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
1870
1955
|
state.scrollTime = currentTime;
|
|
1871
1956
|
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
1872
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
|
+
}
|
|
1873
1962
|
const allowedEdge = isUserScrollEvent ? beginReachedEdgeUserScroll(ctx, newScroll - prevScroll) : void 0;
|
|
1874
1963
|
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
1875
1964
|
const scrollLength = state.scrollLength;
|
|
@@ -1878,7 +1967,7 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
1878
1967
|
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
1879
1968
|
const lastCalculated = state.scrollLastCalculate;
|
|
1880
1969
|
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
1881
|
-
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;
|
|
1882
1971
|
if (shouldUpdate) {
|
|
1883
1972
|
state.scrollLastCalculate = state.scroll;
|
|
1884
1973
|
state.ignoreScrollFromMVCPIgnored = false;
|
|
@@ -2707,7 +2796,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2707
2796
|
}
|
|
2708
2797
|
}
|
|
2709
2798
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2710
|
-
var _a3, _b
|
|
2799
|
+
var _a3, _b;
|
|
2711
2800
|
const state = ctx.state;
|
|
2712
2801
|
const initialScroll = state.initialScroll;
|
|
2713
2802
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2721,19 +2810,15 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2721
2810
|
if (state.didFinishInitialScroll) {
|
|
2722
2811
|
schedulePreservedEndAnchorCorrection(ctx);
|
|
2723
2812
|
} else if (scrollingTo) {
|
|
2724
|
-
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2725
|
-
scrollingTo.offset = resolvedOffset;
|
|
2726
|
-
scrollingTo.targetOffset = resolvedOffset;
|
|
2727
2813
|
state.initialScroll = {
|
|
2728
2814
|
...initialScroll,
|
|
2729
2815
|
contentOffset: resolvedOffset
|
|
2730
2816
|
};
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2817
|
+
dispatchInitialScroll(ctx, {
|
|
2818
|
+
forceScroll: true,
|
|
2819
|
+
resolvedOffset,
|
|
2820
|
+
target: state.initialScroll
|
|
2735
2821
|
});
|
|
2736
|
-
requestAdjust(ctx, offsetDiff);
|
|
2737
2822
|
}
|
|
2738
2823
|
}
|
|
2739
2824
|
} else {
|
|
@@ -3960,6 +4045,9 @@ function setDidLayout(ctx) {
|
|
|
3960
4045
|
state.queuedInitialLayout = true;
|
|
3961
4046
|
checkAtBottom(ctx);
|
|
3962
4047
|
setInitialRenderState(ctx, { didLayout: true });
|
|
4048
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
4049
|
+
doMaintainScrollAtEnd(ctx);
|
|
4050
|
+
}
|
|
3963
4051
|
}
|
|
3964
4052
|
|
|
3965
4053
|
// src/core/calculateItemsInView.ts
|
|
@@ -4196,7 +4284,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4196
4284
|
const stickyHeaderIndicesArr = state.props.stickyHeaderIndicesArr || [];
|
|
4197
4285
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4198
4286
|
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4199
|
-
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4287
|
+
const { dataChanged, doMVCP, forceFullItemPositions, mvcpAdjustmentSource } = params;
|
|
4200
4288
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
4201
4289
|
const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
|
|
4202
4290
|
const prevNumContainers = peek$(ctx, "numContainers");
|
|
@@ -4700,9 +4788,12 @@ function runOrScheduleMVCPRecalculate(ctx) {
|
|
|
4700
4788
|
} else {
|
|
4701
4789
|
if (!state.mvcpAnchorLock) {
|
|
4702
4790
|
state.scheduledWork.cancel("mvcpRecalculate");
|
|
4703
|
-
calculateItemsInView(ctx, { doMVCP: true });
|
|
4791
|
+
calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" });
|
|
4704
4792
|
} else if (!state.scheduledWork.has("mvcpRecalculate")) {
|
|
4705
|
-
state.scheduledWork.frame(
|
|
4793
|
+
state.scheduledWork.frame(
|
|
4794
|
+
() => calculateItemsInView(ctx, { doMVCP: true, mvcpAdjustmentSource: "item-size" }),
|
|
4795
|
+
"mvcpRecalculate"
|
|
4796
|
+
);
|
|
4706
4797
|
}
|
|
4707
4798
|
}
|
|
4708
4799
|
}
|
|
@@ -4829,7 +4920,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
|
|
|
4829
4920
|
if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
|
|
4830
4921
|
needsRecalculate = true;
|
|
4831
4922
|
}
|
|
4832
|
-
if (prevSizeKnown
|
|
4923
|
+
if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
|
|
4833
4924
|
shouldMaintainScrollAtEnd = true;
|
|
4834
4925
|
}
|
|
4835
4926
|
onItemSizeChanged == null ? void 0 : onItemSizeChanged({
|
|
@@ -5069,6 +5160,30 @@ function useContainerItemSignals(containerContext) {
|
|
|
5069
5160
|
itemKey
|
|
5070
5161
|
};
|
|
5071
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
|
+
}
|
|
5072
5187
|
function useAdaptiveRender() {
|
|
5073
5188
|
const [mode] = useArr$(["adaptiveRender"]);
|
|
5074
5189
|
return mode;
|
|
@@ -5108,7 +5223,9 @@ function useViewability(callback, configId) {
|
|
|
5108
5223
|
const { containerId } = containerContext;
|
|
5109
5224
|
const key = containerId + (configId != null ? configId : "");
|
|
5110
5225
|
ctx.mapViewabilityCallbacks.set(key, callback);
|
|
5226
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewability", configId) : void 0;
|
|
5111
5227
|
return () => {
|
|
5228
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5112
5229
|
ctx.mapViewabilityCallbacks.delete(key);
|
|
5113
5230
|
};
|
|
5114
5231
|
}, [ctx, callback, configId, containerContext]);
|
|
@@ -5132,7 +5249,9 @@ function useViewabilityAmount(callback) {
|
|
|
5132
5249
|
}
|
|
5133
5250
|
const { containerId } = containerContext;
|
|
5134
5251
|
ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
5252
|
+
const cancelConfigWarning = IS_DEV ? scheduleViewabilityConfigWarning(ctx, "useViewabilityAmount") : void 0;
|
|
5135
5253
|
return () => {
|
|
5254
|
+
cancelConfigWarning == null ? void 0 : cancelConfigWarning();
|
|
5136
5255
|
ctx.mapViewabilityAmountCallbacks.delete(containerId);
|
|
5137
5256
|
};
|
|
5138
5257
|
}, [ctx, callback, containerContext]);
|
|
@@ -5729,13 +5848,11 @@ function useDOMOrder(ref) {
|
|
|
5729
5848
|
}, [ctx]);
|
|
5730
5849
|
}
|
|
5731
5850
|
function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
|
|
5732
|
-
const completedTransitionEpoch =
|
|
5733
|
-
const isTransitionPending = completedTransitionEpoch
|
|
5851
|
+
const [completedTransitionEpoch, setCompletedTransitionEpoch] = useState(transitionEpoch);
|
|
5852
|
+
const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
|
|
5734
5853
|
useLayoutEffect(() => {
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
}
|
|
5738
|
-
}, [readyToRender, transitionEpoch]);
|
|
5854
|
+
setCompletedTransitionEpoch(transitionEpoch);
|
|
5855
|
+
}, [transitionEpoch]);
|
|
5739
5856
|
return readyToRender && !isTransitionPending;
|
|
5740
5857
|
}
|
|
5741
5858
|
|
|
@@ -6376,10 +6493,9 @@ function ScrollAdjust() {
|
|
|
6376
6493
|
const lastScrollOffsetRef = React3.useRef(0);
|
|
6377
6494
|
const lastScrollAdjustUserOffsetRef = React3.useRef(0);
|
|
6378
6495
|
const resetPaddingRafRef = React3.useRef(void 0);
|
|
6379
|
-
const
|
|
6496
|
+
const temporaryPaddingRef = React3.useRef(void 0);
|
|
6380
6497
|
const contentNodeRef = React3.useRef(null);
|
|
6381
6498
|
const callback = React3.useCallback(() => {
|
|
6382
|
-
var _a3;
|
|
6383
6499
|
const scrollAdjust = peek$(ctx, "scrollAdjust");
|
|
6384
6500
|
const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
|
|
6385
6501
|
const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
|
|
@@ -6403,19 +6519,28 @@ function ScrollAdjust() {
|
|
|
6403
6519
|
const nextScroll = currentScroll + scrollDelta;
|
|
6404
6520
|
const needsTemporaryPadding = scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + viewportSize;
|
|
6405
6521
|
if (needsTemporaryPadding) {
|
|
6406
|
-
const
|
|
6407
|
-
|
|
6522
|
+
const currentInlinePaddingEnd = contentNode.style[axis.paddingEndProp];
|
|
6523
|
+
const previousTemporaryPadding = temporaryPaddingRef.current;
|
|
6524
|
+
const baselinePaddingEnd = (previousTemporaryPadding == null ? void 0 : previousTemporaryPadding.value) === currentInlinePaddingEnd ? previousTemporaryPadding.baseline : currentInlinePaddingEnd;
|
|
6408
6525
|
const pad = (nextScroll + viewportSize - totalSize) * 2;
|
|
6409
|
-
|
|
6526
|
+
const currentPaddingEnd = Number.parseFloat(
|
|
6527
|
+
window.getComputedStyle(contentNode)[axis.paddingEndProp]
|
|
6528
|
+
);
|
|
6529
|
+
const temporaryPaddingEnd = `${(currentPaddingEnd || 0) + pad}px`;
|
|
6530
|
+
temporaryPaddingRef.current = { baseline: baselinePaddingEnd, value: temporaryPaddingEnd };
|
|
6531
|
+
contentNode.style[axis.paddingEndProp] = temporaryPaddingEnd;
|
|
6410
6532
|
void contentNode.offsetHeight;
|
|
6411
6533
|
scrollBy();
|
|
6412
6534
|
if (resetPaddingRafRef.current !== void 0) {
|
|
6413
6535
|
cancelAnimationFrame(resetPaddingRafRef.current);
|
|
6414
6536
|
}
|
|
6415
6537
|
resetPaddingRafRef.current = requestAnimationFrame(() => {
|
|
6538
|
+
const temporaryPadding = temporaryPaddingRef.current;
|
|
6416
6539
|
resetPaddingRafRef.current = void 0;
|
|
6417
|
-
|
|
6418
|
-
contentNode.style[axis.paddingEndProp]
|
|
6540
|
+
temporaryPaddingRef.current = void 0;
|
|
6541
|
+
if (contentNode.style[axis.paddingEndProp] === (temporaryPadding == null ? void 0 : temporaryPadding.value)) {
|
|
6542
|
+
contentNode.style[axis.paddingEndProp] = temporaryPadding.baseline;
|
|
6543
|
+
}
|
|
6419
6544
|
});
|
|
6420
6545
|
} else {
|
|
6421
6546
|
scrollBy();
|
|
@@ -6999,11 +7124,29 @@ var ScheduledWork = class {
|
|
|
6999
7124
|
constructor() {
|
|
7000
7125
|
this.work = /* @__PURE__ */ new Map();
|
|
7001
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
|
+
}
|
|
7002
7145
|
timeout(callback, delay, key) {
|
|
7003
7146
|
if (key) {
|
|
7004
7147
|
this.cancel(key);
|
|
7005
7148
|
}
|
|
7006
|
-
const work =
|
|
7149
|
+
const work = { cancel: () => clearTimeout(handle) };
|
|
7007
7150
|
const handle = setTimeout(() => {
|
|
7008
7151
|
const workKey = key != null ? key : handle;
|
|
7009
7152
|
if (this.work.get(workKey) === work) {
|
|
@@ -7011,14 +7154,13 @@ var ScheduledWork = class {
|
|
|
7011
7154
|
callback();
|
|
7012
7155
|
}
|
|
7013
7156
|
}, delay);
|
|
7014
|
-
work[0] = handle;
|
|
7015
7157
|
this.work.set(key != null ? key : handle, work);
|
|
7016
7158
|
}
|
|
7017
7159
|
frame(callback, key) {
|
|
7018
7160
|
this.cancel(key);
|
|
7019
|
-
const work =
|
|
7161
|
+
const work = { cancel: () => cancelAnimationFrame(handle) };
|
|
7020
7162
|
this.work.set(key, work);
|
|
7021
|
-
|
|
7163
|
+
const handle = requestAnimationFrame(() => {
|
|
7022
7164
|
if (this.work.get(key) === work) {
|
|
7023
7165
|
this.work.delete(key);
|
|
7024
7166
|
callback();
|
|
@@ -7027,21 +7169,21 @@ var ScheduledWork = class {
|
|
|
7027
7169
|
}
|
|
7028
7170
|
register(key, cancel) {
|
|
7029
7171
|
this.cancel(key);
|
|
7030
|
-
this.work.set(key,
|
|
7172
|
+
this.work.set(key, { cancel });
|
|
7031
7173
|
}
|
|
7032
7174
|
cancel(key) {
|
|
7033
7175
|
const work = this.work.get(key);
|
|
7034
7176
|
if (work) {
|
|
7035
7177
|
this.work.delete(key);
|
|
7036
|
-
work
|
|
7178
|
+
work.cancel();
|
|
7037
7179
|
}
|
|
7038
7180
|
}
|
|
7039
7181
|
has(key) {
|
|
7040
7182
|
return this.work.has(key);
|
|
7041
7183
|
}
|
|
7042
7184
|
dispose() {
|
|
7043
|
-
for (const
|
|
7044
|
-
cancel(
|
|
7185
|
+
for (const work of this.work.values()) {
|
|
7186
|
+
work.cancel();
|
|
7045
7187
|
}
|
|
7046
7188
|
this.work.clear();
|
|
7047
7189
|
}
|
|
@@ -7098,6 +7240,25 @@ var ScrollAdjustHandler = class {
|
|
|
7098
7240
|
}
|
|
7099
7241
|
};
|
|
7100
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
|
+
|
|
7101
7262
|
// src/core/updateContentInsetEndAdjustment.ts
|
|
7102
7263
|
function updateContentInsetEndAdjustment(ctx, previousContentInsetEndAdjustment) {
|
|
7103
7264
|
const state = ctx.state;
|
|
@@ -7160,25 +7321,6 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
7160
7321
|
}
|
|
7161
7322
|
}
|
|
7162
7323
|
|
|
7163
|
-
// src/core/scrollToEnd.ts
|
|
7164
|
-
function scrollToEnd(ctx, options) {
|
|
7165
|
-
const state = ctx.state;
|
|
7166
|
-
const data = state.props.data;
|
|
7167
|
-
const index = data.length - 1;
|
|
7168
|
-
if (index === -1) {
|
|
7169
|
-
return false;
|
|
7170
|
-
}
|
|
7171
|
-
const paddingBottom = state.props.stylePaddingBottom || 0;
|
|
7172
|
-
const footerSize = peek$(ctx, "footerSize") || 0;
|
|
7173
|
-
scrollToIndex(ctx, {
|
|
7174
|
-
...options,
|
|
7175
|
-
index,
|
|
7176
|
-
viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
|
|
7177
|
-
viewPosition: 1
|
|
7178
|
-
});
|
|
7179
|
-
return true;
|
|
7180
|
-
}
|
|
7181
|
-
|
|
7182
7324
|
// src/utils/createImperativeHandle.ts
|
|
7183
7325
|
var DEFAULT_AVERAGE_ITEM_SIZE_TYPE = "default";
|
|
7184
7326
|
function getAverageItemSizes(state) {
|
|
@@ -7201,9 +7343,9 @@ function triggerMountedContainerLayouts(ctx) {
|
|
|
7201
7343
|
}
|
|
7202
7344
|
function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
7203
7345
|
const state = ctx.state;
|
|
7346
|
+
const scrollRequestTracker = getScrollRequestTracker(ctx);
|
|
7204
7347
|
const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
|
|
7205
7348
|
const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
|
|
7206
|
-
let imperativeScrollToken = 0;
|
|
7207
7349
|
const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.scheduledWork.has("mvcpRecalculate") || state.ignoreScrollFromMVCP !== void 0;
|
|
7208
7350
|
const isScrollToIndexReady = (targetIndex, allowEmpty = false) => {
|
|
7209
7351
|
var _a3;
|
|
@@ -7225,7 +7367,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7225
7367
|
const startedAt = Date.now();
|
|
7226
7368
|
let stableFrames = 0;
|
|
7227
7369
|
const check = () => {
|
|
7228
|
-
if (token
|
|
7370
|
+
if (!scrollRequestTracker.isCurrent(token)) {
|
|
7229
7371
|
return;
|
|
7230
7372
|
}
|
|
7231
7373
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
@@ -7243,40 +7385,23 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7243
7385
|
state.scheduledWork.frame(check, "imperativeScrollReady");
|
|
7244
7386
|
};
|
|
7245
7387
|
const runScrollRequest = (token, resolve, run, isReady = () => true) => {
|
|
7246
|
-
const runNow = () =>
|
|
7247
|
-
if (token !== imperativeScrollToken) {
|
|
7248
|
-
return;
|
|
7249
|
-
}
|
|
7250
|
-
const didStartScroll = run();
|
|
7251
|
-
if (!didStartScroll || !state.scrollingTo) {
|
|
7252
|
-
if (state.pendingScrollResolve === resolve) {
|
|
7253
|
-
state.pendingScrollResolve = void 0;
|
|
7254
|
-
}
|
|
7255
|
-
resolve();
|
|
7256
|
-
}
|
|
7257
|
-
};
|
|
7388
|
+
const runNow = () => scrollRequestTracker.runNow(token, resolve, run);
|
|
7258
7389
|
if (isSettlingAfterDataChange() || !isReady()) {
|
|
7259
7390
|
runWhenReady(token, runNow, isReady);
|
|
7260
7391
|
} else {
|
|
7261
7392
|
runNow();
|
|
7262
7393
|
}
|
|
7263
7394
|
};
|
|
7264
|
-
const startImperativeScroll = (resolve) => {
|
|
7265
|
-
state.scheduledWork.cancel("imperativeScrollReady");
|
|
7266
|
-
const token = ++imperativeScrollToken;
|
|
7267
|
-
settlePendingImperativeScroll(state);
|
|
7268
|
-
state.pendingScrollResolve = resolve;
|
|
7269
|
-
return token;
|
|
7270
|
-
};
|
|
7271
7395
|
const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
|
|
7272
|
-
const token =
|
|
7396
|
+
const token = scrollRequestTracker.start(resolve);
|
|
7397
|
+
supersedeInitialScroll(ctx);
|
|
7273
7398
|
runScrollRequest(token, resolve, run, isReady);
|
|
7274
7399
|
});
|
|
7275
7400
|
state.runPendingScrollToEnd = () => {
|
|
7276
7401
|
const pendingScroll = state.pendingScrollToEnd;
|
|
7277
7402
|
if (pendingScroll) {
|
|
7278
7403
|
state.pendingScrollToEnd = void 0;
|
|
7279
|
-
if (pendingScroll.token
|
|
7404
|
+
if (scrollRequestTracker.isCurrent(pendingScroll.token)) {
|
|
7280
7405
|
runScrollRequest(
|
|
7281
7406
|
pendingScroll.token,
|
|
7282
7407
|
pendingScroll.resolve,
|
|
@@ -7390,15 +7515,15 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
|
|
|
7390
7515
|
}),
|
|
7391
7516
|
scrollToEnd: (options) => new Promise((resolve) => {
|
|
7392
7517
|
var _a3;
|
|
7393
|
-
const token =
|
|
7518
|
+
const token = scrollRequestTracker.start(resolve);
|
|
7394
7519
|
state.pendingScrollToEnd = {
|
|
7395
7520
|
options,
|
|
7396
7521
|
resolve,
|
|
7397
7522
|
token
|
|
7398
7523
|
};
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7524
|
+
scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
|
|
7525
|
+
supersedeInitialScroll(ctx);
|
|
7526
|
+
if (!scheduleImperativeScrollCommit) {
|
|
7402
7527
|
(_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
|
|
7403
7528
|
}
|
|
7404
7529
|
}),
|
|
@@ -7770,6 +7895,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7770
7895
|
const shouldInitializeHorizontalRTL = !initialScrollAtEnd && !hasInitialScrollIndex && !hasInitialScrollOffset && isHorizontalRTLProps({ horizontal, rtl });
|
|
7771
7896
|
const initialScrollUsesOffsetOnly = !initialScrollAtEnd && !hasInitialScrollIndex && (hasInitialScrollOffset || shouldInitializeHorizontalRTL);
|
|
7772
7897
|
const usesBootstrapInitialScroll = initialScrollAtEnd || hasInitialScrollIndex;
|
|
7898
|
+
const shouldBottomAlignNumericInitialScrollIndex = typeof initialScrollIndexProp === "number" && !hasInitialScrollOffset && dataProp.length > 1 && initialScrollIndexProp >= dataProp.length - 1;
|
|
7773
7899
|
const initialScrollProp = initialScrollAtEnd ? {
|
|
7774
7900
|
index: Math.max(0, dataProp.length - 1),
|
|
7775
7901
|
preserveForBottomPadding: true,
|
|
@@ -7782,7 +7908,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7782
7908
|
viewPosition: (_d = initialScrollIndexProp.viewPosition) != null ? _d : 0
|
|
7783
7909
|
} : {
|
|
7784
7910
|
index: initialScrollIndexProp != null ? initialScrollIndexProp : 0,
|
|
7785
|
-
|
|
7911
|
+
preserveForBottomPadding: shouldBottomAlignNumericInitialScrollIndex ? true : void 0,
|
|
7912
|
+
viewOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : shouldBottomAlignNumericInitialScrollIndex ? -stylePaddingEndState : 0,
|
|
7913
|
+
viewPosition: shouldBottomAlignNumericInitialScrollIndex ? 1 : void 0
|
|
7786
7914
|
} : initialScrollUsesOffsetOnly ? {
|
|
7787
7915
|
contentOffset: initialScrollOffsetProp != null ? initialScrollOffsetProp : 0,
|
|
7788
7916
|
index: 0,
|
|
@@ -7888,6 +8016,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7888
8016
|
viewabilityConfigCallbackPairs: void 0
|
|
7889
8017
|
};
|
|
7890
8018
|
const internalState = ctx.state;
|
|
8019
|
+
ctx.scrollToEnd = (options) => scrollToEnd(ctx, options);
|
|
7891
8020
|
internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
|
|
7892
8021
|
internalState.reprocessCurrentScroll = () => updateScroll(ctx, internalState.scroll, true);
|
|
7893
8022
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
|
|
@@ -8241,6 +8370,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
8241
8370
|
onScroll: (event) => onScroll(ctx, event),
|
|
8242
8371
|
onScrollBeginDrag: (event) => {
|
|
8243
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
|
+
}
|
|
8244
8380
|
prepareReachedEdgeForNextUserScroll(ctx);
|
|
8245
8381
|
(_b2 = (_a4 = state.props).onScrollBeginDrag) == null ? void 0 : _b2.call(_a4, event);
|
|
8246
8382
|
},
|