Enigma.Icons.Avalonia 1.0.0

dotnet add package Enigma.Icons.Avalonia --version 1.0.0
                    
NuGet\Install-Package Enigma.Icons.Avalonia -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Enigma.Icons.Avalonia" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Enigma.Icons.Avalonia" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Enigma.Icons.Avalonia" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Enigma.Icons.Avalonia --version 1.0.0
                    
#r "nuget: Enigma.Icons.Avalonia, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Enigma.Icons.Avalonia@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Enigma.Icons.Avalonia&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Enigma.Icons.Avalonia&version=1.0.0
                    
Install as a Cake Tool

Enigma.Icons.Avalonia

Icons for Avalonia — the Icon control, two XAML markup extensions, and the extension methods that turn any IconGlyph into an Avalonia Geometry, Drawing or DrawingImage. Ships with the 1,512 × 6 Phosphor glyphs of Enigma.Icons.Phosphor, and renders your own SVGs just as happily.

What this package is

You want… Use
The model, the parser, your own .svg files Enigma.Icons
The Phosphor artwork — 1,512 icons × 6 weights Enigma.Icons.Phosphor
Avalonia rendering — Geometry, markup extensions, the Icon control Enigma.Icons.Avalonia (this package)

Target frameworks: net8.0, net10.0. Unlike its two siblings this package has no netstandard2.0 target — Avalonia 12 ships net8.0 and net10.0 assets only, so a netstandard2.0 consumer could not resolve it anyway.

It depends on Avalonia and on Enigma.Icons.Phosphor — which brings Enigma.Icons transitively — and on nothing else.

Quick start

dotnet add package Enigma.Icons.Avalonia

One namespace declaration reaches the control and both markup extensions:

xmlns:ei="https://github.com/josueclement/Enigma.Icons"
<ei:Icon Kind="Acorn" Weight="Duotone" Size="24"
         Foreground="{DynamicResource SystemControlForegroundAccentBrush}" />

The per-namespace using: forms remain the documented fallback — Avalonia's using: mapping covers one CLR namespace and not its sub-namespaces, so that route needs two declarations (xmlns:ei="using:Enigma.Icons.Avalonia" for the control and xmlns:eim="using:Enigma.Icons.Avalonia.Markup" for the extensions).

Nothing goes into App.axaml. Icon derives from Control, not TemplatedControl, and renders itself. The package ships no XAML and no theme resources, so there is no <StyleInclude> to add and no resource key to get wrong. Add the package, declare the namespace, use the control.

And from C#:

using Avalonia.Media;
using Enigma.Icons.Avalonia;
using Enigma.Icons.Phosphor;

Geometry geometry = PhosphorIconSet.Instance
    .GetGlyph(PhosphorIcon.Acorn, PhosphorWeight.Bold)
    .ToGeometry();

The Icon control

Property Default What it does
Kind Acorn (enum value 0) The built-in Phosphor icon to draw
Weight Regular Thin, Light, Regular, Bold, Fill, Duotone
IconSet null A custom IIconSet. When set, it wins over Kind/Weight
IconName null The name to resolve against IconSet
Variant null The variant of IconName, or the set's default
Foreground inherited The brush every layer paints with
Size 16 The measured size on both axes
Stretch Uniform None, Uniform, UniformToFill, Fill

Four behaviours are worth stating outright:

  • Foreground inherits. It re-owns TextElement.ForegroundProperty, which is an inheriting property, so an icon inside a Button, a MenuItem, a TextBlock — any text scope — picks up that scope's brush and follows a theme switch with no binding written by you. When Foreground resolves to null the control paints nothing; it does not fall back to black.
  • An explicit Width/Height wins over Size. Size is the measured square; the framework's own explicit-size coercion takes precedence over it.
  • Render never throws. A missing glyph, an unresolvable name, or a misbehaving third-party icon set all paint nothing — a throwing render pass would take down the XAML previewer's surface for the whole window, not just the icon.
  • Path data is parsed once per glyph, not once per frame. A resize, a theme switch or a scroll through a virtualized list re-renders every visible icon; the parsed geometry is held against the glyph itself, so those passes cost no parsing at all — and many controls showing the same icon share one parse. The cache holds its glyphs weakly, so a custom IIconSet that goes out of scope is collected normally.
