gitstack
closed

Wrapped flex-row child does not propagate post-flex height growth

#126
metrofun · 2026-08-26T00:33:12Z view on GitHub

I'm seeing a layout issue when a wrapping text element is placed next to another child in a horizontal flex row.

The text gets the correct final width and wraps, but the row does not grow to the wrapped child's final height. As a result, following content is laid out too early and can overlap / render on top of the wrapped text.

I can reproduce this on go-tui v0.17.0. I also checked the current layout code on main and the relevant behavior appears unchanged.

Minimal shape

Conceptually:

column
├── row
│   ├── fixed-width label
│   └── wrapping text, flex-grow
└── next row

For example, something along these lines:

root := tui.New(
    tui.WithDisplay(tui.DisplayFlex),
    tui.WithDirection(tui.Column),
    tui.WithWidth(40),
)

row := tui.New(
    tui.WithDisplay(tui.DisplayFlex),
    tui.WithDirection(tui.Row),
    tui.WithWidthPercent(100),
)

row.AddChild(tui.New(
    tui.WithText("label"),
    tui.WithWidth(10),
))

row.AddChild(tui.New(
    tui.WithText("this is a long value that should wrap onto several lines"),
    tui.WithFlexGrow(1),
    tui.WithMinWidth(0),
    tui.WithWrap(true),
    tui.WithHeightAuto(),
))

root.AddChild(row)
root.AddChild(tui.New(tui.WithText("SENTINEL")))

With a narrow enough width, the second child wraps to multiple lines.

Expected

The horizontal row's height should become the height required by its children after their final flex widths are known.

So if the text wraps to three lines, the row should be three lines high and SENTINEL should start below it.

Actual

The wrapping child renders across multiple lines, but the horizontal row retains a smaller cross-axis height. The following sibling is positioned as if the wrapped child had not increased the row height.

In practice this causes subsequent content to overlap or appear inside the wrapped text.

What seems to be happening

From reading the layout code, this looks like a two-pass sizing problem.

HeightForWidth has to estimate child widths before the row's final flex distribution is known. Later, flex layout gives the wrapping child its real main-axis width, and at that point the child can require a larger height.

That larger post-flex child height does not appear to make it back into the row's final cross size. For a single flex line, the computed line cross size appears to get constrained/overwritten by the cross size that was allocated earlier.

So the problematic sequence seems roughly like:

estimate height using pre-flex widths
resolve actual flex widths
wrapping child now needs more height
row cross size does not grow accordingly

I don't think this is specific to text itself. The more general invariant I would expect is:

For an auto-height horizontal flex row, its final cross size should be derived from child cross sizes after final main-axis widths have been resolved.

A standalone wrapping block works as expected; the issue shows up when that wrapping element is a child of a horizontal flex row alongside other children.

grindlemire grindlemire · 2026-08-25T00:51:31Z

Thanks for the report! I'll take a look

grindlemire grindlemire · 2026-08-26T00:33:12Z

I merged a fix for this. I'll cut a release with the fix. Thanks!