react-native-list 1.0.1 → 2.0.0-alpha.2

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 (224) hide show
  1. package/README.md +186 -32
  2. package/ReactNativeList.podspec +39 -0
  3. package/android/CMakeLists.txt +48 -0
  4. package/android/build.gradle +151 -0
  5. package/android/fix-prefab.gradle +51 -0
  6. package/android/gradle.properties +5 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/cpp/JHybridUiListModule.cpp +192 -0
  9. package/android/src/main/cpp/JHybridUiListModule.h +50 -0
  10. package/android/src/main/cpp/cpp-adapter.cpp +12 -0
  11. package/android/src/main/java/com/hannojg/reactnativelist/ReactNativeListPackage.kt +27 -0
  12. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridNativeListDataSource.kt +146 -0
  13. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridNativeListLayout.kt +86 -0
  14. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridUiListModule.kt +116 -0
  15. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridUiListView.kt +410 -0
  16. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridViewHolder.kt +9 -0
  17. package/android/src/main/java/com/margelo/nitro/reactnativelist/NativeListAdapter.kt +217 -0
  18. package/ios/DataSource/HybridNativeListDataSource.swift +213 -0
  19. package/ios/HybridObjects/HybridUiListModule.swift +49 -0
  20. package/ios/HybridObjects/HybridViewHolder.swift +16 -0
  21. package/ios/Layout/HybridNativeListLayout.swift +128 -0
  22. package/ios/Utils/ErrorUtils.h +26 -0
  23. package/ios/Utils/HybridIOSWorkletsModuleProxyHolder.swift +10 -0
  24. package/ios/Utils/SurfaceHelper.h +20 -0
  25. package/ios/Utils/SurfaceHelper.mm +144 -0
  26. package/ios/Utils/SurfacePresenterRegistry.h +17 -0
  27. package/ios/Utils/SurfacePresenterRegistry.m +31 -0
  28. package/ios/Utils/TurboModuleInstaller.h +18 -0
  29. package/ios/Utils/TurboModuleInstaller.mm +267 -0
  30. package/ios/Views/HostCell.swift +216 -0
  31. package/ios/Views/HybridUiListView.swift +695 -0
  32. package/lib/ReactFabricMirror.d.ts +4 -0
  33. package/lib/ReactFabricMirror.js +515 -0
  34. package/lib/UiListModule.d.ts +2 -0
  35. package/lib/UiListModule.js +2 -0
  36. package/lib/index.d.ts +8 -0
  37. package/lib/index.js +21 -0
  38. package/lib/privateGlobals.d.ts +14 -0
  39. package/lib/privateGlobals.js +2 -0
  40. package/lib/renderer/RenderHelper.d.ts +2 -0
  41. package/lib/renderer/RenderHelper.js +11 -0
  42. package/lib/renderer/UiManagerHelper.d.ts +2 -0
  43. package/lib/renderer/UiManagerHelper.js +2 -0
  44. package/lib/renderer/fabric/RenderHelper.d.ts +2 -0
  45. package/lib/renderer/fabric/RenderHelper.js +11 -0
  46. package/lib/renderer/fabric/UiManagerHelper.d.ts +2 -0
  47. package/lib/renderer/fabric/UiManagerHelper.js +2 -0
  48. package/lib/renderer/react/ReactFabricMirror.d.ts +4 -0
  49. package/lib/renderer/react/ReactFabricMirror.js +515 -0
  50. package/lib/renderer/react/ReactFabricRenderer.d.ts +3 -0
  51. package/lib/renderer/react/ReactFabricRenderer.js +9 -0
  52. package/lib/specs/IOSWorkletsModuleProxyHolder.nitro.d.ts +6 -0
  53. package/lib/specs/IOSWorkletsModuleProxyHolder.nitro.js +1 -0
  54. package/lib/specs/UIListModule.nitro.d.ts +9 -0
  55. package/lib/specs/UIListModule.nitro.js +1 -0
  56. package/lib/specs/UIManagerHelper.nitro.d.ts +13 -0
  57. package/lib/specs/UIManagerHelper.nitro.js +1 -0
  58. package/lib/specs/UiListView.nitro.d.ts +20 -0
  59. package/lib/specs/UiListView.nitro.js +1 -0
  60. package/lib/specs/ViewHolder.nitro.d.ts +6 -0
  61. package/lib/specs/ViewHolder.nitro.js +1 -0
  62. package/lib/views/List.d.ts +35 -0
  63. package/lib/views/List.js +225 -0
  64. package/lib/views/UiListHostComponent.d.ts +2 -0
  65. package/lib/views/UiListHostComponent.js +3 -0
  66. package/metro/RendererProxyThreadSwitch.js +66 -0
  67. package/metro-config.d.ts +1 -0
  68. package/metro-config.js +124 -0
  69. package/nitro.json +47 -0
  70. package/nitrogen/generated/.gitattributes +1 -0
  71. package/nitrogen/generated/android/ReactNativeList+autolinking.cmake +99 -0
  72. package/nitrogen/generated/android/ReactNativeList+autolinking.gradle +27 -0
  73. package/nitrogen/generated/android/ReactNativeListOnLoad.cpp +156 -0
  74. package/nitrogen/generated/android/ReactNativeListOnLoad.hpp +34 -0
  75. package/nitrogen/generated/android/c++/JFunc_bool_NativeListItem_NativeListItem.hpp +83 -0
  76. package/nitrogen/generated/android/c++/JFunc_bool_double_NativeListItem_double.hpp +83 -0
  77. package/nitrogen/generated/android/c++/JFunc_double_std__string.hpp +78 -0
  78. package/nitrogen/generated/android/c++/JHybridIOSWorkletsModuleProxyHolderSpec.cpp +49 -0
  79. package/nitrogen/generated/android/c++/JHybridIOSWorkletsModuleProxyHolderSpec.hpp +63 -0
  80. package/nitrogen/generated/android/c++/JHybridNativeLinearListLayoutSpec.cpp +63 -0
  81. package/nitrogen/generated/android/c++/JHybridNativeLinearListLayoutSpec.hpp +65 -0
  82. package/nitrogen/generated/android/c++/JHybridNativeListDataSourceSpec.cpp +101 -0
  83. package/nitrogen/generated/android/c++/JHybridNativeListDataSourceSpec.hpp +70 -0
  84. package/nitrogen/generated/android/c++/JHybridNativeListLayoutSpec.cpp +49 -0
  85. package/nitrogen/generated/android/c++/JHybridNativeListLayoutSpec.hpp +63 -0
  86. package/nitrogen/generated/android/c++/JHybridUiListModuleSpec.cpp +65 -0
  87. package/nitrogen/generated/android/c++/JHybridUiListModuleSpec.hpp +64 -0
  88. package/nitrogen/generated/android/c++/JHybridUiListViewSpec.cpp +92 -0
  89. package/nitrogen/generated/android/c++/JHybridUiListViewSpec.hpp +67 -0
  90. package/nitrogen/generated/android/c++/JHybridViewHolderSpec.cpp +49 -0
  91. package/nitrogen/generated/android/c++/JHybridViewHolderSpec.hpp +63 -0
  92. package/nitrogen/generated/android/c++/JNativeItemSizeEstimate.hpp +61 -0
  93. package/nitrogen/generated/android/c++/JNativeLinearListLayoutConfig.hpp +81 -0
  94. package/nitrogen/generated/android/c++/JNativeLinearListLayoutIOSConfig.hpp +59 -0
  95. package/nitrogen/generated/android/c++/JNativeListItem.hpp +76 -0
  96. package/nitrogen/generated/android/c++/JVariant_NullType_HybridIOSWorkletsModuleProxyHolderSpec.cpp +26 -0
  97. package/nitrogen/generated/android/c++/JVariant_NullType_HybridIOSWorkletsModuleProxyHolderSpec.hpp +72 -0
  98. package/nitrogen/generated/android/c++/views/JHybridUiListViewStateUpdater.cpp +53 -0
  99. package/nitrogen/generated/android/c++/views/JHybridUiListViewStateUpdater.hpp +49 -0
  100. package/nitrogen/generated/android/c++/views/JHybridViewHolderStateUpdater.cpp +53 -0
  101. package/nitrogen/generated/android/c++/views/JHybridViewHolderStateUpdater.hpp +49 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Func_bool_NativeListItem_NativeListItem.kt +80 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Func_bool_double_NativeListItem_double.kt +80 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Func_double_std__string.kt +80 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridIOSWorkletsModuleProxyHolderSpec.kt +52 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridNativeLinearListLayoutSpec.kt +54 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridNativeListDataSourceSpec.kt +87 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridNativeListLayoutSpec.kt +52 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridUiListModuleSpec.kt +59 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridUiListViewSpec.kt +76 -0
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridViewHolderSpec.kt +53 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeItemSizeEstimate.kt +56 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeLinearListLayoutConfig.kt +76 -0
  114. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeLinearListLayoutIOSConfig.kt +51 -0
  115. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeListItem.kt +71 -0
  116. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/ReactNativeListOnLoad.kt +35 -0
  117. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Variant_NullType_HybridIOSWorkletsModuleProxyHolderSpec.kt +62 -0
  118. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridUiListViewManager.kt +80 -0
  119. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridUiListViewStateUpdater.kt +23 -0
  120. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridViewHolderManager.kt +80 -0
  121. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridViewHolderStateUpdater.kt +23 -0
  122. package/nitrogen/generated/ios/ReactNativeList+autolinking.rb +62 -0
  123. package/nitrogen/generated/ios/ReactNativeList-Swift-Cxx-Bridge.cpp +162 -0
  124. package/nitrogen/generated/ios/ReactNativeList-Swift-Cxx-Bridge.hpp +368 -0
  125. package/nitrogen/generated/ios/ReactNativeList-Swift-Cxx-Umbrella.hpp +92 -0
  126. package/nitrogen/generated/ios/ReactNativeListAutolinking.mm +83 -0
  127. package/nitrogen/generated/ios/ReactNativeListAutolinking.swift +86 -0
  128. package/nitrogen/generated/ios/c++/HybridIOSWorkletsModuleProxyHolderSpecSwift.cpp +11 -0
  129. package/nitrogen/generated/ios/c++/HybridIOSWorkletsModuleProxyHolderSpecSwift.hpp +75 -0
  130. package/nitrogen/generated/ios/c++/HybridNativeLinearListLayoutSpecSwift.cpp +11 -0
  131. package/nitrogen/generated/ios/c++/HybridNativeLinearListLayoutSpecSwift.hpp +92 -0
  132. package/nitrogen/generated/ios/c++/HybridNativeListDataSourceSpecSwift.cpp +11 -0
  133. package/nitrogen/generated/ios/c++/HybridNativeListDataSourceSpecSwift.hpp +132 -0
  134. package/nitrogen/generated/ios/c++/HybridNativeListLayoutSpecSwift.cpp +11 -0
  135. package/nitrogen/generated/ios/c++/HybridNativeListLayoutSpecSwift.hpp +75 -0
  136. package/nitrogen/generated/ios/c++/HybridUiListModuleSpecSwift.cpp +11 -0
  137. package/nitrogen/generated/ios/c++/HybridUiListModuleSpecSwift.hpp +93 -0
  138. package/nitrogen/generated/ios/c++/HybridUiListViewSpecSwift.cpp +11 -0
  139. package/nitrogen/generated/ios/c++/HybridUiListViewSpecSwift.hpp +121 -0
  140. package/nitrogen/generated/ios/c++/HybridViewHolderSpecSwift.cpp +11 -0
  141. package/nitrogen/generated/ios/c++/HybridViewHolderSpecSwift.hpp +75 -0
  142. package/nitrogen/generated/ios/c++/views/HybridUiListViewComponent.mm +118 -0
  143. package/nitrogen/generated/ios/c++/views/HybridViewHolderComponent.mm +118 -0
  144. package/nitrogen/generated/ios/swift/Func_bool_NativeListItem_NativeListItem.swift +47 -0
  145. package/nitrogen/generated/ios/swift/Func_bool_double_NativeListItem_double.swift +47 -0
  146. package/nitrogen/generated/ios/swift/Func_double_std__string.swift +47 -0
  147. package/nitrogen/generated/ios/swift/HybridIOSWorkletsModuleProxyHolderSpec.swift +55 -0
  148. package/nitrogen/generated/ios/swift/HybridIOSWorkletsModuleProxyHolderSpec_cxx.swift +128 -0
  149. package/nitrogen/generated/ios/swift/HybridNativeLinearListLayoutSpec.swift +55 -0
  150. package/nitrogen/generated/ios/swift/HybridNativeLinearListLayoutSpec_cxx.swift +140 -0
  151. package/nitrogen/generated/ios/swift/HybridNativeListDataSourceSpec.swift +62 -0
  152. package/nitrogen/generated/ios/swift/HybridNativeListDataSourceSpec_cxx.swift +222 -0
  153. package/nitrogen/generated/ios/swift/HybridNativeListLayoutSpec.swift +55 -0
  154. package/nitrogen/generated/ios/swift/HybridNativeListLayoutSpec_cxx.swift +128 -0
  155. package/nitrogen/generated/ios/swift/HybridUiListModuleSpec.swift +56 -0
  156. package/nitrogen/generated/ios/swift/HybridUiListModuleSpec_cxx.swift +175 -0
  157. package/nitrogen/generated/ios/swift/HybridUiListViewSpec.swift +59 -0
  158. package/nitrogen/generated/ios/swift/HybridUiListViewSpec_cxx.swift +227 -0
  159. package/nitrogen/generated/ios/swift/HybridViewHolderSpec.swift +55 -0
  160. package/nitrogen/generated/ios/swift/HybridViewHolderSpec_cxx.swift +147 -0
  161. package/nitrogen/generated/ios/swift/NativeItemSizeEstimate.swift +60 -0
  162. package/nitrogen/generated/ios/swift/NativeLinearListLayoutConfig.swift +60 -0
  163. package/nitrogen/generated/ios/swift/NativeLinearListLayoutIOSConfig.swift +35 -0
  164. package/nitrogen/generated/ios/swift/NativeListItem.swift +75 -0
  165. package/nitrogen/generated/ios/swift/Variant_NullType__any_HybridIOSWorkletsModuleProxyHolderSpec_.swift +30 -0
  166. package/nitrogen/generated/shared/c++/HybridIOSWorkletsModuleProxyHolderSpec.cpp +21 -0
  167. package/nitrogen/generated/shared/c++/HybridIOSWorkletsModuleProxyHolderSpec.hpp +62 -0
  168. package/nitrogen/generated/shared/c++/HybridNativeLinearListLayoutSpec.cpp +22 -0
  169. package/nitrogen/generated/shared/c++/HybridNativeLinearListLayoutSpec.hpp +67 -0
  170. package/nitrogen/generated/shared/c++/HybridNativeListDataSourceSpec.cpp +28 -0
  171. package/nitrogen/generated/shared/c++/HybridNativeListDataSourceSpec.hpp +72 -0
  172. package/nitrogen/generated/shared/c++/HybridNativeListLayoutSpec.cpp +21 -0
  173. package/nitrogen/generated/shared/c++/HybridNativeListLayoutSpec.hpp +62 -0
  174. package/nitrogen/generated/shared/c++/HybridUiListModuleSpec.cpp +22 -0
  175. package/nitrogen/generated/shared/c++/HybridUiListModuleSpec.hpp +68 -0
  176. package/nitrogen/generated/shared/c++/HybridUiListViewSpec.cpp +25 -0
  177. package/nitrogen/generated/shared/c++/HybridUiListViewSpec.hpp +79 -0
  178. package/nitrogen/generated/shared/c++/HybridUiManagerHelperSpec.cpp +23 -0
  179. package/nitrogen/generated/shared/c++/HybridUiManagerHelperSpec.hpp +65 -0
  180. package/nitrogen/generated/shared/c++/HybridViewHolderSpec.cpp +21 -0
  181. package/nitrogen/generated/shared/c++/HybridViewHolderSpec.hpp +62 -0
  182. package/nitrogen/generated/shared/c++/NativeItemSizeEstimate.hpp +87 -0
  183. package/nitrogen/generated/shared/c++/NativeLinearListLayoutConfig.hpp +105 -0
  184. package/nitrogen/generated/shared/c++/NativeLinearListLayoutIOSConfig.hpp +85 -0
  185. package/nitrogen/generated/shared/c++/NativeListItem.hpp +101 -0
  186. package/nitrogen/generated/shared/c++/views/HybridUiListViewComponent.cpp +72 -0
  187. package/nitrogen/generated/shared/c++/views/HybridUiListViewComponent.hpp +109 -0
  188. package/nitrogen/generated/shared/c++/views/HybridViewHolderComponent.cpp +72 -0
  189. package/nitrogen/generated/shared/c++/views/HybridViewHolderComponent.hpp +109 -0
  190. package/nitrogen/generated/shared/json/UiListViewConfig.json +9 -0
  191. package/nitrogen/generated/shared/json/ViewHolderConfig.json +9 -0
  192. package/package.json +152 -5
  193. package/react-native.config.js +16 -0
  194. package/src/ListDataSource.ts +232 -0
  195. package/src/ListLayout.ts +95 -0
  196. package/src/UiListModule.ts +5 -0
  197. package/src/hooks/useChangeEffect.ts +50 -0
  198. package/src/index.tsx +49 -0
  199. package/src/privateGlobals.ts +20 -0
  200. package/src/renderer/fabric/RenderHelper.ts +29 -0
  201. package/src/renderer/fabric/UiManagerHelper.ts +5 -0
  202. package/src/renderer/react/ReactFabricMirror.bundle.js +1984 -0
  203. package/src/renderer/react/ReactFabricMirror.ts +766 -0
  204. package/src/renderer/react/ReactFabricRenderer.ts +11 -0
  205. package/src/specs/IOSWorkletsModuleProxyHolder.nitro.ts +6 -0
  206. package/src/specs/NativeLinearListLayout.nitro.ts +23 -0
  207. package/src/specs/NativeListDataSource.nitro.ts +28 -0
  208. package/src/specs/NativeListLayout.nitro.ts +6 -0
  209. package/src/specs/UIListModule.nitro.ts +13 -0
  210. package/src/specs/UIManagerHelper.nitro.ts +34 -0
  211. package/src/specs/UiListView.nitro.ts +31 -0
  212. package/src/specs/ViewHolder.nitro.ts +11 -0
  213. package/src/views/List.tsx +525 -0
  214. package/src/views/UiListHostComponent.ts +8 -0
  215. package/FillRateHelper.js +0 -179
  216. package/FlatList.js +0 -494
  217. package/LICENSE.md +0 -31
  218. package/MetroListView.js +0 -166
  219. package/SectionList.js +0 -291
  220. package/ViewabilityHelper.js +0 -260
  221. package/VirtualizeUtils.js +0 -163
  222. package/VirtualizedList.js +0 -861
  223. package/VirtualizedSectionList.js +0 -397
  224. package/index.js +0 -5