<Button Content="Delete">
    <Button.Template>
        <ControlTemplate>
            <StackPanel Orientation="Horizontal">
                <ei:Icon Kind="Trash" />   
                <ContentPresenter />
            </StackPanel>
        </ControlTemplate>
    </Button.Template>
</Button>

Accessibility. Icon is decorative by default: Focusable is false and a screen reader skips it. Set AutomationProperties.Name when the icon carries meaning of its own, and it joins the automation content view.

Control or markup extension?

A markup extension is evaluated once, at load time. It therefore cannot follow a bound brush, a DynamicResource, or a theme switch — not as a design choice, but structurally. The control can, because it resolves its brush at render time.

  • Use ei:Icon for anything themed, bound, or interactive. This is most icons in most apps.
  • Use the markup extensions for a static Path.Data or Image.Source that never changes.

There is one more deliberate asymmetry: the markup extensions fail fast — a bad icon or weight in XAML throws at load time, because that is an authoring error you want to see — while Icon.Render never throws.

The markup extensions

<Path Data="{ei:IconGeometry Acorn, Weight=Bold}" Fill="Black" Stretch="Uniform" />
<Image Source="{ei:IconImage Acorn, Weight=Fill, Brush=Red}" Width="24" Height="24" />

Both take the icon as a positional argument and default Weight to Regular; IconImage also takes a Brush, defaulting to black. It is called IconImage rather than IconSource because it returns a DrawingImage and Avalonia already has an IconSource concept of its own.

The extension methods

Geometry      ToGeometry(this IconGlyph glyph);
Drawing       ToDrawing(this IconGlyph glyph, IBrush brush);
DrawingImage  ToDrawingImage(this IconGlyph glyph, IBrush brush);

They take an IconGlyph — from any IIconSet — so nothing here is Phosphor-specific.

ToGeometry collapses a multi-layer glyph into a GeometryGroup, and per-layer opacity is lost. A Geometry has no per-child opacity and one shared fill rule, so every layer paints at full opacity. For the two-layer Duotone weight that means the backing shape comes out solid — visually wrong, and deliberately allowed, because a single Geometry is what Path.Data needs. Use ToDrawing, or the Icon control, for duotone; both walk the layers and honour each one's opacity.

Every call parses afresh, and the result is yours to keep or mutate. Unlike the Icon control, which caches its parsed geometry per glyph because it never hands it out, these methods return an independent object each time — so setting Transform on one, or putting it in a GeometryGroup, can never disturb another caller holding the same icon.

Works with any IIconSet

The extension methods and the control's IconSet / IconName / Variant path take any icon set, including an SvgIconSet over a folder of your own artwork — the built-in set has no privileged route:

using Enigma.Icons;

// Build the set once — at start-up, or as a ViewModel property — and bind it.
IIconSet mine = SvgIconSet.FromDirectory("Assets/Icons", name: "House");
<ei:Icon IconSet="{Binding MyIconSet}" IconName="logo" Variant="bold" Size="32" />

Stroked and translucent layers survive the trip: ToDrawing and the control build a Pen from the layer's stroke width, cap and join, and honour a layer's own stroke colour when it names one. See Enigma.Icons for the set factories and the parser's supported subset.

Trimming and AOT

The package is marked IsTrimmable and IsAotCompatible on the modern target frameworks, and builds free of IL2xxx/IL3xxx warnings.

The repository ships a gallery sample that filters all 1,512 icons by name as you type, switches between the six weights, and offers size and colour controls — click an icon to copy its XAML snippet: samples/Enigma.Icons.Avalonia.Gallery.

Licence

MIT — see LICENSE.md, which ships in this package.

The icon artwork is separately MIT-licensed by Phosphor Icons; its notice travels with Enigma.Icons.Phosphor, the package that carries the artwork.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 78 7/31/2026

Enigma.Icons.Avalonia 1.0.0 — initial release. Avalonia rendering for Enigma.Icons: the Icon control (no StyleInclude needed; inherits Foreground and follows theme switches), the {ei:IconGeometry} and {ei:IconImage} markup extensions, and Geometry / Drawing / DrawingImage conversion extensions. Supersedes the retired PhosphorIconsAvalonia package — new identity, no upgrade path. See RELEASENOTES.md for the full details.