Lucide 0.15.0 (#272)
* add configs
* Add vue components
* Add documentation
* add alpha release version
* improve npm ignore files
* add tests
* Make style and class attrs work
* 📦 bump version
* Add Icon suffix for component names
* bump version
* Add icon component example
* remove space
* add new build strategy
* Write a better intro
* add other node design
* fix
* add new default template
* add tempalte
* improve code
* small improvements
* small improvements
* move files
* Connect lucide with lucide-react
* Add support for vue
* Add licenses to packages
* Fix tests
* refactor build scripts
* Minor code fixes
* update homepage readme
* Update footer text
* Add a better introduction to packages
* Split up in tempaltes
* Add new types build file
* Setup workflow file
* update readme
* update
* Fix build
* remove debug code
* Add check if svgs have duplicated children
* Add check if their are no children
* small fixes
* last fixes in the build
* Move script to packages folder
* Fix tests and add types for lucide
* Add rule to package.json
* add types in build
* add npm ignore
* update package.jsons
9
.github/workflows/font.yml
vendored
@@ -20,13 +20,9 @@ jobs:
|
|||||||
- name: Install FontForge
|
- name: Install FontForge
|
||||||
run: sudo apt-get install zlib1g-dev fontforge
|
run: sudo apt-get install zlib1g-dev fontforge
|
||||||
|
|
||||||
- name: Install NodeJS and Yarn
|
|
||||||
run: sudo apt-get install nodejs yarn
|
|
||||||
|
|
||||||
- name: Clone sfnt2woff-zopfli repo
|
- name: Clone sfnt2woff-zopfli repo
|
||||||
run: git clone https://github.com/bramstein/sfnt2woff-zopfli.git sfnt2woff-zopfli
|
run: git clone https://github.com/bramstein/sfnt2woff-zopfli.git sfnt2woff-zopfli
|
||||||
|
|
||||||
|
|
||||||
- name: Install and move sfnt2woff-zopfli
|
- name: Install and move sfnt2woff-zopfli
|
||||||
run: |
|
run: |
|
||||||
cd sfnt2woff-zopfli
|
cd sfnt2woff-zopfli
|
||||||
@@ -36,7 +32,6 @@ jobs:
|
|||||||
- name: Clone woff2
|
- name: Clone woff2
|
||||||
run: git clone --recursive https://github.com/google/woff2.git
|
run: git clone --recursive https://github.com/google/woff2.git
|
||||||
|
|
||||||
|
|
||||||
- name: Install woff2
|
- name: Install woff2
|
||||||
run: |
|
run: |
|
||||||
cd woff2
|
cd woff2
|
||||||
@@ -47,16 +42,14 @@ jobs:
|
|||||||
run: sudo gem install fontcustom
|
run: sudo gem install fontcustom
|
||||||
|
|
||||||
- name: Install "outline-stroke"
|
- name: Install "outline-stroke"
|
||||||
run: sudo yarn add svg-outline-stroke svgson
|
run: sudo yarn add svg-outline-stroke -W
|
||||||
|
|
||||||
- name: "Outline SVG"
|
- name: "Outline SVG"
|
||||||
run: mkdir converted_icons && node scripts/outline_svg.js
|
run: mkdir converted_icons && node scripts/outline_svg.js
|
||||||
|
|
||||||
|
|
||||||
- name: Build 'Lucide'
|
- name: Build 'Lucide'
|
||||||
run: echo "Building Lucide font" && fontcustom compile ./converted_icons -h -n Lucide -o build -F
|
run: echo "Building Lucide font" && fontcustom compile ./converted_icons -h -n Lucide -o build -F
|
||||||
|
|
||||||
|
|
||||||
- name: Zip 'Lucide'
|
- name: Zip 'Lucide'
|
||||||
run: zip -r Lucide.zip build
|
run: zip -r Lucide.zip build
|
||||||
|
|
||||||
|
|||||||
194
.github/workflows/release.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Release to NPM
|
name: Release Packages
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -6,94 +6,150 @@ on:
|
|||||||
- 'v*'
|
- 'v*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
pre-build:
|
||||||
if: github.repository == 'lucide-icons/lucide'
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
env:
|
VERSION: ${{ steps.get_version.outputs.VERSION }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
YARN_CACHE_DIR: ${{ steps.get_version.outputs.YARN_CACHE_DIR }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Get the version
|
- name: Get the version
|
||||||
id: get_version
|
id: get_version
|
||||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/\v}
|
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/\v}
|
||||||
|
|
||||||
|
- name: Get yarn cache directory path
|
||||||
|
id: yarn-cache-dir-path
|
||||||
|
run: echo "::set-output name=YARN_CACHE_DIR::$(yarn cache dir)"
|
||||||
|
|
||||||
|
lucide:
|
||||||
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: pre-build
|
||||||
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
clean: true
|
node-version: '12.x'
|
||||||
|
|
||||||
- name: Set Auth Token
|
- uses: actions/cache@v2
|
||||||
run: npm config set //registry.npmjs.org/:_authToken ${{ secrets.NPM_TOKEN }}
|
id: yarn-cache
|
||||||
|
with:
|
||||||
|
path: ${{ needs.pre-build.outputs.YARN_CACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-yarn-
|
||||||
|
|
||||||
# Build lucide
|
- name: Install dependencies
|
||||||
- name: Install Dependencies Lucide
|
if: steps.yarn-cache.outputs.cache-hit != 'true'
|
||||||
run: yarn --pure-lockfile
|
run: yarn --pure-lockfile
|
||||||
|
|
||||||
- name: Build lucide package
|
- name: Set new version
|
||||||
run: yarn build
|
run: yarn workspace lucide version --new-version ${{ needs.pre-build.outputs.VERSION }} --no-git-tag-version
|
||||||
|
|
||||||
- name: Test lucide package
|
- name: Build
|
||||||
run: yarn test
|
run: yarn workspace lucide build
|
||||||
|
|
||||||
# Build lucide-react
|
- name: Test
|
||||||
- name: Install Dependencies lucide-react
|
run: yarn workspace lucide test
|
||||||
run: yarn --pure-lockfile
|
|
||||||
working-directory: packages/lucide-react
|
|
||||||
|
|
||||||
- name: Build lucide-react
|
- name: Publish
|
||||||
run: yarn build
|
run: yarn workspace lucide publish
|
||||||
working-directory: packages/lucide-react
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
- name: Test lucide-react
|
|
||||||
run: yarn test
|
|
||||||
working-directory: packages/lucide-react
|
|
||||||
|
|
||||||
# Build lucide-vue
|
|
||||||
- name: Install Dependencies lucide-vue
|
|
||||||
run: yarn --pure-lockfile
|
|
||||||
working-directory: packages/lucide-vue
|
|
||||||
|
|
||||||
- name: Build lucide-vue
|
|
||||||
run: yarn build
|
|
||||||
working-directory: packages/lucide-vue
|
|
||||||
|
|
||||||
- name: Test lucide-vue
|
|
||||||
run: yarn test
|
|
||||||
working-directory: packages/lucide-vue
|
|
||||||
|
|
||||||
# Publish lucide
|
|
||||||
- name: Set package.json version lucide
|
|
||||||
run: yarn version --new-version ${{ steps.get_version.outputs.VERSION }} --no-git-tag-version
|
|
||||||
|
|
||||||
- name: publish lucide
|
|
||||||
run: yarn publish
|
|
||||||
|
|
||||||
# Publish lucide-react
|
|
||||||
- name: Set package.json version lucide-react
|
|
||||||
run: yarn version --new-version ${{ steps.get_version.outputs.VERSION }} --no-git-tag-version
|
|
||||||
working-directory: packages/lucide-react
|
|
||||||
|
|
||||||
- name: publish lucide-react
|
|
||||||
run: yarn publish
|
|
||||||
working-directory: packages/lucide-react
|
|
||||||
|
|
||||||
# Publish lucide-vue
|
|
||||||
- name: Set package.json version lucide-vue
|
|
||||||
run: yarn version --new-version ${{ steps.get_version.outputs.VERSION }} --no-git-tag-version
|
|
||||||
working-directory: packages/lucide-vue
|
|
||||||
|
|
||||||
- name: publish lucide-vue
|
|
||||||
run: yarn publish
|
|
||||||
working-directory: packages/lucide-vue
|
|
||||||
|
|
||||||
- name: Commit package.json
|
- name: Commit package.json
|
||||||
run: |
|
run: |
|
||||||
git add package.json
|
git add packages/lucide/package.json
|
||||||
git add packages/lucide-react/package.json
|
|
||||||
git add packages/lucide-vue/package.json
|
|
||||||
git -c user.name="Lucide Bot" -c user.email="lucide-bot@users.noreply.github.com" \
|
git -c user.name="Lucide Bot" -c user.email="lucide-bot@users.noreply.github.com" \
|
||||||
commit -m ":package: Bump version to ${{ steps.get_version.outputs.VERSION }}" --no-verify --quiet
|
commit -m ":package: Bump version lucide to ${{ needs.pre-build.outputs.VERSION }}" --no-verify --quiet
|
||||||
git remote set-url --push origin https://lucide-bot:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git
|
git remote set-url --push origin https://lucide-bot:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git
|
||||||
git push origin HEAD:master
|
git push origin HEAD:master
|
||||||
|
|
||||||
|
lucide-react:
|
||||||
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: pre-build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '12.x'
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
id: yarn-cache
|
||||||
|
with:
|
||||||
|
path: ${{ needs.pre-build.outputs.YARN_CACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-yarn-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: steps.yarn-cache.outputs.cache-hit != 'true'
|
||||||
|
run: yarn --pure-lockfile
|
||||||
|
|
||||||
|
- name: Set package.json version lucide
|
||||||
|
run: yarn workspace lucide-react version --new-version ${{ needs.pre-build.outputs.VERSION }} --no-git-tag-version
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: yarn workspace lucide-react build
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: yarn workspace lucide-react test
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
run: yarn workspace lucide-react publish
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
|
- name: Commit package.json
|
||||||
|
run: |
|
||||||
|
git add packages/lucide-react/package.json
|
||||||
|
git -c user.name="Lucide Bot" -c user.email="lucide-bot@users.noreply.github.com" \
|
||||||
|
commit -m ":package: Bump version lucide-react to ${{ needs.pre-build.outputs.VERSION }}" --no-verify --quiet
|
||||||
|
git remote set-url --push origin https://lucide-bot:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git
|
||||||
|
git push origin HEAD:master
|
||||||
|
|
||||||
|
lucide-vue:
|
||||||
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: pre-build
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '12.x'
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
id: yarn-cache
|
||||||
|
with:
|
||||||
|
path: ${{ needs.pre-build.outputs.YARN_CACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-yarn-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: steps.yarn-cache.outputs.cache-hit != 'true'
|
||||||
|
run: yarn --pure-lockfile
|
||||||
|
|
||||||
|
- name: Set new version
|
||||||
|
run: yarn workspace lucide-vue version --new-version ${{ needs.pre-build.outputs.VERSION }} --no-git-tag-version
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: yarn workspace lucide-vue build
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: yarn workspace lucide-vue test
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
run: yarn workspace lucide-vue publish
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
|
- name: Commit package.json
|
||||||
|
run: |
|
||||||
|
git add packages/lucide-vue/package.json
|
||||||
|
git -c user.name="Lucide Bot" -c user.email="lucide-bot@users.noreply.github.com" \
|
||||||
|
commit -m ":package: Bump version lucide-vue to ${{ needs.pre-build.outputs.VERSION }}" --no-verify --quiet
|
||||||
|
git remote set-url --push origin https://lucide-bot:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git
|
||||||
|
git push origin HEAD:master
|
||||||
|
|||||||
3
.gitignore
vendored
@@ -4,10 +4,9 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
build
|
build
|
||||||
/lib
|
|
||||||
sandbox
|
sandbox
|
||||||
stash
|
stash
|
||||||
coverage
|
coverage
|
||||||
stats
|
stats
|
||||||
*.log
|
*.log
|
||||||
index.d.ts
|
packages/**/src/icons/*.js
|
||||||
|
|||||||
166
README.md
@@ -9,6 +9,15 @@
|
|||||||
## What is Lucide?
|
## What is Lucide?
|
||||||
|
|
||||||
Lucide is a community-run fork of [Feather Icons](https://github.com/feathericons/feather), open for anyone to contribute icons.
|
Lucide is a community-run fork of [Feather Icons](https://github.com/feathericons/feather), open for anyone to contribute icons.
|
||||||
|
Started after growing disaffection of the moderation of the [Feather Icons](https://github.com/feathericons/feather) project, with over 300+ open issues and over 100+ open PRs, this project is no longer maintained. The owner of the project stopped merging icons and want to keep the project like it now is. Hundreds of developers/designer wasted their time trying to contribute, what a shame.
|
||||||
|
|
||||||
|
We're trying to expanding the icon set as much as possible while keeping it nice-looking, we do it as a community of devs and designers, join us!
|
||||||
|
|
||||||
|
### Why choose Lucide over Feather Icons
|
||||||
|
|
||||||
|
- Lucide already expended the icon set by 130+ in less then a year, so more icons to work with.
|
||||||
|
- Well maintained code base.
|
||||||
|
- Active community.
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
@@ -16,38 +25,14 @@ Lucide is a community-run fork of [Feather Icons](https://github.com/feathericon
|
|||||||
* [Package managers](#package-managers)
|
* [Package managers](#package-managers)
|
||||||
* [CDN](#cdn)
|
* [CDN](#cdn)
|
||||||
* [Usage](#usage)
|
* [Usage](#usage)
|
||||||
* [Unpkg](#with-unpkg)
|
* [Web](#web)
|
||||||
* [ESModules](#with-esmodules)
|
* [React](#react)
|
||||||
* [Options](#additional-options)
|
* [Vue](#vue)
|
||||||
* [Treeshake library](#treeshake-the-library-only-use-the-icons-you-use)
|
|
||||||
* [Custom binding](#custom-element-binding)
|
|
||||||
* [React](#with-react)
|
|
||||||
* [Vue](#with-vue)
|
|
||||||
* [Figma](#figma)
|
* [Figma](#figma)
|
||||||
* [Contributing](#contributing)
|
* [Contributing](#contributing)
|
||||||
* [Community](#community)
|
* [Community](#community)
|
||||||
* [License](#license)
|
* [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
|
## Usage
|
||||||
|
|
||||||
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)
|
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)
|
||||||
@@ -55,104 +40,23 @@ At its core, Lucide is a collection of [SVG](https://svgontheweb.com/#svg) files
|
|||||||
The following are additional ways you can use Lucide.
|
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 the Javascript library you can easily incorporate the icon you want in your webpage.
|
||||||
|
|
||||||
### With unpkg
|
### Web
|
||||||
|
|
||||||
Here is a complete example with unpkg
|
Implementation of the lucide icon library for web applications.
|
||||||
|
|
||||||
```html
|
```sh
|
||||||
<!DOCTYPE html>
|
npm install lucide
|
||||||
<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>
|
#or
|
||||||
<script>
|
|
||||||
lucide.createIcons();
|
yarn add lucide
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### With ESModules
|
For more details, see the [documentation](https://github.com/lucide-icons/lucide/blob/master/packages/lucide-react/README.md).
|
||||||
|
|
||||||
To reduce bundle size, lucide is built to be fully treeshakable.
|
### React
|
||||||
The `createIcons` function will search for HTMLElements with the attribute `icon-name` and replace it with the svg from the given icon name.
|
|
||||||
|
|
||||||
```html
|
Implementation of the lucide icon library for react applications.
|
||||||
<!-- Your HTML file -->
|
|
||||||
<i icon-name="menu"></i>
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { createIcons, icons } from 'lucide';
|
|
||||||
|
|
||||||
// Caution, 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', // attribute for the icon name.
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Treeshake 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);
|
|
||||||
```
|
|
||||||
|
|
||||||
### With React
|
|
||||||
|
|
||||||
You can also use the Lucide library using the react package.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yarn add lucide-react
|
yarn add lucide-react
|
||||||
@@ -162,11 +66,11 @@ yarn add lucide-react
|
|||||||
npm install lucide-react
|
npm install lucide-react
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details, see the [documentation](https://github.com/lucide-icons/lucide/blob/master/packages/lucide-react/README.md).
|
For more details, see the [documentation](https://github.com/lucide-icons/lucide/tree/master/packages/lucide-react#lucide-react).
|
||||||
|
|
||||||
### With Vue
|
### Vue
|
||||||
|
|
||||||
You can also use the Lucide library using the Vue package.
|
Implementation of the lucide icon library for vue applications.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yarn add lucide-vue
|
yarn add lucide-vue
|
||||||
@@ -176,11 +80,15 @@ yarn add lucide-vue
|
|||||||
npm install lucide-vue
|
npm install lucide-vue
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details, see the [documentation](https://github.com/lucide-icons/lucide/blob/master/packages/lucide-vue/README.md).
|
For more details, see the [documentation](https://github.com/lucide-icons/lucide/tree/master/packages/lucide-vue#lucide-vue).
|
||||||
|
|
||||||
### Figma
|
### Figma
|
||||||
|
|
||||||
You can use the components from [this Figma file](https://www.figma.com/file/g0UipfQlRfGrntKPxZknM7/Featherity).
|
The lucide figma plugin.
|
||||||
|
|
||||||
|
Visit [Figma community page](https://www.figma.com/community/plugin/939567362549682242/Lucide-Icons) to install the plugin.
|
||||||
|
|
||||||
|
<img width="420" src="https://www.figma.com/community/plugin/939567362549682242/thumbnail" alt="Figma Lucide Cover">
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -194,10 +102,10 @@ Join the community on our [Discord](https://discord.gg/EH6nSts) server!
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Lucide is licensed under the [ISC License](https://github.com/lucide-icons/lucide/blob/master/LICENSE).
|
Lucide is totally free for commercial use and personally use, this software is licensed under the [ISC License](https://github.com/lucide-icons/lucide/blob/master/LICENSE).
|
||||||
|
|
||||||
<p align="center">
|
## Sponsors
|
||||||
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss">
|
|
||||||
<img src="./site/public/vercel.svg" alt="Powered by Vercel" width="200" />
|
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss">
|
||||||
</a>
|
<img src="./site/public/vercel.svg" alt="Powered by Vercel" width="200" />
|
||||||
</p>
|
</a>
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: ['@babel/env'],
|
||||||
[
|
|
||||||
'@babel/env',
|
|
||||||
{
|
|
||||||
loose: true,
|
|
||||||
modules: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
env: {
|
env: {
|
||||||
test: {
|
test: {
|
||||||
presets: ['@babel/env'],
|
presets: ['@babel/env'],
|
||||||
|
|||||||
@@ -1 +1,15 @@
|
|||||||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="2" y="6" width="20" height="12" rx="2"/><circle cx="12" cy="12" r="2"/><path d="M6 12h.01M18 12h.01"/></svg>
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<rect x="2" y="6" width="20" height="12" rx="2" />
|
||||||
|
<circle cx="12" cy="12" r="2" />
|
||||||
|
<path d="M6 12h.01M18 12h.01" />
|
||||||
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 252 B After Width: | Height: | Size: 331 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 455 B After Width: | Height: | Size: 455 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 347 B |
@@ -11,6 +11,6 @@
|
|||||||
>
|
>
|
||||||
<path d="M4 22h14a2 2 0 002-2V7.5L14.5 2H6a2 2 0 00-2 2v4" />
|
<path d="M4 22h14a2 2 0 002-2V7.5L14.5 2H6a2 2 0 00-2 2v4" />
|
||||||
<path d="M14 2v6h6" />
|
<path d="M14 2v6h6" />
|
||||||
<path d="M2 15l10-0" />
|
<path d="M2 15h10" />
|
||||||
<path d="M9 18l3-3-3-3" />
|
<path d="M9 18l3-3-3-3" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 350 B |
@@ -11,6 +11,6 @@
|
|||||||
>
|
>
|
||||||
<path d="M4 22h14a2 2 0 002-2V7.5L14.5 2H6a2 2 0 00-2 2v4" />
|
<path d="M4 22h14a2 2 0 002-2V7.5L14.5 2H6a2 2 0 00-2 2v4" />
|
||||||
<path d="M14 2v6h6" />
|
<path d="M14 2v6h6" />
|
||||||
<path d="M2 15l10-0" />
|
<path d="M2 15h10" />
|
||||||
<path d="M5 12l-3 3 3 3" />
|
<path d="M5 12l-3 3 3 3" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 351 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 347 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 304 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 321 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
viewBox="0 0 24 24"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 282 B |
@@ -1,5 +0,0 @@
|
|||||||
[build]
|
|
||||||
base = "site/"
|
|
||||||
publish = "build/"
|
|
||||||
command = "yarn deploy"
|
|
||||||
ignore = "git diff --quiet origin/master HEAD ../icons ../site"
|
|
||||||
57
package.json
@@ -1,67 +1,50 @@
|
|||||||
{
|
{
|
||||||
"name": "lucide",
|
"private": true,
|
||||||
"description": "Lucide is a community-run fork of Feather Icons, open for anyone to contribute icons.",
|
"workspaces": [
|
||||||
"version": "0.14.0",
|
"packages/*",
|
||||||
"license": "ISC",
|
"site"
|
||||||
"homepage": "https://lucide.dev",
|
],
|
||||||
"bugs": "https://github.com/lucide-icons/lucide/issues",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/lucide-icons/lucide.git"
|
|
||||||
},
|
|
||||||
"amdName": "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": {
|
"scripts": {
|
||||||
"start": "babel-watch --watch src",
|
"build": "yarn lucide build && yarn lucide-react build && yarn lucide-vue build",
|
||||||
"clean": "rimraf dist && rimraf build && rimraf index.d.ts",
|
"test": "yarn lucide build:icons && yarn lucide-react build:icons && yarn lucide-vue build:icons && jest",
|
||||||
"build": "yarn clean && yarn build:move && yarn build:icons && yarn build:dts && yarn build:es && yarn build:bundles",
|
"lucide": "yarn workspace lucide",
|
||||||
"build:move": "cp -av src build",
|
"lucide-react": "yarn workspace lucide-react",
|
||||||
"build:icons": "npx babel-node ./scripts/buildIcons.js --presets @babel/env",
|
"lucide-vue": "yarn workspace lucide-vue",
|
||||||
"build:dts": "npx babel-node ./scripts/buildDts.js --presets @babel/env",
|
"build:icons": "babel-node ./scripts/buildIcons.js --presets @babel/env",
|
||||||
"build:es": "babel build -d dist/esm",
|
"optimize": "babel-node ./scripts/optimizeSvgs.js --presets @babel/env",
|
||||||
"build:bundles": "rollup -c rollup.config.js",
|
"addtags": "babel-node ./scripts/addMissingKeysToTags.js --presets @babel/env"
|
||||||
"optimize": "npx babel-node ./scripts/optimizeSvgs.js --presets @babel/env",
|
|
||||||
"addtags": "npx babel-node ./scripts/addMissingKeysToTags.js --presets @babel/env",
|
|
||||||
"test": "jest"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ampproject/rollup-plugin-closure-compiler": "^0.25.2",
|
"@ampproject/rollup-plugin-closure-compiler": "^0.25.2",
|
||||||
"@atomico/rollup-plugin-sizes": "^1.1.4",
|
"@atomico/rollup-plugin-sizes": "^1.1.4",
|
||||||
"@babel/cli": "^7.10.5",
|
"@babel/cli": "^7.10.5",
|
||||||
"@babel/core": "^7.11.1",
|
"@babel/core": "^7.11.1",
|
||||||
"@babel/node": "^7.10.5",
|
"@babel/node": "^7.13.10",
|
||||||
"@babel/plugin-transform-runtime": "^7.11.5",
|
"@babel/plugin-transform-runtime": "^7.11.5",
|
||||||
"@babel/preset-env": "^7.11.0",
|
"@babel/preset-env": "^7.11.0",
|
||||||
"@rollup/plugin-babel": "^5.0.0",
|
"@rollup/plugin-babel": "^5.0.0",
|
||||||
"babel-jest": "^26.3.0",
|
"@rollup/plugin-commonjs": "^17.1.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^11.2.0",
|
||||||
|
"@rollup/plugin-replace": "^2.4.1",
|
||||||
|
"babel-jest": "^26.6.3",
|
||||||
"babel-plugin-add-import-extension": "^1.4.3",
|
"babel-plugin-add-import-extension": "^1.4.3",
|
||||||
"cheerio": "^1.0.0-rc.2",
|
|
||||||
"core-js": "3",
|
"core-js": "3",
|
||||||
"eslint": "^4.19.1",
|
"eslint": "^4.19.1",
|
||||||
"eslint-config-airbnb-base": "^12.1.0",
|
"eslint-config-airbnb-base": "^12.1.0",
|
||||||
"eslint-config-prettier": "^2.9.0",
|
"eslint-config-prettier": "^2.9.0",
|
||||||
"eslint-plugin-import": "^2.5.0",
|
"eslint-plugin-import": "^2.5.0",
|
||||||
"eslint-plugin-prettier": "^2.5.0",
|
"eslint-plugin-prettier": "^2.5.0",
|
||||||
"html-minifier": "^3.5.8",
|
|
||||||
"htmlparser2": "^4.1.0",
|
|
||||||
"husky": "^4.3.6",
|
"husky": "^4.3.6",
|
||||||
"jest": "^26.4.2",
|
"jest": "^26.4.2",
|
||||||
"lint-staged": "^10.5.3",
|
"lint-staged": "^10.5.3",
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
"prettier": "1.17.1",
|
"prettier": "1.17.1",
|
||||||
"rollup": "^2.7.3",
|
"rollup": "^2.7.3",
|
||||||
"rollup-plugin-commonjs": "^10.1.0",
|
|
||||||
"rollup-plugin-license": "^2.0.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-terser": "^5.2.0",
|
||||||
"rollup-plugin-visualizer": "^4.1.0",
|
"rollup-plugin-visualizer": "^4.1.0",
|
||||||
"svgo": "^1.3.2"
|
"svgo": "^1.3.2",
|
||||||
|
"svgson": "^4.1.0"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "lucide-figma",
|
"name": "lucide-figma",
|
||||||
"version": "0.13.0",
|
"version": "0.13.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
"private": true,
|
||||||
"main": "build/ui.js",
|
"main": "build/ui.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --mode=production",
|
"build": "webpack --mode=production",
|
||||||
|
|||||||
15
packages/lucide-react/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
ISC License
|
||||||
|
|
||||||
|
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
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
# Lucide React
|
# Lucide React
|
||||||
|
|
||||||
Use the lucide icon library in you react app.
|
Implementation of the lucide icon library for react applications.
|
||||||
|
|
||||||
|
> What is lucide? Read it [here](https://github.com/lucide-icons/lucide#what-is-lucide).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
const mainConfig = require('../../babel.config');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['react-app'],
|
presets: ['react-app'],
|
||||||
|
env: mainConfig.env,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
const fs = require("fs")
|
|
||||||
const path = require("path")
|
|
||||||
const srcDirectory = path.join(__dirname, "dist")
|
|
||||||
|
|
||||||
// Declare type definitions
|
|
||||||
const typeDefinitions = `
|
|
||||||
/// <reference types="react" />
|
|
||||||
import { SVGAttributes } from 'react'
|
|
||||||
|
|
||||||
// Create interface extending SVGAttributes
|
|
||||||
export interface LucideProps extends Partial<React.SVGProps<SVGSVGElement>> {
|
|
||||||
color?: string
|
|
||||||
size?: string | number
|
|
||||||
stroke?: string | number
|
|
||||||
strokeWidth?: string | number
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generated icons
|
|
||||||
`
|
|
||||||
|
|
||||||
// Write type definitions to file
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.join(srcDirectory, "index.d.ts"),
|
|
||||||
typeDefinitions,
|
|
||||||
"utf-8",
|
|
||||||
)
|
|
||||||
|
|
||||||
const iconsFolder = "./build/icons"
|
|
||||||
fs.readdir(iconsFolder, (err, files) => {
|
|
||||||
|
|
||||||
files.forEach(file => {
|
|
||||||
|
|
||||||
const fileName = file.replace(".js", "")
|
|
||||||
|
|
||||||
// Convert fileName to component name
|
|
||||||
const componentName = fileName.split("-")
|
|
||||||
.map(word => word[0].toUpperCase() + word.substr(1, word.length))
|
|
||||||
.join("")
|
|
||||||
|
|
||||||
// Declare component type
|
|
||||||
const exportTypeString = `export declare const ${componentName}: (props: LucideProps) => JSX.Element;\n`
|
|
||||||
|
|
||||||
// Add component to the types file
|
|
||||||
fs.appendFileSync(
|
|
||||||
path.join(srcDirectory, "index.d.ts"),
|
|
||||||
exportTypeString,
|
|
||||||
"utf-8",
|
|
||||||
)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log("Generated index.d.ts file with", files.length, "icons")
|
|
||||||
|
|
||||||
})
|
|
||||||
@@ -3,9 +3,6 @@ module.exports = {
|
|||||||
roots: ['<rootDir>/src/', '<rootDir>/tests/'],
|
roots: ['<rootDir>/src/', '<rootDir>/tests/'],
|
||||||
moduleFileExtensions: ['js'],
|
moduleFileExtensions: ['js'],
|
||||||
transformIgnorePatterns: [`/node_modules`],
|
transformIgnorePatterns: [`/node_modules`],
|
||||||
moduleNameMapper: {
|
|
||||||
'^@/(.*)$': '<rootDir>/src/$1',
|
|
||||||
},
|
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.js$': 'babel-jest',
|
'^.+\\.js$': 'babel-jest',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,14 +16,13 @@
|
|||||||
"main:umd": "dist/umd/lucide-react.js",
|
"main:umd": "dist/umd/lucide-react.js",
|
||||||
"module": "dist/esm/lucide-react.js",
|
"module": "dist/esm/lucide-react.js",
|
||||||
"unpkg": "dist/umd/lucide-react.min.js",
|
"unpkg": "dist/umd/lucide-react.min.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist/lucide-react.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn clean && yarn build:move && yarn build:icons && yarn build:es && yarn build:types && yarn build:bundles",
|
"build": "yarn clean && yarn build:icons && yarn build:es && yarn build:types && yarn build:bundles",
|
||||||
"clean": "rm -rf dist && rm -rf build",
|
"clean": "rm -rf dist && rm -rf ./src/icons/*.js",
|
||||||
"build:move": "cp -av src build",
|
"build:icons": "yarn --cwd ../../ build:icons --output=../packages/lucide-react/src --templateSrc=../packages/lucide-react/scripts/exportTemplate --renderUniqueKey",
|
||||||
"build:icons": "yarn --cwd ../../ build:icons --output=../packages/lucide-react/build --templateSrc=../packages/lucide-react/scripts/exportTemplate --camelizeAttrs --noDefaultAttrs --renderUniqueKey",
|
"build:es": "yarn --cwd ../../ babel packages/lucide-react/src -d packages/lucide-react/dist/esm",
|
||||||
"build:types": "node build-types.js",
|
"build:types": "yarn --cwd ../../ babel-node packages/lucide-react/scripts/buildTypes.js",
|
||||||
"build:es": "yarn --cwd ../../ babel packages/lucide-react/build -d packages/lucide-react/dist/esm",
|
|
||||||
"build:bundles": "yarn --cwd ../../ rollup -c packages/lucide-react/rollup.config.js",
|
"build:bundles": "yarn --cwd ../../ rollup -c packages/lucide-react/rollup.config.js",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const plugins = require('../../rollup.plugins');
|
import plugins from '../../rollup.plugins';
|
||||||
const pkg = require('./package.json');
|
import pkg from './package.json';
|
||||||
|
|
||||||
const packageName = 'LucideReact';
|
const packageName = 'LucideReact';
|
||||||
const outputFileName = 'lucide-react';
|
const outputFileName = 'lucide-react';
|
||||||
const rootDir = 'packages/lucide-react'; // It runs from the root
|
const rootDir = 'packages/lucide-react'; // It runs from the root
|
||||||
const outputDir = `${rootDir}/dist`;
|
const outputDir = `${rootDir}/dist`;
|
||||||
const inputs = [`${rootDir}/build/lucide-react.js`];
|
const inputs = [`${rootDir}/src/lucide-react.js`];
|
||||||
const bundles = [
|
const bundles = [
|
||||||
{
|
{
|
||||||
format: 'umd',
|
format: 'umd',
|
||||||
@@ -30,7 +30,7 @@ const configs = bundles
|
|||||||
inputs.map(input => ({
|
inputs.map(input => ({
|
||||||
input,
|
input,
|
||||||
plugins: plugins(pkg, minify),
|
plugins: plugins(pkg, minify),
|
||||||
external: ['react', 'prop-types'],
|
external: ['react', 'prop-types', 'lucide'],
|
||||||
output: {
|
output: {
|
||||||
name: packageName,
|
name: packageName,
|
||||||
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||||
@@ -39,6 +39,7 @@ const configs = bundles
|
|||||||
globals: {
|
globals: {
|
||||||
react: 'react',
|
react: 'react',
|
||||||
'prop-types': 'PropTypes',
|
'prop-types': 'PropTypes',
|
||||||
|
lucide: 'lucide',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
|
|||||||
44
packages/lucide-react/scripts/buildTypes.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import {
|
||||||
|
writeFile,
|
||||||
|
readSvgDirectory,
|
||||||
|
resetFile,
|
||||||
|
toPascalCase,
|
||||||
|
appendFile,
|
||||||
|
} from '../../../scripts/helpers';
|
||||||
|
|
||||||
|
const srcDirectory = path.join(__dirname, '../dist');
|
||||||
|
|
||||||
|
// Declare type definitions
|
||||||
|
const typeDefinitions = `\
|
||||||
|
/// <reference types="react" />
|
||||||
|
import { SVGAttributes } from 'react'
|
||||||
|
|
||||||
|
// Create interface extending SVGAttributes
|
||||||
|
export interface LucideProps extends Partial<React.SVGProps<SVGSVGElement>> {
|
||||||
|
color?: string
|
||||||
|
size?: string | number
|
||||||
|
stroke?: string | number
|
||||||
|
strokeWidth?: string | number
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generated icons
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ICONS_DIR = path.resolve(__dirname, '../../../icons');
|
||||||
|
const TYPES_FILE = 'lucide-react.d.ts';
|
||||||
|
|
||||||
|
resetFile(TYPES_FILE, srcDirectory);
|
||||||
|
writeFile(typeDefinitions, TYPES_FILE, srcDirectory);
|
||||||
|
|
||||||
|
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||||
|
|
||||||
|
svgFiles.forEach(svgFile => {
|
||||||
|
const iconName = path.basename(svgFile, '.svg');
|
||||||
|
const componentName = toPascalCase(iconName);
|
||||||
|
|
||||||
|
const exportTypeString = `export declare const ${componentName}: (props: LucideProps) => JSX.Element;\n`;
|
||||||
|
appendFile(exportTypeString, TYPES_FILE, srcDirectory);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Generated ${TYPES_FILE} file with`, svgFiles.length, 'icons');
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
export default ({ componentName, node }) => `
|
export default ({ componentName, children }) => `
|
||||||
import createReactComponent from '../createReactComponent';
|
import createReactComponent from '../createReactComponent';
|
||||||
import defaultAttributes from '../defaultAttributes';
|
|
||||||
|
|
||||||
const ${componentName} = createReactComponent('${componentName}', ['svg', defaultAttributes, ${node}]);
|
const ${componentName} = createReactComponent('${componentName}', ${JSON.stringify(children)});
|
||||||
|
|
||||||
export default ${componentName};
|
export default ${componentName};
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
import { forwardRef, createElement } from 'react';
|
import { forwardRef, createElement } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import defaultAttributes from './defaultAttributes';
|
||||||
|
|
||||||
export default (iconName, [tag, attrs, children]) => {
|
export default (iconName, iconNode) => {
|
||||||
const Component = forwardRef(
|
const Component = forwardRef(
|
||||||
({ color = 'currentColor', size = 24, strokeWidth = 2, ...rest }, ref) =>
|
({ color = 'currentColor', size = 24, strokeWidth = 2, ...rest }, ref) =>
|
||||||
createElement(
|
createElement(
|
||||||
tag,
|
'svg',
|
||||||
{
|
{
|
||||||
ref,
|
ref,
|
||||||
...attrs,
|
...defaultAttributes,
|
||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
stroke: color,
|
stroke: color,
|
||||||
strokeWidth,
|
strokeWidth,
|
||||||
...rest,
|
...rest,
|
||||||
},
|
},
|
||||||
children.map(([childTag, childAttrs]) => createElement(childTag, childAttrs)),
|
iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
1
packages/lucide-react/src/icons/.gitkeep
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Folder for generated icons
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
/*
|
|
||||||
Icons exports.
|
|
||||||
|
|
||||||
Will be generated
|
|
||||||
*/
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
import { Grid } from '..'
|
import { Grid } from '../src/icons'
|
||||||
|
|
||||||
describe('Using lucide icon components', () => {
|
describe('Using lucide icon components', () => {
|
||||||
it('should render an component', () => {
|
it('should render an component', () => {
|
||||||
|
|||||||
15
packages/lucide-vue/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
ISC License
|
||||||
|
|
||||||
|
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
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
# Lucide Vue
|
# Lucide Vue
|
||||||
|
|
||||||
Use the lucide icon library in you Vue app.
|
Implementation of the lucide icon library for Vue applications.
|
||||||
|
|
||||||
|
> What is lucide? Read it [here](https://github.com/lucide-icons/lucide#what-is-lucide).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ module.exports = {
|
|||||||
'^.+\\.vue$': 'vue-jest',
|
'^.+\\.vue$': 'vue-jest',
|
||||||
},
|
},
|
||||||
transformIgnorePatterns: [`/node_modules`],
|
transformIgnorePatterns: [`/node_modules`],
|
||||||
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
|
snapshotSerializers: ['jest-serializer-vue'],
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'^@/(.*)$': '<rootDir>/src/$1',
|
'^@/(.*)$': '<rootDir>/src/$1',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,19 +21,16 @@
|
|||||||
"vue": "^2.6.12"
|
"vue": "^2.6.12"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn clean && yarn build:move && yarn build:icons && yarn build:es && yarn build:bundles",
|
"build": "yarn clean && yarn build:icons && yarn build:es && yarn build:bundles",
|
||||||
"clean": "rm -rf dist && rm -rf build",
|
"clean": "rm -rf dist && rm -rf ./src/icons/*.js",
|
||||||
"build:move": "cp -av src build",
|
"build:icons": "yarn --cwd ../../ build:icons --output=../packages/lucide-vue/src --templateSrc=../packages/lucide-vue/scripts/exportTemplate",
|
||||||
"build:icons": "yarn --cwd ../../ build:icons --output=../packages/lucide-vue/build --templateSrc=../packages/lucide-vue/scripts/exportTemplate --noDefaultAttrs",
|
"build:es": "yarn --cwd ../../ babel packages/lucide-vue/src -d packages/lucide-vue/dist/esm",
|
||||||
"build:es": "yarn --cwd ../../ babel packages/lucide-vue/build -d packages/lucide-vue/dist/esm",
|
|
||||||
"build:bundles": "yarn --cwd ../../ rollup -c packages/lucide-vue/rollup.config.js",
|
"build:bundles": "yarn --cwd ../../ rollup -c packages/lucide-vue/rollup.config.js",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:watch": "jest --watchAll"
|
"test:watch": "jest --watchAll"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/test-utils": "^1.1.2",
|
"@vue/test-utils": "^1.1.2",
|
||||||
"babel-jest": "^26.6.3",
|
|
||||||
"jest": "^26.6.3",
|
|
||||||
"jest-serializer-vue": "^2.0.2",
|
"jest-serializer-vue": "^2.0.2",
|
||||||
"vue-jest": "^3.0.7",
|
"vue-jest": "^3.0.7",
|
||||||
"vue-template-compiler": "^2.6.12"
|
"vue-template-compiler": "^2.6.12"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const plugins = require('../../rollup.plugins');
|
import plugins from '../../rollup.plugins';
|
||||||
const pkg = require('./package.json');
|
import pkg from './package.json';
|
||||||
|
|
||||||
const packageName = 'LucideVue';
|
const packageName = 'LucideVue';
|
||||||
const outputFileName = 'lucide-vue';
|
const outputFileName = 'lucide-vue';
|
||||||
const rootDir = 'packages/lucide-vue'; // It runs from the root
|
const rootDir = 'packages/lucide-vue'; // It runs from the root
|
||||||
const outputDir = `${rootDir}/dist`;
|
const outputDir = `${rootDir}/dist`;
|
||||||
const inputs = [`${rootDir}/build/lucide-vue.js`];
|
const inputs = [`${rootDir}/src/lucide-vue.js`];
|
||||||
const bundles = [
|
const bundles = [
|
||||||
{
|
{
|
||||||
format: 'umd',
|
format: 'umd',
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
export default ({ componentName, node }) => `
|
export default ({ componentName, children }) => `
|
||||||
import createVueComponent from '../createVueComponent';
|
import createVueComponent from '../createVueComponent';
|
||||||
import defaultAttributes from '../defaultAttributes';
|
|
||||||
|
|
||||||
const ${componentName} = createVueComponent('${componentName}Icon', ['svg', defaultAttributes, ${node}]);
|
const ${componentName} = createVueComponent('${componentName}Icon', ${JSON.stringify(children)});
|
||||||
|
|
||||||
export default ${componentName};
|
export default ${componentName};
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export default (iconName, [tag, defaultAttrs, children]) => ({
|
import defaultAttributes from './defaultAttributes';
|
||||||
|
|
||||||
|
export default (iconName, iconNode) => ({
|
||||||
name: iconName,
|
name: iconName,
|
||||||
functional: true,
|
functional: true,
|
||||||
props: {
|
props: {
|
||||||
@@ -27,13 +29,13 @@ export default (iconName, [tag, defaultAttrs, children]) => ({
|
|||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
return createElement(
|
return createElement(
|
||||||
tag,
|
'svg',
|
||||||
{
|
{
|
||||||
// eslint-disable-next-line prettier/prettier
|
// eslint-disable-next-line prettier/prettier
|
||||||
class: [defaultClass, data.class, data.staticClass, data.attrs && data.attrs.class].filter(Boolean),
|
class: [defaultClass, data.class, data.staticClass, data.attrs && data.attrs.class].filter(Boolean),
|
||||||
style: [data.style, data.staticStyle, data.attrs && data.attrs.style].filter(Boolean),
|
style: [data.style, data.staticStyle, data.attrs && data.attrs.style].filter(Boolean),
|
||||||
attrs: {
|
attrs: {
|
||||||
...defaultAttrs,
|
...defaultAttributes,
|
||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
stroke: color,
|
stroke: color,
|
||||||
@@ -41,7 +43,7 @@ export default (iconName, [tag, defaultAttrs, children]) => ({
|
|||||||
...data.attrs,
|
...data.attrs,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
children.map(([childTag, childAttrs]) => createElement(childTag, { attrs: childAttrs })),
|
iconNode.map(([tag, attrs]) => createElement(tag, { attrs })),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
1
packages/lucide-vue/src/icons/.gitkeep
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Folder for generated icons
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
/*
|
|
||||||
Icons exports.
|
|
||||||
|
|
||||||
Will be generated
|
|
||||||
*/
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import { Smile } from '..'
|
import { Smile } from '../src/icons'
|
||||||
|
|
||||||
describe('Using lucide icon components', () => {
|
describe('Using lucide icon components', () => {
|
||||||
it('should render an component', () => {
|
it('should render an component', () => {
|
||||||
|
|||||||
1
packages/lucide/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
src/icons/*.js
|
||||||
10
packages/lucide/.npmignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
stats
|
||||||
|
node_modules
|
||||||
|
tests
|
||||||
|
scripts
|
||||||
|
build
|
||||||
|
src
|
||||||
|
babel.config.js
|
||||||
|
jest.config.js
|
||||||
|
rollup.config.js
|
||||||
|
yarn.error.log
|
||||||
15
packages/lucide/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
ISC License
|
||||||
|
|
||||||
|
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
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
120
packages/lucide/README.md
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
# Lucide
|
||||||
|
|
||||||
|
Implementation of the lucide icon library for web applications.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
### 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 built to be fully treeshakable.
|
||||||
|
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';
|
||||||
|
|
||||||
|
// Caution, 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', // attribute for the icon name.
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Treeshake 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);
|
||||||
|
```
|
||||||
14
packages/lucide/babel.config.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const mainConfig = require('../../babel.config');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
'@babel/env',
|
||||||
|
{
|
||||||
|
loose: true,
|
||||||
|
modules: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
env: mainConfig.env,
|
||||||
|
};
|
||||||
@@ -5,9 +5,6 @@ module.exports = {
|
|||||||
roots: ['<rootDir>/src/', '<rootDir>/tests/'],
|
roots: ['<rootDir>/src/', '<rootDir>/tests/'],
|
||||||
moduleFileExtensions: ['js'],
|
moduleFileExtensions: ['js'],
|
||||||
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
|
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
|
||||||
moduleNameMapper: {
|
|
||||||
'^@/(.*)$': '<rootDir>/src/$1',
|
|
||||||
},
|
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.js$': 'babel-jest',
|
'^.+\\.js$': 'babel-jest',
|
||||||
},
|
},
|
||||||
30
packages/lucide/package.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "lucide",
|
||||||
|
"description": "Lucide is a community-run fork of Feather Icons, open for anyone to contribute icons.",
|
||||||
|
"version": "0.14.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"homepage": "https://lucide.dev",
|
||||||
|
"bugs": "https://github.com/lucide-icons/lucide/issues",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/lucide-icons/lucide.git",
|
||||||
|
"directory": "packages/lucide"
|
||||||
|
},
|
||||||
|
"amdName": "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",
|
||||||
|
"typings": "dist/lucide.d.ts",
|
||||||
|
"sideEffects": false,
|
||||||
|
"scripts": {
|
||||||
|
"build": "yarn clean && yarn build:icons && yarn build:es && yarn build:types && yarn build:bundles",
|
||||||
|
"clean": "rm -rf dist && rm -rf ./src/icons/*.js",
|
||||||
|
"build:icons": "yarn --cwd ../../ build:icons --output=../packages/lucide/src",
|
||||||
|
"build:es": "babel src -d dist/esm",
|
||||||
|
"build:types": "yarn --cwd ../../ babel-node packages/lucide/scripts/buildTypes.js",
|
||||||
|
"build:bundles": "rollup -c rollup.config.js",
|
||||||
|
"test": "jest"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
const plugins = require('./rollup.plugins');
|
import plugins from '../../rollup.plugins';
|
||||||
const pkg = require('./package.json');
|
import pkg from './package.json';
|
||||||
|
|
||||||
const outputFileName = pkg.name;
|
const outputFileName = pkg.name;
|
||||||
const outputDir = 'dist';
|
const outputDir = 'dist';
|
||||||
const inputs = ['build/lucide.js'];
|
const inputs = ['src/lucide.js'];
|
||||||
const bundles = [
|
const bundles = [
|
||||||
{
|
{
|
||||||
format: 'umd',
|
format: 'umd',
|
||||||
@@ -38,4 +38,4 @@ const configs = bundles
|
|||||||
)
|
)
|
||||||
.flat();
|
.flat();
|
||||||
|
|
||||||
module.exports = configs;
|
export default configs;
|
||||||
37
packages/lucide/scripts/buildTypes.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
import { readSvgDirectory, resetFile, appendFile, toPascalCase } from '../../../scripts/helpers';
|
||||||
|
|
||||||
|
const TARGET_DIR = path.join(__dirname, '../dist');
|
||||||
|
const ICONS_DIR = path.resolve(__dirname, '../../../icons');
|
||||||
|
const TYPES_FILE_NAME = 'lucide.d.ts';
|
||||||
|
|
||||||
|
// Generates header of d.ts file include some types and functions
|
||||||
|
const typeDefinitions = `\
|
||||||
|
export type IconName = string;
|
||||||
|
export type IconNode = readonly [tag: string, object:SVGProps<SVGSVGElement>, children:IconNode?];
|
||||||
|
export type IconsObj = { [IconName]: IconNode }
|
||||||
|
|
||||||
|
export interface Attributes extends Partial<Props<Element>> {}
|
||||||
|
|
||||||
|
export function createElement(icon: IconNode): SVGSVGElement;
|
||||||
|
export function createIcons({ icons: IconsObj, nameAttr: string = 'icon-name', attrs: Attributes = {} }): VoidFunction;
|
||||||
|
|
||||||
|
export declare const icons: IconsObj;
|
||||||
|
|
||||||
|
// Generated icons
|
||||||
|
`;
|
||||||
|
|
||||||
|
resetFile(TYPES_FILE_NAME, TARGET_DIR);
|
||||||
|
appendFile(typeDefinitions, TYPES_FILE_NAME, TARGET_DIR);
|
||||||
|
|
||||||
|
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||||
|
|
||||||
|
svgFiles.forEach(svgFile => {
|
||||||
|
const nameSvg = path.basename(svgFile, '.svg');
|
||||||
|
const namePascal = toPascalCase(nameSvg);
|
||||||
|
|
||||||
|
appendFile(`export declare const ${namePascal}: IconNode;\n`, TYPES_FILE_NAME, TARGET_DIR);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`Generated ${TYPES_FILE_NAME} file with`, svgFiles.length, 'icons');
|
||||||
@@ -5,7 +5,7 @@ export default {
|
|||||||
viewBox: '0 0 24 24',
|
viewBox: '0 0 24 24',
|
||||||
fill: 'none',
|
fill: 'none',
|
||||||
stroke: 'currentColor',
|
stroke: 'currentColor',
|
||||||
strokeWidth: 2,
|
'stroke-width': 2,
|
||||||
strokeLinecap: 'round',
|
'stroke-linecap': 'round',
|
||||||
strokeLinejoin: 'round',
|
'stroke-linejoin': 'round',
|
||||||
};
|
};
|
||||||
1
packages/lucide/src/icons/.gitkeep
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Folder for generated icons
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import replaceElement from './replaceElement';
|
import replaceElement from './replaceElement';
|
||||||
import * as allIcons from './icons/index';
|
import * as allIcons from './icons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces all elements with matching nameAttr with the defined icons
|
* Replaces all elements with matching nameAttr with the defined icons
|
||||||
@@ -34,4 +34,4 @@ export { default as createElement } from './createElement';
|
|||||||
Icons exports.
|
Icons exports.
|
||||||
*/
|
*/
|
||||||
export { allIcons as icons };
|
export { allIcons as icons };
|
||||||
export * from './icons/index';
|
export * from './icons';
|
||||||
@@ -17,6 +17,7 @@ export const getAttrs = element =>
|
|||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
*/
|
*/
|
||||||
export const getClassNames = attrs => {
|
export const getClassNames = attrs => {
|
||||||
|
if (typeof attrs === 'string') return attrs;
|
||||||
if (!attrs || !attrs.class) return '';
|
if (!attrs || !attrs.class) return '';
|
||||||
if (attrs.class && typeof attrs.class === 'string') {
|
if (attrs.class && typeof attrs.class === 'string') {
|
||||||
return attrs.class.split(' ');
|
return attrs.class.split(' ');
|
||||||
@@ -38,6 +39,7 @@ export const combineClassNames = arrayOfClassnames => {
|
|||||||
return classNameArray
|
return classNameArray
|
||||||
.map(classItem => classItem.trim())
|
.map(classItem => classItem.trim())
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
.filter((value, index, self) => self.indexOf(value) === index)
|
||||||
.join(' ');
|
.join(' ');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,23 +65,21 @@ export default (element, { nameAttr, icons, attrs }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const elementAttrs = getAttrs(element);
|
const elementAttrs = getAttrs(element);
|
||||||
|
const [tag, iconAttributes, children] = iconNode;
|
||||||
|
|
||||||
const [, iconAttrs] = iconNode;
|
const iconAttrs = {
|
||||||
|
...iconAttributes,
|
||||||
const allAttrs = {
|
'icon-name': iconName,
|
||||||
...iconAttrs,
|
|
||||||
...attrs,
|
...attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
iconNode[1] = { ...allAttrs };
|
const classNames = combineClassNames(['lucide', elementAttrs, attrs]);
|
||||||
|
|
||||||
const classNames = combineClassNames([iconAttrs, elementAttrs, attrs]);
|
|
||||||
|
|
||||||
if (classNames) {
|
if (classNames) {
|
||||||
iconNode[1].class = classNames;
|
iconAttrs.class = classNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
const svgElement = createElement(iconNode);
|
const svgElement = createElement([tag, iconAttrs, children]);
|
||||||
|
|
||||||
return element.parentNode.replaceChild(svgElement, element);
|
return element.parentNode.replaceChild(svgElement, element);
|
||||||
};
|
};
|
||||||
5
packages/lucide/tests/__snapshots__/lucide.spec.js.snap
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`createIcons should add custom attributes 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"black\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" icon-name=\\"volume-2\\" class=\\"lucide icon custom-class\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M19.07 4.93a10 10 0 010 14.14M15.54 8.46a5 5 0 010 7.07\\"></path></svg>"`;
|
||||||
|
|
||||||
|
exports[`createIcons should read elements from DOM and replace it with icons 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\\" icon-name=\\"volume-2\\" class=\\"lucide\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M19.07 4.93a10 10 0 010 14.14M15.54 8.46a5 5 0 010 7.07\\"></path></svg>"`;
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`combineClassNames should retuns a string of classNames 1`] = `"item1 item2 item3 item4 item5 item6 item7 item8 item9"`;
|
exports[`combineClassNames should retuns a string of classNames 1`] = `"item item1 item2 item3 item4 item5 item6 item7 item8 item9"`;
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
import * as icons from './icons';
|
import * as icons from '../src/icons';
|
||||||
import { createIcons } from '../src/lucide';
|
import { createIcons } from '../src/lucide';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { minify } from 'html-minifier';
|
import { parseSync, stringify } from 'svgson';
|
||||||
|
|
||||||
const ICONS_DIR = path.resolve(__dirname, '../icons');
|
const ICONS_DIR = path.resolve(__dirname, '../../../icons');
|
||||||
|
|
||||||
const getOriginalSvg = (iconName) => {
|
const getOriginalSvg = (iconName) => {
|
||||||
const svgContent = fs.readFileSync(path.join(ICONS_DIR, `${iconName}.svg`), 'utf8');
|
const svgContent = fs.readFileSync(path.join(ICONS_DIR, `${iconName}.svg`), 'utf8');
|
||||||
|
const svgParsed = parseSync(svgContent);
|
||||||
|
|
||||||
return minify(svgContent, { collapseWhitespace: true, keepClosingSlash: true, });
|
svgParsed.attributes['icon-name'] = iconName;
|
||||||
|
svgParsed.attributes['class'] = 'lucide';
|
||||||
|
|
||||||
|
return stringify(svgParsed, { selfClose: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('createIcons', () => {
|
describe('createIcons', () => {
|
||||||
@@ -19,6 +23,8 @@ describe('createIcons', () => {
|
|||||||
createIcons({icons});
|
createIcons({icons});
|
||||||
|
|
||||||
const svg = getOriginalSvg('volume-2');
|
const svg = getOriginalSvg('volume-2');
|
||||||
|
|
||||||
|
expect(document.body.innerHTML).toBe(svg)
|
||||||
expect(document.body.innerHTML).toMatchSnapshot()
|
expect(document.body.innerHTML).toMatchSnapshot()
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,10 +42,10 @@ describe('createIcons', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should add custom attributes', () => {
|
it('should add custom attributes', () => {
|
||||||
document.body.innerHTML = `<i icon-name="volume-2"></i>`;
|
document.body.innerHTML = `<i icon-name="volume-2" class="lucide"></i>`;
|
||||||
|
|
||||||
const attrs = {
|
const attrs = {
|
||||||
class: 'icon custom-class',
|
class: 'lucide icon custom-class',
|
||||||
fill: 'black',
|
fill: 'black',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,6 +60,8 @@ describe('createIcons', () => {
|
|||||||
return acc;
|
return acc;
|
||||||
},{})
|
},{})
|
||||||
|
|
||||||
|
expect(document.body.innerHTML).toMatchSnapshot();
|
||||||
|
|
||||||
expect(attributesAndValues).toEqual(expect.objectContaining(attrs));
|
expect(attributesAndValues).toEqual(expect.objectContaining(attrs));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -44,6 +44,7 @@ describe('getClassNames', () => {
|
|||||||
describe('combineClassNames', () => {
|
describe('combineClassNames', () => {
|
||||||
it('should retuns a string of classNames', () => {
|
it('should retuns a string of classNames', () => {
|
||||||
const arrayOfClassnames = [
|
const arrayOfClassnames = [
|
||||||
|
'item',
|
||||||
{
|
{
|
||||||
class: ['item1','item2','item3']
|
class: ['item1','item2','item3']
|
||||||
},
|
},
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
const babel = require('@rollup/plugin-babel').default;
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
const bundleSize = require('@atomico/rollup-plugin-sizes');
|
import babel from '@rollup/plugin-babel';
|
||||||
const compiler = require('@ampproject/rollup-plugin-closure-compiler');
|
import bundleSize from '@atomico/rollup-plugin-sizes';
|
||||||
const { terser } = require('rollup-plugin-terser');
|
import compiler from '@ampproject/rollup-plugin-closure-compiler';
|
||||||
const visualizer = require('rollup-plugin-visualizer');
|
import { terser } from 'rollup-plugin-terser';
|
||||||
const license = require('rollup-plugin-license');
|
import visualizer from 'rollup-plugin-visualizer';
|
||||||
const replace = require('rollup-plugin-replace');
|
import license from 'rollup-plugin-license';
|
||||||
const resolve = require('rollup-plugin-node-resolve');
|
import replace from '@rollup/plugin-replace';
|
||||||
const commonJS = require('rollup-plugin-commonjs');
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
|
import commonJS from '@rollup/plugin-commonjs';
|
||||||
|
|
||||||
const plugins = (pkg, minify) =>
|
const plugins = (pkg, minify) =>
|
||||||
[
|
[
|
||||||
replace({
|
replace({
|
||||||
'icons = {}': 'icons = allIcons',
|
'icons = {}': 'icons = allIcons',
|
||||||
delimiters: ['', ''],
|
delimiters: ['', ''],
|
||||||
|
preventAssignment: false,
|
||||||
}),
|
}),
|
||||||
babel({
|
babel({
|
||||||
babelHelpers: 'bundled',
|
babelHelpers: 'bundled',
|
||||||
@@ -34,4 +36,4 @@ const plugins = (pkg, minify) =>
|
|||||||
}),
|
}),
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
|
||||||
module.exports = plugins;
|
export default plugins;
|
||||||
|
|||||||
@@ -4,24 +4,28 @@ import path from 'path';
|
|||||||
import prettier from 'prettier';
|
import prettier from 'prettier';
|
||||||
import { toPascalCase } from '../helpers';
|
import { toPascalCase } from '../helpers';
|
||||||
|
|
||||||
export default function(iconNode, outputDirectory, template) {
|
export default function(iconNodes, outputDirectory, template, { showLog = true }) {
|
||||||
const icons = Object.keys(iconNode);
|
const icons = Object.keys(iconNodes);
|
||||||
const iconsDistDirectory = path.join(outputDirectory, `icons`);
|
const iconsDistDirectory = path.join(outputDirectory, `icons`);
|
||||||
|
|
||||||
if (!fs.existsSync(iconsDistDirectory)) {
|
if (!fs.existsSync(iconsDistDirectory)) {
|
||||||
fs.mkdirSync(iconsDistDirectory);
|
fs.mkdirSync(iconsDistDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
icons.forEach(icon => {
|
icons.forEach(iconName => {
|
||||||
const location = path.join(iconsDistDirectory, `${icon}.js`);
|
const location = path.join(iconsDistDirectory, `${iconName}.js`);
|
||||||
const componentName = toPascalCase(icon);
|
const componentName = toPascalCase(iconName);
|
||||||
|
|
||||||
const node = JSON.stringify(iconNode[icon]);
|
let { children } = iconNodes[iconName];
|
||||||
|
children = children.map(({name, attributes}) => ([name, attributes]))
|
||||||
|
|
||||||
const elementTemplate = template({ componentName, node });
|
const elementTemplate = template({ componentName, iconName, children });
|
||||||
|
|
||||||
fs.writeFileSync(location, prettier.format(elementTemplate, { parser: 'babel' }), 'utf-8');
|
|
||||||
|
|
||||||
console.log('Successfully built', componentName);
|
fs.writeFileSync(location, prettier.format(elementTemplate, { singleQuote: true, trailingComma: 'all', parser: 'babel' }), 'utf-8');
|
||||||
|
|
||||||
|
if(showLog) {
|
||||||
|
console.log('Successfully built', componentName);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
import path from 'path';
|
|
||||||
|
|
||||||
import { readSvgDirectory, resetFile, appendFile, toPascalCase } from './helpers';
|
|
||||||
|
|
||||||
const ICONS_DIR = path.resolve(__dirname, '../icons');
|
|
||||||
const DTS_FILE_NAME = 'index.d.ts';
|
|
||||||
const DTS_FILE_ROOT = path.resolve(__dirname, '../');
|
|
||||||
|
|
||||||
resetFile(DTS_FILE_NAME, DTS_FILE_ROOT);
|
|
||||||
|
|
||||||
// Generates header of d.ts file include some types and functions
|
|
||||||
appendFile(
|
|
||||||
`
|
|
||||||
export type IconData = readonly [string, object, IconData?];
|
|
||||||
export type IconString = string;
|
|
||||||
|
|
||||||
export function createElement(ico: IconData): SVGSVGElement;
|
|
||||||
|
|
||||||
export declare const icons: { [key: string]: IconData };
|
|
||||||
|
|
||||||
// Generated icons
|
|
||||||
`,
|
|
||||||
DTS_FILE_NAME,
|
|
||||||
DTS_FILE_ROOT,
|
|
||||||
);
|
|
||||||
|
|
||||||
const svgFiles = readSvgDirectory(ICONS_DIR);
|
|
||||||
|
|
||||||
svgFiles.forEach(svgFile => {
|
|
||||||
const nameSvg = path.basename(svgFile, '.svg');
|
|
||||||
const namePascal = toPascalCase(nameSvg);
|
|
||||||
appendFile(`export declare const ${namePascal}: IconData;\n`, DTS_FILE_NAME, DTS_FILE_ROOT);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`Successfully generated '${DTS_FILE_NAME}'.`);
|
|
||||||
@@ -1,15 +1,12 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
import getArgumentOptions from 'minimist'; // eslint-disable-line import/no-extraneous-dependencies
|
||||||
import getArgumentOptions from 'minimist';
|
|
||||||
|
|
||||||
import renderIconsObject from './render/renderIconsObject';
|
import renderIconsObject from './render/renderIconsObject';
|
||||||
import renderIconNodes from './render/renderIconNodes';
|
|
||||||
import generateIconFiles from './build/generateIconFiles';
|
import generateIconFiles from './build/generateIconFiles';
|
||||||
import generateExportsFile from './build/generateExportsFile';
|
import generateExportsFile from './build/generateExportsFile';
|
||||||
import { readSvgDirectory } from './helpers';
|
|
||||||
|
|
||||||
/* eslint-disable import/no-dynamic-require */
|
import { readSvgDirectory } from './helpers';
|
||||||
|
|
||||||
const cliArguments = getArgumentOptions(process.argv.slice(2));
|
const cliArguments = getArgumentOptions(process.argv.slice(2));
|
||||||
|
|
||||||
@@ -23,26 +20,14 @@ if (!fs.existsSync(OUTPUT_DIR)) {
|
|||||||
|
|
||||||
const svgFiles = readSvgDirectory(ICONS_DIR);
|
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||||
|
|
||||||
const icons = renderIconsObject(svgFiles, ICONS_DIR);
|
const icons = renderIconsObject(svgFiles, ICONS_DIR, cliArguments.renderUniqueKey);
|
||||||
|
|
||||||
const iconVNodes = renderIconNodes(icons, cliArguments);
|
const defaultIconFileTemplate = './templates/defaultIconFileTemplate';
|
||||||
|
// eslint-disable-next-line import/no-dynamic-require
|
||||||
const defaultIconFileTemplate = ({ componentName, node }) => `
|
const iconFileTemplate = require(cliArguments.templateSrc || defaultIconFileTemplate).default;
|
||||||
const ${componentName} = ${node};
|
|
||||||
|
|
||||||
export default ${componentName};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const iconFileTemplate = cliArguments.templateSrc
|
|
||||||
? require(cliArguments.templateSrc).default
|
|
||||||
: defaultIconFileTemplate;
|
|
||||||
|
|
||||||
// Generates iconsNodes files for each icon
|
// Generates iconsNodes files for each icon
|
||||||
generateIconFiles(iconVNodes, OUTPUT_DIR, iconFileTemplate);
|
generateIconFiles(icons, OUTPUT_DIR, iconFileTemplate, { showLog: !cliArguments.silent });
|
||||||
|
|
||||||
// Generates entry files for the compiler filled with icons exports
|
// Generates entry files for the compiler filled with icons exports
|
||||||
generateExportsFile(
|
generateExportsFile(path.join(SRC_DIR, 'icons/index.js'), path.join(OUTPUT_DIR, 'icons'), icons);
|
||||||
path.join(SRC_DIR, 'icons/index.js'),
|
|
||||||
path.join(OUTPUT_DIR, 'icons'),
|
|
||||||
iconVNodes,
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts string to PascalCase
|
* Converts string to CamelCase
|
||||||
*
|
*
|
||||||
* @param {string} string
|
* @param {string} string
|
||||||
|
* @returns {string} A camelized string
|
||||||
*/
|
*/
|
||||||
export const toCamelCase = string =>
|
export const toCamelCase = string =>
|
||||||
string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) =>
|
string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) =>
|
||||||
@@ -15,6 +16,7 @@ export const toCamelCase = string =>
|
|||||||
* Converts string to PascalCase
|
* Converts string to PascalCase
|
||||||
*
|
*
|
||||||
* @param {string} string
|
* @param {string} string
|
||||||
|
* @returns {string} A pascalized string
|
||||||
*/
|
*/
|
||||||
export const toPascalCase = string => {
|
export const toPascalCase = string => {
|
||||||
const camelCase = toCamelCase(string);
|
const camelCase = toCamelCase(string);
|
||||||
@@ -23,9 +25,10 @@ export const toPascalCase = string => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts string to PascalCase
|
* Converts string to KebabCase
|
||||||
*
|
*
|
||||||
* @param {string} string
|
* @param {string} string
|
||||||
|
* @returns {string} A kebabized string
|
||||||
*/
|
*/
|
||||||
export const toKebabCase = string => string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
export const toKebabCase = string => string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
||||||
|
|
||||||
@@ -42,6 +45,7 @@ export const resetFile = (fileName, outputDirectory) =>
|
|||||||
* Reads the file contents.
|
* Reads the file contents.
|
||||||
*
|
*
|
||||||
* @param {string} path
|
* @param {string} path
|
||||||
|
* @returns {string} The contents of a file
|
||||||
*/
|
*/
|
||||||
export const readFile = entry => fs.readFileSync(path.resolve(__dirname, '../', entry), 'utf-8');
|
export const readFile = entry => fs.readFileSync(path.resolve(__dirname, '../', entry), 'utf-8');
|
||||||
|
|
||||||
@@ -69,6 +73,7 @@ export const writeFile = (content, fileName, outputDirectory) =>
|
|||||||
* reads the icon directory
|
* reads the icon directory
|
||||||
*
|
*
|
||||||
* @param {string} directory
|
* @param {string} directory
|
||||||
|
* @returns {array} An array of file paths containig svgs
|
||||||
*/
|
*/
|
||||||
export const readSvgDirectory = directory =>
|
export const readSvgDirectory = directory =>
|
||||||
fs.readdirSync(directory).filter(file => path.extname(file) === '.svg');
|
fs.readdirSync(directory).filter(file => path.extname(file) === '.svg');
|
||||||
@@ -79,7 +84,8 @@ export const readSvgDirectory = directory =>
|
|||||||
* @param {string} fileName
|
* @param {string} fileName
|
||||||
* @param {string} directory
|
* @param {string} directory
|
||||||
*/
|
*/
|
||||||
export const readSvg = (fileName, directory) => fs.readFileSync(path.join(directory, fileName));
|
export const readSvg = (fileName, directory) =>
|
||||||
|
fs.readFileSync(path.join(directory, fileName), 'utf-8');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* writes content to a file
|
* writes content to a file
|
||||||
@@ -91,7 +97,13 @@ export const readSvg = (fileName, directory) => fs.readFileSync(path.join(direct
|
|||||||
export const writeSvgFile = (fileName, outputDirectory, content) =>
|
export const writeSvgFile = (fileName, outputDirectory, content) =>
|
||||||
fs.writeFileSync(path.join(outputDirectory, fileName), content, 'utf-8');
|
fs.writeFileSync(path.join(outputDirectory, fileName), content, 'utf-8');
|
||||||
|
|
||||||
// This is a djb2 hashing function
|
/**
|
||||||
|
* djb2 hashing function
|
||||||
|
*
|
||||||
|
* @param {string} string
|
||||||
|
* @param {number} seed
|
||||||
|
* @returns {string} A hashed string of 6 characters
|
||||||
|
*/
|
||||||
export const hash = (string, seed = 5381) => {
|
export const hash = (string, seed = 5381) => {
|
||||||
let i = string.length;
|
let i = string.length;
|
||||||
|
|
||||||
@@ -103,3 +115,27 @@ export const hash = (string, seed = 5381) => {
|
|||||||
// eslint-disable-next-line no-bitwise
|
// eslint-disable-next-line no-bitwise
|
||||||
return (seed >>> 0).toString(36).substr(0, 6);
|
return (seed >>> 0).toString(36).substr(0, 6);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Hashed string based on name and attributes
|
||||||
|
*
|
||||||
|
* @param {object} seed
|
||||||
|
* @param {string} seed.name A name, for example an icon name
|
||||||
|
* @param {object} seed.attributes An object of SVGElement Attrbutes
|
||||||
|
* @returns {string} A hashed string of 6 characters
|
||||||
|
*/
|
||||||
|
export const generateHashedKey = ({ name, attributes }) => hash(JSON.stringify([name, attributes]));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if array of items contains duplicated items
|
||||||
|
*
|
||||||
|
* @param {array} children an array of items
|
||||||
|
* @returns {Boolean} if items contains duplicated items.
|
||||||
|
*/
|
||||||
|
export const hasDuplicatedChildren = children => {
|
||||||
|
const hashedKeys = children.map(generateHashedKey);
|
||||||
|
|
||||||
|
return !hashedKeys.every(
|
||||||
|
(key, index) => index === hashedKeys.findIndex(childKey => childKey === key),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const { promises: fs } = require("fs");
|
const { promises: fs } = require('fs');
|
||||||
const outlineStroke = require("svg-outline-stroke");
|
const outlineStroke = require('svg-outline-stroke');
|
||||||
const { parse, stringify } = require("svgson");
|
const { parse, stringify } = require('svgson');
|
||||||
|
|
||||||
const inputDir = `./icons/`;
|
const inputDir = `./icons/`;
|
||||||
const outputDir = `./converted_icons/`;
|
const outputDir = `./converted_icons/`;
|
||||||
@@ -8,19 +8,16 @@ const outputDir = `./converted_icons/`;
|
|||||||
async function init() {
|
async function init() {
|
||||||
try {
|
try {
|
||||||
const files = await fs.readdir(inputDir);
|
const files = await fs.readdir(inputDir);
|
||||||
for (let file of files) {
|
for (const file of files) {
|
||||||
const icon = await fs.readFile(`${inputDir}${file}`);
|
const icon = await fs.readFile(`${inputDir}${file}`);
|
||||||
const scaled = await parse(icon.toString(), {
|
const scaled = await parse(icon.toString(), {
|
||||||
transformNode: transformForward
|
transformNode: transformForward,
|
||||||
});
|
});
|
||||||
const outlined = await outlineStroke(stringify(scaled));
|
const outlined = await outlineStroke(stringify(scaled));
|
||||||
const outlinedWithoutAttrs = await parse(outlined, {
|
const outlinedWithoutAttrs = await parse(outlined, {
|
||||||
transformNode: transformBackwards
|
transformNode: transformBackwards,
|
||||||
});
|
});
|
||||||
await fs.writeFile(
|
await fs.writeFile(`${outputDir}${file}`, stringify(outlinedWithoutAttrs));
|
||||||
`${outputDir}${file}`,
|
|
||||||
stringify(outlinedWithoutAttrs)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -30,25 +27,25 @@ async function init() {
|
|||||||
init();
|
init();
|
||||||
|
|
||||||
function transformForward(node) {
|
function transformForward(node) {
|
||||||
if (node.name === "svg") {
|
if (node.name === 'svg') {
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
attributes: {
|
attributes: {
|
||||||
...node.attributes,
|
...node.attributes,
|
||||||
width: 960,
|
width: 960,
|
||||||
height: 960
|
height: 960,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformBackwards(node) {
|
function transformBackwards(node) {
|
||||||
if (node.name === "svg") {
|
if (node.name === 'svg') {
|
||||||
const { width, height, ...attributes } = node.attributes;
|
const { width, height, ...attributes } = node.attributes;
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
attributes
|
attributes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
@@ -1,30 +1,13 @@
|
|||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import Svgo from 'svgo';
|
import Svgo from 'svgo';
|
||||||
import cheerio from 'cheerio';
|
|
||||||
import { format } from 'prettier';
|
import { format } from 'prettier';
|
||||||
|
import { parseSync, stringify } from 'svgson';
|
||||||
import DEFAULT_ATTRS from './default-attrs.json';
|
import DEFAULT_ATTRS from './default-attrs.json';
|
||||||
|
|
||||||
/**
|
|
||||||
* Process SVG string.
|
|
||||||
* @param {string} svg - An SVG string.
|
|
||||||
* @param {Promise<string>}
|
|
||||||
*/
|
|
||||||
function processSvg(svg) {
|
|
||||||
return (
|
|
||||||
optimize(svg)
|
|
||||||
.then(setAttrs)
|
|
||||||
.then(optimizedSvg => format(optimizedSvg, { parser: 'babel' }))
|
|
||||||
// remove semicolon inserted by prettier
|
|
||||||
// because prettier thinks it's formatting JSX not HTML
|
|
||||||
.then(svg => svg.replace(/;/g, ''))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimize SVG with `svgo`.
|
* Optimize SVG with `svgo`.
|
||||||
* @param {string} svg - An SVG string.
|
* @param {string} svg - An SVG string.
|
||||||
* @returns {Promise<string>}
|
* @returns {Promise<string>} An optimized svg
|
||||||
*/
|
*/
|
||||||
function optimize(svg) {
|
function optimize(svg) {
|
||||||
const svgo = new Svgo({
|
const svgo = new Svgo({
|
||||||
@@ -42,14 +25,30 @@ function optimize(svg) {
|
|||||||
/**
|
/**
|
||||||
* Set default attibutes on SVG.
|
* Set default attibutes on SVG.
|
||||||
* @param {string} svg - An SVG string.
|
* @param {string} svg - An SVG string.
|
||||||
* @returns {string}
|
* @returns {string} An SVG string, included with the default attributes.
|
||||||
*/
|
*/
|
||||||
function setAttrs(svg) {
|
function setAttrs(svg) {
|
||||||
const $ = cheerio.load(svg);
|
const contents = parseSync(svg);
|
||||||
|
|
||||||
Object.keys(DEFAULT_ATTRS).forEach(key => $('svg').attr(key, DEFAULT_ATTRS[key]));
|
contents.attributes = DEFAULT_ATTRS;
|
||||||
|
|
||||||
return $('body').html();
|
return stringify(contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process SVG string.
|
||||||
|
* @param {string} svg An SVG string.
|
||||||
|
* @returns {Promise<string>} An optimized svg
|
||||||
|
*/
|
||||||
|
function processSvg(svg) {
|
||||||
|
return (
|
||||||
|
optimize(svg)
|
||||||
|
.then(setAttrs)
|
||||||
|
.then(optimizedSvg => format(optimizedSvg, { parser: 'babel' }))
|
||||||
|
// remove semicolon inserted by prettier
|
||||||
|
// because prettier thinks it's formatting JSX not HTML
|
||||||
|
.then(svg => svg.replace(/;/g, ''))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default processSvg;
|
export default processSvg;
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
/* eslint-disable import/no-extraneous-dependencies */
|
|
||||||
import { parseDOM } from 'htmlparser2';
|
|
||||||
import DEFAULT_ATTRS from './default-attrs.json';
|
|
||||||
import { toCamelCase, hash } from '../helpers';
|
|
||||||
|
|
||||||
const camelizeAttrs = attrs =>
|
|
||||||
Object.keys(attrs).reduce((newAttrs, attr) => {
|
|
||||||
const attrKey = toCamelCase(attr);
|
|
||||||
|
|
||||||
newAttrs[attrKey] = attrs[attr];
|
|
||||||
return newAttrs;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
export default (iconsObject, options) => {
|
|
||||||
const iconNodes = {};
|
|
||||||
|
|
||||||
Object.keys(iconsObject).forEach(icon => {
|
|
||||||
const svgString = iconsObject[icon];
|
|
||||||
const dom = parseDOM(svgString);
|
|
||||||
|
|
||||||
const children = dom.map(element => {
|
|
||||||
if (options.renderUniqueKey) {
|
|
||||||
const hashSource = {
|
|
||||||
name: element.name,
|
|
||||||
...element.attribs,
|
|
||||||
};
|
|
||||||
|
|
||||||
const uniqueKey = hash(JSON.stringify(hashSource));
|
|
||||||
|
|
||||||
element.attribs.key = uniqueKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
element.name,
|
|
||||||
{
|
|
||||||
...(options.camelizeAttrs ? camelizeAttrs(element.attribs) : element.attribs),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
iconNodes[icon] = !options.noDefaultAttrs
|
|
||||||
? [
|
|
||||||
'svg',
|
|
||||||
{
|
|
||||||
...(options.camelizeAttrs ? camelizeAttrs(DEFAULT_ATTRS) : DEFAULT_ATTRS),
|
|
||||||
},
|
|
||||||
children,
|
|
||||||
]
|
|
||||||
: children;
|
|
||||||
});
|
|
||||||
|
|
||||||
return iconNodes;
|
|
||||||
};
|
|
||||||
@@ -1,19 +1,7 @@
|
|||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import path from 'path';
|
import { basename } from 'path';
|
||||||
import cheerio from 'cheerio';
|
import { parseSync } from 'svgson';
|
||||||
import { minify } from 'html-minifier';
|
import { generateHashedKey, readSvg, hasDuplicatedChildren } from '../helpers';
|
||||||
import { readSvg } from '../helpers';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get contents between opening and closing `<svg>` tags.
|
|
||||||
* @param {string} svg
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
function getSvgContents(svg) {
|
|
||||||
const $ = cheerio.load(svg);
|
|
||||||
|
|
||||||
return minify($('svg').html(), { collapseWhitespace: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an object in the format: `{ <name>: <contents> }`.
|
* Build an object in the format: `{ <name>: <contents> }`.
|
||||||
@@ -21,12 +9,29 @@ function getSvgContents(svg) {
|
|||||||
* @param {Function} getSvg - A function that returns the contents of an SVG file given a filename.
|
* @param {Function} getSvg - A function that returns the contents of an SVG file given a filename.
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
export default (svgFiles, iconsDirectory) =>
|
export default (svgFiles, iconsDirectory, renderUniqueKey = false) =>
|
||||||
svgFiles
|
svgFiles
|
||||||
.map(svgFile => {
|
.map(svgFile => {
|
||||||
const name = path.basename(svgFile, '.svg');
|
const name = basename(svgFile, '.svg');
|
||||||
const svg = readSvg(svgFile, iconsDirectory);
|
const svg = readSvg(svgFile, iconsDirectory);
|
||||||
const contents = getSvgContents(svg);
|
const contents = parseSync(svg);
|
||||||
|
|
||||||
|
if (!(contents.children && contents.children.length)) {
|
||||||
|
throw new Error(`${name}.svg has no children!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasDuplicatedChildren(contents.children)) {
|
||||||
|
throw new Error(`Duplicated children in ${name}.svg`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderUniqueKey) {
|
||||||
|
contents.children = contents.children.map(child => {
|
||||||
|
child.attributes.key = generateHashedKey(child);
|
||||||
|
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return { name, contents };
|
return { name, contents };
|
||||||
})
|
})
|
||||||
.reduce((icons, icon) => {
|
.reduce((icons, icon) => {
|
||||||
|
|||||||
11
scripts/templates/defaultIconFileTemplate.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export default ({ componentName, children }) => `
|
||||||
|
import defaultAttributes from '../defaultAttributes';
|
||||||
|
|
||||||
|
const ${componentName} = [
|
||||||
|
'svg',
|
||||||
|
defaultAttributes,
|
||||||
|
${JSON.stringify(children)}
|
||||||
|
];
|
||||||
|
|
||||||
|
export default ${componentName};
|
||||||
|
`;
|
||||||
@@ -14,12 +14,10 @@
|
|||||||
"@chakra-ui/core": "^1.0.0-rc.8",
|
"@chakra-ui/core": "^1.0.0-rc.8",
|
||||||
"downloadjs": "^1.4.7",
|
"downloadjs": "^1.4.7",
|
||||||
"framer-motion": "^3.3.0",
|
"framer-motion": "^3.3.0",
|
||||||
"fuse.js": "^6.0.4",
|
|
||||||
"jszip": "^3.4.0",
|
"jszip": "^3.4.0",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"lucide-react": "^0.11.0",
|
"lucide-react": "0.14.0",
|
||||||
"next": "^10.0.4",
|
"next": "^10.0.4",
|
||||||
"object-path": "0.11.5",
|
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-color": "2.17.3",
|
"react-color": "2.17.3",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {Button, Flex, Link, WrapItem, Text, Wrap,} from "@chakra-ui/core";
|
import { Button, Flex, Link, WrapItem, Text, Wrap } from "@chakra-ui/core";
|
||||||
import download from "downloadjs";
|
import download from "downloadjs";
|
||||||
import JSZip from "jszip";
|
import JSZip from "jszip";
|
||||||
import { Download, Github } from 'lucide-react';
|
import { Download, Github } from 'lucide-react';
|
||||||
import {IconCustomizerDrawer} from "./IconCustomizerDrawer";
|
import { IconCustomizerDrawer } from "./IconCustomizerDrawer";
|
||||||
|
|
||||||
function generateZip(icons) {
|
function generateZip(icons) {
|
||||||
const zip = new JSZip();
|
const zip = new JSZip();
|
||||||
@@ -31,7 +31,6 @@ const Header = ({ data }) => {
|
|||||||
An open-source icon library, a fork of <Link href="https://github.com/feathericons/feather" isExternal>Feather Icons</Link>. <br/>We're expanding the icon set as much as possible while keeping it nice-looking - <Link href={repositoryUrl} isExternal>join us</Link>!
|
An open-source icon library, a fork of <Link href="https://github.com/feathericons/feather" isExternal>Feather Icons</Link>. <br/>We're expanding the icon set as much as possible while keeping it nice-looking - <Link href={repositoryUrl} isExternal>join us</Link>!
|
||||||
</Text>
|
</Text>
|
||||||
<Wrap
|
<Wrap
|
||||||
isInline
|
|
||||||
marginTop={3}
|
marginTop={3}
|
||||||
marginBottom={10}
|
marginBottom={10}
|
||||||
spacing="15px"
|
spacing="15px"
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ const IconDetailOverlay = ({ open = true, close, icon }) => {
|
|||||||
{ icon.contributors.map((commit, index) => (
|
{ icon.contributors.map((commit, index) => (
|
||||||
<Link href={`https://github.com/${commit.author}`} isExternal key={`${index}_${commit.sha}`}>
|
<Link href={`https://github.com/${commit.author}`} isExternal key={`${index}_${commit.sha}`}>
|
||||||
<Tooltip label={commit.author} key={commit.sha}>
|
<Tooltip label={commit.author} key={commit.sha}>
|
||||||
<Avatar name={commit.author} showBorder={false} src={`https://github.com/${commit.author}.png?size=88`} />
|
<Avatar name={commit.author} src={`https://github.com/${commit.author}.png?size=88`} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Link>
|
</Link>
|
||||||
)) }
|
)) }
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
/*
|
|
||||||
Icons exports.
|
|
||||||
|
|
||||||
Will be generated
|
|
||||||
*/
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`createIcons should read elements from DOM and replace it with icons 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\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\\"></path></svg>"`;
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
const Download = [
|
|
||||||
"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: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }],
|
|
||||||
["polyline", { points: "7 10 12 15 17 10" }],
|
|
||||||
["line", { x1: "12", y1: "15", x2: "12", y2: "3" }]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
export default Download;
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
const Globe = [
|
|
||||||
"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"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
["circle", { cx: "12", cy: "12", r: "10" }],
|
|
||||||
["line", { x1: "2", y1: "12", x2: "22", y2: "12" }],
|
|
||||||
[
|
|
||||||
"path",
|
|
||||||
{
|
|
||||||
d:
|
|
||||||
"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
export default Globe;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
export { default as Download } from './download';
|
|
||||||
export { default as Globe } from './globe';
|
|
||||||
export { default as Menu } from './menu';
|
|
||||||
export { default as Moon } from './moon';
|
|
||||||
export { default as Volume2 } from './volume-2';
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
const Menu = [
|
|
||||||
"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" }],
|
|
||||||
["line", { x1: "3", y1: "6", x2: "21", y2: "6" }],
|
|
||||||
["line", { x1: "3", y1: "18", x2: "21", y2: "18" }]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
export default Menu;
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
const Moon = [
|
|
||||||
"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: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }]]
|
|
||||||
];
|
|
||||||
|
|
||||||
export default Moon;
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
const Volume2 = [
|
|
||||||
"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"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
["polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }],
|
|
||||||
[
|
|
||||||
"path",
|
|
||||||
{ d: "M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" }
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
export default Volume2;
|
|
||||||