react-native-nitro-list 0.1.2 → 0.1.3

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 (160) hide show
  1. package/README.md +16 -44
  2. package/ios/HybridNitroList.swift +7 -5
  3. package/lib/commonjs/index.js +31 -3
  4. package/lib/commonjs/index.js.map +1 -1
  5. package/lib/commonjs/layout/MutableLinearLayout.js.map +1 -1
  6. package/lib/commonjs/native/NitroListView.js +20 -0
  7. package/lib/commonjs/native/NitroListView.js.map +1 -0
  8. package/lib/commonjs/recycler/CellPool.js +5 -18
  9. package/lib/commonjs/recycler/CellPool.js.map +1 -1
  10. package/lib/commonjs/recycler/{RecyclerList.js → NitroList.js} +91 -92
  11. package/lib/commonjs/recycler/NitroList.js.map +1 -0
  12. package/lib/commonjs/scroll/useScrollVelocity.js +20 -0
  13. package/lib/commonjs/scroll/useScrollVelocity.js.map +1 -0
  14. package/lib/commonjs/{native/NitroList.types.js → specs/NitroList.nitro.js} +1 -1
  15. package/lib/commonjs/{native/NitroList.types.js.map → specs/NitroList.nitro.js.map} +1 -1
  16. package/lib/commonjs/types/CellType.js +25 -0
  17. package/lib/commonjs/types/CellType.js.map +1 -1
  18. package/lib/commonjs/types/recycler/CellPool.js +42 -0
  19. package/lib/commonjs/types/recycler/CellPool.js.map +1 -0
  20. package/lib/commonjs/types/recycler/{RecyclerListProps.js → NitroListProps.js} +1 -1
  21. package/lib/commonjs/types/recycler/NitroListProps.js.map +1 -0
  22. package/lib/commonjs/types/recycler/{RecyclerCellInstance.js → RecyclerCell.js} +1 -1
  23. package/lib/commonjs/types/recycler/RecyclerCell.js.map +1 -0
  24. package/lib/commonjs/windowing/computeVisibleItemRange.js +22 -32
  25. package/lib/commonjs/windowing/computeVisibleItemRange.js.map +1 -1
  26. package/lib/module/index.js +5 -1
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/module/layout/MutableLinearLayout.js.map +1 -1
  29. package/lib/module/native/NitroListView.js +17 -0
  30. package/lib/module/native/NitroListView.js.map +1 -0
  31. package/lib/module/recycler/CellPool.js +5 -18
  32. package/lib/module/recycler/CellPool.js.map +1 -1
  33. package/lib/module/recycler/NitroList.js +220 -0
  34. package/lib/module/recycler/NitroList.js.map +1 -0
  35. package/lib/module/scroll/useScrollVelocity.js +16 -0
  36. package/lib/module/scroll/useScrollVelocity.js.map +1 -0
  37. package/lib/module/specs/NitroList.nitro.js +4 -0
  38. package/lib/module/{native/NitroList.types.js.map → specs/NitroList.nitro.js.map} +1 -1
  39. package/lib/module/types/CellType.js +20 -0
  40. package/lib/module/types/CellType.js.map +1 -1
  41. package/lib/module/types/recycler/CellPool.js +37 -0
  42. package/lib/module/types/recycler/CellPool.js.map +1 -0
  43. package/lib/module/types/recycler/NitroListProps.js +4 -0
  44. package/lib/module/types/recycler/NitroListProps.js.map +1 -0
  45. package/lib/module/types/recycler/RecyclerCell.js +4 -0
  46. package/lib/module/types/recycler/RecyclerCell.js.map +1 -0
  47. package/lib/module/windowing/computeVisibleItemRange.js +22 -32
  48. package/lib/module/windowing/computeVisibleItemRange.js.map +1 -1
  49. package/lib/typescript/src/index.d.ts +3 -1
  50. package/lib/typescript/src/index.d.ts.map +1 -1
  51. package/lib/typescript/src/native/NitroListView.d.ts +20 -0
  52. package/lib/typescript/src/native/NitroListView.d.ts.map +1 -0
  53. package/lib/typescript/src/recycler/CellPool.d.ts +4 -7
  54. package/lib/typescript/src/recycler/CellPool.d.ts.map +1 -1
  55. package/lib/typescript/src/recycler/NitroList.d.ts +4 -0
  56. package/lib/typescript/src/recycler/NitroList.d.ts.map +1 -0
  57. package/lib/typescript/src/scroll/useScrollVelocity.d.ts +2 -0
  58. package/lib/typescript/src/scroll/useScrollVelocity.d.ts.map +1 -0
  59. package/lib/typescript/src/specs/NitroList.nitro.d.ts +26 -0
  60. package/lib/typescript/src/specs/NitroList.nitro.d.ts.map +1 -0
  61. package/lib/typescript/src/types/CellKey.d.ts +1 -9
  62. package/lib/typescript/src/types/CellKey.d.ts.map +1 -1
  63. package/lib/typescript/src/types/CellType.d.ts +12 -1
  64. package/lib/typescript/src/types/CellType.d.ts.map +1 -1
  65. package/lib/typescript/src/types/recycler/CellPool.d.ts +16 -0
  66. package/lib/typescript/src/types/recycler/CellPool.d.ts.map +1 -0
  67. package/lib/typescript/src/types/recycler/{RecyclerListProps.d.ts → NitroListProps.d.ts} +3 -3
  68. package/lib/typescript/src/types/recycler/NitroListProps.d.ts.map +1 -0
  69. package/lib/typescript/src/types/recycler/RecyclerCell.d.ts +12 -0
  70. package/lib/typescript/src/types/recycler/RecyclerCell.d.ts.map +1 -0
  71. package/lib/typescript/src/types/recycler/RecyclerItemRenderer.d.ts +6 -2
  72. package/lib/typescript/src/types/recycler/RecyclerItemRenderer.d.ts.map +1 -1
  73. package/lib/typescript/src/types/recycler/index.d.ts +2 -2
  74. package/lib/typescript/src/types/recycler/index.d.ts.map +1 -1
  75. package/lib/typescript/src/windowing/computeVisibleItemRange.d.ts +16 -12
  76. package/lib/typescript/src/windowing/computeVisibleItemRange.d.ts.map +1 -1
  77. package/nitro.json +5 -5
  78. package/nitrogen/generated/android/NitroList+autolinking.cmake +2 -2
  79. package/nitrogen/generated/android/NitroListOnLoad.cpp +2 -2
  80. package/nitrogen/generated/android/c++/{JHybridNitroLayoutEngineSpec.cpp → JHybridNitroListSpec.cpp} +15 -15
  81. package/nitrogen/generated/android/c++/{JHybridNitroLayoutEngineSpec.hpp → JHybridNitroListSpec.hpp} +11 -11
  82. package/nitrogen/generated/android/c++/{JLayoutRect.hpp → JItemLayout.hpp} +10 -10
  83. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/{HybridNitroLayoutEngineSpec.kt → HybridNitroListSpec.kt} +7 -7
  84. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrolist/{LayoutRect.kt → ItemLayout.kt} +5 -5
  85. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Bridge.cpp +9 -9
  86. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Bridge.hpp +27 -27
  87. package/nitrogen/generated/ios/NitroList-Swift-Cxx-Umbrella.hpp +8 -8
  88. package/nitrogen/generated/ios/c++/{HybridNitroLayoutEngineSpecSwift.cpp → HybridNitroListSpecSwift.cpp} +2 -2
  89. package/nitrogen/generated/ios/c++/{HybridNitroLayoutEngineSpecSwift.hpp → HybridNitroListSpecSwift.hpp} +16 -16
  90. package/nitrogen/generated/ios/swift/HybridNitroListSpec.swift +56 -0
  91. package/nitrogen/generated/ios/swift/{HybridNitroLayoutEngineSpec_cxx.swift → HybridNitroListSpec_cxx.swift} +23 -23
  92. package/nitrogen/generated/ios/swift/{LayoutRect.swift → ItemLayout.swift} +5 -5
  93. package/nitrogen/generated/shared/c++/{HybridNitroLayoutEngineSpec.cpp → HybridNitroListSpec.cpp} +4 -4
  94. package/nitrogen/generated/shared/c++/{HybridNitroLayoutEngineSpec.hpp → HybridNitroListSpec.hpp} +13 -13
  95. package/nitrogen/generated/shared/c++/{LayoutRect.hpp → ItemLayout.hpp} +11 -11
  96. package/package.json +5 -5
  97. package/src/index.ts +7 -1
  98. package/src/layout/MutableLinearLayout.ts +1 -1
  99. package/src/native/NitroListView.ts +22 -0
  100. package/src/recycler/CellPool.ts +10 -24
  101. package/src/recycler/NitroList.tsx +317 -0
  102. package/src/scroll/useScrollVelocity.ts +16 -0
  103. package/src/specs/NitroList.nitro.ts +29 -0
  104. package/src/types/CellKey.ts +2 -9
  105. package/src/types/CellType.ts +8 -9
  106. package/src/types/recycler/CellPool.ts +45 -0
  107. package/src/types/recycler/{RecyclerListProps.ts → NitroListProps.ts} +2 -2
  108. package/src/types/recycler/RecyclerCell.ts +12 -0
  109. package/src/types/recycler/RecyclerItemRenderer.ts +6 -2
  110. package/src/types/recycler/index.ts +2 -2
  111. package/src/windowing/computeVisibleItemRange.ts +42 -38
  112. package/lib/commonjs/NitroList.js +0 -9
  113. package/lib/commonjs/NitroList.js.map +0 -1
  114. package/lib/commonjs/native/NitroLayoutEngine.js +0 -9
  115. package/lib/commonjs/native/NitroLayoutEngine.js.map +0 -1
  116. package/lib/commonjs/native/NitroRecyclerView.js +0 -9
  117. package/lib/commonjs/native/NitroRecyclerView.js.map +0 -1
  118. package/lib/commonjs/recycler/RecyclerList.js.map +0 -1
  119. package/lib/commonjs/specs/nitro-layout-engine.nitro.js +0 -6
  120. package/lib/commonjs/specs/nitro-layout-engine.nitro.js.map +0 -1
  121. package/lib/commonjs/types/recycler/RecyclerCellInstance.js.map +0 -1
  122. package/lib/commonjs/types/recycler/RecyclerListProps.js.map +0 -1
  123. package/lib/module/NitroList.js +0 -5
  124. package/lib/module/NitroList.js.map +0 -1
  125. package/lib/module/native/NitroLayoutEngine.js +0 -5
  126. package/lib/module/native/NitroLayoutEngine.js.map +0 -1
  127. package/lib/module/native/NitroList.types.js +0 -4
  128. package/lib/module/native/NitroRecyclerView.js +0 -5
  129. package/lib/module/native/NitroRecyclerView.js.map +0 -1
  130. package/lib/module/recycler/RecyclerList.js +0 -221
  131. package/lib/module/recycler/RecyclerList.js.map +0 -1
  132. package/lib/module/specs/nitro-layout-engine.nitro.js +0 -4
  133. package/lib/module/specs/nitro-layout-engine.nitro.js.map +0 -1
  134. package/lib/module/types/recycler/RecyclerCellInstance.js +0 -4
  135. package/lib/module/types/recycler/RecyclerCellInstance.js.map +0 -1
  136. package/lib/module/types/recycler/RecyclerListProps.js +0 -4
  137. package/lib/module/types/recycler/RecyclerListProps.js.map +0 -1
  138. package/lib/typescript/src/NitroList.d.ts +0 -5
  139. package/lib/typescript/src/NitroList.d.ts.map +0 -1
  140. package/lib/typescript/src/native/NitroLayoutEngine.d.ts +0 -3
  141. package/lib/typescript/src/native/NitroLayoutEngine.d.ts.map +0 -1
  142. package/lib/typescript/src/native/NitroList.types.d.ts +0 -9
  143. package/lib/typescript/src/native/NitroList.types.d.ts.map +0 -1
  144. package/lib/typescript/src/native/NitroRecyclerView.d.ts +0 -5
  145. package/lib/typescript/src/native/NitroRecyclerView.d.ts.map +0 -1
  146. package/lib/typescript/src/recycler/RecyclerList.d.ts +0 -4
  147. package/lib/typescript/src/recycler/RecyclerList.d.ts.map +0 -1
  148. package/lib/typescript/src/specs/nitro-layout-engine.nitro.d.ts +0 -14
  149. package/lib/typescript/src/specs/nitro-layout-engine.nitro.d.ts.map +0 -1
  150. package/lib/typescript/src/types/recycler/RecyclerCellInstance.d.ts +0 -37
  151. package/lib/typescript/src/types/recycler/RecyclerCellInstance.d.ts.map +0 -1
  152. package/lib/typescript/src/types/recycler/RecyclerListProps.d.ts.map +0 -1
  153. package/nitrogen/generated/ios/swift/HybridNitroLayoutEngineSpec.swift +0 -56
  154. package/src/NitroList.ts +0 -8
  155. package/src/native/NitroLayoutEngine.ts +0 -7
  156. package/src/native/NitroList.types.ts +0 -13
  157. package/src/native/NitroRecyclerView.ts +0 -8
  158. package/src/recycler/RecyclerList.tsx +0 -304
  159. package/src/specs/nitro-layout-engine.nitro.ts +0 -17
  160. package/src/types/recycler/RecyclerCellInstance.ts +0 -40
