Better SVG workflows with React 👌
There are different approaches to use SVG inside a React component, the process usually involves the following steps
- Create SVG in Editor (Sketch, Illustrator..)
- Copy SVG contents and paste them into the React
- Adjust content (e.g class -> className) to make it JSX compatible
- Manipulate the SVG JSX like any other element.
This works ok for small components but there are some issues that can get annoying for bigger components:
We lose the ability to keep iterating on the SVG assets (We would have to adjust them again or just copy/paste the parts that changed into our JSX).
Having all the SVG markup creates a lot of noise making it harder to read the source code of our components.
The goals of this library is overcoming those issues, making it easier to work on SVG based components:
- Keeping the .svg file independent (so it becomes trivial to update )
- Provide a way to declare SVG manipulations
the React way.
npm install react-samy-svg
Loading the asset (Additional network request)
path prop is used, then the asset will be fetched from the url.
<Samy ="svg public url here"><SvgProxy ="#Star" = /></Samy>;
In the previous code, the stroke attribute of the element with id "star" is set
to the value of the state property
strokeColor. Any property set in the
SvgProxy element will also be set in the svg child node.
Note: Just load assets from sites you trust.
Bundling the svg assets with your component.
Having the svg file bundled with your component avoids the additional network request.
You can use something like the webpack raw-loader to read the .svg file contents at build time and use the
svgXML property (instead of path) to pass the file contents to Samy.
import svgcontents from 'raw-loader!./my-nice-graphic.svg'...<Samy = =><SvgProxy ="#Star" ="red"/></Samy>
In the previous snippet the svg contents are read by the webpack raw-loader into the
svgcontents variable. An internal svg element with the id "#Star" is modified to change its fill color to
Using SvgProxy to manipulate the SVG in a declarative way
In the previous example there's a child component of
In this context and Svg proxy just transfers its props to the selected SVG elements. CSS selectors are used.
<SvgProxy ="#Star" ="red"/>
Note 1: Use any valid svg attribute and it will be applied to the selected element
Note 2: Multiple elements can be manipulated at once if they match the CSS selector!
Note 3: Keep in mind that proxies transfer additional props (as is) to the underlying DOM element (not React elements) so props like
style are expected to be a string in this context.
If you need to rename the svg element ids, its recommended to do it from the editor (In Sketch, the layer names are used as the element id's ). This keeps the svg file as the 'source of truth'. Communication with the SVG designer is important so the internal SVG structure and ids are known.
The basic syntax to load and external SVG:
<Samy ="1.svg" />;
If you already bundle the file contents and don't want an additional request use :
<Samy = />;
- path: (string)the URL of the svg file (optional)
- svgXML: (string) contents of the svg file (optional)
- style: (object) style that will be forwarded to the SVG element when loaded
- onSVGReady (function): Callback called when the SVG element has been loaded.
Note: Additional properties (e.g width, viewBox) will be transferred to the DOM svg node
Used to manipulate internal SVG nodes. Must be a child of a
<SvgProxy ="#myElementId" ="#000" />;
selector attribute can target multiple elements, so this is valid:
<SvgProxy ="#rightEye,#leftEye" ="#000" />;
Note Use the token $ORIGINAL to keep the original attribute value. For example, to keep the original transform but add a translate operation:
<SvgProxy ="$ORIGINAL translate(0,40)" ="#000" />;
(Remember than in SVG transforms are applied right to left)
- selector: (string) CSS selector for the element(s)
- onElementSelected: (function(elem)) callback that receives the DOM element (or list of elements that this SvgProxy tracks), if multiple elements are being controlled by the proxy, a list is returned.
The ajax loading bits are based on: