diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d2850f..a08652b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,3 +66,22 @@ jobs: - name: Build MAUI Demo (Windows) run: dotnet build examples/MAUI.Demo/MAUI.Demo.csproj --configuration Release --framework net10.0-windows10.0.19041.0 + + # Avalonia is the cross-desktop target, so its demo builds on all three desktop OSes + build-avalonia: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Build Avalonia Demo + run: dotnet build examples/Avalonia.Demo/AvaloniaDemo.csproj --configuration Release diff --git a/ShellUI.Native.slnx b/ShellUI.Native.slnx index 0ecb332..d125114 100644 --- a/ShellUI.Native.slnx +++ b/ShellUI.Native.slnx @@ -6,6 +6,7 @@ + diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 07dba0c..7c223d9 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -168,33 +168,41 @@ public partial class Button : ContentView } ``` -## Component Pattern (Avalonia, planned) +## Component Pattern (Avalonia) -Avalonia components will follow the `StyledProperty`/`TemplatedControl` pattern instead of -MAUI's `BindableProperty`/`ContentView` — the same property-driven visual-state approach, just -Avalonia's equivalent APIs: +Same model as MAUI: one C# file per component, built in code from Avalonia primitives +(`Border`, `Panel`, `TextBlock`, a custom `Render` for icons), with no `.axaml`. The CLI keeps +installing one file per component, and nothing has to be registered in `App.axaml`. + +- **Properties** are `StyledProperty`s; class handlers or `AffectsRender` react to changes. +- **Colors** bind to the same tokens with `control.Token(property, ShellToken.X)`, a + resource-observable binding. `ShellTheme` publishes the light and dark palettes as theme + dictionaries, so Avalonia swaps them when `RequestedThemeVariant` changes. +- **Names match MAUI** where Avalonia allows it. The one difference so far: `Icon` uses `Kind` + for the icon, because every Avalonia control already has a `Name`. +- **Usings are explicit.** `dotnet new avalonia.app` has implicit usings off, so each component + carries `using System;` and the rest; the demo turns them off too, so it catches a missing one. ```csharp -public partial class Button : TemplatedControl +public class Badge : Border { - public static readonly StyledProperty VariantProperty = - AvaloniaProperty.Register(nameof(Variant), ButtonVariant.Default); + public static readonly StyledProperty TextProperty = + AvaloniaProperty.Register(nameof(Text)); - public ButtonVariant Variant - { - get => GetValue(VariantProperty); - set => SetValue(VariantProperty, value); - } + private readonly TextBlock _label = new() { FontSize = 12 }; - static Button() + public Badge() { - VariantProperty.Changed.AddClassHandler