@@ -1 +0,0 @@
1
- {"version":3,"file":"NitroRecyclerView.d.ts","sourceRoot":"","sources":["../../../../src/native/NitroRecyclerView.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,eAAO,MAAM,iBAAiB,8DACuC,CAAA"}
@@ -1,4 +0,0 @@
1
- import React from 'react';
2
- import type { RecyclerListProps } from '../types/recycler';
3
- export declare function RecyclerList<T>(props: RecyclerListProps<T>): React.ReactElement;
4
- //# sourceMappingURL=RecyclerList.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RecyclerList.d.ts","sourceRoot":"","sources":["../../../../src/recycler/RecyclerList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAA;AAU1D,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,mBAAmB,CAAA;AAmB1B,wBAAgB,YAAY,CAAC,CAAC,EAC5B,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC1B,KAAK,CAAC,YAAY,CAmQpB"}
@@ -1,14 +0,0 @@
1
- import type { HybridObject } from 'react-native-nitro-modules';
2
- export interface LayoutRect {
3
- readonly x: number;
4
- readonly y: number;
5
- readonly width: number;
6
- readonly height: number;
7
- }
8
- export interface NitroLayoutEngine extends HybridObject<{
9
- ios: 'swift';
10
- android: 'kotlin';
11
- }> {
12
- computeLayout(containerWidth: number, itemHeights: readonly number[]): readonly LayoutRect[];
13
- }
14
- //# sourceMappingURL=nitro-layout-engine.nitro.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nitro-layout-engine.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/nitro-layout-engine.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,iBACf,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IAEzD,aAAa,CACX,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,SAAS,UAAU,EAAE,CAAA;CACzB"}
@@ -1,37 +0,0 @@
1
- import type { CellKey } from "../CellKey";
2
- import type { CellType } from "../CellType";
3
- /**
4
- * Physical reusable cell instance.
5
- *
6
- * Represents a single mounted view that can be rebound
7
- * to different data items as scrolling occurs.
8
- *
9
- * Cross-platform equivalent:
10
- * - Flutter: Element / RenderObject
11
- * - Android: ViewHolder
12
- * - iOS: UICollectionViewCell
13
- */
14
- export interface RecyclerCellInstance {
15
- /**
16
- * Stable physical identity.
17
- *
18
- * Used as React key.
19
- * MUST remain constant for the lifetime of the instance.
20
- */
21
- readonly key: CellKey;
22
- /**
23
- * Logical data index currently bound to this instance.
24
- *
25
- * This value changes as the cell is recycled.
26
- * - -1 may be used to indicate "unbound".
27
- */
28
- index: number;
29
- /**
30
- * Logical compatibility type.
31
- *
32
- * Determines which instances can be reused together.
33
- * Instances with different types MUST NOT be reused.
34
- */
35
- readonly type: CellType;
36
- }
37
- //# sourceMappingURL=RecyclerCellInstance.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RecyclerCellInstance.d.ts","sourceRoot":"","sources":["../../../../../src/types/recycler/RecyclerCellInstance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAG3C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IAErB;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAA;IAEb;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CACxB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"RecyclerListProps.d.ts","sourceRoot":"","sources":["../../../../../src/types/recycler/RecyclerListProps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAElE;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;IAE/B;;;;;;OAMG;IACH,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAA;IAEvC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAE3B;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAA;IAE7C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAA;IAElC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAE7B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAE7B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAA;IAE1D;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAA;CAC7C"}
@@ -1,56 +0,0 @@
1
- ///
2
- /// HybridNitroLayoutEngineSpec.swift
3
- /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
- /// https://github.com/mrousavy/nitro
5
- /// Copyright © 2025 Marc Rousavy @ Margelo
6
- ///
7
-
8
- import Foundation
9
- import NitroModules
10
-
11
- /// See ``HybridNitroLayoutEngineSpec``
12
- public protocol HybridNitroLayoutEngineSpec_protocol: HybridObject {
13
- // Properties
14
-
15
-
16
- // Methods
17
- func computeLayout(containerWidth: Double, itemHeights: [Double]) throws -> [LayoutRect]
18
- }
19
-
20
- public extension HybridNitroLayoutEngineSpec_protocol {
21
- /// Default implementation of ``HybridObject.toString``
22
- func toString() -> String {
23
- return "[HybridObject NitroLayoutEngine]"
24
- }
25
- }
26
-
27
- /// See ``HybridNitroLayoutEngineSpec``
28
- open class HybridNitroLayoutEngineSpec_base {
29
- private weak var cxxWrapper: HybridNitroLayoutEngineSpec_cxx? = nil
30
- public init() { }
31
- public func getCxxWrapper() -> HybridNitroLayoutEngineSpec_cxx {
32
- #if DEBUG
33
- guard self is HybridNitroLayoutEngineSpec else {
34
- fatalError("`self` is not a `HybridNitroLayoutEngineSpec`! Did you accidentally inherit from `HybridNitroLayoutEngineSpec_base` instead of `HybridNitroLayoutEngineSpec`?")
35
- }
36
- #endif
37
- if let cxxWrapper = self.cxxWrapper {
38
- return cxxWrapper
39
- } else {
40
- let cxxWrapper = HybridNitroLayoutEngineSpec_cxx(self as! HybridNitroLayoutEngineSpec)
41
- self.cxxWrapper = cxxWrapper
42
- return cxxWrapper
43
- }
44
- }
45
- }
46
-
47
- /**
48
- * A Swift base-protocol representing the NitroLayoutEngine HybridObject.
49
- * Implement this protocol to create Swift-based instances of NitroLayoutEngine.
50
- * ```swift
51
- * class HybridNitroLayoutEngine : HybridNitroLayoutEngineSpec {
52
- * // ...
53
- * }
54
- * ```
55
- */
56
- public typealias HybridNitroLayoutEngineSpec = HybridNitroLayoutEngineSpec_protocol & HybridNitroLayoutEngineSpec_base
package/src/NitroList.ts DELETED
@@ -1,8 +0,0 @@
1
- import { requireNativeComponent } from 'react-native'
2
-
3
- export type NitroRecyclerViewProps = {
4
- itemCount: number
5
- }
6
-
7
- export const NitroRecyclerView =
8
- requireNativeComponent<NitroRecyclerViewProps>('NitroRecyclerView')
@@ -1,7 +0,0 @@
1
- import { NitroModules } from 'react-native-nitro-modules'
2
- import type { NitroLayoutEngine as NitroLayoutEngineSpec } from '../specs/nitro-layout-engine.nitro'
3
-
4
- export const NitroLayoutEngine =
5
- NitroModules.createHybridObject<NitroLayoutEngineSpec>(
6
- 'NitroLayoutEngine'
7
- )
@@ -1,13 +0,0 @@
1
- import type { LayoutRect } from "../types/layout";
2
-
3
-
4
- /**
5
- * JS runtime interface backed by Nitro (JSI).
6
- * Must match native HybridNitroList exactly.
7
- */
8
- export interface NitroList {
9
- computeLayout(
10
- containerWidth: number,
11
- itemHeights: readonly number[]
12
- ): readonly LayoutRect[]
13
- }
@@ -1,8 +0,0 @@
1
- import { requireNativeComponent } from 'react-native'
2
-
3
- export type NitroRecyclerViewProps = {
4
- itemCount: number
5
- }
6
-
7
- export const NitroRecyclerView =
8
- requireNativeComponent<NitroRecyclerViewProps>('NitroRecyclerView')
@@ -1,304 +0,0 @@
1
- import React, { useRef, useEffect, useState } from 'react'
2
- import {
3
- ScrollView,
4
- View,
5
- StyleSheet,
6
- type NativeSyntheticEvent,
7
- type NativeScrollEvent,
8
- } from 'react-native'
9
-
10
- import type { LayoutRect, VisibleRange } from '../types'
11
- import type {
12
- RecyclerCellInstance,
13
- RecyclerListProps,
14
- } from '../types/recycler'
15
- import type { CellType } from '../types/CellType'
16
-
17
- import { MutableLinearLayout } from '../layout/MutableLinearLayout'
18
- import { computeVisibleItemRange } from '../windowing'
19
- import { CellPool } from './CellPool'
20
-
21
- /* =========================================================
22
- * Constants
23
- * =======================================================*/
24
-
25
- const DEFAULT_VIEWPORT_SIZE = 800
26
- const DEFAULT_ITEM_SIZE = 60
27
- const SCROLL_EVENT_THROTTLE = 16
28
-
29
- /* =========================================================
30
- * RecyclerList
31
- * =======================================================*/
32
-
33
- export function RecyclerList<T>(
34
- props: RecyclerListProps<T>
35
- ): React.ReactElement {
36
- const {
37
- scrollDirection = 'vertical',
38
- containerCrossAxisSize,
39
- data,
40
- itemMainAxisSizes,
41
- padding = { start: 0, end: 0 },
42
- itemSpacing,
43
- bufferRatio = 1.3,
44
- getCellType,
45
- renderItem,
46
- } = props
47
-
48
- const isVertical = scrollDirection === 'vertical'
49
- const itemCount = data.length
50
-
51
- /* -------------------------------------------------------
52
- * Controlled render
53
- * -----------------------------------------------------*/
54
-
55
- const [, forceRender] = useState(0)
56
-
57
- /* -------------------------------------------------------
58
- * Layout engine
59
- * -----------------------------------------------------*/
60
-
61
- const layoutEngineRef = useRef<MutableLinearLayout | null>(null)
62
- const layoutSignatureRef = useRef('')
63
-
64
- const layoutSignature = [
65
- scrollDirection,
66
- containerCrossAxisSize,
67
- itemCount,
68
- itemMainAxisSizes,
69
- padding.start,
70
- padding.end,
71
- itemSpacing ?? 'default',
72
- ].join('|')
73
-
74
- if (
75
- !layoutEngineRef.current ||
76
- layoutSignatureRef.current !== layoutSignature
77
- ) {
78
- const engine = new MutableLinearLayout(scrollDirection)
79
- engine.compute({
80
- crossAxisSize: containerCrossAxisSize,
81
- itemMainAxisSizes,
82
- padding,
83
- itemSpacing,
84
- })
85
- layoutEngineRef.current = engine
86
- layoutSignatureRef.current = layoutSignature
87
- }
88
-
89
- const layouts: readonly LayoutRect[] =
90
- layoutEngineRef.current.getLayouts()
91
-
92
- const contentSize =
93
- layoutEngineRef.current.getContentSize()
94
-
95
- /* -------------------------------------------------------
96
- * Scroll metrics
97
- * -----------------------------------------------------*/
98
-
99
- const scrollOffsetRef = useRef(0)
100
- const viewportSizeRef = useRef(DEFAULT_VIEWPORT_SIZE)
101
-
102
- /* -------------------------------------------------------
103
- * Cell pool + physical cells
104
- * -----------------------------------------------------*/
105
-
106
- const cellPoolRef = useRef(new CellPool())
107
- const activeCellsRef = useRef<RecyclerCellInstance[]>([])
108
- const nextCellKeyRef = useRef(0)
109
-
110
- const createCell = (type: CellType): RecyclerCellInstance => ({
111
- key: nextCellKeyRef.current++,
112
- index: -1,
113
- type,
114
- })
115
-
116
- const MAX_CELLS = Math.ceil(
117
- (viewportSizeRef.current / DEFAULT_ITEM_SIZE) *
118
- bufferRatio
119
- ) + 2
120
-
121
- /* -------------------------------------------------------
122
- * Visible cell coordinator
123
- * -----------------------------------------------------*/
124
-
125
- const updateVisibleCells = (): void => {
126
- const offset = scrollOffsetRef.current
127
- const viewportSize = viewportSizeRef.current
128
- const buffer = viewportSize * bufferRatio
129
-
130
- const range: VisibleRange | null =
131
- computeVisibleItemRange({
132
- layouts,
133
- offset,
134
- viewportSize,
135
- buffer,
136
- isVertical,
137
- })
138
-
139
- if (!range) return
140
-
141
- const nextCells: RecyclerCellInstance[] = []
142
- const used = new Set<RecyclerCellInstance>()
143
-
144
- for (
145
- let index = range.startIndex;
146
- index <= range.endIndex;
147
- index++
148
- ) {
149
- const item = data[index]
150
- if (item === undefined) continue
151
-
152
- const type = getCellType(item, index)
153
-
154
- // Register type once, with hard cap
155
- if (!cellPoolRef.current.hasType(type)) {
156
- cellPoolRef.current.registerType(type, MAX_CELLS)
157
- for (let i = 0; i < MAX_CELLS; i++) {
158
- cellPoolRef.current.release(createCell(type))
159
- }
160
- }
161
-
162
- let cell = cellPoolRef.current.acquire(type)
163
-
164
- if (!cell) {
165
- const reuseIndex =
166
- activeCellsRef.current.findIndex(
167
- c => c.type === type
168
- )
169
-
170
- if (reuseIndex === -1) continue
171
-
172
- cell =
173
- activeCellsRef.current.splice(
174
- reuseIndex,
175
- 1
176
- )[0]!
177
- }
178
-
179
- cell.index = index
180
- nextCells.push(cell)
181
- used.add(cell)
182
- }
183
-
184
- for (const cell of activeCellsRef.current) {
185
- if (!used.has(cell)) {
186
- cellPoolRef.current.release(cell)
187
- }
188
- }
189
-
190
- let changed =
191
- nextCells.length !== activeCellsRef.current.length
192
-
193
- if (!changed) {
194
- for (let i = 0; i < nextCells.length; i++) {
195
- if (nextCells[i] !== activeCellsRef.current[i]) {
196
- changed = true
197
- break
198
- }
199
- }
200
- }
201
-
202
- if (changed) {
203
- activeCellsRef.current = nextCells
204
- forceRender(v => v + 1)
205
- }
206
- }
207
-
208
- /* -------------------------------------------------------
209
- * Scroll handlers
210
- * -----------------------------------------------------*/
211
-
212
- const frameScheduledRef = useRef(false)
213
-
214
- const onScroll = (
215
- e: NativeSyntheticEvent<NativeScrollEvent>
216
- ): void => {
217
- scrollOffsetRef.current = isVertical
218
- ? e.nativeEvent.contentOffset.y
219
- : e.nativeEvent.contentOffset.x
220
-
221
- if (frameScheduledRef.current) return
222
- frameScheduledRef.current = true
223
-
224
- requestAnimationFrame(() => {
225
- frameScheduledRef.current = false
226
- updateVisibleCells()
227
- })
228
- }
229
-
230
- const onLayout = (e: any): void => {
231
- viewportSizeRef.current = isVertical
232
- ? e.nativeEvent.layout.height
233
- : e.nativeEvent.layout.width
234
-
235
- updateVisibleCells()
236
- }
237
-
238
- useEffect(() => {
239
- updateVisibleCells()
240
- // eslint-disable-next-line react-hooks/exhaustive-deps
241
- }, [])
242
-
243
- /* -------------------------------------------------------
244
- * Render
245
- * -----------------------------------------------------*/
246
-
247
- return (
248
- <ScrollView
249
- onScroll={onScroll}
250
- onLayout={onLayout}
251
- horizontal={!isVertical}
252
- scrollEventThrottle={SCROLL_EVENT_THROTTLE}
253
- removeClippedSubviews
254
- >
255
- <View
256
- style={
257
- isVertical
258
- ? { height: contentSize }
259
- : { width: contentSize }
260
- }
261
- >
262
- {activeCellsRef.current.map(cell => {
263
- const index = cell.index
264
- const layout = layouts[index]
265
- const item = data[index]
266
-
267
- if (!layout || item === undefined) return null
268
-
269
- return (
270
- <View
271
- key={cell.key}
272
- style={[
273
- styles.cell,
274
- isVertical
275
- ? {
276
- top: layout.y,
277
- height: layout.height,
278
- width: layout.width,
279
- }
280
- : {
281
- left: layout.x,
282
- width: layout.width,
283
- height: layout.height,
284
- },
285
- ]}
286
- >
287
- {renderItem({ item, index, cell })}
288
- </View>
289
- )
290
- })}
291
- </View>
292
- </ScrollView>
293
- )
294
- }
295
-
296
- /* =========================================================
297
- * Styles
298
- * =======================================================*/
299
-
300
- const styles = StyleSheet.create({
301
- cell: {
302
- position: 'absolute',
303
- },
304
- })
@@ -1,17 +0,0 @@
1
- import type { HybridObject } from 'react-native-nitro-modules'
2
-
3
- export interface LayoutRect {
4
- readonly x: number
5
- readonly y: number
6
- readonly width: number
7
- readonly height: number
8
- }
9
-
10
- export interface NitroLayoutEngine
11
- extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
12
-
13
- computeLayout(
14
- containerWidth: number,
15
- itemHeights: readonly number[]
16
- ): readonly LayoutRect[]
17
- }
@@ -1,40 +0,0 @@
1
- import type { CellKey } from "../CellKey"
2
- import type { CellType } from "../CellType"
3
-
4
-
5
- /**
6
- * Physical reusable cell instance.
7
- *
8
- * Represents a single mounted view that can be rebound
9
- * to different data items as scrolling occurs.
10
- *
11
- * Cross-platform equivalent:
12
- * - Flutter: Element / RenderObject
13
- * - Android: ViewHolder
14
- * - iOS: UICollectionViewCell
15
- */
16
- export interface RecyclerCellInstance {
17
- /**
18
- * Stable physical identity.
19
- *
20
- * Used as React key.
21
- * MUST remain constant for the lifetime of the instance.
22
- */
23
- readonly key: CellKey
24
-
25
- /**
26
- * Logical data index currently bound to this instance.
27
- *
28
- * This value changes as the cell is recycled.
29
- * - -1 may be used to indicate "unbound".
30
- */
31
- index: number
32
-
33
- /**
34
- * Logical compatibility type.
35
- *
36
- * Determines which instances can be reused together.
37
- * Instances with different types MUST NOT be reused.
38
- */
39
- readonly type: CellType
40
- }