Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions docs/COMPONENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,10 @@ your background so the splash-to-app transition doesn't flash the template's pur

---

## Avalonia (in progress)
## Avalonia

Ported so far: `shell`, `icon`, `theme-toggle`, P0 (`button`, `input`, `label`, `checkbox`,
`switch`, `card` and its parts, `separator`, `badge`, `progress`, `alert`), P1 (`dialog`,
`drawer`, `sheet`, `dropdown`, `popover` and their parts), P2 (`textarea`, `select`, `slider`,
`radio-group`, `calendar`, `date-picker`, `time-picker`), P3 (`collapsible`, `accordion`,
`tabs`, `breadcrumb` and their parts, `skeleton`, `scroll-area`), P4 (`spinner`, `tooltip`,
`toast`, `alert-dialog`, `hover-card` and its parts), P5 (`avatar`, `toggle`, `callout`,
`table`, `empty-state`, `pagination`) and P6 (`context-menu`, `carousel`, `stepper`). Not yet
published to NuGet. In an Avalonia project, `shellui-native list` shows only these.
Every component on this page has an Avalonia version, installed by the same CLI commands. The
Avalonia templates are not on NuGet yet: they ship with the next release.

Overlays use Avalonia's `Popup` in the window's overlay layer: the content stays in the logical
tree (theme, DataContext and `FindParentOfType` work as declared), dropdowns and popovers get
Expand All @@ -88,6 +82,10 @@ Setup after `shellui-native init`: call `Components.UI.ShellTheme.EnsureInitiali
`xmlns:ui="using:YourApp.Components.UI"` to your XAML. Switch theme with
`ShellTheme.SetTheme(ThemeVariant.Dark)` or `ShellTheme.ToggleTheme()`.

Some names match Avalonia's own controls (`Button`, `Calendar`, `Carousel`, `ContextMenu`,
`TreeView`, …). In XAML the `ui:` prefix picks the ShellUI one. In C# that imports both
namespaces, qualify the name or add an alias: `using UI = YourApp.Components.UI;`.

Same names, properties and variants as MAUI, except:

| | MAUI | Avalonia |
Expand All @@ -114,6 +112,17 @@ Same names, properties and variants as MAUI, except:
| Carousel | Swipe, arrows, dots | Drag with the mouse or touch; the arrows are tab stops and Left / Right move while one has focus; with `AspectRatio="0"` set `Height` |
| Stepper | Shows the active step's view | Every step stays in the tree and only the active one is visible; reached steps are tab stops (Enter / Space) |
| Pagination | Labels hidden on phones | `ShowLabels` defaults to true; every page and arrow is a tab stop (Enter / Space) |
| ToggleGroup | Items toggle on tap | Items are also tab stops (Enter / Space); children are collected in `Items` |
| NumberInput | Numeric keyboard | Up / Down step the value while the field has focus |
| TagInput | Enter, comma or semicolon adds a tag | Backspace in the empty field also removes the last tag |
| InputOtp | Hidden entry with the numeric keyboard | Invisible text box over the slots; `Focus()` focuses it |
| Combobox / MultiSelect | Type to filter, Enter takes the first match | Up / Down move a highlight and Enter takes it; the search field has focus as soon as the panel opens; `Value` is `string?` |
| TreeView | Rows are tab stops | Also Right to expand and Left to collapse |
| TimelineItem content | One `Body` view | One child control, also reachable as `Body` |
| CopyButton | `Clipboard.Default` | The window's clipboard; does nothing until the button is in a window |
| LinkCard `Url` | `Launcher.Default` | The window's `Launcher` |
| AspectRatio | `ContentView` | A `Border`, so `CornerRadius` rounds the content |
| WrapLayout | Custom layout with `Padding` | A `Panel` (no `Padding`); Avalonia's own `WrapPanel` covers the plain case, `LastChildFill` is what this adds |

---

Expand Down
2 changes: 1 addition & 1 deletion docs/COMPONENTS_ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Prioritized list of components to create for ShellUI Native, aligned with [Shell

Last revised: **2026-10-07** (first prerelease, `0.1.0-alpha.1`).

**Status at a glance:** P0–P5 ✅ done · P6 partly done (resizable, navbar, sidebar open) · P7 partly done · shipped as `0.1.0-alpha.1` (58 families, 89 CLI targets) · **Avalonia (Phase 2) ⏭️ next**.
**Status at a glance:** P0–P5 ✅ done · P6 partly done (resizable, navbar, sidebar open) · P7 partly done · shipped as `0.1.0-alpha.1` (58 families, 89 CLI targets) · **Avalonia (Phase 2): every component ported, not released yet**.

---

Expand Down
14 changes: 10 additions & 4 deletions docs/DEVELOPMENT_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ main ← Phase 1a (2026-07-05), 1b (PR #2), 1c + 1d (PR #3), 1e (PR #4), brand

| Branch | Base | Status | Purpose |
|--------|------|--------|---------|
| `main` | — | Phase 1a–1e, release `0.1.0-alpha.1`, Phase 2 foundation and P0–P4 merged | 92 registry entries (89 CLI targets, 58 families); Avalonia templates for the foundation and P0–P4 |
| `feat/avalonia-p5-data-display` | `main` | Pushed, PR next | Phase 2 P5: Avalonia data display |
| `feat/avalonia-p6-advanced` | `feat/avalonia-p5-data-display` | **Active** | Phase 2 P6: Avalonia context menu, carousel and stepper |
| `main` | — | Phase 1a–1e, release `0.1.0-alpha.1`, Phase 2 foundation and P0–P6 merged | 92 registry entries (89 CLI targets, 58 families); Avalonia templates for the foundation and P0–P6 |
| `feat/avalonia-p7-remaining` | `main` | **Active** | Phase 2: the 14 components that were still MAUI-only |

---

Expand Down Expand Up @@ -435,7 +434,7 @@ After merge: tag `v0.1.0-alpha.1` on `main` and push the tag.

---

## Phase 2 — Avalonia (active; one branch per tier, `feat/avalonia-p6-advanced` now)
## Phase 2 — Avalonia (active; one branch per tier, `feat/avalonia-p7-remaining` now)

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

Expand Down Expand Up @@ -490,6 +489,13 @@ Cross-desktop (Windows + macOS + Linux) from one XAML codebase.
animation frames. Each installs alone into a fresh Avalonia app and builds with 0 warnings;
checked in the demo in light and dark with real pointer and key input. resizable, navbar and
sidebar wait for their MAUI versions
- [x] The rest (P7 and the P5 leftovers): toggle-group, number-input, tag-input, input-otp,
combobox, multi-select, kbd, copy-button, stat-card, link-card, tree-view, timeline,
aspect-ratio, wrap-layout. Every registry entry now has Avalonia content. Combobox and
multi-select float their panel with `ShellAnchoredPopup` and add an Up / Down highlight;
wrap-layout is a `Panel` with the MAUI layout's `LastChildFill`. Each installs alone into a
fresh Avalonia app and builds with 0 warnings; checked in the demo in light and dark with
pointer and key input
- [ ] 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`
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ shellui-native list
| Platform | Status | .NET Version |
|----------|--------|--------------|
| .NET MAUI | Available (`0.1.0-alpha.1`) — Android, iOS, Mac Catalyst, Windows | .NET 10.0 |
| Avalonia UI | In progress (Phase 2): theme, icons, P0–P5 components and P6's context menu, carousel and stepper; not on NuGet yet | .NET 10.0 (Avalonia 12) |
| Avalonia UI | Every component ported (Phase 2); not on NuGet yet, ships with the next release | .NET 10.0 (Avalonia 12) |
| WinUI 3 | Conditional (Phase 3) | .NET 10.0 |

