@legendapp/list 3.0.0-beta.0 → 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.
package/index.native.mjs CHANGED
@@ -7,30 +7,64 @@ import { useSyncExternalStore } from 'use-sync-external-store/shim';
7
7
  Animated.View;
8
8
  var View = View$1;
9
9
  var Text = Text$1;
10
+
11
+ // src/state/getContentInsetEnd.ts
12
+ function getContentInsetEnd(state) {
13
+ var _a3;
14
+ const { props } = state;
15
+ const horizontal = props.horizontal;
16
+ let contentInset = props.contentInset;
17
+ if (!contentInset) {
18
+ const animatedInset = (_a3 = props.animatedProps) == null ? void 0 : _a3.contentInset;
19
+ if (animatedInset) {
20
+ if ("get" in animatedInset) {
21
+ contentInset = animatedInset.get();
22
+ } else {
23
+ contentInset = animatedInset;
24
+ }
25
+ }
26
+ }
27
+ return (horizontal ? contentInset == null ? void 0 : contentInset.right : contentInset == null ? void 0 : contentInset.bottom) || 0;
28
+ }
29
+
30
+ // src/state/getContentSize.ts
31
+ function getContentSize(ctx) {
32
+ var _a3;
33
+ const { values, state } = ctx;
34
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
35
+ const stylePaddingBottom = state.props.stylePaddingBottom || 0;
36
+ const headerSize = values.get("headerSize") || 0;
37
+ const footerSize = values.get("footerSize") || 0;
38
+ const contentInsetBottom = getContentInsetEnd(state);
39
+ const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
40
+ return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
41
+ }
10
42
  var createAnimatedValue = (value) => new Animated.Value(value);
11
43
 
12
44
  // src/state/state.tsx
13
45
  var ContextState = React2.createContext(null);
46
+ var contextNum = 0;
14
47
  function StateProvider({ children }) {
15
48
  const [value] = React2.useState(() => ({
16
49
  animatedScrollY: createAnimatedValue(0),
17
50
  columnWrapperStyle: void 0,
18
- internalState: void 0,
51
+ contextNum: contextNum++,
19
52
  listeners: /* @__PURE__ */ new Map(),
20
53
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
21
54
  mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
22
55
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
23
56
  mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
24
57
  mapViewabilityValues: /* @__PURE__ */ new Map(),
58
+ positionListeners: /* @__PURE__ */ new Map(),
59
+ state: void 0,
25
60
  values: /* @__PURE__ */ new Map([
26
61
  ["alignItemsPaddingTop", 0],
27
62
  ["stylePaddingTop", 0],
28
63
  ["headerSize", 0],
29
64
  ["numContainers", 0],
30
- ["activeStickyIndex", void 0],
65
+ ["activeStickyIndex", -1],
31
66
  ["totalSize", 0],
32
- ["scrollAdjustPending", 0],
33
- ["scrollingTo", void 0]
67
+ ["scrollAdjustPending", 0]
34
68
  ]),
35
69
  viewRefs: /* @__PURE__ */ new Map()
36
70
  }));
@@ -98,14 +132,24 @@ function set$(ctx, signalName, value) {
98
132
  }
99
133
  }
100
134
  }
