SIGN IN SIGN UP
facebook / react-native UNCLAIMED

A framework for building native applications using React

0 0 154 C++

Spec-correct CSS Flexbox §4.5 auto-min-size opt-in on YGConfig (#57015)

Summary:
X-link: https://github.com/facebook/yoga/pull/1966

Pull Request resolved: https://github.com/facebook/react-native/pull/57015

Implements CSS Flexbox §4.5 automatic minimum sizing in Yoga. When opted in on a `YGConfig`, every flex item whose main-axis `min-{width,height}` is undefined receives a content-derived floor — `min(min-content, specified-size, max-size)` plus any aspect-ratio-transferred lower bound — so it cannot shrink below the size CSS browsers would honor.

How to opt in: clear the new `YGErrataMinSizeUndefinedInsteadOfAuto` errata bit on the config. Default configs carry the bit (preserves today's behaviour); existing trees see no change. The bit is added to `YGErrataClassic` so consumers using that constant continue to get the same default.

Three ways for a node to declare its min-content size along an axis, in this precedence order:

1. **Static per-axis value** via `YGNodeSetMinContentWidth/Height(node, value)`. Pass `YGUndefined` to clear. When set, the §4.5 probe short-circuits at this node — skipping both the dynamic callback and any container recursion. Use for known constants (e.g., images returning 0 per CSS-Images; scroll containers returning 0 on their scroll axis).

2. **Dynamic callback** via `YGNodeSetMinContentMeasureFunc(node, fn)`. Mirrors `YGMeasureFunc`'s shape. The algorithm invokes it for measure-func leaves when no static value is set.

3. **Default fallback**: the existing `YGMeasureFunc` invoked with `AtMost 0`, which text measurers naturally answer with their longest-word width.

For container nodes without a static value, the algorithm walks children directly — sum on the container's own main axis, max on the cross axis — mirroring RenderCore FlexLayout's `computeMinContentSize`. This replaces the previous `calculateLayoutInternal(performLayout=false)` re-entry and skips cross-axis sizing, padding/border resolution, alignment, and baseline machinery that the probe doesn't need.

Per-item opt-outs follow the CSS spec: explicit `min-{width,height}` (including 0), `display: none`, and `overflow != visible`.

Cost when off (default): a single errata-bit check per flex line plus one `FloatOptional` short-circuit per `boundAxisWithAutoMin` call. Sub-microsecond.

Cost when on: one min-content probe per opted-in flex item per layout pass. Static values short-circuit in ~30 ns; measure-func leaves cost one extra `measure()` call; container subtrees do one recursive sum/max walk over in-flow descendants.

Reference: https://www.w3.org/TR/css-flexbox-1/#min-size-auto. Modeled after `xplat/flexlayout/`'s `MinSizeUndefinedInsteadOfAuto` errata path.

Changelog:
[General][Added] - Add CSS Flexbox §4.5 automatic minimum sizing. Opt in by clearing the new `YGErrataMinSizeUndefinedInsteadOfAuto` errata bit on `YGConfig`. Adds `YGNodeSetMinContentWidth/Height` for static contributions and `YGMinContentMeasureFunc` for dynamic ones.'

GH pull request
https://github.com/facebook/react-native/pull/57015
https://github.com/facebook/yoga/pull/1966

Reviewed By: fbcbl

Differential Revision: D105720159

fbshipit-source-id: 57a14408b10535fd84623b4d99ae9b5fba7b35ba
A
Aditya Sharat committed
7f396d1116b4d372376439317d8f8d01452bc343
Parent: ee6958a
Committed by meta-codesync[bot] <215208954+meta-codesync[bot]@users.noreply.github.com> on 6/1/2026, 5:05:39 PM