I am creating React components that will render out various SVGs:
const Close = ({
fill, width, height, float,
}) => (
<svg width={ `${width}px` } height={ `${height}px` } viewBox="0 0 14.48 14.48" style={ { float: `${float}`, cursor: 'pointer' } }>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={ { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 } } x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={ { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 } } x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);
It's very convenient to be able to supply various attributed to this component to control dimensions, colour, etc...
What I don't have a good solution for, however, is handling the styles in a DRY manner. Note the line
elements have the same value for style
. I presently have them written inline because if I added an embedded stylesheet, then I would get class name collisions with other SVGs I render elsewhere on the page (our SVG software uses the same classes over and over).
<style scoped>
has been removed from the spec: https://github.com/whatwg/html/issues/552
Shadow DOM is not yet supported by Edge: https://caniuse.com/#feat=shadowdomv1
Is there any other alternative for scoping styles?
To combine the best of both worlds, you could create an external styles file, as you would for CSS, but with exported style objects. You could then import it into any file that needs it.
As example, main file:
import React, { Component } from 'react';
import { render } from 'react-dom';
import * as Styles from './svgstyles';
class App extends Component {
render() {
return (
<div>
<svg width="100" height="200" viewBox="0 0 100 200">
<rect x="0" y="0" width="10" height="10" style={Styles.style1} />
<rect x="15" y="0" width="10" height="10" style={Styles.style2} />
<rect x="30" y="0" width="10" height="10" style={Styles.style3} />
<rect x="45" y="0" width="10" height="10" style={Styles.style4} />
<rect x="0" y="15" width="10" height="10" style={Styles.style4} />
<rect x="15" y="15" width="10" height="10" style={Styles.style3} />
<rect x="30" y="15" width="10" height="10" style={Styles.style2} />
<rect x="45" y="15" width="10" height="10" style={Styles.style1} />
</svg>
</div>
);
}
}
render(<App />, document.getElementById('root'));
And an external styles file:
export const style1 = {
stroke: 'red',
strokeWidth: "1",
fill: "blue",
}
export const style2 = {
stroke: 'red',
strokeWidth: "1",
fill: "green",
}
export const style3 = {
stroke: 'red',
strokeWidth: "1",
fill: "yellow",
}
export const style4 = {
...style3,
fill: "pink",
}
Live example here
If you just want to DRY up the code, you could create one style-object and reuse it:
const Close = ({
fill, width, height, float,
}) => {
const style = { fill: 'none', stroke: `${fill}`, strokeMiterlimit: 10 }
return (
<svg width={ `${width}px` } height={ `${height}px` } viewBox="0 0 14.48 14.48" style={ { float: `${float}`, cursor: 'pointer' } }>
<title>x</title>
<g id="Layer_2" data-name="Layer 2">
<g id="Background">
<line style={ style } x1="14.13" y1="0.35" x2="0.35" y2="14.13" />
<line style={ style } x1="14.13" y1="14.13" x2="0.35" y2="0.35" />
</g>
</g>
</svg>
);
}
This would also result in a small performance improvement since fewer objects would be created in each render cycle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With