@legendapp/list 1.0.0-beta.28 → 1.0.0-beta.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.mts CHANGED
@@ -22,9 +22,9 @@ declare class ScrollAdjustHandler {
22
22
 
23
23
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices"> & {
24
24
  /**
25
- * If true, aligns items at the end of the list.
26
- * @default false
27
- */
25
+ * If true, aligns items at the end of the list.
26
+ * @default false
27
+ */
28
28
  alignItemsAtEnd?: boolean;
29
29
  /**
30
30
  * Style applied to each column's wrapper view.
@@ -271,6 +271,7 @@ interface InternalState {
271
271
  queuedCalculateItemsInView: number | undefined;
272
272
  lastBatchingAction: number;
273
273
  ignoreScrollFromCalcTotal?: boolean;
274
+ didInitialScroll?: boolean;
274
275
  onScroll: ((event: NativeSyntheticEvent<NativeScrollEvent>) => void) | undefined;
275
276
  }
276
277
  interface ViewableRange<T> {
@@ -289,10 +290,21 @@ interface LegendListRenderItemProps<ItemT> {
289
290
  useRecyclingEffect: (effect: (info: LegendListRecyclingState<ItemT>) => void | (() => void)) => void;
290
291
  useRecyclingState: <T>(updateState: ((info: LegendListRecyclingState<ItemT>) => T) | T) => [T, React.Dispatch<T>];
291
292
  }
293
+ type ScrollState = {
294
+ contentLength: number;
295
+ end: number;
296
+ endBuffered: number;
297
+ isAtEnd: boolean;
298
+ isAtStart: boolean;
299
+ scroll: number;
300
+ scrollLength: number;
301
+ start: number;
302
+ startBuffered: number;
303
+ };
292
304
  type LegendListRef = {
293
305
  /**
294
- * Displays the scroll indicators momentarily.
295
- */
306
+ * Displays the scroll indicators momentarily.
307
+ */
296
308
  flashScrollIndicators(): void;
297
309
  /**
298
310
  * Returns the native ScrollView component reference.
@@ -306,6 +318,30 @@ type LegendListRef = {
306
318
  * Returns the ScrollResponderMixin for advanced scroll handling.
307
319
  */
308
320
  getScrollResponder(): ScrollResponderMixin;
321
+ /**
322
+ * Returns the internal state of the scroll virtualization.
323
+ */
324
+ getState(): ScrollState;
325
+ /**
326
+ * Scrolls a specific index into view.
327
+ * @param params - Parameters for scrolling.
328
+ * @param params.animated - If true, animates the scroll. Default: true.
329
+ * @param params.index - The index to scroll to.
330
+ */
331
+ scrollIndexIntoView(params: {
332
+ animated?: boolean | undefined;
333
+ index: number;
334
+ }): void;
335
+ /**
336
+ * Scrolls a specific index into view.
337
+ * @param params - Parameters for scrolling.
338
+ * @param params.animated - If true, animates the scroll. Default: true.
339
+ * @param params.item - The item to scroll to.
340
+ */
341
+ scrollItemIntoView(params: {
342
+ animated?: boolean | undefined;
343
+ item: any;
344
+ }): void;
309
345
  /**
310
346
  * Scrolls to the end of the list.
311
347
  * @param options - Options for scrolling.
@@ -477,4 +513,4 @@ declare function useViewabilityAmount(callback: ViewabilityAmountCallback): void
477
513
  declare function useRecyclingEffect(effect: (info: LegendListRecyclingState<unknown>) => void | (() => void)): void;
478
514
  declare function useRecyclingState(valueOrFun: ((info: LegendListRecyclingState<unknown>) => any) | any): [any, React$1.Dispatch<any>];
479
515
 
480
- export { type AnchoredPosition, type ColumnWrapperStyle, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
516
+ export { type AnchoredPosition, type ColumnWrapperStyle, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ScrollState, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
package/index.d.ts CHANGED
@@ -22,9 +22,9 @@ declare class ScrollAdjustHandler {
22
22
 
23
23
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices"> & {
24
24
  /**
25
- * If true, aligns items at the end of the list.
26
- * @default false
27
- */
25
+ * If true, aligns items at the end of the list.
26
+ * @default false
27
+ */
28
28
  alignItemsAtEnd?: boolean;
29
29
  /**
30
30
  * Style applied to each column's wrapper view.
@@ -271,6 +271,7 @@ interface InternalState {
271
271
  queuedCalculateItemsInView: number | undefined;
272
272
  lastBatchingAction: number;
273
273
  ignoreScrollFromCalcTotal?: boolean;
274
+ didInitialScroll?: boolean;
274
275
  onScroll: ((event: NativeSyntheticEvent<NativeScrollEvent>) => void) | undefined;
275
276
  }
276
277
  interface ViewableRange<T> {
@@ -289,10 +290,21 @@ interface LegendListRenderItemProps<ItemT> {
289
290
  useRecyclingEffect: (effect: (info: LegendListRecyclingState<ItemT>) => void | (() => void)) => void;
290
291
  useRecyclingState: <T>(updateState: ((info: LegendListRecyclingState<ItemT>) => T) | T) => [T, React.Dispatch<T>];
291
292
  }
293
+ type ScrollState = {
294
+ contentLength: number;
295
+ end: number;
296
+ endBuffered: number;
297
+ isAtEnd: boolean;
298
+ isAtStart: boolean;
299
+ scroll: number;
300
+ scrollLength: number;
301
+ start: number;
302
+ startBuffered: number;
303
+ };
292
304
  type LegendListRef = {
293
305
  /**
294
- * Displays the scroll indicators momentarily.
295
- */
306
+ * Displays the scroll indicators momentarily.
307
+ */
296
308
  flashScrollIndicators(): void;
297
309
  /**
298
310
  * Returns the native ScrollView component reference.
@@ -306,6 +318,30 @@ type LegendListRef = {
306
318
  * Returns the ScrollResponderMixin for advanced scroll handling.
307
319
  */
308
320
  getScrollResponder(): ScrollResponderMixin;
321
+ /**
322
+ * Returns the internal state of the scroll virtualization.
323
+ */
324
+ getState(): ScrollState;
325
+ /**
326
+ * Scrolls a specific index into view.
327
+ * @param params - Parameters for scrolling.
328
+ * @param params.animated - If true, animates the scroll. Default: true.
329
+ * @param params.index - The index to scroll to.
330
+ */
331
+ scrollIndexIntoView(params: {
332
+ animated?: boolean | undefined;
333
+ index: number;
334
+ }): void;
335
+ /**
336
+ * Scrolls a specific index into view.
337
+ * @param params - Parameters for scrolling.
338
+ * @param params.animated - If true, animates the scroll. Default: true.
339
+ * @param params.item - The item to scroll to.
340
+ */
341
+ scrollItemIntoView(params: {
342
+ animated?: boolean | undefined;
343
+ item: any;
344
+ }): void;
309
345
  /**
310
346
  * Scrolls to the end of the list.
311
347
  * @param options - Options for scrolling.
@@ -477,4 +513,4 @@ declare function useViewabilityAmount(callback: ViewabilityAmountCallback): void
477
513
  declare function useRecyclingEffect(effect: (info: LegendListRecyclingState<unknown>) => void | (() => void)): void;
478
514
  declare function useRecyclingState(valueOrFun: ((info: LegendListRecyclingState<unknown>) => any) | any): [any, React$1.Dispatch<any>];
479
515
 
480
- export { type AnchoredPosition, type ColumnWrapperStyle, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
516
+ export { type AnchoredPosition, type ColumnWrapperStyle, type InternalState, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ScrollState, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
package/index.js CHANGED
@@ -831,7 +831,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
831
831
  ctx.columnWrapperStyle = columnWrapperStyle;
832
832
  const refScroller = React6.useRef(null);
833
833
  const combinedRef = useCombinedRef(refScroller, refScrollView);
834
- const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
834
+ const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
835
835
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
836
836
  const refState = React6.useRef();
837
837
  const getId = (index) => {
@@ -1321,6 +1321,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1321
1321
  set$(ctx, "paddingTop", paddingTop);
1322
1322
  }
1323
1323
  };
1324
+ const scrollTo = (offset, animated) => {
1325
+ var _a2;
1326
+ (_a2 = refScroller.current) == null ? void 0 : _a2.scrollTo({
1327
+ x: horizontal ? offset : 0,
1328
+ y: horizontal ? 0 : offset,
1329
+ animated: !!animated
1330
+ });
1331
+ };
1324
1332
  const doMaintainScrollAtEnd = (animated) => {
1325
1333
  const state = refState.current;
1326
1334
  if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd) {
@@ -1433,7 +1441,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1433
1441
  }
1434
1442
  };
1435
1443
  const calcTotalSizesAndPositions = ({ forgetPositions = false }) => {
1436
- var _a2, _b2, _c2, _d2;
1444
+ var _a2, _b2;
1437
1445
  let totalSize = 0;
1438
1446
  let totalSizeBelowIndex = 0;
1439
1447
  const indexByKey = /* @__PURE__ */ new Map();
@@ -1470,7 +1478,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1470
1478
  };
