@lodev09/react-native-true-sheet 2.0.5 → 4.0.0-beta.0

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 (194) hide show
  1. package/README.md +36 -8
  2. package/RNTrueSheet.podspec +20 -0
  3. package/android/build.gradle +26 -14
  4. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +108 -0
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerViewManager.kt +21 -0
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +46 -0
  7. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +21 -0
  8. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +47 -0
  9. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterViewManager.kt +21 -0
  10. package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +165 -0
  11. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +36 -4
  12. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +257 -299
  13. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +855 -0
  14. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +104 -82
  15. package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +26 -0
  16. package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +20 -0
  17. package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +26 -0
  18. package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +26 -0
  19. package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +26 -0
  20. package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +26 -0
  21. package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +20 -0
  22. package/android/src/main/java/com/lodev09/truesheet/events/PositionChangeEvent.kt +32 -0
  23. package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +27 -0
  24. package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +20 -0
  25. package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +26 -0
  26. package/android/src/main/java/com/lodev09/truesheet/{core/Utils.kt → utils/ScreenUtils.kt} +47 -17
  27. package/android/src/main/res/values/styles.xml +8 -0
  28. package/ios/TrueSheetComponentDescriptor.h +24 -0
  29. package/ios/TrueSheetContainerView.h +47 -0
  30. package/ios/TrueSheetContainerView.mm +117 -0
  31. package/ios/TrueSheetContentView.h +37 -0
  32. package/ios/TrueSheetContentView.mm +114 -0
  33. package/ios/TrueSheetFooterView.h +27 -0
  34. package/ios/TrueSheetFooterView.mm +101 -0
  35. package/ios/TrueSheetModule.h +44 -0
  36. package/ios/TrueSheetModule.mm +133 -0
  37. package/ios/TrueSheetView.h +53 -0
  38. package/ios/TrueSheetView.mm +433 -0
  39. package/ios/TrueSheetViewController.h +53 -0
  40. package/ios/TrueSheetViewController.mm +649 -0
  41. package/ios/events/OnDetentChangeEvent.h +28 -0
  42. package/ios/events/OnDetentChangeEvent.mm +30 -0
  43. package/ios/events/OnDidDismissEvent.h +26 -0
  44. package/ios/events/OnDidDismissEvent.mm +25 -0
  45. package/ios/events/OnDidPresentEvent.h +28 -0
  46. package/ios/events/OnDidPresentEvent.mm +30 -0
  47. package/ios/events/OnDragBeginEvent.h +28 -0
  48. package/ios/events/OnDragBeginEvent.mm +30 -0
  49. package/ios/events/OnDragChangeEvent.h +28 -0
  50. package/ios/events/OnDragChangeEvent.mm +30 -0
  51. package/ios/events/OnDragEndEvent.h +28 -0
  52. package/ios/events/OnDragEndEvent.mm +30 -0
  53. package/ios/events/OnMountEvent.h +26 -0
  54. package/ios/events/OnMountEvent.mm +25 -0
  55. package/ios/events/OnPositionChangeEvent.h +29 -0
  56. package/ios/events/OnPositionChangeEvent.mm +32 -0
  57. package/ios/events/OnSizeChangeEvent.h +28 -0
  58. package/ios/events/OnSizeChangeEvent.mm +30 -0
  59. package/ios/events/OnWillDismissEvent.h +26 -0
  60. package/ios/events/OnWillDismissEvent.mm +25 -0
  61. package/ios/events/OnWillPresentEvent.h +28 -0
  62. package/ios/events/OnWillPresentEvent.mm +30 -0
  63. package/ios/utils/GestureUtil.h +25 -0
  64. package/ios/utils/GestureUtil.mm +26 -0
  65. package/ios/utils/LayoutUtil.h +44 -0
  66. package/ios/utils/LayoutUtil.mm +50 -0
  67. package/ios/utils/WindowUtil.h +27 -0
  68. package/ios/utils/WindowUtil.mm +42 -0
  69. package/lib/module/TrueSheet.js +231 -135
  70. package/lib/module/TrueSheet.js.map +1 -1
  71. package/lib/module/TrueSheetGrabber.js +16 -14
  72. package/lib/module/TrueSheetGrabber.js.map +1 -1
  73. package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +8 -0
  74. package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +8 -0
  75. package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +8 -0
  76. package/lib/module/fabric/TrueSheetViewNativeComponent.ts +63 -0
  77. package/lib/module/index.js +1 -0
  78. package/lib/module/index.js.map +1 -1
  79. package/lib/module/reanimated/ReanimatedTrueSheet.js +87 -0
  80. package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -0
  81. package/lib/module/reanimated/ReanimatedTrueSheetProvider.js +72 -0
  82. package/lib/module/reanimated/ReanimatedTrueSheetProvider.js.map +1 -0
  83. package/lib/module/reanimated/index.js +6 -0
  84. package/lib/module/reanimated/index.js.map +1 -0
  85. package/lib/module/reanimated/useReanimatedPositionChangeHandler.js +19 -0
  86. package/lib/module/reanimated/useReanimatedPositionChangeHandler.js.map +1 -0
  87. package/lib/module/specs/NativeTrueSheetModule.js +12 -0
  88. package/lib/module/specs/NativeTrueSheetModule.js.map +1 -0
  89. package/lib/typescript/package.json +1 -0
  90. package/lib/typescript/src/TrueSheet.d.ts +79 -0
  91. package/lib/typescript/src/TrueSheet.d.ts.map +1 -0
  92. package/lib/typescript/src/TrueSheet.types.d.ts +260 -0
  93. package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -0
  94. package/lib/typescript/{commonjs/src → src}/TrueSheetGrabber.d.ts +1 -1
  95. package/lib/typescript/src/TrueSheetGrabber.d.ts.map +1 -0
  96. package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts +6 -0
  97. package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -0
  98. package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts +6 -0
  99. package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts.map +1 -0
  100. package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +6 -0
  101. package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -0
  102. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +44 -0
  103. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -0
  104. package/lib/typescript/{commonjs/src → src}/index.d.ts +1 -0
  105. package/lib/typescript/src/index.d.ts.map +1 -0
  106. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts +43 -0
  107. package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts.map +1 -0
  108. package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts +57 -0
  109. package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts.map +1 -0
  110. package/lib/typescript/src/reanimated/index.d.ts +4 -0
  111. package/lib/typescript/src/reanimated/index.d.ts.map +1 -0
  112. package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.d.ts +6 -0
  113. package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.d.ts.map +1 -0
  114. package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts +34 -0
  115. package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts.map +1 -0
  116. package/package.json +104 -75
  117. package/react-native.config.js +17 -0
  118. package/src/TrueSheet.tsx +285 -188
  119. package/src/TrueSheet.types.ts +119 -106
  120. package/src/TrueSheetGrabber.tsx +29 -28
  121. package/src/__mocks__/index.js +60 -12
  122. package/src/fabric/TrueSheetContainerViewNativeComponent.ts +8 -0
  123. package/src/fabric/TrueSheetContentViewNativeComponent.ts +8 -0
  124. package/src/fabric/TrueSheetFooterViewNativeComponent.ts +8 -0
  125. package/src/fabric/TrueSheetViewNativeComponent.ts +63 -0
  126. package/src/index.ts +4 -3
  127. package/src/reanimated/ReanimatedTrueSheet.tsx +95 -0
  128. package/src/reanimated/ReanimatedTrueSheetProvider.tsx +92 -0
  129. package/src/reanimated/index.ts +3 -0
  130. package/src/reanimated/useReanimatedPositionChangeHandler.ts +26 -0
  131. package/src/specs/NativeTrueSheetModule.ts +38 -0
  132. package/TrueSheet.podspec +0 -49
  133. package/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt +0 -400
  134. package/android/src/main/java/com/lodev09/truesheet/TrueSheetEvent.kt +0 -22
  135. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewModule.kt +0 -63
  136. package/android/src/main/java/com/lodev09/truesheet/core/KeyboardManager.kt +0 -58
  137. package/android/src/main/java/com/lodev09/truesheet/core/RootSheetView.kt +0 -102
  138. package/ios/Extensions/UIBlurEffect+withTint.swift +0 -62
  139. package/ios/Extensions/UIView+pinTo.swift +0 -74
  140. package/ios/Extensions/UIViewController+detentForSize.swift +0 -134
  141. package/ios/TrueSheet-Bridging-Header.h +0 -14
  142. package/ios/TrueSheetEvent.swift +0 -48
  143. package/ios/TrueSheetView.swift +0 -461
  144. package/ios/TrueSheetViewController.swift +0 -275
  145. package/ios/TrueSheetViewManager.m +0 -53
  146. package/ios/TrueSheetViewManager.swift +0 -48
  147. package/ios/Utils/Logger.swift +0 -39
  148. package/ios/Utils/Promise.swift +0 -25
  149. package/lib/commonjs/TrueSheet.js +0 -258
  150. package/lib/commonjs/TrueSheet.js.map +0 -1
  151. package/lib/commonjs/TrueSheet.types.js +0 -6
  152. package/lib/commonjs/TrueSheet.types.js.map +0 -1
  153. package/lib/commonjs/TrueSheetFooter.js +0 -19
  154. package/lib/commonjs/TrueSheetFooter.js.map +0 -1
  155. package/lib/commonjs/TrueSheetGrabber.js +0 -54
  156. package/lib/commonjs/TrueSheetGrabber.js.map +0 -1
  157. package/lib/commonjs/TrueSheetModule.js +0 -19
  158. package/lib/commonjs/TrueSheetModule.js.map +0 -1
  159. package/lib/commonjs/__mocks__/index.js +0 -52
  160. package/lib/commonjs/__mocks__/index.js.map +0 -1
  161. package/lib/commonjs/index.js +0 -39
  162. package/lib/commonjs/index.js.map +0 -1
  163. package/lib/module/TrueSheetFooter.js +0 -14
  164. package/lib/module/TrueSheetFooter.js.map +0 -1
  165. package/lib/module/TrueSheetModule.js +0 -15
  166. package/lib/module/TrueSheetModule.js.map +0 -1
  167. package/lib/module/__mocks__/index.js +0 -21
  168. package/lib/module/__mocks__/index.js.map +0 -1
  169. package/lib/typescript/commonjs/package.json +0 -1
  170. package/lib/typescript/commonjs/src/TrueSheet.d.ts +0 -70
  171. package/lib/typescript/commonjs/src/TrueSheet.d.ts.map +0 -1
  172. package/lib/typescript/commonjs/src/TrueSheet.types.d.ts +0 -241
  173. package/lib/typescript/commonjs/src/TrueSheet.types.d.ts.map +0 -1
  174. package/lib/typescript/commonjs/src/TrueSheetFooter.d.ts +0 -7
  175. package/lib/typescript/commonjs/src/TrueSheetFooter.d.ts.map +0 -1
  176. package/lib/typescript/commonjs/src/TrueSheetGrabber.d.ts.map +0 -1
  177. package/lib/typescript/commonjs/src/TrueSheetModule.d.ts +0 -2
  178. package/lib/typescript/commonjs/src/TrueSheetModule.d.ts.map +0 -1
  179. package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
  180. package/lib/typescript/module/src/TrueSheet.d.ts +0 -70
  181. package/lib/typescript/module/src/TrueSheet.d.ts.map +0 -1
  182. package/lib/typescript/module/src/TrueSheet.types.d.ts +0 -241
  183. package/lib/typescript/module/src/TrueSheet.types.d.ts.map +0 -1
  184. package/lib/typescript/module/src/TrueSheetFooter.d.ts +0 -7
  185. package/lib/typescript/module/src/TrueSheetFooter.d.ts.map +0 -1
  186. package/lib/typescript/module/src/TrueSheetGrabber.d.ts +0 -39
  187. package/lib/typescript/module/src/TrueSheetGrabber.d.ts.map +0 -1
  188. package/lib/typescript/module/src/TrueSheetModule.d.ts +0 -2
  189. package/lib/typescript/module/src/TrueSheetModule.d.ts.map +0 -1
  190. package/lib/typescript/module/src/index.d.ts +0 -4
  191. package/lib/typescript/module/src/index.d.ts.map +0 -1
  192. package/src/TrueSheetFooter.tsx +0 -17
  193. package/src/TrueSheetModule.ts +0 -19
  194. /package/lib/{typescript/module → module}/package.json +0 -0
