react-native-nitro-list 0.0.1 → 0.1.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 (336) hide show
  1. package/README.md +250 -16
  2. package/android/build.gradle +5 -4
  3. package/android/src/main/java/com/nitrolist/HybridNitroRecyclerView.kt +26 -0
  4. package/android/src/main/java/com/nitrolist/HybridNitroRecyclerViewManager.kt +29 -0
  5. package/android/src/main/java/com/nitrolist/NitroListPackage.kt +13 -24
  6. package/android/src/main/java/com/nitrolist/NitroRecyclerAdapter.kt +32 -0
  7. package/android/src/main/java/com/nitrolist/NitroRecyclerViewHolder.kt +8 -0
  8. package/ios/HybridNitroList.swift +32 -15
  9. package/lib/commonjs/NitroList.js +9 -0
  10. package/lib/commonjs/NitroList.js.map +1 -0
  11. package/lib/commonjs/RecyclerList.internal.js +25 -0
  12. package/lib/commonjs/RecyclerList.internal.js.map +1 -0
  13. package/lib/commonjs/RecyclerList.js +171 -0
  14. package/lib/commonjs/RecyclerList.js.map +1 -0
  15. package/lib/commonjs/RecyclerList.types.js +6 -0
  16. package/lib/commonjs/RecyclerList.types.js.map +1 -0
  17. package/lib/commonjs/ReusableView.js +2 -0
  18. package/lib/commonjs/ReusableView.js.map +1 -0
  19. package/lib/commonjs/cell/Cell.js +2 -0
  20. package/lib/{module/specs/nitro-list.nitro.js.map → commonjs/cell/Cell.js.map} +1 -1
  21. package/lib/commonjs/cell/CellRecycler.js +62 -0
  22. package/lib/commonjs/cell/CellRecycler.js.map +1 -0
  23. package/lib/commonjs/cell/StableKey.js +10 -0
  24. package/lib/commonjs/cell/StableKey.js.map +1 -0
  25. package/lib/commonjs/debug/useDebugOverlay.js +15 -0
  26. package/lib/commonjs/debug/useDebugOverlay.js.map +1 -0
  27. package/lib/commonjs/getVisibleIndices.js +38 -0
  28. package/lib/commonjs/getVisibleIndices.js.map +1 -0
  29. package/lib/commonjs/hooks/useCellRenderer.js +62 -0
  30. package/lib/commonjs/hooks/useCellRenderer.js.map +1 -0
  31. package/lib/commonjs/hooks/useStableCallback.js +13 -0
  32. package/lib/commonjs/hooks/useStableCallback.js.map +1 -0
  33. package/lib/commonjs/index.js +7 -5
  34. package/lib/commonjs/index.js.map +1 -1
  35. package/lib/commonjs/layout/EstimatedLayoutProvider.js +30 -0
  36. package/lib/commonjs/layout/EstimatedLayoutProvider.js.map +1 -0
  37. package/lib/commonjs/layout/LayoutEngine.js +21 -0
  38. package/lib/commonjs/layout/LayoutEngine.js.map +1 -0
  39. package/lib/commonjs/{specs/nitro-list.nitro.js → layout/LayoutProvider.js} +1 -1
  40. package/lib/commonjs/{specs/nitro-list.nitro.js.map → layout/LayoutProvider.js.map} +1 -1
  41. package/lib/commonjs/layout/LayoutRectangle.js +2 -0
  42. package/lib/commonjs/layout/LayoutRectangle.js.map +1 -0
  43. package/lib/commonjs/layout/MutableLinearLayout.js +65 -0
  44. package/lib/commonjs/layout/MutableLinearLayout.js.map +1 -0
  45. package/lib/commonjs/layout/index.js +20 -0
  46. package/lib/commonjs/layout/index.js.map +1 -0
  47. package/lib/commonjs/measurement/MeasureLayout.js +20 -0
  48. package/lib/commonjs/measurement/MeasureLayout.js.map +1 -0
  49. package/lib/commonjs/measurement/useItemMeasurement.js +28 -0
  50. package/lib/commonjs/measurement/useItemMeasurement.js.map +1 -0
  51. package/lib/commonjs/native/NitroLayoutEngine.js +9 -0
  52. package/lib/commonjs/native/NitroLayoutEngine.js.map +1 -0
  53. package/lib/commonjs/native/NitroList.types.js +6 -0
  54. package/lib/commonjs/native/NitroList.types.js.map +1 -0
  55. package/lib/commonjs/native/NitroRecyclerView.js +9 -0
  56. package/lib/commonjs/native/NitroRecyclerView.js.map +1 -0
  57. package/lib/commonjs/prefetch/PrefetchHelper.js +39 -0
  58. package/lib/commonjs/prefetch/PrefetchHelper.js.map +1 -0
  59. package/lib/commonjs/specs/nitro-layout-engine.nitro.js +6 -0
  60. package/lib/commonjs/specs/nitro-layout-engine.nitro.js.map +1 -0
  61. package/lib/commonjs/utils/arrayEqual.js +15 -0
  62. package/lib/commonjs/utils/arrayEqual.js.map +1 -0
  63. package/lib/commonjs/utils/assertNever.js +10 -0
  64. package/lib/commonjs/utils/assertNever.js.map +1 -0
  65. package/lib/commonjs/utils/clamp.js +10 -0
  66. package/lib/commonjs/utils/clamp.js.map +1 -0
  67. package/lib/commonjs/utils/devAssert.js +12 -0
  68. package/lib/commonjs/utils/devAssert.js.map +1 -0
  69. package/lib/commonjs/utils/invariant.js +12 -0
  70. package/lib/commonjs/utils/invariant.js.map +1 -0
  71. package/lib/commonjs/utils/isDefined.js +10 -0
  72. package/lib/commonjs/utils/isDefined.js.map +1 -0
  73. package/lib/commonjs/utils/isNumber.js +10 -0
  74. package/lib/commonjs/utils/isNumber.js.map +1 -0
  75. package/lib/commonjs/utils/noop.js +10 -0
  76. package/lib/commonjs/utils/noop.js.map +1 -0
  77. package/lib/commonjs/utils/shallowEqual.js +22 -0
  78. package/lib/commonjs/utils/shallowEqual.js.map +1 -0
  79. package/lib/commonjs/utils/throttle.js +17 -0
  80. package/lib/commonjs/utils/throttle.js.map +1 -0
  81. package/lib/commonjs/viewability/ViewabilityHelper.js +121 -0
  82. package/lib/commonjs/viewability/ViewabilityHelper.js.map +1 -0
  83. package/lib/commonjs/windowing/ScrollMetrics.js +2 -0
  84. package/lib/commonjs/windowing/ScrollMetrics.js.map +1 -0
  85. package/lib/commonjs/windowing/findVisibleIndexRange.js +48 -0
  86. package/lib/commonjs/windowing/findVisibleIndexRange.js.map +1 -0
  87. package/lib/commonjs/windowing/index.js +20 -0
  88. package/lib/commonjs/windowing/index.js.map +1 -0
  89. package/lib/commonjs/windowing/useScrollMetrics.js +39 -0
  90. package/lib/commonjs/windowing/useScrollMetrics.js.map +1 -0
  91. package/lib/module/NitroList.js +5 -0
  92. package/lib/module/NitroList.js.map +1 -0
  93. package/lib/module/RecyclerList.internal.js +22 -0
  94. package/lib/module/RecyclerList.internal.js.map +1 -0
  95. package/lib/module/RecyclerList.js +166 -0
  96. package/lib/module/RecyclerList.js.map +1 -0
  97. package/lib/module/RecyclerList.types.js +4 -0
  98. package/lib/module/RecyclerList.types.js.map +1 -0
  99. package/lib/module/ReusableView.js +2 -0
  100. package/lib/module/ReusableView.js.map +1 -0
  101. package/lib/module/cell/Cell.js +2 -0
  102. package/lib/module/cell/Cell.js.map +1 -0
  103. package/lib/module/cell/CellRecycler.js +57 -0
  104. package/lib/module/cell/CellRecycler.js.map +1 -0
  105. package/lib/module/cell/StableKey.js +6 -0
  106. package/lib/module/cell/StableKey.js.map +1 -0
  107. package/lib/module/debug/useDebugOverlay.js +11 -0
  108. package/lib/module/debug/useDebugOverlay.js.map +1 -0
  109. package/lib/module/getVisibleIndices.js +34 -0
  110. package/lib/module/getVisibleIndices.js.map +1 -0
  111. package/lib/module/hooks/useCellRenderer.js +58 -0
  112. package/lib/module/hooks/useCellRenderer.js.map +1 -0
  113. package/lib/module/hooks/useStableCallback.js +9 -0
  114. package/lib/module/hooks/useStableCallback.js.map +1 -0
  115. package/lib/module/index.js +1 -3
  116. package/lib/module/index.js.map +1 -1
  117. package/lib/module/layout/EstimatedLayoutProvider.js +25 -0
  118. package/lib/module/layout/EstimatedLayoutProvider.js.map +1 -0
  119. package/lib/module/layout/LayoutEngine.js +17 -0
  120. package/lib/module/layout/LayoutEngine.js.map +1 -0
  121. package/lib/module/layout/LayoutProvider.js +4 -0
  122. package/lib/module/layout/LayoutProvider.js.map +1 -0
  123. package/lib/module/layout/LayoutRectangle.js +2 -0
  124. package/lib/module/layout/LayoutRectangle.js.map +1 -0
  125. package/lib/module/layout/MutableLinearLayout.js +60 -0
  126. package/lib/module/layout/MutableLinearLayout.js.map +1 -0
  127. package/lib/module/layout/index.js +5 -0
  128. package/lib/module/layout/index.js.map +1 -0
  129. package/lib/module/measurement/MeasureLayout.js +16 -0
  130. package/lib/module/measurement/MeasureLayout.js.map +1 -0
  131. package/lib/module/measurement/useItemMeasurement.js +24 -0
  132. package/lib/module/measurement/useItemMeasurement.js.map +1 -0
  133. package/lib/module/native/NitroLayoutEngine.js +5 -0
  134. package/lib/module/native/NitroLayoutEngine.js.map +1 -0
  135. package/lib/module/native/NitroList.types.js +4 -0
  136. package/lib/module/native/NitroList.types.js.map +1 -0
  137. package/lib/module/native/NitroRecyclerView.js +5 -0
  138. package/lib/module/native/NitroRecyclerView.js.map +1 -0
  139. package/lib/module/prefetch/PrefetchHelper.js +34 -0
  140. package/lib/module/prefetch/PrefetchHelper.js.map +1 -0
  141. package/lib/module/specs/nitro-layout-engine.nitro.js +4 -0
  142. package/lib/module/specs/nitro-layout-engine.nitro.js.map +1 -0
  143. package/lib/module/utils/arrayEqual.js +11 -0
  144. package/lib/module/utils/arrayEqual.js.map +1 -0
  145. package/lib/module/utils/assertNever.js +6 -0
  146. package/lib/module/utils/assertNever.js.map +1 -0
  147. package/lib/module/utils/clamp.js +6 -0
  148. package/lib/module/utils/clamp.js.map +1 -0
  149. package/lib/module/utils/devAssert.js +8 -0
  150. package/lib/module/utils/devAssert.js.map +1 -0
  151. package/lib/module/utils/invariant.js +8 -0
  152. package/lib/module/utils/invariant.js.map +1 -0
  153. package/lib/module/utils/isDefined.js +6 -0
  154. package/lib/module/utils/isDefined.js.map +1 -0
  155. package/lib/module/utils/isNumber.js +6 -0
  156. package/lib/module/utils/isNumber.js.map +1 -0
  157. package/lib/module/utils/noop.js +6 -0
  158. package/lib/module/utils/noop.js.map +1 -0
  159. package/lib/module/utils/shallowEqual.js +18 -0
  160. package/lib/module/utils/shallowEqual.js.map +1 -0
  161. package/lib/module/utils/throttle.js +13 -0
  162. package/lib/module/utils/throttle.js.map +1 -0
  163. package/lib/module/viewability/ViewabilityHelper.js +116 -0
  164. package/lib/module/viewability/ViewabilityHelper.js.map +1 -0
  165. package/lib/module/windowing/ScrollMetrics.js +2 -0
  166. package/lib/module/windowing/ScrollMetrics.js.map +1 -0
  167. package/lib/module/windowing/findVisibleIndexRange.js +44 -0
  168. package/lib/module/windowing/findVisibleIndexRange.js.map +1 -0
  169. package/lib/module/windowing/index.js +5 -0
  170. package/lib/module/windowing/index.js.map +1 -0
  171. package/lib/module/windowing/useScrollMetrics.js +35 -0
  172. package/lib/module/windowing/useScrollMetrics.js.map +1 -0
  173. package/lib/typescript/src/NitroList.d.ts +5 -0
  174. package/lib/typescript/src/NitroList.d.ts.map +1 -0
  175. package/lib/typescript/src/RecyclerList.d.ts +26 -0
  176. package/lib/typescript/src/RecyclerList.d.ts.map +1 -0
  177. package/lib/typescript/src/RecyclerList.internal.d.ts +9 -0
  178. package/lib/typescript/src/RecyclerList.internal.d.ts.map +1 -0
  179. package/lib/typescript/src/RecyclerList.types.d.ts +18 -0
  180. package/lib/typescript/src/RecyclerList.types.d.ts.map +1 -0
  181. package/lib/typescript/src/ReusableView.d.ts +9 -0
  182. package/lib/typescript/src/ReusableView.d.ts.map +1 -0
  183. package/lib/typescript/src/__tests__/windowing/findVisibleIndexRange.test.d.ts +2 -0
  184. package/lib/typescript/src/__tests__/windowing/findVisibleIndexRange.test.d.ts.map +1 -0
  185. package/lib/typescript/src/cell/Cell.d.ts +13 -0
  186. package/lib/typescript/src/cell/Cell.d.ts.map +1 -0
  187. package/lib/typescript/src/cell/CellRecycler.d.ts +19 -0
  188. package/lib/typescript/src/cell/CellRecycler.d.ts.map +1 -0
  189. package/lib/typescript/src/cell/StableKey.d.ts +2 -0
  190. package/lib/typescript/src/cell/StableKey.d.ts.map +1 -0
  191. package/lib/typescript/src/debug/useDebugOverlay.d.ts +2 -0
  192. package/lib/typescript/src/debug/useDebugOverlay.d.ts.map +1 -0
  193. package/lib/typescript/src/getVisibleIndices.d.ts +8 -0
  194. package/lib/typescript/src/getVisibleIndices.d.ts.map +1 -0
  195. package/lib/typescript/src/hooks/useCellRenderer.d.ts +19 -0
  196. package/lib/typescript/src/hooks/useCellRenderer.d.ts.map +1 -0
  197. package/lib/typescript/src/hooks/useStableCallback.d.ts +2 -0
  198. package/lib/typescript/src/hooks/useStableCallback.d.ts.map +1 -0
  199. package/lib/typescript/src/index.d.ts +2 -4
  200. package/lib/typescript/src/index.d.ts.map +1 -1
  201. package/lib/typescript/src/layout/EstimatedLayoutProvider.d.ts +15 -0
  202. package/lib/typescript/src/layout/EstimatedLayoutProvider.d.ts.map +1 -0
  203. package/lib/typescript/src/layout/LayoutEngine.d.ts +10 -0
  204. package/lib/typescript/src/layout/LayoutEngine.d.ts.map +1 -0
  205. package/lib/typescript/src/layout/LayoutProvider.d.ts +16 -0
  206. package/lib/typescript/src/layout/LayoutProvider.d.ts.map +1 -0
  207. package/lib/typescript/src/layout/LayoutRectangle.d.ts +11 -0
  208. package/lib/typescript/src/layout/LayoutRectangle.d.ts.map +1 -0
  209. package/lib/typescript/src/layout/MutableLinearLayout.d.ts +22 -0
  210. package/lib/typescript/src/layout/MutableLinearLayout.d.ts.map +1 -0
  211. package/lib/typescript/src/layout/index.d.ts +5 -0
  212. package/lib/typescript/src/layout/index.d.ts.map +1 -0
  213. package/lib/typescript/src/measurement/MeasureLayout.d.ts +10 -0
  214. package/lib/typescript/src/measurement/MeasureLayout.d.ts.map +1 -0
  215. package/lib/typescript/src/measurement/useItemMeasurement.d.ts +11 -0
  216. package/lib/typescript/src/measurement/useItemMeasurement.d.ts.map +1 -0
  217. package/lib/typescript/src/native/NitroLayoutEngine.d.ts +3 -0
  218. package/lib/typescript/src/native/NitroLayoutEngine.d.ts.map +1 -0
  219. package/lib/typescript/src/native/NitroList.types.d.ts +9 -0
  220. package/lib/typescript/src/native/NitroList.types.d.ts.map +1 -0
  221. package/lib/typescript/src/native/NitroRecyclerView.d.ts +5 -0
  222. package/lib/typescript/src/native/NitroRecyclerView.d.ts.map +1 -0
  223. package/lib/typescript/src/prefetch/PrefetchHelper.d.ts +17 -0
  224. package/lib/typescript/src/prefetch/PrefetchHelper.d.ts.map +1 -0
  225. package/lib/typescript/src/specs/nitro-layout-engine.nitro.d.ts +14 -0
  226. package/lib/typescript/src/specs/nitro-layout-engine.nitro.d.ts.map +1 -0
  227. package/lib/typescript/src/utils/arrayEqual.d.ts +2 -0
  228. package/lib/typescript/src/utils/arrayEqual.d.ts.map +1 -0
  229. package/lib/typescript/src/utils/assertNever.d.ts +2 -0
  230. package/lib/typescript/src/utils/assertNever.d.ts.map +1 -0
  231. package/lib/typescript/src/utils/clamp.d.ts +2 -0
  232. package/lib/typescript/src/utils/clamp.d.ts.map +1 -0
  233. package/lib/typescript/src/utils/devAssert.d.ts +2 -0
  234. package/lib/typescript/src/utils/devAssert.d.ts.map +1 -0
  235. package/lib/typescript/src/utils/invariant.d.ts +2 -0
  236. package/lib/typescript/src/utils/invariant.d.ts.map +1 -0
  237. package/lib/typescript/src/utils/isDefined.d.ts +2 -0
  238. package/lib/typescript/src/utils/isDefined.d.ts.map +1 -0
  239. package/lib/typescript/src/utils/isNumber.d.ts +2 -0
  240. package/lib/typescript/src/utils/isNumber.d.ts.map +1 -0
  241. package/lib/typescript/src/utils/noop.d.ts +2 -0
  242. package/lib/typescript/src/utils/noop.d.ts.map +1 -0
  243. package/lib/typescript/src/utils/shallowEqual.d.ts +2 -0
  244. package/lib/typescript/src/utils/shallowEqual.d.ts.map +1 -0
  245. package/lib/typescript/src/utils/throttle.d.ts +2 -0
  246. package/lib/typescript/src/utils/throttle.d.ts.map +1 -0
  247. package/lib/typescript/src/viewability/ViewabilityHelper.d.ts +50 -0
  248. package/lib/typescript/src/viewability/ViewabilityHelper.d.ts.map +1 -0
  249. package/lib/typescript/src/windowing/ScrollMetrics.d.ts +11 -0
  250. package/lib/typescript/src/windowing/ScrollMetrics.d.ts.map +1 -0
  251. package/lib/typescript/src/windowing/findVisibleIndexRange.d.ts +11 -0
  252. package/lib/typescript/src/windowing/findVisibleIndexRange.d.ts.map +1 -0
  253. package/lib/typescript/src/windowing/index.d.ts +4 -0
  254. package/lib/typescript/src/windowing/index.d.ts.map +1 -0
  255. package/lib/typescript/src/windowing/useScrollMetrics.d.ts +14 -0
  256. package/lib/typescript/src/windowing/useScrollMetrics.d.ts.map +1 -0
  257. package/nitro.json +20 -13
  258. package/nitrogen/generated/android/NitroList+autolinking.cmake +2 -4
  259. package/nitrogen/generated/android/NitroListOnLoad.cpp +3 -13
  260. package/nitrogen/generated/android/c++/JHybridNitroLayoutEngineSpec.cpp +69 -0
  261. package/nitrogen/generated/android/c++/{JHybridNitroListSpec.hpp → JHybridNitroLayoutEngineSpec.hpp} +12 -13
  262. package/nitrogen/generated/android/c++/JLayoutRectangle.hpp +69 -0
  263. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/{HybridNitroListSpec.kt → HybridNitroLayoutEngineSpec.kt} +11 -13
  264. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/LayoutRectangle.kt +47 -0
  265. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Bridge.cpp +9 -9
  266. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Bridge.hpp +50 -13
  267. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Umbrella.hpp +11 -5
  268. package/nitrogen/generated/ios/c++/{HybridNitroListSpecSwift.cpp → HybridNitroLayoutEngineSpecSwift.cpp} +2 -2
  269. package/nitrogen/generated/ios/c++/HybridNitroLayoutEngineSpecSwift.hpp +78 -0
  270. package/nitrogen/generated/ios/swift/HybridNitroLayoutEngineSpec.swift +56 -0
  271. package/nitrogen/generated/ios/swift/{HybridNitroListSpec_cxx.swift → HybridNitroLayoutEngineSpec_cxx.swift} +35 -38
  272. package/nitrogen/generated/ios/swift/LayoutRectangle.swift +45 -0
  273. package/nitrogen/generated/shared/c++/{HybridNitroListSpec.cpp → HybridNitroLayoutEngineSpec.cpp} +4 -5
  274. package/nitrogen/generated/shared/c++/{HybridNitroListSpec.hpp → HybridNitroLayoutEngineSpec.hpp} +15 -14
  275. package/nitrogen/generated/shared/c++/LayoutRectangle.hpp +95 -0
  276. package/package.json +12 -4
  277. package/src/NitroList.ts +8 -0
  278. package/src/RecyclerList.internal.ts +38 -0
  279. package/src/RecyclerList.tsx +252 -0
  280. package/src/RecyclerList.types.ts +24 -0
  281. package/src/ReusableView.ts +12 -0
  282. package/src/__tests__/windowing/findVisibleIndexRange.test.ts +55 -0
  283. package/src/cell/Cell.ts +14 -0
  284. package/src/cell/CellRecycler.ts +66 -0
  285. package/src/cell/StableKey.ts +6 -0
  286. package/src/debug/useDebugOverlay.ts +14 -0
  287. package/src/getVisibleIndices.ts +53 -0
  288. package/src/hooks/useCellRenderer.ts +86 -0
  289. package/src/hooks/useStableCallback.ts +13 -0
  290. package/src/index.ts +2 -14
  291. package/src/layout/EstimatedLayoutProvider.ts +35 -0
  292. package/src/layout/LayoutEngine.ts +21 -0
  293. package/src/layout/LayoutProvider.ts +17 -0
  294. package/src/layout/LayoutRectangle.ts +10 -0
  295. package/src/layout/MutableLinearLayout.ts +79 -0
  296. package/src/layout/index.ts +4 -0
  297. package/src/measurement/MeasureLayout.ts +20 -0
  298. package/src/measurement/useItemMeasurement.ts +32 -0
  299. package/src/native/NitroLayoutEngine.ts +7 -0
  300. package/src/native/NitroList.types.ts +12 -0
  301. package/src/native/NitroRecyclerView.ts +8 -0
  302. package/src/prefetch/PrefetchHelper.ts +47 -0
  303. package/src/specs/nitro-layout-engine.nitro.ts +17 -0
  304. package/src/utils/arrayEqual.ts +13 -0
  305. package/src/utils/assertNever.ts +3 -0
  306. package/src/utils/clamp.ts +7 -0
  307. package/src/utils/devAssert.ts +8 -0
  308. package/src/utils/invariant.ts +8 -0
  309. package/src/utils/isDefined.ts +5 -0
  310. package/src/utils/isNumber.ts +3 -0
  311. package/src/utils/noop.ts +3 -0
  312. package/src/utils/shallowEqual.ts +34 -0
  313. package/src/utils/throttle.ts +13 -0
  314. package/src/viewability/ViewabilityHelper.ts +130 -0
  315. package/src/windowing/ScrollMetrics.ts +11 -0
  316. package/src/windowing/findVisibleIndexRange.ts +60 -0
  317. package/src/windowing/index.ts +3 -0
  318. package/src/windowing/useScrollMetrics.ts +56 -0
  319. package/android/src/main/java/com/nitrolist/HybridNitroList.kt +0 -27
  320. package/lib/module/specs/nitro-list.nitro.js +0 -4
  321. package/lib/typescript/src/specs/nitro-list.nitro.d.ts +0 -11
  322. package/lib/typescript/src/specs/nitro-list.nitro.d.ts.map +0 -1
  323. package/nitrogen/generated/android/c++/JHybridNitroListSpec.cpp +0 -56
  324. package/nitrogen/generated/android/c++/views/JHybridNitroListStateUpdater.cpp +0 -56
  325. package/nitrogen/generated/android/c++/views/JHybridNitroListStateUpdater.hpp +0 -49
  326. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/views/HybridNitroListManager.kt +0 -50
  327. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/views/HybridNitroListStateUpdater.kt +0 -23
  328. package/nitrogen/generated/ios/NitroListAutolinking.mm +0 -33
  329. package/nitrogen/generated/ios/NitroListAutolinking.swift +0 -25
  330. package/nitrogen/generated/ios/c++/HybridNitroListSpecSwift.hpp +0 -74
  331. package/nitrogen/generated/ios/c++/views/HybridNitroListComponent.mm +0 -96
  332. package/nitrogen/generated/ios/swift/HybridNitroListSpec.swift +0 -56
  333. package/nitrogen/generated/shared/c++/views/HybridNitroListComponent.cpp +0 -88
  334. package/nitrogen/generated/shared/c++/views/HybridNitroListComponent.hpp +0 -107
  335. package/nitrogen/generated/shared/json/NitroListConfig.json +0 -10
  336. package/src/specs/nitro-list.nitro.ts +0 -13
