@legendapp/list 2.0.0-next.2 → 2.0.0-next.21

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.
Files changed (264) hide show
  1. package/{dist/animated.d.mts → animated.d.mts} +10 -3
  2. package/{dist/animated.d.ts → animated.d.ts} +10 -3
  3. package/{dist/animated.js → animated.js} +2 -2
  4. package/{dist/animated.mjs → animated.mjs} +2 -2
  5. package/{dist/index.d.mts → index.d.mts} +86 -167
  6. package/{dist/index.d.ts → index.d.ts} +86 -167
  7. package/{dist/index.js → index.js} +1594 -1098
  8. package/{dist/index.mjs → index.mjs} +1596 -1100
  9. package/keyboard-controller.d.mts +148 -0
  10. package/keyboard-controller.d.ts +148 -0
  11. package/{dist/keyboard-controller.js → keyboard-controller.js} +4 -4
  12. package/{dist/keyboard-controller.mjs → keyboard-controller.mjs} +4 -4
  13. package/package.json +34 -88
  14. package/{dist/reanimated.d.mts → reanimated.d.mts} +2 -2
  15. package/{dist/reanimated.d.ts → reanimated.d.ts} +2 -2
  16. package/reanimated.js +60 -0
  17. package/reanimated.mjs +53 -0
  18. package/.claude/settings.local.json +0 -8
  19. package/.cursor/rules/changelog.mdc +0 -60
  20. package/.github/FUNDING.yml +0 -15
  21. package/.gitignore +0 -5
  22. package/.prettierrc.json +0 -5
  23. package/.vscode/settings.json +0 -14
  24. package/CLAUDE.md +0 -126
  25. package/biome.json +0 -46
  26. package/bun.lock +0 -1289
  27. package/bunfig.toml +0 -2
  28. package/dist/CHANGELOG.md +0 -119
  29. package/dist/LICENSE +0 -21
  30. package/dist/README.md +0 -139
  31. package/dist/keyboard-controller.d.mts +0 -261
  32. package/dist/keyboard-controller.d.ts +0 -261
  33. package/dist/package.json +0 -35
  34. package/dist/reanimated.js +0 -58
  35. package/dist/reanimated.mjs +0 -51
  36. package/example/README.md +0 -40
  37. package/example/api/data/genres.json +0 -23
  38. package/example/api/data/playlist/10402-10749.json +0 -1
  39. package/example/api/data/playlist/10402-10770.json +0 -1
  40. package/example/api/data/playlist/10402-37.json +0 -1
  41. package/example/api/data/playlist/10749-10752.json +0 -1
  42. package/example/api/data/playlist/10749-10770.json +0 -1
  43. package/example/api/data/playlist/10749-37.json +0 -1
  44. package/example/api/data/playlist/10749-878.json +0 -1
  45. package/example/api/data/playlist/10751-10402.json +0 -1
  46. package/example/api/data/playlist/10751-10752.json +0 -1
  47. package/example/api/data/playlist/10751-37.json +0 -1
  48. package/example/api/data/playlist/10751-53.json +0 -1
  49. package/example/api/data/playlist/10751-878.json +0 -1
  50. package/example/api/data/playlist/10751-9648.json +0 -1
  51. package/example/api/data/playlist/10752-37.json +0 -1
  52. package/example/api/data/playlist/12-10402.json +0 -1
  53. package/example/api/data/playlist/12-10749.json +0 -1
  54. package/example/api/data/playlist/12-18.json +0 -1
  55. package/example/api/data/playlist/12-27.json +0 -1
  56. package/example/api/data/playlist/12-35.json +0 -1
  57. package/example/api/data/playlist/14-36.json +0 -1
  58. package/example/api/data/playlist/14-878.json +0 -1
  59. package/example/api/data/playlist/16-10751.json +0 -1
  60. package/example/api/data/playlist/16-10770.json +0 -1
  61. package/example/api/data/playlist/16-35.json +0 -1
  62. package/example/api/data/playlist/16-36.json +0 -1
  63. package/example/api/data/playlist/16-53.json +0 -1
  64. package/example/api/data/playlist/18-10751.json +0 -1
  65. package/example/api/data/playlist/18-10752.json +0 -1
  66. package/example/api/data/playlist/18-37.json +0 -1
  67. package/example/api/data/playlist/18-53.json +0 -1
  68. package/example/api/data/playlist/18-878.json +0 -1
  69. package/example/api/data/playlist/27-10749.json +0 -1
  70. package/example/api/data/playlist/27-10770.json +0 -1
  71. package/example/api/data/playlist/28-10749.json +0 -1
  72. package/example/api/data/playlist/28-10751.json +0 -1
  73. package/example/api/data/playlist/28-10770.json +0 -1
  74. package/example/api/data/playlist/28-16.json +0 -1
  75. package/example/api/data/playlist/28-18.json +0 -1
  76. package/example/api/data/playlist/28-36.json +0 -1
  77. package/example/api/data/playlist/28-37.json +0 -1
  78. package/example/api/data/playlist/28-53.json +0 -1
  79. package/example/api/data/playlist/28-80.json +0 -1
  80. package/example/api/data/playlist/28-99.json +0 -1
  81. package/example/api/data/playlist/35-10749.json +0 -1
  82. package/example/api/data/playlist/35-10751.json +0 -1
  83. package/example/api/data/playlist/35-10752.json +0 -1
  84. package/example/api/data/playlist/35-27.json +0 -1
  85. package/example/api/data/playlist/35-36.json +0 -1
  86. package/example/api/data/playlist/35-53.json +0 -1
  87. package/example/api/data/playlist/35-80.json +0 -1
  88. package/example/api/data/playlist/36-37.json +0 -1
  89. package/example/api/data/playlist/36-878.json +0 -1
  90. package/example/api/data/playlist/36-9648.json +0 -1
  91. package/example/api/data/playlist/53-10752.json +0 -1
  92. package/example/api/data/playlist/80-10770.json +0 -1
  93. package/example/api/data/playlist/80-14.json +0 -1
  94. package/example/api/data/playlist/80-18.json +0 -1
  95. package/example/api/data/playlist/80-37.json +0 -1
  96. package/example/api/data/playlist/878-37.json +0 -1
  97. package/example/api/data/playlist/9648-10770.json +0 -1
  98. package/example/api/data/playlist/9648-37.json +0 -1
  99. package/example/api/data/playlist/9648-53.json +0 -1
  100. package/example/api/data/playlist/9648-878.json +0 -1
  101. package/example/api/data/playlist/99-10749.json +0 -1
  102. package/example/api/data/playlist/99-14.json +0 -1
  103. package/example/api/data/playlist/99-18.json +0 -1
  104. package/example/api/data/playlist/99-27.json +0 -1
  105. package/example/api/data/playlist/99-53.json +0 -1
  106. package/example/api/data/playlist/99-9648.json +0 -1
  107. package/example/api/data/playlist/index.ts +0 -73
  108. package/example/api/data/rows.json +0 -1
  109. package/example/api/index.ts +0 -36
  110. package/example/app/(tabs)/_layout.tsx +0 -60
  111. package/example/app/(tabs)/cards.tsx +0 -81
  112. package/example/app/(tabs)/index.tsx +0 -205
  113. package/example/app/(tabs)/moviesL.tsx +0 -7
  114. package/example/app/(tabs)/moviesLR.tsx +0 -7
  115. package/example/app/+not-found.tsx +0 -32
  116. package/example/app/_layout.tsx +0 -34
  117. package/example/app/accurate-scrollto/index.tsx +0 -125
  118. package/example/app/accurate-scrollto-2/index.tsx +0 -52
  119. package/example/app/accurate-scrollto-huge/index.tsx +0 -128
  120. package/example/app/add-to-end/index.tsx +0 -82
  121. package/example/app/ai-chat/index.tsx +0 -236
  122. package/example/app/bidirectional-infinite-list/index.tsx +0 -133
  123. package/example/app/cards-columns/index.tsx +0 -37
  124. package/example/app/cards-flashlist/index.tsx +0 -122
  125. package/example/app/cards-flatlist/index.tsx +0 -94
  126. package/example/app/cards-no-recycle/index.tsx +0 -110
  127. package/example/app/cards-renderItem.tsx +0 -354
  128. package/example/app/chat-example/index.tsx +0 -167
  129. package/example/app/chat-infinite/index.tsx +0 -239
  130. package/example/app/chat-keyboard/index.tsx +0 -248
  131. package/example/app/chat-resize-outer/index.tsx +0 -247
  132. package/example/app/columns/index.tsx +0 -78
  133. package/example/app/countries/index.tsx +0 -182
  134. package/example/app/countries-flashlist/index.tsx +0 -163
  135. package/example/app/countries-reorder/index.tsx +0 -187
  136. package/example/app/extra-data/index.tsx +0 -86
  137. package/example/app/filter-elements/filter-data-provider.tsx +0 -55
  138. package/example/app/filter-elements/index.tsx +0 -118
  139. package/example/app/initial-scroll-index/index.tsx +0 -106
  140. package/example/app/initial-scroll-index/renderFixedItem.tsx +0 -215
  141. package/example/app/initial-scroll-index-free-height/index.tsx +0 -70
  142. package/example/app/initial-scroll-index-keyed/index.tsx +0 -62
  143. package/example/app/lazy-list/index.tsx +0 -123
  144. package/example/app/movies-flashlist/index.tsx +0 -7
  145. package/example/app/mutable-cells/index.tsx +0 -104
  146. package/example/app/video-feed/index.tsx +0 -119
  147. package/example/app.config.js +0 -22
  148. package/example/app.json +0 -45
  149. package/example/assets/fonts/SpaceMono-Regular.ttf +0 -0
  150. package/example/assets/images/adaptive-icon.png +0 -0
  151. package/example/assets/images/favicon.png +0 -0
  152. package/example/assets/images/icon.png +0 -0
  153. package/example/assets/images/partial-react-logo.png +0 -0
  154. package/example/assets/images/react-logo.png +0 -0
  155. package/example/assets/images/react-logo@2x.png +0 -0
  156. package/example/assets/images/react-logo@3x.png +0 -0
  157. package/example/assets/images/splash-icon.png +0 -0
  158. package/example/autoscroll.sh +0 -101
  159. package/example/bun.lock +0 -2266
  160. package/example/bunfig.toml +0 -2
  161. package/example/components/Breathe.tsx +0 -54
  162. package/example/components/Circle.tsx +0 -69
  163. package/example/components/Collapsible.tsx +0 -44
  164. package/example/components/ExternalLink.tsx +0 -24
  165. package/example/components/HapticTab.tsx +0 -18
  166. package/example/components/HelloWave.tsx +0 -37
  167. package/example/components/Movies.tsx +0 -179
  168. package/example/components/ParallaxScrollView.tsx +0 -81
  169. package/example/components/ThemedText.tsx +0 -60
  170. package/example/components/ThemedView.tsx +0 -14
  171. package/example/components/__tests__/ThemedText-test.tsx +0 -10
  172. package/example/components/__tests__/__snapshots__/ThemedText-test.tsx.snap +0 -24
  173. package/example/components/ui/IconSymbol.ios.tsx +0 -32
  174. package/example/components/ui/IconSymbol.tsx +0 -43
  175. package/example/components/ui/TabBarBackground.ios.tsx +0 -22
  176. package/example/components/ui/TabBarBackground.tsx +0 -6
  177. package/example/constants/Colors.ts +0 -26
  178. package/example/constants/constants.ts +0 -5
  179. package/example/constants/useScrollTest.ts +0 -19
  180. package/example/hooks/useColorScheme.ts +0 -1
  181. package/example/hooks/useColorScheme.web.ts +0 -8
  182. package/example/hooks/useThemeColor.ts +0 -22
  183. package/example/ios/.xcode.env +0 -11
  184. package/example/ios/Podfile +0 -64
  185. package/example/ios/Podfile.lock +0 -2767
  186. package/example/ios/Podfile.properties.json +0 -5
  187. package/example/ios/listtest/AppDelegate.swift +0 -70
  188. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
  189. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/Contents.json +0 -14
  190. package/example/ios/listtest/Images.xcassets/Contents.json +0 -6
  191. package/example/ios/listtest/Images.xcassets/SplashScreenBackground.colorset/Contents.json +0 -20
  192. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/Contents.json +0 -23
  193. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image.png +0 -0
  194. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@2x.png +0 -0
  195. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@3x.png +0 -0
  196. package/example/ios/listtest/Info.plist +0 -85
  197. package/example/ios/listtest/PrivacyInfo.xcprivacy +0 -48
  198. package/example/ios/listtest/SplashScreen.storyboard +0 -42
  199. package/example/ios/listtest/Supporting/Expo.plist +0 -12
  200. package/example/ios/listtest/listtest-Bridging-Header.h +0 -3
  201. package/example/ios/listtest/listtest.entitlements +0 -5
  202. package/example/ios/listtest.xcodeproj/project.pbxproj +0 -547
  203. package/example/ios/listtest.xcodeproj/xcshareddata/xcschemes/listtest.xcscheme +0 -88
  204. package/example/ios/listtest.xcworkspace/contents.xcworkspacedata +0 -10
  205. package/example/metro.config.js +0 -16
  206. package/example/package.json +0 -73
  207. package/example/scripts/reset-project.js +0 -84
  208. package/example/tsconfig.json +0 -26
  209. package/posttsup.ts +0 -24
  210. package/src/Container.tsx +0 -176
  211. package/src/Containers.tsx +0 -85
  212. package/src/ContextContainer.ts +0 -145
  213. package/src/DebugView.tsx +0 -83
  214. package/src/LazyLegendList.tsx +0 -41
  215. package/src/LeanView.tsx +0 -18
  216. package/src/LegendList.tsx +0 -558
  217. package/src/ListComponent.tsx +0 -191
  218. package/src/ScrollAdjust.tsx +0 -24
  219. package/src/ScrollAdjustHandler.ts +0 -26
  220. package/src/Separator.tsx +0 -14
  221. package/src/animated.tsx +0 -6
  222. package/src/calculateItemsInView.ts +0 -363
  223. package/src/calculateOffsetForIndex.ts +0 -23
  224. package/src/calculateOffsetWithOffsetPosition.ts +0 -26
  225. package/src/checkAllSizesKnown.ts +0 -17
  226. package/src/checkAtBottom.ts +0 -36
  227. package/src/checkAtTop.ts +0 -27
  228. package/src/checkThreshold.ts +0 -30
  229. package/src/constants.ts +0 -11
  230. package/src/createColumnWrapperStyle.ts +0 -16
  231. package/src/doInitialAllocateContainers.ts +0 -40
  232. package/src/doMaintainScrollAtEnd.ts +0 -34
  233. package/src/findAvailableContainers.ts +0 -98
  234. package/src/finishScrollTo.ts +0 -8
  235. package/src/getId.ts +0 -21
  236. package/src/getItemSize.ts +0 -52
  237. package/src/getRenderedItem.ts +0 -34
  238. package/src/getScrollVelocity.ts +0 -47
  239. package/src/handleLayout.ts +0 -70
  240. package/src/helpers.ts +0 -39
  241. package/src/index.ts +0 -11
  242. package/src/keyboard-controller.tsx +0 -63
  243. package/src/onScroll.ts +0 -66
  244. package/src/prepareMVCP.ts +0 -50
  245. package/src/reanimated.tsx +0 -63
  246. package/src/requestAdjust.ts +0 -41
  247. package/src/scrollTo.ts +0 -40
  248. package/src/scrollToIndex.ts +0 -34
  249. package/src/setDidLayout.ts +0 -25
  250. package/src/setPaddingTop.ts +0 -28
  251. package/src/state.tsx +0 -304
  252. package/src/types.ts +0 -610
  253. package/src/updateAlignItemsPaddingTop.ts +0 -18
  254. package/src/updateAllPositions.ts +0 -130
  255. package/src/updateItemSize.ts +0 -203
  256. package/src/updateTotalSize.ts +0 -44
  257. package/src/useAnimatedValue.ts +0 -6
  258. package/src/useCombinedRef.ts +0 -22
  259. package/src/useInit.ts +0 -17
  260. package/src/useSyncLayout.tsx +0 -68
  261. package/src/useValue$.ts +0 -53
  262. package/src/viewability.ts +0 -279
  263. package/tsconfig.json +0 -59
  264. package/tsup.config.ts +0 -21
@@ -24,21 +24,24 @@ function _interopNamespace(e) {
24
24
 
25
25
  var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
26
26
 
27
- // src/LegendList.tsx
27
+ // src/components/LazyLegendList.tsx
28
28
  var ContextState = React3__namespace.createContext(null);
29
29
  function StateProvider({ children }) {
30
30
  const [value] = React3__namespace.useState(() => ({
31
+ animatedScrollY: new reactNative.Animated.Value(0),
32
+ columnWrapperStyle: void 0,
31
33
  listeners: /* @__PURE__ */ new Map(),
34
+ mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
35
+ mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
36
+ mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
37
+ mapViewabilityValues: /* @__PURE__ */ new Map(),
32
38
  values: /* @__PURE__ */ new Map([
33
39
  ["alignItemsPaddingTop", 0],
34
40
  ["stylePaddingTop", 0],
35
- ["headerSize", 0]
41
+ ["headerSize", 0],
42
+ ["numContainers", 0],
43
+ ["totalSize", 0]
36
44
  ]),
37
- mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
38
- mapViewabilityValues: /* @__PURE__ */ new Map(),
39
- mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
40
- mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
41
- columnWrapperStyle: void 0,
42
45
  viewRefs: /* @__PURE__ */ new Map()
43
46
  }));
44
47
  return /* @__PURE__ */ React3__namespace.createElement(ContextState.Provider, { value }, children);
@@ -50,17 +53,6 @@ function createSelectorFunctionsArr(ctx, signalNames) {
50
53
  let lastValues = [];
51
54
  let lastSignalValues = [];
52
55
  return {
53
- subscribe: (cb) => {
54
- const listeners = [];
55
- for (const signalName of signalNames) {
56
- listeners.push(listen$(ctx, signalName, cb));
57
- }
58
- return () => {
59
- for (const listener of listeners) {
60
- listener();
61
- }
62
- };
63
- },
64
56
  get: () => {
65
57
  const currentValues = [];
66
58
  let hasChanged = false;
@@ -76,6 +68,17 @@ function createSelectorFunctionsArr(ctx, signalNames) {
76
68
  lastValues = currentValues;
77
69
  }
78
70
  return lastValues;
71
+ },
72
+ subscribe: (cb) => {
73
+ const listeners = [];
74
+ for (const signalName of signalNames) {
75
+ listeners.push(listen$(ctx, signalName, cb));
76
+ }
77
+ return () => {
78
+ for (const listener of listeners) {
79
+ listener();
80
+ }
81
+ };
79
82
  }
80
83
  };
81
84
  }
@@ -110,7 +113,7 @@ function getContentSize(ctx) {
110
113
  const stylePaddingTop = values.get("stylePaddingTop") || 0;
111
114
  const headerSize = values.get("headerSize") || 0;
112
115
  const footerSize = values.get("footerSize") || 0;
113
- const totalSize = values.get("totalSize") || 0;
116
+ const totalSize = values.get("totalSize");
114
117
  return headerSize + footerSize + totalSize + stylePaddingTop;
115
118
  }
116
119
  function useArr$(signalNames) {
@@ -126,13 +129,13 @@ function useSelector$(signalName, selector) {
126
129
  return value;
127
130
  }
128
131
 
129
- // src/DebugView.tsx
132
+ // src/components/DebugView.tsx
130
133
  var DebugRow = ({ children }) => {
131
- return /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, children);
134
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: { alignItems: "center", flexDirection: "row", justifyContent: "space-between" } }, children);
132
135
  };
