diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js index 9f87352219ef2b..bd5010909ab8b4 100644 --- a/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -105,6 +105,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = { borderBottomRightRadius: true, borderBottomStartRadius: true, borderColor: colorAttributes, + borderCurve: true, borderEndColor: colorAttributes, borderLeftColor: colorAttributes, borderRadius: true, diff --git a/Libraries/Components/View/ReactNativeViewViewConfig.js b/Libraries/Components/View/ReactNativeViewViewConfig.js index ff0b6d837e17ad..866cf829573da8 100644 --- a/Libraries/Components/View/ReactNativeViewViewConfig.js +++ b/Libraries/Components/View/ReactNativeViewViewConfig.js @@ -140,6 +140,7 @@ const ReactNativeViewConfig: ViewConfig = { borderBottomStartRadius: true, borderBottomWidth: true, borderColor: {process: require('../../StyleSheet/processColor')}, + borderCurve: true, borderEndColor: {process: require('../../StyleSheet/processColor')}, borderEndWidth: true, borderLeftColor: {process: require('../../StyleSheet/processColor')}, diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js index 5a32873e345643..e65a04175ffd8e 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -559,6 +559,7 @@ export type ____ViewStyle_Internal = $ReadOnly<{| backfaceVisibility?: 'visible' | 'hidden', backgroundColor?: ____ColorValue_Internal, borderColor?: ____ColorValue_Internal, + borderCurve?: 'circular' | 'continuous', borderBottomColor?: ____ColorValue_Internal, borderEndColor?: ____ColorValue_Internal, borderLeftColor?: ____ColorValue_Internal, diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index 1137788402b12b..ec080942b99d66 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -10,6 +10,7 @@ #import #import +#import #import #import #import @@ -130,6 +131,7 @@ typedef BOOL css_backface_visibility_t; + (RCTPointerEvents)RCTPointerEvents:(id)json; + (RCTAnimationType)RCTAnimationType:(id)json; + (RCTBorderStyle)RCTBorderStyle:(id)json; ++ (RCTBorderCurve)RCTBorderCurve:(id)json; + (RCTTextDecorationLineType)RCTTextDecorationLineType:(id)json; @end diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 4b59899560bc07..e366613fcb600a 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -345,6 +345,15 @@ + (NSLocale *)NSLocale:(id)json RCTBorderStyleSolid, integerValue) +RCT_ENUM_CONVERTER( + RCTBorderCurve, + (@{ + @"circular" : @(RCTBorderCurveCircular), + @"continuous" : @(RCTBorderCurveContinuous), + }), + RCTBorderCurveCircular, + integerValue) + RCT_ENUM_CONVERTER( RCTTextDecorationLineType, (@{ diff --git a/React/Views/RCTBorderCurve.h b/React/Views/RCTBorderCurve.h new file mode 100644 index 00000000000000..3b26407067a092 --- /dev/null +++ b/React/Views/RCTBorderCurve.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +typedef NS_ENUM(NSInteger, RCTBorderCurve) { + RCTBorderCurveContinuous = 0, + RCTBorderCurveCircular, +}; diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index 799e60a0793747..160336d750eed1 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -9,6 +9,7 @@ #import "RCTAssert.h" #import "RCTBorderStyle.h" +#import "RCTBorderCurve.h" #import "RCTBridge.h" #import "RCTConvert+Transform.h" #import "RCTConvert.h" @@ -259,6 +260,19 @@ - (RCTShadowView *)shadowView view.removeClippedSubviews = json ? [RCTConvert BOOL:json] : defaultView.removeClippedSubviews; } } +RCT_CUSTOM_VIEW_PROPERTY(borderCurve, RCTBorderCurve, RCTView) +{ + if (@available(iOS 13.0, *)) { + switch ([RCTConvert RCTBorderCurve:json]) { + case RCTBorderCurveContinuous: + view.layer.cornerCurve = kCACornerCurveContinuous; + break; + case RCTBorderCurveCircular: + view.layer.cornerCurve = kCACornerCurveCircular; + break; + } + } +} RCT_CUSTOM_VIEW_PROPERTY(borderRadius, CGFloat, RCTView) { if ([view respondsToSelector:@selector(setBorderRadius:)]) { diff --git a/packages/rn-tester/js/examples/View/ViewExample.js b/packages/rn-tester/js/examples/View/ViewExample.js index dee2a5947b9a49..3a767a62412a2a 100644 --- a/packages/rn-tester/js/examples/View/ViewExample.js +++ b/packages/rn-tester/js/examples/View/ViewExample.js @@ -17,6 +17,7 @@ const { Text, TouchableWithoutFeedback, View, + Platform, } = require('react-native'); exports.title = 'View'; @@ -81,12 +82,29 @@ exports.examples = [ title: 'Border Radius', render(): React.Node { return ( - - - Too much use of `borderRadius` (especially large radii) on anything - which is scrolling may result in dropped frames. Use sparingly. - - + <> + + + Too much use of `borderRadius` (especially large radii) on + anything which is scrolling may result in dropped frames. Use + sparingly. + + + {Platform.OS === 'ios' && ( + + + View with continuous border curve + + + )} + ); }, },