From 585c4e6d30277087926ae7331b8176094258c837 Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Wed, 15 Nov 2023 11:31:34 -0800 Subject: [PATCH] Allow the containing block to set trailing position of absolute descendants (#41489) Summary: 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 --- .../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 f9674ef27c8fbc..764c065c9174f7 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -92,6 +92,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, @@ -553,6 +558,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); @@ -2392,16 +2408,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) {