Skip to content

fix(dom): measureTextNode returns natural in Undefined mode (A1+A5 / #51 #58)#89

Merged
re-marked merged 5 commits into
mainfrom
fix/nested-text-truncation
May 17, 2026
Merged

fix(dom): measureTextNode returns natural in Undefined mode (A1+A5 / #51 #58)#89
re-marked merged 5 commits into
mainfrom
fix/nested-text-truncation

Conversation

@re-marked

Copy link
Copy Markdown
Owner

Closes #51 (A1) and #58 (A5).

Summary

measureTextNode (the yoga measureFunc bound to every ink-text node) used to call wrapText even when yoga asked for intrinsic size — i.e. widthMode === Undefined with width = NaN. With 'truncate' it appended an ellipsis to the natural text and reported natural + 1; with 'truncate-start' it collapsed the entire string to a single "…" cell. That bogus width became the flex basis and cascaded into all kinds of downstream weirdness (silent truncation, surprise wrapping, layout assumptions that don't hold).

The fix is a single early return: in Undefined mode, skip wrap/truncate entirely and report the natural dimensions. Wrap and truncate are about fitting within an ACTUAL constraint; without one, the natural size is the only honest answer.

Why this is the right level

  • Yoga's basis pass calls measureFunc with Undefined when the parent's main-axis size is unknown (typical for column parents auto-sizing to content). The contract for that call is "what's your intrinsic size?" — the prior code answered with a constrained truncation, which is a category error.
  • The pre-existing if (text.includes('\n') && widthMode === Undefined) return natural branch was the same invariant for a narrower case (multiline content). It's now subsumed by the general rule.
  • Wrap/truncate at render time (render-node-to-output.ts) already engages when widestLine(plainText) > maxWidth — the truth source for fit-or-overflow stays there. Nothing changes about how text is displayed once layout has a real constraint.

Test plan

  • dom.test.ts — 9 unit tests of the Undefined / AtMost / Exactly contract, including the A1 ellipsis-poisoning bug and the truncate-start "whole string → '…'" pathology.
  • render-node-to-output.test.ts — 8 nested-text integration tests covering the issue Nested <Text> inside flex-row parent silently truncates trailing content even with abundant slack #51 repro (row parent, abundant slack), narrower widths down to exact fit, the column-parent A1 path (where the Undefined-mode call actually fires), the truncate-start render path, and a cross-stretch column scenario.
  • Full test suite: 789 passed (was 772, +17 across the new files; no regressions).
  • typecheck / lint / build clean.

Commits

  1. 40d97c4 test(render): pin nested-text + flex-row good-path behavior (Nested <Text> inside flex-row parent silently truncates trailing content even with abundant slack #51)
  2. a412ce1 test(dom): failing tests for measureTextNode Undefined-mode invariant (Nested <Text> inside flex-row parent silently truncates trailing content even with abundant slack #51, A5: <Text> always carries flexShrink: 1 on wrap-family modes #58)
  3. 9224140 fix(dom): measureTextNode returns natural in Undefined mode (closes Nested <Text> inside flex-row parent silently truncates trailing content even with abundant slack #51, A5: <Text> always carries flexShrink: 1 on wrap-family modes #58)
  4. d5d8789 test(render): column-parent + cross-stretch scenarios for nested text (Nested <Text> inside flex-row parent silently truncates trailing content even with abundant slack #51, A5: <Text> always carries flexShrink: 1 on wrap-family modes #58)
  5. 554b771 docs: note Undefined-mode measureTextNode invariant (Nested <Text> inside flex-row parent silently truncates trailing content even with abundant slack #51, A5: <Text> always carries flexShrink: 1 on wrap-family modes #58)

re-marked and others added 5 commits May 17, 2026 10:59
Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…#51, #58)

Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…, #58)

Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…#51, #58)

Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Mark <psyhik17@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@re-marked
re-marked merged commit 8feaa4f into main May 17, 2026
1 check passed
@re-marked
re-marked deleted the fix/nested-text-truncation branch May 17, 2026 09:10
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.

Nested <Text> inside flex-row parent silently truncates trailing content even with abundant slack

1 participant