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

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.
@@ -28,30 +28,64 @@ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
28
28
  reactNative.Animated.View;
29
29
  var View = reactNative.View;
30
30
  var Text = reactNative.Text;
31
+
32
+ // src/state/getContentInsetEnd.ts
33
+ function getContentInsetEnd(state) {
34
+ var _a3;
35
+ const { props } = state;
36
+ const horizontal = props.horizontal;
37
+ let contentInset = props.contentInset;
38
+ if (!contentInset) {
39
+ const animatedInset = (_a3 = props.animatedProps) == null ? void 0 : _a3.contentInset;
40
+ if (animatedInset) {
41
+ if ("get" in animatedInset) {
42
+ contentInset = animatedInset.get();
43
+ } else {
44
+ contentInset = animatedInset;
45
+ }
46
+ }
47
+ }
48
+ return (horizontal ? contentInset == null ? void 0 : contentInset.right : contentInset == null ? void 0 : contentInset.bottom) || 0;
49
+ }
50
+
51
+ // src/state/getContentSize.ts
52
+ function getContentSize(ctx) {
53
+ var _a3;
54
+ const { values, state } = ctx;
55
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
56
+ const stylePaddingBottom = state.props.stylePaddingBottom || 0;
57
+ const headerSize = values.get("headerSize") || 0;
58
+ const footerSize = values.get("footerSize") || 0;
59
+ const contentInsetBottom = getContentInsetEnd(state);
60
+ const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
61
+ return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
62
+ }
31
63
  var createAnimatedValue = (value) => new reactNative.Animated.Value(value);
32
64
 
33
65
  // src/state/state.tsx
34
66
  var ContextState = React2__namespace.createContext(null);
67
+ var contextNum = 0;
35
68
  function StateProvider({ children }) {
36
69
  const [value] = React2__namespace.useState(() => ({
37
70
  animatedScrollY: createAnimatedValue(0),
38
71
  columnWrapperStyle: void 0,
39
- internalState: void 0,
72
+ contextNum: contextNum++,
40
73
  listeners: /* @__PURE__ */ new Map(),
41
74
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
42
75
  mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
43
76
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
44
77
  mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
45
78
  mapViewabilityValues: /* @__PURE__ */ new Map(),
79
+ positionListeners: /* @__PURE__ */ new Map(),
80
+ state: void 0,
46
81
  values: /* @__PURE__ */ new Map([
47
82
  ["alignItemsPaddingTop", 0],
48
83
  ["stylePaddingTop", 0],
49
84
  ["headerSize", 0],
50
85
  ["numContainers", 0],
51
- ["activeStickyIndex", void 0],
86
+ ["activeStickyIndex", -1],
52
87
  ["totalSize", 0],
53
- ["scrollAdjustPending", 0],
54
- ["scrollingTo", void 0]
88
+ ["scrollAdjustPending", 0]
55
89
  ]),
56
90
  viewRefs: /* @__PURE__ */ new Map()
57
91
  }));
@@ -119,15 +153,24 @@ function set$(ctx, signalName, value) {
119
153
  }
120
154
  }
121
155
  }