1471
1479
  refState.current.anchorElement = newAnchorElement;
1472
1480
  (_b2 = refState.current.belowAnchorElementPositions) == null ? void 0 : _b2.clear();
1473
- (_c2 = refScroller.current) == null ? void 0 : _c2.scrollTo({ x: 0, y: 0, animated: false });
1481
+ scrollTo(0, false);
1474
1482
  setTimeout(() => {
1475
1483
  calculateItemsInView();
1476
1484
  }, 0);
@@ -1485,7 +1493,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1485
1493
  } else {
1486
1494
  refState.current.startBufferedId = void 0;
1487
1495
  }
1488
- (_d2 = refScroller.current) == null ? void 0 : _d2.scrollTo({ x: 0, y: 0, animated: false });
1496
+ scrollTo(0, false);
1489
1497
  setTimeout(() => {
1490
1498
  calculateItemsInView();
1491
1499
  }, 0);
@@ -1686,6 +1694,19 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1686
1694
  }
1687
1695
  }
1688
1696
  if (needsCalculate) {
1697
+ let fixingScroll = false;
1698
+ if (needsUpdateContainersDidLayout && initialScrollIndex && !state.didInitialScroll) {
1699
+ const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
1700
+ state.didInitialScroll = true;
1701
+ if (updatedOffset !== initialContentOffset) {
1702
+ fixingScroll = true;
1703
+ scrollTo(updatedOffset, false);
1704
+ requestAnimationFrame(() => {
1705
+ const updatedOffset2 = calculateOffsetForIndex(initialScrollIndex);
1706
+ scrollTo(updatedOffset2, false);
1707
+ });
1708
+ }
1709
+ }
1689
1710
  const scrollVelocity = state.scrollVelocity;
1690
1711
  if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1) && (!waitForInitialLayout || state.numPendingInitialLayout < 0)) {
1691
1712
  const setDidLayout = () => {
@@ -1707,7 +1728,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1707
1728
  } else {
1708
1729
  calculateItemsInView();
1709
1730
  if (needsUpdateContainersDidLayout) {
1710
- queueMicrotask(setDidLayout);
1731
+ if (fixingScroll) {
1732
+ requestAnimationFrame(setDidLayout);
1733
+ } else {
1734
+ queueMicrotask(setDidLayout);
1735
+ }
1711
1736
  }
1712
1737
  }
1713
1738
  }