@@ -0,0 +1,47 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import <React/RCTViewComponentView.h>
12
+ #import <UIKit/UIKit.h>
13
+
14
+ NS_ASSUME_NONNULL_BEGIN
15
+
16
+ @protocol TrueSheetContainerViewDelegate <NSObject>
17
+
18
+ /**
19
+ * Called when the container's content size changes
20
+ * @param newSize The new size of the content
21
+ */
22
+ - (void)containerViewContentDidChangeSize:(CGSize)newSize;
23
+
24
+ @end
25
+
26
+ @interface TrueSheetContainerView : RCTViewComponentView
27
+
28
+ /**
29
+ * Delegate to notify of content size changes
30
+ */
31
+ @property (nonatomic, weak, nullable) id<TrueSheetContainerViewDelegate> delegate;
32
+
33
+ /**
34
+ * Returns the current content height
35
+ */
36
+ - (CGFloat)contentHeight;
37
+
38
+ /**
39
+ * Updates footer layout constraints if needed
40
+ */
41
+ - (void)layoutFooter;
42
+
43
+ @end
44
+
45
+ NS_ASSUME_NONNULL_END
46
+
47
+ #endif
@@ -0,0 +1,117 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import "TrueSheetContainerView.h"
12
+ #import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
13
+ #import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
14
+ #import <react/renderer/components/TrueSheetSpec/Props.h>
15
+ #import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
16
+ #import "TrueSheetContentView.h"
17
+ #import "TrueSheetFooterView.h"
18
+
19
+ #import <React/RCTConversions.h>
20
+
21
+ using namespace facebook::react;
22
+
23
+ @interface TrueSheetContainerView () <TrueSheetContentViewDelegate>
24
+ @end
25
+
26
+ @implementation TrueSheetContainerView {
27
+ TrueSheetContentView *_contentView;
28
+ TrueSheetFooterView *_footerView;
29
+ }
30
+
31
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
32
+ return concreteComponentDescriptorProvider<TrueSheetContainerViewComponentDescriptor>();
33
+ }
34
+
35
+ - (instancetype)initWithFrame:(CGRect)frame {
36
+ if (self = [super initWithFrame:frame]) {
37
+ static const auto defaultProps = std::make_shared<const TrueSheetContainerViewProps>();
38
+ _props = defaultProps;
39
+
40
+ self.backgroundColor = [UIColor clearColor];
41
+
42
+ _contentView = nil;
43
+ _footerView = nil;
44
+ }
45
+ return self;
46
+ }
47
+
48
+ - (void)dealloc {
49
+ }
50
+
51
+ - (CGFloat)contentHeight {
52
+ return _contentView ? _contentView.frame.size.height : 0;
53
+ }
54
+
55
+ - (void)layoutFooter {
56
+ if (_footerView) {
57
+ // Force footer to reapply constraints on size change
58
+ CGFloat height = _footerView.frame.size.height;
59
+ if (height > 0) {
60
+ [_footerView setupConstraintsWithHeight:height];
61
+ }
62
+ }
63
+ }
64
+
65
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
66
+ [super mountChildComponentView:childComponentView index:index];
67
+
68
+ // Handle content view mounting
69
+ if ([childComponentView isKindOfClass:[TrueSheetContentView class]]) {
70
+ if (_contentView != nil) {
71
+ NSLog(@"TrueSheet: Container can only have one content component.");
72
+ return;
73
+ }
74
+
75
+ _contentView = (TrueSheetContentView *)childComponentView;
76
+ _contentView.delegate = self;
77
+ }
78
+
79
+ // Handle footer view mounting
80
+ if ([childComponentView isKindOfClass:[TrueSheetFooterView class]]) {
81
+ if (_footerView != nil) {
82
+ NSLog(@"TrueSheet: Container can only have one footer component.");
83
+ return;
84
+ }
85
+
86
+ _footerView = (TrueSheetFooterView *)childComponentView;
87
+ }
88
+ }
89
+
90
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
91
+ if ([childComponentView isKindOfClass:[TrueSheetContentView class]]) {
92
+ _contentView = nil;
93
+ }
94
+
95
+ if ([childComponentView isKindOfClass:[TrueSheetFooterView class]]) {
96
+ _footerView = nil;
97
+ }
98
+
99
+ [super unmountChildComponentView:childComponentView index:index];
100
+ }
101
+
102
+ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
103
+ [super updateProps:props oldProps:oldProps];
104
+ }
105
+
106
+ #pragma mark - TrueSheetContentViewDelegate
107
+
108
+ - (void)contentViewDidChangeSize:(CGSize)newSize {
109
+ // Forward content size changes to host view for sheet resizing
110
+ if ([self.delegate respondsToSelector:@selector(containerViewContentDidChangeSize:)]) {
111
+ [self.delegate containerViewContentDidChangeSize:newSize];
112
+ }
113
+ }
114
+
115
+ @end
116
+
117
+ #endif
@@ -0,0 +1,37 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import <React/RCTSurfaceTouchHandler.h>
12
+ #import <React/RCTViewComponentView.h>
13
+ #import <UIKit/UIKit.h>
14
+ #import <react/renderer/core/LayoutMetrics.h>
15
+
16
+ @class TrueSheetViewController;
17
+ @class RCTScrollViewComponentView;
18
+
19
+ NS_ASSUME_NONNULL_BEGIN
20
+
21
+ @protocol TrueSheetContentViewDelegate <NSObject>
22
+
23
+ - (void)contentViewDidChangeSize:(CGSize)newSize;
24
+
25
+ @end
26
+
27
+ @interface TrueSheetContentView : RCTViewComponentView
28
+
29
+ @property (nonatomic, weak, nullable) id<TrueSheetContentViewDelegate> delegate;
30
+
31
+ - (RCTScrollViewComponentView *_Nullable)findScrollView;
32
+
33
+ @end
34
+
35
+ NS_ASSUME_NONNULL_END
36
+
37
+ #endif
@@ -0,0 +1,114 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import "TrueSheetContentView.h"
12
+ #import <React/RCTScrollViewComponentView.h>
13
+ #import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
14
+ #import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
15
+ #import <react/renderer/components/TrueSheetSpec/Props.h>
16
+ #import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
17
+ #import "TrueSheetViewController.h"
18
+ #import "utils/LayoutUtil.h"
19
+
20
+ using namespace facebook::react;
21
+
22
+ @implementation TrueSheetContentView {
23
+ RCTScrollViewComponentView *_pinnedScrollView;
24
+ CGSize _lastSize;
25
+ }
26
+
27
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
28
+ return concreteComponentDescriptorProvider<TrueSheetContentViewComponentDescriptor>();
29
+ }
30
+
31
+ - (instancetype)initWithFrame:(CGRect)frame {
32
+ if (self = [super initWithFrame:frame]) {
33
+ static const auto defaultProps = std::make_shared<const TrueSheetContentViewProps>();
34
+ _props = defaultProps;
35
+
36
+ _pinnedScrollView = nil;
37
+ _lastSize = CGSizeZero;
38
+ }
39
+ return self;
40
+ }
41
+
42
+ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
43
+ oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics {
44
+ [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
45
+
46
+ // Notify delegate when content size changes for sheet height updates
47
+ CGSize newSize = CGSizeMake(layoutMetrics.frame.size.width, layoutMetrics.frame.size.height);
48
+ if (!CGSizeEqualToSize(newSize, _lastSize)) {
49
+ _lastSize = newSize;
50
+ if ([self.delegate respondsToSelector:@selector(contentViewDidChangeSize:)]) {
51
+ [self.delegate contentViewDidChangeSize:newSize];
52
+ }
53
+ }
54
+ }
55
+
56
+ - (void)didMoveToSuperview {
57
+ [super didMoveToSuperview];
58
+
59
+ // Setup scroll view pinning after Fabric mounts the view in container
60
+ // Ensures proper view hierarchy for scroll detection and pinning
61
+ if (self.superview) {
62
+ [self setupScrollViewPinning];
63
+ }
64
+ }
65
+
66
+ - (void)setupScrollViewPinning {
67
+ // Auto-detect and pin scroll views for proper sheet scrolling behavior
68
+ // Pinning ensures ScrollView fills the sheet area and scrolls correctly with the sheet
69
+ RCTScrollViewComponentView *scrollView = [self findScrollView];
70
+
71
+ if (scrollView && scrollView != _pinnedScrollView) {
72
+ // Unpin previous scroll view if exists
73
+ if (_pinnedScrollView) {
74
+ [LayoutUtil unpinView:_pinnedScrollView];
75
+ }
76
+
77
+ // Pin to container view to enable proper scrolling within the sheet
78
+ UIView *containerView = self.superview;
79
+ if (containerView) {
80
+ [LayoutUtil pinView:scrollView toParentView:containerView edges:UIRectEdgeAll];
81
+ _pinnedScrollView = scrollView;
82
+ }
83
+ }
84
+ }
85
+
86
+ - (RCTScrollViewComponentView *)findScrollView {
87
+ // Get the React component's root view
88
+ if (self.subviews.count == 0) {
89
+ return nil;
90
+ }
91
+
92
+ // Check first-level children for scroll views (ScrollView or FlatList)
93
+ for (UIView *subview in self.subviews) {
94
+ if ([subview isKindOfClass:RCTScrollViewComponentView.class]) {
95
+ return static_cast<RCTScrollViewComponentView *>(subview);
96
+ }
97
+ }
98
+
99
+ return nil;
100
+ }
101
+
102
+ - (void)prepareForRecycle {
103
+ [super prepareForRecycle];
104
+
105
+ // Remove scroll view constraints
106
+ if (_pinnedScrollView) {
107
+ [LayoutUtil unpinView:_pinnedScrollView];
108
+ _pinnedScrollView = nil;
109
+ }
110
+ }
111
+
112
+ @end
113
+
114
+ #endif
@@ -0,0 +1,27 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import <React/RCTSurfaceTouchHandler.h>
12
+ #import <React/RCTViewComponentView.h>
13
+ #import <UIKit/UIKit.h>
14
+
15
+ @class TrueSheetViewController;
16
+
17
+ NS_ASSUME_NONNULL_BEGIN
18
+
19
+ @interface TrueSheetFooterView : RCTViewComponentView
20
+
21
+ - (void)setupConstraintsWithHeight:(CGFloat)height;
22
+
23
+ @end
24
+
25
+ NS_ASSUME_NONNULL_END
26
+
27
+ #endif
@@ -0,0 +1,101 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #ifdef RCT_NEW_ARCH_ENABLED
10
+
11
+ #import "TrueSheetFooterView.h"
12
+ #import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
13
+ #import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
14
+ #import <react/renderer/components/TrueSheetSpec/Props.h>
15
+ #import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
16
+ #import "TrueSheetViewController.h"
17
+ #import "utils/LayoutUtil.h"
18
+
19
+ using namespace facebook::react;
20
+
21
+ @implementation TrueSheetFooterView {
22
+ CGFloat _lastHeight;
23
+ BOOL _didInitialLayout;
24
+ }
25
+
26
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
27
+ return concreteComponentDescriptorProvider<TrueSheetFooterViewComponentDescriptor>();
28
+ }
29
+
30
+ - (instancetype)initWithFrame:(CGRect)frame {
31
+ if (self = [super initWithFrame:frame]) {
32
+ static const auto defaultProps = std::make_shared<const TrueSheetFooterViewProps>();
33
+ _props = defaultProps;
34
+
35
+ // Set background color to clear by default
36
+ self.backgroundColor = [UIColor clearColor];
37
+
38
+ _lastHeight = 0;
39
+ _didInitialLayout = NO;
40
+ }
41
+ return self;
42
+ }
43
+
44
+ - (void)setupConstraintsWithHeight:(CGFloat)height {
45
+ UIView *parentView = self.superview;
46
+ if (!parentView) {
47
+ return;
48
+ }
49
+
50
+ // Remove existing constraints before applying new ones
51
+ [LayoutUtil unpinView:self];
52
+
53
+ // Pin footer to bottom and sides of container with specific height
54
+ [LayoutUtil pinView:self
55
+ toParentView:parentView
56
+ edges:UIRectEdgeLeft | UIRectEdgeRight | UIRectEdgeBottom
57
+ height:height];
58
+
59
+ _lastHeight = height;
60
+ }
61
+
62
+ - (void)didMoveToSuperview {
63
+ [super didMoveToSuperview];
64
+
65
+ // Setup footer constraints when added to container
66
+ if (self.superview) {
67
+ CGFloat initialHeight = self.frame.size.height;
68
+ [self setupConstraintsWithHeight:initialHeight];
69
+ }
70
+ }
71
+
72
+ - (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
73
+ oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics {
74
+ CGFloat height = layoutMetrics.frame.size.height;
75
+
76
+ // On initial layout, call super to let React Native position the view
77
+ // After that, we use Auto Layout constraints instead
78
+ if (!_didInitialLayout) {
79
+ [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
80
+ _didInitialLayout = YES;
81
+ }
82
+
83
+ // Update footer constraints when height changes
84
+ if (height != _lastHeight) {
85
+ [self setupConstraintsWithHeight:height];
86
+ }
87
+ }
88
+
89
+ - (void)prepareForRecycle {
90
+ [super prepareForRecycle];
91
+
92
+ // Remove footer constraints
93
+ [LayoutUtil unpinView:self];
94
+
95
+ _lastHeight = 0;
96
+ _didInitialLayout = NO;
97
+ }
98
+
99
+ @end
100
+
101
+ #endif
@@ -0,0 +1,44 @@
1
+ //
2
+ // TrueSheetModule.h
3
+ // TrueSheet
4
+ //
5
+ // Created by Jovanni Lo (@lodev09)
6
+ // Copyright (c) 2024-present. All rights reserved.
7
+ //
8
+ // This source code is licensed under the MIT license found in the
9
+ // LICENSE file in the root directory of this source tree.
10
+ //
11
+
12
+ #pragma once
13
+
14
+ #ifdef RCT_NEW_ARCH_ENABLED
15
+
16
+ #import <React/RCTBridgeModule.h>
17
+
18
+ NS_ASSUME_NONNULL_BEGIN
19
+
20
+ @class TrueSheetView;
21
+
22
+ /**
23
+ * TurboModule for TrueSheet imperative API
24
+ * Provides promise-based async operations using view references
25
+ */
26
+ @interface TrueSheetModule : NSObject <RCTBridgeModule>
27
+
28
+ /**
29
+ * Register a sheet component view with its React tag
30
+ * Called automatically by TrueSheetView during initialization
31
+ */
32
+ + (void)registerView:(TrueSheetView *)view withTag:(NSNumber *)tag;
33
+
34
+ /**
35
+ * Unregister a sheet component view
36
+ * Called automatically by TrueSheetView during dealloc
37
+ */
38
+ + (void)unregisterViewWithTag:(NSNumber *)tag;
39
+
40
+ @end
41
+
42
+ NS_ASSUME_NONNULL_END
43
+
44
+ #endif // RCT_NEW_ARCH_ENABLED
@@ -0,0 +1,133 @@
1
+ //
2
+ // TrueSheetModule.mm
3
+ // TrueSheet
4
+ //
5
+ // Created by Jovanni Lo (@lodev09)
6
+ // Copyright (c) 2024-present. All rights reserved.
7
+ //
8
+ // This source code is licensed under the MIT license found in the
9
+ // LICENSE file in the root directory of this source tree.
10
+ //
11
+
12
+ #ifdef RCT_NEW_ARCH_ENABLED
13
+
14
+ #import "TrueSheetModule.h"
15
+ #import <React/RCTUtils.h>
16
+ #import "TrueSheetView.h"
17
+
18
+ #import <TrueSheetSpec/TrueSheetSpec.h>
19
+
20
+ // Static registry to store view references by tag
21
+ static NSMutableDictionary<NSNumber *, TrueSheetView *> *viewRegistry;
22
+
23
+ @interface TrueSheetModule () <NativeTrueSheetModuleSpec>
24
+ @end
25
+
26
+ @implementation TrueSheetModule
27
+
28
+ RCT_EXPORT_MODULE(TrueSheetModule)
29
+
30
+ + (void)initialize {
31
+ if (self == [TrueSheetModule class]) {
32
+ viewRegistry = [NSMutableDictionary new];
33
+ }
34
+ }
35
+
36
+ + (BOOL)requiresMainQueueSetup {
37
+ return NO;
38
+ }
39
+
40
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
41
+ (const facebook::react::ObjCTurboModule::InitParams &)params {
42
+ return std::make_shared<facebook::react::NativeTrueSheetModuleSpecJSI>(params);
43
+ }
44
+
45
+ #pragma mark - TurboModule Methods
46
+
47
+ - (void)presentByRef:(double)viewTag
48
+ index:(double)index
49
+ resolve:(RCTPromiseResolveBlock)resolve
50
+ reject:(RCTPromiseRejectBlock)reject {
51
+ RCTExecuteOnMainQueue(^{
52
+ TrueSheetView *trueSheetView = [TrueSheetModule getTrueSheetViewByTag:@((NSInteger)viewTag)];
53
+
54
+ if (!trueSheetView) {
55
+ reject(@"SHEET_NOT_FOUND", [NSString stringWithFormat:@"No sheet found with tag %d", (int)viewTag], nil);
56
+ return;
57
+ }
58
+
59
+ [trueSheetView presentAtIndex:(NSInteger)index
60
+ animated:YES
61
+ completion:^(BOOL success, NSError *_Nullable error) {
62
+ if (success) {
63
+ resolve(nil);
64
+ } else {
65
+ reject(@"PRESENT_FAILED", error.localizedDescription ?: @"Failed to present sheet", error);
66
+ }
67
+ }];
68
+ });
69
+ }
70
+
71
+ - (void)dismissByRef:(double)viewTag resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
72
+ RCTExecuteOnMainQueue(^{
73
+ TrueSheetView *trueSheetView = [TrueSheetModule getTrueSheetViewByTag:@((NSInteger)viewTag)];
74
+
75
+ if (!trueSheetView) {
76
+ reject(@"SHEET_NOT_FOUND", [NSString stringWithFormat:@"No sheet found with tag %d", (int)viewTag], nil);
77
+ return;
78
+ }
79
+
80
+ [trueSheetView dismissAnimated:YES
81
+ completion:^(BOOL success, NSError *_Nullable error) {
82
+ if (success) {
83
+ resolve(nil);
84
+ } else {
85
+ reject(@"DISMISS_FAILED", error.localizedDescription ?: @"Failed to dismiss sheet", error);
86
+ }
87
+ }];
88
+ });
89
+ }
90
+
91
+ - (void)resizeByRef:(double)viewTag
92
+ index:(double)index
93
+ resolve:(RCTPromiseResolveBlock)resolve
94
+ reject:(RCTPromiseRejectBlock)reject {
95
+ // Resize is just present with a different index
96
+ [self presentByRef:viewTag index:index resolve:resolve reject:reject];
97
+ }
98
+
99
+ #pragma mark - Helper Methods
100
+
101
+ + (nullable TrueSheetView *)getTrueSheetViewByTag:(NSNumber *)reactTag {
102
+ if (!reactTag) {
103
+ return nil;
104
+ }
105
+
106
+ @synchronized(viewRegistry) {
107
+ return viewRegistry[reactTag];
108
+ }
109
+ }
110
+
111
+ + (void)registerView:(TrueSheetView *)view withTag:(NSNumber *)tag {
112
+ if (!tag || !view) {
113
+ return;
114
+ }
115
+
116
+ @synchronized(viewRegistry) {
117
+ viewRegistry[tag] = view;
118
+ }
119
+ }
120
+
121
+ + (void)unregisterViewWithTag:(NSNumber *)tag {
122
+ if (!tag) {
123
+ return;
124
+ }
125
+
126
+ @synchronized(viewRegistry) {
127
+ [viewRegistry removeObjectForKey:tag];
128
+ }
129
+ }
130
+
131
+ @end
132
+
133
+ #endif // RCT_NEW_ARCH_ENABLED
@@ -0,0 +1,53 @@
1
+ //
2
+ // Created by Jovanni Lo (@lodev09)
3
+ // Copyright (c) 2024-present. All rights reserved.
4
+ //
5
+ // This source code is licensed under the MIT license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ #pragma once
10
+
11
+ #ifdef RCT_NEW_ARCH_ENABLED
12
+
13
+ #import <React/RCTBridgeModule.h>
14
+ #import <React/RCTViewComponentView.h>
15
+ #import <UIKit/UIKit.h>
16
+
17
+ @class TrueSheetViewController;
18
+
19
+ NS_ASSUME_NONNULL_BEGIN
20
+
21
+ // Completion block for async operations
22
+ typedef void (^TrueSheetCompletionBlock)(BOOL success, NSError *_Nullable error);
23
+
24
+ @interface TrueSheetView : RCTViewComponentView
25
+
26
+ ///**
27
+ // * The view controller managing the sheet presentation
28
+ // * Exposed so container can access it
29
+ // */
30
+ //@property (nonatomic, readonly, strong) TrueSheetViewController *controller;
31
+ //
32
+ ///**
33
+ // * Whether the sheet is currently presented
34
+ // */
35
+ //@property (nonatomic, readonly) BOOL isPresented;
36
+ //
37
+ ///**
38
+ // * The currently active detent index
39
+ // */
40
+ //@property (nonatomic, readonly, strong, nullable) NSNumber *activeIndex;
41
+
42
+ // TurboModule methods
43
+ - (void)presentAtIndex:(NSInteger)index
44
+ animated:(BOOL)animated
45
+ completion:(nullable TrueSheetCompletionBlock)completion;
46
+
47
+ - (void)dismissAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion;
48
+
49
+ @end
50
+
51
+ NS_ASSUME_NONNULL_END
52
+
53
+ #endif // RCT_NEW_ARCH_ENABLED