diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 4e7930a92bc..43983227bec 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -1280,6 +1280,19 @@ static void distributeFreeSpaceFirstPass( float boundMainSize = 0; float deltaFreeSpace = 0; + // The first pass performs a single distribution of the free space over all + // of the line's flexible items, so every item's tentative size must be + // computed against the *original* totals. The totals are still reduced as + // items get frozen below (so the second pass can redistribute), but those + // reduced values must not feed back into the fair-share calculation for the + // remaining items: doing so inflates their tentative size and can freeze + // items that should still be able to grow/shrink (see + // https://github.com/react/yoga/issues/2006). + const float originalTotalFlexGrowFactors = + flexLine.layout.totalFlexGrowFactors; + const float originalTotalFlexShrinkScaledFactors = + flexLine.layout.totalFlexShrinkScaledFactors; + for (auto currentLineChild : flexLine.itemsInFlow) { float childFlexBasis = boundAxisWithinMinAndMax( currentLineChild, @@ -1299,8 +1312,7 @@ static void distributeFreeSpaceFirstPass( flexShrinkScaledFactor != 0) { baseMainSize = childFlexBasis + flexLine.layout.remainingFreeSpace / - flexLine.layout.totalFlexShrinkScaledFactors * - flexShrinkScaledFactor; + originalTotalFlexShrinkScaledFactors * flexShrinkScaledFactor; boundMainSize = boundAxisWithAutoMin( currentLineChild, mainAxis, @@ -1328,8 +1340,8 @@ static void distributeFreeSpaceFirstPass( // Is this child able to grow? if (yoga::isDefined(flexGrowFactor) && flexGrowFactor != 0) { baseMainSize = childFlexBasis + - flexLine.layout.remainingFreeSpace / - flexLine.layout.totalFlexGrowFactors * flexGrowFactor; + flexLine.layout.remainingFreeSpace / originalTotalFlexGrowFactors * + flexGrowFactor; boundMainSize = boundAxis( currentLineChild, mainAxis,