mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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:
committed by
Facebook GitHub Bot
parent
66927ec3aa
commit
4ae4984094
@@ -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
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+43
-10
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user