@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
@@ -1,89 +1,100 @@
1
+ import ViewabilityManager from "../viewability/ViewabilityManager";
2
+
1
3
  import { ConsecutiveNumbers } from "./helpers/ConsecutiveNumbers";
2
4
  import { RVGridLayoutManagerImpl } from "./layout-managers/GridLayoutManager";
3
5
  import {
6
+ LayoutParams,
4
7
  RVDimension,
5
8
  RVLayoutInfo,
6
9
  RVLayoutManager,
10
+ SpanSizeInfo,
7
11
  } from "./layout-managers/LayoutManager";
8
12
  import { RVLinearLayoutManagerImpl } from "./layout-managers/LinearLayoutManager";
9
13
  import { RVMasonryLayoutManagerImpl } from "./layout-managers/MasonryLayoutManager";
10
- import { RecycleKeyManagerImpl, RecycleKeyManager } from "./RecycleKeyManager";
11
14
  import { RecyclerViewProps } from "./RecyclerViewProps";
12
15
  import {
13
16
  RVEngagedIndicesTracker,
14
17
  RVEngagedIndicesTrackerImpl,
15
18
  Velocity,
16
19
  } from "./helpers/EngagedIndicesTracker";
17
- import ViewabilityManager from "../viewability/ViewabilityManager";
18
-
19
- // Abstracts layout manager, key manager and viewability manager and generates render stack (progressively on load)
20
+ import { RenderStackManager } from "./RenderStackManager";
21
+ // Abstracts layout manager, render stack manager and viewability manager and generates render stack (progressively on load)
20
22
  export class RecyclerViewManager<T> {
21
- private initialDrawBatchSize = 1;
23
+ private initialDrawBatchSize = 2;
22
24
  private engagedIndicesTracker: RVEngagedIndicesTracker;
23
- private recycleKeyManager: RecycleKeyManager;
25
+ private renderStackManager: RenderStackManager;
24
26
  private layoutManager?: RVLayoutManager;
25
27
  // Map of index to key
26
- private renderStack: Map<number, string> = new Map();
27
28
  private isFirstLayoutComplete = false;
28
29
  private hasRenderedProgressively = false;
29
- private props: RecyclerViewProps<T>;
30
+ private progressiveRenderCount = 0;
31
+ private propsRef: RecyclerViewProps<T>;
30
32
  private itemViewabilityManager: ViewabilityManager<T>;
33
+ private _isDisposed = false;
34
+ private _isLayoutManagerDirty = false;
35
+ private _animationOptimizationsEnabled = false;
31
36
 
32
- public disableRecycling = false;
33
37
  public firstItemOffset = 0;
38
+ public ignoreScrollEvents = false;
39
+
40
+ public get animationOptimizationsEnabled() {
41
+ return this._animationOptimizationsEnabled;
42
+ }
43
+
44
+ public set animationOptimizationsEnabled(value: boolean) {
45
+ this._animationOptimizationsEnabled = value;
46
+ this.renderStackManager.disableRecycling = value;
47
+ }
48
+
49
+ public get isOffsetProjectionEnabled() {
50
+ return this.engagedIndicesTracker.enableOffsetProjection;
51
+ }
52
+
53
+ public get isDisposed() {
54
+ return this._isDisposed;
55
+ }
56
+
57
+ public get numColumns() {
58
+ return this.propsRef.numColumns ?? 1;
59
+ }
34
60
 
35
61
  constructor(props: RecyclerViewProps<T>) {
36
- this.props = props;
62
+ this.getDataKey = this.getDataKey.bind(this);
63
+ this.getItemType = this.getItemType.bind(this);
64
+ this.overrideItemLayout = this.overrideItemLayout.bind(this);
65
+ this.propsRef = props;
37
66
  this.engagedIndicesTracker = new RVEngagedIndicesTrackerImpl();
38
- this.recycleKeyManager = new RecycleKeyManagerImpl();
67
+ this.renderStackManager = new RenderStackManager(
68
+ props.maxItemsInRecyclePool
69
+ );
39
70
  this.itemViewabilityManager = new ViewabilityManager<T>(this as any);
40
71
  }
41
72
 
42
73
  // updates render stack based on the engaged indices which are sorted. Recycles unused keys.
43
- // TODO: Call getKey anyway if stableIds are present
44
74
  private updateRenderStack = (engagedIndices: ConsecutiveNumbers): void => {
45
- //console.log("updateRenderStack", engagedIndices);
46
- const newRenderStack = new Map<number, string>();
47
- for (const [index, key] of this.renderStack) {
48
- if (!engagedIndices.includes(index)) {
49
- this.recycleKeyManager.recycleKey(key);
50
- }
51
- }
52
- if (this.disableRecycling) {
53
- this.recycleKeyManager.clearPool();
54
- }
55
- for (const index of engagedIndices) {
56
- const newKey = this.recycleKeyManager.getKey(
57
- this.getItemType(index),
58
- this.getStableId(index),
59
- this.renderStack.get(index)
60
- );
61
- newRenderStack.set(index, newKey);
62
- }
75
+ this.renderStackManager.sync(
76
+ this.getDataKey,
77
+ this.getItemType,
78
+ engagedIndices,
79
+ this.getDataLength()
80
+ );
81
+ };
63
82
 
64
- // DANGER
65
- for (const [index, key] of this.renderStack) {
66
- if (
67
- this.recycleKeyManager.hasKeyInPool(key) &&
68
- !newRenderStack.has(index) &&
69
- index < (this.props.data?.length ?? 0)
70
- ) {
71
- newRenderStack.set(index, key);
72
- }
73
- }
83
+ get props() {
84
+ return this.propsRef;
85
+ }
74
86
 
75
- this.renderStack = newRenderStack;
76
- };
87
+ setOffsetProjectionEnabled(value: boolean) {
88
+ this.engagedIndicesTracker.enableOffsetProjection = value;
89
+ }
77
90
 
