react-native-nitro-list 0.1.1 → 0.1.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 (312) hide show
  1. package/ios/HybridNitroList.swift +10 -14
  2. package/lib/commonjs/cell/CellKeyGenerator.js +21 -0
  3. package/lib/commonjs/cell/CellKeyGenerator.js.map +1 -0
  4. package/lib/commonjs/cell/CellRecycler.js +48 -40
  5. package/lib/commonjs/cell/CellRecycler.js.map +1 -1
  6. package/lib/commonjs/cell/createCell.js +21 -0
  7. package/lib/commonjs/cell/createCell.js.map +1 -0
  8. package/lib/commonjs/cell/index.js +20 -0
  9. package/lib/commonjs/cell/index.js.map +1 -0
  10. package/lib/commonjs/getVisibleIndices.js.map +1 -1
  11. package/lib/commonjs/hooks/usePersistentCallback.js +36 -0
  12. package/lib/commonjs/hooks/usePersistentCallback.js.map +1 -0
  13. package/lib/commonjs/index.js +1 -1
  14. package/lib/commonjs/layout/MutableLinearLayout.js +78 -39
  15. package/lib/commonjs/layout/MutableLinearLayout.js.map +1 -1
  16. package/lib/commonjs/layout/constants/layoutDefaults.js +19 -0
  17. package/lib/commonjs/layout/constants/layoutDefaults.js.map +1 -0
  18. package/lib/commonjs/layout/index.js +0 -18
  19. package/lib/commonjs/layout/index.js.map +1 -1
  20. package/lib/commonjs/recycler/CellPool.js +46 -0
  21. package/lib/commonjs/recycler/CellPool.js.map +1 -0
  22. package/lib/commonjs/recycler/RecyclerList.js +224 -0
  23. package/lib/commonjs/recycler/RecyclerList.js.map +1 -0
  24. package/lib/commonjs/types/Axis.js +2 -0
  25. package/lib/commonjs/{layout/LayoutProvider.js.map → types/Axis.js.map} +1 -1
  26. package/lib/commonjs/types/CellKey.js +2 -0
  27. package/lib/{module/layout/LayoutProvider.js.map → commonjs/types/CellKey.js.map} +1 -1
  28. package/lib/commonjs/types/CellType.js +2 -0
  29. package/lib/commonjs/{layout/LayoutRectangle.js.map → types/CellType.js.map} +1 -1
  30. package/lib/commonjs/types/VisibleRange.js +2 -0
  31. package/lib/{module/layout/LayoutRectangle.js.map → commonjs/types/VisibleRange.js.map} +1 -1
  32. package/lib/commonjs/{RecyclerList.types.js → types/VisibleRangeInput.js} +1 -1
  33. package/lib/commonjs/types/VisibleRangeInput.js.map +1 -0
  34. package/lib/commonjs/types/index.js +13 -0
  35. package/lib/commonjs/types/index.js.map +1 -0
  36. package/lib/commonjs/types/layout/LayoutRect.js +2 -0
  37. package/lib/commonjs/types/layout/LayoutRect.js.map +1 -0
  38. package/lib/commonjs/types/layout/LinearLayoutInput.js +6 -0
  39. package/lib/commonjs/types/layout/LinearLayoutInput.js.map +1 -0
  40. package/lib/commonjs/types/layout/MainAxisPadding.js +26 -0
  41. package/lib/commonjs/types/layout/MainAxisPadding.js.map +1 -0
  42. package/lib/commonjs/types/layout/index.js +2 -0
  43. package/lib/commonjs/types/layout/index.js.map +1 -0
  44. package/lib/commonjs/types/recycler/RecyclerCellInstance.js +6 -0
  45. package/lib/commonjs/types/recycler/RecyclerCellInstance.js.map +1 -0
  46. package/lib/commonjs/types/recycler/RecyclerItemRenderer.js +6 -0
  47. package/lib/commonjs/types/recycler/RecyclerItemRenderer.js.map +1 -0
  48. package/lib/commonjs/types/recycler/RecyclerListProps.js +6 -0
  49. package/lib/commonjs/types/recycler/RecyclerListProps.js.map +1 -0
  50. package/lib/commonjs/types/recycler/index.js +2 -0
  51. package/lib/commonjs/types/recycler/index.js.map +1 -0
  52. package/lib/commonjs/{layout/LayoutProvider.js → types/scroll/ScrollMetrics.js} +1 -1
  53. package/lib/commonjs/types/scroll/ScrollMetrics.js.map +1 -0
  54. package/lib/commonjs/types/scroll/index.js +2 -0
  55. package/lib/commonjs/types/scroll/index.js.map +1 -0
  56. package/lib/commonjs/windowing/computeVisibleItemRange.js +71 -0
  57. package/lib/commonjs/windowing/computeVisibleItemRange.js.map +1 -0
  58. package/lib/commonjs/windowing/index.js +3 -3
  59. package/lib/commonjs/windowing/index.js.map +1 -1
  60. package/lib/module/cell/CellKeyGenerator.js +16 -0
  61. package/lib/module/cell/CellKeyGenerator.js.map +1 -0
  62. package/lib/module/cell/CellRecycler.js +48 -39
  63. package/lib/module/cell/CellRecycler.js.map +1 -1
  64. package/lib/module/cell/createCell.js +17 -0
  65. package/lib/module/cell/createCell.js.map +1 -0
  66. package/lib/module/cell/index.js +7 -0
  67. package/lib/module/cell/index.js.map +1 -0
  68. package/lib/module/getVisibleIndices.js.map +1 -1
  69. package/lib/module/hooks/usePersistentCallback.js +33 -0
  70. package/lib/module/hooks/usePersistentCallback.js.map +1 -0
  71. package/lib/module/index.js +1 -1
  72. package/lib/module/index.js.map +1 -1
  73. package/lib/module/layout/MutableLinearLayout.js +78 -38
  74. package/lib/module/layout/MutableLinearLayout.js.map +1 -1
  75. package/lib/module/layout/constants/layoutDefaults.js +15 -0
  76. package/lib/module/layout/constants/layoutDefaults.js.map +1 -0
  77. package/lib/module/layout/index.js +0 -3
  78. package/lib/module/layout/index.js.map +1 -1
  79. package/lib/module/recycler/CellPool.js +41 -0
  80. package/lib/module/recycler/CellPool.js.map +1 -0
  81. package/lib/module/recycler/RecyclerList.js +221 -0
  82. package/lib/module/recycler/RecyclerList.js.map +1 -0
  83. package/lib/module/types/Axis.js +2 -0
  84. package/lib/module/types/Axis.js.map +1 -0
  85. package/lib/module/types/CellKey.js +2 -0
  86. package/lib/module/types/CellKey.js.map +1 -0
  87. package/lib/module/types/CellType.js +2 -0
  88. package/lib/module/types/CellType.js.map +1 -0
  89. package/lib/module/types/VisibleRange.js +2 -0
  90. package/lib/module/types/VisibleRange.js.map +1 -0
  91. package/lib/module/types/VisibleRangeInput.js +4 -0
  92. package/lib/module/types/VisibleRangeInput.js.map +1 -0
  93. package/lib/module/types/index.js +4 -0
  94. package/lib/module/types/index.js.map +1 -0
  95. package/lib/module/types/layout/LayoutRect.js +2 -0
  96. package/lib/module/types/layout/LayoutRect.js.map +1 -0
  97. package/lib/module/types/layout/LinearLayoutInput.js +4 -0
  98. package/lib/module/types/layout/LinearLayoutInput.js.map +1 -0
  99. package/lib/module/types/layout/MainAxisPadding.js +22 -0
  100. package/lib/module/types/layout/MainAxisPadding.js.map +1 -0
  101. package/lib/module/types/layout/index.js +2 -0
  102. package/lib/module/types/layout/index.js.map +1 -0
  103. package/lib/module/types/recycler/RecyclerCellInstance.js +4 -0
  104. package/lib/module/types/recycler/RecyclerCellInstance.js.map +1 -0
  105. package/lib/module/types/recycler/RecyclerItemRenderer.js +4 -0
  106. package/lib/module/types/recycler/RecyclerItemRenderer.js.map +1 -0
  107. package/lib/module/types/recycler/RecyclerListProps.js +4 -0
  108. package/lib/module/types/recycler/RecyclerListProps.js.map +1 -0
  109. package/lib/module/types/recycler/index.js +2 -0
  110. package/lib/module/types/recycler/index.js.map +1 -0
  111. package/lib/module/types/scroll/ScrollMetrics.js +4 -0
  112. package/lib/module/types/scroll/ScrollMetrics.js.map +1 -0
  113. package/lib/module/types/scroll/index.js +2 -0
  114. package/lib/module/types/scroll/index.js.map +1 -0
  115. package/lib/module/windowing/computeVisibleItemRange.js +67 -0
  116. package/lib/module/windowing/computeVisibleItemRange.js.map +1 -0
  117. package/lib/module/windowing/index.js +1 -1
  118. package/lib/module/windowing/index.js.map +1 -1
  119. package/lib/typescript/src/cell/Cell.d.ts +13 -4
  120. package/lib/typescript/src/cell/Cell.d.ts.map +1 -1
  121. package/lib/typescript/src/cell/CellKeyGenerator.d.ts +11 -0
  122. package/lib/typescript/src/cell/CellKeyGenerator.d.ts.map +1 -0
  123. package/lib/typescript/src/cell/CellRecycler.d.ts +19 -11
  124. package/lib/typescript/src/cell/CellRecycler.d.ts.map +1 -1
  125. package/lib/typescript/src/cell/createCell.d.ts +7 -0
  126. package/lib/typescript/src/cell/createCell.d.ts.map +1 -0
  127. package/lib/typescript/src/cell/index.d.ts +4 -0
  128. package/lib/typescript/src/cell/index.d.ts.map +1 -0
  129. package/lib/typescript/src/getVisibleIndices.d.ts +2 -2
  130. package/lib/typescript/src/getVisibleIndices.d.ts.map +1 -1
  131. package/lib/typescript/src/hooks/usePersistentCallback.d.ts +16 -0
  132. package/lib/typescript/src/hooks/usePersistentCallback.d.ts.map +1 -0
  133. package/lib/typescript/src/index.d.ts +1 -2
  134. package/lib/typescript/src/index.d.ts.map +1 -1
  135. package/lib/typescript/src/layout/MutableLinearLayout.d.ts +45 -13
  136. package/lib/typescript/src/layout/MutableLinearLayout.d.ts.map +1 -1
  137. package/lib/typescript/src/layout/constants/layoutDefaults.d.ts +13 -0
  138. package/lib/typescript/src/layout/constants/layoutDefaults.d.ts.map +1 -0
  139. package/lib/typescript/src/layout/index.d.ts +1 -4
  140. package/lib/typescript/src/layout/index.d.ts.map +1 -1
  141. package/lib/typescript/src/native/NitroList.types.d.ts +2 -2
  142. package/lib/typescript/src/native/NitroList.types.d.ts.map +1 -1
  143. package/lib/typescript/src/recycler/CellPool.d.ts +14 -0
  144. package/lib/typescript/src/recycler/CellPool.d.ts.map +1 -0
  145. package/lib/typescript/src/recycler/RecyclerList.d.ts +4 -0
  146. package/lib/typescript/src/recycler/RecyclerList.d.ts.map +1 -0
  147. package/lib/typescript/src/specs/nitro-layout-engine.nitro.d.ts +2 -2
  148. package/lib/typescript/src/specs/nitro-layout-engine.nitro.d.ts.map +1 -1
  149. package/lib/typescript/src/types/Axis.d.ts +11 -0
  150. package/lib/typescript/src/types/Axis.d.ts.map +1 -0
  151. package/lib/typescript/src/types/CellKey.d.ts +10 -0
  152. package/lib/typescript/src/types/CellKey.d.ts.map +1 -0
  153. package/lib/typescript/src/types/CellType.d.ts +11 -0
  154. package/lib/typescript/src/types/CellType.d.ts.map +1 -0
  155. package/lib/typescript/src/types/VisibleRange.d.ts +10 -0
  156. package/lib/typescript/src/types/VisibleRange.d.ts.map +1 -0
  157. package/lib/typescript/src/types/VisibleRangeInput.d.ts +35 -0
  158. package/lib/typescript/src/types/VisibleRangeInput.d.ts.map +1 -0
  159. package/lib/typescript/src/types/index.d.ts +8 -0
  160. package/lib/typescript/src/types/index.d.ts.map +1 -0
  161. package/lib/typescript/src/types/layout/LayoutRect.d.ts +15 -0
  162. package/lib/typescript/src/types/layout/LayoutRect.d.ts.map +1 -0
  163. package/lib/typescript/src/types/layout/LinearLayoutInput.d.ts +10 -0
  164. package/lib/typescript/src/types/layout/LinearLayoutInput.d.ts.map +1 -0
  165. package/lib/typescript/src/types/layout/MainAxisPadding.d.ts +20 -0
  166. package/lib/typescript/src/types/layout/MainAxisPadding.d.ts.map +1 -0
  167. package/lib/typescript/src/types/layout/index.d.ts +4 -0
  168. package/lib/typescript/src/types/layout/index.d.ts.map +1 -0
  169. package/lib/typescript/src/types/recycler/RecyclerCellInstance.d.ts +37 -0
  170. package/lib/typescript/src/types/recycler/RecyclerCellInstance.d.ts.map +1 -0
  171. package/lib/typescript/src/types/recycler/RecyclerItemRenderer.d.ts +8 -0
  172. package/lib/typescript/src/types/recycler/RecyclerItemRenderer.d.ts.map +1 -0
  173. package/lib/typescript/src/types/recycler/RecyclerListProps.d.ts +66 -0
  174. package/lib/typescript/src/types/recycler/RecyclerListProps.d.ts.map +1 -0
  175. package/lib/typescript/src/types/recycler/index.d.ts +4 -0
  176. package/lib/typescript/src/types/recycler/index.d.ts.map +1 -0
  177. package/lib/typescript/src/types/scroll/ScrollMetrics.d.ts +15 -0
  178. package/lib/typescript/src/types/scroll/ScrollMetrics.d.ts.map +1 -0
  179. package/lib/typescript/src/types/scroll/index.d.ts +2 -0
  180. package/lib/typescript/src/types/scroll/index.d.ts.map +1 -0
  181. package/lib/typescript/src/windowing/computeVisibleItemRange.d.ts +15 -0
  182. package/lib/typescript/src/windowing/computeVisibleItemRange.d.ts.map +1 -0
  183. package/lib/typescript/src/windowing/index.d.ts +1 -1
  184. package/lib/typescript/src/windowing/index.d.ts.map +1 -1
  185. package/nitrogen/generated/android/c++/JHybridNitroLayoutEngineSpec.cpp +7 -7
  186. package/nitrogen/generated/android/c++/JHybridNitroLayoutEngineSpec.hpp +1 -1
  187. package/nitrogen/generated/android/c++/{JLayoutRectangle.hpp → JLayoutRect.hpp} +10 -10
  188. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/HybridNitroLayoutEngineSpec.kt +1 -1
  189. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/{LayoutRectangle.kt → LayoutRect.kt} +5 -5
  190. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Bridge.hpp +14 -14
  191. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Umbrella.hpp +3 -3
  192. package/nitrogen/generated/ios/c++/HybridNitroLayoutEngineSpecSwift.hpp +4 -4
  193. package/nitrogen/generated/ios/swift/HybridNitroLayoutEngineSpec.swift +1 -1
  194. package/nitrogen/generated/ios/swift/HybridNitroLayoutEngineSpec_cxx.swift +5 -5
  195. package/nitrogen/generated/ios/swift/{LayoutRectangle.swift → LayoutRect.swift} +5 -5
  196. package/nitrogen/generated/shared/c++/HybridNitroLayoutEngineSpec.hpp +4 -4
  197. package/nitrogen/generated/shared/c++/{LayoutRectangle.hpp → LayoutRect.hpp} +11 -11
  198. package/package.json +1 -1
  199. package/src/cell/Cell.ts +13 -4
  200. package/src/cell/CellKeyGenerator.ts +17 -0
  201. package/src/cell/CellRecycler.ts +53 -43
  202. package/src/cell/createCell.ts +15 -0
  203. package/src/cell/index.ts +5 -0
  204. package/src/getVisibleIndices.ts +4 -2
  205. package/src/hooks/usePersistentCallback.ts +37 -0
  206. package/src/index.ts +1 -2
  207. package/src/layout/MutableLinearLayout.ts +91 -58
  208. package/src/layout/constants/layoutDefaults.ts +12 -0
  209. package/src/layout/index.ts +1 -4
  210. package/src/native/NitroList.types.ts +3 -2
  211. package/src/recycler/CellPool.ts +47 -0
  212. package/src/recycler/RecyclerList.tsx +304 -0
  213. package/src/specs/nitro-layout-engine.nitro.ts +2 -2
  214. package/src/types/Axis.ts +10 -0
  215. package/src/types/CellKey.ts +9 -0
  216. package/src/types/CellType.ts +10 -0
  217. package/src/types/VisibleRange.ts +9 -0
  218. package/src/types/VisibleRangeInput.ts +39 -0
  219. package/src/types/index.ts +15 -0
  220. package/src/types/layout/LayoutRect.ts +14 -0
  221. package/src/types/layout/LinearLayoutInput.ts +12 -0
  222. package/src/types/layout/MainAxisPadding.ts +23 -0
  223. package/src/types/layout/index.ts +3 -0
  224. package/src/types/recycler/RecyclerCellInstance.ts +40 -0
  225. package/src/types/recycler/RecyclerItemRenderer.ts +8 -0
  226. package/src/types/recycler/RecyclerListProps.ts +74 -0
  227. package/src/types/recycler/index.ts +3 -0
  228. package/src/types/scroll/ScrollMetrics.ts +18 -0
  229. package/src/types/scroll/index.ts +1 -0
  230. package/src/windowing/computeVisibleItemRange.ts +78 -0
  231. package/src/windowing/index.ts +1 -1
  232. package/lib/commonjs/RecyclerList.internal.js +0 -25
  233. package/lib/commonjs/RecyclerList.internal.js.map +0 -1
  234. package/lib/commonjs/RecyclerList.js +0 -171
  235. package/lib/commonjs/RecyclerList.js.map +0 -1
  236. package/lib/commonjs/RecyclerList.types.js.map +0 -1
  237. package/lib/commonjs/cell/StableKey.js +0 -10
  238. package/lib/commonjs/cell/StableKey.js.map +0 -1
  239. package/lib/commonjs/hooks/useCellRenderer.js +0 -62
  240. package/lib/commonjs/hooks/useCellRenderer.js.map +0 -1
  241. package/lib/commonjs/hooks/useStableCallback.js +0 -13
  242. package/lib/commonjs/hooks/useStableCallback.js.map +0 -1
  243. package/lib/commonjs/layout/EstimatedLayoutProvider.js +0 -30
  244. package/lib/commonjs/layout/EstimatedLayoutProvider.js.map +0 -1
  245. package/lib/commonjs/layout/LayoutEngine.js +0 -21
  246. package/lib/commonjs/layout/LayoutEngine.js.map +0 -1
  247. package/lib/commonjs/layout/LayoutRectangle.js +0 -2
  248. package/lib/commonjs/viewability/ViewabilityHelper.js +0 -121
  249. package/lib/commonjs/viewability/ViewabilityHelper.js.map +0 -1
  250. package/lib/commonjs/windowing/findVisibleIndexRange.js +0 -48
  251. package/lib/commonjs/windowing/findVisibleIndexRange.js.map +0 -1
  252. package/lib/module/RecyclerList.internal.js +0 -22
  253. package/lib/module/RecyclerList.internal.js.map +0 -1
  254. package/lib/module/RecyclerList.js +0 -166
  255. package/lib/module/RecyclerList.js.map +0 -1
  256. package/lib/module/RecyclerList.types.js +0 -4
  257. package/lib/module/RecyclerList.types.js.map +0 -1
  258. package/lib/module/cell/StableKey.js +0 -6
  259. package/lib/module/cell/StableKey.js.map +0 -1
  260. package/lib/module/hooks/useCellRenderer.js +0 -58
  261. package/lib/module/hooks/useCellRenderer.js.map +0 -1
  262. package/lib/module/hooks/useStableCallback.js +0 -9
  263. package/lib/module/hooks/useStableCallback.js.map +0 -1
  264. package/lib/module/layout/EstimatedLayoutProvider.js +0 -25
  265. package/lib/module/layout/EstimatedLayoutProvider.js.map +0 -1
  266. package/lib/module/layout/LayoutEngine.js +0 -17
  267. package/lib/module/layout/LayoutEngine.js.map +0 -1
  268. package/lib/module/layout/LayoutProvider.js +0 -4
  269. package/lib/module/layout/LayoutRectangle.js +0 -2
  270. package/lib/module/viewability/ViewabilityHelper.js +0 -116
  271. package/lib/module/viewability/ViewabilityHelper.js.map +0 -1
  272. package/lib/module/windowing/findVisibleIndexRange.js +0 -44
  273. package/lib/module/windowing/findVisibleIndexRange.js.map +0 -1
  274. package/lib/typescript/src/RecyclerList.d.ts +0 -26
  275. package/lib/typescript/src/RecyclerList.d.ts.map +0 -1
  276. package/lib/typescript/src/RecyclerList.internal.d.ts +0 -9
  277. package/lib/typescript/src/RecyclerList.internal.d.ts.map +0 -1
  278. package/lib/typescript/src/RecyclerList.types.d.ts +0 -18
  279. package/lib/typescript/src/RecyclerList.types.d.ts.map +0 -1
  280. package/lib/typescript/src/__tests__/windowing/findVisibleIndexRange.test.d.ts +0 -2
  281. package/lib/typescript/src/__tests__/windowing/findVisibleIndexRange.test.d.ts.map +0 -1
  282. package/lib/typescript/src/cell/StableKey.d.ts +0 -2
  283. package/lib/typescript/src/cell/StableKey.d.ts.map +0 -1
  284. package/lib/typescript/src/hooks/useCellRenderer.d.ts +0 -19
  285. package/lib/typescript/src/hooks/useCellRenderer.d.ts.map +0 -1
  286. package/lib/typescript/src/hooks/useStableCallback.d.ts +0 -2
  287. package/lib/typescript/src/hooks/useStableCallback.d.ts.map +0 -1
  288. package/lib/typescript/src/layout/EstimatedLayoutProvider.d.ts +0 -15
  289. package/lib/typescript/src/layout/EstimatedLayoutProvider.d.ts.map +0 -1
  290. package/lib/typescript/src/layout/LayoutEngine.d.ts +0 -10
  291. package/lib/typescript/src/layout/LayoutEngine.d.ts.map +0 -1
  292. package/lib/typescript/src/layout/LayoutProvider.d.ts +0 -16
  293. package/lib/typescript/src/layout/LayoutProvider.d.ts.map +0 -1
  294. package/lib/typescript/src/layout/LayoutRectangle.d.ts +0 -11
  295. package/lib/typescript/src/layout/LayoutRectangle.d.ts.map +0 -1
  296. package/lib/typescript/src/viewability/ViewabilityHelper.d.ts +0 -50
  297. package/lib/typescript/src/viewability/ViewabilityHelper.d.ts.map +0 -1
  298. package/lib/typescript/src/windowing/findVisibleIndexRange.d.ts +0 -11
  299. package/lib/typescript/src/windowing/findVisibleIndexRange.d.ts.map +0 -1
  300. package/src/RecyclerList.internal.ts +0 -38
  301. package/src/RecyclerList.tsx +0 -252
  302. package/src/RecyclerList.types.ts +0 -24
  303. package/src/__tests__/windowing/findVisibleIndexRange.test.ts +0 -55
  304. package/src/cell/StableKey.ts +0 -6
  305. package/src/hooks/useCellRenderer.ts +0 -86
  306. package/src/hooks/useStableCallback.ts +0 -13
  307. package/src/layout/EstimatedLayoutProvider.ts +0 -35
  308. package/src/layout/LayoutEngine.ts +0 -21
  309. package/src/layout/LayoutProvider.ts +0 -17
  310. package/src/layout/LayoutRectangle.ts +0 -10
  311. package/src/viewability/ViewabilityHelper.ts +0 -130
  312. package/src/windowing/findVisibleIndexRange.ts +0 -60