package/README.md CHANGED
@@ -1,49 +1,203 @@
1
- FlatList, VirtualizedList, SectionList for React-Native < 0.43
2
- --
1
+ # React Native List
3
2
 
4
- This repository mimics the latest changes in React Native 0.43.
3
+ High-performance list for React Native.
5
4
 
6
- ## Motivation
7
- Currently, React-Native@0.43 depends on React@16.0.0-alpha6 which isn't yet supported by many libraries like Enzyme etc. Although, this version of RN brings us amazing list views: FlatList, VirtualizedList & SectionList. So there is a choice either to use 0.43 with its awesome lists or use 0.42 and being able to test your applications with Enzyme. Well, I choose both ;)
5
+ - 📱 True native [`UICollectionView`](https://developer.apple.com/documentation/uikit/uicollectionview) on iOS
6
+ - 🤖 True native [`RecyclerView`](https://developer.android.com/develop/ui/views/layout/recyclerview) on android
7
+ - 🔄 Synchronous rendering of react components using "worklet" function components
8
+ - 🐎 Platform native animations out of the box for list item transitions
9
+ - 📉 Low memory usage due to true native view recycling
8
10
 
9
- This package contains copied and adapted implementation of 0.43 list features to < 0.43 realms.
11
+ https://github.com/user-attachments/assets/4a2684bf-7337-45e0-bb17-ee7b8a382943
10
12
 
11
13
  ## Installation
12
14
 
13
- - Install package using your favorite manager:
15
+ > [!WARNING]
16
+ > Using this library requires you to use [react-native-worklets **bundle mode**](https://docs.swmansion.com/react-native-worklets/docs/bundleMode/setup).
17
+ >
18
+ > - Please follow [the setup instructions of it first](https://docs.swmansion.com/react-native-worklets/docs/bundleMode/setup), and make sure your app works before using react-native-list!
19
+ > - You need at least version 0.10.0!
14
20
 
15
- ```sh
16
- yarn add react-native-list
17
- ```
18
- or
19
- ```sh
20
- npm add react-native --save
21
- ```
21
+ Once that's out of the way, you can start with the regular setup of the library:
22
22
 
23
- - Add `react-native-list` to your `providesModuleNodeModules`:
23
+ ```sh
24
+ bun add react-native-list@alpha
25
+ ```
26
+
27
+ ### Configuring Metro
28
+
29
+ Simply wrap your config with `getReactNativeListMetroConfig` in `metro.config.js`:
30
+
31
+ ```js
32
+ const { getDefaultConfig } = require("expo/metro-config");
33
+ const {
34
+ getBundleModeMetroConfig,
35
+ } = require("react-native-worklets/bundleMode");
36
+
37
+ let config = getDefaultConfig(__dirname);
38
+ config = getBundleModeMetroConfig(config);
39
+ // ⚠️ Make sure to apply this _after_ the bundle mode metro config:
40
+ config = getReactNativeListMetroConfig(config);
41
+ module.exports = config;
42
+ ```
43
+
44
+ > [!NOTE]
45
+ > If you're using expo you need to make sure to enable inline requires in your metro config:
46
+ >
47
+ > ```js
48
+ > const config = {
49
+ > transformer: {
50
+ > getTransformOptions: async () => ({
51
+ > transform: {
52
+ > // Bundle mode only works with inline support
53
+ > // See: https://github.com/software-mansion/react-native-reanimated/issues/8904
54
+ > inlineRequires: true,
55
+ > },
56
+ > }),
57
+ > },
58
+ > };
59
+ > ```
60
+ >
61
+ > If you don't see a `metro.config.js` in your project, see [expo's documentation on modifying metro](https://docs.expo.dev/guides/customizing-metro/).
62
+
63
+ ## Simple example
64
+
65
+ ```tsx
66
+ import { List, useLinearListLayout, useListDataSource } from "react-native-list";
67
+ import type { ListItem, ListRenderers } from "react-native-list";
24
68
 
25
- - If you don't have `rn-cli.config.js`, create `rn-cli.config.js` in the root directory of your project:
69
+ type TextItem = ListItem<
70
+ // The type of your list item
71
+ "text",
72
+ // The data shape for that list item:
73
+ {
74
+ text: string;
75
+ }
76
+ >;
26
77
 
27
- ```js
28
- module.exports = {
29
- getProvidesModuleNodeModules() {
30
- return [
31
- 'react-native',
32
- 'react-native-windows',
33
- 'react-native-list',
34
- ];
78
+ type ImageItem = ...
79
+
80
+ type Items = TextItem | ImageItem
81
+
82
+ // Provide render functions for your item types:
83
+ const renderers: ListRenderers<Items> = {
84
+ text: {
85
+ renderItemWorklet: ({ item }) => {
86
+ "worklet"; // 👀 Note: our render function is a worklet!
87
+
88
+ return (
89
+ // Though being in a worklet, you can use any component you like in here
90
+ <View
91
+ style={{
92
+ justifyContent: "center",
93
+ paddingHorizontal: 16,
94
+ backgroundColor: "#f6f8fa",
95
+ }}
96
+ >
97
+ // Note: there are two phases: 1. View creation (without data), 2. binding data to the views
98
+ // that's why item.data can be undefined because the native list is requesting to
99
+ // create the view hierarchy, but without any data yet.
100
+ <Text>{item.data?.text}</Text>
101
+ </View>
102
+ );
35
103
  },
36
- };
37
- ```
104
+ },
105
+ image: ...
106
+ };
38
107
 
39
- - If you already have `rn-cli.config.js`, add `react-native-list` to your `getProvidesModuleNodeModules` function or copy it from the snippet above.
108
+ export function ExampleList() {
109
+ const dataSource = useListDataSource<Items>({
110
+ data: [...],
111
+ });
112
+ const layout = useLinearListLayout({
113
+ itemSpacing: 8,
114
+ });
40
115
 
41
- ## Usage
116
+ return (
117
+ <List
118
+ dataSource={dataSource}
119
+ layout={layout}
120
+ renderers={renderers}
121
+ style={{
122
+ flex: 1,
123
+ }}
124
+ />
125
+ );
126
+ }
127
+ ```
42
128
 
43
- ```js
44
- import { FlatList, VirtualizedList, SectionList } from 'react-native-list';
129
+ ## API
130
+
131
+ XXXX TODO
132
+
133
+ ## Benchmark
134
+
135
+ > Scrolling as fast as possible. Release build. iPhone 13 Pro.
136
+
137
+ https://github.com/user-attachments/assets/aa7c2c41-b7ac-4d8b-9eb1-fd8b2feda4de
45
138
 
46
- // then use it like a regular react-native@0.43 components
139
+ | | Legend List | react-native-list |
140
+ | --------- | ----------- | ----------------- |
141
+ | FPS | 60 | 60 |
142
+ | Memory | 86.89mb | 86.88mb |
143
+ | Total CPU | 144.69% | 185.93% |
144
+ | Can blank | yes | no |
145
+
146
+ Performance difference is best described as this:
147
+
148
+ - With react-native-list you will never get a blank. However, instead, you could see UI thread drop frames if your item rendering is too heavy.
149
+ - With Legend List you may see blanks, however, its way less likely you will drop frames on the UI thread (instead your JS thread might be fully busy, but you won't really get to notice that on the UIs performance)
150
+
151
+ ## Known performance pitfalls
152
+
153
+ - For iOS when using dynamically sized items, try to use `iosConfig.estimatedItemSize` to roughly specify how many items will be visible in the view port. This can help a lot with performance.
154
+ - When specifying sizes for items use `useLinearListLayout({})` inset configs. Avoid setting a width in the styles that exceed the actual available view port width.
155
+ - If you can, always provide item sizes upfront. With that the performance will be unbeatable.
156
+ - In your item render function, when you have no item data yet it is tempting to return early with `null` or just an empty `<View />`. However, this is super bad for performance. There are two phases for native lists. First is view creation, where you're expected to create the view hierarchy for your item - just not with any data yet (so that any data could be bind to it). The second phase is actually binding data to the view. This will result in a simple "update props" operation on the native side instead of needing to create a new view hierarchy. Example:
157
+
158
+ ❌ **Bad**:
159
+
160
+ ```jsx
161
+ renderItemWorklet: ({ item }) => {
162
+ "worklet";
163
+ if (item == null) return <View />
164
+ return (
165
+ <View>
166
+ <Image src={item.image}>
167
+ <Text>{item.userName}</Text>
168
+ </View>
169
+ )
170
+ ```
171
+
172
+ ✅ **Good**:
173
+
174
+ ```jsx
175
+ renderItemWorklet: ({ item }) => {
176
+ "worklet";
177
+ return (
178
+ <View>
179
+ <Image src={item?.image}>
180
+ <Text>{item?.userName ?? ""}</Text>
181
+ </View>
182
+ )
47
183
  ```
48
184
 
49
- For more information, see [Better List Views in React Native](https://facebook.github.io/react-native/blog/2017/03/13/better-list-views.html).
185
+ ## Development
186
+
187
+ First clone init the submodules:
188
+
189
+ ```sh
190
+ git submodule update --init --recursive
191
+ ```
192
+
193
+ Regenerate native Nitro specs after changing files in `src/specs` or `nitro.json`:
194
+
195
+ ```sh
196
+ bun specs
197
+ ```
198
+
199
+ Run TypeScript checks:
200
+
201
+ ```sh
202
+ bun run typecheck
203
+ ```
@@ -0,0 +1,39 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "ReactNativeList"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported, :visionos => 1.0 }
14
+ s.source = { :git => "https://github.com/hannojg/react-native-list.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = [
17
+ # Implementation (Swift)
18
+ "ios/**/*.{h,swift}",
19
+ # Autolinking/Registration (Objective-C++)
20
+ "ios/**/*.{m,mm}",
21
+ # Implementation (C++ objects)
22
+ "cpp/**/*.{hpp,cpp}",
23
+ ]
24
+ s.public_header_files = "ios/**/*.h"
25
+ s.pod_target_xcconfig = {
26
+ "HEADER_SEARCH_PATHS" => [
27
+ '"$(PODS_TARGET_SRCROOT)/ReactCommon"',
28
+ ].join(' ')
29
+ }
30
+
31
+ load 'nitrogen/generated/ios/ReactNativeList+autolinking.rb'
32
+ add_nitrogen_files(s)
33
+
34
+ s.dependency 'React-jsi'
35
+ s.dependency 'React-callinvoker'
36
+ s.dependency 'DifferenceKit', '~> 1.3'
37
+ s.dependency "RNWorklets"
38
+ install_modules_dependencies(s)
39
+ end
@@ -0,0 +1,48 @@
1
+ project(ReactNativeList)
2
+ cmake_minimum_required(VERSION 3.9.0)
3
+
4
+ set (PACKAGE_NAME ReactNativeList)
5
+ set (CMAKE_VERBOSE_MAKEFILE ON)
6
+ set (CMAKE_CXX_STANDARD 20)
7
+
8
+ # Define C++ library and add all sources
9
+ add_library(${PACKAGE_NAME} SHARED
10
+ ../cpp/HybridUiManagerHelper.cpp
11
+ ../cpp/WorkletsUiCallInvoker.cpp
12
+ src/main/cpp/cpp-adapter.cpp
13
+ src/main/cpp/JHybridUiListModule.cpp
14
+ )
15
+
16
+ # Add Nitrogen specs :)
17
+ include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/ReactNativeList+autolinking.cmake)
18
+
19
+ # Set up local includes
20
+ include_directories(
21
+ "src/main/cpp"
22
+ "../cpp"
23
+ )
24
+
25
+
26
+ find_library(LOG_LIB log)
27
+ find_package(react-native-worklets REQUIRED) # <-- for Worklets
28
+
29
+ # Worklets prefab headers transitively need these React Native internal headers
30
+ # (they are PRIVATE in the worklets CMakeLists.txt, so not propagated via prefab)
31
+ #TODO: THIS SHOULDN'T BE HARDCODED LIKE THIS!
32
+ set(REACT_NATIVE_DIR "${CMAKE_SOURCE_DIR}/../../node_modules/react-native")
33
+ target_include_directories(${PACKAGE_NAME} PRIVATE
34
+ "${REACT_NATIVE_DIR}/ReactCommon"
35
+ "${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
36
+ "${REACT_NATIVE_DIR}/ReactCommon/runtimeexecutor"
37
+ "${REACT_NATIVE_DIR}/ReactCommon/jsiexecutor"
38
+ "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/turbomodule"
39
+ "${REACT_NATIVE_DIR}/ReactCommon/react/nativemodule/core/ReactCommon"
40
+ )
41
+
42
+ # Link all libraries together
43
+ target_link_libraries(
44
+ ${PACKAGE_NAME}
45
+ ${LOG_LIB}
46
+ android # <-- Android core
47
+ react-native-worklets::worklets # <-- Worklets C++ library
48
+ )
@@ -0,0 +1,151 @@
1
+ buildscript {
2
+ repositories {
3
+ google()
4
+ mavenCentral()
5
+ }
6
+
7
+ dependencies {
8
+ classpath "com.android.tools.build:gradle:8.13.2"
9
+ }
10
+ }
11
+
12
+ def reactNativeArchitectures() {
13
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
14
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
15
+ }
16
+
17
+ def isNewArchitectureEnabled() {
18
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
19
+ }
20
+
21
+ apply plugin: "com.android.library"
22
+ apply plugin: 'org.jetbrains.kotlin.android'
23
+ apply from: '../nitrogen/generated/android/ReactNativeList+autolinking.gradle'
24
+ apply from: "./fix-prefab.gradle"
25
+
26
+ if (isNewArchitectureEnabled()) {
27
+ apply plugin: "com.facebook.react"
28
+
29
+ react {
30
+ libraryName = "ReactNativeList"
31
+ codegenJavaPackageName = "com.hannojg.reactnativelist"
32
+ jsRootDir = file("../src")
33
+ }
34
+ }
35
+
36
+ def getExtOrDefault(name) {
37
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["ReactNativeList_" + name]
38
+ }
39
+
40
+ def getExtOrIntegerDefault(name) {
41
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["ReactNativeList_" + name]).toInteger()
42
+ }
43
+
44
+ android {
45
+ namespace "com.hannojg.reactnativelist"
46
+ ndkVersion getExtOrDefault("ndkVersion")
47
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
48
+
49
+ defaultConfig {
50
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
51
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
52
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
53
+
54
+ externalNativeBuild {
55
+ cmake {
56
+ cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
57
+ arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
58
+ abiFilters (*reactNativeArchitectures())
59
+
60
+ buildTypes {
61
+ debug {
62
+ cppFlags "-O1 -g"
63
+ }
64
+ release {
65
+ cppFlags "-O2"
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ externalNativeBuild {
73
+ cmake {
74
+ path "CMakeLists.txt"
75
+ }
76
+ }
77
+
78
+ packagingOptions {
79
+ excludes = [
80
+ "META-INF",
81
+ "META-INF/**",
82
+ "**/libc++_shared.so",
83
+ "**/libNitroModules.so",
84
+ "**/libfbjni.so",
85
+ "**/libjsi.so",
86
+ "**/libfolly_json.so",
87
+ "**/libfolly_runtime.so",
88
+ "**/libglog.so",
89
+ "**/libhermes.so",
90
+ "**/libhermes-executor-debug.so",
91
+ "**/libhermes_executor.so",
92
+ "**/libreactnative.so",
93
+ "**/libreactnativejni.so",
94
+ "**/libturbomodulejsijni.so",
95
+ "**/libreact_nativemodule_core.so",
96
+ "**/libjscexecutor.so"
97
+ ]
98
+ }
99
+
100
+ buildFeatures {
101
+ buildConfig true
102
+ prefab true
103
+ }
104
+
105
+ buildTypes {
106
+ release {
107
+ minifyEnabled false
108
+ }
109
+ }
110
+
111
+ lintOptions {
112
+ disable "GradleCompatible"
113
+ }
114
+
115
+ sourceSets {
116
+ main {
117
+ if (isNewArchitectureEnabled()) {
118
+ java.srcDirs += [
119
+ // React Codegen files
120
+ "${project.buildDir}/generated/source/codegen/java"
121
+ ]
122
+ }
123
+ }
124
+ }
125
+
126
+ compileOptions {
127
+ sourceCompatibility JavaVersion.VERSION_1_8
128
+ targetCompatibility JavaVersion.VERSION_1_8
129
+ }
130
+
131
+ }
132
+
133
+ repositories {
134
+ mavenCentral()
135
+ google()
136
+ }
137
+
138
+
139
+ dependencies {
140
+ // For < 0.71, this will be from the local maven repo
141
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
142
+ //noinspection GradleDynamicVersion
143
+ implementation "com.facebook.react:react-native:+"
144
+
145
+ // Add a dependency on NitroModules
146
+ implementation project(":react-native-nitro-modules")
147
+ implementation project(":react-native-worklets")
148
+
149
+ // RecyclerView
150
+ implementation "androidx.recyclerview:recyclerview:1.4.0"
151
+ }
@@ -0,0 +1,51 @@
1
+ tasks.configureEach { task ->
2
+ // Make sure that we generate our prefab publication file only after having built the native library
3
+ // so that not a header publication file, but a full configuration publication will be generated, which
4
+ // will include the .so file
5
+
6
+ def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
7
+ def matcher = task.name =~ prefabConfigurePattern
8
+ if (matcher.matches()) {
9
+ def variantName = matcher[0][1]
10
+ task.outputs.upToDateWhen { false }
11
+ task.dependsOn("externalNativeBuild${variantName}")
12
+ }
13
+ }
14
+
15
+ afterEvaluate {
16
+ def abis = reactNativeArchitectures()
17
+ rootProject.allprojects.each { proj ->
18
+ if (proj === rootProject) return
19
+
20
+ def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
21
+ config.dependencies.any { dep ->
22
+ dep.group == project.group && dep.name == project.name
23
+ }
24
+ }
25
+ if (!dependsOnThisLib && proj != project) return
26
+
27
+ if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
28
+ return
29
+ }
30
+
31
+ def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
32
+ // Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
33
+ // generate a libnameConfig.cmake file that will contain our native library (.so).
34
+ // See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
35
+ variants.all { variant ->
36
+ def variantName = variant.name
37
+ abis.each { abi ->
38
+ def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
39
+ if (!searchDir.exists()) return
40
+ def matches = []
41
+ searchDir.eachDir { randomDir ->
42
+ def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
43
+ if (prefabFile.exists()) matches << prefabFile
44
+ }
45
+ matches.each { prefabConfig ->
46
+ prefabConfig.setLastModified(System.currentTimeMillis())
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,5 @@
1
+ ReactNativeList_kotlinVersion=2.1.20
2
+ ReactNativeList_minSdkVersion=23
3
+ ReactNativeList_targetSdkVersion=36
4
+ ReactNativeList_compileSdkVersion=36
5
+ ReactNativeList_ndkVersion=27.1.12297006
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>