Compare commits
295 Commits
fix/fixed-
...
update-dep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
141ff59bd7 | ||
|
|
570f7d7e76 | ||
|
|
6d43b9feb3 | ||
|
|
16166f838b | ||
|
|
425bcc3f3d | ||
|
|
982af91724 | ||
|
|
a3ec4428f1 | ||
|
|
673e76831d | ||
|
|
b4291576b7 | ||
|
|
95f5ecacad | ||
|
|
ef5c1b9bdd | ||
|
|
b01715ebe8 | ||
|
|
05dd5fcfde | ||
|
|
e71198d9b3 | ||
|
|
57714e36ea | ||
|
|
358c9c1e80 | ||
|
|
64ddff76c5 | ||
|
|
31a9cdcbcc | ||
|
|
69319ee2f0 | ||
|
|
7beb3ee666 | ||
|
|
396d6d42ce | ||
|
|
37a60eefb2 | ||
|
|
c2c46b21ed | ||
|
|
0a0c8aa7e7 | ||
|
|
dc14e6ea8e | ||
|
|
1f67ef5307 | ||
|
|
ff6f9a09ad | ||
|
|
585b65f28f | ||
|
|
405feea8f6 | ||
|
|
5931a4a227 | ||
|
|
d3bafc2848 | ||
|
|
a6f4a08bda | ||
|
|
5a93aff903 | ||
|
|
e6c50d543b | ||
|
|
0d7c70cab6 | ||
|
|
379d1b1002 | ||
|
|
7d6998941d | ||
|
|
667bb8034d | ||
|
|
fd9c489d7a | ||
|
|
acb0e37ac2 | ||
|
|
6c25cbee67 | ||
|
|
08121af31e | ||
|
|
2d484469cd | ||
|
|
f66d167ead | ||
|
|
c63e5a456e | ||
|
|
aac12f991a | ||
|
|
3844a4b346 | ||
|
|
98b43826a4 | ||
|
|
e8194cbabe | ||
|
|
17bbbe1cbb | ||
|
|
c698121170 | ||
|
|
7a380a8177 | ||
|
|
55623e1611 | ||
|
|
803d237fef | ||
|
|
151bd33cd7 | ||
|
|
b3b8cfd59c | ||
|
|
996fc68c7e | ||
|
|
69e99093b8 | ||
|
|
030c7b9cb9 | ||
|
|
6f384680b4 | ||
|
|
e810b7273f | ||
|
|
599c517188 | ||
|
|
95830a0d88 | ||
|
|
5f0c19afaa | ||
|
|
37135af384 | ||
|
|
0fdc2413f6 | ||
|
|
d565b951d7 | ||
|
|
3e7d748827 | ||
|
|
0e54626bdb | ||
|
|
110d8cce27 | ||
|
|
9db00bfe3c | ||
|
|
e21d0e2dd6 | ||
|
|
483a594622 | ||
|
|
2136843515 | ||
|
|
ad842796dc | ||
|
|
f6a7eadd99 | ||
|
|
f51a01a7d0 | ||
|
|
30ed887ad1 | ||
|
|
a87ac013f7 | ||
|
|
87a67cc314 | ||
|
|
e418be64a1 | ||
|
|
0ca76a1de1 | ||
|
|
be81f20a6b | ||
|
|
41d32b8f40 | ||
|
|
c543914fb0 | ||
|
|
40d9e44b03 | ||
|
|
5821c62880 | ||
|
|
d15973e7ef | ||
|
|
475439bca9 | ||
|
|
13fc99f80d | ||
|
|
6a49a51164 | ||
|
|
ba5a701faf | ||
|
|
9e74dbb617 | ||
|
|
3e644fda2d | ||
|
|
7517894f2d | ||
|
|
5e363f48af | ||
|
|
537040bf81 | ||
|
|
308e738e0e | ||
|
|
e16e8b2783 | ||
|
|
e7f03df844 | ||
|
|
8aed9b826d | ||
|
|
e332d8b7ce | ||
|
|
92aeac569f | ||
|
|
53c16e191b | ||
|
|
4791674365 | ||
|
|
8527049827 | ||
|
|
8205ef68ed | ||
|
|
f5c708adf2 | ||
|
|
d42539d2b4 | ||
|
|
3614b6b46e | ||
|
|
86443054e2 | ||
|
|
cc09c2640f | ||
|
|
394399bfb8 | ||
|
|
af1b0e033e | ||
|
|
bdb5f6c137 | ||
|
|
d42a21610f | ||
|
|
f5be7a9862 | ||
|
|
52d408e6d0 | ||
|
|
f69c760598 | ||
|
|
22a43cbdeb | ||
|
|
1ca70df074 | ||
|
|
5514709fb3 | ||
|
|
34a8280ba8 | ||
|
|
f814c94672 | ||
|
|
e1cfbe14be | ||
|
|
a549fd65ef | ||
|
|
239bbd9a9a | ||
|
|
85b6de6684 | ||
|
|
19fa01b5fc | ||
|
|
e3e6dd9ccc | ||
|
|
ba77aa6a76 | ||
|
|
42f36a9da3 | ||
|
|
9abed5ee16 | ||
|
|
e6246ed5c6 | ||
|
|
877b467d96 | ||
|
|
781620d669 | ||
|
|
3ad1f07ffc | ||
|
|
47880403d3 | ||
|
|
89d204a35d | ||
|
|
bdcd417c1c | ||
|
|
4c7738fea1 | ||
|
|
12e7cfd7f7 | ||
|
|
09841dd721 | ||
|
|
8ae65a8fb1 | ||
|
|
fda32bee52 | ||
|
|
e913eab8bb | ||
|
|
2408b8bb8f | ||
|
|
8b257abaf6 | ||
|
|
c00ef3a835 | ||
|
|
0d3c8f4ea2 | ||
|
|
771cb0bbd6 | ||
|
|
3f34f4e7b6 | ||
|
|
e4f411ce9c | ||
|
|
0f47888a17 | ||
|
|
81ce8fed07 | ||
|
|
03b3a4f179 | ||
|
|
24178ca1bc | ||
|
|
e91dd659f0 | ||
|
|
6277ceb274 | ||
|
|
45b22c9f2d | ||
|
|
3a375e1a17 | ||
|
|
ac09719ba6 | ||
|
|
8d8c41c371 | ||
|
|
951c142e96 | ||
|
|
dcdc0b8bb3 | ||
|
|
e11e134ce1 | ||
|
|
e149de42ff | ||
|
|
5baa37b85a | ||
|
|
7916c44484 | ||
|
|
922ba5c781 | ||
|
|
c9c1b47e7a | ||
|
|
03eb86287a | ||
|
|
1ab3826607 | ||
|
|
2fde138c46 | ||
|
|
2640a7c585 | ||
|
|
25ce89b191 | ||
|
|
fd3f3eb607 | ||
|
|
b473c10af9 | ||
|
|
a01c15cc8c | ||
|
|
0fccc276c3 | ||
|
|
06c33964cb | ||
|
|
232d7b4557 | ||
|
|
3205e11173 | ||
|
|
0778ec87ad | ||
|
|
85983552ee | ||
|
|
7b954807da | ||
|
|
9105f0e3dd | ||
|
|
fe57bdd291 | ||
|
|
34cb6b12f8 | ||
|
|
6a8591c348 | ||
|
|
547b1846ae | ||
|
|
187ce5cff8 | ||
|
|
40f544433b | ||
|
|
05fa11e073 | ||
|
|
e4988bc1df | ||
|
|
3a24adec64 | ||
|
|
a620a0b08c | ||
|
|
2cc06fa703 | ||
|
|
9aac2e8424 | ||
|
|
2517eb642c | ||
|
|
7acf492f63 | ||
|
|
abe8910247 | ||
|
|
b35b16e96e | ||
|
|
b49c387cfe | ||
|
|
61d6f93023 | ||
|
|
1a3e9f273e | ||
|
|
8023c01f37 | ||
|
|
674a6bf799 | ||
|
|
e3a476a027 | ||
|
|
a021c1dbce | ||
|
|
a5ea7932dc | ||
|
|
6eb67bde5a | ||
|
|
19eb810537 | ||
|
|
6c865ccd9a | ||
|
|
667c80b39f | ||
|
|
dbada2a227 | ||
|
|
849d9c8af2 | ||
|
|
d61d47470f | ||
|
|
8b80cf2cef | ||
|
|
41f6c26228 | ||
|
|
02efe87c5a | ||
|
|
dc39f3d96a | ||
|
|
9879d8f4ed | ||
|
|
f95afd258a | ||
|
|
6ca07ea1bc | ||
|
|
3ff082cfd9 | ||
|
|
f776aaa9bc | ||
|
|
1587bee16d | ||
|
|
c78686ceca | ||
|
|
a11ba9e1cd | ||
|
|
99d992678a | ||
|
|
14822456aa | ||
|
|
64d6b10239 | ||
|
|
0232ce490d | ||
|
|
9d9e2c995a | ||
|
|
c68ee7f9a0 | ||
|
|
5f5e052038 | ||
|
|
aeb376f3a2 | ||
|
|
ed733916f3 | ||
|
|
64a8b7d4d0 | ||
|
|
c138c2e97d | ||
|
|
d82718b222 | ||
|
|
acdcf74faf | ||
|
|
9fa525e8c6 | ||
|
|
20c0012e62 | ||
|
|
70248c0f42 | ||
|
|
f8af6ae309 | ||
|
|
e8f64d8dcc | ||
|
|
4ea41dc329 | ||
|
|
4835ae67a9 | ||
|
|
6d6aa4c4cc | ||
|
|
70dad77b96 | ||
|
|
cc09030f9d | ||
|
|
73a6c8045d | ||
|
|
fccfaa3dd0 | ||
|
|
14fec0e184 | ||
|
|
fcebb5c4db | ||
|
|
1058ea5ae3 | ||
|
|
e08a1f7973 | ||
|
|
07f9d3ea79 | ||
|
|
73a2c9da6c | ||
|
|
afa4176737 | ||
|
|
cb86576661 | ||
|
|
9b738c1cb6 | ||
|
|
aefb710e5c | ||
|
|
df063fa378 | ||
|
|
2c3b6754d5 | ||
|
|
47303ac790 | ||
|
|
3aab3b9b08 | ||
|
|
3d29ab9279 | ||
|
|
e0fbbb6f2d | ||
|
|
c1331798f5 | ||
|
|
ddad14a96d | ||
|
|
a17609b5e4 | ||
|
|
e619963183 | ||
|
|
56948fe7c2 | ||
|
|
68116414d0 | ||
|
|
16a18f7908 | ||
|
|
ae8af191f7 | ||
|
|
1787b82cfe | ||
|
|
0e49b2b88c | ||
|
|
bab52d7333 | ||
|
|
c96260d82a | ||
|
|
3c23331e9e | ||
|
|
5a7c49dc55 | ||
|
|
6ae047557e | ||
|
|
fa064306fa | ||
|
|
4f46f43379 | ||
|
|
fc87643aae | ||
|
|
6f4f47684f | ||
|
|
c6632ce8d7 | ||
|
|
a59c5de61a | ||
|
|
2bd0ae55fd | ||
|
|
3f2ad5b2a6 | ||
|
|
1250fc276d |
@@ -8,10 +8,10 @@ squircle
|
|||||||
strikethrough
|
strikethrough
|
||||||
touchpad
|
touchpad
|
||||||
ungroup
|
ungroup
|
||||||
pilcrow
|
|
||||||
toc
|
toc
|
||||||
|
|
||||||
# Brands
|
# Brands
|
||||||
codepen
|
codepen
|
||||||
codesandbox
|
codesandbox
|
||||||
dribbble
|
dribbble
|
||||||
|
x.com
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
dist
|
|
||||||
build
|
|
||||||
coverage
|
|
||||||
lib
|
|
||||||
tests
|
|
||||||
node_modules
|
|
||||||
.eslintrc.js
|
|
||||||
docs/images
|
|
||||||
docs/**/examples/
|
|
||||||
packages/lucide-react/dynamicIconImports.js
|
|
||||||
75
.eslintrc.js
@@ -1,75 +0,0 @@
|
|||||||
const DEFAULT_ATTRS = require('./tools/build-icons/render/default-attrs.json');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
node: true,
|
|
||||||
},
|
|
||||||
extends: ['airbnb-base', 'prettier'],
|
|
||||||
plugins: ['import', '@html-eslint'],
|
|
||||||
rules: {
|
|
||||||
'no-console': 'off',
|
|
||||||
'no-param-reassign': 'off',
|
|
||||||
'no-shadow': 'off',
|
|
||||||
'no-use-before-define': 'off',
|
|
||||||
'import/no-extraneous-dependencies': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
devDependencies: ['**/*.test.js', '**/*.spec.js', '**/scripts/**'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'import/extensions': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
pattern: {
|
|
||||||
mjs: 'always',
|
|
||||||
json: 'always',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
parserOptions: {
|
|
||||||
tsconfigRootDir: __dirname,
|
|
||||||
project: ['./docs/tsconfig.json', './packages/*/tsconfig.json'],
|
|
||||||
ecmaVersion: 'latest',
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['./icons/*.svg'],
|
|
||||||
parser: '@html-eslint/parser',
|
|
||||||
rules: {
|
|
||||||
'@html-eslint/require-doctype': 'off',
|
|
||||||
'@html-eslint/no-duplicate-attrs': 'error',
|
|
||||||
'@html-eslint/no-inline-styles': 'error',
|
|
||||||
'@html-eslint/require-attrs': [
|
|
||||||
'error',
|
|
||||||
...Object.entries(DEFAULT_ATTRS).map(([attr, value]) => ({
|
|
||||||
tag: 'svg',
|
|
||||||
attr,
|
|
||||||
value: String(value),
|
|
||||||
})),
|
|
||||||
],
|
|
||||||
'@html-eslint/indent': ['error', 2],
|
|
||||||
'@html-eslint/no-multiple-empty-lines': ['error', { max: 0 }],
|
|
||||||
'@html-eslint/no-extra-spacing-attrs': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
enforceBeforeSelfClose: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@html-eslint/require-closing-tags': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
selfClosing: 'always',
|
|
||||||
allowSelfClosingCustom: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@html-eslint/element-newline': 'error',
|
|
||||||
'@html-eslint/no-trailing-spaces': 'error',
|
|
||||||
'@html-eslint/quotes': 'error',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
1
.github/ISSUE_TEMPLATE/02_bug_report.yml
vendored
@@ -22,6 +22,7 @@ body:
|
|||||||
- label: lucide-svelte
|
- label: lucide-svelte
|
||||||
- label: lucide-vue
|
- label: lucide-vue
|
||||||
- label: lucide-vue-next
|
- label: lucide-vue-next
|
||||||
|
- label: lucide-astro
|
||||||
- label: Figma plugin
|
- label: Figma plugin
|
||||||
- label: source/main
|
- label: source/main
|
||||||
- label: other/not relevant
|
- label: other/not relevant
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ body:
|
|||||||
- label: lucide-svelte
|
- label: lucide-svelte
|
||||||
- label: lucide-vue
|
- label: lucide-vue
|
||||||
- label: lucide-vue-next
|
- label: lucide-vue-next
|
||||||
|
- label: lucide-astro
|
||||||
- label: Figma plugin
|
- label: Figma plugin
|
||||||
- label: all JS packages
|
- label: all JS packages
|
||||||
- label: site
|
- label: site
|
||||||
|
|||||||
44
.github/actions/build-and-test.yml
vendored
@@ -1,44 +0,0 @@
|
|||||||
name: 'Build and Test'
|
|
||||||
description: 'Builds and test a package'
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
name:
|
|
||||||
description: “Name of the package”
|
|
||||||
required: true
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: 'composite'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v2
|
|
||||||
name: Install pnpm
|
|
||||||
id: pnpm-install
|
|
||||||
with:
|
|
||||||
version: 8
|
|
||||||
run_install: false
|
|
||||||
|
|
||||||
- name: Get pnpm store directory
|
|
||||||
id: pnpm-cache
|
|
||||||
run: |
|
|
||||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
name: Setup pnpm cache
|
|
||||||
with:
|
|
||||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
||||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pnpm-store-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install --filter lucide-preact
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: pnpm --filter lucide-preact build
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: pnpm --filter lucide-preact test
|
|
||||||
41
.github/actions/check-icons.yml
vendored
@@ -1,41 +0,0 @@
|
|||||||
name: 'Check icons'
|
|
||||||
description: 'Cross-checks icon and category references in JSON descriptors'
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
name:
|
|
||||||
description: “Name of the package”
|
|
||||||
required: true
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: 'composite'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v2
|
|
||||||
name: Install pnpm
|
|
||||||
id: pnpm-install
|
|
||||||
with:
|
|
||||||
version: 8
|
|
||||||
run_install: false
|
|
||||||
|
|
||||||
- name: Get pnpm store directory
|
|
||||||
id: pnpm-cache
|
|
||||||
run: |
|
|
||||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
name: Setup pnpm cache
|
|
||||||
with:
|
|
||||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
|
||||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pnpm-store-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: pnpm install --filter .
|
|
||||||
|
|
||||||
- name: Check icons and categories
|
|
||||||
run: pnpm checkIcons
|
|
||||||
6
.github/labeler.yml
vendored
@@ -79,6 +79,12 @@
|
|||||||
- any-glob-to-any-file:
|
- any-glob-to-any-file:
|
||||||
- 'packages/lucide-solid/*'
|
- 'packages/lucide-solid/*'
|
||||||
|
|
||||||
|
# For changes in the lucide astro package
|
||||||
|
🚀 astro package:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file:
|
||||||
|
- 'packages/astro/*'
|
||||||
|
|
||||||
# For changes in the lucide static package
|
# For changes in the lucide static package
|
||||||
🪨 static package:
|
🪨 static package:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
|
|||||||
22
.github/pull_request_template.md
vendored
@@ -1,16 +1,18 @@
|
|||||||
<!-- Thank you for contributing! -->
|
<!-- Thank you for contributing! -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
PR Title Guidelines:
|
||||||
|
|
||||||
|
Please use the format: <type>(<scope>): <short description>
|
||||||
|
|
||||||
|
Example: feat(icons): added `camera` icon
|
||||||
|
|
||||||
|
Available types: fix, feat, perf, docs, style, refactor, test, chore, ci, build
|
||||||
|
Common scopes: icons, docs, studio, site, dev
|
||||||
|
-->
|
||||||
|
|
||||||
<!-- Insert `closes #issueNumber` here if merging this PR will resolve an existing issue -->
|
<!-- Insert `closes #issueNumber` here if merging this PR will resolve an existing issue -->
|
||||||
|
## Description
|
||||||
## What is the purpose of this pull request?
|
|
||||||
<!-- Please choose one of the following, and put an "x" next to it. -->
|
|
||||||
- [ ] New Icon
|
|
||||||
- [ ] Bug fix
|
|
||||||
- [ ] New Feature
|
|
||||||
- [ ] Documentation update
|
|
||||||
- [ ] Other:
|
|
||||||
|
|
||||||
### Description
|
|
||||||
<!-- Please insert your description here and provide info about the "what" this PR is contribution -->
|
<!-- Please insert your description here and provide info about the "what" this PR is contribution -->
|
||||||
|
|
||||||
### Icon use case <!-- ONLY for new icons, remove this part if not icon PR -->
|
### Icon use case <!-- ONLY for new icons, remove this part if not icon PR -->
|
||||||
|
|||||||
42
.github/workflows/ci.yml
vendored
@@ -9,18 +9,18 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
create-release:
|
create-release:
|
||||||
if: github.repository == 'lucide-icons/lucide'
|
if: github.repository == 'lucide-icons/lucide' && startsWith(github.event.head_commit.message, 'feat(icons)')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
VERSION: ${{ steps.new-version.outputs.NEW_VERSION }}
|
VERSION: ${{ steps.new-version.outputs.NEW_VERSION }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -61,8 +61,40 @@ jobs:
|
|||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ steps.new-version.outputs.NEW_VERSION }}
|
tag_name: ${{ steps.new-version.outputs.NEW_VERSION }}
|
||||||
name: New icons ${{ steps.new-version.outputs.NEW_VERSION }}
|
name: Version ${{ steps.new-version.outputs.NEW_VERSION }}
|
||||||
body: ${{ steps.change-log.outputs.CHANGE_LOG }}
|
generate_release_notes: true
|
||||||
|
|
||||||
|
test-semantic-release:
|
||||||
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Semantic Release
|
||||||
|
id: semantic
|
||||||
|
uses: cycjimmy/semantic-release-action@v4
|
||||||
|
with:
|
||||||
|
tag_format: ${version}
|
||||||
|
branches: |
|
||||||
|
['new-release-workflow']
|
||||||
|
extends: |
|
||||||
|
semantic-release-monorepo
|
||||||
|
extra_plugins: |
|
||||||
|
@semantic-release/github
|
||||||
|
@semantic-release/git
|
||||||
|
@semantic-release/release-notes-generator
|
||||||
|
conventional-changelog-conventionalcommits
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Log output
|
||||||
|
if: steps.semantic.outputs.new_release_published == 'true'
|
||||||
|
run: |
|
||||||
|
echo ${{ steps.semantic.outputs.new_release_version }}
|
||||||
|
echo ${{ steps.semantic.outputs.new_release_major_version }}
|
||||||
|
echo ${{ steps.semantic.outputs.new_release_minor_version }}
|
||||||
|
echo ${{ steps.semantic.outputs.new_release_patch_version }}
|
||||||
|
|
||||||
start-release:
|
start-release:
|
||||||
if: github.repository == 'lucide-icons/lucide'
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Check for blocked phrases in issue title
|
- name: Check for blocked phrases in issue title
|
||||||
run: |
|
run: |
|
||||||
ISSUE_TITLE=$(jq -r '.issue.title' "$GITHUB_EVENT_PATH")
|
ISSUE_TITLE=$(jq -r '.issue.title' "$GITHUB_EVENT_PATH")
|
||||||
BLOCKED_PHRASES=("twitter" "whatsapp" "logo" "google" "tiktok" "facebook" "slack" "discord" "bluesky")
|
BLOCKED_PHRASES=("twitter" "whatsapp" "logo" "google" "tiktok" "facebook" "slack" "discord" "bluesky" "spotify" "behance" "pix" "x.com" "telegram")
|
||||||
|
|
||||||
# Check title and body for blocked phrases
|
# Check title and body for blocked phrases
|
||||||
for PHRASE in "${BLOCKED_PHRASES[@]}"
|
for PHRASE in "${BLOCKED_PHRASES[@]}"
|
||||||
|
|||||||
58
.github/workflows/comment-icon-preview.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
name: Icon preview comment
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: ['Pull request icon preview']
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
upload:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: >
|
||||||
|
github.event.workflow_run.event == 'pull_request' &&
|
||||||
|
github.event.workflow_run.conclusion == 'success'
|
||||||
|
steps:
|
||||||
|
- name: 'Download artifact'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
run_id: context.payload.workflow_run.id,
|
||||||
|
});
|
||||||
|
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
|
||||||
|
return artifact.name == "pr_number"
|
||||||
|
})[0];
|
||||||
|
let download = await github.rest.actions.downloadArtifact({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
artifact_id: matchArtifact.id,
|
||||||
|
archive_format: 'zip',
|
||||||
|
});
|
||||||
|
const fs = require('fs');
|
||||||
|
fs.writeFileSync('${{github.workspace}}/pr_number.zip', Buffer.from(download.data));
|
||||||
|
|
||||||
|
- name: 'Unzip artifact'
|
||||||
|
run: unzip pr_number.zip
|
||||||
|
|
||||||
|
- name: 'Get PR number'
|
||||||
|
run: echo "number=$(cat NR)" >> $GITHUB_OUTPUT
|
||||||
|
id: pr-number
|
||||||
|
|
||||||
|
- name: Find Comment
|
||||||
|
uses: peter-evans/find-comment@v2
|
||||||
|
id: pr-comment
|
||||||
|
with:
|
||||||
|
issue-number: ${{ steps.pr-number.outputs.number }}
|
||||||
|
comment-author: 'github-actions[bot]'
|
||||||
|
body-includes: Added or changed icons
|
||||||
|
|
||||||
|
- name: Create or update comment
|
||||||
|
uses: peter-evans/create-or-update-comment@v3
|
||||||
|
with:
|
||||||
|
comment-id: ${{ steps.pr-comment.outputs.comment-id }}
|
||||||
|
issue-number: ${{ steps.pr-number.outputs.number }}
|
||||||
|
body-path: comment-markup.md
|
||||||
|
edit-mode: replace
|
||||||
1
.github/workflows/labeler.yml
vendored
@@ -9,4 +9,5 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/labeler@v5
|
- uses: actions/labeler@v5
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
name: Linting
|
name: Linting PR
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
paths-ignore:
|
||||||
- '**'
|
- icons/*.svg
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
linting:
|
lint-code:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
32
.github/workflows/lint-pr-title.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: Linting PR
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- edited
|
||||||
|
- reopened
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-pr-title:
|
||||||
|
name: PR Title Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: amannn/action-semantic-pull-request@v5
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
types: |
|
||||||
|
fix
|
||||||
|
feat
|
||||||
|
perf
|
||||||
|
refactor
|
||||||
|
test
|
||||||
|
style
|
||||||
|
docs
|
||||||
|
ci
|
||||||
|
build
|
||||||
|
chore
|
||||||
|
requireScope: true
|
||||||
|
ignoreLabels: |
|
||||||
|
bot
|
||||||
39
.github/workflows/linting-icons.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
name: Linting Icons
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'icons/*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-filenames:
|
||||||
|
name: Lint Filenames
|
||||||
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
- name: Get changed files
|
||||||
|
id: changed-files
|
||||||
|
uses: tj-actions/changed-files@v46
|
||||||
|
with:
|
||||||
|
files: icons/*
|
||||||
|
|
||||||
|
- name: Generate annotations
|
||||||
|
run: node ./scripts/lintFilenames.mts
|
||||||
|
env:
|
||||||
|
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||||
|
|
||||||
|
lint-aliases:
|
||||||
|
name: Check Uniqueness of Aliases
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check Uniqueness of Aliases
|
||||||
|
run: "! cat <(printf \"%s\\n\" icons/*.json | while read -r name; do basename \"$name\" .json; done) <(jq -cr 'select(.aliases) | .aliases[] | if type==\"string\" then . else .name end' icons/*.json) | sort | uniq -c | grep -ve '^\\s*1 '"
|
||||||
12
.github/workflows/lucide-angular.yml
vendored
@@ -12,11 +12,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -27,12 +27,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
name: Lucide Vue checks
|
name: Lucide Astro Checks
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- packages/lucide-vue/**
|
- packages/astro/**
|
||||||
- packages/shared/**
|
- packages/shared/**
|
||||||
- tools/build-icons/**
|
- tools/build-icons/**
|
||||||
- tools/rollup-plugins/**
|
|
||||||
- pnpm-lock.yaml
|
- pnpm-lock.yaml
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -17,14 +16,14 @@ jobs:
|
|||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v2
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version-file: 'package.json'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: pnpm --filter lucide-vue build
|
run: pnpm --filter @lucide/astro build
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -33,11 +32,11 @@ jobs:
|
|||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v2
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v3.8.1
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version-file: 'package.json'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: pnpm --filter lucide-vue test
|
run: pnpm --filter @lucide/astro test
|
||||||
7
.github/workflows/lucide-font.yml
vendored
@@ -3,7 +3,6 @@ name: Lucide font checks
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- icons/**
|
|
||||||
- tools/build-font/**
|
- tools/build-font/**
|
||||||
- pnpm-lock.yaml
|
- pnpm-lock.yaml
|
||||||
|
|
||||||
@@ -12,11 +11,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -28,7 +27,7 @@ jobs:
|
|||||||
run: pnpm build:font
|
run: pnpm build:font
|
||||||
|
|
||||||
- name: 'Upload to Artifacts'
|
- name: 'Upload to Artifacts'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: lucide-font
|
name: lucide-font
|
||||||
path: lucide-font
|
path: lucide-font
|
||||||
|
|||||||
4
.github/workflows/lucide-preact.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
22
.github/workflows/lucide-react-native.yml
vendored
@@ -10,15 +10,31 @@ on:
|
|||||||
- pnpm-lock.yaml
|
- pnpm-lock.yaml
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lucide-react-native:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: pnpm --filter lucide-react-native build
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: pnpm/action-setup@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
12
.github/workflows/lucide-react.yml
vendored
@@ -15,11 +15,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -30,12 +30,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
8
.github/workflows/lucide-shared.yml
vendored
@@ -10,12 +10,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
12
.github/workflows/lucide-solid.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -29,12 +29,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
4
.github/workflows/lucide-static.yml
vendored
@@ -12,11 +12,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
43
.github/workflows/lucide-svelte-5.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Lucide Svelte 5 checks
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- packages/svelte/**
|
||||||
|
- packages/shared/**
|
||||||
|
- tools/build-icons/**
|
||||||
|
- tools/rollup-plugins/**
|
||||||
|
- pnpm-lock.yaml
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: pnpm/action-setup@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: pnpm --filter @lucide/svelte build
|
||||||
|
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: pnpm/action-setup@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: pnpm --filter @lucide/svelte test
|
||||||
12
.github/workflows/lucide-svelte.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -29,12 +29,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
12
.github/workflows/lucide-vue-next.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -29,12 +29,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
12
.github/workflows/lucide.yml
vendored
@@ -13,11 +13,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -28,12 +28,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v3.8.1
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
|
|||||||
46
.github/workflows/pull-request-icon-preview.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: Pull request icon preview
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'icons/*.svg'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate-changed-icons-comment:
|
||||||
|
name: Generate Changed Icons Comment
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
|
- name: Get changed files
|
||||||
|
id: changed-files
|
||||||
|
uses: tj-actions/changed-files@v46
|
||||||
|
with:
|
||||||
|
files: icons/*.svg
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
- name: Install svgson for code preview (safer and faster than installing all deps)
|
||||||
|
run: npm install svgson@5.3.1 --force
|
||||||
|
|
||||||
|
- name: Save PR number
|
||||||
|
run: |
|
||||||
|
mkdir -p ./pr
|
||||||
|
echo ${{ github.event.number }} > ./pr/NR
|
||||||
|
|
||||||
|
- name: Generate comment markup
|
||||||
|
run: node ./scripts/generateChangedIconsCommentMarkup.mts >> ./pr/comment-markup.md
|
||||||
|
id: comment-markup
|
||||||
|
env:
|
||||||
|
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: pr_number
|
||||||
|
path: pr/
|
||||||
37
.github/workflows/pull-request-tags-suggestions.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: Pull request tags suggestions
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
paths:
|
||||||
|
- 'icons/*.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pull-request-tags-suggestions:
|
||||||
|
name: Pull Request Tags Suggestions
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# We checkout the main branch of main repository for security reasons.
|
||||||
|
# This is to prevent the workflow from running on a forked repository.
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: lucide-icons/lucide
|
||||||
|
- uses: pnpm/action-setup@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Generate comment markup
|
||||||
|
run: node ./scripts/suggestTags.mts
|
||||||
|
env:
|
||||||
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||||
|
PULL_REQUEST_NUMBER: ${{ github.event.number }}
|
||||||
|
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
123
.github/workflows/pull-request.yml
vendored
@@ -1,123 +0,0 @@
|
|||||||
name: Add Changed Icons comment
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
paths:
|
|
||||||
- 'icons/*'
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- fix-icon-preview
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint-filenames:
|
|
||||||
if: github.repository == 'lucide-icons/lucide'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
- name: Get changed files
|
|
||||||
id: changed-files
|
|
||||||
uses: tj-actions/changed-files@v41
|
|
||||||
with:
|
|
||||||
files: icons/*
|
|
||||||
- name: Generate annotations
|
|
||||||
run: node ./scripts/lintFilenames.mjs
|
|
||||||
env:
|
|
||||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
|
||||||
|
|
||||||
lint-contributors:
|
|
||||||
if: github.repository == 'lucide-icons/lucide'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
- name: Get changed files
|
|
||||||
id: changed-files
|
|
||||||
uses: tj-actions/changed-files@v41
|
|
||||||
with:
|
|
||||||
files: icons/*
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
- name: Install simple-git (safer and faster than installing all deps)
|
|
||||||
run: npm install simple-git
|
|
||||||
- name: Generate annotations
|
|
||||||
run: node ./scripts/updateContributors.mjs
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
FETCH_DEPTH: ${{ github.event.pull_request.commits }}
|
|
||||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
|
||||||
- name: Generate annotations
|
|
||||||
env:
|
|
||||||
ANNOTATION_SEVERITY: notice
|
|
||||||
ANNOTATION_TITLE: Contributors have changed!
|
|
||||||
ANNOTATION_DESCRIPTION: Don't add people who have only performed automatic optimizations.
|
|
||||||
run: |
|
|
||||||
git diff --unified=0 -- icons/*.json | # diff icon metadata (unified=0 gives the correct chunk line number)
|
|
||||||
perl -ne '/^(\+|- |@)/ && print' | # get chunks (lines that start with "+++", "@@", "+ ", "- ")
|
|
||||||
perl -pe 's/\n/%0A/' | # url encode line breaks (\n -> %0A)
|
|
||||||
perl -pe 's/%0A(\+\+\+ b\/)/\n\1/g' | # split chunks(one chunk per line)
|
|
||||||
perl -pe "s/\+\+\+ b\/([^@]*)%0A@@ -(\d+)[^\s]* \+(\d+)[^@]*@@(.*)/::$ANNOTATION_SEVERITY file=\1,line=\2,endLine=\3,title=$ANNOTATION_TITLE::$ANNOTATION_DESCRIPTION%0A\4/"
|
|
||||||
# Example for the previous substitution
|
|
||||||
# input: +++ b/icons/accessibility.json%0A@@ -2,0 +3 @@%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
|
|
||||||
# output: ::$ANNOTATION_SEVERITY file=icons/accessibility.json,line=2,endLine=3,title=$ANNOTATION_TITLE::$ANNOTATION_DESCRIPTION%0A%0A+ "contributors": ["hi"],%0A@@ -13 +14 @@%0A+}%0A
|
|
||||||
|
|
||||||
lint-aliases:
|
|
||||||
name: Check Uniqueness of Aliases
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Check Uniqueness of Aliases
|
|
||||||
run: "! cat <(printf \"%s\\n\" icons/*.json | while read -r name; do basename \"$name\" .json; done) <(jq -cr 'select(.aliases) | .aliases[] | if type==\"string\" then . else .name end' icons/*.json) | sort | uniq -c | grep -ve '^\\s*1 '"
|
|
||||||
|
|
||||||
generate-changed-icons-comment:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
|
||||||
|
|
||||||
- name: Get changed files
|
|
||||||
id: changed-files
|
|
||||||
uses: tj-actions/changed-files@v41
|
|
||||||
with:
|
|
||||||
files: icons/*.svg
|
|
||||||
|
|
||||||
- name: Find Comment
|
|
||||||
uses: peter-evans/find-comment@v2
|
|
||||||
id: pr-comment
|
|
||||||
with:
|
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
|
||||||
comment-author: 'github-actions[bot]'
|
|
||||||
body-includes: Added or changed icons
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
- name: Install svgson for code preview (safer and faster than installing all deps)
|
|
||||||
run: npm install svgson
|
|
||||||
|
|
||||||
- name: Generate comment markup
|
|
||||||
run: node ./scripts/generateChangedIconsCommentMarkup.mjs >> comment-markup.md
|
|
||||||
id: comment-markup
|
|
||||||
env:
|
|
||||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
|
||||||
|
|
||||||
- name: Create or update comment
|
|
||||||
uses: peter-evans/create-or-update-comment@v3
|
|
||||||
with:
|
|
||||||
comment-id: ${{ steps.pr-comment.outputs.comment-id }}
|
|
||||||
issue-number: ${{ github.event.pull_request.number }}
|
|
||||||
body-path: ./comment-markup.md
|
|
||||||
edit-mode: replace
|
|
||||||
32
.github/workflows/release.yml
vendored
@@ -38,6 +38,8 @@ jobs:
|
|||||||
if: github.repository == 'lucide-icons/lucide'
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: pre-release
|
needs: pre-release
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -52,14 +54,16 @@ jobs:
|
|||||||
'lucide-preact',
|
'lucide-preact',
|
||||||
'lucide-solid',
|
'lucide-solid',
|
||||||
'lucide-svelte',
|
'lucide-svelte',
|
||||||
|
'@lucide/astro',
|
||||||
|
'@lucide/svelte',
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -77,20 +81,24 @@ jobs:
|
|||||||
run: pnpm --filter ${{ matrix.package }} test
|
run: pnpm --filter ${{ matrix.package }} test
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: pnpm --filter ${{ matrix.package }} publish --no-git-checks --ignore-scripts
|
run: pnpm --filter ${{ matrix.package }} publish --access public --no-git-checks --ignore-scripts
|
||||||
|
env:
|
||||||
|
NPM_CONFIG_PROVENANCE: true
|
||||||
|
|
||||||
lucide-static:
|
lucide-static:
|
||||||
if: github.repository == 'lucide-icons/lucide'
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [pre-release, lucide-font]
|
needs: [pre-release, lucide-font]
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -109,6 +117,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: pnpm --filter lucide-static publish --no-git-checks
|
run: pnpm --filter lucide-static publish --no-git-checks
|
||||||
|
env:
|
||||||
|
NPM_CONFIG_PROVENANCE: true
|
||||||
|
|
||||||
lucide-font:
|
lucide-font:
|
||||||
if: github.repository == 'lucide-icons/lucide'
|
if: github.repository == 'lucide-icons/lucide'
|
||||||
@@ -116,11 +126,11 @@ jobs:
|
|||||||
needs: pre-release
|
needs: pre-release
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: pnpm/action-setup@v2
|
- uses: pnpm/action-setup@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -132,7 +142,7 @@ jobs:
|
|||||||
run: pnpm build:font
|
run: pnpm build:font
|
||||||
|
|
||||||
- name: 'Upload to Artifacts'
|
- name: 'Upload to Artifacts'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: lucide-font
|
name: lucide-font
|
||||||
path: lucide-font
|
path: lucide-font
|
||||||
@@ -144,14 +154,14 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v4
|
||||||
- name: Zip font and icons
|
- name: Zip font and icons
|
||||||
run: |
|
run: |
|
||||||
zip -r lucide-font-${{ needs.pre-release.outputs.VERSION }}.zip lucide-font
|
zip -r lucide-font-${{ needs.pre-release.outputs.VERSION }}.zip lucide-font
|
||||||
zip -r lucide-icons-${{ needs.pre-release.outputs.VERSION }}.zip icons
|
zip -r lucide-icons-${{ needs.pre-release.outputs.VERSION }}.zip icons
|
||||||
|
|
||||||
- name: Release zip and fonts
|
- name: Release zip and fonts
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ needs.pre-release.outputs.VERSION }}
|
tag_name: ${{ needs.pre-release.outputs.VERSION }}
|
||||||
files: |
|
files: |
|
||||||
|
|||||||
32
.github/workflows/request-review.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: 'Request Review'
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened]
|
||||||
|
paths: icons/*.svg
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
request-review:
|
||||||
|
if: github.event.pull_request.draft == false
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||||
|
- name: Get changed files
|
||||||
|
id: changed-files
|
||||||
|
uses: tj-actions/changed-files@v41
|
||||||
|
with:
|
||||||
|
files: icons/*.svg
|
||||||
|
- run: |
|
||||||
|
while IFS= read -r file; do
|
||||||
|
jq -r '.contributors[]' "${file%.svg}.json"
|
||||||
|
done <<< "$CHANGED_FILES" | while read -r contributor; do
|
||||||
|
gh pr edit "${{ github.event.pull_request.number }}" --add-reviewer "$contributor" || true
|
||||||
|
done
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||||
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
|||||||
.obsidian
|
.obsidian
|
||||||
.now
|
.now
|
||||||
.idea
|
.idea
|
||||||
|
.env
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
build
|
build
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ Guidelines for pull requests:
|
|||||||
|
|
||||||
- __Make your commit messages as descriptive as possible.__ Include as much information as you can. Explain anything that the file diffs themselves won’t make apparent.
|
- __Make your commit messages as descriptive as possible.__ Include as much information as you can. Explain anything that the file diffs themselves won’t make apparent.
|
||||||
- __Document your pull request__. Explain your fix, link to the relevant issue, add screenshots when adding new icons.
|
- __Document your pull request__. Explain your fix, link to the relevant issue, add screenshots when adding new icons.
|
||||||
- __Make sure the target of your pull request is the relevant branch__. Most of bugfix or new feature should go to the `main` branch.
|
- __Make sure the target of your pull request is the relevant branch__. Most of bug fixes or new feature should go to the `main` branch.
|
||||||
- __Include only related work__. If your pull request has unrelated commit, it won't be accepted.
|
- __Include only related work__. If your pull request has unrelated commits, it won't be accepted.
|
||||||
|
|
||||||
### Pull Requests Including Icons
|
### Icon Pull Requests
|
||||||
|
|
||||||
#### Guidelines
|
#### Guidelines
|
||||||
|
|
||||||
@@ -27,26 +27,30 @@ Please make sure you follow the icon guidelines, that should be followed to keep
|
|||||||
|
|
||||||
Read it here: [ICON_GUIDELINES](https://lucide.dev/docs/icon-design-guide).
|
Read it here: [ICON_GUIDELINES](https://lucide.dev/docs/icon-design-guide).
|
||||||
|
|
||||||
### Editor guides
|
#### Lucide Studio
|
||||||
|
|
||||||
|
For formatting and adjusting SVG icons, [@jguddas](https://github.com/jguddas) made a great tool called [Lucide Studio](https://studio.lucide.dev/). It is a web-based SVG editor that allows you to edit and adjust icons in the Lucide style. You can use it to create new icons or modify existing ones.
|
||||||
|
|
||||||
|
#### Editor guides
|
||||||
|
|
||||||
Here you can find instructions on how to implement the guidelines with different vector graphics editors:
|
Here you can find instructions on how to implement the guidelines with different vector graphics editors:
|
||||||
|
|
||||||
#### [Adobe Illustrator Guide](https://lucide.dev/docs/illustrator-guide)
|
##### [Adobe Illustrator Guide](https://lucide.dev/docs/illustrator-guide)
|
||||||
|
|
||||||
You can also [download an Adobe Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai).
|
You can also [download an Adobe Illustrator template](https://github.com/lucide-icons/lucide/blob/main/docs/public/templates/illustrator_template.ai).
|
||||||
|
|
||||||
#### [Inkscape Guide](https://lucide.dev/docs/inkscape-guide)
|
##### [Inkscape Guide](https://lucide.dev/docs/inkscape-guide)
|
||||||
|
|
||||||
#### [Figma Guide](https://lucide.dev/docs/figma-guide)
|
##### [Figma Guide](https://lucide.dev/docs/figma-guide)
|
||||||
|
|
||||||
#### [Affinity Designer Guide](https://lucide.dev/guide/design/affinity-designer-guide)
|
##### [Affinity Designer Guide](https://lucide.dev/guide/design/affinity-designer-guide)
|
||||||
|
|
||||||
### Submitting Multiple Icons
|
#### Submitting Multiple Icons
|
||||||
|
|
||||||
If you want submit multiple icons, please separate the icons and group them. That makes reviewing the icons easier and keep the thread clean and scoped.
|
If you want to submit multiple icons, please separate the icons and group them. That makes reviewing the icons easier and keeps the thread clean and scoped.
|
||||||
So don't submit multiple icons in one PR that have noting to do with each other.
|
So don't submit multiple icons in one PR that have nothing to do with each other.
|
||||||
So for example don't create one PR with icons: `arrow-up`, `bicycle`, `arrow-down`.
|
So for example don't create one PR with icons: `arrow-up`, `bicycle`, `arrow-down`.
|
||||||
Seperate them by two PRs; 'pr-01' `arrow`, `arrow-down` and 'pr-02' `bicycle`.
|
Separate them into two PRs; 'pr-01' `arrow`, `arrow-down` and 'pr-02' `bicycle`.
|
||||||
|
|
||||||
## Icon Requests
|
## Icon Requests
|
||||||
|
|
||||||
@@ -77,7 +81,7 @@ To distribute different packages we use [PNPM workspaces](https://pnpm.io/worksp
|
|||||||
The configured directory for workspaces is the [packages](https://github.com/lucide-icons/lucide/tree/main/packages) directory, located in the root directory. There you will find all the current packages from lucide.
|
The configured directory for workspaces is the [packages](https://github.com/lucide-icons/lucide/tree/main/packages) directory, located in the root directory. There you will find all the current packages from lucide.
|
||||||
There are more workspaces defined, see [`pnpm-workspace.yaml`](https://github.com/lucide-icons/lucide/blob/main/pnpm-workspace.yaml).
|
There are more workspaces defined, see [`pnpm-workspace.yaml`](https://github.com/lucide-icons/lucide/blob/main/pnpm-workspace.yaml).
|
||||||
|
|
||||||
> Note: One package is not managed by pnpm: **lucide-flutter**, this package is written in Dart and used pub for publishing.
|
> Note: One package is not managed by pnpm: **lucide-flutter**, this package is written in Dart and uses pub for publishing.
|
||||||
|
|
||||||
### Generated Code
|
### Generated Code
|
||||||
|
|
||||||
@@ -127,7 +131,7 @@ When adding new features to for example the icon component for a framework. It i
|
|||||||
|
|
||||||
### Local Testing
|
### Local Testing
|
||||||
|
|
||||||
To test changes in a local project, you can use `yarn link`, `npm link`, `bun link` or `pnpm link` to link the package. Before you do this make sure you builded the package first.
|
To test changes in a local project, you can use `yarn link`, `npm link`, `bun link` or `pnpm link` to link the package. Before you do this make sure you've built the package first.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# in packages/lucide-react
|
# in packages/lucide-react
|
||||||
@@ -157,6 +161,30 @@ lucide
|
|||||||
|
|
||||||
The lucide.dev website is using [vitepress](https://vitepress.dev/) to generate the static website. The markdown files are located in the docs directory.
|
The lucide.dev website is using [vitepress](https://vitepress.dev/) to generate the static website. The markdown files are located in the docs directory.
|
||||||
|
|
||||||
|
#### Running the Docs Website Locally
|
||||||
|
|
||||||
|
To test the docs website locally, follow these steps:
|
||||||
|
|
||||||
|
1. **Navigate to the docs directory**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd docs
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Start the Local Development Server**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm run docs:dev
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Open the Website Locally**
|
||||||
|
|
||||||
|
Vitepress should open with the following format:
|
||||||
|
|
||||||
|
VitePress dev server is running at:
|
||||||
|
- **Local**: `http://localhost:3000/`
|
||||||
|
- **Network**: `http://192.168.x.x:3000/`
|
||||||
|
|
||||||
### Guides
|
### Guides
|
||||||
|
|
||||||
Detailed documentation about: installation, guides, packages, design guides etc.
|
Detailed documentation about: installation, guides, packages, design guides etc.
|
||||||
@@ -165,15 +193,13 @@ Detailed documentation about: installation, guides, packages, design guides etc.
|
|||||||
|
|
||||||
All the icons of lucide in SVG format. These will be used as source for all the packages and other distributions for the lucide icons.
|
All the icons of lucide in SVG format. These will be used as source for all the packages and other distributions for the lucide icons.
|
||||||
|
|
||||||
### packages
|
### Packages
|
||||||
|
|
||||||
Includes all the (npm) packages of lucide.
|
Includes all the (npm) packages of lucide.
|
||||||
|
|
||||||
> Note: One package is not managed by pnpm: **lucide-flutter**, this package is written in Dart and used pub for publishing.
|
### Scripts
|
||||||
|
|
||||||
### scripts
|
Includes useful scripts to automate certain jobs. Big part of the scripts is the template generation, for example it generates icon components for all the packages. These scripts are usually executed from the "scripts" section in the package.json.
|
||||||
|
|
||||||
Includes usefully scripts to automate certain jobs. Big part of the scripts is the template generation, for example it generates icon components for all the packages. These scripts are usually executed from the "scripts" section in the package.json.
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
@@ -190,4 +216,4 @@ If you need any help or have problems with you contribution. Please don't hesita
|
|||||||
Thank you to all the people who already contributed to Lucide!
|
Thank you to all the people who already contributed to Lucide!
|
||||||
|
|
||||||
<a href="https://github.com/lucide-icons/lucide/graphs/contributors">
|
<a href="https://github.com/lucide-icons/lucide/graphs/contributors">
|
||||||
<img src="https://opencollective.com/lucide-icons/contributors.svg?width=890" /></a>
|
<img src="https://opencollective.com/lucide-icons/contributors.svg?width=800" /></a>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ Lucide is an open-source icon library that provides 1000+ vector (svg) files for
|
|||||||
| <img src="https://lucide.dev/framework-logos/preact.svg" alt="Preact logo" width="48"> | **`lucide-preact`** | [](https://www.npmjs.com/package/lucide-preact) |  | [Docs](https://lucide.dev/guide/packages/lucide-preact) · [Source](./packages/lucide-preact) |
|
| <img src="https://lucide.dev/framework-logos/preact.svg" alt="Preact logo" width="48"> | **`lucide-preact`** | [](https://www.npmjs.com/package/lucide-preact) |  | [Docs](https://lucide.dev/guide/packages/lucide-preact) · [Source](./packages/lucide-preact) |
|
||||||
| <img src="https://lucide.dev/framework-logos/react-native.svg" alt="React Native logo" width="48"> | **`lucide-react-native`** | [](https://www.npmjs.com/package/lucide-react-native) |  | [Docs](https://lucide.dev/guide/packages/lucide-react-native) · [Source](./packages/lucide-react-native) |
|
| <img src="https://lucide.dev/framework-logos/react-native.svg" alt="React Native logo" width="48"> | **`lucide-react-native`** | [](https://www.npmjs.com/package/lucide-react-native) |  | [Docs](https://lucide.dev/guide/packages/lucide-react-native) · [Source](./packages/lucide-react-native) |
|
||||||
| <img src="https://lucide.dev/framework-logos/angular.svg" alt="Angular logo" width="48"> | **`lucide-angular`** | [](https://www.npmjs.com/package/lucide-angular) |  | [Docs](https://lucide.dev/guide/packages/lucide-angular) · [Source](./packages/lucide-angular) |
|
| <img src="https://lucide.dev/framework-logos/angular.svg" alt="Angular logo" width="48"> | **`lucide-angular`** | [](https://www.npmjs.com/package/lucide-angular) |  | [Docs](https://lucide.dev/guide/packages/lucide-angular) · [Source](./packages/lucide-angular) |
|
||||||
|
| <img src="https://lucide.dev/framework-logos/astro.svg" alt="Astro logo" width="48"> | **`@lucide/astro`** | [](https://www.npmjs.com/package/@lucide/astro) |  | [Docs](https://lucide.dev/guide/packages/lucide-astro) · [Source](./packages/astro) |
|
||||||
| <img src="https://lucide.dev/framework-logos/svg.svg" alt="SVG logo" width="48"> | **`lucide-static`** | [](https://www.npmjs.com/package/lucide-static) |  | [Docs](https://lucide.dev/guide/packages/lucide-static) · [Source](./packages/lucide-static) |
|
| <img src="https://lucide.dev/framework-logos/svg.svg" alt="SVG logo" width="48"> | **`lucide-static`** | [](https://www.npmjs.com/package/lucide-static) |  | [Docs](https://lucide.dev/guide/packages/lucide-static) · [Source](./packages/lucide-static) |
|
||||||
|
|
||||||
### Figma
|
### Figma
|
||||||
@@ -69,7 +70,9 @@ Lucide is totally free for commercial use and personal use, this software is lic
|
|||||||
Thank you to all the people who contributed to Lucide!
|
Thank you to all the people who contributed to Lucide!
|
||||||
|
|
||||||
<a href="https://github.com/lucide-icons/lucide/graphs/contributors">
|
<a href="https://github.com/lucide-icons/lucide/graphs/contributors">
|
||||||
<img src="https://opencollective.com/lucide-icons/contributors.svg?width=890" /></a>
|
|
||||||
|
<img src="https://opencollective.com/lucide-icons/contributors.svg?width=800" />
|
||||||
|
</a>
|
||||||
|
|
||||||
## Sponsors
|
## Sponsors
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ export default eventHandler((event) => {
|
|||||||
const data = pathData.at(-1).slice(0, -4);
|
const data = pathData.at(-1).slice(0, -4);
|
||||||
const [name] = pathData;
|
const [name] = pathData;
|
||||||
|
|
||||||
const src = Buffer.from(data, 'base64')
|
const src = Buffer.from(data, 'base64').toString('utf8').replaceAll('\n', '');
|
||||||
.toString('utf8')
|
|
||||||
.replaceAll('\n', '')
|
const width = parseInt((src.includes('svg') ? src.match(/width="(\d+)"/)?.[1] : null) ?? '24');
|
||||||
.replace(/<svg[^>]*>|<\/svg>/g, '');
|
const height = parseInt((src.includes('svg') ? src.match(/height="(\d+)"/)?.[1] : null) ?? '24');
|
||||||
|
|
||||||
const children = [];
|
const children = [];
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export default eventHandler((event) => {
|
|||||||
children.push(
|
children.push(
|
||||||
createElement(Backdrop, {
|
createElement(Backdrop, {
|
||||||
backdropString,
|
backdropString,
|
||||||
src,
|
src: src.replace(/<svg[^>]*>|<\/svg>/g, ''),
|
||||||
color: '#777',
|
color: '#777',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -46,7 +46,18 @@ export default eventHandler((event) => {
|
|||||||
|
|
||||||
const svg = Buffer.from(
|
const svg = Buffer.from(
|
||||||
// We can't use jsx here, is not supported here by nitro.
|
// We can't use jsx here, is not supported here by nitro.
|
||||||
renderToString(createElement(SvgPreview, { src, showGrid: true }, children)),
|
renderToString(
|
||||||
|
createElement(
|
||||||
|
SvgPreview,
|
||||||
|
{
|
||||||
|
src: src.replace(/<svg[^>]*>|<\/svg>/g, ''),
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
showGrid: true,
|
||||||
|
},
|
||||||
|
children,
|
||||||
|
),
|
||||||
|
),
|
||||||
).toString('utf8');
|
).toString('utf8');
|
||||||
|
|
||||||
defaultContentType(event, 'image/svg+xml');
|
defaultContentType(event, 'image/svg+xml');
|
||||||
|
|||||||
@@ -36,6 +36,13 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
head: [
|
head: [
|
||||||
|
[
|
||||||
|
'link',
|
||||||
|
{
|
||||||
|
rel: 'preconnect',
|
||||||
|
href: 'https://analytics.lucide.dev',
|
||||||
|
},
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'script',
|
'script',
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -127,8 +127,27 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lucide-static": {
|
"@lucide/astro": {
|
||||||
|
"docsAlias": "lucide-astro",
|
||||||
|
"packageDirname": "astro",
|
||||||
"order": 8,
|
"order": 8,
|
||||||
|
"icon": "astro",
|
||||||
|
"iconDark": "astro-dark",
|
||||||
|
"shields": [
|
||||||
|
{
|
||||||
|
"alt": "npm",
|
||||||
|
"src": "https://img.shields.io/npm/v/@lucide/astro",
|
||||||
|
"href": "https://www.npmjs.com/package/@lucide/astro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alt": "npm",
|
||||||
|
"src": "https://img.shields.io/npm/dw/@lucide/astro",
|
||||||
|
"href": "https://www.npmjs.com/package/@lucide/astro"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lucide-static": {
|
||||||
|
"order": 9,
|
||||||
"icon": "svg",
|
"icon": "svg",
|
||||||
"shields": [
|
"shields": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lucide-lustre",
|
"name": "lucide-lustre",
|
||||||
"description": "A library providing https://lucide.dev icons to lustre",
|
"description": "A library providing https://lucide.dev icons to lustre.",
|
||||||
"icon": "/framework-logos/lustre.webp",
|
"icon": "/framework-logos/lustre.webp",
|
||||||
"shields": [
|
"shields": [
|
||||||
{
|
{
|
||||||
|
|||||||
137
docs/.vitepress/lib/SvgPreview/GapViolationHighlight.tsx
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import pathToPoints from './path-to-points';
|
||||||
|
import { Path, PathProps } from './types';
|
||||||
|
|
||||||
|
export const GapViolationHighlight = ({
|
||||||
|
radius,
|
||||||
|
stroke,
|
||||||
|
strokeWidth,
|
||||||
|
strokeOpacity,
|
||||||
|
paths,
|
||||||
|
...props
|
||||||
|
}: {
|
||||||
|
paths: Path[];
|
||||||
|
} & PathProps<'stroke' | 'strokeOpacity' | 'strokeWidth', 'd'>) => {
|
||||||
|
const id = React.useId();
|
||||||
|
|
||||||
|
const groupedPaths = Object.entries(
|
||||||
|
paths.reduce(
|
||||||
|
(groups, val) => {
|
||||||
|
const key = val.c.id;
|
||||||
|
groups[key] = [...(groups[key] || []), val];
|
||||||
|
return groups;
|
||||||
|
},
|
||||||
|
{} as Record<number, Path[]>,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const groups: Group[] = [];
|
||||||
|
|
||||||
|
for (const [, paths] of groupedPaths) {
|
||||||
|
const d = paths.map((path) => path.d).join(' ');
|
||||||
|
const points = paths.flatMap((path) => pathToPoints(path));
|
||||||
|
groups.push({ id: d, points });
|
||||||
|
}
|
||||||
|
|
||||||
|
const mergedGroups = mergeGroups(groups, 2);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g {...props}>
|
||||||
|
<defs xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<pattern
|
||||||
|
id={`backdrop-pattern-${id}`}
|
||||||
|
width=".1"
|
||||||
|
height=".1"
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
patternTransform="rotate(45 50 50)"
|
||||||
|
>
|
||||||
|
<line
|
||||||
|
stroke={stroke}
|
||||||
|
strokeWidth={0.1}
|
||||||
|
y2={1}
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
stroke={stroke}
|
||||||
|
strokeWidth={0.1}
|
||||||
|
y2={1}
|
||||||
|
/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
{mergedGroups.flatMap((ds, idx, arr) =>
|
||||||
|
arr.slice(0, idx).map((val, i) => (
|
||||||
|
<g
|
||||||
|
strokeWidth={strokeWidth}
|
||||||
|
key={i}
|
||||||
|
>
|
||||||
|
<mask
|
||||||
|
id={`svg-preview-backdrop-mask-${id}-${i}`}
|
||||||
|
maskUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke="white"
|
||||||
|
d={val.join(' ')}
|
||||||
|
/>
|
||||||
|
</mask>
|
||||||
|
<path
|
||||||
|
d={ds.join(' ')}
|
||||||
|
stroke={`url(#backdrop-pattern-${id})`}
|
||||||
|
strokeWidth={strokeWidth}
|
||||||
|
strokeOpacity={strokeOpacity}
|
||||||
|
mask={`url(#svg-preview-backdrop-mask-${id}-${i})`}
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
)),
|
||||||
|
)}
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type Point = { x: number; y: number };
|
||||||
|
type Group = { id: string; points: Point[] };
|
||||||
|
|
||||||
|
// Euclidean distance
|
||||||
|
function distance(a: Point, b: Point): number {
|
||||||
|
return Math.hypot(a.x - b.x, a.y - b.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if two groups should be merged based on minimum distance
|
||||||
|
function shouldMerge(a: Group, b: Group, minDistance: number): boolean {
|
||||||
|
for (const pa of a.points) {
|
||||||
|
for (const pb of b.points) {
|
||||||
|
if (distance(pa, pb) <= minDistance) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge groups and return arrays of merged group IDs
|
||||||
|
function mergeGroups(groups: Group[], minDistance: number): string[][] {
|
||||||
|
const mergedGroups: Group[][] = groups.map((g) => [g]);
|
||||||
|
|
||||||
|
let changed = true;
|
||||||
|
while (changed) {
|
||||||
|
changed = false;
|
||||||
|
|
||||||
|
outer: for (let i = 0; i < mergedGroups.length; i++) {
|
||||||
|
for (let j = i + 1; j < mergedGroups.length; j++) {
|
||||||
|
// Check if any group in mergedGroups[i] should merge with any in mergedGroups[j]
|
||||||
|
if (
|
||||||
|
mergedGroups[i].some((ga) =>
|
||||||
|
mergedGroups[j].some((gb) => shouldMerge(ga, gb, minDistance)),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// Merge group j into group i
|
||||||
|
mergedGroups[i] = [...mergedGroups[i], ...mergedGroups[j]];
|
||||||
|
mergedGroups.splice(j, 1);
|
||||||
|
changed = true;
|
||||||
|
break outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return only arrays of IDs
|
||||||
|
return mergedGroups.map((groupList) => groupList.map((g) => g.id));
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PathProps, Path } from './types';
|
import { PathProps, Path } from './types';
|
||||||
import { getPaths, assert } from './utils';
|
import getPaths, { assert } from './utils';
|
||||||
|
import { GapViolationHighlight } from './GapViolationHighlight.tsx';
|
||||||
|
|
||||||
export const darkModeCss = `
|
export const darkModeCss = `
|
||||||
@media screen and (prefers-color-scheme: light) {
|
@media screen and (prefers-color-scheme: light) {
|
||||||
@@ -20,10 +21,16 @@ export const darkModeCss = `
|
|||||||
|
|
||||||
export const Grid = ({
|
export const Grid = ({
|
||||||
radius,
|
radius,
|
||||||
fill = '#fff',
|
fill,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
subGridSize = 0,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
strokeWidth: number;
|
strokeWidth: number;
|
||||||
|
subGridSize?: number;
|
||||||
radius: number;
|
radius: number;
|
||||||
} & PathProps<'stroke', 'strokeWidth'>) => (
|
} & PathProps<'stroke', 'strokeWidth'>) => (
|
||||||
<g
|
<g
|
||||||
@@ -33,43 +40,53 @@ export const Grid = ({
|
|||||||
>
|
>
|
||||||
<rect
|
<rect
|
||||||
className="svg-preview-grid-rect"
|
className="svg-preview-grid-rect"
|
||||||
width={24 - props.strokeWidth}
|
width={width - props.strokeWidth}
|
||||||
height={24 - props.strokeWidth}
|
height={height - props.strokeWidth}
|
||||||
x={props.strokeWidth / 2}
|
x={props.strokeWidth / 2}
|
||||||
y={props.strokeWidth / 2}
|
y={props.strokeWidth / 2}
|
||||||
rx={radius}
|
rx={radius}
|
||||||
fill={fill}
|
fill={fill}
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
strokeDasharray={'0 0.1 ' + '0.1 0.15 '.repeat(11) + '0 0.15'}
|
strokeDasharray={
|
||||||
|
'0 0.1 ' + '0.1 0.15 '.repeat(subGridSize ? subGridSize * 4 - 1 : 95) + '0 0.15'
|
||||||
|
}
|
||||||
strokeWidth={0.1}
|
strokeWidth={0.1}
|
||||||
d={
|
d={
|
||||||
props.d ||
|
props.d ||
|
||||||
new Array(Math.floor(24 - 1))
|
[
|
||||||
.fill(null)
|
...new Array(Math.floor(width - 1))
|
||||||
.map((_, i) => i)
|
.fill(null)
|
||||||
.filter((i) => i % 3 !== 2)
|
.map((_, i) => i)
|
||||||
.flatMap((i) => [
|
.filter((i) => !subGridSize || i % subGridSize !== subGridSize - 1)
|
||||||
`M${props.strokeWidth} ${i + 1}h${24 - props.strokeWidth * 2}`,
|
.flatMap((i) => [`M${i + 1} ${props.strokeWidth}v${height - props.strokeWidth * 2}`]),
|
||||||
`M${i + 1} ${props.strokeWidth}v${24 - props.strokeWidth * 2}`,
|
...new Array(Math.floor(height - 1))
|
||||||
])
|
.fill(null)
|
||||||
.join('')
|
.map((_, i) => i)
|
||||||
}
|
.filter((i) => !subGridSize || i % subGridSize !== subGridSize - 1)
|
||||||
/>
|
.flatMap((i) => [`M${props.strokeWidth} ${i + 1}h${width - props.strokeWidth * 2}`]),
|
||||||
<path
|
].join('')
|
||||||
d={
|
|
||||||
props.d ||
|
|
||||||
new Array(Math.floor(24 - 1))
|
|
||||||
.fill(null)
|
|
||||||
.map((_, i) => i)
|
|
||||||
.filter((i) => i % 3 === 2)
|
|
||||||
.flatMap((i) => [
|
|
||||||
`M${props.strokeWidth} ${i + 1}h${24 - props.strokeWidth * 2}`,
|
|
||||||
`M${i + 1} ${props.strokeWidth}v${24 - props.strokeWidth * 2}`,
|
|
||||||
])
|
|
||||||
.join('')
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{!!subGridSize && (
|
||||||
|
<path
|
||||||
|
d={
|
||||||
|
props.d ||
|
||||||
|
[
|
||||||
|
...new Array(Math.floor(width - 1))
|
||||||
|
.fill(null)
|
||||||
|
.map((_, i) => i)
|
||||||
|
.filter((i) => i % subGridSize === subGridSize - 1)
|
||||||
|
.flatMap((i) => [`M${i + 1} ${props.strokeWidth}v${height - props.strokeWidth * 2}`]),
|
||||||
|
...new Array(Math.floor(height - 1))
|
||||||
|
.fill(null)
|
||||||
|
.map((_, i) => i)
|
||||||
|
.filter((i) => i % subGridSize === subGridSize - 1)
|
||||||
|
.flatMap((i) => [`M${props.strokeWidth} ${i + 1}h${width - props.strokeWidth * 2}`]),
|
||||||
|
].join('')
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</g>
|
</g>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -99,6 +116,7 @@ const Shadow = ({
|
|||||||
>
|
>
|
||||||
{groupedPaths.map(([id, paths]) => (
|
{groupedPaths.map(([id, paths]) => (
|
||||||
<mask
|
<mask
|
||||||
|
key={`svg-preview-shadow-mask-${id}`}
|
||||||
id={`svg-preview-shadow-mask-${id}`}
|
id={`svg-preview-shadow-mask-${id}`}
|
||||||
maskUnits="userSpaceOnUse"
|
maskUnits="userSpaceOnUse"
|
||||||
strokeOpacity="1"
|
strokeOpacity="1"
|
||||||
@@ -108,8 +126,8 @@ const Shadow = ({
|
|||||||
<rect
|
<rect
|
||||||
x={0}
|
x={0}
|
||||||
y={0}
|
y={0}
|
||||||
width={24}
|
width="100%"
|
||||||
height={24}
|
height="100%"
|
||||||
fill="#fff"
|
fill="#fff"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
rx={radius}
|
rx={radius}
|
||||||
@@ -152,30 +170,34 @@ const ColoredPath = ({
|
|||||||
colors,
|
colors,
|
||||||
paths,
|
paths,
|
||||||
...props
|
...props
|
||||||
}: { paths: Path[]; colors: string[] } & PathProps<never, 'd' | 'stroke'>) => (
|
}: { paths: Path[]; colors: string[] } & PathProps<never, 'd' | 'stroke'>) => {
|
||||||
<g
|
let idx = 0;
|
||||||
className="svg-preview-colored-path-group"
|
return (
|
||||||
{...props}
|
<g
|
||||||
>
|
className="svg-preview-colored-path-group"
|
||||||
{paths.map(({ d, c }, i) => (
|
{...props}
|
||||||
<path
|
>
|
||||||
key={i}
|
{paths.map(({ d, c }, i) => (
|
||||||
d={d}
|
<path
|
||||||
stroke={colors[(c.name === 'path' ? i : c.id) % colors.length]}
|
key={i}
|
||||||
/>
|
d={d}
|
||||||
))}
|
stroke={colors[(c.name === 'path' ? idx++ : c.id) % colors.length]}
|
||||||
</g>
|
/>
|
||||||
);
|
))}
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const ControlPath = ({
|
const ControlPath = ({
|
||||||
paths,
|
paths,
|
||||||
radius,
|
radius,
|
||||||
pointSize,
|
pointSize,
|
||||||
...props
|
...props
|
||||||
}: { pointSize: number; paths: Path[]; radius: number } & PathProps<
|
}: {
|
||||||
'stroke' | 'strokeWidth',
|
pointSize: number;
|
||||||
'd'
|
paths: Path[];
|
||||||
>) => {
|
radius: number;
|
||||||
|
} & PathProps<'stroke' | 'strokeWidth', 'd'>) => {
|
||||||
const controlPaths = paths.map((path, i) => {
|
const controlPaths = paths.map((path, i) => {
|
||||||
const element = paths.filter((p) => p.c.id === path.c.id);
|
const element = paths.filter((p) => p.c.id === path.c.id);
|
||||||
const lastElement = element.at(-1)?.next;
|
const lastElement = element.at(-1)?.next;
|
||||||
@@ -207,8 +229,8 @@ const ControlPath = ({
|
|||||||
<rect
|
<rect
|
||||||
x="0"
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
width="24"
|
width="100%"
|
||||||
height="24"
|
height="100%"
|
||||||
fill="#fff"
|
fill="#fff"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
rx={radius}
|
rx={radius}
|
||||||
@@ -243,7 +265,7 @@ const ControlPath = ({
|
|||||||
)
|
)
|
||||||
.join('')}
|
.join('')}
|
||||||
/>
|
/>
|
||||||
{controlPaths.map(({ d, prev, next, startMarker, endMarker }, i) => (
|
{controlPaths.map(({ prev, next, startMarker, endMarker }, i) => (
|
||||||
<React.Fragment key={i}>
|
<React.Fragment key={i}>
|
||||||
{startMarker && (
|
{startMarker && (
|
||||||
<circle
|
<circle
|
||||||
@@ -279,11 +301,37 @@ const Radii = ({
|
|||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{paths.map(
|
{paths.map(
|
||||||
({ c, prev, next, circle }, i) =>
|
({ circle, next, prev, c }, i) =>
|
||||||
circle && (
|
circle && (
|
||||||
<React.Fragment key={i}>
|
<React.Fragment key={i}>
|
||||||
{c.name !== 'circle' && (
|
{circle.tangentIntersection && c.name === 'path' && (
|
||||||
<path d={`M${prev.x} ${prev.y} ${circle.x} ${circle.y} ${next.x} ${next.y}`} />
|
<>
|
||||||
|
<circle
|
||||||
|
cx={next.x * 2 - circle.tangentIntersection.x}
|
||||||
|
cy={next.y * 2 - circle.tangentIntersection.y}
|
||||||
|
r={0.25}
|
||||||
|
/>
|
||||||
|
<circle
|
||||||
|
cx={prev.x * 2 - circle.tangentIntersection.x}
|
||||||
|
cy={prev.y * 2 - circle.tangentIntersection.y}
|
||||||
|
r={0.25}
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d={`M${next.x * 2 - circle.tangentIntersection.x} ${
|
||||||
|
next.y * 2 - circle.tangentIntersection.y
|
||||||
|
}L${circle.tangentIntersection.x} ${circle.tangentIntersection.y}L${prev.x * 2 - circle.tangentIntersection.x} ${
|
||||||
|
prev.y * 2 - circle.tangentIntersection.y
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
<circle
|
||||||
|
cx={circle.tangentIntersection.x}
|
||||||
|
cy={circle.tangentIntersection.y}
|
||||||
|
r={0.25}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{c.name === 'path' && (
|
||||||
|
<path d={`M${next.x} ${next.y}L${circle.x} ${circle.y}L${prev.x} ${prev.y}`} />
|
||||||
)}
|
)}
|
||||||
<circle
|
<circle
|
||||||
cy={circle.y}
|
cy={circle.y}
|
||||||
@@ -313,55 +361,60 @@ const Radii = ({
|
|||||||
const Handles = ({
|
const Handles = ({
|
||||||
paths,
|
paths,
|
||||||
...props
|
...props
|
||||||
}: { paths: Path[] } & PathProps<
|
}: { paths: Path[] } & PathProps<'strokeWidth' | 'stroke' | 'strokeOpacity', any>) => (
|
||||||
'strokeWidth' | 'stroke' | 'strokeDasharray' | 'strokeOpacity',
|
<g
|
||||||
any
|
className="svg-preview-handles-group"
|
||||||
>) => {
|
{...props}
|
||||||
return (
|
>
|
||||||
<g
|
{paths.map(({ c, prev, next, cp1, cp2 }, i) => (
|
||||||
className="svg-preview-handles-group"
|
<React.Fragment key={i}>
|
||||||
{...props}
|
{cp1 && <path d={`M${prev.x} ${prev.y} ${cp1.x} ${cp1.y}`} />}
|
||||||
>
|
{cp1 && (
|
||||||
{paths.map(({ c, prev, next, cp1, cp2 }) => (
|
<circle
|
||||||
<>
|
cy={cp1.y}
|
||||||
{cp1 && <path d={`M${prev.x} ${prev.y} ${cp1.x} ${cp1.y}`} />}
|
cx={cp1.x}
|
||||||
{cp1 && (
|
r={0.25}
|
||||||
<circle
|
/>
|
||||||
cy={cp1.y}
|
)}
|
||||||
cx={cp1.x}
|
{cp2 && <path d={`M${next.x} ${next.y} ${cp2.x} ${cp2.y}`} />}
|
||||||
r={0.25}
|
{cp2 && (
|
||||||
/>
|
<circle
|
||||||
)}
|
cy={cp2.y}
|
||||||
{cp2 && <path d={`M${next.x} ${next.y} ${cp2.x} ${cp2.y}`} />}
|
cx={cp2.x}
|
||||||
{cp2 && (
|
r={0.25}
|
||||||
<circle
|
/>
|
||||||
cy={cp2.y}
|
)}
|
||||||
cx={cp2.x}
|
</React.Fragment>
|
||||||
r={0.25}
|
))}
|
||||||
/>
|
</g>
|
||||||
)}
|
);
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</g>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const SvgPreview = React.forwardRef<
|
const SvgPreview = React.forwardRef<
|
||||||
SVGSVGElement,
|
SVGSVGElement,
|
||||||
{
|
{
|
||||||
|
height?: number;
|
||||||
|
width?: number;
|
||||||
src: string | ReturnType<typeof getPaths>;
|
src: string | ReturnType<typeof getPaths>;
|
||||||
showGrid?: boolean;
|
showGrid?: boolean;
|
||||||
} & React.SVGProps<SVGSVGElement>
|
} & React.SVGProps<SVGSVGElement>
|
||||||
>(({ src, children, showGrid = false, ...props }, ref) => {
|
>(({ src, children, height = 24, width = 24, showGrid = false, ...props }, ref) => {
|
||||||
|
const subGridSize =
|
||||||
|
Math.max(height, width) % 3 === 0
|
||||||
|
? Math.max(height, width) > 24
|
||||||
|
? 12
|
||||||
|
: 3
|
||||||
|
: Math.max(height, width) % 5 === 0
|
||||||
|
? 5
|
||||||
|
: 0;
|
||||||
const paths = typeof src === 'string' ? getPaths(src) : src;
|
const paths = typeof src === 'string' ? getPaths(src) : src;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
ref={ref}
|
ref={ref}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width={24}
|
width={width}
|
||||||
height={24}
|
height={height}
|
||||||
viewBox="0 0 24 24"
|
viewBox={`0 0 ${width} ${height}`}
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
@@ -372,8 +425,12 @@ const SvgPreview = React.forwardRef<
|
|||||||
<style>{darkModeCss}</style>
|
<style>{darkModeCss}</style>
|
||||||
{showGrid && (
|
{showGrid && (
|
||||||
<Grid
|
<Grid
|
||||||
|
height={height}
|
||||||
|
width={width}
|
||||||
|
subGridSize={subGridSize}
|
||||||
strokeWidth={0.1}
|
strokeWidth={0.1}
|
||||||
stroke="#777"
|
stroke="#777"
|
||||||
|
mask="url(#svg-preview-bounding-box-mask)"
|
||||||
strokeOpacity={0.3}
|
strokeOpacity={0.3}
|
||||||
radius={1}
|
radius={1}
|
||||||
/>
|
/>
|
||||||
@@ -385,6 +442,12 @@ const SvgPreview = React.forwardRef<
|
|||||||
radius={1}
|
radius={1}
|
||||||
strokeOpacity={0.15}
|
strokeOpacity={0.15}
|
||||||
/>
|
/>
|
||||||
|
<GapViolationHighlight
|
||||||
|
paths={paths}
|
||||||
|
stroke="red"
|
||||||
|
strokeOpacity={0.75}
|
||||||
|
strokeWidth={4}
|
||||||
|
/>
|
||||||
<Handles
|
<Handles
|
||||||
paths={paths}
|
paths={paths}
|
||||||
strokeWidth={0.12}
|
strokeWidth={0.12}
|
||||||
@@ -433,4 +496,6 @@ const SvgPreview = React.forwardRef<
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
SvgPreview.displayName = 'SvgPreview';
|
||||||
|
|
||||||
export default SvgPreview;
|
export default SvgPreview;
|
||||||
|
|||||||
19
docs/.vitepress/lib/SvgPreview/path-to-points.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import memoize from 'lodash/memoize';
|
||||||
|
import SVGPathCommander from 'svg-path-commander';
|
||||||
|
import { Path } from './types';
|
||||||
|
|
||||||
|
function pathToPoints({ d, prev, next }: Path, interval = 1) {
|
||||||
|
const commander = new SVGPathCommander(d);
|
||||||
|
const points = [];
|
||||||
|
try {
|
||||||
|
const totalLength = commander.getTotalLength();
|
||||||
|
points.push(prev);
|
||||||
|
for (let i = interval; i < totalLength - interval; i += interval) {
|
||||||
|
points.push(commander.getPointAtLength(i));
|
||||||
|
}
|
||||||
|
points.push(next);
|
||||||
|
} catch (err) {}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memoize(pathToPoints);
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
import { INode, parseSync } from 'svgson';
|
import { INode, parseSync } from 'svgson';
|
||||||
|
// @ts-ignore
|
||||||
import toPath from 'element-to-path';
|
import toPath from 'element-to-path';
|
||||||
|
// @ts-ignore
|
||||||
import { SVGPathData, encodeSVGPath } from 'svg-pathdata';
|
import { SVGPathData, encodeSVGPath } from 'svg-pathdata';
|
||||||
import { Path, Point } from './types';
|
import { Path, Point } from './types';
|
||||||
|
import memoize from 'lodash/memoize';
|
||||||
|
|
||||||
function assertNever(x: never): never {
|
function assertNever(x: never): never {
|
||||||
throw new Error('Unknown type: ' + x['type']);
|
throw new Error('Unknown type: ' + x['type']);
|
||||||
@@ -44,17 +47,21 @@ const extractNodes = (node: INode): INode[] => {
|
|||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getNodes = (src: string) =>
|
export const getNodes = memoize((src: string) =>
|
||||||
extractNodes(parseSync(src.includes('<svg') ? src : `<svg>${src}</svg>`));
|
extractNodes(parseSync(src.includes('<svg') ? src : `<svg>${src}</svg>`)),
|
||||||
|
);
|
||||||
|
|
||||||
export const getCommands = (src: string) =>
|
export const getCommands = (src: string) =>
|
||||||
getNodes(src)
|
getNodes(src)
|
||||||
.map(convertToPathNode)
|
.map(convertToPathNode)
|
||||||
.flatMap(({ d, name }, idx) =>
|
.flatMap(({ d, name }, idx) =>
|
||||||
new SVGPathData(d).toAbs().commands.map((c, cIdx) => ({ ...c, id: idx, idx: cIdx, name })),
|
new SVGPathData(d)
|
||||||
|
.toAbs()
|
||||||
|
// @ts-ignore
|
||||||
|
.commands.map((c, cIdx) => ({ ...c, id: idx, idx: cIdx, name })),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getPaths = (src: string) => {
|
const getPaths = (src: string) => {
|
||||||
const commands = getCommands(src.includes('<svg') ? src : `<svg>${src}</svg>`);
|
const commands = getCommands(src.includes('<svg') ? src : `<svg>${src}</svg>`);
|
||||||
const paths: Path[] = [];
|
const paths: Path[] = [];
|
||||||
let prev: Point | undefined = undefined;
|
let prev: Point | undefined = undefined;
|
||||||
@@ -237,6 +244,7 @@ export const getPaths = (src: string) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
// @ts-ignore
|
||||||
assertNever(c);
|
assertNever(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,7 +252,7 @@ export const getPaths = (src: string) => {
|
|||||||
return paths;
|
return paths;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const arcEllipseCenter = (
|
const arcEllipseCenter = (
|
||||||
x1: number,
|
x1: number,
|
||||||
y1: number,
|
y1: number,
|
||||||
rx: number,
|
rx: number,
|
||||||
@@ -296,5 +304,52 @@ export const arcEllipseCenter = (
|
|||||||
M2[1][0] * Cp[0] + M2[1][1] * Cp[1] + V3[1],
|
M2[1][0] * Cp[0] + M2[1][1] * Cp[1] + V3[1],
|
||||||
];
|
];
|
||||||
|
|
||||||
return { x: C[0], y: C[1] };
|
return {
|
||||||
|
x: C[0],
|
||||||
|
y: C[1],
|
||||||
|
tangentIntersection: intersectTangents(
|
||||||
|
{ x: x1, y: y1 },
|
||||||
|
{ x: x2, y: y2 },
|
||||||
|
{ x: C[0], y: C[1] },
|
||||||
|
),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getTangentDirection(p: Point, center: Point): Point {
|
||||||
|
// Tangent is perpendicular to the radius vector (rotate radius 90°)
|
||||||
|
const dx = p.x - center.x;
|
||||||
|
const dy = p.y - center.y;
|
||||||
|
return { x: -dy, y: dx }; // 90° rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
function intersectTangents(start: Point, end: Point, center: Point): Point | null {
|
||||||
|
const t1 = getTangentDirection(start, center);
|
||||||
|
const t2 = getTangentDirection(end, center);
|
||||||
|
|
||||||
|
// Solve: start + λ * t1 = end + μ * t2
|
||||||
|
const A = [
|
||||||
|
[t1.x, -t2.x],
|
||||||
|
[t1.y, -t2.y],
|
||||||
|
];
|
||||||
|
const b = [end.x - start.x, end.y - start.y];
|
||||||
|
|
||||||
|
// Compute determinant
|
||||||
|
const det = A[0][0] * A[1][1] - A[0][1] * A[1][0];
|
||||||
|
|
||||||
|
if (Math.abs(det) < 1e-10) {
|
||||||
|
// Lines are parallel, no intersection
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const invDet = 1 / det;
|
||||||
|
|
||||||
|
const lambda = (b[0] * A[1][1] - b[1] * A[0][1]) * invDet;
|
||||||
|
|
||||||
|
// Intersection point = start + lambda * t1
|
||||||
|
return {
|
||||||
|
x: start.x + lambda * t1.x,
|
||||||
|
y: start.y + lambda * t1.y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default memoize(getPaths);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { bundledLanguages, type ThemeRegistration } from 'shikiji';
|
import { bundledLanguages, getHighlighter, type ThemeRegistration } from 'shikiji';
|
||||||
import { getHighlighter } from 'shikiji';
|
|
||||||
|
|
||||||
type CodeExampleType = {
|
type CodeExampleType = {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -102,13 +101,8 @@ import { LucideAngularModule, $PascalCase } from 'lucide-angular';
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
language: 'html',
|
language: 'html',
|
||||||
title: 'Icon Font',
|
title: 'Icon font',
|
||||||
code: `<style>
|
code: `<div class="icon-$Name"></div>`,
|
||||||
@import ('~lucide-static/font/Lucide.css');
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="icon-$Name"></div>
|
|
||||||
`,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -96,6 +96,10 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
|||||||
text: 'Lucide Preact',
|
text: 'Lucide Preact',
|
||||||
link: '/guide/packages/lucide-preact',
|
link: '/guide/packages/lucide-preact',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Lucide Astro',
|
||||||
|
link: '/guide/packages/lucide-astro',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: 'Lucide Static',
|
text: 'Lucide Static',
|
||||||
link: '/guide/packages/lucide-static',
|
link: '/guide/packages/lucide-static',
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const value = computed({
|
|||||||
<Input
|
<Input
|
||||||
ref="input"
|
ref="input"
|
||||||
type="search"
|
type="search"
|
||||||
|
autofocus
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
v-model="value"
|
v-model="value"
|
||||||
class="input-wrapper"
|
class="input-wrapper"
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
|
||||||
import { Switch } from '@headlessui/vue'
|
import { Switch } from '@headlessui/vue'
|
||||||
|
|
||||||
const enabled = ref(false)
|
defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Switch
|
<Switch
|
||||||
v-model="enabled"
|
:model-value="modelValue"
|
||||||
|
@update:model-value="emit('update:modelValue', $event)"
|
||||||
class="switch"
|
class="switch"
|
||||||
:class="{ enabled }"
|
:class="{ enabled: modelValue }"
|
||||||
>
|
>
|
||||||
<span class="thumb" />
|
<span class="thumb" />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ function resetStyle () {
|
|||||||
color.value = 'currentColor'
|
color.value = 'currentColor'
|
||||||
strokeWidth.value = 2
|
strokeWidth.value = 2
|
||||||
size.value = 24
|
size.value = 24
|
||||||
|
absoluteStrokeWidth.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(absoluteStrokeWidth, (enabled) => {
|
watch(absoluteStrokeWidth, (enabled) => {
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ export default {
|
|||||||
logo: '/framework-logos/angular.svg',
|
logo: '/framework-logos/angular.svg',
|
||||||
label: 'Lucide documentation for Angular',
|
label: 'Lucide documentation for Angular',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'lucide-astro',
|
||||||
|
logo: '/framework-logos/astro.svg',
|
||||||
|
logoDark: '/framework-logos/astro-dark.svg',
|
||||||
|
label: 'Lucide documentation for Astro',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'lucide-react-native',
|
name: 'lucide-react-native',
|
||||||
logo: '/framework-logos/react-native.svg',
|
logo: '/framework-logos/react-native.svg',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const { go } = useRouter()
|
|||||||
<HomeSectionTitle>Available For:</HomeSectionTitle>
|
<HomeSectionTitle>Available For:</HomeSectionTitle>
|
||||||
<div class="packages-list">
|
<div class="packages-list">
|
||||||
<a
|
<a
|
||||||
v-for="{ name, logo } in data.packages"
|
v-for="{ name, logo, logoDark } in data.packages"
|
||||||
:href="`/guide/packages/${name}`"
|
:href="`/guide/packages/${name}`"
|
||||||
class="package-logo"
|
class="package-logo"
|
||||||
:aria-label="`Read more about: ${name} package`"
|
:aria-label="`Read more about: ${name} package`"
|
||||||
@@ -21,10 +21,17 @@ const { go } = useRouter()
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="logo"
|
:src="logo"
|
||||||
height="36"
|
:class="{ light: logoDark, 'image-logo': true }"
|
||||||
width="36"
|
|
||||||
loading="lazy"
|
|
||||||
:alt="`${name} logo`"
|
:alt="`${name} logo`"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="logoDark"
|
||||||
|
:src="logoDark"
|
||||||
|
:alt="`${name} logo`"
|
||||||
|
class="image-logo dark"
|
||||||
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,6 +42,13 @@ const { go } = useRouter()
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
|
.image-logo {
|
||||||
|
object-fit: contain;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
.packages-list {
|
.packages-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -57,4 +71,11 @@ const { go } = useRouter()
|
|||||||
.package-logo:hover {
|
.package-logo:hover {
|
||||||
opacity: .6;
|
opacity: .6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.dark .image-logo.light {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
html:not(.dark) .image-logo.dark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import {useData, useRouter} from 'vitepress';
|
|||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
|
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
|
||||||
import { diamond } from '../../../data/iconNodes'
|
import { diamond } from '../../../data/iconNodes'
|
||||||
|
import deprecationReasonTemplate from '../../../../../tools/build-icons/utils/deprecationReasonTemplate.ts';
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
icon: IconEntity
|
icon: IconEntity
|
||||||
@@ -24,6 +26,15 @@ const tags = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const DiamondIcon = createLucideIcon('Diamond', diamond)
|
const DiamondIcon = createLucideIcon('Diamond', diamond)
|
||||||
|
|
||||||
|
const deprecatedTitle = computed(() => {
|
||||||
|
if (!props.icon.deprecationReason) return '';
|
||||||
|
return deprecationReasonTemplate(props.icon.deprecationReason, {
|
||||||
|
componentName: props.icon.name,
|
||||||
|
iconName: props.icon.name,
|
||||||
|
toBeRemovedInVersion: props.icon.toBeRemovedInVersion,
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -36,6 +47,13 @@ const DiamondIcon = createLucideIcon('Diamond', diamond)
|
|||||||
<DiamondIcon fill="currentColor" :size="12"/>
|
<DiamondIcon fill="currentColor" :size="12"/>
|
||||||
{{ icon.externalLibrary }}
|
{{ icon.externalLibrary }}
|
||||||
</div>
|
</div>
|
||||||
|
<Badge
|
||||||
|
v-if="icon.deprecated"
|
||||||
|
class="deprecated-badge"
|
||||||
|
:title="deprecatedTitle"
|
||||||
|
>
|
||||||
|
Deprecated
|
||||||
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
<div class="tags-scroller" v-if="tags.length">
|
<div class="tags-scroller" v-if="tags.length">
|
||||||
<p class="icon-tags horizontal-scroller">
|
<p class="icon-tags horizontal-scroller">
|
||||||
@@ -98,6 +116,16 @@ const DiamondIcon = createLucideIcon('Diamond', diamond)
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.deprecated-badge {
|
||||||
|
background-color: var(--vp-c-brand-5);
|
||||||
|
margin-left: 40px;
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deprecated-badge:hover {
|
||||||
|
background-color: var(--vp-c-brand-2);
|
||||||
|
}
|
||||||
|
|
||||||
.icon-tags {
|
.icon-tags {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--vp-c-text-2);
|
color: var(--vp-c-text-2);
|
||||||
|
|||||||
@@ -14,7 +14,15 @@ import CarbonAdOverlay from './CarbonAdOverlay.vue';
|
|||||||
|
|
||||||
const ICON_SIZE = 56;
|
const ICON_SIZE = 56;
|
||||||
const ICON_GRID_GAP = 8;
|
const ICON_GRID_GAP = 8;
|
||||||
const DEFAULT_GRID_ITEMS = 10 * 160;
|
|
||||||
|
const initialGridItems = computed(() => {
|
||||||
|
if (containerWidth.value === 0) return 120;
|
||||||
|
|
||||||
|
const itemsPerRow = columnSize.value || 10;
|
||||||
|
const visibleRows = Math.ceil(window.innerHeight / (ICON_SIZE + ICON_GRID_GAP));
|
||||||
|
|
||||||
|
return Math.min(itemsPerRow * (visibleRows + 2), 200);
|
||||||
|
});
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
icons: IconEntity[];
|
icons: IconEntity[];
|
||||||
@@ -115,15 +123,14 @@ function handleCloseDrawer() {
|
|||||||
/>
|
/>
|
||||||
</StickyBar>
|
</StickyBar>
|
||||||
<NoResults
|
<NoResults
|
||||||
v-if="list.length === 0 && searchQuery !== ''"
|
v-if="searchResults.length === 0 && searchQuery !== ''"
|
||||||
:searchQuery="searchQuery"
|
:searchQuery="searchQuery"
|
||||||
@clear="searchQuery = ''"
|
@clear="searchQuery = ''"
|
||||||
/>
|
/>
|
||||||
<IconGrid
|
<IconGrid
|
||||||
v-else-if="list.length === 0"
|
v-else-if="list.length === 0"
|
||||||
:key="index"
|
|
||||||
overlayMode
|
overlayMode
|
||||||
:icons="[...searchResults].splice(0, DEFAULT_GRID_ITEMS)"
|
:icons="searchResults.slice(0, initialGridItems)"
|
||||||
:activeIcon="activeIconName"
|
:activeIcon="activeIconName"
|
||||||
@setActiveIcon="setActiveIconName"
|
@setActiveIcon="setActiveIconName"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ function resetStyle () {
|
|||||||
color.value = STYLE_DEFAULTS.color
|
color.value = STYLE_DEFAULTS.color
|
||||||
strokeWidth.value = STYLE_DEFAULTS.strokeWidth
|
strokeWidth.value = STYLE_DEFAULTS.strokeWidth
|
||||||
size.value = STYLE_DEFAULTS.size
|
size.value = STYLE_DEFAULTS.size
|
||||||
|
absoluteStrokeWidth.value = STYLE_DEFAULTS.absoluteStrokeWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(absoluteStrokeWidth, (enabled) => {
|
watch(absoluteStrokeWidth, (enabled) => {
|
||||||
@@ -59,9 +60,8 @@ const customizingActive = computed(() => {
|
|||||||
return color.value !== STYLE_DEFAULTS.color
|
return color.value !== STYLE_DEFAULTS.color
|
||||||
|| strokeWidth.value !== STYLE_DEFAULTS.strokeWidth
|
|| strokeWidth.value !== STYLE_DEFAULTS.strokeWidth
|
||||||
|| size.value !== STYLE_DEFAULTS.size
|
|| size.value !== STYLE_DEFAULTS.size
|
||||||
|
|| absoluteStrokeWidth.value !== STYLE_DEFAULTS.absoluteStrokeWidth
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -120,8 +120,8 @@ const customizingActive = computed(() => {
|
|||||||
label="Absolute Stroke width"
|
label="Absolute Stroke width"
|
||||||
>
|
>
|
||||||
<Switch
|
<Switch
|
||||||
id="size"
|
id="absolute-stroke-width"
|
||||||
name="size"
|
name="absolute-stroke-width"
|
||||||
v-model="absoluteStrokeWidth"
|
v-model="absoluteStrokeWidth"
|
||||||
/>
|
/>
|
||||||
</InputField>
|
</InputField>
|
||||||
@@ -161,9 +161,4 @@ const customizingActive = computed(() => {
|
|||||||
.color-picker {
|
.color-picker {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#absolute-stroke-width {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,21 +1,27 @@
|
|||||||
import packageData from '../../../data/packageData.json';
|
import packageDataList from '../../../data/packageData.json';
|
||||||
import thirdPartyPackages from '../../../data/packageData.thirdParty.json';
|
import thirdPartyPackages from '../../../data/packageData.thirdParty.json';
|
||||||
import fetchPackages from '../../../lib/fetchPackages';
|
import fetchPackages from '../../../lib/fetchPackages';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async load() {
|
async load() {
|
||||||
const packages = await fetchPackages();
|
const packageJsonList = await fetchPackages();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
packages: packages
|
packages: packageJsonList
|
||||||
.filter((p) => p?.name != null && p.name in packageData)
|
.filter((pJson) => pJson?.name != null && pJson.name in packageDataList)
|
||||||
.map((pData) => ({
|
.map((pJson) => {
|
||||||
...pData,
|
const packageData = packageDataList[pJson.name];
|
||||||
...packageData[pData.name],
|
return {
|
||||||
documentation: `/guide/packages/${pData.name}`,
|
...pJson,
|
||||||
source: `https://github.com/lucide-icons/lucide/tree/main/packages/${pData.name}`,
|
...packageData,
|
||||||
icon: `/framework-logos/${packageData[pData.name].icon}.svg`,
|
documentation: `/guide/packages/${packageData.docsAlias ?? pJson.name}`,
|
||||||
}))
|
source: `https://github.com/lucide-icons/lucide/tree/main/packages/${packageData.packageDirname ?? pJson.name}`,
|
||||||
|
icon: `/framework-logos/${packageData.icon}.svg`,
|
||||||
|
iconDark: Boolean(packageData.iconDark)
|
||||||
|
? `/framework-logos/${packageData.iconDark}.svg`
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
})
|
||||||
.sort((a, b) => a.order - b.order),
|
.sort((a, b) => a.order - b.order),
|
||||||
thirdPartyPackages,
|
thirdPartyPackages,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
--vp-code-editor-string: #032f62;
|
--vp-code-editor-string: #032f62;
|
||||||
|
|
||||||
--vp-c-text-4: rgba(60, 60, 67, 0.32);
|
--vp-c-text-4: rgba(60, 60, 67, 0.32);
|
||||||
|
--vp-home-hero-name-color: var(--vp-c-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
@@ -60,36 +61,15 @@
|
|||||||
.VPHomeHero .image-container {
|
.VPHomeHero .image-container {
|
||||||
transform: none;
|
transform: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/* padding: 0 24px; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .VPHomeHero .container {
|
.VPHomeHero .name::first-line {
|
||||||
flex-direction: column-reverse;
|
|
||||||
} */
|
|
||||||
.VPHomeHero .container .main {
|
|
||||||
/* flex:1; */
|
|
||||||
flex-shirk: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VPHomeHero .container .main h1.name {
|
|
||||||
color: var(--vp-c-text);
|
|
||||||
}
|
|
||||||
.VPHomeHero .container .main h1.name .clip {
|
|
||||||
color: inherit;
|
|
||||||
-webkit-text-fill-color: unset;
|
|
||||||
color: var(--vp-c-text);
|
|
||||||
font-size: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VPHomeHero .container .main h1::first-line {
|
|
||||||
color: var(--vp-c-brand);
|
color: var(--vp-c-brand);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
|
||||||
.VPHomeHero .container .image {
|
.VPHomeHero .container .image {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
order: 2;
|
order: 2;
|
||||||
/* flex: 1; */
|
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,10 +78,6 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPHomeHero .container .image-bg {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.VPFeature .icon {
|
.VPFeature .icon {
|
||||||
background-color: var(--vp-c-bg);
|
background-color: var(--vp-c-bg);
|
||||||
}
|
}
|
||||||
@@ -115,12 +91,6 @@
|
|||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
|
||||||
.VPHomeHero .container .main h1.name .clip {
|
|
||||||
font-size: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 960px) {
|
@media (min-width: 960px) {
|
||||||
.VPHomeHero .container .image {
|
.VPHomeHero .container .image {
|
||||||
order: 1;
|
order: 1;
|
||||||
@@ -140,18 +110,11 @@
|
|||||||
.VPHomeHero .container .image-container {
|
.VPHomeHero .container .image-container {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPHomeHero .container .main h1.name {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBarHamburger .container > span {
|
.VPNavBarHamburger .container > span {
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
html:has(* .outline-link:target) {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
} */
|
|
||||||
|
|
||||||
.sp-wrapper + * {
|
.sp-wrapper + * {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
@@ -183,7 +146,6 @@ html:has(* .outline-link:target) {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
position: relative;
|
position: relative;
|
||||||
/* box-sizing: content-box; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sp-wrapper .sp-tabs .sp-tab-button:after {
|
.sp-wrapper .sp-tabs .sp-tab-button:after {
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ export interface IconMetaData {
|
|||||||
categories: string[];
|
categories: string[];
|
||||||
contributors: string[];
|
contributors: string[];
|
||||||
aliases?: string[];
|
aliases?: string[];
|
||||||
|
deprecated?: boolean;
|
||||||
|
deprecationReason?: string;
|
||||||
|
toBeRemovedInVersion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExternalLibs = 'lab';
|
export type ExternalLibs = 'lab';
|
||||||
@@ -33,12 +36,19 @@ interface Shield {
|
|||||||
|
|
||||||
export interface PackageItem {
|
export interface PackageItem {
|
||||||
name: string;
|
name: string;
|
||||||
|
// set when the package's directory
|
||||||
|
// name under the `packages/` directory
|
||||||
|
// is diffrent from the package name
|
||||||
|
packageDirname?: string;
|
||||||
description: string;
|
description: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
iconDark: string;
|
iconDark: string;
|
||||||
shields: Shield[];
|
shields: Shield[];
|
||||||
source: string;
|
source: string;
|
||||||
documentation: string;
|
documentation: string;
|
||||||
|
// set when the docs page name is
|
||||||
|
// diffrent from the package name
|
||||||
|
docsAlias?: string;
|
||||||
order?: number;
|
order?: number;
|
||||||
private?: boolean;
|
private?: boolean;
|
||||||
flutter?: object;
|
flutter?: object;
|
||||||
|
|||||||
@@ -139,22 +139,22 @@ contained icon.
|
|||||||
```tsx
|
```tsx
|
||||||
// Don't do this
|
// Don't do this
|
||||||
<button class="btn-icon">
|
<button class="btn-icon">
|
||||||
<Home/>
|
<House/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
// Don't do this either
|
// Don't do this either
|
||||||
<button class="btn-icon">
|
<button class="btn-icon">
|
||||||
<Home aria-label="Home icon"/>
|
<House aria-label="Home icon"/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
// This works but might not be the best solution, see below
|
// This works but might not be the best solution, see below
|
||||||
<button aria-label="Go to home" class="btn-icon">
|
<button aria-label="Go to home" class="btn-icon">
|
||||||
<Home/>
|
<House/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
// Do this instead
|
// Do this instead
|
||||||
<button class="btn-icon">
|
<button class="btn-icon">
|
||||||
<Home/>
|
<House/>
|
||||||
<span class="visually-hidden">Go to home</span>
|
<span class="visually-hidden">Go to home</span>
|
||||||
</button>
|
</button>
|
||||||
```
|
```
|
||||||
@@ -167,6 +167,7 @@ Although you could provide accessible labels to your elements via the `aria-labe
|
|||||||
generally recommend avoiding this and instead suggest that you use your chosen CSS framework's "
|
generally recommend avoiding this and instead suggest that you use your chosen CSS framework's "
|
||||||
visually hidden" utility whenever possible. You can
|
visually hidden" utility whenever possible. You can
|
||||||
[read more about why `aria-label` might not be the best solution](https://gomakethings.com/revisting-aria-label-versus-a-visually-hidden-class/).
|
[read more about why `aria-label` might not be the best solution](https://gomakethings.com/revisting-aria-label-versus-a-visually-hidden-class/).
|
||||||
|
|
||||||
### Example - Radix UI
|
### Example - Radix UI
|
||||||
|
|
||||||
Use [Radix UI's built-in accessible icon utility component](https://www.radix-ui.com/primitives/docs/utilities/accessible-icon).
|
Use [Radix UI's built-in accessible icon utility component](https://www.radix-ui.com/primitives/docs/utilities/accessible-icon).
|
||||||
@@ -179,6 +180,7 @@ import { AccessibleIcon } from '@radix-ui/react-accessible-icon';
|
|||||||
<ArrowRightIcon />
|
<ArrowRightIcon />
|
||||||
</AccessibleIcon>
|
</AccessibleIcon>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Example - Bootstrap
|
### Example - Bootstrap
|
||||||
|
|
||||||
```html
|
```html
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ Beside aliases names lucide also includes prefixed and suffixed names to use wit
|
|||||||
```tsx
|
```tsx
|
||||||
// These are all the same icon
|
// These are all the same icon
|
||||||
import {
|
import {
|
||||||
Home,
|
House,
|
||||||
HomeIcon,
|
HouseIcon,
|
||||||
LucideHome,
|
LucideHouse,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,11 @@ Here are rules that should be followed to keep quality and consistency when maki
|
|||||||
|
|
||||||
### 8. Distinct elements must have **2 pixels of spacing between each other**
|
### 8. Distinct elements must have **2 pixels of spacing between each other**
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### 9. Icons should have a similar optical volume to `circle` and `square`.
|
### 9. Icons should have a similar optical volume to `circle` and `square`.
|
||||||
|
|
||||||
@@ -142,7 +146,7 @@ For each icon these attributes are applied, corresponding to the above rules.
|
|||||||
### Minify paths
|
### Minify paths
|
||||||
|
|
||||||
The code of paths can sometimes get quite large. To reduce file size we like to minify the code.
|
The code of paths can sometimes get quite large. To reduce file size we like to minify the code.
|
||||||
We recommend to use [SVGOMG](https://jakearchibald.github.io/svgomg/) to minify paths to 2 points of precision.
|
We recommend to use [Lucide Studio](https://studio.lucide.dev/) to tidy paths to 3 points of precision.
|
||||||
|
|
||||||
### Allowed elements
|
### Allowed elements
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ However, not everyone can understand them easily. Read more about [how to use Lu
|
|||||||
|
|
||||||
## Official Packages
|
## Official Packages
|
||||||
|
|
||||||
Lucide's official packages are designed to work on different platforms, making it easier for users to integrate icons into their projects. The packages are available for various technologies, including [Web (Vanilla)](https://lucide.dev/guide/packages/lucide), [React](https://lucide.dev/guide/packages/lucide-react), [React Native](https://lucide.dev/guide/packages/lucide-react-native), [Vue](https://lucide.dev/guide/packages/lucide-vue), [Vue 3](https://lucide.dev/guide/packages/lucide-vue-next), [Svelte](https://lucide.dev/guide/packages/lucide-svelte), [Preact](https://lucide.dev/guide/packages/lucide-preact), [Solid](https://lucide.dev/guide/packages/lucide-solid), [Angular](https://lucide.dev/guide/packages/lucide-angular), [NodeJS](https://lucide.dev/guide/packages/lucide-static#nodejs) and [Flutter](https://lucide.dev/guide/packages/lucide-flutter).
|
Lucide's official packages are designed to work on different platforms, making it easier for users to integrate icons into their projects. The packages are available for various technologies, including [Web (Vanilla)](https://lucide.dev/guide/packages/lucide), [React](https://lucide.dev/guide/packages/lucide-react), [React Native](https://lucide.dev/guide/packages/lucide-react-native), [Vue](https://lucide.dev/guide/packages/lucide-vue), [Vue 3](https://lucide.dev/guide/packages/lucide-vue-next), [Svelte](https://lucide.dev/guide/packages/lucide-svelte), [Preact](https://lucide.dev/guide/packages/lucide-preact), [Solid](https://lucide.dev/guide/packages/lucide-solid), [Angular](https://lucide.dev/guide/packages/lucide-angular), [Astro](https://lucide.dev/guide/packages/lucide-astro), and [NodeJS](https://lucide.dev/guide/packages/lucide-static#nodejs).
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
If you have any questions about Lucide, feel free to reach out to the community. You can find them on [GitHub](https://github.com/lucide-icons/lucide) and [Discord](https://discord.gg/EH6nSts).
|
If you have any questions about Lucide, feel free to reach out to the community. You can find them on [GitHub](https://github.com/lucide-icons/lucide) and [Discord](https://discord.gg/EH6nSts).
|
||||||
|
|||||||
@@ -184,8 +184,37 @@ npm install lucide-preact
|
|||||||
bun add lucide-preact
|
bun add lucide-preact
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
For more details, see the [documentation](packages/lucide-preact.md).
|
||||||
|
|
||||||
|
## Astro
|
||||||
|
|
||||||
|
Implementation of the lucide icon library for Astro applications.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```sh [pnpm]
|
||||||
|
pnpm install @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh [yarn]
|
||||||
|
yarn add @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh [npm]
|
||||||
|
npm install @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh [bun]
|
||||||
|
bun add @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
For more details, see the [documentation](packages/lucide-astro.md).
|
||||||
|
|
||||||
## Static usage
|
## Static usage
|
||||||
|
|
||||||
Implementation of the lucide icon library for multiple usages that like to use: SVG files icons, SVG Sprite, Icon Fonts and static SVG strings export in Common JS modules (for NodeJS).
|
Implementation of the lucide icon library for multiple usages that like to use: SVG files icons, SVG Sprite, Icon Fonts and static SVG strings export in Common JS modules (for NodeJS).
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ bun add lucide-angular
|
|||||||
In any Angular module you wish to use Lucide icons in, you have to import `LucideAngularModule`, and pick any icons you wish to use:
|
In any Angular module you wish to use Lucide icons in, you have to import `LucideAngularModule`, and pick any icons you wish to use:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { LucideAngularModule, File, Home, Menu, UserCheck } from 'lucide-angular';
|
import { LucideAngularModule, File, House, Menu, UserCheck } from 'lucide-angular';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
LucideAngularModule.pick({File, Home, Menu, UserCheck})
|
LucideAngularModule.pick({File, House, Menu, UserCheck})
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
@@ -64,7 +64,7 @@ Within your templates you may now use one of the following component tags to ins
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<lucide-angular name="file" class="my-icon"></lucide-angular>
|
<lucide-angular name="file" class="my-icon"></lucide-angular>
|
||||||
<lucide-icon name="home" class="my-icon"></lucide-icon>
|
<lucide-icon name="house" class="my-icon"></lucide-icon>
|
||||||
<i-lucide name="menu" class="my-icon"></i-lucide>
|
<i-lucide name="menu" class="my-icon"></i-lucide>
|
||||||
<span-lucide name="user-check" class="my-icon"></span-lucide>
|
<span-lucide name="user-check" class="my-icon"></span-lucide>
|
||||||
```
|
```
|
||||||
@@ -88,7 +88,7 @@ You can pass additional props to adjust the icon appearance.
|
|||||||
| `absoluteStrokeWidth` | *boolean* | false |
|
| `absoluteStrokeWidth` | *boolean* | false |
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<i-lucide name="home" [size]="48" color="red" [strokeWidth]="1"></i-lucide>
|
<i-lucide name="house" [size]="48" color="red" [strokeWidth]="1"></i-lucide>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Global configuration
|
### Global configuration
|
||||||
@@ -151,11 +151,11 @@ They can be used in the same way as the official icons.
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
import { LucideAngularModule } from 'lucide-angular';
|
import { LucideAngularModule } from 'lucide-angular';
|
||||||
import { burger } from '@lucide/lab';
|
import { coconut } from '@lucide/lab';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
LucideAngularModule.pick({ burger })
|
LucideAngularModule.pick({ coconut })
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
|||||||
187
docs/guide/packages/lucide-astro.md
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
# Lucide Astro
|
||||||
|
|
||||||
|
Implementation of the lucide icon library for Astro applications.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```sh [pnpm]
|
||||||
|
pnpm add @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh [yarn]
|
||||||
|
yarn add @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh [npm]
|
||||||
|
npm install @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh [bun]
|
||||||
|
bun add @lucide/astro
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||||
|
|
||||||
|
Each icon can be imported as an Astro component, which renders an inline SVG element. This way, only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
Default usage:
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { Skull } from '@lucide/astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Skull />
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional props can be passed to adjust the icon:
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { Camera } from '@lucide/astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Camera color="#ff3e98" />
|
||||||
|
```
|
||||||
|
|
||||||
|
For faster builds and load times, you can import icons directly from the `@lucide/astro/icons` directory:
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import CircleAlert from '@lucide/astro/icons/circle-alert';
|
||||||
|
---
|
||||||
|
|
||||||
|
<CircleAlert color="#ff3e98" />
|
||||||
|
```
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
| name | type | default |
|
||||||
|
| --------------------- | --------- | ------------ |
|
||||||
|
| `size` | _number_ | 24 |
|
||||||
|
| `color` | _string_ | currentColor |
|
||||||
|
| `stroke-width` | _number_ | 2 |
|
||||||
|
| `absoluteStrokeWidth` | _boolean_ | false |
|
||||||
|
|
||||||
|
### Applying props
|
||||||
|
|
||||||
|
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { Phone } from '@lucide/astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Phone fill="#333" />
|
||||||
|
```
|
||||||
|
|
||||||
|
This results a filled phone icon.
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
The package includes type definitions for all icons. This is useful if you want to dynamically render icons.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { House, Library, Cog, type Icon as IconType } from '@lucide/astro';
|
||||||
|
|
||||||
|
type MenuItem = {
|
||||||
|
name: string;
|
||||||
|
href: string;
|
||||||
|
icon: typeof IconType;
|
||||||
|
};
|
||||||
|
|
||||||
|
const menuItems: MenuItem[] = [
|
||||||
|
{
|
||||||
|
name: 'Home',
|
||||||
|
href: '/',
|
||||||
|
icon: House,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Blog',
|
||||||
|
href: '/blog',
|
||||||
|
icon: Library,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Projects',
|
||||||
|
href: '/projects',
|
||||||
|
icon: Cog,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
menuItems.map((item) => (
|
||||||
|
<a href={item.href}>
|
||||||
|
<item.icon />
|
||||||
|
<span>{item.name}</span>
|
||||||
|
</a>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## With Lucide lab or custom icons
|
||||||
|
|
||||||
|
[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
|
||||||
|
|
||||||
|
They can be used by using the `Icon` component.
|
||||||
|
All props of the regular Lucide icons can be passed to adjust the icon appearance.
|
||||||
|
|
||||||
|
### Using the `Icon` component
|
||||||
|
|
||||||
|
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { Icon } from '@lucide/astro';
|
||||||
|
import { burger, sausage } from '@lucide/lab';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Icon iconNode={burger} />
|
||||||
|
<Icon iconNode={sausage} color="red"/>
|
||||||
|
```
|
||||||
|
|
||||||
|
## One generic icon component
|
||||||
|
|
||||||
|
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||||
|
|
||||||
|
::: danger
|
||||||
|
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application. This may be passable if you're doing SSG and SSR in server environments. However if you're doing SSR in serverless environments, it could negatively affect your app's performance, as a bigger bundle size will translate to an increase in cold starts.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Icon Component Example
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import { icons, type IconProps } from '@lucide/astro';
|
||||||
|
|
||||||
|
interface Props extends IconProps {
|
||||||
|
name: keyof typeof icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { name, ...restProps } = Astro.props;
|
||||||
|
const Icon = icons[name];
|
||||||
|
---
|
||||||
|
|
||||||
|
<Icon {...restProps} />
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the Icon Component
|
||||||
|
|
||||||
|
```astro
|
||||||
|
---
|
||||||
|
import LucideIcon from './LucideIcon.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<LucideIcon name="Menu" />
|
||||||
|
```
|
||||||
@@ -84,10 +84,10 @@ This creates a single icon based on the iconNode passed and renders a Lucide ico
|
|||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Icon } from 'lucide-preact';
|
import { Icon } from 'lucide-preact';
|
||||||
import { burger } from '@lucide/lab';
|
import { coconut } from '@lucide/lab';
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (
|
||||||
<Icon iconNode={burger} />
|
<Icon iconNode={coconut} />
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ export default Icon;
|
|||||||
import Icon from './Icon';
|
import Icon from './Icon';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return <Icon name="home" />;
|
return <Icon name="house" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
@@ -78,10 +78,10 @@ This creates a single icon based on the iconNode passed and renders a Lucide ico
|
|||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Icon } from 'lucide-react-native';
|
import { Icon } from 'lucide-react-native';
|
||||||
import { burger } from '@lucide/lab';
|
import { coconut } from '@lucide/lab';
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (
|
||||||
<Icon iconNode={burger} />
|
<Icon iconNode={coconut} />
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ export default Icon;
|
|||||||
import Icon from './Icon';
|
import Icon from './Icon';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return <Icon name="home" />;
|
return <Icon name="house" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
@@ -78,17 +78,16 @@ This creates a single icon based on the iconNode passed and renders a Lucide ico
|
|||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Icon } from 'lucide-react';
|
import { Icon } from 'lucide-react';
|
||||||
import { burger } from '@lucide/lab';
|
import { coconut } from '@lucide/lab';
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (
|
||||||
<Icon iconNode={burger} />
|
<Icon iconNode={coconut} />
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Dynamic Icon Component
|
## Dynamic Icon Component
|
||||||
|
|
||||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
It is possible to create one generic icon component to load icons. But it is not recommended, since it is importing all icons during the build. This increases build time and the different modules it will create.
|
||||||
Since it is importing all icons during build. This increases build time and the different modules it will create.
|
|
||||||
|
|
||||||
`DynamicIcon` is useful for applications that want to show icons dynamically by icon name. For example, when using a content management system with where icon names are stored in a database.
|
`DynamicIcon` is useful for applications that want to show icons dynamically by icon name. For example, when using a content management system with where icon names are stored in a database.
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ This creates a single icon based on the iconNode passed and renders a Lucide ico
|
|||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { Icon } from 'lucide-solid';
|
import { Icon } from 'lucide-solid';
|
||||||
import { burger, sausage } from '@lucide/lab';
|
import { sausage } from '@lucide/lab';
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (
|
||||||
<Icon iconNode={sausage} color="red"/>
|
<Icon iconNode={sausage} color="red"/>
|
||||||
|
|||||||
@@ -1,24 +1,38 @@
|
|||||||
# Lucide Static
|
# Lucide Static
|
||||||
|
|
||||||
This package include the following lucide implementations:
|
This package includes the following implementations of Lucide icons:
|
||||||
|
|
||||||
- All SVG files
|
- Individual SVG files
|
||||||
- SVG sprite
|
- SVG sprite
|
||||||
- Icon fonts
|
- Icon font files
|
||||||
- JavaScript library containing strings of SVGs.
|
- A JavaScript library exporting SVG strings
|
||||||
|
|
||||||
## Why lucide-static?
|
## Who is this for?
|
||||||
|
|
||||||
This package is suitable for specific use cases, for example if you want to use icon fonts, SVG sprites, normal SVGs or Common.js SVG strings in your javascript project.
|
`lucide-static` is suitable for _very specific use cases_ where you want to use Lucide icons without relying on a JavaScript framework or component system. It's ideal for:
|
||||||
|
|
||||||
::: warning
|
- Projects that use icon fonts with plain CSS or utility-first frameworks
|
||||||
While they can be useful for prototyping, it is not recommended to use the SVG sprites or icon fonts provided by this package in production web apps as all the available icons are included in the app, hence increasing loading time and data usage. We recommend to use a bundler and tree-shaking to make sure only the icons you use are bundled with your app. Tree-shaking is only available in these packages: [lucide](lucide), [lucide-react](lucide-react), [lucide-vue](lucide-vue), [lucide-vue-next](lucide-vue-next), [lucide-angular](lucide-angular), [lucide-preact](lucide-preact)
|
- Embedding raw SVG files or sprites directly in HTML
|
||||||
|
- Using SVGs as CSS background images
|
||||||
|
- Importing SVG strings into Node.js (CommonJS) environments
|
||||||
|
|
||||||
|
::: danger
|
||||||
|
### Not recommended for production {#production-warning}
|
||||||
|
|
||||||
|
SVG sprites and icon fonts include **all icons**, which can significantly increase your app's bundle size and load time.
|
||||||
|
|
||||||
|
For production environments, we recommend using a bundler with tree-shaking support to include only the icons you actually use. Consider using:
|
||||||
|
|
||||||
|
- [lucide](lucide)
|
||||||
|
- [lucide-react](lucide-react)
|
||||||
|
- [lucide-vue](lucide-vue)
|
||||||
|
- [lucide-vue-next](lucide-vue-next)
|
||||||
|
- [lucide-angular](lucide-angular)
|
||||||
|
- [lucide-preact](lucide-preact)
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
## Package Managers
|
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
|
|
||||||
```sh [pnpm]
|
```sh [pnpm]
|
||||||
@@ -39,64 +53,77 @@ bun add lucide-static
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### CDN
|
## SVG Files
|
||||||
|
|
||||||
```html
|
You can use standalone SVG files or SVG sprites in several ways.
|
||||||
<!-- SVG file for a single icon -->
|
|
||||||
<img src="https://unpkg.com/lucide-static@latest/icons/house.svg" />
|
|
||||||
|
|
||||||
<!-- Icon font -->
|
Check out our [codesandbox example](https://codesandbox.io/s/using-the-svg-sprite-lz1kk).
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family: 'LucideIcons';
|
|
||||||
src: url(https://unpkg.com/lucide-static@latest/font/Lucide.ttf) format('truetype');
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
### SVG file as image
|
||||||
|
|
||||||
Check out the [codesandbox examples](https://codesandbox.io/s/using-the-svg-sprite-lz1kk).
|
#### In HTML:
|
||||||
|
|
||||||
### SVG Files
|
::: code-group
|
||||||
|
|
||||||
#### SVG file as image
|
```html [Webpack]
|
||||||
|
|
||||||
To use it in for example html:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<!-- SVG file for a single icon -->
|
<!-- SVG file for a single icon -->
|
||||||
<img src="~lucide-static/icons/house.svg" />
|
<img src="~lucide-static/icons/house.svg" />
|
||||||
```
|
```
|
||||||
|
|
||||||
```css
|
```html [CDN]
|
||||||
|
<!-- SVG file for a single icon -->
|
||||||
|
<img src="https://unpkg.com/lucide-static@latest/icons/house.svg" />
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
#### In CSS:
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```css [Webpack]
|
||||||
.house-icon {
|
.house-icon {
|
||||||
background-image: url(~lucide-static/icons/house.svg);
|
background-image: url(~lucide-static/icons/house.svg);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Make sure you have the correct webpack loaders to make this work. [url-loader](https://v4.webpack.js.org/loaders/url-loader/)
|
```css [CDN]
|
||||||
|
.house-icon {
|
||||||
|
background-image: url(https://unpkg.com/lucide-static@latest/icons/house.svg);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### SVG file as string
|
:::
|
||||||
|
|
||||||
You can simply import each SVG by targeting `lucide-static/icons/{icon-name}.svg`.
|
Make sure you have the correct Webpack loader configured, such as [`url-loader`](https://v4.webpack.js.org/loaders/url-loader/).
|
||||||
To use SVGs in your project you can for example use a [SVG loader](https://v4.webpack.js.org/loaders/svg-inline-loader/).
|
|
||||||
|
### SVG file as string
|
||||||
|
|
||||||
|
To import an SVG as a string (e.g., for templating):
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import arrowRightIcon from 'lucide-static/icons/arrow-right';
|
import arrowRightIcon from 'lucide-static/icons/arrow-right';
|
||||||
|
|
||||||
// return string of an SVG
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### SVG Sprite
|
You'll need an SVG loader like [`svg-inline-loader`](https://v4.webpack.js.org/loaders/svg-inline-loader/).
|
||||||
|
|
||||||
You may need additional loader for this.
|
### Using the SVG sprite
|
||||||
|
|
||||||
|
:::danger
|
||||||
|
[Not intended for production use.](#production-warning)
|
||||||
|
:::
|
||||||
|
|
||||||
|
You may also need an additional SVG loader to handle this.
|
||||||
|
|
||||||
|
#### Basic sprite usage (not production-optimized):
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- Icon Sprite, not recommended for production! -->
|
|
||||||
<img src="lucide-static/sprite.svg#house" />
|
<img src="lucide-static/sprite.svg#house" />
|
||||||
|
```
|
||||||
|
|
||||||
<!-- or -->
|
#### Inline usage:
|
||||||
|
|
||||||
|
```html
|
||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
@@ -109,12 +136,13 @@ You may need additional loader for this.
|
|||||||
<use href="#alert-triangle" />
|
<use href="#alert-triangle" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<svg>
|
<!-- sprite SVG -->
|
||||||
...sprite svg
|
<svg>...</svg>
|
||||||
</svg>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you'd prefer, you can use CSS to hold your base SVG properties
|
#### Inline with CSS helper class
|
||||||
|
|
||||||
|
If you'd prefer, you can use CSS to hold your base SVG properties:
|
||||||
|
|
||||||
```css
|
```css
|
||||||
.lucide-icon {
|
.lucide-icon {
|
||||||
@@ -128,47 +156,71 @@ If you'd prefer, you can use CSS to hold your base SVG properties
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
and update the SVG as follows
|
...and update the SVG as follows:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="lucide-icon"
|
class="lucide-icon"
|
||||||
>
|
>
|
||||||
<use
|
<use href="#triangle-alert" />
|
||||||
href="#alert-triangle"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<svg>
|
|
||||||
...sprite svg
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
<!-- sprite SVG -->
|
||||||
|
<svg>...</svg>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Icon Font
|
## Icon font
|
||||||
|
|
||||||
```css
|
:::danger
|
||||||
|
[Not intended for production use.](#production-warning)
|
||||||
|
:::
|
||||||
|
|
||||||
|
Lucide icons are also available as a web font. To use them, you first need to include the corresponding stylesheet:
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```css [Vite]
|
||||||
|
@import 'lucide-static/font/lucide.css';
|
||||||
|
```
|
||||||
|
|
||||||
|
```css [Webpack]
|
||||||
@import ('~lucide-static/font/lucide.css');
|
@import ('~lucide-static/font/lucide.css');
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```html [CDN]
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/lucide-static@latest/font/lucide.css" />
|
||||||
|
```
|
||||||
|
|
||||||
|
```html [Static asset]
|
||||||
|
<link rel="stylesheet" href="/your/path/to/lucide.css" />
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
Once included, use the format `icon-{kebab-case-name}`. You can copy icon names from the [Lucide Icons page](https://lucide.dev/icons).
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<div class="icon-house"></div>
|
<div class="icon-house"></div>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Node.js
|
If you're not using a package manager, you can download the font files directly from the [latest release](https://github.com/lucide-icons/lucide/releases/latest).
|
||||||
|
|
||||||
To use lucide icons in your Nodejs project you can import each icon as:
|
## Node.js
|
||||||
|
|
||||||
|
You can also import Lucide icons in Node.js (CommonJS) projects:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { messageSquare } = require('lucide-static/lib');
|
const {messageSquare} = require('lucide-static/lib');
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note: Each icon name is in camelCase.
|
> Note: Each icon name is in camelCase.
|
||||||
|
|
||||||
#### Example in node.js project
|
#### Express app example in Node.js
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { messageSquare } = require('lucide-static/lib');
|
const {messageSquare} = require('lucide-static/lib');
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = 3000;
|
const port = 3000;
|
||||||
|
|
||||||
@@ -181,7 +233,7 @@ app.get('/', (req, res) => {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Lucide Icons</h1>
|
<h1>Lucide Icons</h1>
|
||||||
<p>This is a lucide icon ${messageSquare}</p>
|
<p>This is a Lucide icon ${messageSquare}</p>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -7,22 +7,22 @@ Implementation of the lucide icon library for svelte applications.
|
|||||||
::: code-group
|
::: code-group
|
||||||
|
|
||||||
```sh [pnpm]
|
```sh [pnpm]
|
||||||
pnpm add lucide-svelte
|
pnpm add @lucide/svelte
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [yarn]
|
```sh [yarn]
|
||||||
yarn add lucide-svelte
|
yarn add @lucide/svelte
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [npm]
|
```sh [npm]
|
||||||
npm install lucide-svelte
|
npm install @lucide/svelte
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [bun]
|
```sh [bun]
|
||||||
bun add lucide-svelte
|
bun add @lucide/svelte
|
||||||
```
|
```
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
> `@lucide/svelte` is only for Svelte 5, for Svelte 4 use the `lucide-svelte` package.
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ Default usage:
|
|||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<script>
|
<script>
|
||||||
import { Skull } from 'lucide-svelte';
|
import { Skull } from '@lucide/svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Skull />
|
<Skull />
|
||||||
@@ -46,17 +46,17 @@ Additional props can be passed to adjust the icon:
|
|||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<script>
|
<script>
|
||||||
import { Camera } from 'lucide-svelte';
|
import { Camera } from '@lucide/svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Camera color="#ff3e98" />
|
<Camera color="#ff3e98" />
|
||||||
```
|
```
|
||||||
|
|
||||||
For faster builds and load times, you can import icons directly from the `lucide-svelte/icons` directory:
|
For faster builds and load times, you can import icons directly from the `@lucide/svelte/icons` directory:
|
||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<script>
|
<script>
|
||||||
import CircleAlert from 'lucide-svelte/icons/circle-alert';
|
import CircleAlert from '@lucide/svelte/icons/circle-alert';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CircleAlert color="#ff3e98" />
|
<CircleAlert color="#ff3e98" />
|
||||||
@@ -77,7 +77,7 @@ To customize the appearance of an icon, you can pass custom properties as props
|
|||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<script>
|
<script>
|
||||||
import { Phone } from 'lucide-svelte';
|
import { Phone } from '@lucide/svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Phone fill="#333" />
|
<Phone fill="#333" />
|
||||||
@@ -91,101 +91,140 @@ The package includes type definitions for all icons. This is useful if you want
|
|||||||
|
|
||||||
### TypeScript Example
|
### TypeScript Example
|
||||||
|
|
||||||
#### Svelte 4
|
::: code-group
|
||||||
|
|
||||||
```svelte
|
```svelte [Svelte 5]
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Home, Library, Cog, type Icon } from 'lucide-svelte';
|
import { Home, Library, Cog, type Icon as IconType } from '@lucide/svelte';
|
||||||
import type { ComponentType } from 'svelte';
|
|
||||||
|
|
||||||
type MenuItem = {
|
type MenuItem = {
|
||||||
name: string;
|
name: string;
|
||||||
href: string;
|
href: string;
|
||||||
icon: ComponentType<Icon>;
|
icon: typeof IconType;
|
||||||
};
|
};
|
||||||
|
|
||||||
const menuItems: MenuItem[] = [
|
const menuItems: MenuItem[] = [
|
||||||
{
|
{
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
href: '/',
|
href: '/',
|
||||||
icon: Home
|
icon: Home
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Blog',
|
name: 'Blog',
|
||||||
href: '/blog',
|
href: '/blog',
|
||||||
icon: Library
|
icon: Library
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Projects',
|
name: 'Projects',
|
||||||
href: '/projects',
|
href: '/projects',
|
||||||
icon: Cog
|
icon: Cog
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each menuItems as item}
|
{#each menuItems as item}
|
||||||
<a href={item.href}>
|
{@const Icon = item.icon}
|
||||||
<svelte:component this={item.icon} />
|
<a href={item.href}>
|
||||||
<span>{item.name}</span>
|
<Icon />
|
||||||
</a>
|
<span>{item.name}</span>
|
||||||
|
</a>
|
||||||
{/each}
|
{/each}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```svelte [Svelte 4]
|
||||||
#### Svelte 5
|
|
||||||
Some changes are required since Svelte 5 [deprecates](https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes-Component-typing-changes) the `ComponentType` typescript type.
|
|
||||||
|
|
||||||
```svelte
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Home, Library, Cog, type Icon as IconType } from 'lucide-svelte';
|
import { Home, Library, Cog, type Icon } from '@lucide/svelte';
|
||||||
|
import type { ComponentType } from 'svelte';
|
||||||
|
|
||||||
type MenuItem = {
|
type MenuItem = {
|
||||||
name: string;
|
name: string;
|
||||||
href: string;
|
href: string;
|
||||||
icon: typeof IconType;
|
icon: ComponentType<Icon>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const menuItems: MenuItem[] = [
|
const menuItems: MenuItem[] = [
|
||||||
{
|
{
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
href: '/',
|
href: '/',
|
||||||
icon: Home
|
icon: Home
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Blog',
|
name: 'Blog',
|
||||||
href: '/blog',
|
href: '/blog',
|
||||||
icon: Library
|
icon: Library
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Projects',
|
name: 'Projects',
|
||||||
href: '/projects',
|
href: '/projects',
|
||||||
icon: Cog
|
icon: Cog
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each menuItems as item}
|
{#each menuItems as item}
|
||||||
{@const Icon = item.icon}
|
{@const Icon = item.icon}
|
||||||
<a href={item.href}>
|
<a href={item.href}>
|
||||||
<Icon />
|
<Icon />
|
||||||
<span>{item.name}</span>
|
<span>{item.name}</span>
|
||||||
</a>
|
</a>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### JSDoc Example
|
### JSDoc Example
|
||||||
|
|
||||||
#### Svelte 4
|
::: code-group
|
||||||
|
|
||||||
```svelte
|
```svelte [Svelte 5]
|
||||||
<script>
|
<script>
|
||||||
import { Home, Library, Cog } from 'lucide-svelte';
|
import { Home, Library, Cog } from '@lucide/svelte';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MenuItem
|
* @typedef {Object} MenuItem
|
||||||
* @property {string} name
|
* @property {string} name
|
||||||
* @property {string} href
|
* @property {string} href
|
||||||
* @property {import('svelte').ComponentType<import('lucide-svelte').Icon>} icon
|
* @property {typeof import('@lucide/svelte').Icon} icon
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {MenuItem[]} */
|
||||||
|
const menuItems = [
|
||||||
|
{
|
||||||
|
name: 'Home',
|
||||||
|
href: '/',
|
||||||
|
icon: Home
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Blog',
|
||||||
|
href: '/blog',
|
||||||
|
icon: Library
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Projects',
|
||||||
|
href: '/projects',
|
||||||
|
icon: Cog
|
||||||
|
}
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each menuItems as item}
|
||||||
|
{@const Icon = item.icon}
|
||||||
|
<a href={item.href}>
|
||||||
|
<Icon />
|
||||||
|
<span>{item.name}</span>
|
||||||
|
</a>
|
||||||
|
{/each}
|
||||||
|
```
|
||||||
|
|
||||||
|
```svelte [Svelte 4]
|
||||||
|
<script>
|
||||||
|
import { Home, Library, Cog } from '@lucide/svelte';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} MenuItem
|
||||||
|
* @property {string} name
|
||||||
|
* @property {string} href
|
||||||
|
* @property {import('svelte').ComponentType<import('@lucide/svelte').Icon>} icon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @type {MenuItem[]} */
|
/** @type {MenuItem[]} */
|
||||||
@@ -209,56 +248,15 @@ Some changes are required since Svelte 5 [deprecates](https://svelte.dev/docs/sv
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each menuItems as item}
|
{#each menuItems as item}
|
||||||
|
{@const Icon = item.icon}
|
||||||
<a href={item.href}>
|
<a href={item.href}>
|
||||||
<svelte:component this={item.icon} />
|
<Icon />
|
||||||
<span>{item.name}</span>
|
<span>{item.name}</span>
|
||||||
</a>
|
</a>
|
||||||
{/each}
|
{/each}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
#### Svelte 5
|
|
||||||
|
|
||||||
```svelte
|
|
||||||
<script>
|
|
||||||
import { Home, Library, Cog } from 'lucide-svelte';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} MenuItem
|
|
||||||
* @property {string} name
|
|
||||||
* @property {string} href
|
|
||||||
* @property {typeof import('lucide-svelte').Icon} icon
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @type {MenuItem[]} */
|
|
||||||
const menuItems = [
|
|
||||||
{
|
|
||||||
name: 'Home',
|
|
||||||
href: '/',
|
|
||||||
icon: Home
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Blog',
|
|
||||||
href: '/blog',
|
|
||||||
icon: Library
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Projects',
|
|
||||||
href: '/projects',
|
|
||||||
icon: Cog
|
|
||||||
}
|
|
||||||
];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#each menuItems as item}
|
|
||||||
{@const Icon = item.icon}
|
|
||||||
<a href={item.href}>
|
|
||||||
<Icon />
|
|
||||||
<span>{item.name}</span>
|
|
||||||
</a>
|
|
||||||
{/each}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
For more details about typing the `svelte:component` directive, see the [Svelte documentation](https://svelte.dev/docs/typescript#types-componenttype).
|
For more details about typing the `svelte:component` directive, see the [Svelte documentation](https://svelte.dev/docs/typescript#types-componenttype).
|
||||||
|
|
||||||
@@ -275,11 +273,11 @@ This creates a single icon based on the iconNode passed and renders a Lucide ico
|
|||||||
|
|
||||||
```svelte
|
```svelte
|
||||||
<script>
|
<script>
|
||||||
import { Icon } from 'lucide-svelte';
|
import { Icon } from '@lucide/svelte';
|
||||||
import { burger, sausage } from '@lucide/lab';
|
import { pear, sausage } from '@lucide/lab';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Icon iconNode={burger} />
|
<Icon iconNode={pear} />
|
||||||
<Icon iconNode={sausage} color="red"/>
|
<Icon iconNode={sausage} color="red"/>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -293,29 +291,29 @@ The example below imports all ES Modules, so exercise caution when using it. Imp
|
|||||||
|
|
||||||
### Icon Component Example
|
### Icon Component Example
|
||||||
|
|
||||||
#### Svelte 4
|
::: code-group
|
||||||
|
|
||||||
```svelte
|
```svelte [Svelte 5]
|
||||||
<script>
|
<script>
|
||||||
import * as icons from 'lucide-svelte';
|
import * as icons from '@lucide/svelte';
|
||||||
|
let { name, ...props } = $props();
|
||||||
|
|
||||||
|
const Icon = icons[name];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Icon {...props} />
|
||||||
|
```
|
||||||
|
|
||||||
|
```svelte [Svelte 4]
|
||||||
|
<script>
|
||||||
|
import * as icons from '@lucide/svelte';
|
||||||
export let name;
|
export let name;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:component this={icons[name]} {...$$props} />
|
<svelte:component this={icons[name]} {...$$props} />
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Svelte 5
|
:::
|
||||||
|
|
||||||
```svelte
|
|
||||||
<script>
|
|
||||||
import * as icons from 'lucide-svelte';
|
|
||||||
let { name } = $props();
|
|
||||||
|
|
||||||
const Icon = icons[name];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Icon {...props} />
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Using the Icon Component
|
#### Using the Icon Component
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ import { Camera } from 'lucide-vue-next';
|
|||||||
| `size` | *number* | 24 |
|
| `size` | *number* | 24 |
|
||||||
| `color` | *string* | currentColor |
|
| `color` | *string* | currentColor |
|
||||||
| `stroke-width` | *number* | 2 |
|
| `stroke-width` | *number* | 2 |
|
||||||
| `absolute-stroke-width` | *boolean* | false |
|
| `absoluteStrokeWidth` | *boolean* | false |
|
||||||
| `default-class` | *string* | lucide-icon |
|
| `default-class` | *string* | lucide-icon |
|
||||||
|
|
||||||
### Applying props
|
### Applying props
|
||||||
@@ -81,11 +81,11 @@ This creates a single icon based on the iconNode passed and renders a Lucide ico
|
|||||||
```vue
|
```vue
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Icon } from 'lucide-vue-next';
|
import { Icon } from 'lucide-vue-next';
|
||||||
import { burger } from '@lucide/lab';
|
import { baseball } from '@lucide/lab';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Icon :iconNode="burger" />
|
<Icon :iconNode="baseball" />
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Additional props can be passed to adjust the icon:
|
|||||||
| `size` | *number* | 24 |
|
| `size` | *number* | 24 |
|
||||||
| `color` | *string* | currentColor |
|
| `color` | *string* | currentColor |
|
||||||
| `stroke-width` | *number* | 2 |
|
| `stroke-width` | *number* | 2 |
|
||||||
| `absolute-stroke-width` | *boolean* | false |
|
| `absoluteStrokeWidth` | *boolean* | false |
|
||||||
| `default-class` | *string* | lucide-icon |
|
| `default-class` | *string* | lucide-icon |
|
||||||
|
|
||||||
### Applying props
|
### Applying props
|
||||||
|
|||||||
@@ -126,11 +126,23 @@ import { createElement, Menu } from 'lucide';
|
|||||||
|
|
||||||
const menuIcon = createElement(Menu); // Returns HTMLElement (svg)
|
const menuIcon = createElement(Menu); // Returns HTMLElement (svg)
|
||||||
|
|
||||||
// set custom attributes with browser native functions
|
// Append HTMLElement in the DOM
|
||||||
menuIcon.setAttribute('stroke', '#333');
|
const myApp = document.getElementById('app');
|
||||||
menuIcon.classList.add('my-icon-class');
|
myApp.appendChild(menuIcon);
|
||||||
|
```
|
||||||
|
|
||||||
// Append HTMLElement in webpage
|
#### Custom Element binding with custom attributes
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { createElement, Menu } from 'lucide';
|
||||||
|
|
||||||
|
const menuIcon = createElement(Menu, {
|
||||||
|
class: ['my-custom-class', 'icon'],
|
||||||
|
'stroke-width': 1,
|
||||||
|
stroke: '#333'
|
||||||
|
}); // Returns HTMLElement (svg)
|
||||||
|
|
||||||
|
// Append HTMLElement in the DOM
|
||||||
const myApp = document.getElementById('app');
|
const myApp = document.getElementById('app');
|
||||||
myApp.appendChild(menuIcon);
|
myApp.appendChild(menuIcon);
|
||||||
```
|
```
|
||||||
@@ -141,11 +153,11 @@ myApp.appendChild(menuIcon);
|
|||||||
They can be used in the same way as the official icons.
|
They can be used in the same way as the official icons.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { burger } from '@lucide/lab';
|
import { coconut } from '@lucide/lab';
|
||||||
|
|
||||||
createIcons({
|
createIcons({
|
||||||
icons: {
|
icons: {
|
||||||
burger
|
coconut
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.9 KiB |
@@ -48,10 +48,12 @@
|
|||||||
<path d="M340 120v240" stroke="#D8D8D9" stroke-width=".5"/>
|
<path d="M340 120v240" stroke="#D8D8D9" stroke-width=".5"/>
|
||||||
<path d="M120 350h240" stroke="#D8D8D9" stroke-width=".5"/>
|
<path d="M120 350h240" stroke="#D8D8D9" stroke-width=".5"/>
|
||||||
<path d="M350 120v240" stroke="#D8D8D9" stroke-width=".5"/>
|
<path d="M350 120v240" stroke="#D8D8D9" stroke-width=".5"/>
|
||||||
</g>
|
</g>
|
||||||
<path d="m240 140-100 50 100 50 100-50-100-50Z" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<g id="embed-lucide-layers" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
||||||
<path d="m140 290 100 50 100-50" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z" />
|
||||||
<path d="m140 240 100 50 100-50" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12" />
|
||||||
|
<path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17" />
|
||||||
|
</g>
|
||||||
<g opacity=".5" stroke="#fff" stroke-width="3">
|
<g opacity=".5" stroke="#fff" stroke-width="3">
|
||||||
<path d="M120 92v16"/>
|
<path d="M120 92v16"/>
|
||||||
<path d="M360 92v16"/>
|
<path d="M360 92v16"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
1
docs/images/2px-element-spacing-abrupt-cut.svg
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
1
docs/images/2px-element-spacing-connected.svg
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -53,9 +53,13 @@
|
|||||||
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
||||||
</g>
|
</g>
|
||||||
<g clip-path="url(#clip1_1612_15659)">
|
<g clip-path="url(#clip1_1612_15659)">
|
||||||
<path d="M310 260C324.9 245.4 340 227.9 340 205C340 190.413 334.205 176.424 323.891 166.109C313.576 155.795 299.587 150 285 150C267.4 150 255 155 240 170C225 155 212.6 150 195 150C180.413 150 166.424 155.795 156.109 166.109C145.795 176.424 140 190.413 140 205C140 228 155 245.5 170 260L240 330L310 260Z" stroke="#F56565" stroke-width="60" stroke-linejoin="round" stroke-dasharray="0.2 0.4"/>
|
<g id="embed-lucide-heart" stroke="#F56565" stroke-width="7" stroke-dasharray="0.04 0.08" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
||||||
|
<path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="embed-lucide-heart" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
||||||
|
<path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z" />
|
||||||
</g>
|
</g>
|
||||||
<path d="M310 260C324.9 245.4 340 227.9 340 205C340 190.413 334.205 176.424 323.891 166.109C313.576 155.795 299.587 150 285 150C267.4 150 255 155 240 170C225 155 212.6 150 195 150C180.413 150 166.424 155.795 156.109 166.109C145.795 176.424 140 190.413 140 205C140 228 155 245.5 170 260L240 330L310 260Z" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
<defs>
|
<defs>
|
||||||
<clipPath id="clip0_1612_15659">
|
<clipPath id="clip0_1612_15659">
|
||||||
<rect x="120" y="120" width="240" height="240" rx="8" fill="white"/>
|
<rect x="120" y="120" width="240" height="240" rx="8" fill="white"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -52,16 +52,18 @@
|
|||||||
<path d="M120 350H360" stroke="#D8D8D9" stroke-width="0.5"/>
|
<path d="M120 350H360" stroke="#D8D8D9" stroke-width="0.5"/>
|
||||||
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
||||||
</g>
|
</g>
|
||||||
<path d="M310 160H170C158.954 160 150 168.954 150 180V320C150 331.046 158.954 340 170 340H310C321.046 340 330 331.046 330 320V180C330 168.954 321.046 160 310 160Z" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<g id="embed-lucide-calendar-days" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
||||||
<path d="M280 140V180" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M8 2v4" />
|
||||||
<path d="M200 140V180" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M16 2v4" />
|
||||||
<path d="M150 220H330" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<rect width="18" height="18" x="3" y="4" rx="2" />
|
||||||
<path d="M200 260H200.1" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M3 10h18" />
|
||||||
<path d="M240 260H240.1" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M8 14h.01" />
|
||||||
<path d="M280 260H280.1" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M12 14h.01" />
|
||||||
<path d="M200 300H200.1" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M16 14h.01" />
|
||||||
<path d="M240 300H240.1" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M8 18h.01" />
|
||||||
<path d="M280 300H280.1" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M12 18h.01" />
|
||||||
|
<path d="M16 18h.01" />
|
||||||
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
<clipPath id="clip0_1612_15298">
|
<clipPath id="clip0_1612_15298">
|
||||||
<rect x="120" y="120" width="240" height="240" rx="8" fill="white"/>
|
<rect x="120" y="120" width="240" height="240" rx="8" fill="white"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
@@ -54,10 +54,12 @@
|
|||||||
</g>
|
</g>
|
||||||
<circle opacity="0.17" cx="240" cy="240" r="100" stroke="#F56565" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<circle opacity="0.17" cx="240" cy="240" r="100" stroke="#F56565" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
<rect opacity="0.17" x="150" y="150" width="180" height="180" rx="20" stroke="#F56565" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<rect opacity="0.17" x="150" y="150" width="180" height="180" rx="20" stroke="#F56565" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
<path d="M330 330L270 270M330 330V282M330 330H282" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<g id="embed-lucide-expand" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
||||||
<path d="M150 282V330M150 330H198M150 330L210 270" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="m21 21-6-6m6 6v-4.8m0 4.8h-4.8" />
|
||||||
<path d="M330 198V150M330 150H282M330 150L270 210" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M3 16.2V21m0 0h4.8M3 21l6-6" />
|
||||||
<path d="M150 198V150M150 150H198M150 150L210 210" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M21 7.8V3m0 0h-4.8M21 3l-6 6" />
|
||||||
|
<path d="M3 7.8V3m0 0h4.8M3 3l6 6" />
|
||||||
|
</g>
|
||||||
<circle opacity="0.5" cx="240" cy="240" r="100" stroke="#F56565" stroke-dasharray="1 1"/>
|
<circle opacity="0.5" cx="240" cy="240" r="100" stroke="#F56565" stroke-dasharray="1 1"/>
|
||||||
<rect opacity="0.5" x="150" y="150" width="180" height="180" rx="20" stroke="#F56565" stroke-dasharray="1 1"/>
|
<rect opacity="0.5" x="150" y="150" width="180" height="180" rx="20" stroke="#F56565" stroke-dasharray="1 1"/>
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -54,7 +54,9 @@
|
|||||||
<path d="M120 350H360" stroke="#D8D8D9" stroke-width="0.5"/>
|
<path d="M120 350H360" stroke="#D8D8D9" stroke-width="0.5"/>
|
||||||
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
||||||
</g>
|
</g>
|
||||||
<path d="M150 150L220.7 320L245.8 246.1L320 220.7L150 150Z" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<g id="embed-lucide-mouse-pointer-2" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(110 110), scale(10)">
|
||||||
|
<path d="M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z" />
|
||||||
|
</g>
|
||||||
<path opacity="0.5" d="M240 120V360M360 240H120" stroke="#F56565" stroke-dasharray="1 1"/>
|
<path opacity="0.5" d="M240 120V360M360 240H120" stroke="#F56565" stroke-dasharray="1 1"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -53,7 +53,9 @@
|
|||||||
<path d="M120 350H360" stroke="#D8D8D9" stroke-width="0.5"/>
|
<path d="M120 350H360" stroke="#D8D8D9" stroke-width="0.5"/>
|
||||||
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
<path d="M350 120V360" stroke="#D8D8D9" stroke-width="0.5"/>
|
||||||
</g>
|
</g>
|
||||||
<path d="M160 160L230.7 330L255.8 256.1L330 230.7L160 160Z" stroke="#3C3C43" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
|
<g id="embed-lucide-mouse-pointer-2" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
||||||
|
<path d="M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z" />
|
||||||
|
</g>
|
||||||
<path opacity="0.5" d="M240 120V360M360 240H120" stroke="#F56565" stroke-dasharray="1 1"/>
|
<path opacity="0.5" d="M240 120V360M360 240H120" stroke="#F56565" stroke-dasharray="1 1"/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -2,6 +2,7 @@ import copy from 'rollup-plugin-copy';
|
|||||||
import replace from '@rollup/plugin-replace';
|
import replace from '@rollup/plugin-replace';
|
||||||
|
|
||||||
export default defineNitroConfig({
|
export default defineNitroConfig({
|
||||||
|
compatibilityDate: '2025-07-30',
|
||||||
preset: 'vercel_edge',
|
preset: 'vercel_edge',
|
||||||
srcDir: '.vitepress',
|
srcDir: '.vitepress',
|
||||||
routeRules: {
|
routeRules: {
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
"docs:build": "pnpm run /^prebuild:.*/ && vitepress build",
|
"docs:build": "pnpm run /^prebuild:.*/ && vitepress build",
|
||||||
"docs:preview": "vitepress preview",
|
"docs:preview": "vitepress preview",
|
||||||
"build:docs": "vitepress build",
|
"build:docs": "vitepress build",
|
||||||
"prebuild:iconNodes": "node ./scripts/writeIconNodes.mjs",
|
"prebuild:iconNodes": "node --experimental-strip-types ./scripts/writeIconNodes.mjs",
|
||||||
"prebuild:metaJson": "node ./scripts/writeIconMetaIndex.mjs",
|
"prebuild:metaJson": "node --experimental-strip-types ./scripts/writeIconMetaIndex.mjs",
|
||||||
"prebuild:releaseJson": "node ./scripts/writeReleaseMetadata.mjs",
|
"prebuild:releaseJson": "node --experimental-strip-types ./scripts/writeReleaseMetadata.mjs",
|
||||||
"prebuild:categoriesJson": "node ./scripts/writeCategoriesMetadata.mjs",
|
"prebuild:categoriesJson": "node --experimental-strip-types ./scripts/writeCategoriesMetadata.mjs",
|
||||||
"prebuild:relatedIcons": "node ./scripts/writeIconRelatedIcons.mjs",
|
"prebuild:relatedIcons": "node --experimental-strip-types ./scripts/writeIconRelatedIcons.mjs",
|
||||||
"prebuild:iconDetails": "node ./scripts/writeIconDetails.mjs",
|
"prebuild:iconDetails": "node --experimental-strip-types ./scripts/writeIconDetails.mjs",
|
||||||
"postbuild:vercelJson": "node ./scripts/writeVercelOutput.mjs",
|
"postbuild:vercelJson": "node --experimental-strip-types ./scripts/writeVercelOutput.mjs",
|
||||||
"dev": "npx nitropack dev",
|
"dev": "npx nitropack dev",
|
||||||
"prebuild:api": "npx nitropack prepare",
|
"prebuild:api": "npx nitropack prepare",
|
||||||
"build:api": "npx nitropack build",
|
"build:api": "npx nitropack build",
|
||||||
@@ -28,12 +28,12 @@
|
|||||||
"@lucide/build-icons": "workspace:*",
|
"@lucide/build-icons": "workspace:*",
|
||||||
"@lucide/helpers": "workspace:*",
|
"@lucide/helpers": "workspace:*",
|
||||||
"@lucide/shared": "workspace:*",
|
"@lucide/shared": "workspace:*",
|
||||||
"@rollup/plugin-replace": "^6.0.1",
|
"@rollup/plugin-replace": "^6.0.2",
|
||||||
"@types/semver": "^7.5.3",
|
"@types/semver": "^7.5.3",
|
||||||
"h3": "^1.8.0",
|
|
||||||
"nitropack": "2.8.1",
|
"nitropack": "2.8.1",
|
||||||
"rollup-plugin-copy": "^3.4.0",
|
"rollup-plugin-copy": "^3.5.0",
|
||||||
"vitepress": "^1.3.1"
|
"vitepress": "^1.6.3",
|
||||||
|
"svg-path-commander": "^2.1.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/vue": "^1.0.3",
|
"@floating-ui/vue": "^1.0.3",
|
||||||
@@ -57,6 +57,6 @@
|
|||||||
"sitemap": "^7.1.1",
|
"sitemap": "^7.1.1",
|
||||||
"svg-pathdata": "^6.0.3",
|
"svg-pathdata": "^6.0.3",
|
||||||
"svgson": "^5.2.1",
|
"svgson": "^5.2.1",
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
docs/public/framework-logos/astro-dark.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg width="85" height="107" viewBox="0 0 85 107" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M27.5894 91.1365C22.7555 86.7178 21.3444 77.4335 23.3583 70.7072C26.8503 74.948 31.6888 76.2914 36.7005 77.0497C44.4375 78.2199 52.0359 77.7822 59.2232 74.2459C60.0454 73.841 60.8052 73.3027 61.7036 72.7574C62.378 74.714 62.5535 76.6892 62.318 78.6996C61.7452 83.5957 59.3086 87.3778 55.4332 90.2448C53.8835 91.3916 52.2437 92.4167 50.6432 93.4979C45.7262 96.8213 44.3959 100.718 46.2435 106.386C46.2874 106.525 46.3267 106.663 46.426 107C43.9155 105.876 42.0817 104.24 40.6845 102.089C39.2087 99.8193 38.5066 97.3081 38.4696 94.5909C38.4511 93.2686 38.4511 91.9345 38.2733 90.6309C37.8391 87.4527 36.3471 86.0297 33.5364 85.9478C30.6518 85.8636 28.37 87.6469 27.7649 90.4554C27.7187 90.6707 27.6517 90.8837 27.5847 91.1341L27.5894 91.1365Z" fill="white"/>
|
||||||
|
<path d="M27.5894 91.1365C22.7555 86.7178 21.3444 77.4335 23.3583 70.7072C26.8503 74.948 31.6888 76.2914 36.7005 77.0497C44.4375 78.2199 52.0359 77.7822 59.2232 74.2459C60.0454 73.841 60.8052 73.3027 61.7036 72.7574C62.378 74.714 62.5535 76.6892 62.318 78.6996C61.7452 83.5957 59.3086 87.3778 55.4332 90.2448C53.8835 91.3916 52.2437 92.4167 50.6432 93.4979C45.7262 96.8213 44.3959 100.718 46.2435 106.386C46.2874 106.525 46.3267 106.663 46.426 107C43.9155 105.876 42.0817 104.24 40.6845 102.089C39.2087 99.8193 38.5066 97.3081 38.4696 94.5909C38.4511 93.2686 38.4511 91.9345 38.2733 90.6309C37.8391 87.4527 36.3471 86.0297 33.5364 85.9478C30.6518 85.8636 28.37 87.6469 27.7649 90.4554C27.7187 90.6707 27.6517 90.8837 27.5847 91.1341L27.5894 91.1365Z" fill="url(#paint0_linear_1_59)"/>
|
||||||
|
<path d="M0 69.5866C0 69.5866 14.3139 62.6137 28.6678 62.6137L39.4901 29.1204C39.8953 27.5007 41.0783 26.3999 42.4139 26.3999C43.7495 26.3999 44.9325 27.5007 45.3377 29.1204L56.1601 62.6137C73.1601 62.6137 84.8278 69.5866 84.8278 69.5866C84.8278 69.5866 60.5145 3.35233 60.467 3.21944C59.7692 1.2612 58.5911 0 57.0029 0H27.8274C26.2392 0 25.1087 1.2612 24.3634 3.21944C24.3108 3.34983 0 69.5866 0 69.5866Z" fill="white"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_1_59" x1="22.4702" y1="107" x2="69.1451" y2="84.9468" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#D83333"/>
|
||||||
|
<stop offset="1" stop-color="#F041FF"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
4
docs/public/framework-logos/astro.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="85" height="107" viewBox="0 0 85 107" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M27.5893 91.1365C22.7555 86.7178 21.3443 77.4335 23.3583 70.7072C26.8503 74.948 31.6888 76.2914 36.7005 77.0497C44.4374 78.2199 52.0358 77.7822 59.2231 74.2459C60.0453 73.841 60.8052 73.3027 61.7036 72.7574C62.378 74.714 62.5535 76.6892 62.3179 78.6996C61.7452 83.5957 59.3086 87.3778 55.4332 90.2448C53.8835 91.3916 52.2437 92.4167 50.6432 93.4979C45.7262 96.8213 44.3959 100.718 46.2435 106.386C46.2874 106.525 46.3267 106.663 46.426 107C43.9155 105.876 42.0817 104.24 40.6844 102.089C39.2086 99.8193 38.5065 97.3081 38.4696 94.5909C38.4511 93.2686 38.4511 91.9345 38.2733 90.6309C37.8391 87.4527 36.3471 86.0297 33.5364 85.9478C30.6518 85.8636 28.37 87.6469 27.7649 90.4554C27.7187 90.6707 27.6517 90.8837 27.5847 91.1341L27.5893 91.1365Z" fill="#17191E"/>
|
||||||
|
<path d="M0 69.5866C0 69.5866 14.3139 62.6137 28.6678 62.6137L39.4901 29.1204C39.8953 27.5007 41.0783 26.3999 42.4139 26.3999C43.7495 26.3999 44.9325 27.5007 45.3377 29.1204L56.1601 62.6137C73.1601 62.6137 84.8278 69.5866 84.8278 69.5866C84.8278 69.5866 60.5145 3.35233 60.467 3.21944C59.7692 1.2612 58.5911 0 57.0029 0H27.8274C26.2392 0 25.1087 1.2612 24.3634 3.21944C24.3108 3.34983 0 69.5866 0 69.5866Z" fill="#17191E"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
25
docs/public/package-logos/dark/lucide-astro.svg
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<svg width="120" height="22" viewBox="0 0 120 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M74.2 17.17C73.4081 17.1897 72.6251 16.9999 71.93 16.62C71.302 16.2576 70.7943 15.7186 70.47 15.07C70.1179 14.3272 69.9466 13.5117 69.97 12.69C69.97 11.79 70.13 11 70.47 10.32C70.8 9.64858 71.3176 9.08722 71.9601 8.70386C72.6026 8.32051 73.3424 8.1316 74.09 8.16C74.63 8.16 75.14 8.25 75.62 8.42C76.1 8.59 76.52 8.86 76.89 9.22C77.26 9.58 77.55 10.03 77.76 10.59C77.98 11.14 78.08 11.8 78.08 12.57V13.2H70.93V11.8H76.11C76.11 11.4 76.02 11.06 75.86 10.75C75.69 10.45 75.46 10.2 75.16 10.02C74.86 9.84 74.52 9.75 74.12 9.75C73.732 9.74115 73.3498 9.84539 73.02 10.05C72.7 10.25 72.45 10.52 72.27 10.85C72.1 11.18 72.01 11.54 72 11.93V13.13C72 13.65 72.1 14.08 72.28 14.44C72.47 14.8 72.73 15.08 73.06 15.27C73.39 15.47 73.78 15.56 74.23 15.56C74.53 15.56 74.8 15.52 75.04 15.43C75.29 15.35 75.5 15.22 75.67 15.05C75.85 14.89 75.99 14.68 76.07 14.43L78 14.65C77.8833 15.1455 77.6424 15.6032 77.3 15.98C76.97 16.35 76.54 16.65 76 16.85C75.48 17.05 74.88 17.16 74.2 17.16V17.17Z" fill="white"/>
|
||||||
|
<path d="M63.5 17.15C62.8309 17.1645 62.1733 16.9752 61.6143 16.6073C61.0553 16.2394 60.6213 15.7102 60.37 15.09C60.0367 14.3208 59.8763 13.4879 59.9 12.65C59.9 11.68 60.06 10.86 60.38 10.19C60.5513 9.78493 60.8009 9.41767 61.1145 9.10931C61.428 8.80095 61.7994 8.55755 62.2073 8.3931C62.6152 8.22864 63.0516 8.14636 63.4913 8.15098C63.9311 8.15559 64.3656 8.24702 64.77 8.42C65.1 8.59 65.36 8.8 65.55 9.04C65.75 9.28 65.89 9.5 66 9.72H66.08V5.36H68.15V17H66.12V15.62H66C65.9 15.84 65.74 16.06 65.54 16.3C65.2864 16.5868 64.9711 16.8123 64.6177 16.9595C64.2644 17.1068 63.8822 17.1719 63.5 17.15ZM64.07 15.47C64.51 15.47 64.87 15.35 65.19 15.11C65.49 14.88 65.73 14.54 65.89 14.11C66.04 13.7 66.12 13.21 66.12 12.64C66.12 12.07 66.04 11.58 65.88 11.16C65.7484 10.7769 65.5087 10.44 65.19 10.19C64.865 9.95506 64.4708 9.8354 64.07 9.85C63.61 9.85 63.23 9.97 62.92 10.2C62.62 10.44 62.39 10.77 62.23 11.2C62.08 11.61 62 12.1 62 12.64C62 13.18 62.08 13.67 62.23 14.1C62.39 14.52 62.63 14.86 62.93 15.1C63.24 15.34 63.63 15.47 64.07 15.47Z" fill="white"/>
|
||||||
|
<path d="M56.09 17V8.27H58.14V17H56.1H56.09ZM57.12 7.03C56.8 7.03 56.52 6.93 56.28 6.71C56.1684 6.6111 56.0795 6.48938 56.0191 6.35307C55.9587 6.21677 55.9283 6.06907 55.93 5.92C55.93 5.61 56.05 5.35 56.28 5.13C56.52 4.91 56.8 4.8 57.12 4.8C57.45 4.8 57.73 4.91 57.96 5.13C58.2 5.35 58.32 5.61 58.32 5.92C58.32 6.22 58.2 6.49 57.96 6.71C57.73 6.93 57.46 7.03 57.12 7.03Z" fill="white"/>
|
||||||
|
<path d="M50.66 17.17C49.9015 17.2156 49.1466 17.0346 48.4913 16.65C47.836 16.2653 47.3099 15.6945 46.98 15.01C46.6351 14.279 46.464 13.4781 46.48 12.67C46.48 11.78 46.65 11 46.99 10.32C47.33 9.64 47.81 9.12 48.43 8.73C49.102 8.33587 49.8712 8.13837 50.65 8.16C51.35 8.16 51.98 8.29 52.53 8.56C53.0617 8.80313 53.5168 9.18684 53.8464 9.66971C54.1759 10.1526 54.3674 10.7163 54.4 11.3H52.43C52.364 10.895 52.1673 10.5228 51.87 10.24C51.57 9.96 51.17 9.82 50.67 9.82C50.26 9.82 49.89 9.93 49.57 10.16C49.25 10.38 49 10.7 48.83 11.12C48.65 11.55 48.56 12.05 48.56 12.64C48.56 13.24 48.66 13.74 48.83 14.17C49 14.59 49.24 14.92 49.56 15.15C49.88 15.38 50.25 15.49 50.68 15.49C50.98 15.49 51.25 15.44 51.49 15.32C51.73 15.21 51.94 15.04 52.09 14.82C52.26 14.6 52.37 14.33 52.43 14.02H54.4C54.3725 14.6024 54.1878 15.1664 53.8656 15.6524C53.5434 16.1383 53.0957 16.5279 52.57 16.78C51.9746 17.053 51.3248 17.1864 50.67 17.17H50.66Z" fill="white"/>
|
||||||
|
<path d="M42.68 13.33V8.27H44.74V17H42.74V15.45H42.65C42.45 15.94 42.13 16.34 41.68 16.65C41.23 16.95 40.68 17.11 40.03 17.11C39.5054 17.1412 38.9835 17.0151 38.531 16.7479C38.0785 16.4806 37.716 16.0844 37.49 15.61C37.2299 15.0535 37.1033 14.444 37.12 13.83V8.27H39.18V13.51C39.18 14.06 39.33 14.51 39.63 14.83C39.93 15.16 40.33 15.32 40.83 15.32C41.1442 15.3154 41.4523 15.2325 41.7265 15.0789C42.0006 14.9252 42.2321 14.7056 42.4 14.44C42.59 14.14 42.68 13.77 42.68 13.33Z" fill="white"/>
|
||||||
|
<path d="M28.15 17V5.36H30.25V15.23H35.38V17H28.15Z" fill="white"/>
|
||||||
|
<path d="M14 11C14 9.93913 13.5786 8.92172 12.8284 8.17157C12.0783 7.42142 11.0609 7 10 7C8.93913 7 7.92172 7.42142 7.17157 8.17157C6.42143 8.92172 6 9.93913 6 11C6 13.1217 6.84285 15.1566 8.34315 16.6569C9.84344 18.1571 11.8783 19 14 19C16.1217 19 18.1566 18.1571 19.6569 16.6569C21.1571 15.1566 22 13.1217 22 11C22 7.45 20.45 4.25 18 2.06" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10 11C10 12.0609 10.4214 13.0783 11.1716 13.8284C11.9217 14.5786 12.9391 15 14 15C15.0609 15 16.0783 14.5786 16.8284 13.8284C17.5786 13.0783 18 12.0609 18 11C18 8.87827 17.1571 6.84344 15.6569 5.34315C14.1566 3.84285 12.1217 3 10 3C7.87827 3 5.84344 3.84285 4.34315 5.34315C2.84285 6.84344 2 8.87827 2 11C2 14.58 3.57 17.8 6.06 20" stroke="#F56565" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M88 13C89.1046 13 90 12.1046 90 11C90 9.89543 89.1046 9 88 9C86.8954 9 86 9.89543 86 11C86 12.1046 86.8954 13 88 13Z" fill="#737374"/>
|
||||||
|
<g clip-path="url(#clip0_2_7)">
|
||||||
|
<path d="M105.193 18.0349C104.283 17.2089 104.018 15.4736 104.397 14.2163C105.054 15.009 105.965 15.2601 106.908 15.4018C108.365 15.6205 109.795 15.5387 111.148 14.8777C111.303 14.8021 111.446 14.7014 111.615 14.5995C111.742 14.9652 111.775 15.3344 111.73 15.7102C111.623 16.6254 111.164 17.3323 110.434 17.8682C110.143 18.0825 109.834 18.2742 109.533 18.4762C108.607 19.0974 108.357 19.8258 108.705 20.8852C108.713 20.9112 108.72 20.937 108.739 21C108.266 20.7899 107.921 20.4841 107.658 20.0821C107.38 19.6578 107.248 19.1884 107.241 18.6805C107.238 18.4334 107.238 18.184 107.204 17.9404C107.123 17.3463 106.842 17.0803 106.313 17.065C105.77 17.0493 105.34 17.3826 105.226 17.9076C105.218 17.9478 105.205 17.9876 105.192 18.0344L105.193 18.0349Z" fill="white"/>
|
||||||
|
<path d="M105.193 18.0349C104.283 17.2089 104.018 15.4736 104.397 14.2163C105.054 15.009 105.965 15.2601 106.908 15.4018C108.365 15.6205 109.795 15.5387 111.148 14.8777C111.303 14.8021 111.446 14.7014 111.615 14.5995C111.742 14.9652 111.775 15.3344 111.73 15.7102C111.623 16.6254 111.164 17.3323 110.434 17.8682C110.143 18.0825 109.834 18.2742 109.533 18.4762C108.607 19.0974 108.357 19.8258 108.705 20.8852C108.713 20.9112 108.72 20.937 108.739 21C108.266 20.7899 107.921 20.4841 107.658 20.0821C107.38 19.6578 107.248 19.1884 107.241 18.6805C107.238 18.4334 107.238 18.184 107.204 17.9404C107.123 17.3463 106.842 17.0803 106.313 17.065C105.77 17.0493 105.34 17.3826 105.226 17.9076C105.218 17.9478 105.205 17.9876 105.192 18.0344L105.193 18.0349Z" fill="url(#paint0_linear_2_7)"/>
|
||||||
|
<path d="M100 14.0068C100 14.0068 102.694 12.7035 105.396 12.7035L107.433 6.44306C107.51 6.14032 107.732 5.93456 107.984 5.93456C108.235 5.93456 108.458 6.14032 108.534 6.44306L110.571 12.7035C113.771 12.7035 115.968 14.0068 115.968 14.0068C115.968 14.0068 111.391 1.6266 111.382 1.60176C111.251 1.23574 111.029 1 110.73 1H105.238C104.939 1 104.726 1.23574 104.586 1.60176C104.576 1.62614 100 14.0068 100 14.0068Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_2_7" x1="104.23" y1="21" x2="112.993" y2="16.8303" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#D83333"/>
|
||||||
|
<stop offset="1" stop-color="#F041FF"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip0_2_7">
|
||||||
|
<rect width="16" height="20" fill="white" transform="translate(100 1)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.2 KiB |
26
docs/public/package-logos/lucide-astro.svg
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<svg width="128" height="32" viewBox="0 0 128 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1_2)">
|
||||||
|
<path d="M120 0H8C3.58172 0 0 3.58172 0 8V24C0 28.4183 3.58172 32 8 32H120C124.418 32 128 28.4183 128 24V8C128 3.58172 124.418 0 120 0Z" fill="white"/>
|
||||||
|
<path d="M78.2 22.17C77.4081 22.1897 76.6251 21.9999 75.93 21.62C75.302 21.2576 74.7943 20.7186 74.47 20.07C74.1179 19.3272 73.9466 18.5117 73.97 17.69C73.97 16.79 74.13 16 74.47 15.32C74.8 14.6486 75.3176 14.0872 75.9601 13.7039C76.6026 13.3205 77.3424 13.1316 78.09 13.16C78.63 13.16 79.14 13.25 79.62 13.42C80.1 13.59 80.52 13.86 80.89 14.22C81.26 14.58 81.55 15.03 81.76 15.59C81.98 16.14 82.08 16.8 82.08 17.57V18.2H74.93V16.8H80.11C80.11 16.4 80.02 16.06 79.86 15.75C79.69 15.45 79.46 15.2 79.16 15.02C78.86 14.84 78.52 14.75 78.12 14.75C77.732 14.7412 77.3498 14.8454 77.02 15.05C76.7 15.25 76.45 15.52 76.27 15.85C76.1 16.18 76.01 16.54 76 16.93V18.13C76 18.65 76.1 19.08 76.28 19.44C76.47 19.8 76.73 20.08 77.06 20.27C77.39 20.47 77.78 20.56 78.23 20.56C78.53 20.56 78.8 20.52 79.04 20.43C79.29 20.35 79.5 20.22 79.67 20.05C79.85 19.89 79.99 19.68 80.07 19.43L82 19.65C81.8833 20.1455 81.6424 20.6032 81.3 20.98C80.97 21.35 80.54 21.65 80 21.85C79.48 22.05 78.88 22.16 78.2 22.16V22.17Z" fill="#1B1B1F"/>
|
||||||
|
<path d="M67.5 22.15C66.8309 22.1645 66.1733 21.9752 65.6143 21.6073C65.0553 21.2394 64.6213 20.7102 64.37 20.09C64.0367 19.3208 63.8763 18.4879 63.9 17.65C63.9 16.68 64.06 15.86 64.38 15.19C64.5513 14.7849 64.8009 14.4177 65.1145 14.1093C65.428 13.8009 65.7994 13.5576 66.2073 13.3931C66.6152 13.2286 67.0516 13.1464 67.4913 13.151C67.9311 13.1556 68.3656 13.247 68.77 13.42C69.1 13.59 69.36 13.8 69.55 14.04C69.75 14.28 69.89 14.5 70 14.72H70.08V10.36H72.15V22H70.12V20.62H70C69.9 20.84 69.74 21.06 69.54 21.3C69.2864 21.5868 68.9711 21.8123 68.6177 21.9595C68.2644 22.1068 67.8822 22.1719 67.5 22.15ZM68.07 20.47C68.51 20.47 68.87 20.35 69.19 20.11C69.49 19.88 69.73 19.54 69.89 19.11C70.04 18.7 70.12 18.21 70.12 17.64C70.12 17.07 70.04 16.58 69.88 16.16C69.7484 15.7769 69.5087 15.44 69.19 15.19C68.865 14.9551 68.4708 14.8354 68.07 14.85C67.61 14.85 67.23 14.97 66.92 15.2C66.62 15.44 66.39 15.77 66.23 16.2C66.08 16.61 66 17.1 66 17.64C66 18.18 66.08 18.67 66.23 19.1C66.39 19.52 66.63 19.86 66.93 20.1C67.24 20.34 67.63 20.47 68.07 20.47Z" fill="#1B1B1F"/>
|
||||||
|
<path d="M60.09 22V13.27H62.14V22H60.1H60.09ZM61.12 12.03C60.8 12.03 60.52 11.93 60.28 11.71C60.1684 11.6111 60.0795 11.4894 60.0191 11.3531C59.9587 11.2168 59.9283 11.0691 59.93 10.92C59.93 10.61 60.05 10.35 60.28 10.13C60.52 9.91 60.8 9.8 61.12 9.8C61.45 9.8 61.73 9.91 61.96 10.13C62.2 10.35 62.32 10.61 62.32 10.92C62.32 11.22 62.2 11.49 61.96 11.71C61.73 11.93 61.46 12.03 61.12 12.03Z" fill="#1B1B1F"/>
|
||||||
|
<path d="M54.66 22.17C53.9015 22.2156 53.1466 22.0346 52.4913 21.65C51.836 21.2653 51.3099 20.6945 50.98 20.01C50.6351 19.279 50.464 18.4781 50.48 17.67C50.48 16.78 50.65 16 50.99 15.32C51.33 14.64 51.81 14.12 52.43 13.73C53.102 13.3359 53.8712 13.1384 54.65 13.16C55.35 13.16 55.98 13.29 56.53 13.56C57.0617 13.8031 57.5168 14.1868 57.8464 14.6697C58.1759 15.1526 58.3674 15.7163 58.4 16.3H56.43C56.364 15.895 56.1673 15.5228 55.87 15.24C55.57 14.96 55.17 14.82 54.67 14.82C54.26 14.82 53.89 14.93 53.57 15.16C53.25 15.38 53 15.7 52.83 16.12C52.65 16.55 52.56 17.05 52.56 17.64C52.56 18.24 52.66 18.74 52.83 19.17C53 19.59 53.24 19.92 53.56 20.15C53.88 20.38 54.25 20.49 54.68 20.49C54.98 20.49 55.25 20.44 55.49 20.32C55.73 20.21 55.94 20.04 56.09 19.82C56.26 19.6 56.37 19.33 56.43 19.02H58.4C58.3725 19.6024 58.1878 20.1664 57.8656 20.6524C57.5434 21.1383 57.0957 21.5279 56.57 21.78C55.9746 22.053 55.3248 22.1864 54.67 22.17H54.66Z" fill="#1B1B1F"/>
|
||||||
|
<path d="M46.68 18.33V13.27H48.74V22H46.74V20.45H46.65C46.45 20.94 46.13 21.34 45.68 21.65C45.23 21.95 44.68 22.11 44.03 22.11C43.5054 22.1412 42.9835 22.0151 42.531 21.7479C42.0785 21.4806 41.716 21.0844 41.49 20.61C41.2299 20.0535 41.1033 19.444 41.12 18.83V13.27H43.18V18.51C43.18 19.06 43.33 19.51 43.63 19.83C43.93 20.16 44.33 20.32 44.83 20.32C45.1442 20.3154 45.4523 20.2325 45.7265 20.0789C46.0006 19.9252 46.2321 19.7056 46.4 19.44C46.59 19.14 46.68 18.77 46.68 18.33Z" fill="#1B1B1F"/>
|
||||||
|
<path d="M32.15 22V10.36H34.25V20.23H39.38V22H32.15Z" fill="#1B1B1F"/>
|
||||||
|
<path d="M18 16C18 14.9391 17.5786 13.9217 16.8284 13.1716C16.0783 12.4214 15.0609 12 14 12C12.9391 12 11.9217 12.4214 11.1716 13.1716C10.4214 13.9217 10 14.9391 10 16C10 18.1217 10.8429 20.1566 12.3431 21.6569C13.8434 23.1571 15.8783 24 18 24C20.1217 24 22.1566 23.1571 23.6569 21.6569C25.1571 20.1566 26 18.1217 26 16C26 12.45 24.45 9.25 22 7.06" stroke="#1B1B1F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M14 16C14 17.0609 14.4214 18.0783 15.1716 18.8284C15.9217 19.5786 16.9391 20 18 20C19.0609 20 20.0783 19.5786 20.8284 18.8284C21.5786 18.0783 22 17.0609 22 16C22 13.8783 21.1571 11.8434 19.6569 10.3431C18.1566 8.84285 16.1217 8 14 8C11.8783 8 9.84344 8.84285 8.34315 10.3431C6.84285 11.8434 6 13.8783 6 16C6 19.58 7.57 22.8 10.06 25" stroke="#F56565" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M92 18C93.1046 18 94 17.1046 94 16C94 14.8954 93.1046 14 92 14C90.8954 14 90 14.8954 90 16C90 17.1046 90.8954 18 92 18Z" fill="#DDDDDD"/>
|
||||||
|
<g clip-path="url(#clip1_1_2)">
|
||||||
|
<path d="M108.193 23.0349C107.283 22.2089 107.018 20.4736 107.397 19.2163C108.054 20.009 108.965 20.2601 109.908 20.4018C111.365 20.6205 112.795 20.5387 114.148 19.8777C114.303 19.8021 114.446 19.7014 114.615 19.5995C114.742 19.9652 114.775 20.3344 114.73 20.7102C114.623 21.6254 114.164 22.3323 113.434 22.8682C113.143 23.0825 112.834 23.2742 112.533 23.4762C111.607 24.0974 111.357 24.8258 111.705 25.8852C111.713 25.9112 111.72 25.937 111.739 26C111.266 25.7899 110.921 25.4841 110.658 25.0821C110.38 24.6578 110.248 24.1884 110.241 23.6805C110.238 23.4334 110.238 23.184 110.204 22.9404C110.123 22.3463 109.842 22.0803 109.313 22.065C108.77 22.0493 108.34 22.3826 108.226 22.9076C108.218 22.9478 108.205 22.9876 108.192 23.0344L108.193 23.0349Z" fill="#17191E"/>
|
||||||
|
<path d="M103 19.0068C103 19.0068 105.694 17.7035 108.396 17.7035L110.433 11.4431C110.51 11.1403 110.732 10.9346 110.984 10.9346C111.235 10.9346 111.458 11.1403 111.534 11.4431L113.571 17.7035C116.771 17.7035 118.968 19.0068 118.968 19.0068C118.968 19.0068 114.391 6.6266 114.382 6.60176C114.251 6.23574 114.029 6 113.73 6H108.238C107.939 6 107.726 6.23574 107.586 6.60176C107.576 6.62614 103 19.0068 103 19.0068Z" fill="#17191E"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_1_2">
|
||||||
|
<rect width="128" height="32" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip1_1_2">
|
||||||
|
<rect width="16" height="20" fill="white" transform="translate(103 6)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.6 KiB |
@@ -27,7 +27,7 @@ import iconNode from '../iconNodes/${iconName}.node.json'
|
|||||||
import metaData from '../../../../icons/${iconName}.json'
|
import metaData from '../../../../icons/${iconName}.json'
|
||||||
import releaseData from '../releaseMetadata/${iconName}.json'
|
import releaseData from '../releaseMetadata/${iconName}.json'
|
||||||
|
|
||||||
const { tags, categories, contributors, aliases } = metaData
|
const { tags, categories, contributors, aliases, deprecated, deprecationReason, toBeRemovedInVersion } = metaData
|
||||||
|
|
||||||
const iconDetails = {
|
const iconDetails = {
|
||||||
name: '${iconName}',
|
name: '${iconName}',
|
||||||
@@ -36,6 +36,9 @@ const iconDetails = {
|
|||||||
tags,
|
tags,
|
||||||
categories,
|
categories,
|
||||||
aliases,
|
aliases,
|
||||||
|
deprecated,
|
||||||
|
deprecationReason,
|
||||||
|
toBeRemovedInVersion,
|
||||||
...releaseData,
|
...releaseData,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ const MAX_RELATED_ICONS = 4 * 17; // grid of 4x17 icons, = 68 icons
|
|||||||
const arrayMatches = (a, b) => a.filter((item) => b.includes(item)).length;
|
const arrayMatches = (a, b) => a.filter((item) => b.includes(item)).length;
|
||||||
|
|
||||||
const nameParts = (icon) =>
|
const nameParts = (icon) =>
|
||||||
[
|
[icon.name, ...(icon.aliases?.map((alias) => alias.name) ?? [])]
|
||||||
icon.name,
|
|
||||||
...(icon.aliases?.map((alias) => (typeof alias === 'string' ? alias : alias.name)) ?? []),
|
|
||||||
]
|
|
||||||
.join('-')
|
.join('-')
|
||||||
.split('-')
|
.split('-')
|
||||||
.filter((word) => word.length > 2);
|
.filter((word) => word.length > 2);
|
||||||
|
|||||||
@@ -159,16 +159,14 @@ try {
|
|||||||
const aliases = iconMetaData.aliases ?? [];
|
const aliases = iconMetaData.aliases ?? [];
|
||||||
|
|
||||||
if (aliases.length) {
|
if (aliases.length) {
|
||||||
aliases
|
aliases.forEach((alias) => {
|
||||||
.map((alias) => (typeof alias === 'string' ? alias : alias.name))
|
if (!(alias.name in newReleaseMetaData)) {
|
||||||
.forEach((alias) => {
|
return;
|
||||||
if (!(alias in newReleaseMetaData)) {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
contents.createdRelease =
|
contents.createdRelease =
|
||||||
newReleaseMetaData[alias].createdRelease ?? defaultReleaseMetaData.createdRelease;
|
newReleaseMetaData[alias.name].createdRelease ?? defaultReleaseMetaData.createdRelease;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const output = JSON.stringify(contents, null, 2);
|
const output = JSON.stringify(contents, null, 2);
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ const iconMetaData = await getIconMetaData(path.resolve(scriptDir, '../../icons'
|
|||||||
const iconAliasesRedirectRoutes = Object.entries(iconMetaData)
|
const iconAliasesRedirectRoutes = Object.entries(iconMetaData)
|
||||||
.filter(([, { aliases }]) => aliases?.length)
|
.filter(([, { aliases }]) => aliases?.length)
|
||||||
.map(([iconName, { aliases }]) => {
|
.map(([iconName, { aliases }]) => {
|
||||||
aliases = aliases.map((alias) => (typeof alias === 'object' ? alias.name : alias));
|
const aliasRouteMatches = aliases.map((alias) => alias.name).join('|');
|
||||||
|
|
||||||
const aliasRouteMatches = aliases.join('|');
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
src: `/icons/${aliasRouteMatches}`,
|
src: `/icons/${aliasRouteMatches}`,
|
||||||
|
|||||||
96
eslint.config.ts
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { defineConfig } from "eslint/config";
|
||||||
|
import { type ESLint } from 'eslint';
|
||||||
|
import DEFAULT_ATTRS from './tools/build-icons/render/default-attrs.json' with { type: 'json' };
|
||||||
|
import ImportPlugin from 'eslint-plugin-import';
|
||||||
|
import HtmlPlugin from '@html-eslint/eslint-plugin';
|
||||||
|
import htmlEslintParser from '@html-eslint/parser';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
extends: ['airbnb-base', 'prettier'],
|
||||||
|
plugins: {
|
||||||
|
'import': ImportPlugin,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'no-console': 'off',
|
||||||
|
'no-param-reassign': 'off',
|
||||||
|
'no-shadow': 'off',
|
||||||
|
'no-use-before-define': 'off',
|
||||||
|
'import/no-extraneous-dependencies': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
devDependencies: ['**/*.test.js', '**/*.spec.js', '**/scripts/**'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'import/extensions': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
pattern: {
|
||||||
|
mjs: 'always',
|
||||||
|
json: 'always',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: ['./docs/tsconfig.json', './packages/*/tsconfig.json'],
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ignores: [
|
||||||
|
"dist",
|
||||||
|
"build",
|
||||||
|
"coverage",
|
||||||
|
"lib",
|
||||||
|
"tests",
|
||||||
|
"node_modules",
|
||||||
|
".eslintrc.js",
|
||||||
|
"docs/images",
|
||||||
|
"docs/**/examples/",
|
||||||
|
"packages/lucide-react/dynamicIconImports.js",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['./icons/*.svg'],
|
||||||
|
plugins: {
|
||||||
|
'@html-eslint': HtmlPlugin,
|
||||||
|
},
|
||||||
|
languageOptions: {
|
||||||
|
parser: htmlEslintParser,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'@html-eslint/require-doctype': 'off',
|
||||||
|
'@html-eslint/no-duplicate-attrs': 'error',
|
||||||
|
'@html-eslint/no-inline-styles': 'error',
|
||||||
|
'@html-eslint/require-attrs': [
|
||||||
|
'error',
|
||||||
|
...Object.entries(DEFAULT_ATTRS).map(([attr, value]) => ({
|
||||||
|
tag: 'svg',
|
||||||
|
attr,
|
||||||
|
value: String(value),
|
||||||
|
})),
|
||||||
|
],
|
||||||
|
'@html-eslint/indent': ['error', 2],
|
||||||
|
'@html-eslint/no-multiple-empty-lines': ['error', { max: 0 }],
|
||||||
|
'@html-eslint/no-extra-spacing-attrs': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
enforceBeforeSelfClose: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'@html-eslint/require-closing-tags': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
selfClosing: 'always',
|
||||||
|
allowSelfClosingCustom: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'@html-eslint/element-newline': 'error',
|
||||||
|
'@html-eslint/no-trailing-spaces': 'error',
|
||||||
|
'@html-eslint/quotes': 'error',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]);
|
||||||