Hotfix Lucide npm package, fix security issues (#84)
* adjust npmignore
* 📦 Fix security issues
* update font workflow
* identation
* update, package.json
* Add description
* Add shields
This commit is contained in:
+10
-25
@@ -1,63 +1,48 @@
|
|||||||
name: Build Featherity
|
name: Build Lucide
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
jobs:
|
jobs:
|
||||||
Build:
|
Build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- name: Clone 'Lucide'
|
||||||
|
|
||||||
- name: Clone 'Featherity'
|
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
|
||||||
- name: Install FontForge
|
- name: Install FontForge
|
||||||
run: sudo apt-get install zlib1g-dev fontforge woff2
|
run: sudo apt-get install zlib1g-dev fontforge woff2
|
||||||
|
|
||||||
|
|
||||||
- name: Clone sfnt2woff-zopfli repo
|
- name: Clone sfnt2woff-zopfli repo
|
||||||
run: git clone https://github.com/bramstein/sfnt2woff-zopfli.git sfnt2woff-zopfli
|
run: git clone https://github.com/bramstein/sfnt2woff-zopfli.git sfnt2woff-zopfli
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- name: Install and move sfnt2woff-zopfli
|
- name: Install and move sfnt2woff-zopfli
|
||||||
run: |
|
run: |
|
||||||
cd sfnt2woff-zopfli
|
cd sfnt2woff-zopfli
|
||||||
make
|
make
|
||||||
sudo mv sfnt2woff-zopfli /usr/local/bin/sfnt2woff
|
sudo mv sfnt2woff-zopfli /usr/local/bin/sfnt2woff
|
||||||
|
|
||||||
|
|
||||||
- name: Clone woff2
|
- name: Clone woff2
|
||||||
run: git clone --recursive https://github.com/google/woff2.git
|
run: git clone --recursive https://github.com/google/woff2.git
|
||||||
|
|
||||||
- name: Install woff2
|
- name: Install woff2
|
||||||
run: |
|
run: |
|
||||||
cd woff2
|
cd woff2
|
||||||
sudo make clean all
|
sudo make clean all
|
||||||
sudo mv woff2_compress /usr/local/bin/ && sudo mv woff2_decompress /usr/local/bin/
|
sudo mv woff2_compress /usr/local/bin/ && sudo mv woff2_decompress /usr/local/bin/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- name: Install Font Custom dependency
|
- name: Install Font Custom dependency
|
||||||
run: sudo gem install fontcustom
|
run: sudo gem install fontcustom
|
||||||
|
|
||||||
- name: Build 'Featherity'
|
- name: Build 'Lucide'
|
||||||
run: echo "Building Featherity font" && fontcustom compile ./icons -h -n Featherity -o build -F
|
run: echo "Building Featherity font" && fontcustom compile ./icons -h -n Featherity -o build -F
|
||||||
|
|
||||||
|
- name: Zip 'Lucide'
|
||||||
- name: Zip 'Featherity'
|
|
||||||
run: zip -r Featherity.zip build
|
run: zip -r Featherity.zip build
|
||||||
|
|
||||||
|
|
||||||
- name: 'Upload to Artifacts'
|
- name: 'Upload to Artifacts'
|
||||||
uses: actions/upload-artifact@v1.0.0
|
uses: actions/upload-artifact@v1.0.0
|
||||||
with:
|
with:
|
||||||
name: Featherity
|
name: Lucide
|
||||||
path: build
|
path: build
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -1,4 +1,6 @@
|
|||||||
.github
|
.github
|
||||||
packages
|
packages
|
||||||
stats
|
stats
|
||||||
build
|
node_modules
|
||||||
|
tests
|
||||||
|
scripts
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# Lucide
|
# Lucide
|
||||||
|
|
||||||
|

|
||||||
|
[](https://www.npmjs.com/package/lucide)
|
||||||
[](https://discord.gg/EH6nSts)
|
[](https://discord.gg/EH6nSts)
|
||||||
|
|
||||||
## What is Lucide?
|
## What is Lucide?
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 329 B |
+4
-3
@@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "lucide",
|
"name": "lucide",
|
||||||
|
"description": "Lucide is a community-run fork of Feather Icons, open for anyone to contribute icons.",
|
||||||
|
"version": "0.1.1",
|
||||||
|
"license": "ISC",
|
||||||
"amdName": "lucide",
|
"amdName": "lucide",
|
||||||
"homepage": "https://featherity.netlify.app",
|
"homepage": "https://featherity.netlify.app",
|
||||||
|
"url": "https://github.com/owner/project/issues",
|
||||||
"repository": "github:lucide-icons/lucide",
|
"repository": "github:lucide-icons/lucide",
|
||||||
"url" : "https://github.com/owner/project/issues",
|
|
||||||
"license": "ISC",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"source": "build/lucide.js",
|
"source": "build/lucide.js",
|
||||||
"main": "dist/cjs/lucide.js",
|
"main": "dist/cjs/lucide.js",
|
||||||
"main:umd": "dist/umd/lucide.js",
|
"main:umd": "dist/umd/lucide.js",
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
[
|
|
||||||
"env",
|
|
||||||
{
|
|
||||||
"targets": {
|
|
||||||
"browsers": ["last 2 versions"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stage-2"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
dist
|
|
||||||
coverage
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["airbnb-base", "prettier"],
|
|
||||||
"plugins": ["import", "prettier"],
|
|
||||||
"rules": {
|
|
||||||
"no-console": ["error", { "allow": ["warn", "error"] }],
|
|
||||||
"no-param-reassign": "off",
|
|
||||||
"no-shadow": "off",
|
|
||||||
"no-use-before-define": "off",
|
|
||||||
"prettier/prettier": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "all"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`builds object correctly 1`] = `
|
|
||||||
Object {
|
|
||||||
"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>",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// 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>"`;
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`processes SVG correctly 1`] = `
|
|
||||||
"<svg
|
|
||||||
xmlns=\\"http://www.w3.org/2000/svg\\"
|
|
||||||
width=\\"24\\"
|
|
||||||
height=\\"24\\"
|
|
||||||
viewBox=\\"0 0 24 24\\"
|
|
||||||
fill=\\"none\\"
|
|
||||||
stroke=\\"currentColor\\"
|
|
||||||
stroke-width=\\"2\\"
|
|
||||||
stroke-linecap=\\"round\\"
|
|
||||||
stroke-linejoin=\\"round\\"
|
|
||||||
>
|
|
||||||
<line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" />
|
|
||||||
<line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" />
|
|
||||||
</svg>
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`rejects when passed unparsable SVG string 1`] = `
|
|
||||||
[Error: Error in parsing SVG: Unclosed root tag
|
|
||||||
Line: 0
|
|
||||||
Column: 10
|
|
||||||
Char: ]
|
|
||||||
`;
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import buildIconsObject from '../build-icons-object';
|
|
||||||
|
|
||||||
const SVG_FILES = {
|
|
||||||
'icon1.svg':
|
|
||||||
'<svg\n xmlns="http://www.w3.org/2000/svg"\n width="24"\n height="24"\n viewBox="0 0 24 24"\n>\n <line x1="23" y1="1" x2="1" y2="23" />\n <line x1="1" y1="1" x2="23" y2="23" />\n</svg>',
|
|
||||||
'icon2.svg':
|
|
||||||
'<svg\n xmlns="http://www.w3.org/2000/svg"\n width="24"\n height="24"\n viewBox="0 0 24 24"\n>\n <circle cx="12" cy="12" r="11" />\n</svg>',
|
|
||||||
};
|
|
||||||
|
|
||||||
function getSvg(svgFile) {
|
|
||||||
return SVG_FILES[svgFile];
|
|
||||||
}
|
|
||||||
|
|
||||||
test('builds object correctly', () => {
|
|
||||||
expect(buildIconsObject(Object.keys(SVG_FILES), getSvg)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
/* 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();
|
|
||||||
});
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import processSvg from '../process-svg';
|
|
||||||
|
|
||||||
test('processes SVG correctly', () => {
|
|
||||||
const SVG =
|
|
||||||
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>Title</title><line x1="23" y1="1" x2="1" y2="23" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="1" y1="1" x2="23" y2="23" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>';
|
|
||||||
|
|
||||||
expect(processSvg(SVG)).resolves.toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('rejects when passed unparsable SVG string', () => {
|
|
||||||
const UNPARSABLE_SVG = '<svg></svg';
|
|
||||||
|
|
||||||
expect(processSvg(UNPARSABLE_SVG)).rejects.toMatchSnapshot();
|
|
||||||
});
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
import buildIconsObject from './build-icons-object';
|
|
||||||
|
|
||||||
const IN_DIR = path.resolve(__dirname, '../icons');
|
|
||||||
const OUT_FILE = path.resolve(__dirname, '../dist/icons.json');
|
|
||||||
|
|
||||||
console.log(`Building ${OUT_FILE}...`);
|
|
||||||
|
|
||||||
const svgFiles = fs
|
|
||||||
.readdirSync(IN_DIR)
|
|
||||||
.filter(file => path.extname(file) === '.svg');
|
|
||||||
|
|
||||||
const getSvg = svgFile => fs.readFileSync(path.join(IN_DIR, svgFile));
|
|
||||||
|
|
||||||
const icons = buildIconsObject(svgFiles, getSvg);
|
|
||||||
|
|
||||||
fs.writeFileSync(OUT_FILE, JSON.stringify(icons));
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import path from 'path';
|
|
||||||
import cheerio from 'cheerio';
|
|
||||||
import { minify } from 'html-minifier';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build an object in the format: `{ <name>: <contents> }`.
|
|
||||||
* @param {string[]} svgFiles - A list of filenames.
|
|
||||||
* @param {Function} getSvg - A function that returns the contents of an SVG file given a filename.
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
function buildIconsObject(svgFiles, getSvg) {
|
|
||||||
return svgFiles
|
|
||||||
.map(svgFile => {
|
|
||||||
const name = path.basename(svgFile, '.svg');
|
|
||||||
const svg = getSvg(svgFile);
|
|
||||||
const contents = getSvgContents(svg);
|
|
||||||
return { name, contents };
|
|
||||||
})
|
|
||||||
.reduce((icons, icon) => {
|
|
||||||
icons[icon.name] = icon.contents;
|
|
||||||
return icons;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get contents between opening and closing `<svg>` tags.
|
|
||||||
* @param {string} svg
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function getSvgContents(svg) {
|
|
||||||
const $ = cheerio.load(svg);
|
|
||||||
return minify($('svg').html(), { collapseWhitespace: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
export default buildIconsObject;
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import DEFAULT_ATTRS from '../src/default-attrs.json';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build an SVG sprite string containing SVG symbols.
|
|
||||||
* @param {Object} icons
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function buildSpriteString(icons) {
|
|
||||||
const symbols = Object.keys(icons)
|
|
||||||
.map(icon => toSvgSymbol(icon, icons[icon]))
|
|
||||||
.join('');
|
|
||||||
|
|
||||||
return `<svg xmlns="${DEFAULT_ATTRS.xmlns}"><defs>${symbols}</defs></svg>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an SVG symbol string.
|
|
||||||
* @param {string} name - Icon name
|
|
||||||
* @param {string} contents - SVG contents
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function toSvgSymbol(name, contents) {
|
|
||||||
return `<symbol id="${name}" viewBox="${DEFAULT_ATTRS.viewBox}">${
|
|
||||||
contents
|
|
||||||
}</symbol>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default buildSpriteString;
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import icons from '../dist/icons.json';
|
|
||||||
import buildSpriteString from './build-sprite-string';
|
|
||||||
|
|
||||||
const OUT_FILE = path.resolve(__dirname, '../dist/feather-sprite.svg');
|
|
||||||
|
|
||||||
console.log(`Building ${OUT_FILE}...`);
|
|
||||||
|
|
||||||
fs.writeFileSync(OUT_FILE, buildSpriteString(icons));
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import icons from '../src/icons';
|
|
||||||
|
|
||||||
const OUT_DIR = path.resolve(__dirname, '../dist/icons');
|
|
||||||
|
|
||||||
console.log(`Building SVGs in ${OUT_DIR}...`);
|
|
||||||
|
|
||||||
Object.keys(icons).forEach(name => {
|
|
||||||
const svg = icons[name].toSvg();
|
|
||||||
|
|
||||||
fs.writeFileSync(path.join(OUT_DIR, `${name}.svg`), svg);
|
|
||||||
});
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Process SVG files
|
|
||||||
npx babel-node bin/process-svgs.js
|
|
||||||
|
|
||||||
# Create dist directory
|
|
||||||
npx rimraf dist
|
|
||||||
mkdir dist
|
|
||||||
|
|
||||||
# Build icons.json
|
|
||||||
npx babel-node bin/build-icons-json.js
|
|
||||||
|
|
||||||
# Build SVG sprite
|
|
||||||
npx babel-node bin/build-sprite.js
|
|
||||||
|
|
||||||
# Create dist/icons directory
|
|
||||||
npx rimraf dist/icons
|
|
||||||
mkdir dist/icons
|
|
||||||
|
|
||||||
# Build SVG icons
|
|
||||||
npx babel-node bin/build-svgs.js
|
|
||||||
|
|
||||||
# Build JavaScript library
|
|
||||||
npx webpack --output-filename feather.js --mode development
|
|
||||||
npx webpack --output-filename feather.min.js --mode production
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
import Svgo from 'svgo';
|
|
||||||
import cheerio from 'cheerio';
|
|
||||||
import { format } from 'prettier';
|
|
||||||
|
|
||||||
import DEFAULT_ATTRS from '../src/default-attrs.json';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process SVG string.
|
|
||||||
* @param {string} svg - An SVG string.
|
|
||||||
* @param {Promise<string>}
|
|
||||||
*/
|
|
||||||
function processSvg(svg) {
|
|
||||||
return (
|
|
||||||
optimize(svg)
|
|
||||||
.then(setAttrs)
|
|
||||||
.then(format)
|
|
||||||
// remove semicolon inserted by prettier
|
|
||||||
// because prettier thinks it's formatting JSX not HTML
|
|
||||||
.then(svg => svg.replace(/;/g, ''))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optimize SVG with `svgo`.
|
|
||||||
* @param {string} svg - An SVG string.
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
function optimize(svg) {
|
|
||||||
const svgo = new Svgo({
|
|
||||||
plugins: [
|
|
||||||
{ convertShapeToPath: false },
|
|
||||||
{ mergePaths: false },
|
|
||||||
{ removeAttrs: { attrs: '(fill|stroke.*)' } },
|
|
||||||
{ removeTitle: true },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Promise(resolve => {
|
|
||||||
svgo.optimize(svg, ({ data }) => resolve(data));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set default attibutes on SVG.
|
|
||||||
* @param {string} svg - An SVG string.
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function setAttrs(svg) {
|
|
||||||
const $ = cheerio.load(svg);
|
|
||||||
|
|
||||||
Object.keys(DEFAULT_ATTRS).forEach(key =>
|
|
||||||
$('svg').attr(key, DEFAULT_ATTRS[key]),
|
|
||||||
);
|
|
||||||
|
|
||||||
return $('body').html();
|
|
||||||
}
|
|
||||||
|
|
||||||
export default processSvg;
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
import processSvg from './process-svg';
|
|
||||||
|
|
||||||
const IN_DIR = path.resolve(__dirname, '../icons');
|
|
||||||
|
|
||||||
console.log(`Processing SVGs in ${IN_DIR}...`);
|
|
||||||
|
|
||||||
fs
|
|
||||||
.readdirSync(IN_DIR)
|
|
||||||
.filter(file => path.extname(file) === '.svg')
|
|
||||||
.forEach(svgFile => {
|
|
||||||
const svg = fs.readFileSync(path.join(IN_DIR, svgFile));
|
|
||||||
processSvg(svg).then(svg =>
|
|
||||||
fs.writeFileSync(path.join(IN_DIR, svgFile), svg),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
import algolia from 'algoliasearch';
|
|
||||||
import icons from '../dist/icons.json';
|
|
||||||
import tags from '../src/tags.json';
|
|
||||||
|
|
||||||
const ALGOLIA_APP_ID = '5EEOG744D0';
|
|
||||||
|
|
||||||
if (
|
|
||||||
process.env.TRAVIS_PULL_REQUEST === 'false' &&
|
|
||||||
process.env.TRAVIS_BRANCH === 'master'
|
|
||||||
) {
|
|
||||||
syncAlgolia();
|
|
||||||
} else {
|
|
||||||
console.log('Skipped Algolia sync.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncAlgolia() {
|
|
||||||
// ALGOLIA_ADMIN_KEY must be added as an environment variable in Travis CI
|
|
||||||
const client = algolia(ALGOLIA_APP_ID, process.env.ALGOLIA_ADMIN_KEY);
|
|
||||||
|
|
||||||
console.log('Initializing target and temporary indexes...');
|
|
||||||
const index = client.initIndex('icons');
|
|
||||||
const indexTmp = client.initIndex('icons_tmp');
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
"Copying target index's settings, synonyms and rules into temporary index...",
|
|
||||||
);
|
|
||||||
scopedCopyIndex(client, index.indexName, indexTmp.indexName)
|
|
||||||
.then(() => {
|
|
||||||
const objects = Object.keys(icons).map(name => ({
|
|
||||||
name,
|
|
||||||
tags: tags[name] || [],
|
|
||||||
}));
|
|
||||||
|
|
||||||
console.log('Adding objects to the temporary index...');
|
|
||||||
return addObjects(indexTmp, objects);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
console.log('Moving temporary index to target index...');
|
|
||||||
return moveIndex(client, indexTmp.indexName, index.indexName);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function scopedCopyIndex(
|
|
||||||
client,
|
|
||||||
indexNameSrc,
|
|
||||||
indexNameDest,
|
|
||||||
scope = ['settings', 'synonyms', 'rules'],
|
|
||||||
) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
client.copyIndex(indexNameSrc, indexNameDest, scope, (error, contents) => {
|
|
||||||
if (error) reject(error);
|
|
||||||
resolve(contents);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addObjects(index, objects) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
index.addObjects(objects, (error, contents) => {
|
|
||||||
if (error) reject(error);
|
|
||||||
resolve(contents);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveIndex(client, indexNameSrc, indexNameDest) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
client.moveIndex(indexNameSrc, indexNameDest, (error, contents) => {
|
|
||||||
if (error) reject(error);
|
|
||||||
resolve(contents);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "feather-icons",
|
|
||||||
"version": "0.0.0-development",
|
|
||||||
"description": "Simply beautiful open source icons",
|
|
||||||
"main": "dist/feather.js",
|
|
||||||
"unpkg": "dist/feather.min.js",
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"all": "npm-run-all --sequential build lint test:coverage",
|
|
||||||
"build": "./bin/build.sh",
|
|
||||||
"lint": "eslint .",
|
|
||||||
"test": "jest --watch",
|
|
||||||
"test:coverage": "jest --coverage",
|
|
||||||
"cm": "git-cz",
|
|
||||||
"precommit": "lint-staged",
|
|
||||||
"commitmsg": "commitlint --edit"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"commitizen": {
|
|
||||||
"path": "cz-conventional-changelog"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"jest": {
|
|
||||||
"collectCoverageFrom": [
|
|
||||||
"src/**/*.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"classnames": "^2.2.5",
|
|
||||||
"core-js": "^3.1.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@commitlint/cli": "^5.2.5",
|
|
||||||
"@commitlint/config-conventional": "^6.1.3",
|
|
||||||
"algoliasearch": "^3.27.1",
|
|
||||||
"babel-cli": "^6.24.1",
|
|
||||||
"babel-loader": "^7.1.1",
|
|
||||||
"babel-preset-env": "^1.7.0",
|
|
||||||
"babel-preset-stage-2": "^6.24.1",
|
|
||||||
"cheerio": "^1.0.0-rc.2",
|
|
||||||
"commitizen": "^2.9.6",
|
|
||||||
"cz-conventional-changelog": "^2.1.0",
|
|
||||||
"eslint": "^4.19.1",
|
|
||||||
"eslint-config-airbnb-base": "^12.1.0",
|
|
||||||
"eslint-config-prettier": "^2.9.0",
|
|
||||||
"eslint-plugin-import": "^2.5.0",
|
|
||||||
"eslint-plugin-prettier": "^2.5.0",
|
|
||||||
"html-minifier": "^3.5.8",
|
|
||||||
"husky": "^0.14.3",
|
|
||||||
"jest": "^22.4.4",
|
|
||||||
"lint-staged": "^6.0.0",
|
|
||||||
"npm-run-all": "^4.1.2",
|
|
||||||
"prettier": "^1.8.2",
|
|
||||||
"semantic-release": "^12.2.2",
|
|
||||||
"svgo": "^0.7.2",
|
|
||||||
"webpack": "^4.8.3",
|
|
||||||
"webpack-cli": "^2.1.3"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/feathericons/feather.git"
|
|
||||||
},
|
|
||||||
"author": "Cole Bemis <cole@colebemis.com> (http://colebemis.com)",
|
|
||||||
"license": "MIT"
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`constructs icon object correctly 1`] = `
|
|
||||||
Icon {
|
|
||||||
"attrs": Object {
|
|
||||||
"class": "feather feather-test",
|
|
||||||
"fill": "none",
|
|
||||||
"height": 24,
|
|
||||||
"stroke": "currentColor",
|
|
||||||
"stroke-linecap": "round",
|
|
||||||
"stroke-linejoin": "round",
|
|
||||||
"stroke-width": 2,
|
|
||||||
"viewBox": "0 0 24 24",
|
|
||||||
"width": 24,
|
|
||||||
"xmlns": "http://www.w3.org/2000/svg",
|
|
||||||
},
|
|
||||||
"contents": "<line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" />",
|
|
||||||
"name": "test",
|
|
||||||
"tags": Array [
|
|
||||||
"hello",
|
|
||||||
"world",
|
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`constructs icon object correctly 2`] = `
|
|
||||||
Icon {
|
|
||||||
"attrs": Object {
|
|
||||||
"class": "feather feather-test",
|
|
||||||
"fill": "none",
|
|
||||||
"height": 24,
|
|
||||||
"stroke": "currentColor",
|
|
||||||
"stroke-linecap": "round",
|
|
||||||
"stroke-linejoin": "round",
|
|
||||||
"stroke-width": 2,
|
|
||||||
"viewBox": "0 0 24 24",
|
|
||||||
"width": 24,
|
|
||||||
"xmlns": "http://www.w3.org/2000/svg",
|
|
||||||
},
|
|
||||||
"contents": "<line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" />",
|
|
||||||
"name": "test",
|
|
||||||
"tags": Array [],
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`toString() returns correct string 1`] = `"<line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" />"`;
|
|
||||||
|
|
||||||
exports[`toSvg() returns correct string 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-test\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" /></svg>"`;
|
|
||||||
|
|
||||||
exports[`toSvg() returns correct string 2`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"1\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-test\\" color=\\"red\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" /></svg>"`;
|
|
||||||
|
|
||||||
exports[`toSvg() returns correct string 3`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-test foo bar\\" color=\\"red\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" /></svg>"`;
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`exports correct object 1`] = `
|
|
||||||
Object {
|
|
||||||
"icon1": Icon {
|
|
||||||
"attrs": Object {
|
|
||||||
"class": "feather feather-icon1",
|
|
||||||
"fill": "none",
|
|
||||||
"height": 24,
|
|
||||||
"stroke": "currentColor",
|
|
||||||
"stroke-linecap": "round",
|
|
||||||
"stroke-linejoin": "round",
|
|
||||||
"stroke-width": 2,
|
|
||||||
"viewBox": "0 0 24 24",
|
|
||||||
"width": 24,
|
|
||||||
"xmlns": "http://www.w3.org/2000/svg",
|
|
||||||
},
|
|
||||||
"contents": "<line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" />",
|
|
||||||
"name": "icon1",
|
|
||||||
"tags": Array [
|
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
"hello",
|
|
||||||
"world",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
"icon2": Icon {
|
|
||||||
"attrs": Object {
|
|
||||||
"class": "feather feather-icon2",
|
|
||||||
"fill": "none",
|
|
||||||
"height": 24,
|
|
||||||
"stroke": "currentColor",
|
|
||||||
"stroke-linecap": "round",
|
|
||||||
"stroke-linejoin": "round",
|
|
||||||
"stroke-width": 2,
|
|
||||||
"viewBox": "0 0 24 24",
|
|
||||||
"width": 24,
|
|
||||||
"xmlns": "http://www.w3.org/2000/svg",
|
|
||||||
},
|
|
||||||
"contents": "<circle cx=\\"12\\" cy=\\"12\\" r=\\"11\\" />",
|
|
||||||
"name": "icon2",
|
|
||||||
"tags": Array [],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`throws an error when run in node environment 1`] = `"\`feather.replace()\` only works in a browser environment."`;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`copies placeholder element attributes to <svg> tag 1`] = `"<i data-feather=\\"icon1\\" id=\\"test\\" class=\\"foo bar\\" stroke-width=\\"1\\"></i>"`;
|
|
||||||
|
|
||||||
exports[`copies placeholder element attributes to <svg> tag 2`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"1\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-icon1 foo bar\\" id=\\"test\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\"></line><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\"></line></svg>"`;
|
|
||||||
|
|
||||||
exports[`replaces [data-feather] elements with SVG markup 1`] = `"<i data-feather=\\"icon1\\"></i><span data-feather=\\"icon2\\"></span>"`;
|
|
||||||
|
|
||||||
exports[`replaces [data-feather] elements with SVG markup 2`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-icon1\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\"></line><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\"></line></svg><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-icon2\\"><circle cx=\\"12\\" cy=\\"12\\" r=\\"11\\"></circle></svg>"`;
|
|
||||||
|
|
||||||
exports[`sets attributes passed as parameters 1`] = `"<i data-feather=\\"icon1\\" id=\\"test\\" class=\\"foo bar\\" stroke-width=\\"1\\"></i>"`;
|
|
||||||
|
|
||||||
exports[`sets attributes passed as parameters 2`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"1\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-icon1 foo bar hello\\" color=\\"salmon\\" id=\\"test\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\"></line><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\"></line></svg>"`;
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`returns correct string 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-icon1\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" /></svg>"`;
|
|
||||||
|
|
||||||
exports[`returns correct string 2`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"1\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-icon1\\" color=\\"red\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" /></svg>"`;
|
|
||||||
|
|
||||||
exports[`returns correct string 3`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"feather feather-icon1 foo bar\\" color=\\"red\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\" /><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\" /></svg>"`;
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import Icon from '../icon';
|
|
||||||
|
|
||||||
const icon1 = new Icon(
|
|
||||||
'test',
|
|
||||||
'<line x1="23" y1="1" x2="1" y2="23" /><line x1="1" y1="1" x2="23" y2="23" />',
|
|
||||||
['hello', 'world', 'foo', 'bar'],
|
|
||||||
);
|
|
||||||
|
|
||||||
const icon2 = new Icon(
|
|
||||||
'test',
|
|
||||||
'<line x1="23" y1="1" x2="1" y2="23" /><line x1="1" y1="1" x2="23" y2="23" />',
|
|
||||||
);
|
|
||||||
|
|
||||||
test('constructs icon object correctly', () => {
|
|
||||||
expect(icon1).toMatchSnapshot();
|
|
||||||
expect(icon2).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('toSvg() returns correct string', () => {
|
|
||||||
expect(icon1.toSvg()).toMatchSnapshot();
|
|
||||||
expect(icon1.toSvg({ 'stroke-width': 1, color: 'red' })).toMatchSnapshot();
|
|
||||||
expect(icon1.toSvg({ class: 'foo bar', color: 'red' })).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('toString() returns correct string', () => {
|
|
||||||
expect(icon1.toString()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import icons from '../icons';
|
|
||||||
|
|
||||||
jest.mock('../../dist/icons.json', () => ({
|
|
||||||
icon1:
|
|
||||||
'<line x1="23" y1="1" x2="1" y2="23" /><line x1="1" y1="1" x2="23" y2="23" />',
|
|
||||||
icon2: '<circle cx="12" cy="12" r="11" />',
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../tags.json', () => ({
|
|
||||||
icon1: ['foo', 'bar', 'hello', 'world'],
|
|
||||||
}));
|
|
||||||
|
|
||||||
test('exports correct object', () => {
|
|
||||||
expect(icons).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import feather from '../index';
|
|
||||||
|
|
||||||
test('has correct properties', () => {
|
|
||||||
expect(feather).toHaveProperty('icons');
|
|
||||||
expect(feather).toHaveProperty('toSvg');
|
|
||||||
expect(feather).toHaveProperty('replace');
|
|
||||||
});
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* @jest-environment node
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* eslint-env jest */
|
|
||||||
import replace from '../replace';
|
|
||||||
|
|
||||||
test('throws an error when run in node environment', () => {
|
|
||||||
expect(replace).toThrowErrorMatchingSnapshot();
|
|
||||||
});
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/* eslint-env jest, browser */
|
|
||||||
import replace from '../replace';
|
|
||||||
|
|
||||||
jest.mock('../../dist/icons.json', () => ({
|
|
||||||
icon1:
|
|
||||||
'<line x1="23" y1="1" x2="1" y2="23" /><line x1="1" y1="1" x2="23" y2="23" />',
|
|
||||||
icon2: '<circle cx="12" cy="12" r="11" />',
|
|
||||||
}));
|
|
||||||
|
|
||||||
test('replaces [data-feather] elements with SVG markup', () => {
|
|
||||||
document.body.innerHTML =
|
|
||||||
'<i data-feather="icon1"></i><span data-feather="icon2"></i>';
|
|
||||||
expect(document.body.innerHTML).toMatchSnapshot();
|
|
||||||
replace();
|
|
||||||
expect(document.body.innerHTML).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('copies placeholder element attributes to <svg> tag', () => {
|
|
||||||
document.body.innerHTML =
|
|
||||||
'<i data-feather="icon1" id="test" class="foo bar" stroke-width="1"></i>';
|
|
||||||
expect(document.body.innerHTML).toMatchSnapshot();
|
|
||||||
replace();
|
|
||||||
expect(document.body.innerHTML).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('sets attributes passed as parameters', () => {
|
|
||||||
document.body.innerHTML =
|
|
||||||
'<i data-feather="icon1" id="test" class="foo bar" stroke-width="1"></i>';
|
|
||||||
expect(document.body.innerHTML).toMatchSnapshot();
|
|
||||||
replace({ class: 'foo bar hello', 'stroke-width': 1.5, color: 'salmon' });
|
|
||||||
expect(document.body.innerHTML).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/* eslint-env jest */
|
|
||||||
import toSvg from '../to-svg';
|
|
||||||
|
|
||||||
jest.mock('../../dist/icons.json', () => ({
|
|
||||||
icon1:
|
|
||||||
'<line x1="23" y1="1" x2="1" y2="23" /><line x1="1" y1="1" x2="23" y2="23" />',
|
|
||||||
}));
|
|
||||||
|
|
||||||
test('returns correct string', () => {
|
|
||||||
expect(toSvg('icon1')).toMatchSnapshot();
|
|
||||||
expect(toSvg('icon1', { 'stroke-width': 1, color: 'red' })).toMatchSnapshot();
|
|
||||||
expect(toSvg('icon1', { class: 'foo bar', color: 'red' })).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws error when `name` parameter is undefined', () => {
|
|
||||||
expect(() => toSvg()).toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throws error when passed unknown icon name', () => {
|
|
||||||
expect(() => toSvg('foo')).toThrow();
|
|
||||||
});
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"xmlns": "http://www.w3.org/2000/svg",
|
|
||||||
"width": 24,
|
|
||||||
"height": 24,
|
|
||||||
"viewBox": "0 0 24 24",
|
|
||||||
"fill": "none",
|
|
||||||
"stroke": "currentColor",
|
|
||||||
"stroke-width": 2,
|
|
||||||
"stroke-linecap": "round",
|
|
||||||
"stroke-linejoin": "round"
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import classnames from 'classnames/dedupe';
|
|
||||||
|
|
||||||
import DEFAULT_ATTRS from './default-attrs.json';
|
|
||||||
|
|
||||||
class Icon {
|
|
||||||
constructor(name, contents, tags = []) {
|
|
||||||
this.name = name;
|
|
||||||
this.contents = contents;
|
|
||||||
this.tags = tags;
|
|
||||||
this.attrs = {
|
|
||||||
...DEFAULT_ATTRS,
|
|
||||||
...{ class: `feather feather-${name}` },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an SVG string.
|
|
||||||
* @param {Object} attrs
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
toSvg(attrs = {}) {
|
|
||||||
const combinedAttrs = {
|
|
||||||
...this.attrs,
|
|
||||||
...attrs,
|
|
||||||
...{ class: classnames(this.attrs.class, attrs.class) },
|
|
||||||
};
|
|
||||||
|
|
||||||
return `<svg ${attrsToString(combinedAttrs)}>${this.contents}</svg>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return string representation of an `Icon`.
|
|
||||||
*
|
|
||||||
* Added for backward compatibility. If old code expects `feather.icons.<name>`
|
|
||||||
* to be a string, `toString()` will get implicitly called.
|
|
||||||
*
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
toString() {
|
|
||||||
return this.contents;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert attributes object to string of HTML attributes.
|
|
||||||
* @param {Object} attrs
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function attrsToString(attrs) {
|
|
||||||
return Object.keys(attrs)
|
|
||||||
.map(key => `${key}="${attrs[key]}"`)
|
|
||||||
.join(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Icon;
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import Icon from './icon';
|
|
||||||
import icons from '../dist/icons.json';
|
|
||||||
import tags from './tags.json';
|
|
||||||
|
|
||||||
export default Object.keys(icons)
|
|
||||||
.map(key => new Icon(key, icons[key], tags[key]))
|
|
||||||
.reduce((object, icon) => {
|
|
||||||
object[icon.name] = icon;
|
|
||||||
return object;
|
|
||||||
}, {});
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import icons from './icons';
|
|
||||||
import toSvg from './to-svg';
|
|
||||||
import replace from './replace';
|
|
||||||
|
|
||||||
module.exports = { icons, toSvg, replace };
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/* eslint-env browser */
|
|
||||||
import classnames from 'classnames/dedupe';
|
|
||||||
|
|
||||||
import icons from './icons';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace all HTML elements that have a `data-feather` attribute with SVG markup
|
|
||||||
* corresponding to the element's `data-feather` attribute value.
|
|
||||||
* @param {Object} attrs
|
|
||||||
*/
|
|
||||||
function replace(attrs = {}) {
|
|
||||||
if (typeof document === 'undefined') {
|
|
||||||
throw new Error('`feather.replace()` only works in a browser environment.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const elementsToReplace = document.querySelectorAll('[data-feather]');
|
|
||||||
|
|
||||||
Array.from(elementsToReplace).forEach(element =>
|
|
||||||
replaceElement(element, attrs),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace a single HTML element with SVG markup
|
|
||||||
* corresponding to the element's `data-feather` attribute value.
|
|
||||||
* @param {HTMLElement} element
|
|
||||||
* @param {Object} attrs
|
|
||||||
*/
|
|
||||||
function replaceElement(element, attrs = {}) {
|
|
||||||
const elementAttrs = getAttrs(element);
|
|
||||||
const name = elementAttrs['data-feather'];
|
|
||||||
delete elementAttrs['data-feather'];
|
|
||||||
|
|
||||||
const svgString = icons[name].toSvg({
|
|
||||||
...attrs,
|
|
||||||
...elementAttrs,
|
|
||||||
...{ class: classnames(attrs.class, elementAttrs.class) },
|
|
||||||
});
|
|
||||||
const svgDocument = new DOMParser().parseFromString(
|
|
||||||
svgString,
|
|
||||||
'image/svg+xml',
|
|
||||||
);
|
|
||||||
const svgElement = svgDocument.querySelector('svg');
|
|
||||||
|
|
||||||
element.parentNode.replaceChild(svgElement, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the attributes of an HTML element.
|
|
||||||
* @param {HTMLElement} element
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
function getAttrs(element) {
|
|
||||||
return Array.from(element.attributes).reduce((attrs, attr) => {
|
|
||||||
attrs[attr.name] = attr.value;
|
|
||||||
return attrs;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default replace;
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import icons from './icons';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an SVG string.
|
|
||||||
* @deprecated
|
|
||||||
* @param {string} name
|
|
||||||
* @param {Object} attrs
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function toSvg(name, attrs = {}) {
|
|
||||||
console.warn(
|
|
||||||
'feather.toSvg() is deprecated. Please use feather.icons[name].toSvg() instead.',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
throw new Error('The required `key` (icon name) parameter is missing.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!icons[name]) {
|
|
||||||
throw new Error(
|
|
||||||
`No icon matching '${
|
|
||||||
name
|
|
||||||
}'. See the complete list of icons at https://feathericons.com`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return icons[name].toSvg(attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default toSvg;
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
entry: ['core-js/es/array/from', path.resolve(__dirname, 'src/index.js')],
|
|
||||||
output: {
|
|
||||||
path: path.resolve(__dirname, 'dist'),
|
|
||||||
libraryTarget: 'umd',
|
|
||||||
library: 'feather',
|
|
||||||
// Prevents webpack from referencing `window` in the UMD build
|
|
||||||
// Source: https://git.io/vppgU
|
|
||||||
globalObject: "typeof self !== 'undefined' ? self : this",
|
|
||||||
},
|
|
||||||
devtool: 'source-map',
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.js$/,
|
|
||||||
loader: 'babel-loader',
|
|
||||||
exclude: /node_modules/,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user