@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.
package/README.md CHANGED
@@ -27,6 +27,7 @@ Beyond standard `FlatList` capabilities:
27
27
  * `true`: Reuses item components for optimal performance. Be cautious if your item components contain local state, as it might be reused unexpectedly.
28
28
  * `false` (default): Creates new item components every time. Less performant but safer if items have complex internal state.
29
29
  * `maintainScrollAtEnd`: (boolean) If `true` and the user is scrolled near the bottom (within `maintainScrollAtEndThreshold * screen height`), the list automatically scrolls to the end when items are added or heights change. Useful for chat interfaces.
30
+ * `maintainVisibleContentPosition`: Keeps visible content steady during size/layout changes while scrolling (default). Pass `true` or `{ dataChanges: true }` to also anchor during data updates; pass `false` to disable; pass `{ scroll: false }` to opt out of scroll-time stabilization.
30
31
  * `alignItemsAtEnd`: (boolean) Useful for chat UIs, content smaller than the View will be aligned to the bottom of the list.
31
32
 
32
33
  ---
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-1Hgg1rTO.mjs';
4
- export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, g as LegendListState, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, 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-1Hgg1rTO.mjs';
3
+ import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-C83aU7VI.mjs';
4
+ export { C as ColumnWrapperStyle, w as GetRenderedItem, G as GetRenderedItemResult, v as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, h as LegendListRenderItemProps, i as LegendListState, f as MaintainScrollAtEndOptions, M as MaintainVisibleContentPositionConfig, e as MaintainVisibleContentPositionNormalized, O as OnViewableItemsChanged, r as ScrollIndexWithOffset, u as ScrollIndexWithOffsetAndContentOffset, s as ScrollIndexWithOffsetPosition, S as ScrollTarget, T as ThresholdSnapshot, o as TypedForwardRef, p as TypedMemo, k as ViewAmountToken, j as ViewToken, n as ViewabilityConfig, l as ViewabilityConfigCallbackPair, m as ViewabilityConfigCallbackPairs, g as ViewableRange, t as typedForwardRef, q as typedMemo } from './types-C83aU7VI.mjs';
5
5
  import 'react-native';
6
6
  import 'react-native-reanimated';
7
7
 
