@shopify/flash-list 2.0.0 → 2.0.2-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/README.md +97 -27
  2. package/RNFlashList.podspec +37 -0
  3. package/android/build.gradle +89 -0
  4. package/android/src/main/AndroidManifest.xml +3 -0
  5. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutShadow.kt +105 -0
  6. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutView.kt +158 -0
  7. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutViewManager.kt +70 -0
  8. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +29 -0
  9. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainer.java +16 -0
  10. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerImpl.kt +16 -0
  11. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerManager.kt +34 -0
  12. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/FlashListPackage.kt +19 -0
  13. package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerDelegate.java +47 -0
  14. package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerInterface.java +21 -0
  15. package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerDelegate.java +32 -0
  16. package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerInterface.java +16 -0
  17. package/android/src/test/java/com/shopify/reactnative/flash_list/AutoLayoutShadowTest.kt +147 -0
  18. package/android/src/test/java/com/shopify/reactnative/flash_list/models/Rect.kt +61 -0
  19. package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestCollection.kt +6 -0
  20. package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestDataModel.kt +8 -0
  21. package/android/src/test/resources/LayoutTestData.json +788 -0
  22. package/dist/AnimatedFlashList.js +2 -2
  23. package/dist/AnimatedFlashList.js.map +1 -1
  24. package/dist/FlashList.d.ts +167 -1
  25. package/dist/FlashList.d.ts.map +1 -1
  26. package/dist/FlashList.js +595 -3
  27. package/dist/FlashList.js.map +1 -1
  28. package/dist/FlashListProps.d.ts +63 -2
  29. package/dist/FlashListProps.d.ts.map +1 -1
  30. package/dist/FlashListProps.js.map +1 -1
  31. package/dist/GridLayoutProviderWithProps.d.ts +42 -0
  32. package/dist/GridLayoutProviderWithProps.d.ts.map +1 -0
  33. package/dist/GridLayoutProviderWithProps.js +114 -0
  34. package/dist/GridLayoutProviderWithProps.js.map +1 -0
  35. package/dist/MasonryFlashList.d.ts +51 -0
  36. package/dist/MasonryFlashList.d.ts.map +1 -0
  37. package/dist/MasonryFlashList.js +252 -0
  38. package/dist/MasonryFlashList.js.map +1 -0
  39. package/dist/PureComponentWrapper.d.ts +22 -0
  40. package/dist/PureComponentWrapper.d.ts.map +1 -0
  41. package/dist/PureComponentWrapper.js +37 -0
  42. package/dist/PureComponentWrapper.js.map +1 -0
  43. package/dist/__tests__/ContentContainerUtils.test.d.ts +2 -0
  44. package/dist/__tests__/ContentContainerUtils.test.d.ts.map +1 -0
  45. package/dist/__tests__/ContentContainerUtils.test.js +85 -0
  46. package/dist/__tests__/ContentContainerUtils.test.js.map +1 -0
  47. package/dist/__tests__/FlashList.test.d.ts +2 -0
  48. package/dist/__tests__/FlashList.test.d.ts.map +1 -0
  49. package/dist/__tests__/FlashList.test.js +902 -0
  50. package/dist/__tests__/FlashList.test.js.map +1 -0
  51. package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts +2 -0
  52. package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts.map +1 -0
  53. package/dist/__tests__/GridLayoutProviderWithProps.test.js +143 -0
  54. package/dist/__tests__/GridLayoutProviderWithProps.test.js.map +1 -0
  55. package/dist/__tests__/MasonryFlashList.test.d.ts +2 -0
  56. package/dist/__tests__/MasonryFlashList.test.d.ts.map +1 -0
  57. package/dist/__tests__/MasonryFlashList.test.js +254 -0
  58. package/dist/__tests__/MasonryFlashList.test.js.map +1 -0
  59. package/dist/__tests__/PlatformHelper.web.test.d.ts +2 -0
  60. package/dist/__tests__/PlatformHelper.web.test.d.ts.map +1 -0
  61. package/dist/__tests__/PlatformHelper.web.test.js +33 -0
  62. package/dist/__tests__/PlatformHelper.web.test.js.map +1 -0
  63. package/dist/__tests__/ViewabilityHelper.test.js +4 -3
  64. package/dist/__tests__/ViewabilityHelper.test.js.map +1 -1
  65. package/dist/__tests__/helpers/mountFlashList.d.ts +19 -0
  66. package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -0
  67. package/dist/__tests__/helpers/mountFlashList.js +44 -0
  68. package/dist/__tests__/helpers/mountFlashList.js.map +1 -0
  69. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +18 -0
  70. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +1 -0
  71. package/dist/__tests__/helpers/mountMasonryFlashList.js +49 -0
  72. package/dist/__tests__/helpers/mountMasonryFlashList.js.map +1 -0
  73. package/dist/__tests__/useBlankAreaTracker.test.d.ts +2 -0
  74. package/dist/__tests__/useBlankAreaTracker.test.d.ts.map +1 -0
  75. package/dist/__tests__/useBlankAreaTracker.test.js +179 -0
  76. package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -0
  77. package/dist/benchmark/JSFPSMonitor.d.ts.map +1 -1
  78. package/dist/benchmark/JSFPSMonitor.js +1 -2
  79. package/dist/benchmark/JSFPSMonitor.js.map +1 -1
  80. package/dist/benchmark/useBenchmark.d.ts +4 -2
  81. package/dist/benchmark/useBenchmark.d.ts.map +1 -1
  82. package/dist/benchmark/useBenchmark.js +24 -12
  83. package/dist/benchmark/useBenchmark.js.map +1 -1
  84. package/dist/benchmark/useBlankAreaTracker.d.ts +34 -0
  85. package/dist/benchmark/useBlankAreaTracker.d.ts.map +1 -0
  86. package/dist/benchmark/useBlankAreaTracker.js +66 -0
  87. package/dist/benchmark/useBlankAreaTracker.js.map +1 -0
  88. package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
  89. package/dist/benchmark/useFlatListBenchmark.js +1 -2
  90. package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
  91. package/dist/enableNewCore.d.ts +3 -0
  92. package/dist/enableNewCore.d.ts.map +1 -0
  93. package/dist/enableNewCore.js +25 -0
  94. package/dist/enableNewCore.js.map +1 -0
  95. package/dist/errors/CustomError.d.ts +8 -0
  96. package/dist/errors/CustomError.d.ts.map +1 -0
  97. package/dist/errors/CustomError.js +14 -0
  98. package/dist/errors/CustomError.js.map +1 -0
  99. package/dist/errors/ExceptionList.d.ts +24 -0
  100. package/dist/errors/ExceptionList.d.ts.map +1 -0
  101. package/dist/errors/ExceptionList.js +26 -0
  102. package/dist/errors/ExceptionList.js.map +1 -0
  103. package/dist/errors/Warnings.d.ts +9 -0
  104. package/dist/errors/Warnings.d.ts.map +1 -0
  105. package/dist/errors/Warnings.js +13 -0
  106. package/dist/errors/Warnings.js.map +1 -0
  107. package/dist/index.d.ts +9 -3
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +29 -7
  110. package/dist/index.js.map +1 -1
  111. package/dist/native/auto-layout/AutoLayoutView.d.ts +22 -0
  112. package/dist/native/auto-layout/AutoLayoutView.d.ts.map +1 -0
  113. package/dist/native/auto-layout/AutoLayoutView.js +48 -0
  114. package/dist/native/auto-layout/AutoLayoutView.js.map +1 -0
  115. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts +4 -0
  116. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts.map +1 -0
  117. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js +6 -0
  118. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js.map +1 -0
  119. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts +5 -0
  120. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +1 -0
  121. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts +4 -0
  122. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts.map +1 -0
  123. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js +6 -0
  124. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js.map +1 -0
  125. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js +6 -0
  126. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js.map +1 -0
  127. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +16 -0
  128. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +1 -0
  129. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js +3 -0
  130. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js.map +1 -0
  131. package/dist/native/cell-container/CellContainer.android.d.ts +6 -0
  132. package/dist/native/cell-container/CellContainer.android.d.ts.map +1 -0
  133. package/dist/native/cell-container/CellContainer.android.js +9 -0
  134. package/dist/native/cell-container/CellContainer.android.js.map +1 -0
  135. package/dist/native/cell-container/CellContainer.d.ts +8 -0
  136. package/dist/native/cell-container/CellContainer.d.ts.map +1 -0
  137. package/dist/native/cell-container/CellContainer.ios.d.ts +6 -0
  138. package/dist/native/cell-container/CellContainer.ios.d.ts.map +1 -0
  139. package/dist/native/cell-container/CellContainer.ios.js +9 -0
  140. package/dist/native/cell-container/CellContainer.ios.js.map +1 -0
  141. package/dist/native/cell-container/CellContainer.js +11 -0
  142. package/dist/native/cell-container/CellContainer.js.map +1 -0
  143. package/dist/native/cell-container/CellContainer.web.d.ts +7 -0
  144. package/dist/native/cell-container/CellContainer.web.d.ts.map +1 -0
  145. package/dist/native/cell-container/CellContainer.web.js +13 -0
  146. package/dist/native/cell-container/CellContainer.web.js.map +1 -0
  147. package/dist/native/config/PlatformHelper.android.d.ts +22 -1
  148. package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
  149. package/dist/native/config/PlatformHelper.android.js +16 -1
  150. package/dist/native/config/PlatformHelper.android.js.map +1 -1
  151. package/dist/native/config/PlatformHelper.d.ts +22 -1
  152. package/dist/native/config/PlatformHelper.d.ts.map +1 -1
  153. package/dist/native/config/PlatformHelper.ios.d.ts +22 -1
  154. package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
  155. package/dist/native/config/PlatformHelper.ios.js +15 -1
  156. package/dist/native/config/PlatformHelper.ios.js.map +1 -1
  157. package/dist/native/config/PlatformHelper.js +16 -1
  158. package/dist/native/config/PlatformHelper.js.map +1 -1
  159. package/dist/native/config/PlatformHelper.web.d.ts +23 -1
  160. package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
  161. package/dist/native/config/PlatformHelper.web.js +18 -1
  162. package/dist/native/config/PlatformHelper.web.js.map +1 -1
  163. package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
  164. package/dist/recyclerview/RecyclerView.js +6 -6
  165. package/dist/recyclerview/RecyclerView.js.map +1 -1
  166. package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
  167. package/dist/recyclerview/RecyclerViewManager.js +8 -9
  168. package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
  169. package/dist/recyclerview/RecyclerViewProps.d.ts +8 -1
  170. package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -1
  171. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts +3 -0
  172. package/dist/recyclerview/helpers/RenderTimeTracker.d.ts.map +1 -1
  173. package/dist/recyclerview/helpers/RenderTimeTracker.js +7 -0
  174. package/dist/recyclerview/helpers/RenderTimeTracker.js.map +1 -1
  175. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
  176. package/dist/recyclerview/hooks/useRecyclerViewController.js +0 -4
  177. package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
  178. package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
  179. package/dist/recyclerview/layout-managers/LayoutManager.js +1 -2
  180. package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
  181. package/dist/specs/AutoLayoutNativeComponent.d.ts +18 -0
  182. package/dist/specs/AutoLayoutNativeComponent.d.ts.map +1 -0
  183. package/dist/specs/AutoLayoutNativeComponent.js +6 -0
  184. package/dist/specs/AutoLayoutNativeComponent.js.map +1 -0
  185. package/dist/specs/CellContainerNativeComponent.d.ts +8 -0
  186. package/dist/specs/CellContainerNativeComponent.d.ts.map +1 -0
  187. package/dist/specs/CellContainerNativeComponent.js +6 -0
  188. package/dist/specs/CellContainerNativeComponent.js.map +1 -0
  189. package/dist/tsconfig.tsbuildinfo +1 -1
  190. package/dist/utils/ContentContainerUtils.d.ts +27 -0
  191. package/dist/utils/ContentContainerUtils.d.ts.map +1 -0
  192. package/dist/utils/ContentContainerUtils.js +48 -0
  193. package/dist/utils/ContentContainerUtils.js.map +1 -0
  194. package/dist/viewability/ViewToken.d.ts.map +1 -0
  195. package/dist/viewability/ViewToken.js.map +1 -0
  196. package/dist/{recyclerview/viewability → viewability}/ViewabilityHelper.d.ts +2 -2
  197. package/dist/viewability/ViewabilityHelper.d.ts.map +1 -0
  198. package/dist/{recyclerview/viewability → viewability}/ViewabilityHelper.js +4 -2
  199. package/dist/{recyclerview/viewability → viewability}/ViewabilityHelper.js.map +1 -1
  200. package/dist/{recyclerview/viewability → viewability}/ViewabilityManager.d.ts +3 -3
  201. package/dist/viewability/ViewabilityManager.d.ts.map +1 -0
  202. package/dist/{recyclerview/viewability → viewability}/ViewabilityManager.js +16 -16
  203. package/dist/viewability/ViewabilityManager.js.map +1 -0
  204. package/ios/RNFlashList.xcodeproj/project.pbxproj +3 -0
  205. package/ios/RNFlashList.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
  206. package/ios/Sources/AutoLayoutView.swift +294 -0
  207. package/ios/Sources/AutoLayoutViewComponentView.h +16 -0
  208. package/ios/Sources/AutoLayoutViewComponentView.mm +90 -0
  209. package/ios/Sources/AutoLayoutViewManager.mm +14 -0
  210. package/ios/Sources/AutoLayoutViewManager.swift +12 -0
  211. package/ios/Sources/CellContainerComponentView.h +18 -0
  212. package/ios/Sources/CellContainerComponentView.mm +62 -0
  213. package/ios/Sources/CellContainerManager.mm +8 -0
  214. package/ios/Sources/CellContainerManager.swift +12 -0
  215. package/ios/Sources/FlatListPro-Bridging-Header.h +11 -0
  216. package/ios/Tests/AutoLayoutViewTests.swift +113 -0
  217. package/package.json +14 -3
  218. package/src/AnimatedFlashList.ts +2 -2
  219. package/src/FlashList.tsx +953 -0
  220. package/src/FlashListProps.ts +79 -3
  221. package/src/GridLayoutProviderWithProps.ts +180 -0
  222. package/src/MasonryFlashList.tsx +476 -0
  223. package/src/PureComponentWrapper.tsx +42 -0
  224. package/src/__tests__/ContentContainerUtils.test.ts +130 -0
  225. package/src/__tests__/FlashList.test.tsx +1001 -0
  226. package/src/__tests__/GridLayoutProviderWithProps.test.ts +179 -0
  227. package/src/__tests__/MasonryFlashList.test.ts +292 -0
  228. package/src/__tests__/PlatformHelper.web.test.ts +45 -0
  229. package/src/__tests__/ViewabilityHelper.test.ts +14 -13
  230. package/src/__tests__/helpers/mountFlashList.tsx +62 -0
  231. package/src/__tests__/helpers/mountMasonryFlashList.tsx +70 -0
  232. package/src/__tests__/useBlankAreaTracker.test.tsx +206 -0
  233. package/src/benchmark/JSFPSMonitor.ts +3 -3
  234. package/src/benchmark/useBenchmark.ts +40 -12
  235. package/src/benchmark/useBlankAreaTracker.ts +117 -0
  236. package/src/benchmark/useFlatListBenchmark.ts +1 -3
  237. package/src/enableNewCore.ts +24 -0
  238. package/src/errors/CustomError.ts +10 -0
  239. package/src/errors/ExceptionList.ts +28 -0
  240. package/src/errors/Warnings.ts +15 -0
  241. package/src/index.ts +43 -7
  242. package/src/native/auto-layout/AutoLayoutView.tsx +73 -0
  243. package/src/native/auto-layout/AutoLayoutViewNativeComponent.android.ts +7 -0
  244. package/src/native/auto-layout/AutoLayoutViewNativeComponent.ios.ts +7 -0
  245. package/src/native/auto-layout/AutoLayoutViewNativeComponent.ts +7 -0
  246. package/src/native/auto-layout/AutoLayoutViewNativeComponentProps.ts +17 -0
  247. package/src/native/cell-container/CellContainer.android.ts +7 -0
  248. package/src/native/cell-container/CellContainer.ios.ts +7 -0
  249. package/src/native/cell-container/CellContainer.tsx +14 -0
  250. package/src/native/cell-container/CellContainer.web.tsx +9 -0
  251. package/src/native/config/PlatformHelper.android.ts +25 -1
  252. package/src/native/config/PlatformHelper.ios.ts +24 -1
  253. package/src/native/config/PlatformHelper.ts +25 -1
  254. package/src/native/config/PlatformHelper.web.ts +30 -1
  255. package/src/recyclerview/RecyclerView.tsx +11 -6
  256. package/src/recyclerview/RecyclerViewManager.ts +18 -9
  257. package/src/recyclerview/RecyclerViewProps.ts +11 -1
  258. package/src/recyclerview/helpers/RenderTimeTracker.ts +8 -0
  259. package/src/recyclerview/hooks/useRecyclerViewController.tsx +0 -4
  260. package/src/recyclerview/layout-managers/LayoutManager.ts +1 -2
  261. package/src/specs/AutoLayoutNativeComponent.ts +24 -0
  262. package/src/specs/CellContainerNativeComponent.ts +9 -0
  263. package/src/utils/ContentContainerUtils.ts +92 -0
  264. package/src/{recyclerview/viewability → viewability}/ViewabilityHelper.ts +9 -8
  265. package/src/{recyclerview/viewability → viewability}/ViewabilityManager.ts +20 -18
  266. package/dist/errors/ErrorMessages.d.ts +0 -16
  267. package/dist/errors/ErrorMessages.d.ts.map +0 -1
  268. package/dist/errors/ErrorMessages.js +0 -19
  269. package/dist/errors/ErrorMessages.js.map +0 -1
  270. package/dist/errors/WarningMessages.d.ts +0 -4
  271. package/dist/errors/WarningMessages.d.ts.map +0 -1
  272. package/dist/errors/WarningMessages.js +0 -7
  273. package/dist/errors/WarningMessages.js.map +0 -1
  274. package/dist/isNewArch.d.ts +0 -2
  275. package/dist/isNewArch.d.ts.map +0 -1
  276. package/dist/isNewArch.js +0 -25
  277. package/dist/isNewArch.js.map +0 -1
  278. package/dist/recyclerview/viewability/ViewToken.d.ts.map +0 -1
  279. package/dist/recyclerview/viewability/ViewToken.js.map +0 -1
  280. package/dist/recyclerview/viewability/ViewabilityHelper.d.ts.map +0 -1
  281. package/dist/recyclerview/viewability/ViewabilityManager.d.ts.map +0 -1
  282. package/dist/recyclerview/viewability/ViewabilityManager.js.map +0 -1
  283. package/src/FlashList.ts +0 -1
  284. package/src/errors/ErrorMessages.ts +0 -26
  285. package/src/errors/WarningMessages.ts +0 -4
  286. package/src/isNewArch.ts +0 -25
  287. /package/dist/{recyclerview/viewability → viewability}/ViewToken.d.ts +0 -0
  288. /package/dist/{recyclerview/viewability → viewability}/ViewToken.js +0 -0
  289. /package/src/{recyclerview/viewability → viewability}/ViewToken.ts +0 -0
