@legendapp/list 3.0.0-beta.10 → 3.0.0-beta.12

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.
@@ -411,9 +411,20 @@ function useInit(cb) {
411
411
 
412
412
  // src/state/ContextContainer.ts
413
413
  var ContextContainer = React2.createContext(null);
414
+ function useContextContainer() {
415
+ return React2.useContext(ContextContainer);
416
+ }
414
417
  function useIsLastItem() {
415
- const { itemKey } = React2.useContext(ContextContainer);
416
- const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
418
+ const containerContext = useContextContainer();
419
+ const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
420
+ if (containerContext) {
421
+ const { itemKey } = containerContext;
422
+ if (!isNullOrUndefined(itemKey)) {
423
+ return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
424
+ }
425
+ }
426
+ return false;
427
+ });
417
428
  return isLast;
418
429
  }
419
430
 
@@ -770,7 +781,6 @@ var ListComponent = typedMemo(function ListComponent2({
770
781
  getRenderedItem: getRenderedItem2,
771
782
  updateItemSize: updateItemSize2,
772
783
  refScrollView,
773
- maintainVisibleContentPosition,
774
784
  renderScrollComponent,
775
785
  scrollAdjustHandler,
776
786
  onLayoutHeader,
@@ -779,6 +789,7 @@ var ListComponent = typedMemo(function ListComponent2({
779
789
  ...rest
780
790
  }) {
781
791
  const ctx = useStateContext();
792
+ const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
782
793
  const ScrollComponent = renderScrollComponent ? React2.useMemo(
783
794
  () => React2__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
784
795
  [renderScrollComponent]
@@ -796,7 +807,7 @@ var ListComponent = typedMemo(function ListComponent2({
796
807
  ],
797
808
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
798
809
  horizontal,
799
- maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
810
+ maintainVisibleContentPosition: maintainVisibleContentPosition.scroll || maintainVisibleContentPosition.dataChanges ? { minIndexForVisible: 0 } : void 0,
800
811
  onLayout,
801
812
  onScroll: onScroll2,
802
813
  ref: refScrollView,
@@ -1067,7 +1078,7 @@ function checkFinishedScrollFrame(ctx) {
1067
1078
  if (scrollingTo) {
1068
1079
  const { state } = ctx;
1069
1080
  state.animFrameCheckFinishedScroll = void 0;
1070
- const scroll = state.scroll;
1081
+ const scroll = state.scrollPending;
1071
1082
  const adjust = state.scrollAdjustHandler.getAdjust();
1072
1083
  const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1073
1084
  const maxOffset = clampScrollOffset(ctx, scroll);
@@ -1422,14 +1433,16 @@ function ensureInitialAnchor(ctx) {
1422
1433
  function prepareMVCP(ctx, dataChanged) {
1423
1434
  const state = ctx.state;
1424
1435
  const { idsInView, positions, props } = state;
1425
- const { maintainVisibleContentPosition } = props;
1436
+ const {
1437
+ maintainVisibleContentPosition: { dataChanges: mvcpDataChanges, scroll: mvcpScroll }
1438
+ } = props;
1426
1439
  const scrollingTo = state.scrollingTo;
1427
1440
  let prevPosition;
1428
1441
  let targetId;
1429
1442
  const idsInViewWithPositions = [];
1430
1443
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1431
1444
  const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1432
- const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1445
+ const shouldMVCP = dataChanged ? mvcpDataChanges : mvcpScroll;
1433
1446
  const indexByKey = state.indexByKey;
1434
1447
  if (shouldMVCP) {
1435
1448
  if (scrollTarget !== void 0) {
@@ -1455,7 +1468,7 @@ function prepareMVCP(ctx, dataChanged) {
1455
1468
  }
1456
1469
  return () => {
1457
1470
  let positionDiff = 0;
1458
- if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1471
+ if (dataChanged && targetId === void 0 && mvcpDataChanges) {
1459
1472
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1460
1473
  const { id, position } = idsInViewWithPositions[i];
1461
1474
  const newPosition = positions.get(id);
@@ -1492,7 +1505,7 @@ function prepareMVCP(ctx, dataChanged) {
1492
1505
  }
1493
1506
  }
1494
1507
  if (Math.abs(positionDiff) > 0.1) {
1495
- requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1508
+ requestAdjust(ctx, positionDiff, dataChanged && mvcpDataChanges);
1496
1509
  }
1497
1510
  };
1498
1511
  }
@@ -1589,39 +1602,40 @@ function updateTotalSize(ctx) {
1589
1602
  // src/utils/getScrollVelocity.ts
1590
1603
  var getScrollVelocity = (state) => {
1591
1604
  const { scrollHistory } = state;
1592
- let velocity = 0;
1593
- if (scrollHistory.length >= 1) {
1594
- const newest = scrollHistory[scrollHistory.length - 1];
1595
- let oldest;
1596
- let start = 0;
1597
- const now = Date.now();
1598
- for (let i = 0; i < scrollHistory.length - 1; i++) {
1599
- const entry = scrollHistory[i];
1600
- const nextEntry = scrollHistory[i + 1];
1601
- if (i > 0) {
1602
- const prevEntry = scrollHistory[i - 1];
1603
- const prevDirection = entry.scroll - prevEntry.scroll;
1604
- const currentDirection = nextEntry.scroll - entry.scroll;
1605
- if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
1606
- start = i;
1607
- break;
1608
- }
1609
- }
1605
+ const newestIndex = scrollHistory.length - 1;
1606
+ if (newestIndex < 1) {
1607
+ return 0;
1608
+ }
1609
+ const newest = scrollHistory[newestIndex];
1610
+ const now = Date.now();
1611
+ let direction = 0;
1612
+ for (let i = newestIndex; i > 0; i--) {
1613
+ const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
1614
+ if (delta !== 0) {
1615
+ direction = Math.sign(delta);
1616
+ break;
1610
1617
  }
1611
- for (let i = start; i < scrollHistory.length - 1; i++) {
1612
- const entry = scrollHistory[i];
1613
- if (now - entry.time <= 1e3) {
1614
- oldest = entry;
1615
- break;
1616
- }
1618
+ }
1619
+ if (direction === 0) {
1620
+ return 0;
1621
+ }
1622
+ let oldest = newest;
1623
+ for (let i = newestIndex - 1; i >= 0; i--) {
1624
+ const current = scrollHistory[i];
1625
+ const next = scrollHistory[i + 1];
1626
+ const delta = next.scroll - current.scroll;
1627
+ const deltaSign = Math.sign(delta);
1628
+ if (deltaSign !== 0 && deltaSign !== direction) {
1629
+ break;
1617
1630
  }
1618
- if (oldest && oldest !== newest) {
1619
- const scrollDiff = newest.scroll - oldest.scroll;
1620
- const timeDiff = newest.time - oldest.time;
1621
- velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
1631
+ if (now - current.time > 1e3) {
1632
+ break;
1622
1633
  }
1634
+ oldest = current;
1623
1635
  }
1624
- return velocity;
1636
+ const scrollDiff = newest.scroll - oldest.scroll;
1637
+ const timeDiff = newest.time - oldest.time;
1638
+ return timeDiff > 0 ? scrollDiff / timeDiff : 0;
1625
1639
  };
1626
1640
 
1627
1641
  // src/utils/updateSnapToOffsets.ts
@@ -2780,7 +2794,6 @@ function onScroll(ctx, event) {
2780
2794
  return;
2781
2795
  }
2782
2796
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2783
- state.scrollPending = newScroll;
2784
2797
  if (state.scrollingTo) {
2785
2798
  const maxOffset = clampScrollOffset(ctx, newScroll);
2786
2799
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -2794,8 +2807,11 @@ function onScroll(ctx, event) {
2794
2807
  return;
2795
2808
  }
2796
2809
  }
2810
+ state.scrollPending = newScroll;
2797
2811
  updateScroll(ctx, newScroll);
2798
- checkFinishedScroll(ctx);
2812
+ if (state.scrollingTo) {
2813
+ checkFinishedScroll(ctx);
2814
+ }
2799
2815
  onScrollProp == null ? void 0 : onScrollProp(event);
2800
2816
  }
2801
2817
 
@@ -3149,6 +3165,24 @@ function getRenderedItem(ctx, key) {
3149
3165
  }
3150
3166
  return { index, item: data[index], renderedItem };
3151
3167
  }
3168
+
3169
+ // src/utils/normalizeMaintainVisibleContentPosition.ts
3170
+ function normalizeMaintainVisibleContentPosition(value) {
3171
+ var _a3, _b;
3172
+ if (value === true) {
3173
+ return { dataChanges: true, scroll: true };
3174
+ }
3175
+ if (value && typeof value === "object") {
3176
+ return {
3177
+ dataChanges: (_a3 = value.dataChanges) != null ? _a3 : false,
3178
+ scroll: (_b = value.scroll) != null ? _b : true
3179
+ };
3180
+ }
3181
+ if (value === false) {
3182
+ return { dataChanges: false, scroll: false };
3183
+ }
3184
+ return { dataChanges: false, scroll: true };
3185
+ }
3152
3186
  function useThrottleDebounce(mode) {
3153
3187
  const timeoutRef = React2.useRef(null);
3154
3188
  const lastCallTimeRef = React2.useRef(0);
@@ -3243,7 +3277,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3243
3277
  ListHeaderComponent,
3244
3278
  maintainScrollAtEnd = false,
3245
3279
  maintainScrollAtEndThreshold = 0.1,
3246
- maintainVisibleContentPosition = false,
3280
+ maintainVisibleContentPosition: maintainVisibleContentPositionProp,
3247
3281
  numColumns: numColumnsProp = 1,
3248
3282
  onEndReached,
3249
3283
  onEndReachedThreshold = 0.5,
@@ -3281,6 +3315,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3281
3315
  const style = { ...StyleSheet.flatten(styleProp) };
3282
3316
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
3283
3317
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
3318
+ const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
3319
+ maintainVisibleContentPositionProp
3320
+ );
3284
3321
  const [renderNum, setRenderNum] = React2.useState(0);
3285
3322
  const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
3286
3323
  const [canRender, setCanRender] = React2__namespace.useState(!IsNewArchitecture);
@@ -3365,7 +3402,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3365
3402
  };
3366
3403
  const internalState = ctx.state;
3367
3404
  internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3368
- set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3405
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
3369
3406
  set$(ctx, "extraData", extraData);
3370
3407
  }
3371
3408
  refState.current = ctx.state;
@@ -3396,7 +3433,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3396
3433
  keyExtractor,
3397
3434
  maintainScrollAtEnd,
3398
3435
  maintainScrollAtEndThreshold,
3399
- maintainVisibleContentPosition,
3436
+ maintainVisibleContentPosition: maintainVisibleContentPositionConfig,
3400
3437
  numColumns: numColumnsProp,
3401
3438
  onEndReached,
3402
3439
  onEndReachedThreshold,
@@ -3431,7 +3468,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3431
3468
  setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3432
3469
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3433
3470
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3434
- if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3471
+ if (maintainVisibleContentPositionConfig.scroll && paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3435
3472
  if (state.scroll < 0) {
3436
3473
  paddingDiff += state.scroll;
3437
3474
  }
@@ -3476,7 +3513,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3476
3513
  value = 0;
3477
3514
  }
3478
3515
  if (!value) {
3479
- state.didFinishInitialScroll = true;
3516
+ setInitialRenderState(ctx, { didInitialScroll: true });
3480
3517
  }
3481
3518
  return value;
3482
3519
  }, [renderNum]);
@@ -3605,7 +3642,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3605
3642
  initialContentOffset,
3606
3643
  ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
3607
3644
  ListHeaderComponent,
3608
- maintainVisibleContentPosition,
3609
3645
  onLayout,
3610
3646
  onLayoutHeader,
3611
3647
  onMomentumScrollEnd: fns.onMomentumScrollEnd,
@@ -390,9 +390,20 @@ function useInit(cb) {
390
390
 
391
391
  // src/state/ContextContainer.ts
392
392
  var ContextContainer = createContext(null);
393
+ function useContextContainer() {
394
+ return useContext(ContextContainer);
395
+ }
393
396
  function useIsLastItem() {
394
- const { itemKey } = useContext(ContextContainer);
395
- const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
397
+ const containerContext = useContextContainer();
398
+ const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
399
+ if (containerContext) {
400
+ const { itemKey } = containerContext;
401
+ if (!isNullOrUndefined(itemKey)) {
402
+ return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
403
+ }
404
+ }
405
+ return false;
406
+ });
396
407
  return isLast;
397
408
  }
398
409
 
@@ -749,7 +760,6 @@ var ListComponent = typedMemo(function ListComponent2({
749
760
  getRenderedItem: getRenderedItem2,
750
761
  updateItemSize: updateItemSize2,
751
762
  refScrollView,
752
- maintainVisibleContentPosition,
753
763
  renderScrollComponent,
754
764
  scrollAdjustHandler,
755
765
  onLayoutHeader,
@@ -758,6 +768,7 @@ var ListComponent = typedMemo(function ListComponent2({
758
768
  ...rest
759
769
  }) {
760
770
  const ctx = useStateContext();
771
+ const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
761
772
  const ScrollComponent = renderScrollComponent ? useMemo(
762
773
  () => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
763
774
  [renderScrollComponent]
@@ -775,7 +786,7 @@ var ListComponent = typedMemo(function ListComponent2({
775
786
  ],
776
787
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
777
788
  horizontal,
778
- maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
789
+ maintainVisibleContentPosition: maintainVisibleContentPosition.scroll || maintainVisibleContentPosition.dataChanges ? { minIndexForVisible: 0 } : void 0,
779
790
  onLayout,
780
791
  onScroll: onScroll2,
781
792
  ref: refScrollView,
@@ -1046,7 +1057,7 @@ function checkFinishedScrollFrame(ctx) {
1046
1057
  if (scrollingTo) {
1047
1058
  const { state } = ctx;
1048
1059
  state.animFrameCheckFinishedScroll = void 0;
1049
- const scroll = state.scroll;
1060
+ const scroll = state.scrollPending;
1050
1061
  const adjust = state.scrollAdjustHandler.getAdjust();
1051
1062
  const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1052
1063
  const maxOffset = clampScrollOffset(ctx, scroll);
@@ -1401,14 +1412,16 @@ function ensureInitialAnchor(ctx) {
1401
1412
  function prepareMVCP(ctx, dataChanged) {
1402
1413
  const state = ctx.state;
1403
1414
  const { idsInView, positions, props } = state;
1404
- const { maintainVisibleContentPosition } = props;
1415
+ const {
1416
+ maintainVisibleContentPosition: { dataChanges: mvcpDataChanges, scroll: mvcpScroll }
1417
+ } = props;
1405
1418
  const scrollingTo = state.scrollingTo;
1406
1419
  let prevPosition;
1407
1420
  let targetId;
1408
1421
  const idsInViewWithPositions = [];
1409
1422
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1410
1423
  const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1411
- const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1424
+ const shouldMVCP = dataChanged ? mvcpDataChanges : mvcpScroll;
1412
1425
  const indexByKey = state.indexByKey;
1413
1426
  if (shouldMVCP) {
1414
1427
  if (scrollTarget !== void 0) {
@@ -1434,7 +1447,7 @@ function prepareMVCP(ctx, dataChanged) {
1434
1447
  }
1435
1448
  return () => {
1436
1449
  let positionDiff = 0;
1437
- if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1450
+ if (dataChanged && targetId === void 0 && mvcpDataChanges) {
1438
1451
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1439
1452
  const { id, position } = idsInViewWithPositions[i];
1440
1453
  const newPosition = positions.get(id);
@@ -1471,7 +1484,7 @@ function prepareMVCP(ctx, dataChanged) {
1471
1484
  }
1472
1485
  }
1473
1486
  if (Math.abs(positionDiff) > 0.1) {
1474
- requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1487
+ requestAdjust(ctx, positionDiff, dataChanged && mvcpDataChanges);
1475
1488
  }
1476
1489
  };
1477
1490
  }
@@ -1568,39 +1581,40 @@ function updateTotalSize(ctx) {
1568
1581
  // src/utils/getScrollVelocity.ts
1569
1582
  var getScrollVelocity = (state) => {
1570
1583
  const { scrollHistory } = state;
1571
- let velocity = 0;
1572
- if (scrollHistory.length >= 1) {
1573
- const newest = scrollHistory[scrollHistory.length - 1];
1574
- let oldest;
1575
- let start = 0;
1576
- const now = Date.now();
1577
- for (let i = 0; i < scrollHistory.length - 1; i++) {
1578
- const entry = scrollHistory[i];
1579
- const nextEntry = scrollHistory[i + 1];
1580
- if (i > 0) {
1581
- const prevEntry = scrollHistory[i - 1];
1582
- const prevDirection = entry.scroll - prevEntry.scroll;
1583
- const currentDirection = nextEntry.scroll - entry.scroll;
1584
- if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
1585
- start = i;
1586
- break;
1587
- }
1588
- }
1584
+ const newestIndex = scrollHistory.length - 1;
1585
+ if (newestIndex < 1) {
1586
+ return 0;
1587
+ }
1588
+ const newest = scrollHistory[newestIndex];
1589
+ const now = Date.now();
1590
+ let direction = 0;
1591
+ for (let i = newestIndex; i > 0; i--) {
1592
+ const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
1593
+ if (delta !== 0) {
1594
+ direction = Math.sign(delta);
1595
+ break;
1589
1596
  }
1590
- for (let i = start; i < scrollHistory.length - 1; i++) {
1591
- const entry = scrollHistory[i];
1592
- if (now - entry.time <= 1e3) {
1593
- oldest = entry;
1594
- break;
1595
- }
1597
+ }
1598
+ if (direction === 0) {
1599
+ return 0;
1600
+ }
1601
+ let oldest = newest;
1602
+ for (let i = newestIndex - 1; i >= 0; i--) {
1603
+ const current = scrollHistory[i];
1604
+ const next = scrollHistory[i + 1];
1605
+ const delta = next.scroll - current.scroll;
1606
+ const deltaSign = Math.sign(delta);
1607
+ if (deltaSign !== 0 && deltaSign !== direction) {
1608
+ break;
1596
1609
  }
1597
- if (oldest && oldest !== newest) {
1598
- const scrollDiff = newest.scroll - oldest.scroll;
1599
- const timeDiff = newest.time - oldest.time;
1600
- velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
1610
+ if (now - current.time > 1e3) {
1611
+ break;
1601
1612
  }
1613
+ oldest = current;
1602
1614
  }
1603
- return velocity;
1615
+ const scrollDiff = newest.scroll - oldest.scroll;
1616
+ const timeDiff = newest.time - oldest.time;
1617
+ return timeDiff > 0 ? scrollDiff / timeDiff : 0;
1604
1618
  };
1605
1619
 
1606
1620
  // src/utils/updateSnapToOffsets.ts
@@ -2759,7 +2773,6 @@ function onScroll(ctx, event) {
2759
2773
  return;
2760
2774
  }
2761
2775
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2762
- state.scrollPending = newScroll;
2763
2776
  if (state.scrollingTo) {
2764
2777
  const maxOffset = clampScrollOffset(ctx, newScroll);
2765
2778
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -2773,8 +2786,11 @@ function onScroll(ctx, event) {
2773
2786
  return;
2774
2787
  }
2775
2788
  }
2789
+ state.scrollPending = newScroll;
2776
2790
  updateScroll(ctx, newScroll);
2777
- checkFinishedScroll(ctx);
2791
+ if (state.scrollingTo) {
2792
+ checkFinishedScroll(ctx);
2793
+ }
2778
2794
  onScrollProp == null ? void 0 : onScrollProp(event);
2779
2795
  }
2780
2796
 
@@ -3128,6 +3144,24 @@ function getRenderedItem(ctx, key) {
3128
3144
  }
3129
3145
  return { index, item: data[index], renderedItem };
3130
3146
  }
3147
+
3148
+ // src/utils/normalizeMaintainVisibleContentPosition.ts
3149
+ function normalizeMaintainVisibleContentPosition(value) {
3150
+ var _a3, _b;
3151
+ if (value === true) {
3152
+ return { dataChanges: true, scroll: true };
3153
+ }
3154
+ if (value && typeof value === "object") {
3155
+ return {
3156
+ dataChanges: (_a3 = value.dataChanges) != null ? _a3 : false,
3157
+ scroll: (_b = value.scroll) != null ? _b : true
3158
+ };
3159
+ }
3160
+ if (value === false) {
3161
+ return { dataChanges: false, scroll: false };
3162
+ }
3163
+ return { dataChanges: false, scroll: true };
3164
+ }
3131
3165
  function useThrottleDebounce(mode) {
3132
3166
  const timeoutRef = useRef(null);
3133
3167
  const lastCallTimeRef = useRef(0);
@@ -3222,7 +3256,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3222
3256
  ListHeaderComponent,
3223
3257
  maintainScrollAtEnd = false,
3224
3258
  maintainScrollAtEndThreshold = 0.1,
3225
- maintainVisibleContentPosition = false,
3259
+ maintainVisibleContentPosition: maintainVisibleContentPositionProp,
3226
3260
  numColumns: numColumnsProp = 1,
3227
3261
  onEndReached,
3228
3262
  onEndReachedThreshold = 0.5,
@@ -3260,6 +3294,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3260
3294
  const style = { ...StyleSheet.flatten(styleProp) };
3261
3295
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
3262
3296
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
3297
+ const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
3298
+ maintainVisibleContentPositionProp
3299
+ );
3263
3300
  const [renderNum, setRenderNum] = useState(0);
3264
3301
  const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
3265
3302
  const [canRender, setCanRender] = React2.useState(!IsNewArchitecture);
@@ -3344,7 +3381,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3344
3381
  };
3345
3382
  const internalState = ctx.state;
3346
3383
  internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3347
- set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3384
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
3348
3385
  set$(ctx, "extraData", extraData);
3349
3386
  }
3350
3387
  refState.current = ctx.state;
@@ -3375,7 +3412,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3375
3412
  keyExtractor,
3376
3413
  maintainScrollAtEnd,
3377
3414
  maintainScrollAtEndThreshold,
3378
- maintainVisibleContentPosition,
3415
+ maintainVisibleContentPosition: maintainVisibleContentPositionConfig,
3379
3416
  numColumns: numColumnsProp,
3380
3417
  onEndReached,
3381
3418
  onEndReachedThreshold,
@@ -3410,7 +3447,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3410
3447
  setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3411
3448
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3412
3449
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3413
- if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3450
+ if (maintainVisibleContentPositionConfig.scroll && paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3414
3451
  if (state.scroll < 0) {
3415
3452
  paddingDiff += state.scroll;
3416
3453
  }
@@ -3455,7 +3492,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3455
3492
  value = 0;
3456
3493
  }
3457
3494
  if (!value) {
3458
- state.didFinishInitialScroll = true;
3495
+ setInitialRenderState(ctx, { didInitialScroll: true });
3459
3496
  }
3460
3497
  return value;
3461
3498
  }, [renderNum]);
@@ -3584,7 +3621,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3584
3621
  initialContentOffset,
3585
3622
  ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
3586
3623
  ListHeaderComponent,
3587
- maintainVisibleContentPosition,
3588
3624
  onLayout,
3589
3625
  onLayoutHeader,
3590
3626
  onMomentumScrollEnd: fns.onMomentumScrollEnd,
@@ -18,7 +18,7 @@ type ListenerTypeValueMap = {
18
18
  headerSize: number;
19
19
  lastItemKeys: string[];
20
20
  lastPositionUpdate: number;
21
- maintainVisibleContentPosition: boolean;
21
+ maintainVisibleContentPosition: MaintainVisibleContentPositionNormalized;
22
22
  numColumns: number;
23
23
  numContainers: number;
24
24
  numContainersPooled: number;
@@ -221,11 +221,13 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
221
221
  */
222
222
  maintainScrollAtEndThreshold?: number;
223
223
  /**
224
- * If true, maintains visibility of content across data changes (filtering/resorting/insertions).
225
- * Scroll-time stability for measurements is always enabled.
226
- * @default false
224
+ * Maintains visibility of content.
225
+ * - scroll (default: true) stabilizes during size/layout changes while scrolling.
226
+ * - dataChanges (default: false) stabilizes when the data array changes; passing true also sets the RN maintainVisibleContentPosition prop.
227
+ * - undefined (default) enables scroll stabilization but skips data-change anchoring.
228
+ * - true enables both behaviors; false disables both.
227
229
  */
228
- maintainVisibleContentPosition?: boolean;
230
+ maintainVisibleContentPosition?: boolean | MaintainVisibleContentPositionConfig;
229
231
  /**
230
232
  * Number of columns to render items in.
231
233
  * @default 1
@@ -343,6 +345,14 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
343
345
  itemsAreEqual?: (itemPrevious: ItemT, item: ItemT, index: number, data: readonly ItemT[]) => boolean;
344
346
  }
345
347
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView> | ComponentProps<typeof Reanimated.ScrollView>, TItemType extends string | undefined = string | undefined> = BaseScrollViewProps<TScrollView> & LegendListSpecificProps<ItemT, TItemType> & (DataModeProps<ItemT, TItemType> | ChildrenModeProps);
348
+ interface MaintainVisibleContentPositionConfig {
349
+ dataChanges?: boolean;
350
+ scroll?: boolean;
351
+ }
352
+ interface MaintainVisibleContentPositionNormalized {
353
+ dataChanges: boolean;
354
+ scroll: boolean;
355
+ }
346
356
  interface MaintainScrollAtEndOptions {
347
357
  onLayout?: boolean;
348
358
  onItemLayout?: boolean;
@@ -476,7 +486,7 @@ interface InternalState {
476
486
  keyExtractor: LegendListProps["keyExtractor"];
477
487
  maintainScrollAtEnd: boolean | MaintainScrollAtEndOptions;
478
488
  maintainScrollAtEndThreshold: number | undefined;
479
- maintainVisibleContentPosition: boolean;
489
+ maintainVisibleContentPosition: MaintainVisibleContentPositionNormalized;
480
490
  numColumns: number;
481
491
  onEndReached: LegendListProps["onEndReached"];
482
492
  onEndReachedThreshold: number | null | undefined;
@@ -721,4 +731,4 @@ type GetRenderedItemResult<ItemT> = {
721
731
  };
722
732
  type GetRenderedItem = (key: string) => GetRenderedItemResult<any> | null;
723
733
 
724
- export { type ColumnWrapperStyle as C, type GetRenderedItemResult as G, type InternalState as I, type LegendListProps as L, type MaintainScrollAtEndOptions as M, type OnViewableItemsChanged as O, type ScrollTarget as S, type ThresholdSnapshot as T, type ViewabilityCallback as V, type LegendListRef as a, type ViewabilityAmountCallback as b, type LegendListRecyclingState as c, type LegendListPropsBase as d, type ViewableRange as e, type LegendListRenderItemProps as f, type LegendListState as g, type ViewToken as h, type ViewAmountToken as i, type ViewabilityConfigCallbackPair as j, type ViewabilityConfigCallbackPairs as k, type ViewabilityConfig as l, type TypedForwardRef as m, type TypedMemo as n, typedMemo as o, type ScrollIndexWithOffset as p, type ScrollIndexWithOffsetPosition as q, type ScrollIndexWithOffsetAndContentOffset as r, type InitialScrollAnchor as s, typedForwardRef as t, type GetRenderedItem as u };
734
+ export { type ColumnWrapperStyle as C, type GetRenderedItemResult as G, type InternalState as I, type LegendListProps as L, type MaintainVisibleContentPositionConfig as M, type OnViewableItemsChanged as O, type ScrollTarget as S, type ThresholdSnapshot as T, type ViewabilityCallback as V, type LegendListRef as a, type ViewabilityAmountCallback as b, type LegendListRecyclingState as c, type LegendListPropsBase as d, type MaintainVisibleContentPositionNormalized as e, type MaintainScrollAtEndOptions as f, type ViewableRange as g, type LegendListRenderItemProps as h, type LegendListState as i, type ViewToken as j, type ViewAmountToken as k, type ViewabilityConfigCallbackPair as l, type ViewabilityConfigCallbackPairs as m, type ViewabilityConfig as n, type TypedForwardRef as o, type TypedMemo as p, typedMemo as q, type ScrollIndexWithOffset as r, type ScrollIndexWithOffsetPosition as s, typedForwardRef as t, type ScrollIndexWithOffsetAndContentOffset as u, type InitialScrollAnchor as v, type GetRenderedItem as w };
@@ -18,7 +18,7 @@ type ListenerTypeValueMap = {
18
18
  headerSize: number;
19
19
  lastItemKeys: string[];
20
20
  lastPositionUpdate: number;
21
- maintainVisibleContentPosition: boolean;
21
+ maintainVisibleContentPosition: MaintainVisibleContentPositionNormalized;
22
22
  numColumns: number;
23
23
  numContainers: number;
24
24
  numContainersPooled: number;
@@ -221,11 +221,13 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
221
221
  */
222
222
  maintainScrollAtEndThreshold?: number;
223
223
  /**
224
- * If true, maintains visibility of content across data changes (filtering/resorting/insertions).
225
- * Scroll-time stability for measurements is always enabled.
226
- * @default false
224
+ * Maintains visibility of content.
225
+ * - scroll (default: true) stabilizes during size/layout changes while scrolling.
226
+ * - dataChanges (default: false) stabilizes when the data array changes; passing true also sets the RN maintainVisibleContentPosition prop.
227
+ * - undefined (default) enables scroll stabilization but skips data-change anchoring.
228
+ * - true enables both behaviors; false disables both.
227
229
  */
228
- maintainVisibleContentPosition?: boolean;
230
+ maintainVisibleContentPosition?: boolean | MaintainVisibleContentPositionConfig;
229
231
  /**
230
232
  * Number of columns to render items in.
231
233
  * @default 1
@@ -343,6 +345,14 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
343
345
  itemsAreEqual?: (itemPrevious: ItemT, item: ItemT, index: number, data: readonly ItemT[]) => boolean;
344
346
  }
345
347
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView> | ComponentProps<typeof Reanimated.ScrollView>, TItemType extends string | undefined = string | undefined> = BaseScrollViewProps<TScrollView> & LegendListSpecificProps<ItemT, TItemType> & (DataModeProps<ItemT, TItemType> | ChildrenModeProps);
348
+ interface MaintainVisibleContentPositionConfig {
349
+ dataChanges?: boolean;
350
+ scroll?: boolean;
351
+ }
352
+ interface MaintainVisibleContentPositionNormalized {
353
+ dataChanges: boolean;
354
+ scroll: boolean;
355
+ }
346
356
  interface MaintainScrollAtEndOptions {
347
357
  onLayout?: boolean;
348
358
  onItemLayout?: boolean;
@@ -476,7 +486,7 @@ interface InternalState {
476
486
  keyExtractor: LegendListProps["keyExtractor"];
477
487
  maintainScrollAtEnd: boolean | MaintainScrollAtEndOptions;
478
488
  maintainScrollAtEndThreshold: number | undefined;
479
- maintainVisibleContentPosition: boolean;
489
+ maintainVisibleContentPosition: MaintainVisibleContentPositionNormalized;
480
490
  numColumns: number;
481
491
  onEndReached: LegendListProps["onEndReached"];
482
492
  onEndReachedThreshold: number | null | undefined;
@@ -721,4 +731,4 @@ type GetRenderedItemResult<ItemT> = {
721
731
  };
722
732
  type GetRenderedItem = (key: string) => GetRenderedItemResult<any> | null;
723
733
 
724
- export { type ColumnWrapperStyle as C, type GetRenderedItemResult as G, type InternalState as I, type LegendListProps as L, type MaintainScrollAtEndOptions as M, type OnViewableItemsChanged as O, type ScrollTarget as S, type ThresholdSnapshot as T, type ViewabilityCallback as V, type LegendListRef as a, type ViewabilityAmountCallback as b, type LegendListRecyclingState as c, type LegendListPropsBase as d, type ViewableRange as e, type LegendListRenderItemProps as f, type LegendListState as g, type ViewToken as h, type ViewAmountToken as i, type ViewabilityConfigCallbackPair as j, type ViewabilityConfigCallbackPairs as k, type ViewabilityConfig as l, type TypedForwardRef as m, type TypedMemo as n, typedMemo as o, type ScrollIndexWithOffset as p, type ScrollIndexWithOffsetPosition as q, type ScrollIndexWithOffsetAndContentOffset as r, type InitialScrollAnchor as s, typedForwardRef as t, type GetRenderedItem as u };
734
+ export { type ColumnWrapperStyle as C, type GetRenderedItemResult as G, type InternalState as I, type LegendListProps as L, type MaintainVisibleContentPositionConfig as M, type OnViewableItemsChanged as O, type ScrollTarget as S, type ThresholdSnapshot as T, type ViewabilityCallback as V, type LegendListRef as a, type ViewabilityAmountCallback as b, type LegendListRecyclingState as c, type LegendListPropsBase as d, type MaintainVisibleContentPositionNormalized as e, type MaintainScrollAtEndOptions as f, type ViewableRange as g, type LegendListRenderItemProps as h, type LegendListState as i, type ViewToken as j, type ViewAmountToken as k, type ViewabilityConfigCallbackPair as l, type ViewabilityConfigCallbackPairs as m, type ViewabilityConfig as n, type TypedForwardRef as o, type TypedMemo as p, typedMemo as q, type ScrollIndexWithOffset as r, type ScrollIndexWithOffsetPosition as s, typedForwardRef as t, type ScrollIndexWithOffsetAndContentOffset as u, type InitialScrollAnchor as v, type GetRenderedItem as w };