@legendapp/list 3.0.0-beta.5 → 3.0.0-beta.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/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Dispatch, SetStateAction } from 'react';
3
- import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-YNdphn_A.mjs';
4
- export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-YNdphn_A.mjs';
3
+ import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-BWlIhlCl.mjs';
4
+ export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-BWlIhlCl.mjs';
5
5
  import 'react-native';
6
6
  import 'react-native-reanimated';
7
7
 
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Dispatch, SetStateAction } from 'react';
3
- import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-YNdphn_A.js';
4
- export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-YNdphn_A.js';
3
+ import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-BWlIhlCl.js';
4
+ export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-BWlIhlCl.js';
5
5
  import 'react-native';
6
6
  import 'react-native-reanimated';
7
7
 
package/index.js CHANGED
@@ -876,7 +876,6 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
876
876
  }, ref) {
877
877
  const scrollRef = React3.useRef(null);
878
878
  const contentRef = React3.useRef(null);
879
- const momentumTimeout = React3.useRef(null);
880
879
  React3.useImperativeHandle(ref, () => {
881
880
  const api = {
882
881
  getBoundingClientRect: () => {
@@ -942,16 +941,6 @@ var ListComponentScrollView = React3.forwardRef(function ListComponentScrollView
942
941
  }
943
942
  };
944
943
  onScroll2(scrollEvent);
945
- if (onMomentumScrollEnd) {
946
- if (momentumTimeout.current != null) clearTimeout(momentumTimeout.current);
947
- momentumTimeout.current = setTimeout(() => {
948
- onMomentumScrollEnd({
949
- nativeEvent: {
950
- contentOffset: scrollEvent.nativeEvent.contentOffset
951
- }
952
- });
953
- }, 100);
954
- }
955
944
  },
956
945
  [onScroll2, onMomentumScrollEnd]
957
946
  );
@@ -1374,13 +1363,76 @@ function finishScrollTo(ctx, state) {
1374
1363
  }
1375
1364
  }
1376
1365
 
1366
+ // src/core/doScrollTo.ts
1367
+ var SCROLL_END_IDLE_MS = 80;
1368
+ var SCROLL_END_MAX_MS = 1500;
1369
+ var SMOOTH_SCROLL_DURATION_MS = 320;
1370
+ function doScrollTo(ctx, state, params) {
1371
+ const { animated, horizontal, offset } = params;
1372
+ const scroller = state.refScroller.current;
1373
+ const node = typeof (scroller == null ? void 0 : scroller.getScrollableNode) === "function" ? scroller.getScrollableNode() : scroller;
1374
+ if (node) {
1375
+ const left = horizontal ? offset : 0;
1376
+ const top = horizontal ? 0 : offset;
1377
+ node.scrollTo({ behavior: animated ? "smooth" : "auto", left, top });
1378
+ if (animated) {
1379
+ listenForScrollEnd(ctx, state, node);
1380
+ } else {
1381
+ state.scroll = offset;
1382
+ setTimeout(() => {
1383
+ finishScrollTo(ctx, state);
1384
+ }, 100);
1385
+ }
1386
+ }
1387
+ }
1388
+ function listenForScrollEnd(ctx, state, node) {
1389
+ const supportsScrollEnd = "onscrollend" in node;
1390
+ let idleTimeout;
1391
+ let maxTimeout;
1392
+ let settled = false;
1393
+ const targetToken = peek$(ctx, "scrollingTo");
1394
+ const finish = () => {
1395
+ if (settled) return;
1396
+ settled = true;
1397
+ cleanup();
1398
+ if (targetToken === peek$(ctx, "scrollingTo")) {
1399
+ finishScrollTo(ctx, state);
1400
+ }
1401
+ };
1402
+ const onScroll2 = () => {
1403
+ if (idleTimeout) {
1404
+ clearTimeout(idleTimeout);
1405
+ }
1406
+ idleTimeout = setTimeout(finish, SCROLL_END_IDLE_MS);
1407
+ };
1408
+ const cleanup = () => {
1409
+ if (supportsScrollEnd) {
1410
+ node.removeEventListener("scrollend", finish);
1411
+ } else {
1412
+ node.removeEventListener("scroll", onScroll2);
1413
+ }
1414
+ if (idleTimeout) {
1415
+ clearTimeout(idleTimeout);
1416
+ }
1417
+ if (maxTimeout) {
1418
+ clearTimeout(maxTimeout);
1419
+ }
1420
+ };
1421
+ if (supportsScrollEnd) {
1422
+ node.addEventListener("scrollend", finish, { once: true });
1423
+ } else {
1424
+ node.addEventListener("scroll", onScroll2);
1425
+ idleTimeout = setTimeout(finish, SMOOTH_SCROLL_DURATION_MS);
1426
+ maxTimeout = setTimeout(finish, SCROLL_END_MAX_MS);
1427
+ }
1428
+ return cleanup;
1429
+ }
1430
+
1377
1431
  // src/core/scrollTo.ts
1378
1432
  function scrollTo(ctx, state, params) {
1379
- var _a3;
1380
1433
  const { noScrollingTo, ...scrollTarget } = params;
1381
1434
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
1382
1435
  const {
1383
- refScroller,
1384
1436
  props: { horizontal }
1385
1437
  } = state;
1386
1438
  let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
@@ -1394,22 +1446,9 @@ function scrollTo(ctx, state, params) {
1394
1446
  }
1395
1447
  state.scrollPending = offset;
1396
1448
  if (!isInitialScroll || Platform.OS === "android") {
1397
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1398
- animated: !!animated,
1399
- x: horizontal ? offset : 0,
1400
- y: horizontal ? 0 : offset
1401
- });
1402
- }
1403
- if (!animated) {
1449
+ doScrollTo(ctx, state, { animated, horizontal, isInitialScroll, offset });
1450
+ } else {
1404
1451
  state.scroll = offset;
1405
- {
1406
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1407
- if (value && peek$(ctx, "scrollingTo")) {
1408
- finishScrollTo(ctx, state);
1409
- unlisten();
1410
- }
1411
- });
1412
- }
1413
1452
  }
