@legendapp/list 3.0.0-beta.1 → 3.0.0-beta.11

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.
@@ -7,30 +7,64 @@ import { useSyncExternalStore } from 'use-sync-external-store/shim';
7
7
  Animated.View;
8
8
  var View = View$1;
9
9
  var Text = Text$1;
10
+
11
+ // src/state/getContentInsetEnd.ts
12
+ function getContentInsetEnd(state) {
13
+ var _a3;
14
+ const { props } = state;
15
+ const horizontal = props.horizontal;
16
+ let contentInset = props.contentInset;
17
+ if (!contentInset) {
18
+ const animatedInset = (_a3 = props.animatedProps) == null ? void 0 : _a3.contentInset;
19
+ if (animatedInset) {
20
+ if ("get" in animatedInset) {
21
+ contentInset = animatedInset.get();
22
+ } else {
23
+ contentInset = animatedInset;
24
+ }
25
+ }
26
+ }
27
+ return (horizontal ? contentInset == null ? void 0 : contentInset.right : contentInset == null ? void 0 : contentInset.bottom) || 0;
28
+ }
29
+
30
+ // src/state/getContentSize.ts
31
+ function getContentSize(ctx) {
32
+ var _a3;
33
+ const { values, state } = ctx;
34
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
35
+ const stylePaddingBottom = state.props.stylePaddingBottom || 0;
36
+ const headerSize = values.get("headerSize") || 0;
37
+ const footerSize = values.get("footerSize") || 0;
38
+ const contentInsetBottom = getContentInsetEnd(state);
39
+ const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
40
+ return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
41
+ }
10
42
  var createAnimatedValue = (value) => new Animated.Value(value);
11
43
 
12
44
  // src/state/state.tsx
13
45
  var ContextState = React2.createContext(null);
46
+ var contextNum = 0;
14
47
  function StateProvider({ children }) {
15
48
  const [value] = React2.useState(() => ({
16
49
  animatedScrollY: createAnimatedValue(0),
17
50
  columnWrapperStyle: void 0,
18
- internalState: void 0,
51
+ contextNum: contextNum++,
19
52
  listeners: /* @__PURE__ */ new Map(),
20
53
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
21
54
  mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
22
55
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
23
56
  mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
24
57
  mapViewabilityValues: /* @__PURE__ */ new Map(),
58
+ positionListeners: /* @__PURE__ */ new Map(),
59
+ state: void 0,
25
60
  values: /* @__PURE__ */ new Map([
26
61
  ["alignItemsPaddingTop", 0],
27
62
  ["stylePaddingTop", 0],
28
63
  ["headerSize", 0],
29
64
  ["numContainers", 0],
30
- ["activeStickyIndex", void 0],
65
+ ["activeStickyIndex", -1],
31
66
  ["totalSize", 0],
32
- ["scrollAdjustPending", 0],
33
- ["scrollingTo", void 0]
67
+ ["scrollAdjustPending", 0]
34
68
  ]),
35
69
  viewRefs: /* @__PURE__ */ new Map()
36
70
  }));
@@ -98,15 +132,24 @@ function set$(ctx, signalName, value) {
98
132
  }
99
133
  }
100
134
  }
