@onekeyfe/react-native-native-list 3.0.157-alpha.254 → 3.0.157-alpha.258

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 (87) hide show
  1. package/android/build.gradle +7 -0
  2. package/android/src/main/java/com/onekey/nativelist/HybridNativeList.kt +20 -0
  3. package/android/src/main/java/com/onekey/nativelist/NativeListActivityDetailsView.kt +179 -0
  4. package/android/src/main/java/com/onekey/nativelist/NativeListActivityRenderer.kt +23 -2
  5. package/android/src/main/java/com/onekey/nativelist/NativeListContainerSlotAdapter.kt +53 -0
  6. package/android/src/main/java/com/onekey/nativelist/NativeListEndAlignment.kt +5 -0
  7. package/android/src/main/java/com/onekey/nativelist/NativeListMediaPreviewSlot.kt +215 -0
  8. package/android/src/main/java/com/onekey/nativelist/NativeListMediaTileRenderer.kt +15 -6
  9. package/android/src/main/java/com/onekey/nativelist/NativeListModels.kt +3 -1
  10. package/android/src/main/java/com/onekey/nativelist/NativeListScrollPositionTracker.kt +29 -0
  11. package/android/src/main/java/com/onekey/nativelist/NativeListSectionHeaderRenderer.kt +16 -1
  12. package/android/src/main/java/com/onekey/nativelist/NativeListView.kt +165 -26
  13. package/android/src/main/res/values/native_scroll_coordinator_ids.xml +5 -0
  14. package/android/src/test/java/com/margelo/nitro/nativelist/NativeListEndAlignmentTest.kt +34 -0
  15. package/android/src/test/java/com/margelo/nitro/nativelist/NativeListScrollPositionTrackerTest.kt +28 -0
  16. package/docs/DESIGN.md +4 -2
  17. package/docs/ROW_TEMPLATES.md +45 -0
  18. package/docs/SPEC.md +241 -1
  19. package/docs/STYLE_SPEC.md +8 -0
  20. package/ios/HybridNativeList.swift +30 -0
  21. package/ios/NativeListActivityDetailsView.swift +229 -0
  22. package/ios/NativeListActivityRenderer.swift +24 -2
  23. package/ios/NativeListMediaPreviewSlot.swift +199 -0
  24. package/ios/NativeListMediaTileRenderer.swift +10 -4
  25. package/ios/NativeListModels.swift +4 -1
  26. package/ios/NativeListScrollPositionTracker.swift +30 -0
  27. package/ios/NativeListSectionHeaderRenderer.swift +27 -1
  28. package/ios/RNCNativeListView.swift +159 -4
  29. package/ios/tests/NativeListActivityPresentationTests.swift +43 -0
  30. package/ios/tests/NativeListLifecycleTests.swift +123 -0
  31. package/ios/tests/NativeListMediaVisibilityTests.swift +42 -0
  32. package/ios/tests/NativeListScrollPositionTrackerTests.swift +25 -0
  33. package/lib/module/NativeList.js +56 -3
  34. package/lib/module/NativeList.web.js +5 -0
  35. package/lib/module/validation.js +64 -4
  36. package/lib/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
  37. package/lib/nitrogen/generated/android/c++/JHybridNativeListSpec.cpp +39 -3
  38. package/lib/nitrogen/generated/android/c++/JHybridNativeListSpec.hpp +6 -0
  39. package/lib/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.cpp +15 -0
  40. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/Func_void_bool.kt +78 -0
  41. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/HybridNativeListSpec.kt +26 -0
  42. package/lib/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListManager.kt +24 -9
  43. package/lib/nitrogen/generated/android/nativelistOnLoad.cpp +2 -0
  44. package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.cpp +8 -0
  45. package/lib/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.hpp +37 -0
  46. package/lib/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.hpp +23 -2
  47. package/lib/nitrogen/generated/ios/c++/views/HybridNativeListComponent.mm +32 -0
  48. package/lib/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  49. package/lib/nitrogen/generated/ios/swift/HybridNativeListSpec.swift +3 -0
  50. package/lib/nitrogen/generated/ios/swift/HybridNativeListSpec_cxx.swift +54 -0
  51. package/lib/nitrogen/generated/shared/c++/HybridNativeListSpec.cpp +6 -0
  52. package/lib/nitrogen/generated/shared/c++/HybridNativeListSpec.hpp +8 -2
  53. package/lib/nitrogen/generated/shared/c++/views/HybridNativeListComponent.cpp +6 -0
  54. package/lib/nitrogen/generated/shared/c++/views/HybridNativeListComponent.hpp +11 -2
  55. package/lib/nitrogen/generated/shared/json/NativeListConfig.json +3 -0
  56. package/lib/typescript/src/NativeList.nitro.d.ts +3 -0
  57. package/lib/typescript/src/NativeList.types.d.ts +14 -1
  58. package/lib/typescript/src/models.d.ts +33 -5
  59. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
  60. package/nitrogen/generated/android/c++/JHybridNativeListSpec.cpp +39 -3
  61. package/nitrogen/generated/android/c++/JHybridNativeListSpec.hpp +6 -0
  62. package/nitrogen/generated/android/c++/views/JHybridNativeListStateUpdater.cpp +15 -0
  63. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/Func_void_bool.kt +78 -0
  64. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/HybridNativeListSpec.kt +26 -0
  65. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nativelist/views/HybridNativeListManager.kt +24 -9
  66. package/nitrogen/generated/android/nativelistOnLoad.cpp +2 -0
  67. package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.cpp +8 -0
  68. package/nitrogen/generated/ios/NativeListModule-Swift-Cxx-Bridge.hpp +37 -0
  69. package/nitrogen/generated/ios/c++/HybridNativeListSpecSwift.hpp +23 -2
  70. package/nitrogen/generated/ios/c++/views/HybridNativeListComponent.mm +32 -0
  71. package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
  72. package/nitrogen/generated/ios/swift/HybridNativeListSpec.swift +3 -0
  73. package/nitrogen/generated/ios/swift/HybridNativeListSpec_cxx.swift +54 -0
  74. package/nitrogen/generated/shared/c++/HybridNativeListSpec.cpp +6 -0
  75. package/nitrogen/generated/shared/c++/HybridNativeListSpec.hpp +8 -2
  76. package/nitrogen/generated/shared/c++/views/HybridNativeListComponent.cpp +6 -0
  77. package/nitrogen/generated/shared/c++/views/HybridNativeListComponent.hpp +11 -2
  78. package/nitrogen/generated/shared/json/NativeListConfig.json +3 -0
  79. package/package.json +6 -5
  80. package/scripts/enable-container-slots.mjs +58 -0
  81. package/scripts/enable-container-slots.test.mjs +58 -0
  82. package/src/NativeList.nitro.ts +3 -0
  83. package/src/NativeList.tsx +84 -2
  84. package/src/NativeList.types.ts +14 -1
  85. package/src/NativeList.web.tsx +5 -0
  86. package/src/models.ts +38 -1
  87. package/src/validation.ts +146 -4