101
- function getContentSize(ctx) {
102
- var _a3, _b;
103
- const { values } = ctx;
104
- const stylePaddingTop = values.get("stylePaddingTop") || 0;
105
- const headerSize = values.get("headerSize") || 0;
106
- const footerSize = values.get("footerSize") || 0;
107
- const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
108
- return headerSize + footerSize + totalSize + stylePaddingTop;
135
+ function listenPosition$(ctx, key, cb) {
136
+ const { positionListeners } = ctx;
137
+ let setListeners = positionListeners.get(key);
138
+ if (!setListeners) {
139
+ setListeners = /* @__PURE__ */ new Set();
140
+ positionListeners.set(key, setListeners);
141
+ }
142
+ setListeners.add(cb);
143
+ return () => setListeners.delete(cb);
144
+ }
145
+ function notifyPosition$(ctx, key, value) {
146
+ const { positionListeners } = ctx;
147
+ const setListeners = positionListeners.get(key);
148
+ if (setListeners) {
149
+ for (const listener of setListeners) {
150
+ listener(value);
151
+ }
152
+ }
109
153
  }
110
154
  function useArr$(signalNames) {
111
155
  const ctx = React2.useContext(ContextState);
@@ -186,7 +230,8 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
186
230
  // src/constants-platform.native.ts
187
231
  var IsNewArchitecture = global.nativeFabricUIManager != null;
188
232
  var useAnimatedValue = (initialValue) => {
189
- return useRef(new Animated.Value(initialValue)).current;
233
+ const [animAnimatedValue] = useState(() => new Animated.Value(initialValue));
234
+ return animAnimatedValue;
190
235
  };
191
236
 
192
237
  // src/utils/helpers.ts
@@ -275,7 +320,7 @@ var typedForwardRef = forwardRef;
275
320
  var typedMemo = memo;
276
321
 
277
322
  // src/components/PositionView.native.tsx
278
- var PositionViewState = typedMemo(function PositionView({
323
+ var PositionViewState = typedMemo(function PositionViewState2({
279
324
  id,
280
325
  horizontal,
281
326
  style,
@@ -295,7 +340,7 @@ var PositionViewState = typedMemo(function PositionView({
295
340
  }
296
341
  );
297
342
  });
298
- var PositionViewAnimated = typedMemo(function PositionView2({
343
+ var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
299
344
  id,
300
345
  horizontal,
301
346
  style,
@@ -338,14 +383,9 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
338
383
  const viewStyle = React2.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
339
384
  return /* @__PURE__ */ React2.createElement(Animated.View, { ref: refView, style: viewStyle, ...rest });
340
385
  });
341
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
342
- var symbolFirst = Symbol();
386
+ var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
343
387
  function useInit(cb) {
344
- const refValue = useRef(symbolFirst);
345
- if (refValue.current === symbolFirst) {
346
- refValue.current = cb();
347
- }
348
- return refValue.current;
388
+ useState(() => cb());
349
389
  }
350
390
 
351
391
  // src/state/ContextContainer.ts
@@ -611,6 +651,7 @@ var Container = typedMemo(function Container2({
611
651
  if (!IsNewArchitecture) {
612
652
  useEffect(() => {
613
653
  if (!isNullOrUndefined(itemKey)) {
654
+ didLayoutRef.current = false;
614
655
  const timeout = setTimeout(() => {
615
656
  if (!didLayoutRef.current) {
616
657
  const {
@@ -630,7 +671,7 @@ var Container = typedMemo(function Container2({
630
671
  }
631
672
  }, [itemKey]);
632
673
  }
633
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
674
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView;
634
675
  return /* @__PURE__ */ React2.createElement(
635
676
  PositionComponent,
636
677
  {
@@ -665,10 +706,10 @@ var Containers = typedMemo(function Containers2({
665
706
  // If this is the initial scroll, we don't want to delay because we want to update the size immediately
666
707
  delay: (value, prevValue) => {
667
708
  var _a3;
668
- return !((_a3 = ctx.internalState) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
709
+ return !((_a3 = ctx.state) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
669
710
  }
670
711
  });
671
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
712
+ const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("readyToRender", { getValue: (value) => value ? 1 : 0 }) : void 0;
672
713
  const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
673
714
  const containers = [];
674
715
  for (let i = 0; i < numContainers; i++) {
@@ -711,7 +752,8 @@ var Containers = typedMemo(function Containers2({
711
752
  return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
712
753
  });
713
754
  function DevNumbers() {
714
- return IS_DEV && React2.memo(function DevNumbers2() {
755
+ return IS_DEV && // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
756
+ React2.memo(function DevNumbers2() {
715
757
  return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2.createElement(
716
758
  View$1,
717
759
  {
@@ -819,13 +861,6 @@ var ListComponent = typedMemo(function ListComponent2({
819
861
  () => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
820
862
  [renderScrollComponent]
821
863
  ) : ListComponentScrollView;
822
- React2.useEffect(() => {
823
- if (canRender) {
824
- setTimeout(() => {
825
- scrollAdjustHandler.setMounted();
826
- }, 0);
827
- }
828
- }, [canRender]);
829
864
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
830
865
  return /* @__PURE__ */ React2.createElement(
831
866
  SnapOrScroll,
@@ -889,10 +924,11 @@ function getId(state, index) {
889
924
  }
890
925
 
891
926
  // src/core/calculateOffsetForIndex.ts
892
- function calculateOffsetForIndex(ctx, state, index) {
927
+ function calculateOffsetForIndex(ctx, index) {
928
+ const state = ctx.state;
893
929
  let position = 0;
894
930
  if (index !== void 0) {
895
- position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
931
+ position = state.positions.get(getId(state, index)) || 0;
896
932
  const paddingTop = peek$(ctx, "stylePaddingTop");
897
933
  if (paddingTop) {
898
934
  position += paddingTop;
@@ -906,7 +942,8 @@ function calculateOffsetForIndex(ctx, state, index) {
906
942
  }
907
943
 
908
944
  // src/utils/setPaddingTop.ts
909
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
945
+ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
946
+ const state = ctx.state;
910
947
  if (stylePaddingTop !== void 0) {
911
948
  const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
912
949
  if (stylePaddingTop < prevStylePaddingTop) {
@@ -925,7 +962,8 @@ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
925
962
  }
926
963
 
927
964
  // src/utils/updateAlignItemsPaddingTop.ts
928
- function updateAlignItemsPaddingTop(ctx, state) {
965
+ function updateAlignItemsPaddingTop(ctx) {
966
+ const state = ctx.state;
929
967
  const {
930
968
  scrollLength,
931
969
  props: { alignItemsAtEnd, data }
@@ -936,12 +974,13 @@ function updateAlignItemsPaddingTop(ctx, state) {
936
974
  const contentSize = getContentSize(ctx);
937
975
  alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
938
976
  }
939
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
977
+ setPaddingTop(ctx, { alignItemsPaddingTop });
940
978
  }
941
979
  }
942
980
 
943
981
  // src/core/addTotalSize.ts
944
- function addTotalSize(ctx, state, key, add) {
982
+ function addTotalSize(ctx, key, add) {
983
+ const state = ctx.state;
945
984
  const { alignItemsAtEnd } = state.props;
946
985
  const prevTotalSize = state.totalSize;
947
986
  let totalSize = state.totalSize;
@@ -962,31 +1001,34 @@ function addTotalSize(ctx, state, key, add) {
962
1001
  state.totalSize = totalSize;
963
1002
  set$(ctx, "totalSize", totalSize);
964
1003
  if (alignItemsAtEnd) {
965
- updateAlignItemsPaddingTop(ctx, state);
1004
+ updateAlignItemsPaddingTop(ctx);
966
1005
  }
967
1006
  }
968
1007
  }
969
1008
  }
970
1009
 
971
1010
  // src/core/setSize.ts
972
- function setSize(ctx, state, itemKey, size) {
1011
+ function setSize(ctx, itemKey, size) {
1012
+ const state = ctx.state;
973
1013
  const { sizes } = state;
974
1014
  const previousSize = sizes.get(itemKey);
975
1015
  const diff = previousSize !== void 0 ? size - previousSize : size;
976
1016
  if (diff !== 0) {
977
- addTotalSize(ctx, state, itemKey, diff);
1017
+ addTotalSize(ctx, itemKey, diff);
978
1018
  }
979
1019
  sizes.set(itemKey, size);
980
1020
  }
981
1021
 
982
1022
  // src/utils/getItemSize.ts
983
- function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
1023
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
984
1024
  var _a3, _b;
1025
+ const state = ctx.state;
985
1026
  const {
986
1027
  sizesKnown,
987
1028
  sizes,
988
1029
  averageSizes,
989
- props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
1030
+ props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
1031
+ scrollingTo
990
1032
  } = state;
991
1033
  const sizeKnown = sizesKnown.get(key);
992
1034
  if (sizeKnown !== void 0) {
@@ -994,7 +1036,6 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
994
1036
  }
995
1037
  let size;
996
1038
  const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
997
- const scrollingTo = peek$(ctx, "scrollingTo");
998
1039
  if (preferCachedSize) {
999
1040
  const cachedSize = sizes.get(key);
1000
1041
  if (cachedSize !== void 0) {
@@ -1022,84 +1063,167 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
1022
1063
  if (size === void 0) {
1023
1064
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
1024
1065
  }
1025
- setSize(ctx, state, key, size);
1066
+ setSize(ctx, key, size);
1026
1067
  return size;
1027
1068
  }
1028
1069
 
1029
1070
  // src/core/calculateOffsetWithOffsetPosition.ts
1030
- function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
1071
+ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1072
+ const state = ctx.state;
1031
1073
  const { index, viewOffset, viewPosition } = params;
1032
1074
  let offset = offsetParam;
1033
1075
  if (viewOffset) {
1034
1076
  offset -= viewOffset;
1035
1077
  }
1036
1078
  if (viewPosition !== void 0 && index !== void 0) {
1037
- offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
1079
+ const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1080
+ const trailingInset = getContentInsetEnd(state);
1081
+ offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
1038
1082
  }
1039
1083
  return offset;
1040
1084
  }
1041
1085
 
1086
+ // src/core/clampScrollOffset.ts
1087
+ function clampScrollOffset(ctx, offset) {
1088
+ const state = ctx.state;
1089
+ const contentSize = getContentSize(ctx);
1090
+ let clampedOffset = offset;
1091
+ if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength)) {
1092
+ const maxOffset = Math.max(0, contentSize - state.scrollLength);
1093
+ clampedOffset = Math.min(offset, maxOffset);
1094
+ }
1095
+ clampedOffset = Math.max(0, clampedOffset);
1096
+ return clampedOffset;
1097
+ }
1098
+ var Platform2 = Platform;
1099
+
1100
+ // src/utils/setInitialRenderState.ts
1101
+ function setInitialRenderState(ctx, {
1102
+ didLayout,
1103
+ didInitialScroll
1104
+ }) {
1105
+ const { state } = ctx;
1106
+ if (didLayout) {
1107
+ state.didContainersLayout = true;
1108
+ }
1109
+ if (didInitialScroll) {
1110
+ state.didFinishInitialScroll = true;
1111
+ }
1112
+ if (state.didContainersLayout && state.didFinishInitialScroll) {
1113
+ set$(ctx, "readyToRender", true);
1114
+ }
1115
+ }
1116
+
1042
1117
  // src/core/finishScrollTo.ts
1043
- function finishScrollTo(ctx, state) {
1118
+ function finishScrollTo(ctx) {
1044
1119
  var _a3, _b;
1045
- if (state) {
1120
+ const state = ctx.state;
1121
+ if (state == null ? void 0 : state.scrollingTo) {
1046
1122
  state.scrollHistory.length = 0;
1047
1123
  state.initialScroll = void 0;
1048
1124
  state.initialAnchor = void 0;
1049
- set$(ctx, "scrollingTo", void 0);
1125
+ state.scrollingTo = void 0;
1050
1126
  if (state.pendingTotalSize !== void 0) {
1051
- addTotalSize(ctx, state, null, state.pendingTotalSize);
1127
+ addTotalSize(ctx, null, state.pendingTotalSize);
1052
1128
  }
1053
1129
  if ((_a3 = state.props) == null ? void 0 : _a3.data) {
1054
1130
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
1055
1131
  }
1132
+ if (Platform2.OS === "web") {
1133
+ state.scrollAdjustHandler.commitPendingAdjust();
1134
+ }
1135
+ setInitialRenderState(ctx, { didInitialScroll: true });
1056
1136
  }
1057
1137
  }
1058
- var Platform2 = Platform;
1059
1138
 
1060
- // src/core/scrollTo.ts
1061
- function scrollTo(ctx, state, params) {
1139
+ // src/core/checkFinishedScroll.ts
1140
+ function checkFinishedScroll(ctx) {
1141
+ ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
1142
+ }
1143
+ function checkFinishedScrollFrame(ctx) {
1144
+ const scrollingTo = ctx.state.scrollingTo;
1145
+ if (scrollingTo) {
1146
+ const { state } = ctx;
1147
+ state.animFrameCheckFinishedScroll = void 0;
1148
+ const scroll = state.scroll;
1149
+ const adjust = state.scrollAdjustHandler.getAdjust();
1150
+ const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1151
+ const maxOffset = clampScrollOffset(ctx, scroll);
1152
+ const diff1 = Math.abs(scroll - clampedTargetOffset);
1153
+ const diff2 = Math.abs(diff1 - adjust);
1154
+ const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
1155
+ if (isNotOverscrolled && (diff1 < 1 || diff2 < 1)) {
1156
+ finishScrollTo(ctx);
1157
+ }
1158
+ }
1159
+ }
1160
+ function checkFinishedScrollFallback(ctx) {
1161
+ const state = ctx.state;
1162
+ const scrollingTo = state.scrollingTo;
1163
+ const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
1164
+ state.timeoutCheckFinishedScrollFallback = setTimeout(
1165
+ () => {
1166
+ let numChecks = 0;
1167
+ const checkHasScrolled = () => {
1168
+ state.timeoutCheckFinishedScrollFallback = void 0;
1169
+ const isStillScrollingTo = state.scrollingTo;
1170
+ if (isStillScrollingTo) {
1171
+ numChecks++;
1172
+ if (state.hasScrolled || numChecks > 5) {
1173
+ finishScrollTo(ctx);
1174
+ } else {
1175
+ state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
1176
+ }
1177
+ }
1178
+ };
1179
+ checkHasScrolled();
1180
+ },
1181
+ slowTimeout ? 500 : 100
1182
+ );
1183
+ }
1184
+
1185
+ // src/core/doScrollTo.native.ts
1186
+ function doScrollTo(ctx, params) {
1062
1187
  var _a3;
1063
- const { noScrollingTo, ...scrollTarget } = params;
1188
+ const state = ctx.state;
1189
+ const { animated, horizontal, offset } = params;
1190
+ const { refScroller } = state;
1191
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1192
+ animated: !!animated,
1193
+ x: horizontal ? offset : 0,
1194
+ y: horizontal ? 0 : offset
1195
+ });
1196
+ if (!animated) {
1197
+ state.scroll = offset;
1198
+ checkFinishedScrollFallback(ctx);
1199
+ }
1200
+ }
1201
+
1202
+ // src/core/scrollTo.ts
1203
+ function scrollTo(ctx, params) {
1204
+ const state = ctx.state;
1205
+ const { noScrollingTo, forceScroll, ...scrollTarget } = params;
1064
1206
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
1065
1207
  const {
1066
- refScroller,
1067
1208
  props: { horizontal }
1068
1209
  } = state;
1069
- let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
1070
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
1071
- const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
1072
- offset = Math.min(offset, maxOffset);
1210
+ if (state.animFrameCheckFinishedScroll) {
1211
+ cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
1212
+ }
1213
+ if (state.timeoutCheckFinishedScrollFallback) {
1214
+ clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
1073
1215
  }
1216
+ let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
1217
+ offset = clampScrollOffset(ctx, offset);
1074
1218
  state.scrollHistory.length = 0;
1075
1219
  if (!noScrollingTo) {
1076
- set$(ctx, "scrollingTo", scrollTarget);
1220
+ state.scrollingTo = scrollTarget;
1077
1221
  }
1078
1222
  state.scrollPending = offset;
1079
- if (!isInitialScroll || Platform2.OS === "android") {
1080
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1081
- animated: !!animated,
1082
- x: horizontal ? offset : 0,
1083
- y: horizontal ? 0 : offset
1084
- });
1085
- }
1086
- if (!animated) {
1223
+ if (forceScroll || !isInitialScroll || Platform2.OS === "android") {
1224
+ doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
1225
+ } else {
1087
1226
  state.scroll = offset;
1088
- if (Platform2.OS === "web") {
1089
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1090
- if (value && peek$(ctx, "scrollingTo")) {
1091
- finishScrollTo(ctx, state);
1092
- unlisten();
1093
- }
1094
- });
1095
- } else {
1096
- setTimeout(() => finishScrollTo(ctx, state), 100);
1097
- }
1098
- if (isInitialScroll) {
1099
- setTimeout(() => {
1100
- state.initialScroll = void 0;
1101
- }, 500);
1102
- }
1103
1227
  }
1104
1228
  }
1105
1229
 
@@ -1108,6 +1232,12 @@ var HYSTERESIS_MULTIPLIER = 1.3;
1108
1232
  var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1109
1233
  const absDistance = Math.abs(distance);
1110
1234
  const within = atThreshold || threshold > 0 && absDistance <= threshold;
1235
+ if (wasReached === null) {
1236
+ if (!within && distance >= 0) {
1237
+ return false;
1238
+ }
1239
+ return null;
1240
+ }
1111
1241
  const updateSnapshot = () => {
1112
1242
  setSnapshot == null ? void 0 : setSnapshot({
1113
1243
  atThreshold,
@@ -1140,8 +1270,9 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
1140
1270
  };
1141
1271
 
1142
1272
  // src/utils/checkAtBottom.ts
1143
- function checkAtBottom(ctx, state) {
1273
+ function checkAtBottom(ctx) {
1144
1274
  var _a3;
1275
+ const state = ctx.state;
1145
1276
  if (!state) {
1146
1277
  return;
1147
1278
  }
@@ -1214,15 +1345,15 @@ function checkAtTop(state) {
1214
1345
  }
1215
1346
 
1216
1347
  // src/core/updateScroll.ts
1217
- function updateScroll(ctx, state, newScroll, forceUpdate) {
1348
+ function updateScroll(ctx, newScroll, forceUpdate) {
1218
1349
  var _a3;
1219
- const scrollingTo = peek$(ctx, "scrollingTo");
1350
+ const state = ctx.state;
1351
+ const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
1220
1352
  state.hasScrolled = true;
1221
1353
  state.lastBatchingAction = Date.now();
1222
1354
  const currentTime = Date.now();
1223
- const adjust = state.scrollAdjustHandler.getAdjust();
1224
- const lastHistoryAdjust = state.lastScrollAdjustForHistory;
1225
- const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
1355
+ const adjust = scrollAdjustHandler.getAdjust();
1356
+ const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1226
1357
  if (adjustChanged) {
1227
1358
  state.scrollHistory.length = 0;
1228
1359
  }
@@ -1247,22 +1378,26 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1247
1378
  return;
1248
1379
  }
1249
1380
  }
1250
- if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1381
+ const lastCalculated = state.scrollLastCalculate;
1382
+ const shouldUpdate = forceUpdate || state.dataChangeNeedsScrollUpdate || state.scrollLastCalculate === void 0 || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
1383
+ if (shouldUpdate) {
1384
+ state.scrollLastCalculate = state.scroll;
1251
1385
  state.ignoreScrollFromMVCPIgnored = false;
1252
1386
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1253
- checkAtBottom(ctx, state);
1387
+ checkAtBottom(ctx);
1254
1388
  checkAtTop(state);
1255
1389
  state.dataChangeNeedsScrollUpdate = false;
1256
1390
  }
1257
1391
  }
1258
1392
 
1259
1393
  // src/utils/requestAdjust.ts
1260
- function requestAdjust(ctx, state, positionDiff, dataChanged) {
1394
+ function requestAdjust(ctx, positionDiff, dataChanged) {
1395
+ const state = ctx.state;
1261
1396
  if (Math.abs(positionDiff) > 0.1) {
1262
1397
  const needsScrollWorkaround = Platform2.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
1263
1398
  const doit = () => {
1264
1399
  if (needsScrollWorkaround) {
1265
- scrollTo(ctx, state, {
1400
+ scrollTo(ctx, {
1266
1401
  noScrollingTo: true,
1267
1402
  offset: state.scroll
1268
1403
  });
@@ -1275,8 +1410,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1275
1410
  };
1276
1411
  state.scroll += positionDiff;
1277
1412
  state.scrollForNextCalculateItemsInView = void 0;
1278
- const didLayout = peek$(ctx, "containersDidLayout");
1279
- if (didLayout) {
1413
+ const readyToRender = peek$(ctx, "readyToRender");
1414
+ if (readyToRender) {
1280
1415
  doit();
1281
1416
  if (Platform2.OS !== "web") {
1282
1417
  const threshold = state.scroll - positionDiff / 2;
@@ -1298,7 +1433,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1298
1433
  if (shouldForceUpdate) {
1299
1434
  state.ignoreScrollFromMVCPIgnored = false;
1300
1435
  state.scrollPending = state.scroll;
1301
- updateScroll(ctx, state, state.scroll, true);
1436
+ updateScroll(ctx, state.scroll, true);
1302
1437
  }
1303
1438
  }, delay);
1304
1439
  }
@@ -1313,28 +1448,27 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1313
1448
  var INITIAL_ANCHOR_TOLERANCE = 0.5;
1314
1449
  var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
1315
1450
  var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1316
- function ensureInitialAnchor(ctx, state) {
1451
+ function ensureInitialAnchor(ctx) {
1317
1452
  var _a3, _b, _c, _d, _e;
1318
- const anchor = state.initialAnchor;
1453
+ const state = ctx.state;
1454
+ const { initialAnchor, didContainersLayout, positions, scroll, scrollLength } = state;
1455
+ const anchor = initialAnchor;
1319
1456
  const item = state.props.data[anchor.index];
1320
- const containersDidLayout = peek$(ctx, "containersDidLayout");
1321
- if (!containersDidLayout) {
1457
+ if (!didContainersLayout) {
1322
1458
  return;
1323
1459
  }
1324
1460
  const id = getId(state, anchor.index);
1325
- if (state.positions.get(id) === void 0) {
1461
+ if (positions.get(id) === void 0) {
1326
1462
  return;
1327
1463
  }
1328
- const size = getItemSize(ctx, state, id, anchor.index, item, true, true);
1464
+ const size = getItemSize(ctx, id, anchor.index, item, true, true);
1329
1465
  if (size === void 0) {
1330
1466
  return;
1331
1467
  }
1332
- const availableSpace = Math.max(0, state.scrollLength - size);
1333
- const desiredOffset = calculateOffsetForIndex(ctx, state, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1334
- const contentSize = getContentSize(ctx);
1335
- const maxOffset = Math.max(0, contentSize - state.scrollLength);
1336
- const clampedDesiredOffset = Math.max(0, Math.min(desiredOffset, maxOffset));
1337
- const delta = clampedDesiredOffset - state.scroll;
1468
+ const availableSpace = Math.max(0, scrollLength - size);
1469
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1470
+ const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset);
1471
+ const delta = clampedDesiredOffset - scroll;
1338
1472
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1339
1473
  const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
1340
1474
  if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
@@ -1358,18 +1492,21 @@ function ensureInitialAnchor(ctx, state) {
1358
1492
  lastDelta: delta,
1359
1493
  settledTicks: 0
1360
1494
  });
1361
- requestAdjust(ctx, state, delta);
1495
+ requestAdjust(ctx, delta);
1496
+ requestAnimationFrame(() => finishScrollTo(ctx));
1362
1497
  }
1363
1498
 
1364
1499
  // src/core/mvcp.ts
1365
- function prepareMVCP(ctx, state, dataChanged) {
1500
+ function prepareMVCP(ctx, dataChanged) {
1501
+ const state = ctx.state;
1366
1502
  const { idsInView, positions, props } = state;
1367
1503
  const { maintainVisibleContentPosition } = props;
1368
- const scrollingTo = peek$(ctx, "scrollingTo");
1504
+ const scrollingTo = state.scrollingTo;
1369
1505
  let prevPosition;
1370
1506
  let targetId;
1371
1507
  const idsInViewWithPositions = [];
1372
1508
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1509
+ const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1373
1510
  const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1374
1511
  const indexByKey = state.indexByKey;
1375
1512
  if (shouldMVCP) {
@@ -1378,7 +1515,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1378
1515
  return void 0;
1379
1516
  }
1380
1517
  targetId = getId(state, scrollTarget);
1381
- } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
1518
+ } else if (idsInView.length > 0 && state.didContainersLayout) {
1382
1519
  if (dataChanged) {
1383
1520
  for (let i = 0; i < idsInView.length; i++) {
1384
1521
  const id = idsInView[i];
@@ -1395,7 +1532,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1395
1532
  prevPosition = positions.get(targetId);
1396
1533
  }
1397
1534
  return () => {
1398
- let positionDiff;
1535
+ let positionDiff = 0;
1399
1536
  if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1400
1537
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1401
1538
  const { id, position } = idsInViewWithPositions[i];
@@ -1421,16 +1558,28 @@ function prepareMVCP(ctx, state, dataChanged) {
1421
1558
  positionDiff = diff;
1422
1559
  }
1423
1560
  }
1424
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1425
- requestAdjust(ctx, state, positionDiff, dataChanged && maintainVisibleContentPosition);
1561
+ if (scrollingToViewPosition && scrollingToViewPosition > 0) {
1562
+ const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
1563
+ const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
1564
+ if (newSize !== void 0 && prevSize !== void 0 && newSize !== (scrollingTo == null ? void 0 : scrollingTo.itemSize)) {
1565
+ const diff = newSize - prevSize;
1566
+ if (diff !== 0) {
1567
+ positionDiff += (newSize - prevSize) * scrollingToViewPosition;
1568
+ scrollingTo.itemSize = newSize;
1569
+ }
1570
+ }
1571
+ }
1572
+ if (Math.abs(positionDiff) > 0.1) {
1573
+ requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1426
1574
  }
1427
1575
  };
1428
1576
  }
1429
1577
  }
1430
1578
 
1431
1579
  // src/core/prepareColumnStartState.ts
1432
- function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1580
+ function prepareColumnStartState(ctx, startIndex, useAverageSize) {
1433
1581
  var _a3;
1582
+ const state = ctx.state;
1434
1583
  const numColumns = peek$(ctx, "numColumns");
1435
1584
  let rowStartIndex = startIndex;
1436
1585
  const columnAtStart = state.columns.get(state.idCache[startIndex]);
@@ -1445,7 +1594,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1445
1594
  const prevId = state.idCache[prevIndex];
1446
1595
  const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1447
1596
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1448
- const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
1597
+ const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
1449
1598
  currentRowTop = prevPosition + prevRowHeight;
1450
1599
  }
1451
1600
  return {
@@ -1468,7 +1617,8 @@ function findRowStartIndex(state, numColumns, index) {
1468
1617
  }
1469
1618
  return rowStart;
1470
1619
  }
1471
- function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1620
+ function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
1621
+ const state = ctx.state;
1472
1622
  if (endIndex < startIndex) {
1473
1623
  return 0;
1474
1624
  }
@@ -1482,7 +1632,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1482
1632
  continue;
1483
1633
  }
1484
1634
  const id = state.idCache[i];
1485
- const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
1635
+ const size = getItemSize(ctx, id, i, data[i], useAverageSize);
1486
1636
  if (size > maxSize) {
1487
1637
  maxSize = size;
1488
1638
  }
@@ -1491,22 +1641,23 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1491
1641
  }
1492
1642
 
1493
1643
  // src/core/updateTotalSize.ts
1494
- function updateTotalSize(ctx, state) {
1644
+ function updateTotalSize(ctx) {
1645
+ const state = ctx.state;
1495
1646
  const {
1496
1647
  positions,
1497
1648
  props: { data }
1498
1649
  } = state;
1499
1650
  if (data.length === 0) {
1500
- addTotalSize(ctx, state, null, 0);
1651
+ addTotalSize(ctx, null, 0);
1501
1652
  } else {
1502
1653
  const lastId = getId(state, data.length - 1);
1503
1654
  if (lastId !== void 0) {
1504
1655
  const lastPosition = positions.get(lastId);
1505
1656
  if (lastPosition !== void 0) {
1506
- const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
1657
+ const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
1507
1658
  if (lastSize !== void 0) {
1508
1659
  const totalSize = lastPosition + lastSize;
1509
- addTotalSize(ctx, state, null, totalSize);
1660
+ addTotalSize(ctx, null, totalSize);
1510
1661
  }
1511
1662
  }
1512
1663
  }
@@ -1552,7 +1703,8 @@ var getScrollVelocity = (state) => {
1552
1703
  };
1553
1704
 
1554
1705
  // src/utils/updateSnapToOffsets.ts
1555
- function updateSnapToOffsets(ctx, state) {
1706
+ function updateSnapToOffsets(ctx) {
1707
+ const state = ctx.state;
1556
1708
  const {
1557
1709
  positions,
1558
1710
  props: { snapToIndices }
@@ -1567,30 +1719,30 @@ function updateSnapToOffsets(ctx, state) {
1567
1719
  }
1568
1720
 
1569
1721
  // src/core/updateItemPositions.ts
1570
- function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1722
+ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1571
1723
  doMVCP: false,
1572
1724
  forceFullUpdate: false,
1573
1725
  scrollBottomBuffered: -1,
1574
1726
  startIndex: 0
1575
1727
  }) {
1576
1728
  var _a3, _b, _c, _d, _e;
1729
+ const state = ctx.state;
1577
1730
  const {
1578
1731
  columns,
1579
1732
  indexByKey,
1580
1733
  positions,
1581
1734
  idCache,
1582
1735
  sizesKnown,
1583
- props: { getEstimatedItemSize, snapToIndices, enableAverages }
1736
+ props: { data, getEstimatedItemSize, snapToIndices },
1737
+ scrollingTo
1584
1738
  } = state;
1585
- const data = state.props.data;
1586
1739
  const dataLength = data.length;
1587
1740
  const numColumns = peek$(ctx, "numColumns");
1588
- const scrollingTo = peek$(ctx, "scrollingTo");
1589
1741
  const hasColumns = numColumns > 1;
1590
1742
  const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1591
1743
  const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
1592
1744
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1593
- const useAverageSize = enableAverages && !getEstimatedItemSize;
1745
+ const useAverageSize = !getEstimatedItemSize;
1594
1746
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1595
1747
  let currentRowTop = 0;
1596
1748
  let column = 1;
@@ -1599,7 +1751,6 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1599
1751
  if (hasColumns) {
1600
1752
  const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1601
1753
  ctx,
1602
- state,
1603
1754
  startIndex,
1604
1755
  useAverageSize
1605
1756
  );
@@ -1609,7 +1760,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1609
1760
  const prevIndex = startIndex - 1;
1610
1761
  const prevId = getId(state, prevIndex);
1611
1762
  const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1612
- const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1763
+ const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1613
1764
  currentRowTop = prevPosition + prevSize;
1614
1765
  }
1615
1766
  }
@@ -1626,7 +1777,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1626
1777
  breakAt = i + itemsPerRow + 10;
1627
1778
  }
1628
1779
  const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1629
- const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
1780
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
1630
1781
  if (IS_DEV && needsIndexByKey) {
1631
1782
  if (indexByKeyForChecking.has(id)) {
1632
1783
  console.error(
@@ -1635,7 +1786,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1635
1786
  }
1636
1787
  indexByKeyForChecking.set(id, i);
1637
1788
  }
1638
- positions.set(id, currentRowTop);
1789
+ if (currentRowTop !== positions.get(id)) {
1790
+ positions.set(id, currentRowTop);
1791
+ notifyPosition$(ctx, id, currentRowTop);
1792
+ }
1639
1793
  if (needsIndexByKey) {
1640
1794
  indexByKey.set(id, i);
1641
1795
  }
@@ -1655,10 +1809,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1655
1809
  }
1656
1810
  }
1657
1811
  if (!didBreakEarly) {
1658
- updateTotalSize(ctx, state);
1812
+ updateTotalSize(ctx);
1659
1813
  }
1660
1814
  if (snapToIndices) {
1661
- updateSnapToOffsets(ctx, state);
1815
+ updateSnapToOffsets(ctx);
1662
1816
  }
1663
1817
  }
1664
1818
 
@@ -1736,7 +1890,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1736
1890
  if (previousViewableItems) {
1737
1891
  for (const viewToken of previousViewableItems) {
1738
1892
  const containerId = findContainerId(ctx, viewToken.key);
1739
- if (!isViewable(
1893
+ if (!checkIsViewable(
1740
1894
  state,
1741
1895
  ctx,
1742
1896
  viewabilityConfig,
@@ -1757,7 +1911,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1757
1911
  if (item) {
1758
1912
  const key = getId(state, i);
1759
1913
  const containerId = findContainerId(ctx, key);
1760
- if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1914
+ if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1761
1915
  const viewToken = {
1762
1916
  containerId,
1763
1917
  index: i,
@@ -1817,11 +1971,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1817
1971
  const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
1818
1972
  const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
1819
1973
  const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1820
- const isViewable2 = percent >= viewablePercentThreshold;
1974
+ const isViewable = percent >= viewablePercentThreshold;
1821
1975
  const value = {
1822
1976
  containerId,
1823
1977
  index,
1824
- isViewable: isViewable2,
1978
+ isViewable,
1825
1979
  item,
1826
1980
  key,
1827
1981
  percentOfScroller,
@@ -1840,8 +1994,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1840
1994
  }
1841
1995
  return value;
1842
1996
  }
1843
- function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1844
- const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1997
+ function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1998
+ let value = ctx.mapViewabilityAmountValues.get(containerId);
1999
+ if (!value || value.key !== key) {
2000
+ value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
2001
+ }
1845
2002
  return value.isViewable;
1846
2003
  }
1847
2004
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
@@ -1869,8 +2026,9 @@ function checkAllSizesKnown(state) {
1869
2026
  }
1870
2027
 
1871
2028
  // src/utils/findAvailableContainers.ts
1872
- function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
2029
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1873
2030
  const numContainers = peek$(ctx, "numContainers");
2031
+ const state = ctx.state;
1874
2032
  const { stickyContainerPool, containerItemTypes } = state;
1875
2033
  const result = [];
1876
2034
  const availableContainers = [];
@@ -1914,14 +2072,14 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1914
2072
  continue;
1915
2073
  }
1916
2074
  const key = peek$(ctx, `containerItemKey${u}`);
1917
- let isOk = key === void 0;
1918
- if (!isOk && pendingRemovalSet.has(u)) {
1919
- pendingRemovalSet.delete(u);
1920
- pendingRemovalChanged = true;
1921
- const requiredType = neededTypes[typeIndex];
1922
- isOk = canReuseContainer(u, requiredType);
1923
- }
1924
- if (isOk) {
2075
+ const requiredType = neededTypes[typeIndex];
2076
+ const isPending = key !== void 0 && pendingRemovalSet.has(u);
2077
+ const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
2078
+ if (canUse) {
2079
+ if (isPending) {
2080
+ pendingRemovalSet.delete(u);
2081
+ pendingRemovalChanged = true;
2082
+ }
1925
2083
  result.push(u);
1926
2084
  if (requiredItemTypes) {
1927
2085
  typeIndex++;
@@ -1990,21 +2148,26 @@ function comparatorByDistance(a, b) {
1990
2148
  }
1991
2149
 
1992
2150
  // src/core/scrollToIndex.ts
1993
- function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1994
- if (index >= state.props.data.length) {
1995
- index = state.props.data.length - 1;
2151
+ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
2152
+ const state = ctx.state;
2153
+ const { data } = state.props;
2154
+ if (index >= data.length) {
2155
+ index = data.length - 1;
1996
2156
  } else if (index < 0) {
1997
2157
  index = 0;
1998
2158
  }
1999
- const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
2000
- const isLast = index === state.props.data.length - 1;
2159
+ const firstIndexOffset = calculateOffsetForIndex(ctx, index);
2160
+ const isLast = index === data.length - 1;
2001
2161
  if (isLast && viewPosition === void 0) {
2002
2162
  viewPosition = 1;
2003
2163
  }
2004
2164
  state.scrollForNextCalculateItemsInView = void 0;
2005
- scrollTo(ctx, state, {
2165
+ const targetId = getId(state, index);
2166
+ const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
2167
+ scrollTo(ctx, {
2006
2168
  animated,
2007
2169
  index,
2170
+ itemSize,
2008
2171
  offset: firstIndexOffset,
2009
2172
  viewOffset,
2010
2173
  viewPosition: viewPosition != null ? viewPosition : 0
@@ -2012,29 +2175,30 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
2012
2175
  }
2013
2176
 
2014
2177
  // src/utils/setDidLayout.ts
2015
- function setDidLayout(ctx, state) {
2178
+ function setDidLayout(ctx) {
2179
+ const state = ctx.state;
2016
2180
  const {
2017
2181
  loadStartTime,
2018
2182
  initialScroll,
2019
2183
  props: { onLoad }
2020
2184
  } = state;
2021
2185
  state.queuedInitialLayout = true;
2022
- checkAtBottom(ctx, state);
2186
+ checkAtBottom(ctx);
2023
2187
  const setIt = () => {
2024
- set$(ctx, "containersDidLayout", true);
2188
+ setInitialRenderState(ctx, { didLayout: true });
2025
2189
  if (onLoad) {
2026
2190
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
2027
2191
  }
2028
2192
  };
2029
2193
  if (Platform2.OS === "android" && initialScroll) {
2030
2194
  if (IsNewArchitecture) {
2031
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2195
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
2032
2196
  requestAnimationFrame(() => {
2033
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2197
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
2034
2198
  setIt();
2035
2199
  });
2036
2200
  } else {
2037
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2201
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
2038
2202
  setIt();
2039
2203
  }
2040
2204
  } else {
@@ -2057,15 +2221,17 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
2057
2221
  }
2058
2222
  return -1;
2059
2223
  }
2060
- function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
2224
+ function getActiveStickyIndices(ctx, stickyHeaderIndices) {
2225
+ const state = ctx.state;
2061
2226
  return new Set(
2062
2227
  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))
2063
2228
  );
2064
2229
  }
2065
- function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2230
+ function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2066
2231
  var _a3;
2067
- const activeIndices = getActiveStickyIndices(ctx, state, stickyHeaderIndices);
2068
- state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
2232
+ const state = ctx.state;
2233
+ const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
2234
+ set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
2069
2235
  for (let offset = 0; offset <= 1; offset++) {
2070
2236
  const idx = currentStickyIdx - offset;
2071
2237
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
@@ -2076,8 +2242,9 @@ function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, cu
2076
2242
  }
2077
2243
  }
2078
2244
  }
2079
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2245
+ function handleStickyRecycling(ctx, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2080
2246
  var _a3, _b, _c;
2247
+ const state = ctx.state;
2081
2248
  for (const containerIndex of state.stickyContainerPool) {
2082
2249
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
2083
2250
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
@@ -2101,7 +2268,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2101
2268
  const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2102
2269
  if (currentId) {
2103
2270
  const currentPos = state.positions.get(currentId);
2104
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
2271
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2105
2272
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
2106
2273
  }
2107
2274
  }
@@ -2110,7 +2277,8 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2110
2277
  }
2111
2278
  }
2112
2279
  }
2113
- function calculateItemsInView(ctx, state, params = {}) {
2280
+ function calculateItemsInView(ctx, params = {}) {
2281
+ const state = ctx.state;
2114
2282
  unstable_batchedUpdates(() => {
2115
2283
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2116
2284
  const {
@@ -2134,8 +2302,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2134
2302
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2135
2303
  const prevNumContainers = peek$(ctx, "numContainers");
2136
2304
  if (!data || scrollLength === 0 || !prevNumContainers) {
2137
- if (state.initialAnchor) {
2138
- ensureInitialAnchor(ctx, state);
2305
+ if (!IsNewArchitecture && state.initialAnchor) {
2306
+ ensureInitialAnchor(ctx);
2139
2307
  }
2140
2308
  return;
2141
2309
  }
@@ -2150,15 +2318,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2150
2318
  if (!queuedInitialLayout && initialScroll) {
2151
2319
  const updatedOffset = calculateOffsetWithOffsetPosition(
2152
2320
  ctx,
2153
- state,
2154
- calculateOffsetForIndex(ctx, state, initialScroll.index),
2321
+ calculateOffsetForIndex(ctx, initialScroll.index),
2155
2322
  initialScroll
2156
2323
  );
2157
2324
  scrollState = updatedOffset;
2158
2325
  }
2159
2326
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2160
2327
  const scrollAdjustPad = scrollAdjustPending - topPad;
2161
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2328
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2162
2329
  if (scroll + scrollLength > totalSize) {
2163
2330
  scroll = Math.max(0, totalSize - scrollLength);
2164
2331
  }
@@ -2166,11 +2333,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2166
2333
  set$(ctx, "debugRawScroll", scrollState);
2167
2334
  set$(ctx, "debugComputedScroll", scroll);
2168
2335
  }
2169
- const previousStickyIndex = state.activeStickyIndex;
2336
+ const previousStickyIndex = peek$(ctx, "activeStickyIndex");
2170
2337
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
2171
- const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
2172
- state.activeStickyIndex = nextActiveStickyIndex;
2173
- set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2338
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
2339
+ if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
2340
+ set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2341
+ }
2174
2342
  let scrollBufferTop = scrollBuffer;
2175
2343
  let scrollBufferBottom = scrollBuffer;
2176
2344
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2183,23 +2351,23 @@ function calculateItemsInView(ctx, state, params = {}) {
2183
2351
  const scrollTopBuffered = scroll - scrollBufferTop;
2184
2352
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2185
2353
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2186
- if (!dataChanged && scrollForNextCalculateItemsInView) {
2354
+ if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
2187
2355
  const { top, bottom } = scrollForNextCalculateItemsInView;
2188
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2189
- if (state.initialAnchor) {
2190
- ensureInitialAnchor(ctx, state);
2356
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2357
+ if (!IsNewArchitecture && state.initialAnchor) {
2358
+ ensureInitialAnchor(ctx);
2191
2359
  }
2192
2360
  return;
2193
2361
  }
2194
2362
  }
2195
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2363
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
2196
2364
  if (dataChanged) {
2197
2365
  indexByKey.clear();
2198
2366
  idCache.length = 0;
2199
2367
  positions.clear();
2200
2368
  }
2201
- const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2202
- updateItemPositions(ctx, state, dataChanged, {
2369
+ const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2370
+ updateItemPositions(ctx, dataChanged, {
2203
2371
  doMVCP,
2204
2372
  forceFullUpdate: !!forceFullItemPositions,
2205
2373
  scrollBottomBuffered,
@@ -2218,9 +2386,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2218
2386
  for (let i = loopStart; i >= 0; i--) {
2219
2387
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2220
2388
  const top = positions.get(id);
2221
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2389
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
2222
2390
  const bottom = top + size;
2223
- if (bottom > scroll - scrollBuffer) {
2391
+ if (bottom > scroll - scrollBufferTop) {
2224
2392
  loopStart = i;
2225
2393
  } else {
2226
2394
  break;
@@ -2245,7 +2413,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2245
2413
  const dataLength = data.length;
2246
2414
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2247
2415
  const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2248
- const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
2416
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
2249
2417
  const top = positions.get(id);
2250
2418
  if (!foundEnd) {
2251
2419
  if (startNoBuffer === null && top + size > scroll) {
@@ -2257,7 +2425,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2257
2425
  if (startBuffered === null && top + size > scrollTopBuffered) {
2258
2426
  startBuffered = i;
2259
2427
  startBufferedId = id;
2260
- nextTop = top;
2428
+ if (scrollTopBuffered < 0) {
2429
+ nextTop = null;
2430
+ } else {
2431
+ nextTop = top;
2432
+ }
2261
2433
  }
2262
2434
  if (startNoBuffer !== null) {
2263
2435
  if (top <= scrollBottom) {
@@ -2265,7 +2437,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2265
2437
  }
2266
2438
  if (top <= scrollBottomBuffered) {
2267
2439
  endBuffered = i;
2268
- nextBottom = top + size;
2440
+ if (scrollBottomBuffered > totalSize) {
2441
+ nextBottom = null;
2442
+ } else {
2443
+ nextBottom = top + size;
2444
+ }
2269
2445
  } else {
2270
2446
  foundEnd = true;
2271
2447
  }
@@ -2292,7 +2468,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2292
2468
  top: nextTop
2293
2469
  } : void 0;
2294
2470
  }
2295
- const numContainers = peek$(ctx, "numContainers");
2471
+ let numContainers = prevNumContainers;
2296
2472
  const pendingRemoval = [];
2297
2473
  if (dataChanged) {
2298
2474
  for (let i = 0; i < numContainers; i++) {
@@ -2303,7 +2479,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2303
2479
  }
2304
2480
  }
2305
2481
  if (startBuffered !== null && endBuffered !== null) {
2306
- let numContainers2 = prevNumContainers;
2307
2482
  const needNewContainers = [];
2308
2483
  for (let i = startBuffered; i <= endBuffered; i++) {
2309
2484
  const id = (_h = idCache[i]) != null ? _h : getId(state, i);
@@ -2314,7 +2489,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2314
2489
  if (stickyIndicesArr.length > 0) {
2315
2490
  handleStickyActivation(
2316
2491
  ctx,
2317
- state,
2318
2492
  stickyIndicesSet,
2319
2493
  stickyIndicesArr,
2320
2494
  currentStickyIdx,
@@ -2322,9 +2496,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2322
2496
  startBuffered,
2323
2497
  endBuffered
2324
2498
  );
2325
- } else {
2326
- state.activeStickyIndex = void 0;
2327
- set$(ctx, "activeStickyIndex", void 0);
2499
+ } else if (previousStickyIndex !== -1) {
2500
+ set$(ctx, "activeStickyIndex", -1);
2328
2501
  }
2329
2502
  if (needNewContainers.length > 0) {
2330
2503
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2333,7 +2506,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2333
2506
  }) : void 0;
2334
2507
  const availableContainers = findAvailableContainers(
2335
2508
  ctx,
2336
- state,
2337
2509
  needNewContainers.length,
2338
2510
  startBuffered,
2339
2511
  endBuffered,
@@ -2355,29 +2527,30 @@ function calculateItemsInView(ctx, state, params = {}) {
2355
2527
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
2356
2528
  }
2357
2529
  containerItemKeys.add(id);
2530
+ const containerSticky = `containerSticky${containerIndex}`;
2358
2531
  if (stickyIndicesSet.has(i)) {
2359
- set$(ctx, `containerSticky${containerIndex}`, true);
2532
+ set$(ctx, containerSticky, true);
2360
2533
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2361
2534
  set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2362
2535
  state.stickyContainerPool.add(containerIndex);
2363
- } else {
2364
- set$(ctx, `containerSticky${containerIndex}`, false);
2536
+ } else if (peek$(ctx, containerSticky)) {
2537
+ set$(ctx, containerSticky, false);
2365
2538
  state.stickyContainerPool.delete(containerIndex);
2366
2539
  }
2367
- if (containerIndex >= numContainers2) {
2368
- numContainers2 = containerIndex + 1;
2540
+ if (containerIndex >= numContainers) {
2541
+ numContainers = containerIndex + 1;
2369
2542
  }
2370
2543
  }
2371
- if (numContainers2 !== prevNumContainers) {
2372
- set$(ctx, "numContainers", numContainers2);
2373
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
2374
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
2544
+ if (numContainers !== prevNumContainers) {
2545
+ set$(ctx, "numContainers", numContainers);
2546
+ if (numContainers > peek$(ctx, "numContainersPooled")) {
2547
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
2375
2548
  }
2376
2549
  }
2377
2550
  }
2378
2551
  }
2379
2552
  if (stickyIndicesArr.length > 0) {
2380
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2553
+ handleStickyRecycling(ctx, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2381
2554
  }
2382
2555
  let didChangePositions = false;
2383
2556
  for (let i = 0; i < numContainers; i++) {
@@ -2429,7 +2602,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2429
2602
  }
2430
2603
  if (!queuedInitialLayout && endBuffered !== null) {
2431
2604
  if (checkAllSizesKnown(state)) {
2432
- setDidLayout(ctx, state);
2605
+ setDidLayout(ctx);
2433
2606
  }
2434
2607
  }
2435
2608
  if (viewabilityConfigCallbackPairs) {
@@ -2442,8 +2615,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2442
2615
  }
2443
2616
  }
2444
2617
  });
2445
- if (state.initialAnchor) {
2446
- ensureInitialAnchor(ctx, state);
2618
+ if (!IsNewArchitecture && state.initialAnchor) {
2619
+ ensureInitialAnchor(ctx);
2447
2620
  }
2448
2621
  }
2449
2622
 
@@ -2468,19 +2641,22 @@ function checkActualChange(state, dataProp, previousData) {
2468
2641
  }
2469
2642
 
2470
2643
  // src/core/doMaintainScrollAtEnd.ts
2471
- function doMaintainScrollAtEnd(ctx, state, animated) {
2644
+ function doMaintainScrollAtEnd(ctx, animated) {
2645
+ const state = ctx.state;
2472
2646
  const {
2647
+ didContainersLayout,
2648
+ isAtEnd,
2473
2649
  refScroller,
2474
2650
  props: { maintainScrollAtEnd }
2475
2651
  } = state;
2476
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2652
+ if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
2477
2653
  const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2478
2654
  if (paddingTop > 0) {
2479
2655
  state.scroll = 0;
2480
2656
  }
2481
2657
  requestAnimationFrame(() => {
2482
2658
  var _a3;
2483
- if (state == null ? void 0 : state.isAtEnd) {
2659
+ if (state.isAtEnd) {
2484
2660
  state.maintainingScrollAtEnd = true;
2485
2661
  (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2486
2662
  animated
@@ -2551,28 +2727,30 @@ function updateAveragesOnDataChange(state, oldData, newData) {
2551
2727
  }
2552
2728
 
2553
2729
  // src/core/checkResetContainers.ts
2554
- function checkResetContainers(ctx, state, dataProp) {
2730
+ function checkResetContainers(ctx, dataProp) {
2731
+ const state = ctx.state;
2555
2732
  const { previousData } = state;
2556
2733
  if (previousData) {
2557
2734
  updateAveragesOnDataChange(state, previousData, dataProp);
2558
2735
  }
2559
2736
  const { maintainScrollAtEnd } = state.props;
2560
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2737
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2561
2738
  const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2562
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
2739
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
2563
2740
  if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
2564
2741
  state.isEndReached = false;
2565
2742
  }
2566
2743
  if (!didMaintainScrollAtEnd) {
2567
2744
  checkAtTop(state);
2568
- checkAtBottom(ctx, state);
2745
+ checkAtBottom(ctx);
2569
2746
  }
2570
2747
  delete state.previousData;
2571
2748
  }
2572
2749
 
2573
2750
  // src/core/doInitialAllocateContainers.ts
2574
- function doInitialAllocateContainers(ctx, state) {
2751
+ function doInitialAllocateContainers(ctx) {
2575
2752
  var _a3, _b, _c;
2753
+ const state = ctx.state;
2576
2754
  const {
2577
2755
  scrollLength,
2578
2756
  props: {
@@ -2610,10 +2788,10 @@ function doInitialAllocateContainers(ctx, state) {
2610
2788
  if (!IsNewArchitecture || state.lastLayout) {
2611
2789
  if (state.initialScroll) {
2612
2790
  requestAnimationFrame(() => {
2613
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2791
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2614
2792
  });
2615
2793
  } else {
2616
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2794
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2617
2795
  }
2618
2796
  }
2619
2797
  return true;
@@ -2621,7 +2799,8 @@ function doInitialAllocateContainers(ctx, state) {
2621
2799
  }
2622
2800
 
2623
2801
  // src/core/handleLayout.ts
2624
- function handleLayout(ctx, state, layout, setCanRender) {
2802
+ function handleLayout(ctx, layout, setCanRender) {
2803
+ const state = ctx.state;
2625
2804
  const { maintainScrollAtEnd } = state.props;
2626
2805
  const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2627
2806
  const previousLength = state.scrollLength;
@@ -2637,19 +2816,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2637
2816
  state.lastBatchingAction = Date.now();
2638
2817
  state.scrollForNextCalculateItemsInView = void 0;
2639
2818
  if (scrollLength > 0) {
2640
- doInitialAllocateContainers(ctx, state);
2819
+ doInitialAllocateContainers(ctx);
2641
2820
  }
2642
2821
  if (needsCalculate) {
2643
- calculateItemsInView(ctx, state, { doMVCP: true });
2822
+ calculateItemsInView(ctx, { doMVCP: true });
2644
2823
  }
2645
2824
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
2646
2825
  set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
2647
2826
  }
2648
2827
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
2649
- doMaintainScrollAtEnd(ctx, state, false);
2828
+ doMaintainScrollAtEnd(ctx, false);
2650
2829
  }
2651
- updateAlignItemsPaddingTop(ctx, state);
2652
- checkAtBottom(ctx, state);
2830
+ updateAlignItemsPaddingTop(ctx);
2831
+ checkAtBottom(ctx);
2653
2832
  checkAtTop(state);
2654
2833
  if (state) {
2655
2834
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
@@ -2665,8 +2844,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2665
2844
  }
2666
2845
 
2667
2846
  // src/core/onScroll.ts
2668
- function onScroll(ctx, state, event) {
2847
+ function onScroll(ctx, event) {
2669
2848
  var _a3, _b, _c;
2849
+ const state = ctx.state;
2670
2850
  const {
2671
2851
  scrollProcessingEnabled,
2672
2852
  props: { onScroll: onScrollProp }
@@ -2677,9 +2857,23 @@ function onScroll(ctx, state, event) {
2677
2857
  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) {
2678
2858
  return;
2679
2859
  }
2680
- const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2860
+ let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2681
2861
  state.scrollPending = newScroll;
2682
- updateScroll(ctx, state, newScroll);
2862
+ if (state.scrollingTo) {
2863
+ const maxOffset = clampScrollOffset(ctx, newScroll);
2864
+ if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
2865
+ newScroll = maxOffset;
2866
+ scrollTo(ctx, {
2867
+ forceScroll: true,
2868
+ isInitialScroll: true,
2869
+ noScrollingTo: true,
2870
+ offset: newScroll
2871
+ });
2872
+ return;
2873
+ }
2874
+ }
2875
+ updateScroll(ctx, newScroll);
2876
+ checkFinishedScroll(ctx);
2683
2877
  onScrollProp == null ? void 0 : onScrollProp(event);
2684
2878
  }
2685
2879
 
@@ -2688,51 +2882,47 @@ var ScrollAdjustHandler = class {
2688
2882
  constructor(ctx) {
2689
2883
  this.appliedAdjust = 0;
2690
2884
  this.pendingAdjust = 0;
2691
- this.mounted = false;
2692
- this.context = ctx;
2693
- if (Platform2.OS === "web") {
2694
- const commitPendingAdjust = () => {
2695
- const state = this.context.internalState;
2696
- const pending = this.pendingAdjust;
2697
- if (pending !== 0) {
2698
- this.pendingAdjust = 0;
2699
- this.appliedAdjust += pending;
2700
- state.scroll += pending;
2701
- state.scrollForNextCalculateItemsInView = void 0;
2702
- set$(this.context, "scrollAdjustPending", 0);
2703
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2704
- calculateItemsInView(this.context, this.context.internalState);
2705
- }
2706
- };
2707
- listen$(this.context, "scrollingTo", (value) => {
2708
- if (value === void 0) {
2709
- commitPendingAdjust();
2710
- }
2711
- });
2712
- }
2885
+ this.ctx = ctx;
2713
2886
  }
2714
2887
  requestAdjust(add) {
2715
- const scrollingTo = peek$(this.context, "scrollingTo");
2888
+ const scrollingTo = this.ctx.state.scrollingTo;
2716
2889
  if (Platform2.OS === "web" && (scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
2717
2890
  this.pendingAdjust += add;
2718
- set$(this.context, "scrollAdjustPending", this.pendingAdjust);
2891
+ set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
2719
2892
  } else {
2720
2893
  this.appliedAdjust += add;
2721
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2894
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2895
+ }
2896
+ if (this.ctx.state.scrollingTo) {
2897
+ checkFinishedScroll(this.ctx);
2722
2898
  }
2723
- }
2724
- setMounted() {
2725
- this.mounted = true;
2726
2899
  }
2727
2900
  getAdjust() {
2728
2901
  return this.appliedAdjust;
2729
2902
  }
2903
+ commitPendingAdjust() {
2904
+ if (Platform2.OS === "web") {
2905
+ const state = this.ctx.state;
2906
+ const pending = this.pendingAdjust;
2907
+ if (pending !== 0) {
2908
+ this.pendingAdjust = 0;
2909
+ this.appliedAdjust += pending;
2910
+ state.scroll += pending;
2911
+ state.scrollForNextCalculateItemsInView = void 0;
2912
+ set$(this.ctx, "scrollAdjustPending", 0);
2913
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2914
+ calculateItemsInView(this.ctx);
2915
+ }
2916
+ }
2917
+ }
2730
2918
  };
2731
2919
 
2732
2920
  // src/core/updateItemSize.ts
2733
- function updateItemSize(ctx, state, itemKey, sizeObj) {
2921
+ function updateItemSize(ctx, itemKey, sizeObj) {
2734
2922
  var _a3;
2923
+ const state = ctx.state;
2735
2924
  const {
2925
+ didContainersLayout,
2736
2926
  sizesKnown,
2737
2927
  props: {
2738
2928
  getFixedItemSize,
@@ -2760,13 +2950,12 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2760
2950
  return;
2761
2951
  }
2762
2952
  }
2763
- const containersDidLayout = peek$(ctx, "containersDidLayout");
2764
- let needsRecalculate = !containersDidLayout;
2953
+ let needsRecalculate = !didContainersLayout;
2765
2954
  let shouldMaintainScrollAtEnd = false;
2766
2955
  let minIndexSizeChanged;
2767
2956
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
2768
2957
  const prevSizeKnown = state.sizesKnown.get(itemKey);
2769
- const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
2958
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj);
2770
2959
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
2771
2960
  if (diff !== 0) {
2772
2961
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -2815,22 +3004,22 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2815
3004
  if (!cur || maxOtherAxisSize > cur) {
2816
3005
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
2817
3006
  }
2818
- if (containersDidLayout || checkAllSizesKnown(state)) {
3007
+ if (didContainersLayout || checkAllSizesKnown(state)) {
2819
3008
  if (needsRecalculate) {
2820
3009
  state.scrollForNextCalculateItemsInView = void 0;
2821
- calculateItemsInView(ctx, state, { doMVCP: true });
3010
+ calculateItemsInView(ctx, { doMVCP: true });
2822
3011
  }
2823
3012
  if (shouldMaintainScrollAtEnd) {
2824
3013
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
2825
- doMaintainScrollAtEnd(ctx, state, false);
3014
+ doMaintainScrollAtEnd(ctx, false);
2826
3015
  }
2827
3016
  }
2828
3017
  }
2829
3018
  }
2830
- function updateOneItemSize(ctx, state, itemKey, sizeObj) {
3019
+ function updateOneItemSize(ctx, itemKey, sizeObj) {
2831
3020
  var _a3;
3021
+ const state = ctx.state;
2832
3022
  const {
2833
- sizes,
2834
3023
  indexByKey,
2835
3024
  sizesKnown,
2836
3025
  averageSizes,
@@ -2838,9 +3027,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2838
3027
  } = state;
2839
3028
  if (!data) return 0;
2840
3029
  const index = indexByKey.get(itemKey);
2841
- const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
3030
+ const prevSize = getItemSize(ctx, itemKey, index, data[index]);
2842
3031
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2843
3032
  const size = Platform2.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
3033
+ const prevSizeKnown = sizesKnown.get(itemKey);
2844
3034
  sizesKnown.set(itemKey, size);
2845
3035
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2846
3036
  const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
@@ -2848,11 +3038,15 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2848
3038
  if (!averages) {
2849
3039
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
2850
3040
  }
2851
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2852
- averages.num++;
3041
+ if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
3042
+ averages.avg += (size - prevSizeKnown) / averages.num;
3043
+ } else {
3044
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
3045
+ averages.num++;
3046
+ }
2853
3047
  }
2854
3048
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2855
- setSize(ctx, state, itemKey, size);
3049
+ setSize(ctx, itemKey, size);
2856
3050
  return size - prevSize;
2857
3051
  }
2858
3052
  return 0;
@@ -2918,14 +3112,15 @@ function createColumnWrapperStyle(contentContainerStyle) {
2918
3112
  }
2919
3113
 
2920
3114
  // src/utils/createImperativeHandle.ts
2921
- function createImperativeHandle(ctx, state) {
3115
+ function createImperativeHandle(ctx) {
3116
+ const state = ctx.state;
2922
3117
  const scrollIndexIntoView = (options) => {
2923
3118
  if (state) {
2924
3119
  const { index, ...rest } = options;
2925
3120
  const { startNoBuffer, endNoBuffer } = state;
2926
3121
  if (index < startNoBuffer || index > endNoBuffer) {
2927
3122
  const viewPosition = index < startNoBuffer ? 0 : 1;
2928
- scrollToIndex(ctx, state, {
3123
+ scrollToIndex(ctx, {
2929
3124
  ...rest,
2930
3125
  index,
2931
3126
  viewPosition
@@ -2940,7 +3135,7 @@ function createImperativeHandle(ctx, state) {
2940
3135
  getScrollableNode: () => refScroller.current.getScrollableNode(),
2941
3136
  getScrollResponder: () => refScroller.current.getScrollResponder(),
2942
3137
  getState: () => ({
2943
- activeStickyIndex: state.activeStickyIndex,
3138
+ activeStickyIndex: peek$(ctx, "activeStickyIndex"),
2944
3139
  contentLength: state.totalSize,
2945
3140
  data: state.props.data,
2946
3141
  elementAtIndex: (index) => {
@@ -2951,6 +3146,8 @@ function createImperativeHandle(ctx, state) {
2951
3146
  endBuffered: state.endBuffered,
2952
3147
  isAtEnd: state.isAtEnd,
2953
3148
  isAtStart: state.isAtStart,
3149
+ listen: (signalName, cb) => listen$(ctx, signalName, cb),
3150
+ listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
2954
3151
  positionAtIndex: (index) => state.positions.get(getId(state, index)),
2955
3152
  positions: state.positions,
2956
3153
  scroll: state.scroll,
@@ -2975,23 +3172,23 @@ function createImperativeHandle(ctx, state) {
2975
3172
  if (index !== -1) {
2976
3173
  const paddingBottom = stylePaddingBottom || 0;
2977
3174
  const footerSize = peek$(ctx, "footerSize") || 0;
2978
- scrollToIndex(ctx, state, {
3175
+ scrollToIndex(ctx, {
3176
+ ...options,
2979
3177
  index,
2980
3178
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
2981
- viewPosition: 1,
2982
- ...options
3179
+ viewPosition: 1
2983
3180
  });
2984
3181
  }
2985
3182
  },
2986
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3183
+ scrollToIndex: (params) => scrollToIndex(ctx, params),
2987
3184
  scrollToItem: ({ item, ...props }) => {
2988
3185
  const data = state.props.data;
2989
3186
  const index = data.indexOf(item);
2990
3187
  if (index !== -1) {
2991
- scrollToIndex(ctx, state, { index, ...props });
3188
+ scrollToIndex(ctx, { index, ...props });
2992
3189
  }
2993
3190
  },
2994
- scrollToOffset: (params) => scrollTo(ctx, state, params),
3191
+ scrollToOffset: (params) => scrollTo(ctx, params),
2995
3192
  setScrollProcessingEnabled: (enabled) => {
2996
3193
  state.scrollProcessingEnabled = enabled;
2997
3194
  },
@@ -3001,8 +3198,9 @@ function createImperativeHandle(ctx, state) {
3001
3198
  }
3002
3199
  };
3003
3200
  }
3004
- function getRenderedItem(ctx, state, key) {
3201
+ function getRenderedItem(ctx, key) {
3005
3202
  var _a3;
3203
+ const state = ctx.state;
3006
3204
  if (!state) {
3007
3205
  return null;
3008
3206
  }
@@ -3079,11 +3277,13 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
3079
3277
  var DEFAULT_DRAW_DISTANCE = 250;
3080
3278
  var DEFAULT_ITEM_SIZE = 100;
3081
3279
  var LegendList = typedMemo(
3280
+ // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
3082
3281
  typedForwardRef(function LegendList2(props, forwardedRef) {
3083
3282
  const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
3084
3283
  const isChildrenMode = children !== void 0 && dataProp === void 0;
3085
3284
  const processedProps = isChildrenMode ? {
3086
3285
  ...restProps,
3286
+ childrenMode: true,
3087
3287
  data: (isArray(children) ? children : React2.Children.toArray(children)).flat(1),
3088
3288
  renderItem: ({ item }) => item
3089
3289
  } : {
@@ -3100,10 +3300,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3100
3300
  alignItemsAtEnd = false,
3101
3301
  columnWrapperStyle,
3102
3302
  contentContainerStyle: contentContainerStyleProp,
3303
+ contentInset,
3103
3304
  data: dataProp = [],
3104
3305
  dataVersion,
3105
3306
  drawDistance = 250,
3106
- enableAverages = true,
3107
3307
  estimatedItemSize: estimatedItemSizeProp,
3108
3308
  estimatedListSize,
3109
3309
  extraData,
@@ -3145,6 +3345,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3145
3345
  snapToIndices,
3146
3346
  stickyHeaderIndices: stickyHeaderIndicesProp,
3147
3347
  stickyIndices: stickyIndicesDeprecated,
3348
+ // TODOV3: Remove from v3 release
3148
3349
  style: styleProp,
3149
3350
  suggestEstimatedItemSize,
3150
3351
  viewabilityConfig,
@@ -3152,6 +3353,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3152
3353
  waitForInitialLayout = true,
3153
3354
  ...rest
3154
3355
  } = props;
3356
+ const animatedPropsInternal = props.animatedPropsInternal;
3357
+ const { childrenMode } = rest;
3155
3358
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
3156
3359
  const style = { ...StyleSheet.flatten(styleProp) };
3157
3360
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -3175,10 +3378,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3175
3378
  }
3176
3379
  const refState = useRef();
3177
3380
  if (!refState.current) {
3178
- if (!ctx.internalState) {
3381
+ if (!ctx.state) {
3179
3382
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : getWindowSize())[horizontal ? "width" : "height"];
3180
- ctx.internalState = {
3181
- activeStickyIndex: void 0,
3383
+ ctx.state = {
3384
+ activeStickyIndex: -1,
3182
3385
  averageSizes: {},
3183
3386
  columns: /* @__PURE__ */ new Map(),
3184
3387
  containerItemKeys: /* @__PURE__ */ new Set(),
@@ -3204,9 +3407,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3204
3407
  initialScroll: initialScrollProp,
3205
3408
  isAtEnd: false,
3206
3409
  isAtStart: false,
3207
- isEndReached: false,
3410
+ isEndReached: null,
3208
3411
  isFirst: true,
3209
- isStartReached: false,
3412
+ isStartReached: null,
3210
3413
  lastBatchingAction: Date.now(),
3211
3414
  lastLayout: void 0,
3212
3415
  loadStartTime: Date.now(),
@@ -3238,12 +3441,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3238
3441
  totalSize: 0,
3239
3442
  viewabilityConfigCallbackPairs: void 0
3240
3443
  };
3241
- const internalState = ctx.internalState;
3242
- internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
3444
+ const internalState = ctx.state;
3445
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3243
3446
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3244
3447
  set$(ctx, "extraData", extraData);
3245
3448
  }
3246
- refState.current = ctx.internalState;
3449
+ refState.current = ctx.state;
3247
3450
  }
3248
3451
  const state = refState.current;
3249
3452
  const isFirstLocal = state.isFirst;
@@ -3257,9 +3460,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3257
3460
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
3258
3461
  state.props = {
3259
3462
  alignItemsAtEnd,
3463
+ animatedProps: animatedPropsInternal,
3464
+ contentInset,
3260
3465
  data: dataProp,
3261
3466
  dataVersion,
3262
- enableAverages,
3263
3467
  estimatedItemSize,
3264
3468
  getEstimatedItemSize,
3265
3469
  getFixedItemSize,
@@ -3302,62 +3506,62 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3302
3506
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3303
3507
  set$(ctx, "numColumns", numColumnsProp);
3304
3508
  const prevPaddingTop = peek$(ctx, "stylePaddingTop");
3305
- setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3509
+ setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3306
3510
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3307
3511
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3308
3512
  if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3309
3513
  if (state.scroll < 0) {
3310
3514
  paddingDiff += state.scroll;
3311
3515
  }
3312
- requestAdjust(ctx, state, paddingDiff);
3516
+ requestAdjust(ctx, paddingDiff);
3313
3517
  }
3314
3518
  };
3315
3519
  if (isFirstLocal) {
3316
3520
  initializeStateVars();
3317
3521
  updateItemPositions(
3318
3522
  ctx,
3319
- state,
3320
3523
  /*dataChanged*/
3321
3524
  true
3322
3525
  );
3323
3526
  }
3324
3527
  const initialContentOffset = useMemo(() => {
3325
- var _a4, _b2;
3326
- const { initialScroll } = refState.current;
3327
- if (!initialScroll) {
3528
+ var _a4;
3529
+ let value;
3530
+ const { initialScroll, initialAnchor } = refState.current;
3531
+ if (initialScroll) {
3532
+ if (!IsNewArchitecture && initialScroll.index !== void 0 && (!initialAnchor || (initialAnchor == null ? void 0 : initialAnchor.index) !== initialScroll.index)) {
3533
+ refState.current.initialAnchor = {
3534
+ attempts: 0,
3535
+ index: initialScroll.index,
3536
+ settledTicks: 0,
3537
+ viewOffset: (_a4 = initialScroll.viewOffset) != null ? _a4 : 0,
3538
+ viewPosition: initialScroll.viewPosition
3539
+ };
3540
+ }
3541
+ if (initialScroll.contentOffset !== void 0) {
3542
+ value = initialScroll.contentOffset;
3543
+ } else {
3544
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
3545
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
3546
+ const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
3547
+ const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3548
+ refState.current.initialScroll = updatedInitialScroll;
3549
+ state.initialScroll = updatedInitialScroll;
3550
+ value = clampedOffset;
3551
+ }
3552
+ } else {
3328
3553
  refState.current.initialAnchor = void 0;
3329
- return 0;
3330
- }
3331
- if (initialScroll.index !== void 0 && (!refState.current.initialAnchor || ((_a4 = refState.current.initialAnchor) == null ? void 0 : _a4.index) !== initialScroll.index)) {
3332
- refState.current.initialAnchor = {
3333
- attempts: 0,
3334
- index: initialScroll.index,
3335
- settledTicks: 0,
3336
- viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
3337
- viewPosition: initialScroll.viewPosition
3338
- };
3554
+ value = 0;
3339
3555
  }
3340
- if (initialScroll.contentOffset !== void 0) {
3341
- return initialScroll.contentOffset;
3342
- }
3343
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
3344
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
3345
- let clampedOffset = resolvedOffset;
3346
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
3347
- const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
3348
- clampedOffset = Math.min(clampedOffset, maxOffset);
3349
- }
3350
- clampedOffset = Math.max(0, clampedOffset);
3351
- const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3352
- refState.current.initialScroll = updatedInitialScroll;
3353
- state.initialScroll = updatedInitialScroll;
3354
- refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
3355
- return clampedOffset;
3556
+ if (!value) {
3557
+ state.didFinishInitialScroll = true;
3558
+ }
3559
+ return value;
3356
3560
  }, [renderNum]);
3357
3561
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
3358
3562
  refState.current.lastBatchingAction = Date.now();
3359
3563
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
3360
- IS_DEV && warnDevOnce(
3564
+ IS_DEV && !childrenMode && warnDevOnce(
3361
3565
  "keyExtractor",
3362
3566
  "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."
3363
3567
  );
@@ -3382,12 +3586,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3382
3586
  }
3383
3587
  }, []);
3384
3588
  const doInitialScroll = useCallback(() => {
3385
- var _a4;
3386
3589
  const initialScroll = state.initialScroll;
3387
3590
  if (initialScroll) {
3388
- scrollTo(ctx, state, {
3591
+ scrollTo(ctx, {
3389
3592
  animated: false,
3390
- index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
3593
+ index: initialScroll == null ? void 0 : initialScroll.index,
3391
3594
  isInitialScroll: true,
3392
3595
  offset: initialContentOffset,
3393
3596
  precomputedWithViewOffset: true
@@ -3396,7 +3599,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3396
3599
  }, [initialContentOffset]);
3397
3600
  const onLayoutChange = useCallback((layout) => {
3398
3601
  doInitialScroll();
3399
- handleLayout(ctx, state, layout, setCanRender);
3602
+ handleLayout(ctx, layout, setCanRender);
3400
3603
  }, []);
3401
3604
  const { onLayout } = useOnLayoutSync({
3402
3605
  onLayoutChange,
@@ -3406,7 +3609,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3406
3609
  });
3407
3610
  useLayoutEffect(() => {
3408
3611
  if (snapToIndices) {
3409
- updateSnapToOffsets(ctx, state);
3612
+ updateSnapToOffsets(ctx);
3410
3613
  }
3411
3614
  }, [snapToIndices]);
3412
3615
  useLayoutEffect(() => {
@@ -3416,9 +3619,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3416
3619
  isFirst,
3417
3620
  props: { data }
3418
3621
  } = state;
3419
- const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
3622
+ const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
3420
3623
  if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
3421
- checkResetContainers(ctx, state, data);
3624
+ checkResetContainers(ctx, data);
3422
3625
  }
3423
3626
  state.didColumnsChange = false;
3424
3627
  state.didDataChange = false;
@@ -3445,18 +3648,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3445
3648
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
3446
3649
  if (!IsNewArchitecture) {
3447
3650
  useInit(() => {
3448
- doInitialAllocateContainers(ctx, state);
3651
+ doInitialAllocateContainers(ctx);
3449
3652
  });
3450
3653
  }
3451
- useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
3654
+ useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
3452
3655
  if (Platform2.OS === "web") {
3453
3656
  useEffect(doInitialScroll, []);
3454
3657
  }
3455
3658
  const fns = useMemo(
3456
3659
  () => ({
3457
- getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3458
- onScroll: (event) => onScroll(ctx, state, event),
3459
- updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj)
3660
+ getRenderedItem: (key) => getRenderedItem(ctx, key),
3661
+ onMomentumScrollEnd: (event) => {
3662
+ checkFinishedScrollFallback(ctx);
3663
+ if (onMomentumScrollEnd) {
3664
+ onMomentumScrollEnd(event);
3665
+ }
3666
+ },
3667
+ onScroll: (event) => onScroll(ctx, event),
3668
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
3460
3669
  }),
3461
3670
  []
3462
3671
  );
@@ -3468,6 +3677,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3468
3677
  alignItemsAtEnd,
3469
3678
  canRender,
3470
3679
  contentContainerStyle,
3680
+ contentInset,
3471
3681
  getRenderedItem: fns.getRenderedItem,
3472
3682
  horizontal,
3473
3683
  initialContentOffset,
@@ -3476,20 +3686,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3476
3686
  maintainVisibleContentPosition,
3477
3687
  onLayout,
3478
3688
  onLayoutHeader,
3479
- onMomentumScrollEnd: (event) => {
3480
- if (IsNewArchitecture) {
3481
- requestAnimationFrame(() => {
3482
- finishScrollTo(ctx, refState.current);
3483
- });
3484
- } else {
3485
- setTimeout(() => {
3486
- finishScrollTo(ctx, refState.current);
3487
- }, 1e3);
3488
- }
3489
- if (onMomentumScrollEnd) {
3490
- onMomentumScrollEnd(event);
3491
- }
3492
- },
3689
+ onMomentumScrollEnd: fns.onMomentumScrollEnd,
3493
3690
  onScroll: onScrollHandler,
3494
3691
  recycleItems,
3495
3692
  refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2.cloneElement(refreshControl, {
@@ -3504,7 +3701,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3504
3701
  ),
3505
3702
  refScrollView: combinedRef,
3506
3703
  scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3507
- scrollEventThrottle: Platform2.OS === "web" ? 16 : void 0,
3704
+ scrollEventThrottle: 0,
3508
3705
  snapToIndices,
3509
3706
  stickyHeaderIndices,
3510
3707
  style,