@legendapp/list 3.0.0-beta.30 → 3.0.0-beta.31
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/index.js +130 -128
- package/index.mjs +130 -128
- package/index.native.js +130 -128
- package/index.native.mjs +130 -128
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1425,6 +1425,132 @@ function clampScrollOffset(ctx, offset) {
|
|
|
1425
1425
|
return clampedOffset;
|
|
1426
1426
|
}
|
|
1427
1427
|
|
|
1428
|
+
// src/utils/checkThreshold.ts
|
|
1429
|
+
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1430
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1431
|
+
const absDistance = Math.abs(distance);
|
|
1432
|
+
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1433
|
+
const updateSnapshot = () => {
|
|
1434
|
+
setSnapshot({
|
|
1435
|
+
atThreshold,
|
|
1436
|
+
contentSize: context.contentSize,
|
|
1437
|
+
dataLength: context.dataLength,
|
|
1438
|
+
scrollPosition: context.scrollPosition
|
|
1439
|
+
});
|
|
1440
|
+
};
|
|
1441
|
+
if (!wasReached) {
|
|
1442
|
+
if (!within) {
|
|
1443
|
+
return false;
|
|
1444
|
+
}
|
|
1445
|
+
onReached(distance);
|
|
1446
|
+
updateSnapshot();
|
|
1447
|
+
return true;
|
|
1448
|
+
}
|
|
1449
|
+
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1450
|
+
if (reset) {
|
|
1451
|
+
setSnapshot(void 0);
|
|
1452
|
+
return false;
|
|
1453
|
+
}
|
|
1454
|
+
if (within) {
|
|
1455
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1456
|
+
if (changed) {
|
|
1457
|
+
if (allowReentryOnChange) {
|
|
1458
|
+
onReached(distance);
|
|
1459
|
+
}
|
|
1460
|
+
updateSnapshot();
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
return true;
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
// src/utils/checkAtBottom.ts
|
|
1467
|
+
function checkAtBottom(ctx) {
|
|
1468
|
+
var _a3;
|
|
1469
|
+
const state = ctx.state;
|
|
1470
|
+
if (!state || state.initialScroll) {
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
const {
|
|
1474
|
+
queuedInitialLayout,
|
|
1475
|
+
scrollLength,
|
|
1476
|
+
scroll,
|
|
1477
|
+
maintainingScrollAtEnd,
|
|
1478
|
+
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1479
|
+
} = state;
|
|
1480
|
+
if (state.initialScroll) {
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
const contentSize = getContentSize(ctx);
|
|
1484
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1485
|
+
const insetEnd = getContentInsetEnd(state);
|
|
1486
|
+
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1487
|
+
const isContentLess = contentSize < scrollLength;
|
|
1488
|
+
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1489
|
+
state.isEndReached = checkThreshold(
|
|
1490
|
+
distanceFromEnd,
|
|
1491
|
+
isContentLess,
|
|
1492
|
+
onEndReachedThreshold * scrollLength,
|
|
1493
|
+
state.isEndReached,
|
|
1494
|
+
state.endReachedSnapshot,
|
|
1495
|
+
{
|
|
1496
|
+
contentSize,
|
|
1497
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1498
|
+
scrollPosition: scroll
|
|
1499
|
+
},
|
|
1500
|
+
(distance) => {
|
|
1501
|
+
var _a4, _b;
|
|
1502
|
+
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1503
|
+
},
|
|
1504
|
+
(snapshot) => {
|
|
1505
|
+
state.endReachedSnapshot = snapshot;
|
|
1506
|
+
},
|
|
1507
|
+
true
|
|
1508
|
+
);
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
// src/utils/checkAtTop.ts
|
|
1513
|
+
function checkAtTop(ctx) {
|
|
1514
|
+
var _a3;
|
|
1515
|
+
const state = ctx == null ? void 0 : ctx.state;
|
|
1516
|
+
if (!state || state.initialScroll) {
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
const {
|
|
1520
|
+
scrollLength,
|
|
1521
|
+
scroll,
|
|
1522
|
+
props: { onStartReachedThreshold }
|
|
1523
|
+
} = state;
|
|
1524
|
+
const distanceFromTop = scroll;
|
|
1525
|
+
state.isAtStart = distanceFromTop <= 0;
|
|
1526
|
+
state.isStartReached = checkThreshold(
|
|
1527
|
+
distanceFromTop,
|
|
1528
|
+
false,
|
|
1529
|
+
onStartReachedThreshold * scrollLength,
|
|
1530
|
+
state.isStartReached,
|
|
1531
|
+
state.startReachedSnapshot,
|
|
1532
|
+
{
|
|
1533
|
+
contentSize: state.totalSize,
|
|
1534
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1535
|
+
scrollPosition: scroll
|
|
1536
|
+
},
|
|
1537
|
+
(distance) => {
|
|
1538
|
+
var _a4, _b;
|
|
1539
|
+
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1540
|
+
},
|
|
1541
|
+
(snapshot) => {
|
|
1542
|
+
state.startReachedSnapshot = snapshot;
|
|
1543
|
+
},
|
|
1544
|
+
false
|
|
1545
|
+
);
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
// src/utils/checkThresholds.ts
|
|
1549
|
+
function checkThresholds(ctx) {
|
|
1550
|
+
checkAtBottom(ctx);
|
|
1551
|
+
checkAtTop(ctx);
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1428
1554
|
// src/utils/setInitialRenderState.ts
|
|
1429
1555
|
function setInitialRenderState(ctx, {
|
|
1430
1556
|
didLayout,
|
|
@@ -1462,6 +1588,7 @@ function finishScrollTo(ctx) {
|
|
|
1462
1588
|
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1463
1589
|
}
|
|
1464
1590
|
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
1591
|
+
checkThresholds(ctx);
|
|
1465
1592
|
}
|
|
1466
1593
|
}
|
|
1467
1594
|
|
|
@@ -1559,128 +1686,6 @@ function scrollTo(ctx, params) {
|
|
|
1559
1686
|
}
|
|
1560
1687
|
}
|
|
1561
1688
|
|
|
1562
|
-
// src/utils/checkThreshold.ts
|
|
1563
|
-
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1564
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1565
|
-
const absDistance = Math.abs(distance);
|
|
1566
|
-
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1567
|
-
if (wasReached === null) {
|
|
1568
|
-
if (!within && distance >= 0) {
|
|
1569
|
-
return false;
|
|
1570
|
-
}
|
|
1571
|
-
return null;
|
|
1572
|
-
}
|
|
1573
|
-
const updateSnapshot = () => {
|
|
1574
|
-
setSnapshot({
|
|
1575
|
-
atThreshold,
|
|
1576
|
-
contentSize: context.contentSize,
|
|
1577
|
-
dataLength: context.dataLength,
|
|
1578
|
-
scrollPosition: context.scrollPosition
|
|
1579
|
-
});
|
|
1580
|
-
};
|
|
1581
|
-
if (!wasReached) {
|
|
1582
|
-
if (!within) {
|
|
1583
|
-
return false;
|
|
1584
|
-
}
|
|
1585
|
-
onReached(distance);
|
|
1586
|
-
updateSnapshot();
|
|
1587
|
-
return true;
|
|
1588
|
-
}
|
|
1589
|
-
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1590
|
-
if (reset) {
|
|
1591
|
-
setSnapshot(void 0);
|
|
1592
|
-
return false;
|
|
1593
|
-
}
|
|
1594
|
-
if (within) {
|
|
1595
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1596
|
-
if (changed) {
|
|
1597
|
-
if (allowReentryOnChange) {
|
|
1598
|
-
onReached(distance);
|
|
1599
|
-
}
|
|
1600
|
-
updateSnapshot();
|
|
1601
|
-
}
|
|
1602
|
-
}
|
|
1603
|
-
return true;
|
|
1604
|
-
};
|
|
1605
|
-
|
|
1606
|
-
// src/utils/checkAtBottom.ts
|
|
1607
|
-
function checkAtBottom(ctx) {
|
|
1608
|
-
var _a3;
|
|
1609
|
-
const state = ctx.state;
|
|
1610
|
-
if (!state) {
|
|
1611
|
-
return;
|
|
1612
|
-
}
|
|
1613
|
-
const {
|
|
1614
|
-
queuedInitialLayout,
|
|
1615
|
-
scrollLength,
|
|
1616
|
-
scroll,
|
|
1617
|
-
maintainingScrollAtEnd,
|
|
1618
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1619
|
-
} = state;
|
|
1620
|
-
const contentSize = getContentSize(ctx);
|
|
1621
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1622
|
-
const insetEnd = getContentInsetEnd(state);
|
|
1623
|
-
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1624
|
-
const isContentLess = contentSize < scrollLength;
|
|
1625
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1626
|
-
state.isEndReached = checkThreshold(
|
|
1627
|
-
distanceFromEnd,
|
|
1628
|
-
isContentLess,
|
|
1629
|
-
onEndReachedThreshold * scrollLength,
|
|
1630
|
-
state.isEndReached,
|
|
1631
|
-
state.endReachedSnapshot,
|
|
1632
|
-
{
|
|
1633
|
-
contentSize,
|
|
1634
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1635
|
-
scrollPosition: scroll
|
|
1636
|
-
},
|
|
1637
|
-
(distance) => {
|
|
1638
|
-
var _a4, _b;
|
|
1639
|
-
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1640
|
-
},
|
|
1641
|
-
(snapshot) => {
|
|
1642
|
-
state.endReachedSnapshot = snapshot;
|
|
1643
|
-
},
|
|
1644
|
-
true
|
|
1645
|
-
);
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
|
|
1649
|
-
// src/utils/checkAtTop.ts
|
|
1650
|
-
function checkAtTop(state) {
|
|
1651
|
-
var _a3;
|
|
1652
|
-
if (!state) {
|
|
1653
|
-
return;
|
|
1654
|
-
}
|
|
1655
|
-
const {
|
|
1656
|
-
scrollLength,
|
|
1657
|
-
scroll,
|
|
1658
|
-
props: { onStartReachedThreshold }
|
|
1659
|
-
} = state;
|
|
1660
|
-
const distanceFromTop = scroll;
|
|
1661
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
1662
|
-
state.isStartReached = checkThreshold(
|
|
1663
|
-
distanceFromTop,
|
|
1664
|
-
false,
|
|
1665
|
-
onStartReachedThreshold * scrollLength,
|
|
1666
|
-
state.isStartReached,
|
|
1667
|
-
state.startReachedSnapshot,
|
|
1668
|
-
{
|
|
1669
|
-
contentSize: state.totalSize,
|
|
1670
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1671
|
-
scrollPosition: scroll
|
|
1672
|
-
},
|
|
1673
|
-
(distance) => {
|
|
1674
|
-
var _a4, _b;
|
|
1675
|
-
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1676
|
-
},
|
|
1677
|
-
(snapshot) => {
|
|
1678
|
-
state.startReachedSnapshot = snapshot;
|
|
1679
|
-
},
|
|
1680
|
-
false
|
|
1681
|
-
);
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
1689
|
// src/core/updateScroll.ts
|
|
1685
1690
|
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
1686
1691
|
const state = ctx.state;
|
|
@@ -1726,8 +1731,7 @@ function updateScroll(ctx, newScroll, forceUpdate) {
|
|
|
1726
1731
|
const runCalculateItems = () => {
|
|
1727
1732
|
var _a3;
|
|
1728
1733
|
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
1729
|
-
|
|
1730
|
-
checkAtTop(state);
|
|
1734
|
+
checkThresholds(ctx);
|
|
1731
1735
|
};
|
|
1732
1736
|
if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
|
|
1733
1737
|
reactDom.flushSync(runCalculateItems);
|
|
@@ -3154,8 +3158,7 @@ function checkResetContainers(ctx, dataProp) {
|
|
|
3154
3158
|
state.isEndReached = false;
|
|
3155
3159
|
}
|
|
3156
3160
|
if (!didMaintainScrollAtEnd) {
|
|
3157
|
-
|
|
3158
|
-
checkAtBottom(ctx);
|
|
3161
|
+
checkThresholds(ctx);
|
|
3159
3162
|
}
|
|
3160
3163
|
delete state.previousData;
|
|
3161
3164
|
}
|
|
@@ -3243,8 +3246,7 @@ function handleLayout(ctx, layout, setCanRender) {
|
|
|
3243
3246
|
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
3244
3247
|
doMaintainScrollAtEnd(ctx, false);
|
|
3245
3248
|
}
|
|
3246
|
-
|
|
3247
|
-
checkAtTop(state);
|
|
3249
|
+
checkThresholds(ctx);
|
|
3248
3250
|
if (state) {
|
|
3249
3251
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
3250
3252
|
}
|
package/index.mjs
CHANGED
|
@@ -1404,6 +1404,132 @@ function clampScrollOffset(ctx, offset) {
|
|
|
1404
1404
|
return clampedOffset;
|
|
1405
1405
|
}
|
|
1406
1406
|
|
|
1407
|
+
// src/utils/checkThreshold.ts
|
|
1408
|
+
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1409
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1410
|
+
const absDistance = Math.abs(distance);
|
|
1411
|
+
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1412
|
+
const updateSnapshot = () => {
|
|
1413
|
+
setSnapshot({
|
|
1414
|
+
atThreshold,
|
|
1415
|
+
contentSize: context.contentSize,
|
|
1416
|
+
dataLength: context.dataLength,
|
|
1417
|
+
scrollPosition: context.scrollPosition
|
|
1418
|
+
});
|
|
1419
|
+
};
|
|
1420
|
+
if (!wasReached) {
|
|
1421
|
+
if (!within) {
|
|
1422
|
+
return false;
|
|
1423
|
+
}
|
|
1424
|
+
onReached(distance);
|
|
1425
|
+
updateSnapshot();
|
|
1426
|
+
return true;
|
|
1427
|
+
}
|
|
1428
|
+
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1429
|
+
if (reset) {
|
|
1430
|
+
setSnapshot(void 0);
|
|
1431
|
+
return false;
|
|
1432
|
+
}
|
|
1433
|
+
if (within) {
|
|
1434
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1435
|
+
if (changed) {
|
|
1436
|
+
if (allowReentryOnChange) {
|
|
1437
|
+
onReached(distance);
|
|
1438
|
+
}
|
|
1439
|
+
updateSnapshot();
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
return true;
|
|
1443
|
+
};
|
|
1444
|
+
|
|
1445
|
+
// src/utils/checkAtBottom.ts
|
|
1446
|
+
function checkAtBottom(ctx) {
|
|
1447
|
+
var _a3;
|
|
1448
|
+
const state = ctx.state;
|
|
1449
|
+
if (!state || state.initialScroll) {
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
const {
|
|
1453
|
+
queuedInitialLayout,
|
|
1454
|
+
scrollLength,
|
|
1455
|
+
scroll,
|
|
1456
|
+
maintainingScrollAtEnd,
|
|
1457
|
+
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1458
|
+
} = state;
|
|
1459
|
+
if (state.initialScroll) {
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
const contentSize = getContentSize(ctx);
|
|
1463
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1464
|
+
const insetEnd = getContentInsetEnd(state);
|
|
1465
|
+
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1466
|
+
const isContentLess = contentSize < scrollLength;
|
|
1467
|
+
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1468
|
+
state.isEndReached = checkThreshold(
|
|
1469
|
+
distanceFromEnd,
|
|
1470
|
+
isContentLess,
|
|
1471
|
+
onEndReachedThreshold * scrollLength,
|
|
1472
|
+
state.isEndReached,
|
|
1473
|
+
state.endReachedSnapshot,
|
|
1474
|
+
{
|
|
1475
|
+
contentSize,
|
|
1476
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1477
|
+
scrollPosition: scroll
|
|
1478
|
+
},
|
|
1479
|
+
(distance) => {
|
|
1480
|
+
var _a4, _b;
|
|
1481
|
+
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1482
|
+
},
|
|
1483
|
+
(snapshot) => {
|
|
1484
|
+
state.endReachedSnapshot = snapshot;
|
|
1485
|
+
},
|
|
1486
|
+
true
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
// src/utils/checkAtTop.ts
|
|
1492
|
+
function checkAtTop(ctx) {
|
|
1493
|
+
var _a3;
|
|
1494
|
+
const state = ctx == null ? void 0 : ctx.state;
|
|
1495
|
+
if (!state || state.initialScroll) {
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
const {
|
|
1499
|
+
scrollLength,
|
|
1500
|
+
scroll,
|
|
1501
|
+
props: { onStartReachedThreshold }
|
|
1502
|
+
} = state;
|
|
1503
|
+
const distanceFromTop = scroll;
|
|
1504
|
+
state.isAtStart = distanceFromTop <= 0;
|
|
1505
|
+
state.isStartReached = checkThreshold(
|
|
1506
|
+
distanceFromTop,
|
|
1507
|
+
false,
|
|
1508
|
+
onStartReachedThreshold * scrollLength,
|
|
1509
|
+
state.isStartReached,
|
|
1510
|
+
state.startReachedSnapshot,
|
|
1511
|
+
{
|
|
1512
|
+
contentSize: state.totalSize,
|
|
1513
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1514
|
+
scrollPosition: scroll
|
|
1515
|
+
},
|
|
1516
|
+
(distance) => {
|
|
1517
|
+
var _a4, _b;
|
|
1518
|
+
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1519
|
+
},
|
|
1520
|
+
(snapshot) => {
|
|
1521
|
+
state.startReachedSnapshot = snapshot;
|
|
1522
|
+
},
|
|
1523
|
+
false
|
|
1524
|
+
);
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// src/utils/checkThresholds.ts
|
|
1528
|
+
function checkThresholds(ctx) {
|
|
1529
|
+
checkAtBottom(ctx);
|
|
1530
|
+
checkAtTop(ctx);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1407
1533
|
// src/utils/setInitialRenderState.ts
|
|
1408
1534
|
function setInitialRenderState(ctx, {
|
|
1409
1535
|
didLayout,
|
|
@@ -1441,6 +1567,7 @@ function finishScrollTo(ctx) {
|
|
|
1441
1567
|
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1442
1568
|
}
|
|
1443
1569
|
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
1570
|
+
checkThresholds(ctx);
|
|
1444
1571
|
}
|
|
1445
1572
|
}
|
|
1446
1573
|
|
|
@@ -1538,128 +1665,6 @@ function scrollTo(ctx, params) {
|
|
|
1538
1665
|
}
|
|
1539
1666
|
}
|
|
1540
1667
|
|
|
1541
|
-
// src/utils/checkThreshold.ts
|
|
1542
|
-
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1543
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1544
|
-
const absDistance = Math.abs(distance);
|
|
1545
|
-
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1546
|
-
if (wasReached === null) {
|
|
1547
|
-
if (!within && distance >= 0) {
|
|
1548
|
-
return false;
|
|
1549
|
-
}
|
|
1550
|
-
return null;
|
|
1551
|
-
}
|
|
1552
|
-
const updateSnapshot = () => {
|
|
1553
|
-
setSnapshot({
|
|
1554
|
-
atThreshold,
|
|
1555
|
-
contentSize: context.contentSize,
|
|
1556
|
-
dataLength: context.dataLength,
|
|
1557
|
-
scrollPosition: context.scrollPosition
|
|
1558
|
-
});
|
|
1559
|
-
};
|
|
1560
|
-
if (!wasReached) {
|
|
1561
|
-
if (!within) {
|
|
1562
|
-
return false;
|
|
1563
|
-
}
|
|
1564
|
-
onReached(distance);
|
|
1565
|
-
updateSnapshot();
|
|
1566
|
-
return true;
|
|
1567
|
-
}
|
|
1568
|
-
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1569
|
-
if (reset) {
|
|
1570
|
-
setSnapshot(void 0);
|
|
1571
|
-
return false;
|
|
1572
|
-
}
|
|
1573
|
-
if (within) {
|
|
1574
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1575
|
-
if (changed) {
|
|
1576
|
-
if (allowReentryOnChange) {
|
|
1577
|
-
onReached(distance);
|
|
1578
|
-
}
|
|
1579
|
-
updateSnapshot();
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
return true;
|
|
1583
|
-
};
|
|
1584
|
-
|
|
1585
|
-
// src/utils/checkAtBottom.ts
|
|
1586
|
-
function checkAtBottom(ctx) {
|
|
1587
|
-
var _a3;
|
|
1588
|
-
const state = ctx.state;
|
|
1589
|
-
if (!state) {
|
|
1590
|
-
return;
|
|
1591
|
-
}
|
|
1592
|
-
const {
|
|
1593
|
-
queuedInitialLayout,
|
|
1594
|
-
scrollLength,
|
|
1595
|
-
scroll,
|
|
1596
|
-
maintainingScrollAtEnd,
|
|
1597
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1598
|
-
} = state;
|
|
1599
|
-
const contentSize = getContentSize(ctx);
|
|
1600
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1601
|
-
const insetEnd = getContentInsetEnd(state);
|
|
1602
|
-
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1603
|
-
const isContentLess = contentSize < scrollLength;
|
|
1604
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1605
|
-
state.isEndReached = checkThreshold(
|
|
1606
|
-
distanceFromEnd,
|
|
1607
|
-
isContentLess,
|
|
1608
|
-
onEndReachedThreshold * scrollLength,
|
|
1609
|
-
state.isEndReached,
|
|
1610
|
-
state.endReachedSnapshot,
|
|
1611
|
-
{
|
|
1612
|
-
contentSize,
|
|
1613
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1614
|
-
scrollPosition: scroll
|
|
1615
|
-
},
|
|
1616
|
-
(distance) => {
|
|
1617
|
-
var _a4, _b;
|
|
1618
|
-
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1619
|
-
},
|
|
1620
|
-
(snapshot) => {
|
|
1621
|
-
state.endReachedSnapshot = snapshot;
|
|
1622
|
-
},
|
|
1623
|
-
true
|
|
1624
|
-
);
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
// src/utils/checkAtTop.ts
|
|
1629
|
-
function checkAtTop(state) {
|
|
1630
|
-
var _a3;
|
|
1631
|
-
if (!state) {
|
|
1632
|
-
return;
|
|
1633
|
-
}
|
|
1634
|
-
const {
|
|
1635
|
-
scrollLength,
|
|
1636
|
-
scroll,
|
|
1637
|
-
props: { onStartReachedThreshold }
|
|
1638
|
-
} = state;
|
|
1639
|
-
const distanceFromTop = scroll;
|
|
1640
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
1641
|
-
state.isStartReached = checkThreshold(
|
|
1642
|
-
distanceFromTop,
|
|
1643
|
-
false,
|
|
1644
|
-
onStartReachedThreshold * scrollLength,
|
|
1645
|
-
state.isStartReached,
|
|
1646
|
-
state.startReachedSnapshot,
|
|
1647
|
-
{
|
|
1648
|
-
contentSize: state.totalSize,
|
|
1649
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1650
|
-
scrollPosition: scroll
|
|
1651
|
-
},
|
|
1652
|
-
(distance) => {
|
|
1653
|
-
var _a4, _b;
|
|
1654
|
-
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1655
|
-
},
|
|
1656
|
-
(snapshot) => {
|
|
1657
|
-
state.startReachedSnapshot = snapshot;
|
|
1658
|
-
},
|
|
1659
|
-
false
|
|
1660
|
-
);
|
|
1661
|
-
}
|
|
1662
|
-
|
|
1663
1668
|
// src/core/updateScroll.ts
|
|
1664
1669
|
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
1665
1670
|
const state = ctx.state;
|
|
@@ -1705,8 +1710,7 @@ function updateScroll(ctx, newScroll, forceUpdate) {
|
|
|
1705
1710
|
const runCalculateItems = () => {
|
|
1706
1711
|
var _a3;
|
|
1707
1712
|
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
1708
|
-
|
|
1709
|
-
checkAtTop(state);
|
|
1713
|
+
checkThresholds(ctx);
|
|
1710
1714
|
};
|
|
1711
1715
|
if (scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
|
|
1712
1716
|
flushSync(runCalculateItems);
|
|
@@ -3133,8 +3137,7 @@ function checkResetContainers(ctx, dataProp) {
|
|
|
3133
3137
|
state.isEndReached = false;
|
|
3134
3138
|
}
|
|
3135
3139
|
if (!didMaintainScrollAtEnd) {
|
|
3136
|
-
|
|
3137
|
-
checkAtBottom(ctx);
|
|
3140
|
+
checkThresholds(ctx);
|
|
3138
3141
|
}
|
|
3139
3142
|
delete state.previousData;
|
|
3140
3143
|
}
|
|
@@ -3222,8 +3225,7 @@ function handleLayout(ctx, layout, setCanRender) {
|
|
|
3222
3225
|
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
3223
3226
|
doMaintainScrollAtEnd(ctx, false);
|
|
3224
3227
|
}
|
|
3225
|
-
|
|
3226
|
-
checkAtTop(state);
|
|
3228
|
+
checkThresholds(ctx);
|
|
3227
3229
|
if (state) {
|
|
3228
3230
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
3229
3231
|
}
|
package/index.native.js
CHANGED
|
@@ -1168,6 +1168,132 @@ function clampScrollOffset(ctx, offset) {
|
|
|
1168
1168
|
return clampedOffset;
|
|
1169
1169
|
}
|
|
1170
1170
|
|
|
1171
|
+
// src/utils/checkThreshold.ts
|
|
1172
|
+
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1173
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1174
|
+
const absDistance = Math.abs(distance);
|
|
1175
|
+
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1176
|
+
const updateSnapshot = () => {
|
|
1177
|
+
setSnapshot({
|
|
1178
|
+
atThreshold,
|
|
1179
|
+
contentSize: context.contentSize,
|
|
1180
|
+
dataLength: context.dataLength,
|
|
1181
|
+
scrollPosition: context.scrollPosition
|
|
1182
|
+
});
|
|
1183
|
+
};
|
|
1184
|
+
if (!wasReached) {
|
|
1185
|
+
if (!within) {
|
|
1186
|
+
return false;
|
|
1187
|
+
}
|
|
1188
|
+
onReached(distance);
|
|
1189
|
+
updateSnapshot();
|
|
1190
|
+
return true;
|
|
1191
|
+
}
|
|
1192
|
+
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1193
|
+
if (reset) {
|
|
1194
|
+
setSnapshot(void 0);
|
|
1195
|
+
return false;
|
|
1196
|
+
}
|
|
1197
|
+
if (within) {
|
|
1198
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1199
|
+
if (changed) {
|
|
1200
|
+
if (allowReentryOnChange) {
|
|
1201
|
+
onReached(distance);
|
|
1202
|
+
}
|
|
1203
|
+
updateSnapshot();
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
return true;
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
// src/utils/checkAtBottom.ts
|
|
1210
|
+
function checkAtBottom(ctx) {
|
|
1211
|
+
var _a3;
|
|
1212
|
+
const state = ctx.state;
|
|
1213
|
+
if (!state || state.initialScroll) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
const {
|
|
1217
|
+
queuedInitialLayout,
|
|
1218
|
+
scrollLength,
|
|
1219
|
+
scroll,
|
|
1220
|
+
maintainingScrollAtEnd,
|
|
1221
|
+
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1222
|
+
} = state;
|
|
1223
|
+
if (state.initialScroll) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
const contentSize = getContentSize(ctx);
|
|
1227
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1228
|
+
const insetEnd = getContentInsetEnd(state);
|
|
1229
|
+
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1230
|
+
const isContentLess = contentSize < scrollLength;
|
|
1231
|
+
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1232
|
+
state.isEndReached = checkThreshold(
|
|
1233
|
+
distanceFromEnd,
|
|
1234
|
+
isContentLess,
|
|
1235
|
+
onEndReachedThreshold * scrollLength,
|
|
1236
|
+
state.isEndReached,
|
|
1237
|
+
state.endReachedSnapshot,
|
|
1238
|
+
{
|
|
1239
|
+
contentSize,
|
|
1240
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1241
|
+
scrollPosition: scroll
|
|
1242
|
+
},
|
|
1243
|
+
(distance) => {
|
|
1244
|
+
var _a4, _b;
|
|
1245
|
+
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1246
|
+
},
|
|
1247
|
+
(snapshot) => {
|
|
1248
|
+
state.endReachedSnapshot = snapshot;
|
|
1249
|
+
},
|
|
1250
|
+
true
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// src/utils/checkAtTop.ts
|
|
1256
|
+
function checkAtTop(ctx) {
|
|
1257
|
+
var _a3;
|
|
1258
|
+
const state = ctx == null ? void 0 : ctx.state;
|
|
1259
|
+
if (!state || state.initialScroll) {
|
|
1260
|
+
return;
|
|
1261
|
+
}
|
|
1262
|
+
const {
|
|
1263
|
+
scrollLength,
|
|
1264
|
+
scroll,
|
|
1265
|
+
props: { onStartReachedThreshold }
|
|
1266
|
+
} = state;
|
|
1267
|
+
const distanceFromTop = scroll;
|
|
1268
|
+
state.isAtStart = distanceFromTop <= 0;
|
|
1269
|
+
state.isStartReached = checkThreshold(
|
|
1270
|
+
distanceFromTop,
|
|
1271
|
+
false,
|
|
1272
|
+
onStartReachedThreshold * scrollLength,
|
|
1273
|
+
state.isStartReached,
|
|
1274
|
+
state.startReachedSnapshot,
|
|
1275
|
+
{
|
|
1276
|
+
contentSize: state.totalSize,
|
|
1277
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1278
|
+
scrollPosition: scroll
|
|
1279
|
+
},
|
|
1280
|
+
(distance) => {
|
|
1281
|
+
var _a4, _b;
|
|
1282
|
+
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1283
|
+
},
|
|
1284
|
+
(snapshot) => {
|
|
1285
|
+
state.startReachedSnapshot = snapshot;
|
|
1286
|
+
},
|
|
1287
|
+
false
|
|
1288
|
+
);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// src/utils/checkThresholds.ts
|
|
1292
|
+
function checkThresholds(ctx) {
|
|
1293
|
+
checkAtBottom(ctx);
|
|
1294
|
+
checkAtTop(ctx);
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1171
1297
|
// src/utils/setInitialRenderState.ts
|
|
1172
1298
|
function setInitialRenderState(ctx, {
|
|
1173
1299
|
didLayout,
|
|
@@ -1205,6 +1331,7 @@ function finishScrollTo(ctx) {
|
|
|
1205
1331
|
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1206
1332
|
}
|
|
1207
1333
|
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
1334
|
+
checkThresholds(ctx);
|
|
1208
1335
|
}
|
|
1209
1336
|
}
|
|
1210
1337
|
|
|
@@ -1304,128 +1431,6 @@ var flushSync = (fn) => {
|
|
|
1304
1431
|
fn();
|
|
1305
1432
|
};
|
|
1306
1433
|
|
|
1307
|
-
// src/utils/checkThreshold.ts
|
|
1308
|
-
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1309
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1310
|
-
const absDistance = Math.abs(distance);
|
|
1311
|
-
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1312
|
-
if (wasReached === null) {
|
|
1313
|
-
if (!within && distance >= 0) {
|
|
1314
|
-
return false;
|
|
1315
|
-
}
|
|
1316
|
-
return null;
|
|
1317
|
-
}
|
|
1318
|
-
const updateSnapshot = () => {
|
|
1319
|
-
setSnapshot({
|
|
1320
|
-
atThreshold,
|
|
1321
|
-
contentSize: context.contentSize,
|
|
1322
|
-
dataLength: context.dataLength,
|
|
1323
|
-
scrollPosition: context.scrollPosition
|
|
1324
|
-
});
|
|
1325
|
-
};
|
|
1326
|
-
if (!wasReached) {
|
|
1327
|
-
if (!within) {
|
|
1328
|
-
return false;
|
|
1329
|
-
}
|
|
1330
|
-
onReached(distance);
|
|
1331
|
-
updateSnapshot();
|
|
1332
|
-
return true;
|
|
1333
|
-
}
|
|
1334
|
-
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1335
|
-
if (reset) {
|
|
1336
|
-
setSnapshot(void 0);
|
|
1337
|
-
return false;
|
|
1338
|
-
}
|
|
1339
|
-
if (within) {
|
|
1340
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1341
|
-
if (changed) {
|
|
1342
|
-
if (allowReentryOnChange) {
|
|
1343
|
-
onReached(distance);
|
|
1344
|
-
}
|
|
1345
|
-
updateSnapshot();
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
return true;
|
|
1349
|
-
};
|
|
1350
|
-
|
|
1351
|
-
// src/utils/checkAtBottom.ts
|
|
1352
|
-
function checkAtBottom(ctx) {
|
|
1353
|
-
var _a3;
|
|
1354
|
-
const state = ctx.state;
|
|
1355
|
-
if (!state) {
|
|
1356
|
-
return;
|
|
1357
|
-
}
|
|
1358
|
-
const {
|
|
1359
|
-
queuedInitialLayout,
|
|
1360
|
-
scrollLength,
|
|
1361
|
-
scroll,
|
|
1362
|
-
maintainingScrollAtEnd,
|
|
1363
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1364
|
-
} = state;
|
|
1365
|
-
const contentSize = getContentSize(ctx);
|
|
1366
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1367
|
-
const insetEnd = getContentInsetEnd(state);
|
|
1368
|
-
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1369
|
-
const isContentLess = contentSize < scrollLength;
|
|
1370
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1371
|
-
state.isEndReached = checkThreshold(
|
|
1372
|
-
distanceFromEnd,
|
|
1373
|
-
isContentLess,
|
|
1374
|
-
onEndReachedThreshold * scrollLength,
|
|
1375
|
-
state.isEndReached,
|
|
1376
|
-
state.endReachedSnapshot,
|
|
1377
|
-
{
|
|
1378
|
-
contentSize,
|
|
1379
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1380
|
-
scrollPosition: scroll
|
|
1381
|
-
},
|
|
1382
|
-
(distance) => {
|
|
1383
|
-
var _a4, _b;
|
|
1384
|
-
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1385
|
-
},
|
|
1386
|
-
(snapshot) => {
|
|
1387
|
-
state.endReachedSnapshot = snapshot;
|
|
1388
|
-
},
|
|
1389
|
-
true
|
|
1390
|
-
);
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
|
|
1394
|
-
// src/utils/checkAtTop.ts
|
|
1395
|
-
function checkAtTop(state) {
|
|
1396
|
-
var _a3;
|
|
1397
|
-
if (!state) {
|
|
1398
|
-
return;
|
|
1399
|
-
}
|
|
1400
|
-
const {
|
|
1401
|
-
scrollLength,
|
|
1402
|
-
scroll,
|
|
1403
|
-
props: { onStartReachedThreshold }
|
|
1404
|
-
} = state;
|
|
1405
|
-
const distanceFromTop = scroll;
|
|
1406
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
1407
|
-
state.isStartReached = checkThreshold(
|
|
1408
|
-
distanceFromTop,
|
|
1409
|
-
false,
|
|
1410
|
-
onStartReachedThreshold * scrollLength,
|
|
1411
|
-
state.isStartReached,
|
|
1412
|
-
state.startReachedSnapshot,
|
|
1413
|
-
{
|
|
1414
|
-
contentSize: state.totalSize,
|
|
1415
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1416
|
-
scrollPosition: scroll
|
|
1417
|
-
},
|
|
1418
|
-
(distance) => {
|
|
1419
|
-
var _a4, _b;
|
|
1420
|
-
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1421
|
-
},
|
|
1422
|
-
(snapshot) => {
|
|
1423
|
-
state.startReachedSnapshot = snapshot;
|
|
1424
|
-
},
|
|
1425
|
-
false
|
|
1426
|
-
);
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
1434
|
// src/core/updateScroll.ts
|
|
1430
1435
|
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
1431
1436
|
const state = ctx.state;
|
|
@@ -1471,8 +1476,7 @@ function updateScroll(ctx, newScroll, forceUpdate) {
|
|
|
1471
1476
|
const runCalculateItems = () => {
|
|
1472
1477
|
var _a3;
|
|
1473
1478
|
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
1474
|
-
|
|
1475
|
-
checkAtTop(state);
|
|
1479
|
+
checkThresholds(ctx);
|
|
1476
1480
|
};
|
|
1477
1481
|
if (Platform2.OS === "web" && scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
|
|
1478
1482
|
flushSync(runCalculateItems);
|
|
@@ -2946,8 +2950,7 @@ function checkResetContainers(ctx, dataProp) {
|
|
|
2946
2950
|
state.isEndReached = false;
|
|
2947
2951
|
}
|
|
2948
2952
|
if (!didMaintainScrollAtEnd) {
|
|
2949
|
-
|
|
2950
|
-
checkAtBottom(ctx);
|
|
2953
|
+
checkThresholds(ctx);
|
|
2951
2954
|
}
|
|
2952
2955
|
delete state.previousData;
|
|
2953
2956
|
}
|
|
@@ -3035,8 +3038,7 @@ function handleLayout(ctx, layout, setCanRender) {
|
|
|
3035
3038
|
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
3036
3039
|
doMaintainScrollAtEnd(ctx, false);
|
|
3037
3040
|
}
|
|
3038
|
-
|
|
3039
|
-
checkAtTop(state);
|
|
3041
|
+
checkThresholds(ctx);
|
|
3040
3042
|
if (state) {
|
|
3041
3043
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
3042
3044
|
}
|
package/index.native.mjs
CHANGED
|
@@ -1147,6 +1147,132 @@ function clampScrollOffset(ctx, offset) {
|
|
|
1147
1147
|
return clampedOffset;
|
|
1148
1148
|
}
|
|
1149
1149
|
|
|
1150
|
+
// src/utils/checkThreshold.ts
|
|
1151
|
+
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1152
|
+
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1153
|
+
const absDistance = Math.abs(distance);
|
|
1154
|
+
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1155
|
+
const updateSnapshot = () => {
|
|
1156
|
+
setSnapshot({
|
|
1157
|
+
atThreshold,
|
|
1158
|
+
contentSize: context.contentSize,
|
|
1159
|
+
dataLength: context.dataLength,
|
|
1160
|
+
scrollPosition: context.scrollPosition
|
|
1161
|
+
});
|
|
1162
|
+
};
|
|
1163
|
+
if (!wasReached) {
|
|
1164
|
+
if (!within) {
|
|
1165
|
+
return false;
|
|
1166
|
+
}
|
|
1167
|
+
onReached(distance);
|
|
1168
|
+
updateSnapshot();
|
|
1169
|
+
return true;
|
|
1170
|
+
}
|
|
1171
|
+
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1172
|
+
if (reset) {
|
|
1173
|
+
setSnapshot(void 0);
|
|
1174
|
+
return false;
|
|
1175
|
+
}
|
|
1176
|
+
if (within) {
|
|
1177
|
+
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1178
|
+
if (changed) {
|
|
1179
|
+
if (allowReentryOnChange) {
|
|
1180
|
+
onReached(distance);
|
|
1181
|
+
}
|
|
1182
|
+
updateSnapshot();
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return true;
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
// src/utils/checkAtBottom.ts
|
|
1189
|
+
function checkAtBottom(ctx) {
|
|
1190
|
+
var _a3;
|
|
1191
|
+
const state = ctx.state;
|
|
1192
|
+
if (!state || state.initialScroll) {
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
const {
|
|
1196
|
+
queuedInitialLayout,
|
|
1197
|
+
scrollLength,
|
|
1198
|
+
scroll,
|
|
1199
|
+
maintainingScrollAtEnd,
|
|
1200
|
+
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1201
|
+
} = state;
|
|
1202
|
+
if (state.initialScroll) {
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
const contentSize = getContentSize(ctx);
|
|
1206
|
+
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1207
|
+
const insetEnd = getContentInsetEnd(state);
|
|
1208
|
+
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1209
|
+
const isContentLess = contentSize < scrollLength;
|
|
1210
|
+
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1211
|
+
state.isEndReached = checkThreshold(
|
|
1212
|
+
distanceFromEnd,
|
|
1213
|
+
isContentLess,
|
|
1214
|
+
onEndReachedThreshold * scrollLength,
|
|
1215
|
+
state.isEndReached,
|
|
1216
|
+
state.endReachedSnapshot,
|
|
1217
|
+
{
|
|
1218
|
+
contentSize,
|
|
1219
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1220
|
+
scrollPosition: scroll
|
|
1221
|
+
},
|
|
1222
|
+
(distance) => {
|
|
1223
|
+
var _a4, _b;
|
|
1224
|
+
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1225
|
+
},
|
|
1226
|
+
(snapshot) => {
|
|
1227
|
+
state.endReachedSnapshot = snapshot;
|
|
1228
|
+
},
|
|
1229
|
+
true
|
|
1230
|
+
);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// src/utils/checkAtTop.ts
|
|
1235
|
+
function checkAtTop(ctx) {
|
|
1236
|
+
var _a3;
|
|
1237
|
+
const state = ctx == null ? void 0 : ctx.state;
|
|
1238
|
+
if (!state || state.initialScroll) {
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
const {
|
|
1242
|
+
scrollLength,
|
|
1243
|
+
scroll,
|
|
1244
|
+
props: { onStartReachedThreshold }
|
|
1245
|
+
} = state;
|
|
1246
|
+
const distanceFromTop = scroll;
|
|
1247
|
+
state.isAtStart = distanceFromTop <= 0;
|
|
1248
|
+
state.isStartReached = checkThreshold(
|
|
1249
|
+
distanceFromTop,
|
|
1250
|
+
false,
|
|
1251
|
+
onStartReachedThreshold * scrollLength,
|
|
1252
|
+
state.isStartReached,
|
|
1253
|
+
state.startReachedSnapshot,
|
|
1254
|
+
{
|
|
1255
|
+
contentSize: state.totalSize,
|
|
1256
|
+
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1257
|
+
scrollPosition: scroll
|
|
1258
|
+
},
|
|
1259
|
+
(distance) => {
|
|
1260
|
+
var _a4, _b;
|
|
1261
|
+
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1262
|
+
},
|
|
1263
|
+
(snapshot) => {
|
|
1264
|
+
state.startReachedSnapshot = snapshot;
|
|
1265
|
+
},
|
|
1266
|
+
false
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
// src/utils/checkThresholds.ts
|
|
1271
|
+
function checkThresholds(ctx) {
|
|
1272
|
+
checkAtBottom(ctx);
|
|
1273
|
+
checkAtTop(ctx);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1150
1276
|
// src/utils/setInitialRenderState.ts
|
|
1151
1277
|
function setInitialRenderState(ctx, {
|
|
1152
1278
|
didLayout,
|
|
@@ -1184,6 +1310,7 @@ function finishScrollTo(ctx) {
|
|
|
1184
1310
|
state.scrollAdjustHandler.commitPendingAdjust(scrollingTo);
|
|
1185
1311
|
}
|
|
1186
1312
|
setInitialRenderState(ctx, { didInitialScroll: true });
|
|
1313
|
+
checkThresholds(ctx);
|
|
1187
1314
|
}
|
|
1188
1315
|
}
|
|
1189
1316
|
|
|
@@ -1283,128 +1410,6 @@ var flushSync = (fn) => {
|
|
|
1283
1410
|
fn();
|
|
1284
1411
|
};
|
|
1285
1412
|
|
|
1286
|
-
// src/utils/checkThreshold.ts
|
|
1287
|
-
var HYSTERESIS_MULTIPLIER = 1.3;
|
|
1288
|
-
var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot, allowReentryOnChange) => {
|
|
1289
|
-
const absDistance = Math.abs(distance);
|
|
1290
|
-
const within = atThreshold || threshold > 0 && absDistance <= threshold;
|
|
1291
|
-
if (wasReached === null) {
|
|
1292
|
-
if (!within && distance >= 0) {
|
|
1293
|
-
return false;
|
|
1294
|
-
}
|
|
1295
|
-
return null;
|
|
1296
|
-
}
|
|
1297
|
-
const updateSnapshot = () => {
|
|
1298
|
-
setSnapshot({
|
|
1299
|
-
atThreshold,
|
|
1300
|
-
contentSize: context.contentSize,
|
|
1301
|
-
dataLength: context.dataLength,
|
|
1302
|
-
scrollPosition: context.scrollPosition
|
|
1303
|
-
});
|
|
1304
|
-
};
|
|
1305
|
-
if (!wasReached) {
|
|
1306
|
-
if (!within) {
|
|
1307
|
-
return false;
|
|
1308
|
-
}
|
|
1309
|
-
onReached(distance);
|
|
1310
|
-
updateSnapshot();
|
|
1311
|
-
return true;
|
|
1312
|
-
}
|
|
1313
|
-
const reset = !atThreshold && threshold > 0 && absDistance >= threshold * HYSTERESIS_MULTIPLIER || !atThreshold && threshold <= 0 && absDistance > 0;
|
|
1314
|
-
if (reset) {
|
|
1315
|
-
setSnapshot(void 0);
|
|
1316
|
-
return false;
|
|
1317
|
-
}
|
|
1318
|
-
if (within) {
|
|
1319
|
-
const changed = !snapshot || snapshot.atThreshold !== atThreshold || snapshot.contentSize !== context.contentSize || snapshot.dataLength !== context.dataLength;
|
|
1320
|
-
if (changed) {
|
|
1321
|
-
if (allowReentryOnChange) {
|
|
1322
|
-
onReached(distance);
|
|
1323
|
-
}
|
|
1324
|
-
updateSnapshot();
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
return true;
|
|
1328
|
-
};
|
|
1329
|
-
|
|
1330
|
-
// src/utils/checkAtBottom.ts
|
|
1331
|
-
function checkAtBottom(ctx) {
|
|
1332
|
-
var _a3;
|
|
1333
|
-
const state = ctx.state;
|
|
1334
|
-
if (!state) {
|
|
1335
|
-
return;
|
|
1336
|
-
}
|
|
1337
|
-
const {
|
|
1338
|
-
queuedInitialLayout,
|
|
1339
|
-
scrollLength,
|
|
1340
|
-
scroll,
|
|
1341
|
-
maintainingScrollAtEnd,
|
|
1342
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
|
|
1343
|
-
} = state;
|
|
1344
|
-
const contentSize = getContentSize(ctx);
|
|
1345
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
1346
|
-
const insetEnd = getContentInsetEnd(state);
|
|
1347
|
-
const distanceFromEnd = contentSize - scroll - scrollLength - insetEnd;
|
|
1348
|
-
const isContentLess = contentSize < scrollLength;
|
|
1349
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
1350
|
-
state.isEndReached = checkThreshold(
|
|
1351
|
-
distanceFromEnd,
|
|
1352
|
-
isContentLess,
|
|
1353
|
-
onEndReachedThreshold * scrollLength,
|
|
1354
|
-
state.isEndReached,
|
|
1355
|
-
state.endReachedSnapshot,
|
|
1356
|
-
{
|
|
1357
|
-
contentSize,
|
|
1358
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1359
|
-
scrollPosition: scroll
|
|
1360
|
-
},
|
|
1361
|
-
(distance) => {
|
|
1362
|
-
var _a4, _b;
|
|
1363
|
-
return (_b = (_a4 = state.props).onEndReached) == null ? void 0 : _b.call(_a4, { distanceFromEnd: distance });
|
|
1364
|
-
},
|
|
1365
|
-
(snapshot) => {
|
|
1366
|
-
state.endReachedSnapshot = snapshot;
|
|
1367
|
-
},
|
|
1368
|
-
true
|
|
1369
|
-
);
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
// src/utils/checkAtTop.ts
|
|
1374
|
-
function checkAtTop(state) {
|
|
1375
|
-
var _a3;
|
|
1376
|
-
if (!state) {
|
|
1377
|
-
return;
|
|
1378
|
-
}
|
|
1379
|
-
const {
|
|
1380
|
-
scrollLength,
|
|
1381
|
-
scroll,
|
|
1382
|
-
props: { onStartReachedThreshold }
|
|
1383
|
-
} = state;
|
|
1384
|
-
const distanceFromTop = scroll;
|
|
1385
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
1386
|
-
state.isStartReached = checkThreshold(
|
|
1387
|
-
distanceFromTop,
|
|
1388
|
-
false,
|
|
1389
|
-
onStartReachedThreshold * scrollLength,
|
|
1390
|
-
state.isStartReached,
|
|
1391
|
-
state.startReachedSnapshot,
|
|
1392
|
-
{
|
|
1393
|
-
contentSize: state.totalSize,
|
|
1394
|
-
dataLength: (_a3 = state.props.data) == null ? void 0 : _a3.length,
|
|
1395
|
-
scrollPosition: scroll
|
|
1396
|
-
},
|
|
1397
|
-
(distance) => {
|
|
1398
|
-
var _a4, _b;
|
|
1399
|
-
return (_b = (_a4 = state.props).onStartReached) == null ? void 0 : _b.call(_a4, { distanceFromStart: distance });
|
|
1400
|
-
},
|
|
1401
|
-
(snapshot) => {
|
|
1402
|
-
state.startReachedSnapshot = snapshot;
|
|
1403
|
-
},
|
|
1404
|
-
false
|
|
1405
|
-
);
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
1413
|
// src/core/updateScroll.ts
|
|
1409
1414
|
function updateScroll(ctx, newScroll, forceUpdate) {
|
|
1410
1415
|
const state = ctx.state;
|
|
@@ -1450,8 +1455,7 @@ function updateScroll(ctx, newScroll, forceUpdate) {
|
|
|
1450
1455
|
const runCalculateItems = () => {
|
|
1451
1456
|
var _a3;
|
|
1452
1457
|
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
|
|
1453
|
-
|
|
1454
|
-
checkAtTop(state);
|
|
1458
|
+
checkThresholds(ctx);
|
|
1455
1459
|
};
|
|
1456
1460
|
if (Platform2.OS === "web" && scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength) {
|
|
1457
1461
|
flushSync(runCalculateItems);
|
|
@@ -2925,8 +2929,7 @@ function checkResetContainers(ctx, dataProp) {
|
|
|
2925
2929
|
state.isEndReached = false;
|
|
2926
2930
|
}
|
|
2927
2931
|
if (!didMaintainScrollAtEnd) {
|
|
2928
|
-
|
|
2929
|
-
checkAtBottom(ctx);
|
|
2932
|
+
checkThresholds(ctx);
|
|
2930
2933
|
}
|
|
2931
2934
|
delete state.previousData;
|
|
2932
2935
|
}
|
|
@@ -3014,8 +3017,7 @@ function handleLayout(ctx, layout, setCanRender) {
|
|
|
3014
3017
|
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
3015
3018
|
doMaintainScrollAtEnd(ctx, false);
|
|
3016
3019
|
}
|
|
3017
|
-
|
|
3018
|
-
checkAtTop(state);
|
|
3020
|
+
checkThresholds(ctx);
|
|
3019
3021
|
if (state) {
|
|
3020
3022
|
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
3021
3023
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/list",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.31",
|
|
4
4
|
"description": "Legend List is a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"private": false,
|