@@ -35,6 +35,11 @@ using namespace margelo::nitro::nativelist::views;
35
35
  + (BOOL)shouldBeRecycled;
36
36
  @end
37
37
 
38
+ @interface UIView (NativeListContainerSlots)
39
+ - (void)mountContainerSlot:(UIView *)view atIndex:(NSInteger)index;
40
+ - (void)unmountContainerSlot:(UIView *)view;
41
+ @end
42
+
38
43
  @implementation HybridNativeListComponent {
39
44
  std::shared_ptr<HybridNativeListSpecSwift> _hybridView;
40
45
  BOOL _didDropView;
@@ -59,6 +64,15 @@ using namespace margelo::nitro::nativelist::views;
59
64
  return self;
60
65
  }
61
66
 
67
+ // NativeList container slot mounting
68
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)child index:(NSInteger)index {
69
+ [self.contentView mountContainerSlot:child atIndex:index];
70
+ }
71
+
72
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)child index:(NSInteger)index {
73
+ [self.contentView unmountContainerSlot:child];
74
+ }
75
+
62
76
  - (void) updateView {
63
77
  // 1. Get Swift part
64
78
  NativeListModule::HybridNativeListSpec_cxx& swiftPart = _hybridView->getSwiftPart();
@@ -104,6 +118,24 @@ using namespace margelo::nitro::nativelist::views;
104
118
  : !newViewProps.snapshotJson.hasSameValue(oldViewProps->snapshotJson)) {
105
119
  swiftPart.setSnapshotJson(newViewProps.snapshotJson.get());
106
120
  }
121
+ // containerSlotHeightsJson: string
122
+ if (oldViewProps == nullptr
123
+ ? newViewProps.containerSlotHeightsJson.isProvided()
124
+ : !newViewProps.containerSlotHeightsJson.hasSameValue(oldViewProps->containerSlotHeightsJson)) {
125
+ swiftPart.setContainerSlotHeightsJson(newViewProps.containerSlotHeightsJson.get());
126
+ }
127
+ // scrollPositionThresholdsJson: string
128
+ if (oldViewProps == nullptr
129
+ ? newViewProps.scrollPositionThresholdsJson.isProvided()
130
+ : !newViewProps.scrollPositionThresholdsJson.hasSameValue(oldViewProps->scrollPositionThresholdsJson)) {
131
+ swiftPart.setScrollPositionThresholdsJson(newViewProps.scrollPositionThresholdsJson.get());
132
+ }
133
+ // onScrollPositionThresholdChange: optional
134
+ if (oldViewProps == nullptr
135
+ ? newViewProps.onScrollPositionThresholdChange.isProvided()
136
+ : !newViewProps.onScrollPositionThresholdChange.hasSameValue(oldViewProps->onScrollPositionThresholdChange)) {
137
+ swiftPart.setOnScrollPositionThresholdChange(newViewProps.onScrollPositionThresholdChange.get());
138
+ }
107
139
  // keyboardDismissMode: enum
