Add margin auto support to react native
Summary: This diff adds margin:auto (https://drafts.csswg.org/css-flexbox-1/#auto-margins) support to React Native. This enables layout not previously supported without inserting empty 'spacer' views. See below Playground for usage. ``` class Playground extends React.Component { render() { return ( <View style={{width: '100%', height: '100%', flexDirection: 'row', backgroundColor: 'white'}}> <View style={{width: 100, height: 100, backgroundColor: 'red'}}/> <View style={{width: 100, height: 100, marginLeft: 'auto', backgroundColor: 'blue'}}/> </View> ); } } ``` Reviewed By: astreet Differential Revision: D4611753 fbshipit-source-id: e78335565c193f7fb263129a638b444715ba5ab0
This commit is contained in:
parent
fb266fcaad
commit
cc275557be
|
@ -507,7 +507,9 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[
|
||||||
return (YGValue) { [json floatValue], YGUnitPoint };
|
return (YGValue) { [json floatValue], YGUnitPoint };
|
||||||
} else if ([json isKindOfClass:[NSString class]]) {
|
} else if ([json isKindOfClass:[NSString class]]) {
|
||||||
NSString *s = (NSString *) json;
|
NSString *s = (NSString *) json;
|
||||||
if ([s hasSuffix:@"%"]) {
|
if ([s isEqualToString:@"auto"]) {
|
||||||
|
return (YGValue) { YGUndefined, YGUnitAuto };
|
||||||
|
} else if ([s hasSuffix:@"%"]) {
|
||||||
return (YGValue) { [[s substringToIndex:s.length] floatValue], YGUnitPercent };
|
return (YGValue) { [[s substringToIndex:s.length] floatValue], YGUnitPercent };
|
||||||
} else {
|
} else {
|
||||||
RCTLogConvertError(json, @"a YGValue. Did you forget the % or pt suffix?");
|
RCTLogConvertError(json, @"a YGValue. Did you forget the % or pt suffix?");
|
||||||
|
|
|
@ -70,19 +70,41 @@ switch (ygvalue.unit) { \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_PROCESS_META_PROPS(type) \
|
#define RCT_SET_YGVALUE_AUTO(ygvalue, setter, ...) \
|
||||||
static void RCTProcessMetaProps##type(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node) { \
|
switch (ygvalue.unit) { \
|
||||||
RCT_SET_YGVALUE(metaProps[META_PROP_LEFT], YGNodeStyleSet##type, node, YGEdgeStart); \
|
case YGUnitAuto: \
|
||||||
RCT_SET_YGVALUE(metaProps[META_PROP_RIGHT], YGNodeStyleSet##type, node, YGEdgeEnd); \
|
setter##Auto(__VA_ARGS__); \
|
||||||
RCT_SET_YGVALUE(metaProps[META_PROP_TOP], YGNodeStyleSet##type, node, YGEdgeTop); \
|
break; \
|
||||||
RCT_SET_YGVALUE(metaProps[META_PROP_BOTTOM], YGNodeStyleSet##type, node, YGEdgeBottom); \
|
case YGUnitUndefined: \
|
||||||
RCT_SET_YGVALUE(metaProps[META_PROP_HORIZONTAL], YGNodeStyleSet##type, node, YGEdgeHorizontal); \
|
setter(__VA_ARGS__, YGUndefined); \
|
||||||
RCT_SET_YGVALUE(metaProps[META_PROP_VERTICAL], YGNodeStyleSet##type, node, YGEdgeVertical); \
|
break; \
|
||||||
RCT_SET_YGVALUE(metaProps[META_PROP_ALL], YGNodeStyleSet##type, node, YGEdgeAll); \
|
case YGUnitPoint: \
|
||||||
|
setter(__VA_ARGS__, ygvalue.value); \
|
||||||
|
break; \
|
||||||
|
case YGUnitPercent: \
|
||||||
|
setter##Percent(__VA_ARGS__, ygvalue.value); \
|
||||||
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PROCESS_META_PROPS(Padding);
|
static void RCTProcessMetaPropsPadding(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node) {
|
||||||
DEFINE_PROCESS_META_PROPS(Margin);
|
RCT_SET_YGVALUE(metaProps[META_PROP_LEFT], YGNodeStyleSetPadding, node, YGEdgeStart);
|
||||||
|
RCT_SET_YGVALUE(metaProps[META_PROP_RIGHT], YGNodeStyleSetPadding, node, YGEdgeEnd);
|
||||||
|
RCT_SET_YGVALUE(metaProps[META_PROP_TOP], YGNodeStyleSetPadding, node, YGEdgeTop);
|
||||||
|
RCT_SET_YGVALUE(metaProps[META_PROP_BOTTOM], YGNodeStyleSetPadding, node, YGEdgeBottom);
|
||||||
|
RCT_SET_YGVALUE(metaProps[META_PROP_HORIZONTAL], YGNodeStyleSetPadding, node, YGEdgeHorizontal);
|
||||||
|
RCT_SET_YGVALUE(metaProps[META_PROP_VERTICAL], YGNodeStyleSetPadding, node, YGEdgeVertical);
|
||||||
|
RCT_SET_YGVALUE(metaProps[META_PROP_ALL], YGNodeStyleSetPadding, node, YGEdgeAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RCTProcessMetaPropsMargin(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node) {
|
||||||
|
RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_LEFT], YGNodeStyleSetMargin, node, YGEdgeStart);
|
||||||
|
RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_RIGHT], YGNodeStyleSetMargin, node, YGEdgeEnd);
|
||||||
|
RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_TOP], YGNodeStyleSetMargin, node, YGEdgeTop);
|
||||||
|
RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_BOTTOM], YGNodeStyleSetMargin, node, YGEdgeBottom);
|
||||||
|
RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_HORIZONTAL], YGNodeStyleSetMargin, node, YGEdgeHorizontal);
|
||||||
|
RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_VERTICAL], YGNodeStyleSetMargin, node, YGEdgeVertical);
|
||||||
|
RCT_SET_YGVALUE_AUTO(metaProps[META_PROP_ALL], YGNodeStyleSetMargin, node, YGEdgeAll);
|
||||||
|
}
|
||||||
|
|
||||||
static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node) {
|
static void RCTProcessMetaPropsBorder(const YGValue metaProps[META_PROP_COUNT], YGNodeRef node) {
|
||||||
YGNodeStyleSetBorder(node, YGEdgeStart, metaProps[META_PROP_LEFT].value);
|
YGNodeStyleSetBorder(node, YGEdgeStart, metaProps[META_PROP_LEFT].value);
|
||||||
|
@ -522,9 +544,19 @@ RCT_BORDER_PROPERTY(Bottom, BOTTOM)
|
||||||
RCT_BORDER_PROPERTY(Right, RIGHT)
|
RCT_BORDER_PROPERTY(Right, RIGHT)
|
||||||
|
|
||||||
// Dimensions
|
// Dimensions
|
||||||
|
|
||||||
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
|
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
|
||||||
- (void)set##setProp:(YGValue)value \
|
- (void)set##setProp:(YGValue)value \
|
||||||
|
{ \
|
||||||
|
RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSet##cssProp, _yogaNode); \
|
||||||
|
[self dirtyText]; \
|
||||||
|
} \
|
||||||
|
- (YGValue)getProp \
|
||||||
|
{ \
|
||||||
|
return YGNodeStyleGet##cssProp(_yogaNode); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RCT_MIN_MAX_DIMENSION_PROPERTY(setProp, getProp, cssProp) \
|
||||||
|
- (void)set##setProp:(YGValue)value \
|
||||||
{ \
|
{ \
|
||||||
RCT_SET_YGVALUE(value, YGNodeStyleSet##cssProp, _yogaNode); \
|
RCT_SET_YGVALUE(value, YGNodeStyleSet##cssProp, _yogaNode); \
|
||||||
[self dirtyText]; \
|
[self dirtyText]; \
|
||||||
|
@ -536,10 +568,10 @@ RCT_BORDER_PROPERTY(Right, RIGHT)
|
||||||
|
|
||||||
RCT_DIMENSION_PROPERTY(Width, width, Width)
|
RCT_DIMENSION_PROPERTY(Width, width, Width)
|
||||||
RCT_DIMENSION_PROPERTY(Height, height, Height)
|
RCT_DIMENSION_PROPERTY(Height, height, Height)
|
||||||
RCT_DIMENSION_PROPERTY(MinWidth, minWidth, MinWidth)
|
RCT_MIN_MAX_DIMENSION_PROPERTY(MinWidth, minWidth, MinWidth)
|
||||||
RCT_DIMENSION_PROPERTY(MinHeight, minHeight, MinHeight)
|
RCT_MIN_MAX_DIMENSION_PROPERTY(MinHeight, minHeight, MinHeight)
|
||||||
RCT_DIMENSION_PROPERTY(MaxWidth, maxWidth, MaxWidth)
|
RCT_MIN_MAX_DIMENSION_PROPERTY(MaxWidth, maxWidth, MaxWidth)
|
||||||
RCT_DIMENSION_PROPERTY(MaxHeight, maxHeight, MaxHeight)
|
RCT_MIN_MAX_DIMENSION_PROPERTY(MaxHeight, maxHeight, MaxHeight)
|
||||||
|
|
||||||
// Position
|
// Position
|
||||||
|
|
||||||
|
@ -644,7 +676,7 @@ static inline YGSize RCTShadowViewMeasure(YGNodeRef node, float width, YGMeasure
|
||||||
|
|
||||||
- (void)setFlexBasis:(YGValue)value
|
- (void)setFlexBasis:(YGValue)value
|
||||||
{
|
{
|
||||||
RCT_SET_YGVALUE(value, YGNodeStyleSetFlexBasis, _yogaNode);
|
RCT_SET_YGVALUE_AUTO(value, YGNodeStyleSetFlexBasis, _yogaNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (YGValue)flexBasis
|
- (YGValue)flexBasis
|
||||||
|
|
|
@ -74,6 +74,9 @@ public class LayoutShadowNode extends ReactShadowNode {
|
||||||
case UNDEFINED:
|
case UNDEFINED:
|
||||||
setStyleWidth(mTempYogaValue.value);
|
setStyleWidth(mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
case AUTO:
|
||||||
|
setStyleWidthAuto();
|
||||||
|
break;
|
||||||
case PERCENT:
|
case PERCENT:
|
||||||
setStyleWidthPercent(mTempYogaValue.value);
|
setStyleWidthPercent(mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
@ -134,6 +137,9 @@ public class LayoutShadowNode extends ReactShadowNode {
|
||||||
case UNDEFINED:
|
case UNDEFINED:
|
||||||
setStyleHeight(mTempYogaValue.value);
|
setStyleHeight(mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
case AUTO:
|
||||||
|
setStyleHeightAuto();
|
||||||
|
break;
|
||||||
case PERCENT:
|
case PERCENT:
|
||||||
setStyleHeightPercent(mTempYogaValue.value);
|
setStyleHeightPercent(mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
@ -218,6 +224,9 @@ public class LayoutShadowNode extends ReactShadowNode {
|
||||||
case UNDEFINED:
|
case UNDEFINED:
|
||||||
setFlexBasis(mTempYogaValue.value);
|
setFlexBasis(mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
case AUTO:
|
||||||
|
setFlexBasisAuto();
|
||||||
|
break;
|
||||||
case PERCENT:
|
case PERCENT:
|
||||||
setFlexBasisPercent(mTempYogaValue.value);
|
setFlexBasisPercent(mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
@ -312,6 +321,9 @@ public class LayoutShadowNode extends ReactShadowNode {
|
||||||
case UNDEFINED:
|
case UNDEFINED:
|
||||||
setMargin(ViewProps.PADDING_MARGIN_SPACING_TYPES[index], mTempYogaValue.value);
|
setMargin(ViewProps.PADDING_MARGIN_SPACING_TYPES[index], mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
case AUTO:
|
||||||
|
setMarginAuto(ViewProps.PADDING_MARGIN_SPACING_TYPES[index]);
|
||||||
|
break;
|
||||||
case PERCENT:
|
case PERCENT:
|
||||||
setMarginPercent(ViewProps.PADDING_MARGIN_SPACING_TYPES[index], mTempYogaValue.value);
|
setMarginPercent(ViewProps.PADDING_MARGIN_SPACING_TYPES[index], mTempYogaValue.value);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -554,6 +554,10 @@ public class ReactShadowNode {
|
||||||
mYogaNode.setWidthPercent(percent);
|
mYogaNode.setWidthPercent(percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStyleWidthAuto() {
|
||||||
|
mYogaNode.setWidthAuto();
|
||||||
|
}
|
||||||
|
|
||||||
public void setStyleMinWidth(float widthPx) {
|
public void setStyleMinWidth(float widthPx) {
|
||||||
mYogaNode.setMinWidth(widthPx);
|
mYogaNode.setMinWidth(widthPx);
|
||||||
}
|
}
|
||||||
|
@ -582,6 +586,10 @@ public class ReactShadowNode {
|
||||||
mYogaNode.setHeightPercent(percent);
|
mYogaNode.setHeightPercent(percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStyleHeightAuto() {
|
||||||
|
mYogaNode.setHeightAuto();
|
||||||
|
}
|
||||||
|
|
||||||
public void setStyleMinHeight(float widthPx) {
|
public void setStyleMinHeight(float widthPx) {
|
||||||
mYogaNode.setMinHeight(widthPx);
|
mYogaNode.setMinHeight(widthPx);
|
||||||
}
|
}
|
||||||
|
@ -614,6 +622,10 @@ public class ReactShadowNode {
|
||||||
mYogaNode.setFlexBasis(flexBasis);
|
mYogaNode.setFlexBasis(flexBasis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFlexBasisAuto() {
|
||||||
|
mYogaNode.setFlexBasisAuto();
|
||||||
|
}
|
||||||
|
|
||||||
public void setFlexBasisPercent(float percent) {
|
public void setFlexBasisPercent(float percent) {
|
||||||
mYogaNode.setFlexBasisPercent(percent);
|
mYogaNode.setFlexBasisPercent(percent);
|
||||||
}
|
}
|
||||||
|
@ -654,6 +666,10 @@ public class ReactShadowNode {
|
||||||
mYogaNode.setMarginPercent(YogaEdge.fromInt(spacingType), percent);
|
mYogaNode.setMarginPercent(YogaEdge.fromInt(spacingType), percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMarginAuto(int spacingType) {
|
||||||
|
mYogaNode.setMarginAuto(YogaEdge.fromInt(spacingType));
|
||||||
|
}
|
||||||
|
|
||||||
public final float getPadding(int spacingType) {
|
public final float getPadding(int spacingType) {
|
||||||
return mYogaNode.getLayoutPadding(YogaEdge.fromInt(spacingType));
|
return mYogaNode.getLayoutPadding(YogaEdge.fromInt(spacingType));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue