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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,30 +7,64 @@ import { useSyncExternalStore } from 'use-sync-external-store/shim';
7
7
  Animated.View;
8
8
  var View = View$1;
9
9
  var Text = Text$1;
10
+
11
+ // src/state/getContentInsetEnd.ts
12
+ function getContentInsetEnd(state) {
13
+ var _a3;
14
+ const { props } = state;
15
+ const horizontal = props.horizontal;
16
+ let contentInset = props.contentInset;
17
+ if (!contentInset) {
18
+ const animatedInset = (_a3 = props.animatedProps) == null ? void 0 : _a3.contentInset;
19
+ if (animatedInset) {
20
+ if ("get" in animatedInset) {
21
+ contentInset = animatedInset.get();
22
+ } else {
23
+ contentInset = animatedInset;
24
+ }
25
+ }
26
+ }
27
+ return (horizontal ? contentInset == null ? void 0 : contentInset.right : contentInset == null ? void 0 : contentInset.bottom) || 0;
28
+ }
29
+
30
+ // src/state/getContentSize.ts
31
+ function getContentSize(ctx) {
32
+ var _a3;
33
+ const { values, state } = ctx;
34
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
35
+ const stylePaddingBottom = state.props.stylePaddingBottom || 0;
36
+ const headerSize = values.get("headerSize") || 0;
37
+ const footerSize = values.get("footerSize") || 0;
38
+ const contentInsetBottom = getContentInsetEnd(state);
39
+ const totalSize = (_a3 = state.pendingTotalSize) != null ? _a3 : values.get("totalSize");
40
+ return headerSize + footerSize + totalSize + stylePaddingTop + stylePaddingBottom + (contentInsetBottom || 0);
41
+ }
10
42
  var createAnimatedValue = (value) => new Animated.Value(value);
11
43
 
12
44
  // src/state/state.tsx
13
45
  var ContextState = React2.createContext(null);
46
+ var contextNum = 0;
14
47
  function StateProvider({ children }) {
15
48
  const [value] = React2.useState(() => ({
16
49
  animatedScrollY: createAnimatedValue(0),
17
50
  columnWrapperStyle: void 0,
18
- internalState: void 0,
51
+ contextNum: contextNum++,
19
52
  listeners: /* @__PURE__ */ new Map(),
20
53
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
21
54
  mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
22
55
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
23
56
  mapViewabilityConfigStates: /* @__PURE__ */ new Map(),
24
57
  mapViewabilityValues: /* @__PURE__ */ new Map(),
58
+ positionListeners: /* @__PURE__ */ new Map(),
59
+ state: void 0,
25
60
  values: /* @__PURE__ */ new Map([
26
61
  ["alignItemsPaddingTop", 0],
27
62
  ["stylePaddingTop", 0],
28
63
  ["headerSize", 0],
29
64
  ["numContainers", 0],
30
- ["activeStickyIndex", void 0],
65
+ ["activeStickyIndex", -1],
31
66
  ["totalSize", 0],
32
- ["scrollAdjustPending", 0],
33
- ["scrollingTo", void 0]
67
+ ["scrollAdjustPending", 0]
34
68
  ]),
35
69
  viewRefs: /* @__PURE__ */ new Map()
36
70
  }));
@@ -98,14 +132,24 @@ function set$(ctx, signalName, value) {
98
132
  }
99
133
  }
100
134
  }
