@react-native-ohos/flash-list 1.8.3 → 2.1.1-rc.1

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 (455) hide show
  1. package/LICENSE +1 -1
  2. package/README.OpenSource +1 -1
  3. package/dist/AnimatedFlashList.d.ts +4 -28
  4. package/dist/AnimatedFlashList.d.ts.map +1 -1
  5. package/dist/AnimatedFlashList.js +5 -30
  6. package/dist/AnimatedFlashList.js.map +1 -1
  7. package/dist/FlashList.d.ts +1 -179
  8. package/dist/FlashList.d.ts.map +1 -1
  9. package/dist/FlashList.js +1 -599
  10. package/dist/FlashList.js.map +1 -1
  11. package/dist/FlashListProps.d.ts +285 -278
  12. package/dist/FlashListProps.d.ts.map +1 -1
  13. package/dist/FlashListProps.js +5 -31
  14. package/dist/FlashListProps.js.map +1 -1
  15. package/dist/FlashListRef.d.ts +305 -0
  16. package/dist/FlashListRef.d.ts.map +1 -0
  17. package/dist/FlashListRef.js +2 -0
  18. package/dist/FlashListRef.js.map +1 -0
  19. package/dist/benchmark/AutoScrollHelper.d.ts +17 -40
  20. package/dist/benchmark/AutoScrollHelper.d.ts.map +1 -1
  21. package/dist/benchmark/AutoScrollHelper.js +59 -90
  22. package/dist/benchmark/AutoScrollHelper.js.map +1 -1
  23. package/dist/benchmark/JSFPSMonitor.d.ts +22 -45
  24. package/dist/benchmark/JSFPSMonitor.d.ts.map +1 -1
  25. package/dist/benchmark/JSFPSMonitor.js +59 -87
  26. package/dist/benchmark/JSFPSMonitor.js.map +1 -1
  27. package/dist/benchmark/roundToDecimalPlaces.d.ts +1 -24
  28. package/dist/benchmark/roundToDecimalPlaces.d.ts.map +1 -1
  29. package/dist/benchmark/roundToDecimalPlaces.js +4 -31
  30. package/dist/benchmark/roundToDecimalPlaces.js.map +1 -1
  31. package/dist/benchmark/useBenchmark.d.ts +40 -57
  32. package/dist/benchmark/useBenchmark.d.ts.map +1 -1
  33. package/dist/benchmark/useBenchmark.js +119 -189
  34. package/dist/benchmark/useBenchmark.js.map +1 -1
  35. package/dist/benchmark/useDataMultiplier.d.ts +8 -31
  36. package/dist/benchmark/useDataMultiplier.d.ts.map +1 -1
  37. package/dist/benchmark/useDataMultiplier.js +19 -47
  38. package/dist/benchmark/useDataMultiplier.js.map +1 -1
  39. package/dist/benchmark/useFlatListBenchmark.d.ts +14 -35
  40. package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
  41. package/dist/benchmark/useFlatListBenchmark.js +92 -122
  42. package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
  43. package/dist/errors/ErrorMessages.d.ts +16 -0
  44. package/dist/errors/ErrorMessages.d.ts.map +1 -0
  45. package/dist/errors/ErrorMessages.js +16 -0
  46. package/dist/errors/ErrorMessages.js.map +1 -0
  47. package/dist/errors/WarningMessages.d.ts +6 -0
  48. package/dist/errors/WarningMessages.d.ts.map +1 -0
  49. package/dist/errors/WarningMessages.js +7 -0
  50. package/dist/errors/WarningMessages.js.map +1 -0
  51. package/dist/index.d.ts +15 -36
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +19 -54
  54. package/dist/index.js.map +1 -1
  55. package/dist/isNewArch.d.ts +2 -0
  56. package/dist/isNewArch.d.ts.map +1 -0
  57. package/dist/isNewArch.js +22 -0
  58. package/dist/isNewArch.js.map +1 -0
  59. package/dist/native/config/PlatformHelper.android.d.ts +6 -48
  60. package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
  61. package/dist/native/config/PlatformHelper.android.js +6 -45
  62. package/dist/native/config/PlatformHelper.android.js.map +1 -1
  63. package/dist/native/config/PlatformHelper.d.ts +6 -48
  64. package/dist/native/config/PlatformHelper.d.ts.map +1 -1
  65. package/dist/native/config/PlatformHelper.harmony.d.ts +29 -48
  66. package/dist/native/config/PlatformHelper.harmony.d.ts.map +1 -1
  67. package/dist/native/config/PlatformHelper.harmony.js +29 -44
  68. package/dist/native/config/PlatformHelper.harmony.js.map +1 -1
  69. package/dist/native/config/PlatformHelper.ios.d.ts +6 -48
  70. package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
  71. package/dist/native/config/PlatformHelper.ios.js +6 -44
  72. package/dist/native/config/PlatformHelper.ios.js.map +1 -1
  73. package/dist/native/config/PlatformHelper.js +6 -45
  74. package/dist/native/config/PlatformHelper.js.map +1 -1
  75. package/dist/native/config/PlatformHelper.web.d.ts +6 -49
  76. package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
  77. package/dist/native/config/PlatformHelper.web.js +6 -47
  78. package/dist/native/config/PlatformHelper.web.js.map +1 -1
  79. package/dist/recyclerview/LayoutCommitObserver.d.ts +12 -0
  80. package/dist/recyclerview/LayoutCommitObserver.d.ts.map +1 -0
  81. package/dist/recyclerview/LayoutCommitObserver.js +58 -0
  82. package/dist/recyclerview/LayoutCommitObserver.js.map +1 -0
  83. package/dist/recyclerview/RecyclerView.d.ts +13 -0
  84. package/dist/recyclerview/RecyclerView.d.ts.map +1 -0
  85. package/dist/recyclerview/RecyclerView.js +368 -0
  86. package/dist/recyclerview/RecyclerView.js.map +1 -0
  87. package/dist/recyclerview/RecyclerViewContextProvider.d.ts +46 -0
  88. package/dist/recyclerview/RecyclerViewContextProvider.d.ts.map +1 -0
  89. package/dist/recyclerview/RecyclerViewContextProvider.js +10 -0
  90. package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -0
  91. package/dist/recyclerview/RecyclerViewManager.d.ts +78 -0
  92. package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -0
  93. package/dist/recyclerview/RecyclerViewManager.js +343 -0
  94. package/dist/recyclerview/RecyclerViewManager.js.map +1 -0
  95. package/dist/recyclerview/RecyclerViewProps.d.ts +2 -0
  96. package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -0
  97. package/dist/recyclerview/RecyclerViewProps.js +2 -0
  98. package/dist/recyclerview/RecyclerViewProps.js.map +1 -0
  99. package/dist/recyclerview/RenderStackManager.d.ts +86 -0
  100. package/dist/recyclerview/RenderStackManager.d.ts.map +1 -0
  101. package/dist/recyclerview/RenderStackManager.js +252 -0
  102. package/dist/recyclerview/RenderStackManager.js.map +1 -0
  103. package/dist/recyclerview/ViewHolder.d.ts +45 -0
  104. package/dist/recyclerview/ViewHolder.d.ts.map +1 -0
  105. package/dist/recyclerview/ViewHolder.js +94 -0
  106. package/dist/recyclerview/ViewHolder.js.map +1 -0
  107. package/dist/recyclerview/ViewHolderCollection.d.ts +63 -0
  108. package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -0
  109. package/dist/recyclerview/ViewHolderCollection.js +87 -0
  110. package/dist/recyclerview/ViewHolderCollection.js.map +1 -0
  111. package/dist/recyclerview/components/CompatScroller.d.ts +7 -0
  112. package/dist/recyclerview/components/CompatScroller.d.ts.map +1 -0
  113. package/dist/recyclerview/components/CompatScroller.js +7 -0
  114. package/dist/recyclerview/components/CompatScroller.js.map +1 -0
  115. package/dist/recyclerview/components/CompatView.d.ts +7 -0
  116. package/dist/recyclerview/components/CompatView.d.ts.map +1 -0
  117. package/dist/recyclerview/components/CompatView.js +7 -0
  118. package/dist/recyclerview/components/CompatView.js.map +1 -0
  119. package/dist/recyclerview/components/ScrollAnchor.d.ts +29 -0
  120. package/dist/recyclerview/components/ScrollAnchor.d.ts.map +1 -0
  121. package/dist/recyclerview/components/ScrollAnchor.js +33 -0
  122. package/dist/recyclerview/components/ScrollAnchor.js.map +1 -0
  123. package/dist/recyclerview/components/StickyHeaders.d.ts +38 -0
  124. package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -0
  125. package/dist/recyclerview/components/StickyHeaders.js +112 -0
  126. package/dist/recyclerview/components/StickyHeaders.js.map +1 -0
  127. package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts +51 -0
  128. package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts.map +1 -0
  129. package/dist/recyclerview/helpers/ConsecutiveNumbers.js +95 -0
  130. package/dist/recyclerview/helpers/ConsecutiveNumbers.js.map +1 -0
  131. package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts +105 -0
  132. package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts.map +1 -0
  133. package/dist/recyclerview/helpers/EngagedIndicesTracker.js +202 -0
  134. package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -0
  135. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts +14 -0
  136. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts.map +1 -0
  137. package/dist/recyclerview/helpers/RenderTimeTracker.js +44 -0
  138. package/dist/recyclerview/helpers/RenderTimeTracker.js.map +1 -0
  139. package/dist/recyclerview/helpers/VelocityTracker.d.ts +29 -0
  140. package/dist/recyclerview/helpers/VelocityTracker.d.ts.map +1 -0
  141. package/dist/recyclerview/helpers/VelocityTracker.js +64 -0
  142. package/dist/recyclerview/helpers/VelocityTracker.js.map +1 -0
  143. package/dist/recyclerview/hooks/useBoundDetection.d.ts +17 -0
  144. package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -0
  145. package/dist/recyclerview/hooks/useBoundDetection.js +132 -0
  146. package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -0
  147. package/dist/recyclerview/hooks/useLayoutState.d.ts +14 -0
  148. package/dist/recyclerview/hooks/useLayoutState.d.ts.map +1 -0
  149. package/dist/recyclerview/hooks/useLayoutState.js +38 -0
  150. package/dist/recyclerview/hooks/useLayoutState.js.map +1 -0
  151. package/dist/recyclerview/hooks/useMappingHelper.d.ts +9 -0
  152. package/dist/recyclerview/hooks/useMappingHelper.d.ts.map +1 -0
  153. package/dist/recyclerview/hooks/useMappingHelper.js +15 -0
  154. package/dist/recyclerview/hooks/useMappingHelper.js.map +1 -0
  155. package/dist/recyclerview/hooks/useOnLoad.d.ts +25 -0
  156. package/dist/recyclerview/hooks/useOnLoad.d.ts.map +1 -0
  157. package/dist/recyclerview/hooks/useOnLoad.js +67 -0
  158. package/dist/recyclerview/hooks/useOnLoad.js.map +1 -0
  159. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts +28 -0
  160. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -0
  161. package/dist/recyclerview/hooks/useRecyclerViewController.js +507 -0
  162. package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -0
  163. package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts +8 -0
  164. package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts.map +1 -0
  165. package/dist/recyclerview/hooks/useRecyclerViewManager.js +32 -0
  166. package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -0
  167. package/dist/recyclerview/hooks/useRecyclingState.d.ts +18 -0
  168. package/dist/recyclerview/hooks/useRecyclingState.d.ts.map +1 -0
  169. package/dist/recyclerview/hooks/useRecyclingState.js +49 -0
  170. package/dist/recyclerview/hooks/useRecyclingState.js.map +1 -0
  171. package/dist/recyclerview/hooks/useSecondaryProps.d.ts +27 -0
  172. package/dist/recyclerview/hooks/useSecondaryProps.d.ts.map +1 -0
  173. package/dist/recyclerview/hooks/useSecondaryProps.js +90 -0
  174. package/dist/recyclerview/hooks/useSecondaryProps.js.map +1 -0
  175. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts +15 -0
  176. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts.map +1 -0
  177. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js +58 -0
  178. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js.map +1 -0
  179. package/dist/recyclerview/hooks/useUnmountFlag.d.ts +10 -0
  180. package/dist/recyclerview/hooks/useUnmountFlag.d.ts.map +1 -0
  181. package/dist/recyclerview/hooks/useUnmountFlag.js +25 -0
  182. package/dist/recyclerview/hooks/useUnmountFlag.js.map +1 -0
  183. package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts +79 -0
  184. package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts.map +1 -0
  185. package/dist/recyclerview/layout-managers/GridLayoutManager.js +221 -0
  186. package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -0
  187. package/dist/recyclerview/layout-managers/LayoutManager.d.ts +296 -0
  188. package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -0
  189. package/dist/recyclerview/layout-managers/LayoutManager.js +279 -0
  190. package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -0
  191. package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts +51 -0
  192. package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts.map +1 -0
  193. package/dist/recyclerview/layout-managers/LinearLayoutManager.js +151 -0
  194. package/dist/recyclerview/layout-managers/LinearLayoutManager.js.map +1 -0
  195. package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts +81 -0
  196. package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts.map +1 -0
  197. package/dist/recyclerview/layout-managers/MasonryLayoutManager.js +269 -0
  198. package/dist/recyclerview/layout-managers/MasonryLayoutManager.js.map +1 -0
  199. package/dist/recyclerview/utils/adjustOffsetForRTL.d.ts +12 -0
  200. package/dist/recyclerview/utils/adjustOffsetForRTL.d.ts.map +1 -0
  201. package/dist/recyclerview/utils/adjustOffsetForRTL.js +14 -0
  202. package/dist/recyclerview/utils/adjustOffsetForRTL.js.map +1 -0
  203. package/dist/recyclerview/utils/componentUtils.d.ts +19 -0
  204. package/dist/recyclerview/utils/componentUtils.d.ts.map +1 -0
  205. package/dist/recyclerview/utils/componentUtils.js +27 -0
  206. package/dist/recyclerview/utils/componentUtils.js.map +1 -0
  207. package/dist/recyclerview/utils/findVisibleIndex.d.ts +24 -0
  208. package/dist/recyclerview/utils/findVisibleIndex.d.ts.map +1 -0
  209. package/dist/recyclerview/utils/findVisibleIndex.js +76 -0
  210. package/dist/recyclerview/utils/findVisibleIndex.js.map +1 -0
  211. package/dist/recyclerview/utils/measureLayout.d.ts +52 -0
  212. package/dist/recyclerview/utils/measureLayout.d.ts.map +1 -0
  213. package/dist/recyclerview/utils/measureLayout.js +99 -0
  214. package/dist/recyclerview/utils/measureLayout.js.map +1 -0
  215. package/dist/recyclerview/utils/measureLayout.web.d.ts +29 -0
  216. package/dist/recyclerview/utils/measureLayout.web.d.ts.map +1 -0
  217. package/dist/recyclerview/utils/measureLayout.web.js +79 -0
  218. package/dist/recyclerview/utils/measureLayout.web.js.map +1 -0
  219. package/dist/recyclerview/viewability/ViewToken.d.ts +8 -0
  220. package/dist/recyclerview/viewability/ViewToken.d.ts.map +1 -0
  221. package/dist/recyclerview/viewability/ViewToken.js +2 -0
  222. package/dist/recyclerview/viewability/ViewToken.js.map +1 -0
  223. package/dist/recyclerview/viewability/ViewabilityHelper.d.ts +26 -0
  224. package/dist/recyclerview/viewability/ViewabilityHelper.d.ts.map +1 -0
  225. package/dist/recyclerview/viewability/ViewabilityHelper.js +98 -0
  226. package/dist/recyclerview/viewability/ViewabilityHelper.js.map +1 -0
  227. package/dist/recyclerview/viewability/ViewabilityManager.d.ts +25 -0
  228. package/dist/recyclerview/viewability/ViewabilityManager.d.ts.map +1 -0
  229. package/dist/recyclerview/viewability/ViewabilityManager.js +94 -0
  230. package/dist/recyclerview/viewability/ViewabilityManager.js.map +1 -0
  231. package/dist/tsconfig.tsbuildinfo +1 -1
  232. package/dist/utils/AverageWindow.d.ts +33 -43
  233. package/dist/utils/AverageWindow.d.ts.map +1 -1
  234. package/dist/utils/AverageWindow.js +66 -71
  235. package/dist/utils/AverageWindow.js.map +1 -1
  236. package/jestSetup.js +23 -37
  237. package/package.json +15 -24
  238. package/src/AnimatedFlashList.ts +2 -25
  239. package/src/FlashList.ts +1 -0
  240. package/src/FlashListProps.ts +109 -100
  241. package/src/FlashListRef.ts +320 -0
  242. package/src/benchmark/AutoScrollHelper.ts +0 -24
  243. package/src/benchmark/JSFPSMonitor.ts +2 -26
  244. package/src/benchmark/roundToDecimalPlaces.ts +0 -24
  245. package/src/benchmark/useBenchmark.ts +59 -105
  246. package/src/benchmark/useDataMultiplier.ts +0 -24
  247. package/src/benchmark/useFlatListBenchmark.ts +43 -32
  248. package/src/errors/ErrorMessages.ts +26 -0
  249. package/src/errors/WarningMessages.ts +9 -0
  250. package/src/index.ts +18 -46
  251. package/src/isNewArch.ts +25 -0
  252. package/src/native/config/PlatformHelper.android.ts +3 -49
  253. package/src/native/config/PlatformHelper.harmony.ts +3 -24
  254. package/src/native/config/PlatformHelper.ios.ts +3 -48
  255. package/src/native/config/PlatformHelper.ts +3 -49
  256. package/src/native/config/PlatformHelper.web.ts +4 -55
  257. package/src/recyclerview/LayoutCommitObserver.tsx +74 -0
  258. package/src/recyclerview/RecyclerView.tsx +616 -0
  259. package/src/recyclerview/RecyclerViewContextProvider.ts +65 -0
  260. package/src/recyclerview/RecyclerViewManager.ts +461 -0
  261. package/src/recyclerview/RecyclerViewProps.ts +1 -0
  262. package/src/recyclerview/RenderStackManager.ts +317 -0
  263. package/src/recyclerview/ViewHolder.tsx +180 -0
  264. package/src/recyclerview/ViewHolderCollection.tsx +193 -0
  265. package/src/recyclerview/components/CompatScroller.ts +9 -0
  266. package/src/recyclerview/components/CompatView.ts +9 -0
  267. package/src/recyclerview/components/ScrollAnchor.tsx +66 -0
  268. package/src/recyclerview/components/StickyHeaders.tsx +222 -0
  269. package/src/recyclerview/helpers/ConsecutiveNumbers.ts +120 -0
  270. package/src/recyclerview/helpers/EngagedIndicesTracker.ts +301 -0
  271. package/src/recyclerview/helpers/RenderTimeTracker.ts +50 -0
  272. package/src/recyclerview/helpers/VelocityTracker.ts +77 -0
  273. package/src/recyclerview/hooks/useBoundDetection.ts +176 -0
  274. package/src/recyclerview/hooks/useLayoutState.ts +55 -0
  275. package/src/recyclerview/hooks/useMappingHelper.ts +20 -0
  276. package/src/recyclerview/hooks/useOnLoad.ts +80 -0
  277. package/src/recyclerview/hooks/useRecyclerViewController.tsx +633 -0
  278. package/src/recyclerview/hooks/useRecyclerViewManager.ts +42 -0
  279. package/src/recyclerview/hooks/useRecyclingState.ts +67 -0
  280. package/src/recyclerview/hooks/useSecondaryProps.tsx +124 -0
  281. package/src/recyclerview/hooks/useUnmountAwareCallbacks.ts +73 -0
  282. package/src/recyclerview/hooks/useUnmountFlag.ts +27 -0
  283. package/src/recyclerview/layout-managers/GridLayoutManager.ts +256 -0
  284. package/src/recyclerview/layout-managers/LayoutManager.ts +568 -0
  285. package/src/recyclerview/layout-managers/LinearLayoutManager.ts +171 -0
  286. package/src/recyclerview/layout-managers/MasonryLayoutManager.ts +323 -0
  287. package/src/recyclerview/utils/adjustOffsetForRTL.ts +17 -0
  288. package/src/recyclerview/utils/componentUtils.ts +28 -0
  289. package/src/recyclerview/utils/findVisibleIndex.ts +93 -0
  290. package/src/recyclerview/utils/measureLayout.ts +128 -0
  291. package/src/recyclerview/utils/measureLayout.web.ts +102 -0
  292. package/src/recyclerview/viewability/ViewToken.ts +7 -0
  293. package/src/{viewability → recyclerview/viewability}/ViewabilityHelper.ts +8 -33
  294. package/src/{viewability → recyclerview/viewability}/ViewabilityManager.ts +23 -46
  295. package/src/utils/AverageWindow.ts +33 -24
  296. package/dist/GridLayoutProviderWithProps.d.ts +0 -65
  297. package/dist/GridLayoutProviderWithProps.d.ts.map +0 -1
  298. package/dist/GridLayoutProviderWithProps.js +0 -138
  299. package/dist/GridLayoutProviderWithProps.js.map +0 -1
  300. package/dist/MasonryFlashList.d.ts +0 -74
  301. package/dist/MasonryFlashList.d.ts.map +0 -1
  302. package/dist/MasonryFlashList.js +0 -275
  303. package/dist/MasonryFlashList.js.map +0 -1
  304. package/dist/PureComponentWrapper.d.ts +0 -45
  305. package/dist/PureComponentWrapper.d.ts.map +0 -1
  306. package/dist/PureComponentWrapper.js +0 -60
  307. package/dist/PureComponentWrapper.js.map +0 -1
  308. package/dist/benchmark/useBlankAreaTracker.d.ts +0 -57
  309. package/dist/benchmark/useBlankAreaTracker.d.ts.map +0 -1
  310. package/dist/benchmark/useBlankAreaTracker.js +0 -90
  311. package/dist/benchmark/useBlankAreaTracker.js.map +0 -1
  312. package/dist/errors/CustomError.d.ts +0 -31
  313. package/dist/errors/CustomError.d.ts.map +0 -1
  314. package/dist/errors/CustomError.js +0 -37
  315. package/dist/errors/CustomError.js.map +0 -1
  316. package/dist/errors/ExceptionList.d.ts +0 -47
  317. package/dist/errors/ExceptionList.d.ts.map +0 -1
  318. package/dist/errors/ExceptionList.js +0 -49
  319. package/dist/errors/ExceptionList.js.map +0 -1
  320. package/dist/errors/Warnings.d.ts +0 -32
  321. package/dist/errors/Warnings.d.ts.map +0 -1
  322. package/dist/errors/Warnings.js +0 -36
  323. package/dist/errors/Warnings.js.map +0 -1
  324. package/dist/fabric/AutoLayoutNativeComponent.d.ts +0 -42
  325. package/dist/fabric/AutoLayoutNativeComponent.d.ts.map +0 -1
  326. package/dist/fabric/AutoLayoutNativeComponent.js +0 -29
  327. package/dist/fabric/AutoLayoutNativeComponent.js.map +0 -1
  328. package/dist/fabric/CellContainerNativeComponent.d.ts +0 -31
  329. package/dist/fabric/CellContainerNativeComponent.d.ts.map +0 -1
  330. package/dist/fabric/CellContainerNativeComponent.js +0 -29
  331. package/dist/fabric/CellContainerNativeComponent.js.map +0 -1
  332. package/dist/native/auto-layout/AutoLayoutView.d.ts +0 -45
  333. package/dist/native/auto-layout/AutoLayoutView.d.ts.map +0 -1
  334. package/dist/native/auto-layout/AutoLayoutView.js +0 -71
  335. package/dist/native/auto-layout/AutoLayoutView.js.map +0 -1
  336. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts +0 -27
  337. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts.map +0 -1
  338. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js +0 -29
  339. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js.map +0 -1
  340. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts +0 -28
  341. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +0 -1
  342. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.harmony.d.ts +0 -27
  343. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.harmony.d.ts.map +0 -1
  344. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.harmony.js +0 -29
  345. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.harmony.js.map +0 -1
  346. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts +0 -27
  347. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts.map +0 -1
  348. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js +0 -29
  349. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js.map +0 -1
  350. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js +0 -29
  351. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js.map +0 -1
  352. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +0 -39
  353. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +0 -1
  354. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js +0 -26
  355. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js.map +0 -1
  356. package/dist/native/cell-container/CellContainer.android.d.ts +0 -29
  357. package/dist/native/cell-container/CellContainer.android.d.ts.map +0 -1
  358. package/dist/native/cell-container/CellContainer.android.js +0 -32
  359. package/dist/native/cell-container/CellContainer.android.js.map +0 -1
  360. package/dist/native/cell-container/CellContainer.d.ts +0 -31
  361. package/dist/native/cell-container/CellContainer.d.ts.map +0 -1
  362. package/dist/native/cell-container/CellContainer.harmony.d.ts +0 -29
  363. package/dist/native/cell-container/CellContainer.harmony.d.ts.map +0 -1
  364. package/dist/native/cell-container/CellContainer.harmony.js +0 -32
  365. package/dist/native/cell-container/CellContainer.harmony.js.map +0 -1
  366. package/dist/native/cell-container/CellContainer.ios.d.ts +0 -29
  367. package/dist/native/cell-container/CellContainer.ios.d.ts.map +0 -1
  368. package/dist/native/cell-container/CellContainer.ios.js +0 -32
  369. package/dist/native/cell-container/CellContainer.ios.js.map +0 -1
  370. package/dist/native/cell-container/CellContainer.js +0 -34
  371. package/dist/native/cell-container/CellContainer.js.map +0 -1
  372. package/dist/native/cell-container/CellContainer.web.d.ts +0 -30
  373. package/dist/native/cell-container/CellContainer.web.d.ts.map +0 -1
  374. package/dist/native/cell-container/CellContainer.web.js +0 -36
  375. package/dist/native/cell-container/CellContainer.web.js.map +0 -1
  376. package/dist/utils/ContentContainerUtils.d.ts +0 -50
  377. package/dist/utils/ContentContainerUtils.d.ts.map +0 -1
  378. package/dist/utils/ContentContainerUtils.js +0 -71
  379. package/dist/utils/ContentContainerUtils.js.map +0 -1
  380. package/dist/viewability/ViewToken.d.ts +0 -31
  381. package/dist/viewability/ViewToken.d.ts.map +0 -1
  382. package/dist/viewability/ViewToken.js +0 -26
  383. package/dist/viewability/ViewToken.js.map +0 -1
  384. package/dist/viewability/ViewabilityHelper.d.ts +0 -49
  385. package/dist/viewability/ViewabilityHelper.d.ts.map +0 -1
  386. package/dist/viewability/ViewabilityHelper.js +0 -130
  387. package/dist/viewability/ViewabilityHelper.js.map +0 -1
  388. package/dist/viewability/ViewabilityManager.d.ts +0 -48
  389. package/dist/viewability/ViewabilityManager.d.ts.map +0 -1
  390. package/dist/viewability/ViewabilityManager.js +0 -131
  391. package/dist/viewability/ViewabilityManager.js.map +0 -1
  392. package/harmony/flash_list/BuildProfile.ets +0 -17
  393. package/harmony/flash_list/LICENSE +0 -7
  394. package/harmony/flash_list/build-profile.json5 +0 -8
  395. package/harmony/flash_list/hvigorfile.ts +0 -1
  396. package/harmony/flash_list/index.ets +0 -27
  397. package/harmony/flash_list/obfuscation-rules.txt +0 -18
  398. package/harmony/flash_list/oh-package.json5 +0 -24
  399. package/harmony/flash_list/src/main/cpp/AutoLayoutNode.cpp +0 -63
  400. package/harmony/flash_list/src/main/cpp/AutoLayoutNode.h +0 -54
  401. package/harmony/flash_list/src/main/cpp/AutoLayoutShadow.cpp +0 -140
  402. package/harmony/flash_list/src/main/cpp/AutoLayoutShadow.h +0 -66
  403. package/harmony/flash_list/src/main/cpp/AutoLayoutViewComponentInstance.cpp +0 -208
  404. package/harmony/flash_list/src/main/cpp/AutoLayoutViewComponentInstance.h +0 -78
  405. package/harmony/flash_list/src/main/cpp/AutoLayoutViewEventEmitRequestHandler.h +0 -53
  406. package/harmony/flash_list/src/main/cpp/AutoLayoutViewJSIBinder.h +0 -50
  407. package/harmony/flash_list/src/main/cpp/CMakeLists.txt +0 -12
  408. package/harmony/flash_list/src/main/cpp/CellContainerComponentInstance.cpp +0 -80
  409. package/harmony/flash_list/src/main/cpp/CellContainerComponentInstance.h +0 -64
  410. package/harmony/flash_list/src/main/cpp/CellContainerJSIBinder.h +0 -39
  411. package/harmony/flash_list/src/main/cpp/ComponentDescriptors.h +0 -40
  412. package/harmony/flash_list/src/main/cpp/EventEmitters.cpp +0 -40
  413. package/harmony/flash_list/src/main/cpp/EventEmitters.h +0 -48
  414. package/harmony/flash_list/src/main/cpp/FlashListPackage.h +0 -85
  415. package/harmony/flash_list/src/main/cpp/FlashListStackNode.cpp +0 -87
  416. package/harmony/flash_list/src/main/cpp/FlashListStackNode.h +0 -57
  417. package/harmony/flash_list/src/main/cpp/Props.cpp +0 -52
  418. package/harmony/flash_list/src/main/cpp/Props.h +0 -64
  419. package/harmony/flash_list/src/main/cpp/ShadowNodes.cpp +0 -34
  420. package/harmony/flash_list/src/main/cpp/ShadowNodes.h +0 -48
  421. package/harmony/flash_list/src/main/ets/Logger.ets +0 -64
  422. package/harmony/flash_list/src/main/ets/RNAutoLayoutShadow.ets +0 -154
  423. package/harmony/flash_list/src/main/ets/RNAutoLayoutView.ets +0 -277
  424. package/harmony/flash_list/src/main/ets/RNCellContainer.ets +0 -113
  425. package/harmony/flash_list/src/main/module.json5 +0 -9
  426. package/harmony/flash_list/src/main/resources/base/element/color.json +0 -8
  427. package/harmony/flash_list/src/main/resources/base/element/string.json +0 -16
  428. package/harmony/flash_list/src/main/resources/base/media/icon.png +0 -0
  429. package/harmony/flash_list/src/main/resources/base/profile/main_pages.json +0 -5
  430. package/harmony/flash_list/src/main/resources/en_US/element/string.json +0 -16
  431. package/harmony/flash_list/src/main/resources/zh_CN/element/string.json +0 -16
  432. package/harmony/flash_list.har +0 -0
  433. package/src/FlashList.tsx +0 -949
  434. package/src/GridLayoutProviderWithProps.ts +0 -204
  435. package/src/MasonryFlashList.tsx +0 -499
  436. package/src/PureComponentWrapper.tsx +0 -65
  437. package/src/benchmark/useBlankAreaTracker.ts +0 -141
  438. package/src/errors/CustomError.ts +0 -34
  439. package/src/errors/ExceptionList.ts +0 -52
  440. package/src/errors/Warnings.ts +0 -39
  441. package/src/fabric/AutoLayoutNativeComponent.ts +0 -52
  442. package/src/fabric/CellContainerNativeComponent.ts +0 -35
  443. package/src/native/auto-layout/AutoLayoutView.tsx +0 -97
  444. package/src/native/auto-layout/AutoLayoutViewNativeComponent.android.ts +0 -31
  445. package/src/native/auto-layout/AutoLayoutViewNativeComponent.harmony.ts +0 -31
  446. package/src/native/auto-layout/AutoLayoutViewNativeComponent.ios.ts +0 -31
  447. package/src/native/auto-layout/AutoLayoutViewNativeComponent.ts +0 -31
  448. package/src/native/auto-layout/AutoLayoutViewNativeComponentProps.ts +0 -41
  449. package/src/native/cell-container/CellContainer.android.ts +0 -31
  450. package/src/native/cell-container/CellContainer.harmony.ts +0 -31
  451. package/src/native/cell-container/CellContainer.ios.ts +0 -31
  452. package/src/native/cell-container/CellContainer.tsx +0 -38
  453. package/src/native/cell-container/CellContainer.web.tsx +0 -33
  454. package/src/utils/ContentContainerUtils.ts +0 -116
  455. package/src/viewability/ViewToken.ts +0 -31
@@ -0,0 +1,633 @@
1
+ import {
2
+ RefObject,
3
+ useCallback,
4
+ useImperativeHandle,
5
+ useMemo,
6
+ useRef,
7
+ useState,
8
+ } from "react";
9
+ import { I18nManager } from "react-native";
10
+
11
+ import {
12
+ ScrollToOffsetParams,
13
+ ScrollToIndexParams,
14
+ ScrollToItemParams,
15
+ ScrollToEdgeParams,
16
+ FlashListRef,
17
+ } from "../../FlashListRef";
18
+ import { CompatScroller } from "../components/CompatScroller";
19
+ import { RecyclerViewManager } from "../RecyclerViewManager";
20
+ import { adjustOffsetForRTL } from "../utils/adjustOffsetForRTL";
21
+ import { RVLayout } from "../layout-managers/LayoutManager";
22
+ import { ScrollAnchorRef } from "../components/ScrollAnchor";
23
+ import { PlatformConfig } from "../../native/config/PlatformHelper";
24
+ import { WarningMessages } from "../../errors/WarningMessages";
25
+
26
+ import { useUnmountFlag } from "./useUnmountFlag";
27
+ import { useUnmountAwareTimeout } from "./useUnmountAwareCallbacks";
28
+
29
+ /**
30
+ * Comprehensive hook that manages RecyclerView scrolling behavior and provides
31
+ * imperative methods for controlling the RecyclerView.
32
+ *
33
+ * This hook combines content offset management and scroll handling functionality:
34
+ * 1. Provides imperative methods for scrolling and measurement
35
+ * 2. Handles initial scroll position when the list first loads
36
+ * 3. Maintains visible content position during updates
37
+ * 4. Manages scroll anchors for chat-like applications
38
+ *
39
+ * @param recyclerViewManager - The RecyclerViewManager instance that handles core functionality
40
+ * @param ref - The ref to expose the imperative methods
41
+ * @param scrollViewRef - Reference to the scrollable container component
42
+ * @param scrollAnchorRef - Reference to the scroll anchor component
43
+ * @param props - The RecyclerViewProps containing configuration
44
+ */
45
+ export function useRecyclerViewController<T>(
46
+ recyclerViewManager: RecyclerViewManager<T>,
47
+ ref: React.Ref<FlashListRef<T>>,
48
+ scrollViewRef: RefObject<CompatScroller>,
49
+ scrollAnchorRef: React.RefObject<ScrollAnchorRef>
50
+ ) {
51
+ const isUnmounted = useUnmountFlag();
52
+ const [_, setRenderId] = useState(0);
53
+ const pauseOffsetCorrection = useRef(false);
54
+ const initialScrollCompletedRef = useRef(false);
55
+ const lastDataLengthRef = useRef(recyclerViewManager.getDataLength());
56
+ const { setTimeout } = useUnmountAwareTimeout();
57
+
58
+ // Track the first visible item for maintaining scroll position
59
+ const firstVisibleItemKey = useRef<string | undefined>(undefined);
60
+ const firstVisibleItemLayout = useRef<RVLayout | undefined>(undefined);
61
+
62
+ // Queue to store callbacks that should be executed after scroll offset updates
63
+ const pendingScrollCallbacks = useRef<(() => void)[]>([]);
64
+
65
+ // Handle initial scroll position when the list first loads
66
+ // useOnLoad(recyclerViewManager, () => {
67
+
68
+ // });
69
+ /**
70
+ * Updates the scroll offset and calls the provided callback
71
+ * after the update has been applied and the component has re-rendered.
72
+ *
73
+ * @param offset - The new scroll offset to apply
74
+ * @param callback - Optional callback to execute after the update is applied
75
+ */
76
+ const updateScrollOffsetWithCallback = useCallback(
77
+ (offset: number, callback: () => void): void => {
78
+ // Attempt to update the scroll offset in the RecyclerViewManager
79
+ // This returns undefined if no update is needed
80
+ if (recyclerViewManager.updateScrollOffset(offset) !== undefined) {
81
+ // It will be executed after the next render
82
+ pendingScrollCallbacks.current.push(callback);
83
+ // Trigger a re-render to apply the scroll offset update
84
+ setRenderId((prev) => prev + 1);
85
+ } else {
86
+ // No update needed, execute callback immediately
87
+ callback();
88
+ }
89
+ },
90
+ [recyclerViewManager]
91
+ );
92
+
93
+ const computeFirstVisibleIndexForOffsetCorrection = useCallback(() => {
94
+ if (
95
+ recyclerViewManager.getIsFirstLayoutComplete() &&
96
+ recyclerViewManager.hasStableDataKeys() &&
97
+ recyclerViewManager.getDataLength() > 0 &&
98
+ recyclerViewManager.shouldMaintainVisibleContentPosition()
99
+ ) {
100
+ // Update the tracked first visible item
101
+ const firstVisibleIndex = Math.max(
102
+ 0,
103
+ recyclerViewManager.computeVisibleIndices().startIndex
104
+ );
105
+ if (firstVisibleIndex !== undefined && firstVisibleIndex >= 0) {
106
+ firstVisibleItemKey.current =
107
+ recyclerViewManager.getDataKey(firstVisibleIndex);
108
+ firstVisibleItemLayout.current = {
109
+ ...recyclerViewManager.getLayout(firstVisibleIndex),
110
+ };
111
+ }
112
+ }
113
+ }, [recyclerViewManager]);
114
+
115
+ /**
116
+ * Maintains the visible content position when the list updates.
117
+ * This is particularly useful for chat applications where we want to keep
118
+ * the user's current view position when new messages are added.
119
+ */
120
+ const applyOffsetCorrection = useCallback(() => {
121
+ const { horizontal, data } = recyclerViewManager.props;
122
+
123
+ // Execute all pending callbacks from previous scroll offset updates
124
+ // This ensures any scroll operations that were waiting for render are completed
125
+ const callbacks = pendingScrollCallbacks.current;
126
+ pendingScrollCallbacks.current = [];
127
+ callbacks.forEach((callback) => callback());
128
+
129
+ const currentDataLength = recyclerViewManager.getDataLength();
130
+
131
+ if (
132
+ recyclerViewManager.getIsFirstLayoutComplete() &&
133
+ recyclerViewManager.hasStableDataKeys() &&
134
+ currentDataLength > 0 &&
135
+ recyclerViewManager.shouldMaintainVisibleContentPosition()
136
+ ) {
137
+ const hasDataChanged = currentDataLength !== lastDataLengthRef.current;
138
+ // If we have a tracked first visible item, maintain its position
139
+ if (firstVisibleItemKey.current) {
140
+ const currentIndexOfFirstVisibleItem =
141
+ recyclerViewManager
142
+ .getEngagedIndices()
143
+ .findValue(
144
+ (index) =>
145
+ recyclerViewManager.getDataKey(index) ===
146
+ firstVisibleItemKey.current
147
+ ) ??
148
+ (hasDataChanged
149
+ ? data?.findIndex(
150
+ (item, index) =>
151
+ recyclerViewManager.getDataKey(index) ===
152
+ firstVisibleItemKey.current
153
+ )
154
+ : undefined);
155
+
156
+ if (
157
+ currentIndexOfFirstVisibleItem !== undefined &&
158
+ currentIndexOfFirstVisibleItem >= 0
159
+ ) {
160
+ // Calculate the difference in position and apply the offset
161
+ const diff = horizontal
162
+ ? recyclerViewManager.getLayout(currentIndexOfFirstVisibleItem).x -
163
+ firstVisibleItemLayout.current!.x
164
+ : recyclerViewManager.getLayout(currentIndexOfFirstVisibleItem).y -
165
+ firstVisibleItemLayout.current!.y;
166
+ firstVisibleItemLayout.current = {
167
+ ...recyclerViewManager.getLayout(currentIndexOfFirstVisibleItem),
168
+ };
169
+ if (
170
+ diff !== 0 &&
171
+ !pauseOffsetCorrection.current &&
172
+ !recyclerViewManager.animationOptimizationsEnabled
173
+ ) {
174
+ // console.log("diff", diff, firstVisibleItemKey.current);
175
+ if (PlatformConfig.supportsOffsetCorrection) {
176
+ // console.log("scrollBy", diff);
177
+ scrollAnchorRef.current?.scrollBy(diff);
178
+ } else {
179
+ const scrollToParams = horizontal
180
+ ? {
181
+ x: recyclerViewManager.getAbsoluteLastScrollOffset() + diff,
182
+ animated: false,
183
+ }
184
+ : {
185
+ y: recyclerViewManager.getAbsoluteLastScrollOffset() + diff,
186
+ animated: false,
187
+ };
188
+ scrollViewRef.current?.scrollTo(scrollToParams);
189
+ }
190
+ if (hasDataChanged) {
191
+ updateScrollOffsetWithCallback(
192
+ recyclerViewManager.getAbsoluteLastScrollOffset() + diff,
193
+ () => {}
194
+ );
195
+ recyclerViewManager.ignoreScrollEvents = true;
196
+ setTimeout(() => {
197
+ recyclerViewManager.ignoreScrollEvents = false;
198
+ }, 100);
199
+ }
200
+ }
201
+ }
202
+ }
203
+
204
+ computeFirstVisibleIndexForOffsetCorrection();
205
+ }
206
+ lastDataLengthRef.current = recyclerViewManager.getDataLength();
207
+ }, [
208
+ recyclerViewManager,
209
+ scrollAnchorRef,
210
+ scrollViewRef,
211
+ setTimeout,
212
+ updateScrollOffsetWithCallback,
213
+ computeFirstVisibleIndexForOffsetCorrection,
214
+ ]);
215
+
216
+ const handlerMethods: FlashListRef<T> = useMemo(() => {
217
+ return {
218
+ get props() {
219
+ return recyclerViewManager.props;
220
+ },
221
+ /**
222
+ * Scrolls the list to a specific offset position.
223
+ * Handles RTL layouts and first item offset adjustments.
224
+ */
225
+ scrollToOffset: ({
226
+ offset,
227
+ animated,
228
+ skipFirstItemOffset = true,
229
+ }: ScrollToOffsetParams) => {
230
+ const { horizontal } = recyclerViewManager.props;
231
+ if (scrollViewRef.current) {
232
+ // Adjust offset for RTL layouts in horizontal mode
233
+ if (I18nManager.isRTL && horizontal) {
234
+ // eslint-disable-next-line no-param-reassign
235
+ offset =
236
+ adjustOffsetForRTL(
237
+ offset,
238
+ recyclerViewManager.getChildContainerDimensions().width,
239
+ recyclerViewManager.getWindowSize().width
240
+ ) +
241
+ (skipFirstItemOffset
242
+ ? recyclerViewManager.firstItemOffset
243
+ : -recyclerViewManager.firstItemOffset);
244
+ }
245
+
246
+ // Calculate the final offset including first item offset if needed
247
+ const adjustedOffset =
248
+ offset +
249
+ (skipFirstItemOffset ? 0 : recyclerViewManager.firstItemOffset);
250
+ const scrollTo = horizontal
251
+ ? { x: adjustedOffset, y: 0 }
252
+ : { x: 0, y: adjustedOffset };
253
+ scrollViewRef.current.scrollTo({
254
+ ...scrollTo,
255
+ animated,
256
+ });
257
+ }
258
+ },
259
+ clearLayoutCacheOnUpdate: () => {
260
+ recyclerViewManager.markLayoutManagerDirty();
261
+ },
262
+
263
+ // Expose native scroll view methods
264
+ flashScrollIndicators: () => {
265
+ scrollViewRef.current!.flashScrollIndicators();
266
+ },
267
+ getNativeScrollRef: () => {
268
+ return scrollViewRef.current;
269
+ },
270
+ getScrollResponder: () => {
271
+ return scrollViewRef.current!.getScrollResponder();
272
+ },
273
+ getScrollableNode: () => {
274
+ return scrollViewRef.current!.getScrollableNode();
275
+ },
276
+
277
+ /**
278
+ * Scrolls to the end of the list.
279
+ */
280
+ scrollToEnd: async ({ animated }: ScrollToEdgeParams = {}) => {
281
+ const { data } = recyclerViewManager.props;
282
+ if (data && data.length > 0) {
283
+ const lastIndex = data.length - 1;
284
+ if (!recyclerViewManager.getEngagedIndices().includes(lastIndex)) {
285
+ await handlerMethods.scrollToIndex({
286
+ index: lastIndex,
287
+ animated,
288
+ });
289
+ }
290
+ }
291
+ setTimeout(() => {
292
+ scrollViewRef.current?.scrollToEnd({ animated });
293
+ }, 0);
294
+ },
295
+
296
+ /**
297
+ * Scrolls to the beginning of the list.
298
+ */
299
+ scrollToTop: ({ animated }: ScrollToEdgeParams = {}) => {
300
+ handlerMethods.scrollToOffset({
301
+ offset: 0,
302
+ animated,
303
+ });
304
+ },
305
+
306
+ /**
307
+ * Scrolls to a specific index in the list.
308
+ * Supports viewPosition and viewOffset for precise positioning.
309
+ * Returns a Promise that resolves when the scroll is complete.
310
+ */
311
+ scrollToIndex: ({
312
+ index,
313
+ animated,
314
+ viewPosition,
315
+ viewOffset,
316
+ }: ScrollToIndexParams): Promise<void> => {
317
+ return new Promise((resolve) => {
318
+ const { horizontal } = recyclerViewManager.props;
319
+ if (
320
+ scrollViewRef.current &&
321
+ index >= 0 &&
322
+ index < recyclerViewManager.getDataLength()
323
+ ) {
324
+ // Pause the scroll offset adjustments
325
+ pauseOffsetCorrection.current = true;
326
+ recyclerViewManager.setOffsetProjectionEnabled(false);
327
+
328
+ const getFinalOffset = () => {
329
+ const layout = recyclerViewManager.getLayout(index);
330
+ const offset = horizontal ? layout.x : layout.y;
331
+ let finalOffset = offset;
332
+ // take viewPosition etc into account
333
+ if (viewPosition !== undefined || viewOffset !== undefined) {
334
+ const containerSize = horizontal
335
+ ? recyclerViewManager.getWindowSize().width
336
+ : recyclerViewManager.getWindowSize().height;
337
+
338
+ const itemSize = horizontal ? layout.width : layout.height;
339
+
340
+ if (viewPosition !== undefined) {
341
+ // viewPosition: 0 = top, 0.5 = center, 1 = bottom
342
+ finalOffset =
343
+ offset - (containerSize - itemSize) * viewPosition;
344
+ }
345
+
346
+ if (viewOffset !== undefined) {
347
+ finalOffset += viewOffset;
348
+ }
349
+ }
350
+ return finalOffset + recyclerViewManager.firstItemOffset;
351
+ };
352
+ const lastAbsoluteScrollOffset =
353
+ recyclerViewManager.getAbsoluteLastScrollOffset();
354
+ const bufferForScroll = horizontal
355
+ ? recyclerViewManager.getWindowSize().width
356
+ : recyclerViewManager.getWindowSize().height;
357
+
358
+ const bufferForCompute = bufferForScroll * 2;
359
+
360
+ const getStartScrollOffset = () => {
361
+ let lastScrollOffset = lastAbsoluteScrollOffset;
362
+ const finalOffset = getFinalOffset();
363
+
364
+ if (finalOffset > lastScrollOffset) {
365
+ lastScrollOffset = Math.max(
366
+ finalOffset - bufferForCompute,
367
+ lastScrollOffset
368
+ );
369
+ recyclerViewManager.setScrollDirection("forward");
370
+ } else {
371
+ lastScrollOffset = Math.min(
372
+ finalOffset + bufferForCompute,
373
+ lastScrollOffset
374
+ );
375
+ recyclerViewManager.setScrollDirection("backward");
376
+ }
377
+ return lastScrollOffset;
378
+ };
379
+ let initialTargetOffset = getFinalOffset();
380
+ let initialStartScrollOffset = getStartScrollOffset();
381
+ let finalOffset = initialTargetOffset;
382
+ let startScrollOffset = initialStartScrollOffset;
383
+
384
+ const steps = 5;
385
+
386
+ /**
387
+ * Recursively performs the scroll animation steps.
388
+ * This function replaces the async/await loop with callback-based execution.
389
+ *
390
+ * @param currentStep - The current step in the animation (0 to steps-1)
391
+ */
392
+ const performScrollStep = (currentStep: number) => {
393
+ // Check if component is unmounted or we've completed all steps
394
+ if (isUnmounted.current) {
395
+ resolve();
396
+ return;
397
+ } else if (currentStep >= steps) {
398
+ // All steps completed, perform final scroll
399
+ finishScrollToIndex();
400
+ return;
401
+ }
402
+
403
+ // Calculate the offset for this step
404
+ // For animated scrolls: interpolate from finalOffset to startScrollOffset
405
+ // For non-animated: interpolate from startScrollOffset to finalOffset
406
+ const nextOffset = animated
407
+ ? finalOffset +
408
+ (startScrollOffset - finalOffset) *
409
+ (currentStep / (steps - 1))
410
+ : startScrollOffset +
411
+ (finalOffset - startScrollOffset) *
412
+ (currentStep / (steps - 1));
413
+
414
+ // Update scroll offset with a callback to continue to the next step
415
+ updateScrollOffsetWithCallback(nextOffset, () => {
416
+ // Check if the index is still valid after the update
417
+ if (index >= recyclerViewManager.getDataLength()) {
418
+ // Index out of bounds, scroll to end instead
419
+ handlerMethods.scrollToEnd({ animated });
420
+ resolve(); // Resolve the promise as we're done
421
+ return;
422
+ }
423
+
424
+ // Check if the target position has changed significantly
425
+ const newFinalOffset = getFinalOffset();
426
+ if (
427
+ (newFinalOffset < initialTargetOffset &&
428
+ newFinalOffset < initialStartScrollOffset) ||
429
+ (newFinalOffset > initialTargetOffset &&
430
+ newFinalOffset > initialStartScrollOffset)
431
+ ) {
432
+ // Target has moved, recalculate and restart from beginning
433
+ finalOffset = newFinalOffset;
434
+ startScrollOffset = getStartScrollOffset();
435
+ initialTargetOffset = newFinalOffset;
436
+ initialStartScrollOffset = startScrollOffset;
437
+ performScrollStep(0); // Restart from step 0
438
+ } else {
439
+ // Continue to next step
440
+ performScrollStep(currentStep + 1);
441
+ }
442
+ });
443
+ };
444
+
445
+ /**
446
+ * Completes the scroll to index operation by performing the final scroll
447
+ * and re-enabling offset correction after a delay.
448
+ */
449
+ const finishScrollToIndex = () => {
450
+ finalOffset = getFinalOffset();
451
+ const maxOffset = recyclerViewManager.getMaxScrollOffset();
452
+
453
+ if (finalOffset > maxOffset) {
454
+ finalOffset = maxOffset;
455
+ }
456
+
457
+ if (animated) {
458
+ // For animated scrolls, first jump to the start position
459
+ // We don't need to add firstItemOffset here as it's already added
460
+ handlerMethods.scrollToOffset({
461
+ offset: startScrollOffset,
462
+ animated: false,
463
+ skipFirstItemOffset: true,
464
+ });
465
+ }
466
+
467
+ // Perform the final scroll to the target position
468
+ handlerMethods.scrollToOffset({
469
+ offset: finalOffset,
470
+ animated,
471
+ skipFirstItemOffset: true,
472
+ });
473
+
474
+ // Re-enable offset correction after a delay
475
+ // Longer delay for animated scrolls to allow animation to complete
476
+ setTimeout(
477
+ () => {
478
+ pauseOffsetCorrection.current = false;
479
+ recyclerViewManager.setOffsetProjectionEnabled(true);
480
+ resolve(); // Resolve the promise after re-enabling corrections
481
+ },
482
+ animated ? 300 : 200
483
+ );
484
+ };
485
+
486
+ // Start the scroll animation process
487
+ performScrollStep(0);
488
+ } else {
489
+ // Invalid parameters, resolve immediately
490
+ resolve();
491
+ }
492
+ });
493
+ },
494
+
495
+ /**
496
+ * Scrolls to a specific item in the list.
497
+ * Finds the item's index and uses scrollToIndex internally.
498
+ */
499
+ scrollToItem: ({
500
+ item,
501
+ animated,
502
+ viewPosition,
503
+ viewOffset,
504
+ }: ScrollToItemParams<T>) => {
505
+ const { data } = recyclerViewManager.props;
506
+ if (scrollViewRef.current && data) {
507
+ // Find the index of the item in the data array
508
+ const index = data.findIndex((dataItem) => dataItem === item);
509
+ if (index >= 0) {
510
+ handlerMethods.scrollToIndex({
511
+ index,
512
+ animated,
513
+ viewPosition,
514
+ viewOffset,
515
+ });
516
+ }
517
+ }
518
+ },
519
+
520
+ // Utility methods for measuring header height / top padding
521
+ getFirstItemOffset: () => {
522
+ return recyclerViewManager.firstItemOffset;
523
+ },
524
+ getWindowSize: () => {
525
+ return recyclerViewManager.getWindowSize();
526
+ },
527
+ getLayout: (index: number) => {
528
+ return recyclerViewManager.tryGetLayout(index);
529
+ },
530
+ getAbsoluteLastScrollOffset: () => {
531
+ return recyclerViewManager.getAbsoluteLastScrollOffset();
532
+ },
533
+ getChildContainerDimensions: () => {
534
+ return recyclerViewManager.getChildContainerDimensions();
535
+ },
536
+ recordInteraction: () => {
537
+ recyclerViewManager.recordInteraction();
538
+ },
539
+ computeVisibleIndices: () => {
540
+ return recyclerViewManager.computeVisibleIndices();
541
+ },
542
+ getFirstVisibleIndex: () => {
543
+ return recyclerViewManager.computeVisibleIndices().startIndex;
544
+ },
545
+ recomputeViewableItems: () => {
546
+ recyclerViewManager.recomputeViewableItems();
547
+ },
548
+ /**
549
+ * Disables item recycling in preparation for layout animations.
550
+ */
551
+ prepareForLayoutAnimationRender: () => {
552
+ if (!recyclerViewManager.props.keyExtractor) {
553
+ console.warn(WarningMessages.keyExtractorNotDefinedForAnimation);
554
+ }
555
+ recyclerViewManager.animationOptimizationsEnabled = true;
556
+ },
557
+ };
558
+ }, [
559
+ recyclerViewManager,
560
+ scrollViewRef,
561
+ setTimeout,
562
+ isUnmounted,
563
+ updateScrollOffsetWithCallback,
564
+ ]);
565
+
566
+ const applyInitialScrollIndex = useCallback(() => {
567
+ const { horizontal, data, initialScrollIndexParams } =
568
+ recyclerViewManager.props;
569
+
570
+ const initialScrollIndex =
571
+ recyclerViewManager.getInitialScrollIndex() ?? -1;
572
+ const dataLength = data?.length ?? 0;
573
+ if (
574
+ initialScrollIndex >= 0 &&
575
+ initialScrollIndex < dataLength &&
576
+ !initialScrollCompletedRef.current &&
577
+ recyclerViewManager.getIsFirstLayoutComplete()
578
+ ) {
579
+ // Use setTimeout to ensure that we keep trying to scroll on first few renders
580
+ setTimeout(() => {
581
+ initialScrollCompletedRef.current = true;
582
+ pauseOffsetCorrection.current = false;
583
+ }, 100);
584
+
585
+ pauseOffsetCorrection.current = true;
586
+
587
+ const additionalOffset = initialScrollIndexParams?.viewOffset ?? 0;
588
+ const offset = horizontal
589
+ ? recyclerViewManager.getLayout(initialScrollIndex).x + additionalOffset
590
+ : recyclerViewManager.getLayout(initialScrollIndex).y +
591
+ additionalOffset;
592
+ handlerMethods.scrollToOffset({
593
+ offset,
594
+ animated: false,
595
+ skipFirstItemOffset: false,
596
+ });
597
+
598
+ setTimeout(() => {
599
+ handlerMethods.scrollToOffset({
600
+ offset,
601
+ animated: false,
602
+ skipFirstItemOffset: false,
603
+ });
604
+ }, 0);
605
+ }
606
+ }, [handlerMethods, recyclerViewManager, setTimeout]);
607
+
608
+ // Expose imperative methods through the ref
609
+ useImperativeHandle(
610
+ ref,
611
+ () => {
612
+ const imperativeApi = { ...scrollViewRef.current, ...handlerMethods };
613
+ // Without this the props getter from handlerMethods is evaluated during spread and
614
+ // future updates to props are not reflected in the ref
615
+ Object.defineProperty(imperativeApi, "props", {
616
+ get() {
617
+ return recyclerViewManager.props;
618
+ },
619
+ enumerable: true,
620
+ configurable: true,
621
+ });
622
+ return imperativeApi;
623
+ },
624
+ [handlerMethods, scrollViewRef, recyclerViewManager]
625
+ );
626
+
627
+ return {
628
+ applyOffsetCorrection,
629
+ computeFirstVisibleIndexForOffsetCorrection,
630
+ applyInitialScrollIndex,
631
+ handlerMethods,
632
+ };
633
+ }
@@ -0,0 +1,42 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+
3
+ import { RecyclerViewProps } from "../RecyclerViewProps";
4
+ import { RecyclerViewManager } from "../RecyclerViewManager";
5
+ import { VelocityTracker } from "../helpers/VelocityTracker";
6
+
7
+ export const useRecyclerViewManager = <T>(props: RecyclerViewProps<T>) => {
8
+ const [recyclerViewManager] = useState<RecyclerViewManager<T>>(
9
+ () => new RecyclerViewManager(props)
10
+ );
11
+ const [velocityTracker] = useState(() => new VelocityTracker());
12
+
13
+ const { data } = props;
14
+
15
+ useMemo(() => {
16
+ recyclerViewManager.updateProps(props);
17
+ // used to update props so rule can be disabled
18
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19
+ }, [props]);
20
+
21
+ /**
22
+ * When data changes, we need to process the data update before the render happens
23
+ */
24
+ useMemo(() => {
25
+ recyclerViewManager.processDataUpdate();
26
+ // used to process data update so rule can be disabled
27
+ // eslint-disable-next-line react-hooks/exhaustive-deps
28
+ }, [data]);
29
+
30
+ useEffect(() => {
31
+ recyclerViewManager.restoreIfNeeded();
32
+
33
+ return () => {
34
+ recyclerViewManager.dispose();
35
+ velocityTracker.cleanUp();
36
+ };
37
+ // Used to perform cleanup on unmount
38
+ // eslint-disable-next-line react-hooks/exhaustive-deps
39
+ }, []);
40
+
41
+ return { recyclerViewManager, velocityTracker };
42
+ };