Skip to content

Instantly share code, notes, and snippets.

@barthap
Created July 18, 2022 16:39
Show Gist options
  • Save barthap/cc8412c5dca6232226c097b368930bba to your computer and use it in GitHub Desktop.
Save barthap/cc8412c5dca6232226c097b368930bba to your computer and use it in GitHub Desktop.
RN 0.68 patch to have iOS 15 detents in <Modal> component
diff --git a/node_modules/react-native/Libraries/Modal/Modal.js b/node_modules/react-native/Libraries/Modal/Modal.js
index 9140a56..1a26c51 100644
--- a/node_modules/react-native/Libraries/Modal/Modal.js
+++ b/node_modules/react-native/Libraries/Modal/Modal.js
@@ -246,6 +246,7 @@ class Modal extends React.Component<Props> {
return (
<RCTModalHostView
+ modalSheetSize={this.props.modalSheetSize}
animationType={animationType}
presentationStyle={presentationStyle}
transparent={this.props.transparent}
diff --git a/node_modules/react-native/React/Views/RCTModalHostView.h b/node_modules/react-native/React/Views/RCTModalHostView.h
index 0246328..ef101f9 100644
--- a/node_modules/react-native/React/Views/RCTModalHostView.h
+++ b/node_modules/react-native/React/Views/RCTModalHostView.h
@@ -11,6 +11,12 @@
#import <React/RCTModalHostViewManager.h>
#import <React/RCTView.h>
+typedef NS_ENUM(NSInteger, ModalSheetSize) {
+ ModalSheetLarge = 0,
+ ModalSheetMedium,
+ ModalSheetMediumResizable
+};
+
@class RCTBridge;
@class RCTModalHostViewController;
@@ -20,6 +26,7 @@
@property (nonatomic, copy) NSString *animationType;
@property (nonatomic, assign) UIModalPresentationStyle presentationStyle;
+@property (nonatomic, assign) ModalSheetSize modalSheetSize;
@property (nonatomic, assign, getter=isTransparent) BOOL transparent;
@property (nonatomic, copy) RCTDirectEventBlock onShow;
diff --git a/node_modules/react-native/React/Views/RCTModalHostView.m b/node_modules/react-native/React/Views/RCTModalHostView.m
index 65428a0..a7ac0df 100644
--- a/node_modules/react-native/React/Views/RCTModalHostView.m
+++ b/node_modules/react-native/React/Views/RCTModalHostView.m
@@ -185,6 +185,31 @@ - (void)ensurePresentedOnlyIfNeeded
if (@available(iOS 13.0, *)) {
_modalViewController.presentationController.delegate = self;
}
+ if (@available(iOS 15.0, *)) {
+ if (_modalViewController.sheetPresentationController) {
+ switch (_modalSheetSize) {
+ case ModalSheetLarge:
+ _modalViewController.sheetPresentationController.detents = @[
+ UISheetPresentationControllerDetent.largeDetent
+ ];
+ break;
+ case ModalSheetMedium:
+ _modalViewController.sheetPresentationController.detents = @[
+ UISheetPresentationControllerDetent.mediumDetent
+ ];
+ break;
+ case ModalSheetMediumResizable:
+ _modalViewController.sheetPresentationController.prefersGrabberVisible = true;
+ _modalViewController.sheetPresentationController.largestUndimmedDetentIdentifier =
+ UISheetPresentationControllerDetentIdentifierMedium;
+ _modalViewController.sheetPresentationController.detents = @[
+ UISheetPresentationControllerDetent.mediumDetent,
+ UISheetPresentationControllerDetent.largeDetent
+ ];
+ break;
+ }
+ }
+ }
[_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]];
_isPresented = YES;
}
diff --git a/node_modules/react-native/React/Views/RCTModalHostViewManager.m b/node_modules/react-native/React/Views/RCTModalHostViewManager.m
index 7fab70e..c439406 100644
--- a/node_modules/react-native/React/Views/RCTModalHostViewManager.m
+++ b/node_modules/react-native/React/Views/RCTModalHostViewManager.m
@@ -27,6 +27,12 @@ @implementation RCTConvert (RCTModalHostView)
UIModalPresentationFullScreen,
integerValue)
+RCT_ENUM_CONVERTER(ModalSheetSize, (@{
+ @"large": @(ModalSheetLarge),
+ @"medium": @(ModalSheetMedium),
+ @"mediumResizable": @(ModalSheetMediumResizable),
+}), ModalSheetLarge, integerValue)
+
@end
@interface RCTModalHostShadowView : RCTShadowView
@@ -125,6 +131,7 @@ - (void)invalidate
RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(visible, BOOL)
RCT_EXPORT_VIEW_PROPERTY(onRequestClose, RCTDirectEventBlock)
+RCT_EXPORT_VIEW_PROPERTY(modalSheetSize, ModalSheetSize)
// Fabric only
RCT_EXPORT_VIEW_PROPERTY(onDismiss, RCTDirectEventBlock)
@nandorojo
Copy link

nandorojo commented Sep 28, 2022

Thanks for this @barthap! Here is a patch for @types/react-native too:

@types+react-native+0.67.14.patch

diff --git a/node_modules/@types/react-native/index.d.ts b/node_modules/@types/react-native/index.d.ts
index a20887d..940b7ee 100755
--- a/node_modules/@types/react-native/index.d.ts
+++ b/node_modules/@types/react-native/index.d.ts
@@ -4807,6 +4807,12 @@ export interface ModalBaseProps {
      * @deprecated Use animationType instead
      */
     animated?: boolean | undefined;
+    /**
+     * Add support for iOS detents.
+     * 
+     * Requires this patch: https://gist.github.com/barthap/cc8412c5dca6232226c097b368930bba
+     */
+    modalSheetSize?: 'large' | 'medium' | 'mediumResizable';
     /**
      * The `animationType` prop controls how the modal animates.
      *

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment