A plugin that converts svg to a react component. Used in react-svg-loader
npm i babel-plugin-react-svg --save-dev
# or with yarn
yarn add babel-plugin-react-svg --dev
Input SVG:
<svg class="foo" style='text-align: center; width: 100px' pointer-events="stroke">
<circle cx="50" cy="50" r="25" style="text-align: center;" stroke-width="5" />
</svg>
Output React Component:
import React from "react";
export default ({ styles = {}, ...props}) => <svg
className={styles["foo"] || "foo"}
style={{ textAlign: "center", width: "100px" }}
pointerEvents="stroke"
{...props}>
<circle cx="50" cy="50" r="25" style={{textAlign: "center"}} strokeWidth="5" />
</svg>;
Going from bottom up, the following transformations are applied and the same can be checked in the partly annotated source - babel-plugin
<svg pointer-events="none">
<path stroke-width="5"/>
</svg>
is transformed to
<svg pointerEvents="none">
<path strokeWidth="5"/>
</svg>
React expects style attribute value to be an object. Also, Hyphenated style names are converted to camel case.
<svg style="text-align: center">
<circle style="width: 10px"/>
</svg>
is transformed to
<svg style={{textAlign: 'center'}}>
<circle style={{width: '10px'}}/>
</svg>
The props passed to the output component is passed on to the root SVG node and the props already defined are overridden by the props passed.
<svg width="50">
...
</svg>
is transformed to
<svg width="50" {...props}>
...
</svg>
<svg class="foo bar"/>
is transformed to
<svg className={ (styles["foo"] || "foo") + " " + (styles["bar"] || "bar") }>
The loader should now export the svg component. And this is done by wrapping it in an ArrowFunctionExpression.
<svg>...</svg>
is transformed to
import React from 'react';
export default ({ styles = {}, ...props }) => <svg {...props}>...</svg>;
- Root element is always
<svg>
- SVG is optimized using SVGO