@dan While I love the idea of the changes to the SVG component, they are however creating a problem. I think there needs to be an option where I can choose to have Elements make the specified updates to the code.
I use a lot of SVG images that have very specific coloring built into them and I want them to maintain there appearance. I’m using them as I want the scalability.
After the update once I opened my site all of these SVG images are altered. They still appear in the image well with all their colors, but in the editor they are just a color blob. Probably because the colors have been stripped from the file, but I’m not sure.
I tried using the fill and stroke settings to reproduce my colors but could not get it to work as it was when designed.
Is there a way of adding an SVG and NOT having the colors stripped out?
To explain the problem more, look at my avatar on this post.
Its is build from a circle filled with red and a path that is stroked in white overlaid on the red. If you strip out the colors and I try to apply a stroke to render the overlaid path it will also stroke the outside of the red circle, not good. Effectively, this means I cannot reproduce this SVG with the current state of the component.
I agree I think there needs to be a way to opt into the optimizations.
The biggest problem is that these changes do not take into account SVG ikages with multiple paths, were some of the paths are filled and others are stroked, It just takes a broad brush approach and blows away those distinctions.
I have spent the morning trying to see if I can navigate my way around the problems to no avail. So this will delay the launching of one of my sites until we have a solution.
@dan That would be really helpful as there is clearly a need for the choice.
I would like to add that I’m not knocking these optimizations, for general simple icons and shapes they are ideal. I’m reworking all of mine to work better with them.
tl;dr: we’ll add some toggles to the SVG for more flexibility.
This thread is a great example of the inherent challenges with SVGs. While they may appear simple, under the hood they’re just XML-based code - and that brings its own set of quirks, especially when integrating them into component-based system like Elements.
Some background for anyone reading that perhaps hasn’t worked much with SVGs previously:
Unlike standard HTML elements, SVGs can have deeply nested structures, inline styles, non-standard attribute naming, and even embedded CSS or JavaScript. This makes them far less predictable when trying to apply styling. In many cases, class names don’t propagate as expected, and applying sizing, transforms, or colours can fail silently if the SVG isn’t structured in a compatible way. For example, setting a fill-red-500 class may have no effect if the fill attribute is hardcoded inline.
Because of that, it’s not realistic to expect that we can drop in any arbitrary SVG and have a fully flexible, styled, and responsive component “just work” every time. That’s why a degree of “cleaning up” or normalisation is so needed - for example, we need to like strip out inline styles so the SVG plays nicely with our theming system.
Having said all that, I’ll be adding some toggles to enable or disable the changes we introduced in the latest build. Hopefully that offer more flexibility and (fingers crossed) fix the issues raised in this thread
Just a quick update, this is what I’m thinking for the SVG component options. Hopefully these options make sense, but let me know if you think I’m missing something or have questions
@ben Assuming your using the same public api? How are you gaining access to the raw svg data? Guessing in hooks.js, but I failed. I could easily get the path to the svg resource, but couldn’t find a way to get the raw data (contents of file)?
Yes, everything we do in the built-in components is available to everyone.
Correct, in the hooks.js file I am simply getting the raw SVG string via the svg.image property (where svg is the ID of your control property) and doing string replacements.
const { svg, stripStroke } = rw.props;
let cleaned = svg.image;
if (stripStroke) {
cleaned = cleaned.replace(/stroke-width="[^"]*"/g, "");
}
this is data coming from the Elements resource field - it’s the data for the Elements resource file dropped in to a resource field.
We keep things consistent across all resources for simplicity. So you can get the raw SVG “image” via the resourceID.image property.
You can’t restrict the resource field to a given set of resource types, yes. So a user can drop any type of resource in to all resource fields at the moment. We need to implement restricted types.
@ben Yes I get it now, and see the allowed types is not implemented yet.
Hopefully when it is, this will return the contents of the file, like it currently does for svg.