Repository navigation
feat: make ShellIcons safe to use next to a UI kit: suffixed components, Icon.* factory, @onclick guard - #1
Merged
Merged
Conversation
…dering and reduce namespace pollution
…g and attribute forwarding
…mespace imports, and rendering methods for ShellIcons
…ering and updating icon snippet logic in documentation
…ve misuse in ShellIcons Blazor tests
…eserved name diagnostics
…prehensive icon rendering validation
…and update .gitignore for local Claude Code configuration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Integrating ShellIcons into an app that already uses a UI kit (ShellUI) broke down:
@using ShellIcons.Iconsputs 1,555 short names into Razor's tag lookup, which collide with UI-kit components likeBadge,TableandRouter(RZ9985).@using Icon = ShellIcons.Icons→<Icon.Plus />) compiles but renders blank, and type aliases don't help either.<ShellIcons.Icons.Plus />in full at ~100 call sites.This PR adds ways to use icons that can't collide, and documents which one to pick.
What changed
Two collision-safe APIs, both from
@using ShellIcons<ChevronRightIcon Size="16" />Icon.*factory@Icon.ChevronRight()RenderFragmentparameters, lists built in C#{Name}Iconcomponent in the rootShellIconsnamespace. The suffix keeps names clear of UI-kit components and tells readers it's an icon (lucide-react ships the same alias). Each one is an empty subclass of the existing component, so all parameters work and it adds almost nothing to the DLL.shellicon would beShellIcon, which is already the dispatcher. It gets no suffixed form and stays reachable asIcon.Shell(). The generator reports this as info diagnosticSHELLICONS003.Icon.*factory: one static method per icon, returning aRenderFragment. All methods share one helper instead of each inlining a lambda.@Icon.Plus()in a hot render path doesn't allocate.ShellIcons.Iconscomponents are unchanged apart from no longer beingsealed.@onclickon an icon now fails with a clear messageOn a component, Razor passes
<PlusIcon @onclick="Save" />as a plain string attribute named@onclick, not as an event handler. That string gets copied onto the<svg>, and the browser rejects@onclickas an attribute name, which breaks rendering with a cryptic JS error. This affected every existing icon component.IconCorenow throws anInvalidOperationExceptionexplaining the two forms that work:<button @onclick="…">(recommended, and what screen readers expect)onclick="@(() => Save())"without the@Size
ShellIcons.Blazor.dll(net9.0, Release)Fixes
Microsoft.SourceLink.GitHubpackage fromDirectory.Build.props. It pulled inMicrosoft.Build.Tasks.Git 8.0.0, which has a known vulnerability (NU1902). The .NET 8+ SDK includes Source Link, and the packed.nuspecstill records the repository commit.["@onclick"]inadditionalAttributeswas wrong; the key is"onclick". It's now covered by a test..gitignorerule for.claude/never matched, because gitignore doesn't allow a comment on the same line.Docs
@using ShellIcons+<ChevronRightIcon />. The/iconsbrowser copies the suffixed name (@Icon.Shell()forshell).Tests
.razortest page that imports a fake UI kit with a clashingBadge, plus Blazor'sRoutingnamespace, and uses<BadgeIcon />,<RouterIcon />and@Icon.Table()together. If a suffixed name ever collides, the test project stops compiling.shellexception, factory caching, theonclickforms, and the@onclickerror message. The test project now uses the Razor SDK so it can compile.razorfiles.Compatibility
<ChevronRight />,<ShellIcon Name="…" />andIcon.*usage keeps working.@onclickon an icon component now throws when it renders instead of breaking in the browser. That code never worked, so this only turns a cryptic error into a clear one.ShellIcons.Icons.*types (no longersealed).