From 4c760518cb1453677da080c12026280b019ccb3b Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Tue, 17 Oct 2023 20:54:57 -0700 Subject: [PATCH 1/3] Support "align-content: space-evenly" (#41019) Summary: ### Changes made - Regenerated tests (as some aspect ratio tests seem to be out of date compared to the fixtures) - Added SpaceEvenly variant to the "Align" enums (via enums.py) - Implemented `align-content: space-evenly` alignment in CalculateLayout.cpp - Added generated tests `align-content: space-evenly` - Updated NumericBitfield test to account for the fact that the Align enum now requires more bits (this bit could do with being reviewed as I am not 100% certain that it's valid to just update the test like this). ### Changes not made - Any attempt to improve the spec-compliance of content alignment in general (e.g. I think https://github.com/facebook/yoga/pull/1013 probably still needs to happen) X-link: https://github.com/facebook/yoga/pull/1422 Reviewed By: yungsters Differential Revision: D50305438 Pulled By: NickGerleman --- .../java/com/facebook/yoga/YogaAlign.java | 4 ++- .../renderer/components/view/conversions.h | 34 ++----------------- .../ReactCommon/yoga/yoga/YGEnums.cpp | 2 ++ .../ReactCommon/yoga/yoga/YGEnums.h | 3 +- .../yoga/yoga/algorithm/CalculateLayout.cpp | 13 +++++++ .../ReactCommon/yoga/yoga/enums/Align.h | 5 +-- 6 files changed, 25 insertions(+), 36 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaAlign.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaAlign.java index a60d77e0f294..00535154fca1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaAlign.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaAlign.java @@ -17,7 +17,8 @@ public enum YogaAlign { STRETCH(4), BASELINE(5), SPACE_BETWEEN(6), - SPACE_AROUND(7); + SPACE_AROUND(7), + SPACE_EVENLY(8); private final int mIntValue; @@ -39,6 +40,7 @@ public static YogaAlign fromInt(int value) { case 5: return BASELINE; case 6: return SPACE_BETWEEN; case 7: return SPACE_AROUND; + case 8: return SPACE_EVENLY; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index b2e8febb6023..6ff6c14f8ea7 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -746,41 +746,11 @@ inline std::string toString(const yoga::FlexDirection& value) { } inline std::string toString(const yoga::Justify& value) { - switch (value) { - case yoga::Justify::FlexStart: - return "flex-start"; - case yoga::Justify::Center: - return "center"; - case yoga::Justify::FlexEnd: - return "flex-end"; - case yoga::Justify::SpaceBetween: - return "space-between"; - case yoga::Justify::SpaceAround: - return "space-around"; - case yoga::Justify::SpaceEvenly: - return "space-evenly"; - } + return YGJustifyToString(yoga::unscopedEnum(value)); } inline std::string toString(const yoga::Align& value) { - switch (value) { - case yoga::Align::Auto: - return "auto"; - case yoga::Align::FlexStart: - return "flex-start"; - case yoga::Align::Center: - return "center"; - case yoga::Align::FlexEnd: - return "flex-end"; - case yoga::Align::Stretch: - return "stretch"; - case yoga::Align::Baseline: - return "baseline"; - case yoga::Align::SpaceBetween: - return "space-between"; - case yoga::Align::SpaceAround: - return "space-around"; - } + return YGAlignToString(yoga::unscopedEnum(value)); } inline std::string toString(const yoga::PositionType& value) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp index b5916ca1ecf3..77e5c802376b 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp @@ -27,6 +27,8 @@ const char* YGAlignToString(const YGAlign value) { return "space-between"; case YGAlignSpaceAround: return "space-around"; + case YGAlignSpaceEvenly: + return "space-evenly"; } return "unknown"; } diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h index 55bbe9fc9d8d..ef09668c811e 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h @@ -21,7 +21,8 @@ YG_ENUM_SEQ_DECL( YGAlignStretch, YGAlignBaseline, YGAlignSpaceBetween, - YGAlignSpaceAround) + YGAlignSpaceAround, + YGAlignSpaceEvenly) YG_ENUM_SEQ_DECL( YGDimension, diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 570070d047f1..59360ff76cd4 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -2036,6 +2036,18 @@ static void calculateLayoutImpl( currentLead += remainingAlignContentDim / 2; } break; + case Align::SpaceEvenly: + if (availableInnerCrossDim > totalLineCrossDim) { + currentLead += + remainingAlignContentDim / static_cast(lineCount + 1); + if (lineCount > 1) { + crossDimLead = + remainingAlignContentDim / static_cast(lineCount + 1); + } + } else { + currentLead += remainingAlignContentDim / 2; + } + break; case Align::SpaceBetween: if (availableInnerCrossDim > totalLineCrossDim && lineCount > 1) { crossDimLead = @@ -2192,6 +2204,7 @@ static void calculateLayoutImpl( case Align::Auto: case Align::SpaceBetween: case Align::SpaceAround: + case Align::SpaceEvenly: break; } } diff --git a/packages/react-native/ReactCommon/yoga/yoga/enums/Align.h b/packages/react-native/ReactCommon/yoga/yoga/enums/Align.h index 95df12a79033..67777fc31b45 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/enums/Align.h +++ b/packages/react-native/ReactCommon/yoga/yoga/enums/Align.h @@ -24,16 +24,17 @@ enum class Align : uint8_t { Baseline = YGAlignBaseline, SpaceBetween = YGAlignSpaceBetween, SpaceAround = YGAlignSpaceAround, + SpaceEvenly = YGAlignSpaceEvenly, }; template <> constexpr inline int32_t ordinalCount() { - return 8; + return 9; } template <> constexpr inline int32_t bitCount() { - return 3; + return 4; } constexpr inline Align scopedEnum(YGAlign unscoped) { From b37ec4e4019e1d6badd5979148282559500e0f55 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 17 Oct 2023 20:54:57 -0700 Subject: [PATCH 2/3] Reuse Yoga enum ToString functions (#41021) Summary: Yoga has generated public `ToString` functions for enums already. Don't duplicate in Fabric. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D50347728 --- .../renderer/components/view/conversions.h | 54 +++---------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index 6ff6c14f8ea7..4eaf353e8104 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -722,27 +722,11 @@ inline std::string toString(const std::array vec) { } inline std::string toString(const yoga::Direction& value) { - switch (value) { - case yoga::Direction::Inherit: - return "inherit"; - case yoga::Direction::LTR: - return "ltr"; - case yoga::Direction::RTL: - return "rtl"; - } + return YGDirectionToString(yoga::unscopedEnum(value)); } inline std::string toString(const yoga::FlexDirection& value) { - switch (value) { - case yoga::FlexDirection::Column: - return "column"; - case yoga::FlexDirection::ColumnReverse: - return "column-reverse"; - case yoga::FlexDirection::Row: - return "row"; - case yoga::FlexDirection::RowReverse: - return "row-reverse"; - } + return YGFlexDirectionToString(yoga::unscopedEnum(value)); } inline std::string toString(const yoga::Justify& value) { @@ -754,45 +738,19 @@ inline std::string toString(const yoga::Align& value) { } inline std::string toString(const yoga::PositionType& value) { - switch (value) { - case yoga::PositionType::Static: - return "static"; - case yoga::PositionType::Relative: - return "relative"; - case yoga::PositionType::Absolute: - return "absolute"; - } + return YGPositionTypeToString(yoga::unscopedEnum(value)); } inline std::string toString(const yoga::Wrap& value) { - switch (value) { - case yoga::Wrap::NoWrap: - return "no-wrap"; - case yoga::Wrap::Wrap: - return "wrap"; - case yoga::Wrap::WrapReverse: - return "wrap-reverse"; - } + return YGWrapToString(yoga::unscopedEnum(value)); } inline std::string toString(const yoga::Overflow& value) { - switch (value) { - case yoga::Overflow::Visible: - return "visible"; - case yoga::Overflow::Scroll: - return "scroll"; - case yoga::Overflow::Hidden: - return "hidden"; - } + return YGOverflowToString(yoga::unscopedEnum(value)); } inline std::string toString(const yoga::Display& value) { - switch (value) { - case yoga::Display::Flex: - return "flex"; - case yoga::Display::None: - return "none"; - } + return YGDisplayToString(yoga::unscopedEnum(value)); } inline std::string toString(const YGValue& value) { From 82cc3a695d0ba5a80fa7203a8ce6a4dc1645b954 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 17 Oct 2023 20:54:57 -0700 Subject: [PATCH 3/3] Bindings for `alignContent: "space-evenly"` (#41020) Summary: This adds Fabric and Paper bindings to support `alignContent: "space-evenly"` as implemented in https://github.com/facebook/yoga/pull/1422 Changelog: [General][Added] - Bindings for `alignContent: "space-evenly"` Reviewed By: yungsters Differential Revision: D50347978 --- .../react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts | 1 + .../react-native/Libraries/StyleSheet/StyleSheetTypes.js | 3 ++- packages/react-native/React/Base/RCTConvert.m | 3 ++- .../java/com/facebook/react/uimanager/LayoutShadowNode.java | 5 +++++ .../ReactCommon/react/renderer/components/view/conversions.h | 4 ++++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts index 92fe7cdaf36b..f7a0de83adc4 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts @@ -40,6 +40,7 @@ export interface FlexStyle { | 'stretch' | 'space-between' | 'space-around' + | 'space-evenly' | undefined; alignItems?: FlexAlignType | undefined; alignSelf?: 'auto' | FlexAlignType | undefined; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js index fb2db1c4c60e..c4f45c7e61c6 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js @@ -552,7 +552,8 @@ type ____LayoutStyle_Internal = $ReadOnly<{ | 'center' | 'stretch' | 'space-between' - | 'space-around', + | 'space-around' + | 'space-evenly', /** `overflow` controls how children are measured and displayed. * `overflow: hidden` causes views to be clipped while `overflow: scroll` diff --git a/packages/react-native/React/Base/RCTConvert.m b/packages/react-native/React/Base/RCTConvert.m index 34822463593f..55f42ebf49e9 100644 --- a/packages/react-native/React/Base/RCTConvert.m +++ b/packages/react-native/React/Base/RCTConvert.m @@ -1172,7 +1172,8 @@ + (NSPropertyList)NSPropertyList:(id)json @"stretch" : @(YGAlignStretch), @"baseline" : @(YGAlignBaseline), @"space-between" : @(YGAlignSpaceBetween), - @"space-around" : @(YGAlignSpaceAround) + @"space-around" : @(YGAlignSpaceAround), + @"space-evenly" : @(YGAlignSpaceEvenly) }), YGAlignFlexStart, intValue) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java index 46b833a053a2..6513dd6268cc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.java @@ -541,6 +541,11 @@ public void setAlignContent(@Nullable String alignContent) { setAlignContent(YogaAlign.SPACE_AROUND); return; } + case "space-evenly": + { + setAlignContent(YogaAlign.SPACE_EVENLY); + return; + } default: { FLog.w(ReactConstants.TAG, "invalid value for alignContent: " + alignContent); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index 4eaf353e8104..c0edf7ce02dd 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -284,6 +284,10 @@ inline void fromRawValue( result = yoga::Align::SpaceAround; return; } + if (stringValue == "space-evenly") { + result = yoga::Align::SpaceEvenly; + return; + } LOG(ERROR) << "Could not parse yoga::Align:" << stringValue; react_native_expect(false); }