ShellIcons.Maui
0.2.0-alpha
dotnet add package ShellIcons.Maui --version 0.2.0-alpha
NuGet\Install-Package ShellIcons.Maui -Version 0.2.0-alpha
<PackageReference Include="ShellIcons.Maui" Version="0.2.0-alpha" />
<PackageVersion Include="ShellIcons.Maui" Version="0.2.0-alpha" />
<PackageReference Include="ShellIcons.Maui" />
paket add ShellIcons.Maui --version 0.2.0-alpha
#r "nuget: ShellIcons.Maui, 0.2.0-alpha"
#:package ShellIcons.Maui@0.2.0-alpha
#addin nuget:?package=ShellIcons.Maui&version=0.2.0-alpha&prerelease
#tool nuget:?package=ShellIcons.Maui&version=0.2.0-alpha&prerelease
ShellIcons.Maui (preview)
Lucide-derived icons for .NET MAUI as native Path shapes, from the same 1,555-icon catalog as
ShellIcons.Blazor. Docs: shellicons.shellui.dev/docs/maui/getting-started.
Install
dotnet add package ShellIcons.Maui --prerelease
Targets net10.0-android, net10.0-ios, net10.0-maccatalyst and net10.0-windows10.0.19041.0.
Use
<ContentPage xmlns:icons="https://shellicons.dev/maui">
<HorizontalStackLayout Spacing="8">
<icons:ChevronRight Size="16" />
<icons:Icon Name="Search" Color="{DynamicResource Primary}" />
<icons:Icon Name="{Binding StatusIcon}" Title="Status" />
</HorizontalStackLayout>
</ContentPage>
| Property | Default | Notes |
|---|---|---|
Size |
24 |
Width and height |
StrokeThickness |
2 |
On the 24-unit grid, scaled with Size like the Blazor target |
AbsoluteStroke |
false |
Keep the rendered stroke at StrokeThickness at any size |
Color |
null |
Bindable. Null means black in light theme, white in dark |
Title |
null |
Sets SemanticProperties.Description; null keeps the icon out of the accessibility tree |
Set a default color app-wide with a style:
<Style TargetType="icons:IconView" ApplyToDerivedTypes="True">
<Setter Property="Color" Value="{DynamicResource Foreground}" />
</Style>
Names and metadata:
IconCatalog.TryParse("home", out var name); // → IconName.House (Lucide alias)
IconCatalog.Get(IconName.House).Tags; // ["home", "living", "building", …]
IconCatalog.Search("cart"); // id matches first, then aliases/tags/categories
How it maps SVG to MAUI
ShellIcons.Generator.Xaml converts each SVG at build time. Every shape element becomes a
sub-path of one normalized path string — absolute commands only (M L C Q A Z), 3-decimal
coordinates:
| SVG | Normalized as |
|---|---|
<path d> |
Tokenized (compact numbers, exponents, compact arc flags), relative → absolute, H/V → L, S → C, T → Q |
<circle> / <ellipse> |
Two half-arcs |
<rect rx ry> |
Lines + four arc corners (SVG radius rules: missing radius copies the other, clamped to half a side) |
<line> / <polyline> / <polygon> |
M + L… (+ Z) |
fill="currentColor" shapes |
A second path that is filled and stroked |
| Shapes entirely outside the viewBox | Dropped (SHELLICONS005) — browsers clip them, a native Path wouldn't |
At runtime the control walks that pre-normalized string into a PathGeometry once per icon and
caches it, so every control showing the same icon shares one geometry.
Design decisions
| Decision | Why |
|---|---|
| Path data ships as compact normalized strings, turned into geometry once per icon and cached | Emitting per-icon construction code would be several times larger than the data. There's still no SVG parsing and no PathGeometryConverter at runtime. |
One Path per icon; a second only for fill="currentColor" shapes |
Lists and toolbars show many icons, so one native view per icon matters. |
Typed controls and an IconName dispatcher |
Typed controls trim per icon; the enum lets an icon be a binding or a component parameter. |
Color, not TintColor |
In MAUI, TintColor usually means image tinting. Color is bindable, so {DynamicResource …} works. |
| Defaults match the Blazor package | Size 24, stroke 2, round caps and joins — icons look the same on both targets. |
| No consumer-selected icon subsets yet | The generator runs when this package is built, not in the consumer's build, so it can't see which icons an app wants. Typed controls already trim unused icons. |
Same IconName / Icon names as ShellUI Native's interim icon component |
ShellUI Native can switch to this package without changing its components. |
The conversion contract for custom icons is in catalog/custom/README.md; both generators share one naming rule (Naming.KebabToPascal).
Verified
- Builds with zero warnings for
net10.0,net10.0-android,net10.0-ios,net10.0-maccatalyst,net10.0-windows10.0.19041.0(on Windows, with the MAUI workloads). - Tests on the plain
net10.0build, including a compiled XAML fixture (xmlns, string →IconName,icons:Imagenext to MAUI'sImage). - A check that parses every icon into MAUI geometry and keeps every endpoint on the 24×24 grid. It caught a stray off-canvas shape in Lucide's own
save-off.svg. - Rendered in a Windows app from the packed package. Not yet looked at on Android or iOS devices.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-android36.0 is compatible. net10.0-browser was computed. net10.0-ios was computed. net10.0-ios26.0 is compatible. net10.0-maccatalyst was computed. net10.0-maccatalyst26.0 is compatible. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. net10.0-windows10.0.19041 is compatible. |
-
net10.0
- Microsoft.Maui.Controls (>= 10.0.110)
-
net10.0-android36.0
- Microsoft.Maui.Controls (>= 10.0.110)
-
net10.0-ios26.0
- Microsoft.Maui.Controls (>= 10.0.110)
-
net10.0-maccatalyst26.0
- Microsoft.Maui.Controls (>= 10.0.110)
-
net10.0-windows10.0.19041
- Microsoft.Maui.Controls (>= 10.0.110)
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 |
|---|---|---|
| 0.2.0-alpha | 61 | 10/23/2026 |