@shopify/flash-list 2.0.0-alpha.2 → 2.0.0-alpha.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 (329) hide show
  1. package/README.md +67 -96
  2. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +2 -2
  3. package/dist/AnimatedFlashList.d.ts +0 -1
  4. package/dist/AnimatedFlashList.d.ts.map +1 -1
  5. package/dist/AnimatedFlashList.js +3 -3
  6. package/dist/AnimatedFlashList.js.map +1 -1
  7. package/dist/FlashList.d.ts +9 -0
  8. package/dist/FlashList.d.ts.map +1 -1
  9. package/dist/FlashList.js +22 -3
  10. package/dist/FlashList.js.map +1 -1
  11. package/dist/FlashListProps.d.ts +33 -13
  12. package/dist/FlashListProps.d.ts.map +1 -1
  13. package/dist/FlashListProps.js.map +1 -1
  14. package/dist/FlashListRef.d.ts +305 -0
  15. package/dist/FlashListRef.d.ts.map +1 -0
  16. package/dist/FlashListRef.js +3 -0
  17. package/dist/FlashListRef.js.map +1 -0
  18. package/dist/GridLayoutProviderWithProps.js +1 -2
  19. package/dist/GridLayoutProviderWithProps.js.map +1 -1
  20. package/dist/MasonryFlashList.d.ts +2 -2
  21. package/dist/MasonryFlashList.d.ts.map +1 -1
  22. package/dist/MasonryFlashList.js.map +1 -1
  23. package/dist/PureComponentWrapper.js +1 -1
  24. package/dist/PureComponentWrapper.js.map +1 -1
  25. package/dist/__tests__/AverageWindow.test.js.map +1 -1
  26. package/dist/__tests__/ConsecutiveNumbers.test.d.ts +2 -0
  27. package/dist/__tests__/ConsecutiveNumbers.test.d.ts.map +1 -0
  28. package/dist/__tests__/ConsecutiveNumbers.test.js +224 -0
  29. package/dist/__tests__/ConsecutiveNumbers.test.js.map +1 -0
  30. package/dist/__tests__/FlashList.test.js.map +1 -1
  31. package/dist/__tests__/GridLayoutManager.test.d.ts +2 -0
  32. package/dist/__tests__/GridLayoutManager.test.d.ts.map +1 -0
  33. package/dist/__tests__/GridLayoutManager.test.js +69 -0
  34. package/dist/__tests__/GridLayoutManager.test.js.map +1 -0
  35. package/dist/__tests__/GridLayoutProviderWithProps.test.js.map +1 -1
  36. package/dist/__tests__/LayoutCommitObserver.test.d.ts +2 -0
  37. package/dist/__tests__/LayoutCommitObserver.test.d.ts.map +1 -0
  38. package/dist/__tests__/LayoutCommitObserver.test.js +35 -0
  39. package/dist/__tests__/LayoutCommitObserver.test.js.map +1 -0
  40. package/dist/__tests__/LinearLayoutManager.test.d.ts +2 -0
  41. package/dist/__tests__/LinearLayoutManager.test.d.ts.map +1 -0
  42. package/dist/__tests__/LinearLayoutManager.test.js +140 -0
  43. package/dist/__tests__/LinearLayoutManager.test.js.map +1 -0
  44. package/dist/__tests__/MasonryFlashList.test.js.map +1 -1
  45. package/dist/__tests__/MasonryLayoutManager.test.d.ts +2 -0
  46. package/dist/__tests__/MasonryLayoutManager.test.d.ts.map +1 -0
  47. package/dist/__tests__/MasonryLayoutManager.test.js +148 -0
  48. package/dist/__tests__/MasonryLayoutManager.test.js.map +1 -0
  49. package/dist/__tests__/RecyclerView.test.d.ts +2 -0
  50. package/dist/__tests__/RecyclerView.test.d.ts.map +1 -0
  51. package/dist/__tests__/RecyclerView.test.js +103 -0
  52. package/dist/__tests__/RecyclerView.test.js.map +1 -0
  53. package/dist/__tests__/RenderStackManager.test.d.ts +2 -0
  54. package/dist/__tests__/RenderStackManager.test.d.ts.map +1 -0
  55. package/dist/__tests__/RenderStackManager.test.js +485 -0
  56. package/dist/__tests__/RenderStackManager.test.js.map +1 -0
  57. package/dist/__tests__/ViewabilityHelper.test.js.map +1 -1
  58. package/dist/__tests__/findVisibleIndex.test.d.ts +2 -0
  59. package/dist/__tests__/findVisibleIndex.test.d.ts.map +1 -0
  60. package/dist/__tests__/findVisibleIndex.test.js +259 -0
  61. package/dist/__tests__/findVisibleIndex.test.js.map +1 -0
  62. package/dist/__tests__/helpers/createLayoutManager.d.ts +34 -0
  63. package/dist/__tests__/helpers/createLayoutManager.d.ts.map +1 -0
  64. package/dist/__tests__/helpers/createLayoutManager.js +110 -0
  65. package/dist/__tests__/helpers/createLayoutManager.js.map +1 -0
  66. package/dist/__tests__/helpers/mountFlashList.d.ts +2 -2
  67. package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -1
  68. package/dist/__tests__/helpers/mountFlashList.js +2 -2
  69. package/dist/__tests__/helpers/mountFlashList.js.map +1 -1
  70. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +2 -2
  71. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +1 -1
  72. package/dist/__tests__/helpers/mountMasonryFlashList.js +2 -2
  73. package/dist/__tests__/helpers/mountMasonryFlashList.js.map +1 -1
  74. package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -1
  75. package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts +2 -0
  76. package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts.map +1 -0
  77. package/dist/__tests__/useUnmountAwareCallbacks.test.js +185 -0
  78. package/dist/__tests__/useUnmountAwareCallbacks.test.js.map +1 -0
  79. package/dist/benchmark/AutoScrollHelper.js +2 -2
  80. package/dist/benchmark/AutoScrollHelper.js.map +1 -1
  81. package/dist/benchmark/JSFPSMonitor.js.map +1 -1
  82. package/dist/benchmark/roundToDecimalPlaces.js +1 -2
  83. package/dist/benchmark/roundToDecimalPlaces.js.map +1 -1
  84. package/dist/benchmark/useBenchmark.js +2 -28
  85. package/dist/benchmark/useBenchmark.js.map +1 -1
  86. package/dist/benchmark/useBlankAreaTracker.js +1 -2
  87. package/dist/benchmark/useBlankAreaTracker.js.map +1 -1
  88. package/dist/benchmark/useDataMultiplier.js +1 -2
  89. package/dist/benchmark/useDataMultiplier.js.map +1 -1
  90. package/dist/benchmark/useFlatListBenchmark.d.ts +0 -1
  91. package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
  92. package/dist/benchmark/useFlatListBenchmark.js +9 -9
  93. package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
  94. package/dist/enableNewCore.d.ts.map +1 -1
  95. package/dist/enableNewCore.js +4 -4
  96. package/dist/enableNewCore.js.map +1 -1
  97. package/dist/errors/CustomError.js.map +1 -1
  98. package/dist/index.d.ts +4 -1
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +11 -3
  101. package/dist/index.js.map +1 -1
  102. package/dist/native/auto-layout/AutoLayoutView.d.ts +1 -1
  103. package/dist/native/auto-layout/AutoLayoutView.d.ts.map +1 -1
  104. package/dist/native/auto-layout/AutoLayoutView.js +1 -1
  105. package/dist/native/auto-layout/AutoLayoutView.js.map +1 -1
  106. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +1 -1
  107. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +1 -1
  108. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +1 -1
  109. package/dist/native/config/PlatformHelper.android.d.ts +2 -0
  110. package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
  111. package/dist/native/config/PlatformHelper.android.js +2 -0
  112. package/dist/native/config/PlatformHelper.android.js.map +1 -1
  113. package/dist/native/config/PlatformHelper.d.ts +2 -0
  114. package/dist/native/config/PlatformHelper.d.ts.map +1 -1
  115. package/dist/native/config/PlatformHelper.ios.d.ts +2 -0
  116. package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
  117. package/dist/native/config/PlatformHelper.ios.js +2 -0
  118. package/dist/native/config/PlatformHelper.ios.js.map +1 -1
  119. package/dist/native/config/PlatformHelper.js +2 -0
  120. package/dist/native/config/PlatformHelper.js.map +1 -1
  121. package/dist/native/config/PlatformHelper.web.d.ts +2 -0
  122. package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
  123. package/dist/native/config/PlatformHelper.web.js +3 -1
  124. package/dist/native/config/PlatformHelper.web.js.map +1 -1
  125. package/dist/recyclerview/LayoutCommitObserver.d.ts +12 -0
  126. package/dist/recyclerview/LayoutCommitObserver.d.ts.map +1 -0
  127. package/dist/recyclerview/LayoutCommitObserver.js +62 -0
  128. package/dist/recyclerview/LayoutCommitObserver.js.map +1 -0
  129. package/dist/recyclerview/RecyclerView.d.ts +3 -2
  130. package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
  131. package/dist/recyclerview/RecyclerView.js +133 -69
  132. package/dist/recyclerview/RecyclerView.js.map +1 -1
  133. package/dist/recyclerview/RecyclerViewContextProvider.d.ts +41 -7
  134. package/dist/recyclerview/RecyclerViewContextProvider.d.ts.map +1 -1
  135. package/dist/recyclerview/RecyclerViewContextProvider.js +6 -2
  136. package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -1
  137. package/dist/recyclerview/RecyclerViewManager.d.ts +31 -7
  138. package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
  139. package/dist/recyclerview/RecyclerViewManager.js +154 -117
  140. package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
  141. package/dist/recyclerview/RecyclerViewProps.d.ts +1 -1
  142. package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -1
  143. package/dist/recyclerview/RenderStackManager.d.ts +86 -0
  144. package/dist/recyclerview/RenderStackManager.d.ts.map +1 -0
  145. package/dist/recyclerview/RenderStackManager.js +343 -0
  146. package/dist/recyclerview/RenderStackManager.js.map +1 -0
  147. package/dist/recyclerview/ViewHolder.d.ts.map +1 -1
  148. package/dist/recyclerview/ViewHolder.js +8 -6
  149. package/dist/recyclerview/ViewHolder.js.map +1 -1
  150. package/dist/recyclerview/ViewHolderCollection.d.ts +10 -4
  151. package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
  152. package/dist/recyclerview/ViewHolderCollection.js +26 -10
  153. package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
  154. package/dist/recyclerview/components/ScrollAnchor.d.ts +2 -1
  155. package/dist/recyclerview/components/ScrollAnchor.d.ts.map +1 -1
  156. package/dist/recyclerview/components/ScrollAnchor.js +12 -9
  157. package/dist/recyclerview/components/ScrollAnchor.js.map +1 -1
  158. package/dist/recyclerview/components/StickyHeaders.d.ts +2 -2
  159. package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -1
  160. package/dist/recyclerview/components/StickyHeaders.js +44 -45
  161. package/dist/recyclerview/components/StickyHeaders.js.map +1 -1
  162. package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts +1 -1
  163. package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts.map +1 -1
  164. package/dist/recyclerview/helpers/ConsecutiveNumbers.js +2 -2
  165. package/dist/recyclerview/helpers/ConsecutiveNumbers.js.map +1 -1
  166. package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts +48 -2
  167. package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts.map +1 -1
  168. package/dist/recyclerview/helpers/EngagedIndicesTracker.js +89 -19
  169. package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -1
  170. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts +11 -0
  171. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts.map +1 -0
  172. package/dist/recyclerview/helpers/RenderTimeTracker.js +42 -0
  173. package/dist/recyclerview/helpers/RenderTimeTracker.js.map +1 -0
  174. package/dist/recyclerview/helpers/VelocityTracker.d.ts +29 -0
  175. package/dist/recyclerview/helpers/VelocityTracker.d.ts.map +1 -0
  176. package/dist/recyclerview/helpers/VelocityTracker.js +70 -0
  177. package/dist/recyclerview/helpers/VelocityTracker.js.map +1 -0
  178. package/dist/recyclerview/hooks/useBoundDetection.d.ts +1 -3
  179. package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -1
  180. package/dist/recyclerview/hooks/useBoundDetection.js +60 -28
  181. package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
  182. package/dist/recyclerview/hooks/useLayoutState.d.ts +3 -1
  183. package/dist/recyclerview/hooks/useLayoutState.d.ts.map +1 -1
  184. package/dist/recyclerview/hooks/useLayoutState.js +6 -5
  185. package/dist/recyclerview/hooks/useLayoutState.js.map +1 -1
  186. package/dist/recyclerview/hooks/useMappingHelper.d.ts +9 -0
  187. package/dist/recyclerview/hooks/useMappingHelper.d.ts.map +1 -0
  188. package/dist/recyclerview/hooks/useMappingHelper.js +19 -0
  189. package/dist/recyclerview/hooks/useMappingHelper.js.map +1 -0
  190. package/dist/recyclerview/hooks/useOnLoad.d.ts +2 -2
  191. package/dist/recyclerview/hooks/useOnLoad.d.ts.map +1 -1
  192. package/dist/recyclerview/hooks/useOnLoad.js +9 -10
  193. package/dist/recyclerview/hooks/useOnLoad.js.map +1 -1
  194. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts +5 -49
  195. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
  196. package/dist/recyclerview/hooks/useRecyclerViewController.js +343 -191
  197. package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
  198. package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts +2 -0
  199. package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts.map +1 -1
  200. package/dist/recyclerview/hooks/useRecyclerViewManager.js +11 -1
  201. package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -1
  202. package/dist/recyclerview/hooks/useRecyclingState.d.ts +4 -2
  203. package/dist/recyclerview/hooks/useRecyclingState.d.ts.map +1 -1
  204. package/dist/recyclerview/hooks/useRecyclingState.js +3 -4
  205. package/dist/recyclerview/hooks/useRecyclingState.js.map +1 -1
  206. package/dist/recyclerview/hooks/useSecondaryProps.d.ts +1 -1
  207. package/dist/recyclerview/hooks/useSecondaryProps.d.ts.map +1 -1
  208. package/dist/recyclerview/hooks/useSecondaryProps.js +15 -12
  209. package/dist/recyclerview/hooks/useSecondaryProps.js.map +1 -1
  210. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts +15 -0
  211. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts.map +1 -0
  212. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js +63 -0
  213. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js.map +1 -0
  214. package/dist/recyclerview/hooks/useUnmountFlag.d.ts +0 -1
  215. package/dist/recyclerview/hooks/useUnmountFlag.d.ts.map +1 -1
  216. package/dist/recyclerview/hooks/useUnmountFlag.js +1 -0
  217. package/dist/recyclerview/hooks/useUnmountFlag.js.map +1 -1
  218. package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts +18 -4
  219. package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts.map +1 -1
  220. package/dist/recyclerview/layout-managers/GridLayoutManager.js +61 -25
  221. package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -1
  222. package/dist/recyclerview/layout-managers/LayoutManager.d.ts +36 -21
  223. package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
  224. package/dist/recyclerview/layout-managers/LayoutManager.js +96 -28
  225. package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
  226. package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts +1 -2
  227. package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts.map +1 -1
  228. package/dist/recyclerview/layout-managers/LinearLayoutManager.js +3 -3
  229. package/dist/recyclerview/layout-managers/LinearLayoutManager.js.map +1 -1
  230. package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts +9 -1
  231. package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts.map +1 -1
  232. package/dist/recyclerview/layout-managers/MasonryLayoutManager.js +30 -16
  233. package/dist/recyclerview/layout-managers/MasonryLayoutManager.js.map +1 -1
  234. package/dist/recyclerview/utils/adjustOffsetForRTL.js +1 -2
  235. package/dist/recyclerview/utils/adjustOffsetForRTL.js.map +1 -1
  236. package/dist/recyclerview/utils/componentUtils.d.ts +1 -1
  237. package/dist/recyclerview/utils/componentUtils.d.ts.map +1 -1
  238. package/dist/recyclerview/utils/componentUtils.js.map +1 -1
  239. package/dist/recyclerview/utils/findVisibleIndex.d.ts.map +1 -1
  240. package/dist/recyclerview/utils/findVisibleIndex.js +3 -5
  241. package/dist/recyclerview/utils/findVisibleIndex.js.map +1 -1
  242. package/dist/recyclerview/utils/measureLayout.d.ts +24 -28
  243. package/dist/recyclerview/utils/measureLayout.d.ts.map +1 -1
  244. package/dist/recyclerview/utils/measureLayout.js +36 -6
  245. package/dist/recyclerview/utils/measureLayout.js.map +1 -1
  246. package/dist/recyclerview/utils/measureLayout.web.d.ts +29 -0
  247. package/dist/recyclerview/utils/measureLayout.web.d.ts.map +1 -0
  248. package/dist/recyclerview/utils/measureLayout.web.js +87 -0
  249. package/dist/recyclerview/utils/measureLayout.web.js.map +1 -0
  250. package/dist/specs/AutoLayoutNativeComponent.d.ts +1 -2
  251. package/dist/specs/AutoLayoutNativeComponent.d.ts.map +1 -1
  252. package/dist/specs/CellContainerNativeComponent.d.ts +0 -1
  253. package/dist/specs/CellContainerNativeComponent.d.ts.map +1 -1
  254. package/dist/tsconfig.tsbuildinfo +1 -1
  255. package/dist/utils/AverageWindow.js.map +1 -1
  256. package/dist/utils/ContentContainerUtils.d.ts.map +1 -1
  257. package/dist/utils/ContentContainerUtils.js.map +1 -1
  258. package/dist/viewability/ViewToken.d.ts +2 -2
  259. package/dist/viewability/ViewToken.d.ts.map +1 -1
  260. package/dist/viewability/ViewabilityHelper.js +1 -1
  261. package/dist/viewability/ViewabilityHelper.js.map +1 -1
  262. package/dist/viewability/ViewabilityManager.d.ts.map +1 -1
  263. package/dist/viewability/ViewabilityManager.js +11 -5
  264. package/dist/viewability/ViewabilityManager.js.map +1 -1
  265. package/jestSetup.js +30 -11
  266. package/package.json +4 -3
  267. package/src/AnimatedFlashList.ts +3 -2
  268. package/src/FlashList.tsx +25 -1
  269. package/src/FlashListProps.ts +42 -11
  270. package/src/FlashListRef.ts +320 -0
  271. package/src/MasonryFlashList.tsx +2 -2
  272. package/src/__tests__/ConsecutiveNumbers.test.ts +232 -0
  273. package/src/__tests__/GridLayoutManager.test.ts +113 -0
  274. package/src/__tests__/LayoutCommitObserver.test.tsx +60 -0
  275. package/src/__tests__/LinearLayoutManager.test.ts +227 -0
  276. package/src/__tests__/MasonryLayoutManager.test.ts +202 -0
  277. package/src/__tests__/RecyclerView.test.tsx +144 -0
  278. package/src/__tests__/RenderStackManager.test.ts +574 -0
  279. package/src/__tests__/findVisibleIndex.test.ts +369 -0
  280. package/src/__tests__/helpers/createLayoutManager.ts +141 -0
  281. package/src/__tests__/useUnmountAwareCallbacks.test.tsx +285 -0
  282. package/src/benchmark/useBenchmark.ts +0 -37
  283. package/src/benchmark/useFlatListBenchmark.ts +2 -2
  284. package/src/enableNewCore.ts +3 -1
  285. package/src/index.ts +14 -3
  286. package/src/native/config/PlatformHelper.android.ts +2 -0
  287. package/src/native/config/PlatformHelper.ios.ts +2 -0
  288. package/src/native/config/PlatformHelper.ts +2 -0
  289. package/src/native/config/PlatformHelper.web.ts +3 -1
  290. package/src/recyclerview/LayoutCommitObserver.tsx +74 -0
  291. package/src/recyclerview/RecyclerView.tsx +178 -89
  292. package/src/recyclerview/RecyclerViewContextProvider.ts +53 -7
  293. package/src/recyclerview/RecyclerViewManager.ts +176 -97
  294. package/src/recyclerview/RecyclerViewProps.ts +2 -1
  295. package/src/recyclerview/RenderStackManager.ts +317 -0
  296. package/src/recyclerview/ViewHolder.tsx +13 -6
  297. package/src/recyclerview/ViewHolderCollection.tsx +45 -16
  298. package/src/recyclerview/components/ScrollAnchor.tsx +24 -11
  299. package/src/recyclerview/components/StickyHeaders.tsx +70 -58
  300. package/src/recyclerview/helpers/ConsecutiveNumbers.ts +2 -2
  301. package/src/recyclerview/helpers/EngagedIndicesTracker.ts +135 -25
  302. package/src/recyclerview/helpers/RenderTimeTracker.ts +42 -0
  303. package/src/recyclerview/helpers/VelocityTracker.ts +77 -0
  304. package/src/recyclerview/hooks/useBoundDetection.ts +74 -25
  305. package/src/recyclerview/hooks/useLayoutState.ts +15 -6
  306. package/src/recyclerview/hooks/useMappingHelper.ts +20 -0
  307. package/src/recyclerview/hooks/useOnLoad.ts +11 -10
  308. package/src/recyclerview/hooks/useRecyclerViewController.tsx +380 -241
  309. package/src/recyclerview/hooks/useRecyclerViewManager.ts +13 -1
  310. package/src/recyclerview/hooks/useRecyclingState.ts +11 -7
  311. package/src/recyclerview/hooks/useSecondaryProps.tsx +12 -7
  312. package/src/recyclerview/hooks/useUnmountAwareCallbacks.ts +73 -0
  313. package/src/recyclerview/hooks/useUnmountFlag.ts +1 -0
  314. package/src/recyclerview/layout-managers/GridLayoutManager.ts +68 -27
  315. package/src/recyclerview/layout-managers/LayoutManager.ts +116 -42
  316. package/src/recyclerview/layout-managers/LinearLayoutManager.ts +12 -8
  317. package/src/recyclerview/layout-managers/MasonryLayoutManager.ts +34 -13
  318. package/src/recyclerview/utils/componentUtils.ts +1 -1
  319. package/src/recyclerview/utils/findVisibleIndex.ts +1 -2
  320. package/src/recyclerview/utils/measureLayout.ts +41 -2
  321. package/src/recyclerview/utils/measureLayout.web.ts +102 -0
  322. package/src/viewability/ViewToken.ts +2 -2
  323. package/src/viewability/ViewabilityHelper.ts +1 -1
  324. package/src/viewability/ViewabilityManager.ts +16 -9
  325. package/dist/recyclerview/RecycleKeyManager.d.ts +0 -82
  326. package/dist/recyclerview/RecycleKeyManager.d.ts.map +0 -1
  327. package/dist/recyclerview/RecycleKeyManager.js +0 -135
  328. package/dist/recyclerview/RecycleKeyManager.js.map +0 -1
  329. package/src/recyclerview/RecycleKeyManager.ts +0 -185