@@ -12,7 +12,7 @@ declare const LegendList: (<T>(props: LegendListProps<T> & React.RefAttributes<L
12
12
  declare function useViewability<ItemT = any>(callback: ViewabilityCallback<ItemT>, configId?: string): void;
13
13
  declare function useViewabilityAmount<ItemT = any>(callback: ViewabilityAmountCallback<ItemT>): void;
14
14
  declare function useRecyclingEffect(effect: (info: LegendListRecyclingState<unknown>) => void | (() => void)): void;
15
- declare function useRecyclingState<ItemT>(valueOrFun: ((info: LegendListRecyclingState<ItemT>) => ItemT) | ItemT): readonly [ItemT | null, Dispatch<SetStateAction<ItemT>>];
15
+ declare function useRecyclingState<ItemT>(valueOrFun: ((info: LegendListRecyclingState<ItemT>) => ItemT) | ItemT): readonly [ItemT, Dispatch<SetStateAction<ItemT>>];
16
16
  declare function useIsLastItem(): boolean;
17
17
  declare function useListScrollSize(): {
18
18
  width: number;
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-1Hgg1rTO.js';
4
- export { C as ColumnWrapperStyle, u as GetRenderedItem, G as GetRenderedItemResult, s as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, f as LegendListRenderItemProps, g as LegendListState, M as MaintainScrollAtEndOptions, O as OnViewableItemsChanged, p as ScrollIndexWithOffset, r as ScrollIndexWithOffsetAndContentOffset, q as ScrollIndexWithOffsetPosition, 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-1Hgg1rTO.js';
3
+ import { L as LegendListProps, a as LegendListRef, V as ViewabilityCallback, b as ViewabilityAmountCallback, c as LegendListRecyclingState } from './types-C83aU7VI.js';
4
+ export { C as ColumnWrapperStyle, w as GetRenderedItem, G as GetRenderedItemResult, v as InitialScrollAnchor, I as InternalState, d as LegendListPropsBase, h as LegendListRenderItemProps, i as LegendListState, f as MaintainScrollAtEndOptions, M as MaintainVisibleContentPositionConfig, e as MaintainVisibleContentPositionNormalized, O as OnViewableItemsChanged, r as ScrollIndexWithOffset, u as ScrollIndexWithOffsetAndContentOffset, s as ScrollIndexWithOffsetPosition, S as ScrollTarget, T as ThresholdSnapshot, o as TypedForwardRef, p as TypedMemo, k as ViewAmountToken, j as ViewToken, n as ViewabilityConfig, l as ViewabilityConfigCallbackPair, m as ViewabilityConfigCallbackPairs, g as ViewableRange, t as typedForwardRef, q as typedMemo } from './types-C83aU7VI.js';
5
5
  import 'react-native';
6
6
  import 'react-native-reanimated';
7
7
 
@@ -12,7 +12,7 @@ declare const LegendList: (<T>(props: LegendListProps<T> & React.RefAttributes<L
12
12
  declare function useViewability<ItemT = any>(callback: ViewabilityCallback<ItemT>, configId?: string): void;
13
13
  declare function useViewabilityAmount<ItemT = any>(callback: ViewabilityAmountCallback<ItemT>): void;
14
14
  declare function useRecyclingEffect(effect: (info: LegendListRecyclingState<unknown>) => void | (() => void)): void;
15
- declare function useRecyclingState<ItemT>(valueOrFun: ((info: LegendListRecyclingState<ItemT>) => ItemT) | ItemT): readonly [ItemT | null, Dispatch<SetStateAction<ItemT>>];
15
+ declare function useRecyclingState<ItemT>(valueOrFun: ((info: LegendListRecyclingState<ItemT>) => ItemT) | ItemT): readonly [ItemT, Dispatch<SetStateAction<ItemT>>];
16
16
  declare function useIsLastItem(): boolean;
17
17
  declare function useListScrollSize(): {
18
18
  width: number;
package/index.js CHANGED
@@ -367,48 +367,70 @@ function useInit(cb) {
367
367
 
368
368
  // src/state/ContextContainer.ts
369
369
  var ContextContainer = React3.createContext(null);
370
+ function useContextContainer() {
371
+ return React3.useContext(ContextContainer);
372
+ }
370
373
  function useViewability(callback, configId) {
371
374
  const ctx = useStateContext();
372
- const { containerId } = React3.useContext(ContextContainer);
373
- const key = containerId + (configId != null ? configId : "");
375
+ const containerContext = useContextContainer();
374
376
  useInit(() => {
377
+ if (!containerContext) {
378
+ return;
379
+ }
380
+ const { containerId } = containerContext;
381
+ const key = containerId + (configId != null ? configId : "");
375
382
  const value = ctx.mapViewabilityValues.get(key);
376
383
  if (value) {
377
384
  callback(value);
378
385
  }
379
386
  });
380
- ctx.mapViewabilityCallbacks.set(key, callback);
381
- React3.useEffect(
382
- () => () => {
387
+ React3.useEffect(() => {
388
+ if (!containerContext) {
389
+ return;
390
+ }
391
+ const { containerId } = containerContext;
392
+ const key = containerId + (configId != null ? configId : "");
393
+ ctx.mapViewabilityCallbacks.set(key, callback);
394
+ return () => {
383
395
  ctx.mapViewabilityCallbacks.delete(key);
384
- },
385
- []
386
- );
396
+ };
397
+ }, [ctx, callback, configId, containerContext]);
387
398
  }
388
399
  function useViewabilityAmount(callback) {
389
400
  const ctx = useStateContext();
390
- const { containerId } = React3.useContext(ContextContainer);
401
+ const containerContext = useContextContainer();
391
402
  useInit(() => {
403
+ if (!containerContext) {
404
+ return;
405
+ }
406
+ const { containerId } = containerContext;
392
407
  const value = ctx.mapViewabilityAmountValues.get(containerId);
393
408
  if (value) {
394
409
  callback(value);
395
410
  }
396
411
  });
397
- ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
398
- React3.useEffect(
399
- () => () => {
412
+ React3.useEffect(() => {
413
+ if (!containerContext) {
414
+ return;
415
+ }
416
+ const { containerId } = containerContext;
417
+ ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
418
+ return () => {
400
419
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
401
- },
402
- []
403
- );
420
+ };
421
+ }, [ctx, callback, containerContext]);
404
422
  }
405
423
  function useRecyclingEffect(effect) {
406
- const { index, value } = React3.useContext(ContextContainer);
424
+ const containerContext = useContextContainer();
407
425
  const prevValues = React3.useRef({
408
426
  prevIndex: void 0,
409
427
  prevItem: void 0
410
428
  });
411
429
  React3.useEffect(() => {
430
+ if (!containerContext) {
431
+ return;
432
+ }
433
+ const { index, value } = containerContext;
412
434
  let ret;
413
435
  if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
414
436
  ret = effect({
@@ -423,48 +445,73 @@ function useRecyclingEffect(effect) {
423
445
  prevItem: value
424
446
  };
425
447
  return ret;
426
- }, [index, value, effect]);
448
+ }, [effect, containerContext]);
427
449
  }
428
450
  function useRecyclingState(valueOrFun) {
429
- const { index, value, itemKey, triggerLayout } = React3.useContext(ContextContainer);
430
- const refState = React3.useRef({
431
- itemKey: null,
432
- value: null
451
+ var _a3, _b;
452
+ const containerContext = useContextContainer();
453
+ const computeValue = (ctx) => {
454
+ if (isFunction(valueOrFun)) {
455
+ const initializer = valueOrFun;
456
+ return ctx ? initializer({
457
+ index: ctx.index,
458
+ item: ctx.value,
459
+ prevIndex: void 0,
460
+ prevItem: void 0
461
+ }) : initializer();
462
+ }
463
+ return valueOrFun;
464
+ };
465
+ const [stateValue, setStateValue] = React3.useState(() => {
466
+ return computeValue(containerContext);
433
467
  });
434
- const [_, setRenderNum] = React3.useState(0);
435
- const state = refState.current;
436
- if (state.itemKey !== itemKey) {
437
- state.itemKey = itemKey;
438
- state.value = isFunction(valueOrFun) ? valueOrFun({
439
- index,
440
- item: value,
441
- prevIndex: void 0,
442
- prevItem: void 0
443
- }) : valueOrFun;
468
+ const prevItemKeyRef = React3.useRef((_a3 = containerContext == null ? void 0 : containerContext.itemKey) != null ? _a3 : null);
469
+ const currentItemKey = (_b = containerContext == null ? void 0 : containerContext.itemKey) != null ? _b : null;
470
+ if (currentItemKey !== null && prevItemKeyRef.current !== currentItemKey) {
471
+ prevItemKeyRef.current = currentItemKey;
472
+ setStateValue(computeValue(containerContext));
444
473
  }
474
+ const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
445
475
  const setState = React3.useCallback(
446
476
  (newState) => {
447
- state.value = isFunction(newState) ? newState(state.value) : newState;
448
- setRenderNum((v) => v + 1);
477
+ if (!triggerLayout) {
478
+ return;
479
+ }
480
+ setStateValue((prevValue) => {
481
+ return isFunction(newState) ? newState(prevValue) : newState;
482
+ });
449
483
  triggerLayout();
450
484
  },
451
- [triggerLayout, state]
485
+ [triggerLayout]
452
486
  );
453
- return [state.value, setState];
487
+ return [stateValue, setState];
454
488
  }
455
489
  function useIsLastItem() {
456
- const { itemKey } = React3.useContext(ContextContainer);
457
- const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
490
+ const containerContext = useContextContainer();
491
+ const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
492
+ if (containerContext) {
493
+ const { itemKey } = containerContext;
494
+ if (!isNullOrUndefined(itemKey)) {
495
+ return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
496
+ }
497
+ }
498
+ return false;
499
+ });
458
500
  return isLast;
459
501
  }
460
502
  function useListScrollSize() {
461
503
  const [scrollSize] = useArr$(["scrollSize"]);
462
504
  return scrollSize;
463
505
  }
506
+ var noop = () => {
507
+ };
464
508
  function useSyncLayout() {
465
- {
466
- const { triggerLayout: syncLayout } = React3.useContext(ContextContainer);
509
+ const containerContext = useContextContainer();
510
+ if (containerContext) {
511
+ const { triggerLayout: syncLayout } = containerContext;
467
512
  return syncLayout;
513
+ } else {
514
+ return noop;
468
515
  }
469
516
  }
470
517
 
@@ -1109,9 +1156,6 @@ function ScrollAdjust() {
1109
1156
  } else {
1110
1157
  scrollView.scrollBy(0, scrollDelta);
1111
1158
  }
1112
- if (IS_DEV) {
1113
- console.log("ScrollAdjust (web scrollBy)", scrollDelta, "total offset:", scrollOffset);
1114
- }
1115
1159
  }
1116
1160
  lastScrollOffsetRef.current = scrollOffset;
1117
1161
  }
@@ -1160,7 +1204,6 @@ var ListComponent = typedMemo(function ListComponent2({
1160
1204
  getRenderedItem: getRenderedItem2,
1161
1205
  updateItemSize: updateItemSize2,
1162
1206
  refScrollView,
1163
- maintainVisibleContentPosition,
1164
1207
  renderScrollComponent,
1165
1208
  scrollAdjustHandler,
1166
1209
  onLayoutHeader,
@@ -1169,6 +1212,7 @@ var ListComponent = typedMemo(function ListComponent2({
1169
1212
  ...rest
1170
1213
  }) {
1171
1214
  const ctx = useStateContext();
1215
+ const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
1172
1216
  const ScrollComponent = renderScrollComponent ? React3.useMemo(
1173
1217
  () => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
1174
1218
  [renderScrollComponent]
@@ -1186,7 +1230,7 @@ var ListComponent = typedMemo(function ListComponent2({
1186
1230
  ],
1187
1231
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
1188
1232
  horizontal,
1189
- maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
1233
+ maintainVisibleContentPosition: maintainVisibleContentPosition.scroll || maintainVisibleContentPosition.dataChanges ? { minIndexForVisible: 0 } : void 0,
1190
1234
  onLayout,
1191
1235
  onScroll: onScroll2,
1192
1236
  ref: refScrollView,
@@ -1730,14 +1774,16 @@ function requestAdjust(ctx, positionDiff, dataChanged) {
1730
1774
  function prepareMVCP(ctx, dataChanged) {
1731
1775
  const state = ctx.state;
1732
1776
  const { idsInView, positions, props } = state;
1733
- const { maintainVisibleContentPosition } = props;
1777
+ const {
1778
+ maintainVisibleContentPosition: { dataChanges: mvcpDataChanges, scroll: mvcpScroll }
1779
+ } = props;
1734
1780
  const scrollingTo = state.scrollingTo;
1735
1781
  let prevPosition;
1736
1782
  let targetId;
1737
1783
  const idsInViewWithPositions = [];
1738
1784
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1739
1785
  const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1740
- const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1786
+ const shouldMVCP = dataChanged ? mvcpDataChanges : mvcpScroll;
1741
1787
  const indexByKey = state.indexByKey;
1742
1788
  if (shouldMVCP) {
1743
1789
  if (scrollTarget !== void 0) {
@@ -1760,7 +1806,7 @@ function prepareMVCP(ctx, dataChanged) {
1760
1806
  }
1761
1807
  return () => {
1762
1808
  let positionDiff = 0;
1763
- if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1809
+ if (dataChanged && targetId === void 0 && mvcpDataChanges) {
1764
1810
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1765
1811
  const { id, position } = idsInViewWithPositions[i];
1766
1812
  const newPosition = positions.get(id);
@@ -1894,39 +1940,40 @@ function updateTotalSize(ctx) {
1894
1940
  // src/utils/getScrollVelocity.ts
1895
1941
  var getScrollVelocity = (state) => {
1896
1942
  const { scrollHistory } = state;
1897
- let velocity = 0;
1898
- if (scrollHistory.length >= 1) {
1899
- const newest = scrollHistory[scrollHistory.length - 1];
1900
- let oldest;
1901
- let start = 0;
1902
- const now = Date.now();
1903
- for (let i = 0; i < scrollHistory.length - 1; i++) {
1904
- const entry = scrollHistory[i];
1905
- const nextEntry = scrollHistory[i + 1];
1906
- if (i > 0) {
1907
- const prevEntry = scrollHistory[i - 1];
1908
- const prevDirection = entry.scroll - prevEntry.scroll;
1909
- const currentDirection = nextEntry.scroll - entry.scroll;
1910
- if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
1911
- start = i;
1912
- break;
1913
- }
1914
- }
1943
+ const newestIndex = scrollHistory.length - 1;
1944
+ if (newestIndex < 1) {
1945
+ return 0;
1946
+ }
1947
+ const newest = scrollHistory[newestIndex];
1948
+ const now = Date.now();
1949
+ let direction = 0;
1950
+ for (let i = newestIndex; i > 0; i--) {
1951
+ const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
1952
+ if (delta !== 0) {
1953
+ direction = Math.sign(delta);
1954
+ break;
1915
1955
  }
1916
- for (let i = start; i < scrollHistory.length - 1; i++) {
1917
- const entry = scrollHistory[i];
1918
- if (now - entry.time <= 1e3) {
1919
- oldest = entry;
1920
- break;
1921
- }
1956
+ }
1957
+ if (direction === 0) {
1958
+ return 0;
1959
+ }
1960
+ let oldest = newest;
1961
+ for (let i = newestIndex - 1; i >= 0; i--) {
1962
+ const current = scrollHistory[i];
1963
+ const next = scrollHistory[i + 1];
1964
+ const delta = next.scroll - current.scroll;
1965
+ const deltaSign = Math.sign(delta);
1966
+ if (deltaSign !== 0 && deltaSign !== direction) {
1967
+ break;
1922
1968
  }
1923
- if (oldest && oldest !== newest) {
1924
- const scrollDiff = newest.scroll - oldest.scroll;
1925
- const timeDiff = newest.time - oldest.time;
1926
- velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
1969
+ if (now - current.time > 1e3) {
1970
+ break;
1927
1971
  }
1972
+ oldest = current;
1928
1973
  }
1929
- return velocity;
1974
+ const scrollDiff = newest.scroll - oldest.scroll;
1975
+ const timeDiff = newest.time - oldest.time;
1976
+ return timeDiff > 0 ? scrollDiff / timeDiff : 0;
1930
1977
  };
1931
1978
 
1932
1979
  // src/utils/updateSnapToOffsets.ts
@@ -2856,7 +2903,7 @@ function checkFinishedScrollFrame(ctx) {
2856
2903
  if (scrollingTo) {
2857
2904
  const { state } = ctx;
2858
2905
  state.animFrameCheckFinishedScroll = void 0;
2859
- const scroll = state.scroll;
2906
+ const scroll = state.scrollPending;
2860
2907
  const adjust = state.scrollAdjustHandler.getAdjust();
2861
2908
  const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
2862
2909
  const maxOffset = clampScrollOffset(ctx, scroll);
@@ -3111,7 +3158,6 @@ function onScroll(ctx, event) {
3111
3158
  return;
3112
3159
  }
3113
3160
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
3114
- state.scrollPending = newScroll;
3115
3161
  if (state.scrollingTo) {
3116
3162
  const maxOffset = clampScrollOffset(ctx, newScroll);
3117
3163
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -3125,8 +3171,11 @@ function onScroll(ctx, event) {
3125
3171
  return;
3126
3172
  }
3127
3173
  }
3174
+ state.scrollPending = newScroll;
3128
3175
  updateScroll(ctx, newScroll);
3129
- checkFinishedScroll(ctx);
3176
+ if (state.scrollingTo) {
3177
+ checkFinishedScroll(ctx);
3178
+ }
3130
3179
  onScrollProp == null ? void 0 : onScrollProp(event);
3131
3180
  }
3132
3181
 
@@ -3461,6 +3510,24 @@ function getRenderedItem(ctx, key) {
3461
3510
  }
3462
3511
  return { index, item: data[index], renderedItem };
3463
3512
  }
3513
+
3514
+ // src/utils/normalizeMaintainVisibleContentPosition.ts
3515
+ function normalizeMaintainVisibleContentPosition(value) {
3516
+ var _a3, _b;
3517
+ if (value === true) {
3518
+ return { dataChanges: true, scroll: true };
3519
+ }
3520
+ if (value && typeof value === "object") {
3521
+ return {
3522
+ dataChanges: (_a3 = value.dataChanges) != null ? _a3 : false,
3523
+ scroll: (_b = value.scroll) != null ? _b : true
3524
+ };
3525
+ }
3526
+ if (value === false) {
3527
+ return { dataChanges: false, scroll: false };
3528
+ }
3529
+ return { dataChanges: false, scroll: true };
3530
+ }
3464
3531
  function useThrottleDebounce(mode) {
3465
3532
  const timeoutRef = React3.useRef(null);
3466
3533
  const lastCallTimeRef = React3.useRef(0);
@@ -3555,7 +3622,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3555
3622
  ListHeaderComponent,
3556
3623
  maintainScrollAtEnd = false,
3557
3624
  maintainScrollAtEndThreshold = 0.1,
3558
- maintainVisibleContentPosition = false,
3625
+ maintainVisibleContentPosition: maintainVisibleContentPositionProp,
3559
3626
  numColumns: numColumnsProp = 1,
3560
3627
  onEndReached,
3561
3628
  onEndReachedThreshold = 0.5,
@@ -3593,6 +3660,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3593
3660
  const style = { ...StyleSheet.flatten(styleProp) };
3594
3661
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
3595
3662
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
3663
+ const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
3664
+ maintainVisibleContentPositionProp
3665
+ );
3596
3666
  const [renderNum, setRenderNum] = React3.useState(0);
3597
3667
  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;
3598
3668
  const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
@@ -3677,7 +3747,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3677
3747
  };
3678
3748
  const internalState = ctx.state;
3679
3749
  internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3680
- set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3750
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
3681
3751
  set$(ctx, "extraData", extraData);
3682
3752
  }
3683
3753
  refState.current = ctx.state;
@@ -3708,7 +3778,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3708
3778
  keyExtractor,
3709
3779
  maintainScrollAtEnd,
3710
3780
  maintainScrollAtEndThreshold,
3711
- maintainVisibleContentPosition,
3781
+ maintainVisibleContentPosition: maintainVisibleContentPositionConfig,
3712
3782
  numColumns: numColumnsProp,
3713
3783
  onEndReached,
3714
3784
  onEndReachedThreshold,
@@ -3743,7 +3813,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3743
3813
  setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3744
3814
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3745
3815
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3746
- if (paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
3816
+ if (maintainVisibleContentPositionConfig.scroll && paddingDiff && prevPaddingTop !== void 0 && Platform.OS === "ios") {
3747
3817
  if (state.scroll < 0) {
3748
3818
  paddingDiff += state.scroll;
3749
3819
  }
@@ -3778,7 +3848,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3778
3848
  value = 0;
3779
3849
  }
3780
3850
  if (!value) {
3781
- state.didFinishInitialScroll = true;
3851
+ setInitialRenderState(ctx, { didInitialScroll: true });
3782
3852
  }
3783
3853
  return value;
3784
3854
  }, [renderNum]);
@@ -3900,7 +3970,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3900
3970
  initialContentOffset,
3901
3971
  ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
3902
3972
  ListHeaderComponent,
3903
- maintainVisibleContentPosition,
3904
3973
  onLayout,
3905
3974
  onLayoutHeader,
3906
3975
  onMomentumScrollEnd: fns.onMomentumScrollEnd,