WPF is intentionally not on this list — it's recognized for project detection only, not an
Expand Down
42 changes: 42 additions & 0 deletions examples/Avalonia.Demo/Components/UI/AspectRatio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Avalonia;
using Avalonia.Controls;

namespace AvaloniaDemo.Components.UI;

// Keeps its content at a fixed width / height ratio: the height follows the width.
// <ui:AspectRatio Ratio="1.7778" CornerRadius="8">
// <Image Source="/Assets/cover.jpg" Stretch="UniformToFill" />
// </ui:AspectRatio>
public class AspectRatio : Border
{
// Width divided by height. 16:9 is 1.7778, 4:3 is 1.3333, a square is 1.
public static readonly StyledProperty<double> RatioProperty =
AvaloniaProperty.Register<AspectRatio, double>(nameof(Ratio), 16d / 9d);

static AspectRatio()
{
AffectsMeasure<AspectRatio>(RatioProperty);
}

public double Ratio
{
get => GetValue(RatioProperty);
set => SetValue(RatioProperty, value);
}

public AspectRatio()
{
// With a CornerRadius the content is clipped to the rounded shape.
ClipToBounds = true;
}

protected override Size MeasureOverride(Size availableSize)
{
if (Ratio <= 0) return base.MeasureOverride(availableSize);
// Without a width to fill (e.g. in a horizontal stack) it takes the content's width.
var width = double.IsInfinity(availableSize.Width) ? base.MeasureOverride(availableSize).Width : availableSize.Width;
var size = new Size(width, width / Ratio);
base.MeasureOverride(size);
return size;
}
}
Loading
Loading