Add .icon--svg for inline SVG icon sets - #359
Merged
Merged
Conversation
Jeremy-Walton
requested changes
Sep 30, 2026
Jeremy-Walton
left a comment
Member
There was a problem hiding this comment.
Can you add screenshots of the documentation page?
Also can you add back the checklist into the PR? There is a reason that exists in the PR template. It tells you how to check everything
Main question is around the class and what the intended usage is. It's named as a modifier and indicated to be used as such but the css is not nested to enforce that.
Review asked whether .icon--svg was a block or a modifier: it was named as a modifier but not nested to enforce it. It is now the .svg-icon block, used with .icon the same way .material-symbols-outlined is. .icon keeps the public API: the stroke-width variables sit with the other icon options, and the weight modifiers set --__op-icon-stroke-width, which .svg-icon reads. Adds an Svg story showing sizes, weights and low emphasis, and shows it in the SVG Icons docs section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jeremy-Walton
requested changes
Sep 30, 2026
Per review, SVG icons are a modifier of .icon rather than their own block. .icon--svg is now nested in .icon, so it only applies together with .icon. The docs point at the rolemodel_rails --custom builder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dallasbpeters
added a commit
to RoleModel/rolemodel_rails
that referenced
this pull request
Sep 30, 2026
Optics settled on a modifier nested inside .icon (RoleModel/optics#359). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jeremy-Walton
approved these changes
Sep 30, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dallasbpeters
added a commit
to RoleModel/rolemodel_rails
that referenced
this pull request
Sep 30, 2026
* Add Hugeicons as an inline SVG icon library `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> * Load Rolemodel::Optics in the generated icon task and spec 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> * Simplify: use CustomIconBuilder for SVG icons instead of a new builder 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> * Emit Optics' icon--svg modifier instead of the svg-icon block Optics settled on a modifier nested inside .icon (RoleModel/optics#359). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Task
No ticket. Companion to RoleModel/rolemodel_rails#211, which makes the
--customicon builder render SVG sets.Why?
Every Optics icon set is an icon font from a CDN today. Apps that use SVG icons (Almanac uses Hugeicons, which is also RoleModel's brand set) style them by hand. This adds one shared set of rules, so SVG icons get the same size, weight, and emphasis modifiers as font icons.
Optics stays CSS only. It ships no SVG files. Each app keeps its own.
What Changed
src/components/icon.css: new.icon--svgmodifier, nested inside.icon(icon icon--svg icon--large)..iconbox, so the size modifiers work unchanged.currentColor.icon--weight-*sets the stroke width. The rule targetssvg [stroke-width], because a CSS rule on the<svg>root cannot beat astroke-widthattribute on a child. With no weight modifier, the set keeps its own widths.icon--low-emphasislowers the opacity..iconkeeps the public API:--_op-icon-stroke-width-{light,normal,semi-bold,bold}and--_op-icon-svg-opacity-low-emphasissit with the other icon options, and the weight modifiers set--__op-icon-stroke-width, which.icon--svgreads.Icon.stories.js: newSvgstory with sizes, weights and low emphasis.Icon.mdx: "SVG Icons" section with the story, and the new variables in the API list. Apps with only SVG icons can useoptics+no_icons.css.package.jsonand the.storybook/assetsexample pages.Quality Assurance
Have you updated any usage of changed tokens?No tokens changed.Did you add a component?Have you added it to the dependency graph?Have you added it to the docs?Have you updated the dependency graph?No new dependencies. The new rules use no tokens..storybook/assets?Were any changes made to the top level optics.css file?Were those changes reflected in the other top level files?Questions for reviewers
Screenshots
SVG Icons section of the Icon docs page: