Skip to content

Instantly share code, notes, and snippets.

@MoOx
Last active December 3, 2018 08:50
Show Gist options
  • Select an option

  • Save MoOx/1eb30eac43b2114de73a to your computer and use it in GitHub Desktop.

Select an option

Save MoOx/1eb30eac43b2114de73a to your computer and use it in GitHub Desktop.
Svg icons with React.js with webpack loader (svg: raw-loader)
.IconSvg {
transform: translate3d(0,0,0); /* fix webkit/blink poor rendering issues */
display: inline-block;
/*width: 1em;*/
height: 1em;
line-height: 1;
vertical-align: middle;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.IconSvg--half {
width: .5em;
height: .5em;
}
.IconSvg--white { color: #fff }
.IconSvg--black { color: #000 }
.IconSvg svg {
width: inherit;
height: inherit;
line-height: inherit;
color: inherit;
fill: currentColor;
}
/**
* <IconSvg />
*
* Usage
* <IconSvg svg={require("gear.svg")} />
* <IconSvg svg={require("gear.svg")} modifier="white" />
* <IconSvg svg={require("gear.svg")} modifier="half" color="#f00" />
*
* @es6
*/
require("./index.css")
var React = require("react")
function getSvgBody(svg) {
return svg
// remove xml prolog
.replace(/<\?xml[\s\S]*?>/gi, "")
// remove doctype
.replace(/<!doctype[\s\S]*?>/gi, "")
// remove comments
.replace(/<!--[\s\S]*?-->/g, "")
// remove hardcoded dimensions
.replace(/width="\d+(\.\d+)?(px)?"/gi, "")
.replace(/height="\d+(\.\d+)?(px)?"/gi, "")
.trim()
}
export default React.createClass({
propTypes: {
svg: React.PropTypes.string.isRequired,
id: React.PropTypes.string,
modifier: React.PropTypes.string,
color: React.PropTypes.string
},
render() {
if (!this.props.svg.trim().match(/^\s*</g)) {
console.warn("Please use <IconSvg> with <svg> file. props= " + JSON.stringify(this.props))
}
var iconClass = "IconSvg"
var style = {}
if (this.props.modifier) {
iconClass += " IconSvg--" + this.props.modifier
}
if (this.props.color) {
style.fill = this.props.color
}
if (this.props.size) {
style.fontSize = this.props.size
}
return (
<span
className={(this.props.className ? this.props.className + " " : "") + iconClass}
onClick={this.props.onClick}
style={this.props.onClick ? {cursor: "pointer"} : null} // iOS won't trigger onClick if pointer is not pointer
hidden={this.props.hidden}
title={this.props.title}
dangerouslySetInnerHTML={{__html: getSvgBody(this.props.svg)}}>
</span>
)
}
})
@gaearon
Copy link

gaearon commented Jun 5, 2014

We use the same convention for modifiers in React. :-)

@wmertens
Copy link

@MoOx do you have a solution for using the same icon multiple times in the same page without having the same markup multiple times, causing more work for the browser?

@wmertens
Copy link

Ooh found a performance comparison (font files win) and apparently there's a symbol mode in svg.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment