mit

Background

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 issues:

  • 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 inside the JSX creates pollutes the component markup and makes it harder to understand.

The goal of this library is to overcome those issues, making it easier to work on SVG based components by:

  • Keeping the .svg file independent (so it becomes trivial to update )
  • Provide a way to declare SVG manipulations the React way.
  • Only focus on the SVG elements we want to modify.

Usage

Import the SvgLoader and SvgProxy elements

import { SvgLoader, SvgProxy } from 'react-svgmt';

Loading the SVG file

There are two options for loading the SVG contents.

  1. Loading from URL.
  2. Loading from string.

Loading the SVG from a URL:

This option is useful if you want to load the asset from a remote site. An additional network request is sent to fetch the asset.

Important: Only load assets you trust.

<SvgLoader path="svg public url here">
  <SvgProxy selector="#Star" stroke={this.state.strokeColor} />
</SvgLoader>

In the previous code, the stroke attribute is set to the value of the strokeColor state field.

Loading the SVG contents from a string.

If you already have the SVG file contents loaded, use the svgXML attribute instead of path.

When creating components with bundled SVG files, this is the preferred approach as it avoids the additional network request:

...
<SvgLoader svgXML={svgcontents}>
  <SvgProxy selector="#Star" fill="red"/>
</SvgLoader>

We just updated the fill attribute of the #Start element.

Notes on SvgLoader:

  • SvgLoader renders the root <svg/> node, props used will modify it.

Updating element attributes with SvgProxy

The cool think about SvgProxy is that it lets you update the SVG in a declarative way. Just add a SvgProxy child element to the SvgLoader.

  <SvgProxy selector="#Star" fill="red"/>

Very cool. We only care about the elements we’ll manipulate, so this keeps our JSX clean.

Updating text content

If you pass any content to the SvgProxy, it will be used as the svg element text content. This is useful to update text elements like tspan or text

  <SvgProxy selector="tspan"> Hello World </SvgProxy>

Important notes on SvgProxy:

  • SvgProxy elements can only be declared inside SvgLoader elements
  • Any property set in the SvgProxy element will be passed to the svg child node(s).
  • Multiple elements can be updated if the selector prop matches them.
  • SvgProxy elements transfer their props (as is) to the underlying DOM element (not React elements) so props like style are expected to be a string in this context. (This only applies to SvgProxy elements, not to parent SvgLoader which behave like normal React components)

Api

<SvgLoader/>

Name Type Description
path (string) the URL of the svg file (optional)
svgXML (string) contents of the svg file (optional)
onSVGReady function(svgnode) function called when the SVG element has been loaded. The svg DOM node is passed as parameter

<SvgProxy/>

Name Type Description
selector string CSS selector for the element(s)
onElementSelected function ( svgnode ) callback that receives the SVG DOM element (or list if more than one) matched by the selector.
Useful to get the reference to the elements and manually update them.    

Notes:

  • Updating namespaced attributes like image xlink:href

This is supported by using the following syntax:

<SvgProxy selector="#myImage" xlink_href="some url"/>
  • SvgProxy children:

The only supported child type is string and is used to update text nodes like tspan. No other uses are currently supported.

Animation shortcuts

react-svgmt includes components to create animation based on springs. These are wrappers over the react-motion library.

<TransformMotion/>

Use this component to animate the transform attribute. The original transform value is preserved, this is convenient to add animation without losing the element original position.

Example: Translating and rotating

Props:

  • start: Object with the shape of:
{
    x: number, //translate x value
    y: number, //translate y value
    angle: number, //rotate angle in degrees
    rotateX: number, //center of rotation x
    rotateY: number //center of rotation y
}

<AttributeMotion/>

Use this component to animate any svg attribute. Props:

  • start: initial state
  • target: target values
  • formatValue (optional): function that returns the final string value, used if you need a different final value being passed to the svg element.

Example: Animating the opacity.