jhamlet/svg-react-loader(opens in a new tab)
Language: JavaScript
Webpack SVG to React Component Loader
- stars
- 559
- watchers
- 1
- forks
- 81
- open issues
- 54
- Last updated
- 06/11/2023
Language: JavaScript
Webpack SVG to React Component Loader
A Webpack Loader to turn SVGs into React Components
A webpack loader allowing for inline usage of a SVG as a React component, or for composing individual SVGs into larger ones.
The latest version has been refactored to allow for receiving an SVG/XML string
or an JSON object-tree representing an SVG. This allows for
other loaders before svg-react to alter/update/remove nodes before reaching
svg-react.
In addition, the new filters API allows for additional ways to
modify the generated SVG Component. This allows svg-react to also be used as a
pre-loader (with filters and raw=true params) for modifying SVGs before they
are acted on by the loader version of svg-react.
As of version 0.4.0,
svg-react-loaderno longer requiresbabelto transpile the generated code. Everything is returned as an ES5-7 compatible module, and the component is just a function. With that, it only works with React@>=0.14
% npm install --save-dev svg-react-loader
ES6+ (Assuming a babel-loader is used on /\.jsx?$/ files):
import React, { Component } from 'react'; import Icon from 'svg-react-loader?name=Icon!../svg/my-icon.svg'; export default class MyIcon extends Component { render () { return <Icon className='normal' />; } };
ES5
var React = require('react'); var Icon = require('svg-react-loader?name=Icon!../svg/my-icon.svg'); module.exports = React.createClass({ render () { return React.createElement(Icon, { className: 'normal' }); } });
Query params can be used on the loader path, or on the resource's path. Those on the resource will override those given for the loader.
name: displayName to use for the compiled component. Defaults to using the
resource's file name, capitalized and camelCased. ex. "?name=MyIcon"
tag: Override the root-level tag name.
props: Attributes to apply to the root-level tag. If a certain attribute is
already assigned to the tag, the value here will override that.
attrs: Alias for props
filters: If given on the query string, it is a list of module names, or
filepaths, to load as filter functions. If given in the webpack
config as a svgReactLoader.filters, or as query.filters for the loader
configuration object, it is an array of functions.
classIdPrefix: A string to prefix all class or id selectors in found style
blocks, or within className properties, with. If indicated without a string,
the file's basename will be used as a prefix.
raw: If set to true will output the parsed object tree repesenting the SVG
as a JSON string. Otherwise, returns a string of JavaScript that represents
the component's module.
propsMap: If given on the query string, it is an array of colon separated
propname:translatedname pairs. If given in the webpack configuration as
svgReactLoader.propsMap, or in an object query for the loader configuration,
is a simple object of propname: 'translatedname'
xmlnsTest: A regular expression used to remove non-supported xmlns
attributes. Default is /^xmlns(Xlink)?$/
titleCaseDelim: A regular expression used to generate component's name. It
would be ignore if name was set.
Default is /[._-]/
// webpack configuration module: { loaders: [ { test: /\.svg$/, exclude: /node_modules/, loader: 'svg-react-loader', query: { classIdPrefix: '[name]-[hash:8]__', filters: [ function (value) { // ... this.update(newvalue); } ], propsMap: { fillRule: 'fill-rule', foo: 'bar' }, xmlnsTest: /^xmlns.*$/ } } ] } // Resource paths import MyIcon from 'svg-react-loader?name=MyIcon!../svg/icon.svg'; import MyIcon from 'svg-react-loader?tag=symbol!../svg/icon.svg'; import MyIcon from 'svg-react-loader?tag=symbol&props[]=id:my-icon?../svg/icon.svg'; import MyIcon from 'svg-react-loader?filters[]=./my-filter.js!../svg/icon.svg';
// webpack configuration module: { loaders: [ { test: /\.svg$/, exclude: /node_modules/, use: { loader: 'svg-react-loader', options: { tag: 'symbol', attrs: { title: 'example', }, name: 'MyIcon', }, }, } ] } // Resource paths import MyIcon from '../svg/icon.svg';
Internally, svg-react-loader converts the given SVG/XML into an object tree
that looks something like:
{ "tagname": "svg", "props": { "xmlns": "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", "viewBox": "0 0 16 16", "enable-background": "new 0 0 16 16", "xml:space": "preserve" }, "children": [ { "tagname": "rect", "props": { "x": "0", "y": "0", "width": "16", "height": "16", "fill": "#fff" } }, { "tagname": "text", "children": ["Foobar"] } ] }
It then uses a variety of filters to modify the tree to conform to
how React expects to see props, styles, etc...
If svg-react-loader receives a JSON string instead of string of SVG/XML, it
expects to receive it in the above format (i.e.: objects with properties
'tagname', 'props', and 'children'). Children is always an array (unless empty),
and children can be objects with the mentioned props, or a plain string (for
text nodes).
A filter is just a function that accepts one value, and it has the same this
context as the traverse API.
svg-react-loader is really just a series of filters applied to a parsed
SVG/XML, or JSON, string and then regenerated as a string to form a React
functional component.
Review lib/sanitize/filters for some examples.