1414
1453
  }
1415
1454
 
@@ -1557,7 +1596,8 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1557
1596
  return;
1558
1597
  }
1559
1598
  }
1560
- if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1599
+ if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollLastCalculate) > 2) {
1600
+ state.scrollLastCalculate = state.scroll;
1561
1601
  state.ignoreScrollFromMVCPIgnored = false;
1562
1602
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1563
1603
  checkAtBottom(ctx, state);
@@ -2424,7 +2464,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2424
2464
  }
2425
2465
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2426
2466
  const scrollAdjustPad = scrollAdjustPending - topPad;
2427
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2467
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2428
2468
  if (scroll + scrollLength > totalSize) {
2429
2469
  scroll = Math.max(0, totalSize - scrollLength);
2430
2470
  }
@@ -2451,7 +2491,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2451
2491
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2452
2492
  if (!dataChanged && scrollForNextCalculateItemsInView) {
2453
2493
  const { top, bottom } = scrollForNextCalculateItemsInView;
2454
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2494
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2455
2495
  if (state.initialAnchor) {
2456
2496
  ensureInitialAnchor(ctx, state);
2457
2497
  }
@@ -2486,7 +2526,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2486
2526
  const top = positions.get(id);
2487
2527
  const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2488
2528
  const bottom = top + size;
2489
- if (bottom > scroll - scrollBuffer) {
2529
+ if (bottom > scroll - scrollBufferTop) {
2490
2530
  loopStart = i;
2491
2531
  } else {
2492
2532
  break;
@@ -2523,7 +2563,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2523
2563
  if (startBuffered === null && top + size > scrollTopBuffered) {
2524
2564
  startBuffered = i;
2525
2565
  startBufferedId = id;
2526
- nextTop = top;
2566
+ if (scrollTopBuffered < 0) {
2567
+ nextTop = null;
2568
+ } else {
2569
+ nextTop = top;
2570
+ }
2527
2571
  }
2528
2572
  if (startNoBuffer !== null) {
2529
2573
  if (top <= scrollBottom) {
@@ -2531,7 +2575,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2531
2575
  }
2532
2576
  if (top <= scrollBottomBuffered) {
2533
2577
  endBuffered = i;
2534
- nextBottom = top + size;
2578
+ if (scrollBottomBuffered > totalSize) {
2579
+ nextBottom = null;
2580
+ } else {
2581
+ nextBottom = top + size;
2582
+ }
2535
2583
  } else {
2536
2584
  foundEnd = true;
2537
2585
  }
@@ -3647,6 +3695,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3647
3695
  offset: initialContentOffset,
3648
3696
  precomputedWithViewOffset: true
3649
3697
  });
3698
+ {
3699
+ const unlisten = listen$(ctx, "containersDidLayout", (value) => {
3700
+ if (value && peek$(ctx, "scrollingTo")) {
3701
+ finishScrollTo(ctx, state);
3702
+ unlisten();
3703
+ }
3704
+ });
3705
+ }
3650
3706
  }
3651
3707
  }, [initialContentOffset]);
