Skip to content

Commit 3422f0a

Browse files
ivanquirinocolebemis
authored andcommitted
feat: Add SVG sprite support (feathericons#319)
1 parent b3655c4 commit 3422f0a

6 files changed

Lines changed: 108 additions & 0 deletions

File tree

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ npm install feather-icons
2727
* [Usage](#usage)
2828
* [Client-side](#client-side)
2929
* [Node](#node)
30+
* [SVG Sprite](#svg-sprite)
3031
* [API Reference](#api-reference)
3132
* [`feather.icons`](#feathericons)
3233
* [`feather.icons[name].toSvg()`](#feathericonsnametosvgattrs)
@@ -166,6 +167,42 @@ feather.icons.x.toSvg({ class: 'foo bar', 'stroke-width': 1, color: 'red' })
166167

167168
See the [API Reference](#api-reference) for more information about the available properties and methods of the `feather` object.
168169

170+
### SVG Sprite
171+
A SVG Sprite is also provided, which can be used as following:
172+
```html
173+
<svg class="feather feather-[iconName]"
174+
width="24"
175+
height="24"
176+
fill="none"
177+
stroke="currentColor"
178+
stroke-width="2"
179+
stroke-linecap="round"
180+
stroke-linejoin="round"
181+
>
182+
<use xlink:href="feather-sprite.svg#[iconName]"/>
183+
</svg>
184+
```
185+
Where `iconName` is the name of the icon you want to display.
186+
187+
Same result but using a CSS class:
188+
```css
189+
.feather {
190+
width: 24px;
191+
height: 24px;
192+
stroke: currentColor;
193+
stroke-width: 2;
194+
stroke-linecap: round;
195+
stroke-linejoin: round;
196+
fill: none;
197+
}
198+
```
199+
```html
200+
<svg class="feather feather-[iconName]">
201+
<use xlink:href="feather-sprite.svg#[iconName]"/>
202+
</svg>
203+
```
204+
Prefer using CSS classes to keep things organized.
205+
169206
## API Reference
170207

171208
### `feather.icons`
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`builds sprite correctly 1`] = `
4+
"<svg xmlns=\\"http://www.w3.org/2000/svg\\">
5+
<defs>
6+
<symbol id=\\"icon1\\" viewBox=\\"0 0 24 24\\">
7+
<line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\"></line><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\"></line>
8+
</symbol>
9+
<symbol id=\\"icon2\\" viewBox=\\"0 0 24 24\\">
10+
<circle cx=\\"12\\" cy=\\"12\\" r=\\"11\\"></circle>
11+
</symbol>
12+
</defs>
13+
</svg>"
14+
`;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* eslint-env jest */
2+
import buildSpriteString from '../build-sprite-string';
3+
4+
const icons = {
5+
icon1:
6+
'<line x1="23" y1="1" x2="1" y2="23"></line><line x1="1" y1="1" x2="23" y2="23"></line>',
7+
icon2: '<circle cx="12" cy="12" r="11"></circle>',
8+
};
9+
10+
test('builds sprite correctly', () => {
11+
expect(buildSpriteString(icons)).toMatchSnapshot();
12+
});

bin/build-sprite-string.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import defaultAttrs from '../src/default-attrs.json';
2+
3+
const svgStartTag = `<svg xmlns="${defaultAttrs.xmlns}">\n<defs>\n`;
4+
const svgEndTag = '</defs>\n</svg>';
5+
6+
/**
7+
* Renders the inner sprites as SVG Symbols
8+
* @param {object} icons the icons object
9+
* @returns {string} the rendered string with SVG symbols
10+
*/
11+
function buildSpriteString(icons) {
12+
const symbols = Object.keys(icons)
13+
.map(icon => toSvgSymbol(icon, icons[icon]))
14+
.join('');
15+
16+
return svgStartTag + symbols + svgEndTag;
17+
}
18+
19+
/**
20+
* Renders a SVG symbol tag
21+
* @param {string} name The name of the icon
22+
* @param {string} contents The contents of the icon
23+
* @returns {string} the rendered SVG symbol
24+
*/
25+
function toSvgSymbol(name, contents) {
26+
return `<symbol id="${name}" viewBox="${defaultAttrs.viewBox}">
27+
${contents}\n</symbol>\n`;
28+
}
29+
30+
export default buildSpriteString;

bin/build-sprite.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
import icons from '../dist/icons.json';
4+
import buildSpriteString from './build-sprite-string';
5+
6+
const sprite = buildSpriteString(icons);
7+
8+
const OUT_FILE = path.resolve(__dirname, '../dist/feather-sprite.svg');
9+
10+
console.log(`Building ${OUT_FILE}`); // eslint-disable-line no-console
11+
12+
fs.writeFile(OUT_FILE, sprite, err => {
13+
if (err) throw err;
14+
});

bin/build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
./node_modules/.bin/rimraf dist
66
mkdir dist
77
./node_modules/.bin/babel-node bin/build-icons-json.js
8+
./node_modules/.bin/babel-node bin/build-sprite.js
89

910
./node_modules/.bin/rimraf dist/icons
1011
mkdir dist/icons

0 commit comments

Comments
 (0)