101
- function getContentSize(ctx) {
102
- var _a3, _b;
103
- const { values, internalState } = ctx;
104
- const stylePaddingTop = values.get("stylePaddingTop") || 0;
105
- const stylePaddingBottom = (internalState == null ? void 0 : internalState.props.stylePaddingBottom) || 0;
106
- const headerSize = values.get("headerSize") || 0;
107
- const footerSize = values.get("footerSize") || 0;
108
- const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
109
- return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom;
135
+ function listenPosition$(ctx, key, cb) {
136
+ const { positionListeners } = ctx;
137
+ let setListeners = positionListeners.get(key);
138
+ if (!setListeners) {
139
+ setListeners = /* @__PURE__ */ new Set();
140
+ positionListeners.set(key, setListeners);
141
+ }
142
+ setListeners.add(cb);
143
+ return () => setListeners.delete(cb);
144
+ }
145
+ function notifyPosition$(ctx, key, value) {
146
+ const { positionListeners } = ctx;
147
+ const setListeners = positionListeners.get(key);
148
+ if (setListeners) {
149
+ for (const listener of setListeners) {
150
+ listener(value);
151
+ }
152
+ }
110
153
  }
111
154
  function useArr$(signalNames) {
112
155
  const ctx = React2.useContext(ContextState);
@@ -187,7 +230,8 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
187
230
  // src/constants-platform.native.ts
188
231
  var IsNewArchitecture = global.nativeFabricUIManager != null;
189
232
  var useAnimatedValue = (initialValue) => {
190
- return useRef(new Animated.Value(initialValue)).current;
233
+ const [animAnimatedValue] = useState(() => new Animated.Value(initialValue));
234
+ return animAnimatedValue;
191
235
  };
192
236
 
193
237
  // src/utils/helpers.ts
@@ -276,7 +320,7 @@ var typedForwardRef = forwardRef;
276
320
  var typedMemo = memo;
277
321
 
278
322
  // src/components/PositionView.native.tsx
279
- var PositionViewState = typedMemo(function PositionView({
323
+ var PositionViewState = typedMemo(function PositionViewState2({
280
324
  id,
281
325
  horizontal,
282
326
  style,
@@ -296,7 +340,7 @@ var PositionViewState = typedMemo(function PositionView({
296
340
  }
297
341
  );
298
342
  });
299
- var PositionViewAnimated = typedMemo(function PositionView2({
343
+ var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
300
344
  id,
301
345
  horizontal,
302
346
  style,
@@ -339,21 +383,27 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
339
383
  const viewStyle = React2.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
340
384
  return /* @__PURE__ */ React2.createElement(Animated.View, { ref: refView, style: viewStyle, ...rest });
341
385
  });
342
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
343
- var symbolFirst = Symbol();
386
+ var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
344
387
  function useInit(cb) {
345
- const refValue = useRef(symbolFirst);
346
- if (refValue.current === symbolFirst) {
347
- refValue.current = cb();
348
- }
349
- return refValue.current;
388
+ useState(() => cb());
350
389
  }
351
390
 
352
391
  // src/state/ContextContainer.ts
353
392
  var ContextContainer = createContext(null);
393
+ function useContextContainer() {
394
+ return useContext(ContextContainer);
395
+ }
354
396
  function useIsLastItem() {
355
- const { itemKey } = useContext(ContextContainer);
356
- 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
+ });
357
407
  return isLast;
358
408
  }
359
409
 
@@ -513,6 +563,7 @@ var Container = typedMemo(function Container2({
513
563
  if (!IsNewArchitecture) {
514
564
  useEffect(() => {
515
565
  if (!isNullOrUndefined(itemKey)) {
566
+ didLayoutRef.current = false;
516
567
  const timeout = setTimeout(() => {
517
568
  if (!didLayoutRef.current) {
518
569
  const {
@@ -532,7 +583,7 @@ var Container = typedMemo(function Container2({
532
583
  }
533
584
  }, [itemKey]);
534
585
  }
535
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
586
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView;
536
587
  return /* @__PURE__ */ React2.createElement(
537
588
  PositionComponent,
538
589
  {
@@ -567,10 +618,10 @@ var Containers = typedMemo(function Containers2({
567
618
  // If this is the initial scroll, we don't want to delay because we want to update the size immediately
568
619
  delay: (value, prevValue) => {
569
620
  var _a3;
570
- return !((_a3 = ctx.internalState) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
621
+ return !((_a3 = ctx.state) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
571
622
  }
572
623
  });
573
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
624
+ const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("readyToRender", { getValue: (value) => value ? 1 : 0 }) : void 0;
574
625
  const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
575
626
  const containers = [];
576
627
  for (let i = 0; i < numContainers; i++) {
@@ -613,7 +664,8 @@ var Containers = typedMemo(function Containers2({
613
664
  return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
614
665
  });
615
666
  function DevNumbers() {
616
- return IS_DEV && React2.memo(function DevNumbers2() {
667
+ return IS_DEV && // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
668
+ React2.memo(function DevNumbers2() {
617
669
  return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2.createElement(
618
670
  View$1,
619
671
  {
@@ -721,13 +773,6 @@ var ListComponent = typedMemo(function ListComponent2({
721
773
  () => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
722
774
  [renderScrollComponent]
723
775
  ) : ListComponentScrollView;
724
- React2.useEffect(() => {
725
- if (canRender) {
726
- setTimeout(() => {
727
- scrollAdjustHandler.setMounted();
728
- }, 0);
729
- }
730
- }, [canRender]);
731
776
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
732
777
  return /* @__PURE__ */ React2.createElement(
733
778
  SnapOrScroll,
@@ -791,10 +836,11 @@ function getId(state, index) {
791
836
  }
792
837
 
793
838
  // src/core/calculateOffsetForIndex.ts
794
- function calculateOffsetForIndex(ctx, state, index) {
839
+ function calculateOffsetForIndex(ctx, index) {
840
+ const state = ctx.state;
795
841
  let position = 0;
796
842
  if (index !== void 0) {
797
- position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
843
+ position = state.positions.get(getId(state, index)) || 0;
798
844
  const paddingTop = peek$(ctx, "stylePaddingTop");
799
845
  if (paddingTop) {
800
846
  position += paddingTop;
@@ -808,7 +854,8 @@ function calculateOffsetForIndex(ctx, state, index) {
808
854
  }
809
855
 
810
856
  // src/utils/setPaddingTop.ts
811
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
857
+ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
858
+ const state = ctx.state;
812
859
  if (stylePaddingTop !== void 0) {
813
860
  const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
814
861
  if (stylePaddingTop < prevStylePaddingTop) {
@@ -827,7 +874,8 @@ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
827
874
  }
828
875
 
829
876
  // src/utils/updateAlignItemsPaddingTop.ts
830
- function updateAlignItemsPaddingTop(ctx, state) {
877
+ function updateAlignItemsPaddingTop(ctx) {
878
+ const state = ctx.state;
831
879
  const {
832
880
  scrollLength,
833
881
  props: { alignItemsAtEnd, data }
@@ -838,12 +886,13 @@ function updateAlignItemsPaddingTop(ctx, state) {
838
886
  const contentSize = getContentSize(ctx);
839
887
  alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
840
888
  }
841
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
889
+ setPaddingTop(ctx, { alignItemsPaddingTop });
842
890
  }
843
891
  }
844
892
 
845
893
  // src/core/addTotalSize.ts
846
- function addTotalSize(ctx, state, key, add) {
894
+ function addTotalSize(ctx, key, add) {
895
+ const state = ctx.state;
847
896
  const { alignItemsAtEnd } = state.props;
848
897
  const prevTotalSize = state.totalSize;
849
898
  let totalSize = state.totalSize;
@@ -864,31 +913,34 @@ function addTotalSize(ctx, state, key, add) {
864
913
  state.totalSize = totalSize;
865
914
  set$(ctx, "totalSize", totalSize);
866
915
  if (alignItemsAtEnd) {
867
- updateAlignItemsPaddingTop(ctx, state);
916
+ updateAlignItemsPaddingTop(ctx);
868
917
  }
869
918
  }
870
919
  }
871
920
  }
872
921
 
873
922
  // src/core/setSize.ts
874
- function setSize(ctx, state, itemKey, size) {
923
+ function setSize(ctx, itemKey, size) {
924
+ const state = ctx.state;
875
925
  const { sizes } = state;
876
926
  const previousSize = sizes.get(itemKey);
877
927
  const diff = previousSize !== void 0 ? size - previousSize : size;
878
928
  if (diff !== 0) {
879
- addTotalSize(ctx, state, itemKey, diff);
929
+ addTotalSize(ctx, itemKey, diff);
880
930
  }
881
931
  sizes.set(itemKey, size);
882
932
  }
883
933
 
884
934
  // src/utils/getItemSize.ts
885
- function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
935
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
886
936
  var _a3, _b;
937
+ const state = ctx.state;
887
938
  const {
888
939
  sizesKnown,
889
940
  sizes,
890
941
  averageSizes,
891
- props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
942
+ props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
943
+ scrollingTo
892
944
  } = state;
893
945
  const sizeKnown = sizesKnown.get(key);
894
946
  if (sizeKnown !== void 0) {
@@ -896,7 +948,6 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
896
948
  }
897
949
  let size;
898
950
  const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
899
- const scrollingTo = peek$(ctx, "scrollingTo");
900
951
  if (preferCachedSize) {
901
952
  const cachedSize = sizes.get(key);
902
953
  if (cachedSize !== void 0) {
@@ -924,84 +975,167 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
924
975
  if (size === void 0) {
925
976
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
926
977
  }
927
- setSize(ctx, state, key, size);
978
+ setSize(ctx, key, size);
928
979
  return size;
929
980
  }
930
981
 
931
982
  // src/core/calculateOffsetWithOffsetPosition.ts
932
- function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
983
+ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
984
+ const state = ctx.state;
933
985
  const { index, viewOffset, viewPosition } = params;
934
986
  let offset = offsetParam;
935
987
  if (viewOffset) {
936
988
  offset -= viewOffset;
937
989
  }
938
990
  if (viewPosition !== void 0 && index !== void 0) {
939
- offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
991
+ const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
992
+ const trailingInset = getContentInsetEnd(state);
993
+ offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
940
994
  }
941
995
  return offset;
942
996
  }
943
997
 
998
+ // src/core/clampScrollOffset.ts
999
+ function clampScrollOffset(ctx, offset) {
1000
+ const state = ctx.state;
1001
+ const contentSize = getContentSize(ctx);
1002
+ let clampedOffset = offset;
1003
+ if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength)) {
1004
+ const maxOffset = Math.max(0, contentSize - state.scrollLength);
1005
+ clampedOffset = Math.min(offset, maxOffset);
1006
+ }
1007
+ clampedOffset = Math.max(0, clampedOffset);
1008
+ return clampedOffset;
1009
+ }
1010
+ var Platform2 = Platform;
1011
+
1012
+ // src/utils/setInitialRenderState.ts
1013
+ function setInitialRenderState(ctx, {
1014
+ didLayout,
1015
+ didInitialScroll
1016
+ }) {
1017
+ const { state } = ctx;
1018
+ if (didLayout) {
1019
+ state.didContainersLayout = true;
1020
+ }
1021
+ if (didInitialScroll) {
1022
+ state.didFinishInitialScroll = true;
1023
+ }
1024
+ if (state.didContainersLayout && state.didFinishInitialScroll) {
1025
+ set$(ctx, "readyToRender", true);
1026
+ }
1027
+ }
1028
+
944
1029
  // src/core/finishScrollTo.ts
945
- function finishScrollTo(ctx, state) {
1030
+ function finishScrollTo(ctx) {
946
1031
  var _a3, _b;
947
- if (state) {
1032
+ const state = ctx.state;
1033
+ if (state == null ? void 0 : state.scrollingTo) {
948
1034
  state.scrollHistory.length = 0;
949
1035
  state.initialScroll = void 0;
950
1036
  state.initialAnchor = void 0;
951
- set$(ctx, "scrollingTo", void 0);
1037
+ state.scrollingTo = void 0;
952
1038
  if (state.pendingTotalSize !== void 0) {
953
- addTotalSize(ctx, state, null, state.pendingTotalSize);
1039
+ addTotalSize(ctx, null, state.pendingTotalSize);
954
1040
  }
955
1041
  if ((_a3 = state.props) == null ? void 0 : _a3.data) {
956
1042
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
957
1043
  }
1044
+ if (Platform2.OS === "web") {
1045
+ state.scrollAdjustHandler.commitPendingAdjust();
1046
+ }
1047
+ setInitialRenderState(ctx, { didInitialScroll: true });
958
1048
  }
959
1049
  }
960
- var Platform2 = Platform;
961
1050
 
962
- // src/core/scrollTo.ts
963
- function scrollTo(ctx, state, params) {
1051
+ // src/core/checkFinishedScroll.ts
1052
+ function checkFinishedScroll(ctx) {
1053
+ ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
1054
+ }
1055
+ function checkFinishedScrollFrame(ctx) {
1056
+ const scrollingTo = ctx.state.scrollingTo;
1057
+ if (scrollingTo) {
1058
+ const { state } = ctx;
1059
+ state.animFrameCheckFinishedScroll = void 0;
1060
+ const scroll = state.scroll;
1061
+ const adjust = state.scrollAdjustHandler.getAdjust();
1062
+ const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1063
+ const maxOffset = clampScrollOffset(ctx, scroll);
1064
+ const diff1 = Math.abs(scroll - clampedTargetOffset);
1065
+ const diff2 = Math.abs(diff1 - adjust);
1066
+ const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
1067
+ if (isNotOverscrolled && (diff1 < 1 || diff2 < 1)) {
1068
+ finishScrollTo(ctx);
1069
+ }
1070
+ }
1071
+ }
1072
+ function checkFinishedScrollFallback(ctx) {
1073
+ const state = ctx.state;
1074
+ const scrollingTo = state.scrollingTo;
1075
+ const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
1076
+ state.timeoutCheckFinishedScrollFallback = setTimeout(
1077
+ () => {
1078
+ let numChecks = 0;
1079
+ const checkHasScrolled = () => {
1080
+ state.timeoutCheckFinishedScrollFallback = void 0;
1081
+ const isStillScrollingTo = state.scrollingTo;
1082
+ if (isStillScrollingTo) {
1083
+ numChecks++;
1084
+ if (state.hasScrolled || numChecks > 5) {
1085
+ finishScrollTo(ctx);
1086
+ } else {
1087
+ state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
1088
+ }
1089
+ }
1090
+ };
1091
+ checkHasScrolled();
1092
+ },
1093
+ slowTimeout ? 500 : 100
1094
+ );
1095
+ }
1096
+
1097
+ // src/core/doScrollTo.native.ts
1098
+ function doScrollTo(ctx, params) {
964
1099
  var _a3;
965
- const { noScrollingTo, ...scrollTarget } = params;
1100
+ const state = ctx.state;
1101
+ const { animated, horizontal, offset } = params;
1102
+ const { refScroller } = state;
1103
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1104
+ animated: !!animated,
1105
+ x: horizontal ? offset : 0,
1106
+ y: horizontal ? 0 : offset
1107
+ });
1108
+ if (!animated) {
1109
+ state.scroll = offset;
1110
+ checkFinishedScrollFallback(ctx);
1111
+ }
1112
+ }
1113
+
1114
+ // src/core/scrollTo.ts
1115
+ function scrollTo(ctx, params) {
1116
+ const state = ctx.state;
1117
+ const { noScrollingTo, forceScroll, ...scrollTarget } = params;
966
1118
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
967
1119
  const {
968
- refScroller,
969
1120
  props: { horizontal }
970
1121
  } = state;
971
- let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
972
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
973
- const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
974
- offset = Math.min(offset, maxOffset);
1122
+ if (state.animFrameCheckFinishedScroll) {
1123
+ cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
1124
+ }
1125
+ if (state.timeoutCheckFinishedScrollFallback) {
1126
+ clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
975
1127
  }
1128
+ let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
1129
+ offset = clampScrollOffset(ctx, offset);
976
1130
  state.scrollHistory.length = 0;
977
1131
  if (!noScrollingTo) {
978
- set$(ctx, "scrollingTo", scrollTarget);
1132
+ state.scrollingTo = scrollTarget;
979
1133
  }
980
1134
  state.scrollPending = offset;
981
- if (!isInitialScroll || Platform2.OS === "android") {
982
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
983
- animated: !!animated,
984
- x: horizontal ? offset : 0,
985
- y: horizontal ? 0 : offset
986
- });
987
- }
988
- if (!animated) {
1135
+ if (forceScroll || !isInitialScroll || Platform2.OS === "android") {
1136
+ doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
1137
+ } else {
989
1138
  state.scroll = offset;
990
- if (Platform2.OS === "web") {
991
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
992
- if (value && peek$(ctx, "scrollingTo")) {
993
- finishScrollTo(ctx, state);
994
- unlisten();
995
- }
996
- });
997
- } else {
998
- setTimeout(() => finishScrollTo(ctx, state), 100);
999
- }
1000
- if (isInitialScroll) {
1001
- setTimeout(() => {
1002
- state.initialScroll = void 0;
1003
- }, 500);
1004
- }
1005
1139
  }
1006
1140
  }
1007
1141
 
@@ -1010,6 +1144,12 @@ var HYSTERESIS_MULTIPLIER = 1.3;
1010
1144
  var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1011
1145
  const absDistance = Math.abs(distance);
1012
1146
  const within = atThreshold || threshold > 0 && absDistance <= threshold;
1147
+ if (wasReached === null) {
1148
+ if (!within && distance >= 0) {
1149
+ return false;
1150
+ }
1151
+ return null;
1152
+ }
1013
1153
  const updateSnapshot = () => {
1014
1154
  setSnapshot == null ? void 0 : setSnapshot({
1015
1155
  atThreshold,
@@ -1042,8 +1182,9 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
1042
1182
  };
1043
1183
 
1044
1184
  // src/utils/checkAtBottom.ts
1045
- function checkAtBottom(ctx, state) {
1185
+ function checkAtBottom(ctx) {
1046
1186
  var _a3;
1187
+ const state = ctx.state;
1047
1188
  if (!state) {
1048
1189
  return;
1049
1190
  }
@@ -1116,15 +1257,15 @@ function checkAtTop(state) {
1116
1257
  }
1117
1258
 
1118
1259
  // src/core/updateScroll.ts
1119
- function updateScroll(ctx, state, newScroll, forceUpdate) {
1260
+ function updateScroll(ctx, newScroll, forceUpdate) {
1120
1261
  var _a3;
1121
- const scrollingTo = peek$(ctx, "scrollingTo");
1262
+ const state = ctx.state;
1263
+ const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
1122
1264
  state.hasScrolled = true;
1123
1265
  state.lastBatchingAction = Date.now();
1124
1266
  const currentTime = Date.now();
1125
- const adjust = state.scrollAdjustHandler.getAdjust();
1126
- const lastHistoryAdjust = state.lastScrollAdjustForHistory;
1127
- const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
1267
+ const adjust = scrollAdjustHandler.getAdjust();
1268
+ const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1128
1269
  if (adjustChanged) {
1129
1270
  state.scrollHistory.length = 0;
1130
1271
  }
@@ -1149,22 +1290,26 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1149
1290
  return;
1150
1291
  }
1151
1292
  }
1152
- if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1293
+ const lastCalculated = state.scrollLastCalculate;
1294
+ const shouldUpdate = forceUpdate || state.dataChangeNeedsScrollUpdate || state.scrollLastCalculate === void 0 || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
1295
+ if (shouldUpdate) {
1296
+ state.scrollLastCalculate = state.scroll;
1153
1297
  state.ignoreScrollFromMVCPIgnored = false;
1154
1298
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1155
- checkAtBottom(ctx, state);
1299
+ checkAtBottom(ctx);
1156
1300
  checkAtTop(state);
1157
1301
  state.dataChangeNeedsScrollUpdate = false;
1158
1302
  }
1159
1303
  }
1160
1304
 
1161
1305
  // src/utils/requestAdjust.ts
1162
- function requestAdjust(ctx, state, positionDiff, dataChanged) {
1306
+ function requestAdjust(ctx, positionDiff, dataChanged) {
1307
+ const state = ctx.state;
1163
1308
  if (Math.abs(positionDiff) > 0.1) {
1164
1309
  const needsScrollWorkaround = Platform2.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
1165
1310
  const doit = () => {
1166
1311
  if (needsScrollWorkaround) {
1167
- scrollTo(ctx, state, {
1312
+ scrollTo(ctx, {
1168
1313
  noScrollingTo: true,
1169
1314
  offset: state.scroll
1170
1315
  });
@@ -1177,8 +1322,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1177
1322
  };
1178
1323
  state.scroll += positionDiff;
1179
1324
  state.scrollForNextCalculateItemsInView = void 0;
1180
- const didLayout = peek$(ctx, "containersDidLayout");
1181
- if (didLayout) {
1325
+ const readyToRender = peek$(ctx, "readyToRender");
1326
+ if (readyToRender) {
1182
1327
  doit();
1183
1328
  if (Platform2.OS !== "web") {
1184
1329
  const threshold = state.scroll - positionDiff / 2;
@@ -1200,7 +1345,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1200
1345
  if (shouldForceUpdate) {
1201
1346
  state.ignoreScrollFromMVCPIgnored = false;
1202
1347
  state.scrollPending = state.scroll;
1203
- updateScroll(ctx, state, state.scroll, true);
1348
+ updateScroll(ctx, state.scroll, true);
1204
1349
  }
1205
1350
  }, delay);
1206
1351
  }
@@ -1215,28 +1360,27 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1215
1360
  var INITIAL_ANCHOR_TOLERANCE = 0.5;
1216
1361
  var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
1217
1362
  var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1218
- function ensureInitialAnchor(ctx, state) {
1363
+ function ensureInitialAnchor(ctx) {
1219
1364
  var _a3, _b, _c, _d, _e;
1220
- const anchor = state.initialAnchor;
1365
+ const state = ctx.state;
1366
+ const { initialAnchor, didContainersLayout, positions, scroll, scrollLength } = state;
1367
+ const anchor = initialAnchor;
1221
1368
  const item = state.props.data[anchor.index];
1222
- const containersDidLayout = peek$(ctx, "containersDidLayout");
1223
- if (!containersDidLayout) {
1369
+ if (!didContainersLayout) {
1224
1370
  return;
1225
1371
  }
1226
1372
  const id = getId(state, anchor.index);
1227
- if (state.positions.get(id) === void 0) {
1373
+ if (positions.get(id) === void 0) {
1228
1374
  return;
1229
1375
  }
1230
- const size = getItemSize(ctx, state, id, anchor.index, item, true, true);
1376
+ const size = getItemSize(ctx, id, anchor.index, item, true, true);
1231
1377
  if (size === void 0) {
1232
1378
  return;
1233
1379
  }
1234
- const availableSpace = Math.max(0, state.scrollLength - size);
1235
- const desiredOffset = calculateOffsetForIndex(ctx, state, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1236
- const contentSize = getContentSize(ctx);
1237
- const maxOffset = Math.max(0, contentSize - state.scrollLength);
1238
- const clampedDesiredOffset = Math.max(0, Math.min(desiredOffset, maxOffset));
1239
- const delta = clampedDesiredOffset - state.scroll;
1380
+ const availableSpace = Math.max(0, scrollLength - size);
1381
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1382
+ const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset);
1383
+ const delta = clampedDesiredOffset - scroll;
1240
1384
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1241
1385
  const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
1242
1386
  if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
@@ -1260,18 +1404,21 @@ function ensureInitialAnchor(ctx, state) {
1260
1404
  lastDelta: delta,
1261
1405
  settledTicks: 0
1262
1406
  });
1263
- requestAdjust(ctx, state, delta);
1407
+ requestAdjust(ctx, delta);
1408
+ requestAnimationFrame(() => finishScrollTo(ctx));
1264
1409
  }
1265
1410
 
1266
1411
  // src/core/mvcp.ts
1267
- function prepareMVCP(ctx, state, dataChanged) {
1412
+ function prepareMVCP(ctx, dataChanged) {
1413
+ const state = ctx.state;
1268
1414
  const { idsInView, positions, props } = state;
1269
1415
  const { maintainVisibleContentPosition } = props;
1270
- const scrollingTo = peek$(ctx, "scrollingTo");
1416
+ const scrollingTo = state.scrollingTo;
1271
1417
  let prevPosition;
1272
1418
  let targetId;
1273
1419
  const idsInViewWithPositions = [];
1274
1420
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1421
+ const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1275
1422
  const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1276
1423
  const indexByKey = state.indexByKey;
1277
1424
  if (shouldMVCP) {
@@ -1280,7 +1427,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1280
1427
  return void 0;
1281
1428
  }
1282
1429
  targetId = getId(state, scrollTarget);
1283
- } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
1430
+ } else if (idsInView.length > 0 && state.didContainersLayout) {
1284
1431
  if (dataChanged) {
1285
1432
  for (let i = 0; i < idsInView.length; i++) {
1286
1433
  const id = idsInView[i];
@@ -1297,7 +1444,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1297
1444
  prevPosition = positions.get(targetId);
1298
1445
  }
1299
1446
  return () => {
1300
- let positionDiff;
1447
+ let positionDiff = 0;
1301
1448
  if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1302
1449
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1303
1450
  const { id, position } = idsInViewWithPositions[i];
@@ -1323,16 +1470,28 @@ function prepareMVCP(ctx, state, dataChanged) {
1323
1470
  positionDiff = diff;
1324
1471
  }
1325
1472
  }
1326
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1327
- requestAdjust(ctx, state, positionDiff, dataChanged && maintainVisibleContentPosition);
1473
+ if (scrollingToViewPosition && scrollingToViewPosition > 0) {
1474
+ const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
1475
+ const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
1476
+ if (newSize !== void 0 && prevSize !== void 0 && newSize !== (scrollingTo == null ? void 0 : scrollingTo.itemSize)) {
1477
+ const diff = newSize - prevSize;
1478
+ if (diff !== 0) {
1479
+ positionDiff += (newSize - prevSize) * scrollingToViewPosition;
1480
+ scrollingTo.itemSize = newSize;
1481
+ }
1482
+ }
1483
+ }
1484
+ if (Math.abs(positionDiff) > 0.1) {
1485
+ requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1328
1486
  }
1329
1487
  };
1330
1488
  }
1331
1489
  }
1332
1490
 
1333
1491
  // src/core/prepareColumnStartState.ts
1334
- function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1492
+ function prepareColumnStartState(ctx, startIndex, useAverageSize) {
1335
1493
  var _a3;
1494
+ const state = ctx.state;
1336
1495
  const numColumns = peek$(ctx, "numColumns");
1337
1496
  let rowStartIndex = startIndex;
1338
1497
  const columnAtStart = state.columns.get(state.idCache[startIndex]);
@@ -1347,7 +1506,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1347
1506
  const prevId = state.idCache[prevIndex];
1348
1507
  const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1349
1508
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1350
- const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
1509
+ const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
1351
1510
  currentRowTop = prevPosition + prevRowHeight;
1352
1511
  }
1353
1512
  return {
@@ -1370,7 +1529,8 @@ function findRowStartIndex(state, numColumns, index) {
1370
1529
  }
1371
1530
  return rowStart;
1372
1531
  }
1373
- function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1532
+ function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
1533
+ const state = ctx.state;
1374
1534
  if (endIndex < startIndex) {
1375
1535
  return 0;
1376
1536
  }
@@ -1384,7 +1544,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1384
1544
  continue;
1385
1545
  }
1386
1546
  const id = state.idCache[i];
1387
- const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
1547
+ const size = getItemSize(ctx, id, i, data[i], useAverageSize);
1388
1548
  if (size > maxSize) {
1389
1549
  maxSize = size;
1390
1550
  }
@@ -1393,22 +1553,23 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1393
1553
  }
1394
1554
 
1395
1555
  // src/core/updateTotalSize.ts
1396
- function updateTotalSize(ctx, state) {
1556
+ function updateTotalSize(ctx) {
1557
+ const state = ctx.state;
1397
1558
  const {
1398
1559
  positions,
1399
1560
  props: { data }
1400
1561
  } = state;
1401
1562
  if (data.length === 0) {
1402
- addTotalSize(ctx, state, null, 0);
1563
+ addTotalSize(ctx, null, 0);
1403
1564
  } else {
1404
1565
  const lastId = getId(state, data.length - 1);
1405
1566
  if (lastId !== void 0) {
1406
1567
  const lastPosition = positions.get(lastId);
1407
1568
  if (lastPosition !== void 0) {
1408
- const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
1569
+ const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
1409
1570
  if (lastSize !== void 0) {
1410
1571
  const totalSize = lastPosition + lastSize;
1411
- addTotalSize(ctx, state, null, totalSize);
1572
+ addTotalSize(ctx, null, totalSize);
1412
1573
  }
1413
1574
  }
1414
1575
  }
@@ -1454,7 +1615,8 @@ var getScrollVelocity = (state) => {
1454
1615
  };
1455
1616
 
1456
1617
  // src/utils/updateSnapToOffsets.ts
1457
- function updateSnapToOffsets(ctx, state) {
1618
+ function updateSnapToOffsets(ctx) {
1619
+ const state = ctx.state;
1458
1620
  const {
1459
1621
  positions,
1460
1622
  props: { snapToIndices }
@@ -1469,30 +1631,30 @@ function updateSnapToOffsets(ctx, state) {
1469
1631
  }
1470
1632
 
1471
1633
  // src/core/updateItemPositions.ts
1472
- function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1634
+ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1473
1635
  doMVCP: false,
1474
1636
  forceFullUpdate: false,
1475
1637
  scrollBottomBuffered: -1,
1476
1638
  startIndex: 0
1477
1639
  }) {
1478
1640
  var _a3, _b, _c, _d, _e;
1641
+ const state = ctx.state;
1479
1642
  const {
1480
1643
  columns,
1481
1644
  indexByKey,
1482
1645
  positions,
1483
1646
  idCache,
1484
1647
  sizesKnown,
1485
- props: { getEstimatedItemSize, snapToIndices, enableAverages }
1648
+ props: { data, getEstimatedItemSize, snapToIndices },
1649
+ scrollingTo
1486
1650
  } = state;
1487
- const data = state.props.data;
1488
1651
  const dataLength = data.length;
1489
1652
  const numColumns = peek$(ctx, "numColumns");
1490
- const scrollingTo = peek$(ctx, "scrollingTo");
1491
1653
  const hasColumns = numColumns > 1;
1492
1654
  const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1493
1655
  const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
1494
1656
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1495
- const useAverageSize = enableAverages && !getEstimatedItemSize;
1657
+ const useAverageSize = !getEstimatedItemSize;
1496
1658
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1497
1659
  let currentRowTop = 0;
1498
1660
  let column = 1;
@@ -1501,7 +1663,6 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1501
1663
  if (hasColumns) {
1502
1664
  const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1503
1665
  ctx,
1504
- state,
1505
1666
  startIndex,
1506
1667
  useAverageSize
1507
1668
  );
@@ -1511,7 +1672,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1511
1672
  const prevIndex = startIndex - 1;
1512
1673
  const prevId = getId(state, prevIndex);
1513
1674
  const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1514
- const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1675
+ const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1515
1676
  currentRowTop = prevPosition + prevSize;
1516
1677
  }
1517
1678
  }
@@ -1528,7 +1689,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1528
1689
  breakAt = i + itemsPerRow + 10;
1529
1690
  }
1530
1691
  const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1531
- const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
1692
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
1532
1693
  if (IS_DEV && needsIndexByKey) {
1533
1694
  if (indexByKeyForChecking.has(id)) {
1534
1695
  console.error(
@@ -1537,7 +1698,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1537
1698
  }
1538
1699
  indexByKeyForChecking.set(id, i);
1539
1700
  }
1540
- positions.set(id, currentRowTop);
1701
+ if (currentRowTop !== positions.get(id)) {
1702
+ positions.set(id, currentRowTop);
1703
+ notifyPosition$(ctx, id, currentRowTop);
1704
+ }
1541
1705
  if (needsIndexByKey) {
1542
1706
  indexByKey.set(id, i);
1543
1707
  }
@@ -1557,10 +1721,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1557
1721
  }
1558
1722
  }
1559
1723
  if (!didBreakEarly) {
1560
- updateTotalSize(ctx, state);
1724
+ updateTotalSize(ctx);
1561
1725
  }
1562
1726
  if (snapToIndices) {
1563
- updateSnapToOffsets(ctx, state);
1727
+ updateSnapToOffsets(ctx);
1564
1728
  }
1565
1729
  }
1566
1730
 
@@ -1638,7 +1802,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1638
1802
  if (previousViewableItems) {
1639
1803
  for (const viewToken of previousViewableItems) {
1640
1804
  const containerId = findContainerId(ctx, viewToken.key);
1641
- if (!isViewable(
1805
+ if (!checkIsViewable(
1642
1806
  state,
1643
1807
  ctx,
1644
1808
  viewabilityConfig,
@@ -1659,7 +1823,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1659
1823
  if (item) {
1660
1824
  const key = getId(state, i);
1661
1825
  const containerId = findContainerId(ctx, key);
1662
- if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1826
+ if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1663
1827
  const viewToken = {
1664
1828
  containerId,
1665
1829
  index: i,
@@ -1719,11 +1883,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1719
1883
  const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
1720
1884
  const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
1721
1885
  const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1722
- const isViewable2 = percent >= viewablePercentThreshold;
1886
+ const isViewable = percent >= viewablePercentThreshold;
1723
1887
  const value = {
1724
1888
  containerId,
1725
1889
  index,
1726
- isViewable: isViewable2,
1890
+ isViewable,
1727
1891
  item,
1728
1892
  key,
1729
1893
  percentOfScroller,
@@ -1742,8 +1906,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1742
1906
  }
1743
1907
  return value;
1744
1908
  }
1745
- function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1746
- const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1909
+ function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1910
+ let value = ctx.mapViewabilityAmountValues.get(containerId);
1911
+ if (!value || value.key !== key) {
1912
+ value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1913
+ }
1747
1914
  return value.isViewable;
1748
1915
  }
1749
1916
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
@@ -1771,8 +1938,9 @@ function checkAllSizesKnown(state) {
1771
1938
  }
1772
1939
 
1773
1940
  // src/utils/findAvailableContainers.ts
1774
- function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1941
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1775
1942
  const numContainers = peek$(ctx, "numContainers");
1943
+ const state = ctx.state;
1776
1944
  const { stickyContainerPool, containerItemTypes } = state;
1777
1945
  const result = [];
1778
1946
  const availableContainers = [];
@@ -1816,14 +1984,14 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1816
1984
  continue;
1817
1985
  }
1818
1986
  const key = peek$(ctx, `containerItemKey${u}`);
1819
- let isOk = key === void 0;
1820
- if (!isOk && pendingRemovalSet.has(u)) {
1821
- pendingRemovalSet.delete(u);
1822
- pendingRemovalChanged = true;
1823
- const requiredType = neededTypes[typeIndex];
1824
- isOk = canReuseContainer(u, requiredType);
1825
- }
1826
- if (isOk) {
1987
+ const requiredType = neededTypes[typeIndex];
1988
+ const isPending = key !== void 0 && pendingRemovalSet.has(u);
1989
+ const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
1990
+ if (canUse) {
1991
+ if (isPending) {
1992
+ pendingRemovalSet.delete(u);
1993
+ pendingRemovalChanged = true;
1994
+ }
1827
1995
  result.push(u);
1828
1996
  if (requiredItemTypes) {
1829
1997
  typeIndex++;
@@ -1892,21 +2060,26 @@ function comparatorByDistance(a, b) {
1892
2060
  }
1893
2061
 
1894
2062
  // src/core/scrollToIndex.ts
1895
- function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1896
- if (index >= state.props.data.length) {
1897
- index = state.props.data.length - 1;
2063
+ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
2064
+ const state = ctx.state;
2065
+ const { data } = state.props;
2066
+ if (index >= data.length) {
2067
+ index = data.length - 1;
1898
2068
  } else if (index < 0) {
1899
2069
  index = 0;
1900
2070
  }
1901
- const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
1902
- const isLast = index === state.props.data.length - 1;
2071
+ const firstIndexOffset = calculateOffsetForIndex(ctx, index);
2072
+ const isLast = index === data.length - 1;
1903
2073
  if (isLast && viewPosition === void 0) {
1904
2074
  viewPosition = 1;
1905
2075
  }
1906
2076
  state.scrollForNextCalculateItemsInView = void 0;
1907
- scrollTo(ctx, state, {
2077
+ const targetId = getId(state, index);
2078
+ const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
2079
+ scrollTo(ctx, {
1908
2080
  animated,
1909
2081
  index,
2082
+ itemSize,
1910
2083
  offset: firstIndexOffset,
1911
2084
  viewOffset,
1912
2085
  viewPosition: viewPosition != null ? viewPosition : 0
@@ -1914,29 +2087,30 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1914
2087
  }
1915
2088
 
1916
2089
  // src/utils/setDidLayout.ts
1917
- function setDidLayout(ctx, state) {
2090
+ function setDidLayout(ctx) {
2091
+ const state = ctx.state;
1918
2092
  const {
1919
2093
  loadStartTime,
1920
2094
  initialScroll,
1921
2095
  props: { onLoad }
1922
2096
  } = state;
1923
2097
  state.queuedInitialLayout = true;
1924
- checkAtBottom(ctx, state);
2098
+ checkAtBottom(ctx);
1925
2099
  const setIt = () => {
1926
- set$(ctx, "containersDidLayout", true);
2100
+ setInitialRenderState(ctx, { didLayout: true });
1927
2101
  if (onLoad) {
1928
2102
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1929
2103
  }
1930
2104
  };
1931
2105
  if (Platform2.OS === "android" && initialScroll) {
1932
2106
  if (IsNewArchitecture) {
1933
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2107
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1934
2108
  requestAnimationFrame(() => {
1935
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2109
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1936
2110
  setIt();
1937
2111
  });
1938
2112
  } else {
1939
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2113
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1940
2114
  setIt();
1941
2115
  }
1942
2116
  } else {
@@ -1959,15 +2133,17 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
1959
2133
  }
1960
2134
  return -1;
1961
2135
  }
1962
- function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
2136
+ function getActiveStickyIndices(ctx, stickyHeaderIndices) {
2137
+ const state = ctx.state;
1963
2138
  return new Set(
1964
2139
  Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyHeaderIndices.has(idx))
1965
2140
  );
1966
2141
  }
1967
- function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2142
+ function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
1968
2143
  var _a3;
1969
- const activeIndices = getActiveStickyIndices(ctx, state, stickyHeaderIndices);
1970
- state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
2144
+ const state = ctx.state;
2145
+ const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
2146
+ set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
1971
2147
  for (let offset = 0; offset <= 1; offset++) {
1972
2148
  const idx = currentStickyIdx - offset;
1973
2149
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
@@ -1978,8 +2154,9 @@ function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, cu
1978
2154
  }
1979
2155
  }
1980
2156
  }
1981
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2157
+ function handleStickyRecycling(ctx, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
1982
2158
  var _a3, _b, _c;
2159
+ const state = ctx.state;
1983
2160
  for (const containerIndex of state.stickyContainerPool) {
1984
2161
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
1985
2162
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
@@ -2003,7 +2180,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2003
2180
  const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2004
2181
  if (currentId) {
2005
2182
  const currentPos = state.positions.get(currentId);
2006
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
2183
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2007
2184
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
2008
2185
  }
2009
2186
  }
@@ -2012,7 +2189,8 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2012
2189
  }
2013
2190
  }
2014
2191
  }
2015
- function calculateItemsInView(ctx, state, params = {}) {
2192
+ function calculateItemsInView(ctx, params = {}) {
2193
+ const state = ctx.state;
2016
2194
  unstable_batchedUpdates(() => {
2017
2195
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2018
2196
  const {
@@ -2036,8 +2214,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2036
2214
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2037
2215
  const prevNumContainers = peek$(ctx, "numContainers");
2038
2216
  if (!data || scrollLength === 0 || !prevNumContainers) {
2039
- if (state.initialAnchor) {
2040
- ensureInitialAnchor(ctx, state);
2217
+ if (!IsNewArchitecture && state.initialAnchor) {
2218
+ ensureInitialAnchor(ctx);
2041
2219
  }
2042
2220
  return;
2043
2221
  }
@@ -2052,15 +2230,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2052
2230
  if (!queuedInitialLayout && initialScroll) {
2053
2231
  const updatedOffset = calculateOffsetWithOffsetPosition(
2054
2232
  ctx,
2055
- state,
2056
- calculateOffsetForIndex(ctx, state, initialScroll.index),
2233
+ calculateOffsetForIndex(ctx, initialScroll.index),
2057
2234
  initialScroll
2058
2235
  );
2059
2236
  scrollState = updatedOffset;
2060
2237
  }
2061
2238
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2062
2239
  const scrollAdjustPad = scrollAdjustPending - topPad;
2063
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2240
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2064
2241
  if (scroll + scrollLength > totalSize) {
2065
2242
  scroll = Math.max(0, totalSize - scrollLength);
2066
2243
  }
@@ -2068,11 +2245,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2068
2245
  set$(ctx, "debugRawScroll", scrollState);
2069
2246
  set$(ctx, "debugComputedScroll", scroll);
2070
2247
  }
2071
- const previousStickyIndex = state.activeStickyIndex;
2248
+ const previousStickyIndex = peek$(ctx, "activeStickyIndex");
2072
2249
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
2073
- const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
2074
- state.activeStickyIndex = nextActiveStickyIndex;
2075
- set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2250
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
2251
+ if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
2252
+ set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2253
+ }
2076
2254
  let scrollBufferTop = scrollBuffer;
2077
2255
  let scrollBufferBottom = scrollBuffer;
2078
2256
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2085,23 +2263,23 @@ function calculateItemsInView(ctx, state, params = {}) {
2085
2263
  const scrollTopBuffered = scroll - scrollBufferTop;
2086
2264
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2087
2265
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2088
- if (!dataChanged && scrollForNextCalculateItemsInView) {
2266
+ if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
2089
2267
  const { top, bottom } = scrollForNextCalculateItemsInView;
2090
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2091
- if (state.initialAnchor) {
2092
- ensureInitialAnchor(ctx, state);
2268
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2269
+ if (!IsNewArchitecture && state.initialAnchor) {
2270
+ ensureInitialAnchor(ctx);
2093
2271
  }
2094
2272
  return;
2095
2273
  }
2096
2274
  }
2097
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2275
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
2098
2276
  if (dataChanged) {
2099
2277
  indexByKey.clear();
2100
2278
  idCache.length = 0;
2101
2279
  positions.clear();
2102
2280
  }
2103
- const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2104
- updateItemPositions(ctx, state, dataChanged, {
2281
+ const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2282
+ updateItemPositions(ctx, dataChanged, {
2105
2283
  doMVCP,
2106
2284
  forceFullUpdate: !!forceFullItemPositions,
2107
2285
  scrollBottomBuffered,
@@ -2120,9 +2298,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2120
2298
  for (let i = loopStart; i >= 0; i--) {
2121
2299
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2122
2300
  const top = positions.get(id);
2123
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2301
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
2124
2302
  const bottom = top + size;
2125
- if (bottom > scroll - scrollBuffer) {
2303
+ if (bottom > scroll - scrollBufferTop) {
2126
2304
  loopStart = i;
2127
2305
  } else {
2128
2306
  break;
@@ -2147,7 +2325,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2147
2325
  const dataLength = data.length;
2148
2326
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2149
2327
  const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2150
- const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
2328
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
2151
2329
  const top = positions.get(id);
2152
2330
  if (!foundEnd) {
2153
2331
  if (startNoBuffer === null && top + size > scroll) {
@@ -2159,7 +2337,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2159
2337
  if (startBuffered === null && top + size > scrollTopBuffered) {
2160
2338
  startBuffered = i;
2161
2339
  startBufferedId = id;
2162
- nextTop = top;
2340
+ if (scrollTopBuffered < 0) {
2341
+ nextTop = null;
2342
+ } else {
2343
+ nextTop = top;
2344
+ }
2163
2345
  }
2164
2346
  if (startNoBuffer !== null) {
2165
2347
  if (top <= scrollBottom) {
@@ -2167,7 +2349,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2167
2349
  }
2168
2350
  if (top <= scrollBottomBuffered) {
2169
2351
  endBuffered = i;
2170
- nextBottom = top + size;
2352
+ if (scrollBottomBuffered > totalSize) {
2353
+ nextBottom = null;
2354
+ } else {
2355
+ nextBottom = top + size;
2356
+ }
2171
2357
  } else {
2172
2358
  foundEnd = true;
2173
2359
  }
@@ -2194,7 +2380,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2194
2380
  top: nextTop
2195
2381
  } : void 0;
2196
2382
  }
2197
- const numContainers = peek$(ctx, "numContainers");
2383
+ let numContainers = prevNumContainers;
2198
2384
  const pendingRemoval = [];
2199
2385
  if (dataChanged) {
2200
2386
  for (let i = 0; i < numContainers; i++) {
@@ -2205,7 +2391,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2205
2391
  }
2206
2392
  }
2207
2393
  if (startBuffered !== null && endBuffered !== null) {
2208
- let numContainers2 = prevNumContainers;
2209
2394
  const needNewContainers = [];
2210
2395
  for (let i = startBuffered; i <= endBuffered; i++) {
2211
2396
  const id = (_h = idCache[i]) != null ? _h : getId(state, i);
@@ -2216,7 +2401,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2216
2401
  if (stickyIndicesArr.length > 0) {
2217
2402
  handleStickyActivation(
2218
2403
  ctx,
2219
- state,
2220
2404
  stickyIndicesSet,
2221
2405
  stickyIndicesArr,
2222
2406
  currentStickyIdx,
@@ -2224,9 +2408,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2224
2408
  startBuffered,
2225
2409
  endBuffered
2226
2410
  );
2227
- } else {
2228
- state.activeStickyIndex = void 0;
2229
- set$(ctx, "activeStickyIndex", void 0);
2411
+ } else if (previousStickyIndex !== -1) {
2412
+ set$(ctx, "activeStickyIndex", -1);
2230
2413
  }
2231
2414
  if (needNewContainers.length > 0) {
2232
2415
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2235,7 +2418,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2235
2418
  }) : void 0;
2236
2419
  const availableContainers = findAvailableContainers(
2237
2420
  ctx,
2238
- state,
2239
2421
  needNewContainers.length,
2240
2422
  startBuffered,
2241
2423
  endBuffered,
@@ -2257,29 +2439,30 @@ function calculateItemsInView(ctx, state, params = {}) {
2257
2439
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
2258
2440
  }
2259
2441
  containerItemKeys.add(id);
2442
+ const containerSticky = `containerSticky${containerIndex}`;
2260
2443
  if (stickyIndicesSet.has(i)) {
2261
- set$(ctx, `containerSticky${containerIndex}`, true);
2444
+ set$(ctx, containerSticky, true);
2262
2445
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2263
2446
  set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2264
2447
  state.stickyContainerPool.add(containerIndex);
2265
- } else {
2266
- set$(ctx, `containerSticky${containerIndex}`, false);
2448
+ } else if (peek$(ctx, containerSticky)) {
2449
+ set$(ctx, containerSticky, false);
2267
2450
  state.stickyContainerPool.delete(containerIndex);
2268
2451
  }
2269
- if (containerIndex >= numContainers2) {
2270
- numContainers2 = containerIndex + 1;
2452
+ if (containerIndex >= numContainers) {
2453
+ numContainers = containerIndex + 1;
2271
2454
  }
2272
2455
  }
2273
- if (numContainers2 !== prevNumContainers) {
2274
- set$(ctx, "numContainers", numContainers2);
2275
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
2276
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
2456
+ if (numContainers !== prevNumContainers) {
2457
+ set$(ctx, "numContainers", numContainers);
2458
+ if (numContainers > peek$(ctx, "numContainersPooled")) {
2459
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
2277
2460
  }
2278
2461
  }
2279
2462
  }
2280
2463
  }
2281
2464
  if (stickyIndicesArr.length > 0) {
2282
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2465
+ handleStickyRecycling(ctx, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2283
2466
  }
2284
2467
  let didChangePositions = false;
2285
2468
  for (let i = 0; i < numContainers; i++) {
@@ -2331,7 +2514,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2331
2514
  }
2332
2515
  if (!queuedInitialLayout && endBuffered !== null) {
2333
2516
  if (checkAllSizesKnown(state)) {
2334
- setDidLayout(ctx, state);
2517
+ setDidLayout(ctx);
2335
2518
  }
2336
2519
  }
2337
2520
  if (viewabilityConfigCallbackPairs) {
@@ -2344,8 +2527,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2344
2527
  }
2345
2528
  }
2346
2529
  });
2347
- if (state.initialAnchor) {
2348
- ensureInitialAnchor(ctx, state);
2530
+ if (!IsNewArchitecture && state.initialAnchor) {
2531
+ ensureInitialAnchor(ctx);
2349
2532
  }
2350
2533
  }
2351
2534
 
@@ -2370,19 +2553,22 @@ function checkActualChange(state, dataProp, previousData) {
2370
2553
  }
2371
2554
 
2372
2555
  // src/core/doMaintainScrollAtEnd.ts
2373
- function doMaintainScrollAtEnd(ctx, state, animated) {
2556
+ function doMaintainScrollAtEnd(ctx, animated) {
2557
+ const state = ctx.state;
2374
2558
  const {
2559
+ didContainersLayout,
2560
+ isAtEnd,
2375
2561
  refScroller,
2376
2562
  props: { maintainScrollAtEnd }
2377
2563
  } = state;
2378
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2564
+ if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
2379
2565
  const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2380
2566
  if (paddingTop > 0) {
2381
2567
  state.scroll = 0;
2382
2568
  }
2383
2569
  requestAnimationFrame(() => {
2384
2570
  var _a3;
2385
- if (state == null ? void 0 : state.isAtEnd) {
2571
+ if (state.isAtEnd) {
2386
2572
  state.maintainingScrollAtEnd = true;
2387
2573
  (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2388
2574
  animated
@@ -2453,28 +2639,30 @@ function updateAveragesOnDataChange(state, oldData, newData) {
2453
2639
  }
2454
2640
 
2455
2641
  // src/core/checkResetContainers.ts
2456
- function checkResetContainers(ctx, state, dataProp) {
2642
+ function checkResetContainers(ctx, dataProp) {
2643
+ const state = ctx.state;
2457
2644
  const { previousData } = state;
2458
2645
  if (previousData) {
2459
2646
  updateAveragesOnDataChange(state, previousData, dataProp);
2460
2647
  }
2461
2648
  const { maintainScrollAtEnd } = state.props;
2462
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2649
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2463
2650
  const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2464
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
2651
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
2465
2652
  if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
2466
2653
  state.isEndReached = false;
2467
2654
  }
2468
2655
  if (!didMaintainScrollAtEnd) {
2469
2656
  checkAtTop(state);
2470
- checkAtBottom(ctx, state);
2657
+ checkAtBottom(ctx);
2471
2658
  }
2472
2659
  delete state.previousData;
2473
2660
  }
2474
2661
 
2475
2662
  // src/core/doInitialAllocateContainers.ts
2476
- function doInitialAllocateContainers(ctx, state) {
2663
+ function doInitialAllocateContainers(ctx) {
2477
2664
  var _a3, _b, _c;
2665
+ const state = ctx.state;
2478
2666
  const {
2479
2667
  scrollLength,
2480
2668
  props: {
@@ -2512,10 +2700,10 @@ function doInitialAllocateContainers(ctx, state) {
2512
2700
  if (!IsNewArchitecture || state.lastLayout) {
2513
2701
  if (state.initialScroll) {
2514
2702
  requestAnimationFrame(() => {
2515
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2703
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2516
2704
  });
2517
2705
  } else {
2518
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2706
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2519
2707
  }
2520
2708
  }
2521
2709
  return true;
@@ -2523,7 +2711,8 @@ function doInitialAllocateContainers(ctx, state) {
2523
2711
  }
2524
2712
 
2525
2713
  // src/core/handleLayout.ts
2526
- function handleLayout(ctx, state, layout, setCanRender) {
2714
+ function handleLayout(ctx, layout, setCanRender) {
2715
+ const state = ctx.state;
2527
2716
  const { maintainScrollAtEnd } = state.props;
2528
2717
  const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2529
2718
  const previousLength = state.scrollLength;
@@ -2539,19 +2728,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2539
2728
  state.lastBatchingAction = Date.now();
2540
2729
  state.scrollForNextCalculateItemsInView = void 0;
2541
2730
  if (scrollLength > 0) {
2542
- doInitialAllocateContainers(ctx, state);
2731
+ doInitialAllocateContainers(ctx);
2543
2732
  }
2544
2733
  if (needsCalculate) {
2545
- calculateItemsInView(ctx, state, { doMVCP: true });
2734
+ calculateItemsInView(ctx, { doMVCP: true });
2546
2735
  }
2547
2736
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
2548
2737
  set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
2549
2738
  }
2550
2739
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
2551
- doMaintainScrollAtEnd(ctx, state, false);
2740
+ doMaintainScrollAtEnd(ctx, false);
2552
2741
  }
2553
- updateAlignItemsPaddingTop(ctx, state);
2554
- checkAtBottom(ctx, state);
2742
+ updateAlignItemsPaddingTop(ctx);
2743
+ checkAtBottom(ctx);
2555
2744
  checkAtTop(state);
2556
2745
  if (state) {
2557
2746
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
@@ -2567,8 +2756,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2567
2756
  }
2568
2757
 
2569
2758
  // src/core/onScroll.ts
2570
- function onScroll(ctx, state, event) {
2759
+ function onScroll(ctx, event) {
2571
2760
  var _a3, _b, _c;
2761
+ const state = ctx.state;
2572
2762
  const {
2573
2763
  scrollProcessingEnabled,
2574
2764
  props: { onScroll: onScrollProp }
@@ -2579,9 +2769,23 @@ function onScroll(ctx, state, event) {
2579
2769
  if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
2580
2770
  return;
2581
2771
  }
2582
- const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2772
+ let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2583
2773
  state.scrollPending = newScroll;
2584
- updateScroll(ctx, state, newScroll);
2774
+ if (state.scrollingTo) {
2775
+ const maxOffset = clampScrollOffset(ctx, newScroll);
2776
+ if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
2777
+ newScroll = maxOffset;
2778
+ scrollTo(ctx, {
2779
+ forceScroll: true,
2780
+ isInitialScroll: true,
2781
+ noScrollingTo: true,
2782
+ offset: newScroll
2783
+ });
2784
+ return;
2785
+ }
2786
+ }
2787
+ updateScroll(ctx, newScroll);
2788
+ checkFinishedScroll(ctx);
2585
2789
  onScrollProp == null ? void 0 : onScrollProp(event);
2586
2790
  }
2587
2791
 
@@ -2590,51 +2794,47 @@ var ScrollAdjustHandler = class {
2590
2794
  constructor(ctx) {
2591
2795
  this.appliedAdjust = 0;
2592
2796
  this.pendingAdjust = 0;
2593
- this.mounted = false;
2594
- this.context = ctx;
2595
- if (Platform2.OS === "web") {
2596
- const commitPendingAdjust = () => {
2597
- const state = this.context.internalState;
2598
- const pending = this.pendingAdjust;
2599
- if (pending !== 0) {
2600
- this.pendingAdjust = 0;
2601
- this.appliedAdjust += pending;
2602
- state.scroll += pending;
2603
- state.scrollForNextCalculateItemsInView = void 0;
2604
- set$(this.context, "scrollAdjustPending", 0);
2605
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2606
- calculateItemsInView(this.context, this.context.internalState);
2607
- }
2608
- };
2609
- listen$(this.context, "scrollingTo", (value) => {
2610
- if (value === void 0) {
2611
- commitPendingAdjust();
2612
- }
2613
- });
2614
- }
2797
+ this.ctx = ctx;
2615
2798
  }
2616
2799
  requestAdjust(add) {
2617
- const scrollingTo = peek$(this.context, "scrollingTo");
2800
+ const scrollingTo = this.ctx.state.scrollingTo;
2618
2801
  if (Platform2.OS === "web" && (scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
2619
2802
  this.pendingAdjust += add;
2620
- set$(this.context, "scrollAdjustPending", this.pendingAdjust);
2803
+ set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
2621
2804
  } else {
2622
2805
  this.appliedAdjust += add;
2623
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2806
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2807
+ }
2808
+ if (this.ctx.state.scrollingTo) {
2809
+ checkFinishedScroll(this.ctx);
2624
2810
  }
2625
- }
2626
- setMounted() {
2627
- this.mounted = true;
2628
2811
  }
2629
2812
  getAdjust() {
2630
2813
  return this.appliedAdjust;
2631
2814
  }
2815
+ commitPendingAdjust() {
2816
+ if (Platform2.OS === "web") {
2817
+ const state = this.ctx.state;
2818
+ const pending = this.pendingAdjust;
2819
+ if (pending !== 0) {
2820
+ this.pendingAdjust = 0;
2821
+ this.appliedAdjust += pending;
2822
+ state.scroll += pending;
2823
+ state.scrollForNextCalculateItemsInView = void 0;
2824
+ set$(this.ctx, "scrollAdjustPending", 0);
2825
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2826
+ calculateItemsInView(this.ctx);
2827
+ }
2828
+ }
2829
+ }
2632
2830
  };
2633
2831
 
2634
2832
  // src/core/updateItemSize.ts
2635
- function updateItemSize(ctx, state, itemKey, sizeObj) {
2833
+ function updateItemSize(ctx, itemKey, sizeObj) {
2636
2834
  var _a3;
2835
+ const state = ctx.state;
2637
2836
  const {
2837
+ didContainersLayout,
2638
2838
  sizesKnown,
2639
2839
  props: {
2640
2840
  getFixedItemSize,
@@ -2662,13 +2862,12 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2662
2862
  return;
2663
2863
  }
2664
2864
  }
2665
- const containersDidLayout = peek$(ctx, "containersDidLayout");
2666
- let needsRecalculate = !containersDidLayout;
2865
+ let needsRecalculate = !didContainersLayout;
2667
2866
  let shouldMaintainScrollAtEnd = false;
2668
2867
  let minIndexSizeChanged;
2669
2868
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
2670
2869
  const prevSizeKnown = state.sizesKnown.get(itemKey);
2671
- const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
2870
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj);
2672
2871
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
2673
2872
  if (diff !== 0) {
2674
2873
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -2717,22 +2916,22 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2717
2916
  if (!cur || maxOtherAxisSize > cur) {
2718
2917
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
2719
2918
  }
2720
- if (containersDidLayout || checkAllSizesKnown(state)) {
2919
+ if (didContainersLayout || checkAllSizesKnown(state)) {
2721
2920
  if (needsRecalculate) {
2722
2921
  state.scrollForNextCalculateItemsInView = void 0;
2723
- calculateItemsInView(ctx, state, { doMVCP: true });
2922
+ calculateItemsInView(ctx, { doMVCP: true });
2724
2923
  }
2725
2924
  if (shouldMaintainScrollAtEnd) {
2726
2925
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
2727
- doMaintainScrollAtEnd(ctx, state, false);
2926
+ doMaintainScrollAtEnd(ctx, false);
2728
2927
  }
2729
2928
  }
2730
2929
  }
2731
2930
  }
2732
- function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2931
+ function updateOneItemSize(ctx, itemKey, sizeObj) {
2733
2932
  var _a3;
2933
+ const state = ctx.state;
2734
2934
  const {
2735
- sizes,
2736
2935
  indexByKey,
2737
2936
  sizesKnown,
2738
2937
  averageSizes,
@@ -2740,9 +2939,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2740
2939
  } = state;
2741
2940
  if (!data) return 0;
2742
2941
  const index = indexByKey.get(itemKey);
2743
- const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
2942
+ const prevSize = getItemSize(ctx, itemKey, index, data[index]);
2744
2943
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2745
2944
  const size = Platform2.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
2945
+ const prevSizeKnown = sizesKnown.get(itemKey);
2746
2946
  sizesKnown.set(itemKey, size);
2747
2947
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2748
2948
  const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
@@ -2750,11 +2950,15 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2750
2950
  if (!averages) {
2751
2951
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
2752
2952
  }
2753
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2754
- averages.num++;
2953
+ if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
2954
+ averages.avg += (size - prevSizeKnown) / averages.num;
2955
+ } else {
2956
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2957
+ averages.num++;
2958
+ }
2755
2959
  }
2756
2960
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2757
- setSize(ctx, state, itemKey, size);
2961
+ setSize(ctx, itemKey, size);
2758
2962
  return size - prevSize;
2759
2963
  }
2760
2964
  return 0;
@@ -2820,14 +3024,15 @@ function createColumnWrapperStyle(contentContainerStyle) {
2820
3024
  }
2821
3025
 
2822
3026
  // src/utils/createImperativeHandle.ts
2823
- function createImperativeHandle(ctx, state) {
3027
+ function createImperativeHandle(ctx) {
3028
+ const state = ctx.state;
2824
3029
  const scrollIndexIntoView = (options) => {
2825
3030
  if (state) {
2826
3031
  const { index, ...rest } = options;
2827
3032
  const { startNoBuffer, endNoBuffer } = state;
2828
3033
  if (index < startNoBuffer || index > endNoBuffer) {
2829
3034
  const viewPosition = index < startNoBuffer ? 0 : 1;
2830
- scrollToIndex(ctx, state, {
3035
+ scrollToIndex(ctx, {
2831
3036
  ...rest,
2832
3037
  index,
2833
3038
  viewPosition
@@ -2842,7 +3047,7 @@ function createImperativeHandle(ctx, state) {
2842
3047
  getScrollableNode: () => refScroller.current.getScrollableNode(),
2843
3048
  getScrollResponder: () => refScroller.current.getScrollResponder(),
2844
3049
  getState: () => ({
2845
- activeStickyIndex: state.activeStickyIndex,
3050
+ activeStickyIndex: peek$(ctx, "activeStickyIndex"),
2846
3051
  contentLength: state.totalSize,
2847
3052
  data: state.props.data,
2848
3053
  elementAtIndex: (index) => {
@@ -2853,6 +3058,8 @@ function createImperativeHandle(ctx, state) {
2853
3058
  endBuffered: state.endBuffered,
2854
3059
  isAtEnd: state.isAtEnd,
2855
3060
  isAtStart: state.isAtStart,
3061
+ listen: (signalName, cb) => listen$(ctx, signalName, cb),
3062
+ listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
2856
3063
  positionAtIndex: (index) => state.positions.get(getId(state, index)),
2857
3064
  positions: state.positions,
2858
3065
  scroll: state.scroll,
@@ -2877,23 +3084,23 @@ function createImperativeHandle(ctx, state) {
2877
3084
  if (index !== -1) {
2878
3085
  const paddingBottom = stylePaddingBottom || 0;
2879
3086
  const footerSize = peek$(ctx, "footerSize") || 0;
2880
- scrollToIndex(ctx, state, {
3087
+ scrollToIndex(ctx, {
3088
+ ...options,
2881
3089
  index,
2882
3090
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
2883
- viewPosition: 1,
2884
- ...options
3091
+ viewPosition: 1
2885
3092
  });
2886
3093
  }
2887
3094
  },
2888
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3095
+ scrollToIndex: (params) => scrollToIndex(ctx, params),
2889
3096
  scrollToItem: ({ item, ...props }) => {
2890
3097
  const data = state.props.data;
2891
3098
  const index = data.indexOf(item);
2892
3099
  if (index !== -1) {
2893
- scrollToIndex(ctx, state, { index, ...props });
3100
+ scrollToIndex(ctx, { index, ...props });
2894
3101
  }
2895
3102
  },
2896
- scrollToOffset: (params) => scrollTo(ctx, state, params),
3103
+ scrollToOffset: (params) => scrollTo(ctx, params),
2897
3104
  setScrollProcessingEnabled: (enabled) => {
2898
3105
  state.scrollProcessingEnabled = enabled;
2899
3106
  },
@@ -2903,8 +3110,9 @@ function createImperativeHandle(ctx, state) {
2903
3110
  }
2904
3111
  };
2905
3112
  }
2906
- function getRenderedItem(ctx, state, key) {
3113
+ function getRenderedItem(ctx, key) {
2907
3114
  var _a3;
3115
+ const state = ctx.state;
2908
3116
  if (!state) {
2909
3117
  return null;
2910
3118
  }
@@ -2981,11 +3189,13 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
2981
3189
  var DEFAULT_DRAW_DISTANCE = 250;
2982
3190
  var DEFAULT_ITEM_SIZE = 100;
2983
3191
  var LegendList = typedMemo(
3192
+ // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
2984
3193
  typedForwardRef(function LegendList2(props, forwardedRef) {
2985
3194
  const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
2986
3195
  const isChildrenMode = children !== void 0 && dataProp === void 0;
2987
3196
  const processedProps = isChildrenMode ? {
2988
3197
  ...restProps,
3198
+ childrenMode: true,
2989
3199
  data: (isArray(children) ? children : React2.Children.toArray(children)).flat(1),
2990
3200
  renderItem: ({ item }) => item
2991
3201
  } : {
@@ -3002,10 +3212,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3002
3212
  alignItemsAtEnd = false,
3003
3213
  columnWrapperStyle,
3004
3214
  contentContainerStyle: contentContainerStyleProp,
3215
+ contentInset,
3005
3216
  data: dataProp = [],
3006
3217
  dataVersion,
3007
3218
  drawDistance = 250,
3008
- enableAverages = true,
3009
3219
  estimatedItemSize: estimatedItemSizeProp,
3010
3220
  estimatedListSize,
3011
3221
  extraData,
@@ -3047,6 +3257,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3047
3257
  snapToIndices,
3048
3258
  stickyHeaderIndices: stickyHeaderIndicesProp,
3049
3259
  stickyIndices: stickyIndicesDeprecated,
3260
+ // TODOV3: Remove from v3 release
3050
3261
  style: styleProp,
3051
3262
  suggestEstimatedItemSize,
3052
3263
  viewabilityConfig,
@@ -3054,6 +3265,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3054
3265
  waitForInitialLayout = true,
3055
3266
  ...rest
3056
3267
  } = props;
3268
+ const animatedPropsInternal = props.animatedPropsInternal;
3269
+ const { childrenMode } = rest;
3057
3270
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
3058
3271
  const style = { ...StyleSheet.flatten(styleProp) };
3059
3272
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -3077,10 +3290,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3077
3290
  }
3078
3291
  const refState = useRef();
3079
3292
  if (!refState.current) {
3080
- if (!ctx.internalState) {
3293
+ if (!ctx.state) {
3081
3294
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : getWindowSize())[horizontal ? "width" : "height"];
3082
- ctx.internalState = {
3083
- activeStickyIndex: void 0,
3295
+ ctx.state = {
3296
+ activeStickyIndex: -1,
3084
3297
  averageSizes: {},
3085
3298
  columns: /* @__PURE__ */ new Map(),
3086
3299
  containerItemKeys: /* @__PURE__ */ new Set(),
@@ -3106,9 +3319,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3106
3319
  initialScroll: initialScrollProp,
3107
3320
  isAtEnd: false,
3108
3321
  isAtStart: false,
3109
- isEndReached: false,
3322
+ isEndReached: null,
3110
3323
  isFirst: true,
3111
- isStartReached: false,
3324
+ isStartReached: null,
3112
3325
  lastBatchingAction: Date.now(),
3113
3326
  lastLayout: void 0,
3114
3327
  loadStartTime: Date.now(),
@@ -3140,12 +3353,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3140
3353
  totalSize: 0,
3141
3354
  viewabilityConfigCallbackPairs: void 0
3142
3355
  };
3143
- const internalState = ctx.internalState;
3144
- internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
3356
+ const internalState = ctx.state;
3357
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3145
3358
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3146
3359
  set$(ctx, "extraData", extraData);
3147
3360
  }
3148
- refState.current = ctx.internalState;
3361
+ refState.current = ctx.state;
3149
3362
  }
3150
3363
  const state = refState.current;
3151
3364
  const isFirstLocal = state.isFirst;
@@ -3159,9 +3372,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3159
3372
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
3160
3373
  state.props = {
3161
3374
  alignItemsAtEnd,
3375
+ animatedProps: animatedPropsInternal,
3376
+ contentInset,
3162
3377
  data: dataProp,
3163
3378
  dataVersion,
3164
- enableAverages,
3165
3379
  estimatedItemSize,
3166
3380
  getEstimatedItemSize,
3167
3381
  getFixedItemSize,
@@ -3204,62 +3418,62 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3204
3418
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3205
3419
  set$(ctx, "numColumns", numColumnsProp);
3206
3420
  const prevPaddingTop = peek$(ctx, "stylePaddingTop");
3207
- setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3421
+ setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3208
3422
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3209
3423
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3210
3424
  if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3211
3425
  if (state.scroll < 0) {
3212
3426
  paddingDiff += state.scroll;
3213
3427
  }
3214
- requestAdjust(ctx, state, paddingDiff);
3428
+ requestAdjust(ctx, paddingDiff);
3215
3429
  }
3216
3430
  };
3217
3431
  if (isFirstLocal) {
3218
3432
  initializeStateVars();
3219
3433
  updateItemPositions(
3220
3434
  ctx,
3221
- state,
3222
3435
  /*dataChanged*/
3223
3436
  true
3224
3437
  );
3225
3438
  }
3226
3439
  const initialContentOffset = useMemo(() => {
3227
- var _a4, _b2;
3228
- const { initialScroll } = refState.current;
3229
- if (!initialScroll) {
3440
+ var _a4;
3441
+ let value;
3442
+ const { initialScroll, initialAnchor } = refState.current;
3443
+ if (initialScroll) {
3444
+ if (!IsNewArchitecture && initialScroll.index !== void 0 && (!initialAnchor || (initialAnchor == null ? void 0 : initialAnchor.index) !== initialScroll.index)) {
3445
+ refState.current.initialAnchor = {
3446
+ attempts: 0,
3447
+ index: initialScroll.index,
3448
+ settledTicks: 0,
3449
+ viewOffset: (_a4 = initialScroll.viewOffset) != null ? _a4 : 0,
3450
+ viewPosition: initialScroll.viewPosition
3451
+ };
3452
+ }
3453
+ if (initialScroll.contentOffset !== void 0) {
3454
+ value = initialScroll.contentOffset;
3455
+ } else {
3456
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
3457
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
3458
+ const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
3459
+ const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3460
+ refState.current.initialScroll = updatedInitialScroll;
3461
+ state.initialScroll = updatedInitialScroll;
3462
+ value = clampedOffset;
3463
+ }
3464
+ } else {
3230
3465
  refState.current.initialAnchor = void 0;
3231
- return 0;
3232
- }
3233
- if (initialScroll.index !== void 0 && (!refState.current.initialAnchor || ((_a4 = refState.current.initialAnchor) == null ? void 0 : _a4.index) !== initialScroll.index)) {
3234
- refState.current.initialAnchor = {
3235
- attempts: 0,
3236
- index: initialScroll.index,
3237
- settledTicks: 0,
3238
- viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
3239
- viewPosition: initialScroll.viewPosition
3240
- };
3466
+ value = 0;
3467
+ }
3468
+ if (!value) {
3469
+ state.didFinishInitialScroll = true;
3241
3470
  }
3242
- if (initialScroll.contentOffset !== void 0) {
3243
- return initialScroll.contentOffset;
3244
- }
3245
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
3246
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
3247
- let clampedOffset = resolvedOffset;
3248
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
3249
- const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
3250
- clampedOffset = Math.min(clampedOffset, maxOffset);
3251
- }
3252
- clampedOffset = Math.max(0, clampedOffset);
3253
- const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3254
- refState.current.initialScroll = updatedInitialScroll;
3255
- state.initialScroll = updatedInitialScroll;
3256
- refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
3257
- return clampedOffset;
3471
+ return value;
3258
3472
  }, [renderNum]);
3259
3473
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
3260
3474
  refState.current.lastBatchingAction = Date.now();
3261
3475
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
3262
- IS_DEV && warnDevOnce(
3476
+ IS_DEV && !childrenMode && warnDevOnce(
3263
3477
  "keyExtractor",
3264
3478
  "Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
3265
3479
  );
@@ -3284,12 +3498,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3284
3498
  }
3285
3499
  }, []);
3286
3500
  const doInitialScroll = useCallback(() => {
3287
- var _a4;
3288
3501
  const initialScroll = state.initialScroll;
3289
3502
  if (initialScroll) {
3290
- scrollTo(ctx, state, {
3503
+ scrollTo(ctx, {
3291
3504
  animated: false,
3292
- index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
3505
+ index: initialScroll == null ? void 0 : initialScroll.index,
3293
3506
  isInitialScroll: true,
3294
3507
  offset: initialContentOffset,
3295
3508
  precomputedWithViewOffset: true
@@ -3298,7 +3511,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3298
3511
  }, [initialContentOffset]);
3299
3512
  const onLayoutChange = useCallback((layout) => {
3300
3513
  doInitialScroll();
3301
- handleLayout(ctx, state, layout, setCanRender);
3514
+ handleLayout(ctx, layout, setCanRender);
3302
3515
  }, []);
3303
3516
  const { onLayout } = useOnLayoutSync({
3304
3517
  onLayoutChange,
@@ -3308,7 +3521,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3308
3521
  });
3309
3522
  useLayoutEffect(() => {
3310
3523
  if (snapToIndices) {
3311
- updateSnapToOffsets(ctx, state);
3524
+ updateSnapToOffsets(ctx);
3312
3525
  }
3313
3526
  }, [snapToIndices]);
3314
3527
  useLayoutEffect(() => {
@@ -3318,9 +3531,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3318
3531
  isFirst,
3319
3532
  props: { data }
3320
3533
  } = state;
3321
- const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
3534
+ const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
3322
3535
  if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
3323
- checkResetContainers(ctx, state, data);
3536
+ checkResetContainers(ctx, data);
3324
3537
  }
3325
3538
  state.didColumnsChange = false;
3326
3539
  state.didDataChange = false;
@@ -3347,18 +3560,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3347
3560
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
3348
3561
  if (!IsNewArchitecture) {
3349
3562
  useInit(() => {
3350
- doInitialAllocateContainers(ctx, state);
3563
+ doInitialAllocateContainers(ctx);
3351
3564
  });
3352
3565
  }
3353
- useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
3566
+ useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
3354
3567
  if (Platform2.OS === "web") {
3355
3568
  useEffect(doInitialScroll, []);
3356
3569
  }
3357
3570
  const fns = useMemo(
3358
3571
  () => ({
3359
- getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3360
- onScroll: (event) => onScroll(ctx, state, event),
3361
- updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj)
3572
+ getRenderedItem: (key) => getRenderedItem(ctx, key),
3573
+ onMomentumScrollEnd: (event) => {
3574
+ checkFinishedScrollFallback(ctx);
3575
+ if (onMomentumScrollEnd) {
3576
+ onMomentumScrollEnd(event);
3577
+ }
3578
+ },
3579
+ onScroll: (event) => onScroll(ctx, event),
3580
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
3362
3581
  }),
3363
3582
  []
3364
3583
  );
@@ -3370,6 +3589,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3370
3589
  alignItemsAtEnd,
3371
3590
  canRender,
3372
3591
  contentContainerStyle,
3592
+ contentInset,
3373
3593
  getRenderedItem: fns.getRenderedItem,
3374
3594
  horizontal,
3375
3595
  initialContentOffset,
@@ -3378,20 +3598,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3378
3598
  maintainVisibleContentPosition,
3379
3599
  onLayout,
3380
3600
  onLayoutHeader,
3381
- onMomentumScrollEnd: (event) => {
3382
- if (IsNewArchitecture) {
3383
- requestAnimationFrame(() => {
3384
- finishScrollTo(ctx, refState.current);
3385
- });
3386
- } else {
3387
- setTimeout(() => {
3388
- finishScrollTo(ctx, refState.current);
3389
- }, 1e3);
3390
- }
3391
- if (onMomentumScrollEnd) {
3392
- onMomentumScrollEnd(event);
3393
- }
3394
- },
3601
+ onMomentumScrollEnd: fns.onMomentumScrollEnd,
3395
3602
  onScroll: onScrollHandler,
3396
3603
  recycleItems,
3397
3604
  refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2.cloneElement(refreshControl, {
@@ -3406,7 +3613,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3406
3613
  ),
3407
3614
  refScrollView: combinedRef,
3408
3615
  scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3409
- scrollEventThrottle: Platform2.OS === "web" ? 16 : void 0,
3616
+ scrollEventThrottle: 0,
3410
3617
  snapToIndices,
3411
3618
  stickyHeaderIndices,
3412
3619
  style,
@@ -3452,8 +3659,8 @@ function buildSectionListData({
3452
3659
  if (hasHeader) {
3453
3660
  const headerIndex = data.length;
3454
3661
  data.push({
3455
- kind: "header",
3456
3662
  key: `${sectionKey}:header`,
3663
+ kind: "header",
3457
3664
  section,
3458
3665
  sectionIndex
3459
3666
  });
@@ -3467,31 +3674,31 @@ function buildSectionListData({
3467
3674
  const itemKeyExtractor = (_b = section.keyExtractor) != null ? _b : keyExtractor;
3468
3675
  const itemKey = itemKeyExtractor(item, itemIndex);
3469
3676
  data.push({
3470
- kind: "item",
3471
- key: `${sectionKey}:item:${itemKey}`,
3472
- section,
3473
- sectionIndex,
3677
+ absoluteItemIndex: absoluteItemIndex++,
3474
3678
  item,
3475
3679
  itemIndex,
3476
- absoluteItemIndex: absoluteItemIndex++
3680
+ key: `${sectionKey}:item:${itemKey}`,
3681
+ kind: "item",
3682
+ section,
3683
+ sectionIndex
3477
3684
  });
3478
3685
  meta.items.push(data.length - 1);
3479
3686
  if (hasItemSeparator && itemIndex < items.length - 1) {
3480
3687
  data.push({
3481
- kind: "item-separator",
3482
3688
  key: `${sectionKey}:separator:${itemIndex}`,
3483
- section,
3484
- sectionIndex,
3689
+ kind: "item-separator",
3485
3690
  leadingItem: item,
3486
3691
  leadingItemIndex: itemIndex,
3692
+ section,
3693
+ sectionIndex,
3487
3694
  trailingItem: items[itemIndex + 1]
3488
3695
  });
3489
3696
  }
3490
3697
  }
3491
3698
  if (hasFooter) {
3492
3699
  data.push({
3493
- kind: "footer",
3494
3700
  key: `${sectionKey}:footer`,
3701
+ kind: "footer",
3495
3702
  section,
3496
3703
  sectionIndex
3497
3704
  });
@@ -3500,8 +3707,8 @@ function buildSectionListData({
3500
3707
  const isLastSection = sectionIndex === sections.length - 1;
3501
3708
  if (hasSectionSeparator && !isLastSection) {
3502
3709
  data.push({
3503
- kind: "section-separator",
3504
3710
  key: `${sectionKey}:section-separator`,
3711
+ kind: "section-separator",
3505
3712
  leadingSection: section,
3506
3713
  leadingSectionIndex: sectionIndex,
3507
3714
  trailingSection: sections[sectionIndex + 1]