From 43ab5fe38ccc8a5eaa6d885b216cc45d0a9c833d Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Mon, 4 Dec 2023 19:35:30 -0800 Subject: [PATCH] Allow the containing block to set trailing position of absolute descendants (#41489) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41489 X-link: https://github.com/facebook/yoga/pull/1471 If we are going to allow the containing block to layout its absolute descendants and NOT the direct parent then we need to change step 11 which is concerned with setting the trailing position in the case we are row or column reverse. This is the very last step in the function and is positioned that way because it operates on the assumption that all children have their position set by this time. That is no longer a valid assumption if CBs layout their absolute children. In that case the CB also needs to take care of setting the position here. Because of this problem I moved some things around. It now works like: * If errata is set, the direct parent will set trailing position for all non absolute children in step 11 * If errata is set the CB will set trailing position of absolute descendants after they are laid out inside of layoutAbsoluteDescendants Reviewed By: NickGerleman Differential Revision: D51217291 fbshipit-source-id: a7eea0d3623f9041b73d609a1de2bfb0f0343a26 --- .../yoga/yoga/algorithm/CalculateLayout.cpp | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index ce745e39430382..733603d043b230 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -93,6 +93,11 @@ static void setChildTrailingPosition( flexEndEdge(axis)); } +static bool needsTrailingPosition(const FlexDirection axis) { + return axis == FlexDirection::RowReverse || + axis == FlexDirection::ColumnReverse; +} + static void constrainMaxSizeForMode( const yoga::Node* const node, const enum FlexDirection axis, @@ -554,6 +559,17 @@ static void layoutAbsoluteDescendants( layoutMarkerData, currentDepth, generationCount); + + const FlexDirection mainAxis = resolveDirection( + currentNode->getStyle().flexDirection(), currentNodeDirection); + const FlexDirection crossAxis = + resolveCrossDirection(mainAxis, currentNodeDirection); + if (needsTrailingPosition(mainAxis)) { + setChildTrailingPosition(currentNode, child, mainAxis); + } + if (needsTrailingPosition(crossAxis)) { + setChildTrailingPosition(currentNode, child, crossAxis); + } } else if (child->getStyle().positionType() == PositionType::Static) { const Direction childDirection = child->resolveDirection(currentNodeDirection); @@ -2386,16 +2402,18 @@ static void calculateLayoutImpl( } // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN - const bool needsMainTrailingPos = mainAxis == FlexDirection::RowReverse || - mainAxis == FlexDirection::ColumnReverse; - const bool needsCrossTrailingPos = crossAxis == FlexDirection::RowReverse || - crossAxis == FlexDirection::ColumnReverse; + const bool needsMainTrailingPos = needsTrailingPosition(mainAxis); + const bool needsCrossTrailingPos = needsTrailingPosition(crossAxis); - // Set trailing position if necessary. if (needsMainTrailingPos || needsCrossTrailingPos) { for (size_t i = 0; i < childCount; i++) { const auto child = node->getChild(i); - if (child->getStyle().display() == Display::None) { + // Absolute children will be handled by their containing block since we + // cannot guarantee that their positions are set when their parents are + // done with layout. + if (child->getStyle().display() == Display::None || + (!node->hasErrata(Errata::PositionStaticBehavesLikeRelative) && + child->getStyle().positionType() == PositionType::Absolute)) { continue; } if (needsMainTrailingPos) {