@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
@@ -22,17 +22,21 @@ export default class ViewabilityManager<T> {
22
22
  this.viewabilityHelpers.push(
23
23
  this.createViewabilityHelper(
24
24
  flashListRef.props.viewabilityConfig,
25
- flashListRef.props.onViewableItemsChanged
25
+ (info) => {
26
+ flashListRef.props.onViewableItemsChanged?.(info);
27
+ }
26
28
  )
27
29
  );
28
30
  }
29
31
  (flashListRef.props.viewabilityConfigCallbackPairs ?? []).forEach(
30
- (pair) => {
32
+ (pair, index) => {
31
33
  this.viewabilityHelpers.push(
32
- this.createViewabilityHelper(
33
- pair.viewabilityConfig,
34
- pair.onViewableItemsChanged
35
- )
34
+ this.createViewabilityHelper(pair.viewabilityConfig, (info) => {
35
+ const callback =
36
+ flashListRef.props.viewabilityConfigCallbackPairs?.[index]
37
+ ?.onViewableItemsChanged;
38
+ callback?.(info);
39
+ })
36
40
  );
37
41
  }
38
42
  );
@@ -102,15 +106,18 @@ export default class ViewabilityManager<T> {
102
106
  private createViewabilityHelper = (
103
107
  viewabilityConfig: ViewabilityConfig | null | undefined,
104
108
  onViewableItemsChanged:
105
- | ((info: { viewableItems: ViewToken[]; changed: ViewToken[] }) => void)
109
+ | ((info: {
110
+ viewableItems: ViewToken<T>[];
111
+ changed: ViewToken<T>[];
112
+ }) => void)
106
113
  | null
107
114
  | undefined
108
115
  ) => {
109
- const mapViewToken: (index: number, isViewable: boolean) => ViewToken = (
116
+ const mapViewToken: (index: number, isViewable: boolean) => ViewToken<T> = (
110
117
  index: number,
111
118
  isViewable: boolean
112
119
  ) => {
113
- const item = this.flashListRef.props.data?.[index];
120
+ const item = this.flashListRef.props.data![index];
114
121
  const key =
115
122
  item === undefined || this.flashListRef.props.keyExtractor === undefined
116
123
  ? index.toString()
@@ -1,82 +0,0 @@
1
- export interface RecycleKeyManager {
2
- /**
3
- * Retrieves a unique key for an item type, maintaining a separate pool for each type.
4
- * If a stableId is provided and exists, returns the associated key.
5
- * Otherwise, generates a new key or reuses one from the pool.
6
- * @param itemType - The type/category of the item (e.g., 'header', 'product', 'footer')
7
- * @param stableId - Optional unique identifier for stable item tracking
8
- * @param currentKey - Optional current key to maintain if it exists in the pool
9
- * @returns A unique key for the item
10
- */
11
- getKey: (itemType: string, stableId: string, currentKey?: string) => string;
12
- /**
13
- * Recycles a key back into its item type's pool when the associated view is no longer visible.
14
- * This allows the key to be reused for new items of the same type.
15
- * @param key - The key to be recycled back into the pool
16
- */
17
- recycleKey: (key: string) => void;
18
- /**
19
- * Checks if a key is currently available in the recycling pool (not in use).
20
- * @param key - The key to check
21
- * @returns True if the key is available in the pool, false otherwise
22
- */
23
- hasKeyInPool: (key: string) => boolean;
24
- /**
25
- * Clears all recycled keys from the pool, resetting the recycling system.
26
- * This is useful when the list needs to be completely reset.
27
- */
28
- clearPool: () => void;
29
- }
30
- export declare class RecycleKeyManagerImpl implements RecycleKeyManager {
31
- private maxItems;
32
- private keyPools;
33
- private keyMap;
34
- private stableIdMap;
35
- private keyCounter;
36
- /**
37
- * Creates a new RecycleKeyManager with a specified maximum number of items.
38
- * @param maxItems - Maximum number of unique keys that can be active simultaneously.
39
- * Defaults to Number.MAX_SAFE_INTEGER if not specified.
40
- */
41
- constructor(maxItems?: number);
42
- /**
43
- * Gets a key for the specified item type, prioritizing stable ID associations.
44
- * If a stable ID exists, returns its associated key. Otherwise, either reuses
45
- * a key from the pool or generates a new one.
46
- * @param itemType - The type/category of the item
47
- * @param stableId - Optional unique identifier for stable item tracking
48
- * @param currentKey - Optional current key to maintain if it exists in the pool
49
- * @returns A unique key for the item
50
- */
51
- getKey(itemType: string, stableId: string, currentKey?: string): string;
52
- /**
53
- * Recycles a key by adding it back to its item type's pool and cleaning up
54
- * associated mappings. This should be called when a view is no longer visible.
55
- * @param key - The key to be recycled
56
- */
57
- recycleKey(key: string): void;
58
- /**
59
- * Checks if a key is currently available in the recycling pool.
60
- * @param key - The key to check
61
- * @returns True if the key is available in the pool, false otherwise
62
- */
63
- hasKeyInPool(key: string): boolean;
64
- /**
65
- * Clears all recycled keys from the pool, effectively resetting the recycling system.
66
- * This operation does not affect currently active keys.
67
- */
68
- clearPool(): void;
69
- /**
70
- * Generates a unique sequential key using an internal counter.
71
- * @returns A unique key as a string
72
- */
73
- private generateKey;
74
- /**
75
- * Ensures the total number of active keys doesn't exceed the maximum limit.
76
- * If the limit is exceeded, recycles the oldest keys until within bounds.
77
- * Note: This operation may impact performance when dealing with large lists.
78
- * TODO: Check performance impact of this
79
- */
80
- private ensurePoolSize;
81
- }
82
- //# sourceMappingURL=RecycleKeyManager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RecycleKeyManager.d.ts","sourceRoot":"","sources":["../../src/recyclerview/RecycleKeyManager.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;OAQG;IACH,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAE5E;;;;OAIG;IACH,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;;;OAIG;IACH,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAEvC;;;OAGG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,qBAAa,qBAAsB,YAAW,iBAAiB;IAE7D,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,QAAQ,CAA2B;IAG3C,OAAO,CAAC,MAAM,CAAuD;IAGrE,OAAO,CAAC,WAAW,CAAsB;IAGzC,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;OAIG;gBACS,QAAQ,GAAE,MAAgC;IAQtD;;;;;;;;OAQG;IACI,MAAM,CACX,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM;IAsCT;;;;OAIG;IACI,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAwBpC;;;;OAIG;IACI,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzC;;;OAGG;IACI,SAAS;IAIhB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;CAWvB"}
@@ -1,135 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RecycleKeyManagerImpl = void 0;
4
- var tslib_1 = require("tslib");
5
- var RecycleKeyManagerImpl = /** @class */ (function () {
6
- /**
7
- * Creates a new RecycleKeyManager with a specified maximum number of items.
8
- * @param maxItems - Maximum number of unique keys that can be active simultaneously.
9
- * Defaults to Number.MAX_SAFE_INTEGER if not specified.
10
- */
11
- function RecycleKeyManagerImpl(maxItems) {
12
- if (maxItems === void 0) { maxItems = Number.MAX_SAFE_INTEGER; }
13
- this.maxItems = maxItems;
14
- this.keyPools = new Map();
15
- this.keyMap = new Map();
16
- this.stableIdMap = new Map();
17
- this.keyCounter = 0;
18
- }
19
- /**
20
- * Gets a key for the specified item type, prioritizing stable ID associations.
21
- * If a stable ID exists, returns its associated key. Otherwise, either reuses
22
- * a key from the pool or generates a new one.
23
- * @param itemType - The type/category of the item
24
- * @param stableId - Optional unique identifier for stable item tracking
25
- * @param currentKey - Optional current key to maintain if it exists in the pool
26
- * @returns A unique key for the item
27
- */
28
- RecycleKeyManagerImpl.prototype.getKey = function (itemType, stableId, currentKey) {
29
- // Return existing key if stableId is already mapped
30
- if (stableId && this.stableIdMap.has(stableId)) {
31
- return this.stableIdMap.get(stableId);
32
- }
33
- // Get or create the pool for this item type
34
- var pool = this.keyPools.get(itemType);
35
- if (!pool) {
36
- pool = new Set();
37
- this.keyPools.set(itemType, pool);
38
- }
39
- var key;
40
- // Reuse existing key from pool if available
41
- if (pool.size > 0) {
42
- key =
43
- currentKey && pool.has(currentKey)
44
- ? currentKey
45
- : pool.values().next().value;
46
- pool.delete(key);
47
- }
48
- else {
49
- // Generate new key if pool is empty
50
- key = this.generateKey();
51
- }
52
- // Update mappings with new key information
53
- this.keyMap.set(key, { itemType: itemType, stableId: stableId });
54
- if (stableId) {
55
- this.stableIdMap.set(stableId, key);
56
- }
57
- // Ensure we don't exceed the maximum number of active keys
58
- this.ensurePoolSize();
59
- return key;
60
- };
61
- /**
62
- * Recycles a key by adding it back to its item type's pool and cleaning up
63
- * associated mappings. This should be called when a view is no longer visible.
64
- * @param key - The key to be recycled
65
- */
66
- RecycleKeyManagerImpl.prototype.recycleKey = function (key) {
67
- var keyInfo = this.keyMap.get(key);
68
- if (!keyInfo) {
69
- return;
70
- }
71
- var itemType = keyInfo.itemType, stableId = keyInfo.stableId;
72
- // Clean up stable ID mapping if it exists
73
- if (stableId) {
74
- this.stableIdMap.delete(stableId);
75
- }
76
- // Add key back to its type's pool
77
- var pool = this.keyPools.get(itemType);
78
- if (!pool) {
79
- pool = new Set();
80
- this.keyPools.set(itemType, pool);
81
- }
82
- pool.add(key);
83
- this.keyMap.delete(key);
84
- };
85
- /**
86
- * Checks if a key is currently available in the recycling pool.
87
- * @param key - The key to check
88
- * @returns True if the key is available in the pool, false otherwise
89
- */
90
- RecycleKeyManagerImpl.prototype.hasKeyInPool = function (key) {
91
- return !this.keyMap.has(key);
92
- };
93
- /**
94
- * Clears all recycled keys from the pool, effectively resetting the recycling system.
95
- * This operation does not affect currently active keys.
96
- */
97
- RecycleKeyManagerImpl.prototype.clearPool = function () {
98
- this.keyPools.clear();
99
- };
100
- /**
101
- * Generates a unique sequential key using an internal counter.
102
- * @returns A unique key as a string
103
- */
104
- RecycleKeyManagerImpl.prototype.generateKey = function () {
105
- return (this.keyCounter++).toString();
106
- };
107
- /**
108
- * Ensures the total number of active keys doesn't exceed the maximum limit.
109
- * If the limit is exceeded, recycles the oldest keys until within bounds.
110
- * Note: This operation may impact performance when dealing with large lists.
111
- * TODO: Check performance impact of this
112
- */
113
- RecycleKeyManagerImpl.prototype.ensurePoolSize = function () {
114
- var e_1, _a;
115
- if (this.keyMap.size <= this.maxItems)
116
- return;
117
- var keysToRecycle = Array.from(this.keyMap.keys()).slice(0, this.keyMap.size - this.maxItems);
118
- try {
119
- for (var keysToRecycle_1 = tslib_1.__values(keysToRecycle), keysToRecycle_1_1 = keysToRecycle_1.next(); !keysToRecycle_1_1.done; keysToRecycle_1_1 = keysToRecycle_1.next()) {
120
- var key = keysToRecycle_1_1.value;
121
- this.recycleKey(key);
122
- }
123
- }
124
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
125
- finally {
126
- try {
127
- if (keysToRecycle_1_1 && !keysToRecycle_1_1.done && (_a = keysToRecycle_1.return)) _a.call(keysToRecycle_1);
128
- }
129
- finally { if (e_1) throw e_1.error; }
130
- }
131
- };
132
- return RecycleKeyManagerImpl;
133
- }());
134
- exports.RecycleKeyManagerImpl = RecycleKeyManagerImpl;
135
- //# sourceMappingURL=RecycleKeyManager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RecycleKeyManager.js","sourceRoot":"","sources":["../../src/recyclerview/RecycleKeyManager.ts"],"names":[],"mappings":"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"}
@@ -1,185 +0,0 @@
1
- export interface RecycleKeyManager {
2
- /**
3
- * Retrieves a unique key for an item type, maintaining a separate pool for each type.
4
- * If a stableId is provided and exists, returns the associated key.
5
- * Otherwise, generates a new key or reuses one from the pool.
6
- * @param itemType - The type/category of the item (e.g., 'header', 'product', 'footer')
7
- * @param stableId - Optional unique identifier for stable item tracking
8
- * @param currentKey - Optional current key to maintain if it exists in the pool
9
- * @returns A unique key for the item
10
- */
11
- getKey: (itemType: string, stableId: string, currentKey?: string) => string;
12
-
13
- /**
14
- * Recycles a key back into its item type's pool when the associated view is no longer visible.
15
- * This allows the key to be reused for new items of the same type.
16
- * @param key - The key to be recycled back into the pool
17
- */
18
- recycleKey: (key: string) => void;
19
-
20
- /**
21
- * Checks if a key is currently available in the recycling pool (not in use).
22
- * @param key - The key to check
23
- * @returns True if the key is available in the pool, false otherwise
24
- */
25
- hasKeyInPool: (key: string) => boolean;
26
-
27
- /**
28
- * Clears all recycled keys from the pool, resetting the recycling system.
29
- * This is useful when the list needs to be completely reset.
30
- */
31
- clearPool: () => void;
32
- }
33
-
34
- export class RecycleKeyManagerImpl implements RecycleKeyManager {
35
- // Maximum number of unique keys that can be active at any time
36
- private maxItems: number;
37
-
38
- // Stores pools of recycled keys for each item type
39
- private keyPools: Map<string, Set<string>>;
40
-
41
- // Maps active keys to their metadata (item type and stable ID)
42
- private keyMap: Map<string, { itemType: string; stableId?: string }>;
43
-
44
- // Maps stable IDs to their corresponding keys for quick lookups
45
- private stableIdMap: Map<string, string>;
46
-
47
- // Counter for generating unique sequential keys
48
- private keyCounter: number;
49
-
50
- /**
51
- * Creates a new RecycleKeyManager with a specified maximum number of items.
52
- * @param maxItems - Maximum number of unique keys that can be active simultaneously.
53
- * Defaults to Number.MAX_SAFE_INTEGER if not specified.
54
- */
55
- constructor(maxItems: number = Number.MAX_SAFE_INTEGER) {
56
- this.maxItems = maxItems;
57
- this.keyPools = new Map();
58
- this.keyMap = new Map();
59
- this.stableIdMap = new Map();
60
- this.keyCounter = 0;
61
- }
62
-
63
- /**
64
- * Gets a key for the specified item type, prioritizing stable ID associations.
65
- * If a stable ID exists, returns its associated key. Otherwise, either reuses
66
- * a key from the pool or generates a new one.
67
- * @param itemType - The type/category of the item
68
- * @param stableId - Optional unique identifier for stable item tracking
69
- * @param currentKey - Optional current key to maintain if it exists in the pool
70
- * @returns A unique key for the item
71
- */
72
- public getKey(
73
- itemType: string,
74
- stableId: string,
75
- currentKey?: string
76
- ): string {
77
- // Return existing key if stableId is already mapped
78
- if (stableId && this.stableIdMap.has(stableId)) {
79
- return this.stableIdMap.get(stableId)!;
80
- }
81
-
82
- // Get or create the pool for this item type
83
- let pool = this.keyPools.get(itemType);
84
- if (!pool) {
85
- pool = new Set();
86
- this.keyPools.set(itemType, pool);
87
- }
88
-
89
- let key: string;
90
- // Reuse existing key from pool if available
91
- if (pool.size > 0) {
92
- key =
93
- currentKey && pool.has(currentKey)
94
- ? currentKey
95
- : pool.values().next().value;
96
- pool.delete(key);
97
- } else {
98
- // Generate new key if pool is empty
99
- key = this.generateKey();
100
- }
101
-
102
- // Update mappings with new key information
103
- this.keyMap.set(key, { itemType, stableId });
104
- if (stableId) {
105
- this.stableIdMap.set(stableId, key);
106
- }
107
-
108
- // Ensure we don't exceed the maximum number of active keys
109
- this.ensurePoolSize();
110
-
111
- return key;
112
- }
113
-
114
- /**
115
- * Recycles a key by adding it back to its item type's pool and cleaning up
116
- * associated mappings. This should be called when a view is no longer visible.
117
- * @param key - The key to be recycled
118
- */
119
- public recycleKey(key: string): void {
120
- const keyInfo = this.keyMap.get(key);
121
-
122
- if (!keyInfo) {
123
- return;
124
- }
125
-
126
- const { itemType, stableId } = keyInfo;
127
- // Clean up stable ID mapping if it exists
128
- if (stableId) {
129
- this.stableIdMap.delete(stableId);
130
- }
131
-
132
- // Add key back to its type's pool
133
- let pool = this.keyPools.get(itemType);
134
- if (!pool) {
135
- pool = new Set();
136
- this.keyPools.set(itemType, pool);
137
- }
138
-
139
- pool.add(key);
140
- this.keyMap.delete(key);
141
- }
142
-
143
- /**
144
- * Checks if a key is currently available in the recycling pool.
145
- * @param key - The key to check
146
- * @returns True if the key is available in the pool, false otherwise
147
- */
148
- public hasKeyInPool(key: string): boolean {
149
- return !this.keyMap.has(key);
150
- }
151
-
152
- /**
153
- * Clears all recycled keys from the pool, effectively resetting the recycling system.
154
- * This operation does not affect currently active keys.
155
- */
156
- public clearPool() {
157
- this.keyPools.clear();
158
- }
159
-
160
- /**
161
- * Generates a unique sequential key using an internal counter.
162
- * @returns A unique key as a string
163
- */
164
- private generateKey(): string {
165
- return (this.keyCounter++).toString();
166
- }
167
-
168
- /**
169
- * Ensures the total number of active keys doesn't exceed the maximum limit.
170
- * If the limit is exceeded, recycles the oldest keys until within bounds.
171
- * Note: This operation may impact performance when dealing with large lists.
172
- * TODO: Check performance impact of this
173
- */
174
- private ensurePoolSize(): void {
175
- if (this.keyMap.size <= this.maxItems) return;
176
-
177
- const keysToRecycle = Array.from(this.keyMap.keys()).slice(
178
- 0,
179
- this.keyMap.size - this.maxItems
180
- );
181
- for (const key of keysToRecycle) {
182
- this.recycleKey(key);
183
- }
184
- }
185
- }