Skip to content

fix(icon): render non-path SVG primitives and preserve stroke caps/joins#6

Open
AsimNet wants to merge 1 commit intohugeicons:mainfrom
AsimNet:fix/non-path-elements-and-stroke-attrs
Open

fix(icon): render non-path SVG primitives and preserve stroke caps/joins#6
AsimNet wants to merge 1 commit intohugeicons:mainfrom
AsimNet:fix/non-path-elements-and-stroke-attrs

Conversation

@AsimNet
Copy link
Copy Markdown

@AsimNet AsimNet commented May 1, 2026

Summary

Fixes two related bugs that cause several icons to render incorrectly when used via <hugeicons-icon>. Closes #5.

Bug 1 — Non-path SVG elements rendered as empty <path>

paths() only extracts d / fill / opacity / fillRule and the template renders every entry as <path>. But many icons contain circle, ellipse, rect, line, polyline, or polygon — these have no d attribute, so they collapse to empty <path d=""> tags and disappear.

Examples affected: CompassIcon (outer circle), AlertCircleIcon (outer circle + dots), MapsLocation01Icon (inner pin dot).

Bug 2 — strokeLinecap / strokeLinejoin stripped

Even for icons that only contain <path> elements, near-zero-length paths require stroke-linecap: round to render. The current code drops both attributes, so dots in icons like Alert02Icon (the exclamation dot is M11.992 16H12.001) become invisible — default linecap: butt collapses them to nothing.

Approach

  • Add an elementToPathD(tag, attrs) helper that converts each non-path SVG primitive into an equivalent path d string (circle, ellipse, rect, line, polyline, polygon).
  • Preserve strokeLinecap and strokeLinejoin from the source attrs, defaulting both to round when missing.
  • Bind the two new attributes in the template.

The template still renders a single <path> — no DOM-shape change, no breaking API change. Default round linecap/linejoin matches how the icons are rendered on hugeicons.com.

Why this approach over native <circle>/<ellipse> rendering

A few previous comments on #5 suggested using @switch to render native SVG tags. That's also valid but bloats the template significantly and changes the DOM structure. Converting to path data is a smaller surface change and preserves the existing rendering pipeline 1:1 — fewer chances of regressions.

Test plan

  • pnpm build passes (verified locally)
  • Visual diff on CompassIcon: outer circle now renders
  • Visual diff on AlertCircleIcon: outer circle + dots render
  • Visual diff on MapsLocation01Icon: inner pin dot renders
  • No change to icons that only contained <path> elements with non-zero-length paths
  • CI runs (the repo doesn't appear to have one wired up — let me know if I should add one)

Verified on

Angular 19, @hugeicons/angular@1.0.7 source, @hugeicons-pro/core-stroke-rounded icon pack.

Two related bugs caused several Hugeicons to render incorrectly in Angular:

1. Non-path elements (`circle`, `ellipse`, `rect`, `line`, `polyline`,
   `polygon`) were rendered as empty `<path>` because `paths()` only
   extracted `d/fill/opacity/fillRule` and the template emitted a single
   `<path>` regardless of the source tag. Affects e.g. `CompassIcon` (the
   outer circle), `AlertCircleIcon` (the outer circle), `MapsLocation01Icon`
   (the inner pin dot).

2. `strokeLinecap` and `strokeLinejoin` were stripped from attrs. Several
   icons draw dots as near-zero-length paths (e.g. `Alert02Icon`'s
   exclamation dot is `M11.992 16H12.001`); without `stroke-linecap: round`
   the default `butt` linecap collapses them to nothing.

Adds an `elementToPathD()` helper that converts each non-path SVG primitive
into an equivalent path `d` string, and preserves linecap/linejoin
(defaulting to `round`) when extracting attributes. The template already
renders a single `<path>`, so no DOM-shape changes.

Closes hugeicons#5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Some icons render incorrectly in @hugeicons/angular (missing inner details)

1 participant