@@ -1826,12 +1851,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1826
1851
  if (viewPosition) {
1827
1852
  firstIndexScrollPostion -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
1828
1853
  }
1829
- const offset = horizontal ? { x: firstIndexScrollPostion, y: 0 } : { x: 0, y: firstIndexScrollPostion };
1830
- refScroller.current.scrollTo({ ...offset, animated });
1854
+ scrollTo(firstIndexScrollPostion, animated);
1831
1855
  const totalSizeWithScrollAdjust = peek$(ctx, "totalSizeWithScrollAdjust");
1832
1856
  if (maintainVisibleContentPosition && totalSizeWithScrollAdjust - firstIndexScrollPostion < state.scrollLength) {
1833
1857
  const doScrollTo = () => {
1834
- refScroller.current.scrollTo({ ...offset, animated });
1858
+ scrollTo(firstIndexScrollPostion, animated);
1835
1859
  };
1836
1860
  setTimeout(doScrollTo, animated ? 150 : 50);
1837
1861
  if (animated) {
@@ -1839,16 +1863,48 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1839
1863
  }
1840
1864
  }
1841
1865
  };
1866
+ const scrollIndexIntoView = (options) => {
1867
+ if (refState.current) {
1868
+ const { index, ...rest2 } = options;
1869
+ const { startNoBuffer, endNoBuffer } = refState.current;
1870
+ if (index < startNoBuffer || index > endNoBuffer) {
1871
+ const viewPosition = index < startNoBuffer ? 0 : 1;
1872
+ scrollToIndex({
1873
+ ...rest2,
1874
+ viewPosition,
1875
+ index
1876
+ });
1877
+ }
1878
+ }
1879
+ };
1842
1880
  return {
1881
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
1843
1882
  getNativeScrollRef: () => refScroller.current,
1844
1883
  getScrollableNode: () => refScroller.current.getScrollableNode(),
1845
1884
  getScrollResponder: () => refScroller.current.getScrollResponder(),
1846
- flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
1847
- scrollToIndex,
1848
- scrollToOffset: ({ offset, animated }) => {
1849
- const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
1850
- refScroller.current.scrollTo({ ...offsetObj, animated });
1885
+ getState: () => {
1886
+ const state = refState.current;
1887
+ return state ? {
1888
+ contentLength: state.totalSize,
1889
+ end: state.endNoBuffer,
1890
+ endBuffered: state.endBuffered,
1891
+ isAtEnd: state.isAtBottom,
1892
+ isAtStart: state.isAtTop,
1893
+ scroll: state.scroll,
1894
+ scrollLength: state.scrollLength,
1895
+ start: state.startNoBuffer,
1896
+ startBuffered: state.startBuffered
1897
+ } : {};
1898
+ },
1899
+ scrollIndexIntoView,
1900
+ scrollItemIntoView: ({ item, ...props2 }) => {
1901
+ const { data } = refState.current;
1902
+ const index = data.indexOf(item);
1903
+ if (index !== -1) {
1904
+ scrollIndexIntoView({ index, ...props2 });
1905
+ }
1851
1906
  },
1907
+ scrollToIndex,
1852
1908
  scrollToItem: ({ item, ...props2 }) => {
1853
1909
  const { data } = refState.current;
1854
1910
  const index = data.indexOf(item);
@@ -1856,6 +1912,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1856
1912
  scrollToIndex({ index, ...props2 });
1857
1913
  }
1858
1914
  },
1915
+ scrollToOffset: ({ offset, animated }) => {
1916
+ scrollTo(offset, animated);
1917
+ },
1859
1918
  scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
1860
1919
  };
