From efe02cd23b444709ca20c706bda999f5c68fc844 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 19 Mar 2026 15:39:29 -0300 Subject: [PATCH 1/7] feat: calc support --- packages/react-native/React/Views/RCTLayout.m | 2 + .../main/java/com/facebook/yoga/YogaUnit.kt | 4 +- .../view/YogaLayoutableShadowNode.cpp | 37 +- .../view/YogaLayoutableShadowNode.h | 7 +- .../components/view/YogaStylableProps.cpp | 339 ++++++++++++++ .../components/view/YogaStylableProps.h | 9 + .../renderer/components/view/primitives.h | 43 ++ .../react/renderer/core/graphicsConversions.h | 4 + .../ReactCommon/react/renderer/css/CSSCalc.h | 327 ++++++++++++++ .../react/renderer/css/tests/CSSCalcTest.cpp | 419 ++++++++++++++++++ .../ReactCommon/yoga/yoga/YGEnums.cpp | 2 + .../ReactCommon/yoga/yoga/YGEnums.h | 3 +- .../ReactCommon/yoga/yoga/YGNodeStyle.cpp | 101 +++++ .../ReactCommon/yoga/yoga/YGNodeStyle.h | 54 +++ .../ReactCommon/yoga/yoga/YGValue.h | 33 ++ .../yoga/yoga/algorithm/AbsoluteLayout.cpp | 51 ++- .../yoga/yoga/algorithm/BoundAxis.h | 12 +- .../yoga/yoga/algorithm/CalculateLayout.cpp | 155 ++++--- .../yoga/yoga/algorithm/FlexLine.cpp | 6 +- .../ReactCommon/yoga/yoga/enums/Unit.h | 3 +- .../ReactCommon/yoga/yoga/node/Node.cpp | 21 +- .../ReactCommon/yoga/yoga/node/Node.h | 6 +- .../ReactCommon/yoga/yoga/style/Style.h | 99 +++-- .../ReactCommon/yoga/yoga/style/StyleLength.h | 74 +++- .../yoga/yoga/style/StyleSizeLength.h | 74 +++- .../yoga/yoga/style/StyleValueHandle.h | 3 +- .../yoga/yoga/style/StyleValuePool.h | 23 + 27 files changed, 1733 insertions(+), 178 deletions(-) create mode 100644 packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h create mode 100644 packages/react-native/ReactCommon/react/renderer/css/tests/CSSCalcTest.cpp diff --git a/packages/react-native/React/Views/RCTLayout.m b/packages/react-native/React/Views/RCTLayout.m index 356866a420c6..ea2911874843 100644 --- a/packages/react-native/React/Views/RCTLayout.m +++ b/packages/react-native/React/Views/RCTLayout.m @@ -87,6 +87,8 @@ CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue) case YGUnitFitContent: case YGUnitStretch: return baseFloatValue; + case YGUnitDynamic: + return RCTCoreGraphicsFloatFromYogaFloat(YGUndefined); } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.kt index 9bd5d69673c3..867d521da76f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.kt @@ -16,7 +16,8 @@ public enum class YogaUnit(public val intValue: Int) { AUTO(3), MAX_CONTENT(4), FIT_CONTENT(5), - STRETCH(6); + STRETCH(6), + DYNAMIC(7); public fun intValue(): Int = intValue @@ -31,6 +32,7 @@ public enum class YogaUnit(public val intValue: Int) { 4 -> MAX_CONTENT 5 -> FIT_CONTENT 6 -> STRETCH + 7 -> DYNAMIC else -> throw IllegalArgumentException("Unknown enum value: $value") } } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index ebe98db8eb4d..3d7103776312 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -139,7 +139,9 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode( } if (fragment.props) { - updateYogaProps(); + auto& sourceProps = + static_cast(*sourceShadowNode.getProps()); + updateYogaProps(sourceProps.calcExpressions); } if (fragment.children) { @@ -389,15 +391,18 @@ void YogaLayoutableShadowNode::updateYogaChildren() { yogaNode_.setDirty(!isClean); } -void YogaLayoutableShadowNode::updateYogaProps() { +void YogaLayoutableShadowNode::updateYogaProps( + const CalcExpressions& previousCalcExpressions) { ensureUnsealed(); auto& props = static_cast(*props_); auto styleResult = applyAliasedProps(props.yogaStyle, props); // Resetting `dirty` flag only if `yogaStyle` portion of `Props` was - // changed. - if (!YGNodeIsDirty(&yogaNode_) && (styleResult != yogaNode_.style())) { + // changed or calc expressions changed. + if (!YGNodeIsDirty(&yogaNode_) && + (props.calcExpressions != previousCalcExpressions || + styleResult != yogaNode_.style())) { yogaNode_.setDirty(true); } @@ -935,6 +940,30 @@ YogaLayoutableShadowNode& YogaLayoutableShadowNode::shadowNodeFromContext( *static_cast(YGNodeGetContext(yogaNode))); } +YGValue YogaLayoutableShadowNode::yogaNodeCalcValueResolver( + YGNodeConstRef yogaNode, + YGValueDynamicID id, + YGValueDynamicContext context) { + if (!yogaNode) { + return {}; + } + + auto& node = shadowNodeFromContext(yogaNode); + auto& props = static_cast(*node.props_); + auto key = static_cast(id); + if (!props.calcExpressions.contains(key)) { + return {}; + } + + auto& calc = props.calcExpressions.at(key); + return YGValue( + calc.resolve( + context.referenceLength, + threadLocalLayoutContext.viewportSize.width, + threadLocalLayoutContext.viewportSize.height), + YGUnitPoint); +}; + yoga::Config& YogaLayoutableShadowNode::initializeYogaConfig( yoga::Config& config, YGConfigConstRef previousConfig) { diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h index 905b98ecaa66..db85062bb217 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h @@ -58,7 +58,7 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode { void updateYogaChildren(); - void updateYogaProps(); + void updateYogaProps(const CalcExpressions& previousCalcExpressions = {}); /* * Sets layoutable size of node. @@ -87,6 +87,11 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode { Rect getContentBounds() const; + static YGValue yogaNodeCalcValueResolver( + YGNodeConstRef yogaNode, + YGValueDynamicID id, + YGValueDynamicContext context); + protected: /** * Subclasses which provide MeasurableYogaNode may override to signal that a diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index d740d4a153bd..fad9b128d91c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -15,10 +15,19 @@ #include #include +#include "YogaLayoutableShadowNode.h" #include "conversions.h" namespace facebook::react { +YGValue yogaNodeCalcValueResolver( + YGNodeConstRef yogaNode, + YGValueDynamicID id, + YGValueDynamicContext context) { + return YogaLayoutableShadowNode::yogaNodeCalcValueResolver( + yogaNode, id, context); +} + YogaStylableProps::YogaStylableProps( const PropsParserContext& context, const YogaStylableProps& sourceProps, @@ -29,6 +38,8 @@ YogaStylableProps::YogaStylableProps( ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.yogaStyle : convertRawProp(context, rawProps, sourceProps.yogaStyle)) { + calcExpressions = + buildCalcExpressions(context, rawProps, sourceProps.calcExpressions); if (!ReactNativeFeatureFlags::enableCppPropsIteratorSetter()) { convertRawPropAliases(context, sourceProps, rawProps); } @@ -119,6 +130,295 @@ static inline const T getFieldValue( REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ position, setPosition, yoga::Edge::All, "inset"); +#define APPLY_CALC_COMMON(fieldName, key, setPoints, setPercent, setDynamic) \ + { \ + if (const auto* rawValue = rawProps.at(fieldName, nullptr, nullptr)) { \ + const auto& value = *rawValue; \ + if (value.hasType()) { \ + auto isCalcExpression{false}; \ + auto parsed = parseCSSProperty((std::string)value); \ + if (std::holds_alternative(parsed)) { \ + auto calc = std::get(parsed); \ + if (calc.isPointsOnly()) { \ + setPoints(calc.px); \ + } else if (calc.isPercentOnly()) { \ + setPercent(calc.percent); \ + } else { \ + setDynamic(static_cast(key)); \ + calcExpressions[key] = std::move(calc); \ + isCalcExpression = true; \ + } \ + } \ + if (!isCalcExpression && calcExpressions.count(key)) { \ + calcExpressions.erase(key); \ + } \ + } \ + } \ + } + +#define APPLY_CALC_YG_INDEXED( \ + getter, setter, index, fieldName, LengthType, key) \ + APPLY_CALC_COMMON( \ + fieldName, \ + key, \ + [&](float points) { \ + yogaStyle.setter(index, LengthType::points(points)); \ + }, \ + [&](float percent) { \ + yogaStyle.setter(index, LengthType::percent(percent)); \ + }, \ + [&](YGValueDynamicID dynamicId) { \ + yogaStyle.setter( \ + index, \ + LengthType::dynamic(&yogaNodeCalcValueResolver, dynamicId)); \ + }) + +#define APPLY_CALC_YG_FIELD(getter, setter, fieldName, LengthType, key) \ + APPLY_CALC_COMMON( \ + fieldName, \ + key, \ + [&](float points) { yogaStyle.setter(LengthType::points(points)); }, \ + [&](float percent) { yogaStyle.setter(LengthType::percent(percent)); }, \ + [&](YGValueDynamicID dynamicId) { \ + yogaStyle.setter( \ + LengthType::dynamic(&yogaNodeCalcValueResolver, dynamicId)); \ + }) + +#define APPLY_CALC_YG_DIMENSION( \ + field, setter, widthStr, heightStr, widthCalcIdx, heightCalcIdx) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Dimension::Width, \ + widthStr, \ + yoga::StyleSizeLength, \ + widthCalcIdx) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Dimension::Height, \ + heightStr, \ + yoga::StyleSizeLength, \ + heightCalcIdx) + +#define APPLY_CALC_YG_EDGES_MARGIN(field, setter, LengthType, prefix) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Left, \ + prefix "Left", \ + LengthType, \ + CalcExpressionPropertyID::MarginLeft) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Top, \ + prefix "Top", \ + LengthType, \ + CalcExpressionPropertyID::MarginTop) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Right, \ + prefix "Right", \ + LengthType, \ + CalcExpressionPropertyID::MarginRight) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Bottom, \ + prefix "Bottom", \ + LengthType, \ + CalcExpressionPropertyID::MarginBottom) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Start, \ + prefix "Start", \ + LengthType, \ + CalcExpressionPropertyID::MarginStart) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::End, \ + prefix "End", \ + LengthType, \ + CalcExpressionPropertyID::MarginEnd) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Horizontal, \ + prefix "Horizontal", \ + LengthType, \ + CalcExpressionPropertyID::MarginHorizontal) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Vertical, \ + prefix "Vertical", \ + LengthType, \ + CalcExpressionPropertyID::MarginVertical) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::All, \ + prefix, \ + LengthType, \ + CalcExpressionPropertyID::MarginAll) + +#define APPLY_CALC_YG_EDGES_PADDING(field, setter, LengthType, prefix) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Left, \ + prefix "Left", \ + LengthType, \ + CalcExpressionPropertyID::PaddingLeft) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Top, \ + prefix "Top", \ + LengthType, \ + CalcExpressionPropertyID::PaddingTop) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Right, \ + prefix "Right", \ + LengthType, \ + CalcExpressionPropertyID::PaddingRight) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Bottom, \ + prefix "Bottom", \ + LengthType, \ + CalcExpressionPropertyID::PaddingBottom) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Start, \ + prefix "Start", \ + LengthType, \ + CalcExpressionPropertyID::PaddingStart) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::End, \ + prefix "End", \ + LengthType, \ + CalcExpressionPropertyID::PaddingEnd) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Horizontal, \ + prefix "Horizontal", \ + LengthType, \ + CalcExpressionPropertyID::PaddingHorizontal) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::Vertical, \ + prefix "Vertical", \ + LengthType, \ + CalcExpressionPropertyID::PaddingVertical) \ + APPLY_CALC_YG_INDEXED( \ + field, \ + setter, \ + yoga::Edge::All, \ + prefix, \ + LengthType, \ + CalcExpressionPropertyID::PaddingAll) + +#define APPLY_CALC_YG_EDGES_POSITION() \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::Left, \ + "left", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::Left) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::Top, \ + "top", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::Top) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::Right, \ + "right", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::Right) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::Bottom, \ + "bottom", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::Bottom) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::Start, \ + "start", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::Start) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::End, \ + "end", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::End) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::Horizontal, \ + "insetInline", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::InsetInline) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::Vertical, \ + "insetBlock", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::InsetBlock) \ + APPLY_CALC_YG_INDEXED( \ + position, \ + setPosition, \ + yoga::Edge::All, \ + "inset", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::Inset) + +#define APPLY_CALC_YG_GUTTER() \ + APPLY_CALC_YG_INDEXED( \ + gap, \ + setGap, \ + yoga::Gutter::Row, \ + "rowGap", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::RowGap) \ + APPLY_CALC_YG_INDEXED( \ + gap, \ + setGap, \ + yoga::Gutter::Column, \ + "columnGap", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::ColumnGap) \ + APPLY_CALC_YG_INDEXED( \ + gap, \ + setGap, \ + yoga::Gutter::All, \ + "gap", \ + yoga::StyleLength, \ + CalcExpressionPropertyID::Gap) + void YogaStylableProps::setProp( const PropsParserContext& context, RawPropsPropNameHash hash, @@ -520,4 +820,43 @@ void YogaStylableProps::convertRawPropAliases( yoga::StyleLength::undefined()); } +CalcExpressions YogaStylableProps::buildCalcExpressions( + const PropsParserContext& context, + const RawProps& rawProps, + const CalcExpressions& defaultValue) { + auto calcExpressions = defaultValue; + APPLY_CALC_YG_DIMENSION( + dimension, + setDimension, + "width", + "height", + CalcExpressionPropertyID::Width, + CalcExpressionPropertyID::Height) + APPLY_CALC_YG_DIMENSION( + minDimension, + setMinDimension, + "minWidth", + "minHeight", + CalcExpressionPropertyID::MinWidth, + CalcExpressionPropertyID::MinHeight) + APPLY_CALC_YG_DIMENSION( + maxDimension, + setMaxDimension, + "maxWidth", + "maxHeight", + CalcExpressionPropertyID::MaxWidth, + CalcExpressionPropertyID::MaxHeight) + APPLY_CALC_YG_FIELD( + flexBasis, + setFlexBasis, + "flexBasis", + yoga::StyleSizeLength, + CalcExpressionPropertyID::FlexBasis) + APPLY_CALC_YG_GUTTER() + APPLY_CALC_YG_EDGES_POSITION() + APPLY_CALC_YG_EDGES_MARGIN(margin, setMargin, yoga::StyleLength, "margin") + APPLY_CALC_YG_EDGES_PADDING(padding, setPadding, yoga::StyleLength, "padding") + return calcExpressions; +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.h b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.h index 6febf08d5ce4..2c5cc67cb25c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.h @@ -9,8 +9,10 @@ #include +#include #include #include +#include #include namespace facebook::react { @@ -57,6 +59,8 @@ class YogaStylableProps : public Props { yoga::Style::Length paddingBlockStart; yoga::Style::Length paddingBlockEnd; + CalcExpressions calcExpressions; + #if RN_DEBUG_STRING_CONVERTIBLE #pragma mark - DebugStringConvertible (Partial) @@ -70,6 +74,11 @@ class YogaStylableProps : public Props { const PropsParserContext &context, const YogaStylableProps &sourceProps, const RawProps &rawProps); + + CalcExpressions buildCalcExpressions( + const PropsParserContext &context, + const RawProps &rawProps, + const CalcExpressions &defaultValue); }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h index aa7e385229f6..778ae58d5047 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -253,4 +254,46 @@ inline bool areBorderRadiiCircular(const BorderRadii &borderRadii) return borderRadii.isUniform() && borderRadii.topLeft.horizontal == borderRadii.topLeft.vertical; } +enum class CalcExpressionPropertyID : uint8_t { + Width, + Height, + MinWidth, + MinHeight, + MaxWidth, + MaxHeight, + FlexBasis, + RowGap, + ColumnGap, + Gap, + Left, + Top, + Right, + Bottom, + Start, + End, + InsetInline, + InsetBlock, + Inset, + MarginLeft, + MarginTop, + MarginRight, + MarginBottom, + MarginStart, + MarginEnd, + MarginHorizontal, + MarginVertical, + MarginAll, + PaddingLeft, + PaddingTop, + PaddingRight, + PaddingBottom, + PaddingStart, + PaddingEnd, + PaddingHorizontal, + PaddingVertical, + PaddingAll, +}; + +using CalcExpressions = std::unordered_map; + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h b/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h index 37fcc87ca379..1286fb506735 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h +++ b/packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h @@ -69,6 +69,10 @@ inline folly::dynamic toDynamic(const YGValue &dimension) return dimension.value; case YGUnitPercent: return std::format("{}%", dimension.value); + case YGUnitDynamic: + // YGValue do not support YGUnitDynamic yet. + // Return placeholder that won't parse as valid calc. + return "calc(dynamic)"; } return nullptr; diff --git a/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h b/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h new file mode 100644 index 000000000000..caf95b96af53 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h @@ -0,0 +1,327 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook::react { + +/** + * Representation of CSS calc() function. + * https://www.w3.org/TR/css-values-4/#calc-func + */ +struct CSSCalc { + float px{0.0f}; + float percent{0.0f}; + float vw{0.0f}; + float vh{0.0f}; + bool unitless{false}; + + constexpr auto operator==(const CSSCalc& rhs) const -> bool = default; + + constexpr auto operator+(const CSSCalc& rhs) const -> CSSCalc { + return CSSCalc{ + px + rhs.px, + percent + rhs.percent, + vw + rhs.vw, + vh + rhs.vh, + unitless && rhs.unitless}; + } + + constexpr auto operator-(const CSSCalc& rhs) const -> CSSCalc { + return CSSCalc{ + px - rhs.px, + percent - rhs.percent, + vw - rhs.vw, + vh - rhs.vh, + unitless && rhs.unitless}; + } + + constexpr auto operator*(float scalar) const -> CSSCalc { + return CSSCalc{ + px * scalar, percent * scalar, vw * scalar, vh * scalar, unitless}; + } + + constexpr auto operator/(float scalar) const -> CSSCalc { + if (scalar == 0.0f) { + return CSSCalc{}; + } + return CSSCalc{ + px / scalar, percent / scalar, vw / scalar, vh / scalar, unitless}; + } + + constexpr auto operator-() const -> CSSCalc { + return CSSCalc{-px, -percent, -vw, -vh, unitless}; + } + + auto resolve(float percentRef, float viewportWidth, float viewportHeight) + const -> float { + return px + (percent * percentRef * 0.01f) + (vw * viewportWidth * 0.01f) + + (vh * viewportHeight * 0.01f); + } + + constexpr auto isUnitless() const -> bool { + return unitless; + } + + constexpr auto isPointsOnly() const -> bool { + return percent == 0.0f && vw == 0.0f && vh == 0.0f && !unitless; + } + + constexpr auto isPercentOnly() const -> bool { + return px == 0.0f && vw == 0.0f && vh == 0.0f && !unitless; + } + + constexpr auto isZero() const -> bool { + return px == 0.0f && percent == 0.0f && vw == 0.0f && vh == 0.0f; + } + + static constexpr auto fromNumber(float value) -> CSSCalc { + return CSSCalc{value, 0.0f, 0.0f, 0.0f, true}; + } + + static constexpr auto fromPoints(float value) -> CSSCalc { + return CSSCalc{value, 0.0f, 0.0f, 0.0f, false}; + } + + static constexpr auto fromPercent(float value) -> CSSCalc { + return CSSCalc{0.0f, value, 0.0f, 0.0f, false}; + } + + static constexpr auto fromVw(float value) -> CSSCalc { + return CSSCalc{0.0f, 0.0f, value, 0.0f, false}; + } + + static constexpr auto fromVh(float value) -> CSSCalc { + return CSSCalc{0.0f, 0.0f, 0.0f, value, false}; + } + + static constexpr auto fromLength(float value, CSSLengthUnit unit) + -> std::optional { + switch (unit) { + case CSSLengthUnit::Px: + return fromPoints(value); + case CSSLengthUnit::Vw: + return fromVw(value); + case CSSLengthUnit::Vh: + return fromVh(value); + default: + return std::nullopt; + } + } +}; + +template <> +struct CSSDataTypeParser { + static constexpr auto consumeFunctionBlock( + const CSSFunctionBlock& func, + CSSValueParser& parser) -> std::optional { + if (!iequals(func.name, "calc")) { + return std::nullopt; + } + + return parseCalcExpression(parser); + } + + static constexpr auto parseCalcExpression(CSSValueParser& parser) + -> std::optional { + parser.syntaxParser().consumeWhitespace(); + auto result = parseAddSub(parser); + parser.syntaxParser().consumeWhitespace(); + return result; + } + + static constexpr auto consumeSimpleBlock( + const CSSSimpleBlock& block, + CSSValueParser& parser) -> std::optional { + if (block.openBracketType != CSSTokenType::OpenParen) { + return std::nullopt; + } + + return parseCalcContents(parser); + } + + private: + static constexpr auto parseAddSub(CSSValueParser& parser) + -> std::optional { + auto left = parseMulDiv(parser); + if (!left) { + return std::nullopt; + } + + while (true) { + auto savedParser = parser.syntaxParser(); + parser.syntaxParser().consumeWhitespace(); + + auto opResult = + parser.syntaxParser().consumeComponentValue>( + CSSDelimiter::None, [](const CSSPreservedToken& token) { + if (token.type() == CSSTokenType::Delim) { + auto sv = token.stringValue(); + if (!sv.empty() && (sv[0] == '+' || sv[0] == '-')) { + return std::optional{sv[0]}; + } + } + return std::optional{}; + }); + + if (!opResult) { + parser.syntaxParser() = savedParser; + break; + } + + parser.syntaxParser().consumeWhitespace(); + auto right = parseMulDiv(parser); + if (!right) { + return std::nullopt; + } + + if (left->isUnitless() != right->isUnitless()) { + return std::nullopt; + } + + if (*opResult == '+') { + left = *left + *right; + } else { + left = *left - *right; + } + } + + return left; + } + + static constexpr auto parseMulDiv(CSSValueParser& parser) + -> std::optional { + auto left = parseUnary(parser); + if (!left) { + return std::nullopt; + } + + while (true) { + auto savedParser = parser.syntaxParser(); + parser.syntaxParser().consumeWhitespace(); + + auto opResult = + parser.syntaxParser().consumeComponentValue>( + CSSDelimiter::None, [](const CSSPreservedToken& token) { + if (token.type() == CSSTokenType::Delim) { + auto sv = token.stringValue(); + if (!sv.empty() && (sv[0] == '*' || sv[0] == '/')) { + return std::optional{sv[0]}; + } + } + return std::optional{}; + }); + + if (!opResult) { + parser.syntaxParser() = savedParser; + break; + } + + parser.syntaxParser().consumeWhitespace(); + auto right = parseUnary(parser); + if (!right) { + return std::nullopt; + } + + if (*opResult == '*') { + if (right->isUnitless()) { + left = *left * right->px; + } else if (left->isUnitless()) { + float scalar = left->px; + left = *right * scalar; + } else { + return std::nullopt; + } + } else { + if (!right->isUnitless() || right->px == 0.0f) { + return std::nullopt; + } + left = *left / right->px; + } + } + + return left; + } + + static constexpr auto parseUnary(CSSValueParser& parser) + -> std::optional { + auto savedParser = parser.syntaxParser(); + + auto opResult = + parser.syntaxParser().consumeComponentValue>( + CSSDelimiter::None, [](const CSSPreservedToken& token) { + if (token.type() == CSSTokenType::Delim) { + auto sv = token.stringValue(); + if (!sv.empty() && (sv[0] == '+' || sv[0] == '-')) { + return std::optional{sv[0]}; + } + } + return std::optional{}; + }); + + if (opResult) { + parser.syntaxParser().consumeWhitespace(); + auto value = parseUnary(parser); + if (!value) { + return std::nullopt; + } + return *opResult == '-' ? -*value : *value; + } + + parser.syntaxParser() = savedParser; + return parsePrimary(parser); + } + + static constexpr auto parsePrimary(CSSValueParser& parser) + -> std::optional { + auto value = + parser.parseNextValue(); + + if (std::holds_alternative(value)) { + return CSSCalc::fromNumber(std::get(value).value); + } + + if (std::holds_alternative(value)) { + return CSSCalc::fromPercent(std::get(value).value); + } + + if (std::holds_alternative(value)) { + const auto& length = std::get(value); + return CSSCalc::fromLength(length.value, length.unit); + } + + if (std::holds_alternative(value)) { + return std::get(value); + } + + return std::nullopt; + } + + static constexpr auto parseCalcContents(CSSValueParser& parser) + -> std::optional { + parser.syntaxParser().consumeWhitespace(); + auto result = parseAddSub(parser); + parser.syntaxParser().consumeWhitespace(); + return result; + } +}; + +static_assert(CSSDataType); + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/css/tests/CSSCalcTest.cpp b/packages/react-native/ReactCommon/react/renderer/css/tests/CSSCalcTest.cpp new file mode 100644 index 000000000000..dbbb3b33e290 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/css/tests/CSSCalcTest.cpp @@ -0,0 +1,419 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include + +namespace facebook::react { + +inline std::optional parseCalc(std::string_view css) { + auto result = parseCSSProperty(css); + if (std::holds_alternative(result)) { + return std::get(result); + } + return std::nullopt; +} + +TEST(CSSCalc, simple_pixel_value) { + auto result = parseCalc("calc(10px)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 10.0f); + EXPECT_FLOAT_EQ(result->percent, 0.0f); + EXPECT_FLOAT_EQ(result->vw, 0.0f); + EXPECT_FLOAT_EQ(result->vh, 0.0f); +} + +TEST(CSSCalc, simple_percentage_value) { + auto result = parseCalc("calc(50%)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 0.0f); + EXPECT_FLOAT_EQ(result->percent, 50.0f); + EXPECT_FLOAT_EQ(result->vw, 0.0f); + EXPECT_FLOAT_EQ(result->vh, 0.0f); +} + +TEST(CSSCalc, simple_vw_value) { + auto result = parseCalc("calc(100vw)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 0.0f); + EXPECT_FLOAT_EQ(result->percent, 0.0f); + EXPECT_FLOAT_EQ(result->vw, 100.0f); + EXPECT_FLOAT_EQ(result->vh, 0.0f); +} + +TEST(CSSCalc, simple_vh_value) { + auto result = parseCalc("calc(100vh)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 0.0f); + EXPECT_FLOAT_EQ(result->percent, 0.0f); + EXPECT_FLOAT_EQ(result->vw, 0.0f); + EXPECT_FLOAT_EQ(result->vh, 100.0f); +} + +TEST(CSSCalc, addition_same_units) { + auto result = parseCalc("calc(10px + 20px)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 30.0f); + EXPECT_FLOAT_EQ(result->percent, 0.0f); +} + +TEST(CSSCalc, subtraction_same_units) { + auto result = parseCalc("calc(50% - 20%)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 0.0f); + EXPECT_FLOAT_EQ(result->percent, 30.0f); +} + +TEST(CSSCalc, mixed_units_addition) { + auto result = parseCalc("calc(100% - 20px)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, -20.0f); + EXPECT_FLOAT_EQ(result->percent, 100.0f); + EXPECT_FLOAT_EQ(result->vw, 0.0f); + EXPECT_FLOAT_EQ(result->vh, 0.0f); +} + +TEST(CSSCalc, mixed_units_complex) { + auto result = parseCalc("calc(50% + 10px - 5vw + 2vh)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 10.0f); + EXPECT_FLOAT_EQ(result->percent, 50.0f); + EXPECT_FLOAT_EQ(result->vw, -5.0f); + EXPECT_FLOAT_EQ(result->vh, 2.0f); +} + +TEST(CSSCalc, multiplication_by_number) { + auto result = parseCalc("calc(50% * 2)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 0.0f); + EXPECT_FLOAT_EQ(result->percent, 100.0f); +} + +TEST(CSSCalc, number_times_unit) { + auto result = parseCalc("calc(2 * 50%)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 0.0f); + EXPECT_FLOAT_EQ(result->percent, 100.0f); +} + +TEST(CSSCalc, chained_unitless_products_then_length) { + auto result = parseCalc("calc(2 * 3 * 10px)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 60.0f); + EXPECT_FLOAT_EQ(result->percent, 0.0f); +} + +TEST(CSSCalc, unitless_division_then_length_multiplication) { + auto result = parseCalc("calc(10 / 2 * 5px)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 25.0f); + EXPECT_FLOAT_EQ(result->percent, 0.0f); +} + +TEST(CSSCalc, division_by_number) { + auto result = parseCalc("calc(100px / 4)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 25.0f); + EXPECT_FLOAT_EQ(result->percent, 0.0f); +} + +TEST(CSSCalc, complex_expression_with_precedence) { + auto result = parseCalc("calc((100% - 20px) * 2)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, -40.0f); + EXPECT_FLOAT_EQ(result->percent, 200.0f); +} + +TEST(CSSCalc, operator_precedence_mul_before_add) { + auto result = parseCalc("calc(10px + 20px * 2)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 50.0f); +} + +TEST(CSSCalc, nested_parentheses) { + auto result = parseCalc("calc(((10px)))"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 10.0f); +} + +TEST(CSSCalc, negative_values) { + auto result = parseCalc("calc(-10px)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, -10.0f); +} + +TEST(CSSCalc, unary_plus) { + auto result = parseCalc("calc(+20px)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 20.0f); +} + +TEST(CSSCalc, resolve_simple_percentage) { + auto result = parseCalc("calc(50%)"); + ASSERT_TRUE(result.has_value()); + float resolved = result->resolve(200.0f, 0.0f, 0.0f); + EXPECT_FLOAT_EQ(resolved, 100.0f); +} + +TEST(CSSCalc, resolve_mixed_units) { + auto result = parseCalc("calc(100% - 20px)"); + ASSERT_TRUE(result.has_value()); + float resolved = result->resolve(200.0f, 0.0f, 0.0f); + EXPECT_FLOAT_EQ(resolved, 180.0f); +} + +TEST(CSSCalc, resolve_with_viewport_units) { + auto result = parseCalc("calc(50vw + 10vh)"); + ASSERT_TRUE(result.has_value()); + float resolved = result->resolve(0.0f, 400.0f, 800.0f); + EXPECT_FLOAT_EQ(resolved, 280.0f); +} + +TEST(CSSCalc, resolve_all_units) { + auto result = parseCalc("calc(10px + 25% + 10vw + 5vh)"); + ASSERT_TRUE(result.has_value()); + float resolved = result->resolve(100.0f, 200.0f, 400.0f); + EXPECT_FLOAT_EQ(resolved, 75.0f); +} + +TEST(CSSCalc, invalid_expression_empty) { + auto result = parseCalc("calc()"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, invalid_multiplication_of_units) { + auto result = parseCalc("calc(10px * 20px)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, invalid_division_by_unit) { + auto result = parseCalc("calc(100px / 10px)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, division_by_zero) { + auto result = parseCalc("calc(100px / 0)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, invalid_addition_of_number_and_length) { + auto result = parseCalc("calc(1 + 10px)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, invalid_subtraction_of_percent_and_number) { + auto result = parseCalc("calc(100% - 2)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, invalid_trailing_operator) { + auto result = parseCalc("calc(10px +)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, invalid_missing_rhs_in_group) { + auto result = parseCalc("calc((10px +))"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, zero_is_parsed_as_number) { + auto result = parseCalc("calc(0 + 10px)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, whitespace_handling) { + auto result = parseCalc("calc( 100% - 20px )"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, -20.0f); + EXPECT_FLOAT_EQ(result->percent, 100.0f); +} + +TEST(CSSCalc, case_insensitive) { + auto result = parseCalc("CALC(10PX + 5VW)"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 10.0f); + EXPECT_FLOAT_EQ(result->vw, 5.0f); +} + +TEST(CSSCalc, addition_operator) { + CSSCalc a{10.0f, 20.0f, 5.0f, 2.0f, false}; + CSSCalc b{5.0f, 10.0f, 3.0f, 1.0f, false}; + auto result = a + b; + EXPECT_FLOAT_EQ(result.px, 15.0f); + EXPECT_FLOAT_EQ(result.percent, 30.0f); + EXPECT_FLOAT_EQ(result.vw, 8.0f); + EXPECT_FLOAT_EQ(result.vh, 3.0f); +} + +TEST(CSSCalc, subtraction_operator) { + CSSCalc a{10.0f, 20.0f, 5.0f, 2.0f, false}; + CSSCalc b{5.0f, 10.0f, 3.0f, 1.0f, false}; + auto result = a - b; + EXPECT_FLOAT_EQ(result.px, 5.0f); + EXPECT_FLOAT_EQ(result.percent, 10.0f); + EXPECT_FLOAT_EQ(result.vw, 2.0f); + EXPECT_FLOAT_EQ(result.vh, 1.0f); +} + +TEST(CSSCalc, multiplication_operator) { + CSSCalc a{10.0f, 20.0f, 5.0f, 2.0f, false}; + auto result = a * 2.0f; + EXPECT_FLOAT_EQ(result.px, 20.0f); + EXPECT_FLOAT_EQ(result.percent, 40.0f); + EXPECT_FLOAT_EQ(result.vw, 10.0f); + EXPECT_FLOAT_EQ(result.vh, 4.0f); +} + +TEST(CSSCalc, division_operator) { + CSSCalc a{20.0f, 40.0f, 10.0f, 4.0f, false}; + auto result = a / 2.0f; + EXPECT_FLOAT_EQ(result.px, 10.0f); + EXPECT_FLOAT_EQ(result.percent, 20.0f); + EXPECT_FLOAT_EQ(result.vw, 5.0f); + EXPECT_FLOAT_EQ(result.vh, 2.0f); +} + +TEST(CSSCalc, negation_operator) { + CSSCalc a{10.0f, 20.0f, 5.0f, 2.0f, false}; + auto result = -a; + EXPECT_FLOAT_EQ(result.px, -10.0f); + EXPECT_FLOAT_EQ(result.percent, -20.0f); + EXPECT_FLOAT_EQ(result.vw, -5.0f); + EXPECT_FLOAT_EQ(result.vh, -2.0f); +} + +TEST(CSSCalc, is_unitless) { + auto number = CSSCalc::fromNumber(10.0f); + EXPECT_TRUE(number.isUnitless()); + + auto points = CSSCalc::fromPoints(10.0f); + EXPECT_FALSE(points.isUnitless()); +} + +TEST(CSSCalc, is_points_only) { + auto pointsOnly = CSSCalc::fromPoints(10.0f); + EXPECT_TRUE(pointsOnly.isPointsOnly()); + + CSSCalc withPercent{10.0f, 5.0f, 0.0f, 0.0f, false}; + EXPECT_FALSE(withPercent.isPointsOnly()); + + auto number = CSSCalc::fromNumber(10.0f); + EXPECT_FALSE(number.isPointsOnly()); +} + +TEST(CSSCalc, is_percent_only) { + auto percentOnly = CSSCalc::fromPercent(50.0f); + EXPECT_TRUE(percentOnly.isPercentOnly()); + + CSSCalc withPx{10.0f, 50.0f, 0.0f, 0.0f, false}; + EXPECT_FALSE(withPx.isPercentOnly()); +} + +TEST(CSSCalc, is_zero) { + CSSCalc zero{0.0f, 0.0f, 0.0f, 0.0f, false}; + EXPECT_TRUE(zero.isZero()); + + CSSCalc nonZero{0.1f, 0.0f, 0.0f, 0.0f, false}; + EXPECT_FALSE(nonZero.isZero()); +} + +TEST(CSSCalc, from_points) { + auto result = CSSCalc::fromPoints(25.0f); + EXPECT_FLOAT_EQ(result.px, 25.0f); + EXPECT_FLOAT_EQ(result.percent, 0.0f); + EXPECT_FLOAT_EQ(result.vw, 0.0f); + EXPECT_FLOAT_EQ(result.vh, 0.0f); +} + +TEST(CSSCalc, from_percent) { + auto result = CSSCalc::fromPercent(75.0f); + EXPECT_FLOAT_EQ(result.px, 0.0f); + EXPECT_FLOAT_EQ(result.percent, 75.0f); + EXPECT_FLOAT_EQ(result.vw, 0.0f); + EXPECT_FLOAT_EQ(result.vh, 0.0f); +} + +TEST(CSSCalc, from_vw) { + auto result = CSSCalc::fromVw(30.0f); + EXPECT_FLOAT_EQ(result.px, 0.0f); + EXPECT_FLOAT_EQ(result.percent, 0.0f); + EXPECT_FLOAT_EQ(result.vw, 30.0f); + EXPECT_FLOAT_EQ(result.vh, 0.0f); +} + +TEST(CSSCalc, from_vh) { + auto result = CSSCalc::fromVh(45.0f); + EXPECT_FLOAT_EQ(result.px, 0.0f); + EXPECT_FLOAT_EQ(result.percent, 0.0f); + EXPECT_FLOAT_EQ(result.vw, 0.0f); + EXPECT_FLOAT_EQ(result.vh, 45.0f); +} + +TEST(CSSCalc, from_length) { + auto px = CSSCalc::fromLength(10.0f, CSSLengthUnit::Px); + ASSERT_TRUE(px.has_value()); + EXPECT_FLOAT_EQ(px->px, 10.0f); + EXPECT_FLOAT_EQ(px->percent, 0.0f); + + auto vw = CSSCalc::fromLength(50.0f, CSSLengthUnit::Vw); + ASSERT_TRUE(vw.has_value()); + EXPECT_FLOAT_EQ(vw->vw, 50.0f); + + auto vh = CSSCalc::fromLength(25.0f, CSSLengthUnit::Vh); + ASSERT_TRUE(vh.has_value()); + EXPECT_FLOAT_EQ(vh->vh, 25.0f); + + auto unsupported = CSSCalc::fromLength(10.0f, CSSLengthUnit::Em); + EXPECT_FALSE(unsupported.has_value()); +} + +TEST(CSSCalc, division_by_zero_operator) { + CSSCalc a{100.0f, 0.0f, 0.0f, 0.0f, false}; + auto result = a / 0.0f; + EXPECT_TRUE(result.isZero()); +} + +TEST(CSSCalc, negation_preserves_unitless) { + auto unitless = CSSCalc::fromNumber(5.0f); + auto negated = -unitless; + EXPECT_TRUE(negated.isUnitless()); + EXPECT_FLOAT_EQ(negated.px, -5.0f); +} + +TEST(CSSCalc, nested_calc) { + auto result = parseCalc("calc(calc(10px))"); + ASSERT_TRUE(result.has_value()); + EXPECT_FLOAT_EQ(result->px, 10.0f); +} + +TEST(CSSCalc, equality) { + CSSCalc a{10.0f, 20.0f, 5.0f, 2.0f, false}; + CSSCalc b{10.0f, 20.0f, 5.0f, 2.0f, false}; + CSSCalc c{10.0f, 20.0f, 5.0f, 2.0f, true}; + EXPECT_EQ(a, b); + EXPECT_NE(a, c); +} + +TEST(CSSCalc, invalid_wrong_function) { + auto result = parseCalc("min(10px)"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, invalid_missing_calc_function) { + auto result = parseCalc("10px"); + EXPECT_FALSE(result.has_value()); +} + +TEST(CSSCalc, is_zero_unitless) { + auto unitlessZero = CSSCalc::fromNumber(0.0f); + EXPECT_TRUE(unitlessZero.isZero()); + EXPECT_TRUE(unitlessZero.isUnitless()); +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp index 1e823138684a..05dab300acd5 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp @@ -285,6 +285,8 @@ const char* YGUnitToString(const YGUnit value) { return "fit-content"; case YGUnitStretch: return "stretch"; + case YGUnitDynamic: + return "dynamic"; } return "unknown"; } diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h index f96abdf2f58c..ce732b738f24 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGEnums.h @@ -151,7 +151,8 @@ YG_ENUM_DECL( YGUnitAuto, YGUnitMaxContent, YGUnitFitContent, - YGUnitStretch) + YGUnitStretch, + YGUnitDynamic) YG_ENUM_DECL( YGWrap, diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp index e43a38e64eb8..0f4866d7842c 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp @@ -226,6 +226,14 @@ void YGNodeStyleSetFlexBasisStretch(const YGNodeRef node) { node, StyleSizeLength::ofStretch()); } +void YGNodeStyleSetFlexBasisDynamic( + const YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().flexBasis(); } @@ -249,6 +257,15 @@ YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { return (YGValue)resolveRef(node)->style().position(scopedEnum(edge)); } +void YGNodeStyleSetPositionDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::position, &Style::setPosition>( + node, scopedEnum(edge), StyleLength::dynamic(callback, id)); +} + void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) { updateStyle<&Style::margin, &Style::setMargin>( node, scopedEnum(edge), StyleLength::points(points)); @@ -268,6 +285,15 @@ YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { return (YGValue)resolveRef(node)->style().margin(scopedEnum(edge)); } +void YGNodeStyleSetMarginDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::margin, &Style::setMargin>( + node, scopedEnum(edge), StyleLength::dynamic(callback, id)); +} + void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) { updateStyle<&Style::padding, &Style::setPadding>( node, scopedEnum(edge), StyleLength::points(points)); @@ -282,6 +308,15 @@ YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { return (YGValue)resolveRef(node)->style().padding(scopedEnum(edge)); } +void YGNodeStyleSetPaddingDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::padding, &Style::setPadding>( + node, scopedEnum(edge), StyleLength::dynamic(callback, id)); +} + void YGNodeStyleSetBorder( const YGNodeRef node, const YGEdge edge, @@ -299,6 +334,15 @@ float YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) { return static_cast(border).value; } +void YGNodeStyleSetBorderDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::border, &Style::setBorder>( + node, scopedEnum(edge), StyleLength::dynamic(callback, id)); +} + void YGNodeStyleSetGap( const YGNodeRef node, const YGGutter gutter, @@ -312,6 +356,15 @@ void YGNodeStyleSetGapPercent(YGNodeRef node, YGGutter gutter, float percent) { node, scopedEnum(gutter), StyleLength::percent(percent)); } +void YGNodeStyleSetGapDynamic( + YGNodeRef node, + YGGutter gutter, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::gap, &Style::setGap>( + node, scopedEnum(gutter), StyleLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetGap(const YGNodeConstRef node, const YGGutter gutter) { return (YGValue)resolveRef(node)->style().gap(scopedEnum(gutter)); } @@ -365,6 +418,14 @@ void YGNodeStyleSetWidthStretch(YGNodeRef node) { node, Dimension::Width, StyleSizeLength::ofStretch()); } +void YGNodeStyleSetWidthDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().dimension(Dimension::Width); } @@ -399,6 +460,14 @@ void YGNodeStyleSetHeightStretch(YGNodeRef node) { node, Dimension::Height, StyleSizeLength::ofStretch()); } +void YGNodeStyleSetHeightDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().dimension(Dimension::Height); } @@ -428,6 +497,14 @@ void YGNodeStyleSetMinWidthStretch(const YGNodeRef node) { node, Dimension::Width, StyleSizeLength::ofStretch()); } +void YGNodeStyleSetMinWidthDynamic( + const YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().minDimension(Dimension::Width); } @@ -459,6 +536,14 @@ void YGNodeStyleSetMinHeightStretch(const YGNodeRef node) { node, Dimension::Height, StyleSizeLength::ofStretch()); } +void YGNodeStyleSetMinHeightDynamic( + const YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().minDimension(Dimension::Height); } @@ -488,6 +573,14 @@ void YGNodeStyleSetMaxWidthStretch(const YGNodeRef node) { node, Dimension::Width, StyleSizeLength::ofStretch()); } +void YGNodeStyleSetMaxWidthDynamic( + const YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Width); } @@ -519,6 +612,14 @@ void YGNodeStyleSetMaxHeightStretch(const YGNodeRef node) { node, Dimension::Height, StyleSizeLength::ofStretch()); } +void YGNodeStyleSetMaxHeightDynamic( + const YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::dynamic(callback, id)); +} + YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Height); } diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h index a1c7e09561f8..b1785ba65a6f 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h @@ -75,6 +75,10 @@ YG_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node); YG_EXPORT void YGNodeStyleSetFlexBasisMaxContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetFlexBasisFitContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetFlexBasisStretch(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetFlexBasisDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node); YG_EXPORT void @@ -83,27 +87,53 @@ YG_EXPORT void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float position); YG_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge); YG_EXPORT void YGNodeStyleSetPositionAuto(YGNodeRef node, YGEdge edge); +YG_EXPORT void YGNodeStyleSetPositionDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float margin); YG_EXPORT void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, float margin); YG_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge); +YG_EXPORT void YGNodeStyleSetMarginDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge); YG_EXPORT void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float padding); YG_EXPORT void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float padding); +YG_EXPORT void YGNodeStyleSetPaddingDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge); YG_EXPORT void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, float border); +YG_EXPORT void YGNodeStyleSetBorderDynamic( + YGNodeRef node, + YGEdge edge, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT float YGNodeStyleGetBorder(YGNodeConstRef node, YGEdge edge); YG_EXPORT void YGNodeStyleSetGap(YGNodeRef node, YGGutter gutter, float gapLength); YG_EXPORT void YGNodeStyleSetGapPercent(YGNodeRef node, YGGutter gutter, float gapLength); +YG_EXPORT void YGNodeStyleSetGapDynamic( + YGNodeRef node, + YGGutter gutter, + YGValueDynamic callback, + YGValueDynamicID id); + YG_EXPORT YGValue YGNodeStyleGetGap(YGNodeConstRef node, YGGutter gutter); YG_EXPORT void YGNodeStyleSetBoxSizing(YGNodeRef node, YGBoxSizing boxSizing); @@ -115,6 +145,10 @@ YG_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node); YG_EXPORT void YGNodeStyleSetWidthMaxContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetWidthFitContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetWidthStretch(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetWidthDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, float height); @@ -123,6 +157,10 @@ YG_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node); YG_EXPORT void YGNodeStyleSetHeightMaxContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetHeightFitContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetHeightStretch(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetHeightDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMinWidth(YGNodeRef node, float minWidth); @@ -130,6 +168,10 @@ YG_EXPORT void YGNodeStyleSetMinWidthPercent(YGNodeRef node, float minWidth); YG_EXPORT void YGNodeStyleSetMinWidthMaxContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMinWidthFitContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMinWidthStretch(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinWidthDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetMinWidth(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMinHeight(YGNodeRef node, float minHeight); @@ -137,6 +179,10 @@ YG_EXPORT void YGNodeStyleSetMinHeightPercent(YGNodeRef node, float minHeight); YG_EXPORT void YGNodeStyleSetMinHeightMaxContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMinHeightFitContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMinHeightStretch(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinHeightDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetMinHeight(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMaxWidth(YGNodeRef node, float maxWidth); @@ -144,6 +190,10 @@ YG_EXPORT void YGNodeStyleSetMaxWidthPercent(YGNodeRef node, float maxWidth); YG_EXPORT void YGNodeStyleSetMaxWidthMaxContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMaxWidthFitContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMaxWidthStretch(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxWidthDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetMaxWidth(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetMaxHeight(YGNodeRef node, float maxHeight); @@ -151,6 +201,10 @@ YG_EXPORT void YGNodeStyleSetMaxHeightPercent(YGNodeRef node, float maxHeight); YG_EXPORT void YGNodeStyleSetMaxHeightMaxContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMaxHeightFitContent(YGNodeRef node); YG_EXPORT void YGNodeStyleSetMaxHeightStretch(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxHeightDynamic( + YGNodeRef node, + YGValueDynamic callback, + YGValueDynamicID id); YG_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node); YG_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, float aspectRatio); diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGValue.h b/packages/react-native/ReactCommon/yoga/yoga/YGValue.h index 138135229b96..56668806268f 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGValue.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGValue.h @@ -25,6 +25,8 @@ constexpr float YGUndefined = std::numeric_limits::quiet_NaN(); YG_EXTERN_C_BEGIN +typedef const struct YGNode* YGNodeConstRef; + /** * Structure used to represent a dimension in a style. */ @@ -53,6 +55,36 @@ YG_EXPORT extern const YGValue YGValueZero; */ YG_EXPORT bool YGFloatIsUndefined(float value); +/** + * Host-defined identifier for a dynamic style value. + */ +typedef uint8_t YGValueDynamicID; + +/** + * Layout context passed to YGValueDynamic for resolving dynamic values. + * May be extended with additional fields (e.g. containing block dimensions). + */ +typedef struct YGValueDynamicContext { + float referenceLength; +} YGValueDynamicContext; + +/** + * Called during layout to resolve a dynamic style value (e.g. calc()). + * Must return a YGValue with unit YGUnitPoint. + */ +typedef YGValue (*YGValueDynamic)( + YGNodeConstRef node, + YGValueDynamicID id, + YGValueDynamicContext context); + +/** + * Callback + identifier pair for internal storage. + */ +struct YGValueDynamicData { + YGValueDynamic callback; + YGValueDynamicID id; +}; + YG_EXTERN_C_END // Equality operators for comparison of YGValue in C++ @@ -72,6 +104,7 @@ inline bool operator==(const YGValue& lhs, const YGValue& rhs) { case YGUnitPoint: case YGUnitPercent: return lhs.value == rhs.value; + case YGUnitDynamic: default: return false; } diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp index a7d15773fc64..93658be87525 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp @@ -20,7 +20,7 @@ static inline void setFlexStartLayoutPosition( const FlexDirection axis, const float containingBlockWidth) { float position = child->style().computeFlexStartMargin( - axis, direction, containingBlockWidth) + + axis, direction, containingBlockWidth, child) + parent->getLayout().border(flexStartEdge(axis)); // https://www.w3.org/TR/css-grid-1/#abspos @@ -42,7 +42,7 @@ static inline void setFlexEndLayoutPosition( const float containingBlockWidth) { float flexEndPosition = parent->getLayout().border(flexEndEdge(axis)) + child->style().computeFlexEndMargin( - axis, direction, containingBlockWidth); + axis, direction, containingBlockWidth, child); // https://www.w3.org/TR/css-grid-1/#abspos // absolute positioned grid items are positioned relative to the padding edge @@ -79,12 +79,12 @@ static inline void setCenterLayoutPosition( const float childOuterSize = child->getLayout().measuredDimension(dimension(axis)) + - child->style().computeMarginForAxis(axis, containingBlockWidth); + child->style().computeMarginForAxis(axis, containingBlockWidth, child); float position = (parentContentBoxSize - childOuterSize) / 2.0f + parent->getLayout().border(flexStartEdge(axis)) + child->style().computeFlexStartMargin( - axis, direction, containingBlockWidth); + axis, direction, containingBlockWidth, child); // https://www.w3.org/TR/css-grid-1/#abspos // absolute positioned grid items are positioned relative to the padding edge @@ -210,10 +210,11 @@ static void positionAbsoluteChild( !child->style().isInlineStartPositionAuto(axis, direction)) { const float positionRelativeToInlineStart = child->style().computeInlineStartPosition( - axis, direction, containingBlockSize) + - containingNode->style().computeInlineStartBorder(axis, direction) + + axis, direction, containingBlockSize, child) + + containingNode->style().computeInlineStartBorder( + axis, direction, containingNode) + child->style().computeInlineStartMargin( - axis, direction, containingBlockSize); + axis, direction, containingBlockSize, child); const float positionRelativeToFlexStart = inlineStartEdge(axis, direction) != flexStartEdge(axis) ? getPositionOfOppositeEdge( @@ -227,11 +228,12 @@ static void positionAbsoluteChild( const float positionRelativeToInlineStart = containingNode->getLayout().measuredDimension(dimension(axis)) - child->getLayout().measuredDimension(dimension(axis)) - - containingNode->style().computeInlineEndBorder(axis, direction) - + containingNode->style().computeInlineEndBorder( + axis, direction, containingNode) - child->style().computeInlineEndMargin( - axis, direction, containingBlockSize) - + axis, direction, containingBlockSize, child) - child->style().computeInlineEndPosition( - axis, direction, containingBlockSize); + axis, direction, containingBlockSize, child); const float positionRelativeToFlexStart = inlineStartEdge(axis, direction) != flexStartEdge(axis) ? getPositionOfOppositeEdge( @@ -275,9 +277,9 @@ void layoutAbsoluteChild( SizingMode childHeightSizingMode = SizingMode::MaxContent; auto marginRow = child->style().computeMarginForAxis( - FlexDirection::Row, containingBlockWidth); + FlexDirection::Row, containingBlockWidth, child); auto marginColumn = child->style().computeMarginForAxis( - FlexDirection::Column, containingBlockWidth); + FlexDirection::Column, containingBlockWidth, child); if (child->hasDefiniteLength(Dimension::Width, containingBlockWidth)) { childWidth = child @@ -301,13 +303,13 @@ void layoutAbsoluteChild( childWidth = containingNode->getLayout().measuredDimension(Dimension::Width) - (containingNode->style().computeFlexStartBorder( - FlexDirection::Row, direction) + + FlexDirection::Row, direction, containingNode) + containingNode->style().computeFlexEndBorder( - FlexDirection::Row, direction)) - + FlexDirection::Row, direction, containingNode)) - (child->style().computeFlexStartPosition( - FlexDirection::Row, direction, containingBlockWidth) + + FlexDirection::Row, direction, containingBlockWidth, child) + child->style().computeFlexEndPosition( - FlexDirection::Row, direction, containingBlockWidth)); + FlexDirection::Row, direction, containingBlockWidth, child)); childWidth = boundAxis( child, FlexDirection::Row, @@ -341,13 +343,13 @@ void layoutAbsoluteChild( childHeight = containingNode->getLayout().measuredDimension(Dimension::Height) - (containingNode->style().computeFlexStartBorder( - FlexDirection::Column, direction) + + FlexDirection::Column, direction, containingNode) + containingNode->style().computeFlexEndBorder( - FlexDirection::Column, direction)) - + FlexDirection::Column, direction, containingNode)) - (child->style().computeFlexStartPosition( - FlexDirection::Column, direction, containingBlockHeight) + + FlexDirection::Column, direction, containingBlockHeight, child) + child->style().computeFlexEndPosition( - FlexDirection::Column, direction, containingBlockHeight)); + FlexDirection::Column, direction, containingBlockHeight, child)); childHeight = boundAxis( child, FlexDirection::Column, @@ -410,10 +412,10 @@ void layoutAbsoluteChild( generationCount); childWidth = child->getLayout().measuredDimension(Dimension::Width) + child->style().computeMarginForAxis( - FlexDirection::Row, containingBlockWidth); + FlexDirection::Row, containingBlockWidth, child); childHeight = child->getLayout().measuredDimension(Dimension::Height) + child->style().computeMarginForAxis( - FlexDirection::Column, containingBlockWidth); + FlexDirection::Column, containingBlockWidth, child); } calculateLayoutInternal( @@ -473,12 +475,13 @@ bool layoutAbsoluteDescendants( const float containingBlockWidth = absoluteErrata ? containingNodeAvailableInnerWidth : containingNode->getLayout().measuredDimension(Dimension::Width) - - containingNode->style().computeBorderForAxis(FlexDirection::Row); + containingNode->style().computeBorderForAxis( + FlexDirection::Row, containingNode); const float containingBlockHeight = absoluteErrata ? containingNodeAvailableInnerHeight : containingNode->getLayout().measuredDimension(Dimension::Height) - containingNode->style().computeBorderForAxis( - FlexDirection::Column); + FlexDirection::Column, containingNode); layoutAbsoluteChild( containingNode, diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h b/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h index d9ebc68c5b3c..f90b1ad2bc97 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h @@ -22,9 +22,9 @@ inline float paddingAndBorderForAxis( const Direction direction, const float widthSize) { return node->style().computeInlineStartPaddingAndBorder( - axis, direction, widthSize) + + axis, direction, widthSize, node) + node->style().computeInlineEndPaddingAndBorder( - axis, direction, widthSize); + axis, direction, widthSize, node); } inline FloatOptional boundAxisWithinMinAndMax( @@ -39,14 +39,14 @@ inline FloatOptional boundAxisWithinMinAndMax( if (isColumn(axis)) { min = node->style().resolvedMinDimension( - direction, Dimension::Height, axisSize, widthSize); + direction, Dimension::Height, axisSize, widthSize, node); max = node->style().resolvedMaxDimension( - direction, Dimension::Height, axisSize, widthSize); + direction, Dimension::Height, axisSize, widthSize, node); } else if (isRow(axis)) { min = node->style().resolvedMinDimension( - direction, Dimension::Width, axisSize, widthSize); + direction, Dimension::Width, axisSize, widthSize, node); max = node->style().resolvedMaxDimension( - direction, Dimension::Width, axisSize, widthSize); + direction, Dimension::Width, axisSize, widthSize, node); } if (max >= FloatOptional{0} && value > max) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index e9d62492daae..35df145ac0e4 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -45,8 +45,8 @@ void constrainMaxSizeForMode( /*in_out*/ float* size) { const FloatOptional maxSize = node->style().resolvedMaxDimension( - direction, dimension(axis), ownerAxisSize, ownerWidth) + - FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth)); + direction, dimension(axis), ownerAxisSize, ownerWidth, node) + + FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth, node)); switch (*mode) { case SizingMode::StretchFit: case SizingMode::FitContent: @@ -142,10 +142,10 @@ static void computeFlexBasisForChild( childWidthSizingMode = SizingMode::MaxContent; childHeightSizingMode = SizingMode::MaxContent; - auto marginRow = - child->style().computeMarginForAxis(FlexDirection::Row, ownerWidth); - auto marginColumn = - child->style().computeMarginForAxis(FlexDirection::Column, ownerWidth); + auto marginRow = child->style().computeMarginForAxis( + FlexDirection::Row, ownerWidth, child); + auto marginColumn = child->style().computeMarginForAxis( + FlexDirection::Column, ownerWidth, child); if (isRowStyleDimDefined) { childWidth = child @@ -554,14 +554,14 @@ float calculateAvailableInnerDimension( // constraints const FloatOptional minDimensionOptional = node->style().resolvedMinDimension( - direction, dimension, ownerDim, ownerWidth); + direction, dimension, ownerDim, ownerWidth, node); const float minInnerDim = minDimensionOptional.isUndefined() ? 0.0f : minDimensionOptional.unwrap() - paddingAndBorder; const FloatOptional maxDimensionOptional = node->style().resolvedMaxDimension( - direction, dimension, ownerDim, ownerWidth); + direction, dimension, ownerDim, ownerWidth, node); const float maxInnerDim = maxDimensionOptional.isUndefined() ? FLT_MAX @@ -660,7 +660,8 @@ static float computeFlexBasisForChildren( totalOuterFlexBasis += (child->getLayout().computedFlexBasis.unwrap() + - child->style().computeMarginForAxis(mainAxis, availableInnerWidth)); + child->style().computeMarginForAxis( + mainAxis, availableInnerWidth, child)); } return totalOuterFlexBasis; @@ -985,9 +986,9 @@ static float distributeFreeSpaceSecondPass( deltaFreeSpace += updatedMainSize - childFlexBasis; const float marginMain = currentLineChild->style().computeMarginForAxis( - mainAxis, availableInnerWidth); + mainAxis, availableInnerWidth, currentLineChild); const float marginCross = currentLineChild->style().computeMarginForAxis( - crossAxis, availableInnerWidth); + crossAxis, availableInnerWidth, currentLineChild); float childCrossSize = YGUndefined; float childMainSize = updatedMainSize + marginMain; @@ -1302,13 +1303,13 @@ static void justifyMainAxis( const float leadingPaddingAndBorderMain = node->style().computeFlexStartPaddingAndBorder( - mainAxis, direction, ownerWidth); + mainAxis, direction, ownerWidth, node); const float trailingPaddingAndBorderMain = node->style().computeFlexEndPaddingAndBorder( - mainAxis, direction, ownerWidth); + mainAxis, direction, ownerWidth, node); const float gap = - node->style().computeGapForAxis(mainAxis, availableInnerMainDim); + node->style().computeGapForAxis(mainAxis, availableInnerMainDim, node); // If we are using "at most" rules in the main axis, make sure that // remainingFreeSpace is 0 when min main dimension is not given if (sizingModeMainDim == SizingMode::FitContent && @@ -1316,7 +1317,11 @@ static void justifyMainAxis( if (style.minDimension(dimension(mainAxis)).isDefined() && style .resolvedMinDimension( - direction, dimension(mainAxis), mainAxisOwnerSize, ownerWidth) + direction, + dimension(mainAxis), + mainAxisOwnerSize, + ownerWidth, + node) .isDefined()) { // This condition makes sure that if the size of main dimension(after // considering child nodes main dim, leading and trailing padding etc) @@ -1325,11 +1330,14 @@ static void justifyMainAxis( // `minAvailableMainDim` denotes minimum available space in which child // can be laid out, it will exclude space consumed by padding and border. - const float minAvailableMainDim = - style - .resolvedMinDimension( - direction, dimension(mainAxis), mainAxisOwnerSize, ownerWidth) - .unwrap() - + const float minAvailableMainDim = style + .resolvedMinDimension( + direction, + dimension(mainAxis), + mainAxisOwnerSize, + ownerWidth, + node) + .unwrap() - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; const float occupiedSpaceByChildNodes = availableInnerMainDim - flexLine.layout.remainingFreeSpace; @@ -1424,8 +1432,8 @@ static void justifyMainAxis( // If we skipped the flex step, then we can't rely on the measuredDims // because they weren't computed. This means we can't call // dimensionWithMargin. - flexLine.layout.mainDim += - child->style().computeMarginForAxis(mainAxis, availableInnerWidth) + + flexLine.layout.mainDim += child->style().computeMarginForAxis( + mainAxis, availableInnerWidth, child) + boundAxisWithinMinAndMax( child, direction, @@ -1446,11 +1454,11 @@ static void justifyMainAxis( // calculated by adding maxAscent and maxDescent from the baseline. const float ascent = calculateBaseline(child) + child->style().computeFlexStartMargin( - FlexDirection::Column, direction, availableInnerWidth); + FlexDirection::Column, direction, availableInnerWidth, child); const float descent = child->getLayout().measuredDimension(Dimension::Height) + child->style().computeMarginForAxis( - FlexDirection::Column, availableInnerWidth) - + FlexDirection::Column, availableInnerWidth, child) - ascent; maxAscentForCurrentLine = @@ -1577,49 +1585,51 @@ static void calculateLayoutImpl( direction == Direction::LTR ? PhysicalEdge::Right : PhysicalEdge::Left; const float marginRowLeading = node->style().computeInlineStartMargin( - flexRowDirection, direction, ownerWidth); + flexRowDirection, direction, ownerWidth, node); node->setLayoutMargin(marginRowLeading, startEdge); const float marginRowTrailing = node->style().computeInlineEndMargin( - flexRowDirection, direction, ownerWidth); + flexRowDirection, direction, ownerWidth, node); node->setLayoutMargin(marginRowTrailing, endEdge); const float marginColumnLeading = node->style().computeInlineStartMargin( - flexColumnDirection, direction, ownerWidth); + flexColumnDirection, direction, ownerWidth, node); node->setLayoutMargin(marginColumnLeading, PhysicalEdge::Top); const float marginColumnTrailing = node->style().computeInlineEndMargin( - flexColumnDirection, direction, ownerWidth); + flexColumnDirection, direction, ownerWidth, node); node->setLayoutMargin(marginColumnTrailing, PhysicalEdge::Bottom); const float marginAxisRow = marginRowLeading + marginRowTrailing; const float marginAxisColumn = marginColumnLeading + marginColumnTrailing; node->setLayoutBorder( - node->style().computeInlineStartBorder(flexRowDirection, direction), + node->style().computeInlineStartBorder(flexRowDirection, direction, node), startEdge); node->setLayoutBorder( - node->style().computeInlineEndBorder(flexRowDirection, direction), + node->style().computeInlineEndBorder(flexRowDirection, direction, node), endEdge); node->setLayoutBorder( - node->style().computeInlineStartBorder(flexColumnDirection, direction), + node->style().computeInlineStartBorder( + flexColumnDirection, direction, node), PhysicalEdge::Top); node->setLayoutBorder( - node->style().computeInlineEndBorder(flexColumnDirection, direction), + node->style().computeInlineEndBorder( + flexColumnDirection, direction, node), PhysicalEdge::Bottom); node->setLayoutPadding( node->style().computeInlineStartPadding( - flexRowDirection, direction, ownerWidth), + flexRowDirection, direction, ownerWidth, node), startEdge); node->setLayoutPadding( node->style().computeInlineEndPadding( - flexRowDirection, direction, ownerWidth), + flexRowDirection, direction, ownerWidth, node), endEdge); node->setLayoutPadding( node->style().computeInlineStartPadding( - flexColumnDirection, direction, ownerWidth), + flexColumnDirection, direction, ownerWidth, node), PhysicalEdge::Top); node->setLayoutPadding( node->style().computeInlineEndPadding( - flexColumnDirection, direction, ownerWidth), + flexColumnDirection, direction, ownerWidth, node), PhysicalEdge::Bottom); if (node->hasMeasureFunc()) { @@ -1703,7 +1713,7 @@ static void calculateLayoutImpl( paddingAndBorderForAxis(node, crossAxis, direction, ownerWidth); const float leadingPaddingAndBorderCross = node->style().computeFlexStartPaddingAndBorder( - crossAxis, direction, ownerWidth); + crossAxis, direction, ownerWidth, node); SizingMode sizingModeMainDim = isMainAxisRow ? widthSizingMode : heightSizingMode; @@ -1799,7 +1809,7 @@ static void calculateLayoutImpl( if (childCount > 1) { totalMainDim += - node->style().computeGapForAxis(mainAxis, availableInnerMainDim) * + node->style().computeGapForAxis(mainAxis, availableInnerMainDim, node) * static_cast(childCount - 1); } @@ -1824,7 +1834,7 @@ static void calculateLayoutImpl( float totalLineCrossDim = 0; const float crossAxisGap = - node->style().computeGapForAxis(crossAxis, availableInnerCrossDim); + node->style().computeGapForAxis(crossAxis, availableInnerCrossDim, node); // Max main dimension of all the lines. float maxLineMainDim = 0; @@ -1857,25 +1867,25 @@ static void calculateLayoutImpl( const float minInnerWidth = style .resolvedMinDimension( - direction, Dimension::Width, ownerWidth, ownerWidth) + direction, Dimension::Width, ownerWidth, ownerWidth, node) .unwrap() - paddingAndBorderAxisRow; const float maxInnerWidth = style .resolvedMaxDimension( - direction, Dimension::Width, ownerWidth, ownerWidth) + direction, Dimension::Width, ownerWidth, ownerWidth, node) .unwrap() - paddingAndBorderAxisRow; const float minInnerHeight = style .resolvedMinDimension( - direction, Dimension::Height, ownerHeight, ownerWidth) + direction, Dimension::Height, ownerHeight, ownerWidth, node) .unwrap() - paddingAndBorderAxisColumn; const float maxInnerHeight = style .resolvedMaxDimension( - direction, Dimension::Height, ownerHeight, ownerWidth) + direction, Dimension::Height, ownerHeight, ownerWidth, node) .unwrap() - paddingAndBorderAxisColumn; @@ -2030,14 +2040,14 @@ static void calculateLayoutImpl( const auto& childStyle = child->style(); float childCrossSize = childStyle.aspectRatio().isDefined() ? child->style().computeMarginForAxis( - crossAxis, availableInnerWidth) + + crossAxis, availableInnerWidth, child) + (isMainAxisRow ? childMainSize / childStyle.aspectRatio().unwrap() : childMainSize * childStyle.aspectRatio().unwrap()) : flexLine.layout.crossDim; childMainSize += child->style().computeMarginForAxis( - mainAxis, availableInnerWidth); + mainAxis, availableInnerWidth, child); SizingMode childMainSizingMode = SizingMode::StretchFit; SizingMode childCrossSizingMode = SizingMode::StretchFit; @@ -2220,16 +2230,19 @@ static void calculateLayoutImpl( lineHeight, child->getLayout().measuredDimension(dimension(crossAxis)) + child->style().computeMarginForAxis( - crossAxis, availableInnerWidth)); + crossAxis, availableInnerWidth, child)); } if (resolveChildAlignment(node, child) == Align::Baseline) { const float ascent = calculateBaseline(child) + child->style().computeFlexStartMargin( - FlexDirection::Column, direction, availableInnerWidth); + FlexDirection::Column, + direction, + availableInnerWidth, + child); const float descent = child->getLayout().measuredDimension(Dimension::Height) + child->style().computeMarginForAxis( - FlexDirection::Column, availableInnerWidth) - + FlexDirection::Column, availableInnerWidth, child) - ascent; maxAscentForCurrentLine = yoga::maxOrDefined(maxAscentForCurrentLine, ascent); @@ -2259,7 +2272,7 @@ static void calculateLayoutImpl( child->setLayoutPosition( currentLead + child->style().computeFlexStartPosition( - crossAxis, direction, availableInnerWidth), + crossAxis, direction, availableInnerWidth, child), flexStartEdge(crossAxis)); break; } @@ -2267,7 +2280,7 @@ static void calculateLayoutImpl( child->setLayoutPosition( currentLead + lineHeight - child->style().computeFlexEndMargin( - crossAxis, direction, availableInnerWidth) - + crossAxis, direction, availableInnerWidth, child) - child->getLayout().measuredDimension( dimension(crossAxis)), flexStartEdge(crossAxis)); @@ -2286,7 +2299,7 @@ static void calculateLayoutImpl( child->setLayoutPosition( currentLead + child->style().computeFlexStartMargin( - crossAxis, direction, availableInnerWidth), + crossAxis, direction, availableInnerWidth, child), flexStartEdge(crossAxis)); // Remeasure child with the line height as it as been only @@ -2296,13 +2309,13 @@ static void calculateLayoutImpl( const float childWidth = isMainAxisRow ? (child->getLayout().measuredDimension(Dimension::Width) + child->style().computeMarginForAxis( - mainAxis, availableInnerWidth)) + mainAxis, availableInnerWidth, child)) : leadPerLine + lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout().measuredDimension(Dimension::Height) + child->style().computeMarginForAxis( - crossAxis, availableInnerWidth)) + crossAxis, availableInnerWidth, child)) : leadPerLine + lineHeight; if (!(yoga::inexactEquals( @@ -2338,7 +2351,8 @@ static void calculateLayoutImpl( child->style().computeFlexStartPosition( FlexDirection::Column, direction, - availableInnerCrossDim), + availableInnerCrossDim, + child), PhysicalEdge::Top); break; @@ -2560,10 +2574,10 @@ bool calculateLayoutInternal( // they are the most expensive to measure, so it's worth avoiding redundant // measurements if at all possible. if (node->hasMeasureFunc()) { - const float marginAxisRow = - node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth); - const float marginAxisColumn = - node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth); + const float marginAxisRow = node->style().computeMarginForAxis( + FlexDirection::Row, ownerWidth, node); + const float marginAxisColumn = node->style().computeMarginForAxis( + FlexDirection::Column, ownerWidth, node); // First, try to use the layout cache. if (canUseCachedMeasurement( @@ -2738,15 +2752,16 @@ void calculateLayout( ownerWidth, ownerWidth) .unwrap() + - node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth)); + node->style().computeMarginForAxis( + FlexDirection::Row, ownerWidth, node)); widthSizingMode = SizingMode::StretchFit; } else if (style .resolvedMaxDimension( - direction, Dimension::Width, ownerWidth, ownerWidth) + direction, Dimension::Width, ownerWidth, ownerWidth, node) .isDefined()) { width = style .resolvedMaxDimension( - direction, Dimension::Width, ownerWidth, ownerWidth) + direction, Dimension::Width, ownerWidth, ownerWidth, node) .unwrap(); widthSizingMode = SizingMode::FitContent; } else { @@ -2765,16 +2780,22 @@ void calculateLayout( ownerHeight, ownerWidth) .unwrap() + - node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth)); + node->style().computeMarginForAxis( + FlexDirection::Column, ownerWidth, node)); heightSizingMode = SizingMode::StretchFit; } else if (style .resolvedMaxDimension( - direction, Dimension::Height, ownerHeight, ownerWidth) + direction, + Dimension::Height, + ownerHeight, + ownerWidth, + node) .isDefined()) { - height = style - .resolvedMaxDimension( - direction, Dimension::Height, ownerHeight, ownerWidth) - .unwrap(); + height = + style + .resolvedMaxDimension( + direction, Dimension::Height, ownerHeight, ownerWidth, node) + .unwrap(); heightSizingMode = SizingMode::FitContent; } else { height = ownerHeight; diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp index dc0a300add24..0f6e2e2c9b2a 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp @@ -37,7 +37,7 @@ FlexLine calculateFlexLine( resolveDirection(node->style().flexDirection(), direction); const bool isNodeFlexWrap = node->style().flexWrap() != Wrap::NoWrap; const float gap = - node->style().computeGapForAxis(mainAxis, availableInnerMainDim); + node->style().computeGapForAxis(mainAxis, availableInnerMainDim, node); const auto childrenEnd = node->getLayoutChildren().end(); // Add items to the current line until it's full or we run out of items. @@ -60,8 +60,8 @@ FlexLine calculateFlexLine( } child->setLineIndex(lineCount); - const float childMarginMainAxis = - child->style().computeMarginForAxis(mainAxis, availableInnerWidth); + const float childMarginMainAxis = child->style().computeMarginForAxis( + mainAxis, availableInnerWidth, child); const float childLeadingGapMainAxis = child == firstElementInLine ? 0.0f : gap; const float flexBasisWithMinAndMaxConstraints = diff --git a/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h b/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h index 685b1caecee6..9176ad21e517 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h +++ b/packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h @@ -23,11 +23,12 @@ enum class Unit : uint8_t { MaxContent = YGUnitMaxContent, FitContent = YGUnitFitContent, Stretch = YGUnitStretch, + Dynamic = YGUnitDynamic, }; template <> constexpr int32_t ordinalCount() { - return 7; + return 8; } constexpr Unit scopedEnum(YGUnit unscoped) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index 692d33d9c4a1..44d6476dab1e 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp @@ -119,7 +119,7 @@ float Node::dimensionWithMargin( const FlexDirection axis, const float widthSize) { return getLayout().measuredDimension(dimension(axis)) + - style_.computeMarginForAxis(axis, widthSize); + style_.computeMarginForAxis(axis, widthSize, this); } bool Node::isLayoutDimensionDefined(const FlexDirection axis) { @@ -305,10 +305,10 @@ float Node::relativePosition( } if (style_.isInlineStartPositionDefined(axis, direction) && !style_.isInlineStartPositionAuto(axis, direction)) { - return style_.computeInlineStartPosition(axis, direction, axisSize); + return style_.computeInlineStartPosition(axis, direction, axisSize, this); } - return -1 * style_.computeInlineEndPosition(axis, direction, axisSize); + return -1 * style_.computeInlineEndPosition(axis, direction, axisSize, this); } void Node::setPosition( @@ -341,19 +341,19 @@ void Node::setPosition( const auto crossAxisTrailingEdge = inlineEndEdge(crossAxis, direction); setLayoutPosition( - (style_.computeInlineStartMargin(mainAxis, direction, ownerWidth) + + (style_.computeInlineStartMargin(mainAxis, direction, ownerWidth, this) + relativePositionMain), mainAxisLeadingEdge); setLayoutPosition( - (style_.computeInlineEndMargin(mainAxis, direction, ownerWidth) + + (style_.computeInlineEndMargin(mainAxis, direction, ownerWidth, this) + relativePositionMain), mainAxisTrailingEdge); setLayoutPosition( - (style_.computeInlineStartMargin(crossAxis, direction, ownerWidth) + + (style_.computeInlineStartMargin(crossAxis, direction, ownerWidth, this) + relativePositionCross), crossAxisLeadingEdge); setLayoutPosition( - (style_.computeInlineEndMargin(crossAxis, direction, ownerWidth) + + (style_.computeInlineEndMargin(crossAxis, direction, ownerWidth, this) + relativePositionCross), crossAxisTrailingEdge); } @@ -375,14 +375,15 @@ FloatOptional Node::resolveFlexBasis( FlexDirection flexDirection, float referenceLength, float ownerWidth) const { - FloatOptional value = processFlexBasis().resolve(referenceLength); + FloatOptional value = processFlexBasis().resolve(referenceLength, this); if (style_.boxSizing() == BoxSizing::BorderBox) { return value; } Dimension dim = dimension(flexDirection); - FloatOptional dimensionPaddingAndBorder = FloatOptional{ - style_.computePaddingAndBorderForDimension(direction, dim, ownerWidth)}; + FloatOptional dimensionPaddingAndBorder = + FloatOptional{style_.computePaddingAndBorderForDimension( + direction, dim, ownerWidth, this)}; return value + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h index 74fd2c20d42e..daa3a016a0e9 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h @@ -106,7 +106,7 @@ class YG_EXPORT Node : public ::YGNode { * https://www.w3.org/TR/css-sizing-3/#definite */ inline bool hasDefiniteLength(Dimension dimension, float ownerSize) { - auto usedValue = getProcessedDimension(dimension).resolve(ownerSize); + auto usedValue = getProcessedDimension(dimension).resolve(ownerSize, this); return usedValue.isDefined() && usedValue.unwrap() >= 0.0f; } @@ -204,14 +204,14 @@ class YG_EXPORT Node : public ::YGNode { float referenceLength, float ownerWidth) const { FloatOptional value = - getProcessedDimension(dimension).resolve(referenceLength); + getProcessedDimension(dimension).resolve(referenceLength, this); if (style_.boxSizing() == BoxSizing::BorderBox) { return value; } FloatOptional dimensionPaddingAndBorder = FloatOptional{style_.computePaddingAndBorderForDimension( - direction, dimension, ownerWidth)}; + direction, dimension, ownerWidth, this)}; return value + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h index a06bd246b456..ff2d93e0f37e 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h @@ -304,7 +304,7 @@ class YG_EXPORT Style { } FloatOptional dimensionPaddingAndBorder = FloatOptional{ - computePaddingAndBorderForDimension(direction, axis, ownerWidth)}; + computePaddingAndBorderForDimension(direction, axis, ownerWidth, node)}; return value + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder @@ -333,7 +333,7 @@ class YG_EXPORT Style { } FloatOptional dimensionPaddingAndBorder = FloatOptional{ - computePaddingAndBorderForDimension(direction, axis, ownerWidth)}; + computePaddingAndBorderForDimension(direction, axis, ownerWidth, node)}; return value + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder @@ -485,14 +485,19 @@ class YG_EXPORT Style { .unwrapOrDefault(0.0f); } - float computeFlexStartBorder(FlexDirection axis, Direction direction) const { + float computeFlexStartBorder( + FlexDirection axis, + Direction direction, + YGNodeConstRef node) const { return maxOrDefined( resolve(computeBorder(flexStartEdge(axis), direction), 0.0f).unwrap(), 0.0f); } - float computeInlineStartBorder(FlexDirection axis, Direction direction) - const { + float computeInlineStartBorder( + FlexDirection axis, + Direction direction, + YGNodeConstRef node) const { return maxOrDefined( resolve( computeBorder(inlineStartEdge(axis, direction), direction), 0.0f) @@ -500,13 +505,19 @@ class YG_EXPORT Style { 0.0f); } - float computeFlexEndBorder(FlexDirection axis, Direction direction) const { + float computeFlexEndBorder( + FlexDirection axis, + Direction direction, + YGNodeConstRef node) const { return maxOrDefined( resolve(computeBorder(flexEndEdge(axis), direction), 0.0f).unwrap(), 0.0f); } - float computeInlineEndBorder(FlexDirection axis, Direction direction) const { + float computeInlineEndBorder( + FlexDirection axis, + Direction direction, + YGNodeConstRef node) const { return maxOrDefined( resolve(computeBorder(inlineEndEdge(axis, direction), direction), 0.0f) .unwrap(), @@ -516,7 +527,8 @@ class YG_EXPORT Style { float computeFlexStartPadding( FlexDirection axis, Direction direction, - float widthSize) const { + float widthSize, + YGNodeConstRef node) const { return maxOrDefined( resolve(computePadding(flexStartEdge(axis), direction), widthSize) .unwrap(), @@ -526,7 +538,8 @@ class YG_EXPORT Style { float computeInlineStartPadding( FlexDirection axis, Direction direction, - float widthSize) const { + float widthSize, + YGNodeConstRef node) const { return maxOrDefined( resolve( computePadding(inlineStartEdge(axis, direction), direction), @@ -538,7 +551,8 @@ class YG_EXPORT Style { float computeFlexEndPadding( FlexDirection axis, Direction direction, - float widthSize) const { + float widthSize, + YGNodeConstRef node) const { return maxOrDefined( resolve(computePadding(flexEndEdge(axis), direction), widthSize) .unwrap(), @@ -548,7 +562,8 @@ class YG_EXPORT Style { float computeInlineEndPadding( FlexDirection axis, Direction direction, - float widthSize) const { + float widthSize, + YGNodeConstRef node) const { return maxOrDefined( resolve( computePadding(inlineEndEdge(axis, direction), direction), @@ -560,67 +575,79 @@ class YG_EXPORT Style { float computeInlineStartPaddingAndBorder( FlexDirection axis, Direction direction, - float widthSize) const { - return computeInlineStartPadding(axis, direction, widthSize) + - computeInlineStartBorder(axis, direction); + float widthSize, + YGNodeConstRef node) const { + return computeInlineStartPadding(axis, direction, widthSize, node) + + computeInlineStartBorder(axis, direction, node); } float computeFlexStartPaddingAndBorder( FlexDirection axis, Direction direction, - float widthSize) const { - return computeFlexStartPadding(axis, direction, widthSize) + - computeFlexStartBorder(axis, direction); + float widthSize, + YGNodeConstRef node) const { + return computeFlexStartPadding(axis, direction, widthSize, node) + + computeFlexStartBorder(axis, direction, node); } float computeInlineEndPaddingAndBorder( FlexDirection axis, Direction direction, - float widthSize) const { - return computeInlineEndPadding(axis, direction, widthSize) + - computeInlineEndBorder(axis, direction); + float widthSize, + YGNodeConstRef node) const { + return computeInlineEndPadding(axis, direction, widthSize, node) + + computeInlineEndBorder(axis, direction, node); } float computeFlexEndPaddingAndBorder( FlexDirection axis, Direction direction, - float widthSize) const { - return computeFlexEndPadding(axis, direction, widthSize) + - computeFlexEndBorder(axis, direction); + float widthSize, + YGNodeConstRef node) const { + return computeFlexEndPadding(axis, direction, widthSize, node) + + computeFlexEndBorder(axis, direction, node); } float computePaddingAndBorderForDimension( Direction direction, Dimension dimension, - float widthSize) const { + float widthSize, + YGNodeConstRef node) const { FlexDirection flexDirectionForDimension = dimension == Dimension::Width ? FlexDirection::Row : FlexDirection::Column; return computeFlexStartPaddingAndBorder( - flexDirectionForDimension, direction, widthSize) + + flexDirectionForDimension, direction, widthSize, node) + computeFlexEndPaddingAndBorder( - flexDirectionForDimension, direction, widthSize); + flexDirectionForDimension, direction, widthSize, node); } - float computeBorderForAxis(FlexDirection axis) const { - return computeInlineStartBorder(axis, Direction::LTR) + - computeInlineEndBorder(axis, Direction::LTR); + float computeBorderForAxis(FlexDirection axis, YGNodeConstRef node) const { + return computeInlineStartBorder(axis, Direction::LTR, node) + + computeInlineEndBorder(axis, Direction::LTR, node); } - float computeMarginForAxis(FlexDirection axis, float widthSize) const { - // The total margin for a given axis does not depend on the direction - // so hardcoding LTR here to avoid piping direction to this function - return computeInlineStartMargin(axis, Direction::LTR, widthSize) + - computeInlineEndMargin(axis, Direction::LTR, widthSize); + float computeMarginForAxis( + FlexDirection axis, + float widthSize, + YGNodeConstRef node) const { + return computeInlineStartMargin(axis, Direction::LTR, widthSize, node) + + computeInlineEndMargin(axis, Direction::LTR, widthSize, node); } - float computeGapForAxis(FlexDirection axis, float ownerSize) const { + float computeGapForAxis( + FlexDirection axis, + float ownerSize, + YGNodeConstRef node) const { auto gap = isRow(axis) ? computeColumnGap() : computeRowGap(); return maxOrDefined(resolve(gap, ownerSize).unwrap(), 0.0f); } - float computeGapForDimension(Dimension dimension, float ownerSize) const { + float computeGapForDimension( + Dimension dimension, + float ownerSize, + YGNodeConstRef node) const { auto gap = dimension == Dimension::Width ? computeColumnGap() : computeRowGap(); return maxOrDefined(resolve(gap, ownerSize).unwrap(), 0.0f); diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h index 8099ce7df4e4..500f3265a92b 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h @@ -49,6 +49,10 @@ class StyleLength { return StyleLength{{}, Unit::Undefined}; } + static StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id) { + return StyleLength{callback, id}; + } + constexpr bool isAuto() const { return unit_ == Unit::Auto; } @@ -65,15 +69,31 @@ class StyleLength { return unit_ == Unit::Percent; } + constexpr bool isDynamic() const { + return unit_ == Unit::Dynamic; + } + constexpr bool isDefined() const { return !isUndefined(); } constexpr FloatOptional value() const { - return value_; + if (isDynamic()) { + return FloatOptional{}; + } + return payload_.value; + } + + YGValueDynamic callback() const { + return isDynamic() ? payload_.dynamic.callback : nullptr; + } + + constexpr YGValueDynamicID callbackId() const { + return isDynamic() ? payload_.dynamic.id : 0; } - constexpr FloatOptional resolve(float referenceLength) { + constexpr FloatOptional resolve(float referenceLength, YGNodeConstRef node) + const { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wswitch-enum" @@ -83,34 +103,68 @@ class StyleLength { #pragma clang diagnostic pop #endif case Unit::Point: - return value_; + return payload_.value; case Unit::Percent: - return FloatOptional{value_.unwrap() * referenceLength * 0.01f}; + return FloatOptional{payload_.value.unwrap() * referenceLength * 0.01f}; + case Unit::Dynamic: + if (payload_.dynamic.callback != nullptr && node != nullptr) { + auto value = payload_.dynamic.callback( + node, + payload_.dynamic.id, + YGValueDynamicContext{referenceLength}); + return FloatOptional{value.value}; + } + return FloatOptional{}; default: return FloatOptional{}; } } explicit constexpr operator YGValue() const { - return YGValue{value_.unwrap(), unscopedEnum(unit_)}; + return YGValue{value().unwrap(), unscopedEnum(unit_)}; } constexpr bool operator==(const StyleLength& rhs) const { - return value_ == rhs.value_ && unit_ == rhs.unit_; + if (unit_ != rhs.unit_) { + return false; + } + if (isDynamic()) { + return payload_.dynamic.callback == rhs.payload_.dynamic.callback && + payload_.dynamic.id == rhs.payload_.dynamic.id; + } + return payload_.value == rhs.payload_.value; } constexpr bool inexactEquals(const StyleLength& other) const { - return unit_ == other.unit_ && - facebook::yoga::inexactEquals(value_, other.value_); + if (unit_ != other.unit_) { + return false; + } + if (isDynamic()) { + return payload_.dynamic.callback == other.payload_.dynamic.callback && + payload_.dynamic.id == other.payload_.dynamic.id; + } + return facebook::yoga::inexactEquals(payload_.value, other.payload_.value); } private: + union Payload { + constexpr Payload() : value{} {} + constexpr explicit Payload(FloatOptional val) : value(val) {} + constexpr Payload(YGValueDynamic callback, YGValueDynamicID id) + : dynamic{callback, id} {} + + FloatOptional value; + YGValueDynamicData dynamic; + }; + // We intentionally do not allow direct construction using value and unit, to // avoid invalid, or redundant combinations. constexpr StyleLength(FloatOptional value, Unit unit) - : value_(value), unit_(unit) {} + : payload_(value), unit_(unit) {} + constexpr StyleLength(YGValueDynamic callback, YGValueDynamicID id) + : payload_(callback, id), unit_(Unit::Dynamic) {} - FloatOptional value_{}; + Payload payload_{}; Unit unit_{Unit::Undefined}; }; diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h index 76e079b2da58..8f112e12113d 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h @@ -68,6 +68,10 @@ class StyleSizeLength { return StyleSizeLength{{}, Unit::Undefined}; } + static StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id) { + return StyleSizeLength{callback, id}; + } + constexpr bool isAuto() const { return unit_ == Unit::Auto; } @@ -100,11 +104,27 @@ class StyleSizeLength { return unit_ == Unit::Percent; } + constexpr bool isDynamic() const { + return unit_ == Unit::Dynamic; + } + constexpr FloatOptional value() const { - return value_; + if (isDynamic()) { + return FloatOptional{}; + } + return payload_.value; + } + + YGValueDynamic callback() const { + return isDynamic() ? payload_.dynamic.callback : nullptr; + } + + constexpr YGValueDynamicID callbackId() const { + return isDynamic() ? payload_.dynamic.id : 0; } - constexpr FloatOptional resolve(float referenceLength) const { + constexpr FloatOptional resolve(float referenceLength, YGNodeConstRef node) + const { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wswitch-enum" @@ -114,34 +134,68 @@ class StyleSizeLength { #pragma clang diagnostic pop #endif case Unit::Point: - return value_; + return payload_.value; case Unit::Percent: - return FloatOptional{value_.unwrap() * referenceLength * 0.01f}; + return FloatOptional{payload_.value.unwrap() * referenceLength * 0.01f}; + case Unit::Dynamic: + if (payload_.dynamic.callback != nullptr && node != nullptr) { + auto value = payload_.dynamic.callback( + node, + payload_.dynamic.id, + YGValueDynamicContext{referenceLength}); + return FloatOptional{value.value}; + } + return FloatOptional{}; default: return FloatOptional{}; } } explicit constexpr operator YGValue() const { - return YGValue{value_.unwrap(), unscopedEnum(unit_)}; + return YGValue{value().unwrap(), unscopedEnum(unit_)}; } constexpr bool operator==(const StyleSizeLength& rhs) const { - return value_ == rhs.value_ && unit_ == rhs.unit_; + if (unit_ != rhs.unit_) { + return false; + } + if (isDynamic()) { + return payload_.dynamic.callback == rhs.payload_.dynamic.callback && + payload_.dynamic.id == rhs.payload_.dynamic.id; + } + return payload_.value == rhs.payload_.value; } constexpr bool inexactEquals(const StyleSizeLength& other) const { - return unit_ == other.unit_ && - facebook::yoga::inexactEquals(value_, other.value_); + if (unit_ != other.unit_) { + return false; + } + if (isDynamic()) { + return payload_.dynamic.callback == other.payload_.dynamic.callback && + payload_.dynamic.id == other.payload_.dynamic.id; + } + return facebook::yoga::inexactEquals(payload_.value, other.payload_.value); } private: + union Payload { + constexpr Payload() : value{} {} + constexpr explicit Payload(FloatOptional val) : value(val) {} + constexpr Payload(YGValueDynamic callback, YGValueDynamicID id) + : dynamic{callback, id} {} + + FloatOptional value; + YGValueDynamicData dynamic; + }; + // We intentionally do not allow direct construction using value and unit, to // avoid invalid, or redundant combinations. constexpr StyleSizeLength(FloatOptional value, Unit unit) - : value_(value), unit_(unit) {} + : payload_(value), unit_(unit) {} + constexpr StyleSizeLength(YGValueDynamic callback, YGValueDynamicID id) + : payload_(callback, id), unit_(Unit::Dynamic) {} - FloatOptional value_{}; + Payload payload_{}; Unit unit_{Unit::Undefined}; }; diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h index 6a2b58902339..9fe036c741b8 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h @@ -70,7 +70,8 @@ class StyleValueHandle { Percent, Number, Auto, - Keyword + Keyword, + Dynamic }; // Intentionally leaving out auto as a fast path diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h index fb31193b9789..64e10bee40bd 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h @@ -32,6 +32,8 @@ class StyleValuePool { handle.setType(StyleValueHandle::Type::Undefined); } else if (length.isAuto()) { handle.setType(StyleValueHandle::Type::Auto); + } else if (length.isDynamic()) { + storeDynamic(handle, length.callback(), length.callbackId()); } else { auto type = length.isPoints() ? StyleValueHandle::Type::Point : StyleValueHandle::Type::Percent; @@ -50,6 +52,8 @@ class StyleValuePool { storeKeyword(handle, StyleValueHandle::Keyword::Stretch); } else if (sizeValue.isFitContent()) { storeKeyword(handle, StyleValueHandle::Keyword::FitContent); + } else if (sizeValue.isDynamic()) { + storeDynamic(handle, sizeValue.callback(), sizeValue.callbackId()); } else { auto type = sizeValue.isPoints() ? StyleValueHandle::Type::Point : StyleValueHandle::Type::Percent; @@ -70,6 +74,9 @@ class StyleValuePool { return StyleLength::undefined(); } else if (handle.isAuto()) { return StyleLength::ofAuto(); + } else if (handle.isDynamic()) { + return StyleLength::dynamic( + getDynamicCallback(handle), getDynamicCallbackID(handle)); } else { assert( handle.type() == StyleValueHandle::Type::Point || @@ -95,6 +102,9 @@ class StyleValuePool { return StyleSizeLength::ofFitContent(); } else if (handle.isKeyword(StyleValueHandle::Keyword::Stretch)) { return StyleSizeLength::ofStretch(); + } else if (handle.isDynamic()) { + return StyleSizeLength::dynamic( + getDynamicCallback(handle), getDynamicCallbackID(handle)); } else { assert( handle.type() == StyleValueHandle::Type::Point || @@ -165,6 +175,19 @@ class StyleValuePool { } } + YGValueDynamic getDynamicCallback(StyleValueHandle handle) const { + assert(handle.isDynamic()); + assert(handle.isValueIndexed()); + return reinterpret_cast( + static_cast(buffer_.get64(handle.value()))); + } + + YGValueDynamicID getDynamicCallbackID(StyleValueHandle handle) const { + assert(handle.isDynamic()); + assert(handle.isValueIndexed()); + return static_cast(buffer_.get32(handle.value() + 2)); + } + static constexpr bool isIntegerPackable(float f) { constexpr uint16_t kMaxInlineAbsValue = (1 << 11) - 1; From c7c50711bd9ec1bccd6eb629d604bab5fbdeb669 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 20 Mar 2026 13:08:41 -0300 Subject: [PATCH 2/7] refactor: adjust CSSCalc formatting --- .../ReactCommon/react/renderer/css/CSSCalc.h | 101 +++++++++++------- 1 file changed, 62 insertions(+), 39 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h b/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h index caf95b96af53..f9ecc402df68 100644 --- a/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h +++ b/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h @@ -32,9 +32,10 @@ struct CSSCalc { float vh{0.0f}; bool unitless{false}; - constexpr auto operator==(const CSSCalc& rhs) const -> bool = default; + constexpr bool operator==(const CSSCalc &rhs) const = default; - constexpr auto operator+(const CSSCalc& rhs) const -> CSSCalc { + constexpr CSSCalc operator+(const CSSCalc &rhs) const -> + { return CSSCalc{ px + rhs.px, percent + rhs.percent, @@ -43,7 +44,8 @@ struct CSSCalc { unitless && rhs.unitless}; } - constexpr auto operator-(const CSSCalc& rhs) const -> CSSCalc { + constexpr CSSCalc operator-(const CSSCalc &rhs) const + { return CSSCalc{ px - rhs.px, percent - rhs.percent, @@ -52,12 +54,14 @@ struct CSSCalc { unitless && rhs.unitless}; } - constexpr auto operator*(float scalar) const -> CSSCalc { + constexpr CSSCalc operator*(float scalar) const + { return CSSCalc{ px * scalar, percent * scalar, vw * scalar, vh * scalar, unitless}; } - constexpr auto operator/(float scalar) const -> CSSCalc { + constexpr CSSCalc operator/(float scalar) const + { if (scalar == 0.0f) { return CSSCalc{}; } @@ -65,54 +69,65 @@ struct CSSCalc { px / scalar, percent / scalar, vw / scalar, vh / scalar, unitless}; } - constexpr auto operator-() const -> CSSCalc { + constexpr CSSCalc operator-() const + { return CSSCalc{-px, -percent, -vw, -vh, unitless}; } - auto resolve(float percentRef, float viewportWidth, float viewportHeight) - const -> float { + float resolve(float percentRef, float viewportWidth, float viewportHeight) + const + { return px + (percent * percentRef * 0.01f) + (vw * viewportWidth * 0.01f) + (vh * viewportHeight * 0.01f); } - constexpr auto isUnitless() const -> bool { + constexpr bool isUnitless() const + { return unitless; } - constexpr auto isPointsOnly() const -> bool { + constexpr bool isPointsOnly() const + { return percent == 0.0f && vw == 0.0f && vh == 0.0f && !unitless; } - constexpr auto isPercentOnly() const -> bool { + constexpr bool isPercentOnly() const + { return px == 0.0f && vw == 0.0f && vh == 0.0f && !unitless; } - constexpr auto isZero() const -> bool { + constexpr bool isZero() const + { return px == 0.0f && percent == 0.0f && vw == 0.0f && vh == 0.0f; } - static constexpr auto fromNumber(float value) -> CSSCalc { + static constexpr CSSCalc fromNumber(float value) + { return CSSCalc{value, 0.0f, 0.0f, 0.0f, true}; } - static constexpr auto fromPoints(float value) -> CSSCalc { + static constexpr CSSCalc fromPoints(float value) + { return CSSCalc{value, 0.0f, 0.0f, 0.0f, false}; } - static constexpr auto fromPercent(float value) -> CSSCalc { + static constexpr CSSCalc fromPercent(float value) + { return CSSCalc{0.0f, value, 0.0f, 0.0f, false}; } - static constexpr auto fromVw(float value) -> CSSCalc { + static constexpr CSSCalc fromVw(float value) + { return CSSCalc{0.0f, 0.0f, value, 0.0f, false}; } - static constexpr auto fromVh(float value) -> CSSCalc { + static constexpr CSSCalc fromVh(float value) + { return CSSCalc{0.0f, 0.0f, 0.0f, value, false}; } - static constexpr auto fromLength(float value, CSSLengthUnit unit) - -> std::optional { + static constexpr std::optional fromLength(float value, CSSLengthUnit unit) + { switch (unit) { case CSSLengthUnit::Px: return fromPoints(value); @@ -129,8 +144,9 @@ struct CSSCalc { template <> struct CSSDataTypeParser { static constexpr auto consumeFunctionBlock( - const CSSFunctionBlock& func, - CSSValueParser& parser) -> std::optional { + const CSSFunctionBlock &func, + CSSValueParser &parser) -> std::optional + { if (!iequals(func.name, "calc")) { return std::nullopt; } @@ -138,8 +154,9 @@ struct CSSDataTypeParser { return parseCalcExpression(parser); } - static constexpr auto parseCalcExpression(CSSValueParser& parser) - -> std::optional { + static constexpr auto parseCalcExpression(CSSValueParser &parser) + -> std::optional + { parser.syntaxParser().consumeWhitespace(); auto result = parseAddSub(parser); parser.syntaxParser().consumeWhitespace(); @@ -147,8 +164,9 @@ struct CSSDataTypeParser { } static constexpr auto consumeSimpleBlock( - const CSSSimpleBlock& block, - CSSValueParser& parser) -> std::optional { + const CSSSimpleBlock &block, + CSSValueParser &parser) -> std::optional + { if (block.openBracketType != CSSTokenType::OpenParen) { return std::nullopt; } @@ -157,8 +175,9 @@ struct CSSDataTypeParser { } private: - static constexpr auto parseAddSub(CSSValueParser& parser) - -> std::optional { + static constexpr auto parseAddSub(CSSValueParser &parser) + -> std::optional + { auto left = parseMulDiv(parser); if (!left) { return std::nullopt; @@ -170,7 +189,7 @@ struct CSSDataTypeParser { auto opResult = parser.syntaxParser().consumeComponentValue>( - CSSDelimiter::None, [](const CSSPreservedToken& token) { + CSSDelimiter::None, [](const CSSPreservedToken &token) { if (token.type() == CSSTokenType::Delim) { auto sv = token.stringValue(); if (!sv.empty() && (sv[0] == '+' || sv[0] == '-')) { @@ -205,8 +224,9 @@ struct CSSDataTypeParser { return left; } - static constexpr auto parseMulDiv(CSSValueParser& parser) - -> std::optional { + static constexpr auto parseMulDiv(CSSValueParser &parser) + -> std::optional + { auto left = parseUnary(parser); if (!left) { return std::nullopt; @@ -218,7 +238,7 @@ struct CSSDataTypeParser { auto opResult = parser.syntaxParser().consumeComponentValue>( - CSSDelimiter::None, [](const CSSPreservedToken& token) { + CSSDelimiter::None, [](const CSSPreservedToken &token) { if (token.type() == CSSTokenType::Delim) { auto sv = token.stringValue(); if (!sv.empty() && (sv[0] == '*' || sv[0] == '/')) { @@ -259,13 +279,14 @@ struct CSSDataTypeParser { return left; } - static constexpr auto parseUnary(CSSValueParser& parser) - -> std::optional { + static constexpr auto parseUnary(CSSValueParser &parser) + -> std::optional + { auto savedParser = parser.syntaxParser(); auto opResult = parser.syntaxParser().consumeComponentValue>( - CSSDelimiter::None, [](const CSSPreservedToken& token) { + CSSDelimiter::None, [](const CSSPreservedToken &token) { if (token.type() == CSSTokenType::Delim) { auto sv = token.stringValue(); if (!sv.empty() && (sv[0] == '+' || sv[0] == '-')) { @@ -288,8 +309,9 @@ struct CSSDataTypeParser { return parsePrimary(parser); } - static constexpr auto parsePrimary(CSSValueParser& parser) - -> std::optional { + static constexpr auto parsePrimary(CSSValueParser &parser) + -> std::optional + { auto value = parser.parseNextValue(); @@ -302,7 +324,7 @@ struct CSSDataTypeParser { } if (std::holds_alternative(value)) { - const auto& length = std::get(value); + const auto &length = std::get(value); return CSSCalc::fromLength(length.value, length.unit); } @@ -313,8 +335,9 @@ struct CSSDataTypeParser { return std::nullopt; } - static constexpr auto parseCalcContents(CSSValueParser& parser) - -> std::optional { + static constexpr auto parseCalcContents(CSSValueParser &parser) + -> std::optional + { parser.syntaxParser().consumeWhitespace(); auto result = parseAddSub(parser); parser.syntaxParser().consumeWhitespace(); From 58afaf974f8370ce996823feb1afdab27435f63b Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Fri, 20 Mar 2026 13:15:59 -0300 Subject: [PATCH 3/7] refactor: use FNV-1a hashing for calc expression property identification --- .../view/YogaLayoutableShadowNode.cpp | 7 +- .../components/view/YogaStylableProps.cpp | 382 +++++------------- .../renderer/components/view/primitives.h | 43 +- .../ReactCommon/yoga/yoga/YGValue.h | 10 +- .../ReactCommon/yoga/yoga/style/StyleLength.h | 5 + .../yoga/yoga/style/StyleSizeLength.h | 5 + .../yoga/yoga/style/StyleValuePool.h | 2 +- 7 files changed, 109 insertions(+), 345 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index 3d7103776312..795fa50ac0aa 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -950,12 +950,11 @@ YGValue YogaLayoutableShadowNode::yogaNodeCalcValueResolver( auto& node = shadowNodeFromContext(yogaNode); auto& props = static_cast(*node.props_); - auto key = static_cast(id); - if (!props.calcExpressions.contains(key)) { + if (!props.calcExpressions.contains(id)) { return {}; } - - auto& calc = props.calcExpressions.at(key); + + auto& calc = props.calcExpressions.at(id); return YGValue( calc.resolve( context.referenceLength, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index fad9b128d91c..71d4451f2e7a 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -130,37 +131,36 @@ static inline const T getFieldValue( REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ position, setPosition, yoga::Edge::All, "inset"); -#define APPLY_CALC_COMMON(fieldName, key, setPoints, setPercent, setDynamic) \ - { \ - if (const auto* rawValue = rawProps.at(fieldName, nullptr, nullptr)) { \ - const auto& value = *rawValue; \ - if (value.hasType()) { \ - auto isCalcExpression{false}; \ - auto parsed = parseCSSProperty((std::string)value); \ - if (std::holds_alternative(parsed)) { \ - auto calc = std::get(parsed); \ - if (calc.isPointsOnly()) { \ - setPoints(calc.px); \ - } else if (calc.isPercentOnly()) { \ - setPercent(calc.percent); \ - } else { \ - setDynamic(static_cast(key)); \ - calcExpressions[key] = std::move(calc); \ - isCalcExpression = true; \ - } \ - } \ - if (!isCalcExpression && calcExpressions.count(key)) { \ - calcExpressions.erase(key); \ - } \ - } \ - } \ +#define APPLY_CALC_COMMON(fieldName, setPoints, setPercent, setDynamic) \ + { \ + if (const auto* rawValue = rawProps.at(fieldName, nullptr, nullptr)) { \ + const auto& value = *rawValue; \ + if (value.hasType()) { \ + constexpr auto key = fnv1a(fieldName); \ + auto isCalcExpression{false}; \ + auto parsed = parseCSSProperty((std::string)value); \ + if (std::holds_alternative(parsed)) { \ + auto calc = std::get(parsed); \ + if (calc.isPointsOnly()) { \ + setPoints(calc.px); \ + } else if (calc.isPercentOnly()) { \ + setPercent(calc.percent); \ + } else { \ + setDynamic(key); \ + calcExpressions[key] = std::move(calc); \ + isCalcExpression = true; \ + } \ + } \ + if (!isCalcExpression && calcExpressions.count(key)) { \ + calcExpressions.erase(key); \ + } \ + } \ + } \ } -#define APPLY_CALC_YG_INDEXED( \ - getter, setter, index, fieldName, LengthType, key) \ +#define APPLY_CALC_YG_INDEXED(setter, index, fieldName, LengthType) \ APPLY_CALC_COMMON( \ fieldName, \ - key, \ [&](float points) { \ yogaStyle.setter(index, LengthType::points(points)); \ }, \ @@ -173,10 +173,9 @@ static inline const T getFieldValue( LengthType::dynamic(&yogaNodeCalcValueResolver, dynamicId)); \ }) -#define APPLY_CALC_YG_FIELD(getter, setter, fieldName, LengthType, key) \ +#define APPLY_CALC_YG_FIELD(setter, fieldName, LengthType) \ APPLY_CALC_COMMON( \ fieldName, \ - key, \ [&](float points) { yogaStyle.setter(LengthType::points(points)); }, \ [&](float percent) { yogaStyle.setter(LengthType::percent(percent)); }, \ [&](YGValueDynamicID dynamicId) { \ @@ -184,240 +183,66 @@ static inline const T getFieldValue( LengthType::dynamic(&yogaNodeCalcValueResolver, dynamicId)); \ }) -#define APPLY_CALC_YG_DIMENSION( \ - field, setter, widthStr, heightStr, widthCalcIdx, heightCalcIdx) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Dimension::Width, \ - widthStr, \ - yoga::StyleSizeLength, \ - widthCalcIdx) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Dimension::Height, \ - heightStr, \ - yoga::StyleSizeLength, \ - heightCalcIdx) - -#define APPLY_CALC_YG_EDGES_MARGIN(field, setter, LengthType, prefix) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Left, \ - prefix "Left", \ - LengthType, \ - CalcExpressionPropertyID::MarginLeft) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Top, \ - prefix "Top", \ - LengthType, \ - CalcExpressionPropertyID::MarginTop) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Right, \ - prefix "Right", \ - LengthType, \ - CalcExpressionPropertyID::MarginRight) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Bottom, \ - prefix "Bottom", \ - LengthType, \ - CalcExpressionPropertyID::MarginBottom) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Start, \ - prefix "Start", \ - LengthType, \ - CalcExpressionPropertyID::MarginStart) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::End, \ - prefix "End", \ - LengthType, \ - CalcExpressionPropertyID::MarginEnd) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Horizontal, \ - prefix "Horizontal", \ - LengthType, \ - CalcExpressionPropertyID::MarginHorizontal) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Vertical, \ - prefix "Vertical", \ - LengthType, \ - CalcExpressionPropertyID::MarginVertical) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::All, \ - prefix, \ - LengthType, \ - CalcExpressionPropertyID::MarginAll) - -#define APPLY_CALC_YG_EDGES_PADDING(field, setter, LengthType, prefix) \ +#define APPLY_CALC_YG_DIMENSION(setter, widthStr, heightStr) \ APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Left, \ - prefix "Left", \ - LengthType, \ - CalcExpressionPropertyID::PaddingLeft) \ + setter, yoga::Dimension::Width, widthStr, yoga::StyleSizeLength) \ APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Top, \ - prefix "Top", \ - LengthType, \ - CalcExpressionPropertyID::PaddingTop) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Right, \ - prefix "Right", \ - LengthType, \ - CalcExpressionPropertyID::PaddingRight) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Bottom, \ - prefix "Bottom", \ - LengthType, \ - CalcExpressionPropertyID::PaddingBottom) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Start, \ - prefix "Start", \ - LengthType, \ - CalcExpressionPropertyID::PaddingStart) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::End, \ - prefix "End", \ - LengthType, \ - CalcExpressionPropertyID::PaddingEnd) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Horizontal, \ - prefix "Horizontal", \ - LengthType, \ - CalcExpressionPropertyID::PaddingHorizontal) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::Vertical, \ - prefix "Vertical", \ - LengthType, \ - CalcExpressionPropertyID::PaddingVertical) \ - APPLY_CALC_YG_INDEXED( \ - field, \ - setter, \ - yoga::Edge::All, \ - prefix, \ - LengthType, \ - CalcExpressionPropertyID::PaddingAll) - -#define APPLY_CALC_YG_EDGES_POSITION() \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::Left, \ - "left", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::Left) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::Top, \ - "top", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::Top) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::Right, \ - "right", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::Right) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::Bottom, \ - "bottom", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::Bottom) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::Start, \ - "start", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::Start) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::End, \ - "end", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::End) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::Horizontal, \ - "insetInline", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::InsetInline) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::Vertical, \ - "insetBlock", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::InsetBlock) \ - APPLY_CALC_YG_INDEXED( \ - position, \ - setPosition, \ - yoga::Edge::All, \ - "inset", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::Inset) - -#define APPLY_CALC_YG_GUTTER() \ - APPLY_CALC_YG_INDEXED( \ - gap, \ - setGap, \ - yoga::Gutter::Row, \ - "rowGap", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::RowGap) \ - APPLY_CALC_YG_INDEXED( \ - gap, \ - setGap, \ - yoga::Gutter::Column, \ - "columnGap", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::ColumnGap) \ - APPLY_CALC_YG_INDEXED( \ - gap, \ - setGap, \ - yoga::Gutter::All, \ - "gap", \ - yoga::StyleLength, \ - CalcExpressionPropertyID::Gap) + setter, yoga::Dimension::Height, heightStr, yoga::StyleSizeLength) + +#define APPLY_CALC_YG_EDGES_MARGIN(setter, LengthType, prefix) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Left, prefix "Left", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Top, prefix "Top", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Right, prefix "Right", LengthType) \ + APPLY_CALC_YG_INDEXED( \ + setter, yoga::Edge::Bottom, prefix "Bottom", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Start, prefix "Start", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::End, prefix "End", LengthType) \ + APPLY_CALC_YG_INDEXED( \ + setter, yoga::Edge::Horizontal, prefix "Horizontal", LengthType) \ + APPLY_CALC_YG_INDEXED( \ + setter, yoga::Edge::Vertical, prefix "Vertical", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::All, prefix, LengthType) + +#define APPLY_CALC_YG_EDGES_PADDING(setter, LengthType, prefix) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Left, prefix "Left", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Top, prefix "Top", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Right, prefix "Right", LengthType) \ + APPLY_CALC_YG_INDEXED( \ + setter, yoga::Edge::Bottom, prefix "Bottom", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::Start, prefix "Start", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::End, prefix "End", LengthType) \ + APPLY_CALC_YG_INDEXED( \ + setter, yoga::Edge::Horizontal, prefix "Horizontal", LengthType) \ + APPLY_CALC_YG_INDEXED( \ + setter, yoga::Edge::Vertical, prefix "Vertical", LengthType) \ + APPLY_CALC_YG_INDEXED(setter, yoga::Edge::All, prefix, LengthType) + +#define APPLY_CALC_YG_EDGES_POSITION() \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::Left, "left", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::Top, "top", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::Right, "right", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::Bottom, "bottom", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::Start, "start", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::End, "end", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::Horizontal, "insetInline", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::Vertical, "insetBlock", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setPosition, yoga::Edge::All, "inset", yoga::StyleLength) + +#define APPLY_CALC_YG_GUTTER() \ + APPLY_CALC_YG_INDEXED( \ + setGap, yoga::Gutter::Row, "rowGap", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED( \ + setGap, yoga::Gutter::Column, "columnGap", yoga::StyleLength) \ + APPLY_CALC_YG_INDEXED(setGap, yoga::Gutter::All, "gap", yoga::StyleLength) void YogaStylableProps::setProp( const PropsParserContext& context, @@ -825,37 +650,14 @@ CalcExpressions YogaStylableProps::buildCalcExpressions( const RawProps& rawProps, const CalcExpressions& defaultValue) { auto calcExpressions = defaultValue; - APPLY_CALC_YG_DIMENSION( - dimension, - setDimension, - "width", - "height", - CalcExpressionPropertyID::Width, - CalcExpressionPropertyID::Height) - APPLY_CALC_YG_DIMENSION( - minDimension, - setMinDimension, - "minWidth", - "minHeight", - CalcExpressionPropertyID::MinWidth, - CalcExpressionPropertyID::MinHeight) - APPLY_CALC_YG_DIMENSION( - maxDimension, - setMaxDimension, - "maxWidth", - "maxHeight", - CalcExpressionPropertyID::MaxWidth, - CalcExpressionPropertyID::MaxHeight) - APPLY_CALC_YG_FIELD( - flexBasis, - setFlexBasis, - "flexBasis", - yoga::StyleSizeLength, - CalcExpressionPropertyID::FlexBasis) + APPLY_CALC_YG_DIMENSION(setDimension, "width", "height") + APPLY_CALC_YG_DIMENSION(setMinDimension, "minWidth", "minHeight") + APPLY_CALC_YG_DIMENSION(setMaxDimension, "maxWidth", "maxHeight") + APPLY_CALC_YG_FIELD(setFlexBasis, "flexBasis", yoga::StyleSizeLength) APPLY_CALC_YG_GUTTER() APPLY_CALC_YG_EDGES_POSITION() - APPLY_CALC_YG_EDGES_MARGIN(margin, setMargin, yoga::StyleLength, "margin") - APPLY_CALC_YG_EDGES_PADDING(padding, setPadding, yoga::StyleLength, "padding") + APPLY_CALC_YG_EDGES_MARGIN(setMargin, yoga::StyleLength, "margin") + APPLY_CALC_YG_EDGES_PADDING(setPadding, yoga::StyleLength, "padding") return calcExpressions; } diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h index 778ae58d5047..cdf1dda12401 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/primitives.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace facebook::react { @@ -254,46 +255,6 @@ inline bool areBorderRadiiCircular(const BorderRadii &borderRadii) return borderRadii.isUniform() && borderRadii.topLeft.horizontal == borderRadii.topLeft.vertical; } -enum class CalcExpressionPropertyID : uint8_t { - Width, - Height, - MinWidth, - MinHeight, - MaxWidth, - MaxHeight, - FlexBasis, - RowGap, - ColumnGap, - Gap, - Left, - Top, - Right, - Bottom, - Start, - End, - InsetInline, - InsetBlock, - Inset, - MarginLeft, - MarginTop, - MarginRight, - MarginBottom, - MarginStart, - MarginEnd, - MarginHorizontal, - MarginVertical, - MarginAll, - PaddingLeft, - PaddingTop, - PaddingRight, - PaddingBottom, - PaddingStart, - PaddingEnd, - PaddingHorizontal, - PaddingVertical, - PaddingAll, -}; - -using CalcExpressions = std::unordered_map; +using CalcExpressions = std::unordered_map; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGValue.h b/packages/react-native/ReactCommon/yoga/yoga/YGValue.h index 56668806268f..27f7524d2de4 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGValue.h +++ b/packages/react-native/ReactCommon/yoga/yoga/YGValue.h @@ -58,7 +58,7 @@ YG_EXPORT bool YGFloatIsUndefined(float value); /** * Host-defined identifier for a dynamic style value. */ -typedef uint8_t YGValueDynamicID; +typedef uint32_t YGValueDynamicID; /** * Layout context passed to YGValueDynamic for resolving dynamic values. @@ -77,14 +77,6 @@ typedef YGValue (*YGValueDynamic)( YGValueDynamicID id, YGValueDynamicContext context); -/** - * Callback + identifier pair for internal storage. - */ -struct YGValueDynamicData { - YGValueDynamic callback; - YGValueDynamicID id; -}; - YG_EXTERN_C_END // Equality operators for comparison of YGValue in C++ diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h index 500f3265a92b..5a833da58e1c 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h @@ -147,6 +147,11 @@ class StyleLength { } private: + struct YGValueDynamicData { + YGValueDynamic callback; + YGValueDynamicID id; + }; + union Payload { constexpr Payload() : value{} {} constexpr explicit Payload(FloatOptional val) : value(val) {} diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h index 8f112e12113d..9a67cd0cb882 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h @@ -178,6 +178,11 @@ class StyleSizeLength { } private: + struct YGValueDynamicData { + YGValueDynamic callback; + YGValueDynamicID id; + }; + union Payload { constexpr Payload() : value{} {} constexpr explicit Payload(FloatOptional val) : value(val) {} diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h index 64e10bee40bd..e11ee6d2add3 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h @@ -185,7 +185,7 @@ class StyleValuePool { YGValueDynamicID getDynamicCallbackID(StyleValueHandle handle) const { assert(handle.isDynamic()); assert(handle.isValueIndexed()); - return static_cast(buffer_.get32(handle.value() + 2)); + return buffer_.get32(handle.value() + 2); } static constexpr bool isIntegerPackable(float f) { From c5845f543450adb6af45766f04363820a320ab05 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Tue, 24 Mar 2026 11:08:05 -0300 Subject: [PATCH 4/7] refactor: fix return type syntax leftover in CSSCalc operator+ --- packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h b/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h index f9ecc402df68..5cf427da3e3e 100644 --- a/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h +++ b/packages/react-native/ReactCommon/react/renderer/css/CSSCalc.h @@ -34,7 +34,7 @@ struct CSSCalc { constexpr bool operator==(const CSSCalc &rhs) const = default; - constexpr CSSCalc operator+(const CSSCalc &rhs) const -> + constexpr CSSCalc operator+(const CSSCalc &rhs) const { return CSSCalc{ px + rhs.px, From 707dbf190b62aba5b790c6909ae461c0d24f4fbe Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Wed, 1 Jul 2026 16:34:18 +0200 Subject: [PATCH 5/7] feat: yoga update --- .../yoga/yoga/algorithm/CalculateLayout.cpp | 45 ++++---- .../ReactCommon/yoga/yoga/style/Style.h | 104 ++++++++++++------ .../yoga/yoga/style/StyleValueHandle.h | 4 + .../yoga/yoga/style/StyleValuePool.h | 45 ++++++-- 4 files changed, 134 insertions(+), 64 deletions(-) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 35df145ac0e4..39eeb071d17a 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -734,9 +734,9 @@ static float computeMinContentMainSize( const Direction leafDirection = node->resolveDirection(ownerDirection); const float paddingAndBorder = node->style().computeFlexStartPaddingAndBorder( - requestedAxis, leafDirection, ownerWidth) + + requestedAxis, leafDirection, ownerWidth, node) + node->style().computeFlexEndPaddingAndBorder( - requestedAxis, leafDirection, ownerWidth); + requestedAxis, leafDirection, ownerWidth, node); return (wantRow ? size.width : size.height) + paddingAndBorder; } @@ -762,25 +762,26 @@ static float computeMinContentMainSize( float childMain = computeMinContentMainSize( child, nodeMainAxis, direction, ownerWidth, ownerHeight); - childMain += child->style().computeMarginForAxis(nodeMainAxis, ownerWidth); + childMain += + child->style().computeMarginForAxis(nodeMainAxis, ownerWidth, child); float childCross = computeMinContentMainSize( child, nodeCrossAxis, direction, ownerWidth, ownerHeight); childCross += - child->style().computeMarginForAxis(nodeCrossAxis, ownerWidth); + child->style().computeMarginForAxis(nodeCrossAxis, ownerWidth, child); mainTotal += childMain; crossMax = std::max(crossMax, childCross); } mainTotal += node->style().computeFlexStartPaddingAndBorder( - nodeMainAxis, direction, ownerWidth) + + nodeMainAxis, direction, ownerWidth, node) + node->style().computeFlexEndPaddingAndBorder( - nodeMainAxis, direction, ownerWidth); + nodeMainAxis, direction, ownerWidth, node); crossMax += node->style().computeFlexStartPaddingAndBorder( - nodeCrossAxis, direction, ownerWidth) + + nodeCrossAxis, direction, ownerWidth, node) + node->style().computeFlexEndPaddingAndBorder( - nodeCrossAxis, direction, ownerWidth); + nodeCrossAxis, direction, ownerWidth, node); const bool nodeMainIsRow = isRow(nodeMainAxis); const float widthMin = nodeMainIsRow ? mainTotal : crossMax; @@ -868,7 +869,7 @@ static FloatOptional computeAutoMinMainSize( // §4.5: cap by the max main size. const FloatOptional maxMain = child->style().resolvedMaxDimension( - direction, mainDim, ownerMainAxisSize, ownerWidth); + direction, mainDim, ownerMainAxisSize, ownerWidth, child); if (maxMain.isDefined() && floor > maxMain) { floor = maxMain; } @@ -2111,8 +2112,8 @@ static void calculateLayoutImpl( leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim / 2); } else if (child->style().flexEndMarginIsAuto(crossAxis, direction)) { // No-Op - } else if (child->style().flexStartMarginIsAuto( - crossAxis, direction)) { + } else if ( + child->style().flexStartMarginIsAuto(crossAxis, direction)) { leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim); } else if (alignItem == Align::FlexStart) { // No-Op @@ -2755,10 +2756,11 @@ void calculateLayout( node->style().computeMarginForAxis( FlexDirection::Row, ownerWidth, node)); widthSizingMode = SizingMode::StretchFit; - } else if (style - .resolvedMaxDimension( - direction, Dimension::Width, ownerWidth, ownerWidth, node) - .isDefined()) { + } else if ( + style + .resolvedMaxDimension( + direction, Dimension::Width, ownerWidth, ownerWidth, node) + .isDefined()) { width = style .resolvedMaxDimension( direction, Dimension::Width, ownerWidth, ownerWidth, node) @@ -2783,14 +2785,11 @@ void calculateLayout( node->style().computeMarginForAxis( FlexDirection::Column, ownerWidth, node)); heightSizingMode = SizingMode::StretchFit; - } else if (style - .resolvedMaxDimension( - direction, - Dimension::Height, - ownerHeight, - ownerWidth, - node) - .isDefined()) { + } else if ( + style + .resolvedMaxDimension( + direction, Dimension::Height, ownerHeight, ownerWidth, node) + .isDefined()) { height = style .resolvedMaxDimension( diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h index ff2d93e0f37e..5168da1ac197 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h @@ -293,12 +293,13 @@ class YG_EXPORT Style { Direction direction, Dimension axis, float referenceLength, - float ownerWidth) const { + float ownerWidth, + YGNodeConstRef node) const { const auto handle = minDimensions_[yoga::to_underlying(axis)]; if (handle.isUndefined()) { return FloatOptional{}; } - FloatOptional value = resolve(handle, referenceLength); + FloatOptional value = resolve(handle, referenceLength, node); if (boxSizing() == BoxSizing::BorderBox || !value.isDefined()) { return value; } @@ -322,12 +323,13 @@ class YG_EXPORT Style { Direction direction, Dimension axis, float referenceLength, - float ownerWidth) const { + float ownerWidth, + YGNodeConstRef node) const { const auto handle = maxDimensions_[yoga::to_underlying(axis)]; if (handle.isUndefined()) { return FloatOptional{}; } - FloatOptional value = resolve(handle, referenceLength); + FloatOptional value = resolve(handle, referenceLength, node); if (boxSizing() == BoxSizing::BorderBox || !value.isDefined()) { return value; } @@ -416,72 +418,87 @@ class YG_EXPORT Style { float computeFlexStartPosition( FlexDirection axis, Direction direction, - float axisSize) const { - return resolve(computePosition(flexStartEdge(axis), direction), axisSize) + float axisSize, + YGNodeConstRef node) const { + return resolve( + computePosition(flexStartEdge(axis), direction), axisSize, node) .unwrapOrDefault(0.0f); } float computeInlineStartPosition( FlexDirection axis, Direction direction, - float axisSize) const { + float axisSize, + YGNodeConstRef node) const { return resolve( computePosition(inlineStartEdge(axis, direction), direction), - axisSize) + axisSize, + node) .unwrapOrDefault(0.0f); } float computeFlexEndPosition( FlexDirection axis, Direction direction, - float axisSize) const { - return resolve(computePosition(flexEndEdge(axis), direction), axisSize) + float axisSize, + YGNodeConstRef node) const { + return resolve( + computePosition(flexEndEdge(axis), direction), axisSize, node) .unwrapOrDefault(0.0f); } float computeInlineEndPosition( FlexDirection axis, Direction direction, - float axisSize) const { + float axisSize, + YGNodeConstRef node) const { return resolve( computePosition(inlineEndEdge(axis, direction), direction), - axisSize) + axisSize, + node) .unwrapOrDefault(0.0f); } float computeFlexStartMargin( FlexDirection axis, Direction direction, - float widthSize) const { - return resolve(computeMargin(flexStartEdge(axis), direction), widthSize) + float widthSize, + YGNodeConstRef node) const { + return resolve( + computeMargin(flexStartEdge(axis), direction), widthSize, node) .unwrapOrDefault(0.0f); } float computeInlineStartMargin( FlexDirection axis, Direction direction, - float widthSize) const { + float widthSize, + YGNodeConstRef node) const { return resolve( computeMargin(inlineStartEdge(axis, direction), direction), - widthSize) + widthSize, + node) .unwrapOrDefault(0.0f); } float computeFlexEndMargin( FlexDirection axis, Direction direction, - float widthSize) const { - return resolve(computeMargin(flexEndEdge(axis), direction), widthSize) + float widthSize, + YGNodeConstRef node) const { + return resolve(computeMargin(flexEndEdge(axis), direction), widthSize, node) .unwrapOrDefault(0.0f); } float computeInlineEndMargin( FlexDirection axis, Direction direction, - float widthSize) const { + float widthSize, + YGNodeConstRef node) const { return resolve( computeMargin(inlineEndEdge(axis, direction), direction), - widthSize) + widthSize, + node) .unwrapOrDefault(0.0f); } @@ -490,7 +507,8 @@ class YG_EXPORT Style { Direction direction, YGNodeConstRef node) const { return maxOrDefined( - resolve(computeBorder(flexStartEdge(axis), direction), 0.0f).unwrap(), + resolve(computeBorder(flexStartEdge(axis), direction), 0.0f, node) + .unwrap(), 0.0f); } @@ -500,7 +518,9 @@ class YG_EXPORT Style { YGNodeConstRef node) const { return maxOrDefined( resolve( - computeBorder(inlineStartEdge(axis, direction), direction), 0.0f) + computeBorder(inlineStartEdge(axis, direction), direction), + 0.0f, + node) .unwrap(), 0.0f); } @@ -510,7 +530,8 @@ class YG_EXPORT Style { Direction direction, YGNodeConstRef node) const { return maxOrDefined( - resolve(computeBorder(flexEndEdge(axis), direction), 0.0f).unwrap(), + resolve(computeBorder(flexEndEdge(axis), direction), 0.0f, node) + .unwrap(), 0.0f); } @@ -519,7 +540,10 @@ class YG_EXPORT Style { Direction direction, YGNodeConstRef node) const { return maxOrDefined( - resolve(computeBorder(inlineEndEdge(axis, direction), direction), 0.0f) + resolve( + computeBorder(inlineEndEdge(axis, direction), direction), + 0.0f, + node) .unwrap(), 0.0f); } @@ -530,7 +554,7 @@ class YG_EXPORT Style { float widthSize, YGNodeConstRef node) const { return maxOrDefined( - resolve(computePadding(flexStartEdge(axis), direction), widthSize) + resolve(computePadding(flexStartEdge(axis), direction), widthSize, node) .unwrap(), 0.0f); } @@ -543,7 +567,8 @@ class YG_EXPORT Style { return maxOrDefined( resolve( computePadding(inlineStartEdge(axis, direction), direction), - widthSize) + widthSize, + node) .unwrap(), 0.0f); } @@ -554,7 +579,7 @@ class YG_EXPORT Style { float widthSize, YGNodeConstRef node) const { return maxOrDefined( - resolve(computePadding(flexEndEdge(axis), direction), widthSize) + resolve(computePadding(flexEndEdge(axis), direction), widthSize, node) .unwrap(), 0.0f); } @@ -567,7 +592,8 @@ class YG_EXPORT Style { return maxOrDefined( resolve( computePadding(inlineEndEdge(axis, direction), direction), - widthSize) + widthSize, + node) .unwrap(), 0.0f); } @@ -632,6 +658,8 @@ class YG_EXPORT Style { FlexDirection axis, float widthSize, YGNodeConstRef node) const { + // The total margin for a given axis does not depend on the direction + // so hardcoding LTR here to avoid piping direction to this function return computeInlineStartMargin(axis, Direction::LTR, widthSize, node) + computeInlineEndMargin(axis, Direction::LTR, widthSize, node); } @@ -641,7 +669,7 @@ class YG_EXPORT Style { float ownerSize, YGNodeConstRef node) const { auto gap = isRow(axis) ? computeColumnGap() : computeRowGap(); - return maxOrDefined(resolve(gap, ownerSize).unwrap(), 0.0f); + return maxOrDefined(resolve(gap, ownerSize, node).unwrap(), 0.0f); } float computeGapForDimension( @@ -650,7 +678,7 @@ class YG_EXPORT Style { YGNodeConstRef node) const { auto gap = dimension == Dimension::Width ? computeColumnGap() : computeRowGap(); - return maxOrDefined(resolve(gap, ownerSize).unwrap(), 0.0f); + return maxOrDefined(resolve(gap, ownerSize, node).unwrap(), 0.0f); } bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const { @@ -913,7 +941,10 @@ class YG_EXPORT Style { * StyleLength/StyleSizeLength object on the stack during hot-path overhead * calculations. */ - FloatOptional resolve(StyleValueHandle handle, float referenceLength) const { + FloatOptional resolve( + StyleValueHandle handle, + float referenceLength, + YGNodeConstRef node) const { if (handle.isPoint()) { return FloatOptional{pool_.getStoredValue(handle)}; } @@ -921,6 +952,17 @@ class YG_EXPORT Style { return FloatOptional{ pool_.getStoredValue(handle) * referenceLength * 0.01f}; } + if (handle.isDynamic()) { + auto callback = pool_.getDynamicCallback(handle); + if (callback) { + return FloatOptional{callback( + node, + pool_.getDynamicCallbackID(handle), + YGValueDynamicContext{referenceLength}) + .value}; + } + } + return FloatOptional{}; } diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h index 9fe036c741b8..0009a20f3c42 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h @@ -57,6 +57,10 @@ class StyleValueHandle { return type() == Type::Point; } + constexpr bool isDynamic() const { + return type() == Type::Dynamic; + } + private: friend class StyleValuePool; diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h index e11ee6d2add3..135cb90aff8d 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h @@ -141,6 +141,19 @@ class StyleValuePool { : unpackInlineInteger(handle.value()); } + YGValueDynamic getDynamicCallback(StyleValueHandle handle) const { + assert(handle.isDynamic()); + assert(handle.isValueIndexed()); + return reinterpret_cast( + static_cast(buffer_.get64(handle.value()))); + } + + YGValueDynamicID getDynamicCallbackID(StyleValueHandle handle) const { + assert(handle.isDynamic()); + assert(handle.isValueIndexed()); + return buffer_.get32(handle.value() + 2); + } + private: void storeValue( StyleValueHandle& handle, @@ -175,17 +188,29 @@ class StyleValuePool { } } - YGValueDynamic getDynamicCallback(StyleValueHandle handle) const { - assert(handle.isDynamic()); - assert(handle.isValueIndexed()); - return reinterpret_cast( - static_cast(buffer_.get64(handle.value()))); - } + void storeDynamic( + StyleValueHandle& handle, + YGValueDynamic callback, + YGValueDynamicID id) { + handle.setType(StyleValueHandle::Type::Dynamic); + auto packed = static_cast(reinterpret_cast(callback)); - YGValueDynamicID getDynamicCallbackID(StyleValueHandle handle) const { - assert(handle.isDynamic()); - assert(handle.isValueIndexed()); - return buffer_.get32(handle.value() + 2); + if (handle.isValueIndexed()) { + auto oldIndex = handle.value(); + auto newIndex = buffer_.replace(oldIndex, packed); + if (newIndex == oldIndex) { + [[maybe_unused]] auto replacedIndex = buffer_.replace( + static_cast(newIndex + 2), static_cast(id)); + } else { + buffer_.push(static_cast(id)); + } + handle.setValue(newIndex); + } else { + auto newIndex = buffer_.push(packed); + buffer_.push(static_cast(id)); + handle.setValue(newIndex); + handle.setValueIsIndexed(); + } } static constexpr bool isIntegerPackable(float f) { From d59fc0953202051e17d193c4c93f92af6c7555ba Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Thu, 2 Jul 2026 14:13:29 +0200 Subject: [PATCH 6/7] feat: update api snapshots --- .../api-snapshots/ReactAndroidDebugCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactAndroidNewarchCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactAndroidReleaseCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactAppleDebugCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactAppleNewarchCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactAppleReleaseCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactCommonDebugCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactCommonNewarchCxx.api | 110 +++++++++++++----- .../api-snapshots/ReactCommonReleaseCxx.api | 110 +++++++++++++----- 9 files changed, 720 insertions(+), 270 deletions(-) diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index d484218abb9d..864af13593f8 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -293,6 +293,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + struct _JNIEnv { public const struct JNINativeInterface* functions; } @@ -598,6 +602,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -5514,6 +5519,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -5528,12 +5534,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -6882,6 +6889,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -9709,6 +9741,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -13116,8 +13154,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -13133,31 +13171,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -13208,28 +13246,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -13237,7 +13282,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -13248,11 +13293,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -13260,6 +13307,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -13435,6 +13484,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index ce3256b5f8be..a5ce80e8083e 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -293,6 +293,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + struct _JNIEnv { public const struct JNINativeInterface* functions; } @@ -597,6 +601,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -5325,6 +5330,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -5339,12 +5345,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -6693,6 +6700,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -9332,6 +9364,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -12739,8 +12777,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -12756,31 +12794,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -12831,28 +12869,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -12860,7 +12905,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -12871,11 +12916,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -12883,6 +12930,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -13058,6 +13107,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 04c7b0691b18..853d37359ed8 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -293,6 +293,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + struct _JNIEnv { public const struct JNINativeInterface* functions; } @@ -598,6 +602,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -5505,6 +5510,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -5519,12 +5525,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -6873,6 +6880,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -9562,6 +9594,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -12969,8 +13007,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -12986,31 +13024,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -13061,28 +13099,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -13090,7 +13135,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -13101,11 +13146,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -13113,6 +13160,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -13288,6 +13337,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index e21c6873a943..b013ad57208c 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -3231,6 +3231,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + template struct RCTRequired { public RCTRequired& operator=(RCTRequired&&) = default; @@ -3463,6 +3467,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -7694,6 +7699,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -7708,12 +7714,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -9076,6 +9083,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -11618,6 +11650,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -14937,8 +14975,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -14954,31 +14992,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -15029,28 +15067,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -15058,7 +15103,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -15069,11 +15114,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -15081,6 +15128,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -15256,6 +15305,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 55d24e18d268..98b30adec72c 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -3219,6 +3219,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + template struct RCTRequired { public RCTRequired& operator=(RCTRequired&&) = default; @@ -3450,6 +3454,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -7533,6 +7538,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -7547,12 +7553,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -8915,6 +8922,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -11303,6 +11335,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -14622,8 +14660,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -14639,31 +14677,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -14714,28 +14752,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -14743,7 +14788,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -14754,11 +14799,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -14766,6 +14813,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -14941,6 +14990,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index cf81dcca1aec..08fcb3e98c88 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -3231,6 +3231,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + template struct RCTRequired { public RCTRequired& operator=(RCTRequired&&) = default; @@ -3463,6 +3467,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -7685,6 +7690,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -7699,12 +7705,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -9067,6 +9074,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -11481,6 +11513,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -14800,8 +14838,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -14817,31 +14855,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -14892,28 +14930,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -14921,7 +14966,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -14932,11 +14977,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -14944,6 +14991,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -15119,6 +15168,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index 66d75beaa700..f8b3151c4b7b 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -16,6 +16,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + bool facebook::xplat::jsArgAsBool(const folly::dynamic& args, size_t n); double facebook::xplat::jsArgAsDouble(const folly::dynamic& args, size_t n); @@ -228,6 +232,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -3927,6 +3932,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -3941,12 +3947,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -5220,6 +5227,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -6781,6 +6813,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -10090,8 +10128,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -10107,31 +10145,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -10182,28 +10220,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -10211,7 +10256,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -10222,11 +10267,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -10234,6 +10281,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -10409,6 +10458,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index cd680589a109..3a9a39599aac 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -16,6 +16,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + bool facebook::xplat::jsArgAsBool(const folly::dynamic& args, size_t n); double facebook::xplat::jsArgAsDouble(const folly::dynamic& args, size_t n); @@ -227,6 +231,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -3778,6 +3783,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -3792,12 +3798,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -5071,6 +5078,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -6606,6 +6638,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -9915,8 +9953,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -9932,31 +9970,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -10007,28 +10045,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -10036,7 +10081,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -10047,11 +10092,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -10059,6 +10106,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -10234,6 +10283,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index b6573d00004b..6ca3c5ff25f2 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -16,6 +16,10 @@ struct YGValue { public float value; } +struct YGValueDynamicContext { + public float referenceLength; +} + bool facebook::xplat::jsArgAsBool(const folly::dynamic& args, size_t n); double facebook::xplat::jsArgAsDouble(const folly::dynamic& args, size_t n); @@ -228,6 +232,7 @@ using facebook::react::CSSRadialGradientSize = std::variant; using facebook::react::CSSTransformFunction = facebook::react::CSSCompoundDataType; using facebook::react::CSSTransformList = facebook::react::CSSWhitespaceSeparatedList; +using facebook::react::CalcExpressions = std::unordered_map; using facebook::react::CallFunc = std::function; using facebook::react::Callback = std::function; using facebook::react::CallbackHandle = facebook::jsi::Object; @@ -3918,6 +3923,7 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public YogaLayoutableShadowNode(const facebook::react::ShadowNode& sourceShadowNode, const facebook::react::ShadowNodeFragment& fragment); public YogaLayoutableShadowNode(const facebook::react::ShadowNodeFragment& fragment, const facebook::react::ShadowNodeFamily::Shared& family, facebook::react::ShadowNodeTraits traits); public facebook::react::Rect getContentBounds() const; + public static YGValue yogaNodeCalcValueResolver(YGNodeConstRef yogaNode, YGValueDynamicID id, YGValueDynamicContext context); public using ListOfShared = std::vector; public using Shared = std::shared_ptr; public virtual bool getIsLayoutClean() const override; @@ -3932,12 +3938,13 @@ class facebook::react::YogaLayoutableShadowNode : public facebook::react::Layout public void setPositionType(YGPositionType positionType) const; public void setSize(facebook::react::Size size) const; public void updateYogaChildren(); - public void updateYogaProps(); + public void updateYogaProps(const facebook::react::CalcExpressions& previousCalcExpressions = {}); } class facebook::react::YogaStylableProps : public facebook::react::Props { public YogaStylableProps() = default; public YogaStylableProps(const facebook::react::PropsParserContext& context, const facebook::react::YogaStylableProps& sourceProps, const facebook::react::RawProps& rawProps, const std::function& filterObjectKeys = nullptr); + public facebook::react::CalcExpressions calcExpressions; public facebook::yoga::Style yogaStyle; public facebook::yoga::Style::Length insetBlockEnd; public facebook::yoga::Style::Length insetBlockStart; @@ -5211,6 +5218,31 @@ struct facebook::react::CSSBrightnessFilter { public float amount; } +struct facebook::react::CSSCalc { + public bool unitless; + public constexpr bool isPercentOnly() const; + public constexpr bool isPointsOnly() const; + public constexpr bool isUnitless() const; + public constexpr bool isZero() const; + public constexpr bool operator==(const facebook::react::CSSCalc& rhs) const = default; + public constexpr facebook::react::CSSCalc operator*(float scalar) const; + public constexpr facebook::react::CSSCalc operator+(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator-() const; + public constexpr facebook::react::CSSCalc operator-(const facebook::react::CSSCalc& rhs) const; + public constexpr facebook::react::CSSCalc operator/(float scalar) const; + public float percent; + public float px; + public float resolve(float percentRef, float viewportWidth, float viewportHeight) const; + public float vh; + public float vw; + public static constexpr facebook::react::CSSCalc fromNumber(float value); + public static constexpr facebook::react::CSSCalc fromPercent(float value); + public static constexpr facebook::react::CSSCalc fromPoints(float value); + public static constexpr facebook::react::CSSCalc fromVh(float value); + public static constexpr facebook::react::CSSCalc fromVw(float value); + public static constexpr std::optional fromLength(float value, facebook::react::CSSLengthUnit unit); +} + struct facebook::react::CSSColor { public constexpr bool operator==(const facebook::react::CSSColor& rhs) const = default; public static constexpr facebook::react::CSSColor black(); @@ -6772,6 +6804,12 @@ struct facebook::react::CSSDataTypeParser { struct facebook::react::CSSDataTypeParser : public facebook::react::detail::CSSFilterSimpleAmountParser { } +struct facebook::react::CSSDataTypeParser { + public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); + public static constexpr std::optional consumeSimpleBlock(const facebook::react::CSSSimpleBlock& block, facebook::react::CSSValueParser& parser); + public static constexpr std::optional parseCalcExpression(facebook::react::CSSValueParser& parser); +} + struct facebook::react::CSSDataTypeParser { public static constexpr std::optional consumeFunctionBlock(const facebook::react::CSSFunctionBlock& func, facebook::react::CSSValueParser& parser); public static constexpr std::optional consumePreservedToken(const facebook::react::CSSPreservedToken& token); @@ -10081,8 +10119,8 @@ class facebook::yoga::Style { public facebook::yoga::FloatOptional flex() const; public facebook::yoga::FloatOptional flexGrow() const; public facebook::yoga::FloatOptional flexShrink() const; - public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; - public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth) const; + public facebook::yoga::FloatOptional resolvedMaxDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; + public facebook::yoga::FloatOptional resolvedMinDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension axis, float referenceLength, float ownerWidth, YGNodeConstRef node) const; public facebook::yoga::Justify justifyContent() const; public facebook::yoga::Justify justifyItems() const; public facebook::yoga::Justify justifySelf() const; @@ -10098,31 +10136,31 @@ class facebook::yoga::Style { public facebook::yoga::Style::SizeLength maxDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Style::SizeLength minDimension(facebook::yoga::Dimension axis) const; public facebook::yoga::Wrap flexWrap() const; - public float computeBorderForAxis(facebook::yoga::FlexDirection axis) const; - public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize) const; - public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize) const; - public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction) const; - public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize) const; - public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize) const; - public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize) const; - public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize) const; + public float computeBorderForAxis(facebook::yoga::FlexDirection axis, YGNodeConstRef node) const; + public float computeFlexEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeFlexStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeFlexStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeFlexStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeGapForAxis(facebook::yoga::FlexDirection axis, float ownerSize, YGNodeConstRef node) const; + public float computeGapForDimension(facebook::yoga::Dimension dimension, float ownerSize, YGNodeConstRef node) const; + public float computeInlineEndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineEndMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineEndPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeInlineStartBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, YGNodeConstRef node) const; + public float computeInlineStartMargin(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPadding(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPaddingAndBorder(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float widthSize, YGNodeConstRef node) const; + public float computeInlineStartPosition(facebook::yoga::FlexDirection axis, facebook::yoga::Direction direction, float axisSize, YGNodeConstRef node) const; + public float computeMarginForAxis(facebook::yoga::FlexDirection axis, float widthSize, YGNodeConstRef node) const; + public float computePaddingAndBorderForDimension(facebook::yoga::Direction direction, facebook::yoga::Dimension dimension, float widthSize, YGNodeConstRef node) const; public static constexpr float DefaultFlexGrow; public static constexpr float DefaultFlexShrink; public static constexpr float WebDefaultFlexShrink; @@ -10173,28 +10211,35 @@ class facebook::yoga::Style { } class facebook::yoga::StyleLength { + public YGValueDynamic callback() const; public constexpr StyleLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoints() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength); + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleLength ofAuto(); public static constexpr facebook::yoga::StyleLength percent(float value); public static constexpr facebook::yoga::StyleLength points(float value); public static constexpr facebook::yoga::StyleLength undefined(); + public static facebook::yoga::StyleLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleSizeLength { + public YGValueDynamic callback() const; public constexpr StyleSizeLength() = default; + public constexpr YGValueDynamicID callbackId() const; public constexpr bool inexactEquals(const facebook::yoga::StyleSizeLength& other) const; public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isFitContent() const; public constexpr bool isMaxContent() const; public constexpr bool isPercent() const; @@ -10202,7 +10247,7 @@ class facebook::yoga::StyleSizeLength { public constexpr bool isStretch() const; public constexpr bool isUndefined() const; public constexpr bool operator==(const facebook::yoga::StyleSizeLength& rhs) const; - public constexpr facebook::yoga::FloatOptional resolve(float referenceLength) const; + public constexpr facebook::yoga::FloatOptional resolve(float referenceLength, YGNodeConstRef node) const; public constexpr facebook::yoga::FloatOptional value() const; public constexpr operator YGValue() const; public static constexpr facebook::yoga::StyleSizeLength ofAuto(); @@ -10213,11 +10258,13 @@ class facebook::yoga::StyleSizeLength { public static constexpr facebook::yoga::StyleSizeLength points(float value); public static constexpr facebook::yoga::StyleSizeLength stretch(float fraction); public static constexpr facebook::yoga::StyleSizeLength undefined(); + public static facebook::yoga::StyleSizeLength dynamic(YGValueDynamic callback, YGValueDynamicID id); } class facebook::yoga::StyleValueHandle { public constexpr bool isAuto() const; public constexpr bool isDefined() const; + public constexpr bool isDynamic() const; public constexpr bool isPercent() const; public constexpr bool isPoint() const; public constexpr bool isUndefined() const; @@ -10225,6 +10272,8 @@ class facebook::yoga::StyleValueHandle { } class facebook::yoga::StyleValuePool { + public YGValueDynamic getDynamicCallback(facebook::yoga::StyleValueHandle handle) const; + public YGValueDynamicID getDynamicCallbackID(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::FloatOptional getNumber(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleLength getLength(facebook::yoga::StyleValueHandle handle) const; public facebook::yoga::StyleSizeLength getSize(facebook::yoga::StyleValueHandle handle) const; @@ -10400,6 +10449,7 @@ enum facebook::yoga::SizingMode { enum facebook::yoga::Unit : uint8_t { Auto, + Dynamic, FitContent, MaxContent, Percent, From 3e05d778852b1e182ea73d307b5bc5258167b763 Mon Sep 17 00:00:00 2001 From: Kamil Paradowski Date: Wed, 8 Jul 2026 16:20:01 +0200 Subject: [PATCH 7/7] feat: introduce a new feature flag `enableCSSCalc` to enable CSS calc() support --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 160 ++++++++++-------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../components/view/YogaStylableProps.cpp | 6 +- .../ReactNativeFeatureFlags.config.js | 11 ++ .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 21 files changed, 211 insertions(+), 92 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 260e0eab4a05..1a2ed7a36c6e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8b571241be0c86847ed265ab665059b2>> + * @generated SignedSource<<3a917b13b408c071a21b2b91e1f9fbb6>> */ /** @@ -120,6 +120,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableBridgelessArchitecture(): Boolean = accessor.enableBridgelessArchitecture() + /** + * Enables CSS calc() support for layout (Yoga) style props in Fabric. + */ + @JvmStatic + public fun enableCSSCalc(): Boolean = accessor.enableCSSCalc() + /** * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index dae9d7bb49f2..51b5a725915b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<856ed167e90b330583c3a6e981927c43>> + * @generated SignedSource<<20981eeda0169d86c09b1568a106827a>> */ /** @@ -35,6 +35,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableAndroidFontWeightAdjustmentCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null + private var enableCSSCalcCache: Boolean? = null private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null @@ -241,6 +242,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableCSSCalc(): Boolean { + var cached = enableCSSCalcCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableCSSCalc() + enableCSSCalcCache = cached + } + return cached + } + override fun enableCppPropsIteratorSetter(): Boolean { var cached = enableCppPropsIteratorSetterCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 92ca8c72acb9..84e8ef083859 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2f68282c0b8c1971acdab2f229189d82>> + * @generated SignedSource<<32561f31188d5b47f5bdfe690ab198de>> */ /** @@ -58,6 +58,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableBridgelessArchitecture(): Boolean + @DoNotStrip @JvmStatic public external fun enableCSSCalc(): Boolean + @DoNotStrip @JvmStatic public external fun enableCppPropsIteratorSetter(): Boolean @DoNotStrip @JvmStatic public external fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 82e2ab209e60..92e0ce7e42cf 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5f946970ba2e0676b55cc150de4bee01>> + * @generated SignedSource<> */ /** @@ -53,6 +53,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableBridgelessArchitecture(): Boolean = false + override fun enableCSSCalc(): Boolean = false + override fun enableCppPropsIteratorSetter(): Boolean = false override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = true diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 7e1021fc7fb7..ff2e8ee164fb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<08aa94f7767a9e3947d88814f7ae0edd>> */ /** @@ -39,6 +39,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableAndroidFontWeightAdjustmentCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null + private var enableCSSCalcCache: Boolean? = null private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null @@ -260,6 +261,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableCSSCalc(): Boolean { + var cached = enableCSSCalcCache + if (cached == null) { + cached = currentProvider.enableCSSCalc() + accessedFeatureFlags.add("enableCSSCalc") + enableCSSCalcCache = cached + } + return cached + } + override fun enableCppPropsIteratorSetter(): Boolean { var cached = enableCppPropsIteratorSetterCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 97cc8ad48c10..c4d44f80b5b1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<1abf44b0b995cb213390879036fc3ce7>> */ /** @@ -53,6 +53,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableBridgelessArchitecture(): Boolean + @DoNotStrip public fun enableCSSCalc(): Boolean + @DoNotStrip public fun enableCppPropsIteratorSetter(): Boolean @DoNotStrip public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 842a22bce848..00eaf1277e83 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6719e639a89507a2019fcf1901394152>> + * @generated SignedSource<<455b05f4803f2289d542ef0debaea35b>> */ /** @@ -129,6 +129,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableCSSCalc() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableCSSCalc"); + return method(javaProvider_); + } + bool enableCppPropsIteratorSetter() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableCppPropsIteratorSetter"); @@ -628,6 +634,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture( return ReactNativeFeatureFlags::enableBridgelessArchitecture(); } +bool JReactNativeFeatureFlagsCxxInterop::enableCSSCalc( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableCSSCalc(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); @@ -1054,6 +1065,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableBridgelessArchitecture", JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture), + makeNativeMethod( + "enableCSSCalc", + JReactNativeFeatureFlagsCxxInterop::enableCSSCalc), makeNativeMethod( "enableCppPropsIteratorSetter", JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index ebec7a9431d4..0af08efeef1c 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<9ca21b0fd2218455c4b694ff9159eda1>> */ /** @@ -75,6 +75,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableBridgelessArchitecture( facebook::jni::alias_ref); + static bool enableCSSCalc( + facebook::jni::alias_ref); + static bool enableCppPropsIteratorSetter( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 420ed77ae700..2fbeab73d037 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<929bf9431ec07ddc39040cfff5b94754>> + * @generated SignedSource<<227025369a508a375cbcb9a9fd7a9acd>> */ /** @@ -86,6 +86,10 @@ bool ReactNativeFeatureFlags::enableBridgelessArchitecture() { return getAccessor().enableBridgelessArchitecture(); } +bool ReactNativeFeatureFlags::enableCSSCalc() { + return getAccessor().enableCSSCalc(); +} + bool ReactNativeFeatureFlags::enableCppPropsIteratorSetter() { return getAccessor().enableCppPropsIteratorSetter(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index e44bb33f8d9e..c18199bdb67f 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<204b892e9a4d38942c286fe8a4e3bb88>> */ /** @@ -114,6 +114,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableBridgelessArchitecture(); + /** + * Enables CSS calc() support for layout (Yoga) style props in Fabric. + */ + RN_EXPORT static bool enableCSSCalc(); + /** * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 2a5b7e9f9ea2..8701033fd57b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8082ced6a04b74c4dd7bff22ccb0fd3c>> + * @generated SignedSource<> */ /** @@ -299,6 +299,24 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableCSSCalc() { + auto flagValue = enableCSSCalc_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(15, "enableCSSCalc"); + + flagValue = currentProvider_->enableCSSCalc(); + enableCSSCalc_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { auto flagValue = enableCppPropsIteratorSetter_.load(); @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(16, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCustomFocusSearchOnClippedElementsAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enableCustomFocusSearchOnClippedElementsAndroid"); + markFlagAsAccessed(17, "enableCustomFocusSearchOnClippedElementsAndroid"); flagValue = currentProvider_->enableCustomFocusSearchOnClippedElementsAndroid(); enableCustomFocusSearchOnClippedElementsAndroid_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableDestroyShadowTreeRevisionAsync"); + markFlagAsAccessed(18, "enableDestroyShadowTreeRevisionAsync"); flagValue = currentProvider_->enableDestroyShadowTreeRevisionAsync(); enableDestroyShadowTreeRevisionAsync_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(19, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableEagerRootViewAttachment"); + markFlagAsAccessed(20, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableExclusivePropsUpdateAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableExclusivePropsUpdateAndroid"); + markFlagAsAccessed(21, "enableExclusivePropsUpdateAndroid"); flagValue = currentProvider_->enableExclusivePropsUpdateAndroid(); enableExclusivePropsUpdateAndroid_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricCommitBranching() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enableFabricCommitBranching"); + markFlagAsAccessed(22, "enableFabricCommitBranching"); flagValue = currentProvider_->enableFabricCommitBranching(); enableFabricCommitBranching_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableFabricLogs"); + markFlagAsAccessed(23, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFlexboxAutoMinSizeInStrictMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableFlexboxAutoMinSizeInStrictMode"); + markFlagAsAccessed(24, "enableFlexboxAutoMinSizeInStrictMode"); flagValue = currentProvider_->enableFlexboxAutoMinSizeInStrictMode(); enableFlexboxAutoMinSizeInStrictMode_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableFontScaleChangesUpdatingLayout"); + markFlagAsAccessed(25, "enableFontScaleChangesUpdatingLayout"); flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); enableFontScaleChangesUpdatingLayout_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(26, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(27, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(28, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(29, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableImperativeFocus"); + markFlagAsAccessed(30, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(31, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(32, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableKeyEvents"); + markFlagAsAccessed(33, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(34, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(35, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(36, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMutationObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableMutationObserverByDefault"); + markFlagAsAccessed(37, "enableMutationObserverByDefault"); flagValue = currentProvider_->enableMutationObserverByDefault(); enableMutationObserverByDefault_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableNativeCSSParsing"); + markFlagAsAccessed(38, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableNetworkEventReporting"); + markFlagAsAccessed(39, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enablePreparedTextLayout"); + markFlagAsAccessed(40, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(41, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableRuntimeSchedulerQueueClearingOnError // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableRuntimeSchedulerQueueClearingOnError"); + markFlagAsAccessed(42, "enableRuntimeSchedulerQueueClearingOnError"); flagValue = currentProvider_->enableRuntimeSchedulerQueueClearingOnError(); enableRuntimeSchedulerQueueClearingOnError_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSchedulerDelegateInvalidation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableSchedulerDelegateInvalidation"); + markFlagAsAccessed(43, "enableSchedulerDelegateInvalidation"); flagValue = currentProvider_->enableSchedulerDelegateInvalidation(); enableSchedulerDelegateInvalidation_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(44, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enableViewCulling"); + markFlagAsAccessed(45, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "enableViewRecycling"); + markFlagAsAccessed(46, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableViewRecyclingForImage"); + markFlagAsAccessed(47, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(48, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "enableViewRecyclingForText"); + markFlagAsAccessed(49, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "enableViewRecyclingForView"); + markFlagAsAccessed(50, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(51, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorParentTagForUnflattenCase // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "fixDifferentiatorParentTagForUnflattenCase"); + markFlagAsAccessed(52, "fixDifferentiatorParentTagForUnflattenCase"); flagValue = currentProvider_->fixDifferentiatorParentTagForUnflattenCase(); fixDifferentiatorParentTagForUnflattenCase_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(53, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::fixYogaFlexBasisFitContentInMainAxis() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "fixYogaFlexBasisFitContentInMainAxis"); + markFlagAsAccessed(54, "fixYogaFlexBasisFitContentInMainAxis"); flagValue = currentProvider_->fixYogaFlexBasisFitContentInMainAxis(); fixYogaFlexBasisFitContentInMainAxis_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(55, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "fuseboxEnabledRelease"); + markFlagAsAccessed(56, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxFrameRecordingEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "fuseboxFrameRecordingEnabled"); + markFlagAsAccessed(57, "fuseboxFrameRecordingEnabled"); flagValue = currentProvider_->fuseboxFrameRecordingEnabled(); fuseboxFrameRecordingEnabled_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(58, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "fuseboxScreenshotCaptureEnabled"); + markFlagAsAccessed(59, "fuseboxScreenshotCaptureEnabled"); flagValue = currentProvider_->fuseboxScreenshotCaptureEnabled(); fuseboxScreenshotCaptureEnabled_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::optimizedAnimatedPropUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "optimizedAnimatedPropUpdates"); + markFlagAsAccessed(60, "optimizedAnimatedPropUpdates"); flagValue = currentProvider_->optimizedAnimatedPropUpdates(); optimizedAnimatedPropUpdates_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(61, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "perfIssuesEnabled"); + markFlagAsAccessed(62, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "perfMonitorV2Enabled"); + markFlagAsAccessed(63, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1172,7 +1190,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "preparedTextCacheSize"); + markFlagAsAccessed(64, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(65, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "redBoxV2Android"); + markFlagAsAccessed(66, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1226,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "redBoxV2IOS"); + markFlagAsAccessed(67, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(68, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1262,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(69, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(70, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1298,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipBoundsWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "syncAndroidClipBoundsWithOverflow"); + markFlagAsAccessed(71, "syncAndroidClipBoundsWithOverflow"); flagValue = currentProvider_->syncAndroidClipBoundsWithOverflow(); syncAndroidClipBoundsWithOverflow_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(72, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1352,7 +1370,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(74, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1370,7 +1388,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(75, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1388,7 +1406,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "useFabricInterop"); + markFlagAsAccessed(76, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1406,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(77, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1424,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "useNestedScrollViewAndroid"); + markFlagAsAccessed(78, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1442,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "useSharedAnimatedBackend"); + markFlagAsAccessed(79, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1460,7 +1478,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(80, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1478,7 +1496,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "useTurboModuleInterop"); + markFlagAsAccessed(81, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1496,7 +1514,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "viewCullingOutsetRatio"); + markFlagAsAccessed(82, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1514,7 +1532,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "viewTransitionEnabled"); + markFlagAsAccessed(83, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1532,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionUseHardwareBitmapAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "viewTransitionUseHardwareBitmapAndroid"); + markFlagAsAccessed(84, "viewTransitionUseHardwareBitmapAndroid"); flagValue = currentProvider_->viewTransitionUseHardwareBitmapAndroid(); viewTransitionUseHardwareBitmapAndroid_ = flagValue; @@ -1550,7 +1568,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "virtualViewPrerenderRatio"); + markFlagAsAccessed(85, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index b543cdb487b6..49c529ff291e 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -47,6 +47,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableAndroidFontWeightAdjustment(); bool enableAndroidTextMeasurementOptimizations(); bool enableBridgelessArchitecture(); + bool enableCSSCalc(); bool enableCppPropsIteratorSetter(); bool enableCustomFocusSearchOnClippedElementsAndroid(); bool enableDestroyShadowTreeRevisionAsync(); @@ -128,7 +129,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 85> accessedFeatureFlags_; + std::array, 86> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -145,6 +146,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableAndroidFontWeightAdjustment_; std::atomic> enableAndroidTextMeasurementOptimizations_; std::atomic> enableBridgelessArchitecture_; + std::atomic> enableCSSCalc_; std::atomic> enableCppPropsIteratorSetter_; std::atomic> enableCustomFocusSearchOnClippedElementsAndroid_; std::atomic> enableDestroyShadowTreeRevisionAsync_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index b8b2898bf214..01293e20b748 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<60a53054768767e46fddbb0e3a3b59d4>> + * @generated SignedSource<> */ /** @@ -87,6 +87,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableCSSCalc() override { + return false; + } + bool enableCppPropsIteratorSetter() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 9a6422671aa6..70a74732d59f 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<553b7e77f96cf03411007ce24cc6ac4b>> + * @generated SignedSource<> */ /** @@ -180,6 +180,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableBridgelessArchitecture(); } + bool enableCSSCalc() override { + auto value = values_["enableCSSCalc"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableCSSCalc(); + } + bool enableCppPropsIteratorSetter() override { auto value = values_["enableCppPropsIteratorSetter"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index a78679c2f54a..6aa7d5ea1142 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -40,6 +40,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableAndroidFontWeightAdjustment() = 0; virtual bool enableAndroidTextMeasurementOptimizations() = 0; virtual bool enableBridgelessArchitecture() = 0; + virtual bool enableCSSCalc() = 0; virtual bool enableCppPropsIteratorSetter() = 0; virtual bool enableCustomFocusSearchOnClippedElementsAndroid() = 0; virtual bool enableDestroyShadowTreeRevisionAsync() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 9a71b9556b0d..98b5bbbe878c 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3428534b48b163a2de69a4ff7568e530>> + * @generated SignedSource<> */ /** @@ -119,6 +119,11 @@ bool NativeReactNativeFeatureFlags::enableBridgelessArchitecture( return ReactNativeFeatureFlags::enableBridgelessArchitecture(); } +bool NativeReactNativeFeatureFlags::enableCSSCalc( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableCSSCalc(); +} + bool NativeReactNativeFeatureFlags::enableCppPropsIteratorSetter( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index b77113df6d98..cecf91f7de8f 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -66,6 +66,8 @@ class NativeReactNativeFeatureFlags bool enableBridgelessArchitecture(jsi::Runtime& runtime); + bool enableCSSCalc(jsi::Runtime& runtime); + bool enableCppPropsIteratorSetter(jsi::Runtime& runtime); bool enableCustomFocusSearchOnClippedElementsAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index 71d4451f2e7a..3105a6b0e8d7 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -39,8 +39,10 @@ YogaStylableProps::YogaStylableProps( ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.yogaStyle : convertRawProp(context, rawProps, sourceProps.yogaStyle)) { - calcExpressions = - buildCalcExpressions(context, rawProps, sourceProps.calcExpressions); + if (ReactNativeFeatureFlags::enableCSSCalc()) { + calcExpressions = + buildCalcExpressions(context, rawProps, sourceProps.calcExpressions); + } if (!ReactNativeFeatureFlags::enableCppPropsIteratorSetter()) { convertRawPropAliases(context, sourceProps, rawProps); } diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index f938ac0987c3..389c8252bb4b 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -211,6 +211,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'canary', }, + enableCSSCalc: { + defaultValue: false, + metadata: { + dateAdded: '2026-07-07', + description: + 'Enables CSS calc() support for layout (Yoga) style props in Fabric.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableCppPropsIteratorSetter: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index ef9b21835664..8c2419de5180 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<20e95086aba6a7d45ccecfcd5321f78d>> * @flow strict * @noformat */ @@ -63,6 +63,7 @@ export type ReactNativeFeatureFlags = Readonly<{ enableAndroidFontWeightAdjustment: Getter, enableAndroidTextMeasurementOptimizations: Getter, enableBridgelessArchitecture: Getter, + enableCSSCalc: Getter, enableCppPropsIteratorSetter: Getter, enableCustomFocusSearchOnClippedElementsAndroid: Getter, enableDestroyShadowTreeRevisionAsync: Getter, @@ -264,6 +265,10 @@ export const enableAndroidTextMeasurementOptimizations: Getter = create * Feature flag to enable the new bridgeless architecture. */ export const enableBridgelessArchitecture: Getter = createNativeFlagGetter('enableBridgelessArchitecture', false); +/** + * Enables CSS calc() support for layout (Yoga) style props in Fabric. + */ +export const enableCSSCalc: Getter = createNativeFlagGetter('enableCSSCalc', false); /** * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 1717fa4dc5b8..b10a3fe098c0 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -40,6 +40,7 @@ export interface Spec extends TurboModule { readonly enableAndroidFontWeightAdjustment?: () => boolean; readonly enableAndroidTextMeasurementOptimizations?: () => boolean; readonly enableBridgelessArchitecture?: () => boolean; + readonly enableCSSCalc?: () => boolean; readonly enableCppPropsIteratorSetter?: () => boolean; readonly enableCustomFocusSearchOnClippedElementsAndroid?: () => boolean; readonly enableDestroyShadowTreeRevisionAsync?: () => boolean;