@shopify/flash-list 2.0.0-alpha.1 → 2.0.0-alpha.11

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 (300) hide show
  1. package/README.md +40 -5
  2. package/dist/AnimatedFlashList.d.ts +0 -1
  3. package/dist/AnimatedFlashList.d.ts.map +1 -1
  4. package/dist/AnimatedFlashList.js +3 -3
  5. package/dist/AnimatedFlashList.js.map +1 -1
  6. package/dist/FlashList.d.ts +9 -0
  7. package/dist/FlashList.d.ts.map +1 -1
  8. package/dist/FlashList.js +22 -3
  9. package/dist/FlashList.js.map +1 -1
  10. package/dist/FlashListProps.d.ts +16 -9
  11. package/dist/FlashListProps.d.ts.map +1 -1
  12. package/dist/FlashListProps.js.map +1 -1
  13. package/dist/FlashListRef.d.ts +295 -0
  14. package/dist/FlashListRef.d.ts.map +1 -0
  15. package/dist/FlashListRef.js +3 -0
  16. package/dist/FlashListRef.js.map +1 -0
  17. package/dist/GridLayoutProviderWithProps.js +1 -2
  18. package/dist/GridLayoutProviderWithProps.js.map +1 -1
  19. package/dist/MasonryFlashList.d.ts +2 -2
  20. package/dist/MasonryFlashList.d.ts.map +1 -1
  21. package/dist/MasonryFlashList.js.map +1 -1
  22. package/dist/PureComponentWrapper.js +1 -1
  23. package/dist/PureComponentWrapper.js.map +1 -1
  24. package/dist/__tests__/AverageWindow.test.js.map +1 -1
  25. package/dist/__tests__/ConsecutiveNumbers.test.d.ts +2 -0
  26. package/dist/__tests__/ConsecutiveNumbers.test.d.ts.map +1 -0
  27. package/dist/__tests__/ConsecutiveNumbers.test.js +224 -0
  28. package/dist/__tests__/ConsecutiveNumbers.test.js.map +1 -0
  29. package/dist/__tests__/FlashList.test.js.map +1 -1
  30. package/dist/__tests__/GridLayoutManager.test.d.ts +2 -0
  31. package/dist/__tests__/GridLayoutManager.test.d.ts.map +1 -0
  32. package/dist/__tests__/GridLayoutManager.test.js +69 -0
  33. package/dist/__tests__/GridLayoutManager.test.js.map +1 -0
  34. package/dist/__tests__/GridLayoutProviderWithProps.test.js.map +1 -1
  35. package/dist/__tests__/LinearLayoutManager.test.d.ts +2 -0
  36. package/dist/__tests__/LinearLayoutManager.test.d.ts.map +1 -0
  37. package/dist/__tests__/LinearLayoutManager.test.js +140 -0
  38. package/dist/__tests__/LinearLayoutManager.test.js.map +1 -0
  39. package/dist/__tests__/MasonryFlashList.test.js.map +1 -1
  40. package/dist/__tests__/MasonryLayoutManager.test.d.ts +2 -0
  41. package/dist/__tests__/MasonryLayoutManager.test.d.ts.map +1 -0
  42. package/dist/__tests__/MasonryLayoutManager.test.js +148 -0
  43. package/dist/__tests__/MasonryLayoutManager.test.js.map +1 -0
  44. package/dist/__tests__/RecyclerView.test.d.ts +2 -0
  45. package/dist/__tests__/RecyclerView.test.d.ts.map +1 -0
  46. package/dist/__tests__/RecyclerView.test.js +94 -0
  47. package/dist/__tests__/RecyclerView.test.js.map +1 -0
  48. package/dist/__tests__/RenderStackManager.test.d.ts +2 -0
  49. package/dist/__tests__/RenderStackManager.test.d.ts.map +1 -0
  50. package/dist/__tests__/RenderStackManager.test.js +405 -0
  51. package/dist/__tests__/RenderStackManager.test.js.map +1 -0
  52. package/dist/__tests__/ViewabilityHelper.test.js.map +1 -1
  53. package/dist/__tests__/findVisibleIndex.test.d.ts +2 -0
  54. package/dist/__tests__/findVisibleIndex.test.d.ts.map +1 -0
  55. package/dist/__tests__/findVisibleIndex.test.js +259 -0
  56. package/dist/__tests__/findVisibleIndex.test.js.map +1 -0
  57. package/dist/__tests__/helpers/createLayoutManager.d.ts +34 -0
  58. package/dist/__tests__/helpers/createLayoutManager.d.ts.map +1 -0
  59. package/dist/__tests__/helpers/createLayoutManager.js +111 -0
  60. package/dist/__tests__/helpers/createLayoutManager.js.map +1 -0
  61. package/dist/__tests__/helpers/mountFlashList.d.ts +2 -2
  62. package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -1
  63. package/dist/__tests__/helpers/mountFlashList.js +2 -2
  64. package/dist/__tests__/helpers/mountFlashList.js.map +1 -1
  65. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +2 -2
  66. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +1 -1
  67. package/dist/__tests__/helpers/mountMasonryFlashList.js +2 -2
  68. package/dist/__tests__/helpers/mountMasonryFlashList.js.map +1 -1
  69. package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -1
  70. package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts +2 -0
  71. package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts.map +1 -0
  72. package/dist/__tests__/useUnmountAwareCallbacks.test.js +185 -0
  73. package/dist/__tests__/useUnmountAwareCallbacks.test.js.map +1 -0
  74. package/dist/benchmark/AutoScrollHelper.js +2 -2
  75. package/dist/benchmark/AutoScrollHelper.js.map +1 -1
  76. package/dist/benchmark/JSFPSMonitor.js.map +1 -1
  77. package/dist/benchmark/roundToDecimalPlaces.js +1 -2
  78. package/dist/benchmark/roundToDecimalPlaces.js.map +1 -1
  79. package/dist/benchmark/useBenchmark.js +2 -3
  80. package/dist/benchmark/useBenchmark.js.map +1 -1
  81. package/dist/benchmark/useBlankAreaTracker.js +1 -2
  82. package/dist/benchmark/useBlankAreaTracker.js.map +1 -1
  83. package/dist/benchmark/useDataMultiplier.js +1 -2
  84. package/dist/benchmark/useDataMultiplier.js.map +1 -1
  85. package/dist/benchmark/useFlatListBenchmark.d.ts +0 -1
  86. package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
  87. package/dist/benchmark/useFlatListBenchmark.js +9 -9
  88. package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
  89. package/dist/enableNewCore.d.ts.map +1 -1
  90. package/dist/enableNewCore.js +4 -4
  91. package/dist/enableNewCore.js.map +1 -1
  92. package/dist/errors/CustomError.js.map +1 -1
  93. package/dist/index.d.ts +3 -3
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +21 -6
  96. package/dist/index.js.map +1 -1
  97. package/dist/native/auto-layout/AutoLayoutView.d.ts +1 -1
  98. package/dist/native/auto-layout/AutoLayoutView.d.ts.map +1 -1
  99. package/dist/native/auto-layout/AutoLayoutView.js +1 -1
  100. package/dist/native/auto-layout/AutoLayoutView.js.map +1 -1
  101. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +1 -1
  102. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +1 -1
  103. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +1 -1
  104. package/dist/native/config/PlatformHelper.android.d.ts +2 -0
  105. package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
  106. package/dist/native/config/PlatformHelper.android.js +2 -0
  107. package/dist/native/config/PlatformHelper.android.js.map +1 -1
  108. package/dist/native/config/PlatformHelper.d.ts +2 -0
  109. package/dist/native/config/PlatformHelper.d.ts.map +1 -1
  110. package/dist/native/config/PlatformHelper.ios.d.ts +2 -0
  111. package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
  112. package/dist/native/config/PlatformHelper.ios.js +2 -0
  113. package/dist/native/config/PlatformHelper.ios.js.map +1 -1
  114. package/dist/native/config/PlatformHelper.js +2 -0
  115. package/dist/native/config/PlatformHelper.js.map +1 -1
  116. package/dist/native/config/PlatformHelper.web.d.ts +2 -0
  117. package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
  118. package/dist/native/config/PlatformHelper.web.js +3 -1
  119. package/dist/native/config/PlatformHelper.web.js.map +1 -1
  120. package/dist/recyclerview/RecyclerView.d.ts +3 -2
  121. package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
  122. package/dist/recyclerview/RecyclerView.js +87 -51
  123. package/dist/recyclerview/RecyclerView.js.map +1 -1
  124. package/dist/recyclerview/RecyclerViewContextProvider.d.ts +6 -6
  125. package/dist/recyclerview/RecyclerViewContextProvider.d.ts.map +1 -1
  126. package/dist/recyclerview/RecyclerViewContextProvider.js +2 -2
  127. package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -1
  128. package/dist/recyclerview/RecyclerViewManager.d.ts +20 -6
  129. package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
  130. package/dist/recyclerview/RecyclerViewManager.js +98 -95
  131. package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
  132. package/dist/recyclerview/RecyclerViewProps.d.ts +1 -1
  133. package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -1
  134. package/dist/recyclerview/RenderStackManager.d.ts +85 -0
  135. package/dist/recyclerview/RenderStackManager.d.ts.map +1 -0
  136. package/dist/recyclerview/RenderStackManager.js +261 -0
  137. package/dist/recyclerview/RenderStackManager.js.map +1 -0
  138. package/dist/recyclerview/ViewHolder.d.ts.map +1 -1
  139. package/dist/recyclerview/ViewHolder.js +8 -6
  140. package/dist/recyclerview/ViewHolder.js.map +1 -1
  141. package/dist/recyclerview/ViewHolderCollection.d.ts +4 -2
  142. package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
  143. package/dist/recyclerview/ViewHolderCollection.js +19 -4
  144. package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
  145. package/dist/recyclerview/components/ScrollAnchor.d.ts +1 -0
  146. package/dist/recyclerview/components/ScrollAnchor.d.ts.map +1 -1
  147. package/dist/recyclerview/components/ScrollAnchor.js +6 -7
  148. package/dist/recyclerview/components/ScrollAnchor.js.map +1 -1
  149. package/dist/recyclerview/components/StickyHeaders.d.ts +1 -1
  150. package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -1
  151. package/dist/recyclerview/components/StickyHeaders.js +49 -30
  152. package/dist/recyclerview/components/StickyHeaders.js.map +1 -1
  153. package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts +1 -1
  154. package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts.map +1 -1
  155. package/dist/recyclerview/helpers/ConsecutiveNumbers.js +2 -2
  156. package/dist/recyclerview/helpers/ConsecutiveNumbers.js.map +1 -1
  157. package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts +48 -2
  158. package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts.map +1 -1
  159. package/dist/recyclerview/helpers/EngagedIndicesTracker.js +90 -19
  160. package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -1
  161. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts +10 -0
  162. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts.map +1 -0
  163. package/dist/recyclerview/helpers/RenderTimeTracker.js +39 -0
  164. package/dist/recyclerview/helpers/RenderTimeTracker.js.map +1 -0
  165. package/dist/recyclerview/helpers/VelocityTracker.d.ts +29 -0
  166. package/dist/recyclerview/helpers/VelocityTracker.d.ts.map +1 -0
  167. package/dist/recyclerview/helpers/VelocityTracker.js +70 -0
  168. package/dist/recyclerview/helpers/VelocityTracker.js.map +1 -0
  169. package/dist/recyclerview/hooks/useBoundDetection.d.ts +1 -3
  170. package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -1
  171. package/dist/recyclerview/hooks/useBoundDetection.js +23 -22
  172. package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
  173. package/dist/recyclerview/hooks/useLayoutState.js +1 -2
  174. package/dist/recyclerview/hooks/useLayoutState.js.map +1 -1
  175. package/dist/recyclerview/hooks/useMappingHelper.d.ts +9 -0
  176. package/dist/recyclerview/hooks/useMappingHelper.d.ts.map +1 -0
  177. package/dist/recyclerview/hooks/useMappingHelper.js +19 -0
  178. package/dist/recyclerview/hooks/useMappingHelper.js.map +1 -0
  179. package/dist/recyclerview/hooks/useOnLoad.d.ts +2 -2
  180. package/dist/recyclerview/hooks/useOnLoad.d.ts.map +1 -1
  181. package/dist/recyclerview/hooks/useOnLoad.js +9 -10
  182. package/dist/recyclerview/hooks/useOnLoad.js.map +1 -1
  183. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts +3 -48
  184. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
  185. package/dist/recyclerview/hooks/useRecyclerViewController.js +236 -160
  186. package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
  187. package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts +2 -0
  188. package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts.map +1 -1
  189. package/dist/recyclerview/hooks/useRecyclerViewManager.js +10 -1
  190. package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -1
  191. package/dist/recyclerview/hooks/useRecyclingState.js +1 -2
  192. package/dist/recyclerview/hooks/useRecyclingState.js.map +1 -1
  193. package/dist/recyclerview/hooks/useSecondaryProps.d.ts +1 -1
  194. package/dist/recyclerview/hooks/useSecondaryProps.d.ts.map +1 -1
  195. package/dist/recyclerview/hooks/useSecondaryProps.js +15 -12
  196. package/dist/recyclerview/hooks/useSecondaryProps.js.map +1 -1
  197. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts +15 -0
  198. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts.map +1 -0
  199. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js +63 -0
  200. package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js.map +1 -0
  201. package/dist/recyclerview/hooks/useUnmountFlag.d.ts +0 -1
  202. package/dist/recyclerview/hooks/useUnmountFlag.d.ts.map +1 -1
  203. package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts +6 -0
  204. package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts.map +1 -1
  205. package/dist/recyclerview/layout-managers/GridLayoutManager.js +29 -10
  206. package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -1
  207. package/dist/recyclerview/layout-managers/LayoutManager.d.ts +3 -2
  208. package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
  209. package/dist/recyclerview/layout-managers/LayoutManager.js +7 -3
  210. package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
  211. package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts +1 -2
  212. package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts.map +1 -1
  213. package/dist/recyclerview/layout-managers/LinearLayoutManager.js +3 -3
  214. package/dist/recyclerview/layout-managers/LinearLayoutManager.js.map +1 -1
  215. package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts.map +1 -1
  216. package/dist/recyclerview/layout-managers/MasonryLayoutManager.js +5 -7
  217. package/dist/recyclerview/layout-managers/MasonryLayoutManager.js.map +1 -1
  218. package/dist/recyclerview/utils/adjustOffsetForRTL.js +1 -2
  219. package/dist/recyclerview/utils/adjustOffsetForRTL.js.map +1 -1
  220. package/dist/recyclerview/utils/componentUtils.d.ts +1 -1
  221. package/dist/recyclerview/utils/componentUtils.d.ts.map +1 -1
  222. package/dist/recyclerview/utils/componentUtils.js.map +1 -1
  223. package/dist/recyclerview/utils/findVisibleIndex.d.ts.map +1 -1
  224. package/dist/recyclerview/utils/findVisibleIndex.js +3 -5
  225. package/dist/recyclerview/utils/findVisibleIndex.js.map +1 -1
  226. package/dist/recyclerview/utils/measureLayout.d.ts +24 -28
  227. package/dist/recyclerview/utils/measureLayout.d.ts.map +1 -1
  228. package/dist/recyclerview/utils/measureLayout.js +36 -6
  229. package/dist/recyclerview/utils/measureLayout.js.map +1 -1
  230. package/dist/recyclerview/utils/measureLayout.web.d.ts +29 -0
  231. package/dist/recyclerview/utils/measureLayout.web.d.ts.map +1 -0
  232. package/dist/recyclerview/utils/measureLayout.web.js +89 -0
  233. package/dist/recyclerview/utils/measureLayout.web.js.map +1 -0
  234. package/dist/specs/AutoLayoutNativeComponent.d.ts +1 -2
  235. package/dist/specs/AutoLayoutNativeComponent.d.ts.map +1 -1
  236. package/dist/specs/CellContainerNativeComponent.d.ts +0 -1
  237. package/dist/specs/CellContainerNativeComponent.d.ts.map +1 -1
  238. package/dist/tsconfig.tsbuildinfo +1 -1
  239. package/dist/utils/AverageWindow.js.map +1 -1
  240. package/dist/utils/ContentContainerUtils.d.ts.map +1 -1
  241. package/dist/utils/ContentContainerUtils.js.map +1 -1
  242. package/dist/viewability/ViewabilityHelper.js.map +1 -1
  243. package/dist/viewability/ViewabilityManager.d.ts.map +1 -1
  244. package/dist/viewability/ViewabilityManager.js.map +1 -1
  245. package/jestSetup.js +30 -11
  246. package/package.json +4 -3
  247. package/src/AnimatedFlashList.ts +3 -2
  248. package/src/FlashList.tsx +25 -1
  249. package/src/FlashListProps.ts +17 -8
  250. package/src/FlashListRef.ts +309 -0
  251. package/src/__tests__/ConsecutiveNumbers.test.ts +232 -0
  252. package/src/__tests__/GridLayoutManager.test.ts +113 -0
  253. package/src/__tests__/LinearLayoutManager.test.ts +227 -0
  254. package/src/__tests__/MasonryLayoutManager.test.ts +202 -0
  255. package/src/__tests__/RecyclerView.test.tsx +123 -0
  256. package/src/__tests__/RenderStackManager.test.ts +488 -0
  257. package/src/__tests__/findVisibleIndex.test.ts +369 -0
  258. package/src/__tests__/helpers/createLayoutManager.ts +142 -0
  259. package/src/__tests__/useUnmountAwareCallbacks.test.tsx +285 -0
  260. package/src/benchmark/useFlatListBenchmark.ts +2 -2
  261. package/src/enableNewCore.ts +3 -1
  262. package/src/index.ts +22 -7
  263. package/src/native/config/PlatformHelper.android.ts +2 -0
  264. package/src/native/config/PlatformHelper.ios.ts +2 -0
  265. package/src/native/config/PlatformHelper.ts +2 -0
  266. package/src/native/config/PlatformHelper.web.ts +3 -1
  267. package/src/recyclerview/RecyclerView.tsx +110 -60
  268. package/src/recyclerview/RecyclerViewContextProvider.ts +13 -6
  269. package/src/recyclerview/RecyclerViewManager.ts +116 -76
  270. package/src/recyclerview/RecyclerViewProps.ts +2 -1
  271. package/src/recyclerview/RenderStackManager.ts +265 -0
  272. package/src/recyclerview/ViewHolder.tsx +13 -6
  273. package/src/recyclerview/ViewHolderCollection.tsx +32 -10
  274. package/src/recyclerview/components/ScrollAnchor.tsx +13 -8
  275. package/src/recyclerview/components/StickyHeaders.tsx +65 -33
  276. package/src/recyclerview/helpers/ConsecutiveNumbers.ts +2 -2
  277. package/src/recyclerview/helpers/EngagedIndicesTracker.ts +136 -25
  278. package/src/recyclerview/helpers/RenderTimeTracker.ts +38 -0
  279. package/src/recyclerview/helpers/VelocityTracker.ts +77 -0
  280. package/src/recyclerview/hooks/useBoundDetection.ts +27 -20
  281. package/src/recyclerview/hooks/useMappingHelper.ts +20 -0
  282. package/src/recyclerview/hooks/useOnLoad.ts +11 -10
  283. package/src/recyclerview/hooks/useRecyclerViewController.tsx +275 -237
  284. package/src/recyclerview/hooks/useRecyclerViewManager.ts +11 -1
  285. package/src/recyclerview/hooks/useSecondaryProps.tsx +12 -7
  286. package/src/recyclerview/hooks/useUnmountAwareCallbacks.ts +73 -0
  287. package/src/recyclerview/layout-managers/GridLayoutManager.ts +32 -12
  288. package/src/recyclerview/layout-managers/LayoutManager.ts +9 -4
  289. package/src/recyclerview/layout-managers/LinearLayoutManager.ts +12 -8
  290. package/src/recyclerview/layout-managers/MasonryLayoutManager.ts +4 -5
  291. package/src/recyclerview/utils/componentUtils.ts +1 -1
  292. package/src/recyclerview/utils/findVisibleIndex.ts +1 -2
  293. package/src/recyclerview/utils/measureLayout.ts +41 -2
  294. package/src/recyclerview/utils/measureLayout.web.ts +104 -0
  295. package/src/viewability/ViewToken.ts +1 -1
  296. package/dist/recyclerview/RecycleKeyManager.d.ts +0 -82
  297. package/dist/recyclerview/RecycleKeyManager.d.ts.map +0 -1
  298. package/dist/recyclerview/RecycleKeyManager.js +0 -135
  299. package/dist/recyclerview/RecycleKeyManager.js.map +0 -1
  300. package/src/recyclerview/RecycleKeyManager.ts +0 -185