@@ -0,0 +1,70 @@
1
+ import React from "react";
2
+ import { Text } from "react-native";
3
+ import "@quilted/react-testing/matchers";
4
+ import { render, Root } from "@quilted/react-testing";
5
+
6
+ import { ListRenderItem } from "../../FlashListProps";
7
+ import {
8
+ MasonryFlashList,
9
+ MasonryFlashListProps,
10
+ MasonryFlashListRef,
11
+ } from "../../MasonryFlashList";
12
+
13
+ jest.mock("../../FlashList", () => {
14
+ const ActualFlashList = jest.requireActual("../../FlashList").default;
15
+ class MockFlashList extends ActualFlashList {
16
+ componentDidMount() {
17
+ super.componentDidMount();
18
+ this.rlvRef?._scrollComponent?._scrollViewRef?.props.onLayout({
19
+ nativeEvent: {
20
+ layout: {
21
+ height: this.props.estimatedListSize?.height ?? 900,
22
+ width: this.props.estimatedListSize?.width ?? 400,
23
+ },
24
+ },
25
+ });
26
+ }
27
+ }
28
+ return MockFlashList;
29
+ });
30
+
31
+ export type MockMasonryFlashListProps = Omit<
32
+ MasonryFlashListProps<string>,
33
+ "estimatedItemSize" | "data" | "renderItem"
34
+ > & {
35
+ estimatedItemSize?: number;
36
+ data?: string[];
37
+ renderItem?: ListRenderItem<string>;
38
+ };
39
+
40
+ /**
41
+ * Helper to mount MasonryFlashList for testing.
42
+ */
43
+ export const mountMasonryFlashList = (
44
+ props?: MockMasonryFlashListProps,
45
+ ref?: React.RefObject<MasonryFlashListRef<string>>
46
+ ) => {
47
+ const flashList = render(renderMasonryFlashList(props, ref)) as Omit<
48
+ Root<MasonryFlashListProps<string>>,
49
+ "instance"
50
+ > & {
51
+ instance: MasonryFlashListRef<string>;
52
+ };
53
+ return flashList;
54
+ };
55
+
56
+ export function renderMasonryFlashList(
57
+ props?: MockMasonryFlashListProps,
58
+ ref?: React.RefObject<MasonryFlashListRef<string>>
59
+ ) {
60
+ return (
61
+ <MasonryFlashList
62
+ {...props}
63
+ ref={ref}
64
+ numColumns={props?.numColumns ?? 2}
65
+ renderItem={props?.renderItem || (({ item }) => <Text>{item}</Text>)}
66
+ estimatedItemSize={props?.estimatedItemSize ?? 200}
67
+ data={props?.data || ["One", "Two", "Three", "Four"]}
68
+ />
69
+ );
70
+ }
@@ -0,0 +1,206 @@
1
+ import React, { useEffect } from "react";
2
+ import { render } from "@quilted/react-testing";
3
+
4
+ import {
5
+ BlankAreaTrackerConfig,
6
+ BlankAreaTrackerResult,
7
+ useBlankAreaTracker,
8
+ } from "../benchmark/useBlankAreaTracker";
9
+ import FlashList from "../FlashList";
10
+
11
+ import { MockFlashListProps, renderFlashList } from "./helpers/mountFlashList";
12
+
13
+ type BlankTrackingFlashListProps = MockFlashListProps & {
14
+ onCumulativeBlankAreaResult?: (result: BlankAreaTrackerResult) => void;
15
+ onCumulativeBlankAreaChange?: (updatedResult: BlankAreaTrackerResult) => void;
16
+ blankAreaTrackerConfig?: BlankAreaTrackerConfig;
17
+ instance?: React.RefObject<FlashList<any>>;
18
+ };
19
+
20
+ const BlankTrackingFlashList = (props?: BlankTrackingFlashListProps) => {
21
+ const ref = props?.instance!;
22
+ const [blankAreaTrackerResult, onBlankArea] = useBlankAreaTracker(
23
+ ref,
24
+ props?.onCumulativeBlankAreaChange,
25
+ {
26
+ startDelayInMs: props?.blankAreaTrackerConfig?.startDelayInMs ?? 500,
27
+ sumNegativeValues:
28
+ props?.blankAreaTrackerConfig?.sumNegativeValues ?? false,
29
+ }
30
+ );
31
+ useEffect(() => {
32
+ return () => {
33
+ props?.onCumulativeBlankAreaResult?.(blankAreaTrackerResult);
34
+ };
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ }, []);
37
+ return renderFlashList(
38
+ { ...props, onBlankArea, estimatedItemSize: 400 },
39
+ ref
40
+ );
41
+ };
42
+
43
+ const mountBlankTrackingFlashList = (props?: BlankTrackingFlashListProps) => {
44
+ const flashListRef: React.RefObject<FlashList<any>> = {
45
+ current: null,
46
+ };
47
+ const blankTrackingFlashList = render(
48
+ <BlankTrackingFlashList {...props} instance={flashListRef} />
49
+ );
50
+ return {
51
+ root: blankTrackingFlashList,
52
+ instance: flashListRef.current!,
53
+ };
54
+ };
55
+
56
+ describe("useBlankAreaTracker Hook", () => {
57
+ beforeEach(() => {
58
+ jest.clearAllMocks();
59
+ jest.useFakeTimers();
60
+ });
61
+
62
+ it("ignores blank events for 500ms on mount and if content is not enough to fill the list", () => {
63
+ const onCumulativeBlankAreaChange = jest.fn();
64
+ const flashList = mountBlankTrackingFlashList({
65
+ onCumulativeBlankAreaChange,
66
+ });
67
+ flashList.instance.props.onBlankArea!({
68
+ blankArea: 100,
69
+ offsetEnd: 100,
70
+ offsetStart: 0,
71
+ });
72
+ flashList.instance.props.onBlankArea!({
73
+ blankArea: 100,
74
+ offsetEnd: 100,
75
+ offsetStart: 0,
76
+ });
77
+ jest.advanceTimersByTime(400);
78
+ flashList.instance.props.onBlankArea!({
79
+ blankArea: 100,
80
+ offsetEnd: 100,
81
+ offsetStart: 0,
82
+ });
83
+ expect(onCumulativeBlankAreaChange).toHaveBeenCalledTimes(0);
84
+ jest.advanceTimersByTime(100);
85
+ flashList.instance.props.onBlankArea!({
86
+ blankArea: 100,
87
+ offsetEnd: 100,
88
+ offsetStart: 0,
89
+ });
90
+ expect(onCumulativeBlankAreaChange).toHaveBeenCalledTimes(1);
91
+ onCumulativeBlankAreaChange.mockClear();
92
+
93
+ flashList.root.setProps({ data: ["1"] });
94
+ flashList.instance.props.onBlankArea!({
95
+ blankArea: 100,
96
+ offsetEnd: 100,
97
+ offsetStart: 0,
98
+ });
99
+ expect(onCumulativeBlankAreaChange).toHaveBeenCalledTimes(0);
100
+ flashList.root.unmount();
101
+ });
102
+ it("keeps result object updated with correct values on unmount", () => {
103
+ let resultObjectCopy: BlankAreaTrackerResult | undefined;
104
+ const onCumulativeBlankAreaChange = jest.fn(
105
+ (result: BlankAreaTrackerResult) => {
106
+ if (!resultObjectCopy) {
107
+ resultObjectCopy = result;
108
+ }
109
+ }
110
+ );
111
+ const onCumulativeBlankAreaResult = jest.fn();
112
+ const flashList = mountBlankTrackingFlashList({
113
+ onCumulativeBlankAreaResult,
114
+ onCumulativeBlankAreaChange,
115
+ blankAreaTrackerConfig: { startDelayInMs: 300 },
116
+ });
117
+ flashList.instance.props.onBlankArea!({
118
+ blankArea: 100,
119
+ offsetEnd: 100,
120
+ offsetStart: 0,
121
+ });
122
+ jest.advanceTimersByTime(300);
123
+ flashList.instance.props.onBlankArea!({
124
+ blankArea: 100,
125
+ offsetEnd: 100,
126
+ offsetStart: 0,
127
+ });
128
+ expect(resultObjectCopy!.cumulativeBlankArea).toBe(100);
129
+ expect(resultObjectCopy!.maxBlankArea).toBe(100);
130
+
131
+ flashList.instance.props.onBlankArea!({
132
+ blankArea: 200,
133
+ offsetEnd: 200,
134
+ offsetStart: 0,
135
+ });
136
+ flashList.instance.props.onBlankArea!({
137
+ blankArea: -200,
138
+ offsetEnd: -200,
139
+ offsetStart: 0,
140
+ });
141
+ expect(resultObjectCopy!.cumulativeBlankArea).toBe(300);
142
+ expect(resultObjectCopy!.maxBlankArea).toBe(200);
143
+
144
+ flashList.root.unmount();
145
+ expect(onCumulativeBlankAreaResult).toHaveBeenCalledWith(resultObjectCopy!);
146
+ });
147
+ it("can track negative values on demand", () => {
148
+ const onCumulativeBlankAreaResult = jest.fn();
149
+ const flashList = mountBlankTrackingFlashList({
150
+ onCumulativeBlankAreaResult,
151
+ blankAreaTrackerConfig: { sumNegativeValues: true },
152
+ });
153
+ flashList.instance.props.onBlankArea!({
154
+ blankArea: -200,
155
+ offsetEnd: -200,
156
+ offsetStart: 0,
157
+ });
158
+ jest.advanceTimersByTime(500);
159
+ flashList.instance.props.onBlankArea!({
160
+ blankArea: -200,
161
+ offsetEnd: -200,
162
+ offsetStart: 0,
163
+ });
164
+ flashList.instance.props.onBlankArea!({
165
+ blankArea: -200,
166
+ offsetEnd: -200,
167
+ offsetStart: 0,
168
+ });
169
+ flashList.root.unmount();
170
+ expect(onCumulativeBlankAreaResult).toHaveBeenCalledWith({
171
+ cumulativeBlankArea: -400,
172
+ maxBlankArea: 0,
173
+ });
174
+ });
175
+ it("only calls onCumulativeBlankAreaChange when values have a change", () => {
176
+ const onCumulativeBlankAreaChange = jest.fn();
177
+ const flashList = mountBlankTrackingFlashList({
178
+ onCumulativeBlankAreaChange,
179
+ });
180
+ flashList.instance.props.onBlankArea!({
181
+ blankArea: -200,
182
+ offsetEnd: -200,
183
+ offsetStart: 0,
184
+ });
185
+ jest.advanceTimersByTime(500);
186
+ flashList.instance.props.onBlankArea!({
187
+ blankArea: -200,
188
+ offsetEnd: -200,
189
+ offsetStart: 0,
190
+ });
191
+ expect(onCumulativeBlankAreaChange).toHaveBeenCalledTimes(0);
192
+ flashList.instance.props.onBlankArea!({
193
+ blankArea: -100,
194
+ offsetEnd: -100,
195
+ offsetStart: 0,
196
+ });
197
+ expect(onCumulativeBlankAreaChange).toHaveBeenCalledTimes(0);
198
+ flashList.instance.props.onBlankArea!({
199
+ blankArea: 100,
200
+ offsetEnd: 100,
201
+ offsetStart: 0,
202
+ });
203
+ expect(onCumulativeBlankAreaChange).toHaveBeenCalledTimes(1);
204
+ flashList.root.unmount();
205
+ });
206
+ });
@@ -1,5 +1,3 @@
1
- import { ErrorMessages } from "../errors/ErrorMessages";
2
-
3
1
  import { roundToDecimalPlaces } from "./roundToDecimalPlaces";
