feat: Add logical border radius implementation (#35572)

Summary:
This PR implements logical border-radius as requested on https://github.com/facebook/react-native/issues/34425. This implementation includes the addition of the following style properties

- `borderEndEndRadius`, equivalent to `borderBottomEndRadius`.
- `borderEndStartRadius`, equivalent to `borderBottomStartRadius`.
- `borderStartEndRadius`, equivalent to `borderTopEndRadius`.
- `borderStartStartRadius`, equivalent to `borderTopStartRadius`.

## Changelog

[GENERAL] [ADDED] - Add logical border-radius implementation

Pull Request resolved: https://github.com/facebook/react-native/pull/35572

Test Plan:
1. Open the RNTester app and navigate to the `RTLExample` page
2. Test the new style properties through the `Logical Border Radii Start/End` section

https://user-images.githubusercontent.com/11707729/206623732-6d542347-93f9-40da-be97-f7dcd5f66ca9.mov

Reviewed By: necolas

Differential Revision: D42002043

Pulled By: NickGerleman

fbshipit-source-id: a0aa9783c280398b437aeb7a00c6eb3f767657a5
This commit is contained in:
Gabriel Donadel Dall'Agnol
2023-01-06 06:00:03 -08:00
committed by Facebook GitHub Bot
parent 66927ec3aa
commit 4ae4984094
20 changed files with 234 additions and 32 deletions
@@ -391,11 +391,15 @@ const SUPPORTED_STYLES = {
borderBottomLeftRadius: true,
borderBottomRightRadius: true,
borderBottomStartRadius: true,
borderEndEndRadius: true,
borderEndStartRadius: true,
borderRadius: true,
borderTopEndRadius: true,
borderTopLeftRadius: true,
borderTopRightRadius: true,
borderTopStartRadius: true,
borderStartEndRadius: true,
borderStartStartRadius: true,
elevation: true,
opacity: true,
transform: true,
@@ -125,10 +125,14 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
borderColor: colorAttributes,
borderCurve: true,
borderEndColor: colorAttributes,
borderEndEndRadius: true,
borderEndStartRadius: true,
borderLeftColor: colorAttributes,
borderRadius: true,
borderRightColor: colorAttributes,
borderStartColor: colorAttributes,
borderStartEndRadius: true,
borderStartStartRadius: true,
borderStyle: true,
borderTopColor: colorAttributes,
borderTopEndRadius: true,
@@ -45,7 +45,10 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
borderTopEndRadius: true,
borderBottomStartRadius: true,
borderBottomEndRadius: true,
borderEndEndRadius: true,
borderEndStartRadius: true,
borderStartEndRadius: true,
borderStartStartRadius: true,
borderStyle: true,
hitSlop: true,
pointerEvents: true,
@@ -221,6 +221,10 @@ const validAttributesForNonEventProps = {
borderBottomRightRadius: true,
borderBottomStartRadius: true,
borderBottomEndRadius: true,
borderEndEndRadius: true,
borderEndStartRadius: true,
borderStartEndRadius: true,
borderStartStartRadius: true,
display: true,
zIndex: true,
+4
View File
@@ -240,12 +240,16 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
borderBottomWidth?: number | undefined;
borderColor?: ColorValue | undefined;
borderEndColor?: ColorValue | undefined;
borderEndEndRadius?: number | undefined;
borderEndStartRadius?: number | undefined;
borderLeftColor?: ColorValue | undefined;
borderLeftWidth?: number | undefined;
borderRadius?: number | undefined;
borderRightColor?: ColorValue | undefined;
borderRightWidth?: number | undefined;
borderStartColor?: ColorValue | undefined;
borderStartEndRadius?: number | undefined;
borderStartStartRadius?: number | undefined;
borderStyle?: 'solid' | 'dotted' | 'dashed' | undefined;
borderTopColor?: ColorValue | undefined;
borderTopEndRadius?: number | undefined;
+4
View File
@@ -703,6 +703,10 @@ export type ____ViewStyle_InternalCore = $ReadOnly<{
borderBottomLeftRadius?: number | AnimatedNode,
borderBottomRightRadius?: number | AnimatedNode,
borderBottomStartRadius?: number | AnimatedNode,
borderEndEndRadius?: number | AnimatedNode,
borderEndStartRadius?: number | AnimatedNode,
borderStartEndRadius?: number | AnimatedNode,
borderStartStartRadius?: number | AnimatedNode,
borderTopEndRadius?: number | AnimatedNode,
borderTopLeftRadius?: number | AnimatedNode,
borderTopRightRadius?: number | AnimatedNode,
+4
View File
@@ -71,6 +71,10 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
@property (nonatomic, assign) CGFloat borderBottomRightRadius;
@property (nonatomic, assign) CGFloat borderBottomStartRadius;
@property (nonatomic, assign) CGFloat borderBottomEndRadius;
@property (nonatomic, assign) CGFloat borderEndEndRadius;
@property (nonatomic, assign) CGFloat borderEndStartRadius;
@property (nonatomic, assign) CGFloat borderStartEndRadius;
@property (nonatomic, assign) CGFloat borderStartStartRadius;
/**
* Border colors (actually retained).
+22 -12
View File
@@ -128,6 +128,10 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
_borderBottomRightRadius = -1;
_borderBottomStartRadius = -1;
_borderBottomEndRadius = -1;
_borderEndEndRadius = -1;
_borderEndStartRadius = -1;
_borderStartEndRadius = -1;
_borderStartStartRadius = -1;
_borderCurve = RCTBorderCurveCircular;
_borderStyle = RCTBorderStyleSolid;
_hitTestEdgeInsets = UIEdgeInsetsZero;
@@ -667,11 +671,16 @@ static CGFloat RCTDefaultIfNegativeTo(CGFloat defaultValue, CGFloat x)
CGFloat bottomLeftRadius;
CGFloat bottomRightRadius;
const CGFloat logicalTopStartRadius = RCTDefaultIfNegativeTo(_borderStartStartRadius, _borderTopStartRadius);
const CGFloat logicalTopEndRadius = RCTDefaultIfNegativeTo(_borderStartEndRadius, _borderTopEndRadius);
const CGFloat logicalBottomStartRadius = RCTDefaultIfNegativeTo(_borderEndStartRadius, _borderBottomStartRadius);
const CGFloat logicalBottomEndRadius = RCTDefaultIfNegativeTo(_borderEndEndRadius, _borderBottomEndRadius);
if ([[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]) {
const CGFloat topStartRadius = RCTDefaultIfNegativeTo(_borderTopLeftRadius, _borderTopStartRadius);
const CGFloat topEndRadius = RCTDefaultIfNegativeTo(_borderTopRightRadius, _borderTopEndRadius);
const CGFloat bottomStartRadius = RCTDefaultIfNegativeTo(_borderBottomLeftRadius, _borderBottomStartRadius);
const CGFloat bottomEndRadius = RCTDefaultIfNegativeTo(_borderBottomRightRadius, _borderBottomEndRadius);
const CGFloat topStartRadius = RCTDefaultIfNegativeTo(_borderTopLeftRadius, logicalTopStartRadius);
const CGFloat topEndRadius = RCTDefaultIfNegativeTo(_borderTopRightRadius, logicalTopEndRadius);
const CGFloat bottomStartRadius = RCTDefaultIfNegativeTo(_borderBottomLeftRadius, logicalBottomStartRadius);
const CGFloat bottomEndRadius = RCTDefaultIfNegativeTo(_borderBottomRightRadius, logicalBottomEndRadius);
const CGFloat directionAwareTopLeftRadius = isRTL ? topEndRadius : topStartRadius;
const CGFloat directionAwareTopRightRadius = isRTL ? topStartRadius : topEndRadius;
@@ -683,10 +692,10 @@ static CGFloat RCTDefaultIfNegativeTo(CGFloat defaultValue, CGFloat x)
bottomLeftRadius = RCTDefaultIfNegativeTo(radius, directionAwareBottomLeftRadius);
bottomRightRadius = RCTDefaultIfNegativeTo(radius, directionAwareBottomRightRadius);
} else {
const CGFloat directionAwareTopLeftRadius = isRTL ? _borderTopEndRadius : _borderTopStartRadius;
const CGFloat directionAwareTopRightRadius = isRTL ? _borderTopStartRadius : _borderTopEndRadius;
const CGFloat directionAwareBottomLeftRadius = isRTL ? _borderBottomEndRadius : _borderBottomStartRadius;
const CGFloat directionAwareBottomRightRadius = isRTL ? _borderBottomStartRadius : _borderBottomEndRadius;
const CGFloat directionAwareTopLeftRadius = isRTL ? logicalTopEndRadius : logicalTopStartRadius;
const CGFloat directionAwareTopRightRadius = isRTL ? logicalTopStartRadius : logicalTopEndRadius;
const CGFloat directionAwareBottomLeftRadius = isRTL ? logicalBottomEndRadius : logicalBottomStartRadius;
const CGFloat directionAwareBottomRightRadius = isRTL ? logicalBottomStartRadius : logicalBottomEndRadius;
topLeftRadius =
RCTDefaultIfNegativeTo(radius, RCTDefaultIfNegativeTo(_borderTopLeftRadius, directionAwareTopLeftRadius));
@@ -946,7 +955,8 @@ setBorderColor() setBorderColor(Top) setBorderColor(Right) setBorderColor(Bottom
setBorderRadius() setBorderRadius(TopLeft) setBorderRadius(TopRight) setBorderRadius(TopStart)
setBorderRadius(TopEnd) setBorderRadius(BottomLeft) setBorderRadius(BottomRight)
setBorderRadius(BottomStart) setBorderRadius(BottomEnd)
setBorderRadius(BottomStart) setBorderRadius(BottomEnd) setBorderRadius(EndEnd)
setBorderRadius(EndStart) setBorderRadius(StartEnd) setBorderRadius(StartStart)
#pragma mark - Border Curve
@@ -960,7 +970,7 @@ setBorderColor() setBorderColor(Top) setBorderColor(Right) setBorderColor(Bottom
[self.layer setNeedsDisplay]; \
}
setBorderCurve()
setBorderCurve()
#pragma mark - Border Style
@@ -974,6 +984,6 @@ setBorderColor() setBorderColor(Top) setBorderColor(Right) setBorderColor(Bottom
[self.layer setNeedsDisplay]; \
}
setBorderStyle()
setBorderStyle()
@end
@end
+4
View File
@@ -376,6 +376,10 @@ RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomLeft)
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomRight)
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomStart)
RCT_VIEW_BORDER_RADIUS_PROPERTY(BottomEnd)
RCT_VIEW_BORDER_RADIUS_PROPERTY(EndEnd)
RCT_VIEW_BORDER_RADIUS_PROPERTY(EndStart)
RCT_VIEW_BORDER_RADIUS_PROPERTY(StartEnd)
RCT_VIEW_BORDER_RADIUS_PROPERTY(StartStart)
RCT_REMAP_VIEW_PROPERTY(display, reactDisplay, YGDisplay)
RCT_REMAP_VIEW_PROPERTY(zIndex, reactZIndex, NSInteger)
@@ -139,6 +139,10 @@ public class ViewProps {
public static final String BORDER_TOP_END_RADIUS = "borderTopEndRadius";
public static final String BORDER_BOTTOM_START_RADIUS = "borderBottomStartRadius";
public static final String BORDER_BOTTOM_END_RADIUS = "borderBottomEndRadius";
public static final String BORDER_END_END_RADIUS = "borderEndEndRadius";
public static final String BORDER_END_START_RADIUS = "borderEndStartRadius";
public static final String BORDER_START_END_RADIUS = "borderStartEndRadius";
public static final String BORDER_START_START_RADIUS = "borderStartStartRadius";
public static final String BORDER_START_COLOR = "borderStartColor";
public static final String BORDER_END_COLOR = "borderEndColor";
public static final String ON_LAYOUT = "onLayout";
@@ -97,6 +97,10 @@ object ReactMapBufferPropSetter {
private const val CORNER_BOTTOM_END = 6
private const val CORNER_BOTTOM_START = 7
private const val CORNER_ALL = 8
private const val CORNER_END_END = 9
private const val CORNER_END_START = 10
private const val CORNER_START_END = 11
private const val CORNER_START_START = 12
private const val NATIVE_DRAWABLE_KIND = 0
private const val NATIVE_DRAWABLE_ATTRIBUTE = 1
@@ -365,6 +369,10 @@ object ReactMapBufferPropSetter {
CORNER_TOP_END -> 6
CORNER_BOTTOM_START -> 7
CORNER_BOTTOM_END -> 8
CORNER_END_END -> 9
CORNER_END_START -> 10
CORNER_START_END -> 11
CORNER_START_START -> 12
else -> throw IllegalArgumentException("Unknown key for border style: $key")
}
val borderRadius = entry.doubleValue
@@ -128,7 +128,11 @@ public class ReactViewBackgroundDrawable extends Drawable {
TOP_START,
TOP_END,
BOTTOM_START,
BOTTOM_END
BOTTOM_END,
END_END,
END_START,
START_END,
START_START
}
public ReactViewBackgroundDrawable(Context context) {
@@ -271,7 +275,7 @@ public class ReactViewBackgroundDrawable extends Drawable {
public void setRadius(float radius, int position) {
if (mBorderCornerRadii == null) {
mBorderCornerRadii = new float[8];
mBorderCornerRadii = new float[12];
Arrays.fill(mBorderCornerRadii, YogaConstants.UNDEFINED);
}
@@ -581,6 +585,11 @@ public class ReactViewBackgroundDrawable extends Drawable {
float bottomStartRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_START);
float bottomEndRadius = getBorderRadius(BorderRadiusLocation.BOTTOM_END);
float endEndRadius = getBorderRadius(BorderRadiusLocation.END_END);
float endStartRadius = getBorderRadius(BorderRadiusLocation.END_START);
float startEndRadius = getBorderRadius(BorderRadiusLocation.START_END);
float startStartRadius = getBorderRadius(BorderRadiusLocation.START_START);
if (I18nUtil.getInstance().doLeftAndRightSwapInRTL(mContext)) {
if (YogaConstants.isUndefined(topStartRadius)) {
topStartRadius = topLeftRadius;
@@ -598,20 +607,44 @@ public class ReactViewBackgroundDrawable extends Drawable {
bottomEndRadius = bottomRightRadius;
}
final float directionAwareTopLeftRadius = isRTL ? topEndRadius : topStartRadius;
final float directionAwareTopRightRadius = isRTL ? topStartRadius : topEndRadius;
final float directionAwareBottomLeftRadius = isRTL ? bottomEndRadius : bottomStartRadius;
final float directionAwareBottomRightRadius = isRTL ? bottomStartRadius : bottomEndRadius;
final float logicalTopStartRadius =
YogaConstants.isUndefined(topStartRadius) ? startStartRadius : topStartRadius;
final float logicalTopEndRadius =
YogaConstants.isUndefined(topEndRadius) ? startEndRadius : topEndRadius;
final float logicalBottomStartRadius =
YogaConstants.isUndefined(bottomStartRadius) ? endStartRadius : bottomStartRadius;
final float logicalBottomEndRadius =
YogaConstants.isUndefined(bottomEndRadius) ? endEndRadius : bottomEndRadius;
final float directionAwareTopLeftRadius = isRTL ? logicalTopEndRadius : logicalTopStartRadius;
final float directionAwareTopRightRadius =
isRTL ? logicalTopStartRadius : logicalTopEndRadius;
final float directionAwareBottomLeftRadius =
isRTL ? logicalBottomEndRadius : logicalBottomStartRadius;
final float directionAwareBottomRightRadius =
isRTL ? logicalBottomStartRadius : logicalBottomEndRadius;
topLeftRadius = directionAwareTopLeftRadius;
topRightRadius = directionAwareTopRightRadius;
bottomLeftRadius = directionAwareBottomLeftRadius;
bottomRightRadius = directionAwareBottomRightRadius;
} else {
final float directionAwareTopLeftRadius = isRTL ? topEndRadius : topStartRadius;
final float directionAwareTopRightRadius = isRTL ? topStartRadius : topEndRadius;
final float directionAwareBottomLeftRadius = isRTL ? bottomEndRadius : bottomStartRadius;
final float directionAwareBottomRightRadius = isRTL ? bottomStartRadius : bottomEndRadius;
final float logicalTopStartRadius =
YogaConstants.isUndefined(topStartRadius) ? startStartRadius : topStartRadius;
final float logicalTopEndRadius =
YogaConstants.isUndefined(topEndRadius) ? startEndRadius : topEndRadius;
final float logicalBottomStartRadius =
YogaConstants.isUndefined(bottomStartRadius) ? endStartRadius : bottomStartRadius;
final float logicalBottomEndRadius =
YogaConstants.isUndefined(bottomEndRadius) ? endEndRadius : bottomEndRadius;
final float directionAwareTopLeftRadius = isRTL ? logicalTopEndRadius : logicalTopStartRadius;
final float directionAwareTopRightRadius =
isRTL ? logicalTopStartRadius : logicalTopEndRadius;
final float directionAwareBottomLeftRadius =
isRTL ? logicalBottomEndRadius : logicalBottomStartRadius;
final float directionAwareBottomRightRadius =
isRTL ? logicalBottomStartRadius : logicalBottomEndRadius;
if (!YogaConstants.isUndefined(directionAwareTopLeftRadius)) {
topLeftRadius = directionAwareTopLeftRadius;
@@ -119,6 +119,10 @@ public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
ViewProps.BORDER_TOP_END_RADIUS,
ViewProps.BORDER_BOTTOM_START_RADIUS,
ViewProps.BORDER_BOTTOM_END_RADIUS,
ViewProps.BORDER_END_END_RADIUS,
ViewProps.BORDER_END_START_RADIUS,
ViewProps.BORDER_START_END_RADIUS,
ViewProps.BORDER_START_START_RADIUS,
},
defaultFloat = YogaConstants.UNDEFINED)
public void setBorderRadius(ReactViewGroup view, int index, float borderRadius) {
@@ -113,6 +113,10 @@ constexpr MapBuffer::Key CORNER_TOP_END = 5;
constexpr MapBuffer::Key CORNER_BOTTOM_END = 6;
constexpr MapBuffer::Key CORNER_BOTTOM_START = 7;
constexpr MapBuffer::Key CORNER_ALL = 8;
constexpr MapBuffer::Key CORNER_END_END = 9;
constexpr MapBuffer::Key CORNER_END_START = 10;
constexpr MapBuffer::Key CORNER_START_END = 11;
constexpr MapBuffer::Key CORNER_START_START = 12;
inline void putOptionalFloat(
MapBufferBuilder &builder,
@@ -122,7 +126,7 @@ inline void putOptionalFloat(
}
MapBuffer convertBorderRadii(CascadedBorderRadii const &radii) {
MapBufferBuilder builder(9);
MapBufferBuilder builder(13);
putOptionalFloat(builder, CORNER_TOP_LEFT, radii.topLeft);
putOptionalFloat(builder, CORNER_TOP_RIGHT, radii.topRight);
putOptionalFloat(builder, CORNER_BOTTOM_RIGHT, radii.bottomRight);
@@ -132,6 +136,10 @@ MapBuffer convertBorderRadii(CascadedBorderRadii const &radii) {
putOptionalFloat(builder, CORNER_BOTTOM_END, radii.bottomEnd);
putOptionalFloat(builder, CORNER_BOTTOM_START, radii.bottomStart);
putOptionalFloat(builder, CORNER_ALL, radii.all);
putOptionalFloat(builder, CORNER_END_END, radii.endEnd);
putOptionalFloat(builder, CORNER_END_START, radii.endStart);
putOptionalFloat(builder, CORNER_START_END, radii.startEnd);
putOptionalFloat(builder, CORNER_START_START, radii.startStart);
return builder.build();
}
@@ -772,6 +772,7 @@ void YogaLayoutableShadowNode::swapLeftAndRightInViewProps(
auto &props = const_cast<ViewProps &>(typedCasting);
// Swap border node values, borderRadii, borderColors and borderStyles.
if (props.borderRadii.topLeft.has_value()) {
props.borderRadii.topStart = props.borderRadii.topLeft;
props.borderRadii.topLeft.reset();
@@ -160,12 +160,21 @@ struct CascadedRectangleCorners {
OptionalT bottomStart{};
OptionalT bottomEnd{};
OptionalT all{};
OptionalT endEnd{};
OptionalT endStart{};
OptionalT startEnd{};
OptionalT startStart{};
Counterpart resolve(bool isRTL, T defaults) const {
const auto topLeading = isRTL ? topEnd : topStart;
const auto topTrailing = isRTL ? topStart : topEnd;
const auto bottomLeading = isRTL ? bottomEnd : bottomStart;
const auto bottomTrailing = isRTL ? bottomStart : bottomEnd;
const auto logicalTopStart = topStart ? topStart : startStart;
const auto logicalTopEnd = topEnd ? topEnd : startEnd;
const auto logicalBottomStart = bottomStart ? bottomStart : endStart;
const auto logicalBottomEnd = bottomEnd ? bottomEnd : endEnd;
const auto topLeading = isRTL ? logicalTopEnd : logicalTopStart;
const auto topTrailing = isRTL ? logicalTopStart : logicalTopEnd;
const auto bottomLeading = isRTL ? logicalBottomEnd : logicalBottomStart;
const auto bottomTrailing = isRTL ? logicalBottomStart : logicalBottomEnd;
return {
/* .topLeft = */ topLeft.value_or(
@@ -189,7 +198,11 @@ struct CascadedRectangleCorners {
this->topEnd,
this->bottomStart,
this->bottomEnd,
this->all) ==
this->all,
this->endEnd,
this->endStart,
this->startEnd,
this->startStart) ==
std::tie(
rhs.topLeft,
rhs.topRight,
@@ -199,7 +212,11 @@ struct CascadedRectangleCorners {
rhs.topEnd,
rhs.bottomStart,
rhs.bottomEnd,
rhs.all);
rhs.all,
rhs.endEnd,
rhs.endStart,
rhs.startEnd,
rhs.startStart);
}
bool operator!=(const CascadedRectangleCorners<T> &rhs) const {
@@ -401,6 +401,38 @@ static inline CascadedRectangleCorners<T> convertRawProp(
defaultValue.bottomEnd,
prefix,
suffix);
result.endEnd = convertRawProp(
context,
rawProps,
"EndEnd",
sourceValue.endEnd,
defaultValue.endEnd,
prefix,
suffix);
result.endStart = convertRawProp(
context,
rawProps,
"EndStart",
sourceValue.endStart,
defaultValue.endStart,
prefix,
suffix);
result.startEnd = convertRawProp(
context,
rawProps,
"StartEnd",
sourceValue.startEnd,
defaultValue.startEnd,
prefix,
suffix);
result.startStart = convertRawProp(
context,
rawProps,
"StartStart",
sourceValue.startStart,
defaultValue.startStart,
prefix,
suffix);
result.all = convertRawProp(
context, rawProps, "", sourceValue.all, defaultValue.all, prefix, suffix);
@@ -38,6 +38,10 @@ constexpr MapBuffer::Key CORNER_TOP_END = 5;
constexpr MapBuffer::Key CORNER_BOTTOM_END = 6;
constexpr MapBuffer::Key CORNER_BOTTOM_START = 7;
constexpr MapBuffer::Key CORNER_ALL = 8;
constexpr MapBuffer::Key CORNER_END_END = 9;
constexpr MapBuffer::Key CORNER_END_START = 10;
constexpr MapBuffer::Key CORNER_START_END = 11;
constexpr MapBuffer::Key CORNER_START_START = 12;
inline void putOptionalFloat(
MapBufferBuilder &builder,
@@ -116,7 +120,7 @@ MapBuffer convertCascadedEdges(CascadedRectangleEdges<T> const &edges) {
template <typename T>
MapBuffer convertCascadedCorners(CascadedRectangleCorners<T> const &corners) {
MapBufferBuilder builder(9);
MapBufferBuilder builder(13);
putOptionalFloat(
builder, CORNER_TOP_LEFT, optionalFromValue(corners.topLeft));
putOptionalFloat(
@@ -132,6 +136,13 @@ MapBuffer convertCascadedCorners(CascadedRectangleCorners<T> const &corners) {
builder, CORNER_BOTTOM_END, optionalFromValue(corners.bottomEnd));
putOptionalFloat(
builder, CORNER_BOTTOM_START, optionalFromValue(corners.bottomStart));
putOptionalFloat(builder, CORNER_END_END, optionalFromValue(corners.endEnd));
putOptionalFloat(
builder, CORNER_END_START, optionalFromValue(corners.endStart));
putOptionalFloat(
builder, CORNER_START_END, optionalFromValue(corners.startEnd));
putOptionalFloat(
builder, CORNER_START_START, optionalFromValue(corners.startStart));
putOptionalFloat(builder, CORNER_ALL, optionalFromValue(corners.all));
return builder.build();
}
@@ -71,7 +71,15 @@
CASE_STATEMENT_SET_FIELD_VALUE_INDEXED( \
struct, bottomEnd, prefix "BottomEnd" suffix, rawValue) \
CASE_STATEMENT_SET_FIELD_VALUE_INDEXED( \
struct, all, prefix "" suffix, rawValue)
struct, all, prefix "" suffix, rawValue) \
CASE_STATEMENT_SET_FIELD_VALUE_INDEXED( \
struct, endEnd, prefix "EndEnd" suffix, rawValue) \
CASE_STATEMENT_SET_FIELD_VALUE_INDEXED( \
struct, endStart, prefix "EndStart" suffix, rawValue) \
CASE_STATEMENT_SET_FIELD_VALUE_INDEXED( \
struct, startEnd, prefix "StartEnd" suffix, rawValue) \
CASE_STATEMENT_SET_FIELD_VALUE_INDEXED( \
struct, startStart, prefix "StartStart" suffix, rawValue)
#define SET_CASCADED_RECTANGLE_EDGES(struct, prefix, suffix, rawValue) \
CASE_STATEMENT_SET_FIELD_VALUE_INDEXED( \
@@ -509,6 +509,35 @@ const BorderRadiiExample = withRTLState(({isRTL, setRTL}) => {
);
});
const LogicalBorderRadiiExample = withRTLState(({isRTL, setRTL}) => {
return (
<View>
<Text style={styles.bold}>Styles</Text>
<Text>borderStartStartRadius: 10,</Text>
<Text>borderStartEndRadius: 20,</Text>
<Text>borderEndStartRadius: 30,</Text>
<Text>borderEndEndRadius: 40</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<View style={directionStyle(isRTL)}>
<View
style={{
borderWidth: 10,
borderStartStartRadius: 10,
borderStartEndRadius: 20,
borderEndStartRadius: 30,
borderEndEndRadius: 40,
padding: 10,
}}>
<View>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</View>
</View>
);
});
const BorderExample = withRTLState(({isRTL, setRTL}) => {
return (
<View>
@@ -771,6 +800,12 @@ exports.examples = [
return <BorderRadiiExample />;
},
},
{
title: 'Logical Border Radii Start/End',
render: function (): React.Element<any> {
return <LogicalBorderRadiiExample />;
},
},
{
title: 'Border',
render: function (): React.Element<any> {