Skip to content

Fix measure-func leaf bug#2

Open
sedrew wants to merge 2 commits into
beorn:mainfrom
sedrew:dev
Open

Fix measure-func leaf bug#2
sedrew wants to merge 2 commits into
beorn:mainfrom
sedrew:dev

Conversation

@sedrew

@sedrew sedrew commented Jul 1, 2026

Copy link
Copy Markdown

I use my own text layout engine for rendering. When a measure-function leaf has an explicit cross-axis size (e.g. width="30%" in a column or height="30%" in a row), Flexily should resolve that size and pass the resolved value to the measure function so the text is measured under the correct constraint. Instead, it was passing the parent's available cross-axis size, causing the text to be measured as if it had the parent's full width. As a result, text didn't wrap correctly and the measured height could incorrectly remain 1.

Root cause

In layout-zero.ts Phase 8 (passWidthToChild), measure-function leaves always received availCross as their cross-axis constraint, even when they had an explicit point, percent, cqi, cqmin, or calc() cross-axis size. The child's own cross-axis dimension was never resolved before calling the measure function.

Fix

Resolve the measure leaf's own cross-axis size before invoking the measure function:

  • point → use the absolute value.
  • percent → resolve against the parent's cross-axis size.
  • cqi, cqmin, and calc() → resolve via resolveValue().

Pass this resolved value to cachedMeasure() instead of the parent's availCross.

Additionally, if flexGrow changes a row measure leaf's width, re-measure it after flex distribution using the final flex-distributed width so text wrapping and the resulting height reflect the actual width.

Test coverage

Four test cases cover the fix:

  1. Row: flexGrow changes the leaf width → the leaf is re-measured at the final width and wrapping is updated.
  2. Column: width="30%" resolves to 30px in a 100px parent instead of measuring at the parent's full width.
  3. Cross-axis sizing: explicit point, percent, cqi, cqmin, and calc() values are correctly resolved before measurement.
  4. Nested flex containers: percentage cross-axis sizes resolve correctly through intermediate flex containers.

All tests fail without the fix and pass with it.

Bug

image

because take parent width

image

Fix

image

… width, not parent

The measure func received parent's full width instead of the child's
resolved percent width, preventing wrapping. 4 test cases.
@neftaly

neftaly commented Jul 2, 2026

Copy link
Copy Markdown

Hi! The description (and test header) say the fix is hasMeasureLeaf ? mainSizeToPass in passWidthToChild, but that's not in the diff? There's a re-measure instead.

…t/ cqi/cqmin/calc) and pass it to the measure func instead of parent's availCross. Additionally, after flex distribution re-measure a row measure-func leaf at the actual flex-distributed width so wrapping reflects the post-grow size. Both together prevent height=1 when the leaf has a percent/point cross-axis size.
@sedrew

sedrew commented Jul 2, 2026

Copy link
Copy Markdown
Author

Thanks neftaly. In my first fix I tried to change like this. But after that I decided change the availCross. I have corrected my PR and commit title.

const passWidthToChild =
  isRow && mainIsAutoChild && !flexGrowHasDefiniteMainBudget && !flexDistChanged && !hasMeasureLeaf
    ? NaN
  : hasMeasureLeaf                                 // ← new hasMeasureLeaf
    ? mainSizeToPass                               // ← measure: childWidth 30% 
  : !isRow && crossIsAutoForLayoutCall && !parentHasDefiniteCross && !crossIsFitContent
    ? NaN
  : isRow && mainIsPercentForLayoutCall
    ? mainAxisSize
  : !isRow && crossIsPercentForLayoutCall
    ? crossAxisSize
  : !isRow && crossIsFitContent
    ? crossAxisSize
  : isRow
    ? mainSizeToPass
  : childWidth

@neftaly

neftaly commented Jul 3, 2026

Copy link
Copy Markdown

My LLM still has problems with this (I basically just started a fresh prompt with "Review #2, tell me what the comment should be, be consise").

Can you please make a commit that is just a failing fuzzer, and a few tests (1-3, 1-2 of them failing)? And no changes to the actual codebase.
Once we have some failing tests we can fix the root cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants