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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,30 +28,64 @@ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
28
28
  reactNative.Animated.View;
29
29
  var View = reactNative.View;
30
30
  var Text = reactNative.Text;
31
+
32
+ // src/state/getContentInsetEnd.ts
33
+ function getContentInsetEnd(state) {
34
+ var _a3;
35
+ const { props } = state;
36
+ const horizontal = props.horizontal;
37
+ let contentInset = props.contentInset;
38
+ if (!contentInset) {
39
+ const animatedInset = (_a3 = props.animatedProps) == null ? void 0 : _a3.contentInset;
40
+ if (animatedInset) {
41
+ if ("get" in animatedInset) {
42
+ contentInset = animatedInset.get();
43
+ } else {
44
+ contentInset = animatedInset;
45
+ }
46
+ }
47
+ }
48
+ return (horizontal ? contentInset == null ? void 0 : contentInset.right : contentInset == null ? void 0 : contentInset.bottom) || 0;
49
+ }
50
+
51
+ // src/state/getContentSize.ts
52
+ function getContentSize(ctx) {
53
+ var _a3;
54
+ const { values, state } = ctx;
55
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
56
+ const stylePaddingBottom = state.props.stylePaddingBottom || 0;
57
+ const headerSize = values.get("headerSize") || 0;
58
+ const footerSize = values.get("footerSize") || 0;
59
+ const contentInsetBottom = getContentInsetEnd(state);
60
+ const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
61
+ return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
62
+ }
31
63
  var createAnimatedValue = (value) => new reactNative.Animated.Value(value);
32
64
 
33
65
  // src/state/state.tsx
34
66
  var ContextState = React2__namespace.createContext(null);
67
+ var contextNum = 0;
35
68
  function StateProvider({ children }) {
36
69
  const [value] = React2__namespace.useState(() => ({
37
70
  animatedScrollY: createAnimatedValue(0),
38
71
  columnWrapperStyle: void 0,
39
- internalState: void 0,
72
+ contextNum: contextNum++,
40
73
  listeners: /* @__PURE__ */ new Map(),
41
74
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
42
75
  mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
43
76
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
44
77
  mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
45
78
  mapViewabilityValues: /* @__PURE__ */ new Map(),
79
+ positionListeners: /* @__PURE__ */ new Map(),
80
+ state: void 0,
46
81
  values: /* @__PURE__ */ new Map([
47
82
  ["alignItemsPaddingTop", 0],
48
83
  ["stylePaddingTop", 0],
49
84
  ["headerSize", 0],
50
85
  ["numContainers", 0],
51
- ["activeStickyIndex", void 0],
86
+ ["activeStickyIndex", -1],
52
87
  ["totalSize", 0],
53
- ["scrollAdjustPending", 0],
54
- ["scrollingTo", void 0]
88
+ ["scrollAdjustPending", 0]
55
89
  ]),
56
90
  viewRefs: /* @__PURE__ */ new Map()
57
91
  }));
@@ -119,15 +153,24 @@ function set$(ctx, signalName, value) {
119
153
  }
120
154
  }
121
155
  }
122
- function getContentSize(ctx) {
123
- var _a3, _b;
124
- const { values, internalState } = ctx;
125
- const stylePaddingTop = values.get("stylePaddingTop") || 0;
126
- const stylePaddingBottom = (internalState == null ? void 0 : internalState.props.stylePaddingBottom) || 0;
127
- const headerSize = values.get("headerSize") || 0;
128
- const footerSize = values.get("footerSize") || 0;
129
- const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
130
- return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom;
156
+ function listenPosition$(ctx, key, cb) {
157
+ const { positionListeners } = ctx;
158
+ let setListeners = positionListeners.get(key);
159
+ if (!setListeners) {
160
+ setListeners = /* @__PURE__ */ new Set();
161
+ positionListeners.set(key, setListeners);
162
+ }
163
+ setListeners.add(cb);
164
+ return () => setListeners.delete(cb);
165
+ }
166
+ function notifyPosition$(ctx, key, value) {
167
+ const { positionListeners } = ctx;
168
+ const setListeners = positionListeners.get(key);
169
+ if (setListeners) {
170
+ for (const listener of setListeners) {
171
+ listener(value);
172
+ }
173
+ }
131
174
  }
132
175
  function useArr$(signalNames) {
133
176
  const ctx = React2__namespace.useContext(ContextState);
@@ -208,7 +251,8 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
208
251
  // src/constants-platform.native.ts
209
252
  var IsNewArchitecture = global.nativeFabricUIManager != null;
210
253
  var useAnimatedValue = (initialValue) => {
211
- return React2.useRef(new reactNative.Animated.Value(initialValue)).current;
254
+ const [animAnimatedValue] = React2.useState(() => new reactNative.Animated.Value(initialValue));
255
+ return animAnimatedValue;
212
256
  };
213
257
 
214
258
  // src/utils/helpers.ts
@@ -297,7 +341,7 @@ var typedForwardRef = React2.forwardRef;
297
341
  var typedMemo = React2.memo;
298
342
 
299
343
  // src/components/PositionView.native.tsx
300
- var PositionViewState = typedMemo(function PositionView({
344
+ var PositionViewState = typedMemo(function PositionViewState2({
301
345
  id,
302
346
  horizontal,
303
347
  style,
@@ -317,7 +361,7 @@ var PositionViewState = typedMemo(function PositionView({
317
361
  }
318
362
  );
319
363
  });
320
- var PositionViewAnimated = typedMemo(function PositionView2({
364
+ var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
321
365
  id,
322
366
  horizontal,
323
367
  style,
@@ -360,21 +404,27 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
360
404
  const viewStyle = React2__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
361
405
  return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest });
362
406
  });
363
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
364
- var symbolFirst = Symbol();
407
+ var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
365
408
  function useInit(cb) {
366
- const refValue = React2.useRef(symbolFirst);
367
- if (refValue.current === symbolFirst) {
368
- refValue.current = cb();
369
- }
370
- return refValue.current;
409
+ React2.useState(() => cb());
371
410
  }
372
411
 
373
412
  // src/state/ContextContainer.ts
374
413
  var ContextContainer = React2.createContext(null);
414
+ function useContextContainer() {
415
+ return React2.useContext(ContextContainer);
416
+ }
375
417
  function useIsLastItem() {
376
- const { itemKey } = React2.useContext(ContextContainer);
377
- const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
418
+ const containerContext = useContextContainer();
419
+ const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
420
+ if (containerContext) {
421
+ const { itemKey } = containerContext;
422
+ if (!isNullOrUndefined(itemKey)) {
423
+ return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
424
+ }
425
+ }
426
+ return false;
427
+ });
378
428
  return isLast;
379
429
  }
380
430
 
@@ -534,6 +584,7 @@ var Container = typedMemo(function Container2({
534
584
  if (!IsNewArchitecture) {
535
585
  React2.useEffect(() => {
536
586
  if (!isNullOrUndefined(itemKey)) {
587
+ didLayoutRef.current = false;
537
588
  const timeout = setTimeout(() => {
538
589
  if (!didLayoutRef.current) {
539
590
  const {
@@ -553,7 +604,7 @@ var Container = typedMemo(function Container2({
553
604
  }
554
605
  }, [itemKey]);
555
606
  }
556
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
607
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView;
557
608
  return /* @__PURE__ */ React2__namespace.createElement(
558
609
  PositionComponent,
559
610
  {
@@ -588,10 +639,10 @@ var Containers = typedMemo(function Containers2({
588
639
  // If this is the initial scroll, we don't want to delay because we want to update the size immediately
589
640
  delay: (value, prevValue) => {
590
641
  var _a3;
591
- return !((_a3 = ctx.internalState) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
642
+ return !((_a3 = ctx.state) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
592
643
  }
593
644
  });
594
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
645
+ const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("readyToRender", { getValue: (value) => value ? 1 : 0 }) : void 0;
595
646
  const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
596
647
  const containers = [];
597
648
  for (let i = 0; i < numContainers; i++) {
@@ -634,7 +685,8 @@ var Containers = typedMemo(function Containers2({
634
685
  return /* @__PURE__ */ React2__namespace.createElement(reactNative.Animated.View, { style }, containers);
635
686
  });
636
687
  function DevNumbers() {
637
- return IS_DEV && React2__namespace.memo(function DevNumbers2() {
688
+ return IS_DEV && // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
689
+ React2__namespace.memo(function DevNumbers2() {
638
690
  return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2__namespace.createElement(
639
691
  reactNative.View,
640
692
  {
@@ -742,13 +794,6 @@ var ListComponent = typedMemo(function ListComponent2({
742
794
  () => React2__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
743
795
  [renderScrollComponent]
744
796
  ) : ListComponentScrollView;
745
- React2__namespace.useEffect(() => {
746
- if (canRender) {
747
- setTimeout(() => {
748
- scrollAdjustHandler.setMounted();
749
- }, 0);
750
- }
751
- }, [canRender]);
752
797
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
753
798
  return /* @__PURE__ */ React2__namespace.createElement(
754
799
  SnapOrScroll,
@@ -812,10 +857,11 @@ function getId(state, index) {
812
857
  }
813
858
 
814
859
  // src/core/calculateOffsetForIndex.ts
815
- function calculateOffsetForIndex(ctx, state, index) {
860
+ function calculateOffsetForIndex(ctx, index) {
861
+ const state = ctx.state;
816
862
  let position = 0;
817
863
  if (index !== void 0) {
818
- position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
864
+ position = state.positions.get(getId(state, index)) || 0;
819
865
  const paddingTop = peek$(ctx, "stylePaddingTop");
820
866
  if (paddingTop) {
821
867
  position += paddingTop;
@@ -829,7 +875,8 @@ function calculateOffsetForIndex(ctx, state, index) {
829
875
  }
830
876
 
831
877
  // src/utils/setPaddingTop.ts
832
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
878
+ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
879
+ const state = ctx.state;
833
880
  if (stylePaddingTop !== void 0) {
834
881
  const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
835
882
  if (stylePaddingTop < prevStylePaddingTop) {
@@ -848,7 +895,8 @@ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
848
895
  }
849
896
 
850
897
  // src/utils/updateAlignItemsPaddingTop.ts
851
- function updateAlignItemsPaddingTop(ctx, state) {
898
+ function updateAlignItemsPaddingTop(ctx) {
899
+ const state = ctx.state;
852
900
  const {
853
901
  scrollLength,
854
902
  props: { alignItemsAtEnd, data }
@@ -859,12 +907,13 @@ function updateAlignItemsPaddingTop(ctx, state) {
859
907
  const contentSize = getContentSize(ctx);
860
908
  alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
861
909
  }
862
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
910
+ setPaddingTop(ctx, { alignItemsPaddingTop });
863
911
  }
864
912
  }
865
913
 
866
914
  // src/core/addTotalSize.ts
867
- function addTotalSize(ctx, state, key, add) {
915
+ function addTotalSize(ctx, key, add) {
916
+ const state = ctx.state;
868
917
  const { alignItemsAtEnd } = state.props;
869
918
  const prevTotalSize = state.totalSize;
870
919
  let totalSize = state.totalSize;
@@ -885,31 +934,34 @@ function addTotalSize(ctx, state, key, add) {
885
934
  state.totalSize = totalSize;
886
935
  set$(ctx, "totalSize", totalSize);
887
936
  if (alignItemsAtEnd) {
888
- updateAlignItemsPaddingTop(ctx, state);
937
+ updateAlignItemsPaddingTop(ctx);
889
938
  }
890
939
  }
891
940
  }
892
941
  }
893
942
 
894
943
  // src/core/setSize.ts
895
- function setSize(ctx, state, itemKey, size) {
944
+ function setSize(ctx, itemKey, size) {
945
+ const state = ctx.state;
896
946
  const { sizes } = state;
897
947
  const previousSize = sizes.get(itemKey);
898
948
  const diff = previousSize !== void 0 ? size - previousSize : size;
899
949
  if (diff !== 0) {
900
- addTotalSize(ctx, state, itemKey, diff);
950
+ addTotalSize(ctx, itemKey, diff);
901
951
  }
902
952
  sizes.set(itemKey, size);
903
953
  }
904
954
 
905
955
  // src/utils/getItemSize.ts
906
- function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
956
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
907
957
  var _a3, _b;
958
+ const state = ctx.state;
908
959
  const {
909
960
  sizesKnown,
910
961
  sizes,
911
962
  averageSizes,
912
- props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
963
+ props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
964
+ scrollingTo
913
965
  } = state;
914
966
  const sizeKnown = sizesKnown.get(key);
915
967
  if (sizeKnown !== void 0) {
@@ -917,7 +969,6 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
917
969
  }
918
970
  let size;
919
971
  const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
920
- const scrollingTo = peek$(ctx, "scrollingTo");
921
972
  if (preferCachedSize) {
922
973
  const cachedSize = sizes.get(key);
923
974
  if (cachedSize !== void 0) {
@@ -945,84 +996,167 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
945
996
  if (size === void 0) {
946
997
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
947
998
  }
948
- setSize(ctx, state, key, size);
999
+ setSize(ctx, key, size);
949
1000
  return size;
950
1001
  }
951
1002
 
952
1003
  // src/core/calculateOffsetWithOffsetPosition.ts
953
- function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
1004
+ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1005
+ const state = ctx.state;
954
1006
  const { index, viewOffset, viewPosition } = params;
955
1007
  let offset = offsetParam;
956
1008
  if (viewOffset) {
957
1009
  offset -= viewOffset;
958
1010
  }
959
1011
  if (viewPosition !== void 0 && index !== void 0) {
960
- offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
1012
+ const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1013
+ const trailingInset = getContentInsetEnd(state);
1014
+ offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
961
1015
  }
962
1016
  return offset;
963
1017
  }
964
1018
 
1019
+ // src/core/clampScrollOffset.ts
1020
+ function clampScrollOffset(ctx, offset) {
1021
+ const state = ctx.state;
1022
+ const contentSize = getContentSize(ctx);
1023
+ let clampedOffset = offset;
1024
+ if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength)) {
1025
+ const maxOffset = Math.max(0, contentSize - state.scrollLength);
1026
+ clampedOffset = Math.min(offset, maxOffset);
1027
+ }
1028
+ clampedOffset = Math.max(0, clampedOffset);
1029
+ return clampedOffset;
1030
+ }
1031
+ var Platform2 = reactNative.Platform;
1032
+
1033
+ // src/utils/setInitialRenderState.ts
1034
+ function setInitialRenderState(ctx, {
1035
+ didLayout,
1036
+ didInitialScroll
1037
+ }) {
1038
+ const { state } = ctx;
1039
+ if (didLayout) {
1040
+ state.didContainersLayout = true;
1041
+ }
1042
+ if (didInitialScroll) {
1043
+ state.didFinishInitialScroll = true;
1044
+ }
1045
+ if (state.didContainersLayout && state.didFinishInitialScroll) {
1046
+ set$(ctx, "readyToRender", true);
1047
+ }
1048
+ }
1049
+
965
1050
  // src/core/finishScrollTo.ts
966
- function finishScrollTo(ctx, state) {
1051
+ function finishScrollTo(ctx) {
967
1052
  var _a3, _b;
968
- if (state) {
1053
+ const state = ctx.state;
1054
+ if (state == null ? void 0 : state.scrollingTo) {
969
1055
  state.scrollHistory.length = 0;
970
1056
  state.initialScroll = void 0;
971
1057
  state.initialAnchor = void 0;
972
- set$(ctx, "scrollingTo", void 0);
1058
+ state.scrollingTo = void 0;
973
1059
  if (state.pendingTotalSize !== void 0) {
974
- addTotalSize(ctx, state, null, state.pendingTotalSize);
1060
+ addTotalSize(ctx, null, state.pendingTotalSize);
975
1061
  }
976
1062
  if ((_a3 = state.props) == null ? void 0 : _a3.data) {
977
1063
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
978
1064
  }
1065
+ if (Platform2.OS === "web") {
1066
+ state.scrollAdjustHandler.commitPendingAdjust();
1067
+ }
1068
+ setInitialRenderState(ctx, { didInitialScroll: true });
979
1069
  }
980
1070
  }
981
- var Platform2 = reactNative.Platform;
982
1071
 
983
- // src/core/scrollTo.ts
984
- function scrollTo(ctx, state, params) {
1072
+ // src/core/checkFinishedScroll.ts
1073
+ function checkFinishedScroll(ctx) {
1074
+ ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
1075
+ }
1076
+ function checkFinishedScrollFrame(ctx) {
1077
+ const scrollingTo = ctx.state.scrollingTo;
1078
+ if (scrollingTo) {
1079
+ const { state } = ctx;
1080
+ state.animFrameCheckFinishedScroll = void 0;
1081
+ const scroll = state.scroll;
1082
+ const adjust = state.scrollAdjustHandler.getAdjust();
1083
+ const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1084
+ const maxOffset = clampScrollOffset(ctx, scroll);
1085
+ const diff1 = Math.abs(scroll - clampedTargetOffset);
1086
+ const diff2 = Math.abs(diff1 - adjust);
1087
+ const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
1088
+ if (isNotOverscrolled && (diff1 < 1 || diff2 < 1)) {
1089
+ finishScrollTo(ctx);
1090
+ }
1091
+ }
1092
+ }
1093
+ function checkFinishedScrollFallback(ctx) {
1094
+ const state = ctx.state;
1095
+ const scrollingTo = state.scrollingTo;
1096
+ const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
1097
+ state.timeoutCheckFinishedScrollFallback = setTimeout(
1098
+ () => {
1099
+ let numChecks = 0;
1100
+ const checkHasScrolled = () => {
1101
+ state.timeoutCheckFinishedScrollFallback = void 0;
1102
+ const isStillScrollingTo = state.scrollingTo;
1103
+ if (isStillScrollingTo) {
1104
+ numChecks++;
1105
+ if (state.hasScrolled || numChecks > 5) {
1106
+ finishScrollTo(ctx);
1107
+ } else {
1108
+ state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
1109
+ }
1110
+ }
1111
+ };
1112
+ checkHasScrolled();
1113
+ },
1114
+ slowTimeout ? 500 : 100
1115
+ );
1116
+ }
1117
+
1118
+ // src/core/doScrollTo.native.ts
1119
+ function doScrollTo(ctx, params) {
985
1120
  var _a3;
986
- const { noScrollingTo, ...scrollTarget } = params;
1121
+ const state = ctx.state;
1122
+ const { animated, horizontal, offset } = params;
1123
+ const { refScroller } = state;
1124
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1125
+ animated: !!animated,
1126
+ x: horizontal ? offset : 0,
1127
+ y: horizontal ? 0 : offset
1128
+ });
1129
+ if (!animated) {
1130
+ state.scroll = offset;
1131
+ checkFinishedScrollFallback(ctx);
1132
+ }
1133
+ }
1134
+
1135
+ // src/core/scrollTo.ts
1136
+ function scrollTo(ctx, params) {
1137
+ const state = ctx.state;
1138
+ const { noScrollingTo, forceScroll, ...scrollTarget } = params;
987
1139
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
988
1140
  const {
989
- refScroller,
990
1141
  props: { horizontal }
991
1142
  } = state;
992
- let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
993
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
994
- const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
995
- offset = Math.min(offset, maxOffset);
1143
+ if (state.animFrameCheckFinishedScroll) {
1144
+ cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
1145
+ }
1146
+ if (state.timeoutCheckFinishedScrollFallback) {
1147
+ clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
996
1148
  }
1149
+ let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
1150
+ offset = clampScrollOffset(ctx, offset);
997
1151
  state.scrollHistory.length = 0;
998
1152
  if (!noScrollingTo) {
999
- set$(ctx, "scrollingTo", scrollTarget);
1153
+ state.scrollingTo = scrollTarget;
1000
1154
  }
1001
1155
  state.scrollPending = offset;
1002
- if (!isInitialScroll || Platform2.OS === "android") {
1003
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1004
- animated: !!animated,
1005
- x: horizontal ? offset : 0,
1006
- y: horizontal ? 0 : offset
1007
- });
1008
- }
1009
- if (!animated) {
1156
+ if (forceScroll || !isInitialScroll || Platform2.OS === "android") {
1157
+ doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
1158
+ } else {
1010
1159
  state.scroll = offset;
1011
- if (Platform2.OS === "web") {
1012
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
1013
- if (value && peek$(ctx, "scrollingTo")) {
1014
- finishScrollTo(ctx, state);
1015
- unlisten();
1016
- }
1017
- });
1018
- } else {
1019
- setTimeout(() => finishScrollTo(ctx, state), 100);
1020
- }
1021
- if (isInitialScroll) {
1022
- setTimeout(() => {
1023
- state.initialScroll = void 0;
1024
- }, 500);
1025
- }
1026
1160
  }
1027
1161
  }
1028
1162
 
@@ -1031,6 +1165,12 @@ var HYSTERESIS_MULTIPLIER = 1.3;
1031
1165
  var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1032
1166
  const absDistance = Math.abs(distance);
1033
1167
  const within = atThreshold || threshold > 0 && absDistance <= threshold;
1168
+ if (wasReached === null) {
1169
+ if (!within && distance >= 0) {
1170
+ return false;
1171
+ }
1172
+ return null;
1173
+ }
1034
1174
  const updateSnapshot = () => {
1035
1175
  setSnapshot == null ? void 0 : setSnapshot({
1036
1176
  atThreshold,
@@ -1063,8 +1203,9 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
1063
1203
  };
1064
1204
 
1065
1205
  // src/utils/checkAtBottom.ts
1066
- function checkAtBottom(ctx, state) {
1206
+ function checkAtBottom(ctx) {
1067
1207
  var _a3;
1208
+ const state = ctx.state;
1068
1209
  if (!state) {
1069
1210
  return;
1070
1211
  }
@@ -1137,15 +1278,15 @@ function checkAtTop(state) {
1137
1278
  }
1138
1279
 
1139
1280
  // src/core/updateScroll.ts
1140
- function updateScroll(ctx, state, newScroll, forceUpdate) {
1281
+ function updateScroll(ctx, newScroll, forceUpdate) {
1141
1282
  var _a3;
1142
- const scrollingTo = peek$(ctx, "scrollingTo");
1283
+ const state = ctx.state;
1284
+ const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
1143
1285
  state.hasScrolled = true;
1144
1286
  state.lastBatchingAction = Date.now();
1145
1287
  const currentTime = Date.now();
1146
- const adjust = state.scrollAdjustHandler.getAdjust();
1147
- const lastHistoryAdjust = state.lastScrollAdjustForHistory;
1148
- const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
1288
+ const adjust = scrollAdjustHandler.getAdjust();
1289
+ const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1149
1290
  if (adjustChanged) {
1150
1291
  state.scrollHistory.length = 0;
1151
1292
  }
@@ -1170,22 +1311,26 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1170
1311
  return;
1171
1312
  }
1172
1313
  }
1173
- if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1314
+ const lastCalculated = state.scrollLastCalculate;
1315
+ const shouldUpdate = forceUpdate || state.dataChangeNeedsScrollUpdate || state.scrollLastCalculate === void 0 || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
1316
+ if (shouldUpdate) {
1317
+ state.scrollLastCalculate = state.scroll;
1174
1318
  state.ignoreScrollFromMVCPIgnored = false;
1175
1319
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1176
- checkAtBottom(ctx, state);
1320
+ checkAtBottom(ctx);
1177
1321
  checkAtTop(state);
1178
1322
  state.dataChangeNeedsScrollUpdate = false;
1179
1323
  }
1180
1324
  }
1181
1325
 
1182
1326
  // src/utils/requestAdjust.ts
1183
- function requestAdjust(ctx, state, positionDiff, dataChanged) {
1327
+ function requestAdjust(ctx, positionDiff, dataChanged) {
1328
+ const state = ctx.state;
1184
1329
  if (Math.abs(positionDiff) > 0.1) {
1185
1330
  const needsScrollWorkaround = Platform2.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
1186
1331
  const doit = () => {
1187
1332
  if (needsScrollWorkaround) {
1188
- scrollTo(ctx, state, {
1333
+ scrollTo(ctx, {
1189
1334
  noScrollingTo: true,
1190
1335
  offset: state.scroll
1191
1336
  });
@@ -1198,8 +1343,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1198
1343
  };
1199
1344
  state.scroll += positionDiff;
1200
1345
  state.scrollForNextCalculateItemsInView = void 0;
1201
- const didLayout = peek$(ctx, "containersDidLayout");
1202
- if (didLayout) {
1346
+ const readyToRender = peek$(ctx, "readyToRender");
1347
+ if (readyToRender) {
1203
1348
  doit();
1204
1349
  if (Platform2.OS !== "web") {
1205
1350
  const threshold = state.scroll - positionDiff / 2;
@@ -1221,7 +1366,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1221
1366
  if (shouldForceUpdate) {
1222
1367
  state.ignoreScrollFromMVCPIgnored = false;
1223
1368
  state.scrollPending = state.scroll;
1224
- updateScroll(ctx, state, state.scroll, true);
1369
+ updateScroll(ctx, state.scroll, true);
1225
1370
  }
1226
1371
  }, delay);
1227
1372
  }
@@ -1236,28 +1381,27 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1236
1381
  var INITIAL_ANCHOR_TOLERANCE = 0.5;
1237
1382
  var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
1238
1383
  var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1239
- function ensureInitialAnchor(ctx, state) {
1384
+ function ensureInitialAnchor(ctx) {
1240
1385
  var _a3, _b, _c, _d, _e;
1241
- const anchor = state.initialAnchor;
1386
+ const state = ctx.state;
1387
+ const { initialAnchor, didContainersLayout, positions, scroll, scrollLength } = state;
1388
+ const anchor = initialAnchor;
1242
1389
  const item = state.props.data[anchor.index];
1243
- const containersDidLayout = peek$(ctx, "containersDidLayout");
1244
- if (!containersDidLayout) {
1390
+ if (!didContainersLayout) {
1245
1391
  return;
1246
1392
  }
1247
1393
  const id = getId(state, anchor.index);
1248
- if (state.positions.get(id) === void 0) {
1394
+ if (positions.get(id) === void 0) {
1249
1395
  return;
1250
1396
  }
1251
- const size = getItemSize(ctx, state, id, anchor.index, item, true, true);
1397
+ const size = getItemSize(ctx, id, anchor.index, item, true, true);
1252
1398
  if (size === void 0) {
1253
1399
  return;
1254
1400
  }
1255
- const availableSpace = Math.max(0, state.scrollLength - size);
1256
- const desiredOffset = calculateOffsetForIndex(ctx, state, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1257
- const contentSize = getContentSize(ctx);
1258
- const maxOffset = Math.max(0, contentSize - state.scrollLength);
1259
- const clampedDesiredOffset = Math.max(0, Math.min(desiredOffset, maxOffset));
1260
- const delta = clampedDesiredOffset - state.scroll;
1401
+ const availableSpace = Math.max(0, scrollLength - size);
1402
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1403
+ const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset);
1404
+ const delta = clampedDesiredOffset - scroll;
1261
1405
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1262
1406
  const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
1263
1407
  if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
@@ -1281,18 +1425,21 @@ function ensureInitialAnchor(ctx, state) {
1281
1425
  lastDelta: delta,
1282
1426
  settledTicks: 0
1283
1427
  });
1284
- requestAdjust(ctx, state, delta);
1428
+ requestAdjust(ctx, delta);
1429
+ requestAnimationFrame(() => finishScrollTo(ctx));
1285
1430
  }
1286
1431
 
1287
1432
  // src/core/mvcp.ts
1288
- function prepareMVCP(ctx, state, dataChanged) {
1433
+ function prepareMVCP(ctx, dataChanged) {
1434
+ const state = ctx.state;
1289
1435
  const { idsInView, positions, props } = state;
1290
1436
  const { maintainVisibleContentPosition } = props;
1291
- const scrollingTo = peek$(ctx, "scrollingTo");
1437
+ const scrollingTo = state.scrollingTo;
1292
1438
  let prevPosition;
1293
1439
  let targetId;
1294
1440
  const idsInViewWithPositions = [];
1295
1441
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1442
+ const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1296
1443
  const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1297
1444
  const indexByKey = state.indexByKey;
1298
1445
  if (shouldMVCP) {
@@ -1301,7 +1448,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1301
1448
  return void 0;
1302
1449
  }
1303
1450
  targetId = getId(state, scrollTarget);
1304
- } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
1451
+ } else if (idsInView.length > 0 && state.didContainersLayout) {
1305
1452
  if (dataChanged) {
1306
1453
  for (let i = 0; i < idsInView.length; i++) {
1307
1454
  const id = idsInView[i];
@@ -1318,7 +1465,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1318
1465
  prevPosition = positions.get(targetId);
1319
1466
  }
1320
1467
  return () => {
1321
- let positionDiff;
1468
+ let positionDiff = 0;
1322
1469
  if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1323
1470
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1324
1471
  const { id, position } = idsInViewWithPositions[i];
@@ -1344,16 +1491,28 @@ function prepareMVCP(ctx, state, dataChanged) {
1344
1491
  positionDiff = diff;
1345
1492
  }
1346
1493
  }
1347
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1348
- requestAdjust(ctx, state, positionDiff, dataChanged && maintainVisibleContentPosition);
1494
+ if (scrollingToViewPosition && scrollingToViewPosition > 0) {
1495
+ const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
1496
+ const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
1497
+ if (newSize !== void 0 && prevSize !== void 0 && newSize !== (scrollingTo == null ? void 0 : scrollingTo.itemSize)) {
1498
+ const diff = newSize - prevSize;
1499
+ if (diff !== 0) {
1500
+ positionDiff += (newSize - prevSize) * scrollingToViewPosition;
1501
+ scrollingTo.itemSize = newSize;
1502
+ }
1503
+ }
1504
+ }
1505
+ if (Math.abs(positionDiff) > 0.1) {
1506
+ requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1349
1507
  }
1350
1508
  };
1351
1509
  }
1352
1510
  }
1353
1511
 
1354
1512
  // src/core/prepareColumnStartState.ts
1355
- function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1513
+ function prepareColumnStartState(ctx, startIndex, useAverageSize) {
1356
1514
  var _a3;
1515
+ const state = ctx.state;
1357
1516
  const numColumns = peek$(ctx, "numColumns");
1358
1517
  let rowStartIndex = startIndex;
1359
1518
  const columnAtStart = state.columns.get(state.idCache[startIndex]);
@@ -1368,7 +1527,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1368
1527
  const prevId = state.idCache[prevIndex];
1369
1528
  const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1370
1529
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1371
- const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
1530
+ const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
1372
1531
  currentRowTop = prevPosition + prevRowHeight;
1373
1532
  }
1374
1533
  return {
@@ -1391,7 +1550,8 @@ function findRowStartIndex(state, numColumns, index) {
1391
1550
  }
1392
1551
  return rowStart;
1393
1552
  }
1394
- function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1553
+ function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
1554
+ const state = ctx.state;
1395
1555
  if (endIndex < startIndex) {
1396
1556
  return 0;
1397
1557
  }
@@ -1405,7 +1565,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1405
1565
  continue;
1406
1566
  }
1407
1567
  const id = state.idCache[i];
1408
- const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
1568
+ const size = getItemSize(ctx, id, i, data[i], useAverageSize);
1409
1569
  if (size > maxSize) {
1410
1570
  maxSize = size;
1411
1571
  }
@@ -1414,22 +1574,23 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1414
1574
  }
1415
1575
 
1416
1576
  // src/core/updateTotalSize.ts
1417
- function updateTotalSize(ctx, state) {
1577
+ function updateTotalSize(ctx) {
1578
+ const state = ctx.state;
1418
1579
  const {
1419
1580
  positions,
1420
1581
  props: { data }
1421
1582
  } = state;
1422
1583
  if (data.length === 0) {
1423
- addTotalSize(ctx, state, null, 0);
1584
+ addTotalSize(ctx, null, 0);
1424
1585
  } else {
1425
1586
  const lastId = getId(state, data.length - 1);
1426
1587
  if (lastId !== void 0) {
1427
1588
  const lastPosition = positions.get(lastId);
1428
1589
  if (lastPosition !== void 0) {
1429
- const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
1590
+ const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
1430
1591
  if (lastSize !== void 0) {
1431
1592
  const totalSize = lastPosition + lastSize;
1432
- addTotalSize(ctx, state, null, totalSize);
1593
+ addTotalSize(ctx, null, totalSize);
1433
1594
  }
1434
1595
  }
1435
1596
  }
@@ -1475,7 +1636,8 @@ var getScrollVelocity = (state) => {
1475
1636
  };
1476
1637
 
1477
1638
  // src/utils/updateSnapToOffsets.ts
1478
- function updateSnapToOffsets(ctx, state) {
1639
+ function updateSnapToOffsets(ctx) {
1640
+ const state = ctx.state;
1479
1641
  const {
1480
1642
  positions,
1481
1643
  props: { snapToIndices }
@@ -1490,30 +1652,30 @@ function updateSnapToOffsets(ctx, state) {
1490
1652
  }
1491
1653
 
1492
1654
  // src/core/updateItemPositions.ts
1493
- function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1655
+ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1494
1656
  doMVCP: false,
1495
1657
  forceFullUpdate: false,
1496
1658
  scrollBottomBuffered: -1,
1497
1659
  startIndex: 0
1498
1660
  }) {
1499
1661
  var _a3, _b, _c, _d, _e;
1662
+ const state = ctx.state;
1500
1663
  const {
1501
1664
  columns,
1502
1665
  indexByKey,
1503
1666
  positions,
1504
1667
  idCache,
1505
1668
  sizesKnown,
1506
- props: { getEstimatedItemSize, snapToIndices, enableAverages }
1669
+ props: { data, getEstimatedItemSize, snapToIndices },
1670
+ scrollingTo
1507
1671
  } = state;
1508
- const data = state.props.data;
1509
1672
  const dataLength = data.length;
1510
1673
  const numColumns = peek$(ctx, "numColumns");
1511
- const scrollingTo = peek$(ctx, "scrollingTo");
1512
1674
  const hasColumns = numColumns > 1;
1513
1675
  const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1514
1676
  const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
1515
1677
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1516
- const useAverageSize = enableAverages && !getEstimatedItemSize;
1678
+ const useAverageSize = !getEstimatedItemSize;
1517
1679
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1518
1680
  let currentRowTop = 0;
1519
1681
  let column = 1;
@@ -1522,7 +1684,6 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1522
1684
  if (hasColumns) {
1523
1685
  const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1524
1686
  ctx,
1525
- state,
1526
1687
  startIndex,
1527
1688
  useAverageSize
1528
1689
  );
@@ -1532,7 +1693,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1532
1693
  const prevIndex = startIndex - 1;
1533
1694
  const prevId = getId(state, prevIndex);
1534
1695
  const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1535
- const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1696
+ const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1536
1697
  currentRowTop = prevPosition + prevSize;
1537
1698
  }
1538
1699
  }
@@ -1549,7 +1710,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1549
1710
  breakAt = i + itemsPerRow + 10;
1550
1711
  }
1551
1712
  const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1552
- const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
1713
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
1553
1714
  if (IS_DEV && needsIndexByKey) {
1554
1715
  if (indexByKeyForChecking.has(id)) {
1555
1716
  console.error(
@@ -1558,7 +1719,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1558
1719
  }
1559
1720
  indexByKeyForChecking.set(id, i);
1560
1721
  }
1561
- positions.set(id, currentRowTop);
1722
+ if (currentRowTop !== positions.get(id)) {
1723
+ positions.set(id, currentRowTop);
1724
+ notifyPosition$(ctx, id, currentRowTop);
1725
+ }
1562
1726
  if (needsIndexByKey) {
1563
1727
  indexByKey.set(id, i);
1564
1728
  }
@@ -1578,10 +1742,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1578
1742
  }
1579
1743
  }
1580
1744
  if (!didBreakEarly) {
1581
- updateTotalSize(ctx, state);
1745
+ updateTotalSize(ctx);
1582
1746
  }
1583
1747
  if (snapToIndices) {
1584
- updateSnapToOffsets(ctx, state);
1748
+ updateSnapToOffsets(ctx);
1585
1749
  }
1586
1750
  }
1587
1751
 
@@ -1659,7 +1823,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1659
1823
  if (previousViewableItems) {
1660
1824
  for (const viewToken of previousViewableItems) {
1661
1825
  const containerId = findContainerId(ctx, viewToken.key);
1662
- if (!isViewable(
1826
+ if (!checkIsViewable(
1663
1827
  state,
1664
1828
  ctx,
1665
1829
  viewabilityConfig,
@@ -1680,7 +1844,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1680
1844
  if (item) {
1681
1845
  const key = getId(state, i);
1682
1846
  const containerId = findContainerId(ctx, key);
1683
- if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1847
+ if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1684
1848
  const viewToken = {
1685
1849
  containerId,
1686
1850
  index: i,
@@ -1740,11 +1904,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1740
1904
  const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
1741
1905
  const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
1742
1906
  const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1743
- const isViewable2 = percent >= viewablePercentThreshold;
1907
+ const isViewable = percent >= viewablePercentThreshold;
1744
1908
  const value = {
1745
1909
  containerId,
1746
1910
  index,
1747
- isViewable: isViewable2,
1911
+ isViewable,
1748
1912
  item,
1749
1913
  key,
1750
1914
  percentOfScroller,
@@ -1763,8 +1927,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1763
1927
  }
1764
1928
  return value;
1765
1929
  }
1766
- function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1767
- const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1930
+ function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1931
+ let value = ctx.mapViewabilityAmountValues.get(containerId);
1932
+ if (!value || value.key !== key) {
1933
+ value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1934
+ }
1768
1935
  return value.isViewable;
1769
1936
  }
1770
1937
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
@@ -1792,8 +1959,9 @@ function checkAllSizesKnown(state) {
1792
1959
  }
1793
1960
 
1794
1961
  // src/utils/findAvailableContainers.ts
1795
- function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1962
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1796
1963
  const numContainers = peek$(ctx, "numContainers");
1964
+ const state = ctx.state;
1797
1965
  const { stickyContainerPool, containerItemTypes } = state;
1798
1966
  const result = [];
1799
1967
  const availableContainers = [];
@@ -1837,14 +2005,14 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1837
2005
  continue;
1838
2006
  }
1839
2007
  const key = peek$(ctx, `containerItemKey${u}`);
1840
- let isOk = key === void 0;
1841
- if (!isOk && pendingRemovalSet.has(u)) {
1842
- pendingRemovalSet.delete(u);
1843
- pendingRemovalChanged = true;
1844
- const requiredType = neededTypes[typeIndex];
1845
- isOk = canReuseContainer(u, requiredType);
1846
- }
1847
- if (isOk) {
2008
+ const requiredType = neededTypes[typeIndex];
2009
+ const isPending = key !== void 0 && pendingRemovalSet.has(u);
2010
+ const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
2011
+ if (canUse) {
2012
+ if (isPending) {
2013
+ pendingRemovalSet.delete(u);
2014
+ pendingRemovalChanged = true;
2015
+ }
1848
2016
  result.push(u);
1849
2017
  if (requiredItemTypes) {
1850
2018
  typeIndex++;
@@ -1913,21 +2081,26 @@ function comparatorByDistance(a, b) {
1913
2081
  }
1914
2082
 
1915
2083
  // src/core/scrollToIndex.ts
1916
- function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1917
- if (index >= state.props.data.length) {
1918
- index = state.props.data.length - 1;
2084
+ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
2085
+ const state = ctx.state;
2086
+ const { data } = state.props;
2087
+ if (index >= data.length) {
2088
+ index = data.length - 1;
1919
2089
  } else if (index < 0) {
1920
2090
  index = 0;
1921
2091
  }
1922
- const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
1923
- const isLast = index === state.props.data.length - 1;
2092
+ const firstIndexOffset = calculateOffsetForIndex(ctx, index);
2093
+ const isLast = index === data.length - 1;
1924
2094
  if (isLast && viewPosition === void 0) {
1925
2095
  viewPosition = 1;
1926
2096
  }
1927
2097
  state.scrollForNextCalculateItemsInView = void 0;
1928
- scrollTo(ctx, state, {
2098
+ const targetId = getId(state, index);
2099
+ const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
2100
+ scrollTo(ctx, {
1929
2101
  animated,
1930
2102
  index,
2103
+ itemSize,
1931
2104
  offset: firstIndexOffset,
1932
2105
  viewOffset,
1933
2106
  viewPosition: viewPosition != null ? viewPosition : 0
@@ -1935,29 +2108,30 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1935
2108
  }
1936
2109
 
1937
2110
  // src/utils/setDidLayout.ts
1938
- function setDidLayout(ctx, state) {
2111
+ function setDidLayout(ctx) {
2112
+ const state = ctx.state;
1939
2113
  const {
1940
2114
  loadStartTime,
1941
2115
  initialScroll,
1942
2116
  props: { onLoad }
1943
2117
  } = state;
1944
2118
  state.queuedInitialLayout = true;
1945
- checkAtBottom(ctx, state);
2119
+ checkAtBottom(ctx);
1946
2120
  const setIt = () => {
1947
- set$(ctx, "containersDidLayout", true);
2121
+ setInitialRenderState(ctx, { didLayout: true });
1948
2122
  if (onLoad) {
1949
2123
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1950
2124
  }
1951
2125
  };
1952
2126
  if (Platform2.OS === "android" && initialScroll) {
1953
2127
  if (IsNewArchitecture) {
1954
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2128
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1955
2129
  requestAnimationFrame(() => {
1956
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2130
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1957
2131
  setIt();
1958
2132
  });
1959
2133
  } else {
1960
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2134
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1961
2135
  setIt();
1962
2136
  }
1963
2137
  } else {
@@ -1980,15 +2154,17 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
1980
2154
  }
1981
2155
  return -1;
1982
2156
  }
1983
- function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
2157
+ function getActiveStickyIndices(ctx, stickyHeaderIndices) {
2158
+ const state = ctx.state;
1984
2159
  return new Set(
1985
2160
  Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyHeaderIndices.has(idx))
1986
2161
  );
1987
2162
  }
1988
- function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2163
+ function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
1989
2164
  var _a3;
1990
- const activeIndices = getActiveStickyIndices(ctx, state, stickyHeaderIndices);
1991
- state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
2165
+ const state = ctx.state;
2166
+ const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
2167
+ set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
1992
2168
  for (let offset = 0; offset <= 1; offset++) {
1993
2169
  const idx = currentStickyIdx - offset;
1994
2170
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
@@ -1999,8 +2175,9 @@ function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, cu
1999
2175
  }
2000
2176
  }
2001
2177
  }
2002
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2178
+ function handleStickyRecycling(ctx, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2003
2179
  var _a3, _b, _c;
2180
+ const state = ctx.state;
2004
2181
  for (const containerIndex of state.stickyContainerPool) {
2005
2182
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
2006
2183
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
@@ -2024,7 +2201,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2024
2201
  const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2025
2202
  if (currentId) {
2026
2203
  const currentPos = state.positions.get(currentId);
2027
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
2204
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2028
2205
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
2029
2206
  }
2030
2207
  }
@@ -2033,7 +2210,8 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2033
2210
  }
2034
2211
  }
2035
2212
  }
2036
- function calculateItemsInView(ctx, state, params = {}) {
2213
+ function calculateItemsInView(ctx, params = {}) {
2214
+ const state = ctx.state;
2037
2215
  reactNative.unstable_batchedUpdates(() => {
2038
2216
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2039
2217
  const {
@@ -2057,8 +2235,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2057
2235
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2058
2236
  const prevNumContainers = peek$(ctx, "numContainers");
2059
2237
  if (!data || scrollLength === 0 || !prevNumContainers) {
2060
- if (state.initialAnchor) {
2061
- ensureInitialAnchor(ctx, state);
2238
+ if (!IsNewArchitecture && state.initialAnchor) {
2239
+ ensureInitialAnchor(ctx);
2062
2240
  }
2063
2241
  return;
2064
2242
  }
@@ -2073,15 +2251,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2073
2251
  if (!queuedInitialLayout && initialScroll) {
2074
2252
  const updatedOffset = calculateOffsetWithOffsetPosition(
2075
2253
  ctx,
2076
- state,
2077
- calculateOffsetForIndex(ctx, state, initialScroll.index),
2254
+ calculateOffsetForIndex(ctx, initialScroll.index),
2078
2255
  initialScroll
2079
2256
  );
2080
2257
  scrollState = updatedOffset;
2081
2258
  }
2082
2259
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2083
2260
  const scrollAdjustPad = scrollAdjustPending - topPad;
2084
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2261
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2085
2262
  if (scroll + scrollLength > totalSize) {
2086
2263
  scroll = Math.max(0, totalSize - scrollLength);
2087
2264
  }
@@ -2089,11 +2266,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2089
2266
  set$(ctx, "debugRawScroll", scrollState);
2090
2267
  set$(ctx, "debugComputedScroll", scroll);
2091
2268
  }
2092
- const previousStickyIndex = state.activeStickyIndex;
2269
+ const previousStickyIndex = peek$(ctx, "activeStickyIndex");
2093
2270
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
2094
- const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
2095
- state.activeStickyIndex = nextActiveStickyIndex;
2096
- set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2271
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
2272
+ if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
2273
+ set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2274
+ }
2097
2275
  let scrollBufferTop = scrollBuffer;
2098
2276
  let scrollBufferBottom = scrollBuffer;
2099
2277
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2106,23 +2284,23 @@ function calculateItemsInView(ctx, state, params = {}) {
2106
2284
  const scrollTopBuffered = scroll - scrollBufferTop;
2107
2285
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2108
2286
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2109
- if (!dataChanged && scrollForNextCalculateItemsInView) {
2287
+ if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
2110
2288
  const { top, bottom } = scrollForNextCalculateItemsInView;
2111
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2112
- if (state.initialAnchor) {
2113
- ensureInitialAnchor(ctx, state);
2289
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2290
+ if (!IsNewArchitecture && state.initialAnchor) {
2291
+ ensureInitialAnchor(ctx);
2114
2292
  }
2115
2293
  return;
2116
2294
  }
2117
2295
  }
2118
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2296
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
2119
2297
  if (dataChanged) {
2120
2298
  indexByKey.clear();
2121
2299
  idCache.length = 0;
2122
2300
  positions.clear();
2123
2301
  }
2124
- const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2125
- updateItemPositions(ctx, state, dataChanged, {
2302
+ const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2303
+ updateItemPositions(ctx, dataChanged, {
2126
2304
  doMVCP,
2127
2305
  forceFullUpdate: !!forceFullItemPositions,
2128
2306
  scrollBottomBuffered,
@@ -2141,9 +2319,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2141
2319
  for (let i = loopStart; i >= 0; i--) {
2142
2320
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2143
2321
  const top = positions.get(id);
2144
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2322
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
2145
2323
  const bottom = top + size;
2146
- if (bottom > scroll - scrollBuffer) {
2324
+ if (bottom > scroll - scrollBufferTop) {
2147
2325
  loopStart = i;
2148
2326
  } else {
2149
2327
  break;
@@ -2168,7 +2346,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2168
2346
  const dataLength = data.length;
2169
2347
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2170
2348
  const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2171
- const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
2349
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
2172
2350
  const top = positions.get(id);
2173
2351
  if (!foundEnd) {
2174
2352
  if (startNoBuffer === null && top + size > scroll) {
@@ -2180,7 +2358,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2180
2358
  if (startBuffered === null && top + size > scrollTopBuffered) {
2181
2359
  startBuffered = i;
2182
2360
  startBufferedId = id;
2183
- nextTop = top;
2361
+ if (scrollTopBuffered < 0) {
2362
+ nextTop = null;
2363
+ } else {
2364
+ nextTop = top;
2365
+ }
2184
2366
  }
2185
2367
  if (startNoBuffer !== null) {
2186
2368
  if (top <= scrollBottom) {
@@ -2188,7 +2370,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2188
2370
  }
2189
2371
  if (top <= scrollBottomBuffered) {
2190
2372
  endBuffered = i;
2191
- nextBottom = top + size;
2373
+ if (scrollBottomBuffered > totalSize) {
2374
+ nextBottom = null;
2375
+ } else {
2376
+ nextBottom = top + size;
2377
+ }
2192
2378
  } else {
2193
2379
  foundEnd = true;
2194
2380
  }
@@ -2215,7 +2401,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2215
2401
  top: nextTop
2216
2402
  } : void 0;
2217
2403
  }
2218
- const numContainers = peek$(ctx, "numContainers");
2404
+ let numContainers = prevNumContainers;
2219
2405
  const pendingRemoval = [];
2220
2406
  if (dataChanged) {
2221
2407
  for (let i = 0; i < numContainers; i++) {
@@ -2226,7 +2412,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2226
2412
  }
2227
2413
  }
2228
2414
  if (startBuffered !== null && endBuffered !== null) {
2229
- let numContainers2 = prevNumContainers;
2230
2415
  const needNewContainers = [];
2231
2416
  for (let i = startBuffered; i <= endBuffered; i++) {
2232
2417
  const id = (_h = idCache[i]) != null ? _h : getId(state, i);
@@ -2237,7 +2422,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2237
2422
  if (stickyIndicesArr.length > 0) {
2238
2423
  handleStickyActivation(
2239
2424
  ctx,
2240
- state,
2241
2425
  stickyIndicesSet,
2242
2426
  stickyIndicesArr,
2243
2427
  currentStickyIdx,
@@ -2245,9 +2429,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2245
2429
  startBuffered,
2246
2430
  endBuffered
2247
2431
  );
2248
- } else {
2249
- state.activeStickyIndex = void 0;
2250
- set$(ctx, "activeStickyIndex", void 0);
2432
+ } else if (previousStickyIndex !== -1) {
2433
+ set$(ctx, "activeStickyIndex", -1);
2251
2434
  }
2252
2435
  if (needNewContainers.length > 0) {
2253
2436
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2256,7 +2439,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2256
2439
  }) : void 0;
2257
2440
  const availableContainers = findAvailableContainers(
2258
2441
  ctx,
2259
- state,
2260
2442
  needNewContainers.length,
2261
2443
  startBuffered,
2262
2444
  endBuffered,
@@ -2278,29 +2460,30 @@ function calculateItemsInView(ctx, state, params = {}) {
2278
2460
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
2279
2461
  }
2280
2462
  containerItemKeys.add(id);
2463
+ const containerSticky = `containerSticky${containerIndex}`;
2281
2464
  if (stickyIndicesSet.has(i)) {
2282
- set$(ctx, `containerSticky${containerIndex}`, true);
2465
+ set$(ctx, containerSticky, true);
2283
2466
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2284
2467
  set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2285
2468
  state.stickyContainerPool.add(containerIndex);
2286
- } else {
2287
- set$(ctx, `containerSticky${containerIndex}`, false);
2469
+ } else if (peek$(ctx, containerSticky)) {
2470
+ set$(ctx, containerSticky, false);
2288
2471
  state.stickyContainerPool.delete(containerIndex);
2289
2472
  }
2290
- if (containerIndex >= numContainers2) {
2291
- numContainers2 = containerIndex + 1;
2473
+ if (containerIndex >= numContainers) {
2474
+ numContainers = containerIndex + 1;
2292
2475
  }
2293
2476
  }
2294
- if (numContainers2 !== prevNumContainers) {
2295
- set$(ctx, "numContainers", numContainers2);
2296
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
2297
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
2477
+ if (numContainers !== prevNumContainers) {
2478
+ set$(ctx, "numContainers", numContainers);
2479
+ if (numContainers > peek$(ctx, "numContainersPooled")) {
2480
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
2298
2481
  }
2299
2482
  }
2300
2483
  }
2301
2484
  }
2302
2485
  if (stickyIndicesArr.length > 0) {
2303
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2486
+ handleStickyRecycling(ctx, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2304
2487
  }
2305
2488
  let didChangePositions = false;
2306
2489
  for (let i = 0; i < numContainers; i++) {
@@ -2352,7 +2535,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2352
2535
  }
2353
2536
  if (!queuedInitialLayout && endBuffered !== null) {
2354
2537
  if (checkAllSizesKnown(state)) {
2355
- setDidLayout(ctx, state);
2538
+ setDidLayout(ctx);
2356
2539
  }
2357
2540
  }
2358
2541
  if (viewabilityConfigCallbackPairs) {
@@ -2365,8 +2548,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2365
2548
  }
2366
2549
  }
2367
2550
  });
2368
- if (state.initialAnchor) {
2369
- ensureInitialAnchor(ctx, state);
2551
+ if (!IsNewArchitecture && state.initialAnchor) {
2552
+ ensureInitialAnchor(ctx);
2370
2553
  }
2371
2554
  }
2372
2555
 
@@ -2391,19 +2574,22 @@ function checkActualChange(state, dataProp, previousData) {
2391
2574
  }
2392
2575
 
2393
2576
  // src/core/doMaintainScrollAtEnd.ts
2394
- function doMaintainScrollAtEnd(ctx, state, animated) {
2577
+ function doMaintainScrollAtEnd(ctx, animated) {
2578
+ const state = ctx.state;
2395
2579
  const {
2580
+ didContainersLayout,
2581
+ isAtEnd,
2396
2582
  refScroller,
2397
2583
  props: { maintainScrollAtEnd }
2398
2584
  } = state;
2399
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2585
+ if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
2400
2586
  const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2401
2587
  if (paddingTop > 0) {
2402
2588
  state.scroll = 0;
2403
2589
  }
2404
2590
  requestAnimationFrame(() => {
2405
2591
  var _a3;
2406
- if (state == null ? void 0 : state.isAtEnd) {
2592
+ if (state.isAtEnd) {
2407
2593
  state.maintainingScrollAtEnd = true;
2408
2594
  (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2409
2595
  animated
@@ -2474,28 +2660,30 @@ function updateAveragesOnDataChange(state, oldData, newData) {
2474
2660
  }
2475
2661
 
2476
2662
  // src/core/checkResetContainers.ts
2477
- function checkResetContainers(ctx, state, dataProp) {
2663
+ function checkResetContainers(ctx, dataProp) {
2664
+ const state = ctx.state;
2478
2665
  const { previousData } = state;
2479
2666
  if (previousData) {
2480
2667
  updateAveragesOnDataChange(state, previousData, dataProp);
2481
2668
  }
2482
2669
  const { maintainScrollAtEnd } = state.props;
2483
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2670
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2484
2671
  const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2485
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
2672
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
2486
2673
  if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
2487
2674
  state.isEndReached = false;
2488
2675
  }
2489
2676
  if (!didMaintainScrollAtEnd) {
2490
2677
  checkAtTop(state);
2491
- checkAtBottom(ctx, state);
2678
+ checkAtBottom(ctx);
2492
2679
  }
2493
2680
  delete state.previousData;
2494
2681
  }
2495
2682
 
2496
2683
  // src/core/doInitialAllocateContainers.ts
2497
- function doInitialAllocateContainers(ctx, state) {
2684
+ function doInitialAllocateContainers(ctx) {
2498
2685
  var _a3, _b, _c;
2686
+ const state = ctx.state;
2499
2687
  const {
2500
2688
  scrollLength,
2501
2689
  props: {
@@ -2533,10 +2721,10 @@ function doInitialAllocateContainers(ctx, state) {
2533
2721
  if (!IsNewArchitecture || state.lastLayout) {
2534
2722
  if (state.initialScroll) {
2535
2723
  requestAnimationFrame(() => {
2536
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2724
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2537
2725
  });
2538
2726
  } else {
2539
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2727
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2540
2728
  }
2541
2729
  }
2542
2730
  return true;
@@ -2544,7 +2732,8 @@ function doInitialAllocateContainers(ctx, state) {
2544
2732
  }
2545
2733
 
2546
2734
  // src/core/handleLayout.ts
2547
- function handleLayout(ctx, state, layout, setCanRender) {
2735
+ function handleLayout(ctx, layout, setCanRender) {
2736
+ const state = ctx.state;
2548
2737
  const { maintainScrollAtEnd } = state.props;
2549
2738
  const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2550
2739
  const previousLength = state.scrollLength;
@@ -2560,19 +2749,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2560
2749
  state.lastBatchingAction = Date.now();
2561
2750
  state.scrollForNextCalculateItemsInView = void 0;
2562
2751
  if (scrollLength > 0) {
2563
- doInitialAllocateContainers(ctx, state);
2752
+ doInitialAllocateContainers(ctx);
2564
2753
  }
2565
2754
  if (needsCalculate) {
2566
- calculateItemsInView(ctx, state, { doMVCP: true });
2755
+ calculateItemsInView(ctx, { doMVCP: true });
2567
2756
  }
2568
2757
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
2569
2758
  set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
2570
2759
  }
2571
2760
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
2572
- doMaintainScrollAtEnd(ctx, state, false);
2761
+ doMaintainScrollAtEnd(ctx, false);
2573
2762
  }
2574
- updateAlignItemsPaddingTop(ctx, state);
2575
- checkAtBottom(ctx, state);
2763
+ updateAlignItemsPaddingTop(ctx);
2764
+ checkAtBottom(ctx);
2576
2765
  checkAtTop(state);
2577
2766
  if (state) {
2578
2767
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
@@ -2588,8 +2777,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2588
2777
  }
2589
2778
 
2590
2779
  // src/core/onScroll.ts
2591
- function onScroll(ctx, state, event) {
2780
+ function onScroll(ctx, event) {
2592
2781
  var _a3, _b, _c;
2782
+ const state = ctx.state;
2593
2783
  const {
2594
2784
  scrollProcessingEnabled,
2595
2785
  props: { onScroll: onScrollProp }
@@ -2600,9 +2790,23 @@ function onScroll(ctx, state, event) {
2600
2790
  if (((_b = (_a3 = event.nativeEvent) == null ? void 0 : _a3.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
2601
2791
  return;
2602
2792
  }
2603
- const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2793
+ let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2604
2794
  state.scrollPending = newScroll;
2605
- updateScroll(ctx, state, newScroll);
2795
+ if (state.scrollingTo) {
2796
+ const maxOffset = clampScrollOffset(ctx, newScroll);
2797
+ if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
2798
+ newScroll = maxOffset;
2799
+ scrollTo(ctx, {
2800
+ forceScroll: true,
2801
+ isInitialScroll: true,
2802
+ noScrollingTo: true,
2803
+ offset: newScroll
2804
+ });
2805
+ return;
2806
+ }
2807
+ }
2808
+ updateScroll(ctx, newScroll);
2809
+ checkFinishedScroll(ctx);
2606
2810
  onScrollProp == null ? void 0 : onScrollProp(event);
2607
2811
  }
2608
2812
 
@@ -2611,51 +2815,47 @@ var ScrollAdjustHandler = class {
2611
2815
  constructor(ctx) {
2612
2816
  this.appliedAdjust = 0;
2613
2817
  this.pendingAdjust = 0;
2614
- this.mounted = false;
2615
- this.context = ctx;
2616
- if (Platform2.OS === "web") {
2617
- const commitPendingAdjust = () => {
2618
- const state = this.context.internalState;
2619
- const pending = this.pendingAdjust;
2620
- if (pending !== 0) {
2621
- this.pendingAdjust = 0;
2622
- this.appliedAdjust += pending;
2623
- state.scroll += pending;
2624
- state.scrollForNextCalculateItemsInView = void 0;
2625
- set$(this.context, "scrollAdjustPending", 0);
2626
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2627
- calculateItemsInView(this.context, this.context.internalState);
2628
- }
2629
- };
2630
- listen$(this.context, "scrollingTo", (value) => {
2631
- if (value === void 0) {
2632
- commitPendingAdjust();
2633
- }
2634
- });
2635
- }
2818
+ this.ctx = ctx;
2636
2819
  }
2637
2820
  requestAdjust(add) {
2638
- const scrollingTo = peek$(this.context, "scrollingTo");
2821
+ const scrollingTo = this.ctx.state.scrollingTo;
2639
2822
  if (Platform2.OS === "web" && (scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
2640
2823
  this.pendingAdjust += add;
2641
- set$(this.context, "scrollAdjustPending", this.pendingAdjust);
2824
+ set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
2642
2825
  } else {
2643
2826
  this.appliedAdjust += add;
2644
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2827
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2828
+ }
2829
+ if (this.ctx.state.scrollingTo) {
2830
+ checkFinishedScroll(this.ctx);
2645
2831
  }
2646
- }
2647
- setMounted() {
2648
- this.mounted = true;
2649
2832
  }
2650
2833
  getAdjust() {
2651
2834
  return this.appliedAdjust;
2652
2835
  }
2836
+ commitPendingAdjust() {
2837
+ if (Platform2.OS === "web") {
2838
+ const state = this.ctx.state;
2839
+ const pending = this.pendingAdjust;
2840
+ if (pending !== 0) {
2841
+ this.pendingAdjust = 0;
2842
+ this.appliedAdjust += pending;
2843
+ state.scroll += pending;
2844
+ state.scrollForNextCalculateItemsInView = void 0;
2845
+ set$(this.ctx, "scrollAdjustPending", 0);
2846
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2847
+ calculateItemsInView(this.ctx);
2848
+ }
2849
+ }
2850
+ }
2653
2851
  };
2654
2852
 
2655
2853
  // src/core/updateItemSize.ts
2656
- function updateItemSize(ctx, state, itemKey, sizeObj) {
2854
+ function updateItemSize(ctx, itemKey, sizeObj) {
2657
2855
  var _a3;
2856
+ const state = ctx.state;
2658
2857
  const {
2858
+ didContainersLayout,
2659
2859
  sizesKnown,
2660
2860
  props: {
2661
2861
  getFixedItemSize,
@@ -2683,13 +2883,12 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2683
2883
  return;
2684
2884
  }
2685
2885
  }
2686
- const containersDidLayout = peek$(ctx, "containersDidLayout");
2687
- let needsRecalculate = !containersDidLayout;
2886
+ let needsRecalculate = !didContainersLayout;
2688
2887
  let shouldMaintainScrollAtEnd = false;
2689
2888
  let minIndexSizeChanged;
2690
2889
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
2691
2890
  const prevSizeKnown = state.sizesKnown.get(itemKey);
2692
- const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
2891
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj);
2693
2892
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
2694
2893
  if (diff !== 0) {
2695
2894
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -2738,22 +2937,22 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2738
2937
  if (!cur || maxOtherAxisSize > cur) {
2739
2938
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
2740
2939
  }
2741
- if (containersDidLayout || checkAllSizesKnown(state)) {
2940
+ if (didContainersLayout || checkAllSizesKnown(state)) {
2742
2941
  if (needsRecalculate) {
2743
2942
  state.scrollForNextCalculateItemsInView = void 0;
2744
- calculateItemsInView(ctx, state, { doMVCP: true });
2943
+ calculateItemsInView(ctx, { doMVCP: true });
2745
2944
  }
2746
2945
  if (shouldMaintainScrollAtEnd) {
2747
2946
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
2748
- doMaintainScrollAtEnd(ctx, state, false);
2947
+ doMaintainScrollAtEnd(ctx, false);
2749
2948
  }
2750
2949
  }
2751
2950
  }
2752
2951
  }
2753
- function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2952
+ function updateOneItemSize(ctx, itemKey, sizeObj) {
2754
2953
  var _a3;
2954
+ const state = ctx.state;
2755
2955
  const {
2756
- sizes,
2757
2956
  indexByKey,
2758
2957
  sizesKnown,
2759
2958
  averageSizes,
@@ -2761,9 +2960,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2761
2960
  } = state;
2762
2961
  if (!data) return 0;
2763
2962
  const index = indexByKey.get(itemKey);
2764
- const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
2963
+ const prevSize = getItemSize(ctx, itemKey, index, data[index]);
2765
2964
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2766
2965
  const size = Platform2.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
2966
+ const prevSizeKnown = sizesKnown.get(itemKey);
2767
2967
  sizesKnown.set(itemKey, size);
2768
2968
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2769
2969
  const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
@@ -2771,11 +2971,15 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2771
2971
  if (!averages) {
2772
2972
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
2773
2973
  }
2774
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2775
- averages.num++;
2974
+ if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
2975
+ averages.avg += (size - prevSizeKnown) / averages.num;
2976
+ } else {
2977
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2978
+ averages.num++;
2979
+ }
2776
2980
  }
2777
2981
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2778
- setSize(ctx, state, itemKey, size);
2982
+ setSize(ctx, itemKey, size);
2779
2983
  return size - prevSize;
2780
2984
  }
2781
2985
  return 0;
@@ -2841,14 +3045,15 @@ function createColumnWrapperStyle(contentContainerStyle) {
2841
3045
  }
2842
3046
 
2843
3047
  // src/utils/createImperativeHandle.ts
2844
- function createImperativeHandle(ctx, state) {
3048
+ function createImperativeHandle(ctx) {
3049
+ const state = ctx.state;
2845
3050
  const scrollIndexIntoView = (options) => {
2846
3051
  if (state) {
2847
3052
  const { index, ...rest } = options;
2848
3053
  const { startNoBuffer, endNoBuffer } = state;
2849
3054
  if (index < startNoBuffer || index > endNoBuffer) {
2850
3055
  const viewPosition = index < startNoBuffer ? 0 : 1;
2851
- scrollToIndex(ctx, state, {
3056
+ scrollToIndex(ctx, {
2852
3057
  ...rest,
2853
3058
  index,
2854
3059
  viewPosition
@@ -2863,7 +3068,7 @@ function createImperativeHandle(ctx, state) {
2863
3068
  getScrollableNode: () => refScroller.current.getScrollableNode(),
2864
3069
  getScrollResponder: () => refScroller.current.getScrollResponder(),
2865
3070
  getState: () => ({
2866
- activeStickyIndex: state.activeStickyIndex,
3071
+ activeStickyIndex: peek$(ctx, "activeStickyIndex"),
2867
3072
  contentLength: state.totalSize,
2868
3073
  data: state.props.data,
2869
3074
  elementAtIndex: (index) => {
@@ -2874,6 +3079,8 @@ function createImperativeHandle(ctx, state) {
2874
3079
  endBuffered: state.endBuffered,
2875
3080
  isAtEnd: state.isAtEnd,
2876
3081
  isAtStart: state.isAtStart,
3082
+ listen: (signalName, cb) => listen$(ctx, signalName, cb),
3083
+ listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
2877
3084
  positionAtIndex: (index) => state.positions.get(getId(state, index)),
2878
3085
  positions: state.positions,
2879
3086
  scroll: state.scroll,
@@ -2898,23 +3105,23 @@ function createImperativeHandle(ctx, state) {
2898
3105
  if (index !== -1) {
2899
3106
  const paddingBottom = stylePaddingBottom || 0;
2900
3107
  const footerSize = peek$(ctx, "footerSize") || 0;
2901
- scrollToIndex(ctx, state, {
3108
+ scrollToIndex(ctx, {
3109
+ ...options,
2902
3110
  index,
2903
3111
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
2904
- viewPosition: 1,
2905
- ...options
3112
+ viewPosition: 1
2906
3113
  });
2907
3114
  }
2908
3115
  },
2909
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3116
+ scrollToIndex: (params) => scrollToIndex(ctx, params),
2910
3117
  scrollToItem: ({ item, ...props }) => {
2911
3118
  const data = state.props.data;
2912
3119
  const index = data.indexOf(item);
2913
3120
  if (index !== -1) {
2914
- scrollToIndex(ctx, state, { index, ...props });
3121
+ scrollToIndex(ctx, { index, ...props });
2915
3122
  }
2916
3123
  },
2917
- scrollToOffset: (params) => scrollTo(ctx, state, params),
3124
+ scrollToOffset: (params) => scrollTo(ctx, params),
2918
3125
  setScrollProcessingEnabled: (enabled) => {
2919
3126
  state.scrollProcessingEnabled = enabled;
2920
3127
  },
@@ -2924,8 +3131,9 @@ function createImperativeHandle(ctx, state) {
2924
3131
  }
2925
3132
  };
2926
3133
  }
2927
- function getRenderedItem(ctx, state, key) {
3134
+ function getRenderedItem(ctx, key) {
2928
3135
  var _a3;
3136
+ const state = ctx.state;
2929
3137
  if (!state) {
2930
3138
  return null;
2931
3139
  }
@@ -3002,11 +3210,13 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
3002
3210
  var DEFAULT_DRAW_DISTANCE = 250;
3003
3211
  var DEFAULT_ITEM_SIZE = 100;
3004
3212
  var LegendList = typedMemo(
3213
+ // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
3005
3214
  typedForwardRef(function LegendList2(props, forwardedRef) {
3006
3215
  const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
3007
3216
  const isChildrenMode = children !== void 0 && dataProp === void 0;
3008
3217
  const processedProps = isChildrenMode ? {
3009
3218
  ...restProps,
3219
+ childrenMode: true,
3010
3220
  data: (isArray(children) ? children : React2__namespace.Children.toArray(children)).flat(1),
3011
3221
  renderItem: ({ item }) => item
3012
3222
  } : {
@@ -3023,10 +3233,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3023
3233
  alignItemsAtEnd = false,
3024
3234
  columnWrapperStyle,
3025
3235
  contentContainerStyle: contentContainerStyleProp,
3236
+ contentInset,
3026
3237
  data: dataProp = [],
3027
3238
  dataVersion,
3028
3239
  drawDistance = 250,
3029
- enableAverages = true,
3030
3240
  estimatedItemSize: estimatedItemSizeProp,
3031
3241
  estimatedListSize,
3032
3242
  extraData,
@@ -3068,6 +3278,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3068
3278
  snapToIndices,
3069
3279
  stickyHeaderIndices: stickyHeaderIndicesProp,
3070
3280
  stickyIndices: stickyIndicesDeprecated,
3281
+ // TODOV3: Remove from v3 release
3071
3282
  style: styleProp,
3072
3283
  suggestEstimatedItemSize,
3073
3284
  viewabilityConfig,
@@ -3075,6 +3286,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3075
3286
  waitForInitialLayout = true,
3076
3287
  ...rest
3077
3288
  } = props;
3289
+ const animatedPropsInternal = props.animatedPropsInternal;
3290
+ const { childrenMode } = rest;
3078
3291
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
3079
3292
  const style = { ...StyleSheet.flatten(styleProp) };
3080
3293
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -3098,10 +3311,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3098
3311
  }
3099
3312
  const refState = React2.useRef();
3100
3313
  if (!refState.current) {
3101
- if (!ctx.internalState) {
3314
+ if (!ctx.state) {
3102
3315
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : getWindowSize())[horizontal ? "width" : "height"];
3103
- ctx.internalState = {
3104
- activeStickyIndex: void 0,
3316
+ ctx.state = {
3317
+ activeStickyIndex: -1,
3105
3318
  averageSizes: {},
3106
3319
  columns: /* @__PURE__ */ new Map(),
3107
3320
  containerItemKeys: /* @__PURE__ */ new Set(),
@@ -3127,9 +3340,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3127
3340
  initialScroll: initialScrollProp,
3128
3341
  isAtEnd: false,
3129
3342
  isAtStart: false,
3130
- isEndReached: false,
3343
+ isEndReached: null,
3131
3344
  isFirst: true,
3132
- isStartReached: false,
3345
+ isStartReached: null,
3133
3346
  lastBatchingAction: Date.now(),
3134
3347
  lastLayout: void 0,
3135
3348
  loadStartTime: Date.now(),
@@ -3161,12 +3374,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3161
3374
  totalSize: 0,
3162
3375
  viewabilityConfigCallbackPairs: void 0
3163
3376
  };
3164
- const internalState = ctx.internalState;
3165
- internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
3377
+ const internalState = ctx.state;
3378
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3166
3379
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3167
3380
  set$(ctx, "extraData", extraData);
3168
3381
  }
3169
- refState.current = ctx.internalState;
3382
+ refState.current = ctx.state;
3170
3383
  }
3171
3384
  const state = refState.current;
3172
3385
  const isFirstLocal = state.isFirst;
@@ -3180,9 +3393,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3180
3393
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
3181
3394
  state.props = {
3182
3395
  alignItemsAtEnd,
3396
+ animatedProps: animatedPropsInternal,
3397
+ contentInset,
3183
3398
  data: dataProp,
3184
3399
  dataVersion,
3185
- enableAverages,
3186
3400
  estimatedItemSize,
3187
3401
  getEstimatedItemSize,
3188
3402
  getFixedItemSize,
@@ -3225,62 +3439,62 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3225
3439
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3226
3440
  set$(ctx, "numColumns", numColumnsProp);
3227
3441
  const prevPaddingTop = peek$(ctx, "stylePaddingTop");
3228
- setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3442
+ setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3229
3443
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3230
3444
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3231
3445
  if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3232
3446
  if (state.scroll < 0) {
3233
3447
  paddingDiff += state.scroll;
3234
3448
  }
3235
- requestAdjust(ctx, state, paddingDiff);
3449
+ requestAdjust(ctx, paddingDiff);
3236
3450
  }
3237
3451
  };
3238
3452
  if (isFirstLocal) {
3239
3453
  initializeStateVars();
3240
3454
  updateItemPositions(
3241
3455
  ctx,
3242
- state,
3243
3456
  /*dataChanged*/
3244
3457
  true
3245
3458
  );
3246
3459
  }
3247
3460
  const initialContentOffset = React2.useMemo(() => {
3248
- var _a4, _b2;
3249
- const { initialScroll } = refState.current;
3250
- if (!initialScroll) {
3461
+ var _a4;
3462
+ let value;
3463
+ const { initialScroll, initialAnchor } = refState.current;
3464
+ if (initialScroll) {
3465
+ if (!IsNewArchitecture && initialScroll.index !== void 0 && (!initialAnchor || (initialAnchor == null ? void 0 : initialAnchor.index) !== initialScroll.index)) {
3466
+ refState.current.initialAnchor = {
3467
+ attempts: 0,
3468
+ index: initialScroll.index,
3469
+ settledTicks: 0,
3470
+ viewOffset: (_a4 = initialScroll.viewOffset) != null ? _a4 : 0,
3471
+ viewPosition: initialScroll.viewPosition
3472
+ };
3473
+ }
3474
+ if (initialScroll.contentOffset !== void 0) {
3475
+ value = initialScroll.contentOffset;
3476
+ } else {
3477
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
3478
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
3479
+ const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
3480
+ const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3481
+ refState.current.initialScroll = updatedInitialScroll;
3482
+ state.initialScroll = updatedInitialScroll;
3483
+ value = clampedOffset;
3484
+ }
3485
+ } else {
3251
3486
  refState.current.initialAnchor = void 0;
3252
- return 0;
3253
- }
3254
- if (initialScroll.index !== void 0 && (!refState.current.initialAnchor || ((_a4 = refState.current.initialAnchor) == null ? void 0 : _a4.index) !== initialScroll.index)) {
3255
- refState.current.initialAnchor = {
3256
- attempts: 0,
3257
- index: initialScroll.index,
3258
- settledTicks: 0,
3259
- viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
3260
- viewPosition: initialScroll.viewPosition
3261
- };
3487
+ value = 0;
3488
+ }
3489
+ if (!value) {
3490
+ state.didFinishInitialScroll = true;
3262
3491
  }
3263
- if (initialScroll.contentOffset !== void 0) {
3264
- return initialScroll.contentOffset;
3265
- }
3266
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
3267
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
3268
- let clampedOffset = resolvedOffset;
3269
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
3270
- const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
3271
- clampedOffset = Math.min(clampedOffset, maxOffset);
3272
- }
3273
- clampedOffset = Math.max(0, clampedOffset);
3274
- const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3275
- refState.current.initialScroll = updatedInitialScroll;
3276
- state.initialScroll = updatedInitialScroll;
3277
- refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
3278
- return clampedOffset;
3492
+ return value;
3279
3493
  }, [renderNum]);
3280
3494
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
3281
3495
  refState.current.lastBatchingAction = Date.now();
3282
3496
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
3283
- IS_DEV && warnDevOnce(
3497
+ IS_DEV && !childrenMode && warnDevOnce(
3284
3498
  "keyExtractor",
3285
3499
  "Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
3286
3500
  );
@@ -3305,12 +3519,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3305
3519
  }
3306
3520
  }, []);
3307
3521
  const doInitialScroll = React2.useCallback(() => {
3308
- var _a4;
3309
3522
  const initialScroll = state.initialScroll;
3310
3523
  if (initialScroll) {
3311
- scrollTo(ctx, state, {
3524
+ scrollTo(ctx, {
3312
3525
  animated: false,
3313
- index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
3526
+ index: initialScroll == null ? void 0 : initialScroll.index,
3314
3527
  isInitialScroll: true,
3315
3528
  offset: initialContentOffset,
3316
3529
  precomputedWithViewOffset: true
@@ -3319,7 +3532,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3319
3532
  }, [initialContentOffset]);
3320
3533
  const onLayoutChange = React2.useCallback((layout) => {
3321
3534
  doInitialScroll();
3322
- handleLayout(ctx, state, layout, setCanRender);
3535
+ handleLayout(ctx, layout, setCanRender);
3323
3536
  }, []);
3324
3537
  const { onLayout } = useOnLayoutSync({
3325
3538
  onLayoutChange,
@@ -3329,7 +3542,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3329
3542
  });
3330
3543
  React2.useLayoutEffect(() => {
3331
3544
  if (snapToIndices) {
3332
- updateSnapToOffsets(ctx, state);
3545
+ updateSnapToOffsets(ctx);
3333
3546
  }
3334
3547
  }, [snapToIndices]);
3335
3548
  React2.useLayoutEffect(() => {
@@ -3339,9 +3552,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3339
3552
  isFirst,
3340
3553
  props: { data }
3341
3554
  } = state;
3342
- const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
3555
+ const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
3343
3556
  if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
3344
- checkResetContainers(ctx, state, data);
3557
+ checkResetContainers(ctx, data);
3345
3558
  }
3346
3559
  state.didColumnsChange = false;
3347
3560
  state.didDataChange = false;
@@ -3368,18 +3581,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3368
3581
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
3369
3582
  if (!IsNewArchitecture) {
3370
3583
  useInit(() => {
3371
- doInitialAllocateContainers(ctx, state);
3584
+ doInitialAllocateContainers(ctx);
3372
3585
  });
3373
3586
  }
3374
- React2.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
3587
+ React2.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
3375
3588
  if (Platform2.OS === "web") {
3376
3589
  React2.useEffect(doInitialScroll, []);
3377
3590
  }
3378
3591
  const fns = React2.useMemo(
3379
3592
  () => ({
3380
- getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3381
- onScroll: (event) => onScroll(ctx, state, event),
3382
- updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj)
3593
+ getRenderedItem: (key) => getRenderedItem(ctx, key),
3594
+ onMomentumScrollEnd: (event) => {
3595
+ checkFinishedScrollFallback(ctx);
3596
+ if (onMomentumScrollEnd) {
3597
+ onMomentumScrollEnd(event);
3598
+ }
3599
+ },
3600
+ onScroll: (event) => onScroll(ctx, event),
3601
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
3383
3602
  }),
3384
3603
  []
3385
3604
  );
@@ -3391,6 +3610,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3391
3610
  alignItemsAtEnd,
3392
3611
  canRender,
3393
3612
  contentContainerStyle,
3613
+ contentInset,
3394
3614
  getRenderedItem: fns.getRenderedItem,
3395
3615
  horizontal,
3396
3616
  initialContentOffset,
@@ -3399,20 +3619,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3399
3619
  maintainVisibleContentPosition,
3400
3620
  onLayout,
3401
3621
  onLayoutHeader,
3402
- onMomentumScrollEnd: (event) => {
3403
- if (IsNewArchitecture) {
3404
- requestAnimationFrame(() => {
3405
- finishScrollTo(ctx, refState.current);
3406
- });
3407
- } else {
3408
- setTimeout(() => {
3409
- finishScrollTo(ctx, refState.current);
3410
- }, 1e3);
3411
- }
3412
- if (onMomentumScrollEnd) {
3413
- onMomentumScrollEnd(event);
3414
- }
3415
- },
3622
+ onMomentumScrollEnd: fns.onMomentumScrollEnd,
3416
3623
  onScroll: onScrollHandler,
3417
3624
  recycleItems,
3418
3625
  refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControl, {
@@ -3427,7 +3634,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3427
3634
  ),
3428
3635
  refScrollView: combinedRef,
3429
3636
  scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3430
- scrollEventThrottle: Platform2.OS === "web" ? 16 : void 0,
3637
+ scrollEventThrottle: 0,
3431
3638
  snapToIndices,
3432
3639
  stickyHeaderIndices,
3433
3640
  style,
@@ -3473,8 +3680,8 @@ function buildSectionListData({
3473
3680
  if (hasHeader) {
3474
3681
  const headerIndex = data.length;
3475
3682
  data.push({
3476
- kind: "header",
3477
3683
  key: `${sectionKey}:header`,
3684
+ kind: "header",
3478
3685
  section,
3479
3686
  sectionIndex
3480
3687
  });
@@ -3488,31 +3695,31 @@ function buildSectionListData({
3488
3695
  const itemKeyExtractor = (_b = section.keyExtractor) != null ? _b : keyExtractor;
3489
3696
  const itemKey = itemKeyExtractor(item, itemIndex);
3490
3697
  data.push({
3491
- kind: "item",
3492
- key: `${sectionKey}:item:${itemKey}`,
3493
- section,
3494
- sectionIndex,
3698
+ absoluteItemIndex: absoluteItemIndex++,
3495
3699
  item,
3496
3700
  itemIndex,
3497
- absoluteItemIndex: absoluteItemIndex++
3701
+ key: `${sectionKey}:item:${itemKey}`,
3702
+ kind: "item",
3703
+ section,
3704
+ sectionIndex
3498
3705
  });
3499
3706
  meta.items.push(data.length - 1);
3500
3707
  if (hasItemSeparator && itemIndex < items.length - 1) {
3501
3708
  data.push({
3502
- kind: "item-separator",
3503
3709
  key: `${sectionKey}:separator:${itemIndex}`,
3504
- section,
3505
- sectionIndex,
3710
+ kind: "item-separator",
3506
3711
  leadingItem: item,
3507
3712
  leadingItemIndex: itemIndex,
3713
+ section,
3714
+ sectionIndex,
3508
3715
  trailingItem: items[itemIndex + 1]
3509
3716
  });
3510
3717
  }
3511
3718
  }
3512
3719
  if (hasFooter) {
3513
3720
  data.push({
3514
- kind: "footer",
3515
3721
  key: `${sectionKey}:footer`,
3722
+ kind: "footer",
3516
3723
  section,
3517
3724
  sectionIndex
3518
3725
  });
@@ -3521,8 +3728,8 @@ function buildSectionListData({
3521
3728
  const isLastSection = sectionIndex === sections.length - 1;
3522
3729
  if (hasSectionSeparator && !isLastSection) {
3523
3730
  data.push({
3524
- kind: "section-separator",
3525
3731
  key: `${sectionKey}:section-separator`,
3732
+ kind: "section-separator",
3526
3733
  leadingSection: section,
3527
3734
  leadingSectionIndex: sectionIndex,
3528
3735
  trailingSection: sections[sectionIndex + 1]