Compare commits

...

33 Commits

Author SHA1 Message Date
Eric Fennis 762cf32666 Release/v0.1.2 (#97)
* optimize build

* bumb version

Co-authored-by: Eric Fennis <eric.fennis@endurance.com>
2020-10-15 09:17:00 +02:00
Eric Fennis 216f42cdcb remove building icon from root (#96)
Co-authored-by: Eric Fennis <eric.fennis@endurance.com>
2020-10-15 09:00:40 +02:00
delnyn b80c2805b2 Add Laptop icon (#88)
* Add laptop icon

* Update tags.json

* Update laptop.svg

* Update laptop.svg

* Update icons/laptop.svg

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update icons/laptop.svg

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2020-10-14 17:58:04 +02:00
mishkaio d80a267c81 feat: add box select, box select with pointer, bullhorn, document los… (#57)
* feat: add box select, box select with pointer, bullhorn, document lost, document search, lasso select, lasso, newspaper

* Delete box-select-pointer.svg

* Delete box-select.svg

* Delete bullhorn.svg

* Delete document-lost.svg

* Delete document-search.svg

* Update icons/lasso-select.svg

* Update lasso.svg

* Delete newspaper.svg

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2020-10-14 17:23:48 +02:00
delnyn 07fa908631 Fix: move building icon (#95)
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2020-10-13 19:00:42 +02:00
delnyn 1bdf6febac Add building icon (#91)
* Add building icon

* Add building to tags

* Update building.svg

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update building.svg

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update tags.json

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2020-10-13 08:46:25 +02:00
Eric Fennis 78e1057515 Feat: Adds list-ordered, list-unordered, list-checks (#43)
* Add list icons

* Update icons

* update list icons
2020-10-11 23:51:11 +02:00
dependabot[bot] 9d6d0c340d chore(deps): Bump next from 9.5.3 to 9.5.4 in /site (#89)
Bumps [next](https://github.com/vercel/next.js) from 9.5.3 to 9.5.4.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v9.5.3...v9.5.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-11 13:51:07 +02:00
Eric Fennis 77f3f49ce7 Update site (#87)
* Move the site to the root directory

* Update Site name

Co-authored-by: Eric Fennis <eric.fennis@endurance.com>
2020-10-08 12:44:09 +02:00
Frank Riccobono a55620d6ba refactor: use memoization and native NextJS router queries to reduce re-renders (#85)
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2020-10-07 17:47:41 +02:00
Eric Fennis dad9648e20 Fix the site, before other site changes (#86)
* fix the site

* Change base

* Change publish folder

Co-authored-by: Eric Fennis <eric.fennis@endurance.com>
2020-10-07 17:42:59 +02:00
Frank Riccobono b3b39afb95 docs: Create guide for creating icons in Inkscape (#81) 2020-10-07 17:34:40 +02:00
Eric Fennis 4406cbaea0 Hotfix Lucide npm package, fix security issues (#84)
* adjust npmignore

* 📦 Fix security issues

* update font workflow

* identation

* update, package.json

* Add description

* Add shields
2020-10-06 23:03:11 +02:00
Eric Fennis 11c6a2e917 Featherity Npm package, reorganize scripting. (#52)
* New setup for new NPM package

* Add build scripts for dist

* Add introduction readme

* Refactor names

* update package.json

* remove log

* rename variable

* Factoring

* Improve optimize script

* Add eslint config

* Eslint fixes

* rename import

* Move packeges

* Setup rollup and build progress

* Refactor scripts

* fix lint error

* remove lint disabler

* Bring back old libraries

* add indentation

* reset packages directory

* remove vscode setting files

* 0.1.0-alpha.0

* new version

* 0.1.0-alpha.1

* Fix build process

* Add create element to the entry file

* update version number

* publish new alhpa version

* fixing bugs

* Add jest and tests

* replace with XML createElement

* set new version

* Fix svg generation

* Add tests for main library

* Update docs

* Adjust tests and selectors

* update the spec

* Update README.md

* Update README.md

* Update README.md

* update version

* Update README.md

* Move function to helpers file

* rename license, package and readme

* Fix build files

* rename packages

Co-authored-by: Eric Fennis <eric.fennis@endurance.com>
2020-10-06 20:23:26 +02:00
Locness 8b5278437a README : Mention Featherity is independent + various changes (#82) 2020-10-05 20:30:34 +02:00
Collin Monahan c84fcfe3cb feat: add box select (#69)
* feat: add box select, box select with pointer, bullhorn, document lost, document search, lasso select, lasso, newspaper

* remove other icons on this branch

* more space for box-select

* maybe similarly spacing box-sel-ptr

* focus down to box select

* try dashed-line square

* polylines at corners

* space before close-element

* rounded version

* undo change to wrong file

Co-authored-by: mishkaio <60020191+mishkaio@users.noreply.github.com>
2020-09-29 08:43:00 +02:00
Eric Fennis 058c40a1ec Feat: Dashboard/Masonry Icon (#72)
* add brick layout icon

* Add Masonry icon

* delete other icons

* rename icon
2020-09-28 18:31:35 +02:00
Eric Fennis 6dad37a1b5 feat: Add equal icons and refactor devide icon (#56)
* Add equal icons and refactor devide icon

* update icon

* remove white space
2020-09-25 12:50:51 +02:00
Eric Fennis 85d3bb9b82 feat: 'move-horizontal', 'move-vertical', 'move-diagonal', 'mouse-pointer-2' (#49)
* add cursors

* update icons to match same length as othe move icons
2020-09-21 13:01:24 +02:00
Eric Fennis dee5d33bcd Add image-off icon (#74) 2020-09-20 19:13:31 +02:00
Eric Fennis a26745a3be add calculator icon (#75) 2020-09-20 19:12:52 +02:00
Lennard Scheibel 9550ec28b8 feat: Add shirt icon (#20) 2020-09-19 12:14:08 +02:00
Eric Fennis 845d6add1f feat: add more bluetooth icons (#67)
* add more bluetooth icons

* change to lines
2020-09-11 22:10:41 +02:00
Yashu Mittal 06972942cd Add bot icon (#71) 2020-09-11 22:10:24 +02:00
Eric Fennis d33b6674f3 add Gauge icon (#66) 2020-09-11 22:10:11 +02:00
Eric Fennis 70be911f69 feat: refactor heart icon (#64)
* Add lightbulb icon

* update heart icon

* add white space
2020-09-11 22:09:40 +02:00
Eric Fennis 6f06e05a47 Add lightbulb icon (#63) 2020-09-11 22:09:27 +02:00
Eric Fennis 8a15bca8cd feat: refactor wifi-icons (#62)
* refactor wifi-icons

* add spacings
2020-09-11 22:09:13 +02:00
Alexander Barrios 5aef4e6110 Workflow that will compile font files (#68)
* Create font.yml

* Change to show logs

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update .github/workflows/font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update font.yml

* Update font.yml

* Update font.yml

* Update font.yml

* Update font.yml

* Fix syntax

* Update font.yml

* Update font.yml

* Update font.yml

* Update font.yml

* Update font.yml

* Update font.yml

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2020-09-09 09:48:52 +02:00
Eric Fennis e1cead9531 feat: Add separator icons (#47)
* Add separator icons

* Add more serpartor icons

* Remove other separator icons

* Shorter lines
2020-09-03 11:50:02 +02:00
dependabot[bot] c686c1a0c3 chore(deps): Bump lodash from 4.17.15 to 4.17.20 (#59)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.20.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.20)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-08-30 11:12:36 +02:00
dependabot[bot] af87274bf4 chore(deps): Bump elliptic from 6.5.2 to 6.5.3 (#58)
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-08-29 23:18:02 +02:00
John Letey e3e4514dcc feat: Site (#1)
* site: pull data from "icons" dir

* site: display icons

* site: remove redundant code

* site: colour mode support

* site: header

* site: order imports

* site: search

* site: add toast when copying icon

* site: styling

* site: hero

* fix: disable theme toggle transitions

* feat: Use Yarn Workspaces

* refactor: Update site deploy scripts

* refactor: Remove dark mode for now

* feat: Add site title

* refactor: Fix warning and format

* feat: Add dark mode back 👀

* feat: Escape key to reset query

* Fix by aelfric

* Add Github link

* Fix #40

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2020-08-29 23:16:38 +02:00
131 changed files with 15106 additions and 855 deletions
+11
View File
@@ -0,0 +1,11 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
quote_type = single
max_line_length = 100
+5
View File
@@ -0,0 +1,5 @@
dist
build
coverage
lib
tests
@@ -1,8 +1,12 @@
{
"env": {
"browser": true,
"node": true
},
"extends": ["airbnb-base", "prettier"],
"plugins": ["import", "prettier"],
"rules": {
"no-console": ["error", { "allow": ["warn", "error"] }],
"no-console": "off",
"no-param-reassign": "off",
"no-shadow": "off",
"no-use-before-define": "off",
+48
View File
@@ -0,0 +1,48 @@
name: Build Lucide
on:
push:
branches: [ master ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Clone 'Lucide'
uses: actions/checkout@v2
- name: Install FontForge
run: sudo apt-get install zlib1g-dev fontforge woff2
- name: Clone sfnt2woff-zopfli repo
run: git clone https://github.com/bramstein/sfnt2woff-zopfli.git sfnt2woff-zopfli
- name: Install and move sfnt2woff-zopfli
run: |
cd sfnt2woff-zopfli
make
sudo mv sfnt2woff-zopfli /usr/local/bin/sfnt2woff
- name: Clone woff2
run: git clone --recursive https://github.com/google/woff2.git
- name: Install woff2
run: |
cd woff2
sudo make clean all
sudo mv woff2_compress /usr/local/bin/ && sudo mv woff2_decompress /usr/local/bin/
- name: Install Font Custom dependency
run: sudo gem install fontcustom
- name: Build 'Lucide'
run: echo "Building Featherity font" && fontcustom compile ./icons -h -n Featherity -o build -F
- name: Zip 'Lucide'
run: zip -r Featherity.zip build
- name: 'Upload to Artifacts'
uses: actions/upload-artifact@v1.0.0
with:
name: Lucide
path: build
+7 -1
View File
@@ -1,6 +1,12 @@
.DS_Store
.next
.now
node_modules
dist
build
/lib
sandbox
stash
coverage
coverage
stats
*.log
+7
View File
@@ -0,0 +1,7 @@
.github
packages
stats
node_modules
tests
scripts
site
+1 -1
View File
@@ -21,4 +21,4 @@ Guidelines for pull requests:
Before creating an icon request, please search to see if someone has requested the icon already. If there is an open request, please add a :+1:.
If the icon has not already been requested, [create an issue](https://github.com/featherity/featherity/issues/new?title=Icon%20Request:) with a title of `Icon request: <icon name>` and add as much information as possible.
If the icon has not already been requested, [create an issue](https://github.com/lucide-icons/lucide/issues/new?title=Icon%20Request:) with a title of `Icon request: <icon name>` and add as much information as possible.
+1 -1
View File
@@ -1,6 +1,6 @@
ISC License
Copyright (c) 2020, Featherity Contributors
Copyright (c) 2020, Lucide Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
+127 -10
View File
@@ -1,10 +1,12 @@
# Featherity
# Lucide
![NPM](https://img.shields.io/npm/l/lucide)
[![npm](https://img.shields.io/npm/v/lucide)](https://www.npmjs.com/package/lucide)
[![Discord](https://img.shields.io/discord/723074157486800936?label=chat&logo=discord&logoColor=%23ffffff&colorB=%237289DA)](https://discord.gg/EH6nSts)
## What is Featherity?
## What is Lucide?
Featherity is a fork of [Feather Icons](https://github.com/feathericons/feather), with icons sourced by the community.
Lucide is a community-run fork of [Feather Icons](https://github.com/feathericons/feather), open for anyone to contribute icons.
## Table of Contents
@@ -13,11 +15,127 @@ Featherity is a fork of [Feather Icons](https://github.com/feathericons/feather)
* [Contributing](#contributing)
* [License](#license)
## Installation
### Package Managers
``` bash
npm install lucide
#or
yarn add lucide
```
### CDN
``` html
<!-- Development version -->
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script>
<!-- Production version -->
<script src="https://unpkg.com/lucide@latest"></script>
```
## Usage
At its core, Featherity is a collection of [SVG](https://svgontheweb.com/#svg) files. This means that you can use Feather icons in all the same ways you can use SVGs (e.g. `img`, `background-image`, `inline`, `object`, `embed`, `iframe`). Here's a helpful article detailing the many ways SVGs can be used on the web: [SVG on the Web Implementation Options](https://svgontheweb.com/#implementation)
At its core, Lucide is a collection of [SVG](https://svgontheweb.com/#svg) files. This means that you can use Feather icons in all the same ways you can use SVGs (e.g. `img`, `background-image`, `inline`, `object`, `embed`, `iframe`). Here's a helpful article detailing the many ways SVGs can be used on the web: [SVG on the Web Implementation Options](https://svgontheweb.com/#implementation)
The following are additional ways you can use Featherity.
The following are additional ways you can use Lucide.
With the Javascript library you can easily incorporate the icon you want in your webpage.
### With unpkg
Here is a complete example with unpkg
```html
<!DOCTYPE html>
<body>
<i icon-name="volume-2" class="my-class"></i>
<i icon-name="x"></i>
<i icon-name="menu"></i>
<script src="https://unpkg.com/lucide@latest"></script>
<script>
lucide.createIcons();
</script>
</body>
```
### With ESModules
To reduce bundle size, lucide is build to be fully threeshakeble.
The `createIcons` function will search for HTMLElements with the attribute `icon-name` and replace it with the svg from the given icon name.
```html
<!-- Your HTML file -->
<i icon-name="menu"></i>
```
```js
import { createIcons, icons } from 'lucide';
// Caustion, this will import all the icons and bundle them.
createIcons({icons});
// Recommended way, to include only the icons you need.
import { createIcons, Menu, ArrowRight, Globe } from 'lucide';
createIcons({
icons: {
Menu,
ArrowRight,
Globe,
},
});
```
#### Additional Options
In the `createIcons` function you can pass some extra parameters to adjust the `nameAttr` or add custom attributes like for example classes.
Here is a full example:
```js
import { createIcons } from 'lucide';
createIcons({
attrs: {
class: ['my-custom-class', 'icon'],
'stroke-width': 1,
stroke: '#333',
},
nameAttr: 'icon-name', // atrribute for the icon name.
});
```
#### Threeshake the library, only use the icons you use
```js
import { createIcons, Menu, ArrowRight, Globe } from 'lucide';
createIcons({
icons: {
Menu,
ArrowRight,
Globe,
},
});
```
#### Custom Element binding
```js
import { createElement, Menu } from 'lucide';
const menuIcon = createElement(Menu); // Returns HTMLElement (svg)
// set custom attributes with browser native functions
menuIcon.setAttribute('stroke', '#333');
menuIcon.classList.add('my-icon-class');
// Append HTMLElement in webpage
const myApp = document.getElementById('app');
myApp.appendChild(menuIcon);
```
### Figma
@@ -25,15 +143,14 @@ You can use the components from [this Figma file](https://www.figma.com/file/g0U
## Contributing
For more info on how to contribute please see the [contribution guidelines](https://github.com/featherity/featherity/blob/master/CONTRIBUTING.md).
For more info on how to contribute please see the [contribution guidelines](https://github.com/lucide-icons/lucide/blob/master/CONTRIBUTING.md).
Caught a mistake or want to contribute to the documentation? [Edit this page on Github](https://github.com/featherity/featherity/blob/master/README.md)
Caught a mistake or want to contribute to the documentation? [Edit this page on Github](https://github.com/lucide-icons/lucide/blob/master/README.md)
## Community
Do you want to join our community?
Join us in [discord](https://discord.gg/EH6nSts)!
Join the community on our [Discord](https://discord.gg/EH6nSts) server!
## License
Feather is licensed under the [ISC License](https://github.com/featherity/featherity/blob/master/LICENSE).
Lucide is licensed under the [ISC License](https://github.com/lucide-icons/lucide/blob/master/LICENSE).
+27
View File
@@ -0,0 +1,27 @@
module.exports = {
presets: [
[
'@babel/env',
{
loose: true,
modules: false,
},
],
],
env: {
test: {
presets: ['@babel/env'],
plugins: ['@babel/plugin-transform-runtime'],
},
dev: {
plugins: [
[
'transform-inline-environment-variables',
{
include: ['NODE_ENV'],
},
],
],
},
},
};
+37
View File
@@ -0,0 +1,37 @@
# Inkscape Setup Guide
This guide shows the steps to setup Inkscape for creating icons that conform to the Featherity design
guidelines.
## Setting up The Canvas
When opening a new document, Inkscape will create a canvas of a default size. To change the size to 24x24:
1. Open the Document Properties dialog (File -> Document Properties).
2. On the “Page Size” tab, under “Custom Size” set the Units to `px` and set both Height and Width to 24.
![Setting Page Size](images/page-size.png?raw=true "Setting Page Size")
3. On the “Grid” tab, select `Rectangular Grid` and click “New Grid”.
![Setting Grid Properties](images/grid-1.png?raw=true "Setting Grid Properties")
4. Set the Grid Units to `px` and set Spacing X and Spacing Y both to 1.
![Setting Grid Properties](images/grid-2.png?raw=true "Setting Grid Properties")
5. Close the Document Properties dialog.
6. To center the canvas in the viewport, select View -> Zoom -> Drawing.
## Setting up The Paths
1. Create a path or shape.
2. With the path selected, open the Stroke and Fill panel by pressing `Ctrl+Shift+F` on your keyboard.
![Stroke Style Properties](images/strokes.png?raw=true "Setting Grid Properties")
3. On the “Stroke Style” tab:
* Set Stroke Width to `2px`.
* Select the rounded join type.
* Select the rounded cap type.
4. If the shape is a rectangle, select the rectangle and in the top of the screen below the menu bar, set `Rx` and `Ry` to `2px`.
![Rectangle Radius Properties](images/corner-radius.png?raw=true "Rectangle Radius Properties")
## Saving A File
1. When ready to save the file, click Save As and select “Optimized SVG” as the file type.
![Save As](images/save-as.png?raw=true "Save as")
2. After clicking Save, to conform with the other icons in the package, set Pretty Printing to use spaces and set the indentation depth to 2.
![Optimize](images/optimize-settings.png?raw=true "Optimize")
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

+15
View File
@@ -0,0 +1,15 @@
<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"
>
<path d="M7 7L17 17L12 22V2L17 7L7 17" />
<line x1="18" y1="12" y2="12" x2="21" />
<line x1="3" y1="12" y2="12" x2="6" />
</svg>

After

Width:  |  Height:  |  Size: 336 B

+15
View File
@@ -0,0 +1,15 @@
<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"
>
<path d="M17 17L12 22V12L7 17" />
<path d="M2 2L22 22" />
<path d="M14.5 9.5L17 7L12 2V6.5" />
</svg>

After

Width:  |  Height:  |  Size: 309 B

+15
View File
@@ -0,0 +1,15 @@
<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"
>
<path d="M7 7l10 10-5 5V2l5 5L7 17" />
<path d="M20.83 14.83a4 4 0 000-5.66" />
<path d="M18 12h.01"/>
</svg>

After

Width:  |  Height:  |  Size: 317 B

+1 -1
View File
@@ -9,5 +9,5 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="6.5 6.5 17.5 17.5 12 23 12 1 17.5 6.5 6.5 17.5" />
<path d="M7 7L17 17L12 22V2L17 7L7 17" />
</svg>

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 252 B

+17
View File
@@ -0,0 +1,17 @@
<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"
>
<rect x="3" y="11" width="18" height="10" rx="2" />
<circle cx="12" cy="5" r="2" />
<path d="M12 7v4" />
<line x1="8" y1="16" x2="8" y2="16" />
<line x1="16" y1="16" x2="16" y2="16" />
</svg>

After

Width:  |  Height:  |  Size: 403 B

+24
View File
@@ -0,0 +1,24 @@
<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"
>
<path d="M4 2a2 2 0 00-2 2" />
<line x1="8" y1="2" x2="10" y2="2" />
<line x1="14" y1="2" x2="16" y2="2" />
<path d="M4 22a2 2 0 01-2-2" />
<line x1="22" y1="8" x2="22" y2="10" />
<line x1="22" y1="14" x2="22" y2="16" />
<path d="M22 20a2 2 0 01-2 2" />
<line x1="14" y1="22" x2="16" y2="22" />
<line x1="8" y1="22" x2="10" y2="22" />
<path d="M20 2a2 2 0 012 2" />
<line x1="2" y1="14" x2="2" y2="16" />
<line x1="2" y1="8" x2="2" y2="10" />
</svg>

After

Width:  |  Height:  |  Size: 675 B

+23
View File
@@ -0,0 +1,23 @@
<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"
>
<rect x="4" y="2" width="16" height="20" rx="2" ry="2" />
<path d="M9 22v-4h6v4" />
<path d="M8 6h.01" />
<path d="M16 6h.01" />
<path d="M12 6h.01" />
<path d="M12 10h.01" />
<path d="M12 14h.01" />
<path d="M16 10h.01" />
<path d="M16 14h.01" />
<path d="M8 10h.01" />
<path d="M8 14h.01" />
</svg>

After

Width:  |  Height:  |  Size: 524 B

+22
View File
@@ -0,0 +1,22 @@
<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"
>
<rect x="4" y="2" width="16" height="20" rx="2" />
<line x1="8" x2="16" y1="6" y2="6" />
<line x1="16" x2="16" y1="14" y2="18" />
<path d="M16 10H16.01" />
<path d="M12 10H12.01" />
<path d="M8 10H8.01" />
<path d="M12 14H12.01" />
<path d="M8 14H8.01" />
<path d="M12 18H12.01" />
<path d="M8 18H8.01" />
</svg>

After

Width:  |  Height:  |  Size: 534 B

+2 -2
View File
@@ -9,7 +9,7 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="12" cy="6" r="2" />
<circle cx="12" cy="6" r="1" />
<line x1="5" y1="12" x2="19" y2="12" />
<circle cx="12" cy="18" r="2" />
<circle cx="12" cy="18" r="1" />
</svg>

Before

Width:  |  Height:  |  Size: 319 B

After

Width:  |  Height:  |  Size: 319 B

+15
View File
@@ -0,0 +1,15 @@
<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="5" y1="9" x2="19" y2="9" />
<line x1="5" y1="15" x2="19" y2="15" />
<line x1="19" y1="5" x2="5" y2="19" />
</svg>

After

Width:  |  Height:  |  Size: 331 B

+14
View File
@@ -0,0 +1,14 @@
<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="5" y1="9" x2="19" y2="9" />
<line x1="5" y1="15" x2="19" y2="15" />
</svg>

After

Width:  |  Height:  |  Size: 290 B

+14
View File
@@ -0,0 +1,14 @@
<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"
>
<path d="M12 15l3.5-3.5"/>
<path d="M20.3 18c.4-1 .7-2.2.7-3.4C21 9.8 17 6 12 6s-9 3.8-9 8.6c0 1.2.3 2.4.7 3.4"/>
</svg>

After

Width:  |  Height:  |  Size: 326 B

+1 -1
View File
@@ -9,5 +9,5 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
<path d="M20.42 4.58a5.4 5.4 0 00-7.65 0l-.77.78-.77-.78a5.4 5.4 0 00-7.65 0C1.46 6.7 1.33 10.28 4 13l8 8 8-8c2.67-2.72 2.54-6.3.42-8.42z" />
</svg>

Before

Width:  |  Height:  |  Size: 360 B

After

Width:  |  Height:  |  Size: 352 B

+16
View File
@@ -0,0 +1,16 @@
<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"
>
<path d="M2 2l20 20" />
<path d="M9 3h10a2 2 0 012 2v10M3.59 3.59A2 2 0 003 5v14c0 1.1.9 2 2 2h14a2 2 0 001.41-.59" />
<path d="M9.56 9.56a1.5 1.5 0 01-2.12-2.12" />
<path d="M21 15l-5-5M5 21l8-8" />
</svg>

After

Width:  |  Height:  |  Size: 416 B

+13
View File
@@ -0,0 +1,13 @@
<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"
>
<path d="M20 16V7a2 2 0 00-2-2H6a2 2 0 00-2 2v9m16 0H4m16 0l1.28 2.55a1 1 0 01-.9 1.45H3.62a1 1 0 01-.9-1.45L4 16" />
</svg>

After

Width:  |  Height:  |  Size: 364 B

+17
View File
@@ -0,0 +1,17 @@
<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"
>
<path d="M7 22a5 5 0 01-2-4" />
<path d="M7 16.93c.96.43 1.96.74 2.99.91" />
<path d="M3.34 14A6.8 6.8 0 012 10c0-4.42 4.48-8 10-8s10 3.58 10 8a7.19 7.19 0 01-.33 2" />
<path d="M5 18a2 2 0 100-4 2 2 0 000 4z" />
<path d="M14.33 22h-.09a.35.35 0 01-.24-.32v-10a.34.34 0 01.33-.34c.08 0 .15.03.21.08l7.34 6a.33.33 0 01-.21.59h-4.49l-2.57 3.85a.35.35 0 01-.28.14v0z" />
</svg>

After

Width:  |  Height:  |  Size: 588 B

+15
View File
@@ -0,0 +1,15 @@
<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"
>
<path d="M7 22a5 5 0 01-2-4" />
<path d="M3.3 14A6.8 6.8 0 012 10c0-4.4 4.5-8 10-8s10 3.6 10 8-4.5 8-10 8a12 12 0 01-5-1" />
<path d="M5 18a2 2 0 100-4 2 2 0 000 4z" />
</svg>

After

Width:  |  Height:  |  Size: 385 B

+16
View File
@@ -0,0 +1,16 @@
<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"
>
<rect x="3" y="3" width="7" height="9" />
<rect x="14" y="3" width="7" height="5" />
<rect x="14" y="12" width="7" height="9" />
<rect x="3" y="16" width="7" height="5" />
</svg>

After

Width:  |  Height:  |  Size: 388 B

+15
View File
@@ -0,0 +1,15 @@
<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="9" y1="18" x2="15" y2="18" />
<line x1="10" y1="22" x2="14" y2="22" />
<path d="M15.09 14c.18-.98.65-1.74 1.41-2.5A4.65 4.65 0 0018 8 6 6 0 006 8c0 1 .23 2.23 1.5 3.5A4.61 4.61 0 018.91 14" />
</svg>

After

Width:  |  Height:  |  Size: 417 B

+18
View File
@@ -0,0 +1,18 @@
<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="10" y1="6" x2="21" y2="6" />
<line x1="10" y1="12" x2="21" y2="12" />
<line x1="10" y1="18" x2="21" y2="18" />
<polyline points="3 6 4 7 6 5" />
<polyline points="3 12 4 13 6 11" />
<polyline points="3 18 4 19 6 17" />
</svg>

After

Width:  |  Height:  |  Size: 449 B

+18
View File
@@ -0,0 +1,18 @@
<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="10" y1="6" x2="21" y2="6" />
<line x1="10" y1="12" x2="21" y2="12" />
<line x1="10" y1="18" x2="21" y2="18" />
<path d="M4 6H5V10" />
<path d="M4 10H6" />
<path d="M6 18H4C4 17 6 16 6 15C6 13.9999 5 13.5 4 14" />
</svg>

After

Width:  |  Height:  |  Size: 443 B

+13
View File
@@ -0,0 +1,13 @@
<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"
>
<path d="M4 4l7.07 17 2.51-7.39L21 11.07Z" />
</svg>

After

Width:  |  Height:  |  Size: 256 B

+15
View File
@@ -0,0 +1,15 @@
<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"
>
<polyline points="5 11 5 5 11 5" />
<polyline points="19 13 19 19 13 19" />
<line x1="5" y1="5" x2="19" y2="19" />
</svg>

After

Width:  |  Height:  |  Size: 329 B

+15
View File
@@ -0,0 +1,15 @@
<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"
>
<polyline points="13 5 19 5 19 11" />
<polyline points="11 19 5 19 5 13" />
<line x1="19" y1="5" x2="5" y2="19" />
</svg>

After

Width:  |  Height:  |  Size: 329 B

+16
View File
@@ -0,0 +1,16 @@
<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"
>
<polyline points="18 8 22 12 18 16" />
<polyline points="6 8 2 12 6 16" />
<line x1="2" y1="12" x2="22" y2="12" />
</svg>

After

Width:  |  Height:  |  Size: 330 B

+15
View File
@@ -0,0 +1,15 @@
<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"
>
<polyline points="8 18 12 22 16 18" />
<polyline points="8 6 12 2 16 6" />
<line x1="12" y1="2" x2="12" y2="22" />
</svg>

After

Width:  |  Height:  |  Size: 329 B

+15
View File
@@ -0,0 +1,15 @@
<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="3" y1="12" x2="21" y2="12" />
<polyline points="8 8 12 4 16 8" />
<polyline points="16 16 12 20 8 16" />
</svg>

After

Width:  |  Height:  |  Size: 329 B

+15
View File
@@ -0,0 +1,15 @@
<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="12" y1="3" x2="12" y2="21" />
<polyline points="8 8 4 12 8 16" />
<polyline points="16 16 20 12 16 8" />
</svg>

After

Width:  |  Height:  |  Size: 329 B

+13
View File
@@ -0,0 +1,13 @@
<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"
>
<path d="M20.38 3.46L16 2a4 4 0 01-8 0L3.62 3.46a2 2 0 00-1.34 2.23l.58 3.47a1 1 0 00.99.84H6v10c0 1.1.9 2 2 2h8a2 2 0 002-2V10h2.15a1 1 0 00.99-.84l.58-3.47a2 2 0 00-1.34-2.23z"/>
</svg>

After

Width:  |  Height:  |  Size: 391 B

+6 -6
View File
@@ -9,11 +9,11 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="1" y1="1" x2="23" y2="23" />
<path d="M16.72 11.06A10.94 10.94 0 0 1 19 12.55" />
<path d="M5 12.55a10.94 10.94 0 0 1 5.17-2.39" />
<path d="M10.71 5.05A16 16 0 0 1 22.58 9" />
<path d="M1.42 9a15.91 15.91 0 0 1 4.7-2.88" />
<path d="M8.53 16.11a6 6 0 0 1 6.95 0" />
<line x1="2" y1="2" x2="22" y2="22" />
<path d="M8.5 16.5a5 5 0 017 0" />
<path d="M2 8.82a15 15 0 014.17-2.65" />
<path d="M10.66 5c4.01-.36 8.14.9 11.34 3.76" />
<path d="M16.85 11.25a10 10 0 012.22 1.68" />
<path d="M5 13a10 10 0 015.24-2.76" />
<line x1="12" y1="20" x2="12.01" y2="20" />
</svg>

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 515 B

+3 -3
View File
@@ -9,8 +9,8 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M5 12.55a11 11 0 0 1 14.08 0" />
<path d="M1.42 9a16 16 0 0 1 21.16 0" />
<path d="M8.53 16.11a6 6 0 0 1 6.95 0" />
<path d="M5 13a10 10 0 0114 0" />
<path d="M8.5 16.5a5 5 0 017 0" />
<path d="M2 8.82a15 15 0 0120 0" />
<line x1="12" y1="20" x2="12.01" y2="20" />
</svg>

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 365 B

+14
View File
@@ -0,0 +1,14 @@
const esModules = ['lodash-es'].join('|');
module.exports = {
verbose: true,
roots: ['<rootDir>/src/', '<rootDir>/tests/'],
moduleFileExtensions: ['js'],
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
transform: {
'^.+\\.js$': 'babel-jest',
},
};
+4
View File
@@ -0,0 +1,4 @@
[build]
base = "site/"
publish = "build/"
command = "yarn deploy"
+59 -5
View File
@@ -1,9 +1,63 @@
{
"private": true,
"name": "lucide",
"description": "Lucide is a community-run fork of Feather Icons, open for anyone to contribute icons.",
"version": "0.1.2",
"license": "ISC",
"amdName": "lucide",
"homepage": "https://lucide.netlify.app",
"url": "https://github.com/owner/project/issues",
"repository": "github:lucide-icons/lucide",
"source": "build/lucide.js",
"main": "dist/cjs/lucide.js",
"main:umd": "dist/umd/lucide.js",
"module": "dist/esm/lucide.js",
"unpkg": "dist/umd/lucide.min.js",
"sideEffects": false,
"scripts": {
"react:compile": "yarn workspace react compile"
"start": "babel-watch --watch src",
"clean": "rimraf lib && rimraf dist && rimraf build",
"build": "yarn clean && yarn build:move && yarn build:icons && yarn build:es && yarn build:bundles",
"build:move": "cp -av src build",
"build:icons": "npx babel-node ./scripts/buildIcons.js --presets @babel/env",
"build:es": "babel build -d dist/esm --ignore '**/*.test.js','**/__mocks__'",
"build:bundles": "rollup -c rollup.config.js",
"optimize": "npx babel-node ./scripts/optimizeSvgs.js --presets @babel/env",
"test": "jest"
},
"workspaces": [
"packages/react"
]
"devDependencies": {
"@ampproject/rollup-plugin-closure-compiler": "^0.25.2",
"@atomico/rollup-plugin-sizes": "^1.1.4",
"@babel/cli": "^7.10.5",
"@babel/core": "^7.11.1",
"@babel/node": "^7.10.5",
"@babel/preset-env": "^7.11.0",
"@rollup/plugin-babel": "^5.0.0",
"babel-jest": "^26.3.0",
"babel-plugin-add-import-extension": "^1.4.3",
"cheerio": "^1.0.0-rc.2",
"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",
"jest": "^26.4.2",
"lodash": "^4.17.19",
"prettier": "^1.8.2",
"rollup": "^2.7.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-license": "^2.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-terser": "^5.2.0",
"rollup-plugin-visualizer": "^4.1.0",
"svgo": "^1.3.2"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.11.5",
"core-js": "3",
"htmlparser2": "^4.1.0",
"lodash-es": "^4.17.15",
"prop-types": "^15.7.2"
}
}
-13
View File
@@ -1,13 +0,0 @@
{
"presets": [
[
"env",
{
"targets": {
"browsers": ["last 2 versions"]
}
}
],
"stage-2"
]
}
-2
View File
@@ -1,2 +0,0 @@
dist
coverage
@@ -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();
});
-19
View File
@@ -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));
-28
View File
@@ -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;
-10
View File
@@ -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));
-13
View File
@@ -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);
});
-25
View File
@@ -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
-18
View File
@@ -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),
);
});
-73
View File
@@ -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);
});
});
}
-67
View File
@@ -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>"`;
-28
View File
@@ -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();
});
-16
View File
@@ -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();
});
-8
View File
@@ -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();
});
-32
View File
@@ -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();
});
-21
View File
@@ -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();
});
-55
View File
@@ -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;
-10
View File
@@ -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;
}, {});
-5
View File
@@ -1,5 +0,0 @@
import icons from './icons';
import toSvg from './to-svg';
import replace from './replace';
module.exports = { icons, toSvg, replace };
-60
View File
@@ -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;
-30
View File
@@ -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;
-23
View File
@@ -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/,
},
],
},
};
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "react-featherity",
"name": "lucide-react",
"version": "1.0.0",
"description": "React component for Featherity icons",
"description": "React component for lucide icons",
"main": "src/index.js",
"typings": "src/index.d.ts",
"author": "John Letey",
+77
View File
@@ -0,0 +1,77 @@
import babel from '@rollup/plugin-babel';
import bundleSize from '@atomico/rollup-plugin-sizes';
import compiler from '@ampproject/rollup-plugin-closure-compiler';
import { terser } from 'rollup-plugin-terser';
import visualizer from 'rollup-plugin-visualizer';
import license from 'rollup-plugin-license';
import replace from 'rollup-plugin-replace';
import resolve from 'rollup-plugin-node-resolve';
import commonJS from 'rollup-plugin-commonjs';
import pkg from './package.json';
const outputFileName = pkg.name;
const inputs = ['build/lucide.js'];
const bundles = [
{
inputs,
format: 'umd',
dir: 'dist',
minify: true,
},
{
inputs,
format: 'umd',
dir: 'dist',
},
{
inputs,
format: 'cjs',
dir: 'dist',
},
];
const configs = bundles
.map(({ inputs, dir, format, minify }) =>
inputs.map(input => ({
input,
external: ['lodash/camelCase', 'lodash/upperFirst'],
plugins: [
replace({
'icons = {}': 'icons = allIcons',
delimiters: ['', ''],
}),
babel({
babelHelpers: 'bundled',
}),
// The two minifiers together seem to procude a smaller bundle 🤷‍♂️
minify && compiler(),
minify && terser(),
license({
banner: `${pkg.name} v${pkg.version} - ${pkg.license}`,
}),
bundleSize(),
resolve(),
commonJS({
include: 'node_modules/**',
}),
visualizer({
sourcemap: true,
filename: `stats/${outputFileName}${minify ? '-min' : ''}.html`,
}),
].filter(Boolean),
output: {
name: 'lucide',
file: `${dir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
format,
sourcemap: true,
globals: {
'lodash/camelCase': 'camelCase',
'lodash/upperFirst': 'upperFirst',
},
},
})),
)
.flat();
export default configs;
+23
View File
@@ -0,0 +1,23 @@
import path from 'path';
import { generateComponentName, resetFile, appendFile } from '../helpers';
export default function(inputEntry, outputDirectory, componentGetter, iconNodes) {
const fileName = path.basename(inputEntry);
// Reset file
resetFile(fileName, outputDirectory);
const icons = Object.keys(iconNodes);
// Generate Import for Icon VNodes
icons.forEach(iconName => {
const componentName = generateComponentName(iconName);
const importString = `export { default as ${componentName} } from './${iconName}';\n`;
appendFile(importString, fileName, outputDirectory);
});
appendFile('\n', fileName, outputDirectory);
console.log(`Successfully generated ${fileName} file`);
}
+27
View File
@@ -0,0 +1,27 @@
/* eslint-disable import/no-extraneous-dependencies */
import fs from 'fs';
import path from 'path';
import prettier from 'prettier';
import { generateComponentName } from '../helpers';
export default function(iconNode, outputDirectory, template) {
const icons = Object.keys(iconNode);
const iconsDistDirectory = path.join(outputDirectory, `icons`);
if (!fs.existsSync(iconsDistDirectory)) {
fs.mkdirSync(iconsDistDirectory);
}
icons.forEach(icon => {
const location = path.join(iconsDistDirectory, `${icon}.js`);
const componentName = generateComponentName(icon);
const node = JSON.stringify(iconNode[icon]);
const elementTemplate = template({ componentName, node });
fs.writeFileSync(location, prettier.format(elementTemplate, { parser: 'babel' }), 'utf-8');
console.log('Successfully built', componentName);
});
}
+42
View File
@@ -0,0 +1,42 @@
import fs from 'fs';
import path from 'path';
import renderIconsObject from './render/renderIconsObject';
import renderIconNodes from './render/renderIconNodes';
import generateIconFiles from './build/generateIconFiles';
import generateExportsFile from './build/generateExportsFile';
import { readSvgDirectory } from './helpers';
const ICONS_DIR = path.resolve(__dirname, '../icons');
const OUTPUT_DIR = path.resolve(__dirname, '../build');
const SRC_DIR = path.resolve(__dirname, '../src');
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR);
}
const svgFiles = readSvgDirectory(ICONS_DIR);
const icons = renderIconsObject(svgFiles, ICONS_DIR);
const iconVNodes = renderIconNodes(icons);
// Generates iconsNodes files for each icon
generateIconFiles(
iconVNodes,
OUTPUT_DIR,
({ componentName, node }) => `
const ${componentName} = ${node};
export default ${componentName};
`,
);
// Generates entry files for the compiler filled with icons exports
generateExportsFile(
path.join(SRC_DIR, 'icons/index.js'),
path.join(OUTPUT_DIR, 'icons'),
'getElement',
iconVNodes,
);
+74
View File
@@ -0,0 +1,74 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { upperFirst, camelCase } from 'lodash/string';
import fs from 'fs';
import path from 'path';
/**
* Generates a componentName of a String.
*
* @param {string} iconName
*/
export const generateComponentName = iconName =>
iconName === 'github' ? 'GitHub' : upperFirst(camelCase(iconName));
/**
* Resets the file contents.
*
* @param {string} fileName
* @param {string} outputDirectory
*/
export const resetFile = (fileName, outputDirectory) =>
fs.writeFileSync(path.join(outputDirectory, fileName), '', 'utf-8');
/**
* Reads the file contents.
*
* @param {string} path
*/
export const readFile = entry => fs.readFileSync(path.resolve(__dirname, '../', entry), 'utf-8');
/**
* append content to a file
*
* @param {string} content
* @param {string} fileName
* @param {string} outputDirectory
*/
export const appendFile = (content, fileName, outputDirectory) =>
fs.appendFileSync(path.join(outputDirectory, fileName), content, 'utf-8');
/**
* writes content to a file
*
* @param {string} content
* @param {string} fileName
* @param {string} outputDirectory
*/
export const writeFile = (content, fileName, outputDirectory) =>
fs.writeFileSync(path.join(outputDirectory, fileName), content, 'utf-8');
/**
* reads the icon directory
*
* @param {string} directory
*/
export const readSvgDirectory = directory =>
fs.readdirSync(directory).filter(file => path.extname(file) === '.svg');
/**
* Read svg from directory
*
* @param {string} fileName
* @param {string} directory
*/
export const readSvg = (fileName, directory) => fs.readFileSync(path.join(directory, fileName));
/**
* writes content to a file
*
* @param {string} fileName
* @param {string} outputDirectory
* @param {string} content
*/
export const writeSvgFile = (fileName, outputDirectory, content) =>
fs.appendFileSync(path.join(outputDirectory, fileName), content, 'utf-8');
+15
View File
@@ -0,0 +1,15 @@
import fs from 'fs';
import path from 'path';
import processSvg from './render/processSvg';
import { readSvgDirectory, writeSvgFile } from './helpers';
const ICONS_DIR = path.resolve(__dirname, '../icons');
console.log(`Optimizing SVGs...`);
const svgFiles = readSvgDirectory(ICONS_DIR);
svgFiles.forEach(svgFile => {
const content = fs.readFileSync(path.join(ICONS_DIR, svgFile));
processSvg(content).then(svg => writeSvgFile(svg, ICONS_DIR, content));
});
@@ -1,8 +1,9 @@
/* eslint-disable import/no-extraneous-dependencies */
import Svgo from 'svgo';
import cheerio from 'cheerio';
import { format } from 'prettier';
import DEFAULT_ATTRS from '../src/default-attrs.json';
import DEFAULT_ATTRS from './default-attrs.json';
/**
* Process SVG string.
@@ -48,9 +49,7 @@ function optimize(svg) {
function setAttrs(svg) {
const $ = cheerio.load(svg);
Object.keys(DEFAULT_ATTRS).forEach(key =>
$('svg').attr(key, DEFAULT_ATTRS[key]),
);
Object.keys(DEFAULT_ATTRS).forEach(key => $('svg').attr(key, DEFAULT_ATTRS[key]));
return $('body').html();
}
+29
View File
@@ -0,0 +1,29 @@
/* eslint-disable import/no-extraneous-dependencies */
import { parseDOM } from 'htmlparser2';
import DEFAULT_ATTRS from './default-attrs.json';
export default iconsObject => {
const iconNodes = {};
Object.keys(iconsObject).forEach(icon => {
const svgString = iconsObject[icon];
const dom = parseDOM(svgString);
const children = dom.map(element => [
element.name,
{
...element.attribs,
},
]);
iconNodes[icon] = [
'svg',
{
...DEFAULT_ATTRS,
},
children,
];
});
return iconNodes;
};
@@ -1,26 +1,8 @@
/* eslint-disable import/no-extraneous-dependencies */
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;
}, {});
}
import { readSvg } from '../helpers';
/**
* Get contents between opening and closing `<svg>` tags.
@@ -29,7 +11,25 @@ function buildIconsObject(svgFiles, getSvg) {
*/
function getSvgContents(svg) {
const $ = cheerio.load(svg);
return minify($('svg').html(), { collapseWhitespace: true });
}
export default buildIconsObject;
/**
* 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}
*/
export default (svgFiles, iconsDirectory) =>
svgFiles
.map(svgFile => {
const name = path.basename(svgFile, '.svg');
const svg = readSvg(svgFile, iconsDirectory);
const contents = getSvgContents(svg);
return { name, contents };
})
.reduce((icons, icon) => {
icons[icon.name] = icon.contents;
return icons;
}, {});
+3
View File
@@ -0,0 +1,3 @@
{
"presets": ["next/babel"]
}
+1
View File
@@ -0,0 +1 @@
.next
+7
View File
@@ -0,0 +1,7 @@
module.exports = {
testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/../../node_modules/babel-jest',
},
};
+2
View File
@@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

Some files were not shown because too many files have changed in this diff Show More