From 65a3ac189d3bffe30f629ed94d9b447afafa94c6 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Tue, 1 Aug 2023 15:55:06 +0200 Subject: [PATCH 01/73] Add PoC --- ios/RNSScreen.h | 1 + ios/RNSScreen.mm | 88 +++++++++++++++------- src/index.native.tsx | 4 + src/native-stack/views/NativeStackView.tsx | 2 + 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index f1bd9d8175..e0ab5041cc 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -90,6 +90,7 @@ namespace react = facebook::react; @property (nonatomic) BOOL sheetGrabberVisible; @property (nonatomic) CGFloat sheetCornerRadius; @property (nonatomic) BOOL sheetExpandsWhenScrolledToEdge; +@property (nonatomic) NSArray *sheetHeight; #endif // !TARGET_OS_TV #ifdef RCT_NEW_ARCH_ENABLED diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 740d48c738..c7ced4ee6b 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -88,6 +88,7 @@ - (void)initCommonProps _hasHomeIndicatorHiddenSet = NO; #if !TARGET_OS_TV _sheetExpandsWhenScrolledToEdge = YES; + _sheetHeight = @[ @0.5, @0.7 ]; #endif // !TARGET_OS_TV } @@ -608,7 +609,24 @@ - (void)updatePresentationStyle { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_15_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0 + if (@available(iOS 15.0, *)) { + NSMutableArray)> *resolvers = + [NSMutableArray arrayWithCapacity:self->_sheetHeight.count]; + for (NSNumber *val in self->_sheetHeight) { + [resolvers addObject:^CGFloat(id ctx) { + return ctx.maximumDetentValue * val.floatValue; + }]; + } + + // CGFloat (^resolver)(id) = ^ CGFloat + // (id _ctx) { + // return _ctx.maximumDetentValue * self->_sheetHeight; + // }; + + // UISheetPresentationControllerDetent *customDetent = [UISheetPresentationControllerDetent + // customDetentWithIdentifier:@"customDetent" resolver:resolver]; + UISheetPresentationController *sheet = _controller.sheetPresentationController; if (_stackPresentation == RNSScreenStackPresentationFormSheet && sheet != nil) { sheet.prefersScrollingExpandsWhenScrolledToEdge = _sheetExpandsWhenScrolledToEdge; @@ -616,36 +634,49 @@ - (void)updatePresentationStyle sheet.preferredCornerRadius = _sheetCornerRadius < 0 ? UISheetPresentationControllerAutomaticDimension : _sheetCornerRadius; - if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeMedium) { - sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; - } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeLarge) { - sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; - } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeAll) { - sheet.largestUndimmedDetentIdentifier = nil; - } else { - RCTLogError(@"Unhandled value of sheetLargestUndimmedDetent passed"); - } + sheet.largestUndimmedDetentIdentifier = nil; - if (_sheetAllowedDetents == RNSScreenDetentTypeMedium) { - sheet.detents = @[ UISheetPresentationControllerDetent.mediumDetent ]; - if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierMedium) { - [sheet animateChanges:^{ - sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; - }]; - } - } else if (_sheetAllowedDetents == RNSScreenDetentTypeLarge) { - sheet.detents = @[ UISheetPresentationControllerDetent.largeDetent ]; - if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierLarge) { - [sheet animateChanges:^{ - sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; - }]; - } - } else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) { - sheet.detents = - @[ UISheetPresentationControllerDetent.mediumDetent, UISheetPresentationControllerDetent.largeDetent ]; - } else { - RCTLogError(@"Unhandled value of sheetAllowedDetents passed"); + NSMutableArray *customDetents = + [NSMutableArray arrayWithCapacity:resolvers.count]; + for (NSInteger i = 0; i < resolvers.count; ++i) { + const auto &resolver = resolvers[i]; + [customDetents addObject:[UISheetPresentationControllerDetent customDetentWithIdentifier:nil + resolver:resolver]]; } + sheet.detents = customDetents; + + // sheet.detents = @[ customDetent ]; + // if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeMedium) { + // sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + // } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeLarge) { + // sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + // } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeAll) { + // sheet.largestUndimmedDetentIdentifier = nil; + // } else { + // RCTLogError(@"Unhandled value of sheetLargestUndimmedDetent passed"); + // } + // + // if (_sheetAllowedDetents == RNSScreenDetentTypeMedium) { + // sheet.detents = @[ UISheetPresentationControllerDetent.mediumDetent ]; + // if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierMedium) { + // [sheet animateChanges:^{ + // sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + // }]; + // } + // } else if (_sheetAllowedDetents == RNSScreenDetentTypeLarge) { + // sheet.detents = @[ UISheetPresentationControllerDetent.largeDetent ]; + // if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierLarge) { + // [sheet animateChanges:^{ + // sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + // }]; + // } + // } else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) { + // sheet.detents = + // @[ UISheetPresentationControllerDetent.mediumDetent, UISheetPresentationControllerDetent.largeDetent + // ]; + // } else { + // RCTLogError(@"Unhandled value of sheetAllowedDetents passed"); + // } } } #endif // Check for max allowed iOS version @@ -1475,6 +1506,7 @@ @implementation RNSScreenManager RCT_EXPORT_VIEW_PROPERTY(sheetGrabberVisible, BOOL); RCT_EXPORT_VIEW_PROPERTY(sheetCornerRadius, CGFloat); RCT_EXPORT_VIEW_PROPERTY(sheetExpandsWhenScrolledToEdge, BOOL); +RCT_EXPORT_VIEW_PROPERTY(sheetHeight, NSArray *); #endif #if !TARGET_OS_TV diff --git a/src/index.native.tsx b/src/index.native.tsx index a51898a853..ec5dfe7af7 100644 --- a/src/index.native.tsx +++ b/src/index.native.tsx @@ -271,6 +271,7 @@ class InnerScreen extends React.Component { sheetGrabberVisible = false, sheetCornerRadius = -1.0, sheetExpandsWhenScrolledToEdge = true, + sheetHeight = [0.5, 0.7], } = rest; if (enabled && isPlatformSupported) { @@ -308,6 +309,8 @@ class InnerScreen extends React.Component { } }; + console.log('[JS] sheetHeight: ', sheetHeight); + return ( { sheetGrabberVisible={sheetGrabberVisible} sheetCornerRadius={sheetCornerRadius} sheetExpandsWhenScrolledToEdge={sheetExpandsWhenScrolledToEdge} + sheetHeight={sheetHeight} gestureResponseDistance={{ start: gestureResponseDistance?.start ?? -1, end: gestureResponseDistance?.end ?? -1, diff --git a/src/native-stack/views/NativeStackView.tsx b/src/native-stack/views/NativeStackView.tsx index 6e75c79d1d..20d786720a 100644 --- a/src/native-stack/views/NativeStackView.tsx +++ b/src/native-stack/views/NativeStackView.tsx @@ -177,6 +177,7 @@ const RouteView = ({ sheetGrabberVisible = false, sheetCornerRadius = -1.0, sheetExpandsWhenScrolledToEdge = true, + sheetHeight = [0.5, 0.7], nativeBackButtonDismissalEnabled = false, navigationBarColor, navigationBarHidden, @@ -275,6 +276,7 @@ const RouteView = ({ sheetGrabberVisible={sheetGrabberVisible} sheetCornerRadius={sheetCornerRadius} sheetExpandsWhenScrolledToEdge={sheetExpandsWhenScrolledToEdge} + sheetHeight={sheetHeight} customAnimationOnSwipe={customAnimationOnSwipe} freezeOnBlur={freezeOnBlur} fullScreenSwipeEnabled={fullScreenSwipeEnabled} From 894c45a3ca4365951e335d46f704d27d4871c641 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 08:27:11 +0200 Subject: [PATCH 02/73] Reorganise native code & rename the prop to sheetCustomDetents --- ios/RNSEnums.h | 1 + ios/RNSScreen.h | 2 +- ios/RNSScreen.mm | 125 ++++++++++++++++++++++++----------------------- 3 files changed, 66 insertions(+), 62 deletions(-) diff --git a/ios/RNSEnums.h b/ios/RNSEnums.h index 1895f447ec..e9378136fb 100644 --- a/ios/RNSEnums.h +++ b/ios/RNSEnums.h @@ -61,6 +61,7 @@ typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { typedef NS_ENUM(NSInteger, RNSScreenDetentType) { RNSScreenDetentTypeMedium, RNSScreenDetentTypeLarge, + RNSScreenDetentTypeCustom, RNSScreenDetentTypeAll, }; diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index e0ab5041cc..0dab05f793 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -90,7 +90,7 @@ namespace react = facebook::react; @property (nonatomic) BOOL sheetGrabberVisible; @property (nonatomic) CGFloat sheetCornerRadius; @property (nonatomic) BOOL sheetExpandsWhenScrolledToEdge; -@property (nonatomic) NSArray *sheetHeight; +@property (nonatomic) NSArray *sheetCustomDetents; #endif // !TARGET_OS_TV #ifdef RCT_NEW_ARCH_ENABLED diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index c7ced4ee6b..aba74f907b 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -88,7 +88,7 @@ - (void)initCommonProps _hasHomeIndicatorHiddenSet = NO; #if !TARGET_OS_TV _sheetExpandsWhenScrolledToEdge = YES; - _sheetHeight = @[ @0.5, @0.7 ]; + _sheetCustomDetents = [NSArray array]; #endif // !TARGET_OS_TV } @@ -609,24 +609,7 @@ - (void)updatePresentationStyle { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_15_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0 - if (@available(iOS 15.0, *)) { - NSMutableArray)> *resolvers = - [NSMutableArray arrayWithCapacity:self->_sheetHeight.count]; - for (NSNumber *val in self->_sheetHeight) { - [resolvers addObject:^CGFloat(id ctx) { - return ctx.maximumDetentValue * val.floatValue; - }]; - } - - // CGFloat (^resolver)(id) = ^ CGFloat - // (id _ctx) { - // return _ctx.maximumDetentValue * self->_sheetHeight; - // }; - - // UISheetPresentationControllerDetent *customDetent = [UISheetPresentationControllerDetent - // customDetentWithIdentifier:@"customDetent" resolver:resolver]; - UISheetPresentationController *sheet = _controller.sheetPresentationController; if (_stackPresentation == RNSScreenStackPresentationFormSheet && sheet != nil) { sheet.prefersScrollingExpandsWhenScrolledToEdge = _sheetExpandsWhenScrolledToEdge; @@ -634,53 +617,72 @@ - (void)updatePresentationStyle sheet.preferredCornerRadius = _sheetCornerRadius < 0 ? UISheetPresentationControllerAutomaticDimension : _sheetCornerRadius; - sheet.largestUndimmedDetentIdentifier = nil; + if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeMedium) { + sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeLarge) { + sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeAll) { + sheet.largestUndimmedDetentIdentifier = nil; + } else { + RCTLogError(@"Unhandled value of sheetLargestUndimmedDetent passed"); + } + + NSMutableArray *detents = [NSMutableArray array]; - NSMutableArray *customDetents = - [NSMutableArray arrayWithCapacity:resolvers.count]; - for (NSInteger i = 0; i < resolvers.count; ++i) { - const auto &resolver = resolvers[i]; - [customDetents addObject:[UISheetPresentationControllerDetent customDetentWithIdentifier:nil - resolver:resolver]]; + if (_sheetAllowedDetents == RNSScreenDetentTypeMedium) { + sheet.detents = @[ UISheetPresentationControllerDetent.mediumDetent ]; + if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierMedium) { + [sheet animateChanges:^{ + sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + }]; + } + } else if (_sheetAllowedDetents == RNSScreenDetentTypeLarge) { + sheet.detents = @[ UISheetPresentationControllerDetent.largeDetent ]; + if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierLarge) { + [sheet animateChanges:^{ + sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + }]; + } + } +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \ + __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0 + else if (_sheetAllowedDetents == RNSScreenDetentTypeCustom) { + if (@available(iOS 16.0, *)) { + [detents addObjectsFromArray:[self detentsFromSnapPoints]]; + sheet.detents = detents; + } + } +#endif // Check for iOS >= 16 + else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) { + [detents addObjectsFromArray:[self detentsFromSnapPoints]]; + [detents addObjectsFromArray:@[ + UISheetPresentationControllerDetent.mediumDetent, + UISheetPresentationControllerDetent.largeDetent + ]]; + sheet.detents = detents; + } else { + RCTLogError(@"Unhandled value of sheetAllowedDetents passed"); } - sheet.detents = customDetents; - - // sheet.detents = @[ customDetent ]; - // if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeMedium) { - // sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; - // } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeLarge) { - // sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; - // } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeAll) { - // sheet.largestUndimmedDetentIdentifier = nil; - // } else { - // RCTLogError(@"Unhandled value of sheetLargestUndimmedDetent passed"); - // } - // - // if (_sheetAllowedDetents == RNSScreenDetentTypeMedium) { - // sheet.detents = @[ UISheetPresentationControllerDetent.mediumDetent ]; - // if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierMedium) { - // [sheet animateChanges:^{ - // sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; - // }]; - // } - // } else if (_sheetAllowedDetents == RNSScreenDetentTypeLarge) { - // sheet.detents = @[ UISheetPresentationControllerDetent.largeDetent ]; - // if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierLarge) { - // [sheet animateChanges:^{ - // sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; - // }]; - // } - // } else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) { - // sheet.detents = - // @[ UISheetPresentationControllerDetent.mediumDetent, UISheetPresentationControllerDetent.largeDetent - // ]; - // } else { - // RCTLogError(@"Unhandled value of sheetAllowedDetents passed"); - // } } } -#endif // Check for max allowed iOS version +#endif // Check for iOS >= 15 } + +- (NSArray *)detentsFromSnapPoints API_AVAILABLE(ios(16.0)) +{ + NSMutableArray *customDetents = + [NSMutableArray arrayWithCapacity:_sheetCustomDetents.count]; + for (NSNumber *val in _sheetCustomDetents) { + [customDetents addObject:[UISheetPresentationControllerDetent + customDetentWithIdentifier:nil + resolver:^CGFloat( + id ctx) { + return ctx.maximumDetentValue * val.floatValue; + }]]; + } + return customDetents; +} + #endif // !TARGET_OS_TV #pragma mark - Fabric specific @@ -1506,7 +1508,7 @@ @implementation RNSScreenManager RCT_EXPORT_VIEW_PROPERTY(sheetGrabberVisible, BOOL); RCT_EXPORT_VIEW_PROPERTY(sheetCornerRadius, CGFloat); RCT_EXPORT_VIEW_PROPERTY(sheetExpandsWhenScrolledToEdge, BOOL); -RCT_EXPORT_VIEW_PROPERTY(sheetHeight, NSArray *); +RCT_EXPORT_VIEW_PROPERTY(sheetCustomDetents, NSArray *); #endif #if !TARGET_OS_TV @@ -1625,6 +1627,7 @@ @implementation RCTConvert (RNSScreen) (@{ @"large" : @(RNSScreenDetentTypeLarge), @"medium" : @(RNSScreenDetentTypeMedium), + @"custom" : @(RNSScreenDetentTypeCustom), @"all" : @(RNSScreenDetentTypeAll), }), RNSScreenDetentTypeAll, From d04c3541a7e75d09540302ad6665589f10dfbf7d Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 08:28:26 +0200 Subject: [PATCH 03/73] Set default for `sheetCustomDetents` in `InnerScreen` --- src/index.native.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.native.tsx b/src/index.native.tsx index ec5dfe7af7..4c94839405 100644 --- a/src/index.native.tsx +++ b/src/index.native.tsx @@ -271,7 +271,7 @@ class InnerScreen extends React.Component { sheetGrabberVisible = false, sheetCornerRadius = -1.0, sheetExpandsWhenScrolledToEdge = true, - sheetHeight = [0.5, 0.7], + sheetCustomDetents = [], } = rest; if (enabled && isPlatformSupported) { @@ -321,7 +321,7 @@ class InnerScreen extends React.Component { sheetGrabberVisible={sheetGrabberVisible} sheetCornerRadius={sheetCornerRadius} sheetExpandsWhenScrolledToEdge={sheetExpandsWhenScrolledToEdge} - sheetHeight={sheetHeight} + sheetCustomDetents={sheetCustomDetents} gestureResponseDistance={{ start: gestureResponseDistance?.start ?? -1, end: gestureResponseDistance?.end ?? -1, From 1f9499efb82688a68265b7382b5dd3e9f78c146a Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 08:32:46 +0200 Subject: [PATCH 04/73] Pass the new prop through NativeStackView --- src/native-stack/views/NativeStackView.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/native-stack/views/NativeStackView.tsx b/src/native-stack/views/NativeStackView.tsx index 20d786720a..de852fb1d3 100644 --- a/src/native-stack/views/NativeStackView.tsx +++ b/src/native-stack/views/NativeStackView.tsx @@ -167,6 +167,7 @@ const RouteView = ({ stateKey: string; }) => { const { options, render: renderScene } = descriptors[route.key]; + const { gestureEnabled, headerShown, @@ -177,7 +178,7 @@ const RouteView = ({ sheetGrabberVisible = false, sheetCornerRadius = -1.0, sheetExpandsWhenScrolledToEdge = true, - sheetHeight = [0.5, 0.7], + sheetCustomDetents = [], nativeBackButtonDismissalEnabled = false, navigationBarColor, navigationBarHidden, @@ -276,7 +277,7 @@ const RouteView = ({ sheetGrabberVisible={sheetGrabberVisible} sheetCornerRadius={sheetCornerRadius} sheetExpandsWhenScrolledToEdge={sheetExpandsWhenScrolledToEdge} - sheetHeight={sheetHeight} + sheetCustomDetents={sheetCustomDetents} customAnimationOnSwipe={customAnimationOnSwipe} freezeOnBlur={freezeOnBlur} fullScreenSwipeEnabled={fullScreenSwipeEnabled} From 0fcad0611db837d5761edb100eb41f0cf7aa63a9 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 08:33:19 +0200 Subject: [PATCH 05/73] Remove debug logging --- src/index.native.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/index.native.tsx b/src/index.native.tsx index 4c94839405..3c1b575f8c 100644 --- a/src/index.native.tsx +++ b/src/index.native.tsx @@ -309,8 +309,6 @@ class InnerScreen extends React.Component { } }; - console.log('[JS] sheetHeight: ', sheetHeight); - return ( Date: Wed, 2 Aug 2023 08:33:43 +0200 Subject: [PATCH 06/73] Add stubs for type documentation --- src/native-stack/types.tsx | 4 ++++ src/types.tsx | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/native-stack/types.tsx b/src/native-stack/types.tsx index 261af8b02c..9ac945c6aa 100644 --- a/src/native-stack/types.tsx +++ b/src/native-stack/types.tsx @@ -357,6 +357,10 @@ export type NativeStackNavigationOptions = { * @platform ios */ sheetCornerRadius?: number; + /** + * TODO + */ + sheetCustomDetents?: number[]; /** * Boolean indicating whether the sheet shows a grabber at the top. * Works only when `stackPresentation` is set to `formSheet`. diff --git a/src/types.tsx b/src/types.tsx index 46e633b61f..9231e05fd9 100644 --- a/src/types.tsx +++ b/src/types.tsx @@ -286,6 +286,10 @@ export interface ScreenProps extends ViewProps { * @platform ios */ sheetCornerRadius?: number; + /** + * TODO + */ + sheetCustomDetents?: number[]; /** * Boolean indicating whether the sheet shows a grabber at the top. * Works only when `stackPresentation` is set to `formSheet`. From 9c2636f9d1e27a876fcecd146c3d7bf311861d86 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 09:01:01 +0200 Subject: [PATCH 07/73] Cleanup native code a bit --- ios/RNSScreen.mm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index aba74f907b..38c451a77e 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -627,8 +627,6 @@ - (void)updatePresentationStyle RCTLogError(@"Unhandled value of sheetLargestUndimmedDetent passed"); } - NSMutableArray *detents = [NSMutableArray array]; - if (_sheetAllowedDetents == RNSScreenDetentTypeMedium) { sheet.detents = @[ UISheetPresentationControllerDetent.mediumDetent ]; if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierMedium) { @@ -643,22 +641,24 @@ - (void)updatePresentationStyle sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; }]; } - } + } else if (_sheetAllowedDetents == RNSScreenDetentTypeCustom) { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0 - else if (_sheetAllowedDetents == RNSScreenDetentTypeCustom) { if (@available(iOS 16.0, *)) { - [detents addObjectsFromArray:[self detentsFromSnapPoints]]; - sheet.detents = detents; + sheet.detents = [self detentsFromSnapPoints]; } - } #endif // Check for iOS >= 16 - else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) { - [detents addObjectsFromArray:[self detentsFromSnapPoints]]; - [detents addObjectsFromArray:@[ + } else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) { + NSMutableArray *detents = [NSMutableArray arrayWithArray:@[ UISheetPresentationControllerDetent.mediumDetent, - UISheetPresentationControllerDetent.largeDetent + UISheetPresentationControllerDetent.largeDetent, ]]; +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \ + __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0 + if (@available(iOS 16.0, *)) { + [detents addObjectsFromArray:[self detentsFromSnapPoints]]; + } +#endif // Check for iOS >= 16 sheet.detents = detents; } else { RCTLogError(@"Unhandled value of sheetAllowedDetents passed"); From 1ce34bcc27ae1d402a847a791be287f679bc0f2b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 09:03:56 +0200 Subject: [PATCH 08/73] Rename updatePresentationStyle to updateFormSheetPresentationStyle So that the method's name better describes its purpose --- ios/RNSScreen.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 38c451a77e..1f2fd54fb7 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -605,7 +605,7 @@ - (BOOL)isTransparentModal * Note that this method should not be called inside `stackPresentation` setter, because on Paper we don't have * guarantee that values of all related props had been updated earlier. */ -- (void)updatePresentationStyle +- (void)updateFormSheetPresentationStyle { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_15_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0 @@ -849,7 +849,7 @@ - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask { [super finalizeUpdates:updateMask]; #if !TARGET_OS_TV - [self updatePresentationStyle]; + [self updateFormSheetPresentationStyle]; #endif // !TARGET_OS_TV } @@ -860,7 +860,7 @@ - (void)didSetProps:(NSArray *)changedProps { [super didSetProps:changedProps]; #if !TARGET_OS_TV - [self updatePresentationStyle]; + [self updateFormSheetPresentationStyle]; #endif // !TARGET_OS_TV } From 3db72e7d40c85512f446af6cd01abb1a8e9b94c3 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 12:45:36 +0200 Subject: [PATCH 09/73] Add dev dependency on `jotai` Test example was much more easier to write with some kind of state management library. --- TestsExample/package.json | 1 + TestsExample/yarn.lock | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/TestsExample/package.json b/TestsExample/package.json index 667e2d411f..b69aebc329 100644 --- a/TestsExample/package.json +++ b/TestsExample/package.json @@ -38,6 +38,7 @@ "eslint": "^8.19.0", "jest": "^29.2.1", "metro-react-native-babel-preset": "0.76.8", + "jotai": "^2.2.3", "prettier": "^2.4.1", "react-test-renderer": "18.2.0", "typescript": "4.8.4" diff --git a/TestsExample/yarn.lock b/TestsExample/yarn.lock index b4005a8d62..2b13153951 100644 --- a/TestsExample/yarn.lock +++ b/TestsExample/yarn.lock @@ -4563,6 +4563,11 @@ joi@^17.2.1: "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" +jotai@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/jotai/-/jotai-2.2.3.tgz#4dd9f429e9cd23d81f08a6b1492931db05ccf79f" + integrity sha512-E3tTBb2CKwjAJKUJYVV6rKM8zxmpsPMedRclRnI2RgLzkvgDEH6mhtZPVesxIoixJ8p7949RWd8eo/8TqDDFDA== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" From b34b6e5dd88a5d9573cf7ca64c22c96e8205d72d Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 2 Aug 2023 12:49:51 +0200 Subject: [PATCH 10/73] Refactor test example using `jotai` --- TestsExample/src/Test1649.tsx | 190 +++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 60 deletions(-) diff --git a/TestsExample/src/Test1649.tsx b/TestsExample/src/Test1649.tsx index 2822c809ee..f50a53785a 100644 --- a/TestsExample/src/Test1649.tsx +++ b/TestsExample/src/Test1649.tsx @@ -1,5 +1,12 @@ import * as React from 'react'; -import { Button, StyleSheet, View, Text, ScrollView } from 'react-native'; +import { + Button, + StyleSheet, + View, + Text, + ScrollView, + TextInput, +} from 'react-native'; import { NavigationContainer, ParamListBase } from '@react-navigation/native'; import { createNativeStackNavigator, @@ -7,17 +14,56 @@ import { NativeStackNavigationOptions, } from 'react-native-screens/native-stack'; import { SheetDetentTypes } from 'react-native-screens'; +import * as jotai from 'jotai'; + +type NavProp = { + navigation: NativeStackNavigationProp; +}; + +type SheetOptions = { + sheetAllowedDetents: SheetDetentTypes; + sheetLargestUndimmedDetent: SheetDetentTypes; + sheetGrabberVisible: boolean; + sheetCornerRadius: number; + sheetExpandsWhenScrolledToEdge: boolean; + sheetCustomDetents: number[]; +}; const Stack = createNativeStackNavigator(); +/// Sheet options +const allowedDetentsAtom = jotai.atom('custom'); +const largestUndimmedDetentAtom = jotai.atom('medium'); +const grabberVisibleAtom = jotai.atom(false); +const cornerRadiusAtom = jotai.atom(-1); +const expandsWhenScrolledToEdgeAtom = jotai.atom(false); +const customDetentsAtom = jotai.atom([0.3, 0.6, 0.85]); + +const sheetOptionsAtom = jotai.atom( + get => ({ + sheetAllowedDetents: get(allowedDetentsAtom), + sheetLargestUndimmedDetent: get(largestUndimmedDetentAtom), + sheetGrabberVisible: get(grabberVisibleAtom), + sheetCornerRadius: get(cornerRadiusAtom), + sheetExpandsWhenScrolledToEdge: get(expandsWhenScrolledToEdgeAtom), + sheetCustomDetents: get(customDetentsAtom), + }), + (_get, set, value: SheetOptions) => { + set(allowedDetentsAtom, value.sheetAllowedDetents); + set(largestUndimmedDetentAtom, value.sheetLargestUndimmedDetent); + set(grabberVisibleAtom, value.sheetGrabberVisible); + set(cornerRadiusAtom, value.sheetCornerRadius); + set(expandsWhenScrolledToEdgeAtom, value.sheetExpandsWhenScrolledToEdge); + set(customDetentsAtom, value.sheetCustomDetents); + }, +); + export default function App(): JSX.Element { + const sheetOptions = jotai.useAtomValue(sheetOptionsAtom); + const initialScreenOptions: NativeStackNavigationOptions = { stackPresentation: 'formSheet', - sheetAllowedDetents: 'all', - sheetLargestUndimmedDetent: 'medium', - sheetGrabberVisible: false, - sheetCornerRadius: -1, - sheetExpandsWhenScrolledToEdge: true, + ...sheetOptions, }; return ( @@ -31,7 +77,7 @@ export default function App(): JSX.Element { headerShown: true, headerHideBackButton: false, }}> - + + ); } -function First({ - navigation, -}: { - navigation: NativeStackNavigationProp; -}) { +function Home({ navigation }: NavProp) { return (