@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.js CHANGED
@@ -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,14 +153,24 @@ function set$(ctx, signalName, value) {
119
153
  }
120
154
  }
121
155
  }
122
- function getContentSize(ctx) {
123
- var _a3, _b;
124
- const { values } = ctx;
125
- const stylePaddingTop = values.get("stylePaddingTop") || 0;
126
- const headerSize = values.get("headerSize") || 0;
127
- const footerSize = values.get("footerSize") || 0;
128
- const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
129
- return headerSize + footerSize + totalSize + stylePaddingTop;
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
+ }
130
174
  }
131
175
  function useArr$(signalNames) {
132
176
  const ctx = React2__namespace.useContext(ContextState);
@@ -207,7 +251,8 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
207
251
  // src/constants-platform.native.ts
208
252
  var IsNewArchitecture = global.nativeFabricUIManager != null;
209
253
  var useAnimatedValue = (initialValue) => {
210
- return React2.useRef(new reactNative.Animated.Value(initialValue)).current;
254
+ const [animAnimatedValue] = React2.useState(() => new reactNative.Animated.Value(initialValue));
255
+ return animAnimatedValue;
211
256
  };
212
257
 
213
258
  // src/utils/helpers.ts
@@ -296,7 +341,7 @@ var typedForwardRef = React2.forwardRef;
296
341
  var typedMemo = React2.memo;
297
342
 
298
343
  // src/components/PositionView.native.tsx
299
- var PositionViewState = typedMemo(function PositionView({
344
+ var PositionViewState = typedMemo(function PositionViewState2({
300
345
  id,
301
346
  horizontal,
302
347
  style,
@@ -316,7 +361,7 @@ var PositionViewState = typedMemo(function PositionView({
316
361
  }
317
362
  );
318
363
  });
319
- var PositionViewAnimated = typedMemo(function PositionView2({
364
+ var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
320
365
  id,
321
366
  horizontal,
322
367
  style,
@@ -359,14 +404,9 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
359
404
  const viewStyle = React2__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
360
405
  return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest });
361
406
  });
362
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
363
- var symbolFirst = Symbol();
407
+ var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
364
408
  function useInit(cb) {
365
- const refValue = React2.useRef(symbolFirst);
366
- if (refValue.current === symbolFirst) {
367
- refValue.current = cb();
368
- }
369
- return refValue.current;
409
+ React2.useState(() => cb());
370
410
  }
371
411
 
372
412
  // src/state/ContextContainer.ts
@@ -632,6 +672,7 @@ var Container = typedMemo(function Container2({
632
672
  if (!IsNewArchitecture) {
633
673
  React2.useEffect(() => {
634
674
  if (!isNullOrUndefined(itemKey)) {
675
+ didLayoutRef.current = false;
635
676
  const timeout = setTimeout(() => {
636
677
  if (!didLayoutRef.current) {
637
678
  const {
@@ -651,7 +692,7 @@ var Container = typedMemo(function Container2({
651
692
  }
652
693
  }, [itemKey]);
653
694
  }
654
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
695
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView;
655
696
  return /* @__PURE__ */ React2__namespace.createElement(
656
697
  PositionComponent,
657
698
  {
@@ -686,10 +727,10 @@ var Containers = typedMemo(function Containers2({
686
727
  // If this is the initial scroll, we don't want to delay because we want to update the size immediately
687
728
  delay: (value, prevValue) => {
688
729
  var _a3;
689
- return !((_a3 = ctx.internalState) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
730
+ return !((_a3 = ctx.state) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
690
731
  }
691
732
  });
692
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
733
+ const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("readyToRender", { getValue: (value) => value ? 1 : 0 }) : void 0;
693
734
  const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
694
735
  const containers = [];
695
736
  for (let i = 0; i < numContainers; i++) {
@@ -732,7 +773,8 @@ var Containers = typedMemo(function Containers2({
732
773
  return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style }, containers);
733
774
  });
734
775
  function DevNumbers() {
735
- return IS_DEV && React2__namespace.memo(function DevNumbers2() {
776
+ return IS_DEV && // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
777
+ React2__namespace.memo(function DevNumbers2() {
736
778
  return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2__namespace.createElement(
737
779
  reactNative.View,
738
780
  {
@@ -840,13 +882,6 @@ var ListComponent = typedMemo(function ListComponent2({
840
882
  () => React2__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
841
883
  [renderScrollComponent]
842
884
  ) : ListComponentScrollView;
843
- React2__namespace.useEffect(() => {
844
- if (canRender) {
845
- setTimeout(() => {
846
- scrollAdjustHandler.setMounted();
847
- }, 0);
848
- }
849
- }, [canRender]);
850
885
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
851
886
  return /* @__PURE__ */ React2__namespace.createElement(
852
887
  SnapOrScroll,
@@ -910,10 +945,11 @@ function getId(state, index) {
910
945
  }
911
946
 
912
947
  // src/core/calculateOffsetForIndex.ts
913
- function calculateOffsetForIndex(ctx, state, index) {
948
+ function calculateOffsetForIndex(ctx, index) {
949
+ const state = ctx.state;
914
950
  let position = 0;
915
951
  if (index !== void 0) {
916
- position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
952
+ position = state.positions.get(getId(state, index)) || 0;
917
953
  const paddingTop = peek$(ctx, "stylePaddingTop");
918
954
  if (paddingTop) {
919
955
  position += paddingTop;
@@ -927,7 +963,8 @@ function calculateOffsetForIndex(ctx, state, index) {
927
963
  }
928
964
 
929
965
  // src/utils/setPaddingTop.ts
930
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
966
+ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
967
+ const state = ctx.state;
931
968
  if (stylePaddingTop !== void 0) {
932
969
  const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
933
970
  if (stylePaddingTop < prevStylePaddingTop) {
@@ -946,7 +983,8 @@ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
946
983
  }
947
984
 
948
985
  // src/utils/updateAlignItemsPaddingTop.ts
949
- function updateAlignItemsPaddingTop(ctx, state) {
986
+ function updateAlignItemsPaddingTop(ctx) {
987
+ const state = ctx.state;
950
988
  const {
951
989
  scrollLength,
952
990
  props: { alignItemsAtEnd, data }
@@ -957,12 +995,13 @@ function updateAlignItemsPaddingTop(ctx, state) {
957
995
  const contentSize = getContentSize(ctx);
958
996
  alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
959
997
  }
960
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
998
+ setPaddingTop(ctx, { alignItemsPaddingTop });
961
999
  }
962
1000
  }
963
1001
 
964
1002
  // src/core/addTotalSize.ts
965
- function addTotalSize(ctx, state, key, add) {
1003
+ function addTotalSize(ctx, key, add) {
1004
+ const state = ctx.state;
966
1005
  const { alignItemsAtEnd } = state.props;
967
1006
  const prevTotalSize = state.totalSize;
968
1007
  let totalSize = state.totalSize;
@@ -983,31 +1022,34 @@ function addTotalSize(ctx, state, key, add) {
983
1022
  state.totalSize = totalSize;
984
1023
  set$(ctx, "totalSize", totalSize);
985
1024
  if (alignItemsAtEnd) {
986
- updateAlignItemsPaddingTop(ctx, state);
1025
+ updateAlignItemsPaddingTop(ctx);
987
1026
  }
988
1027
  }
989
1028
  }
990
1029
  }
991
1030
 
992
1031
  // src/core/setSize.ts
993
- function setSize(ctx, state, itemKey, size) {
1032
+ function setSize(ctx, itemKey, size) {
1033
+ const state = ctx.state;
994
1034
  const { sizes } = state;
995
1035
  const previousSize = sizes.get(itemKey);
996
1036
  const diff = previousSize !== void 0 ? size - previousSize : size;
997
1037
  if (diff !== 0) {
998
- addTotalSize(ctx, state, itemKey, diff);
1038
+ addTotalSize(ctx, itemKey, diff);
999
1039
  }
1000
1040
  sizes.set(itemKey, size);
1001
1041
  }
1002
1042
 
1003
1043
  // src/utils/getItemSize.ts
1004
- function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
1044
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
1005
1045
  var _a3, _b;
1046
+ const state = ctx.state;
1006
1047
  const {
1007
1048
  sizesKnown,
1008
1049
  sizes,
1009
1050
  averageSizes,
1010
- props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
1051
+ props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
1052
+ scrollingTo
1011
1053
  } = state;
1012
1054
  const sizeKnown = sizesKnown.get(key);
1013
1055
  if (sizeKnown !== void 0) {
@@ -1015,7 +1057,6 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
1015
1057
  }
1016
1058
  let size;
1017
1059
  const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
1018
- const scrollingTo = peek$(ctx, "scrollingTo");
1019
1060
  if (preferCachedSize) {
1020
1061
  const cachedSize = sizes.get(key);
1021
1062
  if (cachedSize !== void 0) {
@@ -1043,84 +1084,167 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
1043
1084
  if (size === void 0) {
1044
1085
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
1045
1086
  }
1046
- setSize(ctx, state, key, size);
1087
+ setSize(ctx, key, size);
1047
1088
  return size;
1048
1089
  }
1049
1090
 
1050
1091
  // src/core/calculateOffsetWithOffsetPosition.ts
1051
- function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
1092
+ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1093
+ const state = ctx.state;
1052
1094
  const { index, viewOffset, viewPosition } = params;
1053
1095
  let offset = offsetParam;
1054
1096
  if (viewOffset) {
1055
1097
  offset -= viewOffset;
1056
1098
  }
1057
1099
  if (viewPosition !== void 0 && index !== void 0) {
1058
- offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
1100
+ const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1101
+ const trailingInset = getContentInsetEnd(state);
1102
+ offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
1059
1103
  }
1060
1104
  return offset;
1061
1105
  }
1062
1106
 
1107
+ // src/core/clampScrollOffset.ts
1108
+ function clampScrollOffset(ctx, offset) {
1109
+ const state = ctx.state;
1110
+ const contentSize = getContentSize(ctx);
1111
+ let clampedOffset = offset;
1112
+ if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength)) {
1113
+ const maxOffset = Math.max(0, contentSize - state.scrollLength);
1114
+ clampedOffset = Math.min(offset, maxOffset);
1115
+ }
1116
+ clampedOffset = Math.max(0, clampedOffset);
1117
+ return clampedOffset;
1118
+ }
1119
+ var Platform2 = reactNative.Platform;
1120
+
1121
+ // src/utils/setInitialRenderState.ts
1122
+ function setInitialRenderState(ctx, {
1123
+ didLayout,
1124
+ didInitialScroll
1125
+ }) {
1126
+ const { state } = ctx;
1127
+ if (didLayout) {
1128
+ state.didContainersLayout = true;
1129
+ }
1130
+ if (didInitialScroll) {
1131
+ state.didFinishInitialScroll = true;
1132
+ }
1133
+ if (state.didContainersLayout && state.didFinishInitialScroll) {
1134
+ set$(ctx, "readyToRender", true);
1135
+ }
1136
+ }
1137
+
1063
1138
  // src/core/finishScrollTo.ts
1064
- function finishScrollTo(ctx, state) {
1139
+ function finishScrollTo(ctx) {
1065
1140
  var _a3, _b;
1066
- if (state) {
1141
+ const state = ctx.state;
1142
+ if (state == null ? void 0 : state.scrollingTo) {
1067
1143
  state.scrollHistory.length = 0;
1068
1144
  state.initialScroll = void 0;
1069
1145
  state.initialAnchor = void 0;
1070
- set$(ctx, "scrollingTo", void 0);
1146
+ state.scrollingTo = void 0;
1071
1147
  if (state.pendingTotalSize !== void 0) {
1072
- addTotalSize(ctx, state, null, state.pendingTotalSize);
1148
+ addTotalSize(ctx, null, state.pendingTotalSize);
1073
1149
  }
1074
1150
  if ((_a3 = state.props) == null ? void 0 : _a3.data) {
1075
1151
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
1076
1152
  }
1153
+ if (Platform2.OS === "web") {
1154
+ state.scrollAdjustHandler.commitPendingAdjust();
1155
+ }
1156
+ setInitialRenderState(ctx, { didInitialScroll: true });
1077
1157
  }
1078
1158
  }
1079
- var Platform2 = reactNative.Platform;
1080
1159
 
1081
- // src/core/scrollTo.ts
1082
- function scrollTo(ctx, state, params) {
1160
+ // src/core/checkFinishedScroll.ts
1161
+ function checkFinishedScroll(ctx) {
1162
+ ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
1163
+ }
1164
+ function checkFinishedScrollFrame(ctx) {
1165
+ const scrollingTo = ctx.state.scrollingTo;
1166
+ if (scrollingTo) {
1167
+ const { state } = ctx;
1168
+ state.animFrameCheckFinishedScroll = void 0;
1169
+ const scroll = state.scroll;
1170
+ const adjust = state.scrollAdjustHandler.getAdjust();
1171
+ const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1172
+ const maxOffset = clampScrollOffset(ctx, scroll);
1173
+ const diff1 = Math.abs(scroll - clampedTargetOffset);
1174
+ const diff2 = Math.abs(diff1 - adjust);
1175
+ const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
1176
+ if (isNotOverscrolled && (diff1 < 1 || diff2 < 1)) {
1177
+ finishScrollTo(ctx);
1178
+ }
1179
+ }
1180
+ }
1181
+ function checkFinishedScrollFallback(ctx) {
1182
+ const state = ctx.state;
1183
+ const scrollingTo = state.scrollingTo;
1184
+ const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
1185
+ state.timeoutCheckFinishedScrollFallback = setTimeout(
1186
+ () => {
1187
+ let numChecks = 0;
1188
+ const checkHasScrolled = () => {
1189
+ state.timeoutCheckFinishedScrollFallback = void 0;
1190
+ const isStillScrollingTo = state.scrollingTo;
1191
+ if (isStillScrollingTo) {
1192
+ numChecks++;
1193
+ if (state.hasScrolled || numChecks > 5) {
1194
+ finishScrollTo(ctx);
1195
+ } else {
1196
+ state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
1197
+ }
1198
+ }
1199
+ };
1200
+ checkHasScrolled();
1201
+ },
1202
+ slowTimeout ? 500 : 100
1203
+ );
1204
+ }
1205
+
1206
+ // src/core/doScrollTo.native.ts
1207
+ function doScrollTo(ctx, params) {
1083
1208
  var _a3;
1084
- const { noScrollingTo, ...scrollTarget } = params;
1209
+ const state = ctx.state;
1210
+ const { animated, horizontal, offset } = params;
1211
+ const { refScroller } = state;
1212
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1213
+ animated: !!animated,
1214
+ x: horizontal ? offset : 0,
1215
+ y: horizontal ? 0 : offset
1216
+ });
1217
+ if (!animated) {
1218
+ state.scroll = offset;
1219
+ checkFinishedScrollFallback(ctx);
1220
+ }
1221
+ }
1222
+
1223
+ // src/core/scrollTo.ts
1224
+ function scrollTo(ctx, params) {
1225
+ const state = ctx.state;
1226
+ const { noScrollingTo, forceScroll, ...scrollTarget } = params;
1085
1227
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
1086
1228
  const {
1087
- refScroller,
1088
1229
  props: { horizontal }
1089
1230
  } = state;
1090
- let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
1091
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
1092
- const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
1093
- offset = Math.min(offset, maxOffset);
1231
+ if (state.animFrameCheckFinishedScroll) {
1232
+ cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
1233
+ }
1234
+ if (state.timeoutCheckFinishedScrollFallback) {
1235
+ clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
1094
1236
  }
1237
+ let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
1238
+ offset = clampScrollOffset(ctx, offset);
1095
1239
  state.scrollHistory.length = 0;
1096
1240
  if (!noScrollingTo) {
1097
- set$(ctx, "scrollingTo", scrollTarget);
1241
+ state.scrollingTo = scrollTarget;
1098
1242
  }
1099
1243
  state.scrollPending = offset;
1100
- if (!isInitialScroll || Platform2.OS === "android") {
1101
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1102
- animated: !!animated,
1103
- x: horizontal ? offset : 0,
1104
- y: horizontal ? 0 : offset
1105
- });
1106
- }
1107
- if (!animated) {
1244
+ if (forceScroll || !isInitialScroll || Platform2.OS === "android") {
1245
+ doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
1246
+ } else {
1108
1247
  state.scroll = offset;
1109
- if (Platform2.OS === "web") {
1110
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1111
- if (value && peek$(ctx, "scrollingTo")) {
1112
- finishScrollTo(ctx, state);
1113
- unlisten();
1114
- }
1115
- });
1116
- } else {
1117
- setTimeout(() => finishScrollTo(ctx, state), 100);
1118
- }
1119
- if (isInitialScroll) {
1120
- setTimeout(() => {
1121
- state.initialScroll = void 0;
1122
- }, 500);
1123
- }
1124
1248
  }
1125
1249
  }
1126
1250
 
@@ -1129,6 +1253,12 @@ var HYSTERESIS_MULTIPLIER = 1.3;
1129
1253
  var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1130
1254
  const absDistance = Math.abs(distance);
1131
1255
  const within = atThreshold || threshold > 0 && absDistance <= threshold;
1256
+ if (wasReached === null) {
1257
+ if (!within && distance >= 0) {
1258
+ return false;
1259
+ }
1260
+ return null;
1261
+ }
1132
1262
  const updateSnapshot = () => {
1133
1263
  setSnapshot == null ? void 0 : setSnapshot({
1134
1264
  atThreshold,
@@ -1161,8 +1291,9 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
1161
1291
  };
1162
1292
 
1163
1293
  // src/utils/checkAtBottom.ts
1164
- function checkAtBottom(ctx, state) {
1294
+ function checkAtBottom(ctx) {
1165
1295
  var _a3;
1296
+ const state = ctx.state;
1166
1297
  if (!state) {
1167
1298
  return;
1168
1299
  }
@@ -1235,15 +1366,15 @@ function checkAtTop(state) {
1235
1366
  }
1236
1367
 
1237
1368
  // src/core/updateScroll.ts
1238
- function updateScroll(ctx, state, newScroll, forceUpdate) {
1369
+ function updateScroll(ctx, newScroll, forceUpdate) {
1239
1370
  var _a3;
1240
- const scrollingTo = peek$(ctx, "scrollingTo");
1371
+ const state = ctx.state;
1372
+ const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
1241
1373
  state.hasScrolled = true;
1242
1374
  state.lastBatchingAction = Date.now();
1243
1375
  const currentTime = Date.now();
1244
- const adjust = state.scrollAdjustHandler.getAdjust();
1245
- const lastHistoryAdjust = state.lastScrollAdjustForHistory;
1246
- const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
1376
+ const adjust = scrollAdjustHandler.getAdjust();
1377
+ const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1247
1378
  if (adjustChanged) {
1248
1379
  state.scrollHistory.length = 0;
1249
1380
  }
@@ -1268,22 +1399,26 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1268
1399
  return;
1269
1400
  }
1270
1401
  }
1271
- if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1402
+ const lastCalculated = state.scrollLastCalculate;
1403
+ const shouldUpdate = forceUpdate || state.dataChangeNeedsScrollUpdate || state.scrollLastCalculate === void 0 || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
1404
+ if (shouldUpdate) {
1405
+ state.scrollLastCalculate = state.scroll;
1272
1406
  state.ignoreScrollFromMVCPIgnored = false;
1273
1407
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1274
- checkAtBottom(ctx, state);
1408
+ checkAtBottom(ctx);
1275
1409
  checkAtTop(state);
1276
1410
  state.dataChangeNeedsScrollUpdate = false;
1277
1411
  }
1278
1412
  }
1279
1413
 
1280
1414
  // src/utils/requestAdjust.ts
1281
- function requestAdjust(ctx, state, positionDiff, dataChanged) {
1415
+ function requestAdjust(ctx, positionDiff, dataChanged) {
1416
+ const state = ctx.state;
1282
1417
  if (Math.abs(positionDiff) > 0.1) {
1283
1418
  const needsScrollWorkaround = Platform2.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
1284
1419
  const doit = () => {
1285
1420
  if (needsScrollWorkaround) {
1286
- scrollTo(ctx, state, {
1421
+ scrollTo(ctx, {
1287
1422
  noScrollingTo: true,
1288
1423
  offset: state.scroll
1289
1424
  });
@@ -1296,8 +1431,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1296
1431
  };
1297
1432
  state.scroll += positionDiff;
1298
1433
  state.scrollForNextCalculateItemsInView = void 0;
1299
- const didLayout = peek$(ctx, "containersDidLayout");
1300
- if (didLayout) {
1434
+ const readyToRender = peek$(ctx, "readyToRender");
1435
+ if (readyToRender) {
1301
1436
  doit();
1302
1437
  if (Platform2.OS !== "web") {
1303
1438
  const threshold = state.scroll - positionDiff / 2;
@@ -1319,7 +1454,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1319
1454
  if (shouldForceUpdate) {
1320
1455
  state.ignoreScrollFromMVCPIgnored = false;
1321
1456
  state.scrollPending = state.scroll;
1322
- updateScroll(ctx, state, state.scroll, true);
1457
+ updateScroll(ctx, state.scroll, true);
1323
1458
  }
1324
1459
  }, delay);
1325
1460
  }
@@ -1334,28 +1469,27 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1334
1469
  var INITIAL_ANCHOR_TOLERANCE = 0.5;
1335
1470
  var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
1336
1471
  var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1337
- function ensureInitialAnchor(ctx, state) {
1472
+ function ensureInitialAnchor(ctx) {
1338
1473
  var _a3, _b, _c, _d, _e;
1339
- const anchor = state.initialAnchor;
1474
+ const state = ctx.state;
1475
+ const { initialAnchor, didContainersLayout, positions, scroll, scrollLength } = state;
1476
+ const anchor = initialAnchor;
1340
1477
  const item = state.props.data[anchor.index];
1341
- const containersDidLayout = peek$(ctx, "containersDidLayout");
1342
- if (!containersDidLayout) {
1478
+ if (!didContainersLayout) {
1343
1479
  return;
1344
1480
  }
1345
1481
  const id = getId(state, anchor.index);
1346
- if (state.positions.get(id) === void 0) {
1482
+ if (positions.get(id) === void 0) {
1347
1483
  return;
1348
1484
  }
1349
- const size = getItemSize(ctx, state, id, anchor.index, item, true, true);
1485
+ const size = getItemSize(ctx, id, anchor.index, item, true, true);
1350
1486
  if (size === void 0) {
1351
1487
  return;
1352
1488
  }
1353
- const availableSpace = Math.max(0, state.scrollLength - size);
1354
- const desiredOffset = calculateOffsetForIndex(ctx, state, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1355
- const contentSize = getContentSize(ctx);
1356
- const maxOffset = Math.max(0, contentSize - state.scrollLength);
1357
- const clampedDesiredOffset = Math.max(0, Math.min(desiredOffset, maxOffset));
1358
- const delta = clampedDesiredOffset - state.scroll;
1489
+ const availableSpace = Math.max(0, scrollLength - size);
1490
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1491
+ const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset);
1492
+ const delta = clampedDesiredOffset - scroll;
1359
1493
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1360
1494
  const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
1361
1495
  if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
@@ -1379,18 +1513,21 @@ function ensureInitialAnchor(ctx, state) {
1379
1513
  lastDelta: delta,
1380
1514
  settledTicks: 0
1381
1515
  });
1382
- requestAdjust(ctx, state, delta);
1516
+ requestAdjust(ctx, delta);
1517
+ requestAnimationFrame(() => finishScrollTo(ctx));
1383
1518
  }
1384
1519
 
1385
1520
  // src/core/mvcp.ts
1386
- function prepareMVCP(ctx, state, dataChanged) {
1521
+ function prepareMVCP(ctx, dataChanged) {
1522
+ const state = ctx.state;
1387
1523
  const { idsInView, positions, props } = state;
1388
1524
  const { maintainVisibleContentPosition } = props;
1389
- const scrollingTo = peek$(ctx, "scrollingTo");
1525
+ const scrollingTo = state.scrollingTo;
1390
1526
  let prevPosition;
1391
1527
  let targetId;
1392
1528
  const idsInViewWithPositions = [];
1393
1529
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1530
+ const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1394
1531
  const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1395
1532
  const indexByKey = state.indexByKey;
1396
1533
  if (shouldMVCP) {
@@ -1399,7 +1536,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1399
1536
  return void 0;
1400
1537
  }
1401
1538
  targetId = getId(state, scrollTarget);
1402
- } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
1539
+ } else if (idsInView.length > 0 && state.didContainersLayout) {
1403
1540
  if (dataChanged) {
1404
1541
  for (let i = 0; i < idsInView.length; i++) {
1405
1542
  const id = idsInView[i];
@@ -1416,7 +1553,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1416
1553
  prevPosition = positions.get(targetId);
1417
1554
  }
1418
1555
  return () => {
1419
- let positionDiff;
1556
+ let positionDiff = 0;
1420
1557
  if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1421
1558
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1422
1559
  const { id, position } = idsInViewWithPositions[i];
@@ -1442,16 +1579,28 @@ function prepareMVCP(ctx, state, dataChanged) {
1442
1579
  positionDiff = diff;
1443
1580
  }
1444
1581
  }
1445
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1446
- requestAdjust(ctx, state, positionDiff, dataChanged && maintainVisibleContentPosition);
1582
+ if (scrollingToViewPosition && scrollingToViewPosition > 0) {
1583
+ const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
1584
+ const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
1585
+ if (newSize !== void 0 && prevSize !== void 0 && newSize !== (scrollingTo == null ? void 0 : scrollingTo.itemSize)) {
1586
+ const diff = newSize - prevSize;
1587
+ if (diff !== 0) {
1588
+ positionDiff += (newSize - prevSize) * scrollingToViewPosition;
1589
+ scrollingTo.itemSize = newSize;
1590
+ }
1591
+ }
1592
+ }
1593
+ if (Math.abs(positionDiff) > 0.1) {
1594
+ requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1447
1595
  }
1448
1596
  };
1449
1597
  }
1450
1598
  }
1451
1599
 
1452
1600
  // src/core/prepareColumnStartState.ts
1453
- function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1601
+ function prepareColumnStartState(ctx, startIndex, useAverageSize) {
1454
1602
  var _a3;
1603
+ const state = ctx.state;
1455
1604
  const numColumns = peek$(ctx, "numColumns");
1456
1605
  let rowStartIndex = startIndex;
1457
1606
  const columnAtStart = state.columns.get(state.idCache[startIndex]);
@@ -1466,7 +1615,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1466
1615
  const prevId = state.idCache[prevIndex];
1467
1616
  const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1468
1617
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1469
- const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
1618
+ const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
1470
1619
  currentRowTop = prevPosition + prevRowHeight;
1471
1620
  }
1472
1621
  return {
@@ -1489,7 +1638,8 @@ function findRowStartIndex(state, numColumns, index) {
1489
1638
  }
1490
1639
  return rowStart;
1491
1640
  }
1492
- function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1641
+ function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
1642
+ const state = ctx.state;
1493
1643
  if (endIndex < startIndex) {
1494
1644
  return 0;
1495
1645
  }
@@ -1503,7 +1653,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1503
1653
  continue;
1504
1654
  }
1505
1655
  const id = state.idCache[i];
1506
- const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
1656
+ const size = getItemSize(ctx, id, i, data[i], useAverageSize);
1507
1657
  if (size > maxSize) {
1508
1658
  maxSize = size;
1509
1659
  }
@@ -1512,22 +1662,23 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1512
1662
  }
1513
1663
 
1514
1664
  // src/core/updateTotalSize.ts
1515
- function updateTotalSize(ctx, state) {
1665
+ function updateTotalSize(ctx) {
1666
+ const state = ctx.state;
1516
1667
  const {
1517
1668
  positions,
1518
1669
  props: { data }
1519
1670
  } = state;
1520
1671
  if (data.length === 0) {
1521
- addTotalSize(ctx, state, null, 0);
1672
+ addTotalSize(ctx, null, 0);
1522
1673
  } else {
1523
1674
  const lastId = getId(state, data.length - 1);
1524
1675
  if (lastId !== void 0) {
1525
1676
  const lastPosition = positions.get(lastId);
1526
1677
  if (lastPosition !== void 0) {
1527
- const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
1678
+ const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
1528
1679
  if (lastSize !== void 0) {
1529
1680
  const totalSize = lastPosition + lastSize;
1530
- addTotalSize(ctx, state, null, totalSize);
1681
+ addTotalSize(ctx, null, totalSize);
1531
1682
  }
1532
1683
  }
1533
1684
  }
@@ -1573,7 +1724,8 @@ var getScrollVelocity = (state) => {
1573
1724
  };
1574
1725
 
1575
1726
  // src/utils/updateSnapToOffsets.ts
1576
- function updateSnapToOffsets(ctx, state) {
1727
+ function updateSnapToOffsets(ctx) {
1728
+ const state = ctx.state;
1577
1729
  const {
1578
1730
  positions,
1579
1731
  props: { snapToIndices }
@@ -1588,30 +1740,30 @@ function updateSnapToOffsets(ctx, state) {
1588
1740
  }
1589
1741
 
1590
1742
  // src/core/updateItemPositions.ts
1591
- function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1743
+ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1592
1744
  doMVCP: false,
1593
1745
  forceFullUpdate: false,
1594
1746
  scrollBottomBuffered: -1,
1595
1747
  startIndex: 0
1596
1748
  }) {
1597
1749
  var _a3, _b, _c, _d, _e;
1750
+ const state = ctx.state;
1598
1751
  const {
1599
1752
  columns,
1600
1753
  indexByKey,
1601
1754
  positions,
1602
1755
  idCache,
1603
1756
  sizesKnown,
1604
- props: { getEstimatedItemSize, snapToIndices, enableAverages }
1757
+ props: { data, getEstimatedItemSize, snapToIndices },
1758
+ scrollingTo
1605
1759
  } = state;
1606
- const data = state.props.data;
1607
1760
  const dataLength = data.length;
1608
1761
  const numColumns = peek$(ctx, "numColumns");
1609
- const scrollingTo = peek$(ctx, "scrollingTo");
1610
1762
  const hasColumns = numColumns > 1;
1611
1763
  const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1612
1764
  const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
1613
1765
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1614
- const useAverageSize = enableAverages && !getEstimatedItemSize;
1766
+ const useAverageSize = !getEstimatedItemSize;
1615
1767
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1616
1768
  let currentRowTop = 0;
1617
1769
  let column = 1;
@@ -1620,7 +1772,6 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1620
1772
  if (hasColumns) {
1621
1773
  const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1622
1774
  ctx,
1623
- state,
1624
1775
  startIndex,
1625
1776
  useAverageSize
1626
1777
  );
@@ -1630,7 +1781,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1630
1781
  const prevIndex = startIndex - 1;
1631
1782
  const prevId = getId(state, prevIndex);
1632
1783
  const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1633
- const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1784
+ const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1634
1785
  currentRowTop = prevPosition + prevSize;
1635
1786
  }
1636
1787
  }
@@ -1647,7 +1798,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1647
1798
  breakAt = i + itemsPerRow + 10;
1648
1799
  }
1649
1800
  const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1650
- const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
1801
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
1651
1802
  if (IS_DEV && needsIndexByKey) {
1652
1803
  if (indexByKeyForChecking.has(id)) {
1653
1804
  console.error(
@@ -1656,7 +1807,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1656
1807
  }
1657
1808
  indexByKeyForChecking.set(id, i);
1658
1809
  }
1659
- positions.set(id, currentRowTop);
1810
+ if (currentRowTop !== positions.get(id)) {
1811
+ positions.set(id, currentRowTop);
1812
+ notifyPosition$(ctx, id, currentRowTop);
1813
+ }
1660
1814
  if (needsIndexByKey) {
1661
1815
  indexByKey.set(id, i);
1662
1816
  }
@@ -1676,10 +1830,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1676
1830
  }
1677
1831
  }
1678
1832
  if (!didBreakEarly) {
1679
- updateTotalSize(ctx, state);
1833
+ updateTotalSize(ctx);
1680
1834
  }
1681
1835
  if (snapToIndices) {
1682
- updateSnapToOffsets(ctx, state);
1836
+ updateSnapToOffsets(ctx);
1683
1837
  }
1684
1838
  }
1685
1839
 
@@ -1757,7 +1911,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1757
1911
  if (previousViewableItems) {
1758
1912
  for (const viewToken of previousViewableItems) {
1759
1913
  const containerId = findContainerId(ctx, viewToken.key);
1760
- if (!isViewable(
1914
+ if (!checkIsViewable(
1761
1915
  state,
1762
1916
  ctx,
1763
1917
  viewabilityConfig,
@@ -1778,7 +1932,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1778
1932
  if (item) {
1779
1933
  const key = getId(state, i);
1780
1934
  const containerId = findContainerId(ctx, key);
1781
- if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1935
+ if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1782
1936
  const viewToken = {
1783
1937
  containerId,
1784
1938
  index: i,
@@ -1838,11 +1992,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1838
1992
  const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
1839
1993
  const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
1840
1994
  const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1841
- const isViewable2 = percent >= viewablePercentThreshold;
1995
+ const isViewable = percent >= viewablePercentThreshold;
1842
1996
  const value = {
1843
1997
  containerId,
1844
1998
  index,
1845
- isViewable: isViewable2,
1999
+ isViewable,
1846
2000
  item,
1847
2001
  key,
1848
2002
  percentOfScroller,
@@ -1861,8 +2015,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1861
2015
  }
1862
2016
  return value;
1863
2017
  }
1864
- function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1865
- const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
2018
+ function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
2019
+ let value = ctx.mapViewabilityAmountValues.get(containerId);
2020
+ if (!value || value.key !== key) {
2021
+ value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
2022
+ }
1866
2023
  return value.isViewable;
1867
2024
  }
1868
2025
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
@@ -1890,8 +2047,9 @@ function checkAllSizesKnown(state) {
1890
2047
  }
1891
2048
 
1892
2049
  // src/utils/findAvailableContainers.ts
1893
- function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
2050
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1894
2051
  const numContainers = peek$(ctx, "numContainers");
2052
+ const state = ctx.state;
1895
2053
  const { stickyContainerPool, containerItemTypes } = state;
1896
2054
  const result = [];
1897
2055
  const availableContainers = [];
@@ -1935,14 +2093,14 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1935
2093
  continue;
1936
2094
  }
1937
2095
  const key = peek$(ctx, `containerItemKey${u}`);
1938
- let isOk = key === void 0;
1939
- if (!isOk && pendingRemovalSet.has(u)) {
1940
- pendingRemovalSet.delete(u);
1941
- pendingRemovalChanged = true;
1942
- const requiredType = neededTypes[typeIndex];
1943
- isOk = canReuseContainer(u, requiredType);
1944
- }
1945
- if (isOk) {
2096
+ const requiredType = neededTypes[typeIndex];
2097
+ const isPending = key !== void 0 && pendingRemovalSet.has(u);
2098
+ const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
2099
+ if (canUse) {
2100
+ if (isPending) {
2101
+ pendingRemovalSet.delete(u);
2102
+ pendingRemovalChanged = true;
2103
+ }
1946
2104
  result.push(u);
1947
2105
  if (requiredItemTypes) {
1948
2106
  typeIndex++;
@@ -2011,21 +2169,26 @@ function comparatorByDistance(a, b) {
2011
2169
  }
2012
2170
 
2013
2171
  // src/core/scrollToIndex.ts
2014
- function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
2015
- if (index >= state.props.data.length) {
2016
- index = state.props.data.length - 1;
2172
+ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
2173
+ const state = ctx.state;
2174
+ const { data } = state.props;
2175
+ if (index >= data.length) {
2176
+ index = data.length - 1;
2017
2177
  } else if (index < 0) {
2018
2178
  index = 0;
2019
2179
  }
2020
- const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
2021
- const isLast = index === state.props.data.length - 1;
2180
+ const firstIndexOffset = calculateOffsetForIndex(ctx, index);
2181
+ const isLast = index === data.length - 1;
2022
2182
  if (isLast && viewPosition === void 0) {
2023
2183
  viewPosition = 1;
2024
2184
  }
2025
2185
  state.scrollForNextCalculateItemsInView = void 0;
2026
- scrollTo(ctx, state, {
2186
+ const targetId = getId(state, index);
2187
+ const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
2188
+ scrollTo(ctx, {
2027
2189
  animated,
2028
2190
  index,
2191
+ itemSize,
2029
2192
  offset: firstIndexOffset,
2030
2193
  viewOffset,
2031
2194
  viewPosition: viewPosition != null ? viewPosition : 0
@@ -2033,29 +2196,30 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
2033
2196
  }
2034
2197
 
2035
2198
  // src/utils/setDidLayout.ts
2036
- function setDidLayout(ctx, state) {
2199
+ function setDidLayout(ctx) {
2200
+ const state = ctx.state;
2037
2201
  const {
2038
2202
  loadStartTime,
2039
2203
  initialScroll,
2040
2204
  props: { onLoad }
2041
2205
  } = state;
2042
2206
  state.queuedInitialLayout = true;
2043
- checkAtBottom(ctx, state);
2207
+ checkAtBottom(ctx);
2044
2208
  const setIt = () => {
2045
- set$(ctx, "containersDidLayout", true);
2209
+ setInitialRenderState(ctx, { didLayout: true });
2046
2210
  if (onLoad) {
2047
2211
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
2048
2212
  }
2049
2213
  };
2050
2214
  if (Platform2.OS === "android" && initialScroll) {
2051
2215
  if (IsNewArchitecture) {
2052
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2216
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
2053
2217
  requestAnimationFrame(() => {
2054
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2218
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
2055
2219
  setIt();
2056
2220
  });
2057
2221
  } else {
2058
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2222
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
2059
2223
  setIt();
2060
2224
  }
2061
2225
  } else {
@@ -2078,15 +2242,17 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
2078
2242
  }
2079
2243
  return -1;
2080
2244
  }
2081
- function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
2245
+ function getActiveStickyIndices(ctx, stickyHeaderIndices) {
2246
+ const state = ctx.state;
2082
2247
  return new Set(
2083
2248
  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))
2084
2249
  );
2085
2250
  }
2086
- function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2251
+ function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2087
2252
  var _a3;
2088
- const activeIndices = getActiveStickyIndices(ctx, state, stickyHeaderIndices);
2089
- state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
2253
+ const state = ctx.state;
2254
+ const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
2255
+ set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
2090
2256
  for (let offset = 0; offset <= 1; offset++) {
2091
2257
  const idx = currentStickyIdx - offset;
2092
2258
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
@@ -2097,8 +2263,9 @@ function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, cu
2097
2263
  }
2098
2264
  }
2099
2265
  }
2100
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2266
+ function handleStickyRecycling(ctx, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2101
2267
  var _a3, _b, _c;
2268
+ const state = ctx.state;
2102
2269
  for (const containerIndex of state.stickyContainerPool) {
2103
2270
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
2104
2271
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
@@ -2122,7 +2289,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2122
2289
  const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2123
2290
  if (currentId) {
2124
2291
  const currentPos = state.positions.get(currentId);
2125
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
2292
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2126
2293
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
2127
2294
  }
2128
2295
  }
@@ -2131,7 +2298,8 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2131
2298
  }
2132
2299
  }
2133
2300
  }
2134
- function calculateItemsInView(ctx, state, params = {}) {
2301
+ function calculateItemsInView(ctx, params = {}) {
2302
+ const state = ctx.state;
2135
2303
  reactNative.unstable_batchedUpdates(() => {
2136
2304
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2137
2305
  const {
@@ -2155,8 +2323,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2155
2323
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2156
2324
  const prevNumContainers = peek$(ctx, "numContainers");
2157
2325
  if (!data || scrollLength === 0 || !prevNumContainers) {
2158
- if (state.initialAnchor) {
2159
- ensureInitialAnchor(ctx, state);
2326
+ if (!IsNewArchitecture && state.initialAnchor) {
2327
+ ensureInitialAnchor(ctx);
2160
2328
  }
2161
2329
  return;
2162
2330
  }
@@ -2171,15 +2339,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2171
2339
  if (!queuedInitialLayout && initialScroll) {
2172
2340
  const updatedOffset = calculateOffsetWithOffsetPosition(
2173
2341
  ctx,
2174
- state,
2175
- calculateOffsetForIndex(ctx, state, initialScroll.index),
2342
+ calculateOffsetForIndex(ctx, initialScroll.index),
2176
2343
  initialScroll
2177
2344
  );
2178
2345
  scrollState = updatedOffset;
2179
2346
  }
2180
2347
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2181
2348
  const scrollAdjustPad = scrollAdjustPending - topPad;
2182
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2349
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2183
2350
  if (scroll + scrollLength > totalSize) {
2184
2351
  scroll = Math.max(0, totalSize - scrollLength);
2185
2352
  }
@@ -2187,11 +2354,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2187
2354
  set$(ctx, "debugRawScroll", scrollState);
2188
2355
  set$(ctx, "debugComputedScroll", scroll);
2189
2356
  }
2190
- const previousStickyIndex = state.activeStickyIndex;
2357
+ const previousStickyIndex = peek$(ctx, "activeStickyIndex");
2191
2358
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
2192
- const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
2193
- state.activeStickyIndex = nextActiveStickyIndex;
2194
- set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2359
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
2360
+ if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
2361
+ set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2362
+ }
2195
2363
  let scrollBufferTop = scrollBuffer;
2196
2364
  let scrollBufferBottom = scrollBuffer;
2197
2365
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2204,23 +2372,23 @@ function calculateItemsInView(ctx, state, params = {}) {
2204
2372
  const scrollTopBuffered = scroll - scrollBufferTop;
2205
2373
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2206
2374
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2207
- if (!dataChanged && scrollForNextCalculateItemsInView) {
2375
+ if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
2208
2376
  const { top, bottom } = scrollForNextCalculateItemsInView;
2209
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2210
- if (state.initialAnchor) {
2211
- ensureInitialAnchor(ctx, state);
2377
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2378
+ if (!IsNewArchitecture && state.initialAnchor) {
2379
+ ensureInitialAnchor(ctx);
2212
2380
  }
2213
2381
  return;
2214
2382
  }
2215
2383
  }
2216
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2384
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
2217
2385
  if (dataChanged) {
2218
2386
  indexByKey.clear();
2219
2387
  idCache.length = 0;
2220
2388
  positions.clear();
2221
2389
  }
2222
- const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2223
- updateItemPositions(ctx, state, dataChanged, {
2390
+ const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2391
+ updateItemPositions(ctx, dataChanged, {
2224
2392
  doMVCP,
2225
2393
  forceFullUpdate: !!forceFullItemPositions,
2226
2394
  scrollBottomBuffered,
@@ -2239,9 +2407,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2239
2407
  for (let i = loopStart; i >= 0; i--) {
2240
2408
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2241
2409
  const top = positions.get(id);
2242
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2410
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
2243
2411
  const bottom = top + size;
2244
- if (bottom > scroll - scrollBuffer) {
2412
+ if (bottom > scroll - scrollBufferTop) {
2245
2413
  loopStart = i;
2246
2414
  } else {
2247
2415
  break;
@@ -2266,7 +2434,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2266
2434
  const dataLength = data.length;
2267
2435
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2268
2436
  const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2269
- const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
2437
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
2270
2438
  const top = positions.get(id);
2271
2439
  if (!foundEnd) {
2272
2440
  if (startNoBuffer === null && top + size > scroll) {
@@ -2278,7 +2446,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2278
2446
  if (startBuffered === null && top + size > scrollTopBuffered) {
2279
2447
  startBuffered = i;
2280
2448
  startBufferedId = id;
2281
- nextTop = top;
2449
+ if (scrollTopBuffered < 0) {
2450
+ nextTop = null;
2451
+ } else {
2452
+ nextTop = top;
2453
+ }
2282
2454
  }
2283
2455
  if (startNoBuffer !== null) {
2284
2456
  if (top <= scrollBottom) {
@@ -2286,7 +2458,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2286
2458
  }
2287
2459
  if (top <= scrollBottomBuffered) {
2288
2460
  endBuffered = i;
2289
- nextBottom = top + size;
2461
+ if (scrollBottomBuffered > totalSize) {
2462
+ nextBottom = null;
2463
+ } else {
2464
+ nextBottom = top + size;
2465
+ }
2290
2466
  } else {
2291
2467
  foundEnd = true;
2292
2468
  }
@@ -2313,7 +2489,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2313
2489
  top: nextTop
2314
2490
  } : void 0;
2315
2491
  }
2316
- const numContainers = peek$(ctx, "numContainers");
2492
+ let numContainers = prevNumContainers;
2317
2493
  const pendingRemoval = [];
2318
2494
  if (dataChanged) {
2319
2495
  for (let i = 0; i < numContainers; i++) {
@@ -2324,7 +2500,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2324
2500
  }
2325
2501
  }
2326
2502
  if (startBuffered !== null && endBuffered !== null) {
2327
- let numContainers2 = prevNumContainers;
2328
2503
  const needNewContainers = [];
2329
2504
  for (let i = startBuffered; i <= endBuffered; i++) {
2330
2505
  const id = (_h = idCache[i]) != null ? _h : getId(state, i);
@@ -2335,7 +2510,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2335
2510
  if (stickyIndicesArr.length > 0) {
2336
2511
  handleStickyActivation(
2337
2512
  ctx,
2338
- state,
2339
2513
  stickyIndicesSet,
2340
2514
  stickyIndicesArr,
2341
2515
  currentStickyIdx,
@@ -2343,9 +2517,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2343
2517
  startBuffered,
2344
2518
  endBuffered
2345
2519
  );
2346
- } else {
2347
- state.activeStickyIndex = void 0;
2348
- set$(ctx, "activeStickyIndex", void 0);
2520
+ } else if (previousStickyIndex !== -1) {
2521
+ set$(ctx, "activeStickyIndex", -1);
2349
2522
  }
2350
2523
  if (needNewContainers.length > 0) {
2351
2524
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2354,7 +2527,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2354
2527
  }) : void 0;
2355
2528
  const availableContainers = findAvailableContainers(
2356
2529
  ctx,
2357
- state,
2358
2530
  needNewContainers.length,
2359
2531
  startBuffered,
2360
2532
  endBuffered,
@@ -2376,29 +2548,30 @@ function calculateItemsInView(ctx, state, params = {}) {
2376
2548
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
2377
2549
  }
2378
2550
  containerItemKeys.add(id);
2551
+ const containerSticky = `containerSticky${containerIndex}`;
2379
2552
  if (stickyIndicesSet.has(i)) {
2380
- set$(ctx, `containerSticky${containerIndex}`, true);
2553
+ set$(ctx, containerSticky, true);
2381
2554
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2382
2555
  set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2383
2556
  state.stickyContainerPool.add(containerIndex);
2384
- } else {
2385
- set$(ctx, `containerSticky${containerIndex}`, false);
2557
+ } else if (peek$(ctx, containerSticky)) {
2558
+ set$(ctx, containerSticky, false);
2386
2559
  state.stickyContainerPool.delete(containerIndex);
2387
2560
  }
2388
- if (containerIndex >= numContainers2) {
2389
- numContainers2 = containerIndex + 1;
2561
+ if (containerIndex >= numContainers) {
2562
+ numContainers = containerIndex + 1;
2390
2563
  }
2391
2564
  }
2392
- if (numContainers2 !== prevNumContainers) {
2393
- set$(ctx, "numContainers", numContainers2);
2394
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
2395
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
2565
+ if (numContainers !== prevNumContainers) {
2566
+ set$(ctx, "numContainers", numContainers);
2567
+ if (numContainers > peek$(ctx, "numContainersPooled")) {
2568
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
2396
2569
  }
2397
2570
  }
2398
2571
  }
2399
2572
  }
2400
2573
  if (stickyIndicesArr.length > 0) {
2401
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2574
+ handleStickyRecycling(ctx, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2402
2575
  }
2403
2576
  let didChangePositions = false;
2404
2577
  for (let i = 0; i < numContainers; i++) {
@@ -2450,7 +2623,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2450
2623
  }
2451
2624
  if (!queuedInitialLayout && endBuffered !== null) {
2452
2625
  if (checkAllSizesKnown(state)) {
2453
- setDidLayout(ctx, state);
2626
+ setDidLayout(ctx);
2454
2627
  }
2455
2628
  }
2456
2629
  if (viewabilityConfigCallbackPairs) {
@@ -2463,8 +2636,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2463
2636
  }
2464
2637
  }
2465
2638
  });
2466
- if (state.initialAnchor) {
2467
- ensureInitialAnchor(ctx, state);
2639
+ if (!IsNewArchitecture && state.initialAnchor) {
2640
+ ensureInitialAnchor(ctx);
2468
2641
  }
2469
2642
  }
2470
2643
 
@@ -2489,19 +2662,22 @@ function checkActualChange(state, dataProp, previousData) {
2489
2662
  }
2490
2663
 
2491
2664
  // src/core/doMaintainScrollAtEnd.ts
2492
- function doMaintainScrollAtEnd(ctx, state, animated) {
2665
+ function doMaintainScrollAtEnd(ctx, animated) {
2666
+ const state = ctx.state;
2493
2667
  const {
2668
+ didContainersLayout,
2669
+ isAtEnd,
2494
2670
  refScroller,
2495
2671
  props: { maintainScrollAtEnd }
2496
2672
  } = state;
2497
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2673
+ if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
2498
2674
  const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2499
2675
  if (paddingTop > 0) {
2500
2676
  state.scroll = 0;
2501
2677
  }
2502
2678
  requestAnimationFrame(() => {
2503
2679
  var _a3;
2504
- if (state == null ? void 0 : state.isAtEnd) {
2680
+ if (state.isAtEnd) {
2505
2681
  state.maintainingScrollAtEnd = true;
2506
2682
  (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2507
2683
  animated
@@ -2572,28 +2748,30 @@ function updateAveragesOnDataChange(state, oldData, newData) {
2572
2748
  }
2573
2749
 
2574
2750
  // src/core/checkResetContainers.ts
2575
- function checkResetContainers(ctx, state, dataProp) {
2751
+ function checkResetContainers(ctx, dataProp) {
2752
+ const state = ctx.state;
2576
2753
  const { previousData } = state;
2577
2754
  if (previousData) {
2578
2755
  updateAveragesOnDataChange(state, previousData, dataProp);
2579
2756
  }
2580
2757
  const { maintainScrollAtEnd } = state.props;
2581
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2758
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2582
2759
  const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2583
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
2760
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
2584
2761
  if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
2585
2762
  state.isEndReached = false;
2586
2763
  }
2587
2764
  if (!didMaintainScrollAtEnd) {
2588
2765
  checkAtTop(state);
2589
- checkAtBottom(ctx, state);
2766
+ checkAtBottom(ctx);
2590
2767
  }
2591
2768
  delete state.previousData;
2592
2769
  }
2593
2770
 
2594
2771
  // src/core/doInitialAllocateContainers.ts
2595
- function doInitialAllocateContainers(ctx, state) {
2772
+ function doInitialAllocateContainers(ctx) {
2596
2773
  var _a3, _b, _c;
2774
+ const state = ctx.state;
2597
2775
  const {
2598
2776
  scrollLength,
2599
2777
  props: {
@@ -2631,10 +2809,10 @@ function doInitialAllocateContainers(ctx, state) {
2631
2809
  if (!IsNewArchitecture || state.lastLayout) {
2632
2810
  if (state.initialScroll) {
2633
2811
  requestAnimationFrame(() => {
2634
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2812
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2635
2813
  });
2636
2814
  } else {
2637
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2815
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2638
2816
  }
2639
2817
  }
2640
2818
  return true;
@@ -2642,7 +2820,8 @@ function doInitialAllocateContainers(ctx, state) {
2642
2820
  }
2643
2821
 
2644
2822
  // src/core/handleLayout.ts
2645
- function handleLayout(ctx, state, layout, setCanRender) {
2823
+ function handleLayout(ctx, layout, setCanRender) {
2824
+ const state = ctx.state;
2646
2825
  const { maintainScrollAtEnd } = state.props;
2647
2826
  const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2648
2827
  const previousLength = state.scrollLength;
@@ -2658,19 +2837,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2658
2837
  state.lastBatchingAction = Date.now();
2659
2838
  state.scrollForNextCalculateItemsInView = void 0;
2660
2839
  if (scrollLength > 0) {
2661
- doInitialAllocateContainers(ctx, state);
2840
+ doInitialAllocateContainers(ctx);
2662
2841
  }
2663
2842
  if (needsCalculate) {
2664
- calculateItemsInView(ctx, state, { doMVCP: true });
2843
+ calculateItemsInView(ctx, { doMVCP: true });
2665
2844
  }
2666
2845
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
2667
2846
  set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
2668
2847
  }
2669
2848
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
2670
- doMaintainScrollAtEnd(ctx, state, false);
2849
+ doMaintainScrollAtEnd(ctx, false);
2671
2850
  }
2672
- updateAlignItemsPaddingTop(ctx, state);
2673
- checkAtBottom(ctx, state);
2851
+ updateAlignItemsPaddingTop(ctx);
2852
+ checkAtBottom(ctx);
2674
2853
  checkAtTop(state);
2675
2854
  if (state) {
2676
2855
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
@@ -2686,8 +2865,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2686
2865
  }
2687
2866
 
2688
2867
  // src/core/onScroll.ts
2689
- function onScroll(ctx, state, event) {
2868
+ function onScroll(ctx, event) {
2690
2869
  var _a3, _b, _c;
2870
+ const state = ctx.state;
2691
2871
  const {
2692
2872
  scrollProcessingEnabled,
2693
2873
  props: { onScroll: onScrollProp }
@@ -2698,9 +2878,23 @@ function onScroll(ctx, state, event) {
2698
2878
  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) {
2699
2879
  return;
2700
2880
  }
2701
- const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2881
+ let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2702
2882
  state.scrollPending = newScroll;
2703
- updateScroll(ctx, state, newScroll);
2883
+ if (state.scrollingTo) {
2884
+ const maxOffset = clampScrollOffset(ctx, newScroll);
2885
+ if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
2886
+ newScroll = maxOffset;
2887
+ scrollTo(ctx, {
2888
+ forceScroll: true,
2889
+ isInitialScroll: true,
2890
+ noScrollingTo: true,
2891
+ offset: newScroll
2892
+ });
2893
+ return;
2894
+ }
2895
+ }
2896
+ updateScroll(ctx, newScroll);
2897
+ checkFinishedScroll(ctx);
2704
2898
  onScrollProp == null ? void 0 : onScrollProp(event);
2705
2899
  }
2706
2900
 
@@ -2709,51 +2903,47 @@ var ScrollAdjustHandler = class {
2709
2903
  constructor(ctx) {
2710
2904
  this.appliedAdjust = 0;
2711
2905
  this.pendingAdjust = 0;
2712
- this.mounted = false;
2713
- this.context = ctx;
2714
- if (Platform2.OS === "web") {
2715
- const commitPendingAdjust = () => {
2716
- const state = this.context.internalState;
2717
- const pending = this.pendingAdjust;
2718
- if (pending !== 0) {
2719
- this.pendingAdjust = 0;
2720
- this.appliedAdjust += pending;
2721
- state.scroll += pending;
2722
- state.scrollForNextCalculateItemsInView = void 0;
2723
- set$(this.context, "scrollAdjustPending", 0);
2724
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2725
- calculateItemsInView(this.context, this.context.internalState);
2726
- }
2727
- };
2728
- listen$(this.context, "scrollingTo", (value) => {
2729
- if (value === void 0) {
2730
- commitPendingAdjust();
2731
- }
2732
- });
2733
- }
2906
+ this.ctx = ctx;
2734
2907
  }
2735
2908
  requestAdjust(add) {
2736
- const scrollingTo = peek$(this.context, "scrollingTo");
2909
+ const scrollingTo = this.ctx.state.scrollingTo;
2737
2910
  if (Platform2.OS === "web" && (scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
2738
2911
  this.pendingAdjust += add;
2739
- set$(this.context, "scrollAdjustPending", this.pendingAdjust);
2912
+ set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
2740
2913
  } else {
2741
2914
  this.appliedAdjust += add;
2742
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2915
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2916
+ }
2917
+ if (this.ctx.state.scrollingTo) {
2918
+ checkFinishedScroll(this.ctx);
2743
2919
  }
2744
- }
2745
- setMounted() {
2746
- this.mounted = true;
2747
2920
  }
2748
2921
  getAdjust() {
2749
2922
  return this.appliedAdjust;
2750
2923
  }
2924
+ commitPendingAdjust() {
2925
+ if (Platform2.OS === "web") {
2926
+ const state = this.ctx.state;
2927
+ const pending = this.pendingAdjust;
2928
+ if (pending !== 0) {
2929
+ this.pendingAdjust = 0;
2930
+ this.appliedAdjust += pending;
2931
+ state.scroll += pending;
2932
+ state.scrollForNextCalculateItemsInView = void 0;
2933
+ set$(this.ctx, "scrollAdjustPending", 0);
2934
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2935
+ calculateItemsInView(this.ctx);
2936
+ }
2937
+ }
2938
+ }
2751
2939
  };
2752
2940
 
2753
2941
  // src/core/updateItemSize.ts
2754
- function updateItemSize(ctx, state, itemKey, sizeObj) {
2942
+ function updateItemSize(ctx, itemKey, sizeObj) {
2755
2943
  var _a3;
2944
+ const state = ctx.state;
2756
2945
  const {
2946
+ didContainersLayout,
2757
2947
  sizesKnown,
2758
2948
  props: {
2759
2949
  getFixedItemSize,
@@ -2781,13 +2971,12 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2781
2971
  return;
2782
2972
  }
2783
2973
  }
2784
- const containersDidLayout = peek$(ctx, "containersDidLayout");
2785
- let needsRecalculate = !containersDidLayout;
2974
+ let needsRecalculate = !didContainersLayout;
2786
2975
  let shouldMaintainScrollAtEnd = false;
2787
2976
  let minIndexSizeChanged;
2788
2977
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
2789
2978
  const prevSizeKnown = state.sizesKnown.get(itemKey);
2790
- const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
2979
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj);
2791
2980
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
2792
2981
  if (diff !== 0) {
2793
2982
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -2836,22 +3025,22 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2836
3025
  if (!cur || maxOtherAxisSize > cur) {
2837
3026
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
2838
3027
  }
2839
- if (containersDidLayout || checkAllSizesKnown(state)) {
3028
+ if (didContainersLayout || checkAllSizesKnown(state)) {
2840
3029
  if (needsRecalculate) {
2841
3030
  state.scrollForNextCalculateItemsInView = void 0;
2842
- calculateItemsInView(ctx, state, { doMVCP: true });
3031
+ calculateItemsInView(ctx, { doMVCP: true });
2843
3032
  }
2844
3033
  if (shouldMaintainScrollAtEnd) {
2845
3034
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
2846
- doMaintainScrollAtEnd(ctx, state, false);
3035
+ doMaintainScrollAtEnd(ctx, false);
2847
3036
  }
2848
3037
  }
2849
3038
  }
2850
3039
  }
2851
- function updateOneItemSize(ctx, state, itemKey, sizeObj) {
3040
+ function updateOneItemSize(ctx, itemKey, sizeObj) {
2852
3041
  var _a3;
3042
+ const state = ctx.state;
2853
3043
  const {
2854
- sizes,
2855
3044
  indexByKey,
2856
3045
  sizesKnown,
2857
3046
  averageSizes,
@@ -2859,9 +3048,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2859
3048
  } = state;
2860
3049
  if (!data) return 0;
2861
3050
  const index = indexByKey.get(itemKey);
2862
- const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
3051
+ const prevSize = getItemSize(ctx, itemKey, index, data[index]);
2863
3052
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2864
3053
  const size = Platform2.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
3054
+ const prevSizeKnown = sizesKnown.get(itemKey);
2865
3055
  sizesKnown.set(itemKey, size);
2866
3056
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2867
3057
  const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
@@ -2869,11 +3059,15 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2869
3059
  if (!averages) {
2870
3060
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
2871
3061
  }
2872
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2873
- averages.num++;
3062
+ if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
3063
+ averages.avg += (size - prevSizeKnown) / averages.num;
3064
+ } else {
3065
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
3066
+ averages.num++;
3067
+ }
2874
3068
  }
2875
3069
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2876
- setSize(ctx, state, itemKey, size);
3070
+ setSize(ctx, itemKey, size);
2877
3071
  return size - prevSize;
2878
3072
  }
2879
3073
  return 0;
@@ -2939,14 +3133,15 @@ function createColumnWrapperStyle(contentContainerStyle) {
2939
3133
  }
2940
3134
 
2941
3135
  // src/utils/createImperativeHandle.ts
2942
- function createImperativeHandle(ctx, state) {
3136
+ function createImperativeHandle(ctx) {
3137
+ const state = ctx.state;
2943
3138
  const scrollIndexIntoView = (options) => {
2944
3139
  if (state) {
2945
3140
  const { index, ...rest } = options;
2946
3141
  const { startNoBuffer, endNoBuffer } = state;
2947
3142
  if (index < startNoBuffer || index > endNoBuffer) {
2948
3143
  const viewPosition = index < startNoBuffer ? 0 : 1;
2949
- scrollToIndex(ctx, state, {
3144
+ scrollToIndex(ctx, {
2950
3145
  ...rest,
2951
3146
  index,
2952
3147
  viewPosition
@@ -2961,7 +3156,7 @@ function createImperativeHandle(ctx, state) {
2961
3156
  getScrollableNode: () => refScroller.current.getScrollableNode(),
2962
3157
  getScrollResponder: () => refScroller.current.getScrollResponder(),
2963
3158
  getState: () => ({
2964
- activeStickyIndex: state.activeStickyIndex,
3159
+ activeStickyIndex: peek$(ctx, "activeStickyIndex"),
2965
3160
  contentLength: state.totalSize,
2966
3161
  data: state.props.data,
2967
3162
  elementAtIndex: (index) => {
@@ -2972,6 +3167,8 @@ function createImperativeHandle(ctx, state) {
2972
3167
  endBuffered: state.endBuffered,
2973
3168
  isAtEnd: state.isAtEnd,
2974
3169
  isAtStart: state.isAtStart,
3170
+ listen: (signalName, cb) => listen$(ctx, signalName, cb),
3171
+ listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
2975
3172
  positionAtIndex: (index) => state.positions.get(getId(state, index)),
2976
3173
  positions: state.positions,
2977
3174
  scroll: state.scroll,
@@ -2996,23 +3193,23 @@ function createImperativeHandle(ctx, state) {
2996
3193
  if (index !== -1) {
2997
3194
  const paddingBottom = stylePaddingBottom || 0;
2998
3195
  const footerSize = peek$(ctx, "footerSize") || 0;
2999
- scrollToIndex(ctx, state, {
3196
+ scrollToIndex(ctx, {
3197
+ ...options,
3000
3198
  index,
3001
3199
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
3002
- viewPosition: 1,
3003
- ...options
3200
+ viewPosition: 1
3004
3201
  });
3005
3202
  }
3006
3203
  },
3007
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3204
+ scrollToIndex: (params) => scrollToIndex(ctx, params),
3008
3205
  scrollToItem: ({ item, ...props }) => {
3009
3206
  const data = state.props.data;
3010
3207
  const index = data.indexOf(item);
3011
3208
  if (index !== -1) {
3012
- scrollToIndex(ctx, state, { index, ...props });
3209
+ scrollToIndex(ctx, { index, ...props });
3013
3210
  }
3014
3211
  },
3015
- scrollToOffset: (params) => scrollTo(ctx, state, params),
3212
+ scrollToOffset: (params) => scrollTo(ctx, params),
3016
3213
  setScrollProcessingEnabled: (enabled) => {
3017
3214
  state.scrollProcessingEnabled = enabled;
3018
3215
  },
@@ -3022,8 +3219,9 @@ function createImperativeHandle(ctx, state) {
3022
3219
  }
3023
3220
  };
3024
3221
  }
3025
- function getRenderedItem(ctx, state, key) {
3222
+ function getRenderedItem(ctx, key) {
3026
3223
  var _a3;
3224
+ const state = ctx.state;
3027
3225
  if (!state) {
3028
3226
  return null;
3029
3227
  }
@@ -3100,11 +3298,13 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
3100
3298
  var DEFAULT_DRAW_DISTANCE = 250;
3101
3299
  var DEFAULT_ITEM_SIZE = 100;
3102
3300
  var LegendList = typedMemo(
3301
+ // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
3103
3302
  typedForwardRef(function LegendList2(props, forwardedRef) {
3104
3303
  const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
3105
3304
  const isChildrenMode = children !== void 0 && dataProp === void 0;
3106
3305
  const processedProps = isChildrenMode ? {
3107
3306
  ...restProps,
3307
+ childrenMode: true,
3108
3308
  data: (isArray(children) ? children : React2__namespace.Children.toArray(children)).flat(1),
3109
3309
  renderItem: ({ item }) => item
3110
3310
  } : {
@@ -3121,10 +3321,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3121
3321
  alignItemsAtEnd = false,
3122
3322
  columnWrapperStyle,
3123
3323
  contentContainerStyle: contentContainerStyleProp,
3324
+ contentInset,
3124
3325
  data: dataProp = [],
3125
3326
  dataVersion,
3126
3327
  drawDistance = 250,
3127
- enableAverages = true,
3128
3328
  estimatedItemSize: estimatedItemSizeProp,
3129
3329
  estimatedListSize,
3130
3330
  extraData,
@@ -3166,6 +3366,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3166
3366
  snapToIndices,
3167
3367
  stickyHeaderIndices: stickyHeaderIndicesProp,
3168
3368
  stickyIndices: stickyIndicesDeprecated,
3369
+ // TODOV3: Remove from v3 release
3169
3370
  style: styleProp,
3170
3371
  suggestEstimatedItemSize,
3171
3372
  viewabilityConfig,
@@ -3173,6 +3374,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3173
3374
  waitForInitialLayout = true,
3174
3375
  ...rest
3175
3376
  } = props;
3377
+ const animatedPropsInternal = props.animatedPropsInternal;
3378
+ const { childrenMode } = rest;
3176
3379
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
3177
3380
  const style = { ...StyleSheet.flatten(styleProp) };
3178
3381
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -3196,10 +3399,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3196
3399
  }
3197
3400
  const refState = React2.useRef();
3198
3401
  if (!refState.current) {
3199
- if (!ctx.internalState) {
3402
+ if (!ctx.state) {
3200
3403
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : getWindowSize())[horizontal ? "width" : "height"];
3201
- ctx.internalState = {
3202
- activeStickyIndex: void 0,
3404
+ ctx.state = {
3405
+ activeStickyIndex: -1,
3203
3406
  averageSizes: {},
3204
3407
  columns: /* @__PURE__ */ new Map(),
3205
3408
  containerItemKeys: /* @__PURE__ */ new Set(),
@@ -3225,9 +3428,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3225
3428
  initialScroll: initialScrollProp,
3226
3429
  isAtEnd: false,
3227
3430
  isAtStart: false,
3228
- isEndReached: false,
3431
+ isEndReached: null,
3229
3432
  isFirst: true,
3230
- isStartReached: false,
3433
+ isStartReached: null,
3231
3434
  lastBatchingAction: Date.now(),
3232
3435
  lastLayout: void 0,
3233
3436
  loadStartTime: Date.now(),
@@ -3259,12 +3462,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3259
3462
  totalSize: 0,
3260
3463
  viewabilityConfigCallbackPairs: void 0
3261
3464
  };
3262
- const internalState = ctx.internalState;
3263
- internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
3465
+ const internalState = ctx.state;
3466
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3264
3467
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3265
3468
  set$(ctx, "extraData", extraData);
3266
3469
  }
3267
- refState.current = ctx.internalState;
3470
+ refState.current = ctx.state;
3268
3471
  }
3269
3472
  const state = refState.current;
3270
3473
  const isFirstLocal = state.isFirst;
@@ -3278,9 +3481,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3278
3481
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
3279
3482
  state.props = {
3280
3483
  alignItemsAtEnd,
3484
+ animatedProps: animatedPropsInternal,
3485
+ contentInset,
3281
3486
  data: dataProp,
3282
3487
  dataVersion,
3283
- enableAverages,
3284
3488
  estimatedItemSize,
3285
3489
  getEstimatedItemSize,
3286
3490
  getFixedItemSize,
@@ -3323,62 +3527,62 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3323
3527
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3324
3528
  set$(ctx, "numColumns", numColumnsProp);
3325
3529
  const prevPaddingTop = peek$(ctx, "stylePaddingTop");
3326
- setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3530
+ setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3327
3531
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3328
3532
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3329
3533
  if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3330
3534
  if (state.scroll < 0) {
3331
3535
  paddingDiff += state.scroll;
3332
3536
  }
3333
- requestAdjust(ctx, state, paddingDiff);
3537
+ requestAdjust(ctx, paddingDiff);
3334
3538
  }
3335
3539
  };
3336
3540
  if (isFirstLocal) {
3337
3541
  initializeStateVars();
3338
3542
  updateItemPositions(
3339
3543
  ctx,
3340
- state,
3341
3544
  /*dataChanged*/
3342
3545
  true
3343
3546
  );
3344
3547
  }
3345
3548
  const initialContentOffset = React2.useMemo(() => {
3346
- var _a4, _b2;
3347
- const { initialScroll } = refState.current;
3348
- if (!initialScroll) {
3549
+ var _a4;
3550
+ let value;
3551
+ const { initialScroll, initialAnchor } = refState.current;
3552
+ if (initialScroll) {
3553
+ if (!IsNewArchitecture && initialScroll.index !== void 0 && (!initialAnchor || (initialAnchor == null ? void 0 : initialAnchor.index) !== initialScroll.index)) {
3554
+ refState.current.initialAnchor = {
3555
+ attempts: 0,
3556
+ index: initialScroll.index,
3557
+ settledTicks: 0,
3558
+ viewOffset: (_a4 = initialScroll.viewOffset) != null ? _a4 : 0,
3559
+ viewPosition: initialScroll.viewPosition
3560
+ };
3561
+ }
3562
+ if (initialScroll.contentOffset !== void 0) {
3563
+ value = initialScroll.contentOffset;
3564
+ } else {
3565
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
3566
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
3567
+ const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
3568
+ const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3569
+ refState.current.initialScroll = updatedInitialScroll;
3570
+ state.initialScroll = updatedInitialScroll;
3571
+ value = clampedOffset;
3572
+ }
3573
+ } else {
3349
3574
  refState.current.initialAnchor = void 0;
3350
- return 0;
3351
- }
3352
- if (initialScroll.index !== void 0 && (!refState.current.initialAnchor || ((_a4 = refState.current.initialAnchor) == null ? void 0 : _a4.index) !== initialScroll.index)) {
3353
- refState.current.initialAnchor = {
3354
- attempts: 0,
3355
- index: initialScroll.index,
3356
- settledTicks: 0,
3357
- viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
3358
- viewPosition: initialScroll.viewPosition
3359
- };
3575
+ value = 0;
3360
3576
  }
3361
- if (initialScroll.contentOffset !== void 0) {
3362
- return initialScroll.contentOffset;
3363
- }
3364
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
3365
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
3366
- let clampedOffset = resolvedOffset;
3367
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
3368
- const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
3369
- clampedOffset = Math.min(clampedOffset, maxOffset);
3370
- }
3371
- clampedOffset = Math.max(0, clampedOffset);
3372
- const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3373
- refState.current.initialScroll = updatedInitialScroll;
3374
- state.initialScroll = updatedInitialScroll;
3375
- refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
3376
- return clampedOffset;
3577
+ if (!value) {
3578
+ state.didFinishInitialScroll = true;
3579
+ }
3580
+ return value;
3377
3581
  }, [renderNum]);
3378
3582
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
3379
3583
  refState.current.lastBatchingAction = Date.now();
3380
3584
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
3381
- IS_DEV && warnDevOnce(
3585
+ IS_DEV && !childrenMode && warnDevOnce(
3382
3586
  "keyExtractor",
3383
3587
  "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."
3384
3588
  );
@@ -3403,12 +3607,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3403
3607
  }
3404
3608
  }, []);
3405
3609
  const doInitialScroll = React2.useCallback(() => {
3406
- var _a4;
3407
3610
  const initialScroll = state.initialScroll;
3408
3611
  if (initialScroll) {
3409
- scrollTo(ctx, state, {
3612
+ scrollTo(ctx, {
3410
3613
  animated: false,
3411
- index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
3614
+ index: initialScroll == null ? void 0 : initialScroll.index,
3412
3615
  isInitialScroll: true,
3413
3616
  offset: initialContentOffset,
3414
3617
  precomputedWithViewOffset: true
@@ -3417,7 +3620,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3417
3620
  }, [initialContentOffset]);
3418
3621
  const onLayoutChange = React2.useCallback((layout) => {
3419
3622
  doInitialScroll();
3420
- handleLayout(ctx, state, layout, setCanRender);
3623
+ handleLayout(ctx, layout, setCanRender);
3421
3624
  }, []);
3422
3625
  const { onLayout } = useOnLayoutSync({
3423
3626
  onLayoutChange,
@@ -3427,7 +3630,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3427
3630
  });
3428
3631
  React2.useLayoutEffect(() => {
3429
3632
  if (snapToIndices) {
3430
- updateSnapToOffsets(ctx, state);
3633
+ updateSnapToOffsets(ctx);
3431
3634
  }
3432
3635
  }, [snapToIndices]);
3433
3636
  React2.useLayoutEffect(() => {
@@ -3437,9 +3640,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3437
3640
  isFirst,
3438
3641
  props: { data }
3439
3642
  } = state;
3440
- const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
3643
+ const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
3441
3644
  if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
3442
- checkResetContainers(ctx, state, data);
3645
+ checkResetContainers(ctx, data);
3443
3646
  }
3444
3647
  state.didColumnsChange = false;
3445
3648
  state.didDataChange = false;
@@ -3466,18 +3669,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3466
3669
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
3467
3670
  if (!IsNewArchitecture) {
3468
3671
  useInit(() => {
3469
- doInitialAllocateContainers(ctx, state);
3672
+ doInitialAllocateContainers(ctx);
3470
3673
  });
3471
3674
  }
3472
- React2.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
3675
+ React2.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
3473
3676
  if (Platform2.OS === "web") {
3474
3677
  React2.useEffect(doInitialScroll, []);
3475
3678
  }
3476
3679
  const fns = React2.useMemo(
3477
3680
  () => ({
3478
- getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3479
- onScroll: (event) => onScroll(ctx, state, event),
3480
- updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj)
3681
+ getRenderedItem: (key) => getRenderedItem(ctx, key),
3682
+ onMomentumScrollEnd: (event) => {
3683
+ checkFinishedScrollFallback(ctx);
3684
+ if (onMomentumScrollEnd) {
3685
+ onMomentumScrollEnd(event);
3686
+ }
3687
+ },
3688
+ onScroll: (event) => onScroll(ctx, event),
3689
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
3481
3690
  }),
3482
3691
  []
3483
3692
  );
@@ -3489,6 +3698,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3489
3698
  alignItemsAtEnd,
3490
3699
  canRender,
3491
3700
  contentContainerStyle,
3701
+ contentInset,
3492
3702
  getRenderedItem: fns.getRenderedItem,
3493
3703
  horizontal,
3494
3704
  initialContentOffset,
@@ -3497,20 +3707,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3497
3707
  maintainVisibleContentPosition,
3498
3708
  onLayout,
3499
3709
  onLayoutHeader,
3500
- onMomentumScrollEnd: (event) => {
3501
- if (IsNewArchitecture) {
3502
- requestAnimationFrame(() => {
3503
- finishScrollTo(ctx, refState.current);
3504
- });
3505
- } else {
3506
- setTimeout(() => {
3507
- finishScrollTo(ctx, refState.current);
3508
- }, 1e3);
3509
- }
3510
- if (onMomentumScrollEnd) {
3511
- onMomentumScrollEnd(event);
3512
- }
3513
- },
3710
+ onMomentumScrollEnd: fns.onMomentumScrollEnd,
3514
3711
  onScroll: onScrollHandler,
3515
3712
  recycleItems,
3516
3713
  refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControl, {
@@ -3525,7 +3722,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3525
3722
  ),
3526
3723
  refScrollView: combinedRef,
3527
3724
  scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3528
- scrollEventThrottle: Platform2.OS === "web" ? 16 : void 0,
3725
+ scrollEventThrottle: 0,
3529
3726
  snapToIndices,
3530
3727
  stickyHeaderIndices,
3531
3728
  style,