From 5b3a321422648c0f62985fac40338167532708c8 Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Mon, 10 Jun 2024 18:25:19 -0700 Subject: [PATCH] Fix issue with alternating flex direction and percent postions (#44792) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44792 X-link: https://github.com/facebook/yoga/pull/1663 Fixing https://github.com/facebook/yoga/issues/1658. We had a problem where if a child had a different flex direction than its parent, and it also set a position as a percent, it would look at the wrong axis to evaluate the percent. What was happening was we were passing in the container's mainAxis size and crossAxis size to use to evaluate the position size if it was a percent. However, we matched these sizes with the main/cross axis of the child - which is wrong if the flex direction is different. I changed it so that the function just takes in ownerWidth and ownerHeight then calls isRow to determine which one to use for the main/cross axis position. This reduces the ambiguity quite a bit imo. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D58172416 fbshipit-source-id: eafd8069e03493fc56c41a76879d1ad9b7e9236d --- .../yoga/yoga/algorithm/CalculateLayout.cpp | 9 ++------- .../ReactCommon/yoga/yoga/node/Node.cpp | 17 ++++++++++------- .../ReactCommon/yoga/yoga/node/Node.h | 6 +----- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index b54eeeeca3f4af..58394a4563210b 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -545,12 +545,8 @@ static float computeFlexBasisForChildren( if (performLayout) { // Set the initial position (relative to the owner). const Direction childDirection = child->resolveDirection(direction); - const float mainDim = - isRow(mainAxis) ? availableInnerWidth : availableInnerHeight; - const float crossDim = - isRow(mainAxis) ? availableInnerHeight : availableInnerWidth; child->setPosition( - childDirection, mainDim, crossDim, availableInnerWidth); + childDirection, availableInnerWidth, availableInnerHeight); } if (child->style().positionType() == PositionType::Absolute) { @@ -2388,8 +2384,7 @@ void calculateLayout( markerData, 0, // tree root gCurrentGenerationCount.load(std::memory_order_relaxed))) { - node->setPosition( - node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth); + node->setPosition(node->getLayout().direction(), ownerWidth, ownerHeight); roundLayoutResultsToPixelGrid(node, 0.0f, 0.0f); } diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index 31ad09f8c98131..abda52f5cfe93c 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp @@ -230,9 +230,8 @@ float Node::relativePosition( void Node::setPosition( const Direction direction, - const float mainSize, - const float crossSize, - const float ownerWidth) { + const float ownerWidth, + const float ownerHeight) { /* Root nodes should be always layouted as LTR, so we don't return negative * values. */ const Direction directionRespectingRoot = @@ -244,10 +243,14 @@ void Node::setPosition( // In the case of position static these are just 0. See: // https://www.w3.org/TR/css-position-3/#valdef-position-static - const float relativePositionMain = - relativePosition(mainAxis, directionRespectingRoot, mainSize); - const float relativePositionCross = - relativePosition(crossAxis, directionRespectingRoot, crossSize); + const float relativePositionMain = relativePosition( + mainAxis, + directionRespectingRoot, + isRow(mainAxis) ? ownerWidth : ownerHeight); + const float relativePositionCross = relativePosition( + crossAxis, + directionRespectingRoot, + isRow(mainAxis) ? ownerHeight : ownerWidth); const auto mainAxisLeadingEdge = inlineStartEdge(mainAxis, direction); const auto mainAxisTrailingEdge = inlineEndEdge(mainAxis, direction); diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h index cd029b40d46671..06175b8ee03249 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h @@ -229,11 +229,7 @@ class YG_EXPORT Node : public ::YGNode { void setLayoutBorder(float border, PhysicalEdge edge); void setLayoutPadding(float padding, PhysicalEdge edge); void setLayoutPosition(float position, PhysicalEdge edge); - void setPosition( - Direction direction, - float mainSize, - float crossSize, - float ownerWidth); + void setPosition(Direction direction, float ownerWidth, float ownerHeight); // Other methods Style::Length resolveFlexBasisPtr() const;