@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.
- package/README.md +36 -8
- package/RNTrueSheet.podspec +20 -0
- package/android/build.gradle +26 -14
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +108 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +46 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +47 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +165 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +36 -4
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +257 -299
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +855 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +104 -82
- package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +20 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +20 -0
- package/android/src/main/java/com/lodev09/truesheet/events/PositionChangeEvent.kt +32 -0
- package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +27 -0
- package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +20 -0
- package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +26 -0
- package/android/src/main/java/com/lodev09/truesheet/{core/Utils.kt → utils/ScreenUtils.kt} +47 -17
- package/android/src/main/res/values/styles.xml +8 -0
- package/ios/TrueSheetComponentDescriptor.h +24 -0
- package/ios/TrueSheetContainerView.h +47 -0
- package/ios/TrueSheetContainerView.mm +117 -0
- package/ios/TrueSheetContentView.h +37 -0
- package/ios/TrueSheetContentView.mm +114 -0
- package/ios/TrueSheetFooterView.h +27 -0
- package/ios/TrueSheetFooterView.mm +101 -0
- package/ios/TrueSheetModule.h +44 -0
- package/ios/TrueSheetModule.mm +133 -0
- package/ios/TrueSheetView.h +53 -0
- package/ios/TrueSheetView.mm +433 -0
- package/ios/TrueSheetViewController.h +53 -0
- package/ios/TrueSheetViewController.mm +649 -0
- package/ios/events/OnDetentChangeEvent.h +28 -0
- package/ios/events/OnDetentChangeEvent.mm +30 -0
- package/ios/events/OnDidDismissEvent.h +26 -0
- package/ios/events/OnDidDismissEvent.mm +25 -0
- package/ios/events/OnDidPresentEvent.h +28 -0
- package/ios/events/OnDidPresentEvent.mm +30 -0
- package/ios/events/OnDragBeginEvent.h +28 -0
- package/ios/events/OnDragBeginEvent.mm +30 -0
- package/ios/events/OnDragChangeEvent.h +28 -0
- package/ios/events/OnDragChangeEvent.mm +30 -0
- package/ios/events/OnDragEndEvent.h +28 -0
- package/ios/events/OnDragEndEvent.mm +30 -0
- package/ios/events/OnMountEvent.h +26 -0
- package/ios/events/OnMountEvent.mm +25 -0
- package/ios/events/OnPositionChangeEvent.h +29 -0
- package/ios/events/OnPositionChangeEvent.mm +32 -0
- package/ios/events/OnSizeChangeEvent.h +28 -0
- package/ios/events/OnSizeChangeEvent.mm +30 -0
- package/ios/events/OnWillDismissEvent.h +26 -0
- package/ios/events/OnWillDismissEvent.mm +25 -0
- package/ios/events/OnWillPresentEvent.h +28 -0
- package/ios/events/OnWillPresentEvent.mm +30 -0
- package/ios/utils/GestureUtil.h +25 -0
- package/ios/utils/GestureUtil.mm +26 -0
- package/ios/utils/LayoutUtil.h +44 -0
- package/ios/utils/LayoutUtil.mm +50 -0
- package/ios/utils/WindowUtil.h +27 -0
- package/ios/utils/WindowUtil.mm +42 -0
- package/lib/module/TrueSheet.js +231 -135
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheetGrabber.js +16 -14
- package/lib/module/TrueSheetGrabber.js.map +1 -1
- package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +63 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/reanimated/ReanimatedTrueSheet.js +87 -0
- package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -0
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js +72 -0
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js.map +1 -0
- package/lib/module/reanimated/index.js +6 -0
- package/lib/module/reanimated/index.js.map +1 -0
- package/lib/module/reanimated/useReanimatedPositionChangeHandler.js +19 -0
- package/lib/module/reanimated/useReanimatedPositionChangeHandler.js.map +1 -0
- package/lib/module/specs/NativeTrueSheetModule.js +12 -0
- package/lib/module/specs/NativeTrueSheetModule.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/TrueSheet.d.ts +79 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheet.types.d.ts +260 -0
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -0
- package/lib/typescript/{commonjs/src → src}/TrueSheetGrabber.d.ts +1 -1
- package/lib/typescript/src/TrueSheetGrabber.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +44 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/{commonjs/src → src}/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts +43 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts +57 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/index.d.ts +4 -0
- package/lib/typescript/src/reanimated/index.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.d.ts +6 -0
- package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts +34 -0
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts.map +1 -0
- package/package.json +104 -75
- package/react-native.config.js +17 -0
- package/src/TrueSheet.tsx +285 -188
- package/src/TrueSheet.types.ts +119 -106
- package/src/TrueSheetGrabber.tsx +29 -28
- package/src/__mocks__/index.js +60 -12
- package/src/fabric/TrueSheetContainerViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +63 -0
- package/src/index.ts +4 -3
- package/src/reanimated/ReanimatedTrueSheet.tsx +95 -0
- package/src/reanimated/ReanimatedTrueSheetProvider.tsx +92 -0
- package/src/reanimated/index.ts +3 -0
- package/src/reanimated/useReanimatedPositionChangeHandler.ts +26 -0
- package/src/specs/NativeTrueSheetModule.ts +38 -0
- package/TrueSheet.podspec +0 -49
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt +0 -400
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetEvent.kt +0 -22
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewModule.kt +0 -63
- package/android/src/main/java/com/lodev09/truesheet/core/KeyboardManager.kt +0 -58
- package/android/src/main/java/com/lodev09/truesheet/core/RootSheetView.kt +0 -102
- package/ios/Extensions/UIBlurEffect+withTint.swift +0 -62
- package/ios/Extensions/UIView+pinTo.swift +0 -74
- package/ios/Extensions/UIViewController+detentForSize.swift +0 -134
- package/ios/TrueSheet-Bridging-Header.h +0 -14
- package/ios/TrueSheetEvent.swift +0 -48
- package/ios/TrueSheetView.swift +0 -461
- package/ios/TrueSheetViewController.swift +0 -275
- package/ios/TrueSheetViewManager.m +0 -53
- package/ios/TrueSheetViewManager.swift +0 -48
- package/ios/Utils/Logger.swift +0 -39
- package/ios/Utils/Promise.swift +0 -25
- package/lib/commonjs/TrueSheet.js +0 -258
- package/lib/commonjs/TrueSheet.js.map +0 -1
- package/lib/commonjs/TrueSheet.types.js +0 -6
- package/lib/commonjs/TrueSheet.types.js.map +0 -1
- package/lib/commonjs/TrueSheetFooter.js +0 -19
- package/lib/commonjs/TrueSheetFooter.js.map +0 -1
- package/lib/commonjs/TrueSheetGrabber.js +0 -54
- package/lib/commonjs/TrueSheetGrabber.js.map +0 -1
- package/lib/commonjs/TrueSheetModule.js +0 -19
- package/lib/commonjs/TrueSheetModule.js.map +0 -1
- package/lib/commonjs/__mocks__/index.js +0 -52
- package/lib/commonjs/__mocks__/index.js.map +0 -1
- package/lib/commonjs/index.js +0 -39
- package/lib/commonjs/index.js.map +0 -1
- package/lib/module/TrueSheetFooter.js +0 -14
- package/lib/module/TrueSheetFooter.js.map +0 -1
- package/lib/module/TrueSheetModule.js +0 -15
- package/lib/module/TrueSheetModule.js.map +0 -1
- package/lib/module/__mocks__/index.js +0 -21
- package/lib/module/__mocks__/index.js.map +0 -1
- package/lib/typescript/commonjs/package.json +0 -1
- package/lib/typescript/commonjs/src/TrueSheet.d.ts +0 -70
- package/lib/typescript/commonjs/src/TrueSheet.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheet.types.d.ts +0 -241
- package/lib/typescript/commonjs/src/TrueSheet.types.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheetFooter.d.ts +0 -7
- package/lib/typescript/commonjs/src/TrueSheetFooter.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheetGrabber.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/TrueSheetModule.d.ts +0 -2
- package/lib/typescript/commonjs/src/TrueSheetModule.d.ts.map +0 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheet.d.ts +0 -70
- package/lib/typescript/module/src/TrueSheet.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheet.types.d.ts +0 -241
- package/lib/typescript/module/src/TrueSheet.types.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheetFooter.d.ts +0 -7
- package/lib/typescript/module/src/TrueSheetFooter.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheetGrabber.d.ts +0 -39
- package/lib/typescript/module/src/TrueSheetGrabber.d.ts.map +0 -1
- package/lib/typescript/module/src/TrueSheetModule.d.ts +0 -2
- package/lib/typescript/module/src/TrueSheetModule.d.ts.map +0 -1
- package/lib/typescript/module/src/index.d.ts +0 -4
- package/lib/typescript/module/src/index.d.ts.map +0 -1
- package/src/TrueSheetFooter.tsx +0 -17
- package/src/TrueSheetModule.ts +0 -19
- /package/lib/{typescript/module → module}/package.json +0 -0
|
@@ -0,0 +1,433 @@
|
|
|
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 "TrueSheetView.h"
|
|
12
|
+
#import "TrueSheetContainerView.h"
|
|
13
|
+
#import "TrueSheetContentView.h"
|
|
14
|
+
#import "TrueSheetFooterView.h"
|
|
15
|
+
#import "TrueSheetModule.h"
|
|
16
|
+
#import "TrueSheetViewController.h"
|
|
17
|
+
#import "events/OnDetentChangeEvent.h"
|
|
18
|
+
#import "events/OnDidDismissEvent.h"
|
|
19
|
+
#import "events/OnDidPresentEvent.h"
|
|
20
|
+
#import "events/OnDragBeginEvent.h"
|
|
21
|
+
#import "events/OnDragChangeEvent.h"
|
|
22
|
+
#import "events/OnDragEndEvent.h"
|
|
23
|
+
#import "events/OnMountEvent.h"
|
|
24
|
+
#import "events/OnPositionChangeEvent.h"
|
|
25
|
+
#import "events/OnSizeChangeEvent.h"
|
|
26
|
+
#import "events/OnWillDismissEvent.h"
|
|
27
|
+
#import "events/OnWillPresentEvent.h"
|
|
28
|
+
#import "utils/LayoutUtil.h"
|
|
29
|
+
#import "utils/WindowUtil.h"
|
|
30
|
+
|
|
31
|
+
#import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
|
|
32
|
+
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
33
|
+
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
34
|
+
#import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
|
|
35
|
+
|
|
36
|
+
#import <React/RCTConversions.h>
|
|
37
|
+
#import <React/RCTFabricComponentsPlugins.h>
|
|
38
|
+
#import <React/RCTSurfaceTouchHandler.h>
|
|
39
|
+
#import <React/RCTUtils.h>
|
|
40
|
+
|
|
41
|
+
using namespace facebook::react;
|
|
42
|
+
|
|
43
|
+
@interface TrueSheetView () <TrueSheetViewControllerDelegate, TrueSheetContainerViewDelegate>
|
|
44
|
+
@end
|
|
45
|
+
|
|
46
|
+
@implementation TrueSheetView {
|
|
47
|
+
TrueSheetContainerView *_containerView;
|
|
48
|
+
TrueSheetViewController *_controller;
|
|
49
|
+
RCTSurfaceTouchHandler *_touchHandler;
|
|
50
|
+
NSInteger _initialDetentIndex;
|
|
51
|
+
BOOL _initialDetentAnimated;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
55
|
+
if (self = [super initWithFrame:frame]) {
|
|
56
|
+
static const auto defaultProps = std::make_shared<const TrueSheetViewProps>();
|
|
57
|
+
_props = defaultProps;
|
|
58
|
+
|
|
59
|
+
// Initialize controller - persists across container lifecycle
|
|
60
|
+
_controller = [[TrueSheetViewController alloc] init];
|
|
61
|
+
_controller.delegate = self;
|
|
62
|
+
|
|
63
|
+
// Initialize touch handler - will be attached to container when mounted
|
|
64
|
+
_touchHandler = [[RCTSurfaceTouchHandler alloc] init];
|
|
65
|
+
|
|
66
|
+
_containerView = nil;
|
|
67
|
+
|
|
68
|
+
_initialDetentIndex = -1;
|
|
69
|
+
_initialDetentAnimated = YES;
|
|
70
|
+
}
|
|
71
|
+
return self;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
- (void)didMoveToWindow {
|
|
75
|
+
[super didMoveToWindow];
|
|
76
|
+
|
|
77
|
+
if (!self.window) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Register this view with the TurboModule when added to window
|
|
82
|
+
// This ensures the tag is properly set by the framework
|
|
83
|
+
if (self.tag > 0) {
|
|
84
|
+
[TrueSheetModule registerView:self withTag:@(self.tag)];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
- (void)dealloc {
|
|
89
|
+
// Dismiss controller if presented
|
|
90
|
+
if (_controller && _controller.presentingViewController) {
|
|
91
|
+
[_controller dismissViewControllerAnimated:NO completion:nil];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Clean up controller
|
|
95
|
+
_controller.delegate = nil;
|
|
96
|
+
_controller = nil;
|
|
97
|
+
|
|
98
|
+
// Unregister this view from the TurboModule
|
|
99
|
+
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#pragma mark - RCTComponentViewProtocol
|
|
103
|
+
|
|
104
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
105
|
+
return concreteComponentDescriptorProvider<TrueSheetViewComponentDescriptor>();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#pragma mark - TurboModule Methods
|
|
109
|
+
|
|
110
|
+
- (void)presentAtIndex:(NSInteger)index
|
|
111
|
+
animated:(BOOL)animated
|
|
112
|
+
completion:(nullable TrueSheetCompletionBlock)completion {
|
|
113
|
+
if (_controller.isPresented) {
|
|
114
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
115
|
+
[self->_controller setupActiveDetentWithIndex:index];
|
|
116
|
+
}];
|
|
117
|
+
|
|
118
|
+
if (completion) {
|
|
119
|
+
completion(YES, nil);
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
UIViewController *presentingViewController = [self findPresentingViewController];
|
|
125
|
+
|
|
126
|
+
if (!presentingViewController) {
|
|
127
|
+
NSError *error = [NSError errorWithDomain:@"com.lodev09.TrueSheet"
|
|
128
|
+
code:1001
|
|
129
|
+
userInfo:@{NSLocalizedDescriptionKey : @"No presenting view controller found"}];
|
|
130
|
+
|
|
131
|
+
if (completion) {
|
|
132
|
+
completion(NO, error);
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Setup our sheet properties
|
|
138
|
+
[_controller setupSheetProps];
|
|
139
|
+
[_controller setupSheetDetents];
|
|
140
|
+
|
|
141
|
+
// Set to the given detent index
|
|
142
|
+
[_controller setupActiveDetentWithIndex:index];
|
|
143
|
+
|
|
144
|
+
// Present our sheet
|
|
145
|
+
[presentingViewController presentViewController:self->_controller
|
|
146
|
+
animated:animated
|
|
147
|
+
completion:^{
|
|
148
|
+
// Call completion handler
|
|
149
|
+
if (completion) {
|
|
150
|
+
completion(YES, nil);
|
|
151
|
+
}
|
|
152
|
+
}];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
- (void)dismissAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion {
|
|
156
|
+
if (!_controller.isPresented) {
|
|
157
|
+
if (completion) {
|
|
158
|
+
completion(YES, nil);
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
[_controller dismissViewControllerAnimated:animated
|
|
164
|
+
completion:^{
|
|
165
|
+
if (completion) {
|
|
166
|
+
completion(YES, nil);
|
|
167
|
+
}
|
|
168
|
+
}];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
- (void)resizeToIndex:(NSInteger)index {
|
|
172
|
+
if (_controller.isPresented) {
|
|
173
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
174
|
+
[self->_controller setupActiveDetentWithIndex:index];
|
|
175
|
+
}];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
|
|
180
|
+
[super updateProps:props oldProps:oldProps];
|
|
181
|
+
|
|
182
|
+
const auto &newProps = *std::static_pointer_cast<TrueSheetViewProps const>(props);
|
|
183
|
+
|
|
184
|
+
// Update detents - pass numbers directly (-1 represents "auto")
|
|
185
|
+
NSMutableArray *detents = [NSMutableArray new];
|
|
186
|
+
for (const auto &detent : newProps.detents) {
|
|
187
|
+
[detents addObject:@(detent)];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
_controller.detents = detents;
|
|
191
|
+
|
|
192
|
+
// Update background color - always set it, even if 0 (which could be a valid color like black)
|
|
193
|
+
UIColor *color = RCTUIColorFromSharedColor(SharedColor(newProps.background));
|
|
194
|
+
_controller.backgroundColor = color;
|
|
195
|
+
|
|
196
|
+
// Update blur tint - always set it to clear when removed
|
|
197
|
+
_controller.blurTint = !newProps.blurTint.empty() ? RCTNSStringFromString(newProps.blurTint) : nil;
|
|
198
|
+
|
|
199
|
+
// Update corner radius
|
|
200
|
+
if (newProps.cornerRadius < 0) {
|
|
201
|
+
_controller.cornerRadius = nil;
|
|
202
|
+
} else {
|
|
203
|
+
_controller.cornerRadius = @(newProps.cornerRadius);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Update max height
|
|
207
|
+
if (newProps.maxHeight != 0.0) {
|
|
208
|
+
_controller.maxHeight = @(newProps.maxHeight);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Update grabber
|
|
212
|
+
_controller.grabber = newProps.grabber;
|
|
213
|
+
|
|
214
|
+
// Update dismissible
|
|
215
|
+
_controller.modalInPresentation = !newProps.dismissible;
|
|
216
|
+
|
|
217
|
+
// Update dimmed
|
|
218
|
+
_controller.dimmed = newProps.dimmed;
|
|
219
|
+
|
|
220
|
+
// Update dimmedIndex
|
|
221
|
+
if (newProps.dimmedIndex >= 0) {
|
|
222
|
+
_controller.dimmedIndex = @(newProps.dimmedIndex);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Store initial presentation settings
|
|
226
|
+
_initialDetentIndex = newProps.initialDetentIndex;
|
|
227
|
+
_initialDetentAnimated = newProps.initialDetentAnimated;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask {
|
|
231
|
+
[super finalizeUpdates:updateMask];
|
|
232
|
+
|
|
233
|
+
// Apply controller updates after all props and children are updated
|
|
234
|
+
if (updateMask & RNComponentViewUpdateMaskProps) {
|
|
235
|
+
// Apply changes to presented sheet if needed
|
|
236
|
+
if (_controller.isPresented) {
|
|
237
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
238
|
+
[self->_controller setupSheetDetents];
|
|
239
|
+
[self->_controller applyActiveDetent];
|
|
240
|
+
}];
|
|
241
|
+
} else {
|
|
242
|
+
// Handle initial presentation
|
|
243
|
+
if (_initialDetentIndex >= 0 && !_controller.isPresented) {
|
|
244
|
+
[self presentAtIndex:_initialDetentIndex animated:_initialDetentAnimated completion:nil];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
251
|
+
// Check if it's a container view
|
|
252
|
+
if ([childComponentView isKindOfClass:[TrueSheetContainerView class]]) {
|
|
253
|
+
if (_containerView != nil) {
|
|
254
|
+
NSLog(@"TrueSheet: Sheet can only have one container component.");
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
_containerView = (TrueSheetContainerView *)childComponentView;
|
|
259
|
+
|
|
260
|
+
// Set this view as the container's delegate
|
|
261
|
+
_containerView.delegate = self;
|
|
262
|
+
|
|
263
|
+
// Attach touch handler to container for touch event handling
|
|
264
|
+
[_touchHandler attachToView:_containerView];
|
|
265
|
+
|
|
266
|
+
// Add to parent view hierarchy
|
|
267
|
+
[_controller.view addSubview:_containerView];
|
|
268
|
+
|
|
269
|
+
// Pin container to fill the entire parent view
|
|
270
|
+
[LayoutUtil pinView:_containerView toParentView:_controller.view edges:UIRectEdgeAll];
|
|
271
|
+
|
|
272
|
+
// Ensure container is above background view
|
|
273
|
+
[_controller.view bringSubviewToFront:_containerView];
|
|
274
|
+
|
|
275
|
+
// Get initial content height from container
|
|
276
|
+
CGFloat contentHeight = [_containerView contentHeight];
|
|
277
|
+
if (contentHeight > 0) {
|
|
278
|
+
_controller.contentHeight = @(contentHeight);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Emit onMount event when container is mounted
|
|
282
|
+
[OnMountEvent emit:_eventEmitter];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
287
|
+
if ([childComponentView isKindOfClass:[TrueSheetContainerView class]]) {
|
|
288
|
+
_containerView.delegate = nil;
|
|
289
|
+
|
|
290
|
+
// Detach touch handler
|
|
291
|
+
if (_touchHandler) {
|
|
292
|
+
[_touchHandler detachFromView:_containerView];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Unpin and remove from view hierarchy
|
|
296
|
+
[LayoutUtil unpinView:_containerView];
|
|
297
|
+
[_containerView removeFromSuperview];
|
|
298
|
+
|
|
299
|
+
_containerView = nil;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
- (void)prepareForRecycle {
|
|
304
|
+
[super prepareForRecycle];
|
|
305
|
+
[self invalidate];
|
|
306
|
+
|
|
307
|
+
// Unregister from the registry
|
|
308
|
+
// Note: Re-registration will happen automatically when the component is reused
|
|
309
|
+
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
#pragma mark - TrueSheetContainerViewDelegate
|
|
313
|
+
|
|
314
|
+
- (void)containerViewContentDidChangeSize:(CGSize)newSize {
|
|
315
|
+
// Clamp content height to container height to prevent unbounded growth with scrollable content
|
|
316
|
+
CGFloat containerHeight = _controller.containerHeight;
|
|
317
|
+
CGFloat contentHeight = containerHeight > 0 ? MIN(newSize.height, containerHeight) : newSize.height;
|
|
318
|
+
|
|
319
|
+
_controller.contentHeight = @(contentHeight);
|
|
320
|
+
|
|
321
|
+
// Update detents if sheet is already presented
|
|
322
|
+
if (_controller.isPresented) {
|
|
323
|
+
// Tell controller that we are transitioning from layout changes.
|
|
324
|
+
// Controller viewDidLayoutSubviews will handle position notification.
|
|
325
|
+
_controller.layoutTransitioning = YES;
|
|
326
|
+
|
|
327
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
328
|
+
[self->_controller setupSheetDetents];
|
|
329
|
+
}];
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
#pragma mark - TrueSheetViewControllerDelegate
|
|
334
|
+
|
|
335
|
+
- (void)viewControllerWillPresent {
|
|
336
|
+
NSInteger index = [_controller currentDetentIndex];
|
|
337
|
+
CGFloat position = _controller.currentPosition;
|
|
338
|
+
|
|
339
|
+
_controller.activeDetentIndex = index;
|
|
340
|
+
|
|
341
|
+
[OnWillPresentEvent emit:_eventEmitter index:index position:position];
|
|
342
|
+
|
|
343
|
+
// Emit onChangeSize event to layout our container on JS
|
|
344
|
+
CGSize controllerSize = _controller.view.frame.size;
|
|
345
|
+
[OnSizeChangeEvent emit:_eventEmitter width:controllerSize.width height:controllerSize.height];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
- (void)viewControllerDidPresent {
|
|
349
|
+
NSInteger index = [_controller currentDetentIndex];
|
|
350
|
+
CGFloat position = _controller.currentPosition;
|
|
351
|
+
|
|
352
|
+
[OnDidPresentEvent emit:_eventEmitter index:index position:position];
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state index:(NSInteger)index position:(CGFloat)position {
|
|
356
|
+
switch (state) {
|
|
357
|
+
case UIGestureRecognizerStateBegan:
|
|
358
|
+
[OnDragBeginEvent emit:_eventEmitter index:index position:position];
|
|
359
|
+
break;
|
|
360
|
+
|
|
361
|
+
case UIGestureRecognizerStateChanged:
|
|
362
|
+
[OnDragChangeEvent emit:_eventEmitter index:index position:position];
|
|
363
|
+
break;
|
|
364
|
+
|
|
365
|
+
case UIGestureRecognizerStateEnded:
|
|
366
|
+
case UIGestureRecognizerStateCancelled:
|
|
367
|
+
[OnDragEndEvent emit:_eventEmitter index:index position:position];
|
|
368
|
+
break;
|
|
369
|
+
|
|
370
|
+
default:
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
- (void)viewControllerWillDismiss {
|
|
376
|
+
[OnWillDismissEvent emit:_eventEmitter];
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
- (void)viewControllerDidDismiss {
|
|
380
|
+
_controller.activeDetentIndex = -1;
|
|
381
|
+
|
|
382
|
+
[OnDidDismissEvent emit:_eventEmitter];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position {
|
|
386
|
+
if (_controller.activeDetentIndex != index) {
|
|
387
|
+
_controller.activeDetentIndex = index;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
[OnDetentChangeEvent emit:_eventEmitter index:index position:position];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
- (void)viewControllerDidChangePosition:(NSInteger)index position:(CGFloat)position transitioning:(BOOL)transitioning {
|
|
394
|
+
[OnPositionChangeEvent emit:_eventEmitter index:index position:position transitioning:transitioning];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
- (void)viewControllerDidChangeSize:(CGSize)size {
|
|
398
|
+
[OnSizeChangeEvent emit:_eventEmitter width:size.width height:size.height];
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
#pragma mark - Private Helpers
|
|
402
|
+
|
|
403
|
+
- (UIViewController *)findPresentingViewController {
|
|
404
|
+
UIWindow *keyWindow = [WindowUtil keyWindow];
|
|
405
|
+
|
|
406
|
+
if (!keyWindow) {
|
|
407
|
+
return nil;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
UIViewController *rootViewController = keyWindow.rootViewController;
|
|
411
|
+
|
|
412
|
+
// Find the top-most presented view controller
|
|
413
|
+
while (rootViewController.presentedViewController) {
|
|
414
|
+
UIViewController *presented = rootViewController.presentedViewController;
|
|
415
|
+
|
|
416
|
+
// Skip TrueSheetViewController if it's being dismissed
|
|
417
|
+
if ([presented isKindOfClass:[TrueSheetViewController class]] && presented.isBeingDismissed) {
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
rootViewController = presented;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return rootViewController;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
@end
|
|
428
|
+
|
|
429
|
+
Class<RCTComponentViewProtocol> TrueSheetViewCls(void) {
|
|
430
|
+
return TrueSheetView.class;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
#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
|
+
#import <UIKit/UIKit.h>
|
|
10
|
+
|
|
11
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
12
|
+
|
|
13
|
+
@protocol TrueSheetViewControllerDelegate <NSObject>
|
|
14
|
+
|
|
15
|
+
- (void)viewControllerWillPresent;
|
|
16
|
+
- (void)viewControllerDidPresent;
|
|
17
|
+
- (void)viewControllerWillDismiss;
|
|
18
|
+
- (void)viewControllerDidDismiss;
|
|
19
|
+
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position;
|
|
20
|
+
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state index:(NSInteger)index position:(CGFloat)position;
|
|
21
|
+
- (void)viewControllerDidChangePosition:(NSInteger)index position:(CGFloat)position transitioning:(BOOL)transitioning;
|
|
22
|
+
- (void)viewControllerDidChangeSize:(CGSize)size;
|
|
23
|
+
|
|
24
|
+
@end
|
|
25
|
+
|
|
26
|
+
@interface TrueSheetViewController : UIViewController <UISheetPresentationControllerDelegate>
|
|
27
|
+
|
|
28
|
+
@property (nonatomic, weak, nullable) id<TrueSheetViewControllerDelegate> delegate;
|
|
29
|
+
@property (nonatomic, strong) NSArray *detents;
|
|
30
|
+
@property (nonatomic, strong, nullable) NSNumber *maxHeight;
|
|
31
|
+
@property (nonatomic, strong, nullable) NSNumber *contentHeight;
|
|
32
|
+
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
|
|
33
|
+
@property (nonatomic, strong, nullable) NSNumber *cornerRadius;
|
|
34
|
+
@property (nonatomic, assign) BOOL grabber;
|
|
35
|
+
@property (nonatomic, assign) BOOL dimmed;
|
|
36
|
+
@property (nonatomic, strong, nullable) NSNumber *dimmedIndex;
|
|
37
|
+
@property (nonatomic, copy, nullable) NSString *blurTint;
|
|
38
|
+
@property (nonatomic, assign) BOOL layoutTransitioning;
|
|
39
|
+
@property (nonatomic, assign) BOOL isPresented;
|
|
40
|
+
@property (nonatomic, assign) NSInteger activeDetentIndex;
|
|
41
|
+
|
|
42
|
+
- (void)applyActiveDetent;
|
|
43
|
+
- (void)setupActiveDetentWithIndex:(NSInteger)index;
|
|
44
|
+
- (void)setupSheetDetents;
|
|
45
|
+
- (void)setupSheetProps;
|
|
46
|
+
- (NSInteger)currentDetentIndex;
|
|
47
|
+
- (CGFloat)currentPosition;
|
|
48
|
+
- (CGFloat)currentHeight;
|
|
49
|
+
- (CGFloat)containerHeight;
|
|
50
|
+
|
|
51
|
+
@end
|
|
52
|
+
|
|
53
|
+
NS_ASSUME_NONNULL_END
|