1861
1920
  },
@@ -1863,14 +1922,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1863
1922
  );
1864
1923
  if (reactNative.Platform.OS === "web") {
1865
1924
  React6.useEffect(() => {
1866
- var _a2, _b2;
1925
+ var _a2;
1867
1926
  if (initialContentOffset) {
1868
1927
  (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(true);
1869
- (_b2 = refScroller.current) == null ? void 0 : _b2.scrollTo({
1870
- x: horizontal ? initialContentOffset : 0,
1871
- y: horizontal ? 0 : initialContentOffset,
1872
- animated: false
1873
- });
1928
+ scrollTo(initialContentOffset, false);
1874
1929
  setTimeout(() => {
1875
1930
  var _a3;
1876
1931
  (_a3 = refState.current) == null ? void 0 : _a3.scrollAdjustHandler.setDisableAdjust(false);
@@ -1878,31 +1933,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1878
1933
  }
1879
1934
  }, []);
1880
1935
  }
1881
- if (isFirst) {
1882
- refState.current.scrollAdjustHandler.setDisableAdjust(true);
1883
- }
1884
- React6.useEffect(() => {
1885
- setTimeout(
1886
- () => {
1887
- var _a2;
1888
- return (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(false);
1889
- },
1890
- initialContentOffset ? 1e3 : 0
1891
- );
1892
- if (initialContentOffset) {
1893
- const doScrollTo = () => {
1894
- var _a2;
1895
- (_a2 = refScroller.current) == null ? void 0 : _a2.scrollTo({
1896
- x: horizontal ? initialContentOffset : 0,
1897
- y: horizontal ? 0 : initialContentOffset,
1898
- animated: false
1899
- });
1900
- calculateItemsInView();
1901
- };
1902
- setTimeout(doScrollTo, 32);
1903
- setTimeout(doScrollTo, 300);
1904
- }
1905
- }, []);
1906
1936
  return /* @__PURE__ */ React6__namespace.createElement(React6__namespace.Fragment, null, /* @__PURE__ */ React6__namespace.createElement(
1907
1937
  ListComponent,
1908
1938
  {
package/index.mjs CHANGED
@@ -810,7 +810,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
810
810
  ctx.columnWrapperStyle = columnWrapperStyle;
811
811
  const refScroller = useRef(null);
812
812
  const combinedRef = useCombinedRef(refScroller, refScrollView);
813
- const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
813
+ const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
814
814
  const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
815
815
  const refState = useRef();
816
816
  const getId = (index) => {
@@ -1300,6 +1300,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1300
1300
  set$(ctx, "paddingTop", paddingTop);
1301
1301
  }
1302
1302
  };
1303
+ const scrollTo = (offset, animated) => {
1304
+ var _a2;
1305
+ (_a2 = refScroller.current) == null ? void 0 : _a2.scrollTo({
1306
+ x: horizontal ? offset : 0,
1307
+ y: horizontal ? 0 : offset,
1308
+ animated: !!animated
1309
+ });
1310
+ };
1303
1311
  const doMaintainScrollAtEnd = (animated) => {
1304
1312
  const state = refState.current;
1305
1313
  if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd) {
@@ -1412,7 +1420,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1412
1420
  }
1413
1421
  };
1414
1422
  const calcTotalSizesAndPositions = ({ forgetPositions = false }) => {
1415
- var _a2, _b2, _c2, _d2;
1423
+ var _a2, _b2;
1416
1424
  let totalSize = 0;
1417
1425
  let totalSizeBelowIndex = 0;
1418
1426
  const indexByKey = /* @__PURE__ */ new Map();
@@ -1449,7 +1457,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1449
1457
  };
1450
1458
  refState.current.anchorElement = newAnchorElement;
1451
1459
  (_b2 = refState.current.belowAnchorElementPositions) == null ? void 0 : _b2.clear();
1452
- (_c2 = refScroller.current) == null ? void 0 : _c2.scrollTo({ x: 0, y: 0, animated: false });
1460
+ scrollTo(0, false);
1453
1461
  setTimeout(() => {
1454
1462
  calculateItemsInView();
1455
1463
  }, 0);
@@ -1464,7 +1472,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1464
1472
  } else {
1465
1473
  refState.current.startBufferedId = void 0;
1466
1474
  }
1467
- (_d2 = refScroller.current) == null ? void 0 : _d2.scrollTo({ x: 0, y: 0, animated: false });
1475
+ scrollTo(0, false);
1468
1476
  setTimeout(() => {
1469
1477
  calculateItemsInView();
1470
1478
  }, 0);
@@ -1665,6 +1673,19 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1665
1673
  }
1666
1674
  }
1667
1675
  if (needsCalculate) {
1676
+ let fixingScroll = false;
1677
+ if (needsUpdateContainersDidLayout && initialScrollIndex && !state.didInitialScroll) {
1678
+ const updatedOffset = calculateOffsetForIndex(initialScrollIndex);
1679
+ state.didInitialScroll = true;
1680
+ if (updatedOffset !== initialContentOffset) {
1681
+ fixingScroll = true;
1682
+ scrollTo(updatedOffset, false);
1683
+ requestAnimationFrame(() => {
1684
+ const updatedOffset2 = calculateOffsetForIndex(initialScrollIndex);
1685
+ scrollTo(updatedOffset2, false);
1686
+ });
1687
+ }
1688
+ }
1668
1689
  const scrollVelocity = state.scrollVelocity;
1669
1690
  if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1) && (!waitForInitialLayout || state.numPendingInitialLayout < 0)) {
1670
1691
  const setDidLayout = () => {
@@ -1686,7 +1707,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1686
1707
  } else {
1687
1708
  calculateItemsInView();
1688
1709
  if (needsUpdateContainersDidLayout) {
1689
- queueMicrotask(setDidLayout);
1710
+ if (fixingScroll) {
1711
+ requestAnimationFrame(setDidLayout);
1712
+ } else {
1713
+ queueMicrotask(setDidLayout);
1714
+ }
1690
1715
  }
1691
1716
  }
1692
1717
  }
@@ -1805,12 +1830,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1805
1830
  if (viewPosition) {
1806
1831
  firstIndexScrollPostion -= viewPosition * (state.scrollLength - getItemSize(getId(index), index, state.data[index]));
1807
1832
  }
1808
- const offset = horizontal ? { x: firstIndexScrollPostion, y: 0 } : { x: 0, y: firstIndexScrollPostion };
1809
- refScroller.current.scrollTo({ ...offset, animated });
1833
+ scrollTo(firstIndexScrollPostion, animated);
1810
1834
  const totalSizeWithScrollAdjust = peek$(ctx, "totalSizeWithScrollAdjust");
1811
1835
  if (maintainVisibleContentPosition && totalSizeWithScrollAdjust - firstIndexScrollPostion < state.scrollLength) {
1812
1836
  const doScrollTo = () => {
1813
- refScroller.current.scrollTo({ ...offset, animated });
1837
+ scrollTo(firstIndexScrollPostion, animated);
1814
1838
  };
1815
1839
  setTimeout(doScrollTo, animated ? 150 : 50);
1816
1840
  if (animated) {
@@ -1818,16 +1842,48 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1818
1842
  }
1819
1843
  }
1820
1844
  };