@@ -19,11 +19,14 @@ import {
19
19
  NativeSyntheticEvent,
20
20
  } from "react-native";
21
21
 
22
+ import { FlashListRef } from "../FlashListRef";
23
+
22
24
  import { RVDimension } from "./layout-managers/LayoutManager";
23
25
  import {
24
26
  areDimensionsNotEqual,
25
- measureLayout,
26
- measureLayoutRelative,
27
+ measureFirstChildLayout,
28
+ measureItemLayout,
29
+ measureParentSize,
27
30
  } from "./utils/measureLayout";
28
31
  import {
29
32
  RecyclerViewContext,
@@ -46,6 +49,7 @@ import { useSecondaryProps } from "./hooks/useSecondaryProps";
46
49
  import { StickyHeaders, StickyHeaderRef } from "./components/StickyHeaders";
47
50
  import { ScrollAnchor, ScrollAnchorRef } from "./components/ScrollAnchor";
48
51
  import { useRecyclerViewController } from "./hooks/useRecyclerViewController";
52
+ import { RenderTimeTracker } from "./helpers/RenderTimeTracker";
49
53
 
50
54
  /**
51
55
  * Main RecyclerView component that handles list rendering, scrolling, and item recycling.
@@ -53,7 +57,7 @@ import { useRecyclerViewController } from "./hooks/useRecyclerViewController";
53
57
  */
54
58
  const RecyclerViewComponent = <T,>(
55
59
  props: RecyclerViewProps<T>,
56
- ref: React.Ref<any>
60
+ ref: React.Ref<FlashListRef<T>>
57
61
  ) => {
58
62
  // Destructure props and initialize refs
59
63
  const {
@@ -74,8 +78,6 @@ const RecyclerViewComponent = <T,>(
74
78
  ListFooterComponentStyle,
75
79
  ItemSeparatorComponent,
76
80
  renderScrollComponent,
77
- onScroll,
78
- disableRecycling,
79
81
  style,
80
82
  stickyHeaderIndices,
81
83
  maintainVisibleContentPosition,
@@ -83,10 +85,14 @@ const RecyclerViewComponent = <T,>(
83
85
  ...rest
84
86
  } = props;
85
87
 
88
+ const [renderTimeTracker] = useState(() => new RenderTimeTracker());
89
+
90
+ renderTimeTracker.startTracking();
91
+
86
92
  // Core refs for managing scroll view, internal view, and child container
87
93
  const scrollViewRef = useRef<CompatScroller>(null);
88
94
  const internalViewRef = useRef<CompatView>(null);
89
- const childContainerViewRef = useRef<CompatView>(null);
95
+ const firstChildViewRef = useRef<CompatView>(null);
90
96
  const containerViewSizeRef = useRef<RVDimension | undefined>(undefined);
91
97
  const pendingChildIds = useRef<Set<string>>(new Set()).current;
92
98
 
@@ -108,14 +114,14 @@ const RecyclerViewComponent = <T,>(
108
114
  );
109
115
 
110
116
  // Initialize core RecyclerView manager and content offset management
111
- const { recyclerViewManager } = useRecyclerViewManager(props);
112
- const { applyContentOffset, applyInitialScrollIndex } =
117
+ const { recyclerViewManager, velocityTracker } =
118
+ useRecyclerViewManager(props);
119
+ const { applyContentOffset, applyInitialScrollIndex, handlerMethods } =
113
120
  useRecyclerViewController(
114
121
  recyclerViewManager,
115
122
  ref,
116
123
  scrollViewRef,
117
- scrollAnchorRef,
118
- props
124
+ scrollAnchorRef
119
125
  );
120
126
 
121
127
  // Initialize view holder collection ref
@@ -125,40 +131,44 @@ const RecyclerViewComponent = <T,>(
125
131
  useOnListLoad(recyclerViewManager, onLoad);
126
132
 
127
133
  // Hook to detect when scrolling reaches list bounds
128
- const { checkBounds } = useBoundDetection(
129
- recyclerViewManager,
130
- props,
131
- scrollViewRef
132
- );
134
+ const { checkBounds } = useBoundDetection(recyclerViewManager, scrollViewRef);
135
+
136
+ const isHorizontalRTL = I18nManager.isRTL && horizontal;
133
137
 
134
138
  /**
135
139
  * Initialize the RecyclerView by measuring and setting up the window size
136
140
  * This effect runs when the component mounts or when layout changes
137
141
  */
138
142
  useLayoutEffect(() => {
139
- if (internalViewRef.current && childContainerViewRef.current) {
143
+ if (internalViewRef.current && firstChildViewRef.current) {
140
144
  // Measure the outer and inner container layouts
141
- const outerViewLayout = measureLayout(internalViewRef.current, undefined);
142
- const childViewLayout = measureLayoutRelative(
143
- childContainerViewRef.current,
144
- internalViewRef.current,
145
- undefined
145
+ const outerViewLayout = measureParentSize(internalViewRef.current);
146
+ const firstChildViewLayout = measureFirstChildLayout(
147
+ firstChildViewRef.current,
148
+ internalViewRef.current
146
149
  );
147
150
 
148
151
  containerViewSizeRef.current = outerViewLayout;
149
152
 
150
153
  // Calculate offset of first item
151
154
  const firstItemOffset = horizontal
152
- ? childViewLayout.x - outerViewLayout.x
153
- : childViewLayout.y - outerViewLayout.y;
155
+ ? firstChildViewLayout.x - outerViewLayout.x
156
+ : firstChildViewLayout.y - outerViewLayout.y;
154
157
 
155
158
  // Update the RecyclerView manager with window dimensions
156
159
  recyclerViewManager.updateLayoutParams(
157
160
  {
158
- width: horizontal ? outerViewLayout.width : childViewLayout.width,
159
- height: horizontal ? childViewLayout.height : outerViewLayout.height,
161
+ width: horizontal
162
+ ? outerViewLayout.width
163
+ : firstChildViewLayout.width,
164
+ height: horizontal
165
+ ? firstChildViewLayout.height
166
+ : outerViewLayout.height,
160
167
  },
161
- firstItemOffset
168
+ isHorizontalRTL && recyclerViewManager.hasLayout()
169
+ ? firstItemOffset -
170
+ recyclerViewManager.getChildContainerDimensions().width
171
+ : firstItemOffset
162
172
  );
163
173
  }
164
174
  });
@@ -167,18 +177,19 @@ const RecyclerViewComponent = <T,>(
167
177
  * Effect to handle layout updates for list items
168
178
  * This ensures proper positioning and recycling of items
169
179
  */
180
+ // eslint-disable-next-line react-hooks/exhaustive-deps
170
181
  useLayoutEffect(() => {
171
182
  if (pendingChildIds.size > 0) {
172
183
  return;
173
184
  }
174
185
  const layoutInfo = Array.from(refHolder, ([index, viewHolderRef]) => {
175
- const layout = measureLayout(
186
+ const layout = measureItemLayout(
176
187
  viewHolderRef.current!,
177
188
  recyclerViewManager.getLayout(index)
178
189
  );
179
190
 
180
- //comapre height with stored layout
181
- //const storedLayout = recyclerViewManager.getLayout(index);
191
+ // comapre height with stored layout
192
+ // const storedLayout = recyclerViewManager.getLayout(index);
182
193
  // if (
183
194
  // storedLayout.height !== layout.height &&
184
195
  // storedLayout.isHeightMeasured
@@ -199,8 +210,6 @@ const RecyclerViewComponent = <T,>(
199
210
  // Trigger re-render if layout modifications were made
200
211
  setRenderId((prev) => prev + 1);
201
212
  } else {
202
- //console.log("commitLayout");
203
- // TODO: reduce perf impact of commitLayout
204
213
  viewHolderCollectionRef.current?.commitLayout();
205
214
  applyContentOffset();
206
215
  }
@@ -211,30 +220,44 @@ const RecyclerViewComponent = <T,>(
211
220
  */
212
221
  const onScrollHandler = useCallback(
213
222
  (event: NativeSyntheticEvent<NativeScrollEvent>) => {
214
- let velocity = event.nativeEvent.velocity;
223
+ if (recyclerViewManager.ignoreScrollEvents) {
224
+ return;
225
+ }
226
+
215
227
  let scrollOffset = horizontal
216
228
  ? event.nativeEvent.contentOffset.x
217
229
  : event.nativeEvent.contentOffset.y;
218
230
 
219
231
  // Handle RTL (Right-to-Left) layout adjustments
220
- if (I18nManager.isRTL && horizontal) {
232
+ if (isHorizontalRTL) {
221
233
  scrollOffset = adjustOffsetForRTL(
222
234
  scrollOffset,
223
235
  event.nativeEvent.contentSize.width,
224
236
  event.nativeEvent.layoutMeasurement.width
225
237
  );
226
- if (velocity) {
227
- velocity = {
228
- x: -velocity.x,
229
- y: velocity.y,
230
- };
231
- }
232
238
  }
233
239
 
234
- // Update scroll position and trigger re-render if needed
235
- if (recyclerViewManager.updateScrollOffset(scrollOffset, velocity)) {
236
- setRenderId((prev) => prev + 1);
237
- }
240
+ velocityTracker.computeVelocity(
241
+ scrollOffset,
242
+ recyclerViewManager.getAbsoluteLastScrollOffset(),
243
+ Boolean(horizontal),
244
+ (velocity, isMomentumEnd) => {
245
+ if (recyclerViewManager.ignoreScrollEvents) {
246
+ return;
247
+ }
248
+
249
+ if (isMomentumEnd) {
250
+ if (!recyclerViewManager.isOffsetProjectionEnabled) {
251
+ return;
252
+ }
253
+ recyclerViewManager.resetVelocityCompute();
254
+ }
255
+ // Update scroll position and trigger re-render if needed
256
+ if (recyclerViewManager.updateScrollOffset(scrollOffset, velocity)) {
257
+ setRenderId((prev) => prev + 1);
258
+ }
259
+ }
260
+ );
238
261
 
239
262
  // Update sticky headers and check bounds
240
263
  stickyHeaderRef.current?.reportScrollEvent(event.nativeEvent);
@@ -245,22 +268,31 @@ const RecyclerViewComponent = <T,>(
245
268
  recyclerViewManager.computeItemViewability();
246
269
 
247
270
  // Call user-provided onScroll handler
248
- onScroll?.(event);
271
+ recyclerViewManager.props.onScroll?.(event);
249
272
  },
250
- [horizontal, recyclerViewManager]
273
+ [
274
+ checkBounds,
275
+ horizontal,
276
+ isHorizontalRTL,
277
+ recyclerViewManager,
278
+ velocityTracker,
279
+ ]
251
280
  );
252
281
 
253
282
  // Create context for child components
254
- const recyclerViewContext: RecyclerViewContext = useMemo(() => {
283
+ const recyclerViewContext: RecyclerViewContext<T> = useMemo(() => {
255
284
  return {
256
285
  layout: () => {
257
286
  setLayoutTreeId((prev) => prev + 1);
258
287
  },
259
288
  getRef: () => {
260
- return ref;
289
+ if (recyclerViewManager.isDisposed) {
290
+ return null;
291
+ }
292
+ return handlerMethods;
261
293
  },
262
294
  getScrollViewRef: () => {
263
- return scrollViewRef;
295
+ return scrollViewRef.current;
264
296
  },
265
297
  markChildLayoutAsPending: (id: string) => {
266
298
  pendingChildIds.add(id);
@@ -272,7 +304,7 @@ const RecyclerViewComponent = <T,>(
272
304
  }
273
305
  },
274
306
  };
275
- }, [setLayoutTreeId]);
307
+ }, [handlerMethods, pendingChildIds, recyclerViewManager, setLayoutTreeId]);
276
308
 
277
309
  const parentRecyclerViewContext = useRecyclerViewContext();
278
310
  const recyclerViewId = useId();
@@ -307,7 +339,7 @@ const RecyclerViewComponent = <T,>(
307
339
  recyclerViewContext.layout();
308
340
  }
309
341
  },
310
- [recyclerViewManager]
342
+ [recyclerViewContext, recyclerViewManager]
311
343
  );
312
344
 
313
345
  // Get secondary props and components
@@ -347,7 +379,14 @@ const RecyclerViewComponent = <T,>(
347
379
  );
348
380
  }
349
381
  return null;
350
- }, [data, stickyHeaderIndices, renderItem, extraData]);
382
+ }, [
383
+ data,
384
+ stickyHeaderIndices,
385
+ renderItem,
386
+ scrollY,
387
+ recyclerViewManager,
388
+ extraData,
389
+ ]);
351
390
 
352
391
  // Set up scroll event handling with animation support for sticky headers
353
392
  const animatedEvent = useMemo(() => {
@@ -358,7 +397,7 @@ const RecyclerViewComponent = <T,>(
358
397
  );
359
398
  }
360
399
  return onScrollHandler;
361
- }, [onScrollHandler, stickyHeaders]);
400
+ }, [onScrollHandler, scrollY, stickyHeaders]);
362
401
 
363
402
  const maintainVisibleContentPositionInternal = useMemo(() => {
364
403
  if (maintainVisibleContentPosition?.disabled || horizontal) {
@@ -369,7 +408,7 @@ const RecyclerViewComponent = <T,>(
369
408
  minIndexForVisible: 0,
370
409
  };
371
410
  }
372
- }, [maintainVisibleContentPosition]);
411
+ }, [horizontal, maintainVisibleContentPosition]);
373
412
 
374
413
  const shouldRenderFromBottom =
375
414
  maintainVisibleContentPositionInternal?.startRenderingFromBottom ?? false;
@@ -393,18 +432,22 @@ const RecyclerViewComponent = <T,>(
393
432
  width: horizontal ? 0 : undefined,
394
433
  minHeight: shouldRenderFromBottom ? adjustmentMinHeight : undefined,
395
434
  }}
396
- ref={childContainerViewRef}
435
+ ref={firstChildViewRef}
397
436
  />
398
437
  );
399
438
  }, [horizontal, shouldRenderFromBottom, adjustmentMinHeight]);
