@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.
Files changed (4) hide show
  1. package/CHANGELOG.md +48 -2
  2. package/index.js +66 -51
  3. package/index.mjs +67 -52
  4. package/package.json +4 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
- # 1.0.0
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
- let scroll = scrollState + scrollExtra - previousScrollAdjust - topPad;
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 > 0) {
1428
- scrollBufferTop = scrollBuffer * 0.1;
1429
- scrollBufferBottom = scrollBuffer * 1.9;
1430
- }
1431
- if (speed < 0) {
1432
- scrollBufferTop = scrollBuffer * 1.9;
1433
- scrollBufferBottom = scrollBuffer * 0.1;
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 lastSize;
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
- lastSize = maxSizeInRow;
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 && lastSize) {
1553
- const aboveFirst = startBuffered - 1;
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
- if (startBuffered < prevStartBuffered || endBuffered > prevEndBuffered) {
1569
- const isContained = (i) => {
1570
- const id = getId(i);
1571
- for (let j = 0; j < numContainers; j++) {
1572
- const key = peek$(ctx, `containerItemKey${j}`);
1573
- if (key === id) {
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
- for (let i = Math.max(prevEndBuffered + 1, startBuffered); i <= endBuffered; i++) {
1584
- if (!isContained(i)) {
1585
- needNewContainers.push(i);
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 to recycle, 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."
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, useSyncExternalStore, useContext, useState, forwardRef, memo, useLayoutEffect } from 'react';
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
- let scroll = scrollState + scrollExtra - previousScrollAdjust - topPad;
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 > 0) {
1407
- scrollBufferTop = scrollBuffer * 0.1;
1408
- scrollBufferBottom = scrollBuffer * 1.9;
1409
- }
1410
- if (speed < 0) {
1411
- scrollBufferTop = scrollBuffer * 1.9;
1412
- scrollBufferBottom = scrollBuffer * 0.1;
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 lastSize;
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
- lastSize = maxSizeInRow;
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 && lastSize) {
1532
- const aboveFirst = startBuffered - 1;
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
- if (startBuffered < prevStartBuffered || endBuffered > prevEndBuffered) {
1548
- const isContained = (i) => {
1549
- const id = getId(i);
1550
- for (let j = 0; j < numContainers; j++) {
1551
- const key = peek$(ctx, `containerItemKey${j}`);
1552
- if (key === id) {
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
- for (let i = Math.max(prevEndBuffered + 1, startBuffered); i <= endBuffered; i++) {
1563
- if (!isContained(i)) {
1564
- needNewContainers.push(i);
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 to recycle, 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."
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.8",
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
  }