@legendapp/list 1.0.8 → 1.0.10
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 +48 -2
- package/index.js +66 -51
- package/index.mjs +67 -52
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
## 1.0.10
|
|
2
|
+
- Fix: Removed an optimization that only checked newly visible items, which could sometimes cause gaps in lists
|
|
3
|
+
- Fix: Scroll history resets properly during scroll operations, which was causing gaps after scroll
|
|
4
|
+
- Fix: Made scroll buffer calculations and scroll jump handling more reliable
|
|
2
5
|
|
|
6
|
+
## 1.0.9
|
|
7
|
+
- Fix: Use the `use-sync-external-store` shim to support older versions of react
|
|
8
|
+
- Fix: Lists sometimes leaving some gaps when reordering a list
|
|
9
|
+
- Fix: Sometimes precomputing next scroll position for calculation incorrectly
|
|
10
|
+
|
|
11
|
+
## 1.0.8
|
|
12
|
+
- Perf: The scroll buffering algorithm is smarter and adjusts based on scroll direction for better performance
|
|
13
|
+
- Perf: The container-finding logic keeps index order, reducing gaps in rendering
|
|
14
|
+
- Perf: Combine multiple hooks in Container to a single `useArray$` hook
|
|
15
|
+
|
|
16
|
+
## 1.0.7
|
|
17
|
+
- Fix: Containers that move out of view are handled better
|
|
18
|
+
|
|
19
|
+
## 1.0.6
|
|
20
|
+
- Fix: Average item size calculations are more accurate while scrolling
|
|
21
|
+
- Fix: Items in view are handled better when data changes
|
|
22
|
+
- Fix: Scroll position is maintained more accurately during updates
|
|
23
|
+
|
|
24
|
+
## 1.0.5
|
|
25
|
+
- Fix: Fast scrolling sometimes caused elements to disappear
|
|
26
|
+
- Fix: Out-of-range `scrollToIndex` calls are handled better
|
|
27
|
+
|
|
28
|
+
## 1.0.4
|
|
29
|
+
- Fix: Container allocation is more efficient
|
|
30
|
+
- Fix: Bidirectional infinite lists scroll better on the old architecture
|
|
31
|
+
- Fix: Item size updates are handled more reliably
|
|
32
|
+
- Fix: Container reuse logic is more accurate
|
|
33
|
+
- Fix: Zero-size layouts are handled better in the old architecture
|
|
34
|
+
|
|
35
|
+
## 1.0.3
|
|
36
|
+
- Fix: Items that are larger than the estimated size are handled correctly
|
|
37
|
+
|
|
38
|
+
## 1.0.2
|
|
39
|
+
- Fix: Initial layout works better in the old architecture
|
|
40
|
+
- Fix: Average size calculations are more accurate for bidirectional scrolling
|
|
41
|
+
- Fix: Initial scroll index behavior is more precise
|
|
42
|
+
- Fix: Item size calculations are more accurate overall
|
|
43
|
+
|
|
44
|
+
## 1.0.1
|
|
45
|
+
- Fix: Total size calculations are correct when using average sizes
|
|
46
|
+
- Fix: Keyboard avoiding behavior is improved for a smoother experience
|
|
47
|
+
|
|
48
|
+
## 1.0.0
|
|
3
49
|
Initial release! Major changes if you're coming from a beta version:
|
|
4
50
|
|
|
5
|
-
- Item hooks like `useRecyclingState` are no longer render props, but can be imported from `@legendapp/list
|
|
51
|
+
- Item hooks like `useRecyclingState` are no longer render props, but can be imported directly from `@legendapp/list`.
|
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var React2 = require('react');
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
|
+
var shim = require('use-sync-external-store/shim');
|
|
5
6
|
|
|
6
7
|
function _interopNamespace(e) {
|
|
7
8
|
if (e && e.__esModule) return e;
|
|
@@ -79,12 +80,6 @@ function createSelectorFunctionsArr(ctx, signalNames) {
|
|
|
79
80
|
}
|
|
80
81
|
};
|
|
81
82
|
}
|
|
82
|
-
function useArr$(signalNames) {
|
|
83
|
-
const ctx = React2__namespace.useContext(ContextState);
|
|
84
|
-
const { subscribe, get } = React2__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
85
|
-
const value = React2.useSyncExternalStore(subscribe, get);
|
|
86
|
-
return value;
|
|
87
|
-
}
|
|
88
83
|
function listen$(ctx, signalName, cb) {
|
|
89
84
|
const { listeners } = ctx;
|
|
90
85
|
let setListeners = listeners.get(signalName);
|
|
@@ -119,6 +114,12 @@ function getContentSize(ctx) {
|
|
|
119
114
|
const totalSize = values.get("totalSize") || 0;
|
|
120
115
|
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
121
116
|
}
|
|
117
|
+
function useArr$(signalNames) {
|
|
118
|
+
const ctx = React2__namespace.useContext(ContextState);
|
|
119
|
+
const { subscribe, get } = React2__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
120
|
+
const value = shim.useSyncExternalStore(subscribe, get);
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
122
123
|
|
|
123
124
|
// src/DebugView.tsx
|
|
124
125
|
var DebugRow = ({ children }) => {
|
|
@@ -1293,6 +1294,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1293
1294
|
const state = refState.current;
|
|
1294
1295
|
if (state.scrollingToOffset === void 0) {
|
|
1295
1296
|
state.disableScrollJumpsFrom = state.scroll - state.scrollAdjustHandler.getAppliedAdjust();
|
|
1297
|
+
state.scrollHistory.length = 0;
|
|
1296
1298
|
setTimeout(() => {
|
|
1297
1299
|
state.disableScrollJumpsFrom = void 0;
|
|
1298
1300
|
}, timeout);
|
|
@@ -1388,7 +1390,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1388
1390
|
}
|
|
1389
1391
|
return false;
|
|
1390
1392
|
}, []);
|
|
1391
|
-
const calculateItemsInView = React2.useCallback(() => {
|
|
1393
|
+
const calculateItemsInView = React2.useCallback((isReset) => {
|
|
1392
1394
|
var _a;
|
|
1393
1395
|
const state = refState.current;
|
|
1394
1396
|
const {
|
|
@@ -1414,7 +1416,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1414
1416
|
const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
|
|
1415
1417
|
scrollState = updatedOffset;
|
|
1416
1418
|
}
|
|
1417
|
-
|
|
1419
|
+
const scrollAdjustPad = -previousScrollAdjust - topPad;
|
|
1420
|
+
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
1418
1421
|
if (scroll + scrollLength > totalSize) {
|
|
1419
1422
|
scroll = totalSize - scrollLength;
|
|
1420
1423
|
}
|
|
@@ -1424,13 +1427,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1424
1427
|
}
|
|
1425
1428
|
let scrollBufferTop = scrollBuffer;
|
|
1426
1429
|
let scrollBufferBottom = scrollBuffer;
|
|
1427
|
-
if (speed >
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1430
|
+
if (Math.abs(speed) > 4) {
|
|
1431
|
+
if (speed > 0) {
|
|
1432
|
+
scrollBufferTop = scrollBuffer * 0.1;
|
|
1433
|
+
scrollBufferBottom = scrollBuffer * 1.9;
|
|
1434
|
+
} else {
|
|
1435
|
+
scrollBufferTop = scrollBuffer * 1.9;
|
|
1436
|
+
scrollBufferBottom = scrollBuffer * 0.1;
|
|
1437
|
+
}
|
|
1434
1438
|
}
|
|
1435
1439
|
if (state.scrollForNextCalculateItemsInView) {
|
|
1436
1440
|
const { top: top2, bottom } = state.scrollForNextCalculateItemsInView;
|
|
@@ -1490,7 +1494,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1490
1494
|
return topOffset;
|
|
1491
1495
|
};
|
|
1492
1496
|
let foundEnd = false;
|
|
1493
|
-
let
|
|
1497
|
+
let nextTop;
|
|
1498
|
+
let nextBottom;
|
|
1494
1499
|
const prevNumContainers = ctx.values.get("numContainers");
|
|
1495
1500
|
let maxIndexRendered = 0;
|
|
1496
1501
|
for (let i = 0; i < prevNumContainers; i++) {
|
|
@@ -1520,6 +1525,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1520
1525
|
if (startBuffered === null && top + size > scroll - scrollBufferTop) {
|
|
1521
1526
|
startBuffered = i;
|
|
1522
1527
|
startBufferedId = id;
|
|
1528
|
+
nextTop = top;
|
|
1523
1529
|
}
|
|
1524
1530
|
if (startNoBuffer !== null) {
|
|
1525
1531
|
if (top <= scrollBottom) {
|
|
@@ -1527,7 +1533,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1527
1533
|
}
|
|
1528
1534
|
if (top <= scrollBottom + scrollBufferBottom) {
|
|
1529
1535
|
endBuffered = i;
|
|
1530
|
-
|
|
1536
|
+
nextBottom = top + maxSizeInRow - scrollLength;
|
|
1531
1537
|
} else {
|
|
1532
1538
|
foundEnd = true;
|
|
1533
1539
|
}
|
|
@@ -1540,8 +1546,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1540
1546
|
maxSizeInRow = 0;
|
|
1541
1547
|
}
|
|
1542
1548
|
}
|
|
1543
|
-
const prevStartBuffered = state.startBuffered;
|
|
1544
|
-
const prevEndBuffered = state.endBuffered;
|
|
1545
1549
|
Object.assign(state, {
|
|
1546
1550
|
startBuffered,
|
|
1547
1551
|
startBufferedId,
|
|
@@ -1549,15 +1553,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1549
1553
|
endBuffered,
|
|
1550
1554
|
endNoBuffer
|
|
1551
1555
|
});
|
|
1552
|
-
if (state.enableScrollForNextCalculateItemsInView &&
|
|
1553
|
-
|
|
1554
|
-
let nextTop = 0;
|
|
1555
|
-
if (aboveFirst >= 0) {
|
|
1556
|
-
const aboveFirstSize = getItemSize(getId(aboveFirst), aboveFirst, data[aboveFirst], useAverageSize);
|
|
1557
|
-
nextTop = scroll - aboveFirstSize;
|
|
1558
|
-
}
|
|
1559
|
-
const nextBottom = scroll + lastSize;
|
|
1560
|
-
state.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
|
|
1556
|
+
if (state.enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0 && state.disableScrollJumpsFrom === void 0) {
|
|
1557
|
+
state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
|
|
1561
1558
|
top: nextTop,
|
|
1562
1559
|
bottom: nextBottom
|
|
1563
1560
|
} : void 0;
|
|
@@ -1565,25 +1562,18 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1565
1562
|
if (startBuffered !== null && endBuffered !== null) {
|
|
1566
1563
|
let numContainers = prevNumContainers;
|
|
1567
1564
|
const needNewContainers = [];
|
|
1568
|
-
|
|
1569
|
-
const
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
return true;
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
|
-
};
|
|
1578
|
-
for (let i = startBuffered; i < prevStartBuffered; i++) {
|
|
1579
|
-
if (!isContained(i)) {
|
|
1580
|
-
needNewContainers.push(i);
|
|
1565
|
+
const isContained = (i) => {
|
|
1566
|
+
const id = getId(i);
|
|
1567
|
+
for (let j = 0; j < numContainers; j++) {
|
|
1568
|
+
const key = peek$(ctx, `containerItemKey${j}`);
|
|
1569
|
+
if (key === id) {
|
|
1570
|
+
return true;
|
|
1581
1571
|
}
|
|
1582
1572
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1573
|
+
};
|
|
1574
|
+
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
1575
|
+
if (!isContained(i)) {
|
|
1576
|
+
needNewContainers.push(i);
|
|
1587
1577
|
}
|
|
1588
1578
|
}
|
|
1589
1579
|
if (needNewContainers.length > 0) {
|
|
@@ -1710,6 +1700,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1710
1700
|
var _a;
|
|
1711
1701
|
const state = refState.current;
|
|
1712
1702
|
state.scrollAdjustHandler.setDisableAdjust(true);
|
|
1703
|
+
state.scrollHistory.length = 0;
|
|
1713
1704
|
state.scrollingToOffset = offset;
|
|
1714
1705
|
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1715
1706
|
x: horizontal ? offset : 0,
|
|
@@ -1831,7 +1822,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1831
1822
|
if (!keyExtractorProp) {
|
|
1832
1823
|
state.positions.clear();
|
|
1833
1824
|
}
|
|
1834
|
-
calculateItemsInView(
|
|
1825
|
+
calculateItemsInView(
|
|
1826
|
+
/*isReset*/
|
|
1827
|
+
true
|
|
1828
|
+
);
|
|
1835
1829
|
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
|
|
1836
1830
|
if (!didMaintainScrollAtEnd && dataProp.length > state.data.length) {
|
|
1837
1831
|
state.isEndReached = false;
|
|
@@ -1884,7 +1878,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1884
1878
|
(_b = state.belowAnchorElementPositions) == null ? void 0 : _b.clear();
|
|
1885
1879
|
scrollTo(0, false);
|
|
1886
1880
|
setTimeout(() => {
|
|
1887
|
-
calculateItemsInView(
|
|
1881
|
+
calculateItemsInView(
|
|
1882
|
+
/*reset*/
|
|
1883
|
+
true
|
|
1884
|
+
);
|
|
1888
1885
|
}, 0);
|
|
1889
1886
|
} else {
|
|
1890
1887
|
state.startBufferedId = void 0;
|
|
@@ -1899,7 +1896,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1899
1896
|
}
|
|
1900
1897
|
scrollTo(0, false);
|
|
1901
1898
|
setTimeout(() => {
|
|
1902
|
-
calculateItemsInView(
|
|
1899
|
+
calculateItemsInView(
|
|
1900
|
+
/*reset*/
|
|
1901
|
+
true
|
|
1902
|
+
);
|
|
1903
1903
|
}, 0);
|
|
1904
1904
|
}
|
|
1905
1905
|
}
|
|
@@ -1971,7 +1971,15 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1971
1971
|
}
|
|
1972
1972
|
if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
|
|
1973
1973
|
console.warn(
|
|
1974
|
-
"[legend-list] No container
|
|
1974
|
+
"[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
|
|
1975
|
+
{
|
|
1976
|
+
debugInfo: {
|
|
1977
|
+
numContainers,
|
|
1978
|
+
numNeeded,
|
|
1979
|
+
stillNeeded,
|
|
1980
|
+
numContainersPooled: peek$(ctx, "numContainersPooled")
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1975
1983
|
);
|
|
1976
1984
|
}
|
|
1977
1985
|
}
|
|
@@ -2059,10 +2067,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2059
2067
|
set$(ctx, "numContainersPooled", numContainers * initialContainerPoolRatio);
|
|
2060
2068
|
if (initialScrollIndex) {
|
|
2061
2069
|
requestAnimationFrame(() => {
|
|
2062
|
-
calculateItemsInView(
|
|
2070
|
+
calculateItemsInView(
|
|
2071
|
+
/*isReset*/
|
|
2072
|
+
true
|
|
2073
|
+
);
|
|
2063
2074
|
});
|
|
2064
2075
|
} else {
|
|
2065
|
-
calculateItemsInView(
|
|
2076
|
+
calculateItemsInView(
|
|
2077
|
+
/*isReset*/
|
|
2078
|
+
true
|
|
2079
|
+
);
|
|
2066
2080
|
}
|
|
2067
2081
|
return true;
|
|
2068
2082
|
}
|
|
@@ -2098,6 +2112,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2098
2112
|
}
|
|
2099
2113
|
const index = indexByKey.get(itemKey);
|
|
2100
2114
|
const numColumns = peek$(ctx, "numColumns");
|
|
2115
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2101
2116
|
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
|
|
2102
2117
|
const prevSize = getItemSize(itemKey, index, data);
|
|
2103
2118
|
const prevSizeKnown = sizesKnown.get(itemKey);
|
package/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
|
-
import React2__default, { useReducer, useEffect, createContext, useMemo, useRef, useCallback, useImperativeHandle,
|
|
2
|
+
import React2__default, { useReducer, useEffect, createContext, useMemo, useRef, useCallback, useImperativeHandle, useContext, useState, forwardRef, memo, useLayoutEffect } from 'react';
|
|
3
3
|
import { View, Text, Platform, Animated, ScrollView, StyleSheet, Dimensions, RefreshControl } from 'react-native';
|
|
4
|
+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
4
5
|
|
|
5
6
|
// src/LegendList.tsx
|
|
6
7
|
var ContextState = React2.createContext(null);
|
|
@@ -58,12 +59,6 @@ function createSelectorFunctionsArr(ctx, signalNames) {
|
|
|
58
59
|
}
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
|
-
function useArr$(signalNames) {
|
|
62
|
-
const ctx = React2.useContext(ContextState);
|
|
63
|
-
const { subscribe, get } = React2.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
64
|
-
const value = useSyncExternalStore(subscribe, get);
|
|
65
|
-
return value;
|
|
66
|
-
}
|
|
67
62
|
function listen$(ctx, signalName, cb) {
|
|
68
63
|
const { listeners } = ctx;
|
|
69
64
|
let setListeners = listeners.get(signalName);
|
|
@@ -98,6 +93,12 @@ function getContentSize(ctx) {
|
|
|
98
93
|
const totalSize = values.get("totalSize") || 0;
|
|
99
94
|
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
100
95
|
}
|
|
96
|
+
function useArr$(signalNames) {
|
|
97
|
+
const ctx = React2.useContext(ContextState);
|
|
98
|
+
const { subscribe, get } = React2.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
99
|
+
const value = useSyncExternalStore(subscribe, get);
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
101
102
|
|
|
102
103
|
// src/DebugView.tsx
|
|
103
104
|
var DebugRow = ({ children }) => {
|
|
@@ -1272,6 +1273,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1272
1273
|
const state = refState.current;
|
|
1273
1274
|
if (state.scrollingToOffset === void 0) {
|
|
1274
1275
|
state.disableScrollJumpsFrom = state.scroll - state.scrollAdjustHandler.getAppliedAdjust();
|
|
1276
|
+
state.scrollHistory.length = 0;
|
|
1275
1277
|
setTimeout(() => {
|
|
1276
1278
|
state.disableScrollJumpsFrom = void 0;
|
|
1277
1279
|
}, timeout);
|
|
@@ -1367,7 +1369,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1367
1369
|
}
|
|
1368
1370
|
return false;
|
|
1369
1371
|
}, []);
|
|
1370
|
-
const calculateItemsInView = useCallback(() => {
|
|
1372
|
+
const calculateItemsInView = useCallback((isReset) => {
|
|
1371
1373
|
var _a;
|
|
1372
1374
|
const state = refState.current;
|
|
1373
1375
|
const {
|
|
@@ -1393,7 +1395,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1393
1395
|
const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
|
|
1394
1396
|
scrollState = updatedOffset;
|
|
1395
1397
|
}
|
|
1396
|
-
|
|
1398
|
+
const scrollAdjustPad = -previousScrollAdjust - topPad;
|
|
1399
|
+
let scroll = scrollState + scrollExtra + scrollAdjustPad;
|
|
1397
1400
|
if (scroll + scrollLength > totalSize) {
|
|
1398
1401
|
scroll = totalSize - scrollLength;
|
|
1399
1402
|
}
|
|
@@ -1403,13 +1406,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1403
1406
|
}
|
|
1404
1407
|
let scrollBufferTop = scrollBuffer;
|
|
1405
1408
|
let scrollBufferBottom = scrollBuffer;
|
|
1406
|
-
if (speed >
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1409
|
+
if (Math.abs(speed) > 4) {
|
|
1410
|
+
if (speed > 0) {
|
|
1411
|
+
scrollBufferTop = scrollBuffer * 0.1;
|
|
1412
|
+
scrollBufferBottom = scrollBuffer * 1.9;
|
|
1413
|
+
} else {
|
|
1414
|
+
scrollBufferTop = scrollBuffer * 1.9;
|
|
1415
|
+
scrollBufferBottom = scrollBuffer * 0.1;
|
|
1416
|
+
}
|
|
1413
1417
|
}
|
|
1414
1418
|
if (state.scrollForNextCalculateItemsInView) {
|
|
1415
1419
|
const { top: top2, bottom } = state.scrollForNextCalculateItemsInView;
|
|
@@ -1469,7 +1473,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1469
1473
|
return topOffset;
|
|
1470
1474
|
};
|
|
1471
1475
|
let foundEnd = false;
|
|
1472
|
-
let
|
|
1476
|
+
let nextTop;
|
|
1477
|
+
let nextBottom;
|
|
1473
1478
|
const prevNumContainers = ctx.values.get("numContainers");
|
|
1474
1479
|
let maxIndexRendered = 0;
|
|
1475
1480
|
for (let i = 0; i < prevNumContainers; i++) {
|
|
@@ -1499,6 +1504,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1499
1504
|
if (startBuffered === null && top + size > scroll - scrollBufferTop) {
|
|
1500
1505
|
startBuffered = i;
|
|
1501
1506
|
startBufferedId = id;
|
|
1507
|
+
nextTop = top;
|
|
1502
1508
|
}
|
|
1503
1509
|
if (startNoBuffer !== null) {
|
|
1504
1510
|
if (top <= scrollBottom) {
|
|
@@ -1506,7 +1512,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1506
1512
|
}
|
|
1507
1513
|
if (top <= scrollBottom + scrollBufferBottom) {
|
|
1508
1514
|
endBuffered = i;
|
|
1509
|
-
|
|
1515
|
+
nextBottom = top + maxSizeInRow - scrollLength;
|
|
1510
1516
|
} else {
|
|
1511
1517
|
foundEnd = true;
|
|
1512
1518
|
}
|
|
@@ -1519,8 +1525,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1519
1525
|
maxSizeInRow = 0;
|
|
1520
1526
|
}
|
|
1521
1527
|
}
|
|
1522
|
-
const prevStartBuffered = state.startBuffered;
|
|
1523
|
-
const prevEndBuffered = state.endBuffered;
|
|
1524
1528
|
Object.assign(state, {
|
|
1525
1529
|
startBuffered,
|
|
1526
1530
|
startBufferedId,
|
|
@@ -1528,15 +1532,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1528
1532
|
endBuffered,
|
|
1529
1533
|
endNoBuffer
|
|
1530
1534
|
});
|
|
1531
|
-
if (state.enableScrollForNextCalculateItemsInView &&
|
|
1532
|
-
|
|
1533
|
-
let nextTop = 0;
|
|
1534
|
-
if (aboveFirst >= 0) {
|
|
1535
|
-
const aboveFirstSize = getItemSize(getId(aboveFirst), aboveFirst, data[aboveFirst], useAverageSize);
|
|
1536
|
-
nextTop = scroll - aboveFirstSize;
|
|
1537
|
-
}
|
|
1538
|
-
const nextBottom = scroll + lastSize;
|
|
1539
|
-
state.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
|
|
1535
|
+
if (state.enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0 && state.disableScrollJumpsFrom === void 0) {
|
|
1536
|
+
state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
|
|
1540
1537
|
top: nextTop,
|
|
1541
1538
|
bottom: nextBottom
|
|
1542
1539
|
} : void 0;
|
|
@@ -1544,25 +1541,18 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1544
1541
|
if (startBuffered !== null && endBuffered !== null) {
|
|
1545
1542
|
let numContainers = prevNumContainers;
|
|
1546
1543
|
const needNewContainers = [];
|
|
1547
|
-
|
|
1548
|
-
const
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
return true;
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
};
|
|
1557
|
-
for (let i = startBuffered; i < prevStartBuffered; i++) {
|
|
1558
|
-
if (!isContained(i)) {
|
|
1559
|
-
needNewContainers.push(i);
|
|
1544
|
+
const isContained = (i) => {
|
|
1545
|
+
const id = getId(i);
|
|
1546
|
+
for (let j = 0; j < numContainers; j++) {
|
|
1547
|
+
const key = peek$(ctx, `containerItemKey${j}`);
|
|
1548
|
+
if (key === id) {
|
|
1549
|
+
return true;
|
|
1560
1550
|
}
|
|
1561
1551
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1552
|
+
};
|
|
1553
|
+
for (let i = startBuffered; i <= endBuffered; i++) {
|
|
1554
|
+
if (!isContained(i)) {
|
|
1555
|
+
needNewContainers.push(i);
|
|
1566
1556
|
}
|
|
1567
1557
|
}
|
|
1568
1558
|
if (needNewContainers.length > 0) {
|
|
@@ -1689,6 +1679,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1689
1679
|
var _a;
|
|
1690
1680
|
const state = refState.current;
|
|
1691
1681
|
state.scrollAdjustHandler.setDisableAdjust(true);
|
|
1682
|
+
state.scrollHistory.length = 0;
|
|
1692
1683
|
state.scrollingToOffset = offset;
|
|
1693
1684
|
(_a = refScroller.current) == null ? void 0 : _a.scrollTo({
|
|
1694
1685
|
x: horizontal ? offset : 0,
|
|
@@ -1810,7 +1801,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1810
1801
|
if (!keyExtractorProp) {
|
|
1811
1802
|
state.positions.clear();
|
|
1812
1803
|
}
|
|
1813
|
-
calculateItemsInView(
|
|
1804
|
+
calculateItemsInView(
|
|
1805
|
+
/*isReset*/
|
|
1806
|
+
true
|
|
1807
|
+
);
|
|
1814
1808
|
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
|
|
1815
1809
|
if (!didMaintainScrollAtEnd && dataProp.length > state.data.length) {
|
|
1816
1810
|
state.isEndReached = false;
|
|
@@ -1863,7 +1857,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1863
1857
|
(_b = state.belowAnchorElementPositions) == null ? void 0 : _b.clear();
|
|
1864
1858
|
scrollTo(0, false);
|
|
1865
1859
|
setTimeout(() => {
|
|
1866
|
-
calculateItemsInView(
|
|
1860
|
+
calculateItemsInView(
|
|
1861
|
+
/*reset*/
|
|
1862
|
+
true
|
|
1863
|
+
);
|
|
1867
1864
|
}, 0);
|
|
1868
1865
|
} else {
|
|
1869
1866
|
state.startBufferedId = void 0;
|
|
@@ -1878,7 +1875,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1878
1875
|
}
|
|
1879
1876
|
scrollTo(0, false);
|
|
1880
1877
|
setTimeout(() => {
|
|
1881
|
-
calculateItemsInView(
|
|
1878
|
+
calculateItemsInView(
|
|
1879
|
+
/*reset*/
|
|
1880
|
+
true
|
|
1881
|
+
);
|
|
1882
1882
|
}, 0);
|
|
1883
1883
|
}
|
|
1884
1884
|
}
|
|
@@ -1950,7 +1950,15 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1950
1950
|
}
|
|
1951
1951
|
if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
|
|
1952
1952
|
console.warn(
|
|
1953
|
-
"[legend-list] No container
|
|
1953
|
+
"[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
|
|
1954
|
+
{
|
|
1955
|
+
debugInfo: {
|
|
1956
|
+
numContainers,
|
|
1957
|
+
numNeeded,
|
|
1958
|
+
stillNeeded,
|
|
1959
|
+
numContainersPooled: peek$(ctx, "numContainersPooled")
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1954
1962
|
);
|
|
1955
1963
|
}
|
|
1956
1964
|
}
|
|
@@ -2038,10 +2046,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2038
2046
|
set$(ctx, "numContainersPooled", numContainers * initialContainerPoolRatio);
|
|
2039
2047
|
if (initialScrollIndex) {
|
|
2040
2048
|
requestAnimationFrame(() => {
|
|
2041
|
-
calculateItemsInView(
|
|
2049
|
+
calculateItemsInView(
|
|
2050
|
+
/*isReset*/
|
|
2051
|
+
true
|
|
2052
|
+
);
|
|
2042
2053
|
});
|
|
2043
2054
|
} else {
|
|
2044
|
-
calculateItemsInView(
|
|
2055
|
+
calculateItemsInView(
|
|
2056
|
+
/*isReset*/
|
|
2057
|
+
true
|
|
2058
|
+
);
|
|
2045
2059
|
}
|
|
2046
2060
|
return true;
|
|
2047
2061
|
}
|
|
@@ -2077,6 +2091,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2077
2091
|
}
|
|
2078
2092
|
const index = indexByKey.get(itemKey);
|
|
2079
2093
|
const numColumns = peek$(ctx, "numColumns");
|
|
2094
|
+
state.scrollForNextCalculateItemsInView = void 0;
|
|
2080
2095
|
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
|
|
2081
2096
|
const prevSize = getItemSize(itemKey, index, data);
|
|
2082
2097
|
const prevSizeKnown = sizesKnown.get(itemKey);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/list",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
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,
|
|
@@ -28,5 +28,8 @@
|
|
|
28
28
|
"homepage": "https://github.com/LegendApp/legend-list#readme",
|
|
29
29
|
"publishConfig": {
|
|
30
30
|
"registry": "https://registry.npmjs.org/"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"use-sync-external-store": "^1.5.0"
|
|
31
34
|
}
|
|
32
35
|
}
|