Skip to content

feat(api): RowBuilder.verticalAlign(...) — cross-axis row child alignment#239

Merged
DemchaAV merged 2 commits into
developfrom
feat/row-vertical-align
Jun 26, 2026
Merged

feat(api): RowBuilder.verticalAlign(...) — cross-axis row child alignment#239
DemchaAV merged 2 commits into
developfrom
feat/row-vertical-align

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Why

A row sizes its band to the tallest child, but shorter children always sat flush with the band top. Aligning a small /month label beside a large price, or an icon with a line of text, meant computing vertical offsets by hand.

What changed

  • RowBuilder.verticalAlign(RowVerticalAlign.{TOP, CENTER, BOTTOM}) — seats a row's children on the cross axis within the band (height = tallest child). The align-items analogue for a horizontal row, no manual coordinates. Applies to both leaf and container children.
  • TOP is the default and the measure phase is untouched — an existing row computes the same band height and places its children byte-for-byte as before. Only CENTER/BOTTOM shift a child, by the band slack (accounting for the child's own margin). The seating computes a 0.0 offset for TOP, so the placement expression is bit-identical to the pre-feature code.
  • BASELINE is intentionally omitted — first-line ascent is not carried through MeasureResult, so it cannot be honoured without a measure-layer change. The enum admits it additively later.

This is the cross-axis half of the row-layout work; flex-spacer + main-axis arrangement (pushRight, SPACE_BETWEEN, …) is a separate follow-up that touches the width-distribution lockstep.

Lane: canonical DSL (RowBuilder, RowVerticalAlign, RowNode) + a 2-line shared-engine seating change. Purely additive → japicmp-safe (the new RowNode component is gated behind re-declared back-compat delegating constructors).

Verification

  • ./mvnw test -pl .green, 0 changed visual baselines → existing (TOP) rows render identically. ./mvnw -P japicmp verify — binary-compatible.
  • RowVerticalAlignTest (7): a short child beside a 60pt-tall one lands 40 / 20 / 0 pt above the tall child's bottom for TOP / CENTER / BOTTOM; a container child seats at CENTER; a child's own bottom margin offsets BOTTOM; the default and the back-compat RowNode constructor resolve to TOP.
  • A cold review confirmed the TOP byte-identity (including the -0.0 edge), the offset math incl. margins, and the delegating-ctor chain; it drove the composite-child + margined-child tests.
  • Runnable RowVerticalAlignExample + committed preview: a $49 / month row at all three alignments.

DemchaAV added 2 commits June 26, 2026 01:36
…ment

A row sizes its band to the tallest child, but shorter children always sat
flush with the band top; aligning a small label beside a large price, or an
icon with a line of text, meant computing offsets by hand.

verticalAlign(RowVerticalAlign.{TOP, CENTER, BOTTOM}) seats a row's children
on the cross axis within the band — the align-items analogue for a horizontal
row. The default is TOP, and the measure phase is untouched, so an existing
row computes the same band height and places its children byte-for-byte as
before; only CENTER/BOTTOM shift a child, by the band slack (accounting for
the child's own margin). Applies to both leaf and container children.
BASELINE is intentionally omitted for now — first-line ascent is not carried
through the measure result, so it cannot be honoured without a measure-layer
change; the enum admits it additively later.

Tests: RowVerticalAlignTest seats a short child beside a 60pt-tall one and
asserts its bottom lands 40 / 20 / 0 pt above the tall child's for TOP /
CENTER / BOTTOM, covers a container child at CENTER and a child whose own
bottom margin offsets BOTTOM, and confirms the default and the back-compat
RowNode constructor resolve to TOP. Example: RowVerticalAlignExample (a price
row at all three alignments). Full suite green, no visual baselines changed.
The cross-axis offset subtracts the child margin from the band slack; add a
comment that the measure phase guarantees that slack stays non-negative (the
band is the tallest child's margin-box), so the offset never lifts a child
above the band top.
@DemchaAV DemchaAV merged commit cb01014 into develop Jun 26, 2026
11 checks passed
@DemchaAV DemchaAV deleted the feat/row-vertical-align branch June 26, 2026 01:20
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