101
- function getContentSize(ctx) {
102
- var _a3, _b;
103
- const { values } = ctx;
104
- const stylePaddingTop = values.get("stylePaddingTop") || 0;
105
- const headerSize = values.get("headerSize") || 0;
106
- const footerSize = values.get("footerSize") || 0;
107
- const totalSize = (_b = (_a3 = ctx.internalState) == null ? void 0 : _a3.pendingTotalSize) != null ? _b : values.get("totalSize");
108
- return headerSize + footerSize + totalSize + stylePaddingTop;
135
+ function listenPosition$(ctx, key, cb) {
136
+ const { positionListeners } = ctx;
137
+ let setListeners = positionListeners.get(key);
138
+ if (!setListeners) {
139
+ setListeners = /* @__PURE__ */ new Set();
140
+ positionListeners.set(key, setListeners);
141
+ }
142
+ setListeners.add(cb);
143
+ return () => setListeners.delete(cb);
144
+ }
145
+ function notifyPosition$(ctx, key, value) {
146
+ const { positionListeners } = ctx;
147
+ const setListeners = positionListeners.get(key);
148
+ if (setListeners) {
149
+ for (const listener of setListeners) {
150
+ listener(value);
151
+ }
152
+ }
109
153
  }
110
154
  function useArr$(signalNames) {
111
155
  const ctx = React2.useContext(ContextState);
@@ -186,7 +230,8 @@ var ENABLE_DEBUG_VIEW = IS_DEV && false;
186
230
  // src/constants-platform.native.ts
187
231
  var IsNewArchitecture = global.nativeFabricUIManager != null;
188
232
  var useAnimatedValue = (initialValue) => {
189
- return useRef(new Animated.Value(initialValue)).current;
233
+ const [animAnimatedValue] = useState(() => new Animated.Value(initialValue));
234
+ return animAnimatedValue;
190
235
  };
191
236
 
192
237
  // src/utils/helpers.ts
@@ -275,7 +320,7 @@ var typedForwardRef = forwardRef;
275
320
  var typedMemo = memo;
276
321
 
277
322
  // src/components/PositionView.native.tsx
278
- var PositionViewState = typedMemo(function PositionView({
323
+ var PositionViewState = typedMemo(function PositionViewState2({
279
324
  id,
280
325
  horizontal,
281
326
  style,
@@ -295,7 +340,7 @@ var PositionViewState = typedMemo(function PositionView({
295
340
  }
296
341
  );
297
342
  });
298
- var PositionViewAnimated = typedMemo(function PositionView2({
343
+ var PositionViewAnimated = typedMemo(function PositionViewAnimated2({
299
344
  id,
300
345
  horizontal,
301
346
  style,
@@ -338,14 +383,9 @@ var PositionViewSticky = typedMemo(function PositionViewSticky2({
338
383
  const viewStyle = React2.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
339
384
  return /* @__PURE__ */ React2.createElement(Animated.View, { ref: refView, style: viewStyle, ...rest });
340
385
  });
341
- var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
342
- var symbolFirst = Symbol();
386
+ var PositionView = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
343
387
  function useInit(cb) {
344
- const refValue = useRef(symbolFirst);
345
- if (refValue.current === symbolFirst) {
346
- refValue.current = cb();
347
- }
348
- return refValue.current;
388
+ useState(() => cb());
349
389
  }
350
390
 
351
391
  // src/state/ContextContainer.ts
@@ -512,6 +552,7 @@ var Container = typedMemo(function Container2({
512
552
  if (!IsNewArchitecture) {
513
553
  useEffect(() => {
514
554
  if (!isNullOrUndefined(itemKey)) {
555
+ didLayoutRef.current = false;
515
556
  const timeout = setTimeout(() => {
516
557
  if (!didLayoutRef.current) {
517
558
  const {
@@ -531,7 +572,7 @@ var Container = typedMemo(function Container2({
531
572
  }
532
573
  }, [itemKey]);
533
574
  }
534
- const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
575
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView;
535
576
  return /* @__PURE__ */ React2.createElement(
536
577
  PositionComponent,
537
578
  {
@@ -566,10 +607,10 @@ var Containers = typedMemo(function Containers2({
566
607
  // If this is the initial scroll, we don't want to delay because we want to update the size immediately
567
608
  delay: (value, prevValue) => {
568
609
  var _a3;
569
- return !((_a3 = ctx.internalState) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
610
+ return !((_a3 = ctx.state) == null ? void 0 : _a3.initialScroll) ? !prevValue || value - prevValue > 20 ? 0 : 200 : void 0;
570
611
  }
571
612
  });
572
- const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
613
+ const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("readyToRender", { getValue: (value) => value ? 1 : 0 }) : void 0;
573
614
  const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
574
615
  const containers = [];
575
616
  for (let i = 0; i < numContainers; i++) {
@@ -612,7 +653,8 @@ var Containers = typedMemo(function Containers2({
612
653
  return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
613
654
  });
614
655
  function DevNumbers() {
615
- return IS_DEV && React2.memo(function DevNumbers2() {
656
+ return IS_DEV && // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
657
+ React2.memo(function DevNumbers2() {
616
658
  return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React2.createElement(
617
659
  View$1,
618
660
  {
@@ -720,13 +762,6 @@ var ListComponent = typedMemo(function ListComponent2({
720
762
  () => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
721
763
  [renderScrollComponent]
722
764
  ) : ListComponentScrollView;
723
- React2.useEffect(() => {
724
- if (canRender) {
725
- setTimeout(() => {
726
- scrollAdjustHandler.setMounted();
727
- }, 0);
728
- }
729
- }, [canRender]);
730
765
  const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
731
766
  return /* @__PURE__ */ React2.createElement(
732
767
  SnapOrScroll,
@@ -790,10 +825,11 @@ function getId(state, index) {
790
825
  }
791
826
 
792
827
  // src/core/calculateOffsetForIndex.ts
793
- function calculateOffsetForIndex(ctx, state, index) {
828
+ function calculateOffsetForIndex(ctx, index) {
829
+ const state = ctx.state;
794
830
  let position = 0;
795
831
  if (index !== void 0) {
796
- position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
832
+ position = state.positions.get(getId(state, index)) || 0;
797
833
  const paddingTop = peek$(ctx, "stylePaddingTop");
798
834
  if (paddingTop) {
799
835
  position += paddingTop;
@@ -807,7 +843,8 @@ function calculateOffsetForIndex(ctx, state, index) {
807
843
  }
808
844
 
809
845
  // src/utils/setPaddingTop.ts
810
- function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
846
+ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
847
+ const state = ctx.state;
811
848
  if (stylePaddingTop !== void 0) {
812
849
  const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
813
850
  if (stylePaddingTop < prevStylePaddingTop) {
@@ -826,7 +863,8 @@ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
826
863
  }
827
864
 
828
865
  // src/utils/updateAlignItemsPaddingTop.ts
829
- function updateAlignItemsPaddingTop(ctx, state) {
866
+ function updateAlignItemsPaddingTop(ctx) {
867
+ const state = ctx.state;
830
868
  const {
831
869
  scrollLength,
832
870
  props: { alignItemsAtEnd, data }
@@ -837,12 +875,13 @@ function updateAlignItemsPaddingTop(ctx, state) {
837
875
  const contentSize = getContentSize(ctx);
838
876
  alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
839
877
  }
840
- setPaddingTop(ctx, state, { alignItemsPaddingTop });
878
+ setPaddingTop(ctx, { alignItemsPaddingTop });
841
879
  }
842
880
  }
843
881
 
844
882
  // src/core/addTotalSize.ts
845
- function addTotalSize(ctx, state, key, add) {
883
+ function addTotalSize(ctx, key, add) {
884
+ const state = ctx.state;
846
885
  const { alignItemsAtEnd } = state.props;
847
886
  const prevTotalSize = state.totalSize;
848
887
  let totalSize = state.totalSize;
@@ -863,31 +902,34 @@ function addTotalSize(ctx, state, key, add) {
863
902
  state.totalSize = totalSize;
864
903
  set$(ctx, "totalSize", totalSize);
865
904
  if (alignItemsAtEnd) {
866
- updateAlignItemsPaddingTop(ctx, state);
905
+ updateAlignItemsPaddingTop(ctx);
867
906
  }
868
907
  }
869
908
  }
870
909
  }
871
910
 
872
911
  // src/core/setSize.ts
873
- function setSize(ctx, state, itemKey, size) {
912
+ function setSize(ctx, itemKey, size) {
913
+ const state = ctx.state;
874
914
  const { sizes } = state;
875
915
  const previousSize = sizes.get(itemKey);
876
916
  const diff = previousSize !== void 0 ? size - previousSize : size;
877
917
  if (diff !== 0) {
878
- addTotalSize(ctx, state, itemKey, diff);
918
+ addTotalSize(ctx, itemKey, diff);
879
919
  }
880
920
  sizes.set(itemKey, size);
881
921
  }
882
922
 
883
923
  // src/utils/getItemSize.ts
884
- function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedSize) {
924
+ function getItemSize(ctx, key, index, data, useAverageSize, preferCachedSize) {
885
925
  var _a3, _b;
926
+ const state = ctx.state;
886
927
  const {
887
928
  sizesKnown,
888
929
  sizes,
889
930
  averageSizes,
890
- props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
931
+ props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType },
932
+ scrollingTo
891
933
  } = state;
892
934
  const sizeKnown = sizesKnown.get(key);
893
935
  if (sizeKnown !== void 0) {
@@ -895,7 +937,6 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
895
937
  }
896
938
  let size;
897
939
  const itemType = getItemType ? (_a3 = getItemType(data, index)) != null ? _a3 : "" : "";
898
- const scrollingTo = peek$(ctx, "scrollingTo");
899
940
  if (preferCachedSize) {
900
941
  const cachedSize = sizes.get(key);
901
942
  if (cachedSize !== void 0) {
@@ -923,84 +964,167 @@ function getItemSize(ctx, state, key, index, data, useAverageSize, preferCachedS
923
964
  if (size === void 0) {
924
965
  size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
925
966
  }
926
- setSize(ctx, state, key, size);
967
+ setSize(ctx, key, size);
927
968
  return size;
928
969
  }
929
970
 
930
971
  // src/core/calculateOffsetWithOffsetPosition.ts
931
- function calculateOffsetWithOffsetPosition(ctx, state, offsetParam, params) {
972
+ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
973
+ const state = ctx.state;
932
974
  const { index, viewOffset, viewPosition } = params;
933
975
  let offset = offsetParam;
934
976
  if (viewOffset) {
935
977
  offset -= viewOffset;
936
978
  }
937
979
  if (viewPosition !== void 0 && index !== void 0) {
938
- offset -= viewPosition * (state.scrollLength - getItemSize(ctx, state, getId(state, index), index, state.props.data[index]));
980
+ const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
981
+ const trailingInset = getContentInsetEnd(state);
982
+ offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
939
983
  }
940
984
  return offset;
941
985
  }
942
986
 
987
+ // src/core/clampScrollOffset.ts
988
+ function clampScrollOffset(ctx, offset) {
989
+ const state = ctx.state;
990
+ const contentSize = getContentSize(ctx);
991
+ let clampedOffset = offset;
992
+ if (Number.isFinite(contentSize) && Number.isFinite(state.scrollLength)) {
993
+ const maxOffset = Math.max(0, contentSize - state.scrollLength);
994
+ clampedOffset = Math.min(offset, maxOffset);
995
+ }
996
+ clampedOffset = Math.max(0, clampedOffset);
997
+ return clampedOffset;
998
+ }
999
+ var Platform2 = Platform;
1000
+
1001
+ // src/utils/setInitialRenderState.ts
1002
+ function setInitialRenderState(ctx, {
1003
+ didLayout,
1004
+ didInitialScroll
1005
+ }) {
1006
+ const { state } = ctx;
1007
+ if (didLayout) {
1008
+ state.didContainersLayout = true;
1009
+ }
1010
+ if (didInitialScroll) {
1011
+ state.didFinishInitialScroll = true;
1012
+ }
1013
+ if (state.didContainersLayout && state.didFinishInitialScroll) {
1014
+ set$(ctx, "readyToRender", true);
1015
+ }
1016
+ }
1017
+
943
1018
  // src/core/finishScrollTo.ts
944
- function finishScrollTo(ctx, state) {
1019
+ function finishScrollTo(ctx) {
945
1020
  var _a3, _b;
946
- if (state) {
1021
+ const state = ctx.state;
1022
+ if (state == null ? void 0 : state.scrollingTo) {
947
1023
  state.scrollHistory.length = 0;
948
1024
  state.initialScroll = void 0;
949
1025
  state.initialAnchor = void 0;
950
- set$(ctx, "scrollingTo", void 0);
1026
+ state.scrollingTo = void 0;
951
1027
  if (state.pendingTotalSize !== void 0) {
952
- addTotalSize(ctx, state, null, state.pendingTotalSize);
1028
+ addTotalSize(ctx, null, state.pendingTotalSize);
953
1029
  }
954
1030
  if ((_a3 = state.props) == null ? void 0 : _a3.data) {
955
1031
  (_b = state.triggerCalculateItemsInView) == null ? void 0 : _b.call(state, { forceFullItemPositions: true });
956
1032
  }
1033
+ if (Platform2.OS === "web") {
1034
+ state.scrollAdjustHandler.commitPendingAdjust();
1035
+ }
1036
+ setInitialRenderState(ctx, { didInitialScroll: true });
957
1037
  }
958
1038
  }
959
- var Platform2 = Platform;
960
1039
 
961
- // src/core/scrollTo.ts
962
- function scrollTo(ctx, state, params) {
1040
+ // src/core/checkFinishedScroll.ts
1041
+ function checkFinishedScroll(ctx) {
1042
+ ctx.state.animFrameCheckFinishedScroll = requestAnimationFrame(() => checkFinishedScrollFrame(ctx));
1043
+ }
1044
+ function checkFinishedScrollFrame(ctx) {
1045
+ const scrollingTo = ctx.state.scrollingTo;
1046
+ if (scrollingTo) {
1047
+ const { state } = ctx;
1048
+ state.animFrameCheckFinishedScroll = void 0;
1049
+ const scroll = state.scroll;
1050
+ const adjust = state.scrollAdjustHandler.getAdjust();
1051
+ const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1052
+ const maxOffset = clampScrollOffset(ctx, scroll);
1053
+ const diff1 = Math.abs(scroll - clampedTargetOffset);
1054
+ const diff2 = Math.abs(diff1 - adjust);
1055
+ const isNotOverscrolled = Math.abs(scroll - maxOffset) < 1;
1056
+ if (isNotOverscrolled && (diff1 < 1 || diff2 < 1)) {
1057
+ finishScrollTo(ctx);
1058
+ }
1059
+ }
1060
+ }
1061
+ function checkFinishedScrollFallback(ctx) {
1062
+ const state = ctx.state;
1063
+ const scrollingTo = state.scrollingTo;
1064
+ const slowTimeout = (scrollingTo == null ? void 0 : scrollingTo.isInitialScroll) || !state.didContainersLayout;
1065
+ state.timeoutCheckFinishedScrollFallback = setTimeout(
1066
+ () => {
1067
+ let numChecks = 0;
1068
+ const checkHasScrolled = () => {
1069
+ state.timeoutCheckFinishedScrollFallback = void 0;
1070
+ const isStillScrollingTo = state.scrollingTo;
1071
+ if (isStillScrollingTo) {
1072
+ numChecks++;
1073
+ if (state.hasScrolled || numChecks > 5) {
1074
+ finishScrollTo(ctx);
1075
+ } else {
1076
+ state.timeoutCheckFinishedScrollFallback = setTimeout(checkHasScrolled, 100);
1077
+ }
1078
+ }
1079
+ };
1080
+ checkHasScrolled();
1081
+ },
1082
+ slowTimeout ? 500 : 100
1083
+ );
1084
+ }
1085
+
1086
+ // src/core/doScrollTo.native.ts
1087
+ function doScrollTo(ctx, params) {
963
1088
  var _a3;
964
- const { noScrollingTo, ...scrollTarget } = params;
1089
+ const state = ctx.state;
1090
+ const { animated, horizontal, offset } = params;
1091
+ const { refScroller } = state;
1092
+ (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
1093
+ animated: !!animated,
1094
+ x: horizontal ? offset : 0,
1095
+ y: horizontal ? 0 : offset
1096
+ });
1097
+ if (!animated) {
1098
+ state.scroll = offset;
1099
+ checkFinishedScrollFallback(ctx);
1100
+ }
1101
+ }
1102
+
1103
+ // src/core/scrollTo.ts
1104
+ function scrollTo(ctx, params) {
1105
+ const state = ctx.state;
1106
+ const { noScrollingTo, forceScroll, ...scrollTarget } = params;
965
1107
  const { animated, isInitialScroll, offset: scrollTargetOffset, precomputedWithViewOffset } = scrollTarget;
966
1108
  const {
967
- refScroller,
968
1109
  props: { horizontal }
969
1110
  } = state;
970
- let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, state, scrollTargetOffset, scrollTarget);
971
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
972
- const maxOffset = Math.max(0, getContentSize(ctx) - state.scrollLength);
973
- offset = Math.min(offset, maxOffset);
1111
+ if (state.animFrameCheckFinishedScroll) {
1112
+ cancelAnimationFrame(ctx.state.animFrameCheckFinishedScroll);
1113
+ }
1114
+ if (state.timeoutCheckFinishedScrollFallback) {
1115
+ clearTimeout(ctx.state.timeoutCheckFinishedScrollFallback);
974
1116
  }
1117
+ let offset = precomputedWithViewOffset ? scrollTargetOffset : calculateOffsetWithOffsetPosition(ctx, scrollTargetOffset, scrollTarget);
1118
+ offset = clampScrollOffset(ctx, offset);
975
1119
  state.scrollHistory.length = 0;
976
1120
  if (!noScrollingTo) {
977
- set$(ctx, "scrollingTo", scrollTarget);
1121
+ state.scrollingTo = scrollTarget;
978
1122
  }
979
1123
  state.scrollPending = offset;
980
- if (!isInitialScroll || Platform2.OS === "android") {
981
- (_a3 = refScroller.current) == null ? void 0 : _a3.scrollTo({
982
- animated: !!animated,
983
- x: horizontal ? offset : 0,
984
- y: horizontal ? 0 : offset
985
- });
986
- }
987
- if (!animated) {
1124
+ if (forceScroll || !isInitialScroll || Platform2.OS === "android") {
1125
+ doScrollTo(ctx, { animated, horizontal, isInitialScroll, offset });
1126
+ } else {
988
1127
  state.scroll = offset;
989
- if (Platform2.OS === "web") {
990
- const unlisten = listen$(ctx, "containersDidLayout", (value) => {
991
- if (value && peek$(ctx, "scrollingTo")) {
992
- finishScrollTo(ctx, state);
993
- unlisten();
994
- }
995
- });
996
- } else {
997
- setTimeout(() => finishScrollTo(ctx, state), 100);
998
- }
999
- if (isInitialScroll) {
1000
- setTimeout(() => {
1001
- state.initialScroll = void 0;
1002
- }, 500);
1003
- }
1004
1128
  }
1005
1129
  }
1006
1130
 
@@ -1009,6 +1133,12 @@ var HYSTERESIS_MULTIPLIER = 1.3;
1009
1133
  var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, context, onReached, setSnapshot) => {
1010
1134
  const absDistance = Math.abs(distance);
1011
1135
  const within = atThreshold || threshold > 0 && absDistance <= threshold;
1136
+ if (wasReached === null) {
1137
+ if (!within && distance >= 0) {
1138
+ return false;
1139
+ }
1140
+ return null;
1141
+ }
1012
1142
  const updateSnapshot = () => {
1013
1143
  setSnapshot == null ? void 0 : setSnapshot({
1014
1144
  atThreshold,
@@ -1041,8 +1171,9 @@ var checkThreshold = (distance, atThreshold, threshold, wasReached, snapshot, co
1041
1171
  };
1042
1172
 
1043
1173
  // src/utils/checkAtBottom.ts
1044
- function checkAtBottom(ctx, state) {
1174
+ function checkAtBottom(ctx) {
1045
1175
  var _a3;
1176
+ const state = ctx.state;
1046
1177
  if (!state) {
1047
1178
  return;
1048
1179
  }
@@ -1115,15 +1246,15 @@ function checkAtTop(state) {
1115
1246
  }
1116
1247
 
1117
1248
  // src/core/updateScroll.ts
1118
- function updateScroll(ctx, state, newScroll, forceUpdate) {
1249
+ function updateScroll(ctx, newScroll, forceUpdate) {
1119
1250
  var _a3;
1120
- const scrollingTo = peek$(ctx, "scrollingTo");
1251
+ const state = ctx.state;
1252
+ const { scrollingTo, scrollAdjustHandler, lastScrollAdjustForHistory } = state;
1121
1253
  state.hasScrolled = true;
1122
1254
  state.lastBatchingAction = Date.now();
1123
1255
  const currentTime = Date.now();
1124
- const adjust = state.scrollAdjustHandler.getAdjust();
1125
- const lastHistoryAdjust = state.lastScrollAdjustForHistory;
1126
- const adjustChanged = lastHistoryAdjust !== void 0 && Math.abs(adjust - lastHistoryAdjust) > 0.1;
1256
+ const adjust = scrollAdjustHandler.getAdjust();
1257
+ const adjustChanged = lastScrollAdjustForHistory !== void 0 && Math.abs(adjust - lastScrollAdjustForHistory) > 0.1;
1127
1258
  if (adjustChanged) {
1128
1259
  state.scrollHistory.length = 0;
1129
1260
  }
@@ -1148,22 +1279,26 @@ function updateScroll(ctx, state, newScroll, forceUpdate) {
1148
1279
  return;
1149
1280
  }
1150
1281
  }
1151
- if (forceUpdate || state.dataChangeNeedsScrollUpdate || Math.abs(state.scroll - state.scrollPrev) > 2) {
1282
+ const lastCalculated = state.scrollLastCalculate;
1283
+ const shouldUpdate = forceUpdate || state.dataChangeNeedsScrollUpdate || state.scrollLastCalculate === void 0 || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
1284
+ if (shouldUpdate) {
1285
+ state.scrollLastCalculate = state.scroll;
1152
1286
  state.ignoreScrollFromMVCPIgnored = false;
1153
1287
  (_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state, { doMVCP: scrollingTo !== void 0 });
1154
- checkAtBottom(ctx, state);
1288
+ checkAtBottom(ctx);
1155
1289
  checkAtTop(state);
1156
1290
  state.dataChangeNeedsScrollUpdate = false;
1157
1291
  }
1158
1292
  }
1159
1293
 
1160
1294
  // src/utils/requestAdjust.ts
1161
- function requestAdjust(ctx, state, positionDiff, dataChanged) {
1295
+ function requestAdjust(ctx, positionDiff, dataChanged) {
1296
+ const state = ctx.state;
1162
1297
  if (Math.abs(positionDiff) > 0.1) {
1163
1298
  const needsScrollWorkaround = Platform2.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff;
1164
1299
  const doit = () => {
1165
1300
  if (needsScrollWorkaround) {
1166
- scrollTo(ctx, state, {
1301
+ scrollTo(ctx, {
1167
1302
  noScrollingTo: true,
1168
1303
  offset: state.scroll
1169
1304
  });
@@ -1176,8 +1311,8 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1176
1311
  };
1177
1312
  state.scroll += positionDiff;
1178
1313
  state.scrollForNextCalculateItemsInView = void 0;
1179
- const didLayout = peek$(ctx, "containersDidLayout");
1180
- if (didLayout) {
1314
+ const readyToRender = peek$(ctx, "readyToRender");
1315
+ if (readyToRender) {
1181
1316
  doit();
1182
1317
  if (Platform2.OS !== "web") {
1183
1318
  const threshold = state.scroll - positionDiff / 2;
@@ -1199,7 +1334,7 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1199
1334
  if (shouldForceUpdate) {
1200
1335
  state.ignoreScrollFromMVCPIgnored = false;
1201
1336
  state.scrollPending = state.scroll;
1202
- updateScroll(ctx, state, state.scroll, true);
1337
+ updateScroll(ctx, state.scroll, true);
1203
1338
  }
1204
1339
  }, delay);
1205
1340
  }
@@ -1214,28 +1349,27 @@ function requestAdjust(ctx, state, positionDiff, dataChanged) {
1214
1349
  var INITIAL_ANCHOR_TOLERANCE = 0.5;
1215
1350
  var INITIAL_ANCHOR_MAX_ATTEMPTS = 4;
1216
1351
  var INITIAL_ANCHOR_SETTLED_TICKS = 2;
1217
- function ensureInitialAnchor(ctx, state) {
1352
+ function ensureInitialAnchor(ctx) {
1218
1353
  var _a3, _b, _c, _d, _e;
1219
- const anchor = state.initialAnchor;
1354
+ const state = ctx.state;
1355
+ const { initialAnchor, didContainersLayout, positions, scroll, scrollLength } = state;
1356
+ const anchor = initialAnchor;
1220
1357
  const item = state.props.data[anchor.index];
1221
- const containersDidLayout = peek$(ctx, "containersDidLayout");
1222
- if (!containersDidLayout) {
1358
+ if (!didContainersLayout) {
1223
1359
  return;
1224
1360
  }
1225
1361
  const id = getId(state, anchor.index);
1226
- if (state.positions.get(id) === void 0) {
1362
+ if (positions.get(id) === void 0) {
1227
1363
  return;
1228
1364
  }
1229
- const size = getItemSize(ctx, state, id, anchor.index, item, true, true);
1365
+ const size = getItemSize(ctx, id, anchor.index, item, true, true);
1230
1366
  if (size === void 0) {
1231
1367
  return;
1232
1368
  }
1233
- const availableSpace = Math.max(0, state.scrollLength - size);
1234
- const desiredOffset = calculateOffsetForIndex(ctx, state, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1235
- const contentSize = getContentSize(ctx);
1236
- const maxOffset = Math.max(0, contentSize - state.scrollLength);
1237
- const clampedDesiredOffset = Math.max(0, Math.min(desiredOffset, maxOffset));
1238
- const delta = clampedDesiredOffset - state.scroll;
1369
+ const availableSpace = Math.max(0, scrollLength - size);
1370
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1371
+ const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset);
1372
+ const delta = clampedDesiredOffset - scroll;
1239
1373
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
1240
1374
  const settledTicks = ((_c = anchor.settledTicks) != null ? _c : 0) + 1;
1241
1375
  if (settledTicks >= INITIAL_ANCHOR_SETTLED_TICKS) {
@@ -1259,18 +1393,21 @@ function ensureInitialAnchor(ctx, state) {
1259
1393
  lastDelta: delta,
1260
1394
  settledTicks: 0
1261
1395
  });
1262
- requestAdjust(ctx, state, delta);
1396
+ requestAdjust(ctx, delta);
1397
+ requestAnimationFrame(() => finishScrollTo(ctx));
1263
1398
  }
1264
1399
 
1265
1400
  // src/core/mvcp.ts
1266
- function prepareMVCP(ctx, state, dataChanged) {
1401
+ function prepareMVCP(ctx, dataChanged) {
1402
+ const state = ctx.state;
1267
1403
  const { idsInView, positions, props } = state;
1268
1404
  const { maintainVisibleContentPosition } = props;
1269
- const scrollingTo = peek$(ctx, "scrollingTo");
1405
+ const scrollingTo = state.scrollingTo;
1270
1406
  let prevPosition;
1271
1407
  let targetId;
1272
1408
  const idsInViewWithPositions = [];
1273
1409
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1410
+ const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1274
1411
  const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1275
1412
  const indexByKey = state.indexByKey;
1276
1413
  if (shouldMVCP) {
@@ -1279,7 +1416,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1279
1416
  return void 0;
1280
1417
  }
1281
1418
  targetId = getId(state, scrollTarget);
1282
- } else if (idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
1419
+ } else if (idsInView.length > 0 && state.didContainersLayout) {
1283
1420
  if (dataChanged) {
1284
1421
  for (let i = 0; i < idsInView.length; i++) {
1285
1422
  const id = idsInView[i];
@@ -1296,7 +1433,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1296
1433
  prevPosition = positions.get(targetId);
1297
1434
  }
1298
1435
  return () => {
1299
- let positionDiff;
1436
+ let positionDiff = 0;
1300
1437
  if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1301
1438
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1302
1439
  const { id, position } = idsInViewWithPositions[i];
@@ -1322,16 +1459,28 @@ function prepareMVCP(ctx, state, dataChanged) {
1322
1459
  positionDiff = diff;
1323
1460
  }
1324
1461
  }
1325
- if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1326
- requestAdjust(ctx, state, positionDiff, dataChanged && maintainVisibleContentPosition);
1462
+ if (scrollingToViewPosition && scrollingToViewPosition > 0) {
1463
+ const newSize = getItemSize(ctx, targetId, scrollTarget, state.props.data[scrollTarget]);
1464
+ const prevSize = scrollingTo == null ? void 0 : scrollingTo.itemSize;
1465
+ if (newSize !== void 0 && prevSize !== void 0 && newSize !== (scrollingTo == null ? void 0 : scrollingTo.itemSize)) {
1466
+ const diff = newSize - prevSize;
1467
+ if (diff !== 0) {
1468
+ positionDiff += (newSize - prevSize) * scrollingToViewPosition;
1469
+ scrollingTo.itemSize = newSize;
1470
+ }
1471
+ }
1472
+ }
1473
+ if (Math.abs(positionDiff) > 0.1) {
1474
+ requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1327
1475
  }
1328
1476
  };
1329
1477
  }
1330
1478
  }
1331
1479
 
1332
1480
  // src/core/prepareColumnStartState.ts
1333
- function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1481
+ function prepareColumnStartState(ctx, startIndex, useAverageSize) {
1334
1482
  var _a3;
1483
+ const state = ctx.state;
1335
1484
  const numColumns = peek$(ctx, "numColumns");
1336
1485
  let rowStartIndex = startIndex;
1337
1486
  const columnAtStart = state.columns.get(state.idCache[startIndex]);
@@ -1346,7 +1495,7 @@ function prepareColumnStartState(ctx, state, startIndex, useAverageSize) {
1346
1495
  const prevId = state.idCache[prevIndex];
1347
1496
  const prevPosition = (_a3 = state.positions.get(prevId)) != null ? _a3 : 0;
1348
1497
  const prevRowStart = findRowStartIndex(state, numColumns, prevIndex);
1349
- const prevRowHeight = calculateRowMaxSize(ctx, state, prevRowStart, prevIndex, useAverageSize);
1498
+ const prevRowHeight = calculateRowMaxSize(ctx, prevRowStart, prevIndex, useAverageSize);
1350
1499
  currentRowTop = prevPosition + prevRowHeight;
1351
1500
  }
1352
1501
  return {
@@ -1369,7 +1518,8 @@ function findRowStartIndex(state, numColumns, index) {
1369
1518
  }
1370
1519
  return rowStart;
1371
1520
  }
1372
- function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1521
+ function calculateRowMaxSize(ctx, startIndex, endIndex, useAverageSize) {
1522
+ const state = ctx.state;
1373
1523
  if (endIndex < startIndex) {
1374
1524
  return 0;
1375
1525
  }
@@ -1383,7 +1533,7 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1383
1533
  continue;
1384
1534
  }
1385
1535
  const id = state.idCache[i];
1386
- const size = getItemSize(ctx, state, id, i, data[i], useAverageSize);
1536
+ const size = getItemSize(ctx, id, i, data[i], useAverageSize);
1387
1537
  if (size > maxSize) {
1388
1538
  maxSize = size;
1389
1539
  }
@@ -1392,22 +1542,23 @@ function calculateRowMaxSize(ctx, state, startIndex, endIndex, useAverageSize) {
1392
1542
  }
1393
1543
 
1394
1544
  // src/core/updateTotalSize.ts
1395
- function updateTotalSize(ctx, state) {
1545
+ function updateTotalSize(ctx) {
1546
+ const state = ctx.state;
1396
1547
  const {
1397
1548
  positions,
1398
1549
  props: { data }
1399
1550
  } = state;
1400
1551
  if (data.length === 0) {
1401
- addTotalSize(ctx, state, null, 0);
1552
+ addTotalSize(ctx, null, 0);
1402
1553
  } else {
1403
1554
  const lastId = getId(state, data.length - 1);
1404
1555
  if (lastId !== void 0) {
1405
1556
  const lastPosition = positions.get(lastId);
1406
1557
  if (lastPosition !== void 0) {
1407
- const lastSize = getItemSize(ctx, state, lastId, data.length - 1, data[data.length - 1]);
1558
+ const lastSize = getItemSize(ctx, lastId, data.length - 1, data[data.length - 1]);
1408
1559
  if (lastSize !== void 0) {
1409
1560
  const totalSize = lastPosition + lastSize;
1410
- addTotalSize(ctx, state, null, totalSize);
1561
+ addTotalSize(ctx, null, totalSize);
1411
1562
  }
1412
1563
  }
1413
1564
  }
@@ -1453,7 +1604,8 @@ var getScrollVelocity = (state) => {
1453
1604
  };
1454
1605
 
1455
1606
  // src/utils/updateSnapToOffsets.ts
1456
- function updateSnapToOffsets(ctx, state) {
1607
+ function updateSnapToOffsets(ctx) {
1608
+ const state = ctx.state;
1457
1609
  const {
1458
1610
  positions,
1459
1611
  props: { snapToIndices }
@@ -1468,30 +1620,30 @@ function updateSnapToOffsets(ctx, state) {
1468
1620
  }
1469
1621
 
1470
1622
  // src/core/updateItemPositions.ts
1471
- function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1623
+ function updateItemPositions(ctx, dataChanged, { startIndex, scrollBottomBuffered, forceFullUpdate = false, doMVCP } = {
1472
1624
  doMVCP: false,
1473
1625
  forceFullUpdate: false,
1474
1626
  scrollBottomBuffered: -1,
1475
1627
  startIndex: 0
1476
1628
  }) {
1477
1629
  var _a3, _b, _c, _d, _e;
1630
+ const state = ctx.state;
1478
1631
  const {
1479
1632
  columns,
1480
1633
  indexByKey,
1481
1634
  positions,
1482
1635
  idCache,
1483
1636
  sizesKnown,
1484
- props: { getEstimatedItemSize, snapToIndices, enableAverages }
1637
+ props: { data, getEstimatedItemSize, snapToIndices },
1638
+ scrollingTo
1485
1639
  } = state;
1486
- const data = state.props.data;
1487
1640
  const dataLength = data.length;
1488
1641
  const numColumns = peek$(ctx, "numColumns");
1489
- const scrollingTo = peek$(ctx, "scrollingTo");
1490
1642
  const hasColumns = numColumns > 1;
1491
1643
  const indexByKeyForChecking = IS_DEV ? /* @__PURE__ */ new Map() : void 0;
1492
1644
  const shouldOptimize = !forceFullUpdate && !dataChanged && Math.abs(getScrollVelocity(state)) > 0;
1493
1645
  const maxVisibleArea = scrollBottomBuffered + 1e3;
1494
- const useAverageSize = enableAverages && !getEstimatedItemSize;
1646
+ const useAverageSize = !getEstimatedItemSize;
1495
1647
  const preferCachedSize = !doMVCP || dataChanged || state.scrollAdjustHandler.getAdjust() !== 0 || ((_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0) !== 0;
1496
1648
  let currentRowTop = 0;
1497
1649
  let column = 1;
@@ -1500,7 +1652,6 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1500
1652
  if (hasColumns) {
1501
1653
  const { startIndex: processedStartIndex, currentRowTop: initialRowTop } = prepareColumnStartState(
1502
1654
  ctx,
1503
- state,
1504
1655
  startIndex,
1505
1656
  useAverageSize
1506
1657
  );
@@ -1510,7 +1661,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1510
1661
  const prevIndex = startIndex - 1;
1511
1662
  const prevId = getId(state, prevIndex);
1512
1663
  const prevPosition = (_b = positions.get(prevId)) != null ? _b : 0;
1513
- const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, state, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1664
+ const prevSize = (_c = sizesKnown.get(prevId)) != null ? _c : getItemSize(ctx, prevId, prevIndex, data[prevIndex], useAverageSize, preferCachedSize);
1514
1665
  currentRowTop = prevPosition + prevSize;
1515
1666
  }
1516
1667
  }
@@ -1527,7 +1678,7 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1527
1678
  breakAt = i + itemsPerRow + 10;
1528
1679
  }
1529
1680
  const id = (_d = idCache[i]) != null ? _d : getId(state, i);
1530
- const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, state, id, i, data[i], useAverageSize, preferCachedSize);
1681
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(ctx, id, i, data[i], useAverageSize, preferCachedSize);
1531
1682
  if (IS_DEV && needsIndexByKey) {
1532
1683
  if (indexByKeyForChecking.has(id)) {
1533
1684
  console.error(
@@ -1536,7 +1687,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1536
1687
  }
1537
1688
  indexByKeyForChecking.set(id, i);
1538
1689
  }
1539
- positions.set(id, currentRowTop);
1690
+ if (currentRowTop !== positions.get(id)) {
1691
+ positions.set(id, currentRowTop);
1692
+ notifyPosition$(ctx, id, currentRowTop);
1693
+ }
1540
1694
  if (needsIndexByKey) {
1541
1695
  indexByKey.set(id, i);
1542
1696
  }
@@ -1556,10 +1710,10 @@ function updateItemPositions(ctx, state, dataChanged, { startIndex, scrollBottom
1556
1710
  }
1557
1711
  }
1558
1712
  if (!didBreakEarly) {
1559
- updateTotalSize(ctx, state);
1713
+ updateTotalSize(ctx);
1560
1714
  }
1561
1715
  if (snapToIndices) {
1562
- updateSnapToOffsets(ctx, state);
1716
+ updateSnapToOffsets(ctx);
1563
1717
  }
1564
1718
  }
1565
1719
 
@@ -1637,7 +1791,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1637
1791
  if (previousViewableItems) {
1638
1792
  for (const viewToken of previousViewableItems) {
1639
1793
  const containerId = findContainerId(ctx, viewToken.key);
1640
- if (!isViewable(
1794
+ if (!checkIsViewable(
1641
1795
  state,
1642
1796
  ctx,
1643
1797
  viewabilityConfig,
@@ -1658,7 +1812,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1658
1812
  if (item) {
1659
1813
  const key = getId(state, i);
1660
1814
  const containerId = findContainerId(ctx, key);
1661
- if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1815
+ if (checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1662
1816
  const viewToken = {
1663
1817
  containerId,
1664
1818
  index: i,
@@ -1718,11 +1872,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1718
1872
  const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
1719
1873
  const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
1720
1874
  const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1721
- const isViewable2 = percent >= viewablePercentThreshold;
1875
+ const isViewable = percent >= viewablePercentThreshold;
1722
1876
  const value = {
1723
1877
  containerId,
1724
1878
  index,
1725
- isViewable: isViewable2,
1879
+ isViewable,
1726
1880
  item,
1727
1881
  key,
1728
1882
  percentOfScroller,
@@ -1741,8 +1895,11 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1741
1895
  }
1742
1896
  return value;
1743
1897
  }
1744
- function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1745
- const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1898
+ function checkIsViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1899
+ let value = ctx.mapViewabilityAmountValues.get(containerId);
1900
+ if (!value || value.key !== key) {
1901
+ value = computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1902
+ }
1746
1903
  return value.isViewable;
1747
1904
  }
1748
1905
  function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
@@ -1770,8 +1927,9 @@ function checkAllSizesKnown(state) {
1770
1927
  }
1771
1928
 
1772
1929
  // src/utils/findAvailableContainers.ts
1773
- function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1930
+ function findAvailableContainers(ctx, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1774
1931
  const numContainers = peek$(ctx, "numContainers");
1932
+ const state = ctx.state;
1775
1933
  const { stickyContainerPool, containerItemTypes } = state;
1776
1934
  const result = [];
1777
1935
  const availableContainers = [];
@@ -1815,14 +1973,14 @@ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffer
1815
1973
  continue;
1816
1974
  }
1817
1975
  const key = peek$(ctx, `containerItemKey${u}`);
1818
- let isOk = key === void 0;
1819
- if (!isOk && pendingRemovalSet.has(u)) {
1820
- pendingRemovalSet.delete(u);
1821
- pendingRemovalChanged = true;
1822
- const requiredType = neededTypes[typeIndex];
1823
- isOk = canReuseContainer(u, requiredType);
1824
- }
1825
- if (isOk) {
1976
+ const requiredType = neededTypes[typeIndex];
1977
+ const isPending = key !== void 0 && pendingRemovalSet.has(u);
1978
+ const canUse = key === void 0 || isPending && canReuseContainer(u, requiredType);
1979
+ if (canUse) {
1980
+ if (isPending) {
1981
+ pendingRemovalSet.delete(u);
1982
+ pendingRemovalChanged = true;
1983
+ }
1826
1984
  result.push(u);
1827
1985
  if (requiredItemTypes) {
1828
1986
  typeIndex++;
@@ -1891,21 +2049,26 @@ function comparatorByDistance(a, b) {
1891
2049
  }
1892
2050
 
1893
2051
  // src/core/scrollToIndex.ts
1894
- function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1895
- if (index >= state.props.data.length) {
1896
- index = state.props.data.length - 1;
2052
+ function scrollToIndex(ctx, { index, viewOffset = 0, animated = true, viewPosition }) {
2053
+ const state = ctx.state;
2054
+ const { data } = state.props;
2055
+ if (index >= data.length) {
2056
+ index = data.length - 1;
1897
2057
  } else if (index < 0) {
1898
2058
  index = 0;
1899
2059
  }
1900
- const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
1901
- const isLast = index === state.props.data.length - 1;
2060
+ const firstIndexOffset = calculateOffsetForIndex(ctx, index);
2061
+ const isLast = index === data.length - 1;
1902
2062
  if (isLast && viewPosition === void 0) {
1903
2063
  viewPosition = 1;
1904
2064
  }
1905
2065
  state.scrollForNextCalculateItemsInView = void 0;
1906
- scrollTo(ctx, state, {
2066
+ const targetId = getId(state, index);
2067
+ const itemSize = getItemSize(ctx, targetId, index, state.props.data[index]);
2068
+ scrollTo(ctx, {
1907
2069
  animated,
1908
2070
  index,
2071
+ itemSize,
1909
2072
  offset: firstIndexOffset,
1910
2073
  viewOffset,
1911
2074
  viewPosition: viewPosition != null ? viewPosition : 0
@@ -1913,29 +2076,30 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1913
2076
  }
1914
2077
 
1915
2078
  // src/utils/setDidLayout.ts
1916
- function setDidLayout(ctx, state) {
2079
+ function setDidLayout(ctx) {
2080
+ const state = ctx.state;
1917
2081
  const {
1918
2082
  loadStartTime,
1919
2083
  initialScroll,
1920
2084
  props: { onLoad }
1921
2085
  } = state;
1922
2086
  state.queuedInitialLayout = true;
1923
- checkAtBottom(ctx, state);
2087
+ checkAtBottom(ctx);
1924
2088
  const setIt = () => {
1925
- set$(ctx, "containersDidLayout", true);
2089
+ setInitialRenderState(ctx, { didLayout: true });
1926
2090
  if (onLoad) {
1927
2091
  onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1928
2092
  }
1929
2093
  };
1930
2094
  if (Platform2.OS === "android" && initialScroll) {
1931
2095
  if (IsNewArchitecture) {
1932
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2096
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1933
2097
  requestAnimationFrame(() => {
1934
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2098
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1935
2099
  setIt();
1936
2100
  });
1937
2101
  } else {
1938
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2102
+ scrollToIndex(ctx, { ...initialScroll, animated: false });
1939
2103
  setIt();
1940
2104
  }
1941
2105
  } else {
@@ -1958,15 +2122,17 @@ function findCurrentStickyIndex(stickyArray, scroll, state) {
1958
2122
  }
1959
2123
  return -1;
1960
2124
  }
1961
- function getActiveStickyIndices(ctx, state, stickyHeaderIndices) {
2125
+ function getActiveStickyIndices(ctx, stickyHeaderIndices) {
2126
+ const state = ctx.state;
1962
2127
  return new Set(
1963
2128
  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))
1964
2129
  );
1965
2130
  }
1966
- function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
2131
+ function handleStickyActivation(ctx, stickyHeaderIndices, stickyArray, currentStickyIdx, needNewContainers, startBuffered, endBuffered) {
1967
2132
  var _a3;
1968
- const activeIndices = getActiveStickyIndices(ctx, state, stickyHeaderIndices);
1969
- state.activeStickyIndex = currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : void 0;
2133
+ const state = ctx.state;
2134
+ const activeIndices = getActiveStickyIndices(ctx, stickyHeaderIndices);
2135
+ set$(ctx, "activeStickyIndex", currentStickyIdx >= 0 ? stickyArray[currentStickyIdx] : -1);
1970
2136
  for (let offset = 0; offset <= 1; offset++) {
1971
2137
  const idx = currentStickyIdx - offset;
1972
2138
  if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
@@ -1977,8 +2143,9 @@ function handleStickyActivation(ctx, state, stickyHeaderIndices, stickyArray, cu
1977
2143
  }
1978
2144
  }
1979
2145
  }
1980
- function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
2146
+ function handleStickyRecycling(ctx, stickyArray, scroll, scrollBuffer, currentStickyIdx, pendingRemoval) {
1981
2147
  var _a3, _b, _c;
2148
+ const state = ctx.state;
1982
2149
  for (const containerIndex of state.stickyContainerPool) {
1983
2150
  const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
1984
2151
  const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
@@ -2002,7 +2169,7 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2002
2169
  const currentId = (_b = state.idCache[itemIndex]) != null ? _b : getId(state, itemIndex);
2003
2170
  if (currentId) {
2004
2171
  const currentPos = state.positions.get(currentId);
2005
- const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, state, currentId, itemIndex, state.props.data[itemIndex]);
2172
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(ctx, currentId, itemIndex, state.props.data[itemIndex]);
2006
2173
  shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
2007
2174
  }
2008
2175
  }
@@ -2011,7 +2178,8 @@ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, cu
2011
2178
  }
2012
2179
  }
2013
2180
  }
2014
- function calculateItemsInView(ctx, state, params = {}) {
2181
+ function calculateItemsInView(ctx, params = {}) {
2182
+ const state = ctx.state;
2015
2183
  unstable_batchedUpdates(() => {
2016
2184
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2017
2185
  const {
@@ -2035,8 +2203,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2035
2203
  const stickyIndicesSet = state.props.stickyIndicesSet || /* @__PURE__ */ new Set();
2036
2204
  const prevNumContainers = peek$(ctx, "numContainers");
2037
2205
  if (!data || scrollLength === 0 || !prevNumContainers) {
2038
- if (state.initialAnchor) {
2039
- ensureInitialAnchor(ctx, state);
2206
+ if (!IsNewArchitecture && state.initialAnchor) {
2207
+ ensureInitialAnchor(ctx);
2040
2208
  }
2041
2209
  return;
2042
2210
  }
@@ -2051,15 +2219,14 @@ function calculateItemsInView(ctx, state, params = {}) {
2051
2219
  if (!queuedInitialLayout && initialScroll) {
2052
2220
  const updatedOffset = calculateOffsetWithOffsetPosition(
2053
2221
  ctx,
2054
- state,
2055
- calculateOffsetForIndex(ctx, state, initialScroll.index),
2222
+ calculateOffsetForIndex(ctx, initialScroll.index),
2056
2223
  initialScroll
2057
2224
  );
2058
2225
  scrollState = updatedOffset;
2059
2226
  }
2060
2227
  const scrollAdjustPending = (_a3 = peek$(ctx, "scrollAdjustPending")) != null ? _a3 : 0;
2061
2228
  const scrollAdjustPad = scrollAdjustPending - topPad;
2062
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
2229
+ let scroll = Math.round(scrollState + scrollExtra + scrollAdjustPad);
2063
2230
  if (scroll + scrollLength > totalSize) {
2064
2231
  scroll = Math.max(0, totalSize - scrollLength);
2065
2232
  }
@@ -2067,11 +2234,12 @@ function calculateItemsInView(ctx, state, params = {}) {
2067
2234
  set$(ctx, "debugRawScroll", scrollState);
2068
2235
  set$(ctx, "debugComputedScroll", scroll);
2069
2236
  }
2070
- const previousStickyIndex = state.activeStickyIndex;
2237
+ const previousStickyIndex = peek$(ctx, "activeStickyIndex");
2071
2238
  const currentStickyIdx = stickyIndicesArr.length > 0 ? findCurrentStickyIndex(stickyIndicesArr, scroll, state) : -1;
2072
- const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : void 0;
2073
- state.activeStickyIndex = nextActiveStickyIndex;
2074
- set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2239
+ const nextActiveStickyIndex = currentStickyIdx >= 0 ? stickyIndicesArr[currentStickyIdx] : -1;
2240
+ if (currentStickyIdx >= 0 || previousStickyIndex >= 0) {
2241
+ set$(ctx, "activeStickyIndex", nextActiveStickyIndex);
2242
+ }
2075
2243
  let scrollBufferTop = scrollBuffer;
2076
2244
  let scrollBufferBottom = scrollBuffer;
2077
2245
  if (speed > 0 || speed === 0 && scroll < Math.max(50, scrollBuffer)) {
@@ -2084,23 +2252,23 @@ function calculateItemsInView(ctx, state, params = {}) {
2084
2252
  const scrollTopBuffered = scroll - scrollBufferTop;
2085
2253
  const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
2086
2254
  const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
2087
- if (!dataChanged && scrollForNextCalculateItemsInView) {
2255
+ if (!dataChanged && !forceFullItemPositions && scrollForNextCalculateItemsInView) {
2088
2256
  const { top, bottom } = scrollForNextCalculateItemsInView;
2089
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
2090
- if (state.initialAnchor) {
2091
- ensureInitialAnchor(ctx, state);
2257
+ if ((top === null || scrollTopBuffered > top) && (bottom === null || scrollBottomBuffered < bottom)) {
2258
+ if (!IsNewArchitecture && state.initialAnchor) {
2259
+ ensureInitialAnchor(ctx);
2092
2260
  }
2093
2261
  return;
2094
2262
  }
2095
2263
  }
2096
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
2264
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, dataChanged) : void 0;
2097
2265
  if (dataChanged) {
2098
2266
  indexByKey.clear();
2099
2267
  idCache.length = 0;
2100
2268
  positions.clear();
2101
2269
  }
2102
- const startIndex = dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2103
- updateItemPositions(ctx, state, dataChanged, {
2270
+ const startIndex = forceFullItemPositions || dataChanged ? 0 : (_b = minIndexSizeChanged != null ? minIndexSizeChanged : state.startBuffered) != null ? _b : 0;
2271
+ updateItemPositions(ctx, dataChanged, {
2104
2272
  doMVCP,
2105
2273
  forceFullUpdate: !!forceFullItemPositions,
2106
2274
  scrollBottomBuffered,
@@ -2119,9 +2287,9 @@ function calculateItemsInView(ctx, state, params = {}) {
2119
2287
  for (let i = loopStart; i >= 0; i--) {
2120
2288
  const id = (_c = idCache[i]) != null ? _c : getId(state, i);
2121
2289
  const top = positions.get(id);
2122
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, state, id, i, data[i]);
2290
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(ctx, id, i, data[i]);
2123
2291
  const bottom = top + size;
2124
- if (bottom > scroll - scrollBuffer) {
2292
+ if (bottom > scroll - scrollBufferTop) {
2125
2293
  loopStart = i;
2126
2294
  } else {
2127
2295
  break;
@@ -2146,7 +2314,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2146
2314
  const dataLength = data.length;
2147
2315
  for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
2148
2316
  const id = (_e = idCache[i]) != null ? _e : getId(state, i);
2149
- const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, state, id, i, data[i]);
2317
+ const size = (_f = sizes.get(id)) != null ? _f : getItemSize(ctx, id, i, data[i]);
2150
2318
  const top = positions.get(id);
2151
2319
  if (!foundEnd) {
2152
2320
  if (startNoBuffer === null && top + size > scroll) {
@@ -2158,7 +2326,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2158
2326
  if (startBuffered === null && top + size > scrollTopBuffered) {
2159
2327
  startBuffered = i;
2160
2328
  startBufferedId = id;
2161
- nextTop = top;
2329
+ if (scrollTopBuffered < 0) {
2330
+ nextTop = null;
2331
+ } else {
2332
+ nextTop = top;
2333
+ }
2162
2334
  }
2163
2335
  if (startNoBuffer !== null) {
2164
2336
  if (top <= scrollBottom) {
@@ -2166,7 +2338,11 @@ function calculateItemsInView(ctx, state, params = {}) {
2166
2338
  }
2167
2339
  if (top <= scrollBottomBuffered) {
2168
2340
  endBuffered = i;
2169
- nextBottom = top + size;
2341
+ if (scrollBottomBuffered > totalSize) {
2342
+ nextBottom = null;
2343
+ } else {
2344
+ nextBottom = top + size;
2345
+ }
2170
2346
  } else {
2171
2347
  foundEnd = true;
2172
2348
  }
@@ -2193,7 +2369,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2193
2369
  top: nextTop
2194
2370
  } : void 0;
2195
2371
  }
2196
- const numContainers = peek$(ctx, "numContainers");
2372
+ let numContainers = prevNumContainers;
2197
2373
  const pendingRemoval = [];
2198
2374
  if (dataChanged) {
2199
2375
  for (let i = 0; i < numContainers; i++) {
@@ -2204,7 +2380,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2204
2380
  }
2205
2381
  }
2206
2382
  if (startBuffered !== null && endBuffered !== null) {
2207
- let numContainers2 = prevNumContainers;
2208
2383
  const needNewContainers = [];
2209
2384
  for (let i = startBuffered; i <= endBuffered; i++) {
2210
2385
  const id = (_h = idCache[i]) != null ? _h : getId(state, i);
@@ -2215,7 +2390,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2215
2390
  if (stickyIndicesArr.length > 0) {
2216
2391
  handleStickyActivation(
2217
2392
  ctx,
2218
- state,
2219
2393
  stickyIndicesSet,
2220
2394
  stickyIndicesArr,
2221
2395
  currentStickyIdx,
@@ -2223,9 +2397,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2223
2397
  startBuffered,
2224
2398
  endBuffered
2225
2399
  );
2226
- } else {
2227
- state.activeStickyIndex = void 0;
2228
- set$(ctx, "activeStickyIndex", void 0);
2400
+ } else if (previousStickyIndex !== -1) {
2401
+ set$(ctx, "activeStickyIndex", -1);
2229
2402
  }
2230
2403
  if (needNewContainers.length > 0) {
2231
2404
  const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
@@ -2234,7 +2407,6 @@ function calculateItemsInView(ctx, state, params = {}) {
2234
2407
  }) : void 0;
2235
2408
  const availableContainers = findAvailableContainers(
2236
2409
  ctx,
2237
- state,
2238
2410
  needNewContainers.length,
2239
2411
  startBuffered,
2240
2412
  endBuffered,
@@ -2256,29 +2428,30 @@ function calculateItemsInView(ctx, state, params = {}) {
2256
2428
  state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
2257
2429
  }
2258
2430
  containerItemKeys.add(id);
2431
+ const containerSticky = `containerSticky${containerIndex}`;
2259
2432
  if (stickyIndicesSet.has(i)) {
2260
- set$(ctx, `containerSticky${containerIndex}`, true);
2433
+ set$(ctx, containerSticky, true);
2261
2434
  const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2262
2435
  set$(ctx, `containerStickyOffset${containerIndex}`, topPadding);
2263
2436
  state.stickyContainerPool.add(containerIndex);
2264
- } else {
2265
- set$(ctx, `containerSticky${containerIndex}`, false);
2437
+ } else if (peek$(ctx, containerSticky)) {
2438
+ set$(ctx, containerSticky, false);
2266
2439
  state.stickyContainerPool.delete(containerIndex);
2267
2440
  }
2268
- if (containerIndex >= numContainers2) {
2269
- numContainers2 = containerIndex + 1;
2441
+ if (containerIndex >= numContainers) {
2442
+ numContainers = containerIndex + 1;
2270
2443
  }
2271
2444
  }
2272
- if (numContainers2 !== prevNumContainers) {
2273
- set$(ctx, "numContainers", numContainers2);
2274
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
2275
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
2445
+ if (numContainers !== prevNumContainers) {
2446
+ set$(ctx, "numContainers", numContainers);
2447
+ if (numContainers > peek$(ctx, "numContainersPooled")) {
2448
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers * 1.5));
2276
2449
  }
2277
2450
  }
2278
2451
  }
2279
2452
  }
2280
2453
  if (stickyIndicesArr.length > 0) {
2281
- handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2454
+ handleStickyRecycling(ctx, stickyIndicesArr, scroll, scrollBuffer, currentStickyIdx, pendingRemoval);
2282
2455
  }
2283
2456
  let didChangePositions = false;
2284
2457
  for (let i = 0; i < numContainers; i++) {
@@ -2330,7 +2503,7 @@ function calculateItemsInView(ctx, state, params = {}) {
2330
2503
  }
2331
2504
  if (!queuedInitialLayout && endBuffered !== null) {
2332
2505
  if (checkAllSizesKnown(state)) {
2333
- setDidLayout(ctx, state);
2506
+ setDidLayout(ctx);
2334
2507
  }
2335
2508
  }
2336
2509
  if (viewabilityConfigCallbackPairs) {
@@ -2343,8 +2516,8 @@ function calculateItemsInView(ctx, state, params = {}) {
2343
2516
  }
2344
2517
  }
2345
2518
  });
2346
- if (state.initialAnchor) {
2347
- ensureInitialAnchor(ctx, state);
2519
+ if (!IsNewArchitecture && state.initialAnchor) {
2520
+ ensureInitialAnchor(ctx);
2348
2521
  }
2349
2522
  }
2350
2523
 
@@ -2369,19 +2542,22 @@ function checkActualChange(state, dataProp, previousData) {
2369
2542
  }
2370
2543
 
2371
2544
  // src/core/doMaintainScrollAtEnd.ts
2372
- function doMaintainScrollAtEnd(ctx, state, animated) {
2545
+ function doMaintainScrollAtEnd(ctx, animated) {
2546
+ const state = ctx.state;
2373
2547
  const {
2548
+ didContainersLayout,
2549
+ isAtEnd,
2374
2550
  refScroller,
2375
2551
  props: { maintainScrollAtEnd }
2376
2552
  } = state;
2377
- if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
2553
+ if (isAtEnd && maintainScrollAtEnd && didContainersLayout) {
2378
2554
  const paddingTop = peek$(ctx, "alignItemsPaddingTop");
2379
2555
  if (paddingTop > 0) {
2380
2556
  state.scroll = 0;
2381
2557
  }
2382
2558
  requestAnimationFrame(() => {
2383
2559
  var _a3;
2384
- if (state == null ? void 0 : state.isAtEnd) {
2560
+ if (state.isAtEnd) {
2385
2561
  state.maintainingScrollAtEnd = true;
2386
2562
  (_a3 = refScroller.current) == null ? void 0 : _a3.scrollToEnd({
2387
2563
  animated
@@ -2452,28 +2628,30 @@ function updateAveragesOnDataChange(state, oldData, newData) {
2452
2628
  }
2453
2629
 
2454
2630
  // src/core/checkResetContainers.ts
2455
- function checkResetContainers(ctx, state, dataProp) {
2631
+ function checkResetContainers(ctx, dataProp) {
2632
+ const state = ctx.state;
2456
2633
  const { previousData } = state;
2457
2634
  if (previousData) {
2458
2635
  updateAveragesOnDataChange(state, previousData, dataProp);
2459
2636
  }
2460
2637
  const { maintainScrollAtEnd } = state.props;
2461
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2638
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2462
2639
  const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2463
- const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state, false);
2640
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, false);
2464
2641
  if (!didMaintainScrollAtEnd && previousData && dataProp.length > previousData.length) {
2465
2642
  state.isEndReached = false;
2466
2643
  }
2467
2644
  if (!didMaintainScrollAtEnd) {
2468
2645
  checkAtTop(state);
2469
- checkAtBottom(ctx, state);
2646
+ checkAtBottom(ctx);
2470
2647
  }
2471
2648
  delete state.previousData;
2472
2649
  }
2473
2650
 
2474
2651
  // src/core/doInitialAllocateContainers.ts
2475
- function doInitialAllocateContainers(ctx, state) {
2652
+ function doInitialAllocateContainers(ctx) {
2476
2653
  var _a3, _b, _c;
2654
+ const state = ctx.state;
2477
2655
  const {
2478
2656
  scrollLength,
2479
2657
  props: {
@@ -2511,10 +2689,10 @@ function doInitialAllocateContainers(ctx, state) {
2511
2689
  if (!IsNewArchitecture || state.lastLayout) {
2512
2690
  if (state.initialScroll) {
2513
2691
  requestAnimationFrame(() => {
2514
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2692
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2515
2693
  });
2516
2694
  } else {
2517
- calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2695
+ calculateItemsInView(ctx, { dataChanged: true, doMVCP: true });
2518
2696
  }
2519
2697
  }
2520
2698
  return true;
@@ -2522,7 +2700,8 @@ function doInitialAllocateContainers(ctx, state) {
2522
2700
  }
2523
2701
 
2524
2702
  // src/core/handleLayout.ts
2525
- function handleLayout(ctx, state, layout, setCanRender) {
2703
+ function handleLayout(ctx, layout, setCanRender) {
2704
+ const state = ctx.state;
2526
2705
  const { maintainScrollAtEnd } = state.props;
2527
2706
  const measuredLength = layout[state.props.horizontal ? "width" : "height"];
2528
2707
  const previousLength = state.scrollLength;
@@ -2538,19 +2717,19 @@ function handleLayout(ctx, state, layout, setCanRender) {
2538
2717
  state.lastBatchingAction = Date.now();
2539
2718
  state.scrollForNextCalculateItemsInView = void 0;
2540
2719
  if (scrollLength > 0) {
2541
- doInitialAllocateContainers(ctx, state);
2720
+ doInitialAllocateContainers(ctx);
2542
2721
  }
2543
2722
  if (needsCalculate) {
2544
- calculateItemsInView(ctx, state, { doMVCP: true });
2723
+ calculateItemsInView(ctx, { doMVCP: true });
2545
2724
  }
2546
2725
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
2547
2726
  set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
2548
2727
  }
2549
2728
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
2550
- doMaintainScrollAtEnd(ctx, state, false);
2729
+ doMaintainScrollAtEnd(ctx, false);
2551
2730
  }
2552
- updateAlignItemsPaddingTop(ctx, state);
2553
- checkAtBottom(ctx, state);
2731
+ updateAlignItemsPaddingTop(ctx);
2732
+ checkAtBottom(ctx);
2554
2733
  checkAtTop(state);
2555
2734
  if (state) {
2556
2735
  state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
@@ -2566,8 +2745,9 @@ function handleLayout(ctx, state, layout, setCanRender) {
2566
2745
  }
2567
2746
 
2568
2747
  // src/core/onScroll.ts
2569
- function onScroll(ctx, state, event) {
2748
+ function onScroll(ctx, event) {
2570
2749
  var _a3, _b, _c;
2750
+ const state = ctx.state;
2571
2751
  const {
2572
2752
  scrollProcessingEnabled,
2573
2753
  props: { onScroll: onScrollProp }
@@ -2578,9 +2758,23 @@ function onScroll(ctx, state, event) {
2578
2758
  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) {
2579
2759
  return;
2580
2760
  }
2581
- const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2761
+ let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2582
2762
  state.scrollPending = newScroll;
2583
- updateScroll(ctx, state, newScroll);
2763
+ if (state.scrollingTo) {
2764
+ const maxOffset = clampScrollOffset(ctx, newScroll);
2765
+ if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
2766
+ newScroll = maxOffset;
2767
+ scrollTo(ctx, {
2768
+ forceScroll: true,
2769
+ isInitialScroll: true,
2770
+ noScrollingTo: true,
2771
+ offset: newScroll
2772
+ });
2773
+ return;
2774
+ }
2775
+ }
2776
+ updateScroll(ctx, newScroll);
2777
+ checkFinishedScroll(ctx);
2584
2778
  onScrollProp == null ? void 0 : onScrollProp(event);
2585
2779
  }
2586
2780
 
@@ -2589,51 +2783,47 @@ var ScrollAdjustHandler = class {
2589
2783
  constructor(ctx) {
2590
2784
  this.appliedAdjust = 0;
2591
2785
  this.pendingAdjust = 0;
2592
- this.mounted = false;
2593
- this.context = ctx;
2594
- if (Platform2.OS === "web") {
2595
- const commitPendingAdjust = () => {
2596
- const state = this.context.internalState;
2597
- const pending = this.pendingAdjust;
2598
- if (pending !== 0) {
2599
- this.pendingAdjust = 0;
2600
- this.appliedAdjust += pending;
2601
- state.scroll += pending;
2602
- state.scrollForNextCalculateItemsInView = void 0;
2603
- set$(this.context, "scrollAdjustPending", 0);
2604
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2605
- calculateItemsInView(this.context, this.context.internalState);
2606
- }
2607
- };
2608
- listen$(this.context, "scrollingTo", (value) => {
2609
- if (value === void 0) {
2610
- commitPendingAdjust();
2611
- }
2612
- });
2613
- }
2786
+ this.ctx = ctx;
2614
2787
  }
2615
2788
  requestAdjust(add) {
2616
- const scrollingTo = peek$(this.context, "scrollingTo");
2789
+ const scrollingTo = this.ctx.state.scrollingTo;
2617
2790
  if (Platform2.OS === "web" && (scrollingTo == null ? void 0 : scrollingTo.animated) && !scrollingTo.isInitialScroll) {
2618
2791
  this.pendingAdjust += add;
2619
- set$(this.context, "scrollAdjustPending", this.pendingAdjust);
2792
+ set$(this.ctx, "scrollAdjustPending", this.pendingAdjust);
2620
2793
  } else {
2621
2794
  this.appliedAdjust += add;
2622
- set$(this.context, "scrollAdjust", this.appliedAdjust);
2795
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2796
+ }
2797
+ if (this.ctx.state.scrollingTo) {
2798
+ checkFinishedScroll(this.ctx);
2623
2799
  }
2624
- }
2625
- setMounted() {
2626
- this.mounted = true;
2627
2800
  }
2628
2801
  getAdjust() {
2629
2802
  return this.appliedAdjust;
2630
2803
  }
2804
+ commitPendingAdjust() {
2805
+ if (Platform2.OS === "web") {
2806
+ const state = this.ctx.state;
2807
+ const pending = this.pendingAdjust;
2808
+ if (pending !== 0) {
2809
+ this.pendingAdjust = 0;
2810
+ this.appliedAdjust += pending;
2811
+ state.scroll += pending;
2812
+ state.scrollForNextCalculateItemsInView = void 0;
2813
+ set$(this.ctx, "scrollAdjustPending", 0);
2814
+ set$(this.ctx, "scrollAdjust", this.appliedAdjust);
2815
+ calculateItemsInView(this.ctx);
2816
+ }
2817
+ }
2818
+ }
2631
2819
  };
2632
2820
 
2633
2821
  // src/core/updateItemSize.ts
2634
- function updateItemSize(ctx, state, itemKey, sizeObj) {
2822
+ function updateItemSize(ctx, itemKey, sizeObj) {
2635
2823
  var _a3;
2824
+ const state = ctx.state;
2636
2825
  const {
2826
+ didContainersLayout,
2637
2827
  sizesKnown,
2638
2828
  props: {
2639
2829
  getFixedItemSize,
@@ -2661,13 +2851,12 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2661
2851
  return;
2662
2852
  }
2663
2853
  }
2664
- const containersDidLayout = peek$(ctx, "containersDidLayout");
2665
- let needsRecalculate = !containersDidLayout;
2854
+ let needsRecalculate = !didContainersLayout;
2666
2855
  let shouldMaintainScrollAtEnd = false;
2667
2856
  let minIndexSizeChanged;
2668
2857
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
2669
2858
  const prevSizeKnown = state.sizesKnown.get(itemKey);
2670
- const diff = updateOneItemSize(ctx, state, itemKey, sizeObj);
2859
+ const diff = updateOneItemSize(ctx, itemKey, sizeObj);
2671
2860
  const size = roundSize(horizontal ? sizeObj.width : sizeObj.height);
2672
2861
  if (diff !== 0) {
2673
2862
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
@@ -2716,22 +2905,22 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
2716
2905
  if (!cur || maxOtherAxisSize > cur) {
2717
2906
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
2718
2907
  }
2719
- if (containersDidLayout || checkAllSizesKnown(state)) {
2908
+ if (didContainersLayout || checkAllSizesKnown(state)) {
2720
2909
  if (needsRecalculate) {
2721
2910
  state.scrollForNextCalculateItemsInView = void 0;
2722
- calculateItemsInView(ctx, state, { doMVCP: true });
2911
+ calculateItemsInView(ctx, { doMVCP: true });
2723
2912
  }
2724
2913
  if (shouldMaintainScrollAtEnd) {
2725
2914
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
2726
- doMaintainScrollAtEnd(ctx, state, false);
2915
+ doMaintainScrollAtEnd(ctx, false);
2727
2916
  }
2728
2917
  }
2729
2918
  }
2730
2919
  }
2731
- function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2920
+ function updateOneItemSize(ctx, itemKey, sizeObj) {
2732
2921
  var _a3;
2922
+ const state = ctx.state;
2733
2923
  const {
2734
- sizes,
2735
2924
  indexByKey,
2736
2925
  sizesKnown,
2737
2926
  averageSizes,
@@ -2739,9 +2928,10 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2739
2928
  } = state;
2740
2929
  if (!data) return 0;
2741
2930
  const index = indexByKey.get(itemKey);
2742
- const prevSize = getItemSize(ctx, state, itemKey, index, data[index]);
2931
+ const prevSize = getItemSize(ctx, itemKey, index, data[index]);
2743
2932
  const rawSize = horizontal ? sizeObj.width : sizeObj.height;
2744
2933
  const size = Platform2.OS === "web" ? Math.round(rawSize) : roundSize(rawSize);
2934
+ const prevSizeKnown = sizesKnown.get(itemKey);
2745
2935
  sizesKnown.set(itemKey, size);
2746
2936
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
2747
2937
  const itemType = getItemType ? (_a3 = getItemType(data[index], index)) != null ? _a3 : "" : "";
@@ -2749,11 +2939,15 @@ function updateOneItemSize(ctx, state, itemKey, sizeObj) {
2749
2939
  if (!averages) {
2750
2940
  averages = averageSizes[itemType] = { avg: 0, num: 0 };
2751
2941
  }
2752
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2753
- averages.num++;
2942
+ if (prevSizeKnown !== void 0 && prevSizeKnown > 0) {
2943
+ averages.avg += (size - prevSizeKnown) / averages.num;
2944
+ } else {
2945
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2946
+ averages.num++;
2947
+ }
2754
2948
  }
2755
2949
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2756
- setSize(ctx, state, itemKey, size);
2950
+ setSize(ctx, itemKey, size);
2757
2951
  return size - prevSize;
2758
2952
  }
2759
2953
  return 0;
@@ -2819,14 +3013,15 @@ function createColumnWrapperStyle(contentContainerStyle) {
2819
3013
  }
2820
3014
 
2821
3015
  // src/utils/createImperativeHandle.ts
2822
- function createImperativeHandle(ctx, state) {
3016
+ function createImperativeHandle(ctx) {
3017
+ const state = ctx.state;
2823
3018
  const scrollIndexIntoView = (options) => {
2824
3019
  if (state) {
2825
3020
  const { index, ...rest } = options;
2826
3021
  const { startNoBuffer, endNoBuffer } = state;
2827
3022
  if (index < startNoBuffer || index > endNoBuffer) {
2828
3023
  const viewPosition = index < startNoBuffer ? 0 : 1;
2829
- scrollToIndex(ctx, state, {
3024
+ scrollToIndex(ctx, {
2830
3025
  ...rest,
2831
3026
  index,
2832
3027
  viewPosition
@@ -2841,7 +3036,7 @@ function createImperativeHandle(ctx, state) {
2841
3036
  getScrollableNode: () => refScroller.current.getScrollableNode(),
2842
3037
  getScrollResponder: () => refScroller.current.getScrollResponder(),
2843
3038
  getState: () => ({
2844
- activeStickyIndex: state.activeStickyIndex,
3039
+ activeStickyIndex: peek$(ctx, "activeStickyIndex"),
2845
3040
  contentLength: state.totalSize,
2846
3041
  data: state.props.data,
2847
3042
  elementAtIndex: (index) => {
@@ -2852,6 +3047,8 @@ function createImperativeHandle(ctx, state) {
2852
3047
  endBuffered: state.endBuffered,
2853
3048
  isAtEnd: state.isAtEnd,
2854
3049
  isAtStart: state.isAtStart,
3050
+ listen: (signalName, cb) => listen$(ctx, signalName, cb),
3051
+ listenToPosition: (key, cb) => listenPosition$(ctx, key, cb),
2855
3052
  positionAtIndex: (index) => state.positions.get(getId(state, index)),
2856
3053
  positions: state.positions,
2857
3054
  scroll: state.scroll,
@@ -2876,23 +3073,23 @@ function createImperativeHandle(ctx, state) {
2876
3073
  if (index !== -1) {
2877
3074
  const paddingBottom = stylePaddingBottom || 0;
2878
3075
  const footerSize = peek$(ctx, "footerSize") || 0;
2879
- scrollToIndex(ctx, state, {
3076
+ scrollToIndex(ctx, {
3077
+ ...options,
2880
3078
  index,
2881
3079
  viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
2882
- viewPosition: 1,
2883
- ...options
3080
+ viewPosition: 1
2884
3081
  });
2885
3082
  }
2886
3083
  },
2887
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
3084
+ scrollToIndex: (params) => scrollToIndex(ctx, params),
2888
3085
  scrollToItem: ({ item, ...props }) => {
2889
3086
  const data = state.props.data;
2890
3087
  const index = data.indexOf(item);
2891
3088
  if (index !== -1) {
2892
- scrollToIndex(ctx, state, { index, ...props });
3089
+ scrollToIndex(ctx, { index, ...props });
2893
3090
  }
2894
3091
  },
2895
- scrollToOffset: (params) => scrollTo(ctx, state, params),
3092
+ scrollToOffset: (params) => scrollTo(ctx, params),
2896
3093
  setScrollProcessingEnabled: (enabled) => {
2897
3094
  state.scrollProcessingEnabled = enabled;
2898
3095
  },
@@ -2902,8 +3099,9 @@ function createImperativeHandle(ctx, state) {
2902
3099
  }
2903
3100
  };
2904
3101
  }
2905
- function getRenderedItem(ctx, state, key) {
3102
+ function getRenderedItem(ctx, key) {
2906
3103
  var _a3;
3104
+ const state = ctx.state;
2907
3105
  if (!state) {
2908
3106
  return null;
2909
3107
  }
@@ -2980,11 +3178,13 @@ function useThrottledOnScroll(originalHandler, scrollEventThrottle) {
2980
3178
  var DEFAULT_DRAW_DISTANCE = 250;
2981
3179
  var DEFAULT_ITEM_SIZE = 100;
2982
3180
  var LegendList = typedMemo(
3181
+ // biome-ignore lint/nursery/noShadow: const function name shadowing is intentional
2983
3182
  typedForwardRef(function LegendList2(props, forwardedRef) {
2984
3183
  const { children, data: dataProp, renderItem: renderItemProp, ...restProps } = props;
2985
3184
  const isChildrenMode = children !== void 0 && dataProp === void 0;
2986
3185
  const processedProps = isChildrenMode ? {
2987
3186
  ...restProps,
3187
+ childrenMode: true,
2988
3188
  data: (isArray(children) ? children : React2.Children.toArray(children)).flat(1),
2989
3189
  renderItem: ({ item }) => item
2990
3190
  } : {
@@ -3001,10 +3201,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3001
3201
  alignItemsAtEnd = false,
3002
3202
  columnWrapperStyle,
3003
3203
  contentContainerStyle: contentContainerStyleProp,
3204
+ contentInset,
3004
3205
  data: dataProp = [],
3005
3206
  dataVersion,
3006
3207
  drawDistance = 250,
3007
- enableAverages = true,
3008
3208
  estimatedItemSize: estimatedItemSizeProp,
3009
3209
  estimatedListSize,
3010
3210
  extraData,
@@ -3046,6 +3246,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3046
3246
  snapToIndices,
3047
3247
  stickyHeaderIndices: stickyHeaderIndicesProp,
3048
3248
  stickyIndices: stickyIndicesDeprecated,
3249
+ // TODOV3: Remove from v3 release
3049
3250
  style: styleProp,
3050
3251
  suggestEstimatedItemSize,
3051
3252
  viewabilityConfig,
@@ -3053,6 +3254,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3053
3254
  waitForInitialLayout = true,
3054
3255
  ...rest
3055
3256
  } = props;
3257
+ const animatedPropsInternal = props.animatedPropsInternal;
3258
+ const { childrenMode } = rest;
3056
3259
  const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
3057
3260
  const style = { ...StyleSheet.flatten(styleProp) };
3058
3261
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
@@ -3076,10 +3279,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3076
3279
  }
3077
3280
  const refState = useRef();
3078
3281
  if (!refState.current) {
3079
- if (!ctx.internalState) {
3282
+ if (!ctx.state) {
3080
3283
  const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : getWindowSize())[horizontal ? "width" : "height"];
3081
- ctx.internalState = {
3082
- activeStickyIndex: void 0,
3284
+ ctx.state = {
3285
+ activeStickyIndex: -1,
3083
3286
  averageSizes: {},
3084
3287
  columns: /* @__PURE__ */ new Map(),
3085
3288
  containerItemKeys: /* @__PURE__ */ new Set(),
@@ -3105,9 +3308,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3105
3308
  initialScroll: initialScrollProp,
3106
3309
  isAtEnd: false,
3107
3310
  isAtStart: false,
3108
- isEndReached: false,
3311
+ isEndReached: null,
3109
3312
  isFirst: true,
3110
- isStartReached: false,
3313
+ isStartReached: null,
3111
3314
  lastBatchingAction: Date.now(),
3112
3315
  lastLayout: void 0,
3113
3316
  loadStartTime: Date.now(),
@@ -3139,12 +3342,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3139
3342
  totalSize: 0,
3140
3343
  viewabilityConfigCallbackPairs: void 0
3141
3344
  };
3142
- const internalState = ctx.internalState;
3143
- internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, internalState, params);
3345
+ const internalState = ctx.state;
3346
+ internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3144
3347
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3145
3348
  set$(ctx, "extraData", extraData);
3146
3349
  }
3147
- refState.current = ctx.internalState;
3350
+ refState.current = ctx.state;
3148
3351
  }
3149
3352
  const state = refState.current;
3150
3353
  const isFirstLocal = state.isFirst;
@@ -3158,9 +3361,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3158
3361
  const throttleScrollFn = scrollEventThrottle && onScrollProp ? useThrottledOnScroll(onScrollProp, scrollEventThrottle) : onScrollProp;
3159
3362
  state.props = {
3160
3363
  alignItemsAtEnd,
3364
+ animatedProps: animatedPropsInternal,
3365
+ contentInset,
3161
3366
  data: dataProp,
3162
3367
  dataVersion,
3163
- enableAverages,
3164
3368
  estimatedItemSize,
3165
3369
  getEstimatedItemSize,
3166
3370
  getFixedItemSize,
@@ -3203,62 +3407,62 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3203
3407
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
3204
3408
  set$(ctx, "numColumns", numColumnsProp);
3205
3409
  const prevPaddingTop = peek$(ctx, "stylePaddingTop");
3206
- setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
3410
+ setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3207
3411
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3208
3412
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3209
3413
  if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3210
3414
  if (state.scroll < 0) {
3211
3415
  paddingDiff += state.scroll;
3212
3416
  }
3213
- requestAdjust(ctx, state, paddingDiff);
3417
+ requestAdjust(ctx, paddingDiff);
3214
3418
  }
3215
3419
  };
3216
3420
  if (isFirstLocal) {
3217
3421
  initializeStateVars();
3218
3422
  updateItemPositions(
3219
3423
  ctx,
3220
- state,
3221
3424
  /*dataChanged*/
3222
3425
  true
3223
3426
  );
3224
3427
  }
3225
3428
  const initialContentOffset = useMemo(() => {
3226
- var _a4, _b2;
3227
- const { initialScroll } = refState.current;
3228
- if (!initialScroll) {
3429
+ var _a4;
3430
+ let value;
3431
+ const { initialScroll, initialAnchor } = refState.current;
3432
+ if (initialScroll) {
3433
+ if (!IsNewArchitecture && initialScroll.index !== void 0 && (!initialAnchor || (initialAnchor == null ? void 0 : initialAnchor.index) !== initialScroll.index)) {
3434
+ refState.current.initialAnchor = {
3435
+ attempts: 0,
3436
+ index: initialScroll.index,
3437
+ settledTicks: 0,
3438
+ viewOffset: (_a4 = initialScroll.viewOffset) != null ? _a4 : 0,
3439
+ viewPosition: initialScroll.viewPosition
3440
+ };
3441
+ }
3442
+ if (initialScroll.contentOffset !== void 0) {
3443
+ value = initialScroll.contentOffset;
3444
+ } else {
3445
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
3446
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
3447
+ const clampedOffset = clampScrollOffset(ctx, resolvedOffset);
3448
+ const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3449
+ refState.current.initialScroll = updatedInitialScroll;
3450
+ state.initialScroll = updatedInitialScroll;
3451
+ value = clampedOffset;
3452
+ }
3453
+ } else {
3229
3454
  refState.current.initialAnchor = void 0;
3230
- return 0;
3231
- }
3232
- if (initialScroll.index !== void 0 && (!refState.current.initialAnchor || ((_a4 = refState.current.initialAnchor) == null ? void 0 : _a4.index) !== initialScroll.index)) {
3233
- refState.current.initialAnchor = {
3234
- attempts: 0,
3235
- index: initialScroll.index,
3236
- settledTicks: 0,
3237
- viewOffset: (_b2 = initialScroll.viewOffset) != null ? _b2 : 0,
3238
- viewPosition: initialScroll.viewPosition
3239
- };
3455
+ value = 0;
3456
+ }
3457
+ if (!value) {
3458
+ state.didFinishInitialScroll = true;
3240
3459
  }
3241
- if (initialScroll.contentOffset !== void 0) {
3242
- return initialScroll.contentOffset;
3243
- }
3244
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, state, initialScroll.index) : 0;
3245
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, state, baseOffset, initialScroll);
3246
- let clampedOffset = resolvedOffset;
3247
- if (Number.isFinite(state.scrollLength) && Number.isFinite(state.totalSize)) {
3248
- const maxOffset = Math.max(0, state.totalSize - state.scrollLength);
3249
- clampedOffset = Math.min(clampedOffset, maxOffset);
3250
- }
3251
- clampedOffset = Math.max(0, clampedOffset);
3252
- const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
3253
- refState.current.initialScroll = updatedInitialScroll;
3254
- state.initialScroll = updatedInitialScroll;
3255
- refState.current.isStartReached = clampedOffset < refState.current.scrollLength * onStartReachedThreshold;
3256
- return clampedOffset;
3460
+ return value;
3257
3461
  }, [renderNum]);
3258
3462
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
3259
3463
  refState.current.lastBatchingAction = Date.now();
3260
3464
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
3261
- IS_DEV && warnDevOnce(
3465
+ IS_DEV && !childrenMode && warnDevOnce(
3262
3466
  "keyExtractor",
3263
3467
  "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."
3264
3468
  );
@@ -3283,12 +3487,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3283
3487
  }
3284
3488
  }, []);
3285
3489
  const doInitialScroll = useCallback(() => {
3286
- var _a4;
3287
3490
  const initialScroll = state.initialScroll;
3288
3491
  if (initialScroll) {
3289
- scrollTo(ctx, state, {
3492
+ scrollTo(ctx, {
3290
3493
  animated: false,
3291
- index: (_a4 = state.initialScroll) == null ? void 0 : _a4.index,
3494
+ index: initialScroll == null ? void 0 : initialScroll.index,
3292
3495
  isInitialScroll: true,
3293
3496
  offset: initialContentOffset,
3294
3497
  precomputedWithViewOffset: true
@@ -3297,7 +3500,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3297
3500
  }, [initialContentOffset]);
3298
3501
  const onLayoutChange = useCallback((layout) => {
3299
3502
  doInitialScroll();
3300
- handleLayout(ctx, state, layout, setCanRender);
3503
+ handleLayout(ctx, layout, setCanRender);
3301
3504
  }, []);
3302
3505
  const { onLayout } = useOnLayoutSync({
3303
3506
  onLayoutChange,
@@ -3307,7 +3510,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3307
3510
  });
3308
3511
  useLayoutEffect(() => {
3309
3512
  if (snapToIndices) {
3310
- updateSnapToOffsets(ctx, state);
3513
+ updateSnapToOffsets(ctx);
3311
3514
  }
3312
3515
  }, [snapToIndices]);
3313
3516
  useLayoutEffect(() => {
@@ -3317,9 +3520,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3317
3520
  isFirst,
3318
3521
  props: { data }
3319
3522
  } = state;
3320
- const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx, state);
3523
+ const didAllocateContainers = data.length > 0 && doInitialAllocateContainers(ctx);
3321
3524
  if (!didAllocateContainers && !isFirst && (didDataChange || didColumnsChange)) {
3322
- checkResetContainers(ctx, state, data);
3525
+ checkResetContainers(ctx, data);
3323
3526
  }
3324
3527
  state.didColumnsChange = false;
3325
3528
  state.didDataChange = false;
@@ -3346,18 +3549,24 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3346
3549
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
3347
3550
  if (!IsNewArchitecture) {
3348
3551
  useInit(() => {
3349
- doInitialAllocateContainers(ctx, state);
3552
+ doInitialAllocateContainers(ctx);
3350
3553
  });
3351
3554
  }
3352
- useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, state), []);
3555
+ useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx), []);
3353
3556
  if (Platform2.OS === "web") {
3354
3557
  useEffect(doInitialScroll, []);
3355
3558
  }
3356
3559
  const fns = useMemo(
3357
3560
  () => ({
3358
- getRenderedItem: (key) => getRenderedItem(ctx, state, key),
3359
- onScroll: (event) => onScroll(ctx, state, event),
3360
- updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj)
3561
+ getRenderedItem: (key) => getRenderedItem(ctx, key),
3562
+ onMomentumScrollEnd: (event) => {
3563
+ checkFinishedScrollFallback(ctx);
3564
+ if (onMomentumScrollEnd) {
3565
+ onMomentumScrollEnd(event);
3566
+ }
3567
+ },
3568
+ onScroll: (event) => onScroll(ctx, event),
3569
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, itemKey, sizeObj)
3361
3570
  }),
3362
3571
  []
3363
3572
  );
@@ -3369,6 +3578,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3369
3578
  alignItemsAtEnd,
3370
3579
  canRender,
3371
3580
  contentContainerStyle,
3581
+ contentInset,
3372
3582
  getRenderedItem: fns.getRenderedItem,
3373
3583
  horizontal,
3374
3584
  initialContentOffset,
@@ -3377,20 +3587,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3377
3587
  maintainVisibleContentPosition,
3378
3588
  onLayout,
3379
3589
  onLayoutHeader,
3380
- onMomentumScrollEnd: (event) => {
3381
- if (IsNewArchitecture) {
3382
- requestAnimationFrame(() => {
3383
- finishScrollTo(ctx, refState.current);
3384
- });
3385
- } else {
3386
- setTimeout(() => {
3387
- finishScrollTo(ctx, refState.current);
3388
- }, 1e3);
3389
- }
3390
- if (onMomentumScrollEnd) {
3391
- onMomentumScrollEnd(event);
3392
- }
3393
- },
3590
+ onMomentumScrollEnd: fns.onMomentumScrollEnd,
3394
3591
  onScroll: onScrollHandler,
3395
3592
  recycleItems,
3396
3593
  refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2.cloneElement(refreshControl, {
@@ -3405,7 +3602,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3405
3602
  ),
3406
3603
  refScrollView: combinedRef,
3407
3604
  scrollAdjustHandler: (_b = refState.current) == null ? void 0 : _b.scrollAdjustHandler,
3408
- scrollEventThrottle: Platform2.OS === "web" ? 16 : void 0,
3605
+ scrollEventThrottle: 0,
3409
3606
  snapToIndices,
3410
3607
  stickyHeaderIndices,
3411
3608
  style,
@@ -3451,8 +3648,8 @@ function buildSectionListData({
3451
3648
  if (hasHeader) {
3452
3649
  const headerIndex = data.length;
3453
3650
  data.push({
3454
- kind: "header",
3455
3651
  key: `${sectionKey}:header`,
3652
+ kind: "header",
3456
3653
  section,
3457
3654
  sectionIndex
3458
3655
  });
@@ -3466,31 +3663,31 @@ function buildSectionListData({
3466
3663
  const itemKeyExtractor = (_b = section.keyExtractor) != null ? _b : keyExtractor;
3467
3664
  const itemKey = itemKeyExtractor(item, itemIndex);
3468
3665
  data.push({
3469
- kind: "item",
3470
- key: `${sectionKey}:item:${itemKey}`,
3471
- section,
3472
- sectionIndex,
3666
+ absoluteItemIndex: absoluteItemIndex++,
3473
3667
  item,
3474
3668
  itemIndex,
3475
- absoluteItemIndex: absoluteItemIndex++
3669
+ key: `${sectionKey}:item:${itemKey}`,
3670
+ kind: "item",
3671
+ section,
3672
+ sectionIndex
3476
3673
  });
3477
3674
  meta.items.push(data.length - 1);
3478
3675
  if (hasItemSeparator && itemIndex < items.length - 1) {
3479
3676
  data.push({
3480
- kind: "item-separator",
3481
3677
  key: `${sectionKey}:separator:${itemIndex}`,
3482
- section,
3483
- sectionIndex,
3678
+ kind: "item-separator",
3484
3679
  leadingItem: item,
3485
3680
  leadingItemIndex: itemIndex,
3681
+ section,
3682
+ sectionIndex,
3486
3683
  trailingItem: items[itemIndex + 1]
3487
3684
  });
3488
3685
  }
3489
3686
  }
3490
3687
  if (hasFooter) {
3491
3688
  data.push({
3492
- kind: "footer",
3493
3689
  key: `${sectionKey}:footer`,
3690
+ kind: "footer",
3494
3691
  section,
3495
3692
  sectionIndex
3496
3693
  });
@@ -3499,8 +3696,8 @@ function buildSectionListData({
3499
3696
  const isLastSection = sectionIndex === sections.length - 1;
3500
3697
  if (hasSectionSeparator && !isLastSection) {
3501
3698
  data.push({
3502
- kind: "section-separator",
3503
3699
  key: `${sectionKey}:section-separator`,
3700
+ kind: "section-separator",
3504
3701
  leadingSection: section,
3505
3702
  leadingSectionIndex: sectionIndex,
3506
3703
  trailingSection: sections[sectionIndex + 1]