1845
+ const scrollIndexIntoView = (options) => {
1846
+ if (refState.current) {
1847
+ const { index, ...rest2 } = options;
1848
+ const { startNoBuffer, endNoBuffer } = refState.current;
1849
+ if (index < startNoBuffer || index > endNoBuffer) {
1850
+ const viewPosition = index < startNoBuffer ? 0 : 1;
1851
+ scrollToIndex({
1852
+ ...rest2,
1853
+ viewPosition,
1854
+ index
1855
+ });
1856
+ }
1857
+ }
1858
+ };
1821
1859
  return {
1860
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
1822
1861
  getNativeScrollRef: () => refScroller.current,
1823
1862
  getScrollableNode: () => refScroller.current.getScrollableNode(),
1824
1863
  getScrollResponder: () => refScroller.current.getScrollResponder(),
1825
- flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
1826
- scrollToIndex,
1827
- scrollToOffset: ({ offset, animated }) => {
1828
- const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
1829
- refScroller.current.scrollTo({ ...offsetObj, animated });
1864
+ getState: () => {
1865
+ const state = refState.current;
1866
+ return state ? {
1867
+ contentLength: state.totalSize,
1868
+ end: state.endNoBuffer,
1869
+ endBuffered: state.endBuffered,
1870
+ isAtEnd: state.isAtBottom,
1871
+ isAtStart: state.isAtTop,
1872
+ scroll: state.scroll,
1873
+ scrollLength: state.scrollLength,
1874
+ start: state.startNoBuffer,
1875
+ startBuffered: state.startBuffered
1876
+ } : {};
1877
+ },
1878
+ scrollIndexIntoView,
1879
+ scrollItemIntoView: ({ item, ...props2 }) => {
1880
+ const { data } = refState.current;
1881
+ const index = data.indexOf(item);
1882
+ if (index !== -1) {
1883
+ scrollIndexIntoView({ index, ...props2 });
1884
+ }
1830
1885
  },
1886
+ scrollToIndex,
1831
1887
  scrollToItem: ({ item, ...props2 }) => {
1832
1888
  const { data } = refState.current;
1833
1889
  const index = data.indexOf(item);
@@ -1835,6 +1891,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1835
1891
  scrollToIndex({ index, ...props2 });
1836
1892
  }
1837
1893
  },
1894
+ scrollToOffset: ({ offset, animated }) => {
1895
+ scrollTo(offset, animated);
1896
+ },
1838
1897
  scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
1839
1898
  };
