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

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