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

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