Skip to content

Commit

Permalink
feat: Add SVG sprite support (#319)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanquirino authored and colebemis committed Feb 21, 2018
1 parent b3655c4 commit 3422f0a
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 0 deletions.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ npm install feather-icons
* [Usage](#usage)
* [Client-side](#client-side)
* [Node](#node)
* [SVG Sprite](#svg-sprite)
* [API Reference](#api-reference)
* [`feather.icons`](#feathericons)
* [`feather.icons[name].toSvg()`](#feathericonsnametosvgattrs)
Expand Down Expand Up @@ -166,6 +167,42 @@ feather.icons.x.toSvg({ class: 'foo bar', 'stroke-width': 1, color: 'red' })

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

### SVG Sprite
A SVG Sprite is also provided, which can be used as following:
```html
<svg class="feather feather-[iconName]"
width="24"
height="24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<use xlink:href="feather-sprite.svg#[iconName]"/>
</svg>
```
Where `iconName` is the name of the icon you want to display.

Same result but using a CSS class:
```css
.feather {
width: 24px;
height: 24px;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
fill: none;
}
```
```html
<svg class="feather feather-[iconName]">
<use xlink:href="feather-sprite.svg#[iconName]"/>
</svg>
```
Prefer using CSS classes to keep things organized.

## API Reference

### `feather.icons`
Expand Down
14 changes: 14 additions & 0 deletions bin/__tests__/__snapshots__/build-sprite-string.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`builds sprite correctly 1`] = `
"<svg xmlns=\\"http://www.w3.org/2000/svg\\">
<defs>
<symbol id=\\"icon1\\" viewBox=\\"0 0 24 24\\">
<line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\"></line><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\"></line>
</symbol>
<symbol id=\\"icon2\\" viewBox=\\"0 0 24 24\\">
<circle cx=\\"12\\" cy=\\"12\\" r=\\"11\\"></circle>
</symbol>
</defs>
</svg>"
`;
12 changes: 12 additions & 0 deletions bin/__tests__/build-sprite-string.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-env jest */
import buildSpriteString from '../build-sprite-string';

const icons = {
icon1:
'<line x1="23" y1="1" x2="1" y2="23"></line><line x1="1" y1="1" x2="23" y2="23"></line>',
icon2: '<circle cx="12" cy="12" r="11"></circle>',
};

test('builds sprite correctly', () => {
expect(buildSpriteString(icons)).toMatchSnapshot();
});
30 changes: 30 additions & 0 deletions bin/build-sprite-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import defaultAttrs from '../src/default-attrs.json';

const svgStartTag = `<svg xmlns="${defaultAttrs.xmlns}">\n<defs>\n`;
const svgEndTag = '</defs>\n</svg>';

/**
* Renders the inner sprites as SVG Symbols
* @param {object} icons the icons object
* @returns {string} the rendered string with SVG symbols
*/
function buildSpriteString(icons) {
const symbols = Object.keys(icons)
.map(icon => toSvgSymbol(icon, icons[icon]))
.join('');

return svgStartTag + symbols + svgEndTag;
}

/**
* Renders a SVG symbol tag
* @param {string} name The name of the icon
* @param {string} contents The contents of the icon
* @returns {string} the rendered SVG symbol
*/
function toSvgSymbol(name, contents) {
return `<symbol id="${name}" viewBox="${defaultAttrs.viewBox}">
${contents}\n</symbol>\n`;
}

export default buildSpriteString;
14 changes: 14 additions & 0 deletions bin/build-sprite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import fs from 'fs';
import path from 'path';
import icons from '../dist/icons.json';
import buildSpriteString from './build-sprite-string';

const sprite = buildSpriteString(icons);

const OUT_FILE = path.resolve(__dirname, '../dist/feather-sprite.svg');

console.log(`Building ${OUT_FILE}`); // eslint-disable-line no-console

fs.writeFile(OUT_FILE, sprite, err => {
if (err) throw err;
});
1 change: 1 addition & 0 deletions bin/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
./node_modules/.bin/rimraf dist
mkdir dist
./node_modules/.bin/babel-node bin/build-icons-json.js
./node_modules/.bin/babel-node bin/build-sprite.js

./node_modules/.bin/rimraf dist/icons
mkdir dist/icons
Expand Down

0 comments on commit 3422f0a

Please sign in to comment.