108
140
  if (oldViewProps == nullptr
109
141
  ? newViewProps.keyboardDismissMode.isProvided()
@@ -0,0 +1,46 @@
1
+ ///
2
+ /// Func_void_bool.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import NitroModules
9
+
10
+ /**
11
+ * Wraps a Swift `(_ isBeyondThreshold: Bool) -> Void` as a class.
12
+ * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.
13
+ */
14
+ public final class Func_void_bool {
15
+ public typealias bridge = margelo.nitro.nativelist.bridge.swift
16
+
17
+ private let closure: (_ isBeyondThreshold: Bool) -> Void
18
+
19
+ public init(_ closure: @escaping (_ isBeyondThreshold: Bool) -> Void) {
20
+ self.closure = closure
21
+ }
22
+
23
+ @inline(__always)
24
+ public func call(isBeyondThreshold: Bool) -> Void {
25
+ self.closure(isBeyondThreshold)
26
+ }
27
+
28
+ /**
29
+ * Casts this instance to a retained unsafe raw pointer.
30
+ * This acquires one additional strong reference on the object!
31
+ */
32
+ @inline(__always)
33
+ public func toUnsafe() -> UnsafeMutableRawPointer {
34
+ return Unmanaged.passRetained(self).toOpaque()
35
+ }
36
+
37
+ /**
38
+ * Casts an unsafe pointer to a `Func_void_bool`.
39
+ * The pointer has to be a retained opaque `Unmanaged<Func_void_bool>`.
40
+ * This removes one strong reference from the object!
41
+ */
42
+ @inline(__always)
43
+ public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_bool {
44
+ return Unmanaged<Func_void_bool>.fromOpaque(pointer).takeRetainedValue()
45
+ }
46
+ }
@@ -11,6 +11,9 @@ import NitroModules
11
11
  public protocol HybridNativeListSpec_protocol: HybridObject, HybridView {
12
12
  // Properties
13
13
  var snapshotJson: String { get set }
14
+ var containerSlotHeightsJson: String { get set }
15
+ var scrollPositionThresholdsJson: String { get set }
16
+ var onScrollPositionThresholdChange: ((_ isBeyondThreshold: Bool) -> Void)? { get set }
14
17
  var keyboardDismissMode: NativeListKeyboardDismissMode { get set }
15
18
  var keyboardShouldPersistTaps: NativeListKeyboardShouldPersistTaps { get set }
16
19
  var onRowAction: ((_ payloadJson: String) -> Void)? { get set }
@@ -132,6 +132,60 @@ open class HybridNativeListSpec_cxx {
132
132
  }
133
133
  }
134
134
 
135
+ public final var containerSlotHeightsJson: std.string {
136
+ @inline(__always)
137
+ get {
138
+ return std.string(self.__implementation.containerSlotHeightsJson)
139
+ }
140
+ @inline(__always)
141
+ set {
142
+ self.__implementation.containerSlotHeightsJson = String(newValue)
143
+ }
144
+ }
145
+
146
+ public final var scrollPositionThresholdsJson: std.string {
147
+ @inline(__always)
148
+ get {
149
+ return std.string(self.__implementation.scrollPositionThresholdsJson)
150
+ }
151
+ @inline(__always)
152
+ set {
153
+ self.__implementation.scrollPositionThresholdsJson = String(newValue)
154
+ }
155
+ }
156
+
157
+ public final var onScrollPositionThresholdChange: bridge.std__optional_std__function_void_bool____isBeyondThreshold______ {
158
+ @inline(__always)
159
+ get {
160
+ return { () -> bridge.std__optional_std__function_void_bool____isBeyondThreshold______ in
161
+ if let __unwrappedValue = self.__implementation.onScrollPositionThresholdChange {
162
+ return bridge.create_std__optional_std__function_void_bool____isBeyondThreshold______({ () -> bridge.Func_void_bool in
163
+ let __closureWrapper = Func_void_bool(__unwrappedValue)
164
+ return bridge.create_Func_void_bool(__closureWrapper.toUnsafe())
165
+ }())
166
+ } else {
167
+ return .init()
168
+ }
169
+ }()
170
+ }
171
+ @inline(__always)
172
+ set {
173
+ self.__implementation.onScrollPositionThresholdChange = { () -> ((_ isBeyondThreshold: Bool) -> Void)? in
174
+ if bridge.has_value_std__optional_std__function_void_bool____isBeyondThreshold______(newValue) {
175
+ let __unwrapped = bridge.get_std__optional_std__function_void_bool____isBeyondThreshold______(newValue)
176
+ return { () -> (Bool) -> Void in
177
+ let __wrappedFunction = bridge.wrap_Func_void_bool(__unwrapped)
178
+ return { (__isBeyondThreshold: Bool) -> Void in
179
+ __wrappedFunction.call(__isBeyondThreshold)
180
+ }
181
+ }()
182
+ } else {
183
+ return nil
184
+ }
185
+ }()
186
+ }
187
+ }
188
+
135
189
  public final var keyboardDismissMode: Int32 {
136
190
  @inline(__always)
137
191
  get {
@@ -16,6 +16,12 @@ namespace margelo::nitro::nativelist {
16
16
  registerHybrids(this, [](Prototype& prototype) {
17
17
  prototype.registerHybridGetter("snapshotJson", &HybridNativeListSpec::getSnapshotJson);
18
18
  prototype.registerHybridSetter("snapshotJson", &HybridNativeListSpec::setSnapshotJson);
19
+ prototype.registerHybridGetter("containerSlotHeightsJson", &HybridNativeListSpec::getContainerSlotHeightsJson);
20
+ prototype.registerHybridSetter("containerSlotHeightsJson", &HybridNativeListSpec::setContainerSlotHeightsJson);
21
+ prototype.registerHybridGetter("scrollPositionThresholdsJson", &HybridNativeListSpec::getScrollPositionThresholdsJson);
22
+ prototype.registerHybridSetter("scrollPositionThresholdsJson", &HybridNativeListSpec::setScrollPositionThresholdsJson);
23
+ prototype.registerHybridGetter("onScrollPositionThresholdChange", &HybridNativeListSpec::getOnScrollPositionThresholdChange);
24
+ prototype.registerHybridSetter("onScrollPositionThresholdChange", &HybridNativeListSpec::setOnScrollPositionThresholdChange);
19
25
  prototype.registerHybridGetter("keyboardDismissMode", &HybridNativeListSpec::getKeyboardDismissMode);
20
26
  prototype.registerHybridSetter("keyboardDismissMode", &HybridNativeListSpec::setKeyboardDismissMode);
21
27
  prototype.registerHybridGetter("keyboardShouldPersistTaps", &HybridNativeListSpec::getKeyboardShouldPersistTaps);
@@ -21,10 +21,10 @@ namespace margelo::nitro::nativelist { enum class NativeListKeyboardShouldPersis
21
21
  namespace margelo::nitro::nativelist { enum class NativeListScrollAlignment; }
22
22
 
23
23
  #include <string>
24
- #include "NativeListKeyboardDismissMode.hpp"
25
- #include "NativeListKeyboardShouldPersistTaps.hpp"
26
24
  #include <functional>
27
25
  #include <optional>
26
+ #include "NativeListKeyboardDismissMode.hpp"
27
+ #include "NativeListKeyboardShouldPersistTaps.hpp"
28
28
  #include "NativeListScrollAlignment.hpp"
29
29
 
30
30
  namespace margelo::nitro::nativelist {
@@ -56,6 +56,12 @@ namespace margelo::nitro::nativelist {
56
56
  // Properties
57
57
  virtual std::string getSnapshotJson() = 0;
58
58
  virtual void setSnapshotJson(const std::string& snapshotJson) = 0;
59
+ virtual std::string getContainerSlotHeightsJson() = 0;
60
+ virtual void setContainerSlotHeightsJson(const std::string& containerSlotHeightsJson) = 0;
61
+ virtual std::string getScrollPositionThresholdsJson() = 0;
62
+ virtual void setScrollPositionThresholdsJson(const std::string& scrollPositionThresholdsJson) = 0;
63
+ virtual std::optional<std::function<void(bool /* isBeyondThreshold */)>> getOnScrollPositionThresholdChange() = 0;
64
+ virtual void setOnScrollPositionThresholdChange(const std::optional<std::function<void(bool /* isBeyondThreshold */)>>& onScrollPositionThresholdChange) = 0;
59
65
  virtual NativeListKeyboardDismissMode getKeyboardDismissMode() = 0;
60
66
  virtual void setKeyboardDismissMode(NativeListKeyboardDismissMode keyboardDismissMode) = 0;
61
67
  virtual NativeListKeyboardShouldPersistTaps getKeyboardShouldPersistTaps() = 0;
@@ -21,6 +21,9 @@ namespace margelo::nitro::nativelist::views {
21
21
  const react::RawProps& rawProps):
22
22
  react::ViewProps(context, sourceProps, rawProps, filterObjectKeys),
23
23
  snapshotJson(nitro::ReactProp<std::string>::fromRawValue("NativeList", "snapshotJson", rawProps, sourceProps.snapshotJson)),
24
+ containerSlotHeightsJson(nitro::ReactProp<std::string>::fromRawValue("NativeList", "containerSlotHeightsJson", rawProps, sourceProps.containerSlotHeightsJson)),
25
+ scrollPositionThresholdsJson(nitro::ReactProp<std::string>::fromRawValue("NativeList", "scrollPositionThresholdsJson", rawProps, sourceProps.scrollPositionThresholdsJson)),
26
+ onScrollPositionThresholdChange(nitro::ReactProp<std::optional<std::function<void(bool /* isBeyondThreshold */)>>>::fromRawValue("NativeList", "onScrollPositionThresholdChange", rawProps, sourceProps.onScrollPositionThresholdChange)),
24
27
  keyboardDismissMode(nitro::ReactProp<NativeListKeyboardDismissMode>::fromRawValue("NativeList", "keyboardDismissMode", rawProps, sourceProps.keyboardDismissMode)),
25
28
  keyboardShouldPersistTaps(nitro::ReactProp<NativeListKeyboardShouldPersistTaps>::fromRawValue("NativeList", "keyboardShouldPersistTaps", rawProps, sourceProps.keyboardShouldPersistTaps)),
26
29
  onRowAction(nitro::ReactProp<std::optional<std::function<void(const std::string& /* payloadJson */)>>>::fromRawValue("NativeList", "onRowAction", rawProps, sourceProps.onRowAction)),
@@ -34,6 +37,9 @@ namespace margelo::nitro::nativelist::views {
34
37
  bool HybridNativeListProps::filterObjectKeys(const std::string& propName) {
35
38
  switch (hashString(propName)) {
36
39
  case hashString("snapshotJson"): return true;
40
+ case hashString("containerSlotHeightsJson"): return true;
41
+ case hashString("scrollPositionThresholdsJson"): return true;
42
+ case hashString("onScrollPositionThresholdChange"): return true;
37
43
  case hashString("keyboardDismissMode"): return true;
38
44
  case hashString("keyboardShouldPersistTaps"): return true;
39
45
  case hashString("onRowAction"): return true;
@@ -18,10 +18,10 @@
18
18
  #include <string>
19
19
 
20
20
  #include <string>
21
- #include "NativeListKeyboardDismissMode.hpp"
22
- #include "NativeListKeyboardShouldPersistTaps.hpp"
23
21
  #include <functional>
24
22
  #include <optional>
23
+ #include "NativeListKeyboardDismissMode.hpp"
24
+ #include "NativeListKeyboardShouldPersistTaps.hpp"
25
25
  #include <memory>
26
26
  #include "HybridNativeListSpec.hpp"
27
27
 
@@ -46,6 +46,9 @@ namespace margelo::nitro::nativelist::views {
46
46
 
47
47
  public:
48
48
  nitro::ReactProp<std::string> snapshotJson;
49
+ nitro::ReactProp<std::string> containerSlotHeightsJson;
50
+ nitro::ReactProp<std::string> scrollPositionThresholdsJson;
51
+ nitro::ReactProp<std::optional<std::function<void(bool /* isBeyondThreshold */)>>> onScrollPositionThresholdChange;
49
52
  nitro::ReactProp<NativeListKeyboardDismissMode> keyboardDismissMode;
50
53
  nitro::ReactProp<NativeListKeyboardShouldPersistTaps> keyboardShouldPersistTaps;
51
54
  nitro::ReactProp<std::optional<std::function<void(const std::string& /* payloadJson */)>>> onRowAction;
@@ -59,6 +62,9 @@ namespace margelo::nitro::nativelist::views {
59
62
  [[nodiscard]]
60
63
  bool hasSameProps(const HybridNativeListProps& other) const noexcept {
61
64
  return snapshotJson.hasSameValue(other.snapshotJson) &&
65
+ containerSlotHeightsJson.hasSameValue(other.containerSlotHeightsJson) &&
66
+ scrollPositionThresholdsJson.hasSameValue(other.scrollPositionThresholdsJson) &&
67
+ onScrollPositionThresholdChange.hasSameValue(other.onScrollPositionThresholdChange) &&
62
68
  keyboardDismissMode.hasSameValue(other.keyboardDismissMode) &&
63
69
  keyboardShouldPersistTaps.hasSameValue(other.keyboardShouldPersistTaps) &&
64
70
  onRowAction.hasSameValue(other.onRowAction) &&
@@ -73,6 +79,9 @@ namespace margelo::nitro::nativelist::views {
73
79
  [[nodiscard]]
74
80
  bool hasAnyProvidedProps() const noexcept {
75
81
  return snapshotJson.isProvided() ||
82
+ containerSlotHeightsJson.isProvided() ||
83
+ scrollPositionThresholdsJson.isProvided() ||
84
+ onScrollPositionThresholdChange.isProvided() ||
76
85
  keyboardDismissMode.isProvided() ||
77
86
  keyboardShouldPersistTaps.isProvided() ||
78
87
  onRowAction.isProvided() ||
@@ -5,6 +5,9 @@
5
5
  "directEventTypes": {},
6
6
  "validAttributes": {
7
7
  "snapshotJson": true,
8
+ "containerSlotHeightsJson": true,
9
+ "scrollPositionThresholdsJson": true,
10
+ "onScrollPositionThresholdChange": true,
8
11
  "keyboardDismissMode": true,
9
12
  "keyboardShouldPersistTaps": true,
10
13
  "onRowAction": true,
@@ -6,6 +6,9 @@ import type { HybridView, HybridViewMethods, HybridViewProps } from 'react-nativ
6
6
  */
7
7
  export interface NativeListNativeProps extends HybridViewProps {
8
8
  snapshotJson: string;
9
+ containerSlotHeightsJson: string;
10
+ scrollPositionThresholdsJson: string;
11
+ onScrollPositionThresholdChange?: (isBeyondThreshold: boolean) => void;
9
12
  keyboardDismissMode: NativeListKeyboardDismissMode;
10
13
  keyboardShouldPersistTaps: NativeListKeyboardShouldPersistTaps;
11
14
  onRowAction?: (payloadJson: string) => void;
@@ -1,4 +1,4 @@
1
- import type { RefObject } from 'react';
1
+ import type { ReactNode, RefObject } from 'react';
2
2
  import type { View, ViewProps } from 'react-native';
3
3
  import type { ActionAnchorInvalidatedEvent, EndReachedEvent, NativeListSnapshot, ReorderEvent, RowActionEvent, RowModel, RowPatch, SelectionDeltaEvent, VisibleRangeChangedEvent } from './models';
4
4
  export type ActionAnchorState = Readonly<{
@@ -75,6 +75,10 @@ export type NativeListRef = Readonly<{
75
75
  }>;
76
76
  export type NativeListProps = Omit<ViewProps, 'children'> & Readonly<{
77
77
  snapshot: NativeListSnapshot;
78
+ /** Native-only, container-owned scroll content. Never rendered as a data row. */
79
+ listHeader?: ReactNode;
80
+ listFooter?: ReactNode;
81
+ listEmpty?: ReactNode;
78
82
  /** Web only. Defaults to true and is ignored by the native host. */
79
83
  webVirtualizationEnabled?: boolean;
80
84
  /** Web only. Hosts the section index inside this container. */
@@ -92,6 +96,15 @@ export type NativeListProps = Omit<ViewProps, 'children'> & Readonly<{
92
96
  onReorder?: (event: ReorderEvent) => void;
93
97
  onEndReached?: (event: EndReachedEvent) => void;
94
98
  onVisibleRangeChanged?: (event: VisibleRangeChangedEvent) => void;
99
+ /** Native only. Emits initial state and hysteresis transitions, not scroll frames. */
100
+ scrollPositionThresholds?: Readonly<{
101
+ start: number;
102
+ end: number;
103
+ enabled?: boolean;
104
+ }>;
105
+ onScrollPositionThresholdChange?: (event: Readonly<{
106
+ isBeyondThreshold: boolean;
107
+ }>) => void;
95
108
  onRefresh?: () => void;
96
109
  onScrollToIndexFailed?: (info: ScrollToIndexFailedInfo) => void;
97
110
  }> & InitialScrollProps;
@@ -399,6 +399,15 @@ export type RailRow = RowBase & Readonly<{
399
399
  draggable?: boolean;
400
400
  style?: RailRowStyle;
401
401
  }>;
402
+ export type ActivityAmount = Readonly<{
403
+ key: string;
404
+ text: string;
405
+ textSegments?: readonly ValueTextSegment[];
406
+ leading?: LeadingVisual;
407
+ tone?: TextTone;
408
+ secondaryText?: string;
409
+ secondaryTextSegments?: readonly ValueTextSegment[];
410
+ }>;
402
411
  export type ActivityRow = RowBase & Readonly<{
403
412
  type: 'activity';
404
413
  leading: LeadingVisual;
@@ -408,6 +417,18 @@ export type ActivityRow = RowBase & Readonly<{
408
417
  status?: string;
409
418
  primaryAmount?: string;
410
419
  secondaryAmount?: string;
420
+ amounts?: readonly ActivityAmount[];
421
+ badges?: readonly BadgeModel[];
422
+ presentation?: 'stacked' | 'table';
423
+ fee?: Readonly<{
424
+ label?: string;
425
+ primary: string;
426
+ primaryTextSegments?: readonly ValueTextSegment[];
427
+ secondary?: string;
428
+ secondaryTextSegments?: readonly ValueTextSegment[];
429
+ hidden?: boolean;
430
+ }>;
431
+ descriptionActionKey?: string;
411
432
  footerActions?: readonly FooterAction[];
412
433
  style?: ActivityRowStyle;
413
434
  }>;
@@ -479,6 +500,11 @@ export type MarketRow = RowBase & Readonly<{
479
500
  export type MediaTileRow = RowBase & Readonly<{
480
501
  type: 'mediaTile';
481
502
  variant: 'gallery' | 'browserPreview';
503
+ /** Native preview; video candidates display a silent first frame, never autoplay. */
504
+ media?: Readonly<{
505
+ source: ImageSource;
506
+ probeOrder: readonly ('image' | 'video')[];
507
+ }>;
482
508
  image?: ImageSource;
483
509
  imageState?: 'empty' | 'error';
484
510
  networkImage?: ImageSource;
@@ -522,6 +548,7 @@ export type SectionHeaderRow = RowBase & Readonly<{
522
548
  indexTitle?: string;
523
549
  variant?: 'summary' | 'gallery' | 'history';
524
550
  title: string;
551
+ titleLoading?: boolean;
525
552
  subtitle?: string;
526
553
  value?: string;
527
554
  valueActionKey?: string;
@@ -651,7 +678,7 @@ export type NativeListSnapshot = Readonly<{
651
678
  layout: Readonly<{
652
679
  kind: NativeListLayout;
653
680
  orientation?: NativeListOrientation;
654
- gridColumns?: 2 | 3 | 4;
681
+ gridColumns?: 2 | 3 | 4 | 5 | 6 | 7;
655
682
  stickyHeaders?: boolean;
656
683
  contentPadding?: number;
657
684
  contentPaddingHorizontal?: number;
@@ -669,6 +696,7 @@ export type NativeListSnapshot = Readonly<{
669
696
  reorderable?: boolean;
670
697
  pullToRefresh?: boolean;
671
698
  refreshing?: boolean;
699
+ refreshTriggerDistance?: number;
672
700
  loadMore?: boolean;
673
701
  endReachedThreshold?: number;
674
702
  sectionIndex?: SectionIndexConfig;
@@ -690,7 +718,7 @@ export type RowPatch = Readonly<{
690
718
  }> | Readonly<{
691
719
  type: 'activity';
692
720
  key: string;
693
- changes: Partial<Pick<ActivityRow, CommonPatchFields | 'title' | 'description' | 'status' | 'primaryAmount' | 'secondaryAmount' | 'leading' | 'secondaryLeading' | 'footerActions'>>;
721
+ changes: Partial<Pick<ActivityRow, CommonPatchFields | 'title' | 'description' | 'status' | 'amounts' | 'badges' | 'presentation' | 'fee' | 'descriptionActionKey' | 'primaryAmount' | 'secondaryAmount' | 'leading' | 'secondaryLeading' | 'footerActions'>>;
694
722
  }> | Readonly<{
695
723
  type: 'message';
696
724
  key: string;
@@ -706,7 +734,7 @@ export type RowPatch = Readonly<{
706
734
  }> | Readonly<{
707
735
  type: 'mediaTile';
708
736
  key: string;
709
- changes: Partial<Pick<MediaTileRow, CommonPatchFields | 'image' | 'imageState' | 'networkImage' | 'title' | 'subtitle' | 'badge' | 'closeActionKey'>>;
737
+ changes: Partial<Pick<MediaTileRow, CommonPatchFields | 'image' | 'imageState' | 'media' | 'networkImage' | 'title' | 'subtitle' | 'badge' | 'closeActionKey'>>;
710
738
  }> | Readonly<{
711
739
  type: 'metricCard';
712
740
  key: string;
@@ -714,7 +742,7 @@ export type RowPatch = Readonly<{
714
742
  }> | Readonly<{
715
743
  type: 'sectionHeader';
716
744
  key: string;
717
- changes: Partial<Pick<SectionHeaderRow, CommonPatchFields | 'variant' | 'title' | 'subtitle' | 'value' | 'valueActionKey' | 'titleActionKey' | 'titleActionOnHover' | 'titleIcon' | 'valueIcon' | 'checkbox'>>;
745
+ changes: Partial<Pick<SectionHeaderRow, CommonPatchFields | 'variant' | 'titleLoading' | 'title' | 'subtitle' | 'value' | 'valueActionKey' | 'titleActionKey' | 'titleActionOnHover' | 'titleIcon' | 'valueIcon' | 'checkbox'>>;
718
746
  }> | Readonly<{
719
747
  type: 'action';
720
748
  key: string;
@@ -728,7 +756,7 @@ export type RowPatch = Readonly<{
728
756
  message?: string;
729
757
  }>;
730
758
  }>;
731
- export type NativeListActionSource = 'row' | 'marketBadge' | 'leadingAction' | 'trailingAccessory' | 'footerAction' | 'mediaClose';
759
+ export type NativeListActionSource = 'row' | 'marketBadge' | 'leadingAction' | 'trailingAccessory' | 'footerAction' | 'description' | 'mediaClose';
732
760
  export type NativeListWindowRect = Readonly<{
733
761
  x: number;
734
762
  y: number;
@@ -0,0 +1,75 @@
1
+ ///
2
+ /// JFunc_void_bool.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <functional>
12
+
13
+ #include <functional>
14
+ #include <NitroModules/JNICallable.hpp>
15
+
16
+ namespace margelo::nitro::nativelist {
17
+
18
+ using namespace facebook;
19
+
20
+ /**
21
+ * Represents the Java/Kotlin callback `(isBeyondThreshold: Boolean) -> Unit`.
22
+ * This can be passed around between C++ and Java/Kotlin.
23
+ */
24
+ struct JFunc_void_bool: public jni::JavaClass<JFunc_void_bool> {
25
+ public:
26
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/nativelist/Func_void_bool;";
27
+
28
+ public:
29
+ /**
30
+ * Invokes the function this `JFunc_void_bool` instance holds through JNI.
31
+ */
32
+ void invoke(bool isBeyondThreshold) const {
33
+ static const auto method = javaClassStatic()->getMethod<void(jboolean /* isBeyondThreshold */)>("invoke");
34
+ method(self(), isBeyondThreshold);
35
+ }
36
+ };
37
+
38
+ /**
39
+ * An implementation of Func_void_bool that is backed by a C++ implementation (using `std::function<...>`)
40
+ */
41
+ class JFunc_void_bool_cxx final: public jni::HybridClass<JFunc_void_bool_cxx, JFunc_void_bool> {
42
+ public:
43
+ static jni::local_ref<JFunc_void_bool::javaobject> fromCpp(const std::function<void(bool /* isBeyondThreshold */)>& func) {
44
+ return JFunc_void_bool_cxx::newObjectCxxArgs(func);
45
+ }
46
+
47
+ public:
48
+ /**
49
+ * Invokes the C++ `std::function<...>` this `JFunc_void_bool_cxx` instance holds.
50
+ */
51
+ void invoke_cxx(jboolean isBeyondThreshold) {
52
+ _func(static_cast<bool>(isBeyondThreshold));
53
+ }
54
+
55
+ public:
56
+ [[nodiscard]]
57
+ inline const std::function<void(bool /* isBeyondThreshold */)>& getFunction() const {
58
+ return _func;
59
+ }
60
+
61
+ public:
62
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/nativelist/Func_void_bool_cxx;";
63
+ static void registerNatives() {
64
+ registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_bool_cxx::invoke_cxx)});
65
+ }
66
+
67
+ private:
68
+ explicit JFunc_void_bool_cxx(const std::function<void(bool /* isBeyondThreshold */)>& func): _func(func) { }
69
+
70
+ private:
71
+ friend HybridBase;
72
+ std::function<void(bool /* isBeyondThreshold */)> _func;
73
+ };
74
+
75
+ } // namespace margelo::nitro::nativelist
@@ -15,14 +15,15 @@ namespace margelo::nitro::nativelist { enum class NativeListKeyboardShouldPersis
15
15
  namespace margelo::nitro::nativelist { enum class NativeListScrollAlignment; }
16
16
 
17
17
  #include <string>
18
+ #include <functional>
19
+ #include <optional>
20
+ #include "JFunc_void_bool.hpp"
21
+ #include <NitroModules/JNICallable.hpp>
18
22
  #include "NativeListKeyboardDismissMode.hpp"
19
23
  #include "JNativeListKeyboardDismissMode.hpp"
20
24
  #include "NativeListKeyboardShouldPersistTaps.hpp"
21
25
  #include "JNativeListKeyboardShouldPersistTaps.hpp"
22
- #include <functional>
23
- #include <optional>
24
26
  #include "JFunc_void_std__string.hpp"
25
- #include <NitroModules/JNICallable.hpp>
26
27
  #include "NativeListScrollAlignment.hpp"
27
28
  #include "JNativeListScrollAlignment.hpp"
28
29
 
@@ -65,6 +66,41 @@ namespace margelo::nitro::nativelist {
65
66
  static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* snapshotJson */)>("setSnapshotJson");
66
67
  method(_javaPart, jni::make_jstring(snapshotJson));
67
68
  }
69
+ std::string JHybridNativeListSpec::getContainerSlotHeightsJson() {
70
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getContainerSlotHeightsJson");
71
+ auto __result = method(_javaPart);
72
+ return __result->toStdString();
73
+ }
74
+ void JHybridNativeListSpec::setContainerSlotHeightsJson(const std::string& containerSlotHeightsJson) {
75
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* containerSlotHeightsJson */)>("setContainerSlotHeightsJson");
76
+ method(_javaPart, jni::make_jstring(containerSlotHeightsJson));
77
+ }
78
+ std::string JHybridNativeListSpec::getScrollPositionThresholdsJson() {
79
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getScrollPositionThresholdsJson");
80
+ auto __result = method(_javaPart);
81
+ return __result->toStdString();
82
+ }
83
+ void JHybridNativeListSpec::setScrollPositionThresholdsJson(const std::string& scrollPositionThresholdsJson) {
84
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* scrollPositionThresholdsJson */)>("setScrollPositionThresholdsJson");
85
+ method(_javaPart, jni::make_jstring(scrollPositionThresholdsJson));
86
+ }
87
+ std::optional<std::function<void(bool /* isBeyondThreshold */)>> JHybridNativeListSpec::getOnScrollPositionThresholdChange() {
88
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JFunc_void_bool::javaobject>()>("getOnScrollPositionThresholdChange_cxx");
89
+ auto __result = method(_javaPart);
90
+ return __result != nullptr ? std::make_optional([&]() -> std::function<void(bool /* isBeyondThreshold */)> {
91
+ if (__result->isInstanceOf(JFunc_void_bool_cxx::javaClassStatic())) [[likely]] {
92
+ auto downcast = jni::static_ref_cast<JFunc_void_bool_cxx::javaobject>(__result);
93
+ return downcast->cthis()->getFunction();
94
+ } else {
95
+ auto __resultRef = jni::make_global(__result);
96
+ return JNICallable<JFunc_void_bool, void(bool)>(std::move(__resultRef));
97
+ }
98
+ }()) : std::nullopt;
99
+ }
100
+ void JHybridNativeListSpec::setOnScrollPositionThresholdChange(const std::optional<std::function<void(bool /* isBeyondThreshold */)>>& onScrollPositionThresholdChange) {
101
+ static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_bool::javaobject> /* onScrollPositionThresholdChange */)>("setOnScrollPositionThresholdChange_cxx");
102
+ method(_javaPart, onScrollPositionThresholdChange.has_value() ? JFunc_void_bool_cxx::fromCpp(onScrollPositionThresholdChange.value()) : nullptr);
103
+ }
68
104
  NativeListKeyboardDismissMode JHybridNativeListSpec::getKeyboardDismissMode() {
69
105
  static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JNativeListKeyboardDismissMode>()>("getKeyboardDismissMode");
70
106
  auto __result = method(_javaPart);
@@ -52,6 +52,12 @@ namespace margelo::nitro::nativelist {
52
52
  // Properties
53
53
  std::string getSnapshotJson() override;
54
54
  void setSnapshotJson(const std::string& snapshotJson) override;
55
+ std::string getContainerSlotHeightsJson() override;
56
+ void setContainerSlotHeightsJson(const std::string& containerSlotHeightsJson) override;
57
+ std::string getScrollPositionThresholdsJson() override;
58
+ void setScrollPositionThresholdsJson(const std::string& scrollPositionThresholdsJson) override;
59
+ std::optional<std::function<void(bool /* isBeyondThreshold */)>> getOnScrollPositionThresholdChange() override;
60
+ void setOnScrollPositionThresholdChange(const std::optional<std::function<void(bool /* isBeyondThreshold */)>>& onScrollPositionThresholdChange) override;
55
61
  NativeListKeyboardDismissMode getKeyboardDismissMode() override;
56
62
  void setKeyboardDismissMode(NativeListKeyboardDismissMode keyboardDismissMode) override;
57
63
  NativeListKeyboardShouldPersistTaps getKeyboardShouldPersistTaps() override;
@@ -58,6 +58,21 @@ void JHybridNativeListStateUpdater::updateViewProps(jni::alias_ref<jni::JClass>
58
58
  : !newProps->snapshotJson.hasSameValue(oldProps->snapshotJson)) {
59
59
  hybridView->setSnapshotJson(newProps->snapshotJson.get());
60
60
  }
61
+ if (oldProps == nullptr
62
+ ? newProps->containerSlotHeightsJson.isProvided()
63
+ : !newProps->containerSlotHeightsJson.hasSameValue(oldProps->containerSlotHeightsJson)) {
64
+ hybridView->setContainerSlotHeightsJson(newProps->containerSlotHeightsJson.get());
65
+ }
66
+ if (oldProps == nullptr
67
+ ? newProps->scrollPositionThresholdsJson.isProvided()
68
+ : !newProps->scrollPositionThresholdsJson.hasSameValue(oldProps->scrollPositionThresholdsJson)) {
69
+ hybridView->setScrollPositionThresholdsJson(newProps->scrollPositionThresholdsJson.get());
70
+ }
71
+ if (oldProps == nullptr
72
+ ? newProps->onScrollPositionThresholdChange.isProvided()
73
+ : !newProps->onScrollPositionThresholdChange.hasSameValue(oldProps->onScrollPositionThresholdChange)) {
74
+ hybridView->setOnScrollPositionThresholdChange(newProps->onScrollPositionThresholdChange.get());
75
+ }
61
76
  if (oldProps == nullptr
62
77
  ? newProps->keyboardDismissMode.isProvided()
63
78
  : !newProps->keyboardDismissMode.hasSameValue(oldProps->keyboardDismissMode)) {