3652
3708
  const onLayoutChange = React3.useCallback((layout) => {
package/index.mjs CHANGED
@@ -855,7 +855,6 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
855
855
  }, ref) {
856
856
  const scrollRef = useRef(null);
857
857
  const contentRef = useRef(null);
858
- const momentumTimeout = useRef(null);
859
858
  useImperativeHandle(ref, () => {
860
859
  const api = {
861
860
  getBoundingClientRect: () => {
@@ -921,16 +920,6 @@ var ListComponentScrollView = forwardRef(function ListComponentScrollView2({
921
920
  }
922
921
  };
923
922
  onScroll2(scrollEvent);
924
- if (onMomentumScrollEnd) {
925
- if (momentumTimeout.current != null) clearTimeout(momentumTimeout.current);
926
- momentumTimeout.current = setTimeout(() => {
927
- onMomentumScrollEnd({
928
- nativeEvent: {
929
- contentOffset: scrollEvent.nativeEvent.contentOffset
930
- }
931
- });
932
- }, 100);
933
- }
934
923
  },
935
924
  [onScroll2, onMomentumScrollEnd]
936
925
  );
@@ -1353,13 +1342,76 @@ function finishScrollTo(ctx, state) {
1353
1342
  }
1354
1343
  }
1355
1344
 
1345
+ // src/core/doScrollTo.ts
1346
+ var SCROLL_END_IDLE_MS = 80;
1347
+ var SCROLL_END_MAX_MS = 1500;
1348
+ var SMOOTH_SCROLL_DURATION_MS = 320;
1349
+ function doScrollTo(ctx, state, params) {
1350
+ const { animated, horizontal, offset } = params;
1351
+ const scroller = state.refScroller.current;
1352
+ const node = typeof (scroller == null ? void 0 : scroller.getScrollableNode) === "function" ? scroller.getScrollableNode() : scroller;
1353
+ if (node) {
1354
+ const left = horizontal ? offset : 0;
1355
+ const top = horizontal ? 0 : offset;
1356
+ node.scrollTo({ behavior: animated ? "smooth" : "auto", left, top });
1357
+ if (animated) {
1358
+ listenForScrollEnd(ctx, state, node);
1359
+ } else {
1360
+ state.scroll = offset;
1361
+ setTimeout(() => {
1362
+ finishScrollTo(ctx, state);
1363
+ }, 100);
1364
+ }
1365
+ }
1366
+ }
1367
+ function listenForScrollEnd(ctx, state, node) {
1368
+ const supportsScrollEnd = "onscrollend" in node;
1369
+ let idleTimeout;
1370
+ let maxTimeout;
1371
+ let settled = false;
1372
+ const targetToken = peek$(ctx, "scrollingTo");
1373
+ const finish = () => {
1374
+ if (settled) return;
1375
+ settled = true;
1376
+ cleanup();
1377
+ if (targetToken === peek$(ctx, "scrollingTo")) {
1378
+ finishScrollTo(ctx, state);
1379
+ }
1380
+ };
1381
+ const onScroll2 = () => {
1382
+ if (idleTimeout) {
1383
+ clearTimeout(idleTimeout);
1384
+ }
1385
+ idleTimeout = setTimeout(finish, SCROLL_END_IDLE_MS);
1386
+ };
1387
+ const cleanup = () => {
1388
+ if (supportsScrollEnd) {
1389
+ node.removeEventListener("scrollend", finish);
1390
+ } else {
1391
+ node.removeEventListener("scroll", onScroll2);
1392
+ }
1393
+ if (idleTimeout) {
1394
+ clearTimeout(idleTimeout);
1395
+ }
1396
+ if (maxTimeout) {
1397
+ clearTimeout(maxTimeout);
1398
+ }
1399
+ };
1400
+ if (supportsScrollEnd) {
1401
+ node.addEventListener("scrollend", finish, { once: true });
1402
+ } else {
1403
+ node.addEventListener("scroll", onScroll2);
1404
+ idleTimeout = setTimeout(finish, SMOOTH_SCROLL_DURATION_MS);
1405
+ maxTimeout = setTimeout(finish, SCROLL_END_MAX_MS);
1406
+ }
1407
+ return cleanup;
1408
+ }
1409
+
1356
1410
  // src/core/scrollTo.ts
1357
1411
  function scrollTo(ctx, state, params) {
1358
- var _a3;
1359
1412
  const { noScrollingTo, ...scrollTarget } = params;
1360
1413
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
1361
1414
  const {
1362
- refScroller,
1363
1415
  props: { horizontal }
1364
1416
  } = state;
1365
1417
  let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
@@ -1373,22 +1425,9 @@ function scrollTo(ctx, state, params) {
1373
1425
  }
1374
1426
  state.scrollPending = offset;
1375
1427
  if (!isInitialScroll || Platform.OS === "android") {
1376
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1377
- animated: !!animated,
1378
- x: horizontal ? offset : 0,
1379
- y: horizontal ? 0 : offset
1380
- });
1381
- }
1382
- if (!animated) {
1428
+ doScrollTo(ctx, state, { animated, horizontal, isInitialScroll, offset });
1429
+ } else {
1383
1430
  state.scroll = offset;
1384
- {
1385
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1386
- if (value && peek$(ctx, "scrollingTo")) {
1387
- finishScrollTo(ctx, state);
1388
- unlisten();
1389
- }
1390
- });
1391
- }
1392
1431
  }
