Skip to content

Latest commit

 

History

History
532 lines (427 loc) · 30.5 KB

File metadata and controls

532 lines (427 loc) · 30.5 KB

ShellUI Native — Development Plan

Living document tracking branches, phases, and feature implementations for ShellUI Native. Companion to PLAN.md (long-term strategy) and COMPONENTS_ROADMAP.md (prioritized component backlog).

Last revised: 2026-10-07 (Phase 1e merged; 0.1.0-alpha.1 release prep).


Branch Strategy

We use a phase-anchored branch model. main stays shippable; each phase lives on a long-lived feat/* branch that is squash-merged into main when its exit criteria are hit. Short-lived sub-branches (feat/<phase>/<slice>) cut off the phase branch and merge back into it, not directly into main.

main   ← Phase 1a (2026-07-05), 1b (PR #2), 1c + 1d (PR #3), 1e (PR #4), brand mark (PR #5) merged
 └─ chore/release-v0.1.0-alpha.1      ← first prerelease (active)
 └─ feat/avalonia-implementation      ← Phase 2 (next) — Avalonia templates + reference impl
 └─ feat/winui                        ← Phase 3 (conditional)

Rules:

  • Never merge a phase branch to main without a green CI run and the exit criteria table checked.
  • Never open a Phase 2 slice while Phase 1b (template system v2) is unmerged — it's the prerequisite.
  • Docs (docs/*.md) may change on any branch; prefer conflict-free additions over edits to shared prose during parallel work.

Current Snapshot

Branch Base Status Purpose
main — Phase 1a–1e, release 0.1.0-alpha.1, Phase 2 foundation and P0–P3 merged 92 registry entries (89 CLI targets, 58 families); Avalonia templates for the foundation and P0–P3
feat/avalonia-p4-feedback main Active Phase 2 P4: Avalonia feedback and overlays

Phase 1a — feat/initial-foundation (merged 2026-07-05)

The MAUI-only alpha foundation. Merged to main via PR #1.

Delivered

Infrastructure

  • .NET 10 unified across Core, Templates, CLI, and examples/MAUI.Demo
  • global.json pins SDK 10.0.100
  • Solution migrated from .sln to .slnx
  • CI workflows on dotnet-version: 10.0.x (ci.yml, pr-check.yml, release.yml)
  • MAUI demo builds on Windows: WindowsPackageType=None, explicit RuntimeIdentifier=win-x64, explicit Microsoft.Maui.Controls + Microsoft.Extensions.Logging.Debug PackageReferences

Platform model

Components (see COMPONENTS_ROADMAP.md for full priority list)

  • P0 complete: shell, button, input, label, checkbox, switch, card (+ header, content, footer), separator, badge, progress, alert
  • P1 complete: dialog (+ family), drawer (+ family), sheet (+ family), dropdown (+ family), popover (+ family)
  • P2 partial: textarea, slider, select, radio-group (+ item), date-picker, time-picker

Template hygiene

  • All 18 RoundRectangle-using templates now include using Microsoft.Maui.Controls.Shapes; in their Content string (previously produced non-compiling code on install)
  • All 14 compositional-container Children properties (Card, CardFooter, Dialog family, Drawer/Sheet/Popover/DropdownContent, RadioGroup — in both templates and demo copies) now use public new IList<IView> Children, silencing CS0108 shadow warnings against TemplatedView.Children
  • Switch.IsEnabledProperty and Checkbox.IsEnabledProperty marked static new — they are intentional shadows of VisualElement.IsEnabledProperty so the components can observe their own enable-state changes via propertyChanged handlers
  • Switch now uses _ = TranslateToAsync(...) instead of the obsolete TranslateTo
  • Cold multi-TFM build: dotnet build ShellUI.Native.slnx -c Release → 0 warnings, 0 errors across net10.0-android / ios / maccatalyst / windows10.0.19041.0

Tests

  • xUnit test project at tests/ShellUI.Native.Tests — 147 tests covering:
    • Every registered component has non-empty Content
    • Every template using RoundRectangle imports Microsoft.Maui.Controls.Shapes (regression lock for the 2026-07-04 bug)
    • Every template has a YourProjectNamespace placeholder (namespace replacement contract)
    • Every metadata Name matches its registry key
    • Every declared dependency is itself registered
    • ProjectDetector.DetectPlatform maps .csproj XML → NativePlatform correctly for MAUI / Avalonia (both PackageReference + App.axaml paths) / WinUI / WPF / Unknown, and prefers MAUI when a project declares both UseMaui=true and an Avalonia PackageReference
  • ProjectDetector.DetectPlatform promoted to internal + InternalsVisibleTo in ShellUI.Native.CLI.csproj so tests hit the pure XML→enum core without cwd manipulation
  • CI runs dotnet test and uploads TRX + coverage results (ci.yml)

In progress / remaining before merge to main

  • Element.FindParentOfType<T>() is implemented in ElementExtensionsTemplate and auto-installed as a dependency by every overlay component (Dialog, Drawer, Sheet, Dropdown, Popover). Verified.
  • Windows CI head builds MAUI.Demo end-to-end via the build-examples job (ci.yml) — runs dotnet workload install maui then dotnet build … --framework net10.0-windows10.0.19041.0.
  • COMPONENTS.md reconciled with the registry — removed stale "Coming Soon" entries, added docs for textarea, slider, select, radio-group, date-picker, time-picker, updated category summary.
  • QUICKSTART.md — prerequisites now say .NET 10 SDK; platform detection line mentions Avalonia and links the "MAUI-only warning" behavior.
  • Manually run shellui-native init --yes + add button input card dialog against a fresh dotnet new maui project to confirm the end-to-end install path works — needs a human on a workstation with the MAUI workload installed.
  • Manually launch MAUI.Demo at least once to verify components render as expected (compilation is verified by CI, rendering is not).

Exit criteria to merge → main

  1. dotnet build ShellUI.Native.slnx green
  2. dotnet build examples/MAUI.Demo/MAUI.Demo.csproj --framework net10.0-windows10.0.19041.0 green in CI
  3. shellui-native init --yes + shellui-native add button input card dialog works end-to-end on a fresh MAUI project
  4. COMPONENTS.md is honest about what's shipped

Phase 1b — feat/template-system-v2 (merged 2026-08-29 via PR #2)

Focused refactor: the template layer became platform-keyed so adding Avalonia is a per-template dict entry rather than a whole parallel registry. Prerequisite for Phase 2, now unblocked.

Problem (context)

Before this branch, ComponentRegistry.GetComponentContent returned a single MAUI-flavored C# string per component name. There was no platform dimension in the lookup path. Adding Avalonia templates would have meant either duplicating the registry or string-mangling MAUI templates at install time.

Design

Per-template Contents dictionary owned by the template class; registry stores (Metadata, Contents) bundles so lookup is one hop — no per-component switch arms to maintain when a new platform is added.

public static class ButtonTemplate
{
    public static ComponentMetadata Metadata => new() { ... };
    public static IReadOnlyDictionary<NativePlatform, string> Contents { get; } = new()
    {
        [NativePlatform.MAUI] = @"..."
        // [NativePlatform.Avalonia] = @"..."  ← added in Phase 2, one line, no registry edit
    };
}

Deliverables

  • ComponentRegistry.GetComponentContent(name, NativePlatform) signature
  • Every template migrated from public static string Content => to public static IReadOnlyDictionary<NativePlatform, string> Contents { get; } (all 44 templates)
  • Registry stores (Meta, Contents) bundles instead of just metadata; adds SupportsPlatform(name, platform) and GetSupportedPlatforms(name)
  • ComponentInstaller uses config.TargetPlatform; checks SupportsPlatform before installing and prints a clear error listing supported platforms if the combo isn't ready
  • InitService.InstallShellUtilityAsync and ComponentManager.UpdateComponents updated to pass the target platform through
  • New UnsupportedPlatformException typed exception in Core.Models with ComponentName, RequestedPlatform, SupportedPlatforms for programmatic callers
  • Blanket "MAUI-only" warning removed from ComponentInstaller — replaced with per-component platform check (silent when the platform IS supported)

Verification

  • dotnet build src/ → 0 warnings, 0 errors
  • dotnet test → 199/199 passing (up from 147 — 52 new/updated tests):
    • TemplateContentTests parameterized on NativePlatform.MAUI
    • Every_component_reports_MAUI_as_a_supported_platform — regression lock
    • GetComponentContent_returns_null_for_known_component_but_unsupported_platform — verifies the null return contract for the Avalonia case that will flip once Phase 2 adds content
    • SupportsPlatform_reports_MAUI_for_all_components_and_no_others_yet — will fail-loud on Phase 2 when Avalonia content is added (intended trigger to update the test)
    • UnsupportedPlatformExceptionTests — message formatting + property exposure

Follow-ups landed on this branch

  • Input height fix (2026-08-29): InputTemplate now sets HeightRequest = 40 and Padding = (12, 0) on its Border, matching Select / DatePicker / TimePicker. Previously the Border had no explicit height and used Padding = (12, 8), so the composite grew to whatever platform-default height Entry picked (Windows ~44, Android ~48+ with material padding) — inputs rendered visibly taller than the pickers sitting next to them in the same form row. Rule captured in COMPONENTS_ROADMAP.md § Form Sizing Contract. Tests still green (199/199).

  • P0/P1 sweep (2026-08-29): full re-read of every P0 + P1 template looking for the same class of drift Input had. Three real bugs found and fixed:

    1. Primary-blue token drift. InputTemplate focus border and RadioGroupItemTemplate checked indicator used #3B82F6 (blue-500) while Button / Checkbox / Switch / Progress all use #2563EB (blue-600) for the same "primary" role. Standardized on #2563EB and locked the mapping in COMPONENTS_ROADMAP.md § Design Token Contract.
    2. DropdownItem hit target too small. Was Padding = (8, 10) with no minimum height → ~34px rows, below iOS 44px / Android 48dp touch guidance. Now Padding = (12, 12) + MinimumHeightRequest = 40. Rule added to Form Sizing Contract under "Menu / list rows".
    3. RadioGroupItem checked-border missing. Only the fill flipped color when a radio became selected; the ring stayed grey. Checkbox had already handled this. Fixed to match — both stroke and background flip to #2563EB when checked.

    Everything else surveyed (Badge, Progress, Alert, Card + variants, Label, Separator, Dialog/Drawer/Sheet/Popover content boxes, Shell) was sized/tokenized correctly. Build clean, 199/199 tests still passing.

Exit criteria to merge → main

  1. All existing MAUI templates install and compile identically (verified: TemplateContentTests parameterized over all 44 components pass)
  2. Registry.GetComponentContent("button", Avalonia) returns null today (documented behavior); will return non-null once Phase 2 adds Avalonia content
  3. ComponentInstaller fails-loud on unsupported (name, platform) combos with a clear error listing supported platforms
  4. Form controls that share a row (Input, Select, DatePicker, TimePicker) render at the same 40px height on Windows/Android/iOS heads of MAUI.Demo — visual check, not yet automated

Phase 1c — feat/p3-navigation-layout (merged 2026-10-05 via PR #3)

Finish MAUI's component vocabulary through P3 before opening the cross-platform front. Rationale: Phase 2 (Avalonia) turns every new MAUI component into two components to maintain. Locking the P3 tier on MAUI first keeps Phase 2 a mechanical port instead of chasing a moving target.

Small, additive branch — no infrastructure changes, no registry surgery. Each new component is one template file + one ComponentRegistry entry + TemplateContentTests parameters picking it up automatically.

Scope — P3 (Navigation & Layout, from COMPONENTS_ROADMAP.md)

# Component Sub-components Notes
P3.1 tabs tabs-list, tabs-trigger, tabs-content Compositional (Trigger/Content pattern). Tab bar + one visible panel at a time.
P3.2 accordion accordion-item, accordion-trigger, accordion-content Multiple expandable sections; Type="single" vs "multiple" behavior.
P3.3 collapsible collapsible-trigger, collapsible-content Single expand/collapse — the primitive accordion-item composes on top of.
P3.4 breadcrumb breadcrumb-item Nav trail. Icon-aware separator between items.
P3.5 scroll-area — ScrollView wrapper with consistent scrollbar styling.
P3.6 skeleton — Loading placeholder — animated grey block, sized by parent.

Implementation order

Build the primitive before the composite: collapsible → accordion → tabs → breadcrumb → skeleton → scroll-area. Collapsible's animation + IsOpen state is the accordion-item core; accordion-item generalizes it; tabs reuses the same show/hide pattern with mutual exclusion. Breadcrumb and skeleton are standalone and can slot in wherever.

Constraints (locked by Phase 1b)

  • Every new template MUST populate Contents[NativePlatform.MAUI] (registry lookup contract).
  • Every new form-adjacent control MUST follow the Form Sizing Contract — 40px baseline for row-level triggers (tabs-trigger, accordion-trigger, breadcrumb-item).
  • Every new color usage MUST reuse a token from the Design Token Contract. New role → add the token to the table first, then use it.
  • Compositional families use FindParentOfType<T>() from element-extensions (already installed as a dependency by every overlay component — add it as a dependency for the new families too).

Deliverables

  • 6 new template families + their sub-components
  • ComponentRegistry entries for all of them
  • MAUI.Demo gains a demo section for each family (Tabs / Accordion / Collapsible / Breadcrumb / ScrollArea / Skeleton)
  • TemplateContentTests picks the new components up automatically (parameterized over the whole registry — nothing to add manually)
  • COMPONENTS.md updated with usage snippets for each

Fix-forwards that landed here (despite the "no P0–P2 refactoring" rule below) because they blocked the demo from rendering at all on Windows: overlays moved to page-root in MAUI.Demo, outer Border removed from Select/DatePicker/TimePicker, and .NET 10 MAUI nullable Date/Time + non-generic ItemsSource adaptations. Proper fixes → Phase 1d.

Exit criteria to merge → main

  1. dotnet build ShellUI.Native.slnx — 0/0
  2. dotnet test — new baseline count reflects 9 new components (should land ~10 tests up)
  3. Every new component has a demo section in MAUI.Demo that renders on the Windows head
  4. No token drift: grep -E '"#[0-9A-Fa-f]{6}"' src/ShellUI.Native.Templates/Templates/ in the diff introduces zero hexes not already in the Design Token Contract table

What this phase deliberately does NOT do

  • No Avalonia work (that's Phase 2, and starting it now would double the maintenance surface while P3 is in flight).
  • No P4+ components (tooltip, toast, alert-dialog, hover-card) — they need overlay primitives that already exist, but they're feedback/overlay rather than nav/layout; scoping them into a separate feat/p4-feedback branch keeps PRs reviewable.
  • No refactoring of existing P0/P1/P2 components. Sizing + token contracts are locked; any drift found in review gets a fix-forward in the P4 branch, not here.

Phase 1d — overlay portal (merged 2026-10-05 with Phase 1c in PR #3; the separate feat/p4-overlay-portal branch was never cut)

Surface polish pass driven by live testing on Windows 2026-08-30. Two distinct problems that both need architectural fixes rather than sizing tweaks.

Problem 1: Dialog / Drawer / Sheet require a page-root parent

Today these components extend AbsoluteLayout with an inner _overlayLayer set to proportional-fill (0,0,1,1). When placed inside a VerticalStackLayout (the natural place a consumer would drop them next to a form), the AbsoluteLayout sizes to children while the overlay layer wants to fill the parent — circular sizing produces a giant empty inline box. The Phase 1c demo pushed them to page-root as a workaround, but that's a footgun consumers WILL hit.

Fix: rewrite as ContentViews that walk up to ContentPage.Content on attach, wrap it in a Grid once (tracked via attached property), inject the overlay layer as the top child of that grid. Trigger renders inline; content teleports to page root. Portal-style, matches shadcn's Dialog/Sheet behavior in React.

Problem 2: Select / DatePicker / TimePicker use native chrome

Same fix as Phase 1c's short-term patch (remove the outer Border to stop overflow) — functional but not shadcn-quality. Windows' native Picker/CalendarDatePicker/TimePicker draw their own chrome that we can't override cleanly cross-platform.

Fix: replace each with a Popover-based custom control that renders its own trigger (bounded, our styling) and opens a PopoverContent with the item list / calendar / hour-minute wheels. Native pickers drop out entirely. Matches shadcn Select / DatePicker / TimePicker — inspiration: nativewind + shadcn/ui.

Deliverables

  • Portal helper — landed 2026-10-02 as ShellPortal in Shell.cs (page layer, logical owner, anchored popups with flip + click-outside)
  • Dialog / Drawer / Sheet / AlertDialog show their content in the portal layer — declare them anywhere
  • Custom Select — trigger + floating list (landed early, 2026-09-27, with the theme-token pass)
  • Custom DatePicker — trigger + floating calendar component (month navigation + day grid)
  • Custom TimePicker — trigger + floating hour / minute / AM-PM columns (2026-10-04); native picker dropped
  • MAUI.Demo no longer needs the page-root Grid workaround — its root is a plain ScrollView and overlays sit next to their triggers
  • Click-outside closes Dropdown / Popover / Select / DatePicker
  • tooltip and hover-card (unblocked by the portal)
  • Android pass (2026-10-04, Pixel 7 / API 34 emulator): native underline and padding stripped from text fields; Select list sized and placed from real layout; BoxViews no longer pick up the stock dark background; page layer set up as the page appears (first overlay no longer resets the scroll position); overlays edge-to-edge with their content kept inside the safe area; Hover Card opens on tap; opt-in ShellTheme.SyncSystemBars
  • toggle, input-otp, pagination, empty-state
  • Escape (Windows) and the Android back button close the overlay on top — ShellDismiss (2026-10-04; Mac Catalyst still open)
  • callout, combobox

Already in place from the 2026-09-27 pass: theme tokens (ShellTheme), overlay open/close animations, closed overlays no longer block input, triggers that wrap a Button (ShellTriggerView), floating Dropdown/Popover/Select via ShellAnchorLayout, and Date/Time pickers inside a themed border with the native frame stripped.

Exit criteria

  1. MAUI.Demo Dialog / Drawer / Sheet sections can move back into the ScrollView and still render + open correctly
  2. Select / DatePicker / TimePicker render with our own border + rounded corners on Windows (no native chrome bleed)
  3. dotnet test still green (visual tests remain manual until we automate them)
  4. Every color still reuses the Design Token Contract

Phase 1e — feat/p5-p6-components (merged via PR #4)

The remaining MAUI data-display and advanced tiers, built demo-first like Phase 1d.

Deliverables

  • table — header, rows with hover / selection / tap, caption, sideways scroll below a minimum width
  • context-menu — opens at the pointer on right-click; long-press on touch
  • carousel — swipe, arrows, dots, loop, auto-play
  • stepper — numbered steps with completed / active states and built-in navigation
  • Android pass for the four above plus combobox, time picker, callout and back-to-close (2026-10-05, Pixel 7 / API 34, light and dark): fixed popup top padding, context-menu long-press and toast offset
  • toggle-group, number-input, tag-input, kbd, stat-card, timeline, wrap-layout (Windows only so far)
  • Icon generator converts arcs to Bezier curves — MAUI on Windows failed to draw the small arcs in activity, which crashed the app
  • Demo shows one category at a time (a single page of every component exceeded WinUI's layout-pass limit; see COMPONENTS.md, "Long pages on Windows")
  • Android pass for the second batch (2026-10-05): fixed the overlay layer for a Grid page root and the tag-input keyboard / height
  • multi-select, tree-view, copy-button, link-card, aspect-ratio — run on Windows and Android
  • iOS / Mac Catalyst pass for everything (carried over)
  • Escape closes the overlay on top on Mac Catalyst (carried over)
  • resizable, navbar, sidebar (P6.4–P6.6) (moved to the MAUI backlog, after Phase 2 starts)

Each family ships as one template (e.g. table holds Table, TableHeader, TableRow, TableHead and TableCell) rather than one template per part.

Exit criteria

  1. Every new component clicked through in MAUI.Demo on Windows and on an Android device
  2. dotnet build clean for the Windows and Android targets, dotnet test green
  3. Docs and roadmap updated

Release 0.1.0-alpha.1 — chore/release-v0.1.0-alpha.1 (released; tag v0.1.0-alpha.1)

First NuGet prerelease of ShellUI.Native.CLI, MAUI only.

  • Directory.Build.props → 0.1.0 + alpha.1
  • Component versions read from the assembly (an installed tool has no Directory.Build.props)
  • release.yml builds the CLI and tests (not the bare src/ folder), checks the tag against the props version, runs the tests and uses RELEASE_NOTES.md as the GitHub release body (scripts/extract-release-notes.sh); publishes through NuGet Trusted Publishing like ShellDocs (setup in RELEASING.md)
  • Install docs use --prerelease; roadmap and plan brought up to date
  • Every CLI target added alone to a fresh MAUI library, plus all together in a fresh MAUI app

After merge: tag v0.1.0-alpha.1 on main and push the tag.


Phase 2 — Avalonia (active; one branch per tier, feat/avalonia-p4-feedback now)

Cross-desktop (Windows + macOS + Linux) from one XAML codebase.

Deliverables

  • examples/Avalonia.Demo/ (Avalonia 12.1.3, .NET 10, implicit usings off like the Avalonia template); components are developed there, as in the MAUI demo. A separate src/ShellUI.Native.Avalonia/ project isn't needed
  • Theme tokens: ShellTheme in the Avalonia shell publishes both palettes as theme dictionaries (no XAML resource file to install)
  • Foundation templates with Avalonia content: shell, icon (same 110 icons, Kind instead of Name), theme-toggle; pattern in ARCHITECTURE.md § Component Pattern (Avalonia)
  • scripts/sync-templates.py writes the [NativePlatform.Avalonia] entries; scripts/generate-icons.py writes both Icon.cs files
  • CLI: init in an Avalonia project installs the Avalonia Shell.cs and prints Avalonia next steps; list shows only components with a template for the project's platform
  • CI job that builds the Avalonia demo on ubuntu-latest, windows-latest and macos-latest
  • P0: button (+ button-variants), input, label, checkbox, switch, card family, separator, badge, progress, alert. Each installs alone into a fresh dotnet new avalonia.app and builds with 0 warnings; checked in the demo in light and dark, with the keyboard focus ring and loading state
  • P1: dialog, drawer, sheet, dropdown, popover and their parts, on Avalonia's Popup in the overlay layer (shared hosts in shell: ShellOverlayHost, ShellPopoverHost, ShellTriggerView, ShellDismiss for Escape). Each installs alone into a fresh dotnet new avalonia.app; checked in the demo: opening from triggers, placement and flip, Escape, picking an item, DialogClose, light and dark. Focus trap added on the P3 branch: focus moves into the content, Tab cycles inside it and returns to the trigger on close (checked with real key presses); the Dialog and Sheet close buttons are tab stops
  • P2: textarea, select, slider (custom-drawn), radio-group, calendar, date-picker, time-picker. Pickers float their panel with ShellAnchoredPopup (shared with Dropdown and Popover); ShellPlatform.StripNativeChrome clears Fluent's TextBox chrome for Input and Textarea
  • P3: collapsible, accordion, tabs, breadcrumb (and their parts), skeleton, scroll-area. Collapsible and accordion content animate their height with AnimateExpandAsync in element-extensions, as on MAUI. Each installs alone into a fresh dotnet new avalonia.app and builds with 0 warnings; checked in the demo in light and dark, including keyboard tab switching. Also on this branch: floating panels keep their 4px gap when they flip above the trigger, and both demos use the ShellUI Native tile as their app icon (Android: adaptive, grid in the safe zone)
  • P4: spinner, tooltip, toast, alert-dialog, hover-card (and its parts). Toasts live in the window's overlay layer; AlertDialog builds on ShellOverlayHost (focus trap, Escape = Cancel); ShellFloatingHost.ClaimsChild lets a host place XAML children itself. ShellLabel now wraps like MAUI's Label. Each installs alone into a fresh dotnet new avalonia.app and builds with 0 warnings; checked in the demo in light and dark
  • Replace the generated Icon.cs with the ShellIcons.Maui / ShellIcons.Avalonia packages once they are on NuGet. Their names already match (IconName, Icon, Kind on Avalonia), so components change little: token tinting binds the package's Color (MAUI) or Foreground (Avalonia). The CLI needs NuGet dependencies first (add icon runs dotnet add package), and scripts/generate-icons.py goes away

Order of implementation

Same P0 → P7 order as MAUI, per COMPONENTS_ROADMAP.md. Do not start component N until MAUI has landed N.

Exit criteria

  1. Every P0+P1 MAUI component has a working Avalonia counterpart
  2. shellui-native init in an Avalonia project installs Avalonia code (verified by grepping installed files for TemplatedControl, not ContentView)
  3. Avalonia demo builds & runs on Linux (the platform Phase 2 exists to unlock)

Phase 3 — feat/winui (conditional)

Only pursued if a concrete requirement surfaces for Windows 11 Fluent-specific styling that Avalonia's Fluent theme cannot satisfy. Default: skip, redirect that effort into Avalonia's Windows head.

If pursued, mirror Phase 2's structure: new project, WinUIContent per template, dedicated demo, CI job.


Cross-cutting workstreams

These aren't phases but ongoing concerns that touch every branch:

Concern Owner branch Notes
Docs Whatever branch touches the feature Prefer additions over prose rewrites on active parallel branches
CI The branch introducing the new build target Every new platform gets its own job, not a matrix
Versioning main after every merge Bump Directory.Build.props via prepare-release.ps1
Compositional pattern Component-authoring branches Enforce Dialog+Trigger+Content style (see COMPONENTS_ROADMAP.md § Architectural Pattern)
Template hygiene Component-authoring branches Every RoundRectangle/Border/Path usage must ship its using in the template Content string

How to add a new branch to this plan

  1. Cut off the current phase branch (not main) unless you're starting a new phase.
  2. Add a row to the Current Snapshot table above.
  3. If it's a new phase, add a Phase section with Deliverables and Exit criteria.
  4. Link the branch to the priority tier it delivers (P0–P7) in COMPONENTS_ROADMAP.md.
  5. Update this doc's Last revised date.