@@ -0,0 +1,202 @@
1
+ import { RVLayoutManager } from "../recyclerview/layout-managers/LayoutManager";
2
+ import { RVMasonryLayoutManagerImpl } from "../recyclerview/layout-managers/MasonryLayoutManager";
3
+
4
+ import {
5
+ getAllLayouts,
6
+ LayoutManagerType,
7
+ createLayoutParams,
8
+ createLayoutManager,
9
+ createMockLayoutInfo,
10
+ } from "./helpers/createLayoutManager";
11
+
12
+ describe("MasonryLayoutManager", () => {
13
+ const windowSize = { width: 400, height: 900 };
14
+ const defaultParams = {
15
+ windowSize,
16
+ maxColumns: 2,
17
+ optimizeItemArrangement: true,
18
+ };
19
+
20
+ // Helper to get column heights
21
+ const getColumnHeights = (manager: RVLayoutManager): number[] => {
22
+ return (manager as RVMasonryLayoutManagerImpl)["columnHeights"];
23
+ };
24
+
25
+ describe("Vertical Masonry Layout", () => {
26
+ it("should distribute items into columns based on height", () => {
27
+ const manager = createLayoutManager(
28
+ LayoutManagerType.MASONRY,
29
+ defaultParams
30
+ );
31
+ const layoutInfos = [
32
+ createMockLayoutInfo(0, 200, 100), // Col 0
33
+ createMockLayoutInfo(1, 200, 150), // Col 1
34
+ createMockLayoutInfo(2, 200, 120), // Col 0 (shorter)
35
+ createMockLayoutInfo(3, 200, 80), // Col 1 (shorter)
36
+ createMockLayoutInfo(4, 200, 200), // Col 0 (shorter)
37
+ ];
38
+ manager.modifyLayout(layoutInfos, 5);
39
+ const layouts = getAllLayouts(manager);
40
+
41
+ expect(layouts[0].x).toBe(0);
42
+ expect(layouts[0].y).toBe(0);
43
+
44
+ expect(layouts[1].x).toBe(200); // Second column
45
+ expect(layouts[1].y).toBe(0);
46
+
47
+ expect(layouts[2].x).toBe(0); // Back to first column
48
+ expect(layouts[2].y).toBe(100); // Below item 0
49
+
50
+ expect(layouts[3].x).toBe(200); // Still first column
51
+ expect(layouts[3].y).toBe(150); // Below item 2 (100 + 120)
52
+
53
+ expect(layouts[4].x).toBe(0); // Second column
54
+ expect(layouts[4].y).toBe(220); // Below item 1
55
+ });
56
+
57
+ it("should respect maxColumns configuration", () => {
58
+ const manager = createLayoutManager(LayoutManagerType.MASONRY, {
59
+ ...defaultParams,
60
+ maxColumns: 3,
61
+ });
62
+ const layoutInfos = [
63
+ createMockLayoutInfo(0, 133, 100), // Col 0
64
+ createMockLayoutInfo(1, 133, 150), // Col 1
65
+ createMockLayoutInfo(2, 133, 120), // Col 2
66
+ createMockLayoutInfo(3, 133, 80), // Col 0
67
+ ];
68
+ manager.modifyLayout(layoutInfos, 4);
69
+ const layouts = getAllLayouts(manager);
70
+ const colWidth = windowSize.width / 3;
71
+
72
+ expect(layouts[0].x).toBeCloseTo(0);
73
+ expect(layouts[1].x).toBeCloseTo(colWidth);
74
+ expect(layouts[2].x).toBeCloseTo(colWidth * 2);
75
+ expect(layouts[3].x).toBeCloseTo(0); // Placed in the shortest column (Col 0)
76
+ expect(layouts[3].y).toBeCloseTo(100); // Below item 0
77
+ });
78
+
79
+ it("should calculate total layout size correctly", () => {
80
+ const manager = createLayoutManager(
81
+ LayoutManagerType.MASONRY,
82
+ defaultParams
83
+ );
84
+ const layoutInfos = [
85
+ createMockLayoutInfo(0, 200, 100), // Col 0
86
+ createMockLayoutInfo(1, 200, 150), // Col 1
87
+ createMockLayoutInfo(2, 200, 120), // Col 0
88
+ ];
89
+ manager.modifyLayout(layoutInfos, 3);
90
+ const layoutSize = manager.getLayoutSize();
91
+
92
+ expect(layoutSize.width).toBe(400);
93
+ // Height is the tallest column height
94
+ const heights = getColumnHeights(manager);
95
+ expect(layoutSize.height).toBeCloseTo(Math.max(...heights)); // Max of [220, 150]
96
+ expect(layoutSize.height).toBeCloseTo(220);
97
+ });
98
+ });
99
+
100
+ describe("Layout Modifications", () => {
101
+ it("should update layout when items are added", () => {
102
+ const manager = createLayoutManager(
103
+ LayoutManagerType.MASONRY,
104
+ defaultParams
105
+ );
106
+ const initialInfos = [
107
+ createMockLayoutInfo(0, 200, 100), // Col 0 H=100
108
+ createMockLayoutInfo(1, 200, 150), // Col 1 H=150
109
+ ];
110
+ manager.modifyLayout(initialInfos, 2);
111
+ expect(getAllLayouts(manager).length).toBe(2);
112
+ expect(getColumnHeights(manager)).toEqual([100, 150]);
113
+
114
+ // Add item, should go to Col 0
115
+ const newLayoutInfos = [createMockLayoutInfo(2, 200, 120)];
116
+ manager.modifyLayout(newLayoutInfos, 3);
117
+
118
+ const layouts = getAllLayouts(manager);
119
+ expect(layouts.length).toBe(3);
120
+ expect(layouts[2].x).toBe(0); // Col 0
121
+ expect(layouts[2].y).toBe(100); // Below item 0
122
+ expect(getColumnHeights(manager)).toEqual([220, 150]); // 100+120, 150
123
+ });
124
+
125
+ it("should handle removing items (requires full recalculation)", () => {
126
+ const manager = createLayoutManager(
127
+ LayoutManagerType.MASONRY,
128
+ defaultParams
129
+ );
130
+ const initialInfos = [
131
+ createMockLayoutInfo(0, 200, 100), // Col 0 H=100
132
+ createMockLayoutInfo(1, 200, 150), // Col 1 H=150
133
+ createMockLayoutInfo(2, 200, 120), // Col 0 H=220
134
+ ];
135
+ manager.modifyLayout(initialInfos, 3);
136
+ expect(getColumnHeights(manager)).toEqual([220, 150]);
137
+
138
+ // Remove item 2 (from Col 0) - Masonry usually recalculates fully
139
+ // We simulate this by passing the remaining items
140
+ const remainingInfos = [
141
+ createMockLayoutInfo(0, 200, 100),
142
+ createMockLayoutInfo(1, 200, 150),
143
+ ];
144
+ manager.modifyLayout(remainingInfos, 2);
145
+
146
+ const layouts = getAllLayouts(manager);
147
+ expect(layouts.length).toBe(2);
148
+ expect(getColumnHeights(manager)).toEqual([100, 150]); // Back to original state
149
+ });
150
+
151
+ it("should recalculate layout when window size changes", () => {
152
+ const manager = createLayoutManager(
153
+ LayoutManagerType.MASONRY,
154
+ defaultParams
155
+ );
156
+ const initialInfos = [
157
+ createMockLayoutInfo(0, 200, 100), // Col 0
158
+ createMockLayoutInfo(1, 200, 150), // Col 1
159
+ createMockLayoutInfo(2, 200, 120), // Col 0
160
+ ];
161
+ manager.modifyLayout(initialInfos, 3);
162
+ const initialLayouts = getAllLayouts(manager);
163
+ expect(initialLayouts[1].x).toBe(200);
164
+
165
+ // Change window size and columns
166
+ manager.updateLayoutParams(
167
+ createLayoutParams({
168
+ ...defaultParams,
169
+ maxColumns: 3,
170
+ windowSize: { width: 600, height: 900 },
171
+ })
172
+ );
173
+ // modifyLayout needs to be called again as dimensions depend on width
174
+ const updatedInfos = [
175
+ createMockLayoutInfo(0, 200, 100), // New width = 600/3 = 200
176
+ createMockLayoutInfo(1, 200, 150),
177
+ createMockLayoutInfo(2, 200, 120),
178
+ ];
179
+ manager.modifyLayout(updatedInfos, 3);
180
+
181
+ const updatedLayouts = getAllLayouts(manager);
182
+ expect(updatedLayouts[0].width).toBe(200);
183
+ expect(updatedLayouts[1].x).toBe(200); // Col 1 starts at 200
184
+ expect(updatedLayouts[2].x).toBe(400); // Col 2 starts at 400
185
+ expect(getColumnHeights(manager)).toEqual([100, 150, 120]);
186
+ });
187
+ });
188
+
189
+ describe("Empty Layout", () => {
190
+ it("should return zero size for empty layout", () => {
191
+ const manager = createLayoutManager(
192
+ LayoutManagerType.MASONRY,
193
+ defaultParams
194
+ );
195
+ manager.modifyLayout([], 0);
196
+ const layoutSize = manager.getLayoutSize();
197
+ expect(layoutSize.width).toBe(0);
198
+ expect(layoutSize.height).toBe(0);
199
+ expect(getAllLayouts(manager).length).toBe(0);
200
+ });
201
+ });
202
+ });
@@ -0,0 +1,144 @@
1
+ import React, { createRef } from "react";
2
+ import { Text } from "react-native";
3
+ import "@quilted/react-testing/matchers";
4
+ import { render } from "@quilted/react-testing";
5
+
6
+ import { FlashListRef } from "../FlashListRef";
7
+ import { RecyclerView } from "../recyclerview/RecyclerView";
8
+
9
+ // Mock measureLayout to return fixed dimensions
10
+ jest.mock("../recyclerview/utils/measureLayout", () => {
11
+ const originalModule = jest.requireActual(
12
+ "../recyclerview/utils/measureLayout"
13
+ );
14
+ return {
15
+ ...originalModule,
16
+ measureParentSize: jest.fn().mockImplementation(() => ({
17
+ x: 0,
18
+ y: 0,
19
+ width: 399,
20
+ height: 899,
21
+ })),
22
+ measureFirstChildLayout: jest.fn().mockImplementation(() => ({
23
+ x: 0,
24
+ y: 0,
25
+ width: 399,
26
+ height: 899,
27
+ })),
28
+ measureItemLayout: jest.fn().mockImplementation(() => ({
29
+ x: 0,
30
+ y: 0,
31
+ width: 100,
32
+ height: 100,
33
+ })),
34
+ };
35
+ });
36
+
37
+ const renderRecyclerView = (args: {
38
+ numColumns?: number;
39
+ masonry?: boolean;
40
+ horizontal?: boolean;
41
+ ref?: React.Ref<FlashListRef<number>>;
42
+ data?: number[];
43
+ }) => {
44
+ const {
45
+ numColumns = 1,
46
+ masonry = false,
47
+ horizontal = false,
48
+ ref,
49
+ data,
50
+ } = args;
51
+ return render(
52
+ <RecyclerView
53
+ ref={ref}
54
+ data={
55
+ data ?? [
56
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
57
+ ]
58
+ }
59
+ masonry={masonry}
60
+ overrideProps={{ initialDrawBatchSize: 1 }}
61
+ drawDistance={0}
62
+ numColumns={numColumns}
63
+ horizontal={horizontal}
64
+ renderItem={({ item }) => <Text>{item}</Text>}
65
+ />
66
+ );
67
+ };
68
+
69
+ describe("RecyclerView", () => {
70
+ beforeEach(() => {
71
+ jest.clearAllMocks();
72
+ jest.useFakeTimers();
73
+ });
74
+ describe("Linear Layout", () => {
75
+ it("renders items ", () => {
76
+ const result = renderRecyclerView({});
77
+
78
+ expect(result).toContainReactComponent(Text, { children: 0 });
79
+ expect(result).not.toContainReactComponent(Text, { children: 11 });
80
+ });
81
+ });
82
+
83
+ describe("Masonry Layout", () => {
84
+ it("renders items with masonry", () => {
85
+ const result = renderRecyclerView({ masonry: true });
86
+
87
+ expect(result).toContainReactComponent(Text, { children: 0 });
88
+ });
89
+ it("should not render item 18, 19 with numColumns 2", () => {
90
+ const result = renderRecyclerView({ numColumns: 2, masonry: true });
91
+
92
+ expect(result).toContainReactComponent(Text, {
93
+ children: 17,
94
+ });
95
+ expect(result).not.toContainReactComponent(Text, {
96
+ children: 18,
97
+ });
98
+
99
+ expect(result).not.toContainReactComponent(Text, {
100
+ children: 19,
101
+ });
102
+ });
103
+ });
104
+
105
+ describe("Grid Layout", () => {
106
+ it("renders items with numColumns 2", () => {
107
+ const result = renderRecyclerView({ numColumns: 2 });
108
+
109
+ expect(result).toContainReactComponent(Text, { children: 0 });
110
+ });
111
+ it("should not render item 18, 19 with numColumns 2", () => {
112
+ const result = renderRecyclerView({ numColumns: 2 });
113
+
114
+ expect(result).toContainReactComponent(Text, {
115
+ children: 17,
116
+ });
117
+ expect(result).not.toContainReactComponent(Text, {
118
+ children: 18,
119
+ });
120
+
121
+ expect(result).not.toContainReactComponent(Text, {
122
+ children: 19,
123
+ });
124
+ });
125
+ });
126
+
127
+ describe("Horizontal Layout", () => {
128
+ it("renders items with horizontal", () => {
129
+ const result = renderRecyclerView({ horizontal: true });
130
+
131
+ expect(result).toContainReactComponent(Text, { children: 0 });
132
+ expect(result).not.toContainReactComponent(Text, { children: 4 });
133
+ });
134
+ });
135
+
136
+ describe("RecyclerView ref", () => {
137
+ it("check if ref has updated props after re-renders", () => {
138
+ const ref = createRef<FlashListRef<number>>();
139
+ const result = renderRecyclerView({ ref, data: [0, 1, 2] });
140
+ result.setProps({ data: [0, 1, 2, 3] });
141
+ expect(ref.current?.props.data).toEqual([0, 1, 2, 3]);
142
+ });
143
+ });
144
+ });