Skip to content

Commit dac8b4e

Browse files
committed
Add react-svg-loader-cli
1 parent aa915e5 commit dac8b4e

File tree

17 files changed

+634
-223
lines changed

17 files changed

+634
-223
lines changed

README.md

Lines changed: 0 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -149,76 +149,6 @@ and with [babel-preset-env](https://github.com/babel/babel-preset-env) in `.babe
149149

150150
[branch=v0.1](https://github.com/boopathi/react-svg-loader/tree/v0.1)
151151

152-
## Install
153-
154-
```sh
155-
npm i react-svg-loader --save-dev
156-
```
157-
158-
or
159-
160-
```sh
161-
yarn add react-svg-loader --dev
162-
```
163-
164-
## Usage
165-
166-
```js
167-
// without webpack loader config
168-
import Image1 from 'react-svg-loader!./image1.svg';
169-
170-
// or if you're passing all .svg files via react-svg-loader,
171-
import Image2 from './image1.svg';
172-
173-
// and use it like any other React Component
174-
<Image1 width={50} height={50}/>
175-
<Image2 width={50} height={50}/>
176-
```
177-
178-
### Loader output
179-
180-
By default the loader outputs ES2015 code (with JSX compiled to JavaScript using babel-preset-react). You can combine it with [babel-loader](https://github.com/babel/babel-loader) + [babel-preset-env](https://github.com/babel/babel-preset-env) to compile it down to your target.
181-
182-
```js
183-
// In your webpack config
184-
{
185-
test: /\.svg$/,
186-
use: [
187-
{
188-
loader: "babel-loader"
189-
},
190-
{
191-
loader: "react-svg-loader",
192-
options: {
193-
jsx: true // true outputs JSX tags
194-
}
195-
}
196-
]
197-
}
198-
```
199-
200-
### SVGO options
201-
202-
```js
203-
{
204-
test: /\.svg$/,
205-
use: [
206-
"babel-loader",
207-
{
208-
loader: "react-svg-loader",
209-
options: {
210-
svgo: {
211-
plugins: [
212-
{ removeTitle: false }
213-
],
214-
floatPrecision: 2
215-
}
216-
}
217-
}
218-
]
219-
}
220-
```
221-
222152
## Internals
223153

224154
<p align="center">
@@ -233,140 +163,6 @@ SVG Optimize using <a href="https://github.com/svg/svgo">SVGO</a>
233163
Babel Transform with <code>preset=react</code> and <a href="src/plugin.js"><code>plugin=svgToComponent</code></a>
234164
</p>
235165

236-
### Transformations
237-
238-
Going from bottom up, the following transformations are applied and the same can be checked in the partly annotated source - [babel-plugin](src/plugin.js)
239-
240-
#### 1. Hyphenated attributes to camelCase
241-
242-
```html
243-
<svg pointer-events="none">
244-
<path stroke-width="5"/>
245-
</svg>
246-
```
247-
248-
is transformed to
249-
250-
```html
251-
<svg pointerEvents="none">
252-
<path strokeWidth="5"/>
253-
</svg>
254-
```
255-
256-
#### 2. Style attr string to object
257-
258-
React expects style attribute value to be an object. Also, Hyphenated style names are converted to camel case.
259-
260-
```html
261-
<svg style="text-align: center">
262-
<circle style="width: 10px"/>
263-
</svg>
264-
```
265-
266-
is transformed to
267-
268-
```html
269-
<svg style={{textAlign: 'center'}}>
270-
<circle style={{width: '10px'}}/>
271-
</svg>
272-
```
273-
274-
#### 3. Propagate props to root element
275-
276-
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.
277-
278-
```html
279-
<svg width="50">
280-
...
281-
</svg>
282-
```
283-
284-
is transformed to
285-
286-
```html
287-
<svg width="50" {...props}>
288-
...
289-
</svg>
290-
```
291-
292-
#### 4. class to className & class values to styles prop
293-
294-
```html
295-
<svg class="foo bar"/>
296-
```
297-
298-
is transformed to
299-
300-
```jsx
301-
<svg className={ (styles["foo"] || "foo") + " " + (styles["bar"] || "bar") }>
302-
```
303-
304-
#### 5. export React.Component
305-
306-
The loader should now export the svg component. And this is done by wrapping it in an ArrowFunctionExpression.
307-
308-
```html
309-
<svg>...</svg>
310-
```
311-
312-
is transformed to
313-
314-
```js
315-
import React from 'react';
316-
export default ({ styles = {}, ...props }) => <svg {...props}>...</svg>;
317-
```
318-
319-
### Example
320-
321-
Input SVG:
322-
323-
```html
324-
<svg class="foo" style='text-align: center; width: 100px' pointer-events="stroke">
325-
<circle cx="50" cy="50" r="25" style="text-align: center;" stroke-width="5" />
326-
</svg>
327-
```
328-
329-
Output React Component:
330-
331-
```js
332-
import React from "react";
333-
export default ({ styles = {}, ...props}) => <svg
334-
className={styles["foo"] || "foo"}
335-
style={{ textAlign: "center", width: "100px" }}
336-
pointerEvents="stroke"
337-
{...props}>
338-
<circle cx="50" cy="50" r="25" style={{textAlign: "center"}} strokeWidth="5" />
339-
</svg>;
340-
```
341-
342-
## CLI
343-
344-
The react-svg-loader comes with a cli (`svg2react`) that you can use to convert svg files to react components. Use this tool when you'd want to customize your svg component by hand. Otherwise the loader just works.
345-
346-
```sh
347-
`npm bin`/svg2react file1.svg file2.svg
348-
```
349-
350-
and the following files will be emitted
351-
352-
+ `file1.svg.react.js`
353-
+ `file2.svg.react.js`
354-
355-
in the **SAME directory** as the files
356-
357-
### CLI Options
358-
359-
+ `--jsx`: Outputs JSX code instead of compiling it to JavaScript using babel-preset-react
360-
+ `--stdout`: Outputs to STDOUT
361-
+ `--svgo <config_file>`: Supports SVGO Config YAML / JSON / JS
362-
+ `--svgo.plugins <...plugins>`: Takes in an array of plugins that need to be enabled
363-
+ `--svgo.plugins.<plugin> <true|false>`: - Enable/Disable the plugin
364-
+ `--svgo.floatPrecision $N`: Set floatPrecision to `N` for SVGO. SVGO supports 1-8.
365-
366-
```
367-
`npm bin`/svg2react file1.svg --jsx --stdout
368-
```
369-
370166
## Assumptions and Other gotchas
371167

372168
+ Root element is always `<svg>`

package.json

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-svg-loader",
3-
"version": "2.0.0-alpha.3",
3+
"version": "2.0.0",
44
"private": true,
55
"description": "Optimize svg and load it as a React Component",
66
"keywords": [
@@ -16,15 +16,6 @@
1616
},
1717
"license": "MIT",
1818
"author": "boopathi",
19-
"files": [
20-
"lib",
21-
"LICENSE",
22-
"README.md"
23-
],
24-
"main": "lib/loader.js",
25-
"bin": {
26-
"svg2react": "./lib/cli.js"
27-
},
2819
"repository": {
2920
"type": "git",
3021
"url": "git+https://github.com/boopathi/react-svg-loader.git"
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# babel-plugin-react-svg
2+
3+
A plugin that converts svg to a react component
4+
5+
## Install
6+
7+
```sh
8+
npm i babel-plugin-react-svg --save-dev
9+
10+
# or with yarn
11+
12+
yarn add babel-plugin-react-svg --dev
13+
```
14+
15+
## Example
16+
17+
Input SVG:
18+
19+
```html
20+
<svg class="foo" style='text-align: center; width: 100px' pointer-events="stroke">
21+
<circle cx="50" cy="50" r="25" style="text-align: center;" stroke-width="5" />
22+
</svg>
23+
```
24+
25+
Output React Component:
26+
27+
```js
28+
import React from "react";
29+
export default ({ styles = {}, ...props}) => <svg
30+
className={styles["foo"] || "foo"}
31+
style={{ textAlign: "center", width: "100px" }}
32+
pointerEvents="stroke"
33+
{...props}>
34+
<circle cx="50" cy="50" r="25" style={{textAlign: "center"}} strokeWidth="5" />
35+
</svg>;
36+
```
37+
38+
## Transformations
39+
40+
Going from bottom up, the following transformations are applied and the same can be checked in the partly annotated source - [babel-plugin](src/plugin.js)
41+
42+
#### 1. Hyphenated attributes to camelCase
43+
44+
```html
45+
<svg pointer-events="none">
46+
<path stroke-width="5"/>
47+
</svg>
48+
```
49+
50+
is transformed to
51+
52+
```html
53+
<svg pointerEvents="none">
54+
<path strokeWidth="5"/>
55+
</svg>
56+
```
57+
58+
#### 2. Style attr string to object
59+
60+
React expects style attribute value to be an object. Also, Hyphenated style names are converted to camel case.
61+
62+
```html
63+
<svg style="text-align: center">
64+
<circle style="width: 10px"/>
65+
</svg>
66+
```
67+
68+
is transformed to
69+
70+
```html
71+
<svg style={{textAlign: 'center'}}>
72+
<circle style={{width: '10px'}}/>
73+
</svg>
74+
```
75+
76+
#### 3. Propagate props to root element
77+
78+
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.
79+
80+
```html
81+
<svg width="50">
82+
...
83+
</svg>
84+
```
85+
86+
is transformed to
87+
88+
```html
89+
<svg width="50" {...props}>
90+
...
91+
</svg>
92+
```
93+
94+
#### 4. class to className & class values to styles prop
95+
96+
```html
97+
<svg class="foo bar"/>
98+
```
99+
100+
is transformed to
101+
102+
```jsx
103+
<svg className={ (styles["foo"] || "foo") + " " + (styles["bar"] || "bar") }>
104+
```
105+
106+
#### 5. export React.Component
107+
108+
The loader should now export the svg component. And this is done by wrapping it in an ArrowFunctionExpression.
109+
110+
```html
111+
<svg>...</svg>
112+
```
113+
114+
is transformed to
115+
116+
```js
117+
import React from 'react';
118+
export default ({ styles = {}, ...props }) => <svg {...props}>...</svg>;
119+
```
120+
121+
## LICENSE
122+
123+
[MIT](https://github.com/boopathi/react-svg-loader/blob/master/LICENSE)

packages/babel-plugin-react-svg/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"webpack",
1212
"webpack-loader"
1313
],
14-
"homepage": "https://github.com/boopathi/react-svg-loader#readme",
14+
"homepage": "https://github.com/boopathi/react-svg-loader/packages/babel-plugin-react-svg",
1515
"bugs": {
1616
"url": "https://github.com/boopathi/react-svg-loader/issues"
1717
},

0 commit comments

Comments
 (0)