1840
1899
  },
@@ -1842,14 +1901,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1842
1901
  );
1843
1902
  if (Platform.OS === "web") {
1844
1903
  useEffect(() => {
1845
- var _a2, _b2;
1904
+ var _a2;
1846
1905
  if (initialContentOffset) {
1847
1906
  (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(true);
1848
- (_b2 = refScroller.current) == null ? void 0 : _b2.scrollTo({
1849
- x: horizontal ? initialContentOffset : 0,
1850
- y: horizontal ? 0 : initialContentOffset,
1851
- animated: false
1852
- });
1907
+ scrollTo(initialContentOffset, false);
1853
1908
  setTimeout(() => {
1854
1909
  var _a3;
1855
1910
  (_a3 = refState.current) == null ? void 0 : _a3.scrollAdjustHandler.setDisableAdjust(false);
@@ -1857,31 +1912,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1857
1912
  }
1858
1913
  }, []);
1859
1914
  }
1860
- if (isFirst) {
1861
- refState.current.scrollAdjustHandler.setDisableAdjust(true);
1862
- }
1863
- useEffect(() => {
1864
- setTimeout(
1865
- () => {
1866
- var _a2;
1867
- return (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustHandler.setDisableAdjust(false);
1868
- },
1869
- initialContentOffset ? 1e3 : 0
1870
- );
1871
- if (initialContentOffset) {
1872
- const doScrollTo = () => {
1873
- var _a2;
1874
- (_a2 = refScroller.current) == null ? void 0 : _a2.scrollTo({
1875
- x: horizontal ? initialContentOffset : 0,
1876
- y: horizontal ? 0 : initialContentOffset,
1877
- animated: false
1878
- });
1879
- calculateItemsInView();
1880
- };
1881
- setTimeout(doScrollTo, 32);
1882
- setTimeout(doScrollTo, 300);
1883
- }
1884
- }, []);
1885
1915
  return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
1886
1916
  ListComponent,
1887
1917
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "1.0.0-beta.28",
3
+ "version": "1.0.0-beta.29",
4
4
  "description": "Legend List aims to be a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
5
5
  "sideEffects": false,
6
6
  "private": false,