78
91
  updateProps(props: RecyclerViewProps<T>) {
79
- this.props = props;
92
+ this.propsRef = props;
80
93
  this.engagedIndicesTracker.drawDistance =
81
94
  props.drawDistance ?? this.engagedIndicesTracker.drawDistance;
82
- if (this.props.drawDistance === 0) {
83
- this.initialDrawBatchSize = 1;
84
- } else {
85
- this.initialDrawBatchSize = (props.numColumns ?? 1) * 2;
86
- }
95
+ this.initialDrawBatchSize =
96
+ this.propsRef.overrideProps?.initialDrawBatchSize ??
97
+ this.initialDrawBatchSize;
87
98
  }
88
99
 
89
100
  /**
@@ -95,7 +106,7 @@ export class RecyclerViewManager<T> {
95
106
  offset: number,
96
107
  velocity?: Velocity
97
108
  ): ConsecutiveNumbers | undefined {
98
- if (this.layoutManager) {
109
+ if (this.layoutManager && !this._isDisposed) {
99
110
  const engagedIndices = this.engagedIndicesTracker.updateScrollOffset(
100
111
  offset - this.firstItemOffset,
101
112
  velocity,
@@ -110,6 +121,10 @@ export class RecyclerViewManager<T> {
110
121
  return undefined;
111
122
  }
112
123
 
124
+ updateAverageRenderTime(time: number) {
125
+ this.engagedIndicesTracker.averageRenderTime = time;
126
+ }
127
+
113
128
  getIsFirstLayoutComplete() {
114
129
  return this.isFirstLayoutComplete;
115
130
  }
@@ -123,6 +138,17 @@ export class RecyclerViewManager<T> {
123
138
  return this.layoutManager.getLayout(index);
124
139
  }
125
140
 
141
+ tryGetLayout(index: number) {
142
+ if (
143
+ this.layoutManager &&
144
+ index >= 0 &&
145
+ index < this.layoutManager.getLayoutCount()
146
+ ) {
147
+ return this.layoutManager.getLayout(index);
148
+ }
149
+ return undefined;
150
+ }
151
+
126
152
  // Doesn't include header / foot etc
127
153
  getChildContainerDimensions() {
128
154
  if (!this.layoutManager) {
@@ -134,7 +160,7 @@ export class RecyclerViewManager<T> {
134
160
  }
135
161
 
136
162
  getRenderStack() {
137
- return this.renderStack;
163
+ return this.renderStackManager.getRenderStack();
138
164
  }
139
165
 
140
166
  getWindowSize() {
@@ -151,51 +177,65 @@ export class RecyclerViewManager<T> {
151
177
  return this.engagedIndicesTracker.scrollOffset;
152
178
  }
153
179
 
180
+ getMaxScrollOffset() {
181
+ return Math.max(
182
+ 0,
183
+ (this.propsRef.horizontal
184
+ ? this.getChildContainerDimensions().width
185
+ : this.getChildContainerDimensions().height) -
186
+ (this.propsRef.horizontal
187
+ ? this.getWindowSize().width
188
+ : this.getWindowSize().height) +
189
+ this.firstItemOffset
190
+ );
191
+ }
192
+
154
193
  // Doesn't include first item offset correction
155
194
  getAbsoluteLastScrollOffset() {
156
195
  return this.engagedIndicesTracker.scrollOffset + this.firstItemOffset;
157
196
  }
158
197
 
198
+ setScrollDirection(scrollDirection: "forward" | "backward") {
199
+ this.engagedIndicesTracker.setScrollDirection(scrollDirection);
200
+ }
201
+
202
+ resetVelocityCompute() {
203
+ this.engagedIndicesTracker.resetVelocityHistory();
204
+ }
205
+
159
206
  updateLayoutParams(windowSize: RVDimension, firstItemOffset: number) {
160
207
  this.firstItemOffset = firstItemOffset;
161
208
  const LayoutManagerClass = this.getLayoutManagerClass();
162
209
  if (
163
210
  this.layoutManager &&
164
211
  Boolean(this.layoutManager?.isHorizontal()) !==
165
- Boolean(this.props.horizontal)
212
+ Boolean(this.propsRef.horizontal)
166
213
  ) {
167
214
  throw new Error(
168
215
  "Horizontal prop cannot be toggled, you can use a key on FlashList to recreate it."
169
216
  );
170
217
  }
218
+ if (this._isLayoutManagerDirty) {
219
+ this.layoutManager = undefined;
220
+ this._isLayoutManagerDirty = false;
221
+ }
222
+ const layoutManagerParams: LayoutParams = {
223
+ windowSize,
224
+ maxColumns: this.numColumns,
225
+ horizontal: Boolean(this.propsRef.horizontal),
226
+ optimizeItemArrangement: this.propsRef.optimizeItemArrangement ?? true,
227
+ overrideItemLayout: this.overrideItemLayout,
228
+ getItemType: this.getItemType,
229
+ };
171
230
  if (!(this.layoutManager instanceof LayoutManagerClass)) {
172
- //console.log("-----> new LayoutManagerClass");
231
+ // console.log("-----> new LayoutManagerClass");
173
232
 
174
233
  this.layoutManager = new LayoutManagerClass(
175
- {
176
- windowSize,
177
- maxColumns: this.props.numColumns ?? 1,
178
- horizontal: !!this.props.horizontal,
179
- optimizeItemArrangement: this.props.optimizeItemArrangement ?? true,
180
- overrideItemLayout: (index, layout) => {
181
- this.props?.overrideItemLayout?.(
182
- layout,
183
- this.props.data![index],
184
- index,
185
- this.props.numColumns ?? 1,
186
- this.props.extraData
187
- );
188
- },
189
- },
234
+ layoutManagerParams,
190
235
  this.layoutManager
191
236
  );
192
237
  } else {
193
- this.layoutManager.updateLayoutParams({
194
- windowSize,
195
- maxColumns: this.props.numColumns ?? 1,
196
- horizontal: !!this.props.horizontal,
197
- optimizeItemArrangement: this.props.optimizeItemArrangement ?? true,
198
- });
238
+ this.layoutManager.updateLayoutParams(layoutManagerParams);
199
239
  }
200
240
  }
201
241
 
@@ -203,7 +243,7 @@ export class RecyclerViewManager<T> {
203
243
  return this.layoutManager !== undefined;
204
244
  }
205
245
 
206
- getVisibleIndices() {
246
+ computeVisibleIndices() {
207
247
  if (!this.layoutManager) {
208
248
  throw new Error(
209
249
  "LayoutManager is not initialized, visible indices are not unavailable"
@@ -230,7 +270,7 @@ export class RecyclerViewManager<T> {
230
270
  return true;
231
271
  }
232
272
  if (this.hasRenderedProgressively) {
233
- return this.recomputeEngagedIndices() !== undefined; //TODO: Move to an effect as this can block paint for more than necessary
273
+ return this.recomputeEngagedIndices() !== undefined;
234
274
  } else {
235
275
  this.renderProgressively();
236
276
  }
@@ -241,9 +281,9 @@ export class RecyclerViewManager<T> {
241
281
  // Using higher buffer for masonry to avoid missing items
242
282
  this.itemViewabilityManager.shouldListenToVisibleIndices &&
243
283
  this.itemViewabilityManager.updateViewableItems(
244
- this.props.masonry
284
+ this.propsRef.masonry
245
285
  ? this.engagedIndicesTracker.getEngagedIndices().toArray()
246
- : this.getVisibleIndices().toArray()
286
+ : this.computeVisibleIndices().toArray()
247
287
  );
248
288
  }
249
289
 
@@ -257,8 +297,8 @@ export class RecyclerViewManager<T> {
257
297
 
258
298
  processDataUpdate() {
259
299
  if (this.hasLayout()) {
260
- this.modifyChildrenLayout([], this.props.data?.length ?? 0);
261
- if (!this.recomputeEngagedIndices()) {
300
+ this.modifyChildrenLayout([], this.propsRef.data?.length ?? 0);
301
+ if (this.hasRenderedProgressively && !this.recomputeEngagedIndices()) {
262
302
  // recomputeEngagedIndices will update the render stack if there are any changes in the engaged indices.
263
303
  // It's important to update render stack so that elements are assgined right keys incase items were deleted.
264
304
  this.updateRenderStack(this.engagedIndicesTracker.getEngagedIndices());
@@ -270,34 +310,64 @@ export class RecyclerViewManager<T> {
270
310
  return this.updateScrollOffset(this.getAbsoluteLastScrollOffset());
271
311
  }
272
312
 
313
+ restoreIfNeeded() {
314
+ if (this._isDisposed) {
315
+ this._isDisposed = false;
316
+ }
317
+ }
318
+
273
319
  dispose() {
320
+ this._isDisposed = true;
274
321
  this.itemViewabilityManager.dispose();
275
322
  }
276
323
 
324
+ markLayoutManagerDirty() {
325
+ this._isLayoutManagerDirty = true;
326
+ }
327
+
277
328
  getInitialScrollIndex() {
278
329
  return (
279
- this.props.initialScrollIndex ??
280
- (this.props.maintainVisibleContentPosition?.startRenderingFromBottom
330
+ this.propsRef.initialScrollIndex ??
331
+ (this.propsRef.maintainVisibleContentPosition?.startRenderingFromBottom
281
332
  ? this.getDataLength() - 1
282
333
  : undefined)
283
334
  );
284
335
  }
285
336
 
337
+ shouldMaintainVisibleContentPosition() {
338
+ // Return true if maintainVisibleContentPosition is enabled and not horizontal
339
+ return (
340
+ !this.propsRef.maintainVisibleContentPosition?.disabled &&
341
+ !this.propsRef.horizontal
342
+ );
343
+ }
344
+
286
345
  getDataLength() {
287
- return this.props.data?.length ?? 0;
346
+ return this.propsRef.data?.length ?? 0;
347
+ }
348
+
349
+ hasStableDataKeys() {
350
+ return Boolean(this.propsRef.keyExtractor);
351
+ }
352
+
353
+ getDataKey(index: number): string {
354
+ return (
355
+ this.propsRef.keyExtractor?.(this.propsRef.data![index], index) ??
356
+ index.toString()
357
+ );
288
358
  }
289
359
 
290
360
  private getLayoutManagerClass() {
291
361
  // throw errors for incompatible props
292
- if (this.props.masonry && this.props.horizontal) {
362
+ if (this.propsRef.masonry && this.propsRef.horizontal) {
293
363
  throw new Error("Masonry and horizontal props are incompatible");
294
364
  }
295
- if ((this.props.numColumns ?? 1) > 1 && this.props.horizontal) {
365
+ if (this.numColumns > 1 && this.propsRef.horizontal) {
296
366
  throw new Error("numColumns and horizontal props are incompatible");
297
367
  }
298
- return this.props.masonry
368
+ return this.propsRef.masonry
299
369
  ? RVMasonryLayoutManagerImpl
300
- : (this.props.numColumns ?? 1) > 1 && !this.props.horizontal
370
+ : this.numColumns > 1 && !this.propsRef.horizontal
301
371
  ? RVGridLayoutManagerImpl
302
372
  : RVLinearLayoutManagerImpl;
303
373
  }
@@ -311,7 +381,7 @@ export class RecyclerViewManager<T> {
311
381
  const initialItemLayout = this.layoutManager?.getLayout(
312
382
  initialScrollIndex ?? 0
313
383
  );
314
- const initialItemOffset = this.props.horizontal
384
+ const initialItemOffset = this.propsRef.horizontal
315
385
  ? initialItemLayout?.x
316
386
  : initialItemLayout?.y;
317
387
 
@@ -326,18 +396,19 @@ export class RecyclerViewManager<T> {
326
396
  this.engagedIndicesTracker.scrollOffset =
327
397
  initialItemOffset ?? 0 + this.firstItemOffset;
328
398
  } else {
329
- //console.log("initialItemOffset", initialItemOffset, this.firstItemOffset);
399
+ // console.log("initialItemOffset", initialItemOffset, this.firstItemOffset);
330
400
  this.engagedIndicesTracker.scrollOffset =
331
401
  (initialItemOffset ?? 0) - this.firstItemOffset;
332
402
  }
333
403
  }
334
404
 
335
405
  private renderProgressively() {
406
+ this.progressiveRenderCount++;
336
407
  const layoutManager = this.layoutManager;
337
408
  if (layoutManager) {
338
409
  this.applyInitialScrollAdjustment();
339
- const visibleIndices = this.getVisibleIndices();
340
- //console.log("---------> visibleIndices", visibleIndices);
410
+ const visibleIndices = this.computeVisibleIndices();
411
+ // console.log("---------> visibleIndices", visibleIndices);
341
412
  this.hasRenderedProgressively = visibleIndices.every(
342
413
  (index) =>
343
414
  layoutManager.getLayout(index).isHeightMeasured &&
@@ -348,16 +419,20 @@ export class RecyclerViewManager<T> {
348
419
  this.isFirstLayoutComplete = true;
349
420
  }
350
421
 
422
+ const batchSize =
423
+ this.numColumns *
424
+ this.initialDrawBatchSize ** Math.ceil(this.progressiveRenderCount / 5);
425
+
351
426
  // If everything is measured then render stack will be in sync. The buffer items will get rendered in the next update
352
427
  // triggered by the useOnLoad hook.
353
428
  !this.hasRenderedProgressively &&
354
429
  this.updateRenderStack(
355
- // pick first n indices from visible ones and n is size of renderStack
430
+ // pick first n indices from visible ones based on batch size
356
431
  visibleIndices.slice(
357
432
  0,
358
433
  Math.min(
359
434
  visibleIndices.length,
360
- this.renderStack.size + this.initialDrawBatchSize
435
+ this.getRenderStack().size + batchSize
361
436
  )
362
437
  )
363
438
  );
@@ -366,14 +441,18 @@ export class RecyclerViewManager<T> {
366
441
 
367
442
  private getItemType(index: number): string {
368
443
  return (
369
- this.props.getItemType?.(this.props.data![index], index) ?? "default"
444
+ this.propsRef.getItemType?.(this.propsRef.data![index], index) ??
445
+ "default"
370
446
  ).toString();
371
447
  }
372
448
 
373
- private getStableId(index: number): string {
374
- return (
375
- this.props.keyExtractor?.(this.props.data![index], index) ??
376
- index.toString()
449
+ private overrideItemLayout(index: number, layout: SpanSizeInfo) {
450
+ this.propsRef?.overrideItemLayout?.(
451
+ layout,
452
+ this.propsRef.data![index],
453
+ index,
454
+ this.numColumns,
455
+ this.propsRef.extraData
377
456
  );
378
457
  }
379
458
  }
@@ -1,6 +1,7 @@
1
- import { FlashListProps } from "../FlashListProps";
2
1
  import { ScrollViewProps } from "react-native";
3
2
 
3
+ import { FlashListProps } from "../FlashListProps";
4
+
4
5
  export interface RecyclerViewProps<TItem>
5
6
  extends Omit<FlashListProps<TItem>, "contentContainerStyle"> {
6
7
  /**