I have a sprite map SVG, and example usage is like this:
<svg aria-hidden="true" class="block w-full h-full block"><use xlink:href="/src/assets/sprite.svg?t=123#triangle"></use></svg>
This loads the triangle SVG in Shadow DOM like so:
<svg viewBox="0 0 1920 1080" fill="currentColor" id="battery_distributor"><path d="M150 5 75 200h150Z"></path></svg>
However, the triangle SVG is set like this:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1080">
<path d="M150 5 L75 200 L225 200 Z" style="fill: none; stroke: green; stroke-width: 3" />
</svg>
But it appears filled in as black on the output DOM via the sprite.
My guess is because the vite-svg-sprite-wrapper
plugin I use for building the sprite map
https://github.com/vshepel/vite-svg-sprite-wrapper is stripping the style attribute away.
Is there another method to be able to add SVG files via one single React Typescript component in Vite which still support custom style attributes on different grouping g
tags?
The docs for that plugin link to this SVG Sprite tool https://github.com/svg-sprite/svg-sprite/
Which in turn mentions it uses svgo - https://github.com/svg/svgo
EDIT:
The actual SVG has something like this, just fake path numbers. The issue is that the first grouping child using stroke displays correctly but the 2nd grouping child using fill does not display, as I have color: transparent
to try to avoid the weird background clipping grey colour:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1080">
<g>
<g transform="matrix(1,0,0,1,200,500)" opacity="1" style="display: block;">
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path stroke-linecap="round" stroke-linejoin="round" fill-opacity="0" stroke-dasharray="10"
stroke="rgb(0,0,0)" stroke-opacity="0.35" stroke-width="3"
d="M-20, 100">
</path>
</g>
<g opacity="1" transform="matrix(1,0,0,1,0,0)">
<path stroke-linecap="round" stroke-linejoin="round" fill-opacity="0" stroke-dasharray="10"
stroke="rgb(180,211,46)" stroke-opacity="1" stroke-width="3"
d="M-20, 100">
</path>
</g>
</g>
<g transform="matrix(1,0,0,1,1,0)" opacity="1" style="display: block;">
<g opacity="1"
transform="matrix(1,0,0,1,1,0)">
<path fill="rgb(0,0,0)" fill-opacity="0.35"
d="M1, -28z">
</path>
</g>
<g opacity="1"
transform="matrix(0, 0, 1, 1)">
<path fill="rgb(180,211,46)" fill-opacity="1"
d="M1, -28z">
</path>
</g>
</g>
</g>
</svg>
Found a fix, so basically the vite-svg-sprite-wrapper
Vite plugin is a wrapper for svg-sprite
but this uses svgo
After reading through all the docs, there is a sprite
config option which configures how svg-sprite
works. In that it has an option for configuring the tranformation of svgo
using shape.transform
I want to keep the same default preset, and only ovveride the removeStyleElemets
plugin for svgo
, thus my final code is now:
ViteSvgSpriteWrapper({
icons: 'public/animations/*.svg',
outputDir: 'src/assets',
sprite: {
shape: {
transform: [{
svgo: {
plugins: [{
name: 'preset-default',
params: {
overrides: {
removeStyleElement: false,
}
}
}]
}
}]
}
}
}),
...and this works, the style attributes are kept on the g
tags.