@@ -0,0 +1,252 @@
1
+ import React, {
2
+ useMemo,
3
+ useRef,
4
+ useEffect,
5
+ } from 'react'
6
+ import {
7
+ ScrollView,
8
+ View,
9
+ StyleSheet,
10
+ } from 'react-native'
11
+
12
+ import type { Cell } from './cell/Cell'
13
+ import type { LayoutRectangle } from './layout/LayoutRectangle'
14
+
15
+ import { useRecyclerListInternal } from './RecyclerList.internal'
16
+ import { useScrollMetrics } from './windowing'
17
+ import { MutableLinearLayout } from './layout/MutableLinearLayout'
18
+ import { ViewabilityHelper } from './viewability/ViewabilityHelper'
19
+ import { PrefetchHelper } from './prefetch/PrefetchHelper'
20
+
21
+ /**
22
+ * Public API — mirrors FlashList behavior, not internals.
23
+ */
24
+ export type RecyclerListProps = {
25
+ containerWidth: number
26
+ itemCount?: number
27
+ itemHeights?: readonly number[]
28
+ estimatedItemHeight?: number
29
+ renderBufferRatio?: number
30
+ getItemType?: (index: number) => string
31
+ renderItem: (index: number) => React.ReactElement
32
+ onPrefetch?: (indices: number[]) => void
33
+ onViewableItemsChanged?: (info: {
34
+ viewableItems: { index: number; isViewable: boolean }[]
35
+ changed: { index: number; isViewable: boolean }[]
36
+ }) => void
37
+ }
38
+
39
+ /**
40
+ * FlashList invariant:
41
+ * Never allow viewport height = 0 to gate windowing.
42
+ */
43
+ const DEFAULT_VIEWPORT_HEIGHT = 800
44
+
45
+ export function RecyclerList(props: RecyclerListProps): React.ReactElement {
46
+ const {
47
+ containerWidth,
48
+ itemCount,
49
+ itemHeights,
50
+ estimatedItemHeight = 80,
51
+ renderBufferRatio = 1.3,
52
+ getItemType = () => 'default',
53
+ renderItem,
54
+ onPrefetch,
55
+ onViewableItemsChanged,
56
+ } = props
57
+
58
+ /**
59
+ * 🚨 DEV WARNINGS ONLY (never throw in render!)
60
+ */
61
+ if (__DEV__) {
62
+ if (!itemHeights && itemCount == null) {
63
+ console.error(
64
+ 'RecyclerList requires either itemCount or itemHeights.'
65
+ )
66
+ }
67
+
68
+ if (itemHeights && itemCount != null) {
69
+ console.error(
70
+ 'Provide only one of itemCount or itemHeights.'
71
+ )
72
+ }
73
+ }
74
+
75
+ /**
76
+ * STEP 1: Resolve item count safely (props only).
77
+ * Never depend on hooks for structural decisions.
78
+ */
79
+ const itemLength =
80
+ itemHeights?.length ??
81
+ itemCount ??
82
+ 0
83
+
84
+ /**
85
+ * STEP 2: Resolve initial heights (always defined).
86
+ */
87
+ const resolvedHeights = useMemo<readonly number[]>(() => {
88
+ if (itemHeights) return itemHeights
89
+
90
+ return Array.from(
91
+ { length: itemLength },
92
+ () => estimatedItemHeight
93
+ )
94
+ }, [itemHeights, itemLength, estimatedItemHeight])
95
+
96
+ /**
97
+ * STEP 3: Mutable layout lifecycle.
98
+ * Recreate layout only when shape changes.
99
+ */
100
+ const layoutRef = useRef<MutableLinearLayout | null>(null)
101
+ const lastLayoutKeyRef = useRef<string | null>(null)
102
+
103
+ const layoutKey = `${containerWidth}-${itemLength}`
104
+
105
+ if (
106
+ !layoutRef.current ||
107
+ lastLayoutKeyRef.current !== layoutKey
108
+ ) {
109
+ layoutRef.current = new MutableLinearLayout(
110
+ resolvedHeights,
111
+ containerWidth
112
+ )
113
+ lastLayoutKeyRef.current = layoutKey
114
+ }
115
+
116
+ /**
117
+ * STEP 4: Read layout snapshot.
118
+ */
119
+ const layouts: readonly LayoutRectangle[] =
120
+ layoutRef.current.getLayouts()
121
+
122
+ const contentHeight =
123
+ layoutRef.current.getContentHeight()
124
+
125
+ /**
126
+ * STEP 5: Scroll metrics.
127
+ */
128
+ const {
129
+ metrics,
130
+ onScroll,
131
+ onLayout,
132
+ } = useScrollMetrics()
133
+
134
+ /**
135
+ * STEP 6: Guard initial windowing.
136
+ */
137
+ const effectiveViewportHeight =
138
+ metrics.height > 0
139
+ ? metrics.height
140
+ : DEFAULT_VIEWPORT_HEIGHT
141
+
142
+ const bufferPx =
143
+ effectiveViewportHeight * renderBufferRatio
144
+
145
+ /**
146
+ * STEP 7: Windowing + recycling.
147
+ */
148
+ const cells: readonly Cell[] =
149
+ useRecyclerListInternal(
150
+ layouts,
151
+ metrics,
152
+ bufferPx,
153
+ getItemType
154
+ )
155
+
156
+ /**
157
+ * STEP 8: Phase-1 observers.
158
+ */
159
+ const viewabilityRef = useRef(
160
+ new ViewabilityHelper({
161
+ itemVisiblePercentThreshold: 50,
162
+ })
163
+ )
164
+
165
+ const prefetchRef = useRef(
166
+ new PrefetchHelper()
167
+ )
168
+
169
+ useEffect(() => {
170
+ prefetchRef.current = new PrefetchHelper()
171
+ }, [itemLength])
172
+
173
+ useEffect(() => {
174
+ if (metrics.height === 0) return
175
+
176
+ if (onViewableItemsChanged) {
177
+ const visibleLayouts: LayoutRectangle[] = []
178
+
179
+ for (const cell of cells) {
180
+ const layout = layouts[cell.index]
181
+ if (layout) visibleLayouts.push(layout)
182
+ }
183
+
184
+ const info =
185
+ viewabilityRef.current.computeViewableItems(
186
+ visibleLayouts,
187
+ metrics
188
+ )
189
+
190
+ onViewableItemsChanged(info)
191
+ }
192
+
193
+ if (onPrefetch && itemLength > 0) {
194
+ prefetchRef.current.runPrefetch(
195
+ cells.map(c => c.index),
196
+ itemLength,
197
+ 5,
198
+ onPrefetch
199
+ )
200
+ }
201
+ }, [
202
+ cells,
203
+ metrics.offsetY,
204
+ metrics.height,
205
+ onViewableItemsChanged,
206
+ onPrefetch,
207
+ itemLength,
208
+ layouts,
209
+ ])
210
+
211
+ /**
212
+ * STEP 9: Render absolutely positioned cells.
213
+ */
214
+ return (
215
+ <ScrollView
216
+ style={styles.container}
217
+ onLayout={onLayout}
218
+ onScroll={onScroll}
219
+ scrollEventThrottle={16}
220
+ removeClippedSubviews
221
+ >
222
+ <View style={[styles.content, { height: contentHeight }]}>
223
+ {cells.map(cell => {
224
+ const layout = layouts[cell.index]
225
+ if (!layout) return null
226
+
227
+ return (
228
+ <View
229
+ key={cell.key}
230
+ style={[
231
+ styles.cell,
232
+ {
233
+ top: layout.y,
234
+ width: layout.width,
235
+ height: layout.height,
236
+ },
237
+ ]}
238
+ >
239
+ {renderItem(cell.index)}
240
+ </View>
241
+ )
242
+ })}
243
+ </View>
244
+ </ScrollView>
245
+ )
246
+ }
247
+
248
+ const styles = StyleSheet.create({
249
+ container: { flex: 1 },
250
+ content: { position: 'relative', width: '100%' },
251
+ cell: { position: 'absolute', left: 0 },
252
+ })
@@ -0,0 +1,24 @@
1
+ import type React from 'react'
2
+
3
+ export type RecyclerListProps = {
4
+ /** Width of the list container (required) */
5
+ readonly containerWidth: number
6
+
7
+ /** Total number of items (used with estimatedItemHeight) */
8
+ readonly itemCount?: number
9
+
10
+ /** Explicit item heights (fast path, skips estimation) */
11
+ readonly itemHeights?: readonly number[]
12
+
13
+ /** Estimated item height when itemHeights not provided */
14
+ readonly estimatedItemHeight?: number
15
+
16
+ /** Render buffer multiplier (FlashList-style, default ~1.3) */
17
+ readonly renderBufferRatio?: number
18
+
19
+ /** Optional item type resolver for recycling */
20
+ readonly getItemType?: (index: number) => string
21
+
22
+ /** Render function */
23
+ readonly renderItem: (index: number) => React.ReactElement
24
+ }
@@ -0,0 +1,12 @@
1
+ // src/ReusableView.ts
2
+
3
+ export type ReusableView = {
4
+ /** Stable identity for React */
5
+ readonly key: string
6
+
7
+ /** Current data index bound to this slot */
8
+ index: number
9
+
10
+ /** Optional type (header, row, etc — future) */
11
+ type?: string
12
+ }
@@ -0,0 +1,55 @@
1
+ import { findVisibleIndexRange } from '../../windowing/findVisibleIndexRange'
2
+
3
+ describe('findVisibleIndexRange', () => {
4
+ /**
5
+ * Layouts:
6
+ * index 0 → y: 0–50
7
+ * index 1 → y: 50–100
8
+ * index 2 → y: 100–150
9
+ * ...
10
+ */
11
+ const layouts = Array.from({ length: 10 }, (_, i) => ({
12
+ x: 0,
13
+ y: i * 50,
14
+ width: 100,
15
+ height: 50,
16
+ }))
17
+
18
+ it('returns empty array when layouts are empty', () => {
19
+ const result = findVisibleIndexRange([], { offsetY: 0, height: 300 }, 100)
20
+
21
+ expect(result).toEqual([])
22
+ })
23
+ it('returns correct visible indices without buffer', () => {
24
+ const result = findVisibleIndexRange(
25
+ layouts,
26
+ { offsetY: 100, height: 150 },
27
+ 0
28
+ )
29
+
30
+ /**
31
+ * Viewport: 100–250 (inclusive)
32
+ * Items that intersect this window:
33
+ * indices 1–5
34
+ */
35
+ expect(result).toEqual([1, 2, 3, 4, 5])
36
+ })
37
+
38
+ it('extends window using bufferPx (inclusive boundaries)', () => {
39
+ const result = findVisibleIndexRange(
40
+ layouts,
41
+ { offsetY: 100, height: 100 },
42
+ 100
43
+ )
44
+
45
+ /**
46
+ * Viewport: 100–200
47
+ * Buffer: ±100
48
+ * Effective win: 0–300 (inclusive)
49
+ *
50
+ * index 6 starts at y = 300 → included by design
51
+ * This matches FlashList / RecyclerView behavior
52
+ */
53
+ expect(result).toEqual([0, 1, 2, 3, 4, 5, 6])
54
+ })
55
+ })
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Physical reusable cell.
3
+ * Mirrors FlashList's Cell abstraction.
4
+ */
5
+ export interface Cell {
6
+ /** Stable physical identity (never changes) */
7
+ readonly key: string
8
+
9
+ /** Logical data index currently bound */
10
+ index: number
11
+
12
+ /** Compatibility type (row, header, etc.) */
13
+ readonly type: string
14
+ }
@@ -0,0 +1,66 @@
1
+ import type { Cell } from './Cell'
2
+
3
+ const MAX_CELLS = 40
4
+
5
+ /**
6
+ * Owns physical cell reuse.
7
+ * Stateful, imperative, React-agnostic.
8
+ *
9
+ * FlashList equivalent: CellRecycler
10
+ */
11
+ export class CellRecycler {
12
+ private readonly activeCells = new Map<number, Cell>()
13
+ private readonly reusableCellsByType = new Map<string, Cell[]>()
14
+ private readonly orderedCells: Cell[] = []
15
+ private nextCellId = 0
16
+
17
+ /**
18
+ * Reconcile visible indices against existing cells.
19
+ * Returns a stable ordered snapshot.
20
+ */
21
+ reconcile(
22
+ visibleIndices: readonly number[],
23
+ getCellType: (index: number) => string
24
+ ): readonly Cell[] {
25
+ const visibleSet = new Set(visibleIndices)
26
+
27
+ // 1️⃣ Release cells no longer visible
28
+ for (const [index, cell] of this.activeCells) {
29
+ if (visibleSet.has(index)) continue
30
+
31
+ this.activeCells.delete(index)
32
+
33
+ const orderedIndex = this.orderedCells.indexOf(cell)
34
+ if (orderedIndex !== -1) {
35
+ this.orderedCells.splice(orderedIndex, 1)
36
+ }
37
+
38
+ const pool = this.reusableCellsByType.get(cell.type) ?? []
39
+ if (pool.length < MAX_CELLS) pool.push(cell)
40
+ this.reusableCellsByType.set(cell.type, pool)
41
+ }
42
+
43
+ // 2️⃣ Acquire cells for newly visible indices
44
+ for (const index of visibleIndices) {
45
+ if (this.activeCells.has(index)) continue
46
+
47
+ const type = getCellType(index)
48
+ const pool = this.reusableCellsByType.get(type)
49
+ let cell = pool?.pop()
50
+
51
+ if (!cell) {
52
+ cell = {
53
+ key: `cell-${this.nextCellId++}`,
54
+ type,
55
+ index,
56
+ }
57
+ }
58
+
59
+ cell.index = index
60
+ this.activeCells.set(index, cell)
61
+ this.orderedCells.push(cell)
62
+ }
63
+
64
+ return this.orderedCells
65
+ }
66
+ }
@@ -0,0 +1,6 @@
1
+ export function getStableKey(
2
+ slotKey: string,
3
+ index: number
4
+ ): string {
5
+ return `${slotKey}:${index}`
6
+ }
@@ -0,0 +1,14 @@
1
+ import { useEffect } from 'react'
2
+
3
+ export function useDebugOverlay(
4
+ enabled: boolean,
5
+ visibleCount: number
6
+ ): void {
7
+ useEffect(() => {
8
+ if (__DEV__ && enabled) {
9
+ console.log(
10
+ `[RecyclerList] visible items: ${visibleCount}`
11
+ )
12
+ }
13
+ }, [enabled, visibleCount])
14
+ }
@@ -0,0 +1,53 @@
1
+ import type { LayoutRectangle } from './layout/LayoutRectangle'
2
+ import type { ScrollMetrics } from './windowing/ScrollMetrics'
3
+
4
+ /**
5
+ * Binary-search based windowing.
6
+ * Returns indices intersecting viewport ± buffer.
7
+ */
8
+ export function getVisibleRange(
9
+ layouts: readonly LayoutRectangle[],
10
+ metrics: ScrollMetrics,
11
+ bufferPx: number
12
+ ): readonly number[] {
13
+ if (
14
+ layouts.length === 0 ||
15
+ metrics.height <= 0
16
+ ) {
17
+ return []
18
+ }
19
+
20
+ const startY = Math.max(
21
+ 0,
22
+ metrics.offsetY - bufferPx
23
+ )
24
+
25
+ const endY =
26
+ metrics.offsetY + metrics.height + bufferPx
27
+
28
+ let low = 0
29
+ let high = layouts.length - 1
30
+ let first = layouts.length
31
+
32
+ while (low <= high) {
33
+ const mid = (low + high) >> 1
34
+ const rect = layouts[mid]!
35
+
36
+ if (rect.y + rect.height >= startY) {
37
+ first = mid
38
+ high = mid - 1
39
+ } else {
40
+ low = mid + 1
41
+ }
42
+ }
43
+
44
+ const visible: number[] = []
45
+
46
+ for (let i = first; i < layouts.length; i++) {
47
+ const rect = layouts[i]!
48
+ if (rect.y > endY) break
49
+ visible.push(i)
50
+ }
51
+
52
+ return visible
53
+ }
@@ -0,0 +1,86 @@
1
+ import { useEffect, useMemo, useRef, useState } from 'react'
2
+ import type { Cell } from '../cell/Cell'
3
+ import { CellRecycler } from '../cell/CellRecycler'
4
+ import { findVisibleIndexRange } from '../windowing/findVisibleIndexRange'
5
+ import type { LayoutRectangle } from '../layout/LayoutRectangle'
6
+ import type { ScrollMetrics } from '../windowing/ScrollMetrics'
7
+
8
+ /**
9
+ * 🔒 Stable empty references (module-level)
10
+ * These MUST NOT be recreated per render.
11
+ */
12
+ const EMPTY_INDICES: readonly number[] = []
13
+
14
+ /**
15
+ * React bridge for CellRecycler.
16
+ * FlashList equivalent: useCellRenderer
17
+ *
18
+ * Responsibilities:
19
+ * - Translate scroll state → visible indices
20
+ * - Ask recycler for physical cells
21
+ * - Commit results with referential stability
22
+ *
23
+ * Responsibilities it does NOT have:
24
+ * ❌ Layout mutation
25
+ * ❌ Measurement
26
+ * ❌ Rendering
27
+ */
28
+ export function useCellRenderer(
29
+ layouts: readonly LayoutRectangle[],
30
+ metrics: ScrollMetrics,
31
+ bufferPx: number,
32
+ getCellType: (index: number) => string
33
+ ): readonly Cell[] {
34
+ /**
35
+ * Recycler instance is stable across renders.
36
+ */
37
+ const recyclerRef = useRef<CellRecycler>(new CellRecycler())
38
+
39
+ /**
40
+ * Compute visible indices.
41
+ * PURE + TOTAL:
42
+ * - Never throws
43
+ * - Always returns the same reference when empty
44
+ */
45
+ const visibleIndices = useMemo(
46
+ () =>
47
+ layouts.length === 0
48
+ ? EMPTY_INDICES
49
+ : findVisibleIndexRange(
50
+ layouts,
51
+ metrics,
52
+ bufferPx
53
+ ),
54
+ [layouts, metrics.offsetY, metrics.height, bufferPx]
55
+ )
56
+
57
+ /**
58
+ * Physical cells to render.
59
+ */
60
+ const [cells, setCells] =
61
+ useState<readonly Cell[]>([])
62
+
63
+ /**
64
+ * Reconcile visible indices → physical cells.
65
+ *
66
+ * FlashList invariant:
67
+ * - Only update state if identity truly changed
68
+ * - Prevents pointless re-renders
69
+ */
70
+ useEffect(() => {
71
+ const next =
72
+ recyclerRef.current.reconcile(
73
+ visibleIndices,
74
+ getCellType
75
+ )
76
+
77
+ setCells(prev =>
78
+ prev.length === next.length &&
79
+ prev.every((c, i) => c === next[i])
80
+ ? prev
81
+ : next
82
+ )
83
+ }, [visibleIndices, getCellType])
84
+
85
+ return cells
86
+ }
@@ -0,0 +1,13 @@
1
+ import { useRef, useCallback } from 'react'
2
+
3
+ export function useStableCallback<T extends (...args: never[]) => unknown>(
4
+ fn: T
5
+ ): T {
6
+ const ref = useRef(fn)
7
+ ref.current = fn
8
+
9
+ return useCallback(
10
+ ((...args: never[]) => ref.current(...args)) as T,
11
+ []
12
+ )
13
+ }
package/src/index.ts CHANGED
@@ -1,14 +1,2 @@
1
- import { getHostComponent, type HybridRef } from 'react-native-nitro-modules'
2
- import NitroListConfig from '../nitrogen/generated/shared/json/NitroListConfig.json'
3
- import type {
4
- NitroListProps,
5
- NitroListMethods,
6
- } from './specs/nitro-list.nitro'
7
-
8
-
9
- export const NitroList = getHostComponent<NitroListProps, NitroListMethods>(
10
- 'NitroList',
11
- () => NitroListConfig
12
- )
13
-
14
- export type NitroListRef = HybridRef<NitroListProps, NitroListMethods>
1
+ export { RecyclerList } from './RecyclerList'
2
+ export type { RecyclerListProps } from './RecyclerList.types'
@@ -0,0 +1,35 @@
1
+ import type { LayoutProvider } from './LayoutProvider'
2
+ import type { LayoutRectangle } from './LayoutRectangle'
3
+
4
+ /**
5
+ * Layout provider using estimated item heights.
6
+ * Used before real measurements are available.
7
+ */
8
+ export class EstimatedLayoutProvider implements LayoutProvider {
9
+ private readonly itemCount: number
10
+ private readonly itemHeight: number
11
+ private readonly width: number
12
+
13
+ constructor(
14
+ itemCount: number,
15
+ itemHeight: number,
16
+ width: number
17
+ ) {
18
+ this.itemCount = itemCount
19
+ this.itemHeight = itemHeight
20
+ this.width = width
21
+ }
22
+
23
+ getItemCount(): number {
24
+ return this.itemCount
25
+ }
26
+
27
+ getLayout(index: number): LayoutRectangle {
28
+ return {
29
+ x: 0,
30
+ y: index * this.itemHeight,
31
+ width: this.width,
32
+ height: this.itemHeight,
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,21 @@
1
+ import type { LayoutProvider } from './LayoutProvider'
2
+ import type { LayoutRectangle } from './LayoutRectangle'
3
+
4
+ /**
5
+ * Resolves layouts eagerly into a contiguous array.
6
+ * Pure, deterministic, and reusable.
7
+ *
8
+ * FlashList equivalent: internal layout resolver.
9
+ */
10
+ export function computeLayouts(
11
+ provider: LayoutProvider
12
+ ): readonly LayoutRectangle[] {
13
+ const count = provider.getItemCount()
14
+ const layouts: LayoutRectangle[] = new Array(count)
15
+
16
+ for (let i = 0; i < count; i++) {
17
+ layouts[i] = provider.getLayout(i)
18
+ }
19
+
20
+ return layouts
21
+ }
@@ -0,0 +1,17 @@
1
+ import type { LayoutRectangle } from './LayoutRectangle'
2
+
3
+ /**
4
+ * Provides layout information for items.
5
+ * FlashList equivalent: LayoutProvider
6
+ */
7
+ export interface LayoutProvider {
8
+ /**
9
+ * Total number of items
10
+ */
11
+ getItemCount(): number
12
+
13
+ /**
14
+ * Layout rectangle for a given index
15
+ */
16
+ getLayout(index: number): LayoutRectangle
17
+ }