1393
1432
  }
1394
1433
 
@@ -1536,7 +1575,8 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1536
1575
  return;
1537
1576
  }
1538
1577
  }
1539
- if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1578
+ if (state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollLastCalculate) > 2) {
1579
+ state.scrollLastCalculate = state.scroll;
1540
1580
  state.ignoreScrollFromMVCPIgnored = false;
1541
1581
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1542
1582
  checkAtBottom(ctx, state);
@@ -2403,7 +2443,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2403
2443
  }
2404
2444
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2405
2445
  const scrollAdjustPad = scrollAdjustPending - topPad;
2406
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2446
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2407
2447
  if (scroll + scrollLength > totalSize) {
2408
2448
  scroll = Math.max(0, totalSize - scrollLength);
2409
2449
  }
@@ -2430,7 +2470,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2430
2470
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2431
2471
  if (!dataChanged && scrollForNextCalculateItemsInView) {
2432
2472
  const { top, bottom } = scrollForNextCalculateItemsInView;
2433
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2473
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2434
2474
  if (state.initialAnchor) {
2435
2475
  ensureInitialAnchor(ctx, state);
2436
2476
  }
@@ -2465,7 +2505,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2465
2505
  const top = positions.get(id);
2466
2506
  const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2467
2507
  const bottom = top + size;
2468
- if (bottom > scroll - scrollBuffer) {
2508
+ if (bottom > scroll - scrollBufferTop) {
2469
2509
  loopStart = i;
2470
2510
  } else {
2471
2511
  break;
@@ -2502,7 +2542,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2502
2542
  if (startBuffered === null && top + size > scrollTopBuffered) {
2503
2543
  startBuffered = i;
2504
2544
  startBufferedId = id;
2505
- nextTop = top;
2545
+ if (scrollTopBuffered < 0) {
2546
+ nextTop = null;
2547
+ } else {
2548
+ nextTop = top;
2549
+ }
2506
2550
  }
2507
2551
  if (startNoBuffer !== null) {
2508
2552
  if (top <= scrollBottom) {
@@ -2510,7 +2554,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2510
2554
  }
2511
2555
  if (top <= scrollBottomBuffered) {
2512
2556
  endBuffered = i;
2513
- nextBottom = top + size;
2557
+ if (scrollBottomBuffered > totalSize) {
2558
+ nextBottom = null;
2559
+ } else {
2560
+ nextBottom = top + size;
2561
+ }
2514
2562
  } else {
2515
2563
  foundEnd = true;
2516
2564
  }
@@ -3626,6 +3674,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3626
3674
  offset: initialContentOffset,
3627
3675
  precomputedWithViewOffset: true
3628
3676
  });
3677
+ {
3678
+ const unlisten = listen$(ctx, "containersDidLayout", (value) => {
3679
+ if (value && peek$(ctx, "scrollingTo")) {
3680
+ finishScrollTo(ctx, state);
3681
+ unlisten();
3682
+ }
3683
+ });
3684
+ }
3629
3685
  }
3630
3686
  }, [initialContentOffset]);