400
439
 
401
- //console.log("render");
440
+ // console.log("render", recyclerViewManager.getRenderStack());
402
441
 
403
442
  // Render the main RecyclerView structure
404
443
  return (
405
444
  <RecyclerViewContextProvider value={recyclerViewContext}>
406
445
  <CompatView
407
- style={{ flex: horizontal ? undefined : 1, ...style }}
446
+ style={{
447
+ flex: horizontal ? undefined : 1,
448
+ overflow: "hidden",
449
+ ...style,
450
+ }}
408
451
  ref={internalViewRef}
409
452
  collapsable={false}
410
453
  onLayout={(event) => {
@@ -433,7 +476,6 @@ const RecyclerViewComponent = <T,>(
433
476
  horizontal={horizontal}
434
477
  ref={scrollViewRef}
435
478
  onScroll={animatedEvent}
436
- // TODO: evaluate perf
437
479
  maintainVisibleContentPosition={
438
480
  maintainVisibleContentPositionInternal
439
481
  }
@@ -444,8 +486,9 @@ const RecyclerViewComponent = <T,>(
444
486
  {maintainVisibleContentPositionInternal && (
445
487
  <ScrollAnchor scrollAnchorRef={scrollAnchorRef} />
446
488
  )}
489
+ {isHorizontalRTL && viewToMeasureBoundedSize}
447
490
  {renderHeader}
448
- {viewToMeasureBoundedSize}
491
+ {!isHorizontalRTL && viewToMeasureBoundedSize}
449
492
  {/* Main list content */}
450
493
  <ViewHolderCollection
451
494
  viewHolderCollectionRef={viewHolderCollectionRef}
@@ -465,10 +508,14 @@ const RecyclerViewComponent = <T,>(
465
508
  onCommitLayoutEffect?.();
466
509
  }}
467
510
  onCommitEffect={() => {
511
+ renderTimeTracker.markRenderComplete();
512
+ recyclerViewManager.updateAverageRenderTime(
513
+ renderTimeTracker.getAverageRenderTime()
514
+ );
468
515
  applyInitialScrollIndex();
469
516
  checkBounds();
470
517
  recyclerViewManager.computeItemViewability();
471
- recyclerViewManager.disableRecycling = Boolean(disableRecycling);
518
+ recyclerViewManager.disableRecycling(false);
472
519
  }}
473
520
  CellRendererComponent={CellRendererComponent}
474
521
  ItemSeparatorComponent={ItemSeparatorComponent}
@@ -487,9 +534,12 @@ const RecyclerViewComponent = <T,>(
487
534
  );
488
535
  };
489
536
 
537
+ // Set displayName for the inner component
538
+ RecyclerViewComponent.displayName = "FlashList";
539
+
490
540
  // Type definition for the RecyclerView component
491
541
  type RecyclerViewType = <T>(
492
- props: RecyclerViewProps<T> & { ref?: React.Ref<any> }
542
+ props: RecyclerViewProps<T> & { ref?: React.Ref<FlashListRef<T>> }
493
543
  ) => React.JSX.Element;
494
544
 
495
545
  // Create and export the memoized, forwarded ref component
@@ -1,19 +1,26 @@
1
1
  import { createContext, useContext } from "react";
2
+
3
+ import { FlashListRef } from "../FlashListRef";
4
+
2
5
  import { CompatScroller } from "./components/CompatScroller";
3
6
 
4
- export interface RecyclerViewContext {
7
+ export interface RecyclerViewContext<T> {
5
8
  layout: () => void;
6
- getRef: () => React.Ref<any>;
7
- getScrollViewRef: () => React.RefObject<CompatScroller | null>;
9
+ getRef: () => FlashListRef<T> | null;
10
+ getScrollViewRef: () => CompatScroller | null;
8
11
  markChildLayoutAsPending: (id: string) => void;
9
12
  unmarkChildLayoutAsPending: (id: string) => void;
10
13
  }
11
14
 
12
15
  const RecyclerViewContextInstance = createContext<
13
- RecyclerViewContext | undefined
16
+ RecyclerViewContext<unknown> | undefined
14
17
  >(undefined);
15
18
 
16
19
  export const RecyclerViewContextProvider = RecyclerViewContextInstance.Provider;
17
- export function useRecyclerViewContext() {
18
- return useContext(RecyclerViewContextInstance);
20
+ export function useRecyclerViewContext<T>():
21
+ | RecyclerViewContext<T>
22
+ | undefined {
23
+ return useContext(RecyclerViewContextInstance) as
24
+ | RecyclerViewContext<T>
25
+ | undefined;
19
26
  }