Skip to content

SuperJMN/Zafiro.Avalonia

Repository files navigation

Zafiro.Avalonia

NuGet NuGet Downloads License: MIT

A UI components library for Avalonia 11.3.x that provides controls, dialogs, behaviors, and helpers for desktop, mobile, and browser applications. Built with ReactiveUI, a strong functional-reactive orientation (Result<T>, Maybe<T>, IObservable<T>), and absolute respect for the MVVM pattern — no logic in views, no UI in ViewModels.

Packages

Package NuGet Description
Zafiro.Avalonia NuGet Core controls, panels, behaviors, converters, and helpers
Zafiro.Avalonia.Dialogs NuGet Dialog system for desktop and mobile
Zafiro.Avalonia.DataViz NuGet Data visualization (heatmaps, dendrograms, graphs)
Zafiro.Avalonia.Generators NuGet Source generator for view locators and section registration
Zafiro.Avalonia.Icons.Optris NuGet Icon provider using Optris (FontAwesome, Material Design)
Zafiro.Avalonia.Icons.Svg NuGet SVG-based icon provider
Zafiro.Avalonia.Templates NuGet dotnet new templates for cross-platform Zafiro Shell apps

Getting Started

Scaffolding a new app

The fastest way to start a new cross-platform Avalonia app on top of Zafiro is the dotnet new template:

dotnet new install Zafiro.Avalonia.Templates
dotnet new zafiro-shell -n MyApp
cd MyApp && dotnet run --project MyApp.Desktop

You get a multi-project solution (Desktop + Browser + Android + iOS) with the Zafiro Shell, [Section] auto-discovery, ReactiveUI, compiled bindings and Zafiro.Avalonia.Mcp.AppHost wired in. See templates/Zafiro.Avalonia.Templates/README.md for details.

Adding to an existing project

dotnet add package Zafiro.Avalonia

For dialogs:

dotnet add package Zafiro.Avalonia.Dialogs

For auto-generated view locators and section registrations (recommended):

dotnet add package Zafiro.Avalonia.Generators

Quick Start

Application Bootstrap with Connect

Wire up your app in one line — works on Desktop, Mobile, and Browser:

public override void OnFrameworkInitializationCompleted()
{
    this.Connect(() => new MainView(), view => CompositionRoot.Create(view), () => new MainWindow());
    base.OnFrameworkInitializationCompleted();
}

Connect handles IClassicDesktopStyleApplicationLifetime and ISingleViewApplicationLifetime automatically, so the same code runs everywhere.

Shell, Sections, and Navigation

A section-based navigation system integrated with Microsoft.Extensions.DependencyInjection:

ServiceCollection services = new();

services.AddSingleton<IShell, Shell>();
services.AddSingleton(DialogService.Create());
services.AddScoped<INavigator>(provider => new Navigator(provider, logger, RxApp.MainThreadScheduler));
services.AddAllSectionsFromAttributes(logger); // auto-discovers [Section] ViewModels
services.AddTransient<MainViewModel>();

var serviceProvider = services.BuildServiceProvider();
return serviceProvider.GetRequiredService<MainViewModel>();

Combined with Zafiro.Avalonia.Generators, sections are discovered from [Section] attributes and registered automatically.

Dialogs and Wizards

Dialogs that work on both desktop and mobile:

Result<Maybe<T>> result = await dialog.ShowAndGetResult(viewModel, "Title");
Dialogs.desktop.mp4

Build multi-step wizards declaratively with SlimWizard:

var wizard = WizardBuilder
    .StartWith(() => new Page1ViewModel(), "Step 1")
        .NextWith(model => model.Continue.Enhance("Next"))
    .Then(result => new Page2ViewModel(result), "Step 2")
        .NextWhenValid((vm, prev) => Result.Success(vm.Text!))
    .WithCompletionFinalStep();
Wizard.mp4

EnhancedCommand

Wraps ReactiveCommand with UX metadata (text, icon, name) and busy state — distinguishing between busy (executing) and disabled (can't execute) via IEnhancedCommand:

var command = ReactiveCommand.CreateFromTask(() => DoSomething());
var enhanced = command.Enhance("Save", name: "save");
// enhanced.IsBusy tracks execution; enhanced.CanExecute tracks enablement

View Locators

Automatically resolves Views for ViewModels by naming convention (MainViewModelMainView) and by x:DataType discovery via source generators:

DataTemplates.Add(new NamingConventionViewLocator());

With Zafiro.Avalonia.Generators, x:DataType declarations in .axaml files are discovered at compile time and registered automatically.

Key Features

Navigation and Shell

  • Shell / ShellView — Section-based application shell with sidebar navigation.
  • Navigator — Observable navigation stack integrated with DI.
  • SectionStrip — Tab-like section navigation with grouping support.
  • Sections auto-registration — Source generator discovers [Section] ViewModels and wires DI.

Controls

Control Description
HeaderedContainer Content with header, footer, and configurable spacing
EdgePanel Panel with Start, Content, and End regions
EnhancedButton Button with icon, role-based theming, and box shadow
Loading Loading indicator with content transition
BalancedWrapGrid Wrap panel with balanced column widths and MaxItemWidth
MasterDetailsView Side list with detail panel, responsive layout
ResponsivePresenter Width-based content swap (Narrow/Wide + Breakpoint)
StepIndicator Visual step progress for wizards
StringEditorControl.mp4

Services

  • DialogService — Show dialogs from ViewModels without coupling to the View layer.
  • NotificationService — Push notifications from ViewModels.
  • ILauncherService — Open URLs and files from ViewModels.

Commands and Selection

  • EnhancedCommandReactiveCommand wrapper with text/icon metadata, busy/disabled distinction via IEnhancedCommand.
  • ReactiveSelection — Observable selection model with multi-select support.
  • CommandPool / EnqueueCommandAction — Throttled, pooled command execution.

Helpers

  • Connect — One-line app bootstrap for all platforms (Desktop, Mobile, Browser).
  • NamingConventionViewLocator + DataTypeViewLocator — Convention and x:DataType based ViewModel → View resolution.
  • IconExtension — Unified icon markup extension supporting Optris and SVG providers.
  • ReturnExtension — Markup extension for returning observables in design-time data.

Samples

The solution includes runnable samples that demonstrate all features:

# Desktop
dotnet run --project samples/TestApp/TestApp.Desktop

# Browser (WASM)
dotnet run --project samples/TestApp/TestApp.Browser

Philosophy

  • Functional + ReactiveResult<T>, Maybe<T>, and IObservable<T> throughout. No exceptions for control flow, explicit error handling everywhere.
  • MVVM purist — Strict separation: no UI logic in ViewModels, no business logic in Views. Services are injected, never resolved from Views.
  • Composition over inheritance — Small, composable building blocks and extension methods.
  • ReactiveUI-first — State as observables, commands for intents, no imperative event handlers.
  • Cross-platform — Desktop, Android, iOS, and Browser from the same codebase.

Disclaimer

Zafiro.Avalonia is an independent community project and is not affiliated with, endorsed by, or sponsored by AvaloniaUI OÜ.

Avalonia is a trademark of AvaloniaUI OÜ.

License

MIT © José Manuel Nieto (@SuperJMN)

About

Controls and everyday helpers and utilities for Avalonia

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors

Languages