Closed stsiarzhanau closed 6 years ago
Not sure if this will be too specific - using it just for classnames and not other properties. You can of course fork the project and just add this particular transform and use it though.
PR / API suggestions welcome anyway π.
I've found a workaround to achieve my goals. There's relatively new package called babel-plugin-react-css-modules. Using it i can just write <h1 styleName="heading">Hello, world!</h1>
instead of <h1 className={st.heading}>Hello, world!</h1>
. styleName
will be converted to class
during compilation.
So, to have this work
<svg class="icon">
<path class="outer" .... />
<path class="inner" .... />
</svg>
.icon .outer:hover {
fill: cyan;
}
I just need to create component that will render SVG like this:
<svg >
<path styleName="outer" .... />
<path styleName="inner" .... />
</svg>
When I create such a component manually, everything works as expected.
But when I use react-svg-loader it removes that styleName
attribute from source SVG. I am aware that SVGO includes removeUnknownsAndDefaults plugin which removes unknown attributes like styleName
. I disable this plugin into SVGO options. But anyway my styleName
attibute is being removed.
Could you help me to find out what's going on?
When I go to react-svg-loader/lib/loader.js and disable SVGO completely by changing this line
Promise.resolve(String(content)).then(optimize(query.svgo)).then(transform({
to
Promise.resolve(String(content)).then(transform({
My styleName="foo"
attribute is in place in created component.
But when I disable just removeUnknownsAndDefaults plugin in CLI
node_modules\.bin\svg2react --svgo.plugins.removeUnknownsAndDefaults false browsersync.svg
or in my webpack config
{
test: /\.svg$/,
include: SRC,
loaders: [
{
loader: 'babel-loader',
options: {
presets: ['es2015'],
},
},
{
loader: 'react-svg-loader',
options: {
svgo: {
plugins: [
{ removeXMLNS: true },
{ removeUnknownsAndDefaults: false },
],
floatPrecision: 2,
},
},
},
],
},
My styleName="foo"
attribute is removed.
P.S. I also tried
plugins: [
{ removeXMLNS: true },
{ removeUnknownsAndDefaults:
{
unknownAttrs: false,
},
},
],
It didn't help too.
Also trying to figure out a css modules + automatic inline svg solution.
I have found that svg-css-modules loader will work together with react-svg-loader, but of course the generated classes won't match with an imported css/scss file. It sounds right that some sort of transformClassAttrValueTo: /pattern/ available to the loader is what would be needed.
I agree, hoping for a way to use css modules with this module as well.
π Done.
before,
<svg class="foo bar">
// to
<svg className="foo bar">
Now, it is transformed to
<svg className={ (styles["foo"] || "foo") + " " + (styles["bar"] || "bar") }>
So, you can define custom classes for each of the individual classes and also use it with css-modules.
When styling components using CSS Modules our code looks something like this.
Let's assume our icon.svg looks something like this (simplified):
In our styles.css we can write cool things like...
To get the expected result our transformed SVG markup should look like...
But this loader will transform it like this:
And our styles will not work anymore.
So, it would be nice to add an option like
transformClassAttrValueTo: <pattern>
in order we could specify how ourclass="foo"
should be transformed.At the moment the only solution I've found is to create manually separate component for every icon...
... and then use it. It works, but it's very tedious, especially when we have a lot of icons.
So, I hope you will find time to add this useful feature ASAP. Thanks in advance.