I’ve been trying to find a better way of dynamically change the colors of an SVG. The ideia here is to keep those SVGs inside SVG files instead of having N components for each SVG. Now what I’ve been using is creating a component that receives name and color as a prop and renders the SVG inline for that name (imagine how many lines this component has while increasing the number of SVGs in my project). But I don’t know if that’s the best way of doing this, at least I haven’t found another way. How you guys are doing this? Do you think my approach is a good one?
P.S.: Every other topic close to this one is some years old, and didn’t fit my goal. Wonder if there’s any new library that handle this scenario.
How about simply use CSS variable names instead? This way all you do is to read SVG file by it’s name and render it as-is in the template. That requires only few lines of code …
Just putting the CSS color variable name in the SVG fill attribute inside the SVG file doesn’t work, when it imports the SVG, it comes as a static resource. Does it work for you?
Depending on the app and browser the support may be different, but in short you can even add style tag with you custom CSS and support for the @media queries, so you are able to add dark and light versions of same icon.
In Phoenix project you have to declare the variable in your CSS or SCSS file and use it within your SVG file var(--my-css-var-name). This needs to be rendered within DOM as favicon or img does not support “cross-document” styles. However you can still declare said CSS variables in the SVG file and then use as favicon or img.
How about embedding your SVG in a HEEx template file? You can then import it as a component inside your liveviews or controllers with embed_templates/2 and these components can accept assigns. embed_templates docs
defmodule MyAppWeb.HomeLive do
use MyAppWeb, :live_view
embed_templates("*.svg", root: Application.app_dir(:my_app, "lib/my_app_web/components", suffix: "_svg")
def render(assigns) do
~H"""
<.icon_svg color="text-green-500" />
"""
end
# ...
end
Notice the use of the @color assign, along with stroke="currentColor" on the SVG.