Skip to content

Audit [ComposeFacade] partials for omitted primitive default slots (NavigationRailItem, Tab, NavigationDrawerItem, chip family) #243

@jonathanpeppers

Description

@jonathanpeppers

Background

PR #240 added HasExplicitDefaultValue support to ComposeFacadeGenerator so primitive parameters on [ComposeBridge] [ComposeFacade] partial methods can be declared as bool enabled = true, int steps = 0, etc. and surface as optional ctor parameters.

A separate follow-up PR (the one spun off from session 851fbd89) covers the most obvious wins:

  • The six Phase 8 wrappers hardcoding enabled: true (Checkbox, Switch, RadioButton, Slider, TriStateCheckbox, WideNavigationRailItem).
  • NavigationBarItem, whose NavigationBarItemDefault enum already reserves bits for enabled and alwaysShowLabel but the [ComposeFacade] partial omits both slots.

This issue

Audit the remaining [ComposeFacade] partials whose [assembly: ComposeDefaults(...)] declarations reserve bits for primitive Kotlin defaults (commonly enabled, alwaysShowLabel, selected, readOnly, singleLine, maxLines, minLines, steps) but whose partial method signatures don't expose them. Likely candidates:

  • NavigationRailItem (has enabled, alwaysShowLabel bits)
  • Tab (has enabled bit)
  • NavigationDrawerItem (has enabled bit)
  • FilterChip, InputChip, AssistChip, SuggestionChip (all have enabled bit; elevated variants too)
  • IconToggleButton family (enabled bit)
  • LinearProgressIndicator / CircularProgressIndicator — anything with primitive defaults
  • Anything else surfaced by a git grep '\benabled\b' of ComposeDefaults.cs

Pattern

For each, mechanical:

  1. Find the [assembly: ComposeDefaults(...)] map — note which primitive bits are present (not !-prefixed).
  2. Find the matching [ComposeBridge] [ComposeFacade] partial in ComposeBridges.cs.
  3. Add the missing primitive slots with their natural Kotlin defaults: bool enabled = true, bool alwaysShowLabel = true, etc.
  4. For Phase 8 wrapper-passthroughs, also update the wrapper body to forward the new param (replacing the hardcoded value).
  5. Update PublicAPI.Unshipped.txt for the new ctor surface.
  6. Add a gallery toggle to verify the disabled state on device.

Verification

  • dotnet test src/Microsoft.AndroidX.Compose.SourceGenerators.Tests — 145/145 still pass
  • dotnet build Microsoft.AndroidX.Compose.slnx clean
  • On-device: Gallery demos render disabled-state toggles correctly

Why not all-in-one with the clean-wins PR

The clean-wins PR is mechanical for the six Phase 8 wrappers + NavigationBarItem. The rest each need per-facade inspection of:

  • Whether the bit is actually a primitive (not IFunction2? etc.)
  • Whether the natural Kotlin default matches the C# constant we'd assign (almost always true for enabled, but 0 vs. 1 for steps, Int.MAX_VALUE for maxLines, etc. need verification against the Compose source).
  • Whether the facade is Phase 8 wrapper-passthrough (needs body update) or pure Phase 1/2/3/8-hybrid (generator handles forwarding).

Doing them as a separate audit keeps the small fix shippable and surfaces any per-facade quirks one at a time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions