Skip to content

feat(text): verticalAlign works without maxHeight (flex-friendly)#29

Merged
chiefcll merged 2 commits into
mainfrom
feat/text-vertical-align-flex
May 22, 2026
Merged

feat(text): verticalAlign works without maxHeight (flex-friendly)#29
chiefcll merged 2 commits into
mainfrom
feat/text-vertical-align-flex

Conversation

@chiefcll
Copy link
Copy Markdown
Contributor

Summary

Builds on #28. After that PR, verticalAlign activated whenever maxHeight > 0. This change goes further: verticalAlign now activates whenever the containing box is taller than the intrinsic text height — even without maxHeight. The "containing box" is maxHeight if set, otherwise the node's own h (which a flex parent or the user may have grown).

This makes verticalAlign Just Work inside flex layouts:

<View style={{ display: 'flex', alignItems: 'flexStart', height: 300, ... }}>
  <Text style={{ fontSize: 44, verticalAlign: 'middle' }}>A</Text>
  <Text style={{ fontSize: 80, verticalAlign: 'middle' }}>B</Text>
</View>

Each text's caps land dead-center inside the 300px row, with no maxHeight boilerplate.

Implementation

src/core/CoreTextNode.ts:152-161 — switched the slack formula from maxHeight - h to (maxHeight ?? h) - intrinsicH, where intrinsicH = this._renderInfo.height:

const intrinsicH = this._renderInfo.height;
const boxH = hasMaxHeight === true ? maxHeight : h;
const slackY = boxH - intrinsicH;
if (slackY > 0) {
  if (verticalAlign === 'bottom')      containY = slackY;
  else if (verticalAlign === 'middle') containY = slackY * 0.5;
}

This also fixes a subtle bug in the original formula: maxHeight - h was wrong when h had been modified post-load (e.g., by flex), because h no longer equaled the intrinsic text height. The new formula uses intrinsicH explicitly.

Other changes

Test plan

  • pnpm build clean.
  • vitest run — 182/182 pass.
  • Recapture VRT (text-vertical-align-*.png) — will be done before merge. Only the text-vertical-align snapshots are expected to change (added one row); other tests don't grow h past intrinsic without also setting maxHeight.

🤖 Generated with Claude Code

chiefcll and others added 2 commits May 22, 2026 17:02
verticalAlign previously required maxHeight to be set — useless when a
flex parent (or the user) grows the text node's `h` beyond the intrinsic
text height. Switch the alignment math to compare against the intrinsic
text height (`_renderInfo.height`), using `maxHeight` if set and falling
back to the node's own `h` otherwise.

This also fixes a subtle bug in the original formula: `maxHeight - h`
was wrong when `h` had been modified post-load (e.g., by flex), because
`h` no longer equaled intrinsic height. The new formula uses
`intrinsicH` explicitly.

Adds a VRT row ("Explicit h, no maxHeight") that creates a text node,
awaits load, then sets `node.h = 200` to exercise the new path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@chiefcll chiefcll merged commit 767ad53 into main May 22, 2026
1 check passed
@chiefcll chiefcll deleted the feat/text-vertical-align-flex branch May 22, 2026 21:43
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.

1 participant