@legendapp/list 2.0.0-next.6 → 2.0.0-next.7

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/.DS_Store ADDED
Binary file
package/index.d.mts CHANGED
@@ -316,6 +316,14 @@ interface InternalState {
316
316
  loadStartTime: number;
317
317
  initialScroll: ScrollIndexWithOffsetPosition | undefined;
318
318
  lastLayout: LayoutRectangle | undefined;
319
+ queuedItemSizeUpdates: {
320
+ itemKey: string;
321
+ sizeObj: {
322
+ width: number;
323
+ height: number;
324
+ };
325
+ }[];
326
+ queuedItemSizeUpdatesWaiting?: boolean;
319
327
  props: {
320
328
  alignItemsAtEnd: boolean;
321
329
  data: readonly any[];
@@ -543,7 +551,7 @@ interface LegendListRecyclingState<T> {
543
551
  }
544
552
  type TypedForwardRef = <T, P = {}>(render: (props: P, ref: React.Ref<T>) => React.ReactNode) => (props: P & React.RefAttributes<T>) => React.ReactNode;
545
553
  declare const typedForwardRef: TypedForwardRef;
546
- type TypedMemo = <T extends React.ComponentType<any>>(Component: T, propsAreEqual?: (prevProps: Readonly<ComponentProps<T>>, nextProps: Readonly<ComponentProps<T>>) => boolean) => T & {
554
+ type TypedMemo = <T extends React.ComponentType<any>>(Component: T, propsAreEqual?: (prevProps: Readonly<React.JSXElementConstructor<T>>, nextProps: Readonly<React.JSXElementConstructor<T>>) => boolean) => T & {
547
555
  displayName?: string;
548
556
  };
549
557
  declare const typedMemo: TypedMemo;
package/index.d.ts CHANGED
@@ -316,6 +316,14 @@ interface InternalState {
316
316
  loadStartTime: number;
317
317
  initialScroll: ScrollIndexWithOffsetPosition | undefined;
318
318
  lastLayout: LayoutRectangle | undefined;
319
+ queuedItemSizeUpdates: {
320
+ itemKey: string;
321
+ sizeObj: {
322
+ width: number;
323
+ height: number;
324
+ };
325
+ }[];
326
+ queuedItemSizeUpdatesWaiting?: boolean;
319
327
  props: {
320
328
  alignItemsAtEnd: boolean;
321
329
  data: readonly any[];
@@ -543,7 +551,7 @@ interface LegendListRecyclingState<T> {
543
551
  }
544
552
  type TypedForwardRef = <T, P = {}>(render: (props: P, ref: React.Ref<T>) => React.ReactNode) => (props: P & React.RefAttributes<T>) => React.ReactNode;
545
553
  declare const typedForwardRef: TypedForwardRef;
546
- type TypedMemo = <T extends React.ComponentType<any>>(Component: T, propsAreEqual?: (prevProps: Readonly<ComponentProps<T>>, nextProps: Readonly<ComponentProps<T>>) => boolean) => T & {
554
+ type TypedMemo = <T extends React.ComponentType<any>>(Component: T, propsAreEqual?: (prevProps: Readonly<React.JSXElementConstructor<T>>, nextProps: Readonly<React.JSXElementConstructor<T>>) => boolean) => T & {
547
555
  displayName?: string;
548
556
  };
549
557
  declare const typedMemo: TypedMemo;
package/index.js CHANGED
@@ -595,13 +595,15 @@ function useSyncLayout({
595
595
  },
596
596
  [onChange]
597
597
  );
598
- React3.useLayoutEffect(() => {
599
- if (ref.current) {
600
- ref.current.measure((x, y, width, height) => {
601
- onChange({ height, width, x, y }, true);
602
- });
603
- }
604
- }, []);
598
+ if (IsNewArchitecture) {
599
+ React3.useLayoutEffect(() => {
600
+ if (ref.current) {
601
+ ref.current.measure((x, y, width, height) => {
602
+ onChange({ height, width, x, y }, true);
603
+ });
604
+ }
605
+ }, []);
606
+ }
605
607
  return { onLayout, ref };
606
608
  }
607
609
 
@@ -768,7 +770,7 @@ function getItemSize(state, key, index, data, useAverageSize) {
768
770
  return sizeKnown;
769
771
  }
770
772
  let size;
771
- if (IsNewArchitecture && useAverageSize !== void 0 && sizeKnown === void 0 && !getEstimatedItemSize && !scrollingTo) {
773
+ if (useAverageSize !== void 0 && sizeKnown === void 0 && !getEstimatedItemSize && !scrollingTo) {
772
774
  size = useAverageSize;
773
775
  }
774
776
  if (size === void 0) {
@@ -1484,265 +1486,267 @@ function setDidLayout(ctx, state) {
1484
1486
 
1485
1487
  // src/core/calculateItemsInView.ts
1486
1488
  function calculateItemsInView(ctx, state, params = {}) {
1487
- var _a, _b, _c, _d, _e, _f, _g, _h;
1488
- const {
1489
- scrollLength,
1490
- startBufferedId: startBufferedIdOrig,
1491
- positions,
1492
- columns,
1493
- containerItemKeys,
1494
- idCache,
1495
- sizes,
1496
- indexByKey,
1497
- scrollForNextCalculateItemsInView,
1498
- enableScrollForNextCalculateItemsInView,
1499
- minIndexSizeChanged
1500
- } = state;
1501
- const data = state.props.data;
1502
- const prevNumContainers = peek$(ctx, "numContainers");
1503
- if (!data || scrollLength === 0 || !prevNumContainers) {
1504
- return;
1505
- }
1506
- const totalSize = peek$(ctx, "totalSize");
1507
- const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
1508
- const numColumns = peek$(ctx, "numColumns");
1509
- const previousScrollAdjust = 0;
1510
- const { dataChanged, doMVCP } = params;
1511
- const speed = getScrollVelocity(state);
1512
- if (doMVCP || dataChanged) {
1513
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
1514
- updateAllPositions(ctx, state, dataChanged);
1515
- checkMVCP == null ? void 0 : checkMVCP();
1516
- }
1517
- const scrollExtra = 0;
1518
- const { queuedInitialLayout } = state;
1519
- let { scroll: scrollState } = state;
1520
- const initialScroll = state.props.initialScroll;
1521
- if (!queuedInitialLayout && initialScroll) {
1522
- const updatedOffset = calculateOffsetWithOffsetPosition(
1523
- state,
1524
- calculateOffsetForIndex(ctx, state, initialScroll.index),
1525
- initialScroll
1526
- );
1527
- scrollState = updatedOffset;
1528
- }
1529
- const scrollAdjustPad = -previousScrollAdjust - topPad;
1530
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
1531
- if (scroll + scrollLength > totalSize) {
1532
- scroll = totalSize - scrollLength;
1533
- }
1534
- if (ENABLE_DEBUG_VIEW) {
1535
- set$(ctx, "debugRawScroll", scrollState);
1536
- set$(ctx, "debugComputedScroll", scroll);
1537
- }
1538
- const scrollBuffer = state.props.scrollBuffer;
1539
- let scrollBufferTop = scrollBuffer;
1540
- let scrollBufferBottom = scrollBuffer;
1541
- if (speed > 0) {
1542
- scrollBufferTop = scrollBuffer * 0.5;
1543
- scrollBufferBottom = scrollBuffer * 1.5;
1544
- } else {
1545
- scrollBufferTop = scrollBuffer * 1.5;
1546
- scrollBufferBottom = scrollBuffer * 0.5;
1547
- }
1548
- const scrollTopBuffered = scroll - scrollBufferTop;
1549
- const scrollBottom = scroll + scrollLength;
1550
- const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1551
- if (scrollForNextCalculateItemsInView) {
1552
- const { top, bottom } = scrollForNextCalculateItemsInView;
1553
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
1489
+ reactNative.unstable_batchedUpdates(() => {
1490
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1491
+ const {
1492
+ scrollLength,
1493
+ startBufferedId: startBufferedIdOrig,
1494
+ positions,
1495
+ columns,
1496
+ containerItemKeys,
1497
+ idCache,
1498
+ sizes,
1499
+ indexByKey,
1500
+ scrollForNextCalculateItemsInView,
1501
+ enableScrollForNextCalculateItemsInView,
1502
+ minIndexSizeChanged
1503
+ } = state;
1504
+ const data = state.props.data;
1505
+ const prevNumContainers = peek$(ctx, "numContainers");
1506
+ if (!data || scrollLength === 0 || !prevNumContainers) {
1554
1507
  return;
1555
1508
  }
1556
- }
1557
- let startNoBuffer = null;
1558
- let startBuffered = null;
1559
- let startBufferedId = null;
1560
- let endNoBuffer = null;
1561
- let endBuffered = null;
1562
- let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1563
- if (minIndexSizeChanged !== void 0) {
1564
- loopStart = Math.min(minIndexSizeChanged, loopStart);
1565
- state.minIndexSizeChanged = void 0;
1566
- }
1567
- for (let i = loopStart; i >= 0; i--) {
1568
- const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
1569
- const top = positions.get(id);
1570
- const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
1571
- const bottom = top + size;
1572
- if (bottom > scroll - scrollBuffer) {
1573
- loopStart = i;
1509
+ const totalSize = peek$(ctx, "totalSize");
1510
+ const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
1511
+ const numColumns = peek$(ctx, "numColumns");
1512
+ const previousScrollAdjust = 0;
1513
+ const { dataChanged, doMVCP } = params;
1514
+ const speed = getScrollVelocity(state);
1515
+ if (doMVCP || dataChanged) {
1516
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
1517
+ updateAllPositions(ctx, state, dataChanged);
1518
+ checkMVCP == null ? void 0 : checkMVCP();
1519
+ }
1520
+ const scrollExtra = 0;
1521
+ const { queuedInitialLayout } = state;
1522
+ let { scroll: scrollState } = state;
1523
+ const initialScroll = state.props.initialScroll;
1524
+ if (!queuedInitialLayout && initialScroll) {
1525
+ const updatedOffset = calculateOffsetWithOffsetPosition(
1526
+ state,
1527
+ calculateOffsetForIndex(ctx, state, initialScroll.index),
1528
+ initialScroll
1529
+ );
1530
+ scrollState = updatedOffset;
1531
+ }
1532
+ const scrollAdjustPad = -previousScrollAdjust - topPad;
1533
+ let scroll = scrollState + scrollExtra + scrollAdjustPad;
1534
+ if (scroll + scrollLength > totalSize) {
1535
+ scroll = totalSize - scrollLength;
1536
+ }
1537
+ if (ENABLE_DEBUG_VIEW) {
1538
+ set$(ctx, "debugRawScroll", scrollState);
1539
+ set$(ctx, "debugComputedScroll", scroll);
1540
+ }
1541
+ const scrollBuffer = state.props.scrollBuffer;
1542
+ let scrollBufferTop = scrollBuffer;
1543
+ let scrollBufferBottom = scrollBuffer;
1544
+ if (speed > 0) {
1545
+ scrollBufferTop = scrollBuffer * 0.5;
1546
+ scrollBufferBottom = scrollBuffer * 1.5;
1574
1547
  } else {
1575
- break;
1576
- }
1577
- }
1578
- const loopStartMod = loopStart % numColumns;
1579
- if (loopStartMod > 0) {
1580
- loopStart -= loopStartMod;
1581
- }
1582
- let foundEnd = false;
1583
- let nextTop;
1584
- let nextBottom;
1585
- let maxIndexRendered = 0;
1586
- for (let i = 0; i < prevNumContainers; i++) {
1587
- const key = peek$(ctx, `containerItemKey${i}`);
1588
- if (key !== void 0) {
1589
- const index = indexByKey.get(key);
1590
- maxIndexRendered = Math.max(maxIndexRendered, index);
1591
- }
1592
- }
1593
- let firstFullyOnScreenIndex;
1594
- const dataLength = data.length;
1595
- for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1596
- const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
1597
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
1598
- const top = positions.get(id);
1599
- if (!foundEnd) {
1600
- if (startNoBuffer === null && top + size > scroll) {
1601
- startNoBuffer = i;
1602
- }
1603
- if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
1604
- firstFullyOnScreenIndex = i;
1548
+ scrollBufferTop = scrollBuffer * 1.5;
1549
+ scrollBufferBottom = scrollBuffer * 0.5;
1550
+ }
1551
+ const scrollTopBuffered = scroll - scrollBufferTop;
1552
+ const scrollBottom = scroll + scrollLength;
1553
+ const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1554
+ if (scrollForNextCalculateItemsInView) {
1555
+ const { top, bottom } = scrollForNextCalculateItemsInView;
1556
+ if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
1557
+ return;
1605
1558
  }
1606
- if (startBuffered === null && top + size > scrollTopBuffered) {
1607
- startBuffered = i;
1608
- startBufferedId = id;
1609
- nextTop = top;
1559
+ }
1560
+ let startNoBuffer = null;
1561
+ let startBuffered = null;
1562
+ let startBufferedId = null;
1563
+ let endNoBuffer = null;
1564
+ let endBuffered = null;
1565
+ let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1566
+ if (minIndexSizeChanged !== void 0) {
1567
+ loopStart = Math.min(minIndexSizeChanged, loopStart);
1568
+ state.minIndexSizeChanged = void 0;
1569
+ }
1570
+ for (let i = loopStart; i >= 0; i--) {
1571
+ const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
1572
+ const top = positions.get(id);
1573
+ const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
1574
+ const bottom = top + size;
1575
+ if (bottom > scroll - scrollBuffer) {
1576
+ loopStart = i;
1577
+ } else {
1578
+ break;
1610
1579
  }
1611
- if (startNoBuffer !== null) {
1612
- if (top <= scrollBottom) {
1613
- endNoBuffer = i;
1580
+ }
1581
+ const loopStartMod = loopStart % numColumns;
1582
+ if (loopStartMod > 0) {
1583
+ loopStart -= loopStartMod;
1584
+ }
1585
+ let foundEnd = false;
1586
+ let nextTop;
1587
+ let nextBottom;
1588
+ let maxIndexRendered = 0;
1589
+ for (let i = 0; i < prevNumContainers; i++) {
1590
+ const key = peek$(ctx, `containerItemKey${i}`);
1591
+ if (key !== void 0) {
1592
+ const index = indexByKey.get(key);
1593
+ maxIndexRendered = Math.max(maxIndexRendered, index);
1594
+ }
1595
+ }
1596
+ let firstFullyOnScreenIndex;
1597
+ const dataLength = data.length;
1598
+ for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1599
+ const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
1600
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
1601
+ const top = positions.get(id);
1602
+ if (!foundEnd) {
1603
+ if (startNoBuffer === null && top + size > scroll) {
1604
+ startNoBuffer = i;
1605
+ }
1606
+ if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
1607
+ firstFullyOnScreenIndex = i;
1614
1608
  }
1615
- if (top <= scrollBottomBuffered) {
1616
- endBuffered = i;
1617
- nextBottom = top + size;
1618
- } else {
1619
- foundEnd = true;
1609
+ if (startBuffered === null && top + size > scrollTopBuffered) {
1610
+ startBuffered = i;
1611
+ startBufferedId = id;
1612
+ nextTop = top;
1613
+ }
1614
+ if (startNoBuffer !== null) {
1615
+ if (top <= scrollBottom) {
1616
+ endNoBuffer = i;
1617
+ }
1618
+ if (top <= scrollBottomBuffered) {
1619
+ endBuffered = i;
1620
+ nextBottom = top + size;
1621
+ } else {
1622
+ foundEnd = true;
1623
+ }
1620
1624
  }
1621
1625
  }
1622
1626
  }
1623
- }
1624
- const idsInView = [];
1625
- for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
1626
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1627
- idsInView.push(id);
1628
- }
1629
- Object.assign(state, {
1630
- endBuffered,
1631
- endNoBuffer,
1632
- firstFullyOnScreenIndex,
1633
- idsInView,
1634
- startBuffered,
1635
- startBufferedId,
1636
- startNoBuffer
1637
- });
1638
- if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
1639
- state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
1640
- bottom: nextBottom,
1641
- top: nextTop
1642
- } : void 0;
1643
- }
1644
- const numContainers = peek$(ctx, "numContainers");
1645
- const pendingRemoval = [];
1646
- if (dataChanged) {
1647
- for (let i = 0; i < numContainers; i++) {
1648
- const itemKey = peek$(ctx, `containerItemKey${i}`);
1649
- if (!state.props.keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
1650
- pendingRemoval.push(i);
1651
- }
1627
+ const idsInView = [];
1628
+ for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
1629
+ const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1630
+ idsInView.push(id);
1652
1631
  }
1653
- }
1654
- if (startBuffered !== null && endBuffered !== null) {
1655
- let numContainers2 = prevNumContainers;
1656
- const needNewContainers = [];
1657
- for (let i = startBuffered; i <= endBuffered; i++) {
1658
- const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
1659
- if (!containerItemKeys.has(id)) {
1660
- needNewContainers.push(i);
1661
- }
1632
+ Object.assign(state, {
1633
+ endBuffered,
1634
+ endNoBuffer,
1635
+ firstFullyOnScreenIndex,
1636
+ idsInView,
1637
+ startBuffered,
1638
+ startBufferedId,
1639
+ startNoBuffer
1640
+ });
1641
+ if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
1642
+ state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
1643
+ bottom: nextBottom,
1644
+ top: nextTop
1645
+ } : void 0;
1662
1646
  }
1663
- if (needNewContainers.length > 0) {
1664
- const availableContainers = findAvailableContainers(
1665
- ctx,
1666
- state,
1667
- needNewContainers.length,
1668
- startBuffered,
1669
- endBuffered,
1670
- pendingRemoval
1671
- );
1672
- for (let idx = 0; idx < needNewContainers.length; idx++) {
1673
- const i = needNewContainers[idx];
1674
- const containerIndex = availableContainers[idx];
1675
- const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
1676
- const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
1677
- if (oldKey && oldKey !== id) {
1678
- containerItemKeys.delete(oldKey);
1679
- }
1680
- set$(ctx, `containerItemKey${containerIndex}`, id);
1681
- set$(ctx, `containerItemData${containerIndex}`, data[i]);
1682
- containerItemKeys.add(id);
1683
- if (containerIndex >= numContainers2) {
1684
- numContainers2 = containerIndex + 1;
1685
- }
1686
- }
1687
- if (numContainers2 !== prevNumContainers) {
1688
- set$(ctx, "numContainers", numContainers2);
1689
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
1690
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
1647
+ const numContainers = peek$(ctx, "numContainers");
1648
+ const pendingRemoval = [];
1649
+ if (dataChanged) {
1650
+ for (let i = 0; i < numContainers; i++) {
1651
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1652
+ if (!state.props.keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
1653
+ pendingRemoval.push(i);
1691
1654
  }
1692
1655
  }
1693
1656
  }
1694
- }
1695
- for (let i = 0; i < numContainers; i++) {
1696
- const itemKey = peek$(ctx, `containerItemKey${i}`);
1697
- if (pendingRemoval.includes(i)) {
1698
- if (itemKey) {
1699
- containerItemKeys.delete(itemKey);
1657
+ if (startBuffered !== null && endBuffered !== null) {
1658
+ let numContainers2 = prevNumContainers;
1659
+ const needNewContainers = [];
1660
+ for (let i = startBuffered; i <= endBuffered; i++) {
1661
+ const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
1662
+ if (!containerItemKeys.has(id)) {
1663
+ needNewContainers.push(i);
1664
+ }
1700
1665
  }
1701
- set$(ctx, `containerItemKey${i}`, void 0);
1702
- set$(ctx, `containerItemData${i}`, void 0);
1703
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1704
- set$(ctx, `containerColumn${i}`, -1);
1705
- } else {
1706
- const itemIndex = indexByKey.get(itemKey);
1707
- const item = data[itemIndex];
1708
- if (item !== void 0) {
1709
- const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
1710
- const position = positions.get(id);
1711
- if (position === void 0) {
1712
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1713
- } else {
1714
- const column = columns.get(id) || 1;
1715
- const prevPos = peek$(ctx, `containerPosition${i}`);
1716
- const prevColumn = peek$(ctx, `containerColumn${i}`);
1717
- const prevData = peek$(ctx, `containerItemData${i}`);
1718
- if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
1719
- set$(ctx, `containerPosition${i}`, position);
1666
+ if (needNewContainers.length > 0) {
1667
+ const availableContainers = findAvailableContainers(
1668
+ ctx,
1669
+ state,
1670
+ needNewContainers.length,
1671
+ startBuffered,
1672
+ endBuffered,
1673
+ pendingRemoval
1674
+ );
1675
+ for (let idx = 0; idx < needNewContainers.length; idx++) {
1676
+ const i = needNewContainers[idx];
1677
+ const containerIndex = availableContainers[idx];
1678
+ const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
1679
+ const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
1680
+ if (oldKey && oldKey !== id) {
1681
+ containerItemKeys.delete(oldKey);
1720
1682
  }
1721
- if (column >= 0 && column !== prevColumn) {
1722
- set$(ctx, `containerColumn${i}`, column);
1683
+ set$(ctx, `containerItemKey${containerIndex}`, id);
1684
+ set$(ctx, `containerItemData${containerIndex}`, data[i]);
1685
+ containerItemKeys.add(id);
1686
+ if (containerIndex >= numContainers2) {
1687
+ numContainers2 = containerIndex + 1;
1723
1688
  }
1724
- if (prevData !== item) {
1725
- set$(ctx, `containerItemData${i}`, data[itemIndex]);
1689
+ }
1690
+ if (numContainers2 !== prevNumContainers) {
1691
+ set$(ctx, "numContainers", numContainers2);
1692
+ if (numContainers2 > peek$(ctx, "numContainersPooled")) {
1693
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
1726
1694
  }
1727
1695
  }
1728
1696
  }
1729
1697
  }
1730
- }
1731
- if (!queuedInitialLayout && endBuffered !== null) {
1732
- if (checkAllSizesKnown(state)) {
1733
- setDidLayout(ctx, state);
1698
+ for (let i = 0; i < numContainers; i++) {
1699
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1700
+ if (pendingRemoval.includes(i)) {
1701
+ if (itemKey) {
1702
+ containerItemKeys.delete(itemKey);
1703
+ }
1704
+ set$(ctx, `containerItemKey${i}`, void 0);
1705
+ set$(ctx, `containerItemData${i}`, void 0);
1706
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1707
+ set$(ctx, `containerColumn${i}`, -1);
1708
+ } else {
1709
+ const itemIndex = indexByKey.get(itemKey);
1710
+ const item = data[itemIndex];
1711
+ if (item !== void 0) {
1712
+ const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
1713
+ const position = positions.get(id);
1714
+ if (position === void 0) {
1715
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1716
+ } else {
1717
+ const column = columns.get(id) || 1;
1718
+ const prevPos = peek$(ctx, `containerPosition${i}`);
1719
+ const prevColumn = peek$(ctx, `containerColumn${i}`);
1720
+ const prevData = peek$(ctx, `containerItemData${i}`);
1721
+ if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
1722
+ set$(ctx, `containerPosition${i}`, position);
1723
+ }
1724
+ if (column >= 0 && column !== prevColumn) {
1725
+ set$(ctx, `containerColumn${i}`, column);
1726
+ }
1727
+ if (prevData !== item) {
1728
+ set$(ctx, `containerItemData${i}`, data[itemIndex]);
1729
+ }
1730
+ }
1731
+ }
1732
+ }
1734
1733
  }
1735
- }
1736
- if (state.props.viewabilityConfigCallbackPairs) {
1737
- updateViewableItems(
1738
- state,
1739
- ctx,
1740
- state.props.viewabilityConfigCallbackPairs,
1741
- scrollLength,
1742
- startNoBuffer,
1743
- endNoBuffer
1744
- );
1745
- }
1734
+ if (!queuedInitialLayout && endBuffered !== null) {
1735
+ if (checkAllSizesKnown(state)) {
1736
+ setDidLayout(ctx, state);
1737
+ }
1738
+ }
1739
+ if (state.props.viewabilityConfigCallbackPairs) {
1740
+ updateViewableItems(
1741
+ state,
1742
+ ctx,
1743
+ state.props.viewabilityConfigCallbackPairs,
1744
+ scrollLength,
1745
+ startNoBuffer,
1746
+ endNoBuffer
1747
+ );
1748
+ }
1749
+ });
1746
1750
  }
1747
1751
 
1748
1752
  // src/core/doInitialAllocateContainers.ts
@@ -2016,32 +2020,20 @@ function updateItemSizes(ctx, state, itemUpdates) {
2016
2020
  }
2017
2021
  }
2018
2022
  function updateItemSize(ctx, state, itemKey, sizeObj) {
2019
- if (IsNewArchitecture) {
2020
- const { sizesKnown } = state;
2021
- const numContainers = peek$(ctx, "numContainers");
2022
- const changes = [];
2023
- for (let i = 0; i < numContainers; i++) {
2024
- const containerItemKey = peek$(ctx, `containerItemKey${i}`);
2025
- if (itemKey === containerItemKey) {
2026
- changes.push({ itemKey, sizeObj });
2027
- } else if (!sizesKnown.has(containerItemKey) && containerItemKey !== void 0) {
2028
- const containerRef = ctx.viewRefs.get(i);
2029
- if (containerRef == null ? void 0 : containerRef.current) {
2030
- let measured;
2031
- containerRef.current.measure((x, y, width, height) => {
2032
- measured = { height, width, x, y };
2033
- });
2034
- if (measured) {
2035
- changes.push({ itemKey: containerItemKey, sizeObj: measured });
2036
- }
2037
- }
2038
- }
2039
- }
2040
- if (changes.length > 0) {
2041
- updateItemSizes(ctx, state, changes);
2023
+ const { queuedItemSizeUpdates, queuedItemSizeUpdatesWaiting } = state;
2024
+ const containersDidLayout = peek$(ctx, "containersDidLayout");
2025
+ if (!containersDidLayout || !queuedItemSizeUpdatesWaiting) {
2026
+ updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
2027
+ if (containersDidLayout) {
2028
+ state.queuedItemSizeUpdatesWaiting = true;
2029
+ requestAnimationFrame(() => {
2030
+ state.queuedItemSizeUpdatesWaiting = false;
2031
+ updateItemSizes(ctx, state, queuedItemSizeUpdates);
2032
+ queuedItemSizeUpdates.length = 0;
2033
+ });
2042
2034
  }
2043
2035
  } else {
2044
- updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
2036
+ queuedItemSizeUpdates.push({ itemKey, sizeObj });
2045
2037
  }
2046
2038
  }
2047
2039
  function updateOneItemSize(state, itemKey, sizeObj) {
@@ -2222,6 +2214,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2222
2214
  positions: /* @__PURE__ */ new Map(),
2223
2215
  props: {},
2224
2216
  queuedCalculateItemsInView: 0,
2217
+ queuedItemSizeUpdates: [],
2225
2218
  refScroller: void 0,
2226
2219
  scroll: 0,
2227
2220
  scrollAdjustHandler: new ScrollAdjustHandler(ctx),
package/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React3 from 'react';
2
2
  import React3__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useLayoutEffect, useCallback, useImperativeHandle, useContext, forwardRef, memo } from 'react';
3
- import { View, Text, Platform, Animated, ScrollView, StyleSheet, Dimensions, RefreshControl } from 'react-native';
3
+ import { View, Text, Platform, Animated, ScrollView, StyleSheet, Dimensions, RefreshControl, unstable_batchedUpdates } from 'react-native';
4
4
  import { useSyncExternalStore } from 'use-sync-external-store/shim';
5
5
 
6
6
  // src/components/LazyLegendList.tsx
@@ -574,13 +574,15 @@ function useSyncLayout({
574
574
  },
575
575
  [onChange]
576
576
  );
577
- useLayoutEffect(() => {
578
- if (ref.current) {
579
- ref.current.measure((x, y, width, height) => {
580
- onChange({ height, width, x, y }, true);
581
- });
582
- }
583
- }, []);
577
+ if (IsNewArchitecture) {
578
+ useLayoutEffect(() => {
579
+ if (ref.current) {
580
+ ref.current.measure((x, y, width, height) => {
581
+ onChange({ height, width, x, y }, true);
582
+ });
583
+ }
584
+ }, []);
585
+ }
584
586
  return { onLayout, ref };
585
587
  }
586
588
 
@@ -747,7 +749,7 @@ function getItemSize(state, key, index, data, useAverageSize) {
747
749
  return sizeKnown;
748
750
  }
749
751
  let size;
750
- if (IsNewArchitecture && useAverageSize !== void 0 && sizeKnown === void 0 && !getEstimatedItemSize && !scrollingTo) {
752
+ if (useAverageSize !== void 0 && sizeKnown === void 0 && !getEstimatedItemSize && !scrollingTo) {
751
753
  size = useAverageSize;
752
754
  }
753
755
  if (size === void 0) {
@@ -1463,265 +1465,267 @@ function setDidLayout(ctx, state) {
1463
1465
 
1464
1466
  // src/core/calculateItemsInView.ts
1465
1467
  function calculateItemsInView(ctx, state, params = {}) {
1466
- var _a, _b, _c, _d, _e, _f, _g, _h;
1467
- const {
1468
- scrollLength,
1469
- startBufferedId: startBufferedIdOrig,
1470
- positions,
1471
- columns,
1472
- containerItemKeys,
1473
- idCache,
1474
- sizes,
1475
- indexByKey,
1476
- scrollForNextCalculateItemsInView,
1477
- enableScrollForNextCalculateItemsInView,
1478
- minIndexSizeChanged
1479
- } = state;
1480
- const data = state.props.data;
1481
- const prevNumContainers = peek$(ctx, "numContainers");
1482
- if (!data || scrollLength === 0 || !prevNumContainers) {
1483
- return;
1484
- }
1485
- const totalSize = peek$(ctx, "totalSize");
1486
- const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
1487
- const numColumns = peek$(ctx, "numColumns");
1488
- const previousScrollAdjust = 0;
1489
- const { dataChanged, doMVCP } = params;
1490
- const speed = getScrollVelocity(state);
1491
- if (doMVCP || dataChanged) {
1492
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
1493
- updateAllPositions(ctx, state, dataChanged);
1494
- checkMVCP == null ? void 0 : checkMVCP();
1495
- }
1496
- const scrollExtra = 0;
1497
- const { queuedInitialLayout } = state;
1498
- let { scroll: scrollState } = state;
1499
- const initialScroll = state.props.initialScroll;
1500
- if (!queuedInitialLayout && initialScroll) {
1501
- const updatedOffset = calculateOffsetWithOffsetPosition(
1502
- state,
1503
- calculateOffsetForIndex(ctx, state, initialScroll.index),
1504
- initialScroll
1505
- );
1506
- scrollState = updatedOffset;
1507
- }
1508
- const scrollAdjustPad = -previousScrollAdjust - topPad;
1509
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
1510
- if (scroll + scrollLength > totalSize) {
1511
- scroll = totalSize - scrollLength;
1512
- }
1513
- if (ENABLE_DEBUG_VIEW) {
1514
- set$(ctx, "debugRawScroll", scrollState);
1515
- set$(ctx, "debugComputedScroll", scroll);
1516
- }
1517
- const scrollBuffer = state.props.scrollBuffer;
1518
- let scrollBufferTop = scrollBuffer;
1519
- let scrollBufferBottom = scrollBuffer;
1520
- if (speed > 0) {
1521
- scrollBufferTop = scrollBuffer * 0.5;
1522
- scrollBufferBottom = scrollBuffer * 1.5;
1523
- } else {
1524
- scrollBufferTop = scrollBuffer * 1.5;
1525
- scrollBufferBottom = scrollBuffer * 0.5;
1526
- }
1527
- const scrollTopBuffered = scroll - scrollBufferTop;
1528
- const scrollBottom = scroll + scrollLength;
1529
- const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1530
- if (scrollForNextCalculateItemsInView) {
1531
- const { top, bottom } = scrollForNextCalculateItemsInView;
1532
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
1468
+ unstable_batchedUpdates(() => {
1469
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1470
+ const {
1471
+ scrollLength,
1472
+ startBufferedId: startBufferedIdOrig,
1473
+ positions,
1474
+ columns,
1475
+ containerItemKeys,
1476
+ idCache,
1477
+ sizes,
1478
+ indexByKey,
1479
+ scrollForNextCalculateItemsInView,
1480
+ enableScrollForNextCalculateItemsInView,
1481
+ minIndexSizeChanged
1482
+ } = state;
1483
+ const data = state.props.data;
1484
+ const prevNumContainers = peek$(ctx, "numContainers");
1485
+ if (!data || scrollLength === 0 || !prevNumContainers) {
1533
1486
  return;
1534
1487
  }
1535
- }
1536
- let startNoBuffer = null;
1537
- let startBuffered = null;
1538
- let startBufferedId = null;
1539
- let endNoBuffer = null;
1540
- let endBuffered = null;
1541
- let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1542
- if (minIndexSizeChanged !== void 0) {
1543
- loopStart = Math.min(minIndexSizeChanged, loopStart);
1544
- state.minIndexSizeChanged = void 0;
1545
- }
1546
- for (let i = loopStart; i >= 0; i--) {
1547
- const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
1548
- const top = positions.get(id);
1549
- const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
1550
- const bottom = top + size;
1551
- if (bottom > scroll - scrollBuffer) {
1552
- loopStart = i;
1488
+ const totalSize = peek$(ctx, "totalSize");
1489
+ const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
1490
+ const numColumns = peek$(ctx, "numColumns");
1491
+ const previousScrollAdjust = 0;
1492
+ const { dataChanged, doMVCP } = params;
1493
+ const speed = getScrollVelocity(state);
1494
+ if (doMVCP || dataChanged) {
1495
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
1496
+ updateAllPositions(ctx, state, dataChanged);
1497
+ checkMVCP == null ? void 0 : checkMVCP();
1498
+ }
1499
+ const scrollExtra = 0;
1500
+ const { queuedInitialLayout } = state;
1501
+ let { scroll: scrollState } = state;
1502
+ const initialScroll = state.props.initialScroll;
1503
+ if (!queuedInitialLayout && initialScroll) {
1504
+ const updatedOffset = calculateOffsetWithOffsetPosition(
1505
+ state,
1506
+ calculateOffsetForIndex(ctx, state, initialScroll.index),
1507
+ initialScroll
1508
+ );
1509
+ scrollState = updatedOffset;
1510
+ }
1511
+ const scrollAdjustPad = -previousScrollAdjust - topPad;
1512
+ let scroll = scrollState + scrollExtra + scrollAdjustPad;
1513
+ if (scroll + scrollLength > totalSize) {
1514
+ scroll = totalSize - scrollLength;
1515
+ }
1516
+ if (ENABLE_DEBUG_VIEW) {
1517
+ set$(ctx, "debugRawScroll", scrollState);
1518
+ set$(ctx, "debugComputedScroll", scroll);
1519
+ }
1520
+ const scrollBuffer = state.props.scrollBuffer;
1521
+ let scrollBufferTop = scrollBuffer;
1522
+ let scrollBufferBottom = scrollBuffer;
1523
+ if (speed > 0) {
1524
+ scrollBufferTop = scrollBuffer * 0.5;
1525
+ scrollBufferBottom = scrollBuffer * 1.5;
1553
1526
  } else {
1554
- break;
1555
- }
1556
- }
1557
- const loopStartMod = loopStart % numColumns;
1558
- if (loopStartMod > 0) {
1559
- loopStart -= loopStartMod;
1560
- }
1561
- let foundEnd = false;
1562
- let nextTop;
1563
- let nextBottom;
1564
- let maxIndexRendered = 0;
1565
- for (let i = 0; i < prevNumContainers; i++) {
1566
- const key = peek$(ctx, `containerItemKey${i}`);
1567
- if (key !== void 0) {
1568
- const index = indexByKey.get(key);
1569
- maxIndexRendered = Math.max(maxIndexRendered, index);
1570
- }
1571
- }
1572
- let firstFullyOnScreenIndex;
1573
- const dataLength = data.length;
1574
- for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1575
- const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
1576
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
1577
- const top = positions.get(id);
1578
- if (!foundEnd) {
1579
- if (startNoBuffer === null && top + size > scroll) {
1580
- startNoBuffer = i;
1581
- }
1582
- if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
1583
- firstFullyOnScreenIndex = i;
1584
- }
1585
- if (startBuffered === null && top + size > scrollTopBuffered) {
1586
- startBuffered = i;
1587
- startBufferedId = id;
1588
- nextTop = top;
1589
- }
1590
- if (startNoBuffer !== null) {
1591
- if (top <= scrollBottom) {
1592
- endNoBuffer = i;
1593
- }
1594
- if (top <= scrollBottomBuffered) {
1595
- endBuffered = i;
1596
- nextBottom = top + size;
1597
- } else {
1598
- foundEnd = true;
1599
- }
1527
+ scrollBufferTop = scrollBuffer * 1.5;
1528
+ scrollBufferBottom = scrollBuffer * 0.5;
1529
+ }
1530
+ const scrollTopBuffered = scroll - scrollBufferTop;
1531
+ const scrollBottom = scroll + scrollLength;
1532
+ const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1533
+ if (scrollForNextCalculateItemsInView) {
1534
+ const { top, bottom } = scrollForNextCalculateItemsInView;
1535
+ if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
1536
+ return;
1600
1537
  }
1601
1538
  }
1602
- }
1603
- const idsInView = [];
1604
- for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
1605
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1606
- idsInView.push(id);
1607
- }
1608
- Object.assign(state, {
1609
- endBuffered,
1610
- endNoBuffer,
1611
- firstFullyOnScreenIndex,
1612
- idsInView,
1613
- startBuffered,
1614
- startBufferedId,
1615
- startNoBuffer
1616
- });
1617
- if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
1618
- state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
1619
- bottom: nextBottom,
1620
- top: nextTop
1621
- } : void 0;
1622
- }
1623
- const numContainers = peek$(ctx, "numContainers");
1624
- const pendingRemoval = [];
1625
- if (dataChanged) {
1626
- for (let i = 0; i < numContainers; i++) {
1627
- const itemKey = peek$(ctx, `containerItemKey${i}`);
1628
- if (!state.props.keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
1629
- pendingRemoval.push(i);
1539
+ let startNoBuffer = null;
1540
+ let startBuffered = null;
1541
+ let startBufferedId = null;
1542
+ let endNoBuffer = null;
1543
+ let endBuffered = null;
1544
+ let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1545
+ if (minIndexSizeChanged !== void 0) {
1546
+ loopStart = Math.min(minIndexSizeChanged, loopStart);
1547
+ state.minIndexSizeChanged = void 0;
1548
+ }
1549
+ for (let i = loopStart; i >= 0; i--) {
1550
+ const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
1551
+ const top = positions.get(id);
1552
+ const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
1553
+ const bottom = top + size;
1554
+ if (bottom > scroll - scrollBuffer) {
1555
+ loopStart = i;
1556
+ } else {
1557
+ break;
1630
1558
  }
1631
1559
  }
1632
- }
1633
- if (startBuffered !== null && endBuffered !== null) {
1634
- let numContainers2 = prevNumContainers;
1635
- const needNewContainers = [];
1636
- for (let i = startBuffered; i <= endBuffered; i++) {
1637
- const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
1638
- if (!containerItemKeys.has(id)) {
1639
- needNewContainers.push(i);
1560
+ const loopStartMod = loopStart % numColumns;
1561
+ if (loopStartMod > 0) {
1562
+ loopStart -= loopStartMod;
1563
+ }
1564
+ let foundEnd = false;
1565
+ let nextTop;
1566
+ let nextBottom;
1567
+ let maxIndexRendered = 0;
1568
+ for (let i = 0; i < prevNumContainers; i++) {
1569
+ const key = peek$(ctx, `containerItemKey${i}`);
1570
+ if (key !== void 0) {
1571
+ const index = indexByKey.get(key);
1572
+ maxIndexRendered = Math.max(maxIndexRendered, index);
1640
1573
  }
1641
1574
  }
1642
- if (needNewContainers.length > 0) {
1643
- const availableContainers = findAvailableContainers(
1644
- ctx,
1645
- state,
1646
- needNewContainers.length,
1647
- startBuffered,
1648
- endBuffered,
1649
- pendingRemoval
1650
- );
1651
- for (let idx = 0; idx < needNewContainers.length; idx++) {
1652
- const i = needNewContainers[idx];
1653
- const containerIndex = availableContainers[idx];
1654
- const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
1655
- const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
1656
- if (oldKey && oldKey !== id) {
1657
- containerItemKeys.delete(oldKey);
1575
+ let firstFullyOnScreenIndex;
1576
+ const dataLength = data.length;
1577
+ for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1578
+ const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
1579
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
1580
+ const top = positions.get(id);
1581
+ if (!foundEnd) {
1582
+ if (startNoBuffer === null && top + size > scroll) {
1583
+ startNoBuffer = i;
1584
+ }
1585
+ if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
1586
+ firstFullyOnScreenIndex = i;
1658
1587
  }
1659
- set$(ctx, `containerItemKey${containerIndex}`, id);
1660
- set$(ctx, `containerItemData${containerIndex}`, data[i]);
1661
- containerItemKeys.add(id);
1662
- if (containerIndex >= numContainers2) {
1663
- numContainers2 = containerIndex + 1;
1588
+ if (startBuffered === null && top + size > scrollTopBuffered) {
1589
+ startBuffered = i;
1590
+ startBufferedId = id;
1591
+ nextTop = top;
1592
+ }
1593
+ if (startNoBuffer !== null) {
1594
+ if (top <= scrollBottom) {
1595
+ endNoBuffer = i;
1596
+ }
1597
+ if (top <= scrollBottomBuffered) {
1598
+ endBuffered = i;
1599
+ nextBottom = top + size;
1600
+ } else {
1601
+ foundEnd = true;
1602
+ }
1664
1603
  }
1665
1604
  }
1666
- if (numContainers2 !== prevNumContainers) {
1667
- set$(ctx, "numContainers", numContainers2);
1668
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
1669
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
1605
+ }
1606
+ const idsInView = [];
1607
+ for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
1608
+ const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1609
+ idsInView.push(id);
1610
+ }
1611
+ Object.assign(state, {
1612
+ endBuffered,
1613
+ endNoBuffer,
1614
+ firstFullyOnScreenIndex,
1615
+ idsInView,
1616
+ startBuffered,
1617
+ startBufferedId,
1618
+ startNoBuffer
1619
+ });
1620
+ if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
1621
+ state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
1622
+ bottom: nextBottom,
1623
+ top: nextTop
1624
+ } : void 0;
1625
+ }
1626
+ const numContainers = peek$(ctx, "numContainers");
1627
+ const pendingRemoval = [];
1628
+ if (dataChanged) {
1629
+ for (let i = 0; i < numContainers; i++) {
1630
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1631
+ if (!state.props.keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
1632
+ pendingRemoval.push(i);
1670
1633
  }
1671
1634
  }
1672
1635
  }
1673
- }
1674
- for (let i = 0; i < numContainers; i++) {
1675
- const itemKey = peek$(ctx, `containerItemKey${i}`);
1676
- if (pendingRemoval.includes(i)) {
1677
- if (itemKey) {
1678
- containerItemKeys.delete(itemKey);
1636
+ if (startBuffered !== null && endBuffered !== null) {
1637
+ let numContainers2 = prevNumContainers;
1638
+ const needNewContainers = [];
1639
+ for (let i = startBuffered; i <= endBuffered; i++) {
1640
+ const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
1641
+ if (!containerItemKeys.has(id)) {
1642
+ needNewContainers.push(i);
1643
+ }
1679
1644
  }
1680
- set$(ctx, `containerItemKey${i}`, void 0);
1681
- set$(ctx, `containerItemData${i}`, void 0);
1682
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1683
- set$(ctx, `containerColumn${i}`, -1);
1684
- } else {
1685
- const itemIndex = indexByKey.get(itemKey);
1686
- const item = data[itemIndex];
1687
- if (item !== void 0) {
1688
- const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
1689
- const position = positions.get(id);
1690
- if (position === void 0) {
1691
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1692
- } else {
1693
- const column = columns.get(id) || 1;
1694
- const prevPos = peek$(ctx, `containerPosition${i}`);
1695
- const prevColumn = peek$(ctx, `containerColumn${i}`);
1696
- const prevData = peek$(ctx, `containerItemData${i}`);
1697
- if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
1698
- set$(ctx, `containerPosition${i}`, position);
1645
+ if (needNewContainers.length > 0) {
1646
+ const availableContainers = findAvailableContainers(
1647
+ ctx,
1648
+ state,
1649
+ needNewContainers.length,
1650
+ startBuffered,
1651
+ endBuffered,
1652
+ pendingRemoval
1653
+ );
1654
+ for (let idx = 0; idx < needNewContainers.length; idx++) {
1655
+ const i = needNewContainers[idx];
1656
+ const containerIndex = availableContainers[idx];
1657
+ const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
1658
+ const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
1659
+ if (oldKey && oldKey !== id) {
1660
+ containerItemKeys.delete(oldKey);
1699
1661
  }
1700
- if (column >= 0 && column !== prevColumn) {
1701
- set$(ctx, `containerColumn${i}`, column);
1662
+ set$(ctx, `containerItemKey${containerIndex}`, id);
1663
+ set$(ctx, `containerItemData${containerIndex}`, data[i]);
1664
+ containerItemKeys.add(id);
1665
+ if (containerIndex >= numContainers2) {
1666
+ numContainers2 = containerIndex + 1;
1702
1667
  }
1703
- if (prevData !== item) {
1704
- set$(ctx, `containerItemData${i}`, data[itemIndex]);
1668
+ }
1669
+ if (numContainers2 !== prevNumContainers) {
1670
+ set$(ctx, "numContainers", numContainers2);
1671
+ if (numContainers2 > peek$(ctx, "numContainersPooled")) {
1672
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
1705
1673
  }
1706
1674
  }
1707
1675
  }
1708
1676
  }
1709
- }
1710
- if (!queuedInitialLayout && endBuffered !== null) {
1711
- if (checkAllSizesKnown(state)) {
1712
- setDidLayout(ctx, state);
1677
+ for (let i = 0; i < numContainers; i++) {
1678
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1679
+ if (pendingRemoval.includes(i)) {
1680
+ if (itemKey) {
1681
+ containerItemKeys.delete(itemKey);
1682
+ }
1683
+ set$(ctx, `containerItemKey${i}`, void 0);
1684
+ set$(ctx, `containerItemData${i}`, void 0);
1685
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1686
+ set$(ctx, `containerColumn${i}`, -1);
1687
+ } else {
1688
+ const itemIndex = indexByKey.get(itemKey);
1689
+ const item = data[itemIndex];
1690
+ if (item !== void 0) {
1691
+ const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
1692
+ const position = positions.get(id);
1693
+ if (position === void 0) {
1694
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1695
+ } else {
1696
+ const column = columns.get(id) || 1;
1697
+ const prevPos = peek$(ctx, `containerPosition${i}`);
1698
+ const prevColumn = peek$(ctx, `containerColumn${i}`);
1699
+ const prevData = peek$(ctx, `containerItemData${i}`);
1700
+ if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
1701
+ set$(ctx, `containerPosition${i}`, position);
1702
+ }
1703
+ if (column >= 0 && column !== prevColumn) {
1704
+ set$(ctx, `containerColumn${i}`, column);
1705
+ }
1706
+ if (prevData !== item) {
1707
+ set$(ctx, `containerItemData${i}`, data[itemIndex]);
1708
+ }
1709
+ }
1710
+ }
1711
+ }
1713
1712
  }
1714
- }
1715
- if (state.props.viewabilityConfigCallbackPairs) {
1716
- updateViewableItems(
1717
- state,
1718
- ctx,
1719
- state.props.viewabilityConfigCallbackPairs,
1720
- scrollLength,
1721
- startNoBuffer,
1722
- endNoBuffer
1723
- );
1724
- }
1713
+ if (!queuedInitialLayout && endBuffered !== null) {
1714
+ if (checkAllSizesKnown(state)) {
1715
+ setDidLayout(ctx, state);
1716
+ }
1717
+ }
1718
+ if (state.props.viewabilityConfigCallbackPairs) {
1719
+ updateViewableItems(
1720
+ state,
1721
+ ctx,
1722
+ state.props.viewabilityConfigCallbackPairs,
1723
+ scrollLength,
1724
+ startNoBuffer,
1725
+ endNoBuffer
1726
+ );
1727
+ }
1728
+ });
1725
1729
  }
1726
1730
 
1727
1731
  // src/core/doInitialAllocateContainers.ts
@@ -1995,32 +1999,20 @@ function updateItemSizes(ctx, state, itemUpdates) {
1995
1999
  }
1996
2000
  }
1997
2001
  function updateItemSize(ctx, state, itemKey, sizeObj) {
1998
- if (IsNewArchitecture) {
1999
- const { sizesKnown } = state;
2000
- const numContainers = peek$(ctx, "numContainers");
2001
- const changes = [];
2002
- for (let i = 0; i < numContainers; i++) {
2003
- const containerItemKey = peek$(ctx, `containerItemKey${i}`);
2004
- if (itemKey === containerItemKey) {
2005
- changes.push({ itemKey, sizeObj });
2006
- } else if (!sizesKnown.has(containerItemKey) && containerItemKey !== void 0) {
2007
- const containerRef = ctx.viewRefs.get(i);
2008
- if (containerRef == null ? void 0 : containerRef.current) {
2009
- let measured;
2010
- containerRef.current.measure((x, y, width, height) => {
2011
- measured = { height, width, x, y };
2012
- });
2013
- if (measured) {
2014
- changes.push({ itemKey: containerItemKey, sizeObj: measured });
2015
- }
2016
- }
2017
- }
2018
- }
2019
- if (changes.length > 0) {
2020
- updateItemSizes(ctx, state, changes);
2002
+ const { queuedItemSizeUpdates, queuedItemSizeUpdatesWaiting } = state;
2003
+ const containersDidLayout = peek$(ctx, "containersDidLayout");
2004
+ if (!containersDidLayout || !queuedItemSizeUpdatesWaiting) {
2005
+ updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
2006
+ if (containersDidLayout) {
2007
+ state.queuedItemSizeUpdatesWaiting = true;
2008
+ requestAnimationFrame(() => {
2009
+ state.queuedItemSizeUpdatesWaiting = false;
2010
+ updateItemSizes(ctx, state, queuedItemSizeUpdates);
2011
+ queuedItemSizeUpdates.length = 0;
2012
+ });
2021
2013
  }
2022
2014
  } else {
2023
- updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
2015
+ queuedItemSizeUpdates.push({ itemKey, sizeObj });
2024
2016
  }
2025
2017
  }
2026
2018
  function updateOneItemSize(state, itemKey, sizeObj) {
@@ -2201,6 +2193,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2201
2193
  positions: /* @__PURE__ */ new Map(),
2202
2194
  props: {},
2203
2195
  queuedCalculateItemsInView: 0,
2196
+ queuedItemSizeUpdates: [],
2204
2197
  refScroller: void 0,
2205
2198
  scroll: 0,
2206
2199
  scrollAdjustHandler: new ScrollAdjustHandler(ctx),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "2.0.0-next.6",
3
+ "version": "2.0.0-next.7",
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,