4
2
 
5
3
  /**
@@ -46,7 +44,9 @@ export class JSFPSMonitor {
46
44
 
47
45
  public startTracking() {
48
46
  if (this.startTime !== 0) {
49
- throw new Error(ErrorMessages.fpsMonitorAlreadyRunning);
47
+ throw new Error(
48
+ "This FPS Monitor has already been run, please create a new instance"
49
+ );
50
50
  }
51
51
  this.startTime = Date.now();
52
52
  this.timeWindow.startTime = Date.now();
@@ -1,10 +1,14 @@
1
1
  import React, { useEffect } from "react";
2
2
 
3
- import { FlashListRef } from "../FlashListRef";
4
- import { ErrorMessages } from "../errors/ErrorMessages";
3
+ import FlashList from "../FlashList";
5
4
 
6
5
  import { autoScroll, Cancellable } from "./AutoScrollHelper";
7
6
  import { JSFPSMonitor, JSFPSResult } from "./JSFPSMonitor";
7
+ import { roundToDecimalPlaces } from "./roundToDecimalPlaces";
8
+ import {
9
+ BlankAreaTrackerResult,
10
+ useBlankAreaTracker,
11
+ } from "./useBlankAreaTracker";
8
12
 
9
13
  export interface BenchmarkParams {
10
14
  startDelayInMs?: number;
@@ -30,6 +34,7 @@ export interface BenchmarkResult {
30
34
  js?: JSFPSResult;
31
35
  interrupted: boolean;
32
36
  suggestions: string[];
37
+ blankArea?: BlankAreaTrackerResult;
33
38
  formattedString?: string;
34
39
  }
35
40
 
@@ -40,16 +45,21 @@ export interface BenchmarkResult {
40
45
  */
