Typed vs dispatcher
ShellIcons ships two ways to render an icon. Both produce identical HTML. The difference is at build time.
Which typed form? The examples below use the flat
<div data-shelldocs-slot="component" data-shelldocs-id="s17b440663bf5"></div>names fromShellIcons.Icons. In an app that also uses a UI kit, use the suffixed twins fromShellIconsinstead —<div data-shelldocs-slot="component" data-shelldocs-id="s94c799e2ca65"></div>— or the factory@Icon.ChevronRight(). They tree-shake the same way, and they can't collide with UI-kit components likeBadgeorTable(RZ9985).
Typed form — the default
@using ShellIcons.Icons
<ChevronRight />
<Zap Size="16" />
- Each icon is a distinct C# type
- Blazor's IL trimmer sees which types you actually reference and drops the rest
- IntelliSense — start typing
<Chand get every icon starting with "Ch" - Standard
[Parameter]binding, standard everything
Dispatcher form — the escape hatch
@using ShellIcons
<ShellIcon Name="chevron-right" />
<ShellIcon Name="@page.IconName" Size="20" />
- A single
ShellIconcomponent with aNamestring - Backed by a static dictionary of all 1,555 icons the source generator populates
- Referencing
ShellIconanywhere in your app roots the entire catalog — the trimmer can no longer eliminate any of them
The tradeoff, made concrete
| Scenario | Recommendation |
|---|---|
Icon name is known at compile time — <div data-shelldocs-slot="component" data-shelldocs-id="saefbc9aa07d3"></div> on a button |
Typed |
| Icon name comes from a markdown author, JSON payload, CMS field | Dispatcher |
| Icon name is chosen from a small compile-time set | Typed (with a switch if needed) |
| You want the smallest possible bundle | Typed only — don't reference ShellIcon |
Mixing
Both can live in the same app. As long as you never reference <div data-shelldocs-slot="component" data-shelldocs-id="s7e801fcd2ce1"></div> in code the trimmer can reach, it and its dictionary get eliminated. The moment you do reference it — even once — the full catalog stays.
When you need dynamic names, prefer a switch
If you have a handful of dynamic icons and want to keep tree-shaking, a switch beats the dispatcher:
@switch (kind)
{
case "alert": <TriangleAlert />; break;
case "success": <CircleCheck />; break;
case "info": <CircleAlert />; break;
default: <CircleHelp />; break;
}
Uses only the 4 typed icons — the other 1,551 get trimmed.
ShellIcon.Names
The dispatcher exposes the full catalog for enumeration:
var count = ShellIcon.Names.Count; // 1555
var contains = ShellIcon.Names.Contains("chevron-right"); // true
This is fine — accessing Names alone triggers the same "full catalog is rooted" behavior as rendering <div data-shelldocs-slot="component" data-shelldocs-id="sfeee7ded7f73"></div>.