Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 762cf32666 | |||
| 216f42cdcb | |||
| b80c2805b2 | |||
| d80a267c81 | |||
| 07fa908631 | |||
| 1bdf6febac | |||
| 78e1057515 | |||
| 9d6d0c340d | |||
| 77f3f49ce7 | |||
| a55620d6ba | |||
| dad9648e20 | |||
| b3b39afb95 | |||
| 4406cbaea0 | |||
| 11c6a2e917 | |||
| 8b5278437a | |||
| c84fcfe3cb | |||
| 058c40a1ec | |||
| 6dad37a1b5 | |||
| 85d3bb9b82 | |||
| dee5d33bcd | |||
| a26745a3be | |||
| 9550ec28b8 | |||
| 845d6add1f | |||
| 06972942cd | |||
| d33b6674f3 | |||
| 70be911f69 | |||
| 6f06e05a47 | |||
| 8a15bca8cd | |||
| 5aef4e6110 | |||
| e1cead9531 | |||
| c686c1a0c3 | |||
| af87274bf4 | |||
| e3e4514dcc |
@@ -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
|
||||
@@ -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",
|
||||
@@ -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
|
||||
@@ -1,6 +1,12 @@
|
||||
.DS_Store
|
||||
.next
|
||||
.now
|
||||
node_modules
|
||||
dist
|
||||
build
|
||||
/lib
|
||||
sandbox
|
||||
stash
|
||||
coverage
|
||||
coverage
|
||||
stats
|
||||
*.log
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.github
|
||||
packages
|
||||
stats
|
||||
node_modules
|
||||
tests
|
||||
scripts
|
||||
site
|
||||
@@ -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,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
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# Featherity
|
||||
# Lucide
|
||||
|
||||

|
||||
[](https://www.npmjs.com/package/lucide)
|
||||
[](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).
|
||||
|
||||
@@ -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'],
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -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.
|
||||

|
||||
3. On the “Grid” tab, select `Rectangular Grid` and click “New Grid”.
|
||||

|
||||
4. Set the Grid Units to `px` and set Spacing X and Spacing Y both to 1.
|
||||

|
||||
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.
|
||||

|
||||
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`.
|
||||

|
||||
|
||||
## Saving A File
|
||||
|
||||
1. When ready to save the file, click Save As and select “Optimized SVG” as the file type.
|
||||

|
||||
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.
|
||||

|
||||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
[build]
|
||||
base = "site/"
|
||||
publish = "build/"
|
||||
command = "yarn deploy"
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": ["last 2 versions"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"stage-2"
|
||||
]
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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,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,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,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/,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
@@ -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`);
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
@@ -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');
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}, {});
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["next/babel"]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.next
|
||||
@@ -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',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||