Skip to content

Make CustomIconBuilder work for SVG icon sets on Propshaft - #211

Merged
dallasbpeters merged 4 commits into
masterfrom
optics-svg-icons
Sep 30, 2026
Merged

dallasbpeters merged 4 commits into
masterfrom
optics-svg-icons

Conversation

@dallasbpeters

@dallasbpeters dallasbpeters commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Why

SVG icon sets such as Hugeicons can't use a font builder. Review pointed out that CustomIconBuilder already inlines SVGs, so this PR now just makes it work for them.

What changed

CustomIconBuilder:

  • Finds the file with Propshaft as well as Sprockets. It called Rails.application.assets_manifest, which only Sprockets defines, so it raised on Propshaft (the gem's own example app uses Propshaft).
  • Drops a reference to an undefined options, which raised whenever the SVG was found.
  • Emits Optics' icon--svg modifier instead of custom-icons, so size, weight and emphasis modifiers apply to the SVG. Needs Add .icon--svg for inline SVG icon sets optics#359.

A subfolder works as part of the name, so a set with styles needs nothing extra: icon('duotone-rounded/home-01') reads app/assets/images/icons/duotone-rounded/home-01.svg.

README: a short "SVG icons" section. New spec covers Propshaft, Sprockets and a missing file.

Removed from the first version

SvgIconBuilder, HugeiconsIconBuilder, the Hugeicons API client, the optics:icons:vendor rake task and the vendored-icons spec template.

Testing

bundle exec rspec: 108 examples, 0 failures.

🤖 Generated with Claude Code

`bin/rails g rolemodel:optics:icons --hugeicons` renders icons as inline SVG
read from files the app vendors, instead of an icon font.

- SvgIconBuilder: reads app/icons/<name>.svg once per process (re-reads while
  code reloading is on). Decorative by default (aria-hidden); hover_text: makes
  the span role="img" with an aria-label.
- HugeiconsIconBuilder: app/icons/hugeicons/<style>/<name>.svg; filled: and
  duotone: map to solid-rounded and duotone-rounded, style: picks any style.
- Rolemodel::Optics::Hugeicons: fetches SVGs from the Hugeicons API, rewrites
  colors to currentColor, and finds the icons views use.
- Generator adds lib/tasks/optics_icons.rake (optics:icons:vendor) and
  spec/icons_spec.rb, which fails when a used icon is not vendored.

Files live outside app/assets because Propshaft would serve them as
downloads, which the Hugeicons Pro license does not allow.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dallasbpeters
dallasbpeters marked this pull request as ready for review September 30, 2026 13:22
In a new app, bin/rails optics:icons:vendor failed with
uninitialized constant Rolemodel::Optics, because only the icon helper
required it. The task now requires it, and a bad icon name aborts with
its message instead of a stack trace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# downloadable file, which licensed sets (Hugeicons Pro) do not allow.
#
# Subclasses change where the files live (see HugeiconsIconBuilder).
class Rolemodel::Optics::SvgIconBuilder < Rolemodel::Optics::IconBuilder

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure the existing custom icon builder already supports loading SVGs. This feels way more complicated than it needs to be.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I removed the new builders, the API client, the rake task and the spec template. What's left is making CustomIconBuilder work for SVG sets: it now finds files on Propshaft as well as Sprockets (it called assets_manifest, which only Sprockets has), drops an undefined options reference that raised whenever the SVG was found, and emits Optics' svg-icon so the weight and emphasis modifiers apply. Styles are just subfolders: icon('duotone-rounded/home-01').

Review pointed out CustomIconBuilder already inlines SVGs, so the new
SvgIconBuilder, HugeiconsIconBuilder, API client, rake task and spec
template are gone.

What CustomIconBuilder still needed:
- Find the file with Propshaft as well as Sprockets. It called
  assets_manifest, which only Sprockets defines, so it raised on Propshaft.
- Drop the reference to an undefined `options`, which raised whenever
  the SVG was found.
- Emit Optics' `svg-icon` block so size, weight and emphasis modifiers
  apply to the SVG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dallasbpeters dallasbpeters changed the title Add Hugeicons as an inline SVG icon library Make CustomIconBuilder work for SVG icon sets on Propshaft Sep 30, 2026
## SVG icons (for example, Hugeicons)

Use `--custom`. Put each SVG in `app/assets/images/icons/`, and `icon('name')` inlines it with
Optics' `.svg-icon` styles (Optics 2.5+), so size, weight and emphasis modifiers apply. A subfolder

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need to adjust with the .icon .icon--svg naming

Optics settled on a modifier nested inside .icon (RoleModel/optics#359).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dallasbpeters
dallasbpeters merged commit 1e1b179 into master Sep 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants