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

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 +163 -26
  13. package/android/src/main/res/values/native_scroll_coordinator_ids.xml +4 -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 +227 -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
@@ -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)) {
@@ -0,0 +1,78 @@
1
+ ///
2
+ /// Func_void_bool.kt
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
+ package com.margelo.nitro.nativelist
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.jni.HybridData
12
+ import com.facebook.proguard.annotations.DoNotStrip
13
+
14
+
15
+ /**
16
+ * Represents the JavaScript callback `(isBeyondThreshold: boolean) => void`.
17
+ * This can be either implemented in C++ (in which case it might be a callback coming from JS),
18
+ * or in Kotlin/Java (in which case it is a native callback).
19
+ */
20
+ @DoNotStrip
21
+ @Keep
22
+ @Suppress("ClassName", "RedundantUnitReturnType")
23
+ fun interface Func_void_bool: (Boolean) -> Unit {
24
+ /**
25
+ * Call the given JS callback.
26
+ * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.
27
+ */
28
+ @DoNotStrip
29
+ @Keep
30
+ override fun invoke(isBeyondThreshold: Boolean): Unit
31
+ }
32
+
33
+ /**
34
+ * Represents the JavaScript callback `(isBeyondThreshold: boolean) => void`.
35
+ * This is implemented in C++, via a `std::function<...>`.
36
+ * The callback might be coming from JS.
37
+ */
38
+ @DoNotStrip
39
+ @Keep
40
+ @Suppress(
41
+ "KotlinJniMissingFunction", "unused",
42
+ "RedundantSuppression", "RedundantUnitReturnType", "FunctionName",
43
+ "ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName",
44
+ )
45
+ class Func_void_bool_cxx: Func_void_bool {
46
+ @DoNotStrip
47
+ @Keep
48
+ private val mHybridData: HybridData
49
+
50
+ @DoNotStrip
51
+ @Keep
52
+ private constructor(hybridData: HybridData) {
53
+ mHybridData = hybridData
54
+ }
55
+
56
+ @DoNotStrip
57
+ @Keep
58
+ override fun invoke(isBeyondThreshold: Boolean): Unit
59
+ = invoke_cxx(isBeyondThreshold)
60
+
61
+ private external fun invoke_cxx(isBeyondThreshold: Boolean): Unit
62
+ }
63
+
64
+ /**
65
+ * Represents the JavaScript callback `(isBeyondThreshold: boolean) => void`.
66
+ * This is implemented in Java/Kotlin, via a `(Boolean) -> Unit`.
67
+ * The callback is always coming from native.
68
+ */
69
+ @DoNotStrip
70
+ @Keep
71
+ @Suppress("ClassName", "RedundantUnitReturnType", "unused")
72
+ class Func_void_bool_java(private val function: (Boolean) -> Unit): Func_void_bool {
73
+ @DoNotStrip
74
+ @Keep
75
+ override fun invoke(isBeyondThreshold: Boolean): Unit {
76
+ return this.function(isBeyondThreshold)
77
+ }
78
+ }
@@ -33,6 +33,32 @@ abstract class HybridNativeListSpec: HybridView() {
33
33
  @set:Keep
34
34
  abstract var snapshotJson: String
35
35
 
36
+ @get:DoNotStrip
37
+ @get:Keep
38
+ @set:DoNotStrip
39
+ @set:Keep
40
+ abstract var containerSlotHeightsJson: String
41
+
42
+ @get:DoNotStrip
43
+ @get:Keep
44
+ @set:DoNotStrip
45
+ @set:Keep
46
+ abstract var scrollPositionThresholdsJson: String
47
+
48
+ abstract var onScrollPositionThresholdChange: ((isBeyondThreshold: Boolean) -> Unit)?
49
+
50
+ private var onScrollPositionThresholdChange_cxx: Func_void_bool?
51
+ @Keep
52
+ @DoNotStrip
53
+ get() {
54
+ return onScrollPositionThresholdChange?.let { Func_void_bool_java(it) }
55
+ }
56
+ @Keep
57
+ @DoNotStrip
58
+ set(value) {
59
+ onScrollPositionThresholdChange = value?.let { it }
60
+ }
61
+
36
62
  @get:DoNotStrip
37
63
  @get:Keep
38
64
  @set:DoNotStrip
@@ -8,8 +8,9 @@
8
8
  package com.margelo.nitro.nativelist.views
9
9
 
10
10
  import android.view.View
11
+ import android.view.ViewGroup
11
12
  import com.facebook.react.uimanager.ReactStylesDiffMap
12
- import com.facebook.react.uimanager.SimpleViewManager
13
+ import com.facebook.react.uimanager.ViewGroupManager
13
14
  import com.facebook.react.uimanager.StateWrapper
14
15
  import com.facebook.react.uimanager.ThemedReactContext
15
16
  import com.margelo.nitro.R.id.associated_hybrid_view_tag
@@ -19,7 +20,7 @@ import com.margelo.nitro.nativelist.*
19
20
  /**
20
21
  * Represents the React Native `ViewManager` for the "NativeList" Nitro HybridView.
21
22
  */
22
- public class HybridNativeListManager: SimpleViewManager<View>() {
23
+ public class HybridNativeListManager: ViewGroupManager<ViewGroup>() {
23
24
  /**
24
25
  * Represents the View and its last state snapshot (mutable)
25
26
  */
@@ -35,18 +36,32 @@ public class HybridNativeListManager: SimpleViewManager<View>() {
35
36
  }
36
37
  }
37
38
 
39
+ // NativeList container slot mounting
40
+ override fun needsCustomLayoutForChildren(): Boolean = true
41
+ override fun addView(parent: ViewGroup, child: View, index: Int) {
42
+ (parent as NativeListView).mountContainerSlot(child, index)
43
+ }
44
+ override fun getChildCount(parent: ViewGroup): Int = (parent as NativeListView).containerSlotCount()
45
+ override fun getChildAt(parent: ViewGroup, index: Int): View = (parent as NativeListView).containerSlotAt(index)
46
+ override fun removeViewAt(parent: ViewGroup, index: Int) {
47
+ (parent as NativeListView).unmountContainerSlot(index)
48
+ }
49
+ override fun removeAllViews(parent: ViewGroup) {
50
+ while (getChildCount(parent) > 0) removeViewAt(parent, getChildCount(parent) - 1)
51
+ }
52
+
38
53
  override fun getName(): String {
39
54
  return "NativeList"
40
55
  }
41
56
 
42
- override fun createViewInstance(reactContext: ThemedReactContext): View {
57
+ override fun createViewInstance(reactContext: ThemedReactContext): ViewGroup {
43
58
  val hybridView = HybridNativeList(reactContext)
44
- val view = hybridView.view
59
+ val view = hybridView.view as ViewGroup
45
60
  view.setTag(associated_hybrid_view_tag, HybridViewHolder(hybridView))
46
61
  return view
47
62
  }
48
63
 
49
- override fun updateState(view: View, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
64
+ override fun updateState(view: ViewGroup, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
50
65
  val holder = getHybridViewHolder(view)
51
66
  ?: throw Error("Couldn't find view $view in local views table!")
52
67
  val hybridView = holder.hybridView
@@ -63,14 +78,14 @@ public class HybridNativeListManager: SimpleViewManager<View>() {
63
78
  return super.updateState(view, props, newState)
64
79
  }
65
80
 
66
- override fun onDropViewInstance(view: View) {
81
+ override fun onDropViewInstance(view: ViewGroup) {
67
82
  val holder = getHybridViewHolder(view)
68
83
  holder?.lastState = null
69
84
  holder?.hybridView?.onDropView()
70
85
  return super.onDropViewInstance(view)
71
86
  }
72
87
 
73
- protected override fun prepareToRecycleView(reactContext: ThemedReactContext, view: View): View? {
88
+ protected override fun prepareToRecycleView(reactContext: ThemedReactContext, view: ViewGroup): ViewGroup? {
74
89
  val preparedView = super.prepareToRecycleView(reactContext, view)
75
90
  ?: return null
76
91
  val holder = getHybridViewHolder(preparedView)
@@ -84,13 +99,13 @@ public class HybridNativeListManager: SimpleViewManager<View>() {
84
99
  hybridView.prepareForRecycle()
85
100
 
86
101
  // Maybe update the view if it changed
87
- return hybridView.view
102
+ return hybridView.view as ViewGroup
88
103
  } else {
89
104
  return null
90
105
  }
91
106
  }
92
107
 
93
- private fun getHybridViewHolder(view: View): HybridViewHolder? {
108
+ private fun getHybridViewHolder(view: ViewGroup): HybridViewHolder? {
94
109
  return view.getTag(associated_hybrid_view_tag) as? HybridViewHolder
95
110
  }
96
111
  }
@@ -16,6 +16,7 @@
16
16
  #include <NitroModules/HybridObjectRegistry.hpp>
17
17
 
18
18
  #include "JHybridNativeListSpec.hpp"
19
+ #include "JFunc_void_bool.hpp"
19
20
  #include "JFunc_void_std__string.hpp"
20
21
  #include "views/JHybridNativeListStateUpdater.hpp"
21
22
  #include <NitroModules/DefaultConstructableObject.hpp>
@@ -43,6 +44,7 @@ void registerAllNatives() {
43
44
 
44
45
  // Register native JNI methods
45
46
  margelo::nitro::nativelist::JHybridNativeListSpec::CxxPart::registerNatives();
47
+ margelo::nitro::nativelist::JFunc_void_bool_cxx::registerNatives();
46
48
  margelo::nitro::nativelist::JFunc_void_std__string_cxx::registerNatives();
47
49
  margelo::nitro::nativelist::views::JHybridNativeListStateUpdater::registerNatives();
48
50
 
@@ -14,6 +14,14 @@
14
14
 
15
15
  namespace margelo::nitro::nativelist::bridge::swift {
16
16
 
17
+ // pragma MARK: std::function<void(bool /* isBeyondThreshold */)>
18
+ Func_void_bool create_Func_void_bool(void* NON_NULL swiftClosureWrapper) noexcept {
19
+ auto swiftClosure = NativeListModule::Func_void_bool::fromUnsafe(swiftClosureWrapper);
20
+ return [swiftClosure = std::move(swiftClosure)](bool isBeyondThreshold) mutable -> void {
21
+ swiftClosure.call(isBeyondThreshold);
22
+ };
23
+ }
24
+
17
25
  // pragma MARK: std::function<void(const std::string& /* payloadJson */)>
18
26
  Func_void_std__string create_Func_void_std__string(void* NON_NULL swiftClosureWrapper) noexcept {
19
27
  auto swiftClosure = NativeListModule::Func_void_std__string::fromUnsafe(swiftClosureWrapper);
@@ -30,6 +30,43 @@ namespace NativeListModule { class HybridNativeListSpec_cxx; }
30
30
  */
31
31
  namespace margelo::nitro::nativelist::bridge::swift {
32
32
 
33
+ // pragma MARK: std::function<void(bool /* isBeyondThreshold */)>
34
+ /**
35
+ * Specialized version of `std::function<void(bool)>`.
36
+ */
37
+ using Func_void_bool = std::function<void(bool /* isBeyondThreshold */)>;
38
+ /**
39
+ * Wrapper class for a `std::function<void(bool / * isBeyondThreshold * /)>`, this can be used from Swift.
40
+ */
41
+ class Func_void_bool_Wrapper final {
42
+ public:
43
+ explicit Func_void_bool_Wrapper(std::function<void(bool /* isBeyondThreshold */)>&& func): _function(std::make_unique<std::function<void(bool /* isBeyondThreshold */)>>(std::move(func))) {}
44
+ inline void call(bool isBeyondThreshold) const noexcept {
45
+ _function->operator()(isBeyondThreshold);
46
+ }
47
+ private:
48
+ std::unique_ptr<std::function<void(bool /* isBeyondThreshold */)>> _function;
49
+ } SWIFT_NONCOPYABLE;
50
+ Func_void_bool create_Func_void_bool(void* NON_NULL swiftClosureWrapper) noexcept;
51
+ inline Func_void_bool_Wrapper wrap_Func_void_bool(Func_void_bool value) noexcept {
52
+ return Func_void_bool_Wrapper(std::move(value));
53
+ }
54
+
55
+ // pragma MARK: std::optional<std::function<void(bool /* isBeyondThreshold */)>>
56
+ /**
57
+ * Specialized version of `std::optional<std::function<void(bool / * isBeyondThreshold * /)>>`.
58
+ */
59
+ using std__optional_std__function_void_bool____isBeyondThreshold______ = std::optional<std::function<void(bool /* isBeyondThreshold */)>>;
60
+ inline std::optional<std::function<void(bool /* isBeyondThreshold */)>> create_std__optional_std__function_void_bool____isBeyondThreshold______(const std::function<void(bool /* isBeyondThreshold */)>& value) noexcept {
61
+ return std::optional<std::function<void(bool /* isBeyondThreshold */)>>(value);
62
+ }
63
+ inline bool has_value_std__optional_std__function_void_bool____isBeyondThreshold______(const std::optional<std::function<void(bool /* isBeyondThreshold */)>>& optional) noexcept {
64
+ return optional.has_value();
65
+ }
66
+ inline std::function<void(bool /* isBeyondThreshold */)> get_std__optional_std__function_void_bool____isBeyondThreshold______(const std::optional<std::function<void(bool /* isBeyondThreshold */)>>& optional) noexcept {
67
+ return optional.value();
68
+ }
69
+
33
70
  // pragma MARK: std::function<void(const std::string& /* payloadJson */)>
34
71
  /**
35
72
  * Specialized version of `std::function<void(const std::string&)>`.
@@ -20,10 +20,10 @@ namespace margelo::nitro::nativelist { enum class NativeListKeyboardShouldPersis
20
20
  namespace margelo::nitro::nativelist { enum class NativeListScrollAlignment; }
21
21
 
22
22
  #include <string>
23
- #include "NativeListKeyboardDismissMode.hpp"
24
- #include "NativeListKeyboardShouldPersistTaps.hpp"
25
23
  #include <functional>
26
24
  #include <optional>
25
+ #include "NativeListKeyboardDismissMode.hpp"
26
+ #include "NativeListKeyboardShouldPersistTaps.hpp"
27
27
  #include "NativeListScrollAlignment.hpp"
28
28
 
29
29
  #include "NativeListModule-Swift-Cxx-Umbrella.hpp"
@@ -79,6 +79,27 @@ namespace margelo::nitro::nativelist {
79
79
  inline void setSnapshotJson(const std::string& snapshotJson) noexcept override {
80
80
  _swiftPart.setSnapshotJson(snapshotJson);
81
81
  }
82
+ inline std::string getContainerSlotHeightsJson() noexcept override {
83
+ auto __result = _swiftPart.getContainerSlotHeightsJson();
84
+ return __result;
85
+ }
86
+ inline void setContainerSlotHeightsJson(const std::string& containerSlotHeightsJson) noexcept override {
87
+ _swiftPart.setContainerSlotHeightsJson(containerSlotHeightsJson);
88
+ }
89
+ inline std::string getScrollPositionThresholdsJson() noexcept override {
90
+ auto __result = _swiftPart.getScrollPositionThresholdsJson();
91
+ return __result;
92
+ }
93
+ inline void setScrollPositionThresholdsJson(const std::string& scrollPositionThresholdsJson) noexcept override {
94
+ _swiftPart.setScrollPositionThresholdsJson(scrollPositionThresholdsJson);
95
+ }
96
+ inline std::optional<std::function<void(bool /* isBeyondThreshold */)>> getOnScrollPositionThresholdChange() noexcept override {
97
+ auto __result = _swiftPart.getOnScrollPositionThresholdChange();
98
+ return __result;
99
+ }
100
+ inline void setOnScrollPositionThresholdChange(const std::optional<std::function<void(bool /* isBeyondThreshold */)>>& onScrollPositionThresholdChange) noexcept override {
101
+ _swiftPart.setOnScrollPositionThresholdChange(onScrollPositionThresholdChange);
102
+ }
82
103
  inline NativeListKeyboardDismissMode getKeyboardDismissMode() noexcept override {
83
104
  auto __result = _swiftPart.getKeyboardDismissMode();
84
105
  return static_cast<NativeListKeyboardDismissMode>(__result);