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