Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48fa902b1c | ||
|
|
cdd57e6610 | ||
|
|
1f5119785b | ||
|
|
90a3f6e1dd | ||
|
|
4ae4eae53d | ||
|
|
e99228c65d | ||
|
|
34249ff42c | ||
|
|
f9d37968d6 | ||
|
|
864b71822b | ||
|
|
bc3bd1267a | ||
|
|
5d22d8e456 | ||
|
|
db98602331 | ||
|
|
4eca473cd4 | ||
|
|
e6eedee22d | ||
|
|
a8174a34b5 | ||
|
|
3196af66ce | ||
|
|
dd593e3dc3 |
@@ -17,5 +17,9 @@ module.exports = {
|
||||
trailingComma: 'all'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: ['./site/tsconfig.json', './packages/*/tsconfig.json'],
|
||||
},
|
||||
};
|
||||
|
||||
48
.github/workflows/lucide-solid.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Lucide Solid Checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/lucide-solid/**
|
||||
push:
|
||||
paths:
|
||||
- packages/lucide-solid/**
|
||||
|
||||
jobs:
|
||||
lucide-solid:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v3.4.1
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-solid build
|
||||
|
||||
- name: Test
|
||||
run: pnpm --filter lucide-solid test
|
||||
|
||||
73
.github/workflows/release.yml
vendored
@@ -73,7 +73,7 @@ jobs:
|
||||
run: pnpm --filter lucide test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide publish
|
||||
run: pnpm --filter lucide publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -128,7 +128,7 @@ jobs:
|
||||
run: pnpm --filter lucide-react test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-react publish
|
||||
run: pnpm --filter lucide-react publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
run: pnpm --filter lucide-react-native test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-react-native publish
|
||||
run: pnpm --filter lucide-react-native publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -238,7 +238,7 @@ jobs:
|
||||
run: pnpm --filter lucide-vue test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-vue publish
|
||||
run: pnpm --filter lucide-vue publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -293,7 +293,7 @@ jobs:
|
||||
run: pnpm --filter lucide-vue-next test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-vue-next publish
|
||||
run: pnpm --filter lucide-vue-next publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -348,7 +348,7 @@ jobs:
|
||||
run: pnpm --filter lucide-angular test:headless
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-angular publish dist
|
||||
run: pnpm --filter lucide-angular publish dist --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -403,7 +403,7 @@ jobs:
|
||||
run: pnpm --filter lucide-preact test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-preact publish
|
||||
run: pnpm --filter lucide-preact publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -411,6 +411,61 @@ jobs:
|
||||
name: lucide-preact-package-json
|
||||
path: packages/lucide-preact/package.json
|
||||
|
||||
lucide-solid:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
needs: pre-build
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@v3.4.1
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- uses: pnpm/action-setup@v2.0.1
|
||||
name: Install pnpm
|
||||
id: pnpm-install
|
||||
with:
|
||||
version: 7
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: |
|
||||
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
|
||||
|
||||
- uses: actions/cache@v3
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Set Auth Token
|
||||
run: npm config set //registry.npmjs.org/:_authToken ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Set package.json version lucide
|
||||
run: pnpm --filter lucide-solid version --new-version ${{ needs.pre-build.outputs.VERSION }} --no-git-tag-version
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter lucide-solid build
|
||||
|
||||
- name: Test
|
||||
run: pnpm --filter lucide-solid test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-solid publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: lucide-solid-package-json
|
||||
path: packages/lucide-solid/package.json
|
||||
|
||||
lucide-svelte:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
@@ -458,7 +513,7 @@ jobs:
|
||||
run: pnpm --filter lucide-svelte test
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-svelte publish
|
||||
run: pnpm --filter lucide-svelte publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -514,7 +569,7 @@ jobs:
|
||||
run: pnpm --filter lucide-static build
|
||||
|
||||
- name: Publish
|
||||
run: pnpm --filter lucide-static publish
|
||||
run: pnpm --filter lucide-static publish --no-git-checks
|
||||
|
||||
- name: Upload package.json
|
||||
uses: actions/upload-artifact@v2
|
||||
|
||||
@@ -8,7 +8,7 @@ title: Comparison
|
||||
|
||||
Lucide is a community-run fork of [Feather Icons](https://github.com/feathericons/feather).
|
||||
|
||||
It began after growing disaffection of the [Feather Icons](https://github.com/feathericons/feather) project moderation. With over 300+ open issues and over 100+ open PRs, the Feather Icons project has been abandoned adn not maintained actively. This unfortunately means that hundreds of developers and designers wasted their time contributing to Feather Icons with no chance of PRs being accepted.
|
||||
It began after growing disaffection of the [Feather Icons](https://github.com/feathericons/feather) project moderation. With over 300+ open issues and over 100+ open PRs, the Feather Icons project has been abandoned and not maintained actively. This unfortunately means that hundreds of developers and designers wasted their time contributing to Feather Icons with no chance of PRs being accepted.
|
||||
|
||||
Lucide is trying to expand the icon set as much as possible while staying faithful to the original simplistic design language. We do this as a community of devs and designers.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ npm install lucide-preact
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a preact component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -16,7 +16,7 @@ npm install lucide-react-native
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a react component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -14,7 +14,7 @@ npm install lucide-react
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a react component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Implementation of the lucide icon library for Vue 3 applications.
|
||||
|
||||
> ⚠️ This version of lucide is for Vue 3, For Vue 2 got to [lucide-vue-next](lucide-vue)
|
||||
> ⚠️ This version of lucide is for Vue 3, For Vue 2 got to [lucide-vue](lucide-vue)
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -20,7 +20,7 @@ npm install lucide-vue-next
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a vue component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -16,7 +16,7 @@ npm install lucide-vue
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a vue component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -44,7 +44,7 @@ Here is a complete example with unpkg
|
||||
|
||||
### With ESModules
|
||||
|
||||
To reduce bundle size, lucide is built to be fully treeshakable.
|
||||
To reduce bundle size, lucide is built to be fully tree-shakable.
|
||||
The `createIcons` function will search for HTMLElements with the attribute `icon-name` and replace it with the svg from the given icon name.
|
||||
|
||||
```html
|
||||
|
||||
16
icons/arrow-up-down.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polyline points="11 17 7 21 3 17"/>
|
||||
<line x1="7" y1="21" x2="7" y2="9"/>
|
||||
<polyline points="21 7 17 3 13 7"/>
|
||||
<line x1="17" y1="15" x2="17" y2="3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 365 B |
15
icons/book-open-check.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M8 3H2v15h7c1.7 0 3 1.3 3 3V7c0-2.2-1.8-4-4-4Z" />
|
||||
<path d="m16 12 2 2 4-4" />
|
||||
<path d="M22 6V3h-6c-2.2 0-4 1.8-4 4v14c0-1.7 1.3-3 3-3h7v-2.3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 369 B |
16
icons/concierge-bell.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M2 18a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v2H2v-2Z" />
|
||||
<path d="M20 16a8 8 0 1 0-16 0" />
|
||||
<path d="M12 4v4" />
|
||||
<path d="M10 4h4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 351 B |
17
icons/ear-off.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M6 18.5a3.5 3.5 0 1 0 7 0c0-1.57.92-2.52 2.04-3.46" />
|
||||
<path d="M6 8.5c0-.75.13-1.47.36-2.14" />
|
||||
<path d="M8.8 3.15A6.5 6.5 0 0 1 19 8.5c0 1.63-.44 2.81-1.09 3.76" />
|
||||
<path d="M12.5 6A2.5 2.5 0 0 1 15 8.5M10 13a2 2 0 0 0 1.82-1.18" />
|
||||
<line x1="2" y1="2" x2="22" y2="22" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 501 B |
14
icons/ear.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M6 8.5a6.5 6.5 0 1 1 13 0c0 6-6 6-6 10a3.5 3.5 0 1 1-7 0" />
|
||||
<path d="M15 8.5a2.5 2.5 0 0 0-5 0v1a2 2 0 1 1 0 4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 337 B |
14
icons/fan.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M10.827 16.379a6.082 6.082 0 0 1-8.618-7.002l5.412 1.45a6.082 6.082 0 0 1 7.002-8.618l-1.45 5.412a6.082 6.082 0 0 1 8.618 7.002l-5.412-1.45a6.082 6.082 0 0 1-7.002 8.618l1.45-5.412Z" />
|
||||
<path d="M12 12v.01" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 431 B |
17
icons/microwave.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect x="2" y="4" width="20" height="15" rx="2" />
|
||||
<rect x="6" y="8" width="8" height="7" rx="1" />
|
||||
<path d="M18 8v7" />
|
||||
<path d="M6 19v2" />
|
||||
<path d="M18 19v2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 382 B |
17
icons/plug-2.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M9 2v6" />
|
||||
<path d="M15 2v6" />
|
||||
<path d="M12 17v5" />
|
||||
<path d="M5 8h14" />
|
||||
<path d="M6 11V8h12v3a6 6 0 1 1-12 0v0Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 346 B |
16
icons/plug.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M12 22v-5" />
|
||||
<path d="M9 7V2" />
|
||||
<path d="M15 7V2" />
|
||||
<path d="M6 13V8h12v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 338 B |
15
icons/refrigerator.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M5 6a4 4 0 0 1 4-4h6a4 4 0 0 1 4 4v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6Z" />
|
||||
<path d="M5 10h14" />
|
||||
<path d="M15 7v6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 341 B |
15
icons/sailboat.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M22 18H2a4 4 0 0 0 4 4h12a4 4 0 0 0 4-4Z"/>
|
||||
<path d="M21 14 10 2 3 14h18Z"/>
|
||||
<path d="M10 2v16"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 321 B |
22
icons/shower-head.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m4 4 2.5 2.5" />
|
||||
<path d="M13.5 6.5a4.95 4.95 0 0 0-7 7" />
|
||||
<path d="M15 5 5 15" />
|
||||
<path d="M14 17v.01" />
|
||||
<path d="M10 16v.01" />
|
||||
<path d="M13 13v.01" />
|
||||
<path d="M16 10v.01" />
|
||||
<path d="M11 20v.01" />
|
||||
<path d="M17 14v.01" />
|
||||
<path d="M20 11v.01" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 489 B |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lucide-angular",
|
||||
"description": "A Lucide icon library package for Angular applications",
|
||||
"version": "0.84.0",
|
||||
"version": "0.90.0",
|
||||
"author": "SMAH1",
|
||||
"license": "ISC",
|
||||
"homepage": "https://lucide.dev",
|
||||
@@ -31,7 +31,8 @@
|
||||
"test:watch": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e",
|
||||
"postinstall": "ngcc"
|
||||
"postinstall": "ngcc",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: lucide_icons
|
||||
description: A Lucide icon library package for Flutter applications. Fork of Feather Icons, open for anyone to contribute icons.
|
||||
version: 0.84.0
|
||||
version: 0.90.0
|
||||
homepage: https://lucide.dev
|
||||
repository: https://github.com/lucide-icons/lucide
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ npm install lucide-preact
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a preact component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lucide-preact",
|
||||
"description": "A Lucide icon library package for Preact applications",
|
||||
"version": "0.84.0",
|
||||
"version": "0.90.0",
|
||||
"license": "ISC",
|
||||
"homepage": "https://lucide.dev",
|
||||
"bugs": "https://github.com/lucide-icons/lucide/issues",
|
||||
@@ -17,17 +17,20 @@
|
||||
"module": "dist/esm/lucide-preact.js",
|
||||
"unpkg": "dist/umd/lucide-preact.min.js",
|
||||
"typings": "dist/lucide-preact.d.ts",
|
||||
"files": ["dist"],
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:types && pnpm build:bundles",
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:types && pnpm build:bundles",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
"clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.js",
|
||||
"build:icons": "node ../../scripts/buildIcons.mjs --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey",
|
||||
"build:es": "babel src -d dist/esm",
|
||||
"build:types": "node ./scripts/buildTypes.mjs",
|
||||
"build:bundles": "rollup -c ./rollup.config.js",
|
||||
"test": "jest"
|
||||
"test": "jest",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/preact": "^2.0.1",
|
||||
|
||||
@@ -21,6 +21,7 @@ interface LucideProps extends Partial<Omit<JSX.SVGAttributes, "ref" | "size">> {
|
||||
ref?: string | ((component: any) => any) | RefObject<any>;
|
||||
color?: string
|
||||
size?: string | number
|
||||
strokeWidth?: string | number
|
||||
}
|
||||
|
||||
// Generated icons
|
||||
|
||||
@@ -18,7 +18,7 @@ npm install lucide-react-native
|
||||
|
||||
## How to use
|
||||
|
||||
It's built with ES modules so it's completely threeshakable.
|
||||
It's built with ES modules so it's completely tree-shakable.
|
||||
Each icon can be imported as a react component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"build:icons": "node ../../scripts/buildIcons.mjs --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey",
|
||||
"build:types": "node ./scripts/buildTypes.mjs",
|
||||
"build:bundles": "rollup -c ./rollup.config.js",
|
||||
"test": "jest"
|
||||
"test": "jest",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^11.2.6",
|
||||
|
||||
@@ -16,7 +16,7 @@ npm install lucide-react
|
||||
|
||||
## How to use
|
||||
|
||||
It's built with ES modules so it's completely threeshakable.
|
||||
It's built with ES modules so it's completely tree-shakable.
|
||||
Each icon can be imported as a react component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lucide-react",
|
||||
"description": "A Lucide icon library package for React applications",
|
||||
"version": "0.84.0",
|
||||
"version": "0.90.0",
|
||||
"license": "ISC",
|
||||
"homepage": "https://lucide.dev",
|
||||
"bugs": "https://github.com/lucide-icons/lucide/issues",
|
||||
@@ -18,7 +18,9 @@
|
||||
"unpkg": "dist/umd/lucide-react.min.js",
|
||||
"typings": "dist/lucide-react.d.ts",
|
||||
"sideEffects": false,
|
||||
"files": ["dist"],
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:types && pnpm build:bundles",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
@@ -27,7 +29,8 @@
|
||||
"build:es": "babel src -d dist/esm",
|
||||
"build:types": "node ./scripts/buildTypes.mjs",
|
||||
"build:bundles": "rollup -c ./rollup.config.js",
|
||||
"test": "jest"
|
||||
"test": "jest",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^11.2.6",
|
||||
|
||||
78
packages/lucide-solid/README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Lucide Solid
|
||||
|
||||
Implementation of the lucide icon library for solid applications.
|
||||
|
||||
> What is lucide? Read it [here](https://github.com/lucide-icons/lucide#what-is-lucide).
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
yarn add lucide-solid
|
||||
|
||||
# or
|
||||
|
||||
npm install lucide-solid
|
||||
```
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a solid component.
|
||||
|
||||
### Example
|
||||
|
||||
You can pass additional props to adjust the icon.
|
||||
|
||||
``` js
|
||||
import { Camera } from 'lucide-solid';
|
||||
// Returns SolidComponent
|
||||
|
||||
// Usage
|
||||
const App = () => {
|
||||
return <Camera color="red" size={48}/>
|
||||
};
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
| name | type | default
|
||||
| ------------ | -------- | --------
|
||||
| `size` | *Number* | 24
|
||||
| `color` | *String* | currentColor
|
||||
| `strokeWidth`| *Number* | 2
|
||||
|
||||
### Custom props / svg attributes
|
||||
|
||||
You can also pass custom props that will be added in the as attributes. With that you can modify the icons look by passing svg attributes.
|
||||
|
||||
``` js
|
||||
// Usage
|
||||
const App = () => {
|
||||
return <Camera fill="red" stroke-linejoin="bevel"/>
|
||||
};
|
||||
```
|
||||
|
||||
### One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons.
|
||||
|
||||
> :warning: Example below importing all EsModules, caution using this example, not recommended when you using bundlers, your application build size will grow strongly.
|
||||
|
||||
#### Icon Component Example
|
||||
|
||||
``` tsx
|
||||
import * as icons from 'lucide-solid';
|
||||
import type { LucideProps } from 'lucide-solid';
|
||||
import { splitProps } from 'solid-js';
|
||||
import { Dynamic } from 'solid-js/web';
|
||||
|
||||
const Icon = (props: { name: keyof typeof icons } & LucideProps) => {
|
||||
const [local, others] = splitProps(props, ["name"]);
|
||||
|
||||
return <Dynamic component={icons[local.name]} {...others} />
|
||||
};
|
||||
|
||||
export default Icon;
|
||||
```
|
||||
6
packages/lucide-solid/babel.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const mainConfig = require('../../babel.config');
|
||||
|
||||
module.exports = {
|
||||
presets: ['solid'],
|
||||
env: mainConfig.env,
|
||||
};
|
||||
51
packages/lucide-solid/package.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "lucide-solid",
|
||||
"description": "A Lucide icon library package for Solid applications",
|
||||
"version": "0.88.0-beta.3",
|
||||
"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-solid"
|
||||
},
|
||||
"author": "Eric Fennis",
|
||||
"amdName": "lucide-solid",
|
||||
"main": "dist/cjs/lucide-solid.js",
|
||||
"main:umd": "dist/umd/lucide-solid.js",
|
||||
"module": "dist/esm/lucide-solid.js",
|
||||
"unpkg": "dist/umd/lucide-solid.min.js",
|
||||
"typings": "dist/lucide-solid.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:types && pnpm build:bundles",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
"clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.js",
|
||||
"build:icons": "node ../../scripts/buildIcons.mjs --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey",
|
||||
"build:es": "babel src -d dist/esm",
|
||||
"build:types": "node ./scripts/buildTypes.mjs",
|
||||
"build:bundles": "rollup -c ./rollup.config.js",
|
||||
"test:jest": "jest",
|
||||
"test": "vitest",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"babel-preset-solid": "^1.5.4",
|
||||
"jest": "^26.6.3",
|
||||
"jsdom": "^20.0.0",
|
||||
"solid-js": "^1.4.7",
|
||||
"solid-testing-library": "^0.3.0",
|
||||
"solid-jest": "^0.2.0",
|
||||
"vite": "^2.6.4",
|
||||
"vite-plugin-solid": "^2.3.0",
|
||||
"vitest": "^0.23.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-js": "^1.4.7"
|
||||
}
|
||||
}
|
||||
47
packages/lucide-solid/rollup.config.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import plugins from '../../rollup.plugins';
|
||||
import pkg from './package.json';
|
||||
|
||||
const packageName = 'LucideSolid';
|
||||
const outputFileName = 'lucide-solid';
|
||||
const outputDir = 'dist';
|
||||
const inputs = [`src/lucide-solid.js`];
|
||||
const bundles = [
|
||||
{
|
||||
format: 'umd',
|
||||
inputs,
|
||||
outputDir,
|
||||
minify: true,
|
||||
},
|
||||
{
|
||||
format: 'umd',
|
||||
inputs,
|
||||
outputDir,
|
||||
},
|
||||
{
|
||||
format: 'cjs',
|
||||
inputs,
|
||||
outputDir,
|
||||
},
|
||||
];
|
||||
|
||||
const configs = bundles
|
||||
.map(({ inputs, outputDir, format, minify }) =>
|
||||
inputs.map(input => ({
|
||||
input,
|
||||
plugins: plugins(pkg, minify),
|
||||
external: ['solid-js', 'solid-js/h'],
|
||||
output: {
|
||||
name: packageName,
|
||||
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||
format,
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'solid-js': 'solid-js',
|
||||
'solid-js/h': 'solid-js/h',
|
||||
},
|
||||
},
|
||||
})),
|
||||
)
|
||||
.flat();
|
||||
|
||||
export default configs;
|
||||
47
packages/lucide-solid/scripts/buildTypes.mjs
Normal file
@@ -0,0 +1,47 @@
|
||||
import path from 'path';
|
||||
import {
|
||||
writeFile,
|
||||
readSvgDirectory,
|
||||
resetFile,
|
||||
toPascalCase,
|
||||
appendFile,
|
||||
getCurrentDirPath
|
||||
} from '../../../scripts/helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url)
|
||||
const srcDirectory = path.join(currentDir, '../dist');
|
||||
|
||||
// Declare type definitions
|
||||
const typeDefinitions = `\
|
||||
/// <reference types="solid-js" />
|
||||
import { JSX } from 'solid-js'
|
||||
|
||||
interface LucideProps extends Partial<JSX.IntrinsicElements & JSX.SvgSVGAttributes<SVGSVGElement>> {
|
||||
key?: string | number;
|
||||
ref?: string | ((component: any) => any);
|
||||
color?: string
|
||||
size?: string | number
|
||||
strokeWidth?: string | number
|
||||
class?: string
|
||||
}
|
||||
|
||||
// Generated icons
|
||||
`;
|
||||
|
||||
const ICONS_DIR = path.resolve(currentDir, '../../../icons');
|
||||
const TYPES_FILE = 'lucide-solid.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');
|
||||
7
packages/lucide-solid/scripts/exportTemplate.mjs
Normal file
@@ -0,0 +1,7 @@
|
||||
export default ({ componentName, children }) => `
|
||||
import createSolidComponent from '../createSolidComponent';
|
||||
|
||||
const ${componentName} = createSolidComponent('${componentName}', ${JSON.stringify(children)});
|
||||
|
||||
export default ${componentName};
|
||||
`;
|
||||
47
packages/lucide-solid/src/createSolidComponent.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import h from 'solid-js/h';
|
||||
import { splitProps } from 'solid-js';
|
||||
import defaultAttributes from './defaultAttributes';
|
||||
|
||||
/**
|
||||
* Converts string to KebabCase
|
||||
* Copied from scripts/helper. If anyone knows how to properly import it here
|
||||
* then please fix it.
|
||||
*
|
||||
* @param {string} string
|
||||
* @returns {string} A kebabized string
|
||||
*/
|
||||
export const toKebabCase = string => string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
|
||||
export default (iconName, iconNode) => {
|
||||
const Component = props => {
|
||||
const [localProps, rest] = splitProps(props, [
|
||||
'color',
|
||||
'size',
|
||||
'strokeWidth',
|
||||
'children',
|
||||
'class',
|
||||
]);
|
||||
|
||||
const svgProps = {
|
||||
...defaultAttributes,
|
||||
width: () => (localProps.size != null ? localProps.size : defaultAttributes.width),
|
||||
height: () => (localProps.size != null ? localProps.size : defaultAttributes.height),
|
||||
stroke: () => (localProps.color != null ? localProps.color : defaultAttributes.stroke),
|
||||
'stroke-width': () =>
|
||||
localProps.strokeWidth != null ? localProps.strokeWidth : defaultAttributes['stroke-width'],
|
||||
class: () =>
|
||||
`lucide lucide-${toKebabCase(iconName)} ${
|
||||
localProps.class != null ? localProps.class : ''
|
||||
}`,
|
||||
};
|
||||
|
||||
return h(
|
||||
'svg',
|
||||
[svgProps, rest],
|
||||
[...iconNode.map(([tag, attrs]) => h(tag, attrs)), localProps.children],
|
||||
);
|
||||
};
|
||||
|
||||
Component.displayName = `${iconName}`;
|
||||
return Component;
|
||||
};
|
||||
11
packages/lucide-solid/src/defaultAttributes.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
width: 24,
|
||||
height: 24,
|
||||
viewBox: '0 0 24 24',
|
||||
fill: 'none',
|
||||
stroke: 'currentColor',
|
||||
'stroke-width': 2,
|
||||
'stroke-linecap': 'round',
|
||||
'stroke-linejoin': 'round',
|
||||
};
|
||||
1
packages/lucide-solid/src/icons/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
Folder for generated icons
|
||||
1
packages/lucide-solid/src/lucide-solid.js
Normal file
@@ -0,0 +1 @@
|
||||
export * from './icons';
|
||||
@@ -0,0 +1,5 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`Using lucide icon components > should adjust the size, stroke color and stroke width 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"48\\" height=\\"48\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"red\\" stroke-width=\\"4\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"lucide lucide-grid \\" data-testid=\\"grid-icon\\"><rect x=\\"3\\" y=\\"3\\" width=\\"18\\" height=\\"18\\" rx=\\"2\\" ry=\\"2\\" key=\\"maln0c\\"></rect><line x1=\\"3\\" y1=\\"9\\" x2=\\"21\\" y2=\\"9\\" key=\\"1uch6j\\"></line><line x1=\\"3\\" y1=\\"15\\" x2=\\"21\\" y2=\\"15\\" key=\\"1xojw2\\"></line><line x1=\\"9\\" y1=\\"3\\" x2=\\"9\\" y2=\\"21\\" key=\\"nvcl17\\"></line><line x1=\\"15\\" y1=\\"3\\" x2=\\"15\\" y2=\\"21\\" key=\\"jcv93v\\"></line></svg>"`;
|
||||
|
||||
exports[`Using lucide icon components > should render an component 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" class=\\"lucide lucide-grid \\"><rect x=\\"3\\" y=\\"3\\" width=\\"18\\" height=\\"18\\" rx=\\"2\\" ry=\\"2\\" key=\\"maln0c\\"></rect><line x1=\\"3\\" y1=\\"9\\" x2=\\"21\\" y2=\\"9\\" key=\\"1uch6j\\"></line><line x1=\\"3\\" y1=\\"15\\" x2=\\"21\\" y2=\\"15\\" key=\\"1xojw2\\"></line><line x1=\\"9\\" y1=\\"3\\" x2=\\"9\\" y2=\\"21\\" key=\\"nvcl17\\"></line><line x1=\\"15\\" y1=\\"3\\" x2=\\"15\\" y2=\\"21\\" key=\\"jcv93v\\"></line></svg>"`;
|
||||
30
packages/lucide-solid/tests/lucide-solid.spec.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { render } from 'solid-testing-library'
|
||||
import { Grid } from '../src/icons'
|
||||
|
||||
describe('Using lucide icon components', () => {
|
||||
it('should render an component', () => {
|
||||
const { container } = render(() => <Grid/> );
|
||||
|
||||
expect( container.innerHTML ).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should adjust the size, stroke color and stroke width', async () => {
|
||||
const testId = 'grid-icon';
|
||||
const { container, getByTestId } = render( () =>
|
||||
<Grid
|
||||
data-testid={testId}
|
||||
size={48}
|
||||
stroke="red"
|
||||
strokeWidth={4}
|
||||
/>,
|
||||
);
|
||||
|
||||
const { attributes } = await getByTestId(testId) as unknown as{ attributes: Record<string, { value: string }>};
|
||||
expect(attributes.stroke.value).toBe('red');
|
||||
expect(attributes.width.value).toBe('48');
|
||||
expect(attributes.height.value).toBe('48');
|
||||
expect(attributes['stroke-width'].value).toBe('4');
|
||||
expect( container.innerHTML ).toMatchSnapshot();
|
||||
});
|
||||
})
|
||||
1
packages/lucide-solid/tests/setupVitest.js
Normal file
@@ -0,0 +1 @@
|
||||
import '@testing-library/jest-dom';
|
||||
15
packages/lucide-solid/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
"types": ["vite/client"],
|
||||
"noEmit": true,
|
||||
"isolatedModules": true
|
||||
}
|
||||
}
|
||||
19
packages/lucide-solid/vitest.config.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import solidPlugin from 'vite-plugin-solid';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [solidPlugin()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
transformMode: {
|
||||
web: [/\.jsx?$/],
|
||||
},
|
||||
setupFiles: './tests/setupVitest.js',
|
||||
threads: false,
|
||||
isolate: false,
|
||||
},
|
||||
resolve: {
|
||||
conditions: ['development', 'browser'],
|
||||
},
|
||||
});
|
||||
@@ -16,7 +16,8 @@
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm copy:icons && pnpm copy:tags && pnpm build:lib",
|
||||
"build:lib": "node ./scripts/buildLib.mjs",
|
||||
"clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg && rm -f tags.json"
|
||||
"clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg && rm -f tags.json",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^2.3.2",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lucide-svelte",
|
||||
"description": "A Lucide icon library package for Svelte applications",
|
||||
"version": "0.84.0",
|
||||
"version": "0.90.0",
|
||||
"license": "ISC",
|
||||
"homepage": "https://lucide.dev",
|
||||
"bugs": "https://github.com/lucide-icons/lucide/issues",
|
||||
@@ -19,7 +19,9 @@
|
||||
"unpkg": "dist/umd/lucide-svelte.min.js",
|
||||
"typings": "dist/lucide-svelte.d.ts",
|
||||
"sideEffects": false,
|
||||
"files": ["dist"],
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:bundles && pnpm build:types",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
@@ -29,7 +31,8 @@
|
||||
"build:types": "node ./scripts/buildTypes.mjs",
|
||||
"build:bundles": "rollup -c ./rollup.config.js",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch"
|
||||
"test:watch": "jest --watch",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
|
||||
@@ -18,7 +18,7 @@ npm install lucide-vue-next
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a vue component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lucide-vue-next",
|
||||
"version": "0.84.0",
|
||||
"version": "0.90.0",
|
||||
"author": "Eric Fennis",
|
||||
"description": "A Lucide icon library package for Vue 3 applications",
|
||||
"license": "ISC",
|
||||
@@ -19,7 +19,10 @@
|
||||
"unpkg": "dist/umd/lucide-vue-next.min.js",
|
||||
"typings": "dist/lucide-vue-next.d.ts",
|
||||
"sideEffects": false,
|
||||
"files": ["dist", "nuxt.js"],
|
||||
"files": [
|
||||
"dist",
|
||||
"nuxt.js"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:types && pnpm build:bundles",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
@@ -29,7 +32,8 @@
|
||||
"build:types": "node ./scripts/buildTypes.mjs",
|
||||
"build:bundles": "rollup -c ./rollup.config.js",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watchAll"
|
||||
"test:watch": "jest --watchAll",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/vue": "^6.4.2",
|
||||
|
||||
@@ -18,7 +18,7 @@ npm install lucide-vue
|
||||
|
||||
## How to use
|
||||
|
||||
It's build with ESmodules so it's completely threeshakable.
|
||||
It's build with ESmodules so it's completely tree-shakable.
|
||||
Each icon can be imported as a vue component.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lucide-vue",
|
||||
"version": "0.84.0",
|
||||
"version": "0.90.0",
|
||||
"author": "Eric Fennis",
|
||||
"description": "A Lucide icon library package for Vue 2 applications",
|
||||
"license": "ISC",
|
||||
@@ -18,7 +18,9 @@
|
||||
"module": "dist/esm/lucide-vue.js",
|
||||
"unpkg": "dist/umd/lucide-vue.min.js",
|
||||
"sideEffects": false,
|
||||
"files": ["dist"],
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:bundles",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
@@ -27,7 +29,8 @@
|
||||
"build:es": "babel src -d dist/esm",
|
||||
"build:bundles": "rollup -c ./rollup.config.js",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watchAll"
|
||||
"test:watch": "jest --watchAll",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
|
||||
@@ -44,7 +44,7 @@ Here is a complete example with unpkg
|
||||
|
||||
### With ESModules
|
||||
|
||||
To reduce bundle size, lucide is built to be fully treeshakable.
|
||||
To reduce bundle size, lucide is built to be fully tree-shakable.
|
||||
The `createIcons` function will search for HTMLElements with the attribute `icon-name` and replace it with the svg from the given icon name.
|
||||
|
||||
```html
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lucide",
|
||||
"description": "A Lucide icon library package for web and javascript applications.",
|
||||
"version": "0.84.0",
|
||||
"version": "0.90.0",
|
||||
"license": "ISC",
|
||||
"homepage": "https://lucide.dev",
|
||||
"bugs": "https://github.com/lucide-icons/lucide/issues",
|
||||
@@ -18,7 +18,9 @@
|
||||
"unpkg": "dist/umd/lucide.min.js",
|
||||
"typings": "dist/lucide.d.ts",
|
||||
"sideEffects": false,
|
||||
"files": ["dist"],
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:es && pnpm build:bundles && pnpm build:types",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
|
||||
2795
pnpm-lock.yaml
generated
@@ -1,21 +1,14 @@
|
||||
/* eslint-disable no-undef */
|
||||
/* eslint-disable */
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint', 'import', 'prettier'],
|
||||
plugins: ['@typescript-eslint', 'import'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:@next/next/recommended',
|
||||
'prettier',
|
||||
],
|
||||
rules: {
|
||||
'prettier/prettier': [
|
||||
'error',
|
||||
{
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
},
|
||||
],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable */
|
||||
module.exports = {
|
||||
testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
|
||||
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
/* eslint-disable no-undef */
|
||||
/* eslint-disable */
|
||||
module.exports = {
|
||||
webpack(config) {
|
||||
config.module.rules.push({
|
||||
test: /\.svg$/,
|
||||
issuer: {
|
||||
and: [/\.(js|ts)x?$/],
|
||||
},
|
||||
|
||||
use: ['@svgr/webpack'],
|
||||
use: ["@svgr/webpack"]
|
||||
});
|
||||
|
||||
return config;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"export": "next export -o build",
|
||||
"deploy": "pnpm build && pnpm export",
|
||||
"lint": "eslint .",
|
||||
"test": "jest"
|
||||
"lint:fix": "eslint --fix .",
|
||||
"test": "jest",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/react": "1.8.8",
|
||||
@@ -19,7 +21,7 @@
|
||||
"@mdx-js/loader": "^1.6.22",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"@next/mdx": "^11.0.0",
|
||||
"@svgr/webpack": "^6.2.1",
|
||||
"@svgr/webpack": "^6.3.1",
|
||||
"downloadjs": "^1.4.7",
|
||||
"framer-motion": "^4",
|
||||
"fuse.js": "^6.5.3",
|
||||
@@ -37,23 +39,24 @@
|
||||
"react-svg-loader": "^3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/eslint-plugin-next": "^11.1.0",
|
||||
"@testing-library/dom": "^7.24.4",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.0.4",
|
||||
"@testing-library/react-hooks": "^3.4.2",
|
||||
"react-test-renderer": "17.0.2",
|
||||
"@next/eslint-plugin-next": "^12.2.5",
|
||||
"@testing-library/dom": "^7.31.2",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@types/jest": "^28.1.7",
|
||||
"@types/node": "^14.0.11",
|
||||
"@types/react": "^16.9.35",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.1",
|
||||
"@typescript-eslint/parser": "^4.29.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.34.0",
|
||||
"@typescript-eslint/parser": "^5.34.0",
|
||||
"babel-jest": "^26.5.2",
|
||||
"babel-loader": "^8.1.0",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"jest": "^26.5.2",
|
||||
"prettier": "^2.3.2",
|
||||
"react-test-renderer": "17.0.2",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ const calculateLinesToHighlight = (meta: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
interface HighlightProps {
|
||||
interface HighlightProps extends BoxProps {
|
||||
code: string;
|
||||
language: Language;
|
||||
metastring?: string;
|
||||
|
||||
@@ -21,7 +21,7 @@ function ColorPicker({ hsv, hsl, onChange, value: color }: ColorPickerProps) {
|
||||
}, [color]);
|
||||
|
||||
const handleChange = (e) => {
|
||||
let value = e.target.value;
|
||||
const value = e.target.value;
|
||||
setValue(value);
|
||||
onChange(value, e);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Box, ButtonProps, Button, useClipboard } from '@chakra-ui/react';
|
||||
import { Button, useClipboard } from '@chakra-ui/react';
|
||||
|
||||
const CopyButton = ({ copyText, buttonText = 'copy', ...props }) => {
|
||||
const { hasCopied, onCopy } = useClipboard(copyText);
|
||||
|
||||
@@ -21,11 +21,11 @@ const DEFAULT_STYLE = {
|
||||
|
||||
export const IconStyleContext = createContext<ICustomIconStyle>({
|
||||
color: 'currentColor',
|
||||
setColor: (s: string) => null,
|
||||
setColor: () => null,
|
||||
strokeWidth: 2,
|
||||
setStroke: (n: number) => null,
|
||||
setStroke: () => null,
|
||||
size: 24,
|
||||
setSize: (n: number) => null,
|
||||
setSize: () => null,
|
||||
resetStyle: () => null,
|
||||
iconsRef: { current: {} },
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Flex, Link, WrapItem, Text, Wrap, Heading, Icon } from '@chakra-ui/react';
|
||||
import { Button, Flex, Link, WrapItem, Text, Wrap, Heading } from '@chakra-ui/react';
|
||||
import download from 'downloadjs';
|
||||
import JSZip from 'jszip';
|
||||
import { Download, Github } from 'lucide-react';
|
||||
@@ -17,7 +17,7 @@ import { useState } from 'react';
|
||||
import { useCustomizeIconContext } from './CustomizeIconContext';
|
||||
import { IconEntity } from '../types';
|
||||
|
||||
type IconContent = [icon: string, src:string]
|
||||
type IconContent = [icon: string, src:string];
|
||||
|
||||
async function generateZip(icons: IconContent[]) {
|
||||
const zip = new JSZip();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createContext, useState, useContext, useMemo, useCallback, useEffect } from 'react';
|
||||
import { createContext, useState, useContext, useMemo, useCallback } from 'react';
|
||||
|
||||
interface HeadingTypes {
|
||||
anchor: string;
|
||||
@@ -8,7 +8,7 @@ interface HeadingTypes {
|
||||
|
||||
const HeadingNavigationContext = createContext({
|
||||
headings: [],
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
|
||||
addHeading: (heading: HeadingTypes) => {},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { useHeadingNavigationContext } from './HeadingNavigationProvider';
|
||||
|
||||
const HeadingTreeMenu = () => {
|
||||
const { headings } = useHeadingNavigationContext();
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const headingElements = useMemo(
|
||||
() =>
|
||||
headings.map(heading => {
|
||||
|
||||
@@ -1,39 +1,50 @@
|
||||
import { Box, Text, IconButton, useColorMode, Flex, Slide, ButtonGroup, Button, useToast, Heading, Avatar, AvatarGroup, Link, Tooltip, useMediaQuery, useDisclosure } from "@chakra-ui/react";
|
||||
import theme from "../lib/theme";
|
||||
import download from 'downloadjs';
|
||||
import copy from "copy-to-clipboard";
|
||||
import { X as Close } from 'lucide-react';
|
||||
import {useContext, useEffect, useRef} from "react";
|
||||
import {IconStyleContext} from "./CustomizeIconContext";
|
||||
import {IconWrapper} from "./IconWrapper";
|
||||
import ModifiedTooltip from "./ModifiedTooltip";
|
||||
import { IconData } from "../lib/icons";
|
||||
|
||||
type IconDownload = {
|
||||
src: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
const IconDetailOverlay = ({ open = true, close, icon }) => {
|
||||
interface IconDetailOverlayProps {
|
||||
open: boolean
|
||||
close: () => void
|
||||
icon?: IconData
|
||||
}
|
||||
|
||||
const IconDetailOverlay = ({ open = true, close, icon }: IconDetailOverlayProps) => {
|
||||
const toast = useToast();
|
||||
const { colorMode } = useColorMode();
|
||||
const { tags = [], name } = icon;
|
||||
const {color, strokeWidth, size} = useContext(IconStyleContext);
|
||||
const iconRef = useRef<SVGSVGElement>(null);
|
||||
const [isMobile] = useMediaQuery("(max-width: 560px)")
|
||||
const { isOpen, onOpen, onClose } = useDisclosure()
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
close();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(open) {
|
||||
onOpen()
|
||||
}
|
||||
}, [open])
|
||||
|
||||
const iconStyling = (isLight) => ({
|
||||
if(icon == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { tags = [], name = '' } = icon;
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
close();
|
||||
};
|
||||
|
||||
const iconStyling = {
|
||||
height: "25vw",
|
||||
width: "25vw",
|
||||
minHeight: "160px",
|
||||
@@ -41,12 +52,15 @@ const IconDetailOverlay = ({ open = true, close, icon }) => {
|
||||
maxHeight: "240px",
|
||||
maxWidth: "240px",
|
||||
color: color,
|
||||
});
|
||||
};
|
||||
|
||||
const downloadIcon = ({src, name} : IconDownload) => download(src, `${name}.svg`, 'image/svg+xml');
|
||||
const downloadIcon = ({src, name = ''} : IconDownload) => download(src, `${name}.svg`, 'image/svg+xml');
|
||||
|
||||
const copyIcon = async ({src, name} : IconDownload) => {
|
||||
const trimmedSrc = src.replace(/(\r\n|\n|\r|\s\s)/gm, "")
|
||||
|
||||
await navigator.clipboard.writeText(trimmedSrc)
|
||||
|
||||
const copyIcon = ({src, name} : IconDownload) => {
|
||||
copy(src);
|
||||
toast({
|
||||
title: "Copied!",
|
||||
description: `Icon "${name}" copied to clipboard.`,
|
||||
@@ -95,7 +109,6 @@ const IconDetailOverlay = ({ open = true, close, icon }) => {
|
||||
w="full"
|
||||
px={8}
|
||||
>
|
||||
|
||||
<Box
|
||||
borderWidth="1px"
|
||||
rounded="lg"
|
||||
@@ -135,7 +148,7 @@ const IconDetailOverlay = ({ open = true, close, icon }) => {
|
||||
padding={0}
|
||||
>
|
||||
<div
|
||||
style={iconStyling(colorMode == "light")}
|
||||
style={iconStyling}
|
||||
className="icon-large"
|
||||
>
|
||||
<IconWrapper
|
||||
@@ -216,8 +229,8 @@ const IconDetailOverlay = ({ open = true, close, icon }) => {
|
||||
</Heading>
|
||||
<AvatarGroup size="md">
|
||||
{ icon.contributors.map((commit, index) => (
|
||||
<Link href={`https://github.com/${commit.author}`} isExternal key={`${index}_${commit.sha}`}>
|
||||
<Tooltip label={commit.author} key={commit.sha}>
|
||||
<Link href={`https://github.com/${commit.author}`} isExternal key={`${index}_${commit.commit}`}>
|
||||
<Tooltip label={commit.author} key={commit.commit}>
|
||||
<Avatar name={commit.author} src={`https://github.com/${commit.author}.png?size=88`} />
|
||||
</Tooltip>
|
||||
</Link>
|
||||
|
||||
@@ -1,22 +1,42 @@
|
||||
import { Button, ButtonProps, Flex, Text, useToast } from '@chakra-ui/react';
|
||||
import download from 'downloadjs';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { memo } from 'react';
|
||||
import { Contributor } from '../lib/fetchAllContributors';
|
||||
import { useCustomizeIconContext } from './CustomizeIconContext';
|
||||
import { IconWrapper } from './IconWrapper';
|
||||
|
||||
interface IconListItemProps {
|
||||
name: string;
|
||||
content: string;
|
||||
contributors: any[];
|
||||
contributors: Contributor[]
|
||||
src: string;
|
||||
onClick?: ButtonProps['onClick'];
|
||||
onClick?: ButtonProps['onClick']
|
||||
}
|
||||
|
||||
const IconListItem = ({ name, content, onClick, src: svg }: IconListItemProps) => {
|
||||
const toast = useToast();
|
||||
const { color, size, strokeWidth, iconsRef } = useCustomizeIconContext();
|
||||
|
||||
const handleClick:ButtonProps['onClick'] = async (event) => {
|
||||
const src = (iconsRef.current[name].outerHTML ?? svg).replace(/(\r\n|\n|\r|(>\s\s<))/gm, "")
|
||||
if (event.shiftKey) {
|
||||
await navigator.clipboard.writeText(src)
|
||||
|
||||
toast({
|
||||
title: 'Copied!',
|
||||
description: `Icon "${name}" copied to clipboard.`,
|
||||
status: 'success',
|
||||
duration: 1500,
|
||||
});
|
||||
}
|
||||
if (event.altKey) {
|
||||
download(src, `${name}.svg`, 'image/svg+xml');
|
||||
}
|
||||
if (onClick) {
|
||||
onClick(event);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -26,24 +46,7 @@ const IconListItem = ({ name, content, onClick, src: svg }: IconListItemProps) =
|
||||
height={32}
|
||||
position="relative"
|
||||
whiteSpace="normal"
|
||||
onClick={event => {
|
||||
const src = iconsRef.current[name].outerHTML ?? svg
|
||||
if (event.shiftKey) {
|
||||
copy(src);
|
||||
toast({
|
||||
title: 'Copied!',
|
||||
description: `Icon "${name}" copied to clipboard.`,
|
||||
status: 'success',
|
||||
duration: 1500,
|
||||
});
|
||||
}
|
||||
if (event.altKey) {
|
||||
download(src, `${name}.\svg`, 'image/svg+xml');
|
||||
}
|
||||
if (onClick) {
|
||||
onClick(event);
|
||||
}
|
||||
}}
|
||||
onClick={handleClick}
|
||||
key={name}
|
||||
alignItems="center"
|
||||
>
|
||||
|
||||
@@ -121,6 +121,7 @@ const Layout = ({ aside, children }: LayoutProps) => {
|
||||
<Divider mb={6} mt={12} />
|
||||
<p style={{ alignSelf: 'center' }}>
|
||||
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img src="/vercel.svg" alt="Powered by Vercel" width="200" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Icon, Link, Text } from '@chakra-ui/react';
|
||||
//@ts-ignore
|
||||
import LogoImage from '../../public/logo.svg';
|
||||
import NextLink from 'next/link';
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import { useDisclosure } from '@chakra-ui/react';
|
||||
import { createContext, useState, useContext, useMemo, useCallback, useEffect } from 'react';
|
||||
import { createContext, useContext, useMemo } from 'react';
|
||||
|
||||
const MobileNavigationContext = createContext({
|
||||
isOpen: false,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Box, Tooltip, useColorMode } from "@chakra-ui/react";
|
||||
import theme from '../lib/theme';
|
||||
|
||||
const ModifiedTooltip = ({}) => {
|
||||
const ModifiedTooltip = () => {
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
return (
|
||||
|
||||
@@ -5,17 +5,31 @@ import {
|
||||
Heading,
|
||||
Text,
|
||||
useColorMode,
|
||||
Divider,
|
||||
ButtonGroup,
|
||||
Stack,
|
||||
} from '@chakra-ui/react';
|
||||
import Image from 'next/image';
|
||||
import { Code, FileText } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { MDXRemote } from 'next-mdx-remote';
|
||||
import mdxComponents from '../lib/mdxComponents';
|
||||
|
||||
const Package = ({ name, description, image, shields, source, documentation }) => {
|
||||
interface Shield {
|
||||
alt: string
|
||||
src: string
|
||||
href: string
|
||||
}
|
||||
export interface PackageItem {
|
||||
name: string
|
||||
description: string
|
||||
image: string
|
||||
shields: Shield[]
|
||||
source: string
|
||||
documentation: string
|
||||
order: number
|
||||
private?: boolean
|
||||
flutter?: object
|
||||
}
|
||||
|
||||
|
||||
const Package = ({ name, description, image, shields, source, documentation }: PackageItem) => {
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
return (
|
||||
@@ -71,6 +85,7 @@ const Package = ({ name, description, image, shields, source, documentation }) =
|
||||
{shields.map(({ alt, src, href }, index) => (
|
||||
<Link href={href} passHref>
|
||||
<a target="_blank">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img {...{ alt, src }} key={index} />
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
@@ -2,6 +2,11 @@ import crypto from 'crypto';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export interface Contributor {
|
||||
author: string
|
||||
commit: string
|
||||
}
|
||||
|
||||
const IGNORE_COMMIT_MESSAGES = ['fork', 'optimize'];
|
||||
|
||||
function getContentHashOfFile(path) {
|
||||
@@ -14,8 +19,7 @@ function getContentHashOfFile(path) {
|
||||
});
|
||||
}
|
||||
|
||||
const fetchCommitsOfIcon = (name) =>
|
||||
new Promise(async (resolve, reject) => {
|
||||
const fetchCommitsOfIcon = async (name) =>{
|
||||
try {
|
||||
const headers = new Headers();
|
||||
const username = 'ericfennis';
|
||||
@@ -35,22 +39,22 @@ const fetchCommitsOfIcon = (name) =>
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
resolve({
|
||||
return {
|
||||
name,
|
||||
commits: data,
|
||||
});
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
reject(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const filterCommits = (commits) =>
|
||||
commits.filter(({ commit }) =>
|
||||
!IGNORE_COMMIT_MESSAGES.some(ignoreItem =>
|
||||
commit.message.toLowerCase().includes(ignoreItem),
|
||||
))
|
||||
.map(({ sha, author, commit }) => ({
|
||||
.map(({ sha, author }) => ({
|
||||
author: author && author.login ? author.login : null,
|
||||
commit: sha,
|
||||
}))
|
||||
@@ -86,7 +90,7 @@ async function writeIconCache(icon, content) {
|
||||
fs.writeFileSync(iconCachePath, JSON.stringify(content), 'utf-8');
|
||||
}
|
||||
|
||||
export async function getContributors(icon) {
|
||||
export async function getContributors(icon): Promise<Contributor[]> {
|
||||
try {
|
||||
let iconCommits
|
||||
const iconCache = await checkIconCache(icon);
|
||||
@@ -94,7 +98,7 @@ export async function getContributors(icon) {
|
||||
if (iconCache) {
|
||||
iconCommits = iconCache
|
||||
} else {
|
||||
const { commits } : any = await fetchCommitsOfIcon(icon);
|
||||
const { commits } = await fetchCommitsOfIcon(icon);
|
||||
|
||||
writeIconCache(icon, commits)
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { promises as fs, constants } from 'fs';
|
||||
import path from 'path';
|
||||
import yaml from 'js-yaml'
|
||||
import { PackageItem } from '../components/Package';
|
||||
|
||||
const fileExist = (filePath) => fs.access(filePath, constants.F_OK).then(() => true).catch(() => false)
|
||||
|
||||
const fetchPackages = async () => {
|
||||
const fetchPackages = async (): Promise<PackageItem[]> => {
|
||||
const docsDir = path.resolve(process.cwd(), '../packages');
|
||||
const fileNames = await (await fs.readdir(docsDir)).map(filename => ({filename, directory: docsDir}))
|
||||
|
||||
@@ -31,8 +32,6 @@ const fetchPackages = async () => {
|
||||
return null
|
||||
}))
|
||||
|
||||
|
||||
|
||||
return packageJsons
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import cheerio from 'cheerio';
|
||||
import { parseSync, stringify } from 'svgson';
|
||||
import tags from '../../../tags.json';
|
||||
import { getContributors } from "./fetchAllContributors";
|
||||
import { Contributor, getContributors } from "./fetchAllContributors";
|
||||
|
||||
const directory = path.join(process.cwd(), "../icons");
|
||||
|
||||
@@ -14,12 +14,13 @@ export function getAllNames() {
|
||||
});
|
||||
}
|
||||
|
||||
export async function getData(name:string) {
|
||||
export async function getData(name: string) {
|
||||
const fullPath = path.join(directory, `${name}.svg`);
|
||||
const fileContents = fs.readFileSync(fullPath, "utf8");
|
||||
const fileContent = fs.readFileSync(fullPath, "utf8");
|
||||
|
||||
const $ = cheerio.load(fileContents);
|
||||
const content = $("svg").html();
|
||||
const svgNodes = parseSync(fileContent);
|
||||
|
||||
const svgContent = svgNodes.children.map((node) => stringify(node)).join('');
|
||||
|
||||
const contributors = await getContributors(name);
|
||||
|
||||
@@ -27,12 +28,20 @@ export async function getData(name:string) {
|
||||
name,
|
||||
tags: tags[name] || [],
|
||||
contributors,
|
||||
src: fileContents,
|
||||
content: content
|
||||
src: fileContent,
|
||||
content: svgContent
|
||||
};
|
||||
}
|
||||
|
||||
export async function getAllData() {
|
||||
export interface IconData {
|
||||
name: string
|
||||
tags: string[]
|
||||
contributors: Contributor[]
|
||||
src: string
|
||||
content: string
|
||||
}
|
||||
|
||||
export async function getAllData(): Promise<IconData[]> {
|
||||
const names = getAllNames();
|
||||
|
||||
return Promise.all(names.map((name) => getData(name)));
|
||||
|
||||
@@ -10,6 +10,7 @@ export const useKeyBindings = (
|
||||
const [keyBindings] = useState(initialKeyBindings);
|
||||
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
document.addEventListener(
|
||||
eventListener,
|
||||
(event) => {
|
||||
@@ -28,6 +29,7 @@ export const useKeyBindings = (
|
||||
|
||||
return () =>
|
||||
Object.keys(keyBindings).forEach((keyBinding) =>
|
||||
// eslint-disable-next-line no-undef
|
||||
document.removeEventListener(eventListener, keyBindings[keyBinding])
|
||||
);
|
||||
}, []);
|
||||
|
||||
@@ -52,8 +52,7 @@ const components = {
|
||||
|
||||
return (
|
||||
<CodeBlock
|
||||
//@ts-ignore
|
||||
my={6}
|
||||
marginY={6}
|
||||
code={code}
|
||||
language={language}
|
||||
/>
|
||||
@@ -78,7 +77,7 @@ const components = {
|
||||
/>
|
||||
),
|
||||
inlineCode: InlineCode,
|
||||
hr: (props) => <Divider my={4}/>,
|
||||
hr: () => <Divider my={4} />,
|
||||
a: ({children, href, ...rest}) => {
|
||||
let link = href
|
||||
const isExternal = link.startsWith('http')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Fuse from 'fuse.js';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
const useSearch = <T>(query = '', collection: T[], keys: Fuse.FuseOptionKey[]) => {
|
||||
const useSearch = <T>(query = '', collection: T[], keys: Fuse.FuseOptionKey<T>[] = []) => {
|
||||
const index = useMemo(() => {
|
||||
return new Fuse(collection, {
|
||||
threshold: 0.2,
|
||||
|
||||
@@ -17,15 +17,6 @@ class MyDocument extends Document {
|
||||
<meta name="theme-color" content="#F56565" />
|
||||
<meta name="google-site-verification" content="pr2dEIF-6zFdjXlDxutqEokeinrQNLx5qAjeVCqASDY" />
|
||||
</Head>
|
||||
<style jsx global>{`
|
||||
* {
|
||||
-webkit-transition: none !important;
|
||||
-moz-transition: none !important;
|
||||
-o-transition: none !important;
|
||||
-ms-transition: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
`}</style>
|
||||
<body>
|
||||
<ColorModeScript />
|
||||
<Main />
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import Layout from '../../components/Layout';
|
||||
import Header from '../../components/Header';
|
||||
import Head from 'next/head';
|
||||
import fetchAllDocuments from '../../lib/fetchAllDocuments';
|
||||
|
||||
export { default } from '.';
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Box, Button, Text } from '@chakra-ui/react';
|
||||
import { ArrowRight } from 'lucide-react'
|
||||
import Link from 'next/link';
|
||||
|
||||
const DocPage = ({ doc, data, content }) => {
|
||||
const DocPage = ({ doc, data }) => {
|
||||
if (!data || !doc) return null
|
||||
|
||||
const nextPage = data.nextPage || []
|
||||
@@ -69,7 +69,7 @@ const DocPage = ({ doc, data, content }) => {
|
||||
|
||||
export default DocPage
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
export async function getStaticProps() {
|
||||
const allDocs = await fetchAllDocuments();
|
||||
const doc = allDocs.find(({filename = ''}) => filename === 'index.md');
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ const IconPage = ({ icon, data }) => {
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<IconDetailOverlay key={currentIcon.name} icon={currentIcon} close={onClose} />
|
||||
<IconDetailOverlay key={currentIcon.name} icon={currentIcon} close={onClose} open />
|
||||
<Header {...{ data }} />
|
||||
<IconOverview {...{ data }} />
|
||||
</Layout>
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
import Layout from '../components/Layout';
|
||||
import { getAllData } from '../lib/icons';
|
||||
import { getAllData, IconData } from '../lib/icons';
|
||||
|
||||
import IconOverview from '../components/IconOverview';
|
||||
import IconDetailOverlay from '../components/IconDetailOverlay';
|
||||
import { useRouter } from 'next/router';
|
||||
import Header from '../components/Header';
|
||||
import MobileMenu from '../components/MobileMenu';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { GetStaticPropsResult, NextPage } from 'next';
|
||||
|
||||
const IndexPage = ({ data }) => {
|
||||
interface HomePageProps {
|
||||
data: IconData[]
|
||||
}
|
||||
|
||||
const HomePage: NextPage<HomePageProps> = ({ data }) => {
|
||||
const router = useRouter();
|
||||
const getIcon = iconName => data.find(({ name }) => name === iconName) || {};
|
||||
const getIcon = iconName => data.find(({ name }) => name === iconName);
|
||||
|
||||
const currentIcon = useMemo(() => {
|
||||
return getIcon(router.query.iconName)
|
||||
@@ -30,7 +35,7 @@ const IndexPage = ({ data }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export async function getStaticProps() {
|
||||
export async function getStaticProps(): Promise<GetStaticPropsResult<HomePageProps>> {
|
||||
const data = await getAllData();
|
||||
|
||||
return {
|
||||
@@ -40,4 +45,4 @@ export async function getStaticProps() {
|
||||
};
|
||||
}
|
||||
|
||||
export default IndexPage;
|
||||
export default HomePage;
|
||||
|
||||
@@ -5,9 +5,9 @@ import MobileMenu from '../components/MobileMenu';
|
||||
import { Box, Heading, Text } from '@chakra-ui/react';
|
||||
import { promises as fs } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { GetStaticProps, NextPage } from 'next';
|
||||
import { GetStaticProps } from 'next';
|
||||
|
||||
const LicensePage = ({ licenseText }) => {
|
||||
const LicensePage = ({ licenseText }: { licenseText: string[] }): JSX.Element => {
|
||||
return (
|
||||
<Box>
|
||||
<MobileMenu />
|
||||
@@ -43,7 +43,7 @@ const LicensePage = ({ licenseText }) => {
|
||||
|
||||
export default LicensePage;
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
export const getStaticProps: GetStaticProps = async () => {
|
||||
const doc: string = await fs.readFile(resolve('../LICENSE'), 'utf-8');
|
||||
|
||||
const licenseText = doc
|
||||
|
||||
@@ -2,12 +2,17 @@ import Layout from '../../components/Layout';
|
||||
import HeadingNavigationProvider from '../../components/HeadingNavigationProvider';
|
||||
import MobileMenu from '../../components/MobileMenu';
|
||||
import { Stack } from '@chakra-ui/react';
|
||||
import Package from '../../components/Package';
|
||||
import packagesData from '../../lib/packageData';
|
||||
import Package, { PackageItem } from '../../components/Package';
|
||||
import packagesData from '../../data/packageData';
|
||||
import { Heading } from '@chakra-ui/react';
|
||||
import fetchPackages from '../../lib/fetchPackages';
|
||||
import { GetStaticPropsResult } from 'next';
|
||||
|
||||
const PackagesPage = ({ packages }) => {
|
||||
interface PackagesPageProps {
|
||||
packages: PackageItem[]
|
||||
}
|
||||
|
||||
const PackagesPage = ({ packages }: PackagesPageProps): JSX.Element => {
|
||||
return (
|
||||
<HeadingNavigationProvider>
|
||||
<MobileMenu />
|
||||
@@ -25,11 +30,11 @@ const PackagesPage = ({ packages }) => {
|
||||
|
||||
export default PackagesPage;
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const packages = (await fetchPackages())
|
||||
export async function getStaticProps(): Promise<GetStaticPropsResult<PackagesPageProps>> {
|
||||
const packages: PackageItem[] = (await fetchPackages())
|
||||
.filter(Boolean)
|
||||
.filter(packageObj => !packageObj.private && packageObj.name in packagesData)
|
||||
.map(({ name, description, flutter = false }) => {
|
||||
.map(({ name, description, flutter }) => {
|
||||
const packageDirectory = flutter ? 'lucide-flutter' : name;
|
||||
|
||||
return {
|
||||
@@ -43,5 +48,8 @@ export async function getStaticProps({ params }) {
|
||||
})
|
||||
.sort((a, b) => a.order - b.order);
|
||||
|
||||
console.log(packages);
|
||||
|
||||
|
||||
return { props: { packages } };
|
||||
}
|
||||
|
||||
@@ -2,15 +2,20 @@ import { getAllData } from '../src/lib/icons';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import useSearch from '../src/lib/useSearch';
|
||||
|
||||
const keys = [
|
||||
{ name: 'name', weight: 2 },
|
||||
{ name: 'tags', weight: 1 },
|
||||
]
|
||||
|
||||
describe('Icon Overview', () => {
|
||||
it('can search filter icons', async () => {
|
||||
let allData = getAllData();
|
||||
const allData = await getAllData();
|
||||
|
||||
const { result: result1, waitForNextUpdate: wait1 } = renderHook(() => useSearch(allData, ''));
|
||||
const { result: result1 } = renderHook(() => useSearch('', allData, keys));
|
||||
expect(result1.current).toHaveLength(allData.length);
|
||||
|
||||
const { result: result2, waitForNextUpdate: wait2 } = renderHook(() =>
|
||||
useSearch(allData, 'airplay')
|
||||
useSearch(allData, 'airplay', keys)
|
||||
);
|
||||
await wait2();
|
||||
expect(result2.current).toHaveLength(2);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { act, fireEvent, screen } from '@testing-library/react';
|
||||
import { screen, render } from '@testing-library/react';
|
||||
import Index from '../src/pages/index';
|
||||
import React from 'react';
|
||||
import { render } from './test-utils';
|
||||
import { getAllData } from '../src/lib/icons';
|
||||
|
||||
import App from '../src/pages/_app';
|
||||
|
||||
describe('App', () => {
|
||||
it('renders without crashing', () => {
|
||||
let allData = getAllData();
|
||||
it('renders without crashing', async () => {
|
||||
const allData = await getAllData();
|
||||
render(<App Component={Index} pageProps={{ data: allData }} />);
|
||||
expect(
|
||||
screen.getByText('Simply beautiful open source icons, community-sourced')
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import React from 'react';
|
||||
import { render as defaultRender } from '@testing-library/react';
|
||||
import { RouterContext } from 'next/dist/next-server/lib/router-context';
|
||||
import { NextRouter } from 'next/router';
|
||||
|
||||
export * from '@testing-library/react';
|
||||
|
||||
// --------------------------------------------------
|
||||
// Override the default test render with our own
|
||||
//
|
||||
// You can override the router mock like this:
|
||||
//
|
||||
// const { baseElement } = render(<MyComponent />, {
|
||||
// router: { pathname: '/my-custom-pathname' },
|
||||
// });
|
||||
// --------------------------------------------------
|
||||
type DefaultParams = Parameters<typeof defaultRender>;
|
||||
type RenderUI = DefaultParams[0];
|
||||
type RenderOptions = DefaultParams[1] & { router?: Partial<NextRouter> };
|
||||
|
||||
export function render(ui: RenderUI, { wrapper, router, ...options }: RenderOptions = {}) {
|
||||
if (!wrapper) {
|
||||
wrapper = ({ children }) => (
|
||||
<RouterContext.Provider value={{ ...mockRouter, ...router }}>
|
||||
{children}
|
||||
</RouterContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
return defaultRender(ui, { wrapper, ...options });
|
||||
}
|
||||
|
||||
const mockRouter: NextRouter = {
|
||||
basePath: '',
|
||||
pathname: '/',
|
||||
route: '/',
|
||||
asPath: '/',
|
||||
query: {},
|
||||
push: jest.fn(),
|
||||
replace: jest.fn(),
|
||||
reload: jest.fn(),
|
||||
back: jest.fn(),
|
||||
prefetch: jest.fn(),
|
||||
beforePopState: jest.fn(),
|
||||
events: {
|
||||
on: jest.fn(),
|
||||
off: jest.fn(),
|
||||
emit: jest.fn(),
|
||||
},
|
||||
isFallback: false,
|
||||
};
|
||||
1
site/tsconfig.tsbuildinfo
Normal file
77
tags.json
@@ -304,7 +304,9 @@
|
||||
"direction",
|
||||
"swap",
|
||||
"switch",
|
||||
"transaction"
|
||||
"transaction",
|
||||
"reorder",
|
||||
"move"
|
||||
],
|
||||
"arrow-right": [
|
||||
"direction"
|
||||
@@ -318,6 +320,17 @@
|
||||
"arrow-up-circle": [
|
||||
"direction"
|
||||
],
|
||||
"arrow-up-down": [
|
||||
"bidirectional",
|
||||
"direction",
|
||||
"swap",
|
||||
"switch",
|
||||
"network",
|
||||
"mobile data",
|
||||
"internet",
|
||||
"reorder",
|
||||
"move"
|
||||
],
|
||||
"arrow-up-left": [
|
||||
"direction"
|
||||
],
|
||||
@@ -552,6 +565,11 @@
|
||||
"read",
|
||||
"library"
|
||||
],
|
||||
"book-open-check": [
|
||||
"read",
|
||||
"library",
|
||||
"plain language"
|
||||
],
|
||||
"bookmark": [
|
||||
"read",
|
||||
"clip",
|
||||
@@ -1106,6 +1124,11 @@
|
||||
"part",
|
||||
"symbol"
|
||||
],
|
||||
"concierge-bell": [
|
||||
"reception",
|
||||
"bell",
|
||||
"porter"
|
||||
],
|
||||
"contact": [
|
||||
"person",
|
||||
"user"
|
||||
@@ -1320,6 +1343,22 @@
|
||||
"chicken",
|
||||
"meat"
|
||||
],
|
||||
"ear": [
|
||||
"hearing",
|
||||
"noise",
|
||||
"audio",
|
||||
"accessibility"
|
||||
],
|
||||
"ear-off": [
|
||||
"hearing",
|
||||
"hard of hearing",
|
||||
"hearing loss",
|
||||
"deafness",
|
||||
"noise",
|
||||
"silence",
|
||||
"audio",
|
||||
"accessibility"
|
||||
],
|
||||
"edit": [
|
||||
"pencil",
|
||||
"change"
|
||||
@@ -1387,6 +1426,13 @@
|
||||
"manufacture",
|
||||
"sector"
|
||||
],
|
||||
"fan": [
|
||||
"air",
|
||||
"cooler",
|
||||
"ventilation",
|
||||
"ventilator",
|
||||
"blower"
|
||||
],
|
||||
"fast-forward": [
|
||||
"music"
|
||||
],
|
||||
@@ -2701,6 +2747,12 @@
|
||||
"imaging",
|
||||
"research"
|
||||
],
|
||||
"microwave": [
|
||||
"oven",
|
||||
"cooker",
|
||||
"toaster oven",
|
||||
"bake"
|
||||
],
|
||||
"milestone": [
|
||||
"sign",
|
||||
"signpost",
|
||||
@@ -3148,6 +3200,15 @@
|
||||
"synchronize",
|
||||
"arrows"
|
||||
],
|
||||
"refrigerator": [
|
||||
"frigerator",
|
||||
"fridge",
|
||||
"freezer",
|
||||
"cooler",
|
||||
"icebox",
|
||||
"chiller",
|
||||
"cold storage"
|
||||
],
|
||||
"regex": [
|
||||
"search",
|
||||
"text"
|
||||
@@ -3209,6 +3270,13 @@
|
||||
"money",
|
||||
"payment"
|
||||
],
|
||||
"sailboat": [
|
||||
"ship",
|
||||
"boat",
|
||||
"harbor",
|
||||
"harbour",
|
||||
"dock"
|
||||
],
|
||||
"save": [
|
||||
"floppy disk"
|
||||
],
|
||||
@@ -3380,6 +3448,13 @@
|
||||
"dig",
|
||||
"spade"
|
||||
],
|
||||
"shower-head": [
|
||||
"shower",
|
||||
"bath",
|
||||
"bathroom",
|
||||
"amenities",
|
||||
"services"
|
||||
],
|
||||
"shrink": [
|
||||
"scale",
|
||||
"fullscreen"
|
||||
|
||||