@lodev09/react-native-true-sheet 4.0.0-beta.3 → 4.0.0-beta.30
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 +28 -5
- package/android/build.gradle +23 -1
- package/android/proguard-rules.pro +3 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +50 -16
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +303 -184
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +38 -109
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +13 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +127 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +29 -3
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +234 -66
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +491 -186
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +64 -10
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +31 -14
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +135 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +23 -23
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +130 -6
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +104 -39
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +14 -17
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +2 -4
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +148 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +33 -40
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ColorUtils.kt +19 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +15 -2
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +0 -12
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/android/src/main/jni/TrueSheetStateUpdater.cpp +37 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +1 -9
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +114 -30
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +30 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +2 -2
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +9 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +14 -3
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +5 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +10 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +43 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +33 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +7 -40
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +3 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +4 -5
- package/ios/TrueSheetContainerView.h +23 -7
- package/ios/TrueSheetContainerView.mm +45 -25
- package/ios/TrueSheetContentView.h +44 -15
- package/ios/TrueSheetContentView.mm +221 -190
- package/ios/TrueSheetFooterView.mm +133 -28
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +18 -18
- package/ios/TrueSheetOverlayView.h +42 -0
- package/ios/TrueSheetOverlayView.mm +175 -0
- package/ios/TrueSheetView.h +2 -0
- package/ios/TrueSheetView.mm +268 -52
- package/ios/TrueSheetViewController.h +36 -3
- package/ios/TrueSheetViewController.mm +797 -102
- package/ios/core/RNScreensEventObserver.mm +31 -28
- package/ios/core/TrueSheetBlurView.h +0 -2
- package/ios/core/TrueSheetBlurView.mm +3 -36
- package/ios/core/TrueSheetDetentCalculator.h +18 -1
- package/ios/core/TrueSheetDetentCalculator.mm +44 -9
- package/ios/core/TrueSheetDimView.h +27 -0
- package/ios/core/TrueSheetDimView.mm +41 -0
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetKeyboardObserver.h +7 -0
- package/ios/core/TrueSheetKeyboardObserver.mm +107 -15
- package/ios/core/TrueSheetOverlayContainerView.h +31 -0
- package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
- package/ios/events/TrueSheetLifecycleEvents.h +2 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
- package/ios/tvos/TrueSheetStubs.mm +12 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
- package/lib/module/TrueSheet.js +222 -54
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +364 -275
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetBackground.js +15 -0
- package/lib/module/TrueSheetBackground.js.map +1 -0
- package/lib/module/TrueSheetOverlay.js +30 -0
- package/lib/module/TrueSheetOverlay.js.map +1 -0
- package/lib/module/TrueSheetOverlay.web.js +35 -0
- package/lib/module/TrueSheetOverlay.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +20 -15
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/TrueSheetProvider.web.js +13 -9
- package/lib/module/TrueSheetProvider.web.js.map +1 -1
- package/lib/module/detentBackgrounds.js +21 -0
- package/lib/module/detentBackgrounds.js.map +1 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +18 -2
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -1
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/createTrueSheetRouter.js +158 -100
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -1
- package/lib/module/navigation/expo-router/base-types.js +2 -0
- package/lib/module/navigation/expo-router/base-types.js.map +1 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js +71 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +18 -7
- package/lib/module/navigation/expo-router/index.js.map +1 -1
- package/lib/module/navigation/expo-router/types.js +4 -0
- package/lib/module/navigation/expo-router/types.js.map +1 -0
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +1 -0
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/scrollable.js +28 -0
- package/lib/module/scrollable.js.map +1 -0
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/keyboard.js +69 -0
- package/lib/module/web/keyboard.js.map +1 -0
- package/lib/module/web/layout.js +168 -0
- package/lib/module/web/layout.js.map +1 -0
- package/lib/module/web/vaul/constants.js +9 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js +4 -0
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +1 -0
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +83 -21
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/module/web/vaul/use-snap-points.js +57 -28
- package/lib/module/web/vaul/use-snap-points.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +18 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +209 -35
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetBackground.d.ts +3 -0
- package/lib/typescript/src/TrueSheetBackground.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts +8 -4
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts +5 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -1
- package/lib/typescript/src/detentBackgrounds.d.ts +10 -0
- package/lib/typescript/src/detentBackgrounds.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -3
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +76 -65
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +4 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +3 -3
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/base-types.d.ts +9 -0
- package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +36 -10
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts +33 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +9 -6
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +3 -4
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +2 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +43 -6
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/scrollable.d.ts +2 -0
- package/lib/typescript/src/scrollable.d.ts.map +1 -0
- package/lib/typescript/src/web/constants.d.ts +1 -1
- package/lib/typescript/src/web/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/keyboard.d.ts +15 -0
- package/lib/typescript/src/web/keyboard.d.ts.map +1 -0
- package/lib/typescript/src/web/layout.d.ts +20 -0
- package/lib/typescript/src/web/layout.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +3 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +5 -1
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts +1 -0
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +20 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/types.d.ts +9 -0
- package/lib/typescript/src/web/vaul/types.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts +6 -4
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
- package/package.json +18 -8
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +257 -62
- package/src/TrueSheet.types.ts +225 -35
- package/src/TrueSheet.web.tsx +445 -333
- package/src/TrueSheetBackground.tsx +17 -0
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +25 -23
- package/src/TrueSheetProvider.web.tsx +22 -13
- package/src/detentBackgrounds.ts +24 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +17 -2
- package/src/mocks/navigationExpoRouter.ts +6 -5
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +220 -144
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/extendTrueSheetRouter.ts +99 -0
- package/src/navigation/expo-router/index.ts +41 -30
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +6 -7
- package/src/navigation/screen/useSheetScreenState.ts +2 -0
- package/src/navigation/types.ts +81 -23
- package/src/scrollable.ts +25 -0
- package/src/web/constants.ts +1 -1
- package/src/web/keyboard.ts +79 -0
- package/src/web/layout.ts +196 -0
- package/src/web/vaul/constants.ts +9 -0
- package/src/web/vaul/context.ts +7 -1
- package/src/web/vaul/helpers.ts +5 -0
- package/src/web/vaul/index.tsx +113 -16
- package/src/web/vaul/types.ts +10 -0
- package/src/web/vaul/use-snap-points.ts +86 -33
package/ios/TrueSheetView.mm
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#import "TrueSheetContentView.h"
|
|
14
14
|
#import "TrueSheetFooterView.h"
|
|
15
15
|
#import "TrueSheetModule.h"
|
|
16
|
+
#import "TrueSheetOverlayView.h"
|
|
16
17
|
#import "TrueSheetViewController.h"
|
|
17
18
|
#import "core/RNScreensEventObserver.h"
|
|
18
19
|
#import "events/TrueSheetDragEvents.h"
|
|
@@ -53,7 +54,7 @@ using namespace facebook::react;
|
|
|
53
54
|
NSInteger _initialDetentIndex;
|
|
54
55
|
TrueSheetViewInsetAdjustment _insetAdjustment;
|
|
55
56
|
ScrollableOptions *_scrollableOptions;
|
|
56
|
-
|
|
57
|
+
NSInteger _scrollableHandle;
|
|
57
58
|
BOOL _initialDetentAnimated;
|
|
58
59
|
BOOL _isSheetUpdatePending;
|
|
59
60
|
BOOL _pendingLayoutUpdate;
|
|
@@ -63,6 +64,9 @@ using namespace facebook::react;
|
|
|
63
64
|
BOOL _pendingMountEvent;
|
|
64
65
|
BOOL _pendingSizeChange;
|
|
65
66
|
BOOL _pendingPropsUpdate;
|
|
67
|
+
BOOL _isPresentPending;
|
|
68
|
+
NSUInteger _pendingPresentGeneration;
|
|
69
|
+
TrueSheetCompletionBlock _pendingPresentCompletion;
|
|
66
70
|
NSArray *_pendingDetents;
|
|
67
71
|
RNScreensEventObserver *_screensEventObserver;
|
|
68
72
|
}
|
|
@@ -124,13 +128,38 @@ using namespace facebook::react;
|
|
|
124
128
|
|
|
125
129
|
UIViewController *vc = [self findPresentingViewController];
|
|
126
130
|
|
|
127
|
-
// Only present if the view controller is in the same window
|
|
128
|
-
if (!vc || vc.view.window != self.window
|
|
131
|
+
// Only present if the view controller is in the same window
|
|
132
|
+
if (!vc || vc.view.window != self.window) {
|
|
129
133
|
// Animate next time when sheet finally moves to the correct window
|
|
130
134
|
_initialDetentAnimated = YES;
|
|
131
135
|
return;
|
|
132
136
|
}
|
|
133
137
|
|
|
138
|
+
// A sheet still animating out of the presenter (e.g. our own controller,
|
|
139
|
+
// recycled mid-dismissal) blocks presentation — retry once its transition ends.
|
|
140
|
+
UIViewController *dismissing = vc.presentedViewController;
|
|
141
|
+
if (dismissing && dismissing.isBeingDismissed) {
|
|
142
|
+
_initialDetentAnimated = YES;
|
|
143
|
+
|
|
144
|
+
__weak __typeof(self) weakSelf = self;
|
|
145
|
+
void (^retry)(void) = ^{
|
|
146
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
147
|
+
[weakSelf presentInitialIfNeeded];
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
id<UIViewControllerTransitionCoordinator> coordinator = dismissing.transitionCoordinator;
|
|
152
|
+
if (coordinator) {
|
|
153
|
+
[coordinator animateAlongsideTransition:nil
|
|
154
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
155
|
+
retry();
|
|
156
|
+
}];
|
|
157
|
+
} else {
|
|
158
|
+
retry();
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
134
163
|
_didInitiallyPresent = YES;
|
|
135
164
|
|
|
136
165
|
// Deferred a runloop turn so sibling mounts from the current transaction
|
|
@@ -157,6 +186,8 @@ using namespace facebook::react;
|
|
|
157
186
|
[_screensEventObserver stopObserving];
|
|
158
187
|
_screensEventObserver = nil;
|
|
159
188
|
|
|
189
|
+
[self cancelPendingPresent];
|
|
190
|
+
|
|
160
191
|
if (_controller && _controller.presentingViewController) {
|
|
161
192
|
// Find the root presenting controller to dismiss the entire stack
|
|
162
193
|
UIViewController *root = _controller.presentingViewController;
|
|
@@ -175,8 +206,6 @@ using namespace facebook::react;
|
|
|
175
206
|
|
|
176
207
|
[_snapshotView removeFromSuperview];
|
|
177
208
|
_snapshotView = nil;
|
|
178
|
-
|
|
179
|
-
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
180
209
|
}
|
|
181
210
|
|
|
182
211
|
#pragma mark - RCTComponentViewProtocol
|
|
@@ -185,6 +214,15 @@ using namespace facebook::react;
|
|
|
185
214
|
return concreteComponentDescriptorProvider<TrueSheetViewComponentDescriptor>();
|
|
186
215
|
}
|
|
187
216
|
|
|
217
|
+
- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
|
|
218
|
+
oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics {
|
|
219
|
+
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
220
|
+
|
|
221
|
+
// RN 0.88+ resets layout metrics on recycle, so the next mount force-applies
|
|
222
|
+
// `hidden` from the display type and would reveal this host over the screen.
|
|
223
|
+
self.hidden = YES;
|
|
224
|
+
}
|
|
225
|
+
|
|
188
226
|
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
|
|
189
227
|
[super updateProps:props oldProps:oldProps];
|
|
190
228
|
|
|
@@ -192,12 +230,8 @@ using namespace facebook::react;
|
|
|
192
230
|
|
|
193
231
|
// Detents (-1 represents "auto")
|
|
194
232
|
NSMutableArray *detents = [NSMutableArray new];
|
|
195
|
-
_hasAutoDetent = NO;
|
|
196
233
|
for (const auto &detent : newProps.detents) {
|
|
197
234
|
[detents addObject:@(detent)];
|
|
198
|
-
if (detent == -1) {
|
|
199
|
-
_hasAutoDetent = YES;
|
|
200
|
-
}
|
|
201
235
|
}
|
|
202
236
|
|
|
203
237
|
if (oldProps) {
|
|
@@ -216,14 +250,29 @@ using namespace facebook::react;
|
|
|
216
250
|
// Background color
|
|
217
251
|
_controller.backgroundColor = RCTUIColorFromSharedColor(newProps.backgroundColor);
|
|
218
252
|
|
|
253
|
+
NSMutableArray<NSDictionary *> *detentBackgrounds = [NSMutableArray new];
|
|
254
|
+
ContextContainer contextContainer;
|
|
255
|
+
PropsParserContext parserContext{-1, contextContainer};
|
|
256
|
+
for (const auto &entry : newProps.detentBackgrounds) {
|
|
257
|
+
NSMutableDictionary *background = [NSMutableDictionary new];
|
|
258
|
+
UIColor *color = RCTUIColorFromSharedColor(entry.color);
|
|
259
|
+
if (color) {
|
|
260
|
+
background[@"color"] = color;
|
|
261
|
+
}
|
|
262
|
+
if (!entry.blur.empty()) {
|
|
263
|
+
auto blur = TrueSheetViewBackgroundBlur::None;
|
|
264
|
+
fromRawValue(parserContext, RawValue(entry.blur), blur);
|
|
265
|
+
background[@"blur"] = @(static_cast<int>(blur));
|
|
266
|
+
}
|
|
267
|
+
[detentBackgrounds addObject:background];
|
|
268
|
+
}
|
|
269
|
+
if (![_controller.detentBackgrounds isEqualToArray:detentBackgrounds]) {
|
|
270
|
+
_controller.detentBackgrounds = detentBackgrounds;
|
|
271
|
+
}
|
|
272
|
+
|
|
219
273
|
// Blur tint
|
|
220
274
|
_controller.backgroundBlur = newProps.backgroundBlur;
|
|
221
275
|
|
|
222
|
-
// Blur options
|
|
223
|
-
const auto &blurOpts = newProps.blurOptions;
|
|
224
|
-
_controller.blurIntensity = blurOpts.intensity >= 0 ? @(blurOpts.intensity) : nil;
|
|
225
|
-
_controller.blurInteraction = blurOpts.interaction;
|
|
226
|
-
|
|
227
276
|
// Corner radius
|
|
228
277
|
_controller.cornerRadius = newProps.cornerRadius < 0 ? nil : @(newProps.cornerRadius);
|
|
229
278
|
|
|
@@ -233,8 +282,9 @@ using namespace facebook::react;
|
|
|
233
282
|
// Content width
|
|
234
283
|
_controller.maxContentWidth = newProps.maxContentWidth != 0.0 ? @(newProps.maxContentWidth) : nil;
|
|
235
284
|
|
|
236
|
-
|
|
237
|
-
|
|
285
|
+
_controller.placement = newProps.placement;
|
|
286
|
+
|
|
287
|
+
_controller.foldOptions = newProps.foldOptions;
|
|
238
288
|
|
|
239
289
|
_controller.grabber = newProps.grabber;
|
|
240
290
|
|
|
@@ -269,6 +319,8 @@ using namespace facebook::react;
|
|
|
269
319
|
_controller.dismissible = newProps.dismissible;
|
|
270
320
|
_controller.draggable = newProps.draggable;
|
|
271
321
|
_controller.dimmed = newProps.dimmed;
|
|
322
|
+
_controller.dimOpacity = newProps.dimOpacity < 0 ? nil : @(newProps.dimOpacity);
|
|
323
|
+
_controller.dimColor = RCTUIColorFromSharedColor(newProps.dimColor);
|
|
272
324
|
|
|
273
325
|
if (newProps.dimmedDetentIndex >= 0) {
|
|
274
326
|
_controller.dimmedDetentIndex = @(newProps.dimmedDetentIndex);
|
|
@@ -277,33 +329,38 @@ using namespace facebook::react;
|
|
|
277
329
|
_initialDetentIndex = newProps.initialDetentIndex;
|
|
278
330
|
_initialDetentAnimated = newProps.initialDetentAnimated;
|
|
279
331
|
|
|
280
|
-
|
|
281
|
-
BOOL scrollingExpandsSheet = scrollableOpts.scrollingExpandsSheet;
|
|
282
|
-
auto topEdgeEffect = scrollableOpts.topScrollEdgeEffect;
|
|
283
|
-
auto bottomEdgeEffect = scrollableOpts.bottomScrollEdgeEffect;
|
|
284
|
-
BOOL hasScrollableOptions = scrollableOpts.keyboardScrollOffset > 0 || !scrollingExpandsSheet ||
|
|
285
|
-
topEdgeEffect != TrueSheetViewTopScrollEdgeEffect::Hidden ||
|
|
286
|
-
bottomEdgeEffect != TrueSheetViewBottomScrollEdgeEffect::Hidden;
|
|
287
|
-
|
|
288
|
-
if (hasScrollableOptions) {
|
|
289
|
-
ScrollableOptions *options = [[ScrollableOptions alloc] init];
|
|
290
|
-
options.keyboardScrollOffset = scrollableOpts.keyboardScrollOffset;
|
|
291
|
-
options.scrollingExpandsSheet = scrollingExpandsSheet;
|
|
292
|
-
options.topScrollEdgeEffect = topEdgeEffect;
|
|
293
|
-
options.bottomScrollEdgeEffect = bottomEdgeEffect;
|
|
294
|
-
_scrollableOptions = options;
|
|
295
|
-
} else {
|
|
296
|
-
_scrollableOptions = nil;
|
|
297
|
-
}
|
|
332
|
+
_scrollableHandle = newProps.scrollableHandle;
|
|
298
333
|
|
|
299
|
-
|
|
334
|
+
const auto &scrollableOpts = newProps.scrollableOptions;
|
|
335
|
+
ScrollableOptions *options = [[ScrollableOptions alloc] init];
|
|
336
|
+
options.contentInsetAdjustment = scrollableOpts.contentInsetAdjustment;
|
|
337
|
+
options.keyboardScrollOffset = scrollableOpts.keyboardScrollOffset;
|
|
338
|
+
options.keyboardOffset = scrollableOpts.keyboardOffset;
|
|
339
|
+
options.scrollingExpandsSheet = scrollableOpts.scrollingExpandsSheet;
|
|
340
|
+
options.topScrollEdgeEffect = scrollableOpts.topScrollEdgeEffect;
|
|
341
|
+
options.bottomScrollEdgeEffect = scrollableOpts.bottomScrollEdgeEffect;
|
|
342
|
+
|
|
343
|
+
// nil while every option is at its default
|
|
344
|
+
BOOL hasScrollableOptions = options.keyboardScrollOffset > 0 || options.keyboardOffset != 0 ||
|
|
345
|
+
!options.scrollingExpandsSheet ||
|
|
346
|
+
options.contentInsetAdjustment != TrueSheetViewContentInsetAdjustment::Automatic ||
|
|
347
|
+
options.topScrollEdgeEffect != TrueSheetViewTopScrollEdgeEffect::Hidden ||
|
|
348
|
+
options.bottomScrollEdgeEffect != TrueSheetViewBottomScrollEdgeEffect::Hidden;
|
|
349
|
+
_scrollableOptions = hasScrollableOptions ? options : nil;
|
|
350
|
+
|
|
351
|
+
_controller.scrollingExpandsSheet = options.scrollingExpandsSheet;
|
|
300
352
|
|
|
301
353
|
_controller.absoluteHeader = newProps.headerOptions.position == TrueSheetViewPosition::Absolute;
|
|
302
354
|
_controller.absoluteFooter = newProps.footerOptions.footerPosition == TrueSheetViewFooterPosition::Absolute;
|
|
355
|
+
_controller.footerInsetAdjustment =
|
|
356
|
+
options.footerInsetAdjustment && _controller.absoluteFooter && _scrollableHandle > 0;
|
|
303
357
|
|
|
304
358
|
CGFloat footerKeyboardOffset = newProps.footerOptions.keyboardOffset;
|
|
305
|
-
|
|
359
|
+
BOOL footerAvoidsKeyboard = newProps.footerOptions.avoidKeyboard;
|
|
360
|
+
if (_controller.footerKeyboardOffset != footerKeyboardOffset ||
|
|
361
|
+
_controller.footerAvoidsKeyboard != footerAvoidsKeyboard) {
|
|
306
362
|
_controller.footerKeyboardOffset = footerKeyboardOffset;
|
|
363
|
+
_controller.footerAvoidsKeyboard = footerAvoidsKeyboard;
|
|
307
364
|
[_containerView updateFooterKeyboardOffset];
|
|
308
365
|
}
|
|
309
366
|
|
|
@@ -366,7 +423,8 @@ using namespace facebook::react;
|
|
|
366
423
|
[self setupScrollable];
|
|
367
424
|
|
|
368
425
|
if (_controller.isPresented) {
|
|
369
|
-
|
|
426
|
+
_pendingPropsUpdate = YES;
|
|
427
|
+
[self setupSheetDetentsForSizeChange];
|
|
370
428
|
} else if (_controller.isBeingPresented) {
|
|
371
429
|
_pendingPropsUpdate = YES;
|
|
372
430
|
} else if (_initialDetentIndex >= 0) {
|
|
@@ -380,7 +438,40 @@ using namespace facebook::react;
|
|
|
380
438
|
- (void)prepareForRecycle {
|
|
381
439
|
[super prepareForRecycle];
|
|
382
440
|
|
|
383
|
-
|
|
441
|
+
// Pooled mid-dismissal: the next mount can reuse this host — and its
|
|
442
|
+
// controller — while the previous sheet is still animating out. Detach until
|
|
443
|
+
// that transition ends so its tail (didBlur, didDismiss, position) can't reach
|
|
444
|
+
// the new mount, then hand the controller back and let auto-present retry.
|
|
445
|
+
if (_controller.isBeingDismissed) {
|
|
446
|
+
_controller.delegate = nil;
|
|
447
|
+
|
|
448
|
+
__weak __typeof(self) weakSelf = self;
|
|
449
|
+
void (^reattach)(void) = ^{
|
|
450
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
451
|
+
__typeof(self) strongSelf = weakSelf;
|
|
452
|
+
if (!strongSelf)
|
|
453
|
+
return;
|
|
454
|
+
|
|
455
|
+
strongSelf->_controller.delegate = strongSelf;
|
|
456
|
+
strongSelf->_controller.activeDetentIndex = -1;
|
|
457
|
+
if (strongSelf.window) {
|
|
458
|
+
[strongSelf presentInitialIfNeeded];
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
id<UIViewControllerTransitionCoordinator> coordinator = _controller.transitionCoordinator;
|
|
464
|
+
if (coordinator) {
|
|
465
|
+
[coordinator animateAlongsideTransition:nil
|
|
466
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
467
|
+
reattach();
|
|
468
|
+
}];
|
|
469
|
+
} else {
|
|
470
|
+
reattach();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
[self cancelPendingPresent];
|
|
384
475
|
|
|
385
476
|
_lastStateSize = CGSizeZero;
|
|
386
477
|
_didInitiallyPresent = NO;
|
|
@@ -421,7 +512,6 @@ using namespace facebook::react;
|
|
|
421
512
|
[_touchHandler attachToView:_containerView];
|
|
422
513
|
[_controller.view addSubview:_containerView];
|
|
423
514
|
[_controller.view bringSubviewToFront:_containerView];
|
|
424
|
-
_containerView.accessibilityViewIsModal = YES;
|
|
425
515
|
_controller.accessibilityContentView = _containerView;
|
|
426
516
|
[_controller setupAccessibilityContainer];
|
|
427
517
|
|
|
@@ -476,7 +566,7 @@ using namespace facebook::react;
|
|
|
476
566
|
- (void)presentAtIndex:(NSInteger)index
|
|
477
567
|
animated:(BOOL)animated
|
|
478
568
|
completion:(nullable TrueSheetCompletionBlock)completion {
|
|
479
|
-
if (_controller.isBeingPresented || _controller.isPresented) {
|
|
569
|
+
if (_controller.isBeingPresented || _controller.isPresented || _isPresentPending) {
|
|
480
570
|
RCTLogWarn(@"TrueSheet: sheet is already presented. Use resize() to change detent.");
|
|
481
571
|
if (completion) {
|
|
482
572
|
completion(YES, nil);
|
|
@@ -498,11 +588,41 @@ using namespace facebook::react;
|
|
|
498
588
|
return;
|
|
499
589
|
}
|
|
500
590
|
|
|
591
|
+
// A controller still animating out of the presenter (e.g. a navigation modal
|
|
592
|
+
// closing) makes UIKit queue this presentation, so everything measured below
|
|
593
|
+
// goes stale before it starts. Present once that transition ends.
|
|
594
|
+
UIViewController *dismissing = presentingViewController.presentedViewController;
|
|
595
|
+
id<UIViewControllerTransitionCoordinator> dismissCoordinator =
|
|
596
|
+
dismissing.isBeingDismissed ? dismissing.transitionCoordinator : nil;
|
|
597
|
+
if (dismissCoordinator) {
|
|
598
|
+
_isPresentPending = YES;
|
|
599
|
+
_pendingPresentCompletion = completion;
|
|
600
|
+
NSUInteger generation = ++_pendingPresentGeneration;
|
|
601
|
+
|
|
602
|
+
__weak __typeof(self) weakSelf = self;
|
|
603
|
+
[dismissCoordinator
|
|
604
|
+
animateAlongsideTransition:nil
|
|
605
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
606
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
607
|
+
__typeof(self) strongSelf = weakSelf;
|
|
608
|
+
if (!strongSelf || !strongSelf->_isPresentPending ||
|
|
609
|
+
strongSelf->_pendingPresentGeneration != generation)
|
|
610
|
+
return;
|
|
611
|
+
|
|
612
|
+
TrueSheetCompletionBlock pendingCompletion = strongSelf->_pendingPresentCompletion;
|
|
613
|
+
strongSelf->_isPresentPending = NO;
|
|
614
|
+
strongSelf->_pendingPresentCompletion = nil;
|
|
615
|
+
[strongSelf presentAtIndex:index animated:animated completion:pendingCompletion];
|
|
616
|
+
});
|
|
617
|
+
}];
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
|
|
501
621
|
[_controller setupAnchorViewInView:presentingViewController.view];
|
|
502
622
|
[_controller setupSheetSizing];
|
|
503
623
|
[_controller setupSheetProps];
|
|
504
624
|
|
|
505
|
-
//
|
|
625
|
+
// Detect before measuring so a first-time detection doesn't shift sizes mid-animation.
|
|
506
626
|
[self setupScrollable];
|
|
507
627
|
|
|
508
628
|
// Measure synchronously so the presentation starts at the right height —
|
|
@@ -515,6 +635,8 @@ using namespace facebook::react;
|
|
|
515
635
|
_controller.peekContentHeight = @([_containerView peekContentHeight]);
|
|
516
636
|
}
|
|
517
637
|
_pendingSizeChange = NO;
|
|
638
|
+
// Props queued while the previous presentation dismissed — applied above.
|
|
639
|
+
_pendingPropsUpdate = NO;
|
|
518
640
|
|
|
519
641
|
[self refreshFooterBottomInset];
|
|
520
642
|
[_controller setupSheetDetents];
|
|
@@ -523,13 +645,29 @@ using namespace facebook::react;
|
|
|
523
645
|
[_screensEventObserver capturePresenterScreenFromView:self];
|
|
524
646
|
[_screensEventObserver startObservingWithState:_state.get()->getData()];
|
|
525
647
|
|
|
648
|
+
UIWindow *window = presentingViewController.view.window;
|
|
526
649
|
[presentingViewController presentViewController:_controller
|
|
527
650
|
animated:animated
|
|
528
651
|
completion:^{
|
|
652
|
+
[TrueSheetOverlayView bringOverlaysToFrontInWindow:window];
|
|
529
653
|
if (completion) {
|
|
530
654
|
completion(YES, nil);
|
|
531
655
|
}
|
|
532
656
|
}];
|
|
657
|
+
|
|
658
|
+
// Presenting adds the sheet's transition view on top of the window once the
|
|
659
|
+
// transition starts — re-front overlays alongside it so the first frame is
|
|
660
|
+
// already ordered (and again on completion in case the transition was queued)
|
|
661
|
+
id<UIViewControllerTransitionCoordinator> coordinator = _controller.transitionCoordinator;
|
|
662
|
+
if (coordinator) {
|
|
663
|
+
[coordinator
|
|
664
|
+
animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
665
|
+
[TrueSheetOverlayView bringOverlaysToFrontInWindow:window];
|
|
666
|
+
}
|
|
667
|
+
completion:nil];
|
|
668
|
+
} else {
|
|
669
|
+
[TrueSheetOverlayView bringOverlaysToFrontInWindow:window];
|
|
670
|
+
}
|
|
533
671
|
}
|
|
534
672
|
|
|
535
673
|
- (void)resizeToIndex:(NSInteger)index completion:(nullable TrueSheetCompletionBlock)completion {
|
|
@@ -562,7 +700,46 @@ using namespace facebook::react;
|
|
|
562
700
|
realtime:NO];
|
|
563
701
|
}
|
|
564
702
|
|
|
703
|
+
/**
|
|
704
|
+
* Drops a deferred present and resolves its caller. Returns whether one was pending.
|
|
705
|
+
*/
|
|
706
|
+
- (BOOL)cancelPendingPresent {
|
|
707
|
+
if (!_isPresentPending) {
|
|
708
|
+
return NO;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
TrueSheetCompletionBlock pendingCompletion = _pendingPresentCompletion;
|
|
712
|
+
_isPresentPending = NO;
|
|
713
|
+
_pendingPresentCompletion = nil;
|
|
714
|
+
if (pendingCompletion) {
|
|
715
|
+
pendingCompletion(YES, nil);
|
|
716
|
+
}
|
|
717
|
+
return YES;
|
|
718
|
+
}
|
|
719
|
+
|
|
565
720
|
- (void)dismissAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion {
|
|
721
|
+
// Dismissing before a deferred present starts cancels it — nothing was presented.
|
|
722
|
+
if ([self cancelPendingPresent]) {
|
|
723
|
+
if (completion) {
|
|
724
|
+
completion(YES, nil);
|
|
725
|
+
}
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// Still animating in (isPresented flips at viewDidAppear): dismiss once the presentation lands
|
|
730
|
+
id<UIViewControllerTransitionCoordinator> presentCoordinator =
|
|
731
|
+
_controller.isBeingPresented ? _controller.transitionCoordinator : nil;
|
|
732
|
+
if (presentCoordinator) {
|
|
733
|
+
__weak __typeof(self) weakSelf = self;
|
|
734
|
+
[presentCoordinator animateAlongsideTransition:nil
|
|
735
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
736
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
737
|
+
[weakSelf dismissAnimated:animated completion:completion];
|
|
738
|
+
});
|
|
739
|
+
}];
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
|
|
566
743
|
if (_controller.isBeingDismissed || !_controller.isPresented) {
|
|
567
744
|
RCTLogWarn(@"TrueSheet: sheet is already dismissed. No need to dismiss it again.");
|
|
568
745
|
|
|
@@ -612,7 +789,8 @@ using namespace facebook::react;
|
|
|
612
789
|
#pragma mark - TrueSheetContainerViewDelegate
|
|
613
790
|
|
|
614
791
|
/**
|
|
615
|
-
*
|
|
792
|
+
* Coalesces prop and size changes outside Fabric's mount transaction so
|
|
793
|
+
* the footer's layout can mount inside UIKit's resize animation.
|
|
616
794
|
*/
|
|
617
795
|
- (void)setupSheetDetentsForSizeChange {
|
|
618
796
|
// Keep the footer's absorbed inset in sync with the latest measured heights
|
|
@@ -628,26 +806,52 @@ using namespace facebook::react;
|
|
|
628
806
|
}
|
|
629
807
|
|
|
630
808
|
// Not presented: presentAtIndex measures at present time.
|
|
631
|
-
|
|
632
|
-
// presentation stack, visibly glitching the sheet behind.
|
|
633
|
-
if (!_controller.isPresented || _controller.isBeingDismissed)
|
|
809
|
+
if (!_controller.isPresented || _isSheetUpdatePending)
|
|
634
810
|
return;
|
|
635
811
|
|
|
636
|
-
|
|
812
|
+
// Dismissing: the sheet is going away — touching detents perturbs the
|
|
813
|
+
// presentation stack, visibly glitching the sheet behind. An interactive
|
|
814
|
+
// dismiss can still cancel, so retry once the transition resolves.
|
|
815
|
+
if (_controller.isBeingDismissed) {
|
|
816
|
+
id<UIViewControllerTransitionCoordinator> coordinator = _controller.transitionCoordinator;
|
|
817
|
+
if (coordinator) {
|
|
818
|
+
_isSheetUpdatePending = YES;
|
|
819
|
+
|
|
820
|
+
__weak __typeof(self) weakSelf = self;
|
|
821
|
+
[coordinator animateAlongsideTransition:nil
|
|
822
|
+
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
|
|
823
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
824
|
+
__typeof(self) strongSelf = weakSelf;
|
|
825
|
+
if (!strongSelf)
|
|
826
|
+
return;
|
|
827
|
+
|
|
828
|
+
strongSelf->_isSheetUpdatePending = NO;
|
|
829
|
+
[strongSelf setupSheetDetentsForSizeChange];
|
|
830
|
+
});
|
|
831
|
+
}];
|
|
832
|
+
}
|
|
637
833
|
return;
|
|
834
|
+
}
|
|
638
835
|
|
|
639
836
|
_isSheetUpdatePending = YES;
|
|
640
837
|
|
|
641
838
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
642
839
|
self->_isSheetUpdatePending = NO;
|
|
643
|
-
if (!self->_containerView || self->_controller.isBeingDismissed)
|
|
840
|
+
if (!self->_containerView || !self->_controller.isPresented || self->_controller.isBeingDismissed)
|
|
644
841
|
return;
|
|
645
842
|
|
|
646
843
|
// Refresh here (not just on peek size events) since the peek's offset
|
|
647
844
|
// within the content can change without its own size changing.
|
|
648
845
|
self->_controller.peekContentHeight = @([self->_containerView peekContentHeight]);
|
|
649
846
|
[self refreshFooterBottomInset];
|
|
847
|
+
|
|
848
|
+
// Size first: the props rebuild refreshes the heights itself, hiding the
|
|
849
|
+
// change from the controller and skipping its post-resize settle.
|
|
650
850
|
[self->_controller setupSheetDetentsForSizeChange];
|
|
851
|
+
if (self->_pendingPropsUpdate) {
|
|
852
|
+
self->_pendingPropsUpdate = NO;
|
|
853
|
+
[self applySheetPropsUpdate];
|
|
854
|
+
}
|
|
651
855
|
});
|
|
652
856
|
}
|
|
653
857
|
|
|
@@ -664,14 +868,18 @@ using namespace facebook::react;
|
|
|
664
868
|
- (void)containerViewFooterDidChangeSize:(CGSize)newSize {
|
|
665
869
|
[self syncFooterMetrics];
|
|
666
870
|
[self setupSheetDetentsForSizeChange];
|
|
667
|
-
[_controller
|
|
871
|
+
[_controller refreshAccessibilityContainer];
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
- (void)containerViewDidMountTransaction {
|
|
875
|
+
[_controller refreshAccessibilityContainerIfFooterChanged];
|
|
668
876
|
}
|
|
669
877
|
|
|
670
878
|
- (void)containerViewPeekDidChangeSize:(CGSize)newSize {
|
|
671
879
|
[self setupSheetDetentsForSizeChange];
|
|
672
880
|
}
|
|
673
881
|
|
|
674
|
-
// When the ScrollView changes (e.g. conditional remount), re-
|
|
882
|
+
// When the ScrollView changes (e.g. conditional remount), re-detect the new ScrollView.
|
|
675
883
|
- (void)containerViewScrollViewDidChange {
|
|
676
884
|
[self setupScrollable];
|
|
677
885
|
}
|
|
@@ -680,11 +888,12 @@ using namespace facebook::react;
|
|
|
680
888
|
|
|
681
889
|
- (void)viewControllerWillPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
682
890
|
_controller.activeDetentIndex = index;
|
|
891
|
+
// Before emitting, so an input focused in onWillPresent raises a tracked keyboard
|
|
892
|
+
[_containerView setupKeyboardObserverWithViewController:_controller];
|
|
683
893
|
[TrueSheetLifecycleEvents emitWillPresent:_eventEmitter index:index position:position detent:detent];
|
|
684
894
|
}
|
|
685
895
|
|
|
686
896
|
- (void)viewControllerDidPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
687
|
-
[_containerView setupKeyboardObserverWithViewController:_controller];
|
|
688
897
|
[TrueSheetLifecycleEvents emitDidPresent:_eventEmitter index:index position:position detent:detent];
|
|
689
898
|
|
|
690
899
|
if (_pendingPropsUpdate) {
|
|
@@ -724,6 +933,10 @@ using namespace facebook::react;
|
|
|
724
933
|
}
|
|
725
934
|
}
|
|
726
935
|
|
|
936
|
+
- (void)viewControllerDidAttemptDismiss {
|
|
937
|
+
[TrueSheetLifecycleEvents emitDismissAttempt:_eventEmitter];
|
|
938
|
+
}
|
|
939
|
+
|
|
727
940
|
- (void)viewControllerDidDismiss {
|
|
728
941
|
[_containerView cleanupKeyboardObserver];
|
|
729
942
|
if (!_dismissedByNavigation) {
|
|
@@ -755,6 +968,7 @@ using namespace facebook::react;
|
|
|
755
968
|
|
|
756
969
|
- (void)viewControllerSafeAreaInsetsDidChange {
|
|
757
970
|
[self refreshFooterBottomInset];
|
|
971
|
+
[_containerView updateFooterKeyboardOffset];
|
|
758
972
|
}
|
|
759
973
|
|
|
760
974
|
- (void)viewControllerWillFocus {
|
|
@@ -822,9 +1036,11 @@ using namespace facebook::react;
|
|
|
822
1036
|
if (!_containerView)
|
|
823
1037
|
return;
|
|
824
1038
|
|
|
825
|
-
_containerView.insetAdjustment = _insetAdjustment;
|
|
826
1039
|
_containerView.scrollableOptions = _scrollableOptions;
|
|
827
|
-
_containerView.
|
|
1040
|
+
_containerView.scrollableHandle = _scrollableHandle;
|
|
1041
|
+
_containerView.safeAreaInsetAdjustment = (_scrollableOptions ? _scrollableOptions.safeAreaInsetAdjustment : YES) &&
|
|
1042
|
+
_insetAdjustment == TrueSheetViewInsetAdjustment::Automatic;
|
|
1043
|
+
_containerView.footerInsetAdjustment = _controller.footerInsetAdjustment;
|
|
828
1044
|
[self refreshFooterBottomInset];
|
|
829
1045
|
[_containerView setupScrollable];
|
|
830
1046
|
}
|
|
@@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
26
26
|
- (void)viewControllerDidPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent;
|
|
27
27
|
- (void)viewControllerWillDismiss;
|
|
28
28
|
- (void)viewControllerDidDismiss;
|
|
29
|
+
- (void)viewControllerDidAttemptDismiss;
|
|
29
30
|
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent;
|
|
30
31
|
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
31
32
|
index:(NSInteger)index
|
|
@@ -54,6 +55,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
54
55
|
|
|
55
56
|
@property (nonatomic, weak, nullable) id<TrueSheetViewControllerDelegate> delegate;
|
|
56
57
|
@property (nonatomic, strong) NSArray<NSNumber *> *detents;
|
|
58
|
+
@property (nonatomic, copy) NSArray<NSDictionary *> *detentBackgrounds;
|
|
57
59
|
@property (nonatomic, strong, nullable) NSNumber *maxContentHeight;
|
|
58
60
|
@property (nonatomic, strong, nullable) NSNumber *maxContentWidth;
|
|
59
61
|
@property (nonatomic, strong, nullable) NSNumber *contentHeight;
|
|
@@ -61,6 +63,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
61
63
|
@property (nonatomic, assign) BOOL absoluteHeader;
|
|
62
64
|
@property (nonatomic, strong, nullable) NSNumber *footerHeight;
|
|
63
65
|
@property (nonatomic, assign) BOOL absoluteFooter;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* YES while the plugged scrollable is padded by the absolute footer's height
|
|
69
|
+
* (see ScrollableOptions.contentInsetAdjustment) — the footer then counts
|
|
70
|
+
* toward the auto detent like a relative one, so the content ends above it.
|
|
71
|
+
*/
|
|
72
|
+
@property (nonatomic, assign) BOOL footerInsetAdjustment;
|
|
64
73
|
@property (nonatomic, strong, nullable) NSNumber *peekContentHeight;
|
|
65
74
|
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
|
|
66
75
|
@property (nonatomic, strong, nullable) NSNumber *cornerRadius;
|
|
@@ -69,15 +78,22 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
69
78
|
@property (nonatomic, assign) facebook::react::TrueSheetViewAccessibilityOptionsStruct accessibilityOptions;
|
|
70
79
|
@property (nonatomic, assign) BOOL draggable;
|
|
71
80
|
@property (nonatomic, assign) BOOL dimmed;
|
|
81
|
+
@property (nonatomic, strong, nullable) UIColor *dimColor;
|
|
82
|
+
@property (nonatomic, strong, nullable) NSNumber *dimOpacity;
|
|
72
83
|
@property (nonatomic, strong, nullable) NSNumber *dimmedDetentIndex;
|
|
73
84
|
@property (nonatomic, assign) facebook::react::TrueSheetViewBackgroundBlur backgroundBlur;
|
|
74
|
-
@property (nonatomic, strong, nullable) NSNumber *blurIntensity;
|
|
75
|
-
@property (nonatomic, assign) BOOL blurInteraction;
|
|
76
85
|
@property (nonatomic, assign) facebook::react::TrueSheetViewPresentation presentation;
|
|
77
|
-
@property (nonatomic, assign) facebook::react::
|
|
86
|
+
@property (nonatomic, assign) facebook::react::TrueSheetViewPlacement placement;
|
|
87
|
+
@property (nonatomic, assign) facebook::react::TrueSheetViewFoldOptionsStruct foldOptions;
|
|
78
88
|
@property (nonatomic, assign) facebook::react::TrueSheetViewInsetAdjustment insetAdjustment;
|
|
79
89
|
@property (nonatomic, assign) BOOL scrollingExpandsSheet;
|
|
80
90
|
@property (nonatomic, assign) CGFloat footerKeyboardOffset;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* NO keeps an absolute footer pinned to the sheet's bottom edge behind the
|
|
94
|
+
* keyboard instead of rising above it.
|
|
95
|
+
*/
|
|
96
|
+
@property (nonatomic, assign) BOOL footerAvoidsKeyboard;
|
|
81
97
|
@property (nonatomic, assign) BOOL dismissible;
|
|
82
98
|
@property (nonatomic, assign) BOOL isPresented;
|
|
83
99
|
@property (nonatomic, assign) NSInteger activeDetentIndex;
|
|
@@ -88,6 +104,19 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
88
104
|
* ~keyboardHeight into the learned offset.
|
|
89
105
|
*/
|
|
90
106
|
@property (nonatomic, assign) BOOL keyboardSheetGrown;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Target keyboard height, set as soon as the keyboard frame change is
|
|
110
|
+
* announced — ahead of the grow/shrink animation, unlike keyboardSheetGrown.
|
|
111
|
+
*/
|
|
112
|
+
@property (nonatomic, assign) CGFloat keyboardHeight;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* How far UIKit grows the sheet for the iPadOS minimized keyboard, which it
|
|
116
|
+
* treats as docked. Taken off every detent so the sheet stays put.
|
|
117
|
+
*/
|
|
118
|
+
@property (nonatomic, assign) CGFloat minimizedKeyboardOverlap;
|
|
119
|
+
|
|
91
120
|
@property (nonatomic, readonly) BOOL isTopmostPresentedController;
|
|
92
121
|
@property (nonatomic, readonly) BOOL isStackedBehindChild;
|
|
93
122
|
@property (nonatomic, weak, nullable) UIView *accessibilityContentView;
|
|
@@ -109,6 +138,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
109
138
|
@property (nonatomic, assign) CGFloat appliedFooterBottomInset;
|
|
110
139
|
|
|
111
140
|
- (void)setupAccessibilityContainer;
|
|
141
|
+
- (void)refreshAccessibilityContainer;
|
|
142
|
+
- (void)refreshAccessibilityContainerIfFooterChanged;
|
|
143
|
+
|
|
112
144
|
- (void)applyActiveDetent;
|
|
113
145
|
- (void)setupActiveDetentWithIndex:(NSInteger)index;
|
|
114
146
|
- (void)resizeToDetentIndex:(NSInteger)index;
|
|
@@ -117,6 +149,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
117
149
|
- (void)setupSheetDetents;
|
|
118
150
|
- (void)setupSheetDetentsForSizeChange;
|
|
119
151
|
- (void)setupSheetDetentsForDetentsChange;
|
|
152
|
+
- (void)invalidateDetents;
|
|
120
153
|
- (void)setupDraggable;
|
|
121
154
|
- (void)setupAnchorViewInView:(UIView *)parentView;
|
|
122
155
|
|