@@ -1,55 +0,0 @@
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
- })
@@ -1,6 +0,0 @@
1
- export function getStableKey(
2
- slotKey: string,
3
- index: number
4
- ): string {
5
- return `${slotKey}:${index}`
6
- }
@@ -1,86 +0,0 @@
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
- }
@@ -1,13 +0,0 @@
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
- }
@@ -1,35 +0,0 @@
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
- }
@@ -1,21 +0,0 @@
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
- }
@@ -1,17 +0,0 @@
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
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * Immutable layout rectangle for a single item.
3
- * Equivalent to FlashList's Layout.
4
- */
5
- export interface LayoutRectangle {
6
- readonly x: number
7
- readonly y: number
8
- readonly width: number
9
- readonly height: number
10
- }
@@ -1,130 +0,0 @@
1
- import type { LayoutRectangle } from '../layout/LayoutRectangle'
2
- import type { ScrollMetrics } from '../windowing/ScrollMetrics'
3
-
4
- /**
5
- * Public token describing viewability state of an item.
6
- * Mirrors FlashList's ViewToken concept.
7
- */
8
- export type ViewToken = {
9
- index: number
10
- isViewable: boolean
11
- }
12
-
13
- /**
14
- * Configuration for viewability calculations.
15
- */
16
- export type ViewabilityConfig = {
17
- /**
18
- * Percentage (0–100) of item height that must be visible
19
- * for the item to be considered "viewable".
20
- */
21
- itemVisiblePercentThreshold?: number
22
- }
23
-
24
- /**
25
- * ViewabilityHelper
26
- *
27
- * Pure observer:
28
- * - Does NOT affect layout
29
- * - Does NOT affect recycling
30
- * - Computes visibility based on layout + scroll metrics
31
- *
32
- * This class is intentionally stateful (lastVisible)
33
- * to compute "changed" items efficiently.
34
- */
35
- export class ViewabilityHelper {
36
- /** Previously visible indices */
37
- private lastVisible = new Set<number>()
38
-
39
- constructor(
40
- private readonly config: ViewabilityConfig = {}
41
- ) {}
42
-
43
- /**
44
- * Computes which items are viewable and which changed
45
- * since the last invocation.
46
- *
47
- * IMPORTANT:
48
- * - This method should be called AFTER windowing,
49
- * not on the full dataset.
50
- */
51
- computeViewableItems(
52
- layouts: readonly LayoutRectangle[],
53
- metrics: ScrollMetrics
54
- ): {
55
- viewableItems: ViewToken[]
56
- changed: ViewToken[]
57
- } {
58
- const visibleNow = new Set<number>()
59
- const viewableItems: ViewToken[] = []
60
- const changed: ViewToken[] = []
61
-
62
- const viewportTop = metrics.offsetY
63
- const viewportBottom = viewportTop + metrics.height
64
-
65
- // Normalize threshold into [0, 1]
66
- const threshold =
67
- (this.config.itemVisiblePercentThreshold ?? 0) / 100
68
-
69
- /**
70
- * NOTE:
71
- * We intentionally iterate layouts sequentially,
72
- * but EXIT EARLY when items are completely below viewport.
73
- *
74
- * This keeps complexity near O(visibleItems),
75
- * not O(totalItems).
76
- */
77
- for (let i = 0; i < layouts.length; i++) {
78
- const layout = layouts[i]!
79
-
80
- // If item is completely below viewport, stop
81
- if (layout.y > viewportBottom) {
82
- break
83
- }
84
-
85
- const itemTop = layout.y
86
- const itemBottom = layout.y + layout.height
87
-
88
- // If item is completely above viewport, skip
89
- if (itemBottom < viewportTop) {
90
- continue
91
- }
92
-
93
- // Compute visible intersection
94
- const visibleTop = Math.max(itemTop, viewportTop)
95
- const visibleBottom = Math.min(itemBottom, viewportBottom)
96
-
97
- const visibleHeight = Math.max(0, visibleBottom - visibleTop)
98
-
99
- // Guard against zero-height items
100
- const itemHeight =
101
- layout.height > 0 ? layout.height : 1
102
-
103
- const visibleRatio = visibleHeight / itemHeight
104
-
105
- if (visibleRatio >= threshold) {
106
- visibleNow.add(i)
107
- viewableItems.push({ index: i, isViewable: true })
108
-
109
- // Newly visible
110
- if (!this.lastVisible.has(i)) {
111
- changed.push({ index: i, isViewable: true })
112
- }
113
- }
114
- }
115
-
116
- /**
117
- * Items that were visible before but not anymore
118
- */
119
- for (const index of this.lastVisible) {
120
- if (!visibleNow.has(index)) {
121
- changed.push({ index, isViewable: false })
122
- }
123
- }
124
-
125
- // Update snapshot
126
- this.lastVisible = visibleNow
127
-
128
- return { viewableItems, changed }
129
- }
130
- }
@@ -1,60 +0,0 @@
1
- import type { LayoutRectangle } from '../layout/LayoutRectangle'
2
- import type { ScrollMetrics } from './ScrollMetrics'
3
-
4
- /**
5
- * Computes the contiguous range of item indices
6
- * intersecting the viewport expanded by bufferPx.
7
- *
8
- * PURE function. No allocations besides output.
9
- * FlashList-style windowing.
10
- */
11
- export function findVisibleIndexRange(
12
- layouts: readonly LayoutRectangle[],
13
- metrics: ScrollMetrics,
14
- bufferPx: number
15
- ): readonly number[] {
16
- const count = layouts.length
17
-
18
- // 🔒 CRITICAL GUARDS (FlashList-style)
19
- if (
20
- count === 0 ||
21
- metrics.height <= 0 ||
22
- bufferPx < 0
23
- ) {
24
- return []
25
- }
26
-
27
- const windowStart =
28
- Math.max(0, metrics.offsetY - bufferPx)
29
-
30
- const windowEnd =
31
- metrics.offsetY + metrics.height + bufferPx
32
-
33
- // Binary search for first intersecting item
34
- let low = 0
35
- let high = count - 1
36
- let firstVisible = count
37
-
38
- while (low <= high) {
39
- const mid = (low + high) >> 1
40
- const rect = layouts[mid]!
41
-
42
- if (rect.y + rect.height >= windowStart) {
43
- firstVisible = mid
44
- high = mid - 1
45
- } else {
46
- low = mid + 1
47
- }
48
- }
49
-
50
- // Linear scan forward
51
- const visible: number[] = []
52
-
53
- for (let i = firstVisible; i < count; i++) {
54
- const rect = layouts[i]!
55
- if (rect.y > windowEnd) break
56
- visible.push(i)
57
- }
58
-
59
- return visible
60
- }