133
136
  var DebugView = React3__namespace.memo(function DebugView2({ state }) {
134
137
  const ctx = useStateContext();
135
- const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, numContainers = 0, numContainersPooled = 0] = useArr$([
138
+ const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, _numContainers = 0, _numContainersPooled = 0] = useArr$([
136
139
  "totalSize",
137
140
  "scrollAdjust",
138
141
  "debugRawScroll",
@@ -148,18 +151,18 @@ var DebugView = React3__namespace.memo(function DebugView2({ state }) {
148
151
  return /* @__PURE__ */ React3__namespace.createElement(
149
152
  reactNative.View,
150
153
  {
154
+ pointerEvents: "none",
151
155
  style: {
152
- position: "absolute",
153
- top: 0,
154
- right: 0,
155
- paddingLeft: 4,
156
- paddingBottom: 4,
157
156
  // height: 100,
158
157
  backgroundColor: "#FFFFFFCC",
158
+ borderRadius: 4,
159
159
  padding: 4,
160
- borderRadius: 4
161
- },
162
- pointerEvents: "none"
160
+ paddingBottom: 4,
161
+ paddingLeft: 4,
162
+ position: "absolute",
163
+ right: 0,
164
+ top: 0
165
+ }
163
166
  },
164
167
  /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "TotalSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, totalSize.toFixed(2))),
165
168
  /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ContentSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, contentSize.toFixed(2))),
@@ -177,8 +180,143 @@ function useInterval(callback, delay) {
177
180
  return () => clearInterval(interval);
178
181
  }, [delay]);
179
182
  }
183
+ var LeanViewComponent = React3__namespace.forwardRef((props, ref) => {
184
+ return React3__namespace.createElement("RCTView", { ...props, ref });
185
+ });
186
+ LeanViewComponent.displayName = "RCTView";
187
+ var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
188
+
189
+ // src/constants.ts
190
+ var POSITION_OUT_OF_VIEW = -1e7;
191
+ var ENABLE_DEVMODE = __DEV__ && false;
192
+ var ENABLE_DEBUG_VIEW = __DEV__ && false;
193
+ var IsNewArchitecture = global.nativeFabricUIManager != null;
194
+ var useAnimatedValue = (initialValue) => {
195
+ return React3.useRef(new reactNative.Animated.Value(initialValue)).current;
196
+ };
197
+
198
+ // src/hooks/useValue$.ts
199
+ function useValue$(key, params) {
200
+ var _a;
201
+ const { getValue, delay } = params || {};
202
+ const ctx = useStateContext();
203
+ const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
204
+ React3.useMemo(() => {
205
+ let newValue;
206
+ let prevValue;
207
+ let didQueueTask = false;
208
+ listen$(ctx, key, (v) => {
209
+ newValue = getValue ? getValue(v) : v;
210
+ if (delay !== void 0) {
211
+ const fn = () => {
212
+ didQueueTask = false;
213
+ if (newValue !== void 0) {
214
+ animValue.setValue(newValue);
215
+ }
216
+ };
217
+ const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
218
+ prevValue = newValue;
219
+ if (!didQueueTask) {
220
+ didQueueTask = true;
221
+ if (delayValue === 0) {
222
+ queueMicrotask(fn);
223
+ } else {
224
+ setTimeout(fn, delayValue);
225
+ }
226
+ }
227
+ } else {
228
+ animValue.setValue(newValue);
229
+ }
230
+ });
231
+ }, []);
232
+ return animValue;
233
+ }
234
+ var typedForwardRef = React3.forwardRef;
235
+ var typedMemo = React3.memo;
236
+
237
+ // src/components/PositionView.tsx
238
+ var PositionViewState = typedMemo(function PositionView({
239
+ id,
240
+ horizontal,
241
+ style,
242
+ refView,
243
+ ...rest
244
+ }) {
245
+ const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
246
+ return /* @__PURE__ */ React3__namespace.createElement(
247
+ LeanView,
248
+ {
249
+ ref: refView,
250
+ style: [
251
+ style,
252
+ horizontal ? { transform: [{ translateX: position }] } : { transform: [{ translateY: position }] }
253
+ ],
254
+ ...rest
255
+ }
256
+ );
257
+ });
258
+ var PositionViewAnimated = typedMemo(function PositionView2({
259
+ id,
260
+ horizontal,
261
+ style,
262
+ refView,
263
+ ...rest
264
+ }) {
265
+ const position$ = useValue$(`containerPosition${id}`, {
266
+ getValue: (v) => v != null ? v : POSITION_OUT_OF_VIEW
267
+ });
268
+ return /* @__PURE__ */ React3__namespace.createElement(
269
+ reactNative.Animated.View,
270
+ {
271
+ ref: refView,
272
+ style: [
273
+ style,
274
+ horizontal ? { transform: [{ translateX: position$ }] } : { transform: [{ translateY: position$ }] }
275
+ ],
276
+ ...rest
277
+ }
278
+ );
279
+ });
280
+ var PositionViewSticky = typedMemo(function PositionViewSticky2({
281
+ id,
282
+ horizontal,
283
+ style,
284
+ refView,
285
+ animatedScrollY,
286
+ stickyOffset,
287
+ index,
288
+ ...rest
289
+ }) {
290
+ const [position = POSITION_OUT_OF_VIEW] = useArr$([`containerPosition${id}`]);
291
+ const transform = React3__namespace.useMemo(() => {
292
+ if (animatedScrollY && stickyOffset) {
293
+ const stickyPosition = animatedScrollY.interpolate({
294
+ extrapolate: "clamp",
295
+ inputRange: [position, position + 5e3],
296
+ outputRange: [position, position + 5e3]
297
+ });
298
+ return horizontal ? [{ translateX: stickyPosition }] : [{ translateY: stickyPosition }];
299
+ }
300
+ }, [position, horizontal, animatedScrollY, stickyOffset]);
301
+ const viewStyle = React3__namespace.useMemo(() => [style, { zIndex: index + 1e3 }, { transform }], [style, transform]);
302
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { ref: refView, style: viewStyle, ...rest });
303
+ });
304
+ var PositionView3 = IsNewArchitecture ? PositionViewState : PositionViewAnimated;
305
+ function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
306
+ const [lastItemKeys] = useArr$(["lastItemKeys"]);
307
+ const isALastItem = lastItemKeys.includes(itemKey);
308
+ return isALastItem ? null : /* @__PURE__ */ React3__namespace.createElement(ItemSeparatorComponent, { leadingItem });
309
+ }
310
+ var symbolFirst = Symbol();
311
+ function useInit(cb) {
312
+ const refValue = React3.useRef(symbolFirst);
313
+ if (refValue.current === symbolFirst) {
314
+ refValue.current = cb();
315
+ }
316
+ return refValue.current;
317
+ }
180
318
 
181
- // src/helpers.ts
319
+ // src/utils/helpers.ts
182
320
  function isFunction(obj) {
183
321
  return typeof obj === "function";
184
322
  }
@@ -208,16 +346,8 @@ function getPadding(s, type) {
208
346
  function extractPadding(style, contentContainerStyle, type) {
209
347
  return getPadding(style, type) + getPadding(contentContainerStyle, type);
210
348
  }
211
- var symbolFirst = Symbol();
212
- function useInit(cb) {
213
- const refValue = React3.useRef(symbolFirst);
214
- if (refValue.current === symbolFirst) {
215
- refValue.current = cb();
216
- }
217
- return refValue.current;
218
- }
219
349
 
220
- // src/ContextContainer.ts
350
+ // src/state/ContextContainer.ts
221
351
  var ContextContainer = React3.createContext(null);
222
352
  function useViewability(callback, configId) {
223
353
  const ctx = useStateContext();
@@ -261,7 +391,7 @@ function useRecyclingEffect(effect) {
261
391
  prevItem: void 0
262
392
  });
263
393
  React3.useEffect(() => {
264
- let ret = void 0;
394
+ let ret;
265
395
  if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
266
396
  ret = effect({
267
397
  index,
@@ -275,7 +405,7 @@ function useRecyclingEffect(effect) {
275
405
  prevItem: value
276
406
  };
277
407
  return ret;
278
- }, [index, value]);
408
+ }, [index, value, effect]);
279
409
  }
280
410
  function useRecyclingState(valueOrFun) {
281
411
  const { index, value, itemKey, triggerLayout } = React3.useContext(ContextContainer);
@@ -313,43 +443,26 @@ function useListScrollSize() {
313
443
  const [scrollSize] = useArr$(["scrollSize"]);
314
444
  return scrollSize;
315
445
  }
316
- var LeanViewComponent = React3__namespace.forwardRef((props, ref) => {
317
- return React3__namespace.createElement("RCTView", { ...props, ref });
318
- });
319
- LeanViewComponent.displayName = "RCTView";
320
- var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
321
-
322
- // src/Separator.tsx
323
- function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
324
- const [lastItemKeys] = useArr$(["lastItemKeys"]);
325
- const isALastItem = lastItemKeys.includes(itemKey);
326
- return isALastItem ? null : /* @__PURE__ */ React.createElement(ItemSeparatorComponent, { leadingItem });
327
- }
328
-
329
- // src/constants.ts
330
- var POSITION_OUT_OF_VIEW = -1e7;
331
- var ENABLE_DEVMODE = __DEV__ && false;
332
- var ENABLE_DEBUG_VIEW = __DEV__ && false;
333
- var IsNewArchitecture = global.nativeFabricUIManager != null;
334
446
 