41
46
 
42
47
  export function useBenchmark(
43
- flashListRef: React.RefObject<FlashListRef<any>>,
48
+ flashListRef: React.RefObject<FlashList<any>>,
44
49
  callback: (benchmarkResult: BenchmarkResult) => void,
45
50
  params: BenchmarkParams = {}
46
51
  ) {
52
+ const [blankAreaResult, blankAreaTracker] = useBlankAreaTracker(
53
+ flashListRef,
54
+ undefined,
55
+ { sumNegativeValues: params.sumNegativeBlankAreaValues, startDelayInMs: 0 }
56
+ );
47
57
  useEffect(() => {
48
58
  const cancellable = new Cancellable();
49
59
  const suggestions: string[] = [];
50
60
  if (flashListRef.current) {
51
61
  if (!(Number(flashListRef.current.props.data?.length) > 0)) {
52
- throw new Error(ErrorMessages.dataEmptyCannotRunBenchmark);
62
+ throw new Error("Data is empty, cannot run benchmark");
53
63
  }
54
64
  }
55
65
  const cancelTimeout = setTimeout(async () => {
@@ -71,6 +81,7 @@ export function useBenchmark(
71
81
  computeSuggestions(flashListRef, suggestions);
72
82
  const result: BenchmarkResult = generateResult(
73
83
  jsProfilerResponse,
84
+ blankAreaResult,
74
85
  suggestions,
75
86
  cancellable
76
87
  );
@@ -85,12 +96,18 @@ export function useBenchmark(
85
96
  };
86
97
  // eslint-disable-next-line react-hooks/exhaustive-deps
87
98
  }, []);
99
+ return [blankAreaTracker];
88
100
  }
89
101
 
90
102
  export function getFormattedString(res: BenchmarkResult) {
91
103
  return (
92
104
  `Results:\n\n` +
93
105
  `JS FPS: Avg: ${res.js?.averageFPS} | Min: ${res.js?.minFPS} | Max: ${res.js?.maxFPS}\n\n` +
106
+ `${
107
+ res.blankArea
108
+ ? `Blank Area: Max: ${res.blankArea?.maxBlankArea} Cumulative: ${res.blankArea?.cumulativeBlankArea}\n\n`
109
+ : ``
110
+ }` +
94
111
  `${
95
112
  res.suggestions.length > 0
96
113
  ? `Suggestions:\n\n${res.suggestions
@@ -103,11 +120,22 @@ export function getFormattedString(res: BenchmarkResult) {
103
120
 
104
121
  function generateResult(
105
122
  jsProfilerResponse: JSFPSResult,
123
+ blankAreaResult: BlankAreaTrackerResult,
106
124
  suggestions: string[],
107
125
  cancellable: Cancellable
108
126
  ) {
109
127
  return {
110
128
  js: jsProfilerResponse,
129
+ blankArea:
130
+ blankAreaResult.maxBlankArea >= 0
131
+ ? {
132
+ maxBlankArea: roundToDecimalPlaces(blankAreaResult.maxBlankArea, 0),
133
+ cumulativeBlankArea: roundToDecimalPlaces(
134
+ blankAreaResult.cumulativeBlankArea,
135
+ 0
136
+ ),
137
+ }
138
+ : undefined,
111
139
  suggestions,
112
140
  interrupted: cancellable.isCancelled(),
113
141
  };
@@ -117,21 +145,21 @@ function generateResult(
117
145
  * Scrolls to the end of the list and then back to the top
118
146
  */
119
147
  async function runScrollBenchmark(
120
- flashListRef: React.RefObject<FlashListRef<any> | null | undefined>,
148
+ flashListRef: React.RefObject<FlashList<any> | null | undefined>,
121
149
  cancellable: Cancellable,
122
150
  scrollSpeedMultiplier: number
123
151
  ): Promise<void> {
124
152
  if (flashListRef.current) {
125
153
  const horizontal = flashListRef.current.props.horizontal;
126
- const rv = flashListRef.current;
127
- if (rv) {
128
- const rvSize = rv.getWindowSize();
129
- const rvContentSize = rv.getChildContainerDimensions();
154
+ const rlv = flashListRef.current.recyclerlistview_unsafe;
155
+ if (rlv) {
156
+ const rlvSize = rlv.getRenderedSize();
157
+ const rlvContentSize = rlv.getContentDimension();
130
158
 
131
159
  const fromX = 0;
132
160
  const fromY = 0;
133
- const toX = rvContentSize.width - rvSize.width;
134
- const toY = rvContentSize.height - rvSize.height;
161
+ const toX = rlvContentSize.width - rlvSize.width;
162
+ const toY = rlvContentSize.height - rlvSize.height;
135
163
 
136
164
  const scrollNow = (x: number, y: number) => {
137
165
  flashListRef.current?.scrollToOffset({
@@ -162,7 +190,7 @@ async function runScrollBenchmark(
162
190
  }
163
191
  }
164
192
  function computeSuggestions(
165
- flashListRef: React.RefObject<FlashListRef<any> | null | undefined>,
193
+ flashListRef: React.RefObject<FlashList<any> | null | undefined>,
166
194
  suggestions: string[]
167
195
  ) {
168
196
  if (flashListRef.current) {
@@ -0,0 +1,117 @@
1
+ import React, { useCallback, useRef } from "react";
2
+ import { RecyclerListView, RecyclerListViewProps } from "recyclerlistview";
3
+
4
+ import { BlankAreaEvent } from "../native/auto-layout/AutoLayoutView";
5
+ import FlashList from "../FlashList";
6
+
7
+ export interface BlankAreaTrackerResult {
8
+ /**
9
+ * Max blank area displayed
10
+ */
11
+ maxBlankArea: number;
12
+ /**
13
+ * Sum of all blank area values across all frames
14
+ */
15
+ cumulativeBlankArea: number;
16
+ }
17
+ export interface BlankAreaTrackerConfig {
18
+ /**
19
+ * When set to true the hook will also sum all negative blank area values.
20
+ * Blank area is negative when list is able to draw faster than the scroll speed.
21
+ */
22
+ sumNegativeValues?: boolean;
23
+ /**
24
+ * By default, the hook ignores blank events for 1s after the list load. This value can be changed using this parameter.
25
+ * Please note that this duration kicks in after the list has loaded and not after the first scroll.
26
+ */
27
+ startDelayInMs?: number;
28
+ }
29
+
30
+ /**
31
+ * Can be used to track visible blank area in production
32
+ * @param flashListRef Ref to the FlashList component
33
+ * @param onBlankAreaChange This event handler will be called when the blank area changes
34
+ * @param config additional configuration for the blank area tracker
35
+ * @returns blankAreaTrackerResult - maxBlankArea, cumulativeBlankArea this object is mutated and kept up to date. Also returns a callback that needs to be forwarded to FlashList.
36
+ */
37
+ export function useBlankAreaTracker(
38
+ flashListRef: React.RefObject<FlashList<any>>,
39
+ onBlankAreaChange?: (value: BlankAreaTrackerResult) => void,
40
+ config?: BlankAreaTrackerConfig
41
+ ): [BlankAreaTrackerResult, (event: BlankAreaEvent) => void] {
42
+ const startDelay = config?.startDelayInMs ?? 1000;
43
+ const blankAreaResult = useRef({
44
+ maxBlankArea: 0,
45
+ cumulativeBlankArea: 0,
46
+ }).current;
47
+ const waitOperations = useRef({ inProgress: false, complete: false }).current;
48
+ const onBlankAreaChangeRef = useRef(onBlankAreaChange);
49
+ onBlankAreaChangeRef.current = onBlankAreaChange;
50
+
51
+ const blankAreaTracker = useCallback(
52
+ (event: BlankAreaEvent) => {
53
+ // we're ignoring some of the events that will be fired on list load
54
+ // initial events are fired on mount and thus, this won't lead to missing events during scroll
55
+ if (!waitOperations.complete && startDelay > 0) {
56
+ if (!waitOperations.inProgress) {
57
+ waitOperations.inProgress = true;
58
+ setTimeout(() => {
59
+ waitOperations.complete = true;
60
+ }, startDelay);
61
+ }
62
+ return;
63
+ }
64
+ const rlv = flashListRef.current?.recyclerlistview_unsafe;
65
+ const horizontal = Boolean(flashListRef.current?.props.horizontal);
66
+ if (rlv) {
67
+ processBlankAreaChange(
68
+ rlv,
69
+ horizontal,
70
+ blankAreaResult,
71
+ event,
72
+ onBlankAreaChangeRef.current,
73
+ config
74
+ );
75
+ }
76
+ },
77
+ // eslint-disable-next-line react-hooks/exhaustive-deps
78
+ [flashListRef]
79
+ );
80
+ return [blankAreaResult, blankAreaTracker];
81
+ }
82
+
83
+ function processBlankAreaChange(
84
+ rlv: RecyclerListView<RecyclerListViewProps, any>,
85
+ horizontal: boolean,
86
+ blankAreaResult: BlankAreaTrackerResult,
87
+ event: BlankAreaEvent,
88
+ onBlankAreaChange?: (value: BlankAreaTrackerResult) => void,
89
+ config?: BlankAreaTrackerConfig
90
+ ) {
91
+ const listSize = horizontal
92
+ ? rlv.getRenderedSize().width
93
+ : rlv.getRenderedSize().height;
94
+ const contentSize = horizontal
95
+ ? rlv.getContentDimension().width
96
+ : rlv.getContentDimension().height;
97
+
98
+ // ignores blank events when there isn't enough content to fill the list
99
+ if (contentSize > listSize) {
100
+ const lastMaxBlankArea = blankAreaResult.maxBlankArea;
101
+ const lastCumulativeBlankArea = blankAreaResult.cumulativeBlankArea;
102
+ blankAreaResult.maxBlankArea = Math.max(
103
+ blankAreaResult.maxBlankArea,
104
+ event.blankArea,
105
+ 0
106
+ );
107
+ blankAreaResult.cumulativeBlankArea += config?.sumNegativeValues
108
+ ? event.blankArea
109
+ : Math.max(event.blankArea, 0);
110
+ if (
111
+ lastCumulativeBlankArea !== blankAreaResult.cumulativeBlankArea ||
112
+ lastMaxBlankArea !== blankAreaResult.maxBlankArea
113
+ ) {
114
+ onBlankAreaChange?.(blankAreaResult);
115
+ }
116
+ }
117
+ }
@@ -1,8 +1,6 @@
1
1
  import { useEffect } from "react";
2
2
  import { FlatList } from "react-native";
3
3
 
4
- import { ErrorMessages } from "../errors/ErrorMessages";
5
-
6
4
  import { autoScroll, Cancellable } from "./AutoScrollHelper";
7
5
  import { JSFPSMonitor } from "./JSFPSMonitor";
8
6
  import {
@@ -29,7 +27,7 @@ export function useFlatListBenchmark(
29
27
  const cancellable = new Cancellable();
30
28
  if (flatListRef.current && flatListRef.current.props) {
31
29
  if (!(Number(flatListRef.current.props.data?.length) > 0)) {
32
- throw new Error(ErrorMessages.dataEmptyCannotRunBenchmark);
30
+ throw new Error("Data is empty, cannot run benchmark");
33
31
  }
34
32
  }
35
33
  const cancelTimeout = setTimeout(async () => {
@@ -0,0 +1,24 @@
1
+ import { Platform } from "react-native";
2
+
3
+ let useNewCore: boolean | undefined;
4
+ export function enableNewCore(enable: boolean) {
5
+ useNewCore = enable;
6
+ }
7
+
8
+ export function isNewCoreEnabled() {
9
+ return useNewCore ?? isReactNativeNewArchitecture();
10
+ }
11
+
12
+ function isReactNativeNewArchitecture(): boolean {
13
+ try {
14
+ // Check for Fabric UI Manager
15
+ const hasFabricUIManager = Boolean((global as any)?.nativeFabricUIManager);
16
+
17
+ // Check for TurboModule system
18
+ const hasTurboModule = Boolean((global as any)?.__turboModuleProxy);
19
+
20
+ return hasFabricUIManager || hasTurboModule || Platform.OS === "web";
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
@@ -0,0 +1,10 @@
1
+ export default class CustomError extends Error {
2
+ constructor(exception: Exception) {
3
+ super(`${exception.type}: ${exception.message}`);
4
+ this.name = exception.type;
5
+ }
6
+ }
7
+ export interface Exception {
8
+ type: string;
9
+ message: string;
10
+ }
@@ -0,0 +1,28 @@
1
+ const ExceptionList = {
2
+ refreshBooleanMissing: {
3
+ message:
4
+ "`refreshing` prop must be set as a boolean in order to use `onRefresh`, but got `undefined`.",
5
+ type: "InvariantViolation",
6
+ },
7
+ stickyWhileHorizontalNotSupported: {
8
+ message:
9
+ "sticky headers are not supported when list is in horizontal mode. Remove `stickyHeaderIndices` prop.",
10
+ type: "NotSupportedException",
11
+ },
12
+ columnsWhileHorizontalNotSupported: {
13
+ message:
14
+ "numColumns is not supported when list is in horizontal mode. Please remove or set numColumns to 1.",
15
+ type: "NotSupportedException",
16
+ },
17
+ multipleViewabilityThresholdTypesNotSupported: {
18
+ message:
19
+ "You can set exactly one of itemVisiblePercentThreshold or viewAreaCoveragePercentThreshold. Specifying both is not supported.",
20
+ type: "MultipleViewabilityThresholdTypesException",
21
+ },
22
+ overrideItemLayoutRequiredForMasonryOptimization: {
23
+ message:
24
+ "optimizeItemArrangement has been enabled on `MasonryFlashList` but overrideItemLayout is not set.",
25
+ type: "InvariantViolation",
26
+ },
27
+ };
28
+ export default ExceptionList;
@@ -0,0 +1,15 @@
1
+ const WarningList = {
2
+ styleUnsupported:
3
+ "You have passed a style to FlashList. This list doesn't support styling, use contentContainerStyle or wrap the list in a parent and apply style to it instead.",
4
+ styleContentContainerUnsupported:
5
+ "FlashList only supports padding related props and backgroundColor in contentContainerStyle. Please remove other values as they're not used.",
6
+ unusableRenderedSize:
7
+ "FlashList's rendered size is not usable. Either the height or width is too small (<2px). " +
8
+ "Please make sure that the parent view of the list has a valid size. FlashList will match the size of the parent.",
9
+ missingKeyExtractor:
10
+ "FlashList requires a keyExtractor prop to be defined when animating elements. Without it, the animations will not run as expected.",
11
+ estimatedItemSizeMissingWarning:
12
+ "estimatedItemSize FlashList prop is not defined - based on current configuration you can set it to @size to optimize list performance. " +
13
+ "Refer to FlashList documentation for more details.",
14
+ };
15
+ export default WarningList;