3631
3687
  const onLayoutChange = useCallback((layout) => {
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Dispatch, SetStateAction } from 'react';
3
- import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-YNdphn_A.mjs';
4
- export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-YNdphn_A.mjs';
3
+ import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-BWlIhlCl.mjs';
4
+ export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-BWlIhlCl.mjs';
5
5
  import 'react-native';
6
6
  import 'react-native-reanimated';
7
7
 
package/index.native.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Dispatch, SetStateAction } from 'react';
3
- import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-YNdphn_A.js';
4
- export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-YNdphn_A.js';
3
+ import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-BWlIhlCl.js';
4
+ export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, g as ScrollState, S as ScrollTarget, T as ThresholdSnapshot, m as TypedForwardRef, n as TypedMemo, i as ViewAmountToken, h as ViewToken, l as ViewabilityConfig, j as ViewabilityConfigCallbackPair, k as ViewabilityConfigCallbackPairs, e as ViewableRange, t as typedForwardRef, o as typedMemo } from './types-BWlIhlCl.js';
5
5
  import 'react-native';
6
6
  import 'react-native-reanimated';
7
7
 
package/index.native.js CHANGED
@@ -1074,15 +1074,44 @@ function finishScrollTo(ctx, state) {
1074
1074
  }
1075
1075
  }
1076
1076
  }
1077
+
1078
+ // src/core/doScrollTo.native.ts
1079
+ function doScrollTo(ctx, state, params) {
1080
+ var _a3;
1081
+ const { animated, horizontal, isInitialScroll, offset } = params;
1082
+ const { refScroller } = state;
1083
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1084
+ animated: !!animated,
1085
+ x: horizontal ? offset : 0,
1086
+ y: horizontal ? 0 : offset
1087
+ });
1088
+ if (!animated) {
1089
+ state.scroll = offset;
1090
+ const slowTimeout = isInitialScroll || !peek$(ctx, "containersDidLayout");
1091
+ setTimeout(
1092
+ () => {
1093
+ let numChecks = 0;
1094
+ const checkHasScrolled = () => {
1095
+ numChecks++;
1096
+ if (state.hasScrolled || numChecks > 5) {
1097
+ finishScrollTo(ctx, state);
1098
+ } else {
1099
+ setTimeout(checkHasScrolled, 100);
1100
+ }
1101
+ };
1102
+ checkHasScrolled();
1103
+ },
1104
+ slowTimeout ? 500 : 100
1105
+ );
1106
+ }
1107
+ }
1077
1108
  var Platform2 = reactNative.Platform;
1078
1109
 
1079
1110
  // src/core/scrollTo.ts