335
- // src/Container.tsx
336
- var Container = ({
447
+ // src/components/Container.tsx
448
+ var Container = typedMemo(function Container2({
337
449
  id,
338
450
  recycleItems,
339
451
  horizontal,
340
452
  getRenderedItem: getRenderedItem2,
341
453
  updateItemSize: updateItemSize2,
342
454
  ItemSeparatorComponent
343
- }) => {
455
+ }) {
344
456
  const ctx = useStateContext();
345
- const columnWrapperStyle = ctx.columnWrapperStyle;
346
- const [column = 0, data, itemKey, position = POSITION_OUT_OF_VIEW, numColumns, extraData] = useArr$([
457
+ const { columnWrapperStyle, animatedScrollY } = ctx;
458
+ const [column = 0, data, itemKey, numColumns, extraData, isSticky, stickyOffset] = useArr$([
347
459
  `containerColumn${id}`,
348
460
  `containerItemData${id}`,
349
461
  `containerItemKey${id}`,
350
- `containerPosition${id}`,
351
462
  "numColumns",
352
- "extraData"
463
+ "extraData",
464
+ `containerSticky${id}`,
465
+ `containerStickyOffset${id}`
353
466
  ]);
354
467
  const refLastSize = React3.useRef();
355
468
  const ref = React3.useRef(null);
@@ -357,47 +470,54 @@ var Container = ({
357
470
  const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
358
471
  const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
359
472
  let didLayout = false;
360
- let paddingStyles;
361
- if (columnWrapperStyle) {
362
- const { columnGap, rowGap, gap } = columnWrapperStyle;
363
- if (horizontal) {
364
- paddingStyles = {
365
- paddingRight: columnGap || gap || void 0,
366
- paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
367
- };
368
- } else {
369
- paddingStyles = {
370
- paddingBottom: rowGap || gap || void 0,
371
- paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
372
- };
473
+ const style = React3.useMemo(() => {
474
+ let paddingStyles;
475
+ if (columnWrapperStyle) {
476
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
477
+ if (horizontal) {
478
+ paddingStyles = {
479
+ paddingRight: columnGap || gap || void 0,
480
+ paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
481
+ };
482
+ } else {
483
+ paddingStyles = {
484
+ paddingBottom: rowGap || gap || void 0,
485
+ paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
486
+ };
487
+ }
373
488
  }
374
- }
375
- const style = horizontal ? {
376
- flexDirection: ItemSeparatorComponent ? "row" : void 0,
377
- position: "absolute",
378
- top: otherAxisPos,
379
- height: otherAxisSize,
380
- left: position,
381
- ...paddingStyles || {}
382
- } : {
383
- position: "absolute",
384
- left: otherAxisPos,
385
- right: numColumns > 1 ? null : 0,
386
- width: otherAxisSize,
387
- top: position,
388
- ...paddingStyles || {}
389
- };
489
+ return horizontal ? {
490
+ flexDirection: ItemSeparatorComponent ? "row" : void 0,
491
+ height: otherAxisSize,
492
+ left: 0,
493
+ position: "absolute",
494
+ top: otherAxisPos,
495
+ ...paddingStyles || {}
496
+ } : {
497
+ left: otherAxisPos,
498
+ position: "absolute",
499
+ right: numColumns > 1 ? null : 0,
500
+ top: 0,
501
+ width: otherAxisSize,
502
+ ...paddingStyles || {}
503
+ };
504
+ }, [horizontal, otherAxisPos, otherAxisSize, columnWrapperStyle, numColumns]);
390
505
  const renderedItemInfo = React3.useMemo(
391
506
  () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
392
507
  [itemKey, data, extraData]
393
508
  );
394
509
  const { index, renderedItem } = renderedItemInfo || {};
395
- const triggerLayout = React3.useCallback(() => {
396
- forceLayoutRender((v) => v + 1);
397
- }, []);
398
510
  const contextValue = React3.useMemo(() => {
399
511
  ctx.viewRefs.set(id, ref);
400
- return { containerId: id, itemKey, index, value: data, triggerLayout };
512
+ return {
513
+ containerId: id,
514
+ index,
515
+ itemKey,
516
+ triggerLayout: () => {
517
+ forceLayoutRender((v) => v + 1);
518
+ },
519
+ value: data
520
+ };
401
521
  }, [id, itemKey, index, data]);
402
522
  const onLayout = (event) => {
403
523
  var _a, _b;
@@ -406,14 +526,14 @@ var Container = ({
406
526
  let layout = event.nativeEvent.layout;
407
527
  const size = layout[horizontal ? "width" : "height"];
408
528
  const doUpdate = () => {
409
- refLastSize.current = { width: layout.width, height: layout.height };
529
+ refLastSize.current = { height: layout.height, width: layout.width };
410
530
  updateItemSize2(itemKey, layout);
411
531
  };
412
532
  if (IsNewArchitecture || size > 0) {
413
533
  doUpdate();
414
534
  } else {
415
- (_b = (_a = ref.current) == null ? void 0 : _a.measure) == null ? void 0 : _b.call(_a, (x, y, width, height) => {
416
- layout = { width, height };
535
+ (_b = (_a = ref.current) == null ? void 0 : _a.measure) == null ? void 0 : _b.call(_a, (_x, _y, width, height) => {
536
+ layout = { height, width };
417
537
  doUpdate();
418
538
  });
419
539
  }
@@ -446,59 +566,32 @@ var Container = ({
446
566
  }
447
567
  }, [itemKey]);
448
568
  }
449
- return /* @__PURE__ */ React3__namespace.createElement(LeanView, { style, onLayout, ref, key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(
450
- Separator,
569
+ const PositionComponent = isSticky ? PositionViewSticky : PositionView3;
570
+ return /* @__PURE__ */ React3__namespace.createElement(
571
+ PositionComponent,
451
572
  {
452
- itemKey,
453
- ItemSeparatorComponent,
454
- leadingItem: renderedItemInfo.item
455
- }
456
- )));
457
- };
458
- var typedForwardRef = React3.forwardRef;
459
- var typedMemo = React3.memo;
460
- var useAnimatedValue = (initialValue) => {
461
- return React3.useRef(new reactNative.Animated.Value(initialValue)).current;
462
- };
463
-
464
- // src/useValue$.ts
465
- function useValue$(key, params) {
466
- var _a;
467
- const { getValue, delay } = params || {};
468
- const ctx = useStateContext();
469
- const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
470
- React3.useMemo(() => {
471
- let newValue = void 0;
472
- let prevValue = void 0;
473
- let didQueueTask = false;
474
- listen$(ctx, key, (v) => {
475
- newValue = getValue ? getValue(v) : v;
476
- if (delay !== void 0) {
477
- const fn = () => {
478
- didQueueTask = false;
479
- if (newValue !== void 0) {
480
- animValue.setValue(newValue);
481
- }
482
- };
483
- const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
484
- prevValue = newValue;
485
- if (!didQueueTask) {
486
- didQueueTask = true;
487
- if (delayValue === 0) {
488
- queueMicrotask(fn);
489
- } else {
490
- setTimeout(fn, delayValue);
491
- }
492
- }
493
- } else {
494
- animValue.setValue(newValue);
573
+ animatedScrollY: isSticky ? animatedScrollY : void 0,
574
+ horizontal,
575
+ id,
576
+ index,
577
+ key: recycleItems ? void 0 : itemKey,
578
+ onLayout,
579
+ refView: ref,
580
+ stickyOffset: isSticky ? stickyOffset : void 0,
581
+ style
582
+ },
583
+ /* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(
584
+ Separator,
585
+ {
586
+ ItemSeparatorComponent,
587
+ itemKey,
588
+ leadingItem: renderedItemInfo.item
495
589
  }
496
- });
497
- }, []);
498
- return animValue;
499
- }
590
+ ))
591
+ );
592
+ });
500
593
 
501
- // src/Containers.tsx
594
+ // src/components/Containers.tsx
502
595
  var Containers = typedMemo(function Containers2({
503
596
  horizontal,
504
597
  recycleItems,
@@ -522,18 +615,18 @@ var Containers = typedMemo(function Containers2({
522
615
  /* @__PURE__ */ React3__namespace.createElement(
523
616
  Container,
524
617
  {
618
+ getRenderedItem: getRenderedItem2,
619
+ horizontal,
620
+ ItemSeparatorComponent,
525
621
  id: i,
526
622
  key: i,
527
623
  recycleItems,
528
- horizontal,
529
- getRenderedItem: getRenderedItem2,
530
- updateItemSize: updateItemSize2,
531
- ItemSeparatorComponent
624
+ updateItemSize: updateItemSize2
532
625
  }
533
626
  )
534
627
  );
535
628
  }
536
- const style = horizontal ? { width: animSize, opacity: animOpacity, minHeight: otherAxisSize } : { height: animSize, opacity: animOpacity, minWidth: otherAxisSize };
629
+ const style = horizontal ? { minHeight: otherAxisSize, opacity: animOpacity, width: animSize } : { height: animSize, minWidth: otherAxisSize, opacity: animOpacity };
537
630
  if (columnWrapperStyle && numColumns > 1) {
538
631
  const { columnGap, rowGap, gap } = columnWrapperStyle;
539
632
  const gapX = columnGap || gap || 0;
@@ -564,15 +657,21 @@ function ScrollAdjust() {
564
657
  reactNative.View,
565
658
  {
566
659
  style: {
567
- position: "absolute",
568
660
  height: 0,
569
- width: 0,
661
+ left: 0,
662
+ position: "absolute",
570
663
  top: scrollOffset,
571
- left: 0
664
+ width: 0
572
665
  }
573
666
  }
574
667
  );
575
668
  }
669
+
670
+ // src/components/SnapWrapper.tsx
671
+ function SnapWrapper({ ScrollComponent, ...props }) {
672
+ const [snapToOffsets] = useArr$(["snapToOffsets"]);
673
+ return /* @__PURE__ */ React.createElement(ScrollComponent, { ...props, snapToOffsets });
674
+ }
576
675
  function useSyncLayout({
577
676
  onChange
578
677
  }) {
@@ -583,17 +682,19 @@ function useSyncLayout({
583
682
  },
584
683
  [onChange]
585
684
  );
586
- React3.useLayoutEffect(() => {
587
- if (ref.current) {
588
- ref.current.measure((x, y, width, height) => {
589
- onChange({ x, y, width, height }, true);
590
- });
591
- }
592
- }, []);
685
+ if (IsNewArchitecture) {
686
+ React3.useLayoutEffect(() => {
687
+ if (ref.current) {
688
+ ref.current.measure((x, y, width, height) => {
689
+ onChange({ height, width, x, y }, true);
690
+ });
691
+ }
692
+ }, []);
693
+ }
593
694
  return { onLayout, ref };
594
695
  }
595
696
 
596
- // src/ListComponent.tsx
697
+ // src/components/ListComponent.tsx
597
698
  var getComponent = (Component) => {
598
699
  if (React3__namespace.isValidElement(Component)) {
599
700
  return Component;
@@ -613,12 +714,12 @@ var PaddingDevMode = () => {
613
714
  reactNative.Animated.View,
614
715
  {
615
716
  style: {
616
- position: "absolute",
617
- top: 0,
717
+ backgroundColor: "green",
618
718
  height: animPaddingTop,
619
719
  left: 0,
720
+ position: "absolute",
620
721
  right: 0,
621
- backgroundColor: "green"
722
+ top: 0
622
723
  }
623
724
  }
624
725
  ));
@@ -647,6 +748,8 @@ var ListComponent = typedMemo(function ListComponent2({
647
748
  renderScrollComponent,
648
749
  scrollAdjustHandler,
649
750
  onLayoutHeader,
751
+ snapToIndices,
752
+ stickyIndices,
650
753
  ...rest
651
754
  }) {
652
755
  const ctx = useStateContext();
@@ -656,7 +759,7 @@ var ListComponent = typedMemo(function ListComponent2({
656
759
  const ScrollComponent = renderScrollComponent ? React3.useMemo(
657
760
  () => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
658
761
  [renderScrollComponent]
659
- ) : reactNative.ScrollView;
762
+ ) : reactNative.Animated.ScrollView;
660
763
  React3__namespace.useEffect(() => {
661
764
  if (canRender) {
662
765
  setTimeout(() => {
@@ -664,76 +767,73 @@ var ListComponent = typedMemo(function ListComponent2({
664
767
  }, 0);
665
768
  }
666
769
  }, [canRender]);
770
+ const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
667
771
  return /* @__PURE__ */ React3__namespace.createElement(
668
- ScrollComponent,
772
+ SnapOrScroll,
669
773
  {
670
774
  ...rest,
671
- style,
672
- maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
673
775
  contentContainerStyle: [
674
776
  contentContainerStyle,
675
777
  horizontal ? {
676
778
  height: "100%"
677
779
  } : {}
678
780
  ],
679
- onScroll: onScroll2,
680
- onLayout,
681
- horizontal,
682
781
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
683
- ref: refScrollView
782
+ horizontal,
783
+ maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
784
+ onLayout,
785
+ onScroll: onScroll2,
786
+ ref: refScrollView,
787
+ ScrollComponent: snapToIndices ? ScrollComponent : void 0,
788
+ style
684
789
  },
685
790
  maintainVisibleContentPosition && /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
686
791
  ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
687
- ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: ListHeaderComponentStyle, onLayout: onLayoutHeaderSync, ref: refHeader }, getComponent(ListHeaderComponent)),
792
+ ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { onLayout: onLayoutHeaderSync, ref: refHeader, style: ListHeaderComponentStyle }, getComponent(ListHeaderComponent)),
688
793
  ListEmptyComponent && getComponent(ListEmptyComponent),
689
794
  canRender && /* @__PURE__ */ React3__namespace.createElement(
690
795
  Containers,
691
796
  {
692
- horizontal,
693
- recycleItems,
694
- waitForInitialLayout,
695
797
  getRenderedItem: getRenderedItem2,
798
+ horizontal,
696
799
  ItemSeparatorComponent,
697
- updateItemSize: updateItemSize2
800
+ recycleItems,
801
+ updateItemSize: updateItemSize2,
802
+ waitForInitialLayout
698
803
  }
699
804
  ),
700
805
  ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(
701
806
  reactNative.View,
702
807
  {
703
- style: ListFooterComponentStyle,
704
808
  onLayout: (event) => {
705
809
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
706
810
  set$(ctx, "footerSize", size);
707
- }
811
+ },
812
+ style: ListFooterComponentStyle
708
813
  },
709
814
  getComponent(ListFooterComponent)
710
- )
815
+ ),
816
+ __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React3__namespace.createElement(DevNumbers, null)
711
817
  );
712
818
  });
819
+ var DevNumbers = __DEV__ && React3__namespace.memo(function DevNumbers2() {
820
+ return Array.from({ length: 100 }).map((_, index) => /* @__PURE__ */ React3__namespace.createElement(
821
+ reactNative.View,
822
+ {
823
+ key: index,
824
+ style: {
825
+ height: 100,
826
+ pointerEvents: "none",
827
+ position: "absolute",
828
+ top: index * 100,
829
+ width: "100%"
830
+ }
831
+ },
832
+ /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, { style: { color: "red" } }, index * 100)
833
+ ));
834
+ });
713
835
 
714
- // src/ScrollAdjustHandler.ts
715
- var ScrollAdjustHandler = class {
716
- constructor(ctx) {
717
- this.appliedAdjust = 0;
718
- this.mounted = false;
719
- this.context = ctx;
720
- }
721
- requestAdjust(add) {
722
- const oldAdjustTop = peek$(this.context, "scrollAdjust") || 0;
723
- this.appliedAdjust = add + oldAdjustTop;
724
- const set = () => set$(this.context, "scrollAdjust", this.appliedAdjust);
725
- if (this.mounted) {
726
- set();
727
- } else {
728
- requestAnimationFrame(set);
729
- }
730
- }
731
- setMounted() {
732
- this.mounted = true;
733
- }
734
- };
735
-
736
- // src/getId.ts
836
+ // src/utils/getId.ts
737
837
  function getId(state, index) {
738
838
  const { data, keyExtractor } = state.props;
739
839
  if (!data) {
@@ -745,7 +845,7 @@ function getId(state, index) {
745
845
  return id;
746
846
  }
747
847
 
748
- // src/calculateOffsetForIndex.ts
848
+ // src/core/calculateOffsetForIndex.ts
749
849
  function calculateOffsetForIndex(ctx, state, index) {
750
850
  let position = 0;
751
851
  if (index !== void 0) {
@@ -762,21 +862,37 @@ function calculateOffsetForIndex(ctx, state, index) {
762
862
  return position;
763
863
  }
764
864
 
765
- // src/getItemSize.ts
766
- function getItemSize(state, key, index, data, useAverageSize) {
865
+ // src/utils/getItemSize.ts
866
+ function getItemSize(state, key, index, data, useAverageSize, defaultAverageSize) {
867
+ var _a, _b;
767
868
  const {
768
869
  sizesKnown,
769
870
  sizes,
770
871
  scrollingTo,
771
- props: { estimatedItemSize, getEstimatedItemSize }
872
+ averageSizes,
873
+ props: { estimatedItemSize, getEstimatedItemSize, getFixedItemSize, getItemType }
772
874
  } = state;
773
875
  const sizeKnown = sizesKnown.get(key);
774
876
  if (sizeKnown !== void 0) {
775
877
  return sizeKnown;
776
878
  }
777
879
  let size;
778
- if (IsNewArchitecture && useAverageSize !== void 0 && sizeKnown === void 0 && !getEstimatedItemSize && !scrollingTo) {
779
- size = useAverageSize;
880
+ const itemType = getItemType ? (_a = getItemType(data, index)) != null ? _a : "" : "";
881
+ if (getFixedItemSize) {
882
+ size = getFixedItemSize(index, data, itemType);
883
+ if (size !== void 0) {
884
+ sizesKnown.set(key, size);
885
+ }
886
+ }
887
+ if (size === void 0 && useAverageSize && sizeKnown === void 0 && !scrollingTo) {
888
+ if (itemType === "") {
889
+ size = defaultAverageSize;
890
+ } else {
891
+ const averageSizeForType = (_b = averageSizes[itemType]) == null ? void 0 : _b.avg;
892
+ if (averageSizeForType !== void 0) {
893
+ size = roundSize(averageSizeForType);
894
+ }
895
+ }
780
896
  }
781
897
  if (size === void 0) {
782
898
  size = sizes.get(key);
@@ -785,13 +901,13 @@ function getItemSize(state, key, index, data, useAverageSize) {
785
901
  }
786
902
  }
787
903
  if (size === void 0) {
788
- size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
904
+ size = getEstimatedItemSize ? getEstimatedItemSize(index, data, itemType) : estimatedItemSize;
789
905
  }
790
906
  sizes.set(key, size);
791
907
  return size;
792
908
  }
793
909
 
794
- // src/calculateOffsetWithOffsetPosition.ts
910
+ // src/core/calculateOffsetWithOffsetPosition.ts
795
911
  function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
796
912
  const { index, viewOffset, viewPosition } = params;
797
913
  let offset = offsetParam;
@@ -804,127 +920,50 @@ function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
804
920
  return offset;
805
921
  }
806
922
 
807
- // src/checkAllSizesKnown.ts
808
- function checkAllSizesKnown(state) {
809
- const { startBuffered, endBuffered, sizesKnown } = state;
810
- if (endBuffered !== null) {
811
- let areAllKnown = true;
812
- for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
813
- const key = getId(state, i);
814
- areAllKnown && (areAllKnown = sizesKnown.has(key));
815
- }
816
- return areAllKnown;
923
+ // src/core/getEffectiveScroll.ts
924
+ function getEffectiveScroll(ctx, state) {
925
+ const { scroll: scrollState, scrollLength } = state;
926
+ const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
927
+ const totalSize = peek$(ctx, "totalSize");
928
+ let scroll = scrollState - topPad;
929
+ if (scroll + scrollLength > totalSize) {
930
+ scroll = Math.max(0, totalSize - scrollLength);
817
931
  }
818
- return false;
932
+ return scroll;
819
933
  }
820
934
 
821
- // src/findAvailableContainers.ts
822
- function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval) {
823
- const numContainers = peek$(ctx, "numContainers");
824
- const result = [];
825
- const availableContainers = [];
826
- for (let u = 0; u < numContainers; u++) {
827
- const key = peek$(ctx, `containerItemKey${u}`);
828
- let isOk = key === void 0;
829
- if (!isOk) {
830
- const index = pendingRemoval.indexOf(u);
831
- if (index !== -1) {
832
- pendingRemoval.splice(index, 1);
833
- isOk = true;
834
- }
835
- }
836
- if (isOk) {
837
- result.push(u);
838
- if (result.length >= numNeeded) {
839
- return result;
840
- }
841
- }
842
- }
843
- for (let u = 0; u < numContainers; u++) {
844
- const key = peek$(ctx, `containerItemKey${u}`);
845
- if (key === void 0) continue;
846
- const index = state.indexByKey.get(key);
847
- if (index < startBuffered) {
848
- availableContainers.push({ index: u, distance: startBuffered - index });
849
- } else if (index > endBuffered) {
850
- availableContainers.push({ index: u, distance: index - endBuffered });
851
- }
852
- }
853
- const remaining = numNeeded - result.length;
854
- if (remaining > 0) {
855
- if (availableContainers.length > 0) {
856
- if (availableContainers.length > remaining) {
857
- availableContainers.sort(comparatorByDistance);
858
- availableContainers.length = remaining;
859
- }
860
- for (const container of availableContainers) {
861
- result.push(container.index);
862
- }
863
- }
864
- const stillNeeded = numNeeded - result.length;
865
- if (stillNeeded > 0) {
866
- for (let i = 0; i < stillNeeded; i++) {
867
- result.push(numContainers + i);
868
- }
869
- if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
870
- console.warn(
871
- "[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
872
- {
873
- debugInfo: {
874
- numContainers,
875
- numNeeded,
876
- stillNeeded,
877
- numContainersPooled: peek$(ctx, "numContainersPooled")
878
- }
879
- }
880
- );
881
- }
882
- }
935
+ // src/core/finishScrollTo.ts
936
+ var finishScrollTo = (state) => {
937
+ if (state) {
938
+ state.scrollingTo = void 0;
939
+ state.scrollHistory.length = 0;
883
940
  }
884
- return result.sort(comparatorDefault);
885
- }
886
- function comparatorByDistance(a, b) {
887
- return b.distance - a.distance;
888
- }
941
+ };
889
942
 
890
- // src/getScrollVelocity.ts
891
- var getScrollVelocity = (state) => {
892
- const { scrollHistory } = state;
893
- let velocity = 0;
894
- if (scrollHistory.length >= 1) {
895
- const newest = scrollHistory[scrollHistory.length - 1];
896
- let oldest;
897
- let start = 0;
898
- for (let i = 0; i < scrollHistory.length - 1; i++) {
899
- const entry = scrollHistory[i];
900
- const nextEntry = scrollHistory[i + 1];
901
- if (i > 0) {
902
- const prevEntry = scrollHistory[i - 1];
903
- const prevDirection = entry.scroll - prevEntry.scroll;
904
- const currentDirection = nextEntry.scroll - entry.scroll;
905
- if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
906
- start = i;
907
- break;
908
- }
909
- }
910
- }
911
- for (let i = start; i < scrollHistory.length - 1; i++) {
912
- const entry = scrollHistory[i];
913
- if (newest.time - entry.time <= 1e3) {
914
- oldest = entry;
915
- break;
916
- }
917
- }
918
- if (oldest) {
919
- const scrollDiff = newest.scroll - oldest.scroll;
920
- const timeDiff = newest.time - oldest.time;
921
- velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
922
- }
943
+ // src/core/scrollTo.ts
944
+ function scrollTo(state, params = {}) {
945
+ var _a;
946
+ const { animated } = params;
947
+ const {
948
+ refScroller,
949
+ props: { horizontal }
950
+ } = state;
951
+ const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
952
+ state.scrollHistory.length = 0;
953
+ state.scrollingTo = params;
954
+ state.scrollPending = offset;
955
+ (_a = refScroller.current) == null ? void 0 : _a.scrollTo({
956
+ animated: !!animated,
957
+ x: horizontal ? offset : 0,
958
+ y: horizontal ? 0 : offset
959
+ });
960
+ if (!animated) {
961
+ state.scroll = offset;
962
+ setTimeout(() => finishScrollTo(state), 100);
923
963
  }
924
- return velocity;
925
- };
964
+ }
926
965
 
927
- // src/requestAdjust.ts
966
+ // src/utils/requestAdjust.ts
928
967
  function requestAdjust(ctx, state, positionDiff) {
929
968
  if (Math.abs(positionDiff) > 0.1) {
930
969
  const doit = () => {
@@ -956,8 +995,28 @@ function requestAdjust(ctx, state, positionDiff) {
956
995
  }
957
996
  }
958
997
 
959
- // src/prepareMVCP.ts
960
- function prepareMVCP(ctx, state) {
998
+ // src/core/mvcp.ts
999
+ function getItemsInView(ctx, state) {
1000
+ const { startNoBuffer, endNoBuffer, positions, scrollLength } = state;
1001
+ const idsInViewWithPositions = [];
1002
+ const scroll = getEffectiveScroll(ctx, state);
1003
+ if (startNoBuffer !== null && endNoBuffer !== null) {
1004
+ for (let i = startNoBuffer; i <= endNoBuffer; i++) {
1005
+ const id = getId(state, i);
1006
+ if (id) {
1007
+ const position = positions.get(id);
1008
+ if (position === void 0 || position > scroll + scrollLength) {
1009
+ break;
1010
+ } else if (position >= scroll) {
1011
+ idsInViewWithPositions.push({ id, position });
1012
+ }
1013
+ }
1014
+ }
1015
+ }
1016
+ return idsInViewWithPositions;
1017
+ }
1018
+ function prepareMVCP(ctx, state, dataChanged) {
1019
+ var _a;
961
1020
  const {
962
1021
  positions,
963
1022
  scrollingTo,
@@ -965,170 +1024,62 @@ function prepareMVCP(ctx, state) {
965
1024
  } = state;
966
1025
  let prevPosition;
967
1026
  let targetId;
968
- let targetIndex;
1027
+ let idsInViewWithPositions;
969
1028
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
970
1029
  if (maintainVisibleContentPosition) {
971
1030
  const indexByKey = state.indexByKey;
972
1031
  if (scrollTarget !== void 0) {
973
1032
  targetId = getId(state, scrollTarget);
974
- targetIndex = scrollTarget;
975
- } else if (state.idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
976
- targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
977
- targetIndex = indexByKey.get(targetId);
1033
+ } else if (peek$(ctx, "containersDidLayout")) {
1034
+ idsInViewWithPositions = getItemsInView(ctx, state);
1035
+ if (!dataChanged) {
1036
+ targetId = (_a = idsInViewWithPositions.find(({ id }) => indexByKey.get(id) !== void 0)) == null ? void 0 : _a.id;
1037
+ }
978
1038
  }
979
- if (targetId !== void 0 && targetIndex !== void 0) {
1039
+ if (targetId !== void 0) {
980
1040
  prevPosition = positions.get(targetId);
981
1041
  }
982
1042
  }
983
1043
  return () => {
1044
+ let positionDiff;
1045
+ if (dataChanged && idsInViewWithPositions && targetId === void 0) {
1046
+ for (let i = 0; i < idsInViewWithPositions.length; i++) {
1047
+ const { id, position } = idsInViewWithPositions[i];
1048
+ const newPosition = positions.get(id);
1049
+ if (newPosition !== void 0) {
1050
+ positionDiff = newPosition - position;
1051
+ break;
1052
+ }
1053
+ }
1054
+ }
984
1055
  if (targetId !== void 0 && prevPosition !== void 0) {
985
1056
  const newPosition = positions.get(targetId);
986
1057
  if (newPosition !== void 0) {
987
- const positionDiff = newPosition - prevPosition;
988
- if (Math.abs(positionDiff) > 0.1) {
989
- requestAdjust(ctx, state, positionDiff);
990
- }
1058
+ positionDiff = newPosition - prevPosition;
991
1059
  }
992
1060
  }
993
- };
994
- }
995
-
996
- // src/checkThreshold.ts
997
- var checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
998
- const distanceAbs = Math.abs(distance);
999
- const isAtThreshold = atThreshold || distanceAbs < threshold;
1000
- if (!isReached && !isBlockedByTimer) {
1001
- if (isAtThreshold) {
1002
- onReached == null ? void 0 : onReached(distance);
1003
- blockTimer == null ? void 0 : blockTimer(true);
1004
- setTimeout(() => {
1005
- blockTimer == null ? void 0 : blockTimer(false);
1006
- }, 700);
1007
- return true;
1008
- }
1009
- } else {
1010
- if (distance >= 1.3 * threshold) {
1011
- return false;
1012
- }
1013
- }
1014
- return isReached;
1015
- };
1016
-
1017
- // src/checkAtBottom.ts
1018
- function checkAtBottom(ctx, state) {
1019
- if (!state) {
1020
- return;
1021
- }
1022
- const {
1023
- queuedInitialLayout,
1024
- scrollLength,
1025
- scroll,
1026
- maintainingScrollAtEnd,
1027
- props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
1028
- } = state;
1029
- const contentSize = getContentSize(ctx);
1030
- if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
1031
- const distanceFromEnd = contentSize - scroll - scrollLength;
1032
- const isContentLess = contentSize < scrollLength;
1033
- state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1034
- state.isEndReached = checkThreshold(
1035
- distanceFromEnd,
1036
- isContentLess,
1037
- onEndReachedThreshold * scrollLength,
1038
- state.isEndReached,
1039
- state.endReachedBlockedByTimer,
1040
- (distance) => {
1041
- var _a, _b;
1042
- return (_b = (_a = state.props).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
1043
- },
1044
- (block) => {
1045
- state.endReachedBlockedByTimer = block;
1061
+ if (positionDiff !== void 0 && Math.abs(positionDiff) > 0.1) {
1062
+ if (reactNative.Platform.OS === "android" && !IsNewArchitecture && dataChanged && state.scroll <= positionDiff) {
1063
+ scrollTo(state, {
1064
+ offset: state.scroll + positionDiff
1065
+ });
1066
+ } else {
1067
+ requestAdjust(ctx, state, positionDiff);
1046
1068
  }
1047
- );
1048
- }
1049
- }
1050
-
1051
- // src/finishScrollTo.ts
1052
- var finishScrollTo = (state) => {
1053
- if (state) {
1054
- state.scrollingTo = void 0;
1055
- state.scrollHistory.length = 0;
1056
- }
1057
- };
1058
-
1059
- // src/scrollTo.ts
1060
- function scrollTo(state, params = {}) {
1061
- var _a;
1062
- const { animated } = params;
1063
- const {
1064
- refScroller,
1065
- props: { horizontal }
1066
- } = state;
1067
- const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
1068
- state.scrollHistory.length = 0;
1069
- state.scrollingTo = params;
1070
- state.scrollPending = offset;
1071
- (_a = refScroller.current) == null ? void 0 : _a.scrollTo({
1072
- x: horizontal ? offset : 0,
1073
- y: horizontal ? 0 : offset,
1074
- animated: !!animated
1075
- });
1076
- if (!animated) {
1077
- state.scroll = offset;
1078
- setTimeout(() => finishScrollTo(state), 100);
1079
- }
1080
- }
1081
-
1082
- // src/scrollToIndex.ts
1083
- function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1084
- if (index >= state.props.data.length) {
1085
- index = state.props.data.length - 1;
1086
- } else if (index < 0) {
1087
- index = 0;
1088
- }
1089
- const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
1090
- const isLast = index === state.props.data.length - 1;
1091
- if (isLast && viewPosition === void 0) {
1092
- viewPosition = 1;
1093
- }
1094
- const firstIndexScrollPostion = firstIndexOffset - viewOffset;
1095
- state.scrollForNextCalculateItemsInView = void 0;
1096
- scrollTo(state, {
1097
- offset: firstIndexScrollPostion,
1098
- animated,
1099
- index,
1100
- viewPosition: viewPosition != null ? viewPosition : 0,
1101
- viewOffset
1102
- });
1103
- }
1104
-
1105
- // src/setDidLayout.ts
1106
- function setDidLayout(ctx, state) {
1107
- const {
1108
- loadStartTime,
1109
- initialScroll,
1110
- props: { onLoad }
1111
- } = state;
1112
- state.queuedInitialLayout = true;
1113
- checkAtBottom(ctx, state);
1114
- if (!IsNewArchitecture && initialScroll) {
1115
- scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1116
- }
1117
- set$(ctx, "containersDidLayout", true);
1118
- if (onLoad) {
1119
- onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1120
- }
1069
+ }
1070
+ };
1121
1071
  }
1122
1072
 
1123
- // src/setPaddingTop.ts
1124
- function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
1073
+ // src/utils/setPaddingTop.ts
1074
+ function setPaddingTop(ctx, state, { stylePaddingTop, alignItemsPaddingTop }) {
1125
1075
  if (stylePaddingTop !== void 0) {
1126
1076
  const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
1127
1077
  if (stylePaddingTop < prevStylePaddingTop) {
1128
- const prevTotalSize = peek$(ctx, "totalSize") || 0;
1078
+ let prevTotalSize = peek$(ctx, "totalSize");
1129
1079
  set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
1130
- setTimeout(() => {
1131
- set$(ctx, "totalSize", prevTotalSize);
1080
+ state.timeoutSetPaddingTop = setTimeout(() => {
1081
+ prevTotalSize = peek$(ctx, "totalSize");
1082
+ set$(ctx, "totalSize", prevTotalSize - prevStylePaddingTop);
1132
1083
  }, 16);
1133
1084
  }
1134
1085
  set$(ctx, "stylePaddingTop", stylePaddingTop);
@@ -1138,7 +1089,7 @@ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
1138
1089
  }
1139
1090
  }
1140
1091
 
1141
- // src/updateAlignItemsPaddingTop.ts
1092
+ // src/utils/updateAlignItemsPaddingTop.ts
1142
1093
  function updateAlignItemsPaddingTop(ctx, state) {
1143
1094
  const {
1144
1095
  scrollLength,
@@ -1150,55 +1101,118 @@ function updateAlignItemsPaddingTop(ctx, state) {
1150
1101
  const contentSize = getContentSize(ctx);
1151
1102
  alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
1152
1103
  }
1153
- setPaddingTop(ctx, { alignItemsPaddingTop });
1104
+ setPaddingTop(ctx, state, { alignItemsPaddingTop });
1105
+ }
1106
+ }
1107
+
1108
+ // src/core/updateTotalSize.ts
1109
+ function updateTotalSize(ctx, state) {
1110
+ const {
1111
+ positions,
1112
+ props: { data }
1113
+ } = state;
1114
+ if (data.length === 0) {
1115
+ addTotalSize(ctx, state, null, 0);
1116
+ } else {
1117
+ const lastId = getId(state, data.length - 1);
1118
+ if (lastId !== void 0) {
1119
+ const lastPosition = positions.get(lastId);
1120
+ if (lastPosition !== void 0) {
1121
+ const lastSize = getItemSize(state, lastId, data.length - 1, data[data.length - 1]);
1122
+ if (lastSize !== void 0) {
1123
+ const totalSize = lastPosition + lastSize;
1124
+ addTotalSize(ctx, state, null, totalSize);
1125
+ }
1126
+ }
1127
+ }
1128
+ }
1129
+ }
1130
+ function addTotalSize(ctx, state, key, add) {
1131
+ const { alignItemsAtEnd } = state.props;
1132
+ {
1133
+ state.totalSize = add;
1134
+ if (state.timeoutSetPaddingTop) {
1135
+ clearTimeout(state.timeoutSetPaddingTop);
1136
+ state.timeoutSetPaddingTop = void 0;
1137
+ }
1138
+ }
1139
+ set$(ctx, "totalSize", state.totalSize);
1140
+ if (alignItemsAtEnd) {
1141
+ updateAlignItemsPaddingTop(ctx, state);
1142
+ }
1143
+ }
1144
+
1145
+ // src/utils/getScrollVelocity.ts
1146
+ var getScrollVelocity = (state) => {
1147
+ const { scrollHistory } = state;
1148
+ let velocity = 0;
1149
+ if (scrollHistory.length >= 1) {
1150
+ const newest = scrollHistory[scrollHistory.length - 1];
1151
+ let oldest;
1152
+ let start = 0;
1153
+ const now = Date.now();
1154
+ for (let i = 0; i < scrollHistory.length - 1; i++) {
1155
+ const entry = scrollHistory[i];
1156
+ const nextEntry = scrollHistory[i + 1];
1157
+ if (i > 0) {
1158
+ const prevEntry = scrollHistory[i - 1];
1159
+ const prevDirection = entry.scroll - prevEntry.scroll;
1160
+ const currentDirection = nextEntry.scroll - entry.scroll;
1161
+ if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
1162
+ start = i;
1163
+ break;
1164
+ }
1165
+ }
1166
+ }
1167
+ for (let i = start; i < scrollHistory.length - 1; i++) {
1168
+ const entry = scrollHistory[i];
1169
+ if (now - entry.time <= 1e3) {
1170
+ oldest = entry;
1171
+ break;
1172
+ }
1173
+ }
1174
+ if (oldest && oldest !== newest) {
1175
+ const scrollDiff = newest.scroll - oldest.scroll;
1176
+ const timeDiff = newest.time - oldest.time;
1177
+ velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
1178
+ }
1154
1179
  }
1155
- }
1180
+ return velocity;
1181
+ };
1156
1182
 
1157
- // src/updateTotalSize.ts
1158
- function updateTotalSize(ctx, state) {
1183
+ // src/utils/updateSnapToOffsets.ts
1184
+ function updateSnapToOffsets(ctx, state) {
1159
1185
  const {
1160
1186
  positions,
1161
- props: { data }
1187
+ props: { snapToIndices }
1162
1188
  } = state;
1163
- if (data.length === 0) {
1164
- addTotalSize(ctx, state, null, 0);
1165
- } else {
1166
- const lastId = getId(state, data.length - 1);
1167
- if (lastId !== void 0) {
1168
- const lastPosition = positions.get(lastId);
1169
- if (lastPosition !== void 0) {
1170
- const lastSize = getItemSize(state, lastId, data.length - 1, data[data.length - 1]);
1171
- if (lastSize !== void 0) {
1172
- const totalSize = lastPosition + lastSize;
1173
- addTotalSize(ctx, state, null, totalSize);
1174
- }
1175
- }
1176
- }
1177
- }
1178
- }
1179
- function addTotalSize(ctx, state, key, add) {
1180
- const { alignItemsAtEnd } = state.props;
1181
- {
1182
- state.totalSize = add;
1183
- }
1184
- set$(ctx, "totalSize", state.totalSize);
1185
- if (alignItemsAtEnd) {
1186
- updateAlignItemsPaddingTop(ctx, state);
1189
+ const snapToOffsets = Array(snapToIndices.length);
1190
+ for (let i = 0; i < snapToIndices.length; i++) {
1191
+ const idx = snapToIndices[i];
1192
+ const key = getId(state, idx);
1193
+ snapToOffsets[i] = positions.get(key);
1187
1194
  }
1195
+ set$(ctx, "snapToOffsets", snapToOffsets);
1188
1196
  }
1189
1197
 
1190
- // src/updateAllPositions.ts
1198
+ // src/core/updateAllPositions.ts
1191
1199
  function updateAllPositions(ctx, state, dataChanged) {
1192
1200
  var _a, _b, _c, _d, _e;
1193
- const { averageSizes, columns, indexByKey, positions, firstFullyOnScreenIndex, idCache, sizesKnown } = state;
1201
+ const {
1202
+ averageSizes,
1203
+ columns,
1204
+ indexByKey,
1205
+ positions,
1206
+ firstFullyOnScreenIndex,
1207
+ idCache,
1208
+ sizesKnown,
1209
+ props: { getEstimatedItemSize, snapToIndices }
1210
+ } = state;
1194
1211
  const data = state.props.data;
1195
1212
  const numColumns = peek$(ctx, "numColumns");
1196
1213
  const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
1197
1214
  const scrollVelocity = getScrollVelocity(state);
1198
- if (dataChanged) {
1199
- indexByKey.clear();
1200
- idCache.clear();
1201
- }
1215
+ const useAverageSize = false;
1202
1216
  const itemType = "";
1203
1217
  let averageSize = (_a = averageSizes[itemType]) == null ? void 0 : _a.avg;
1204
1218
  if (averageSize !== void 0) {
@@ -1214,7 +1228,7 @@ function updateAllPositions(ctx, state, dataChanged) {
1214
1228
  let bailout = false;
1215
1229
  for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
1216
1230
  const id = (_b = idCache.get(i)) != null ? _b : getId(state, i);
1217
- const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], averageSize);
1231
+ const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
1218
1232
  const itemColumn = columns.get(id);
1219
1233
  maxSizeInRow2 = Math.max(maxSizeInRow2, size);
1220
1234
  if (itemColumn === 1) {
@@ -1241,7 +1255,7 @@ function updateAllPositions(ctx, state, dataChanged) {
1241
1255
  const dataLength = data.length;
1242
1256
  for (let i = 0; i < dataLength; i++) {
1243
1257
  const id = (_d = idCache.get(i)) != null ? _d : getId(state, i);
1244
- const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], averageSize);
1258
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], useAverageSize, averageSize);
1245
1259
  if (__DEV__ && needsIndexByKey) {
1246
1260
  if (indexByKeyForChecking.has(id)) {
1247
1261
  console.error(
@@ -1270,9 +1284,12 @@ function updateAllPositions(ctx, state, dataChanged) {
1270
1284
  }
1271
1285
  }
1272
1286
  updateTotalSize(ctx, state);
1287
+ if (snapToIndices) {
1288
+ updateSnapToOffsets(ctx, state);
1289
+ }
1273
1290
  }
1274
1291
 
1275
- // src/viewability.ts
1292
+ // src/core/viewability.ts
1276
1293
  var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
1277
1294
  function setupViewability(props) {
1278
1295
  let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
@@ -1280,27 +1297,31 @@ function setupViewability(props) {
1280
1297
  viewabilityConfigCallbackPairs = [
1281
1298
  ...viewabilityConfigCallbackPairs || [],
1282
1299
  {
1300
+ onViewableItemsChanged,
1283
1301
  viewabilityConfig: viewabilityConfig || {
1284
1302
  viewAreaCoveragePercentThreshold: 0
1285
- },
1286
- onViewableItemsChanged
1303
+ }
1287
1304
  }
1288
1305
  ];
1289
1306
  }
1290
1307
  if (viewabilityConfigCallbackPairs) {
1291
1308
  for (const pair of viewabilityConfigCallbackPairs) {
1292
1309
  mapViewabilityConfigCallbackPairs.set(pair.viewabilityConfig.id, {
1293
- viewableItems: [],
1294
- start: -1,
1295
1310
  end: -1,
1311
+ previousEnd: -1,
1296
1312
  previousStart: -1,
1297
- previousEnd: -1
1313
+ start: -1,
1314
+ viewableItems: []
1298
1315
  });
1299
1316
  }
1300
1317
  }
1301
1318
  return viewabilityConfigCallbackPairs;
1302
1319
  }
1303
1320
  function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
1321
+ const {
1322
+ timeouts,
1323
+ props: { data }
1324
+ } = state;
1304
1325
  for (const viewabilityConfigCallbackPair of viewabilityConfigCallbackPairs) {
1305
1326
  const viewabilityState = mapViewabilityConfigCallbackPairs.get(
1306
1327
  viewabilityConfigCallbackPair.viewabilityConfig.id
@@ -1309,12 +1330,12 @@ function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollS
1309
1330
  viewabilityState.end = end;
1310
1331
  if (viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime) {
1311
1332
  const timer = setTimeout(() => {
1312
- state.timeouts.delete(timer);
1313
- updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
1333
+ timeouts.delete(timer);
1334
+ updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
1314
1335
  }, viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime);
1315
- state.timeouts.add(timer);
1336
+ timeouts.add(timer);
1316
1337
  } else {
1317
- updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
1338
+ updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
1318
1339
  }
1319
1340
  }
1320
1341
  }
@@ -1366,11 +1387,11 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1366
1387
  const containerId = findContainerId(ctx, key);
1367
1388
  if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1368
1389
  const viewToken = {
1369
- item,
1370
- key,
1390
+ containerId,
1371
1391
  index: i,
1372
1392
  isViewable: true,
1373
- containerId
1393
+ item,
1394
+ key
1374
1395
  };
1375
1396
  viewableItems.push(viewToken);
1376
1397
  if (!(previousViewableItems == null ? void 0 : previousViewableItems.find((v) => v.key === viewToken.key))) {
@@ -1380,9 +1401,9 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1380
1401
  }
1381
1402
  }
1382
1403
  Object.assign(viewabilityState, {
1383
- viewableItems,
1404
+ previousEnd: end,
1384
1405
  previousStart: start,
1385
- previousEnd: end
1406
+ viewableItems
1386
1407
  });
1387
1408
  if (changed.length > 0) {
1388
1409
  viewabilityState.viewableItems = viewableItems;
@@ -1391,7 +1412,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, stat
1391
1412
  maybeUpdateViewabilityCallback(ctx, configId, change.containerId, change);
1392
1413
  }
1393
1414
  if (onViewableItemsChanged) {
1394
- onViewableItemsChanged({ viewableItems, changed });
1415
+ onViewableItemsChanged({ changed, viewableItems });
1395
1416
  }
1396
1417
  }
1397
1418
  for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
@@ -1417,16 +1438,16 @@ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scr
1417
1438
  const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1418
1439
  const isViewable2 = percent >= viewablePercentThreshold;
1419
1440
  const value = {
1441
+ containerId,
1420
1442
  index,
1421
1443
  isViewable: isViewable2,
1422
1444
  item,
1423
1445
  key,
1424
- percentVisible,
1425
1446
  percentOfScroller,
1426
- sizeVisible,
1427
- size,
1447
+ percentVisible,
1428
1448
  scrollSize,
1429
- containerId
1449
+ size,
1450
+ sizeVisible
1430
1451
  };
1431
1452
  if (JSON.stringify(value) !== JSON.stringify(ctx.mapViewabilityAmountValues.get(containerId))) {
1432
1453
  ctx.mapViewabilityAmountValues.set(containerId, value);
@@ -1458,319 +1479,611 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
1458
1479
  cb == null ? void 0 : cb(viewToken);
1459
1480
  }
1460
1481
 
1461
- // src/calculateItemsInView.ts
1462
- function calculateItemsInView(ctx, state, params = {}) {
1463
- var _a, _b, _c, _d, _e, _f, _g, _h;
1464
- const {
1465
- scrollLength,
1466
- startBufferedId: startBufferedIdOrig,
1467
- positions,
1468
- columns,
1469
- containerItemKeys,
1470
- idCache,
1471
- sizes,
1472
- indexByKey,
1473
- scrollForNextCalculateItemsInView,
1474
- enableScrollForNextCalculateItemsInView,
1475
- minIndexSizeChanged
1476
- } = state;
1477
- const data = state.props.data;
1478
- if (!data || scrollLength === 0) {
1479
- return;
1480
- }
1481
- const totalSize = peek$(ctx, "totalSize");
1482
- const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
1483
- const numColumns = peek$(ctx, "numColumns");
1484
- const previousScrollAdjust = 0;
1485
- const { dataChanged, doMVCP } = params;
1486
- const speed = getScrollVelocity(state);
1487
- if (doMVCP || dataChanged) {
1488
- const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
1489
- updateAllPositions(ctx, state, dataChanged);
1490
- checkMVCP == null ? void 0 : checkMVCP();
1491
- }
1492
- const scrollExtra = 0;
1493
- const { queuedInitialLayout } = state;
1494
- let { scroll: scrollState } = state;
1495
- const initialScroll = state.props.initialScroll;
1496
- if (!queuedInitialLayout && initialScroll) {
1497
- const updatedOffset = calculateOffsetWithOffsetPosition(
1498
- state,
1499
- calculateOffsetForIndex(ctx, state, initialScroll.index),
1500
- initialScroll
1501
- );
1502
- scrollState = updatedOffset;
1503
- }
1504
- const scrollAdjustPad = -previousScrollAdjust - topPad;
1505
- let scroll = scrollState + scrollExtra + scrollAdjustPad;
1506
- if (scroll + scrollLength > totalSize) {
1507
- scroll = totalSize - scrollLength;
1508
- }
1509
- if (ENABLE_DEBUG_VIEW) {
1510
- set$(ctx, "debugRawScroll", scrollState);
1511
- set$(ctx, "debugComputedScroll", scroll);
1512
- }
1513
- const scrollBuffer = state.props.scrollBuffer;
1514
- let scrollBufferTop = scrollBuffer;
1515
- let scrollBufferBottom = scrollBuffer;
1516
- if (speed > 0) {
1517
- scrollBufferTop = scrollBuffer * 0.5;
1518
- scrollBufferBottom = scrollBuffer * 1.5;
1519
- } else {
1520
- scrollBufferTop = scrollBuffer * 1.5;
1521
- scrollBufferBottom = scrollBuffer * 0.5;
1522
- }
1523
- const scrollTopBuffered = scroll - scrollBufferTop;
1524
- const scrollBottom = scroll + scrollLength;
1525
- const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1526
- if (scrollForNextCalculateItemsInView) {
1527
- const { top, bottom } = scrollForNextCalculateItemsInView;
1528
- if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
1529
- return;
1482
+ // src/utils/checkAllSizesKnown.ts
1483
+ function checkAllSizesKnown(state) {
1484
+ const { startBuffered, endBuffered, sizesKnown } = state;
1485
+ if (endBuffered !== null) {
1486
+ let areAllKnown = true;
1487
+ for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
1488
+ const key = getId(state, i);
1489
+ areAllKnown && (areAllKnown = sizesKnown.has(key));
1530
1490
  }
1491
+ return areAllKnown;
1531
1492
  }
1532
- let startNoBuffer = null;
1533
- let startBuffered = null;
1534
- let startBufferedId = null;
1535
- let endNoBuffer = null;
1536
- let endBuffered = null;
1537
- let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1538
- if (minIndexSizeChanged !== void 0) {
1539
- loopStart = Math.min(minIndexSizeChanged, loopStart);
1540
- state.minIndexSizeChanged = void 0;
1541
- }
1542
- for (let i = loopStart; i >= 0; i--) {
1543
- const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
1544
- const top = positions.get(id);
1545
- const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
1546
- const bottom = top + size;
1547
- if (bottom > scroll - scrollBuffer) {
1548
- loopStart = i;
1549
- } else {
1550
- break;
1493
+ return false;
1494
+ }
1495
+
1496
+ // src/utils/findAvailableContainers.ts
1497
+ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval, requiredItemTypes, needNewContainers) {
1498
+ const numContainers = peek$(ctx, "numContainers");
1499
+ const { stickyIndicesSet } = state.props;
1500
+ const result = [];
1501
+ const availableContainers = [];
1502
+ const stickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => stickyIndicesSet.has(index))) || [];
1503
+ const nonStickyItemIndices = (needNewContainers == null ? void 0 : needNewContainers.filter((index) => !stickyIndicesSet.has(index))) || [];
1504
+ const canReuseContainer = (containerIndex, requiredType) => {
1505
+ if (!requiredType) return true;
1506
+ const existingType = state.containerItemTypes.get(containerIndex);
1507
+ if (!existingType) return true;
1508
+ return existingType === requiredType;
1509
+ };
1510
+ const neededTypes = requiredItemTypes ? [...requiredItemTypes] : [];
1511
+ let typeIndex = 0;
1512
+ for (let i = 0; i < stickyItemIndices.length; i++) {
1513
+ const requiredType = neededTypes[typeIndex];
1514
+ let foundContainer = false;
1515
+ for (const containerIndex of state.stickyContainerPool) {
1516
+ const key = peek$(ctx, `containerItemKey${containerIndex}`);
1517
+ const isPendingRemoval = pendingRemoval.includes(containerIndex);
1518
+ if ((key === void 0 || isPendingRemoval) && canReuseContainer(containerIndex, requiredType)) {
1519
+ result.push(containerIndex);
1520
+ if (isPendingRemoval) {
1521
+ const index = pendingRemoval.indexOf(containerIndex);
1522
+ pendingRemoval.splice(index, 1);
1523
+ }
1524
+ foundContainer = true;
1525
+ if (requiredItemTypes) typeIndex++;
1526
+ break;
1527
+ }
1528
+ }
1529
+ if (!foundContainer) {
1530
+ const newContainerIndex = numContainers + result.filter((index) => index >= numContainers).length;
1531
+ result.push(newContainerIndex);
1532
+ state.stickyContainerPool.add(newContainerIndex);
1533
+ if (requiredItemTypes) typeIndex++;
1551
1534
  }
1552
1535
  }
1553
- const loopStartMod = loopStart % numColumns;
1554
- if (loopStartMod > 0) {
1555
- loopStart -= loopStartMod;
1536
+ if (nonStickyItemIndices.length > 0) {
1537
+ for (let u = 0; u < numContainers; u++) {
1538
+ if (state.stickyContainerPool.has(u)) {
1539
+ continue;
1540
+ }
1541
+ const key = peek$(ctx, `containerItemKey${u}`);
1542
+ let isOk = key === void 0;
1543
+ if (!isOk) {
1544
+ const index = pendingRemoval.indexOf(u);
1545
+ if (index !== -1) {
1546
+ pendingRemoval.splice(index, 1);
1547
+ const requiredType = neededTypes[typeIndex];
1548
+ isOk = canReuseContainer(u, requiredType);
1549
+ }
1550
+ }
1551
+ if (isOk) {
1552
+ result.push(u);
1553
+ if (requiredItemTypes) {
1554
+ typeIndex++;
1555
+ }
1556
+ if (result.length >= numNeeded) {
1557
+ return result;
1558
+ }
1559
+ }
1560
+ }
1556
1561
  }
1557
- let foundEnd = false;
1558
- let nextTop;
1559
- let nextBottom;
1560
- const prevNumContainers = ctx.values.get("numContainers");
1561
- let maxIndexRendered = 0;
1562
- for (let i = 0; i < prevNumContainers; i++) {
1563
- const key = peek$(ctx, `containerItemKey${i}`);
1564
- if (key !== void 0) {
1565
- const index = indexByKey.get(key);
1566
- maxIndexRendered = Math.max(maxIndexRendered, index);
1562
+ for (let u = 0; u < numContainers; u++) {
1563
+ if (state.stickyContainerPool.has(u)) {
1564
+ continue;
1565
+ }
1566
+ const key = peek$(ctx, `containerItemKey${u}`);
1567
+ if (key === void 0) continue;
1568
+ const index = state.indexByKey.get(key);
1569
+ const isOutOfView = index < startBuffered || index > endBuffered;
1570
+ if (isOutOfView) {
1571
+ const distance = index < startBuffered ? startBuffered - index : index - endBuffered;
1572
+ if (!requiredItemTypes || typeIndex < neededTypes.length && canReuseContainer(u, neededTypes[typeIndex])) {
1573
+ availableContainers.push({ distance, index: u });
1574
+ }
1567
1575
  }
1568
1576
  }
1569
- let firstFullyOnScreenIndex;
1570
- const dataLength = data.length;
1571
- for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1572
- const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
1573
- const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
1574
- const top = positions.get(id);
1575
- if (!foundEnd) {
1576
- if (startNoBuffer === null && top + size > scroll) {
1577
- startNoBuffer = i;
1578
- }
1579
- if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
1580
- firstFullyOnScreenIndex = i;
1581
- }
1582
- if (startBuffered === null && top + size > scrollTopBuffered) {
1583
- startBuffered = i;
1584
- startBufferedId = id;
1585
- nextTop = top;
1586
- }
1587
- if (startNoBuffer !== null) {
1588
- if (top <= scrollBottom) {
1589
- endNoBuffer = i;
1590
- }
1591
- if (top <= scrollBottomBuffered) {
1592
- endBuffered = i;
1593
- nextBottom = top + size;
1594
- } else {
1595
- foundEnd = true;
1577
+ const remaining = numNeeded - result.length;
1578
+ if (remaining > 0) {
1579
+ if (availableContainers.length > 0) {
1580
+ if (availableContainers.length > remaining) {
1581
+ availableContainers.sort(comparatorByDistance);
1582
+ availableContainers.length = remaining;
1583
+ }
1584
+ for (const container of availableContainers) {
1585
+ result.push(container.index);
1586
+ if (requiredItemTypes) {
1587
+ typeIndex++;
1596
1588
  }
1597
1589
  }
1598
1590
  }
1591
+ const stillNeeded = numNeeded - result.length;
1592
+ if (stillNeeded > 0) {
1593
+ for (let i = 0; i < stillNeeded; i++) {
1594
+ result.push(numContainers + i);
1595
+ }
1596
+ if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
1597
+ console.warn(
1598
+ "[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
1599
+ {
1600
+ debugInfo: {
1601
+ numContainers,
1602
+ numContainersPooled: peek$(ctx, "numContainersPooled"),
1603
+ numNeeded,
1604
+ stillNeeded
1605
+ }
1606
+ }
1607
+ );
1608
+ }
1609
+ }
1610
+ }
1611
+ return result.sort(comparatorDefault);
1612
+ }
1613
+ function comparatorByDistance(a, b) {
1614
+ return b.distance - a.distance;
1615
+ }
1616
+
1617
+ // src/core/scrollToIndex.ts
1618
+ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1619
+ if (index >= state.props.data.length) {
1620
+ index = state.props.data.length - 1;
1621
+ } else if (index < 0) {
1622
+ index = 0;
1599
1623
  }
1600
- const idsInView = [];
1601
- for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
1602
- const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1603
- idsInView.push(id);
1624
+ const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
1625
+ const isLast = index === state.props.data.length - 1;
1626
+ if (isLast && viewPosition === void 0) {
1627
+ viewPosition = 1;
1604
1628
  }
1605
- Object.assign(state, {
1606
- startBuffered,
1607
- startBufferedId,
1608
- startNoBuffer,
1609
- endBuffered,
1610
- endNoBuffer,
1611
- idsInView,
1612
- firstFullyOnScreenIndex
1629
+ const firstIndexScrollPostion = firstIndexOffset - viewOffset;
1630
+ state.scrollForNextCalculateItemsInView = void 0;
1631
+ scrollTo(state, {
1632
+ animated,
1633
+ index,
1634
+ offset: firstIndexScrollPostion,
1635
+ viewOffset,
1636
+ viewPosition: viewPosition != null ? viewPosition : 0
1613
1637
  });
1614
- if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
1615
- state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
1616
- top: nextTop,
1617
- bottom: nextBottom
1618
- } : void 0;
1638
+ }
1639
+
1640
+ // src/utils/checkThreshold.ts
1641
+ var checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
1642
+ const distanceAbs = Math.abs(distance);
1643
+ const isAtThreshold = atThreshold || distanceAbs < threshold;
1644
+ if (!isReached && !isBlockedByTimer) {
1645
+ if (isAtThreshold) {
1646
+ onReached == null ? void 0 : onReached(distance);
1647
+ blockTimer == null ? void 0 : blockTimer(true);
1648
+ setTimeout(() => {
1649
+ blockTimer == null ? void 0 : blockTimer(false);
1650
+ }, 700);
1651
+ return true;
1652
+ }
1653
+ } else {
1654
+ if (distance >= 1.3 * threshold) {
1655
+ return false;
1656
+ }
1619
1657
  }
1620
- const numContainers = peek$(ctx, "numContainers");
1621
- const pendingRemoval = [];
1622
- if (dataChanged) {
1623
- for (let i = 0; i < numContainers; i++) {
1624
- const itemKey = peek$(ctx, `containerItemKey${i}`);
1625
- if (!state.props.keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
1626
- pendingRemoval.push(i);
1658
+ return isReached;
1659
+ };
1660
+
1661
+ // src/utils/checkAtBottom.ts
1662
+ function checkAtBottom(ctx, state) {
1663
+ if (!state) {
1664
+ return;
1665
+ }
1666
+ const {
1667
+ queuedInitialLayout,
1668
+ scrollLength,
1669
+ scroll,
1670
+ maintainingScrollAtEnd,
1671
+ props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
1672
+ } = state;
1673
+ const contentSize = getContentSize(ctx);
1674
+ if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
1675
+ const distanceFromEnd = contentSize - scroll - scrollLength;
1676
+ const isContentLess = contentSize < scrollLength;
1677
+ state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1678
+ state.isEndReached = checkThreshold(
1679
+ distanceFromEnd,
1680
+ isContentLess,
1681
+ onEndReachedThreshold * scrollLength,
1682
+ state.isEndReached,
1683
+ state.endReachedBlockedByTimer,
1684
+ (distance) => {
1685
+ var _a, _b;
1686
+ return (_b = (_a = state.props).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
1687
+ },
1688
+ (block) => {
1689
+ state.endReachedBlockedByTimer = block;
1690
+ }
1691
+ );
1692
+ }
1693
+ }
1694
+
1695
+ // src/utils/setDidLayout.ts
1696
+ function setDidLayout(ctx, state) {
1697
+ const {
1698
+ loadStartTime,
1699
+ initialScroll,
1700
+ props: { onLoad }
1701
+ } = state;
1702
+ state.queuedInitialLayout = true;
1703
+ checkAtBottom(ctx, state);
1704
+ const setIt = () => {
1705
+ set$(ctx, "containersDidLayout", true);
1706
+ if (onLoad) {
1707
+ onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1708
+ }
1709
+ };
1710
+ if (reactNative.Platform.OS === "android" || !IsNewArchitecture) {
1711
+ if (initialScroll) {
1712
+ queueMicrotask(() => {
1713
+ scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1714
+ requestAnimationFrame(() => {
1715
+ scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1716
+ setIt();
1717
+ });
1718
+ });
1719
+ } else {
1720
+ queueMicrotask(setIt);
1721
+ }
1722
+ } else {
1723
+ setIt();
1724
+ }
1725
+ }
1726
+
1727
+ // src/core/calculateItemsInView.ts
1728
+ function findCurrentStickyIndex(stickyArray, scroll, state) {
1729
+ var _a;
1730
+ const idCache = state.idCache;
1731
+ const positions = state.positions;
1732
+ for (let i = stickyArray.length - 1; i >= 0; i--) {
1733
+ const stickyId = (_a = idCache.get(stickyArray[i])) != null ? _a : getId(state, stickyArray[i]);
1734
+ const stickyPos = stickyId ? positions.get(stickyId) : void 0;
1735
+ if (stickyPos !== void 0 && scroll >= stickyPos) {
1736
+ return i;
1737
+ }
1738
+ }
1739
+ return -1;
1740
+ }
1741
+ function getActiveStickyIndices(ctx, state, stickyIndices) {
1742
+ return new Set(
1743
+ Array.from(state.stickyContainerPool).map((i) => peek$(ctx, `containerItemKey${i}`)).map((key) => key ? state.indexByKey.get(key) : void 0).filter((idx) => idx !== void 0 && stickyIndices.has(idx))
1744
+ );
1745
+ }
1746
+ function handleStickyActivation(ctx, state, stickyIndices, stickyArray, scroll, needNewContainers, startBuffered, endBuffered) {
1747
+ var _a;
1748
+ const activeIndices = getActiveStickyIndices(ctx, state, stickyIndices);
1749
+ const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
1750
+ for (let offset = 0; offset <= 1; offset++) {
1751
+ const idx = currentStickyIdx - offset;
1752
+ if (idx < 0 || activeIndices.has(stickyArray[idx])) continue;
1753
+ const stickyIndex = stickyArray[idx];
1754
+ const stickyId = (_a = state.idCache.get(stickyIndex)) != null ? _a : getId(state, stickyIndex);
1755
+ if (stickyId && !state.containerItemKeys.has(stickyId) && (stickyIndex < startBuffered || stickyIndex > endBuffered)) {
1756
+ needNewContainers.push(stickyIndex);
1757
+ }
1758
+ }
1759
+ }
1760
+ function handleStickyRecycling(ctx, state, stickyArray, scroll, scrollBuffer, pendingRemoval) {
1761
+ var _a, _b, _c;
1762
+ const currentStickyIdx = findCurrentStickyIndex(stickyArray, scroll, state);
1763
+ for (const containerIndex of state.stickyContainerPool) {
1764
+ const itemKey = peek$(ctx, `containerItemKey${containerIndex}`);
1765
+ const itemIndex = itemKey ? state.indexByKey.get(itemKey) : void 0;
1766
+ if (itemIndex === void 0) continue;
1767
+ const arrayIdx = stickyArray.indexOf(itemIndex);
1768
+ if (arrayIdx === -1) continue;
1769
+ const isRecentSticky = arrayIdx >= currentStickyIdx - 1 && arrayIdx <= currentStickyIdx + 1;
1770
+ if (isRecentSticky) continue;
1771
+ const nextIndex = stickyArray[arrayIdx + 1];
1772
+ let shouldRecycle = false;
1773
+ if (nextIndex) {
1774
+ const nextId = (_a = state.idCache.get(nextIndex)) != null ? _a : getId(state, nextIndex);
1775
+ const nextPos = nextId ? state.positions.get(nextId) : void 0;
1776
+ shouldRecycle = nextPos !== void 0 && scroll > nextPos + scrollBuffer * 2;
1777
+ } else {
1778
+ const currentId = (_b = state.idCache.get(itemIndex)) != null ? _b : getId(state, itemIndex);
1779
+ if (currentId) {
1780
+ const currentPos = state.positions.get(currentId);
1781
+ const currentSize = (_c = state.sizes.get(currentId)) != null ? _c : getItemSize(state, currentId, itemIndex, state.props.data[itemIndex]);
1782
+ shouldRecycle = currentPos !== void 0 && scroll > currentPos + currentSize + scrollBuffer * 3;
1627
1783
  }
1628
1784
  }
1785
+ if (shouldRecycle) {
1786
+ pendingRemoval.push(containerIndex);
1787
+ }
1629
1788
  }
1630
- if (startBuffered !== null && endBuffered !== null) {
1631
- let numContainers2 = prevNumContainers;
1632
- const needNewContainers = [];
1633
- for (let i = startBuffered; i <= endBuffered; i++) {
1634
- const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
1635
- if (!containerItemKeys.has(id)) {
1636
- needNewContainers.push(i);
1789
+ }
1790
+ function calculateItemsInView(ctx, state, params = {}) {
1791
+ reactNative.unstable_batchedUpdates(() => {
1792
+ var _a, _b, _c, _d, _e, _f, _g;
1793
+ const {
1794
+ columns,
1795
+ containerItemKeys,
1796
+ enableScrollForNextCalculateItemsInView,
1797
+ idCache,
1798
+ indexByKey,
1799
+ minIndexSizeChanged,
1800
+ positions,
1801
+ scrollForNextCalculateItemsInView,
1802
+ scrollLength,
1803
+ sizes,
1804
+ startBufferedId: startBufferedIdOrig,
1805
+ viewabilityConfigCallbackPairs,
1806
+ props: { getItemType, initialScroll, itemsAreEqual, keyExtractor, scrollBuffer }
1807
+ } = state;
1808
+ const { data, stickyIndicesArr, stickyIndicesSet } = state.props;
1809
+ const prevNumContainers = peek$(ctx, "numContainers");
1810
+ if (!data || scrollLength === 0 || !prevNumContainers) {
1811
+ return;
1812
+ }
1813
+ const numColumns = peek$(ctx, "numColumns");
1814
+ const { dataChanged, doMVCP } = params;
1815
+ const speed = getScrollVelocity(state);
1816
+ if (doMVCP || dataChanged) {
1817
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, state, dataChanged) : void 0;
1818
+ if (dataChanged) {
1819
+ indexByKey.clear();
1820
+ idCache.clear();
1821
+ positions.clear();
1637
1822
  }
1823
+ updateAllPositions(ctx, state, dataChanged);
1824
+ checkMVCP == null ? void 0 : checkMVCP();
1638
1825
  }
1639
- if (needNewContainers.length > 0) {
1640
- const availableContainers = findAvailableContainers(
1641
- ctx,
1826
+ const { queuedInitialLayout } = state;
1827
+ let { scroll: scrollState } = state;
1828
+ if (!queuedInitialLayout && initialScroll) {
1829
+ const updatedOffset = calculateOffsetWithOffsetPosition(
1642
1830
  state,
1643
- needNewContainers.length,
1644
- startBuffered,
1645
- endBuffered,
1646
- pendingRemoval
1831
+ calculateOffsetForIndex(ctx, state, initialScroll.index),
1832
+ initialScroll
1647
1833
  );
1648
- for (let idx = 0; idx < needNewContainers.length; idx++) {
1649
- const i = needNewContainers[idx];
1650
- const containerIndex = availableContainers[idx];
1651
- const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
1652
- const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
1653
- if (oldKey && oldKey !== id) {
1654
- containerItemKeys.delete(oldKey);
1834
+ scrollState = updatedOffset;
1835
+ state.scroll = scrollState;
1836
+ }
1837
+ const scroll = getEffectiveScroll(ctx, state);
1838
+ if (ENABLE_DEBUG_VIEW) {
1839
+ set$(ctx, "debugRawScroll", scrollState);
1840
+ set$(ctx, "debugComputedScroll", scroll);
1841
+ }
1842
+ let scrollBufferTop = scrollBuffer;
1843
+ let scrollBufferBottom = scrollBuffer;
1844
+ if (speed > 0) {
1845
+ scrollBufferTop = scrollBuffer * 0.5;
1846
+ scrollBufferBottom = scrollBuffer * 1.5;
1847
+ } else {
1848
+ scrollBufferTop = scrollBuffer * 1.5;
1849
+ scrollBufferBottom = scrollBuffer * 0.5;
1850
+ }
1851
+ const scrollTopBuffered = scroll - scrollBufferTop;
1852
+ const scrollBottom = scroll + scrollLength + (scroll < 0 ? -scroll : 0);
1853
+ const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1854
+ if (scrollForNextCalculateItemsInView) {
1855
+ const { top, bottom } = scrollForNextCalculateItemsInView;
1856
+ if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
1857
+ return;
1858
+ }
1859
+ }
1860
+ let startNoBuffer = null;
1861
+ let startBuffered = null;
1862
+ let startBufferedId = null;
1863
+ let endNoBuffer = null;
1864
+ let endBuffered = null;
1865
+ let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1866
+ if (minIndexSizeChanged !== void 0) {
1867
+ loopStart = Math.min(minIndexSizeChanged, loopStart);
1868
+ state.minIndexSizeChanged = void 0;
1869
+ }
1870
+ for (let i = loopStart; i >= 0; i--) {
1871
+ const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
1872
+ const top = positions.get(id);
1873
+ const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
1874
+ const bottom = top + size;
1875
+ if (bottom > scroll - scrollBuffer) {
1876
+ loopStart = i;
1877
+ } else {
1878
+ break;
1879
+ }
1880
+ }
1881
+ const loopStartMod = loopStart % numColumns;
1882
+ if (loopStartMod > 0) {
1883
+ loopStart -= loopStartMod;
1884
+ }
1885
+ let foundEnd = false;
1886
+ let nextTop;
1887
+ let nextBottom;
1888
+ let maxIndexRendered = 0;
1889
+ for (let i = 0; i < prevNumContainers; i++) {
1890
+ const key = peek$(ctx, `containerItemKey${i}`);
1891
+ if (key !== void 0) {
1892
+ const index = indexByKey.get(key);
1893
+ maxIndexRendered = Math.max(maxIndexRendered, index);
1894
+ }
1895
+ }
1896
+ let firstFullyOnScreenIndex;
1897
+ const dataLength = data.length;
1898
+ for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1899
+ const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
1900
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
1901
+ const top = positions.get(id);
1902
+ if (!foundEnd) {
1903
+ if (startNoBuffer === null && top + size > scroll) {
1904
+ startNoBuffer = i;
1905
+ }
1906
+ if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
1907
+ firstFullyOnScreenIndex = i;
1655
1908
  }
1656
- set$(ctx, `containerItemKey${containerIndex}`, id);
1657
- set$(ctx, `containerItemData${containerIndex}`, data[i]);
1658
- containerItemKeys.add(id);
1659
- if (containerIndex >= numContainers2) {
1660
- numContainers2 = containerIndex + 1;
1909
+ if (startBuffered === null && top + size > scrollTopBuffered) {
1910
+ startBuffered = i;
1911
+ startBufferedId = id;
1912
+ nextTop = top;
1913
+ }
1914
+ if (startNoBuffer !== null) {
1915
+ if (top <= scrollBottom) {
1916
+ endNoBuffer = i;
1917
+ }
1918
+ if (top <= scrollBottomBuffered) {
1919
+ endBuffered = i;
1920
+ nextBottom = top + size;
1921
+ } else {
1922
+ foundEnd = true;
1923
+ }
1661
1924
  }
1662
1925
  }
1663
- if (numContainers2 !== prevNumContainers) {
1664
- set$(ctx, "numContainers", numContainers2);
1665
- if (numContainers2 > peek$(ctx, "numContainersPooled")) {
1666
- set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
1926
+ }
1927
+ Object.assign(state, {
1928
+ endBuffered,
1929
+ endNoBuffer,
1930
+ firstFullyOnScreenIndex,
1931
+ startBuffered,
1932
+ startBufferedId,
1933
+ startNoBuffer
1934
+ });
1935
+ if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
1936
+ state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
1937
+ bottom: nextBottom,
1938
+ top: nextTop
1939
+ } : void 0;
1940
+ }
1941
+ const numContainers = peek$(ctx, "numContainers");
1942
+ const pendingRemoval = [];
1943
+ if (dataChanged) {
1944
+ for (let i = 0; i < numContainers; i++) {
1945
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1946
+ if (!keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
1947
+ pendingRemoval.push(i);
1667
1948
  }
1668
1949
  }
1669
1950
  }
1670
- }
1671
- for (let i = 0; i < numContainers; i++) {
1672
- const itemKey = peek$(ctx, `containerItemKey${i}`);
1673
- if (pendingRemoval.includes(i)) {
1674
- if (itemKey) {
1675
- containerItemKeys.delete(itemKey);
1951
+ if (startBuffered !== null && endBuffered !== null) {
1952
+ let numContainers2 = prevNumContainers;
1953
+ const needNewContainers = [];
1954
+ for (let i = startBuffered; i <= endBuffered; i++) {
1955
+ const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1956
+ if (!containerItemKeys.has(id)) {
1957
+ needNewContainers.push(i);
1958
+ }
1676
1959
  }
1677
- set$(ctx, `containerItemKey${i}`, void 0);
1678
- set$(ctx, `containerItemData${i}`, void 0);
1679
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1680
- set$(ctx, `containerColumn${i}`, -1);
1681
- } else {
1682
- const itemIndex = indexByKey.get(itemKey);
1683
- const item = data[itemIndex];
1684
- if (item !== void 0) {
1685
- const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
1686
- const position = positions.get(id);
1687
- if (position === void 0) {
1688
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1689
- } else {
1690
- const pos = positions.get(id);
1691
- const column = columns.get(id) || 1;
1692
- const prevPos = peek$(ctx, `containerPosition${i}`);
1693
- const prevColumn = peek$(ctx, `containerColumn${i}`);
1694
- const prevData = peek$(ctx, `containerItemData${i}`);
1695
- if (!prevPos || pos > POSITION_OUT_OF_VIEW && pos !== prevPos) {
1696
- set$(ctx, `containerPosition${i}`, pos);
1960
+ if (stickyIndicesArr.length > 0) {
1961
+ handleStickyActivation(
1962
+ ctx,
1963
+ state,
1964
+ stickyIndicesSet,
1965
+ stickyIndicesArr,
1966
+ scroll,
1967
+ needNewContainers,
1968
+ startBuffered,
1969
+ endBuffered
1970
+ );
1971
+ }
1972
+ if (needNewContainers.length > 0) {
1973
+ const requiredItemTypes = getItemType ? needNewContainers.map((i) => {
1974
+ const itemType = getItemType(data[i], i);
1975
+ return itemType ? String(itemType) : "";
1976
+ }) : void 0;
1977
+ const availableContainers = findAvailableContainers(
1978
+ ctx,
1979
+ state,
1980
+ needNewContainers.length,
1981
+ startBuffered,
1982
+ endBuffered,
1983
+ pendingRemoval,
1984
+ requiredItemTypes,
1985
+ needNewContainers
1986
+ );
1987
+ for (let idx = 0; idx < needNewContainers.length; idx++) {
1988
+ const i = needNewContainers[idx];
1989
+ const containerIndex = availableContainers[idx];
1990
+ const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
1991
+ const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
1992
+ if (oldKey && oldKey !== id) {
1993
+ containerItemKeys.delete(oldKey);
1994
+ }
1995
+ set$(ctx, `containerItemKey${containerIndex}`, id);
1996
+ set$(ctx, `containerItemData${containerIndex}`, data[i]);
1997
+ if (requiredItemTypes) {
1998
+ state.containerItemTypes.set(containerIndex, requiredItemTypes[idx]);
1999
+ }
2000
+ containerItemKeys.add(id);
2001
+ if (stickyIndicesSet.has(i)) {
2002
+ set$(ctx, `containerSticky${containerIndex}`, true);
2003
+ const topPadding = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
2004
+ set$(ctx, `containerStickyOffset${containerIndex}`, new reactNative.Animated.Value(topPadding));
2005
+ state.stickyContainerPool.add(containerIndex);
2006
+ } else {
2007
+ state.stickyContainerPool.delete(containerIndex);
1697
2008
  }
1698
- if (column >= 0 && column !== prevColumn) {
1699
- set$(ctx, `containerColumn${i}`, column);
2009
+ if (containerIndex >= numContainers2) {
2010
+ numContainers2 = containerIndex + 1;
1700
2011
  }
1701
- if (prevData !== item) {
1702
- set$(ctx, `containerItemData${i}`, data[itemIndex]);
2012
+ }
2013
+ if (numContainers2 !== prevNumContainers) {
2014
+ set$(ctx, "numContainers", numContainers2);
2015
+ if (numContainers2 > peek$(ctx, "numContainersPooled")) {
2016
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
1703
2017
  }
1704
2018
  }
1705
2019
  }
1706
2020
  }
1707
- }
1708
- if (!queuedInitialLayout && endBuffered !== null) {
1709
- if (checkAllSizesKnown(state)) {
1710
- setDidLayout(ctx, state);
2021
+ if (stickyIndicesArr.length > 0) {
2022
+ handleStickyRecycling(ctx, state, stickyIndicesArr, scroll, scrollBuffer, pendingRemoval);
1711
2023
  }
1712
- }
1713
- if (state.props.viewabilityConfigCallbackPairs) {
1714
- updateViewableItems(
1715
- state,
1716
- ctx,
1717
- state.props.viewabilityConfigCallbackPairs,
1718
- scrollLength,
1719
- startNoBuffer,
1720
- endNoBuffer
1721
- );
1722
- }
2024
+ for (let i = 0; i < numContainers; i++) {
2025
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
2026
+ if (pendingRemoval.includes(i)) {
2027
+ if (itemKey) {
2028
+ containerItemKeys.delete(itemKey);
2029
+ }
2030
+ state.containerItemTypes.delete(i);
2031
+ if (state.stickyContainerPool.has(i)) {
2032
+ set$(ctx, `containerSticky${i}`, false);
2033
+ set$(ctx, `containerStickyOffset${i}`, void 0);
2034
+ state.stickyContainerPool.delete(i);
2035
+ }
2036
+ set$(ctx, `containerItemKey${i}`, void 0);
2037
+ set$(ctx, `containerItemData${i}`, void 0);
2038
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
2039
+ set$(ctx, `containerColumn${i}`, -1);
2040
+ } else {
2041
+ const itemIndex = indexByKey.get(itemKey);
2042
+ const item = data[itemIndex];
2043
+ if (item !== void 0) {
2044
+ const id = (_g = idCache.get(itemIndex)) != null ? _g : getId(state, itemIndex);
2045
+ const position = positions.get(id);
2046
+ if (position === void 0) {
2047
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
2048
+ } else {
2049
+ const column = columns.get(id) || 1;
2050
+ const prevPos = peek$(ctx, `containerPosition${i}`);
2051
+ const prevColumn = peek$(ctx, `containerColumn${i}`);
2052
+ const prevData = peek$(ctx, `containerItemData${i}`);
2053
+ if (position > POSITION_OUT_OF_VIEW && position !== prevPos) {
2054
+ set$(ctx, `containerPosition${i}`, position);
2055
+ }
2056
+ if (column >= 0 && column !== prevColumn) {
2057
+ set$(ctx, `containerColumn${i}`, column);
2058
+ }
2059
+ if (prevData !== item && (itemsAreEqual ? !itemsAreEqual(prevData, item, itemIndex, data) : true)) {
2060
+ set$(ctx, `containerItemData${i}`, data[itemIndex]);
2061
+ }
2062
+ }
2063
+ }
2064
+ }
2065
+ }
2066
+ if (!queuedInitialLayout && endBuffered !== null) {
2067
+ if (checkAllSizesKnown(state)) {
2068
+ setDidLayout(ctx, state);
2069
+ }
2070
+ }
2071
+ if (viewabilityConfigCallbackPairs) {
2072
+ updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollLength, startNoBuffer, endNoBuffer);
2073
+ }
2074
+ });
1723
2075
  }
1724
2076
 
1725
- // src/checkAtTop.ts
1726
- function checkAtTop(state) {
1727
- if (!state) {
1728
- return;
1729
- }
2077
+ // src/core/doInitialAllocateContainers.ts
2078
+ function doInitialAllocateContainers(ctx, state) {
2079
+ var _a;
1730
2080
  const {
1731
2081
  scrollLength,
1732
- scroll,
1733
- props: { onStartReachedThreshold }
2082
+ props: { getItemType }
1734
2083
  } = state;
1735
- const distanceFromTop = scroll;
1736
- state.isAtStart = distanceFromTop <= 0;
1737
- state.isStartReached = checkThreshold(
1738
- distanceFromTop,
1739
- false,
1740
- onStartReachedThreshold * scrollLength,
1741
- state.isStartReached,
1742
- state.startReachedBlockedByTimer,
1743
- (distance) => {
1744
- var _a, _b;
1745
- return (_b = (_a = state.props).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
1746
- },
1747
- (block) => {
1748
- state.startReachedBlockedByTimer = block;
1749
- }
1750
- );
1751
- }
1752
-
1753
- // src/createColumnWrapperStyle.ts
1754
- function createColumnWrapperStyle(contentContainerStyle) {
1755
- const { gap, columnGap, rowGap } = contentContainerStyle;
1756
- if (gap || columnGap || rowGap) {
1757
- contentContainerStyle.gap = void 0;
1758
- contentContainerStyle.columnGap = void 0;
1759
- contentContainerStyle.rowGap = void 0;
1760
- return {
1761
- gap,
1762
- columnGap,
1763
- rowGap
1764
- };
1765
- }
1766
- }
1767
-
1768
- // src/doInitialAllocateContainers.ts
1769
- function doInitialAllocateContainers(ctx, state) {
1770
- const { scrollLength } = state;
1771
2084
  const data = state.props.data;
1772
2085
  if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
1773
- const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0]) : state.props.estimatedItemSize;
2086
+ const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0], getItemType ? (_a = getItemType(data[0], 0)) != null ? _a : "" : "") : state.props.estimatedItemSize;
1774
2087
  const Extra = 1.5;
1775
2088
  const numContainers = Math.ceil(
1776
2089
  (scrollLength + state.props.scrollBuffer * 2) / averageItemSize * state.props.numColumns * Extra
@@ -1794,7 +2107,7 @@ function doInitialAllocateContainers(ctx, state) {
1794
2107
  }
1795
2108
  }
1796
2109
 
1797
- // src/doMaintainScrollAtEnd.ts
2110
+ // src/core/doMaintainScrollAtEnd.ts
1798
2111
  function doMaintainScrollAtEnd(ctx, state, animated) {
1799
2112
  const {
1800
2113
  refScroller,
@@ -1807,45 +2120,52 @@ function doMaintainScrollAtEnd(ctx, state, animated) {
1807
2120
  }
1808
2121
  requestAnimationFrame(() => {
1809
2122
  var _a;
1810
- state.maintainingScrollAtEnd = true;
1811
- (_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
1812
- animated
1813
- });
1814
- setTimeout(
1815
- () => {
1816
- state.maintainingScrollAtEnd = false;
1817
- },
1818
- 0
1819
- );
2123
+ if (state == null ? void 0 : state.isAtEnd) {
2124
+ state.maintainingScrollAtEnd = true;
2125
+ (_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
2126
+ animated
2127
+ });
2128
+ setTimeout(
2129
+ () => {
2130
+ state.maintainingScrollAtEnd = false;
2131
+ },
2132
+ 0
2133
+ );
2134
+ }
1820
2135
  });
1821
2136
  return true;
1822
2137
  }
1823
2138
  }
1824
- function getRenderedItem(ctx, state, key) {
2139
+
2140
+ // src/utils/checkAtTop.ts
2141
+ function checkAtTop(state) {
1825
2142
  if (!state) {
1826
- return null;
2143
+ return;
1827
2144
  }
1828
2145
  const {
1829
- indexByKey,
1830
- props: { data, renderItem: renderItem2 }
2146
+ scrollLength,
2147
+ scroll,
2148
+ props: { onStartReachedThreshold }
1831
2149
  } = state;
1832
- const index = indexByKey.get(key);
1833
- if (index === void 0) {
1834
- return null;
1835
- }
1836
- let renderedItem = null;
1837
- if (renderItem2) {
1838
- const itemProps = {
1839
- item: data[index],
1840
- index,
1841
- extraData: peek$(ctx, "extraData")
1842
- };
1843
- renderedItem = React3__namespace.default.createElement(renderItem2, itemProps);
1844
- }
1845
- return { index, item: data[index], renderedItem };
2150
+ const distanceFromTop = scroll;
2151
+ state.isAtStart = distanceFromTop <= 0;
2152
+ state.isStartReached = checkThreshold(
2153
+ distanceFromTop,
2154
+ false,
2155
+ onStartReachedThreshold * scrollLength,
2156
+ state.isStartReached,
2157
+ state.startReachedBlockedByTimer,
2158
+ (distance) => {
2159
+ var _a, _b;
2160
+ return (_b = (_a = state.props).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
2161
+ },
2162
+ (block) => {
2163
+ state.startReachedBlockedByTimer = block;
2164
+ }
2165
+ );
1846
2166
  }
1847
2167
 
1848
- // src/handleLayout.ts
2168
+ // src/core/handleLayout.ts
1849
2169
  function handleLayout(ctx, state, layout, setCanRender) {
1850
2170
  const { maintainScrollAtEnd } = state.props;
1851
2171
  const scrollLength = layout[state.props.horizontal ? "width" : "height"];
@@ -1863,7 +2183,7 @@ function handleLayout(ctx, state, layout, setCanRender) {
1863
2183
  calculateItemsInView(ctx, state, { doMVCP: true });
1864
2184
  }
1865
2185
  if (didChange || otherAxisSize !== prevOtherAxisSize) {
1866
- set$(ctx, "scrollSize", { width: layout.width, height: layout.height });
2186
+ set$(ctx, "scrollSize", { height: layout.height, width: layout.width });
1867
2187
  }
1868
2188
  if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
1869
2189
  doMaintainScrollAtEnd(ctx, state, false);
@@ -1883,9 +2203,12 @@ function handleLayout(ctx, state, layout, setCanRender) {
1883
2203
  setCanRender(true);
1884
2204
  }
1885
2205
 
1886
- // src/onScroll.ts
2206
+ // src/core/onScroll.ts
1887
2207
  function onScroll(ctx, state, event) {
1888
2208
  var _a, _b, _c, _d, _e;
2209
+ if (!state.scrollProcessingEnabled) {
2210
+ return;
2211
+ }
1889
2212
  if (((_b = (_a = event.nativeEvent) == null ? void 0 : _a.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
1890
2213
  return;
1891
2214
  }
@@ -1921,7 +2244,29 @@ function updateScroll(ctx, state, newScroll) {
1921
2244
  checkAtTop(state);
1922
2245
  }
1923
2246
 
1924
- // src/updateItemSize.ts
2247
+ // src/core/ScrollAdjustHandler.ts
2248
+ var ScrollAdjustHandler = class {
2249
+ constructor(ctx) {
2250
+ this.appliedAdjust = 0;
2251
+ this.mounted = false;
2252
+ this.context = ctx;
2253
+ }
2254
+ requestAdjust(add) {
2255
+ const oldAdjustTop = peek$(this.context, "scrollAdjust") || 0;
2256
+ this.appliedAdjust = add + oldAdjustTop;
2257
+ const set = () => set$(this.context, "scrollAdjust", this.appliedAdjust);
2258
+ if (this.mounted) {
2259
+ set();
2260
+ } else {
2261
+ requestAnimationFrame(set);
2262
+ }
2263
+ }
2264
+ setMounted() {
2265
+ this.mounted = true;
2266
+ }
2267
+ };
2268
+
2269
+ // src/core/updateItemSize.ts
1925
2270
  function updateItemSizes(ctx, state, itemUpdates) {
1926
2271
  var _a;
1927
2272
  const {
@@ -1935,7 +2280,8 @@ function updateItemSizes(ctx, state, itemUpdates) {
1935
2280
  }
1936
2281
  } = state;
1937
2282
  if (!data) return;
1938
- let needsRecalculate = false;
2283
+ const containersDidLayout = peek$(ctx, "containersDidLayout");
2284
+ let needsRecalculate = !containersDidLayout;
1939
2285
  let shouldMaintainScrollAtEnd = false;
1940
2286
  let minIndexSizeChanged;
1941
2287
  let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
@@ -1946,7 +2292,7 @@ function updateItemSizes(ctx, state, itemUpdates) {
1946
2292
  const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
1947
2293
  if (diff !== 0) {
1948
2294
  minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
1949
- if (((_a = state.scrollingTo) == null ? void 0 : _a.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index) {
2295
+ if (((_a = state.scrollingTo) == null ? void 0 : _a.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index && diff > 0) {
1950
2296
  requestAdjust(ctx, state, diff * state.scrollingTo.viewPosition);
1951
2297
  }
1952
2298
  const { startBuffered, endBuffered } = state;
@@ -1968,11 +2314,11 @@ function updateItemSizes(ctx, state, itemUpdates) {
1968
2314
  shouldMaintainScrollAtEnd = true;
1969
2315
  }
1970
2316
  onItemSizeChanged == null ? void 0 : onItemSizeChanged({
1971
- size,
1972
- previous: size - diff,
1973
2317
  index,
2318
+ itemData: state.props.data[index],
1974
2319
  itemKey,
1975
- itemData: state.props.data[index]
2320
+ previous: size - diff,
2321
+ size
1976
2322
  });
1977
2323
  }
1978
2324
  }
@@ -1995,7 +2341,6 @@ function updateItemSizes(ctx, state, itemUpdates) {
1995
2341
  if (!cur || maxOtherAxisSize > cur) {
1996
2342
  set$(ctx, "otherAxisSize", maxOtherAxisSize);
1997
2343
  }
1998
- const containersDidLayout = peek$(ctx, "containersDidLayout");
1999
2344
  if (containersDidLayout || checkAllSizesKnown(state)) {
2000
2345
  if (needsRecalculate) {
2001
2346
  state.scrollForNextCalculateItemsInView = void 0;
@@ -2009,127 +2354,239 @@ function updateItemSizes(ctx, state, itemUpdates) {
2009
2354
  }
2010
2355
  }
2011
2356
  function updateItemSize(ctx, state, itemKey, sizeObj) {
2012
- if (IsNewArchitecture) {
2013
- const { sizesKnown } = state;
2014
- const numContainers = ctx.values.get("numContainers");
2015
- const changes = [];
2016
- for (let i = 0; i < numContainers; i++) {
2017
- const containerItemKey = peek$(ctx, `containerItemKey${i}`);
2018
- if (itemKey === containerItemKey) {
2019
- changes.push({ itemKey, sizeObj });
2020
- } else if (!sizesKnown.has(containerItemKey) && containerItemKey !== void 0) {
2021
- const containerRef = ctx.viewRefs.get(i);
2022
- if (containerRef == null ? void 0 : containerRef.current) {
2023
- let measured;
2024
- containerRef.current.measure((x, y, width, height) => {
2025
- measured = { x, y, width, height };
2026
- });
2027
- if (measured) {
2028
- changes.push({ itemKey: containerItemKey, sizeObj: measured });
2029
- }
2030
- }
2031
- }
2357
+ var _a;
2358
+ const {
2359
+ queuedItemSizeUpdates,
2360
+ queuedItemSizeUpdatesWaiting,
2361
+ sizesKnown,
2362
+ props: { getFixedItemSize, getItemType }
2363
+ } = state;
2364
+ if (getFixedItemSize) {
2365
+ const index = state.indexByKey.get(itemKey);
2366
+ if (index === void 0) {
2367
+ return;
2032
2368
  }
2033
- if (changes.length > 0) {
2034
- updateItemSizes(ctx, state, changes);
2369
+ const itemData = state.props.data[index];
2370
+ if (itemData === void 0) {
2371
+ return;
2035
2372
  }
2036
- } else {
2373
+ const type = getItemType ? (_a = getItemType(itemData, index)) != null ? _a : "" : "";
2374
+ const size = getFixedItemSize(index, itemData, type);
2375
+ if (size !== void 0 && size === sizesKnown.get(itemKey)) {
2376
+ return;
2377
+ }
2378
+ }
2379
+ const containersDidLayout = peek$(ctx, "containersDidLayout");
2380
+ const speed = getScrollVelocity(state);
2381
+ if (!containersDidLayout || !queuedItemSizeUpdatesWaiting || Math.abs(speed) < 1) {
2037
2382
  updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
2383
+ if (containersDidLayout) {
2384
+ state.queuedItemSizeUpdatesWaiting = true;
2385
+ requestAnimationFrame(() => {
2386
+ state.queuedItemSizeUpdatesWaiting = false;
2387
+ updateItemSizes(ctx, state, queuedItemSizeUpdates);
2388
+ queuedItemSizeUpdates.length = 0;
2389
+ });
2390
+ }
2391
+ } else {
2392
+ queuedItemSizeUpdates.push({ itemKey, sizeObj });
2038
2393
  }
2039
2394
  }
2040
2395
  function updateOneItemSize(state, itemKey, sizeObj) {
2396
+ var _a;
2041
2397
  const {
2042
2398
  sizes,
2043
2399
  indexByKey,
2044
2400
  sizesKnown,
2045
2401
  averageSizes,
2046
- props: { data, horizontal }
2402
+ props: { data, horizontal, getEstimatedItemSize, getItemType, getFixedItemSize }
2047
2403
  } = state;
2048
2404
  if (!data) return 0;
2049
2405
  const index = indexByKey.get(itemKey);
2050
2406
  const prevSize = getItemSize(state, itemKey, index, data);
2051
2407
  const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
2052
2408
  sizesKnown.set(itemKey, size);
2053
- const itemType = "";
2054
- let averages = averageSizes[itemType];
2055
- if (!averages) {
2056
- averages = averageSizes[itemType] = { num: 0, avg: 0 };
2409
+ if (!getEstimatedItemSize && !getFixedItemSize) {
2410
+ const itemType = getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : "";
2411
+ let averages = averageSizes[itemType];
2412
+ if (!averages) {
2413
+ averages = averageSizes[itemType] = { avg: 0, num: 0 };
2414
+ }
2415
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2416
+ averages.num++;
2057
2417
  }
2058
- averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2059
- averages.num++;
2060
2418
  if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2061
2419
  sizes.set(itemKey, size);
2062
2420
  return size - prevSize;
2063
2421
  }
2064
- return 0;
2065
- }
2066
- var useCombinedRef = (...refs) => {
2067
- const callback = React3.useCallback((element) => {
2068
- for (const ref of refs) {
2069
- if (!ref) {
2070
- continue;
2071
- }
2072
- if (isFunction(ref)) {
2073
- ref(element);
2074
- } else {
2075
- ref.current = element;
2422
+ return 0;
2423
+ }
2424
+ var useCombinedRef = (...refs) => {
2425
+ const callback = React3.useCallback((element) => {
2426
+ for (const ref of refs) {
2427
+ if (!ref) {
2428
+ continue;
2429
+ }
2430
+ if (isFunction(ref)) {
2431
+ ref(element);
2432
+ } else {
2433
+ ref.current = element;
2434
+ }
2435
+ }
2436
+ }, refs);
2437
+ return callback;
2438
+ };
2439
+
2440
+ // src/utils/createColumnWrapperStyle.ts
2441
+ function createColumnWrapperStyle(contentContainerStyle) {
2442
+ const { gap, columnGap, rowGap } = contentContainerStyle;
2443
+ if (gap || columnGap || rowGap) {
2444
+ contentContainerStyle.gap = void 0;
2445
+ contentContainerStyle.columnGap = void 0;
2446
+ contentContainerStyle.rowGap = void 0;
2447
+ return {
2448
+ columnGap,
2449
+ gap,
2450
+ rowGap
2451
+ };
2452
+ }
2453
+ }
2454
+ function getRenderedItem(ctx, state, key) {
2455
+ var _a;
2456
+ if (!state) {
2457
+ return null;
2458
+ }
2459
+ const {
2460
+ indexByKey,
2461
+ props: { data, getItemType, renderItem: renderItem2 }
2462
+ } = state;
2463
+ const index = indexByKey.get(key);
2464
+ if (index === void 0) {
2465
+ return null;
2466
+ }
2467
+ let renderedItem = null;
2468
+ if (renderItem2 && data[index]) {
2469
+ const itemProps = {
2470
+ extraData: peek$(ctx, "extraData"),
2471
+ index,
2472
+ item: data[index],
2473
+ type: getItemType ? (_a = getItemType(data[index], index)) != null ? _a : "" : ""
2474
+ };
2475
+ renderedItem = isFunction(renderItem2) ? renderItem2(itemProps) : React3__namespace.default.createElement(renderItem2, itemProps);
2476
+ }
2477
+ return { index, item: data[index], renderedItem };
2478
+ }
2479
+
2480
+ // src/utils/updateAveragesOnDataChange.ts
2481
+ function updateAveragesOnDataChange(state, oldData, newData) {
2482
+ var _a;
2483
+ const {
2484
+ averageSizes,
2485
+ sizesKnown,
2486
+ indexByKey,
2487
+ props: { itemsAreEqual, getItemType, keyExtractor }
2488
+ } = state;
2489
+ if (!itemsAreEqual || !oldData.length || !newData.length) {
2490
+ for (const key in averageSizes) {
2491
+ delete averageSizes[key];
2492
+ }
2493
+ return;
2494
+ }
2495
+ const itemTypesToPreserve = {};
2496
+ const newDataLength = newData.length;
2497
+ const oldDataLength = oldData.length;
2498
+ for (let newIndex = 0; newIndex < newDataLength; newIndex++) {
2499
+ const newItem = newData[newIndex];
2500
+ const id = keyExtractor ? keyExtractor(newItem, newIndex) : String(newIndex);
2501
+ const oldIndex = indexByKey.get(id);
2502
+ if (oldIndex !== void 0 && oldIndex < oldDataLength) {
2503
+ const knownSize = sizesKnown.get(id);
2504
+ if (knownSize === void 0) continue;
2505
+ const oldItem = oldData[oldIndex];
2506
+ const areEqual = itemsAreEqual(oldItem, newItem, newIndex, newData);
2507
+ if (areEqual) {
2508
+ const itemType = getItemType ? (_a = getItemType(newItem, newIndex)) != null ? _a : "" : "";
2509
+ let typeData = itemTypesToPreserve[itemType];
2510
+ if (!typeData) {
2511
+ typeData = itemTypesToPreserve[itemType] = { count: 0, totalSize: 0 };
2512
+ }
2513
+ typeData.totalSize += knownSize;
2514
+ typeData.count++;
2076
2515
  }
2077
2516
  }
2078
- }, refs);
2079
- return callback;
2080
- };
2517
+ }
2518
+ for (const key in averageSizes) {
2519
+ delete averageSizes[key];
2520
+ }
2521
+ for (const itemType in itemTypesToPreserve) {
2522
+ const { totalSize, count } = itemTypesToPreserve[itemType];
2523
+ if (count > 0) {
2524
+ averageSizes[itemType] = {
2525
+ avg: totalSize / count,
2526
+ num: count
2527
+ };
2528
+ }
2529
+ }
2530
+ }
2081
2531
 
2082
- // src/LegendList.tsx
2532
+ // src/components/LegendList.tsx
2083
2533
  var DEFAULT_DRAW_DISTANCE = 250;
2084
2534
  var DEFAULT_ITEM_SIZE = 100;
2085
- var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
2086
- return /* @__PURE__ */ React3__namespace.createElement(StateProvider, null, /* @__PURE__ */ React3__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
2087
- });
2535
+ var LegendList = typedMemo(
2536
+ typedForwardRef(function LegendList2(props, forwardedRef) {
2537
+ return /* @__PURE__ */ React3__namespace.createElement(StateProvider, null, /* @__PURE__ */ React3__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
2538
+ })
2539
+ );
2088
2540
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
2089
2541
  var _a;
2090
2542
  const {
2543
+ alignItemsAtEnd = false,
2544
+ columnWrapperStyle,
2545
+ contentContainerStyle: contentContainerStyleProp,
2091
2546
  data: dataProp = [],
2547
+ drawDistance = 250,
2548
+ estimatedItemSize: estimatedItemSizeProp,
2549
+ estimatedListSize,
2550
+ extraData,
2551
+ getEstimatedItemSize,
2552
+ getFixedItemSize,
2553
+ getItemType,
2554
+ horizontal,
2555
+ initialContainerPoolRatio = 2,
2092
2556
  initialScrollIndex: initialScrollIndexProp,
2093
2557
  initialScrollOffset,
2094
- horizontal,
2095
- drawDistance = 250,
2096
- recycleItems = false,
2097
- onEndReachedThreshold = 0.5,
2098
- onStartReachedThreshold = 0.5,
2558
+ itemsAreEqual,
2559
+ keyExtractor: keyExtractorProp,
2560
+ ListEmptyComponent,
2561
+ ListHeaderComponent,
2099
2562
  maintainScrollAtEnd = false,
2100
2563
  maintainScrollAtEndThreshold = 0.1,
2101
- alignItemsAtEnd = false,
2102
2564
  maintainVisibleContentPosition = false,
2103
- onScroll: onScrollProp,
2104
- onMomentumScrollEnd,
2105
2565
  numColumns: numColumnsProp = 1,
2106
- columnWrapperStyle,
2107
- keyExtractor: keyExtractorProp,
2108
- renderItem: renderItem2,
2109
- estimatedListSize,
2110
- estimatedItemSize: estimatedItemSizeProp,
2111
- getEstimatedItemSize,
2112
- suggestEstimatedItemSize,
2113
- ListHeaderComponent,
2114
- ListEmptyComponent,
2566
+ onEndReached,
2567
+ onEndReachedThreshold = 0.5,
2115
2568
  onItemSizeChanged,
2116
- refScrollView,
2117
- waitForInitialLayout = true,
2118
- extraData,
2119
- contentContainerStyle: contentContainerStyleProp,
2120
- style: styleProp,
2121
2569
  onLayout: onLayoutProp,
2570
+ onLoad,
2571
+ onMomentumScrollEnd,
2122
2572
  onRefresh,
2123
- refreshing,
2573
+ onScroll: onScrollProp,
2574
+ onStartReached,
2575
+ onStartReachedThreshold = 0.5,
2576
+ onViewableItemsChanged,
2124
2577
  progressViewOffset,
2578
+ recycleItems = false,
2125
2579
  refreshControl,
2126
- initialContainerPoolRatio = 2,
2580
+ refreshing,
2581
+ refScrollView,
2582
+ renderItem: renderItem2,
2583
+ snapToIndices,
2584
+ stickyIndices,
2585
+ style: styleProp,
2586
+ suggestEstimatedItemSize,
2127
2587
  viewabilityConfig,
2128
2588
  viewabilityConfigCallbackPairs,
2129
- onViewableItemsChanged,
2130
- onStartReached,
2131
- onEndReached,
2132
- onLoad,
2589
+ waitForInitialLayout = true,
2133
2590
  ...rest
2134
2591
  } = props;
2135
2592
  const [renderNum, setRenderNum] = React3.useState(0);
@@ -2146,55 +2603,60 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2146
2603
  const combinedRef = useCombinedRef(refScroller, refScrollView);
2147
2604
  const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
2148
2605
  const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
2149
- const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
2606
+ const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (_item, index) => index.toString();
2150
2607
  const refState = React3.useRef();
2151
2608
  if (!refState.current) {
2152
- const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { width: 0, height: 0 } : reactNative.Dimensions.get("window"))[horizontal ? "width" : "height"];
2609
+ const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { height: 0, width: 0 } : reactNative.Dimensions.get("window"))[horizontal ? "width" : "height"];
2153
2610
  refState.current = {
2154
- sizes: /* @__PURE__ */ new Map(),
2155
- positions: /* @__PURE__ */ new Map(),
2611
+ activeStickyIndex: void 0,
2612
+ averageSizes: {},
2156
2613
  columns: /* @__PURE__ */ new Map(),
2157
- pendingAdjust: 0,
2158
- isStartReached: false,
2159
- isEndReached: false,
2160
- isAtEnd: false,
2161
- isAtStart: false,
2162
- scrollLength: initialScrollLength,
2163
- startBuffered: -1,
2164
- startNoBuffer: -1,
2614
+ containerItemKeys: /* @__PURE__ */ new Set(),
2615
+ containerItemTypes: /* @__PURE__ */ new Map(),
2616
+ enableScrollForNextCalculateItemsInView: true,
2165
2617
  endBuffered: -1,
2166
2618
  endNoBuffer: -1,
2619
+ endReachedBlockedByTimer: false,
2167
2620
  firstFullyOnScreenIndex: -1,
2621
+ idCache: /* @__PURE__ */ new Map(),
2622
+ indexByKey: /* @__PURE__ */ new Map(),
2623
+ initialScroll,
2624
+ isAtEnd: false,
2625
+ isAtStart: false,
2626
+ isEndReached: false,
2627
+ isStartReached: false,
2628
+ lastBatchingAction: Date.now(),
2629
+ lastLayout: void 0,
2630
+ loadStartTime: Date.now(),
2631
+ minIndexSizeChanged: 0,
2632
+ nativeMarginTop: 0,
2633
+ pendingAdjust: 0,
2634
+ positions: /* @__PURE__ */ new Map(),
2635
+ props: {},
2636
+ queuedCalculateItemsInView: 0,
2637
+ queuedItemSizeUpdates: [],
2638
+ refScroller: void 0,
2168
2639
  scroll: 0,
2169
- totalSize: 0,
2170
- timeouts: /* @__PURE__ */ new Set(),
2171
- viewabilityConfigCallbackPairs: void 0,
2172
2640
  scrollAdjustHandler: new ScrollAdjustHandler(ctx),
2173
- nativeMarginTop: 0,
2641
+ scrollForNextCalculateItemsInView: void 0,
2642
+ scrollHistory: [],
2643
+ scrollLength: initialScrollLength,
2644
+ scrollPending: 0,
2174
2645
  scrollPrev: 0,
2175
2646
  scrollPrevTime: 0,
2647
+ scrollProcessingEnabled: true,
2176
2648
  scrollTime: 0,
2177
- scrollPending: 0,
2178
- indexByKey: /* @__PURE__ */ new Map(),
2179
- scrollHistory: [],
2649
+ sizes: /* @__PURE__ */ new Map(),
2180
2650
  sizesKnown: /* @__PURE__ */ new Map(),
2181
- timeoutSizeMessage: 0,
2651
+ startBuffered: -1,
2652
+ startNoBuffer: -1,
2182
2653
  startReachedBlockedByTimer: false,
2183
- endReachedBlockedByTimer: false,
2184
- scrollForNextCalculateItemsInView: void 0,
2185
- enableScrollForNextCalculateItemsInView: true,
2186
- minIndexSizeChanged: 0,
2187
- queuedCalculateItemsInView: 0,
2188
- lastBatchingAction: Date.now(),
2189
- averageSizes: {},
2190
- idsInView: [],
2191
- containerItemKeys: /* @__PURE__ */ new Set(),
2192
- idCache: /* @__PURE__ */ new Map(),
2193
- props: {},
2194
- refScroller: void 0,
2195
- loadStartTime: Date.now(),
2196
- initialScroll,
2197
- lastLayout: void 0
2654
+ stickyContainerPool: /* @__PURE__ */ new Set(),
2655
+ stickyContainers: /* @__PURE__ */ new Map(),
2656
+ timeoutSizeMessage: 0,
2657
+ timeouts: /* @__PURE__ */ new Set(),
2658
+ totalSize: 0,
2659
+ viewabilityConfigCallbackPairs: void 0
2198
2660
  };
2199
2661
  set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
2200
2662
  set$(ctx, "extraData", extraData);
@@ -2206,33 +2668,42 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2206
2668
  alignItemsAtEnd,
2207
2669
  data: dataProp,
2208
2670
  estimatedItemSize,
2671
+ getEstimatedItemSize,
2672
+ getFixedItemSize,
2673
+ getItemType,
2674
+ horizontal: !!horizontal,
2675
+ initialContainerPoolRatio,
2676
+ initialScroll,
2677
+ itemsAreEqual,
2678
+ keyExtractor,
2209
2679
  maintainScrollAtEnd,
2210
2680
  maintainScrollAtEndThreshold,
2211
- onEndReachedThreshold,
2212
- onStartReachedThreshold,
2213
- stylePaddingBottom: stylePaddingBottomState,
2214
- horizontal: !!horizontal,
2215
2681
  maintainVisibleContentPosition,
2682
+ numColumns: numColumnsProp,
2683
+ onEndReached,
2684
+ onEndReachedThreshold,
2216
2685
  onItemSizeChanged,
2217
- suggestEstimatedItemSize: !!suggestEstimatedItemSize,
2218
- keyExtractor,
2686
+ onLoad,
2219
2687
  onScroll: onScrollProp,
2220
- getEstimatedItemSize,
2221
2688
  onStartReached,
2222
- onEndReached,
2223
- onLoad,
2689
+ onStartReachedThreshold,
2690
+ recycleItems: !!recycleItems,
2224
2691
  renderItem: renderItem2,
2225
- initialScroll,
2226
2692
  scrollBuffer,
2227
- viewabilityConfigCallbackPairs: void 0,
2228
- numColumns: numColumnsProp,
2229
- initialContainerPoolRatio,
2230
- stylePaddingTop: stylePaddingTopState
2693
+ snapToIndices,
2694
+ stickyIndicesArr: stickyIndices != null ? stickyIndices : [],
2695
+ stickyIndicesSet: React3.useMemo(() => new Set(stickyIndices), [stickyIndices]),
2696
+ stylePaddingBottom: stylePaddingBottomState,
2697
+ stylePaddingTop: stylePaddingTopState,
2698
+ suggestEstimatedItemSize: !!suggestEstimatedItemSize
2231
2699
  };
2232
2700
  state.refScroller = refScroller;
2233
2701
  const checkResetContainers = (isFirst2) => {
2234
2702
  const state2 = refState.current;
2235
2703
  if (state2) {
2704
+ if (!isFirst2 && state2.props.data !== dataProp) {
2705
+ updateAveragesOnDataChange(state2, state2.props.data, dataProp);
2706
+ }
2236
2707
  state2.props.data = dataProp;
2237
2708
  if (!isFirst2) {
2238
2709
  calculateItemsInView(ctx, state2, { dataChanged: true, doMVCP: true });
@@ -2255,27 +2726,29 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2255
2726
  (_, i) => getId(state, dataProp.length - 1 - i)
2256
2727
  );
2257
2728
  }, [dataProp, numColumnsProp]);
2258
- const initalizeStateVars = () => {
2729
+ const initializeStateVars = () => {
2259
2730
  set$(ctx, "lastItemKeys", memoizedLastItemKeys);
2260
2731
  set$(ctx, "numColumns", numColumnsProp);
2261
2732
  const prevPaddingTop = peek$(ctx, "stylePaddingTop");
2262
- setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
2733
+ setPaddingTop(ctx, state, { stylePaddingTop: stylePaddingTopState });
2263
2734
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
2264
- const paddingDiff = stylePaddingTopState - prevPaddingTop;
2265
- if (paddingDiff && prevPaddingTop !== void 0 && reactNative.Platform.OS === "ios") {
2266
- calculateItemsInView(ctx, state, { doMVCP: true });
2735
+ let paddingDiff = stylePaddingTopState - prevPaddingTop;
2736
+ if (maintainVisibleContentPosition && paddingDiff && prevPaddingTop !== void 0 && reactNative.Platform.OS === "ios") {
2737
+ if (state.scroll < 0) {
2738
+ paddingDiff += state.scroll;
2739
+ }
2267
2740
  requestAdjust(ctx, state, paddingDiff);
2268
2741
  }
2269
2742
  };
2270
2743
  if (isFirst) {
2271
- initalizeStateVars();
2744
+ initializeStateVars();
2272
2745
  updateAllPositions(ctx, state);
2273
2746
  }
2274
2747
  const initialContentOffset = React3.useMemo(() => {
2275
2748
  const initialContentOffset2 = initialScrollOffset || calculateOffsetForIndex(ctx, state, initialScrollIndex);
2276
2749
  refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
2277
2750
  if (initialContentOffset2 > 0) {
2278
- scrollTo(state, { offset: initialContentOffset2, animated: false, index: initialScrollIndex });
2751
+ scrollTo(state, { animated: false, index: initialScrollIndex, offset: initialContentOffset2 });
2279
2752
  }
2280
2753
  return initialContentOffset2;
2281
2754
  }, [renderNum]);
@@ -2290,23 +2763,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2290
2763
  refState.current.positions.clear();
2291
2764
  }
2292
2765
  }
2293
- React3.useLayoutEffect(() => {
2294
- if (IsNewArchitecture) {
2295
- let measured;
2296
- refScroller.current.measure((x, y, width, height) => {
2297
- measured = { x, y, width, height };
2298
- });
2299
- if (measured) {
2300
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
2301
- if (size) {
2302
- handleLayout(ctx, state, measured, setCanRender);
2303
- }
2304
- }
2305
- }
2306
- if (!isFirst) {
2307
- calculateItemsInView(ctx, state, { doMVCP: true });
2308
- }
2309
- }, [dataProp]);
2310
2766
  const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
2311
2767
  const size = rect[horizontal ? "width" : "height"];
2312
2768
  set$(ctx, "headerSize", size);
@@ -2322,6 +2778,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2322
2778
  }
2323
2779
  }
2324
2780
  }, []);
2781
+ React3.useLayoutEffect(() => {
2782
+ if (snapToIndices) {
2783
+ updateSnapToOffsets(ctx, state);
2784
+ }
2785
+ }, [snapToIndices]);
2325
2786
  React3.useLayoutEffect(() => {
2326
2787
  const didAllocateContainers = doInitialAllocateContainersCallback();
2327
2788
  if (!didAllocateContainers) {
@@ -2334,7 +2795,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2334
2795
  React3.useLayoutEffect(() => {
2335
2796
  set$(ctx, "extraData", extraData);
2336
2797
  }, [extraData]);
2337
- React3.useLayoutEffect(initalizeStateVars, [
2798
+ React3.useLayoutEffect(() => {
2799
+ if (IsNewArchitecture) {
2800
+ let measured;
2801
+ refScroller.current.measure((x, y, width, height) => {
2802
+ measured = { height, width, x, y };
2803
+ });
2804
+ if (measured) {
2805
+ const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
2806
+ if (size) {
2807
+ handleLayout(ctx, state, measured, setCanRender);
2808
+ }
2809
+ }
2810
+ }
2811
+ }, []);
2812
+ React3.useLayoutEffect(initializeStateVars, [
2338
2813
  memoizedLastItemKeys.join(","),
2339
2814
  numColumnsProp,
2340
2815
  stylePaddingTopState,
@@ -2345,12 +2820,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2345
2820
  };
2346
2821
  React3.useEffect(() => {
2347
2822
  const viewability = setupViewability({
2823
+ onViewableItemsChanged,
2348
2824
  viewabilityConfig,
2349
- viewabilityConfigCallbackPairs,
2350
- onViewableItemsChanged
2825
+ viewabilityConfigCallbackPairs
2351
2826
  });
2352
2827
  state.viewabilityConfigCallbackPairs = viewability;
2353
- state.props.viewabilityConfigCallbackPairs = viewability;
2354
2828
  state.enableScrollForNextCalculateItemsInView = !viewability;
2355
2829
  }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
2356
2830
  if (!IsNewArchitecture) {
@@ -2365,144 +2839,166 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
2365
2839
  onLayoutProp(event);
2366
2840
  }
2367
2841
  }, []);
2368
- React3.useImperativeHandle(
2369
- forwardedRef,
2370
- () => {
2371
- const scrollIndexIntoView = (options) => {
2842
+ React3.useImperativeHandle(forwardedRef, () => {
2843
+ const scrollIndexIntoView = (options) => {
2844
+ const state2 = refState.current;
2845
+ if (state2) {
2846
+ const { index, ...rest2 } = options;
2847
+ const { startNoBuffer, endNoBuffer } = state2;
2848
+ if (index < startNoBuffer || index > endNoBuffer) {
2849
+ const viewPosition = index < startNoBuffer ? 0 : 1;
2850
+ scrollToIndex(ctx, state2, {
2851
+ ...rest2,
2852
+ index,
2853
+ viewPosition
2854
+ });
2855
+ }
2856
+ }
2857
+ };
2858
+ return {
2859
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
2860
+ getNativeScrollRef: () => refScroller.current,
2861
+ getScrollableNode: () => refScroller.current.getScrollableNode(),
2862
+ getScrollResponder: () => refScroller.current.getScrollResponder(),
2863
+ getState: () => {
2372
2864
  const state2 = refState.current;
2373
- if (state2) {
2374
- const { index, ...rest2 } = options;
2375
- const { startNoBuffer, endNoBuffer } = state2;
2376
- if (index < startNoBuffer || index > endNoBuffer) {
2377
- const viewPosition = index < startNoBuffer ? 0 : 1;
2378
- scrollToIndex(ctx, state2, {
2379
- ...rest2,
2380
- viewPosition,
2381
- index
2382
- });
2383
- }
2865
+ return state2 ? {
2866
+ contentLength: state2.totalSize,
2867
+ data: state2.props.data,
2868
+ end: state2.endNoBuffer,
2869
+ endBuffered: state2.endBuffered,
2870
+ isAtEnd: state2.isAtEnd,
2871
+ isAtStart: state2.isAtStart,
2872
+ positionAtIndex: (index) => state2.positions.get(getId(state2, index)),
2873
+ positions: state2.positions,
2874
+ scroll: state2.scroll,
2875
+ scrollLength: state2.scrollLength,
2876
+ sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index)),
2877
+ sizes: state2.sizesKnown,
2878
+ start: state2.startNoBuffer,
2879
+ startBuffered: state2.startBuffered
2880
+ } : {};
2881
+ },
2882
+ scrollIndexIntoView,
2883
+ scrollItemIntoView: ({ item, ...props2 }) => {
2884
+ const data = refState.current.props.data;
2885
+ const index = data.indexOf(item);
2886
+ if (index !== -1) {
2887
+ scrollIndexIntoView({ index, ...props2 });
2384
2888
  }
2385
- };
2386
- return {
2387
- flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
2388
- getNativeScrollRef: () => refScroller.current,
2389
- getScrollableNode: () => refScroller.current.getScrollableNode(),
2390
- getScrollResponder: () => refScroller.current.getScrollResponder(),
2391
- getState: () => {
2392
- const state2 = refState.current;
2393
- return state2 ? {
2394
- contentLength: state2.totalSize,
2395
- end: state2.endNoBuffer,
2396
- endBuffered: state2.endBuffered,
2397
- isAtEnd: state2.isAtEnd,
2398
- isAtStart: state2.isAtStart,
2399
- scroll: state2.scroll,
2400
- scrollLength: state2.scrollLength,
2401
- start: state2.startNoBuffer,
2402
- startBuffered: state2.startBuffered,
2403
- sizes: state2.sizesKnown,
2404
- sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index))
2405
- } : {};
2406
- },
2407
- scrollIndexIntoView,
2408
- scrollItemIntoView: ({ item, ...props2 }) => {
2409
- const data = refState.current.props.data;
2410
- const index = data.indexOf(item);
2411
- if (index !== -1) {
2412
- scrollIndexIntoView({ index, ...props2 });
2413
- }
2414
- },
2415
- scrollToIndex: (params) => scrollToIndex(ctx, state, params),
2416
- scrollToItem: ({ item, ...props2 }) => {
2417
- const data = refState.current.props.data;
2418
- const index = data.indexOf(item);
2419
- if (index !== -1) {
2420
- scrollToIndex(ctx, state, { index, ...props2 });
2421
- }
2422
- },
2423
- scrollToOffset: (params) => scrollTo(state, params),
2424
- scrollToEnd: (options) => {
2425
- const data = refState.current.props.data;
2426
- const stylePaddingBottom = refState.current.props.stylePaddingBottom;
2427
- const index = data.length - 1;
2428
- if (index !== -1) {
2429
- const paddingBottom = stylePaddingBottom || 0;
2430
- const footerSize = peek$(ctx, "footerSize") || 0;
2431
- scrollToIndex(ctx, state, {
2432
- index,
2433
- viewPosition: 1,
2434
- viewOffset: -paddingBottom - footerSize,
2435
- ...options
2436
- });
2437
- }
2438
- },
2439
- setVisibleContentAnchorOffset: (value) => {
2440
- const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
2441
- set$(ctx, "scrollAdjustUserOffset", val);
2889
+ },
2890
+ scrollToEnd: (options) => {
2891
+ const data = refState.current.props.data;
2892
+ const stylePaddingBottom = refState.current.props.stylePaddingBottom;
2893
+ const index = data.length - 1;
2894
+ if (index !== -1) {
2895
+ const paddingBottom = stylePaddingBottom || 0;
2896
+ const footerSize = peek$(ctx, "footerSize") || 0;
2897
+ scrollToIndex(ctx, state, {
2898
+ index,
2899
+ viewOffset: -paddingBottom - footerSize + ((options == null ? void 0 : options.viewOffset) || 0),
2900
+ viewPosition: 1,
2901
+ ...options
2902
+ });
2442
2903
  }
2443
- };
2444
- },
2445
- []
2446
- );
2904
+ },
2905
+ scrollToIndex: (params) => scrollToIndex(ctx, state, params),
2906
+ scrollToItem: ({ item, ...props2 }) => {
2907
+ const data = refState.current.props.data;
2908
+ const index = data.indexOf(item);
2909
+ if (index !== -1) {
2910
+ scrollToIndex(ctx, state, { index, ...props2 });
2911
+ }
2912
+ },
2913
+ scrollToOffset: (params) => scrollTo(state, params),
2914
+ setScrollProcessingEnabled: (enabled) => {
2915
+ refState.current.scrollProcessingEnabled = enabled;
2916
+ },
2917
+ setVisibleContentAnchorOffset: (value) => {
2918
+ const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
2919
+ set$(ctx, "scrollAdjustUserOffset", val);
2920
+ }
2921
+ };
2922
+ }, []);
2447
2923
  if (reactNative.Platform.OS === "web") {
2448
2924
  React3.useEffect(() => {
2449
2925
  if (initialContentOffset) {
2450
- scrollTo(state, { offset: initialContentOffset, animated: false });
2926
+ scrollTo(state, { animated: false, offset: initialContentOffset });
2451
2927
  }
2452
2928
  }, []);
2453
2929
  }
2454
2930
  const fns = React3.useMemo(
2455
2931
  () => ({
2456
- updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj),
2457
2932
  getRenderedItem: (key) => getRenderedItem(ctx, state, key),
2458
- onScroll: (event) => onScroll(ctx, state, event)
2933
+ onScroll: (event) => onScroll(ctx, state, event),
2934
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj)
2459
2935
  }),
2460
2936
  []
2461
2937
  );
2938
+ const animatedScrollHandler = React3.useMemo(() => {
2939
+ if (stickyIndices == null ? void 0 : stickyIndices.length) {
2940
+ const { animatedScrollY } = ctx;
2941
+ return reactNative.Animated.event([{ nativeEvent: { contentOffset: { [horizontal ? "x" : "y"]: animatedScrollY } } }], {
2942
+ listener: fns.onScroll,
2943
+ useNativeDriver: true
2944
+ });
2945
+ }
2946
+ return fns.onScroll;
2947
+ }, [stickyIndices, horizontal, onScroll]);
2462
2948
  return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
2463
2949
  ListComponent,
2464
2950
  {
2465
2951
  ...rest,
2952
+ alignItemsAtEnd,
2466
2953
  canRender,
2954
+ contentContainerStyle,
2955
+ getRenderedItem: fns.getRenderedItem,
2467
2956
  horizontal,
2468
- refScrollView: combinedRef,
2469
2957
  initialContentOffset,
2470
- getRenderedItem: fns.getRenderedItem,
2471
- updateItemSize: fns.updateItemSize,
2472
- onScroll: fns.onScroll,
2958
+ ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
2959
+ ListHeaderComponent,
2960
+ maintainVisibleContentPosition,
2961
+ onLayout,
2962
+ onLayoutHeader,
2473
2963
  onMomentumScrollEnd: (event) => {
2474
- requestAnimationFrame(() => {
2475
- finishScrollTo(refState.current);
2476
- });
2964
+ if (IsNewArchitecture) {
2965
+ requestAnimationFrame(() => {
2966
+ finishScrollTo(refState.current);
2967
+ });
2968
+ } else {
2969
+ setTimeout(() => {
2970
+ finishScrollTo(refState.current);
2971
+ }, 1e3);
2972
+ }
2477
2973
  if (onMomentumScrollEnd) {
2478
2974
  onMomentumScrollEnd(event);
2479
2975
  }
2480
2976
  },
2481
- onLayout,
2977
+ onScroll: animatedScrollHandler,
2482
2978
  recycleItems,
2483
- alignItemsAtEnd,
2484
- ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
2485
- ListHeaderComponent,
2486
- maintainVisibleContentPosition,
2487
- scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
2488
- waitForInitialLayout,
2489
2979
  refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
2490
2980
  progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
2491
2981
  }) : refreshControl : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
2492
2982
  reactNative.RefreshControl,
2493
2983
  {
2494
- refreshing: !!refreshing,
2495
2984
  onRefresh,
2496
- progressViewOffset: (progressViewOffset || 0) + stylePaddingTopState
2985
+ progressViewOffset: (progressViewOffset || 0) + stylePaddingTopState,
2986
+ refreshing: !!refreshing
2497
2987
  }
2498
2988
  ),
2499
- style,
2500
- contentContainerStyle,
2989
+ refScrollView: combinedRef,
2501
2990
  scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
2502
- onLayoutHeader
2991
+ scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
2992
+ snapToIndices,
2993
+ stickyIndices,
2994
+ style,
2995
+ updateItemSize: fns.updateItemSize,
2996
+ waitForInitialLayout
2503
2997
  }
2504
2998
  ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
2505
2999
  });
3000
+
3001
+ // src/components/LazyLegendList.tsx
2506
3002
  var typedForwardRef2 = React3.forwardRef;
2507
3003
  var renderItem = ({ item }) => item;
2508
3004
  var LazyLegendList = typedForwardRef2(function LazyLegendList2(props, forwardedRef) {
@@ -2511,7 +3007,7 @@ var LazyLegendList = typedForwardRef2(function LazyLegendList2(props, forwardedR
2511
3007
  const data = (isArray(children) ? children : React3__namespace.Children.toArray(children)).flat(1);
2512
3008
  return (
2513
3009
  // @ts-expect-error TODO: Fix this type
2514
- /* @__PURE__ */ React3__namespace.createElement(LegendListComponent, { ...rest, data, renderItem, ref: forwardedRef })
3010
+ /* @__PURE__ */ React3__namespace.createElement(LegendListComponent, { ...rest, data, ref: forwardedRef, renderItem })
2515
3011
  );
2516
3012
  });
2517
3013