122
- function getContentSize(ctx) {
123
- var _a3, _b;
124
- const { values, internalState } = ctx;
125
- const stylePaddingTop = values.get("stylePaddingTop") || 0;
126
- const stylePaddingBottom = (internalState == null ? void 0 : internalState.props.stylePaddingBottom) || 0;
127
- const headerSize = values.get("headerSize") || 0;
128
- const footerSize = values.get("footerSize") || 0;
129
- const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
130
- return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom;
156
+ function listenPosition$(ctx, key, cb) {
157
+ const { positionListeners } = ctx;
158
+ let setListeners = positionListeners.get(key);
159
+ if (!setListeners) {
160
+ setListeners = /* @__PURE__ */ new Set();
161
+ positionListeners.set(key, setListeners);
162
+ }
163
+ setListeners.add(cb);
164
+ return () => setListeners.delete(cb);
165
+ }
166
+ function notifyPosition$(ctx, key, value) {
167
+ const { positionListeners } = ctx;
168
+ const setListeners = positionListeners.get(key);
169
+ if (setListeners) {
170
+ for (const listener of setListeners) {
171
+ listener(value);
172
+ }
173
+ }
131
174
  }
132
175
  function useArr$(signalNames) {
133
176
  const ctx = React2__namespace.useContext(ContextState);
@@ -208,7 +251,8 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
208
251
  // src/constants-platform.native.ts
209
252
  var IsNewArchitecture = global.nativeFabricUIManager != null;
210
253
  var useAnimatedValue = (initialValue) => {
211
- return React2.useRef(new reactNative.Animated.Value(initialValue)).current;
254
+ const [animAnimatedValue] = React2.useState(() => new reactNative.Animated.Value(initialValue));
255
+ return animAnimatedValue;
212
256
  };
213
257
 
214
258
  // src/utils/helpers.ts
@@ -297,7 +341,7 @@ var typedForwardRef = React2.forwardRef;
297
341
  var typedMemo = React2.memo;
298
342
 
299
343
  // src/components/PositionView.native.tsx
300
- var PositionViewState = typedMemo(function PositionView({
344
+ var PositionViewState = typedMemo(function PositionViewState2({
301
345
  id,
302
346
  horizontal,
303
347
  style,
@@ -317,7 +361,7 @@ var PositionViewState = typedMemo(function PositionView({
317
361
  }
318
362
  );
319
363
  });
320
- var PositionViewAnimated = typedMemo(function PositionView2({
364
+ var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
321
365
  id,
322
366
  horizontal,
323
367
  style,
@@ -360,14 +404,9 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
360
404
  const viewStyle = React2__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
361
405
  return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest });
362
406
  });
363
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
364
- var symbolFirst = Symbol();
407
+ var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
365
408
  function useInit(cb) {
366
- const refValue = React2.useRef(symbolFirst);
367
- if (refValue.current === symbolFirst) {
368
- refValue.current = cb();
369
- }
370
- return refValue.current;
409
+ React2.useState(() => cb());
371
410
  }
372
411
 
373
412
  // src/state/ContextContainer.ts
@@ -534,6 +573,7 @@ var Container = typedMemo(function Container2({
534
573
  if (!IsNewArchitecture) {
535
574
  React2.useEffect(() => {
536
575
  if (!isNullOrUndefined(itemKey)) {
576
+ didLayoutRef.current = false;
537
577
  const timeout = setTimeout(() => {
538
578
  if (!didLayoutRef.current) {
539
579
  const {
@@ -553,7 +593,7 @@ var Container = typedMemo(function Container2({
553
593
  }
554
594
  }, [itemKey]);
555
595
  }
556
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
596
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView;
557
597
  return /* @__PURE__ */ React2__namespace.createElement(
558
598
  PositionComponent,
559
599
  {
@@ -588,10 +628,10 @@ var Containers = typedMemo(function Containers2({
588
628
  // If this is the initial scroll, we don't want to delay because we want to update the size immediately
589
629
  delay: (value, prevValue) => {
590
630
  var _a3;
591
- return !((_a3 = ctx.internalState) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
631
+ return !((_a3 = ctx.state) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
592
632
  }
593
633
  });
594
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
634
+ const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("readyToRender", { getValue: (value) => value ? 1 : 0 }) : void 0;
595
635
  const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
596
636
  const containers = [];
597
637
  for (let i = 0; i < numContainers; i++) {
@@ -634,7 +674,8 @@ var Containers = typedMemo(function Containers2({
634
674
  return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style }, containers);
635
675
  });
636
676
  function DevNumbers() {
637
- return IS_DEV && React2__namespace.memo(function DevNumbers2() {
677
+ return IS_DEV && // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
678
+ React2__namespace.memo(function DevNumbers2() {
638
679
  return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2__namespace.createElement(
639
680
  reactNative.View,
640
681
  {
@@ -742,13 +783,6 @@ var ListComponent = typedMemo(function ListComponent2({
742
783
  () => React2__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
743
784
  [renderScrollComponent]
744
785
  ) : ListComponentScrollView;
745
- React2__namespace.useEffect(() => {
746
- if (canRender) {
747
- setTimeout(() => {
748
- scrollAdjustHandler.setMounted();
749
- }, 0);
750
- }
751
- }, [canRender]);
752
786
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
753
787
  return /* @__PURE__ */ React2__namespace.createElement(
754
788
  SnapOrScroll,
@@ -812,10 +846,11 @@ function getId(state, index) {
812
846
  }
813
847
 
814
848
  // src/core/calculateOffsetForIndex.ts
815
- function calculateOffsetForIndex(ctx, state, index) {
849
+ function calculateOffsetForIndex(ctx, index) {
850
+ const state = ctx.state;
816
851
  let position = 0;
817
852
  if (index !== void 0) {
818
- position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
853
+ position = state.positions.get(getId(state, index)) || 0;
819
854
  const paddingTop = peek$(ctx, "stylePaddingTop");
820
855
  if (paddingTop) {
821
856
  position += paddingTop;
@@ -829,7 +864,8 @@ function calculateOffsetForIndex(ctx, state, index) {
829
864
  }
830
865
 
831
866
  // src/utils/setPaddingTop.ts
832
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
867
+ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
868
+ const state = ctx.state;
833
869
  if (stylePaddingTop !== void 0) {
834
870
  const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
835
871
  if (stylePaddingTop < prevStylePaddingTop) {
@@ -848,7 +884,8 @@ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
848
884
  }
849
885
 
850
886
  // src/utils/updateAlignItemsPaddingTop.ts
851
- function updateAlignItemsPaddingTop(ctx, state) {
887
+ function updateAlignItemsPaddingTop(ctx) {
888
+ const state = ctx.state;
852
889
  const {
853
890
  scrollLength,
854
891
  props: { alignItemsAtEnd, data }
@@ -859,12 +896,13 @@ function updateAlignItemsPaddingTop(ctx, state) {
859
896
  const contentSize = getContentSize(ctx);
860
897
  alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
861
898
  }
862
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
899
+ setPaddingTop(ctx, { alignItemsPaddingTop });
863
900
  }
864
901
  }
865
902
 
866
903
  // src/core/addTotalSize.ts
867
- function addTotalSize(ctx, state, key, add) {
904
+ function addTotalSize(ctx, key, add) {
905
+ const state = ctx.state;
868
906
  const { alignItemsAtEnd } = state.props;
869
907
  const prevTotalSize = state.totalSize;
870
908
  let totalSize = state.totalSize;
@@ -885,31 +923,34 @@ function addTotalSize(ctx, state, key, add) {
885
923
  state.totalSize = totalSize;
886
924
  set$(ctx, "totalSize", totalSize);
887
925
  if (alignItemsAtEnd) {
888
- updateAlignItemsPaddingTop(ctx, state);
926
+ updateAlignItemsPaddingTop(ctx);
889
927
  }
890
928
  }
891
929
  }
892
930
  }
893
931
 
894
932
  // src/core/setSize.ts
895
- function setSize(ctx, state, itemKey, size) {
933
+ function setSize(ctx, itemKey, size) {
934
+ const state = ctx.state;
896
935
  const { sizes } = state;
897
936
  const previousSize = sizes.get(itemKey);
898
937
  const diff = previousSize !== void 0 ? size - previousSize : size;
899
938
  if (diff !== 0) {
900
- addTotalSize(ctx, state, itemKey, diff);
939
+ addTotalSize(ctx, itemKey, diff);
901
940
  }
902
941
  sizes.set(itemKey, size);
903
942
  }
904
943
 
905
944
  // src/utils/getItemSize.ts
906
- function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
945
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
907
946
  var _a3, _b;
947
+ const state = ctx.state;
908
948
  const {
909
949
  sizesKnown,
910
950
  sizes,
911
951
  averageSizes,
912
- props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
952
+ props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
953
+ scrollingTo
913
954
  } = state;
914
955
  const sizeKnown = sizesKnown.get(key);
915
956
  if (sizeKnown !== void 0) {
@@ -917,7 +958,6 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
917
958
  }
918
959
  let size;
919
960
  const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
920
- const scrollingTo = peek$(ctx, "scrollingTo");
921
961
  if (preferCachedSize) {
922
962
  const cachedSize = sizes.get(key);
923
963
  if (cachedSize !== void 0) {
@@ -945,84 +985,167 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
945
985
  if (size === void 0) {
946
986
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
947
987
  }
948
- setSize(ctx, state, key, size);
988
+ setSize(ctx, key, size);
949
989
  return size;
950
990
  }
951
991
 
952
992
  // src/core/calculateOffsetWithOffsetPosition.ts
953
- function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
993
+ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
994
+ const state = ctx.state;
954
995
  const { index, viewOffset, viewPosition } = params;
955
996
  let offset = offsetParam;
956
997
  if (viewOffset) {
957
998
  offset -= viewOffset;
958
999
  }
959
1000
  if (viewPosition !== void 0 && index !== void 0) {
960
- offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
1001
+ const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1002
+ const trailingInset = getContentInsetEnd(state);
1003
+ offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
961
1004
  }
962
1005
  return offset;
963
1006
  }
964
1007
 
1008
+ // src/core/clampScrollOffset.ts
1009
+ function clampScrollOffset(ctx, offset) {
1010
+ const state = ctx.state;
1011
+ const contentSize = getContentSize(ctx);
1012
+ let clampedOffset = offset;
1013
+ if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength)) {
1014
+ const maxOffset = Math.max(0, contentSize - state.scrollLength);
1015
+ clampedOffset = Math.min(offset, maxOffset);
1016
+ }
1017
+ clampedOffset = Math.max(0, clampedOffset);
1018
+ return clampedOffset;
1019
+ }
1020
+ var Platform2 = reactNative.Platform;
1021
+
1022
+ // src/utils/setInitialRenderState.ts
1023
+ function setInitialRenderState(ctx, {
1024
+ didLayout,
1025
+ didInitialScroll
1026
+ }) {
1027
+ const { state } = ctx;
1028
+ if (didLayout) {
1029
+ state.didContainersLayout = true;
1030
+ }
1031
+ if (didInitialScroll) {
1032
+ state.didFinishInitialScroll = true;
1033
+ }
1034
+ if (state.didContainersLayout && state.didFinishInitialScroll) {
1035
+ set$(ctx, "readyToRender", true);
1036
+ }
1037
+ }
1038
+
965
1039
  // src/core/finishScrollTo.ts
966
- function finishScrollTo(ctx, state) {
1040
+ function finishScrollTo(ctx) {
967
1041
  var _a3, _b;
968
- if (state) {
1042
+ const state = ctx.state;
1043
+ if (state == null ? void 0 : state.scrollingTo) {
969
1044
  state.scrollHistory.length = 0;
970
1045
  state.initialScroll = void 0;
971
1046
  state.initialAnchor = void 0;
972
- set$(ctx, "scrollingTo", void 0);
1047
+ state.scrollingTo = void 0;
973
1048
  if (state.pendingTotalSize !== void 0) {
974
- addTotalSize(ctx, state, null, state.pendingTotalSize);
1049
+ addTotalSize(ctx, null, state.pendingTotalSize);
975
1050
  }
976
1051
  if ((_a3 = state.props) == null ? void 0 : _a3.data) {
977
1052
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
978
1053
  }
1054
+ if (Platform2.OS === "web") {
1055
+ state.scrollAdjustHandler.commitPendingAdjust();
1056
+ }
1057
+ setInitialRenderState(ctx, { didInitialScroll: true });
979
1058
  }
980
1059
  }
981
- var Platform2 = reactNative.Platform;
982
1060
 
983
- // src/core/scrollTo.ts
984
- function scrollTo(ctx, state, params) {
1061
+ // src/core/checkFinishedScroll.ts
1062
+ function checkFinishedScroll(ctx) {
1063
+ ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
1064
+ }
1065
+ function checkFinishedScrollFrame(ctx) {
1066
+ const scrollingTo = ctx.state.scrollingTo;
1067
+ if (scrollingTo) {
1068
+ const { state } = ctx;
1069
+ state.animFrameCheckFinishedScroll = void 0;
1070
+ const scroll = state.scroll;
1071
+ const adjust = state.scrollAdjustHandler.getAdjust();
1072
+ const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1073
+ const maxOffset = clampScrollOffset(ctx, scroll);
1074
+ const diff1 = Math.abs(scroll - clampedTargetOffset);
1075
+ const diff2 = Math.abs(diff1 - adjust);
1076
+ const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
1077
+ if (isNotOverscrolled && (diff1 < 1 || diff2 < 1)) {
1078
+ finishScrollTo(ctx);
1079
+ }
1080
+ }
1081
+ }
1082
+ function checkFinishedScrollFallback(ctx) {
1083
+ const state = ctx.state;
1084
+ const scrollingTo = state.scrollingTo;
1085
+ const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
1086
+ state.timeoutCheckFinishedScrollFallback = setTimeout(
1087
+ () => {
1088
+ let numChecks = 0;
1089
+ const checkHasScrolled = () => {
1090
+ state.timeoutCheckFinishedScrollFallback = void 0;
1091
+ const isStillScrollingTo = state.scrollingTo;
1092
+ if (isStillScrollingTo) {
1093
+ numChecks++;
1094
+ if (state.hasScrolled || numChecks > 5) {
1095
+ finishScrollTo(ctx);
1096
+ } else {
1097
+ state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
1098
+ }
1099
+ }
1100
+ };
1101
+ checkHasScrolled();
1102
+ },
1103
+ slowTimeout ? 500 : 100
1104
+ );
1105
+ }
1106
+
1107
+ // src/core/doScrollTo.native.ts
1108
+ function doScrollTo(ctx, params) {
985
1109
  var _a3;
986
- const { noScrollingTo, ...scrollTarget } = params;
1110
+ const state = ctx.state;
1111
+ const { animated, horizontal, offset } = params;
1112
+ const { refScroller } = state;
1113
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1114
+ animated: !!animated,
1115
+ x: horizontal ? offset : 0,
1116
+ y: horizontal ? 0 : offset
1117
+ });
1118
+ if (!animated) {
1119
+ state.scroll = offset;
1120
+ checkFinishedScrollFallback(ctx);
1121
+ }
1122
+ }
1123
+
1124
+ // src/core/scrollTo.ts
1125
+ function scrollTo(ctx, params) {
1126
+ const state = ctx.state;
1127
+ const { noScrollingTo, forceScroll, ...scrollTarget } = params;
987
1128
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
988
1129
  const {
989
- refScroller,
990
1130
  props: { horizontal }
991
1131
  } = state;
992
- let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
993
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
994
- const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
995
- offset = Math.min(offset, maxOffset);
1132
+ if (state.animFrameCheckFinishedScroll) {
1133
+ cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
996
1134
  }
1135
+ if (state.timeoutCheckFinishedScrollFallback) {
1136
+ clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
1137
+ }
1138
+ let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
1139
+ offset = clampScrollOffset(ctx, offset);
997
1140
  state.scrollHistory.length = 0;
998
1141
  if (!noScrollingTo) {
999
- set$(ctx, "scrollingTo", scrollTarget);
1142
+ state.scrollingTo = scrollTarget;
1000
1143
  }
1001
1144
  state.scrollPending = offset;
1002
- if (!isInitialScroll || Platform2.OS === "android") {
1003
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1004
- animated: !!animated,
1005
- x: horizontal ? offset : 0,
1006
- y: horizontal ? 0 : offset
1007
- });
1008
- }
1009
- if (!animated) {
1145
+ if (forceScroll || !isInitialScroll || Platform2.OS === "android") {
1146
+ doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
1147
+ } else {
1010
1148
  state.scroll = offset;
1011
- if (Platform2.OS === "web") {
1012
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1013
- if (value && peek$(ctx, "scrollingTo")) {
1014
- finishScrollTo(ctx, state);
1015
- unlisten();
1016
- }
1017
- });
1018
- } else {
1019
- setTimeout(() => finishScrollTo(ctx, state), 100);
1020
- }
1021
- if (isInitialScroll) {
1022
- setTimeout(() => {
1023
- state.initialScroll = void 0;
1024
- }, 500);
1025
- }
1026
1149
  }
1027
1150
  }
1028
1151
 
@@ -1031,6 +1154,12 @@ var HYSTERESIS_MULTIPLIER = 1.3;
1031
1154
  var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1032
1155
  const absDistance = Math.abs(distance);
1033
1156
  const within = atThreshold || threshold > 0 && absDistance <= threshold;
1157
+ if (wasReached === null) {
1158
+ if (!within && distance >= 0) {
1159
+ return false;
1160
+ }
1161
+ return null;
1162
+ }
1034
1163
  const updateSnapshot = () => {
1035
1164
  setSnapshot == null ? void 0 : setSnapshot({
1036
1165
  atThreshold,
@@ -1063,8 +1192,9 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
1063
1192
  };
1064
1193
 
1065
1194
  // src/utils/checkAtBottom.ts
1066
- function checkAtBottom(ctx, state) {
1195
+ function checkAtBottom(ctx) {
1067
1196
  var _a3;
1197
+ const state = ctx.state;
1068
1198
  if (!state) {
1069
1199
  return;
1070
1200
  }
@@ -1137,15 +1267,15 @@ function checkAtTop(state) {
1137
1267
  }
1138
1268
 
1139
1269
  // src/core/updateScroll.ts
1140
- function updateScroll(ctx, state, newScroll, forceUpdate) {
1270
+ function updateScroll(ctx, newScroll, forceUpdate) {
1141
1271
  var _a3;
1142
- const scrollingTo = peek$(ctx, "scrollingTo");
1272
+ const state = ctx.state;
1273
+ const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
1143
1274
  state.hasScrolled = true;
1144
1275
  state.lastBatchingAction = Date.now();
1145
1276
  const currentTime = Date.now();
1146
- const adjust = state.scrollAdjustHandler.getAdjust();
1147
- const lastHistoryAdjust = state.lastScrollAdjustForHistory;
1148
- const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
1277
+ const adjust = scrollAdjustHandler.getAdjust();
1278
+ const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1149
1279
  if (adjustChanged) {
1150
1280
  state.scrollHistory.length = 0;
1151
1281
  }
@@ -1170,22 +1300,26 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1170
1300
  return;
1171
1301
  }
1172
1302
  }
1173
- if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1303
+ const lastCalculated = state.scrollLastCalculate;
1304
+ const shouldUpdate = forceUpdate || state.dataChangeNeedsScrollUpdate || state.scrollLastCalculate === void 0 || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
1305
+ if (shouldUpdate) {
1306
+ state.scrollLastCalculate = state.scroll;
1174
1307
  state.ignoreScrollFromMVCPIgnored = false;
1175
1308
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1176
- checkAtBottom(ctx, state);
1309
+ checkAtBottom(ctx);
1177
1310
  checkAtTop(state);
1178
1311
  state.dataChangeNeedsScrollUpdate = false;
1179
1312
  }
1180
1313
  }
1181
1314
 
1182
1315
  // src/utils/requestAdjust.ts
1183
- function requestAdjust(ctx, state, positionDiff, dataChanged) {
1316
+ function requestAdjust(ctx, positionDiff, dataChanged) {
1317
+ const state = ctx.state;
1184
1318
  if (Math.abs(positionDiff) > 0.1) {
1185
1319
  const needsScrollWorkaround = Platform2.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
1186
1320
  const doit = () => {
1187
1321
  if (needsScrollWorkaround) {
1188
- scrollTo(ctx, state, {
1322
+ scrollTo(ctx, {
1189
1323
  noScrollingTo: true,
1190
1324
  offset: state.scroll
1191
1325
  });
@@ -1198,8 +1332,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1198
1332
  };
1199
1333
  state.scroll += positionDiff;
1200
1334
  state.scrollForNextCalculateItemsInView = void 0;
1201
- const didLayout = peek$(ctx, "containersDidLayout");
1202
- if (didLayout) {
1335
+ const readyToRender = peek$(ctx, "readyToRender");
1336
+ if (readyToRender) {
1203
1337
  doit();
1204
1338
  if (Platform2.OS !== "web") {
1205
1339
  const threshold = state.scroll - positionDiff / 2;
@@ -1221,7 +1355,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1221
1355
  if (shouldForceUpdate) {
1222
1356
  state.ignoreScrollFromMVCPIgnored = false;
1223
1357
  state.scrollPending = state.scroll;
1224
- updateScroll(ctx, state, state.scroll, true);
1358
+ updateScroll(ctx, state.scroll, true);
1225
1359
  }
1226
1360
  }, delay);
1227
1361
  }
@@ -1236,28 +1370,27 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1236
1370
  var INITIAL_ANCHOR_TOLERANCE = 0.5;
1237
1371
  var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
1238
1372
  var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1239
- function ensureInitialAnchor(ctx, state) {
1373
+ function ensureInitialAnchor(ctx) {
1240
1374
  var _a3, _b, _c, _d, _e;
1241
- const anchor = state.initialAnchor;
1375
+ const state = ctx.state;
1376
+ const { initialAnchor, didContainersLayout, positions, scroll, scrollLength } = state;
1377
+ const anchor = initialAnchor;
1242
1378
  const item = state.props.data[anchor.index];
1243
- const containersDidLayout = peek$(ctx, "containersDidLayout");
1244
- if (!containersDidLayout) {
1379
+ if (!didContainersLayout) {
1245
1380
  return;
1246
1381
  }
1247
1382
  const id = getId(state, anchor.index);
1248
- if (state.positions.get(id) === void 0) {
1383
+ if (positions.get(id) === void 0) {
1249
1384
  return;
1250
1385
  }
1251
- const size = getItemSize(ctx, state, id, anchor.index, item, true, true);
1386
+ const size = getItemSize(ctx, id, anchor.index, item, true, true);
1252
1387
  if (size === void 0) {
1253
1388
  return;
1254
1389
  }
1255
- const availableSpace = Math.max(0, state.scrollLength - size);
1256
- const desiredOffset = calculateOffsetForIndex(ctx, state, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1257
- const contentSize = getContentSize(ctx);
1258
- const maxOffset = Math.max(0, contentSize - state.scrollLength);
1259
- const clampedDesiredOffset = Math.max(0, Math.min(desiredOffset, maxOffset));
1260
- const delta = clampedDesiredOffset - state.scroll;
1390
+ const availableSpace = Math.max(0, scrollLength - size);
1391
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1392
+ const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset);
1393
+ const delta = clampedDesiredOffset - scroll;
1261
1394
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1262
1395
  const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
1263
1396
  if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
@@ -1281,18 +1414,21 @@ function ensureInitialAnchor(ctx, state) {
1281
1414
  lastDelta: delta,
1282
1415
  settledTicks: 0
1283
1416
  });
1284
- requestAdjust(ctx, state, delta);
1417
+ requestAdjust(ctx, delta);
1418
+ requestAnimationFrame(() => finishScrollTo(ctx));
1285
1419
  }
1286
1420
 
1287
1421
  // src/core/mvcp.ts
1288
- function prepareMVCP(ctx, state, dataChanged) {
1422
+ function prepareMVCP(ctx, dataChanged) {
1423
+ const state = ctx.state;
1289
1424
  const { idsInView, positions, props } = state;
1290
1425
  const { maintainVisibleContentPosition } = props;
1291
- const scrollingTo = peek$(ctx, "scrollingTo");
1426
+ const scrollingTo = state.scrollingTo;
1292
1427
  let prevPosition;
1293
1428
  let targetId;
1294
1429
  const idsInViewWithPositions = [];
1295
1430
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1431
+ const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1296
1432
  const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1297
1433
  const indexByKey = state.indexByKey;
1298
1434
  if (shouldMVCP) {
@@ -1301,7 +1437,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1301
1437
  return void 0;
1302
1438
  }
1303
1439
  targetId = getId(state, scrollTarget);
1304
- } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
1440
+ } else if (idsInView.length > 0 && state.didContainersLayout) {
1305
1441
  if (dataChanged) {
1306
1442
  for (let i = 0; i < idsInView.length; i++) {
1307
1443
  const id = idsInView[i];
@@ -1318,7 +1454,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1318
1454
  prevPosition = positions.get(targetId);
1319
1455
  }
1320
1456
  return () => {
1321
- let positionDiff;
1457
+ let positionDiff = 0;
1322
1458
  if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1323
1459
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1324
1460
  const { id, position } = idsInViewWithPositions[i];
@@ -1344,16 +1480,28 @@ function prepareMVCP(ctx, state, dataChanged) {
1344
1480
  positionDiff = diff;
1345
1481
  }
1346
1482
  }
1347
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1348
- requestAdjust(ctx, state, positionDiff, dataChanged && maintainVisibleContentPosition);
1483
+ if (scrollingToViewPosition && scrollingToViewPosition > 0) {
1484
+ const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
1485
+ const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
1486
+ if (newSize !== void 0 && prevSize !== void 0 && newSize !== (scrollingTo == null ? void 0 : scrollingTo.itemSize)) {
1487
+ const diff = newSize - prevSize;
1488
+ if (diff !== 0) {
1489
+ positionDiff += (newSize - prevSize) * scrollingToViewPosition;
1490
+ scrollingTo.itemSize = newSize;
1491
+ }
1492
+ }
1493
+ }
1494
+ if (Math.abs(positionDiff) > 0.1) {
1495
+ requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1349
1496
  }
1350
1497
  };
1351
1498
  }
1352
1499
  }
1353
1500
 
1354
1501
  // src/core/prepareColumnStartState.ts
1355
- function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1502
+ function prepareColumnStartState(ctx, startIndex, useAverageSize) {
1356
1503
  var _a3;
1504
+ const state = ctx.state;
1357
1505
  const numColumns = peek$(ctx, "numColumns");
1358
1506
  let rowStartIndex = startIndex;
1359
1507
  const columnAtStart = state.columns.get(state.idCache[startIndex]);
@@ -1368,7 +1516,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1368
1516
  const prevId = state.idCache[prevIndex];
1369
1517
  const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1370
1518
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1371
- const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
1519
+ const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
1372
1520
  currentRowTop = prevPosition + prevRowHeight;
1373
1521
  }
1374
1522
  return {
@@ -1391,7 +1539,8 @@ function findRowStartIndex(state, numColumns, index) {
1391
1539
  }
1392
1540
  return rowStart;
1393
1541
  }
1394
- function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1542
+ function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
1543
+ const state = ctx.state;
1395
1544
  if (endIndex < startIndex) {
1396
1545
  return 0;
1397
1546
  }
@@ -1405,7 +1554,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1405
1554
  continue;
1406
1555
  }
1407
1556
  const id = state.idCache[i];
1408
- const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
1557
+ const size = getItemSize(ctx, id, i, data[i], useAverageSize);
1409
1558
  if (size > maxSize) {
1410
1559
  maxSize = size;
1411
1560
  }
@@ -1414,22 +1563,23 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1414
1563
  }
1415
1564
 
1416
1565
  // src/core/updateTotalSize.ts
1417
- function updateTotalSize(ctx, state) {
1566
+ function updateTotalSize(ctx) {
1567
+ const state = ctx.state;
1418
1568
  const {
1419
1569
  positions,
1420
1570
  props: { data }
1421
1571
  } = state;
1422
1572
  if (data.length === 0) {
1423
- addTotalSize(ctx, state, null, 0);
1573
+ addTotalSize(ctx, null, 0);
1424
1574
  } else {
1425
1575
  const lastId = getId(state, data.length - 1);
1426
1576
  if (lastId !== void 0) {
1427
1577
  const lastPosition = positions.get(lastId);
1428
1578
  if (lastPosition !== void 0) {
1429
- const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
1579
+ const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
1430
1580
  if (lastSize !== void 0) {
1431
1581
  const totalSize = lastPosition + lastSize;
1432
- addTotalSize(ctx, state, null, totalSize);
1582
+ addTotalSize(ctx, null, totalSize);
1433
1583
  }
1434
1584
  }
1435
1585
  }
@@ -1475,7 +1625,8 @@ var getScrollVelocity = (state) => {
1475
1625
  };
1476
1626
 
1477
1627
  // src/utils/updateSnapToOffsets.ts
1478
- function updateSnapToOffsets(ctx, state) {
1628
+ function updateSnapToOffsets(ctx) {
1629
+ const state = ctx.state;
1479
1630
  const {
1480
1631
  positions,
1481
1632
  props: { snapToIndices }
@@ -1490,30 +1641,30 @@ function updateSnapToOffsets(ctx, state) {
1490
1641
  }
1491
1642
 
1492
1643
  // src/core/updateItemPositions.ts
1493
- function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1644
+ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1494
1645
  doMVCP: false,
1495
1646
  forceFullUpdate: false,
1496
1647
  scrollBottomBuffered: -1,
1497
1648
  startIndex: 0
1498
1649
  }) {
1499
1650
  var _a3, _b, _c, _d, _e;
1651
+ const state = ctx.state;
1500
1652
  const {
1501
1653
  columns,
1502
1654
  indexByKey,
1503
1655
  positions,
1504
1656
  idCache,
1505
1657
  sizesKnown,
1506
- props: { getEstimatedItemSize, snapToIndices, enableAverages }
1658
+ props: { data, getEstimatedItemSize, snapToIndices },
1659
+ scrollingTo
1507
1660
  } = state;
1508
- const data = state.props.data;
1509
1661
  const dataLength = data.length;
1510
1662
  const numColumns = peek$(ctx, "numColumns");
1511
- const scrollingTo = peek$(ctx, "scrollingTo");
1512
1663
  const hasColumns = numColumns > 1;
1513
1664
  const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1514
1665
  const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
1515
1666
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1516
- const useAverageSize = enableAverages && !getEstimatedItemSize;
1667
+ const useAverageSize = !getEstimatedItemSize;
1517
1668
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1518
1669
  let currentRowTop = 0;
1519
1670
  let column = 1;
@@ -1522,7 +1673,6 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1522
1673
  if (hasColumns) {
1523
1674
  const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1524
1675
  ctx,
1525
- state,
1526
1676
  startIndex,
1527
1677
  useAverageSize
1528
1678
  );
@@ -1532,7 +1682,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1532
1682
  const prevIndex = startIndex - 1;
1533
1683
  const prevId = getId(state, prevIndex);
1534
1684
  const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1535
- const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1685
+ const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1536
1686
  currentRowTop = prevPosition + prevSize;
1537
1687
  }
1538
1688
  }
@@ -1549,7 +1699,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1549
1699
  breakAt = i + itemsPerRow + 10;
1550
1700
  }
1551
1701
  const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1552
- const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
1702
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
1553
1703
  if (IS_DEV && needsIndexByKey) {
1554
1704
  if (indexByKeyForChecking.has(id)) {
1555
1705
  console.error(
@@ -1558,7 +1708,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1558
1708
  }
1559
1709
  indexByKeyForChecking.set(id, i);
1560
1710
  }
1561
- positions.set(id, currentRowTop);
1711
+ if (currentRowTop !== positions.get(id)) {
1712
+ positions.set(id, currentRowTop);
1713
+ notifyPosition$(ctx, id, currentRowTop);
1714
+ }
1562
1715
  if (needsIndexByKey) {
1563
1716
  indexByKey.set(id, i);
1564
1717
  }
@@ -1578,10 +1731,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1578
1731
  }
1579
1732
  }
1580
1733
  if (!didBreakEarly) {
1581
- updateTotalSize(ctx, state);
1734
+ updateTotalSize(ctx);
1582
1735
  }
1583
1736
  if (snapToIndices) {
1584
- updateSnapToOffsets(ctx, state);
1737
+ updateSnapToOffsets(ctx);
1585
1738
  }
1586
1739
  }
1587
1740
 
@@ -1659,7 +1812,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1659
1812
  if (previousViewableItems) {
1660
1813
  for (const viewToken of previousViewableItems) {
1661
1814
  const containerId = findContainerId(ctx, viewToken.key);
1662
- if (!isViewable(
1815
+ if (!checkIsViewable(
1663
1816
  state,
1664
1817
  ctx,
1665
1818
  viewabilityConfig,
@@ -1680,7 +1833,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1680
1833
  if (item) {
1681
1834
  const key = getId(state, i);
1682
1835
  const containerId = findContainerId(ctx, key);
1683
- if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1836
+ if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1684
1837
  const viewToken = {
1685
1838
  containerId,
1686
1839
  index: i,
@@ -1740,11 +1893,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1740
1893
  const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
1741
1894
  const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
1742
1895
  const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1743
- const isViewable2 = percent >= viewablePercentThreshold;
1896
+ const isViewable = percent >= viewablePercentThreshold;
1744
1897
  const value = {
1745
1898
  containerId,
1746
1899
  index,
1747
- isViewable: isViewable2,
1900
+ isViewable,
1748
1901
  item,
1749
1902
  key,
1750
1903
  percentOfScroller,
@@ -1763,8 +1916,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1763
1916
  }
1764
1917
  return value;
1765
1918
  }
1766
- function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1767
- const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1919
+ function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1920
+ let value = ctx.mapViewabilityAmountValues.get(containerId);
1921
+ if (!value || value.key !== key) {
1922
+ value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1923
+ }
1768
1924
  return value.isViewable;
1769
1925
  }
1770
1926
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
@@ -1792,8 +1948,9 @@ function checkAllSizesKnown(state) {
1792
1948
  }
1793
1949
 
1794
1950
  // src/utils/findAvailableContainers.ts
1795
- function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1951
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1796
1952
  const numContainers = peek$(ctx, "numContainers");
1953
+ const state = ctx.state;
1797
1954
  const { stickyContainerPool, containerItemTypes } = state;
1798
1955
  const result = [];
1799
1956
  const availableContainers = [];
@@ -1837,14 +1994,14 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1837
1994
  continue;
1838
1995
  }
1839
1996
  const key = peek$(ctx, `containerItemKey${u}`);
1840
- let isOk = key === void 0;
1841
- if (!isOk && pendingRemovalSet.has(u)) {
1842
- pendingRemovalSet.delete(u);
1843
- pendingRemovalChanged = true;
1844
- const requiredType = neededTypes[typeIndex];
1845
- isOk = canReuseContainer(u, requiredType);
1846
- }
1847
- if (isOk) {
1997
+ const requiredType = neededTypes[typeIndex];
1998
+ const isPending = key !== void 0 && pendingRemovalSet.has(u);
1999
+ const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
2000
+ if (canUse) {
2001
+ if (isPending) {
2002
+ pendingRemovalSet.delete(u);
2003
+ pendingRemovalChanged = true;
2004
+ }
1848
2005
  result.push(u);
1849
2006
  if (requiredItemTypes) {
1850
2007
  typeIndex++;
@@ -1913,21 +2070,26 @@ function comparatorByDistance(a, b) {
1913
2070
  }
1914
2071
 
1915
2072
  // src/core/scrollToIndex.ts
1916
- function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1917
- if (index >= state.props.data.length) {
1918
- index = state.props.data.length - 1;
2073
+ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
2074
+ const state = ctx.state;
2075
+ const { data } = state.props;
2076
+ if (index >= data.length) {
2077
+ index = data.length - 1;
1919
2078
  } else if (index < 0) {
1920
2079
  index = 0;
1921
2080
  }
1922
- const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
1923
- const isLast = index === state.props.data.length - 1;
2081
+ const firstIndexOffset = calculateOffsetForIndex(ctx, index);
2082
+ const isLast = index === data.length - 1;
1924
2083
  if (isLast && viewPosition === void 0) {
1925
2084
  viewPosition = 1;
1926
2085
  }
1927
2086
  state.scrollForNextCalculateItemsInView = void 0;
1928
- scrollTo(ctx, state, {
2087
+ const targetId = getId(state, index);
2088
+ const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
2089
+ scrollTo(ctx, {
1929
2090
  animated,
1930
2091
  index,
2092
+ itemSize,
1931
2093
  offset: firstIndexOffset,
1932
2094
  viewOffset,
1933
2095
  viewPosition: viewPosition != null ? viewPosition : 0
@@ -1935,29 +2097,30 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1935
2097
  }
1936
2098
 
1937
2099
  // src/utils/setDidLayout.ts
1938
- function setDidLayout(ctx, state) {
2100
+ function setDidLayout(ctx) {
2101
+ const state = ctx.state;
1939
2102
  const {
1940
2103
  loadStartTime,
1941
2104
  initialScroll,
1942
2105
  props: { onLoad }
1943
2106
  } = state;
1944
2107
  state.queuedInitialLayout = true;
1945
- checkAtBottom(ctx, state);
2108
+ checkAtBottom(ctx);
1946
2109
  const setIt = () => {
1947
- set$(ctx, "containersDidLayout", true);
2110
+ setInitialRenderState(ctx, { didLayout: true });
1948
2111
  if (onLoad) {
1949
2112
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1950
2113
  }
1951
2114
  };
1952
2115
  if (Platform2.OS === "android" && initialScroll) {
1953
2116
  if (IsNewArchitecture) {
1954
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2117
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1955
2118
  requestAnimationFrame(() => {
1956
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2119
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1957
2120
  setIt();
1958
2121
  });
1959
2122
  } else {
1960
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2123
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1961
2124
  setIt();
1962
2125
  }
1963
2126
  } else {
@@ -1980,15 +2143,17 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
1980
2143
  }
1981
2144
  return -1;
1982
2145
  }
1983
- function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
2146
+ function getActiveStickyIndices(ctx, stickyHeaderIndices) {
2147
+ const state = ctx.state;
1984
2148
  return new Set(
1985
2149
  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))
1986
2150
  );
1987
2151
  }
1988
- function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2152
+ function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
1989
2153
  var _a3;
1990
- const activeIndices = getActiveStickyIndices(ctx, state, stickyHeaderIndices);
1991
- state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
2154
+ const state = ctx.state;
2155
+ const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
2156
+ set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
1992
2157
  for (let offset = 0; offset <= 1; offset++) {
1993
2158
  const idx = currentStickyIdx - offset;
1994
2159
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
@@ -1999,8 +2164,9 @@ function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, cu
1999
2164
  }
2000
2165
  }
2001
2166
  }
2002
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2167
+ function handleStickyRecycling(ctx, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2003
2168
  var _a3, _b, _c;
2169
+ const state = ctx.state;
2004
2170
  for (const containerIndex of state.stickyContainerPool) {
2005
2171
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
2006
2172
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
@@ -2024,7 +2190,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2024
2190
  const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2025
2191
  if (currentId) {
2026
2192
  const currentPos = state.positions.get(currentId);
2027
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
2193
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2028
2194
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
2029
2195
  }
2030
2196
  }
@@ -2033,7 +2199,8 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2033
2199
  }
2034
2200
  }
2035
2201
  }
2036
- function calculateItemsInView(ctx, state, params = {}) {
2202
+ function calculateItemsInView(ctx, params = {}) {
2203
+ const state = ctx.state;
2037
2204
  reactNative.unstable_batchedUpdates(() => {
2038
2205
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2039
2206
  const {
@@ -2057,8 +2224,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2057
2224
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2058
2225
  const prevNumContainers = peek$(ctx, "numContainers");
2059
2226
  if (!data || scrollLength === 0 || !prevNumContainers) {
2060
- if (state.initialAnchor) {
2061
- ensureInitialAnchor(ctx, state);
2227
+ if (!IsNewArchitecture && state.initialAnchor) {
2228
+ ensureInitialAnchor(ctx);
2062
2229
  }
2063
2230
  return;
2064
2231
  }
@@ -2073,15 +2240,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2073
2240
  if (!queuedInitialLayout && initialScroll) {
2074
2241
  const updatedOffset = calculateOffsetWithOffsetPosition(
2075
2242
  ctx,
2076
- state,
2077
- calculateOffsetForIndex(ctx, state, initialScroll.index),
2243
+ calculateOffsetForIndex(ctx, initialScroll.index),
2078
2244
  initialScroll
2079
2245
  );
2080
2246
  scrollState = updatedOffset;
2081
2247
  }
2082
2248
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2083
2249
  const scrollAdjustPad = scrollAdjustPending - topPad;
2084
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2250
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2085
2251
  if (scroll + scrollLength > totalSize) {
2086
2252
  scroll = Math.max(0, totalSize - scrollLength);
2087
2253
  }
@@ -2089,11 +2255,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2089
2255
  set$(ctx, "debugRawScroll", scrollState);
2090
2256
  set$(ctx, "debugComputedScroll", scroll);
2091
2257
  }
2092
- const previousStickyIndex = state.activeStickyIndex;
2258
+ const previousStickyIndex = peek$(ctx, "activeStickyIndex");
2093
2259
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
2094
- const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
2095
- state.activeStickyIndex = nextActiveStickyIndex;
2096
- set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2260
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
2261
+ if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
2262
+ set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2263
+ }
2097
2264
  let scrollBufferTop = scrollBuffer;
2098
2265
  let scrollBufferBottom = scrollBuffer;
2099
2266
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2106,23 +2273,23 @@ function calculateItemsInView(ctx, state, params = {}) {
2106
2273
  const scrollTopBuffered = scroll - scrollBufferTop;
2107
2274
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2108
2275
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2109
- if (!dataChanged && scrollForNextCalculateItemsInView) {
2276
+ if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
2110
2277
  const { top, bottom } = scrollForNextCalculateItemsInView;
2111
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2112
- if (state.initialAnchor) {
2113
- ensureInitialAnchor(ctx, state);
2278
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2279
+ if (!IsNewArchitecture && state.initialAnchor) {
2280
+ ensureInitialAnchor(ctx);
2114
2281
  }
2115
2282
  return;
2116
2283
  }
2117
2284
  }
2118
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2285
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
2119
2286
  if (dataChanged) {
2120
2287
  indexByKey.clear();
2121
2288
  idCache.length = 0;
2122
2289
  positions.clear();
2123
2290
  }
2124
- const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2125
- updateItemPositions(ctx, state, dataChanged, {
2291
+ const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2292
+ updateItemPositions(ctx, dataChanged, {
2126
2293
  doMVCP,
2127
2294
  forceFullUpdate: !!forceFullItemPositions,
2128
2295
  scrollBottomBuffered,
@@ -2141,9 +2308,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2141
2308
  for (let i = loopStart; i >= 0; i--) {
2142
2309
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2143
2310
  const top = positions.get(id);
2144
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2311
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
2145
2312
  const bottom = top + size;
2146
- if (bottom > scroll - scrollBuffer) {
2313
+ if (bottom > scroll - scrollBufferTop) {
2147
2314
  loopStart = i;
2148
2315
  } else {
2149
2316
  break;
@@ -2168,7 +2335,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2168
2335
  const dataLength = data.length;
2169
2336
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2170
2337
  const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2171
- const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
2338
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
2172
2339
  const top = positions.get(id);
2173
2340
  if (!foundEnd) {
2174
2341
  if (startNoBuffer === null && top + size > scroll) {
@@ -2180,7 +2347,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2180
2347
  if (startBuffered === null && top + size > scrollTopBuffered) {
2181
2348
  startBuffered = i;
2182
2349
  startBufferedId = id;
2183
- nextTop = top;
2350
+ if (scrollTopBuffered < 0) {
2351
+ nextTop = null;
2352
+ } else {
2353
+ nextTop = top;
2354
+ }
2184
2355
  }
2185
2356
  if (startNoBuffer !== null) {
2186
2357
  if (top <= scrollBottom) {
@@ -2188,7 +2359,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2188
2359
  }
2189
2360
  if (top <= scrollBottomBuffered) {
2190
2361
  endBuffered = i;
2191
- nextBottom = top + size;
2362
+ if (scrollBottomBuffered > totalSize) {
2363
+ nextBottom = null;
2364
+ } else {
2365
+ nextBottom = top + size;
2366
+ }
2192
2367
  } else {
2193
2368
  foundEnd = true;
2194
2369
  }
@@ -2215,7 +2390,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2215
2390
  top: nextTop
2216
2391
  } : void 0;
2217
2392
  }
2218
- const numContainers = peek$(ctx, "numContainers");
2393
+ let numContainers = prevNumContainers;
2219
2394
  const pendingRemoval = [];
2220
2395
  if (dataChanged) {
2221
2396
  for (let i = 0; i < numContainers; i++) {
@@ -2226,7 +2401,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2226
2401
  }
2227
2402
  }
2228
2403
  if (startBuffered !== null && endBuffered !== null) {
2229
- let numContainers2 = prevNumContainers;
2230
2404
  const needNewContainers = [];
2231
2405
  for (let i = startBuffered; i <= endBuffered; i++) {
2232
2406
  const id = (_h = idCache[i]) != null ? _h : getId(state, i);
@@ -2237,7 +2411,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2237
2411
  if (stickyIndicesArr.length > 0) {
2238
2412
  handleStickyActivation(
2239
2413
  ctx,
2240
- state,
2241
2414
  stickyIndicesSet,
2242
2415
  stickyIndicesArr,
2243
2416
  currentStickyIdx,
@@ -2245,9 +2418,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2245
2418
  startBuffered,
2246
2419
  endBuffered
2247
2420
  );
2248
- } else {
2249
- state.activeStickyIndex = void 0;
2250
- set$(ctx, "activeStickyIndex", void 0);
2421
+ } else if (previousStickyIndex !== -1) {
2422
+ set$(ctx, "activeStickyIndex", -1);
2251
2423
  }
2252
2424
  if (needNewContainers.length > 0) {
2253
2425
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2256,7 +2428,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2256
2428
  }) : void 0;
2257
2429
  const availableContainers = findAvailableContainers(
2258
2430
  ctx,
2259
- state,
2260
2431
  needNewContainers.length,
2261
2432
  startBuffered,
2262
2433
  endBuffered,
@@ -2278,29 +2449,30 @@ function calculateItemsInView(ctx, state, params = {}) {
2278
2449
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
2279
2450
  }
2280
2451
  containerItemKeys.add(id);
2452
+ const containerSticky = `containerSticky${containerIndex}`;
2281
2453
  if (stickyIndicesSet.has(i)) {
2282
- set$(ctx, `containerSticky${containerIndex}`, true);
2454
+ set$(ctx, containerSticky, true);
2283
2455
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2284
2456
  set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2285
2457
  state.stickyContainerPool.add(containerIndex);
2286
- } else {
2287
- set$(ctx, `containerSticky${containerIndex}`, false);
2458
+ } else if (peek$(ctx, containerSticky)) {
2459
+ set$(ctx, containerSticky, false);
2288
2460
  state.stickyContainerPool.delete(containerIndex);
2289
2461
  }
2290
- if (containerIndex >= numContainers2) {
2291
- numContainers2 = containerIndex + 1;
2462
+ if (containerIndex >= numContainers) {
2463
+ numContainers = containerIndex + 1;
2292
2464
  }
2293
2465
  }
2294
- if (numContainers2 !== prevNumContainers) {
2295
- set$(ctx, "numContainers", numContainers2);
2296
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
2297
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
2466
+ if (numContainers !== prevNumContainers) {
2467
+ set$(ctx, "numContainers", numContainers);
2468
+ if (numContainers > peek$(ctx, "numContainersPooled")) {
2469
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
2298
2470
  }
2299
2471
  }
2300
2472
  }
2301
2473
  }
2302
2474
  if (stickyIndicesArr.length > 0) {
2303
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2475
+ handleStickyRecycling(ctx, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2304
2476
  }
2305
2477
  let didChangePositions = false;
2306
2478
  for (let i = 0; i < numContainers; i++) {
@@ -2352,7 +2524,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2352
2524
  }
2353
2525
  if (!queuedInitialLayout && endBuffered !== null) {
2354
2526
  if (checkAllSizesKnown(state)) {
2355
- setDidLayout(ctx, state);
2527
+ setDidLayout(ctx);
2356
2528
  }
2357
2529
  }
2358
2530
  if (viewabilityConfigCallbackPairs) {
@@ -2365,8 +2537,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2365
2537
  }
2366
2538
  }
2367
2539
  });
2368
- if (state.initialAnchor) {
2369
- ensureInitialAnchor(ctx, state);
2540
+ if (!IsNewArchitecture && state.initialAnchor) {
2541
+ ensureInitialAnchor(ctx);
2370
2542
  }
2371
2543
  }
2372
2544
 
@@ -2391,19 +2563,22 @@ function checkActualChange(state, dataProp, previousData) {
2391
2563
  }
2392
2564
 
2393
2565
  // src/core/doMaintainScrollAtEnd.ts
2394
- function doMaintainScrollAtEnd(ctx, state, animated) {
2566
+ function doMaintainScrollAtEnd(ctx, animated) {
2567
+ const state = ctx.state;
2395
2568
  const {
2569
+ didContainersLayout,
2570
+ isAtEnd,
2396
2571
  refScroller,
2397
2572
  props: { maintainScrollAtEnd }
2398
2573
  } = state;
2399
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2574
+ if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
2400
2575
  const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2401
2576
  if (paddingTop > 0) {
2402
2577
  state.scroll = 0;
2403
2578
  }
2404
2579
  requestAnimationFrame(() => {
2405
2580
  var _a3;
2406
- if (state == null ? void 0 : state.isAtEnd) {
2581
+ if (state.isAtEnd) {
2407
2582
  state.maintainingScrollAtEnd = true;
2408
2583
  (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2409
2584
  animated
@@ -2474,28 +2649,30 @@ function updateAveragesOnDataChange(state, oldData, newData) {
2474
2649
  }
2475
2650
 
2476
2651
  // src/core/checkResetContainers.ts
2477
- function checkResetContainers(ctx, state, dataProp) {
2652
+ function checkResetContainers(ctx, dataProp) {
2653
+ const state = ctx.state;
2478
2654
  const { previousData } = state;
2479
2655
  if (previousData) {
2480
2656
  updateAveragesOnDataChange(state, previousData, dataProp);
2481
2657
  }
2482
2658
  const { maintainScrollAtEnd } = state.props;
2483
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2659
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2484
2660
  const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2485
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
2661
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
2486
2662
  if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
2487
2663
  state.isEndReached = false;
2488
2664
  }
2489
2665
  if (!didMaintainScrollAtEnd) {
2490
2666
  checkAtTop(state);
2491
- checkAtBottom(ctx, state);
2667
+ checkAtBottom(ctx);
2492
2668
  }
2493
2669
  delete state.previousData;
2494
2670
  }
2495
2671
 
2496
2672
  // src/core/doInitialAllocateContainers.ts
2497
- function doInitialAllocateContainers(ctx, state) {
2673
+ function doInitialAllocateContainers(ctx) {
2498
2674
  var _a3, _b, _c;
2675
+ const state = ctx.state;
2499
2676
  const {
2500
2677
  scrollLength,
2501
2678
  props: {
@@ -2533,10 +2710,10 @@ function doInitialAllocateContainers(ctx, state) {
2533
2710
  if (!IsNewArchitecture || state.lastLayout) {
2534
2711
  if (state.initialScroll) {
2535
2712
  requestAnimationFrame(() => {
2536
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2713
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2537
2714
  });
2538
2715
  } else {
2539
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2716
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2540
2717
  }
2541
2718
  }
2542
2719
  return true;
@@ -2544,7 +2721,8 @@ function doInitialAllocateContainers(ctx, state) {
2544
2721
  }
2545
2722
 
2546
2723
  // src/core/handleLayout.ts
2547
- function handleLayout(ctx, state, layout, setCanRender) {
2724
+ function handleLayout(ctx, layout, setCanRender) {
2725
+ const state = ctx.state;
2548
2726
  const { maintainScrollAtEnd } = state.props;
2549
2727
  const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2550
2728
  const previousLength = state.scrollLength;
@@ -2560,19 +2738,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2560
2738
  state.lastBatchingAction = Date.now();
2561
2739
  state.scrollForNextCalculateItemsInView = void 0;
2562
2740
  if (scrollLength > 0) {
2563
- doInitialAllocateContainers(ctx, state);
2741
+ doInitialAllocateContainers(ctx);
2564
2742
  }
2565
2743
  if (needsCalculate) {
2566
- calculateItemsInView(ctx, state, { doMVCP: true });
2744
+ calculateItemsInView(ctx, { doMVCP: true });
2567
2745
  }
2568
2746
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
2569
2747
  set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
2570
2748
  }
2571
2749
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
2572
- doMaintainScrollAtEnd(ctx, state, false);
2750
+ doMaintainScrollAtEnd(ctx, false);
2573
2751
  }
2574
- updateAlignItemsPaddingTop(ctx, state);
2575
- checkAtBottom(ctx, state);
2752
+ updateAlignItemsPaddingTop(ctx);
2753
+ checkAtBottom(ctx);
2576
2754
  checkAtTop(state);
2577
2755
  if (state) {
2578
2756
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
@@ -2588,8 +2766,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2588
2766
  }
2589
2767
 
2590
2768
  // src/core/onScroll.ts
2591
- function onScroll(ctx, state, event) {
2769
+ function onScroll(ctx, event) {
2592
2770
  var _a3, _b, _c;
2771
+ const state = ctx.state;
2593
2772
  const {
2594
2773
  scrollProcessingEnabled,
2595
2774
  props: { onScroll: onScrollProp }
@@ -2600,9 +2779,23 @@ function onScroll(ctx, state, event) {
2600
2779
  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) {
2601
2780
  return;
2602
2781
  }
2603
- const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2782
+ let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2604
2783
  state.scrollPending = newScroll;
2605
- updateScroll(ctx, state, newScroll);
2784
+ if (state.scrollingTo) {
2785
+ const maxOffset = clampScrollOffset(ctx, newScroll);
2786
+ if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
2787
+ newScroll = maxOffset;
2788
+ scrollTo(ctx, {
2789
+ forceScroll: true,
2790
+ isInitialScroll: true,
2791
+ noScrollingTo: true,
2792
+ offset: newScroll
2793
+ });
2794
+ return;
2795
+ }
2796
+ }
2797
+ updateScroll(ctx, newScroll);
2798
+ checkFinishedScroll(ctx);
2606
2799
  onScrollProp == null ? void 0 : onScrollProp(event);
2607
2800
  }
2608
2801
 
@@ -2611,51 +2804,47 @@ var ScrollAdjustHandler = class {
2611
2804
  constructor(ctx) {
2612
2805
  this.appliedAdjust = 0;
2613
2806
  this.pendingAdjust = 0;
2614
- this.mounted = false;
2615
- this.context = ctx;
2616
- if (Platform2.OS === "web") {
2617
- const commitPendingAdjust = () => {
2618
- const state = this.context.internalState;
2619
- const pending = this.pendingAdjust;
2620
- if (pending !== 0) {
2621
- this.pendingAdjust = 0;
2622
- this.appliedAdjust += pending;
2623
- state.scroll += pending;
2624
- state.scrollForNextCalculateItemsInView = void 0;
2625
- set$(this.context, "scrollAdjustPending", 0);
2626
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2627
- calculateItemsInView(this.context, this.context.internalState);
2628
- }
2629
- };
2630
- listen$(this.context, "scrollingTo", (value) => {
2631
- if (value === void 0) {
2632
- commitPendingAdjust();
2633
- }
2634
- });
2635
- }
2807
+ this.ctx = ctx;
2636
2808
  }
2637
2809
  requestAdjust(add) {
2638
- const scrollingTo = peek$(this.context, "scrollingTo");
2810
+ const scrollingTo = this.ctx.state.scrollingTo;
2639
2811
  if (Platform2.OS === "web" && (scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
2640
2812
  this.pendingAdjust += add;
2641
- set$(this.context, "scrollAdjustPending", this.pendingAdjust);
2813
+ set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
2642
2814
  } else {
2643
2815
  this.appliedAdjust += add;
2644
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2816
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2817
+ }
2818
+ if (this.ctx.state.scrollingTo) {
2819
+ checkFinishedScroll(this.ctx);
2645
2820
  }
2646
- }
2647
- setMounted() {
2648
- this.mounted = true;
2649
2821
  }
2650
2822
  getAdjust() {
2651
2823
  return this.appliedAdjust;
2652
2824
  }
2825
+ commitPendingAdjust() {
2826
+ if (Platform2.OS === "web") {
2827
+ const state = this.ctx.state;
2828
+ const pending = this.pendingAdjust;
2829
+ if (pending !== 0) {
2830
+ this.pendingAdjust = 0;
2831
+ this.appliedAdjust += pending;
2832
+ state.scroll += pending;
2833
+ state.scrollForNextCalculateItemsInView = void 0;
2834
+ set$(this.ctx, "scrollAdjustPending", 0);
2835
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2836
+ calculateItemsInView(this.ctx);
2837
+ }
2838
+ }
2839
+ }
2653
2840
  };
2654
2841
 
2655
2842
  // src/core/updateItemSize.ts
2656
- function updateItemSize(ctx, state, itemKey, sizeObj) {
2843
+ function updateItemSize(ctx, itemKey, sizeObj) {
2657
2844
  var _a3;
2845
+ const state = ctx.state;
2658
2846
  const {
2847
+ didContainersLayout,
2659
2848
  sizesKnown,
2660
2849
  props: {
2661
2850
  getFixedItemSize,
@@ -2683,13 +2872,12 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2683
2872
  return;
2684
2873
  }
2685
2874
  }
2686
- const containersDidLayout = peek$(ctx, "containersDidLayout");
2687
- let needsRecalculate = !containersDidLayout;
2875
+ let needsRecalculate = !didContainersLayout;
2688
2876
  let shouldMaintainScrollAtEnd = false;
2689
2877
  let minIndexSizeChanged;
2690
2878
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
2691
2879
  const prevSizeKnown = state.sizesKnown.get(itemKey);
2692
- const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
2880
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj);
2693
2881
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
2694
2882
  if (diff !== 0) {
2695
2883
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -2738,22 +2926,22 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2738
2926
  if (!cur || maxOtherAxisSize > cur) {
2739
2927
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
2740
2928
  }
2741
- if (containersDidLayout || checkAllSizesKnown(state)) {
2929
+ if (didContainersLayout || checkAllSizesKnown(state)) {
2742
2930
  if (needsRecalculate) {
2743
2931
  state.scrollForNextCalculateItemsInView = void 0;
2744
- calculateItemsInView(ctx, state, { doMVCP: true });
2932
+ calculateItemsInView(ctx, { doMVCP: true });
2745
2933
  }
2746
2934
  if (shouldMaintainScrollAtEnd) {
2747
2935
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
2748
- doMaintainScrollAtEnd(ctx, state, false);
2936
+ doMaintainScrollAtEnd(ctx, false);
2749
2937
  }
2750
2938
  }
2751
2939
  }
2752
2940
  }
2753
- function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2941
+ function updateOneItemSize(ctx, itemKey, sizeObj) {
2754
2942
  var _a3;
2943
+ const state = ctx.state;
2755
2944
  const {
2756
- sizes,
2757
2945
  indexByKey,
2758
2946
  sizesKnown,
2759
2947
  averageSizes,
@@ -2761,9 +2949,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2761
2949
  } = state;
2762
2950
  if (!data) return 0;
2763
2951
  const index = indexByKey.get(itemKey);
2764
- const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
2952
+ const prevSize = getItemSize(ctx, itemKey, index, data[index]);
2765
2953
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2766
2954
  const size = Platform2.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
2955
+ const prevSizeKnown = sizesKnown.get(itemKey);
2767
2956
  sizesKnown.set(itemKey, size);
2768
2957
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2769
2958
  const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
@@ -2771,11 +2960,15 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2771
2960
  if (!averages) {
2772
2961
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
2773
2962
  }
2774
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2775
- averages.num++;
2963
+ if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
2964
+ averages.avg += (size - prevSizeKnown) / averages.num;
2965
+ } else {
2966
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2967
+ averages.num++;
2968
+ }
2776
2969
  }
2777
2970
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2778
- setSize(ctx, state, itemKey, size);
2971
+ setSize(ctx, itemKey, size);
2779
2972
  return size - prevSize;
2780
2973
  }
2781
2974
  return 0;
@@ -2841,14 +3034,15 @@ function createColumnWrapperStyle(contentContainerStyle) {
2841
3034
  }
2842
3035
 
2843
3036
  // src/utils/createImperativeHandle.ts
2844
- function createImperativeHandle(ctx, state) {
3037
+ function createImperativeHandle(ctx) {
3038
+ const state = ctx.state;
2845
3039
  const scrollIndexIntoView = (options) => {
2846
3040
  if (state) {
2847
3041
  const { index, ...rest } = options;
2848
3042
  const { startNoBuffer, endNoBuffer } = state;
2849
3043
  if (index < startNoBuffer || index > endNoBuffer) {
2850
3044
  const viewPosition = index < startNoBuffer ? 0 : 1;
2851
- scrollToIndex(ctx, state, {
3045
+ scrollToIndex(ctx, {
2852
3046
  ...rest,
2853
3047
  index,
2854
3048
  viewPosition
@@ -2863,7 +3057,7 @@ function createImperativeHandle(ctx, state) {
2863
3057
  getScrollableNode: () => refScroller.current.getScrollableNode(),
2864
3058
  getScrollResponder: () => refScroller.current.getScrollResponder(),
2865
3059
  getState: () => ({
2866
- activeStickyIndex: state.activeStickyIndex,
3060
+ activeStickyIndex: peek$(ctx, "activeStickyIndex"),
2867
3061
  contentLength: state.totalSize,
2868
3062
  data: state.props.data,
2869
3063
  elementAtIndex: (index) => {
@@ -2874,6 +3068,8 @@ function createImperativeHandle(ctx, state) {
2874
3068
  endBuffered: state.endBuffered,
2875
3069
  isAtEnd: state.isAtEnd,
2876
3070
  isAtStart: state.isAtStart,
3071
+ listen: (signalName, cb) => listen$(ctx, signalName, cb),
3072
+ listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
2877
3073
  positionAtIndex: (index) => state.positions.get(getId(state, index)),
2878
3074
  positions: state.positions,
2879
3075
  scroll: state.scroll,
@@ -2898,23 +3094,23 @@ function createImperativeHandle(ctx, state) {
2898
3094
  if (index !== -1) {
2899
3095
  const paddingBottom = stylePaddingBottom || 0;
2900
3096
  const footerSize = peek$(ctx, "footerSize") || 0;
2901
- scrollToIndex(ctx, state, {
3097
+ scrollToIndex(ctx, {
3098
+ ...options,
2902
3099
  index,
2903
3100
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
2904
- viewPosition: 1,
2905
- ...options
3101
+ viewPosition: 1
2906
3102
  });
2907
3103
  }
2908
3104
  },
2909
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3105
+ scrollToIndex: (params) => scrollToIndex(ctx, params),
2910
3106
  scrollToItem: ({ item, ...props }) => {
2911
3107
  const data = state.props.data;
2912
3108
  const index = data.indexOf(item);
2913
3109
  if (index !== -1) {
2914
- scrollToIndex(ctx, state, { index, ...props });
3110
+ scrollToIndex(ctx, { index, ...props });
2915
3111
  }
2916
3112
  },
2917
- scrollToOffset: (params) => scrollTo(ctx, state, params),
3113
+ scrollToOffset: (params) => scrollTo(ctx, params),
2918
3114
  setScrollProcessingEnabled: (enabled) => {
2919
3115
  state.scrollProcessingEnabled = enabled;
2920
3116
  },
@@ -2924,8 +3120,9 @@ function createImperativeHandle(ctx, state) {
2924
3120
  }
2925
3121
  };
2926
3122
  }
2927
- function getRenderedItem(ctx, state, key) {
3123
+ function getRenderedItem(ctx, key) {
2928
3124
  var _a3;
3125
+ const state = ctx.state;
2929
3126
  if (!state) {
2930
3127
  return null;
2931
3128
  }
@@ -3002,11 +3199,13 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
3002
3199
  var DEFAULT_DRAW_DISTANCE = 250;
3003
3200
  var DEFAULT_ITEM_SIZE = 100;
3004
3201
  var LegendList = typedMemo(
3202
+ // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
3005
3203
  typedForwardRef(function LegendList2(props, forwardedRef) {
3006
3204
  const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
3007
3205
  const isChildrenMode = children !== void 0 && dataProp === void 0;
3008
3206
  const processedProps = isChildrenMode ? {
3009
3207
  ...restProps,
3208
+ childrenMode: true,
3010
3209
  data: (isArray(children) ? children : React2__namespace.Children.toArray(children)).flat(1),
3011
3210
  renderItem: ({ item }) => item
3012
3211
  } : {
@@ -3023,10 +3222,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3023
3222
  alignItemsAtEnd = false,
3024
3223
  columnWrapperStyle,
3025
3224
  contentContainerStyle: contentContainerStyleProp,
3225
+ contentInset,
3026
3226
  data: dataProp = [],
3027
3227
  dataVersion,
3028
3228
  drawDistance = 250,
3029
- enableAverages = true,
3030
3229
  estimatedItemSize: estimatedItemSizeProp,
3031
3230
  estimatedListSize,
3032
3231
  extraData,
@@ -3068,6 +3267,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3068
3267
  snapToIndices,
3069
3268
  stickyHeaderIndices: stickyHeaderIndicesProp,
3070
3269
  stickyIndices: stickyIndicesDeprecated,
3270
+ // TODOV3: Remove from v3 release
3071
3271
  style: styleProp,
3072
3272
  suggestEstimatedItemSize,
3073
3273
  viewabilityConfig,
@@ -3075,6 +3275,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3075
3275
  waitForInitialLayout = true,
3076
3276
  ...rest
3077
3277
  } = props;
3278
+ const animatedPropsInternal = props.animatedPropsInternal;
3279
+ const { childrenMode } = rest;
3078
3280
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
3079
3281
  const style = { ...StyleSheet.flatten(styleProp) };
3080
3282
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -3098,10 +3300,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3098
3300
  }
3099
3301
  const refState = React2.useRef();
3100
3302
  if (!refState.current) {
3101
- if (!ctx.internalState) {
3303
+ if (!ctx.state) {
3102
3304
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : getWindowSize())[horizontal ? "width" : "height"];
3103
- ctx.internalState = {
3104
- activeStickyIndex: void 0,
3305
+ ctx.state = {
3306
+ activeStickyIndex: -1,
3105
3307
  averageSizes: {},
3106
3308
  columns: /* @__PURE__ */ new Map(),
3107
3309
  containerItemKeys: /* @__PURE__ */ new Set(),
@@ -3127,9 +3329,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3127
3329
  initialScroll: initialScrollProp,
3128
3330
  isAtEnd: false,
3129
3331
  isAtStart: false,
3130
- isEndReached: false,
3332
+ isEndReached: null,
3131
3333
  isFirst: true,
3132
- isStartReached: false,
3334
+ isStartReached: null,
3133
3335
  lastBatchingAction: Date.now(),
3134
3336
  lastLayout: void 0,
3135
3337
  loadStartTime: Date.now(),
@@ -3161,12 +3363,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3161
3363
  totalSize: 0,
3162
3364
  viewabilityConfigCallbackPairs: void 0
3163
3365
  };
3164
- const internalState = ctx.internalState;
3165
- internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
3366
+ const internalState = ctx.state;
3367
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3166
3368
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3167
3369
  set$(ctx, "extraData", extraData);
3168
3370
  }
3169
- refState.current = ctx.internalState;
3371
+ refState.current = ctx.state;
3170
3372
  }
3171
3373
  const state = refState.current;
3172
3374
  const isFirstLocal = state.isFirst;
@@ -3180,9 +3382,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3180
3382
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
3181
3383
  state.props = {
3182
3384
  alignItemsAtEnd,
3385
+ animatedProps: animatedPropsInternal,
3386
+ contentInset,
3183
3387
  data: dataProp,
3184
3388
  dataVersion,
3185
- enableAverages,
3186
3389
  estimatedItemSize,
3187
3390
  getEstimatedItemSize,
3188
3391
  getFixedItemSize,
@@ -3225,62 +3428,62 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3225
3428
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3226
3429
  set$(ctx, "numColumns", numColumnsProp);
3227
3430
  const prevPaddingTop = peek$(ctx, "stylePaddingTop");
3228
- setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3431
+ setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3229
3432
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3230
3433
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3231
3434
  if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3232
3435
  if (state.scroll < 0) {
3233
3436
  paddingDiff += state.scroll;
3234
3437
  }
3235
- requestAdjust(ctx, state, paddingDiff);
3438
+ requestAdjust(ctx, paddingDiff);
3236
3439
  }
3237
3440
  };
3238
3441
  if (isFirstLocal) {
3239
3442
  initializeStateVars();
3240
3443
  updateItemPositions(
3241
3444
  ctx,
3242
- state,
3243
3445
  /*dataChanged*/
3244
3446
  true
3245
3447
  );
3246
3448
  }
3247
3449
  const initialContentOffset = React2.useMemo(() => {
3248
- var _a4, _b2;
3249
- const { initialScroll } = refState.current;
3250
- if (!initialScroll) {
3450
+ var _a4;
3451
+ let value;
3452
+ const { initialScroll, initialAnchor } = refState.current;
3453
+ if (initialScroll) {
3454
+ if (!IsNewArchitecture && initialScroll.index !== void 0 && (!initialAnchor || (initialAnchor == null ? void 0 : initialAnchor.index) !== initialScroll.index)) {
3455
+ refState.current.initialAnchor = {
3456
+ attempts: 0,
3457
+ index: initialScroll.index,
3458
+ settledTicks: 0,
3459
+ viewOffset: (_a4 = initialScroll.viewOffset) != null ? _a4 : 0,
3460
+ viewPosition: initialScroll.viewPosition
3461
+ };
3462
+ }
3463
+ if (initialScroll.contentOffset !== void 0) {
3464
+ value = initialScroll.contentOffset;
3465
+ } else {
3466
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
3467
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
3468
+ const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
3469
+ const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3470
+ refState.current.initialScroll = updatedInitialScroll;
3471
+ state.initialScroll = updatedInitialScroll;
3472
+ value = clampedOffset;
3473
+ }
3474
+ } else {
3251
3475
  refState.current.initialAnchor = void 0;
3252
- return 0;
3253
- }
3254
- if (initialScroll.index !== void 0 && (!refState.current.initialAnchor || ((_a4 = refState.current.initialAnchor) == null ? void 0 : _a4.index) !== initialScroll.index)) {
3255
- refState.current.initialAnchor = {
3256
- attempts: 0,
3257
- index: initialScroll.index,
3258
- settledTicks: 0,
3259
- viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
3260
- viewPosition: initialScroll.viewPosition
3261
- };
3476
+ value = 0;
3477
+ }
3478
+ if (!value) {
3479
+ state.didFinishInitialScroll = true;
3262
3480
  }
3263
- if (initialScroll.contentOffset !== void 0) {
3264
- return initialScroll.contentOffset;
3265
- }
3266
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
3267
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
3268
- let clampedOffset = resolvedOffset;
3269
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
3270
- const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
3271
- clampedOffset = Math.min(clampedOffset, maxOffset);
3272
- }
3273
- clampedOffset = Math.max(0, clampedOffset);
3274
- const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3275
- refState.current.initialScroll = updatedInitialScroll;
3276
- state.initialScroll = updatedInitialScroll;
3277
- refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
3278
- return clampedOffset;
3481
+ return value;
3279
3482
  }, [renderNum]);
3280
3483
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
3281
3484
  refState.current.lastBatchingAction = Date.now();
3282
3485
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
3283
- IS_DEV && warnDevOnce(
3486
+ IS_DEV && !childrenMode && warnDevOnce(
3284
3487
  "keyExtractor",
3285
3488
  "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."
3286
3489
  );
@@ -3305,12 +3508,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3305
3508
  }
3306
3509
  }, []);
3307
3510
  const doInitialScroll = React2.useCallback(() => {
3308
- var _a4;
3309
3511
  const initialScroll = state.initialScroll;
3310
3512
  if (initialScroll) {
3311
- scrollTo(ctx, state, {
3513
+ scrollTo(ctx, {
3312
3514
  animated: false,
3313
- index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
3515
+ index: initialScroll == null ? void 0 : initialScroll.index,
3314
3516
  isInitialScroll: true,
3315
3517
  offset: initialContentOffset,
3316
3518
  precomputedWithViewOffset: true
@@ -3319,7 +3521,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3319
3521
  }, [initialContentOffset]);
3320
3522
  const onLayoutChange = React2.useCallback((layout) => {
3321
3523
  doInitialScroll();
3322
- handleLayout(ctx, state, layout, setCanRender);
3524
+ handleLayout(ctx, layout, setCanRender);
3323
3525
  }, []);
3324
3526
  const { onLayout } = useOnLayoutSync({
3325
3527
  onLayoutChange,
@@ -3329,7 +3531,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3329
3531
  });
3330
3532
  React2.useLayoutEffect(() => {
3331
3533
  if (snapToIndices) {
3332
- updateSnapToOffsets(ctx, state);
3534
+ updateSnapToOffsets(ctx);
3333
3535
  }
3334
3536
  }, [snapToIndices]);
3335
3537
  React2.useLayoutEffect(() => {
@@ -3339,9 +3541,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3339
3541
  isFirst,
3340
3542
  props: { data }
3341
3543
  } = state;
3342
- const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
3544
+ const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
3343
3545
  if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
3344
- checkResetContainers(ctx, state, data);
3546
+ checkResetContainers(ctx, data);
3345
3547
  }
3346
3548
  state.didColumnsChange = false;
3347
3549
  state.didDataChange = false;
@@ -3368,18 +3570,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3368
3570
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
3369
3571
  if (!IsNewArchitecture) {
3370
3572
  useInit(() => {
3371
- doInitialAllocateContainers(ctx, state);
3573
+ doInitialAllocateContainers(ctx);
3372
3574
  });
3373
3575
  }
3374
- React2.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
3576
+ React2.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
3375
3577
  if (Platform2.OS === "web") {
3376
3578
  React2.useEffect(doInitialScroll, []);
3377
3579
  }
3378
3580
  const fns = React2.useMemo(
3379
3581
  () => ({
3380
- getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3381
- onScroll: (event) => onScroll(ctx, state, event),
3382
- updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj)
3582
+ getRenderedItem: (key) => getRenderedItem(ctx, key),
3583
+ onMomentumScrollEnd: (event) => {
3584
+ checkFinishedScrollFallback(ctx);
3585
+ if (onMomentumScrollEnd) {
3586
+ onMomentumScrollEnd(event);
3587
+ }
3588
+ },
3589
+ onScroll: (event) => onScroll(ctx, event),
3590
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
3383
3591
  }),
3384
3592
  []
3385
3593
  );
@@ -3391,6 +3599,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3391
3599
  alignItemsAtEnd,
3392
3600
  canRender,
3393
3601
  contentContainerStyle,
3602
+ contentInset,
3394
3603
  getRenderedItem: fns.getRenderedItem,
3395
3604
  horizontal,
3396
3605
  initialContentOffset,
@@ -3399,20 +3608,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3399
3608
  maintainVisibleContentPosition,
3400
3609
  onLayout,
3401
3610
  onLayoutHeader,
3402
- onMomentumScrollEnd: (event) => {
3403
- if (IsNewArchitecture) {
3404
- requestAnimationFrame(() => {
3405
- finishScrollTo(ctx, refState.current);
3406
- });
3407
- } else {
3408
- setTimeout(() => {
3409
- finishScrollTo(ctx, refState.current);
3410
- }, 1e3);
3411
- }
3412
- if (onMomentumScrollEnd) {
3413
- onMomentumScrollEnd(event);
3414
- }
3415
- },
3611
+ onMomentumScrollEnd: fns.onMomentumScrollEnd,
3416
3612
  onScroll: onScrollHandler,
3417
3613
  recycleItems,
3418
3614
  refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControl, {
@@ -3427,7 +3623,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3427
3623
  ),
3428
3624
  refScrollView: combinedRef,
3429
3625
  scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3430
- scrollEventThrottle: Platform2.OS === "web" ? 16 : void 0,
3626
+ scrollEventThrottle: 0,
3431
3627
  snapToIndices,
3432
3628
  stickyHeaderIndices,
3433
3629
  style,
@@ -3473,8 +3669,8 @@ function buildSectionListData({
3473
3669
  if (hasHeader) {
3474
3670
  const headerIndex = data.length;
3475
3671
  data.push({
3476
- kind: "header",
3477
3672
  key: `${sectionKey}:header`,
3673
+ kind: "header",
3478
3674
  section,
3479
3675
  sectionIndex
3480
3676
  });
@@ -3488,31 +3684,31 @@ function buildSectionListData({
3488
3684
  const itemKeyExtractor = (_b = section.keyExtractor) != null ? _b : keyExtractor;
3489
3685
  const itemKey = itemKeyExtractor(item, itemIndex);
3490
3686
  data.push({
3491
- kind: "item",
3492
- key: `${sectionKey}:item:${itemKey}`,
3493
- section,
3494
- sectionIndex,
3687
+ absoluteItemIndex: absoluteItemIndex++,
3495
3688
  item,
3496
3689
  itemIndex,
3497
- absoluteItemIndex: absoluteItemIndex++
3690
+ key: `${sectionKey}:item:${itemKey}`,
3691
+ kind: "item",
3692
+ section,
3693
+ sectionIndex
3498
3694
  });
3499
3695
  meta.items.push(data.length - 1);
3500
3696
  if (hasItemSeparator && itemIndex < items.length - 1) {
3501
3697
  data.push({
3502
- kind: "item-separator",
3503
3698
  key: `${sectionKey}:separator:${itemIndex}`,
3504
- section,
3505
- sectionIndex,
3699
+ kind: "item-separator",
3506
3700
  leadingItem: item,
3507
3701
  leadingItemIndex: itemIndex,
3702
+ section,
3703
+ sectionIndex,
3508
3704
  trailingItem: items[itemIndex + 1]
3509
3705
  });
3510
3706
  }
3511
3707
  }
3512
3708
  if (hasFooter) {
3513
3709
  data.push({
3514
- kind: "footer",
3515
3710
  key: `${sectionKey}:footer`,
3711
+ kind: "footer",
3516
3712
  section,
3517
3713
  sectionIndex
3518
3714
  });
@@ -3521,8 +3717,8 @@ function buildSectionListData({
3521
3717
  const isLastSection = sectionIndex === sections.length - 1;
3522
3718
  if (hasSectionSeparator && !isLastSection) {
3523
3719
  data.push({
3524
- kind: "section-separator",
3525
3720
  key: `${sectionKey}:section-separator`,
3721
+ kind: "section-separator",
3526
3722
  leadingSection: section,
3527
3723
  leadingSectionIndex: sectionIndex,
3528
3724
  trailingSection: sections[sectionIndex + 1]