1080
1111
  function scrollTo(ctx, state, params) {
1081
- var _a3;
1082
1112
  const { noScrollingTo, ...scrollTarget } = params;
1083
1113
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
1084
1114
  const {
1085
- refScroller,
1086
1115
  props: { horizontal }
1087
1116
  } = state;
1088
1117
  let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
@@ -1096,39 +1125,9 @@ function scrollTo(ctx, state, params) {
1096
1125
  }
1097
1126
  state.scrollPending = offset;
1098
1127
  if (!isInitialScroll || Platform2.OS === "android") {
1099
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1100
- animated: !!animated,
1101
- x: horizontal ? offset : 0,
1102
- y: horizontal ? 0 : offset
1103
- });
1104
- }
1105
- if (!animated) {
1128
+ doScrollTo(ctx, state, { animated, horizontal, isInitialScroll, offset });
1129
+ } else {
1106
1130
  state.scroll = offset;
1107
- if (Platform2.OS === "web") {
1108
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1109
- if (value && peek$(ctx, "scrollingTo")) {
1110
- finishScrollTo(ctx, state);
1111
- unlisten();
1112
- }
1113
- });
1114
- } else {
1115
- const slowTimeout = isInitialScroll || !peek$(ctx, "containersDidLayout");
1116
- setTimeout(
1117
- () => {
1118
- let numChecks = 0;
1119
- const checkHasScrolled = () => {
1120
- numChecks++;
1121
- if (state.hasScrolled || numChecks > 5) {
1122
- finishScrollTo(ctx, state);
1123
- } else {
1124
- setTimeout(checkHasScrolled, 100);
1125
- }
1126
- };
1127
- checkHasScrolled();
1128
- },
1129
- slowTimeout ? 500 : 100
1130
- );
1131
- }
1132
1131
  }
1133
1132
  }
1134
1133
 
@@ -1276,7 +1275,8 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1276
1275
  return;
1277
1276
  }
1278
1277
  }
1279
- if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1278
+ if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollLastCalculate) > 2) {
1279
+ state.scrollLastCalculate = state.scroll;
1280
1280
  state.ignoreScrollFromMVCPIgnored = false;
1281
1281
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1282
1282
  checkAtBottom(ctx, state);
@@ -2187,7 +2187,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2187
2187
  }
2188
2188
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2189
2189
  const scrollAdjustPad = scrollAdjustPending - topPad;
2190
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2190
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2191
2191
  if (scroll + scrollLength > totalSize) {
2192
2192
  scroll = Math.max(0, totalSize - scrollLength);
2193
2193
  }
@@ -2214,7 +2214,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2214
2214
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2215
2215
  if (!dataChanged && scrollForNextCalculateItemsInView) {
2216
2216
  const { top, bottom } = scrollForNextCalculateItemsInView;
2217
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2217
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2218
2218
  if (state.initialAnchor) {
2219
2219
  ensureInitialAnchor(ctx, state);
2220
2220
  }
@@ -2249,7 +2249,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2249
2249
  const top = positions.get(id);
2250
2250
  const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2251
2251
  const bottom = top + size;
2252
- if (bottom > scroll - scrollBuffer) {
2252
+ if (bottom > scroll - scrollBufferTop) {
2253
2253
  loopStart = i;
2254
2254
  } else {
2255
2255
  break;
@@ -2286,7 +2286,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2286
2286
  if (startBuffered === null && top + size > scrollTopBuffered) {
2287
2287
  startBuffered = i;
2288
2288
  startBufferedId = id;
2289
- nextTop = top;
2289
+ if (scrollTopBuffered < 0) {
2290
+ nextTop = null;
2291
+ } else {
2292
+ nextTop = top;
2293
+ }
2290
2294
  }
2291
2295
  if (startNoBuffer !== null) {
2292
2296
  if (top <= scrollBottom) {
@@ -2294,7 +2298,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2294
2298
  }
2295
2299
  if (top <= scrollBottomBuffered) {
2296
2300
  endBuffered = i;
2297
- nextBottom = top + size;
2301
+ if (scrollBottomBuffered > totalSize) {
2302
+ nextBottom = null;
2303
+ } else {
2304
+ nextBottom = top + size;
2305
+ }
2298
2306
  } else {
2299
2307
  foundEnd = true;
2300
2308
  }
@@ -3431,6 +3439,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3431
3439
  offset: initialContentOffset,
3432
3440
  precomputedWithViewOffset: true
3433
3441
  });
3442
+ if (Platform2.OS === "web") {
3443
+ const unlisten = listen$(ctx, "containersDidLayout", (value) => {
3444
+ if (value && peek$(ctx, "scrollingTo")) {
3445
+ finishScrollTo(ctx, state);
3446
+ unlisten();
3447
+ }
3448
+ });
3449
+ }
3434
3450
  }
3435
3451
  }, [initialContentOffset]);
3436
3452
  const onLayoutChange = React2.useCallback((layout) => {