@lodev09/react-native-true-sheet 3.0.0-beta.9 → 3.0.1
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 +16 -6
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +29 -33
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +3 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +53 -43
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +390 -89
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +42 -4
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensFragmentObserver.kt +0 -5
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDialogObserver.kt +67 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +70 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetDragEvents.kt +71 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetFocusEvents.kt +65 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +94 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetStateEvents.kt +56 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +37 -33
- package/android/src/main/res/anim/true_sheet_slide_in.xml +13 -0
- package/android/src/main/res/anim/true_sheet_slide_out.xml +13 -0
- package/android/src/main/res/values/styles.xml +13 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +5 -3
- package/ios/TrueSheetContainerView.mm +4 -0
- package/ios/TrueSheetContentView.h +2 -1
- package/ios/TrueSheetContentView.mm +91 -11
- package/ios/TrueSheetView.mm +94 -41
- package/ios/TrueSheetViewController.h +22 -10
- package/ios/TrueSheetViewController.mm +360 -173
- package/ios/core/TrueSheetBlurView.h +26 -0
- package/ios/{utils/ConversionUtil.mm → core/TrueSheetBlurView.mm} +64 -3
- package/ios/core/TrueSheetGrabberView.h +42 -0
- package/ios/core/TrueSheetGrabberView.mm +107 -0
- package/ios/events/TrueSheetDragEvents.h +39 -0
- package/ios/events/TrueSheetDragEvents.mm +62 -0
- package/ios/events/{OnPositionChangeEvent.h → TrueSheetFocusEvents.h} +8 -5
- package/ios/events/TrueSheetFocusEvents.mm +49 -0
- package/ios/events/TrueSheetLifecycleEvents.h +40 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +71 -0
- package/ios/events/TrueSheetStateEvents.h +35 -0
- package/ios/events/TrueSheetStateEvents.mm +49 -0
- package/ios/utils/GestureUtil.h +7 -0
- package/ios/utils/GestureUtil.mm +12 -0
- package/lib/module/TrueSheet.js +72 -12
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +28 -5
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/reanimated/ReanimatedTrueSheet.js +13 -7
- package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -1
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js +4 -2
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +4 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +105 -6
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +25 -5
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +0 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts +8 -2
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts.map +1 -1
- package/package.json +8 -2
- package/src/TrueSheet.tsx +87 -10
- package/src/TrueSheet.types.ts +114 -6
- package/src/__mocks__/index.js +0 -5
- package/src/fabric/TrueSheetViewNativeComponent.ts +28 -5
- package/src/index.ts +0 -1
- package/src/reanimated/ReanimatedTrueSheet.tsx +12 -7
- package/src/reanimated/ReanimatedTrueSheetProvider.tsx +11 -3
- package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/PositionChangeEvent.kt +0 -32
- package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +0 -26
- package/ios/events/OnDetentChangeEvent.h +0 -28
- package/ios/events/OnDetentChangeEvent.mm +0 -30
- package/ios/events/OnDidDismissEvent.h +0 -26
- package/ios/events/OnDidDismissEvent.mm +0 -25
- package/ios/events/OnDidPresentEvent.h +0 -28
- package/ios/events/OnDidPresentEvent.mm +0 -30
- package/ios/events/OnDragBeginEvent.h +0 -28
- package/ios/events/OnDragBeginEvent.mm +0 -30
- package/ios/events/OnDragChangeEvent.h +0 -28
- package/ios/events/OnDragChangeEvent.mm +0 -30
- package/ios/events/OnDragEndEvent.h +0 -28
- package/ios/events/OnDragEndEvent.mm +0 -30
- package/ios/events/OnMountEvent.h +0 -26
- package/ios/events/OnMountEvent.mm +0 -25
- package/ios/events/OnPositionChangeEvent.mm +0 -32
- package/ios/events/OnWillDismissEvent.h +0 -26
- package/ios/events/OnWillDismissEvent.mm +0 -25
- package/ios/events/OnWillPresentEvent.h +0 -28
- package/ios/events/OnWillPresentEvent.mm +0 -30
- package/ios/utils/ConversionUtil.h +0 -24
- package/lib/module/TrueSheetGrabber.js +0 -51
- package/lib/module/TrueSheetGrabber.js.map +0 -1
- package/lib/typescript/src/TrueSheetGrabber.d.ts +0 -39
- package/lib/typescript/src/TrueSheetGrabber.d.ts.map +0 -1
- package/src/TrueSheetGrabber.tsx +0 -82
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
|
2
2
|
<resources>
|
|
3
|
-
<!--
|
|
3
|
+
<!-- Smooth slide animation for BottomSheetDialog -->
|
|
4
|
+
<style name="TrueSheetAnimation" parent="Animation.AppCompat.Dialog">
|
|
5
|
+
<item name="android:windowEnterAnimation">@anim/true_sheet_slide_in</item>
|
|
6
|
+
<item name="android:windowExitAnimation">@anim/true_sheet_slide_out</item>
|
|
7
|
+
</style>
|
|
8
|
+
|
|
9
|
+
<!-- Default BottomSheetDialog style with smooth animations -->
|
|
10
|
+
<style name="TrueSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
|
|
11
|
+
<item name="android:windowAnimationStyle">@style/TrueSheetAnimation</item>
|
|
12
|
+
</style>
|
|
13
|
+
|
|
14
|
+
<!-- BottomSheetDialog style with edge-to-edge and smooth animations -->
|
|
4
15
|
<style name="TrueSheetEdgeToEdgeEnabledDialog" parent="Theme.Design.Light.BottomSheetDialog">
|
|
5
16
|
<item name="android:windowIsFloating">false</item>
|
|
6
17
|
<item name="enableEdgeToEdge">true</item>
|
|
18
|
+
<item name="android:windowAnimationStyle">@style/TrueSheetAnimation</item>
|
|
7
19
|
</style>
|
|
8
20
|
</resources>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
#include "TrueSheetViewShadowNode.h"
|
|
2
2
|
|
|
3
|
-
#include <
|
|
3
|
+
#include <react/renderer/components/view/conversions.h>
|
|
4
4
|
|
|
5
5
|
namespace facebook::react {
|
|
6
6
|
|
|
7
|
+
using namespace yoga;
|
|
8
|
+
|
|
7
9
|
extern const char TrueSheetViewComponentName[] = "TrueSheetView";
|
|
8
10
|
|
|
9
11
|
void TrueSheetViewShadowNode::adjustLayoutWithState() {
|
|
@@ -22,7 +24,7 @@ void TrueSheetViewShadowNode::adjustLayoutWithState() {
|
|
|
22
24
|
|
|
23
25
|
// Set width if provided
|
|
24
26
|
if (stateData.containerWidth > 0) {
|
|
25
|
-
adjustedStyle.setDimension(yoga::Dimension::Width,
|
|
27
|
+
adjustedStyle.setDimension(yoga::Dimension::Width, StyleSizeLength::points(stateData.containerWidth));
|
|
26
28
|
if (adjustedStyle.dimension(yoga::Dimension::Width) != currentStyle.dimension(yoga::Dimension::Width)) {
|
|
27
29
|
needsUpdate = true;
|
|
28
30
|
}
|
|
@@ -30,7 +32,7 @@ void TrueSheetViewShadowNode::adjustLayoutWithState() {
|
|
|
30
32
|
|
|
31
33
|
// Set height if provided
|
|
32
34
|
if (stateData.containerHeight > 0) {
|
|
33
|
-
adjustedStyle.setDimension(yoga::Dimension::Height,
|
|
35
|
+
adjustedStyle.setDimension(yoga::Dimension::Height, StyleSizeLength::points(stateData.containerHeight));
|
|
34
36
|
if (adjustedStyle.dimension(yoga::Dimension::Height) != currentStyle.dimension(yoga::Dimension::Height)) {
|
|
35
37
|
needsUpdate = true;
|
|
36
38
|
}
|
|
@@ -167,6 +167,10 @@ using namespace facebook::react;
|
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
- (void)contentViewDidChangeChildren {
|
|
171
|
+
[self setupContentScrollViewPinning];
|
|
172
|
+
}
|
|
173
|
+
|
|
170
174
|
#pragma mark - TrueSheetHeaderViewDelegate
|
|
171
175
|
|
|
172
176
|
- (void)headerViewDidChangeSize:(CGSize)newSize {
|
|
@@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
21
21
|
@protocol TrueSheetContentViewDelegate <NSObject>
|
|
22
22
|
|
|
23
23
|
- (void)contentViewDidChangeSize:(CGSize)newSize;
|
|
24
|
+
- (void)contentViewDidChangeChildren;
|
|
24
25
|
|
|
25
26
|
@end
|
|
26
27
|
|
|
@@ -28,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
28
29
|
|
|
29
30
|
@property (nonatomic, weak, nullable) id<TrueSheetContentViewDelegate> delegate;
|
|
30
31
|
|
|
31
|
-
- (RCTScrollViewComponentView *_Nullable)findScrollView;
|
|
32
|
+
- (RCTScrollViewComponentView *_Nullable)findScrollView:(UIView *_Nullable *_Nullable)outTopSibling;
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Setup ScrollView pinning
|
|
@@ -21,6 +21,7 @@ using namespace facebook::react;
|
|
|
21
21
|
|
|
22
22
|
@implementation TrueSheetContentView {
|
|
23
23
|
RCTScrollViewComponentView *_pinnedScrollView;
|
|
24
|
+
UIView *_pinnedTopView;
|
|
24
25
|
CGSize _lastSize;
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -34,6 +35,7 @@ using namespace facebook::react;
|
|
|
34
35
|
_props = defaultProps;
|
|
35
36
|
|
|
36
37
|
_pinnedScrollView = nil;
|
|
38
|
+
_pinnedTopView = nil;
|
|
37
39
|
_lastSize = CGSizeZero;
|
|
38
40
|
}
|
|
39
41
|
return self;
|
|
@@ -53,6 +55,22 @@ using namespace facebook::react;
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
59
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
60
|
+
|
|
61
|
+
if ([self.delegate respondsToSelector:@selector(contentViewDidChangeChildren)]) {
|
|
62
|
+
[self.delegate contentViewDidChangeChildren];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
67
|
+
[super unmountChildComponentView:childComponentView index:index];
|
|
68
|
+
|
|
69
|
+
if ([self.delegate respondsToSelector:@selector(contentViewDidChangeChildren)]) {
|
|
70
|
+
[self.delegate contentViewDidChangeChildren];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
56
74
|
- (void)unpinScrollViewFromParentView:(UIView *)parentView {
|
|
57
75
|
// Unpin previous scroll view if exists
|
|
58
76
|
if (_pinnedScrollView) {
|
|
@@ -67,43 +85,104 @@ using namespace facebook::react;
|
|
|
67
85
|
if (!pinned) {
|
|
68
86
|
[self unpinScrollViewFromParentView:containerView];
|
|
69
87
|
_pinnedScrollView = nil;
|
|
88
|
+
_pinnedTopView = nil;
|
|
70
89
|
return;
|
|
71
90
|
}
|
|
72
91
|
|
|
73
92
|
// Auto-detect and pin scroll views for proper sheet scrolling behavior
|
|
74
93
|
// Pinning ensures ScrollView fills the available area and scrolls correctly with the sheet
|
|
75
|
-
|
|
94
|
+
UIView *topSibling = nil;
|
|
95
|
+
RCTScrollViewComponentView *scrollView = [self findScrollView:&topSibling];
|
|
96
|
+
|
|
97
|
+
// Use closest top sibling if found, otherwise fall back to header view
|
|
98
|
+
UIView *topView = topSibling ?: headerView;
|
|
76
99
|
|
|
77
|
-
|
|
78
|
-
|
|
100
|
+
// Re-pin when scroll view or top view changes
|
|
101
|
+
BOOL scrollViewChanged = scrollView != _pinnedScrollView;
|
|
102
|
+
BOOL topViewChanged = topView != _pinnedTopView;
|
|
103
|
+
|
|
104
|
+
if (scrollView && containerView && (scrollViewChanged || topViewChanged)) {
|
|
105
|
+
// Unpin first to remove old constraints
|
|
79
106
|
[self unpinScrollViewFromParentView:containerView];
|
|
80
107
|
|
|
81
|
-
if (
|
|
82
|
-
// Pin ScrollView below the
|
|
108
|
+
if (topView) {
|
|
109
|
+
// Pin ScrollView below the top view
|
|
83
110
|
[LayoutUtil pinView:scrollView
|
|
84
111
|
toParentView:containerView
|
|
85
|
-
withTopView:
|
|
112
|
+
withTopView:topView
|
|
86
113
|
edges:UIRectEdgeLeft | UIRectEdgeRight | UIRectEdgeBottom];
|
|
87
114
|
} else {
|
|
88
|
-
// No
|
|
115
|
+
// No top view, pin to all edges of container
|
|
89
116
|
[LayoutUtil pinView:scrollView toParentView:containerView edges:UIRectEdgeAll];
|
|
90
117
|
}
|
|
91
118
|
|
|
92
119
|
_pinnedScrollView = scrollView;
|
|
120
|
+
_pinnedTopView = topView;
|
|
121
|
+
} else if (!scrollView && _pinnedScrollView) {
|
|
122
|
+
// ScrollView was removed, clean up
|
|
123
|
+
[self unpinScrollViewFromParentView:containerView];
|
|
124
|
+
_pinnedScrollView = nil;
|
|
125
|
+
_pinnedTopView = nil;
|
|
93
126
|
}
|
|
94
127
|
}
|
|
95
128
|
|
|
96
|
-
- (RCTScrollViewComponentView *)
|
|
97
|
-
|
|
98
|
-
for (UIView *subview in self.subviews) {
|
|
129
|
+
- (RCTScrollViewComponentView *)findScrollViewInSubviews:(NSArray<UIView *> *)subviews {
|
|
130
|
+
for (UIView *subview in subviews) {
|
|
99
131
|
if ([subview isKindOfClass:RCTScrollViewComponentView.class]) {
|
|
100
132
|
return (RCTScrollViewComponentView *)subview;
|
|
101
133
|
}
|
|
102
134
|
}
|
|
103
|
-
|
|
104
135
|
return nil;
|
|
105
136
|
}
|
|
106
137
|
|
|
138
|
+
- (RCTScrollViewComponentView *)findScrollView:(UIView **)outTopSibling {
|
|
139
|
+
if (self.subviews.count == 0) {
|
|
140
|
+
return nil;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
UIView *topSibling = nil;
|
|
144
|
+
|
|
145
|
+
// Check first-level children for scroll views (ScrollView or FlatList)
|
|
146
|
+
RCTScrollViewComponentView *scrollView = [self findScrollViewInSubviews:self.subviews];
|
|
147
|
+
|
|
148
|
+
// If not found, check second level (grandchildren)
|
|
149
|
+
if (!scrollView) {
|
|
150
|
+
for (UIView *subview in self.subviews) {
|
|
151
|
+
scrollView = [self findScrollViewInSubviews:subview.subviews];
|
|
152
|
+
if (scrollView) {
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Find the view positioned directly above the ScrollView (only for first-level)
|
|
159
|
+
if (scrollView && scrollView.superview == self && self.subviews.count > 1) {
|
|
160
|
+
CGFloat scrollViewTop = CGRectGetMinY(scrollView.frame);
|
|
161
|
+
CGFloat closestDistance = CGFLOAT_MAX;
|
|
162
|
+
|
|
163
|
+
for (UIView *sibling in self.subviews) {
|
|
164
|
+
if (sibling == scrollView) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
CGFloat siblingBottom = CGRectGetMaxY(sibling.frame);
|
|
169
|
+
if (siblingBottom <= scrollViewTop) {
|
|
170
|
+
CGFloat distance = scrollViewTop - siblingBottom;
|
|
171
|
+
if (distance < closestDistance) {
|
|
172
|
+
closestDistance = distance;
|
|
173
|
+
topSibling = sibling;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (outTopSibling) {
|
|
180
|
+
*outTopSibling = topSibling;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return scrollView;
|
|
184
|
+
}
|
|
185
|
+
|
|
107
186
|
- (void)prepareForRecycle {
|
|
108
187
|
[super prepareForRecycle];
|
|
109
188
|
|
|
@@ -111,6 +190,7 @@ using namespace facebook::react;
|
|
|
111
190
|
if (_pinnedScrollView) {
|
|
112
191
|
[LayoutUtil unpinView:_pinnedScrollView fromParentView:self.superview];
|
|
113
192
|
_pinnedScrollView = nil;
|
|
193
|
+
_pinnedTopView = nil;
|
|
114
194
|
}
|
|
115
195
|
}
|
|
116
196
|
|
package/ios/TrueSheetView.mm
CHANGED
|
@@ -14,16 +14,10 @@
|
|
|
14
14
|
#import "TrueSheetFooterView.h"
|
|
15
15
|
#import "TrueSheetModule.h"
|
|
16
16
|
#import "TrueSheetViewController.h"
|
|
17
|
-
#import "events/
|
|
18
|
-
#import "events/
|
|
19
|
-
#import "events/
|
|
20
|
-
#import "events/
|
|
21
|
-
#import "events/OnDragChangeEvent.h"
|
|
22
|
-
#import "events/OnDragEndEvent.h"
|
|
23
|
-
#import "events/OnMountEvent.h"
|
|
24
|
-
#import "events/OnPositionChangeEvent.h"
|
|
25
|
-
#import "events/OnWillDismissEvent.h"
|
|
26
|
-
#import "events/OnWillPresentEvent.h"
|
|
17
|
+
#import "events/TrueSheetDragEvents.h"
|
|
18
|
+
#import "events/TrueSheetFocusEvents.h"
|
|
19
|
+
#import "events/TrueSheetLifecycleEvents.h"
|
|
20
|
+
#import "events/TrueSheetStateEvents.h"
|
|
27
21
|
#import "utils/LayoutUtil.h"
|
|
28
22
|
#import "utils/WindowUtil.h"
|
|
29
23
|
|
|
@@ -53,7 +47,7 @@ using namespace facebook::react;
|
|
|
53
47
|
TrueSheetViewShadowNode::ConcreteState::Shared _state;
|
|
54
48
|
CGSize _lastStateSize;
|
|
55
49
|
NSInteger _initialDetentIndex;
|
|
56
|
-
BOOL
|
|
50
|
+
BOOL _scrollable;
|
|
57
51
|
BOOL _initialDetentAnimated;
|
|
58
52
|
BOOL _isSheetUpdatePending;
|
|
59
53
|
}
|
|
@@ -73,7 +67,7 @@ using namespace facebook::react;
|
|
|
73
67
|
_lastStateSize = CGSizeZero;
|
|
74
68
|
_initialDetentIndex = -1;
|
|
75
69
|
_initialDetentAnimated = YES;
|
|
76
|
-
|
|
70
|
+
_scrollable = NO;
|
|
77
71
|
_isSheetUpdatePending = NO;
|
|
78
72
|
}
|
|
79
73
|
return self;
|
|
@@ -127,6 +121,11 @@ using namespace facebook::react;
|
|
|
127
121
|
// Blur tint
|
|
128
122
|
_controller.blurTint = !newProps.blurTint.empty() ? RCTNSStringFromString(newProps.blurTint) : nil;
|
|
129
123
|
|
|
124
|
+
// Blur options
|
|
125
|
+
const auto &blurOpts = newProps.blurOptions;
|
|
126
|
+
_controller.blurIntensity = blurOpts.intensity >= 0 ? @(blurOpts.intensity) : nil;
|
|
127
|
+
_controller.blurInteraction = blurOpts.interaction;
|
|
128
|
+
|
|
130
129
|
// Corner radius
|
|
131
130
|
_controller.cornerRadius = newProps.cornerRadius < 0 ? nil : @(newProps.cornerRadius);
|
|
132
131
|
|
|
@@ -136,8 +135,39 @@ using namespace facebook::react;
|
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
_controller.grabber = newProps.grabber;
|
|
138
|
+
|
|
139
|
+
// Grabber options - check if any non-default values are set
|
|
140
|
+
const auto &grabberOpts = newProps.grabberOptions;
|
|
141
|
+
BOOL hasGrabberOptions = grabberOpts.width > 0 || grabberOpts.height > 0 || grabberOpts.topMargin > 0 ||
|
|
142
|
+
grabberOpts.cornerRadius >= 0 || grabberOpts.color != 0;
|
|
143
|
+
|
|
144
|
+
if (hasGrabberOptions) {
|
|
145
|
+
NSMutableDictionary *options = [NSMutableDictionary dictionary];
|
|
146
|
+
|
|
147
|
+
if (grabberOpts.width > 0) {
|
|
148
|
+
options[@"width"] = @(grabberOpts.width);
|
|
149
|
+
}
|
|
150
|
+
if (grabberOpts.height > 0) {
|
|
151
|
+
options[@"height"] = @(grabberOpts.height);
|
|
152
|
+
}
|
|
153
|
+
if (grabberOpts.topMargin > 0) {
|
|
154
|
+
options[@"topMargin"] = @(grabberOpts.topMargin);
|
|
155
|
+
}
|
|
156
|
+
if (grabberOpts.cornerRadius >= 0) {
|
|
157
|
+
options[@"cornerRadius"] = @(grabberOpts.cornerRadius);
|
|
158
|
+
}
|
|
159
|
+
if (grabberOpts.color != 0) {
|
|
160
|
+
options[@"color"] = RCTUIColorFromSharedColor(SharedColor(grabberOpts.color));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
_controller.grabberOptions = options;
|
|
164
|
+
} else {
|
|
165
|
+
_controller.grabberOptions = nil;
|
|
166
|
+
}
|
|
167
|
+
|
|
139
168
|
_controller.pageSizing = newProps.pageSizing;
|
|
140
169
|
_controller.modalInPresentation = !newProps.dismissible;
|
|
170
|
+
_controller.draggable = newProps.draggable;
|
|
141
171
|
_controller.dimmed = newProps.dimmed;
|
|
142
172
|
|
|
143
173
|
if (newProps.dimmedDetentIndex >= 0) {
|
|
@@ -146,10 +176,10 @@ using namespace facebook::react;
|
|
|
146
176
|
|
|
147
177
|
_initialDetentIndex = newProps.initialDetentIndex;
|
|
148
178
|
_initialDetentAnimated = newProps.initialDetentAnimated;
|
|
149
|
-
|
|
179
|
+
_scrollable = newProps.scrollable;
|
|
150
180
|
|
|
151
181
|
if (_containerView) {
|
|
152
|
-
_containerView.scrollViewPinningEnabled =
|
|
182
|
+
_containerView.scrollViewPinningEnabled = _scrollable;
|
|
153
183
|
}
|
|
154
184
|
}
|
|
155
185
|
|
|
@@ -193,6 +223,7 @@ using namespace facebook::react;
|
|
|
193
223
|
[self->_controller setupSheetDetents];
|
|
194
224
|
[self->_controller applyActiveDetent];
|
|
195
225
|
}];
|
|
226
|
+
[_controller updateDraggable];
|
|
196
227
|
} else if (_initialDetentIndex >= 0) {
|
|
197
228
|
[self presentAtIndex:_initialDetentIndex animated:_initialDetentAnimated completion:nil];
|
|
198
229
|
}
|
|
@@ -239,10 +270,10 @@ using namespace facebook::react;
|
|
|
239
270
|
_controller.headerHeight = @(headerHeight);
|
|
240
271
|
}
|
|
241
272
|
|
|
242
|
-
_containerView.scrollViewPinningEnabled =
|
|
273
|
+
_containerView.scrollViewPinningEnabled = _scrollable;
|
|
243
274
|
[_containerView setupContentScrollViewPinning];
|
|
244
275
|
|
|
245
|
-
[
|
|
276
|
+
[TrueSheetLifecycleEvents emitMount:_eventEmitter];
|
|
246
277
|
}
|
|
247
278
|
|
|
248
279
|
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
@@ -265,9 +296,14 @@ using namespace facebook::react;
|
|
|
265
296
|
- (void)presentAtIndex:(NSInteger)index
|
|
266
297
|
animated:(BOOL)animated
|
|
267
298
|
completion:(nullable TrueSheetCompletionBlock)completion {
|
|
299
|
+
if (_controller.isBeingPresented) {
|
|
300
|
+
RCTLogWarn(@"TrueSheet: sheet is being presented. Wait for it to transition before presenting again.");
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
268
304
|
if (_controller.isPresented) {
|
|
269
305
|
[_controller.sheetPresentationController animateChanges:^{
|
|
270
|
-
[self->_controller
|
|
306
|
+
[self->_controller resizeToDetentIndex:index];
|
|
271
307
|
}];
|
|
272
308
|
if (completion) {
|
|
273
309
|
completion(YES, nil);
|
|
@@ -300,6 +336,11 @@ using namespace facebook::react;
|
|
|
300
336
|
}
|
|
301
337
|
|
|
302
338
|
- (void)dismissAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion {
|
|
339
|
+
if (_controller.isBeingDismissed) {
|
|
340
|
+
RCTLogWarn(@"TrueSheet: sheet is being dismissed. No need to dismiss it again.");
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
303
344
|
if (!_controller.isPresented) {
|
|
304
345
|
if (completion) {
|
|
305
346
|
completion(YES, nil);
|
|
@@ -315,14 +356,6 @@ using namespace facebook::react;
|
|
|
315
356
|
}];
|
|
316
357
|
}
|
|
317
358
|
|
|
318
|
-
- (void)resizeToIndex:(NSInteger)index {
|
|
319
|
-
if (_controller.isPresented) {
|
|
320
|
-
[_controller.sheetPresentationController animateChanges:^{
|
|
321
|
-
[self->_controller setupActiveDetentWithIndex:index];
|
|
322
|
-
}];
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
359
|
#pragma mark - TrueSheetContainerViewDelegate
|
|
327
360
|
|
|
328
361
|
/**
|
|
@@ -336,7 +369,6 @@ using namespace facebook::react;
|
|
|
336
369
|
|
|
337
370
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
338
371
|
self->_isSheetUpdatePending = NO;
|
|
339
|
-
self->_controller.layoutTransitioning = YES;
|
|
340
372
|
|
|
341
373
|
[self->_controller.sheetPresentationController animateChanges:^{
|
|
342
374
|
[self->_controller setupSheetDetents];
|
|
@@ -356,27 +388,29 @@ using namespace facebook::react;
|
|
|
356
388
|
|
|
357
389
|
#pragma mark - TrueSheetViewControllerDelegate
|
|
358
390
|
|
|
359
|
-
- (void)
|
|
360
|
-
NSInteger index = [_controller currentDetentIndex];
|
|
391
|
+
- (void)viewControllerWillPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
361
392
|
_controller.activeDetentIndex = index;
|
|
362
|
-
[
|
|
393
|
+
[TrueSheetLifecycleEvents emitWillPresent:_eventEmitter index:index position:position detent:detent];
|
|
363
394
|
}
|
|
364
395
|
|
|
365
|
-
- (void)
|
|
366
|
-
[
|
|
396
|
+
- (void)viewControllerDidPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
397
|
+
[TrueSheetLifecycleEvents emitDidPresent:_eventEmitter index:index position:position detent:detent];
|
|
367
398
|
}
|
|
368
399
|
|
|
369
|
-
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
400
|
+
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
401
|
+
index:(NSInteger)index
|
|
402
|
+
position:(CGFloat)position
|
|
403
|
+
detent:(CGFloat)detent {
|
|
370
404
|
switch (state) {
|
|
371
405
|
case UIGestureRecognizerStateBegan:
|
|
372
|
-
[
|
|
406
|
+
[TrueSheetDragEvents emitDragBegin:_eventEmitter index:index position:position detent:detent];
|
|
373
407
|
break;
|
|
374
408
|
case UIGestureRecognizerStateChanged:
|
|
375
|
-
[
|
|
409
|
+
[TrueSheetDragEvents emitDragChange:_eventEmitter index:index position:position detent:detent];
|
|
376
410
|
break;
|
|
377
411
|
case UIGestureRecognizerStateEnded:
|
|
378
412
|
case UIGestureRecognizerStateCancelled:
|
|
379
|
-
[
|
|
413
|
+
[TrueSheetDragEvents emitDragEnd:_eventEmitter index:index position:position detent:detent];
|
|
380
414
|
break;
|
|
381
415
|
default:
|
|
382
416
|
break;
|
|
@@ -384,29 +418,48 @@ using namespace facebook::react;
|
|
|
384
418
|
}
|
|
385
419
|
|
|
386
420
|
- (void)viewControllerWillDismiss {
|
|
387
|
-
[
|
|
421
|
+
[TrueSheetLifecycleEvents emitWillDismiss:_eventEmitter];
|
|
388
422
|
}
|
|
389
423
|
|
|
390
424
|
- (void)viewControllerDidDismiss {
|
|
391
425
|
_controller.activeDetentIndex = -1;
|
|
392
|
-
[
|
|
426
|
+
[TrueSheetLifecycleEvents emitDidDismiss:_eventEmitter];
|
|
393
427
|
}
|
|
394
428
|
|
|
395
|
-
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position {
|
|
429
|
+
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
396
430
|
if (_controller.activeDetentIndex != index) {
|
|
397
431
|
_controller.activeDetentIndex = index;
|
|
398
432
|
}
|
|
399
|
-
[
|
|
433
|
+
[TrueSheetStateEvents emitDetentChange:_eventEmitter index:index position:position detent:detent];
|
|
400
434
|
}
|
|
401
435
|
|
|
402
|
-
- (void)viewControllerDidChangePosition:(
|
|
403
|
-
|
|
436
|
+
- (void)viewControllerDidChangePosition:(CGFloat)index
|
|
437
|
+
position:(CGFloat)position
|
|
438
|
+
detent:(CGFloat)detent
|
|
439
|
+
realtime:(BOOL)realtime {
|
|
440
|
+
[TrueSheetStateEvents emitPositionChange:_eventEmitter index:index position:position detent:detent realtime:realtime];
|
|
404
441
|
}
|
|
405
442
|
|
|
406
443
|
- (void)viewControllerDidChangeSize:(CGSize)size {
|
|
407
444
|
[self updateStateWithSize:size];
|
|
408
445
|
}
|
|
409
446
|
|
|
447
|
+
- (void)viewControllerWillFocus {
|
|
448
|
+
[TrueSheetFocusEvents emitWillFocus:_eventEmitter];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
- (void)viewControllerDidFocus {
|
|
452
|
+
[TrueSheetFocusEvents emitDidFocus:_eventEmitter];
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
- (void)viewControllerWillBlur {
|
|
456
|
+
[TrueSheetFocusEvents emitWillBlur:_eventEmitter];
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
- (void)viewControllerDidBlur {
|
|
460
|
+
[TrueSheetFocusEvents emitDidBlur:_eventEmitter];
|
|
461
|
+
}
|
|
462
|
+
|
|
410
463
|
#pragma mark - Private Helpers
|
|
411
464
|
|
|
412
465
|
- (UIViewController *)findPresentingViewController {
|
|
@@ -19,14 +19,24 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
19
19
|
|
|
20
20
|
@protocol TrueSheetViewControllerDelegate <NSObject>
|
|
21
21
|
|
|
22
|
-
- (void)
|
|
23
|
-
- (void)
|
|
22
|
+
- (void)viewControllerWillPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent;
|
|
23
|
+
- (void)viewControllerDidPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent;
|
|
24
24
|
- (void)viewControllerWillDismiss;
|
|
25
25
|
- (void)viewControllerDidDismiss;
|
|
26
|
-
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position;
|
|
27
|
-
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
28
|
-
|
|
26
|
+
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent;
|
|
27
|
+
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
28
|
+
index:(NSInteger)index
|
|
29
|
+
position:(CGFloat)position
|
|
30
|
+
detent:(CGFloat)detent;
|
|
31
|
+
- (void)viewControllerDidChangePosition:(CGFloat)index
|
|
32
|
+
position:(CGFloat)position
|
|
33
|
+
detent:(CGFloat)detent
|
|
34
|
+
realtime:(BOOL)realtime;
|
|
29
35
|
- (void)viewControllerDidChangeSize:(CGSize)size;
|
|
36
|
+
- (void)viewControllerWillFocus;
|
|
37
|
+
- (void)viewControllerDidFocus;
|
|
38
|
+
- (void)viewControllerWillBlur;
|
|
39
|
+
- (void)viewControllerDidBlur;
|
|
30
40
|
|
|
31
41
|
@end
|
|
32
42
|
|
|
@@ -38,28 +48,30 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
38
48
|
>
|
|
39
49
|
|
|
40
50
|
@property (nonatomic, weak, nullable) id<TrueSheetViewControllerDelegate> delegate;
|
|
41
|
-
@property (nonatomic, strong) NSArray *detents;
|
|
51
|
+
@property (nonatomic, strong) NSArray<NSNumber *> *detents;
|
|
42
52
|
@property (nonatomic, strong, nullable) NSNumber *maxHeight;
|
|
43
53
|
@property (nonatomic, strong, nullable) NSNumber *contentHeight;
|
|
44
54
|
@property (nonatomic, strong, nullable) NSNumber *headerHeight;
|
|
45
55
|
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
|
|
46
56
|
@property (nonatomic, strong, nullable) NSNumber *cornerRadius;
|
|
47
57
|
@property (nonatomic, assign) BOOL grabber;
|
|
58
|
+
@property (nonatomic, strong, nullable) NSDictionary *grabberOptions;
|
|
59
|
+
@property (nonatomic, assign) BOOL draggable;
|
|
48
60
|
@property (nonatomic, assign) BOOL dimmed;
|
|
49
61
|
@property (nonatomic, strong, nullable) NSNumber *dimmedDetentIndex;
|
|
50
62
|
@property (nonatomic, copy, nullable) NSString *blurTint;
|
|
63
|
+
@property (nonatomic, strong, nullable) NSNumber *blurIntensity;
|
|
64
|
+
@property (nonatomic, assign) BOOL blurInteraction;
|
|
51
65
|
@property (nonatomic, assign) BOOL pageSizing;
|
|
52
|
-
@property (nonatomic, assign) BOOL layoutTransitioning;
|
|
53
66
|
@property (nonatomic, assign) BOOL isPresented;
|
|
54
67
|
@property (nonatomic, assign) NSInteger activeDetentIndex;
|
|
55
68
|
|
|
56
69
|
- (void)applyActiveDetent;
|
|
57
70
|
- (void)setupActiveDetentWithIndex:(NSInteger)index;
|
|
71
|
+
- (void)resizeToDetentIndex:(NSInteger)index;
|
|
58
72
|
- (void)setupSheetDetents;
|
|
59
73
|
- (void)setupSheetProps;
|
|
60
|
-
- (
|
|
61
|
-
- (CGFloat)currentPosition;
|
|
62
|
-
- (CGFloat)bottomInset;
|
|
74
|
+
- (void)updateDraggable;
|
|
63
75
|
|
|
64
76
|
@end
|
|
65
77
|
|