Skip to content

Implement VerticalTextAlignment on text-input handlers#275

Open
jonathanpeppers wants to merge 1 commit into
mainfrom
jonathanpeppers/vertical-text-alignment
Open

Implement VerticalTextAlignment on text-input handlers#275
jonathanpeppers wants to merge 1 commit into
mainfrom
jonathanpeppers/vertical-text-alignment

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Owner

Summary

Wires VerticalTextAlignment on the five Compose-backed text-input handlers — LabelHandler, EntryHandler, EditorHandler, SearchBarHandler, PickerHandler — so each goes from 98% → 100% in docs/maui-coverage.md.

Coverage delta

Headline Before After
Property-mapper keys covered 883 / 1224 (72.1%) 888 / 1224 (72.5%)
Leaves category 684 / 695 (98%) 689 / 695 (99%)
LabelHandler 39 / 40 (98%) 40 / 40 (100%)
EntryHandler 48 / 49 (98%) 49 / 49 (100%)
EditorHandler 45 / 46 (98%) 46 / 46 (100%)
SearchBarHandler 46 / 47 (98%) 47 / 47 (100%)
PickerHandler 40 / 41 (98%) 41 / 41 (100%)

Approach

Compose's Modifier.wrapContentHeight(align) measures the child without imposing the parent's min height, then aligns the child within the parent's allocated height. That's exactly the semantic MAUI's VerticalTextAlignment carries — visible only when the control has more height than it naturally needs.

  1. New JNI overloadComposeBridges.ModifierWrapContentHeightAligned(IntPtr, IAlignmentVertical?, bool). Reuses the existing ModifierWrapContentHeightDefault enum (slot 0 = align, slot 1 = unbounded) so the auto-default-mask clears bit 0 only when the C# caller passes a non-null alignment. The pre-existing ModifierWrapContentHeight(IntPtr, bool) overload is untouched (still defaults to Kotlin's CenterVertically).
  2. C# entry points — new Modifier.WrapContentHeight(Alignment.Vertical, bool) static factory + extension method. Public-API entries added to PublicAPI.Unshipped.txt.
  3. MAUI helperMicrosoft.AndroidX.Compose.Maui.Platform.VerticalAlignmentMapping converts Microsoft.Maui.TextAlignmentAlignment.Vertical (Start→Top, Center→CenterVertically, End→Bottom, Justify→Top — Compose has no vertical-justify analog, matching the stock Android backend).
  4. Per-handler wiring — each handler gains a _vTextAlign MutableState<int> slot, a MapVerticalTextAlignment mapper entry, and .ApplyVerticalTextAlignment(vAlign) chained onto its outer modifier (after ApplySemantics). The five // TODO: VerticalTextAlignment … comments are deleted.

Sample

Adds VerticalAlignmentPage to Microsoft.AndroidX.Compose.Maui.Sample — one page exercising VerticalTextAlignment="Start|Center|End" on each of the five controls inside fixed-height frames so the difference is obvious. Wired into HomePage + AppShell under route vertical-align.

Verification

  • dotnet build src/Microsoft.AndroidX.Compose — 0 errors, no new warnings.
  • dotnet build src/Microsoft.AndroidX.Compose.Maui — 0 errors, 0 warnings.
  • dotnet build src/Microsoft.AndroidX.Compose.Maui.Sample — 0 errors, 0 warnings.
  • dotnet run scripts/maui-coverage.cs — regenerated docs/maui-coverage.md; all five handlers ✅ 100%.

Wires VerticalTextAlignment on LabelHandler, EntryHandler,
EditorHandler, SearchBarHandler, and PickerHandler — bringing each
from 98% to 100% in docs/maui-coverage.md.

Approach: add a Modifier.WrapContentHeight(Alignment.Vertical, bool)
overload (new sibling JNI bridge ModifierWrapContentHeightAligned
reusing ModifierWrapContentHeightDefault) so each handler can map
TextAlignment to the corresponding Alignment.Vertical and chain it
onto the outer modifier. A shared helper in
Platform/VerticalAlignmentMapping.cs converts MAUI''s TextAlignment
(Start/Center/End/Justify; Justify collapses to Top) into the
Compose alignment + applies the modifier in one call.

Adds a VerticalAlignmentPage demo to the MAUI sample exercising
VerticalTextAlignment on each of the five controls inside fixed-height
frames so the visual diff is obvious.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 15, 2026 22:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires VerticalTextAlignment support onto the five Compose-backed MAUI text-input handlers (LabelHandler, EntryHandler, EditorHandler, SearchBarHandler, PickerHandler), moving each from 98% to 100% property-mapper coverage. The approach uses Compose's Modifier.wrapContentHeight(Alignment.Vertical) to position text content within a parent slot, which is the correct semantic match for MAUI's VerticalTextAlignment property.

Changes:

  • Adds a new ComposeBridges.ModifierWrapContentHeightAligned JNI bridge and corresponding Modifier.WrapContentHeight(Alignment.Vertical, bool) public API (static factory + extension), reusing the existing ModifierWrapContentHeightDefault enum.
  • Introduces VerticalAlignmentMapping (internal helper in the MAUI project) to convert Microsoft.Maui.TextAlignmentAlignment.Vertical and chain the modifier, then wires _vTextAlign MutableState<int> + MapVerticalTextAlignment + ApplyVerticalTextAlignment onto all five handlers with consistent patterns.
  • Adds a VerticalAlignmentPage XAML sample exercising all five controls with Start/Center/End inside fixed-height frames, and updates docs/maui-coverage.md to reflect the new 100% coverage.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Microsoft.AndroidX.Compose/ComposeBridges.cs New ModifierWrapContentHeightAligned bridge with explicit IAlignmentVertical? param
src/Microsoft.AndroidX.Compose/ModifierExtensions.cs New WrapContentHeight(Alignment.Vertical, bool) extension method with null check
src/Microsoft.AndroidX.Compose/Modifier.cs Static factory overload delegating to the extension; fixes inheritdoc cref for disambiguation
src/Microsoft.AndroidX.Compose/PublicAPI.Unshipped.txt Two new entries for the public overload (static + extension)
src/Microsoft.AndroidX.Compose.Maui/Platform/VerticalAlignmentMapping.cs New internal mapping helper: TextAlignmentAlignment.Vertical + modifier extension
src/Microsoft.AndroidX.Compose.Maui/Handlers/LabelHandler.cs Adds _vTextAlign slot, mapper, and modifier chaining; removes TODO comment
src/Microsoft.AndroidX.Compose.Maui/Handlers/EntryHandler.cs Same wiring pattern as LabelHandler (default Center)
src/Microsoft.AndroidX.Compose.Maui/Handlers/EditorHandler.cs Same wiring pattern (default Start for multi-line)
src/Microsoft.AndroidX.Compose.Maui/Handlers/SearchBarHandler.cs Same wiring pattern (default Center)
src/Microsoft.AndroidX.Compose.Maui/Handlers/PickerHandler.cs Same wiring pattern (default Center)
src/Microsoft.AndroidX.Compose.Maui.Sample/Pages/VerticalAlignmentPage.xaml XAML demo exercising Start/Center/End on all 5 controls in fixed-height frames
src/Microsoft.AndroidX.Compose.Maui.Sample/Pages/VerticalAlignmentPage.xaml.cs Code-behind seeding Picker items
src/Microsoft.AndroidX.Compose.Maui.Sample/HomePage.xaml.cs Demo registry entry
src/Microsoft.AndroidX.Compose.Maui.Sample/AppShell.xaml.cs Route registration for vertical-align
docs/maui-coverage.md Coverage numbers updated to reflect 100% on all 5 handlers

/// content within the parent's allocated height using
/// <paramref name="align"/> instead of Kotlin's default
/// <see cref="Alignment.Vertical.CenterVertically"/>. Useful for
/// mapping <see cref="Microsoft.Maui.ITextAlignment.VerticalTextAlignment"/>
/// <see cref="Alignment.Vertical"/> and the matching
/// <see cref="ModifierExtensions.WrapContentHeight(Modifier, Alignment.Vertical, bool)"/>
/// modifier. Used by every Compose-backed text-input handler so the
/// cross-platform property line up consistently regardless of which
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