Compare commits
194 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e560b8bf3a | ||
|
|
74d6fbc941 | ||
|
|
a2a0821c66 | ||
|
|
b787576f4a | ||
|
|
375ad12aeb | ||
|
|
be55088e75 | ||
|
|
32e93c043f | ||
|
|
920fa7888b | ||
|
|
95766b6682 | ||
|
|
db15bb85c0 | ||
|
|
84c210acf5 | ||
|
|
3c7815c5c0 | ||
|
|
7bb27142c8 | ||
|
|
2811d60184 | ||
|
|
730c24ec55 | ||
|
|
56ebfeb596 | ||
|
|
905d38186c | ||
|
|
1cfb3ff70e | ||
|
|
31cfa79818 | ||
|
|
d1903220db | ||
|
|
ec567e59fc | ||
|
|
1d6b5d6858 | ||
|
|
c368d01d92 | ||
|
|
99427026a3 | ||
|
|
81a1f6e1dc | ||
|
|
7fb4ffc7a7 | ||
|
|
30529bbeb2 | ||
|
|
279ac9ce13 | ||
|
|
2dede9886b | ||
|
|
781fc399a2 | ||
|
|
087b59d55e | ||
|
|
e1f96d8f54 | ||
|
|
7cf38b5b6e | ||
|
|
9c441bd4ff | ||
|
|
507a86a890 | ||
|
|
8d4d9cd6d5 | ||
|
|
341be34b1f | ||
|
|
d52c369b99 | ||
|
|
a7a1973d3f | ||
|
|
b6dfcef41b | ||
|
|
1c5a9dafc1 | ||
|
|
546bb1f391 | ||
|
|
64c1a55e01 | ||
|
|
0e3ac6beb9 | ||
|
|
c7c0e2bead | ||
|
|
85dba80322 | ||
|
|
f8a1a76b83 | ||
|
|
bd50af7afb | ||
|
|
cfabc9f608 | ||
|
|
09f98127c6 | ||
|
|
867c0581af | ||
|
|
987edb14f8 | ||
|
|
9db4dc7e1c | ||
|
|
2150ce75ce | ||
|
|
106e37c3ce | ||
|
|
528ffd6fa5 | ||
|
|
3b92fae633 | ||
|
|
fcf42bf754 | ||
|
|
0b6149c02d | ||
|
|
bc9a8de419 | ||
|
|
26ab33a832 | ||
|
|
ac4c3581c4 | ||
|
|
1ddba6da04 | ||
|
|
8754c9b6fd | ||
|
|
e9febe4fab | ||
|
|
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 |
10
.github/ISSUE_TEMPLATE/01_icon_request.yml
vendored
@@ -7,8 +7,10 @@ body:
|
|||||||
value: |
|
value: |
|
||||||
Before submitting an icon request check if it has already been requested. If there is an open request, please add a 👍.
|
Before submitting an icon request check if it has already been requested. If there is an open request, please add a 👍.
|
||||||
|
|
||||||
**Important note**: No new brand logos are allowed, see https://github.com/lucide-icons/lucide/issues/670.
|
> [!CAUTION]
|
||||||
Existing brand icons will also be phased out. For brand icons, consider using https://simpleicons.org, which offers purpose-built SVGs that are also on a 24×24px grid.
|
> New brand logos are **not** allowed, see our official statement: https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md.
|
||||||
|
>
|
||||||
|
> Existing brand icons are being phased out. Consider using https://simpleicons.org, which offers purpose-built SVGs that are also on a 24×24px grid.
|
||||||
- type: input
|
- type: input
|
||||||
id: name
|
id: name
|
||||||
attributes:
|
attributes:
|
||||||
@@ -41,9 +43,9 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: I have searched existing icons to make sure it does not already exist and I didn't find any.
|
- label: I have searched existing icons to make sure it does not already exist and I didn't find any.
|
||||||
required: true
|
required: true
|
||||||
- label: I am not requesting a brand logo and the art is not protected by copyright.
|
- label: I am not requesting a brand logo and the art is not protected by copyright, see more at https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md
|
||||||
required: true
|
required: true
|
||||||
- label: I am not requesting an icon that includes religious, political imagery or hate symbols.
|
- label: I am not requesting an icon that includes religious, war/violence related, political imagery or hate symbols.
|
||||||
required: true
|
required: true
|
||||||
- label: I have provided appropriate use cases for the icon(s) requested.
|
- label: I have provided appropriate use cases for the icon(s) requested.
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
6
.github/pull_request_template.md
vendored
@@ -25,10 +25,12 @@ Common scopes: icons, docs, studio, site, dev
|
|||||||
|
|
||||||
### Concept <!-- ONLY for new icons -->
|
### Concept <!-- ONLY for new icons -->
|
||||||
<!-- All of these requirements must be fulfilled. -->
|
<!-- All of these requirements must be fulfilled. -->
|
||||||
|
<!-- IMPORTANT! Please read our official statement on brand logos in Lucide: -->
|
||||||
|
<!-- https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md -->
|
||||||
- [ ] I have provided valid use cases for each icon.
|
- [ ] I have provided valid use cases for each icon.
|
||||||
- [ ] I have not added any a brand or logo icon.
|
- [ ] I have [not added any brand or logo icon](https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md).
|
||||||
- [ ] I have not used any hate symbols.
|
- [ ] I have not used any hate symbols.
|
||||||
- [ ] I have not included any religious or political imagery.
|
- [ ] I have not included any religious, war/violence related or political imagery.
|
||||||
|
|
||||||
### Author, credits & license<!-- ONLY for new icons. -->
|
### Author, credits & license<!-- ONLY for new icons. -->
|
||||||
<!-- Please choose one of the following, and put an "x" next to it. -->
|
<!-- Please choose one of the following, and put an "x" next to it. -->
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- 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" "spotify" "behance" "pix" "x.com")
|
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[@]}"
|
||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
if echo "$ISSUE_TITLE" | grep -i "$PHRASE"; then
|
if echo "$ISSUE_TITLE" | grep -i "$PHRASE"; then
|
||||||
gh issue close ${{ github.event.issue.number }} --reason "not planned" --comment "This looks like a duplicate, use the [search](https://github.com/lucide-icons/lucide/issues?q=is%3Aissue+$PHRASE) to find similar issues.
|
gh issue close ${{ github.event.issue.number }} --reason "not planned" --comment "This looks like a duplicate, use the [search](https://github.com/lucide-icons/lucide/issues?q=is%3Aissue+$PHRASE) to find similar issues.
|
||||||
|
|
||||||
Read more about brand guideline rules at [We're not accepting new Brand icons #670](https://github.com/lucide-icons/lucide/issues/670).
|
Read [our official statement about brand logos in Lucide](https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md).
|
||||||
|
|
||||||
Always happy to help on [Discord](https://discord.gg/EH6nSts)."
|
Always happy to help on [Discord](https://discord.gg/EH6nSts)."
|
||||||
gh issue lock ${{ github.event.issue.number }} --reason spam
|
gh issue lock ${{ github.event.issue.number }} --reason spam
|
||||||
|
|||||||
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
|
||||||
|
|||||||
5
.github/workflows/linting-icons.yml
vendored
@@ -14,6 +14,9 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: 'package.json'
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed-files
|
id: changed-files
|
||||||
uses: tj-actions/changed-files@v46
|
uses: tj-actions/changed-files@v46
|
||||||
@@ -21,7 +24,7 @@ jobs:
|
|||||||
files: icons/*
|
files: icons/*
|
||||||
|
|
||||||
- name: Generate annotations
|
- name: Generate annotations
|
||||||
run: node ./scripts/lintFilenames.mjs
|
run: node ./scripts/lintFilenames.mts
|
||||||
env:
|
env:
|
||||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/lucide-astro.yml
vendored
@@ -16,7 +16,7 @@ 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
|
||||||
@@ -32,7 +32,7 @@ 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
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: 'package.json'
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed-files
|
id: changed-files
|
||||||
@@ -24,7 +27,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
- name: Install svgson for code preview (safer and faster than installing all deps)
|
- name: Install svgson for code preview (safer and faster than installing all deps)
|
||||||
run: npm install svgson
|
run: npm install svgson@5.3.1 --force
|
||||||
|
|
||||||
- name: Save PR number
|
- name: Save PR number
|
||||||
run: |
|
run: |
|
||||||
@@ -32,7 +35,7 @@ jobs:
|
|||||||
echo ${{ github.event.number }} > ./pr/NR
|
echo ${{ github.event.number }} > ./pr/NR
|
||||||
|
|
||||||
- name: Generate comment markup
|
- name: Generate comment markup
|
||||||
run: node ./scripts/generateChangedIconsCommentMarkup.mjs >> ./pr/comment-markup.md
|
run: node ./scripts/generateChangedIconsCommentMarkup.mts >> ./pr/comment-markup.md
|
||||||
id: comment-markup
|
id: comment-markup
|
||||||
env:
|
env:
|
||||||
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||||
|
|||||||
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 }}
|
||||||
1
.github/workflows/release.yml
vendored
@@ -48,7 +48,6 @@ jobs:
|
|||||||
'lucide',
|
'lucide',
|
||||||
'lucide-react',
|
'lucide-react',
|
||||||
'lucide-react-native',
|
'lucide-react-native',
|
||||||
'lucide-vue',
|
|
||||||
'lucide-vue-next',
|
'lucide-vue-next',
|
||||||
'lucide-angular',
|
'lucide-angular',
|
||||||
'lucide-preact',
|
'lucide-preact',
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
|||||||
.obsidian
|
.obsidian
|
||||||
.now
|
.now
|
||||||
.idea
|
.idea
|
||||||
|
.env
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
build
|
build
|
||||||
|
|||||||
11
.vscode/svg.code-snippets
vendored
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/Yash-Singh1/vscode-snippets-json-schema/main/schema.json",
|
||||||
"Lucide SVG": {
|
"Lucide SVG": {
|
||||||
"scope": "xml",
|
"scope": "xml",
|
||||||
"description": "Base SVG with Lucide attributes.",
|
"description": "Base SVG with Lucide attributes.",
|
||||||
@@ -51,6 +52,16 @@
|
|||||||
],
|
],
|
||||||
"body": "<circle cx=\"${2:12}\" cy=\"${3:$2}\" r=\"${1|10,2,.5\" fill=\"currentColor|}\" />"
|
"body": "<circle cx=\"${2:12}\" cy=\"${3:$2}\" r=\"${1|10,2,.5\" fill=\"currentColor|}\" />"
|
||||||
},
|
},
|
||||||
|
"Squircle": {
|
||||||
|
"scope": "xml",
|
||||||
|
"description": "SVG `path` with Lucide defaults.",
|
||||||
|
"prefix": [
|
||||||
|
"squircle",
|
||||||
|
"path",
|
||||||
|
"<path"
|
||||||
|
],
|
||||||
|
"body": "<path d=\"M12 3c7.2 0 9 1.8 9 9s-1.8 9-9 9-9-1.8-9-9 1.8-9 9-9\" />"
|
||||||
|
},
|
||||||
"Ellipse": {
|
"Ellipse": {
|
||||||
"scope": "xml",
|
"scope": "xml",
|
||||||
"description": "SVG `ellipse`.",
|
"description": "SVG `ellipse`.",
|
||||||
|
|||||||
71
BRAND_LOGOS_STATEMENT.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Our Official Stance on Including Brand Logos in Lucide
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
Lucide **does not accept** brand logos, and we do not plan to add them in the future.
|
||||||
|
|
||||||
|
This is due to a combination of **legal restrictions**, **design consistency concerns**, and **practical maintenance reasons**.
|
||||||
|
|
||||||
|
If you need brand logos, we recommend [Simple Icons](https://simpleicons.org/), which provides an extensive, legally safer collection of brand marks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Historical Context
|
||||||
|
|
||||||
|
This is not a new debate — other icon sets have gone through the same discussion:
|
||||||
|
|
||||||
|
- **Material Design Icons** [deprecated all brand icons](https://github.com/Templarian/MaterialDesign/issues/6602) because they didn't fit the style, didn't work well in one color, and often looked out of place in a 24×24px grid.
|
||||||
|
- **Feather Icons** [came to the same conclusion](https://github.com/feathericons/feather/issues/763): brand logos have their own style, and forcing them into another inevitably leads to aesthetic compromises.
|
||||||
|
- **Lucide** learned from these examples — we'd rather focus on making a consistent set of non-brand icons that all work together.
|
||||||
|
|
||||||
|
## 2. Legal Considerations
|
||||||
|
|
||||||
|
Most brand logos:
|
||||||
|
- Are **protected by trademark or copyright**.
|
||||||
|
- Have **strict rules** for how they can be used (colors, spacing, proportions, etc.).
|
||||||
|
- **Don't allow modification** — but we'd have to change them to fit Lucide's style.
|
||||||
|
|
||||||
|
This means adding them could:
|
||||||
|
1. Break copyright or trademark law.
|
||||||
|
2. Make both you and the Lucide project legally responsible.
|
||||||
|
3. Force us to review every new request one by one for legal issues — something we simply can't do.
|
||||||
|
|
||||||
|
> **Note:** Simple Icons avoids this by keeping logos exactly as the brand provides them — though even they sometimes face [legal challenges](https://github.com/simple-icons/simple-icons/issues/11236).
|
||||||
|
|
||||||
|
## 3. Design & Consistency
|
||||||
|
|
||||||
|
Lucide is all about **visual consistency**.
|
||||||
|
|
||||||
|
Adding brand logos would:
|
||||||
|
- Break [our own design rules](https://lucide.dev/guide/design/icon-design-guide#icon-design-principles) for shapes, proportions, and stroke.
|
||||||
|
- Mix two fundamentally different categories of graphics (pictograms vs. corporate logos).
|
||||||
|
- Create a library where a subset of icons will always look "out of place".
|
||||||
|
|
||||||
|
If the logos are not in Lucide's style, why include them in Lucide at all? Better to use them from a dedicated brand icon source.
|
||||||
|
|
||||||
|
## 4. Maintenance Burden
|
||||||
|
|
||||||
|
Even with our current **"no brand icon requests"** policy, people still request them regularly.
|
||||||
|
|
||||||
|
Having any brand icons in the set:
|
||||||
|
- Makes people think we might add more in the future.
|
||||||
|
- Leads to repeated requests and the same conversations over and over.
|
||||||
|
- Wastes maintainer time redirecting people to the same explanation.
|
||||||
|
|
||||||
|
Removing them entirely solves this problem.
|
||||||
|
|
||||||
|
## 5. Recommended Alternatives
|
||||||
|
|
||||||
|
If you need brand icons, try:
|
||||||
|
- [Simple Icons](https://simpleicons.org/): offers a huge range of brands, in consistent SVG format, using a 24×24 viewBox, the same as ours.
|
||||||
|
- Official brand asset pages: most major companies provide downloadable SVGs.
|
||||||
|
|
||||||
|
You can use these alongside Lucide without bloating our core library.
|
||||||
|
|
||||||
|
## Final Words
|
||||||
|
|
||||||
|
Lucide is an **icon** set, not a **logo** set.
|
||||||
|
|
||||||
|
Logos belong in dedicated logo resources.
|
||||||
|
|
||||||
|
We're focusing on what Lucide does best: providing a clean, cohesive, and legally safe collection of open-source icons.
|
||||||
@@ -161,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.
|
||||||
@@ -173,8 +197,6 @@ All the icons of lucide in SVG format. These will be used as source for all the
|
|||||||
|
|
||||||
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 uses 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 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.
|
||||||
|
|||||||
26
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
ISC License
|
ISC License
|
||||||
|
|
||||||
Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2022 as part of Feather (MIT). All other copyright (c) for Lucide are held by Lucide Contributors 2022.
|
Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2023 as part of Feather (MIT). All other copyright (c) for Lucide are held by Lucide Contributors 2025.
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -13,3 +13,27 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The MIT License (MIT) (for portions derived from Feather)
|
||||||
|
|
||||||
|
Copyright (c) 2013-2023 Cole Bemis
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ For more info on how to contribute please see the [contribution guidelines](http
|
|||||||
|
|
||||||
Caught a mistake or want to contribute to the documentation? [Edit this page on Github](https://github.com/lucide-icons/lucide/blob/main/README.md)
|
Caught a mistake or want to contribute to the documentation? [Edit this page on Github](https://github.com/lucide-icons/lucide/blob/main/README.md)
|
||||||
|
|
||||||
|
## About brand logos
|
||||||
|
|
||||||
|
Lucide **does not accept** brand logos, and we do not plan to add them in the future. This is due to a combination of **legal restrictions**, **design consistency concerns**, and **practical maintenance reasons**.
|
||||||
|
|
||||||
|
[Click here to read our official statement about brand logos in Lucide.](./BRAND_LOGOS_STATEMENT.md)
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
Join the community on our [Discord](https://discord.gg/EH6nSts) server!
|
Join the community on our [Discord](https://discord.gg/EH6nSts) server!
|
||||||
@@ -84,5 +90,5 @@ Thank you to all the people who contributed to Lucide!
|
|||||||
|
|
||||||
### Awesome backers 🍺
|
### Awesome backers 🍺
|
||||||
|
|
||||||
<a href="https://www.scipress.io?utm_source=lucide"><img src="docs/public/sponsors/scipress.svg" width="180" alt="Scipress sponsor badge" /></a>
|
|
||||||
<a href="https://github.com/pdfme/pdfme"><img src="docs/public/sponsors/pdfme.svg" width="180" alt="pdfme sponsor badge" /></a>
|
<a href="https://github.com/pdfme/pdfme"><img src="docs/public/sponsors/pdfme.svg" width="180" alt="pdfme sponsor badge" /></a>
|
||||||
|
<a href="https://www.fina.money/"><img src="docs/public/sponsors/fina-money.png" width="180" alt="Fina Money sponsor badge" /></a>
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ 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 +40,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 +48,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');
|
||||||
|
|||||||
@@ -17,6 +17,13 @@ export default eventHandler((event) => {
|
|||||||
.replaceAll('\n', '')
|
.replaceAll('\n', '')
|
||||||
.replace(/<svg[^>]*>|<\/svg>/g, '');
|
.replace(/<svg[^>]*>|<\/svg>/g, '');
|
||||||
|
|
||||||
|
const width = parseInt(
|
||||||
|
(newSrc.includes('<svg ') ? newSrc.match(/width="(\d+)"/)?.[1] : null) ?? '24',
|
||||||
|
);
|
||||||
|
const height = parseInt(
|
||||||
|
(newSrc.includes('<svg ') ? newSrc.match(/height="(\d+)"/)?.[1] : null) ?? '24',
|
||||||
|
);
|
||||||
|
|
||||||
const children = [];
|
const children = [];
|
||||||
|
|
||||||
const oldSrc = iconNodes[name]
|
const oldSrc = iconNodes[name]
|
||||||
@@ -27,7 +34,9 @@ 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(Diff, { oldSrc, newSrc, showGrid: true }, children)),
|
renderToString(
|
||||||
|
createElement(Diff, { oldSrc, newSrc, showGrid: true, height, width }, children),
|
||||||
|
),
|
||||||
).toString('utf8');
|
).toString('utf8');
|
||||||
|
|
||||||
defaultContentType(event, 'image/svg+xml');
|
defaultContentType(event, 'image/svg+xml');
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { eventHandler, setResponseHeader, defaultContentType } from 'h3';
|
import { eventHandler, setResponseHeader, defaultContentType } from 'h3';
|
||||||
import { Resvg, initWasm } from '@resvg/resvg-wasm';
|
import { Resvg, initWasm } from '@resvg/resvg-wasm';
|
||||||
|
import iconNodes from '../../../data/iconNodes';
|
||||||
import wasm from './loadWasm';
|
import wasm from './loadWasm';
|
||||||
|
import { createElement } from 'react';
|
||||||
|
import { renderToStaticMarkup } from 'react-dom/server';
|
||||||
|
import createLucideIcon from 'lucide-react/src/createLucideIcon';
|
||||||
|
|
||||||
var initializedResvg = initWasm(wasm);
|
var initializedResvg = initWasm(wasm);
|
||||||
|
|
||||||
@@ -9,27 +13,37 @@ export default eventHandler(async (event) => {
|
|||||||
await initializedResvg;
|
await initializedResvg;
|
||||||
|
|
||||||
const imageSize = 96;
|
const imageSize = 96;
|
||||||
const [iconSizeString, svgData] = params.data.split('/');
|
const name = params.data.split('/').at(-3);
|
||||||
|
const iconSizeString = params.data.split('/').at(-2);
|
||||||
|
const svgData = params.data.split('/').at(-1);
|
||||||
const iconSize = parseInt(iconSizeString, 10);
|
const iconSize = parseInt(iconSizeString, 10);
|
||||||
const data = svgData.slice(0, -4);
|
const data = svgData.slice(0, -4);
|
||||||
|
|
||||||
|
const prevSvg = iconNodes[name]
|
||||||
|
? renderToStaticMarkup(createElement(createLucideIcon(name, iconNodes[name])))
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const src = Buffer.from(data, 'base64').toString('utf8');
|
const src = Buffer.from(data, 'base64').toString('utf8');
|
||||||
const svg = (src.includes('<svg') ? src : `<svg>${src}</svg>`)
|
const svg = (src.includes('<svg') ? src : `<svg>${src}</svg>`)
|
||||||
.replace(/(\r\n|\n|\r)/gm, '')
|
.replace(/(\r\n|\n|\r)/gm, '')
|
||||||
.replace(
|
.replace(
|
||||||
/<svg[^>]*/,
|
/<svg[^>]*>/,
|
||||||
`<svg
|
`<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="${iconSize}"
|
width="${iconSize}"
|
||||||
height="${iconSize}"
|
height="${prevSvg ? iconSize * 2 : iconSize}"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 ${prevSvg ? 48 : 24}"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="#fff"
|
stroke="#fff"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
${prevSvg?.replaceAll('\n', '').replace(/<svg[^>]*>|<\/svg>/g, '')}
|
||||||
|
<g transform="translate(0, ${prevSvg ? 24 : 0})">
|
||||||
`,
|
`,
|
||||||
);
|
)
|
||||||
|
.replace(/<\/svg>/, '</g></svg>');
|
||||||
|
|
||||||
const resvg = new Resvg(svg, { background: '#000' });
|
const resvg = new Resvg(svg, { background: '#000' });
|
||||||
const pngData = resvg.render();
|
const pngData = resvg.render();
|
||||||
@@ -39,7 +53,7 @@ export default eventHandler(async (event) => {
|
|||||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000');
|
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000');
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="${imageSize}" height="${imageSize}" viewBox="0 0 ${imageSize} ${imageSize}">
|
<svg xmlns="http://www.w3.org/2000/svg" width="${imageSize}" height="${prevSvg ? imageSize * 2 : imageSize}" viewBox="0 0 ${imageSize} ${prevSvg ? imageSize * 2 : imageSize}">
|
||||||
<style>
|
<style>
|
||||||
@media screen and (prefers-color-scheme: light) {
|
@media screen and (prefers-color-scheme: light) {
|
||||||
#fallback-background { fill: transparent; }
|
#fallback-background { fill: transparent; }
|
||||||
@@ -52,20 +66,20 @@ export default eventHandler(async (event) => {
|
|||||||
<mask id="mask">
|
<mask id="mask">
|
||||||
<image
|
<image
|
||||||
width="${imageSize}"
|
width="${imageSize}"
|
||||||
height="${imageSize}"
|
height="${prevSvg ? imageSize * 2 : imageSize}"
|
||||||
href="data:image/png;base64,${pngBuffer.toString('base64')}"
|
href="data:image/png;base64,${pngBuffer.toString('base64')}"
|
||||||
image-rendering="pixelated"
|
image-rendering="pixelated"
|
||||||
/>
|
/>
|
||||||
</mask>
|
</mask>
|
||||||
<rect
|
<rect
|
||||||
id="fallback-background"
|
id="fallback-background"
|
||||||
width="${imageSize}"
|
width="100%"
|
||||||
height="${imageSize}" ry="${imageSize / 24}"
|
height="100%" ry="${imageSize / 24}"
|
||||||
fill="#fff"
|
fill="#fff"
|
||||||
/>
|
/>
|
||||||
<rect
|
<rect
|
||||||
width="${imageSize}"
|
width="100%"
|
||||||
height="${imageSize}"
|
height="100%"
|
||||||
fill="#000"
|
fill="#000"
|
||||||
mask="url(#mask)"
|
mask="url(#mask)"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -36,6 +36,13 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
head: [
|
head: [
|
||||||
|
[
|
||||||
|
'link',
|
||||||
|
{
|
||||||
|
rel: 'preconnect',
|
||||||
|
href: 'https://analytics.lucide.dev',
|
||||||
|
},
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'script',
|
'script',
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,14 @@
|
|||||||
"dark": "/company-logos/vercel-dark.svg"
|
"dark": "/company-logos/vercel-dark.svg"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "MDN Web Docs",
|
||||||
|
"url": "https://developer.mozilla.org/",
|
||||||
|
"image": {
|
||||||
|
"light": "/company-logos/mdn-light.svg",
|
||||||
|
"dark": "/company-logos/mdn-dark.svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Supabase",
|
"name": "Supabase",
|
||||||
"url": "https://supabase.com",
|
"url": "https://supabase.com",
|
||||||
@@ -23,6 +31,14 @@
|
|||||||
"dark": "/company-logos/obsidian-dark.svg"
|
"dark": "/company-logos/obsidian-dark.svg"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Nuxt",
|
||||||
|
"url": "https://nuxt.com/",
|
||||||
|
"image": {
|
||||||
|
"light": "/company-logos/nuxt-light.svg",
|
||||||
|
"dark": "/company-logos/nuxt-dark.svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Open Collective",
|
"name": "Open Collective",
|
||||||
"url": "https://opencollective.com",
|
"url": "https://opencollective.com",
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
"source": "https://github.com/swisnl/nuxt-lucide-icons",
|
"source": "https://github.com/swisnl/nuxt-lucide-icons",
|
||||||
"documentation": "https://github.com/swisnl/nuxt-lucide-icons/blob/main/README.md"
|
"documentation": "https://github.com/swisnl/nuxt-lucide-icons/blob/main/README.md"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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",
|
||||||
@@ -95,5 +95,43 @@
|
|||||||
],
|
],
|
||||||
"source": "https://github.com/dinkelspiel/lucide_lustre",
|
"source": "https://github.com/dinkelspiel/lucide_lustre",
|
||||||
"documentation": "https://github.com/dinkelspiel/lucide_lustre/blob/master/README.md"
|
"documentation": "https://github.com/dinkelspiel/lucide_lustre/blob/master/README.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lucide_icons_flutter",
|
||||||
|
"description": "A library providing https://lucide.dev icons to lustre.",
|
||||||
|
"icon": "/framework-logos/flutter.svg",
|
||||||
|
"shields": [
|
||||||
|
{
|
||||||
|
"alt": "Latest Stable Version",
|
||||||
|
"src": "https://img.shields.io/pub/v/lucide_icons_flutter",
|
||||||
|
"href": "https://pub.dev/packages/lucide_icons_flutter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alt": "Total Downloads",
|
||||||
|
"src": "https://img.shields.io/pub/dm/lucide_icons_flutter",
|
||||||
|
"href": "https://pub.dev/packages/lucide_icons_flutter"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": "https://github.com/vqh2602/lucide-flutter-main",
|
||||||
|
"documentation": "https://pub.dev/documentation/lucide_icons_flutter/latest/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lucide-slint",
|
||||||
|
"description": "Implementation of the lucide icon library for Slint.",
|
||||||
|
"icon": "/framework-logos/slint.svg",
|
||||||
|
"shields": [
|
||||||
|
{
|
||||||
|
"alt": "Latest Stable Version",
|
||||||
|
"src": "https://img.shields.io/crates/v/lucide-slint",
|
||||||
|
"href": "https://crates.io/crates/lucide-slint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alt": "Total Downloads",
|
||||||
|
"src": "https://img.shields.io/crates/d/lucide-slint",
|
||||||
|
"href": "https://crates.io/crates/lucide-slint"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": "https://github.com/cnlancehu/lucide-slint",
|
||||||
|
"documentation": "https://github.com/cnlancehu/lucide-slint/blob/main/README.md"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -53,8 +53,8 @@ const Backdrop = ({
|
|||||||
<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"
|
||||||
/>
|
/>
|
||||||
@@ -67,8 +67,8 @@ const Backdrop = ({
|
|||||||
<rect
|
<rect
|
||||||
x="0"
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
width="24"
|
width="100%"
|
||||||
height="24"
|
height="100%"
|
||||||
opacity={0.5}
|
opacity={0.5}
|
||||||
fill={`url(#pattern-${id})`}
|
fill={`url(#pattern-${id})`}
|
||||||
stroke="none"
|
stroke="none"
|
||||||
|
|||||||
@@ -7,15 +7,17 @@ const SvgPreview = React.forwardRef<
|
|||||||
{
|
{
|
||||||
oldSrc: string;
|
oldSrc: string;
|
||||||
newSrc: string;
|
newSrc: string;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
} & React.SVGProps<SVGSVGElement>
|
} & React.SVGProps<SVGSVGElement>
|
||||||
>(({ oldSrc, newSrc, children, ...props }, ref) => {
|
>(({ oldSrc, newSrc, children, height, width, ...props }, ref) => {
|
||||||
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}
|
||||||
@@ -25,6 +27,8 @@ const SvgPreview = React.forwardRef<
|
|||||||
>
|
>
|
||||||
<style>{darkModeCss}</style>
|
<style>{darkModeCss}</style>
|
||||||
<Grid
|
<Grid
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
strokeWidth={0.1}
|
strokeWidth={0.1}
|
||||||
stroke="#777"
|
stroke="#777"
|
||||||
strokeOpacity={0.3}
|
strokeOpacity={0.3}
|
||||||
@@ -37,8 +41,8 @@ const SvgPreview = React.forwardRef<
|
|||||||
<rect
|
<rect
|
||||||
x="0"
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
width="24"
|
width="100%"
|
||||||
height="24"
|
height="100%"
|
||||||
fill="#000"
|
fill="#000"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
/>
|
/>
|
||||||
|
|||||||
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>
|
|
||||||
`,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ 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.mjs';
|
import deprecationReasonTemplate from '../../../../../tools/build-icons/utils/deprecationReasonTemplate.ts';
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -178,6 +178,8 @@ const DiamondIcon = createLucideIcon('Diamond', diamond)
|
|||||||
stroke-width: var(--customize-strokeWidth, 2);
|
stroke-width: var(--customize-strokeWidth, 2);
|
||||||
width: calc(var(--customize-size, 24) * 1px);
|
width: calc(var(--customize-size, 24) * 1px);
|
||||||
height: calc(var(--customize-size, 24) * 1px);
|
height: calc(var(--customize-size, 24) * 1px);
|
||||||
|
max-width: 3rem;
|
||||||
|
max-height: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.absolute-stroke-width .lucide-icon.customizable {
|
html.absolute-stroke-width .lucide-icon.customizable {
|
||||||
|
|||||||
@@ -26,10 +26,9 @@ const iconComponent = computed(() => {
|
|||||||
<component
|
<component
|
||||||
ref="previewIcon"
|
ref="previewIcon"
|
||||||
:is="iconComponent"
|
:is="iconComponent"
|
||||||
:width="size"
|
:size="size"
|
||||||
:height="size"
|
:color="color"
|
||||||
:stroke="color"
|
:strokeWidth="absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth"
|
||||||
:stroke-width="absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth"
|
|
||||||
/>
|
/>
|
||||||
<svg class="icon-grid" :viewBox="`0 0 ${size} ${size}`" fill="none" stroke-width="0.1" xmlns="http://www.w3.org/2000/svg">
|
<svg class="icon-grid" :viewBox="`0 0 ${size} ${size}`" fill="none" stroke-width="0.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g :key="`grid-${i}`" v-for="(_, i) in gridLines">
|
<g :key="`grid-${i}`" v-for="(_, i) in gridLines">
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -110,7 +110,7 @@ const customizingActive = computed(() => {
|
|||||||
name="size"
|
name="size"
|
||||||
v-model="size"
|
v-model="size"
|
||||||
:min="16"
|
:min="16"
|
||||||
:max="48"
|
:max="256"
|
||||||
:step="4"
|
:step="4"
|
||||||
/>
|
/>
|
||||||
</InputField>
|
</InputField>
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { ref, inject, Ref } from 'vue';
|
import { ref, inject, Ref } from 'vue';
|
||||||
|
|
||||||
export const ICON_STYLE_CONTEXT = Symbol('size');
|
export const ICON_STYLE_CONTEXT = Symbol('style');
|
||||||
|
|
||||||
interface IconSizeContext {
|
interface IconSizeContext {
|
||||||
size: Ref<number>;
|
size: Ref<number>;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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`.
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ nextPage:
|
|||||||
|
|
||||||
# What is Lucide?
|
# What is Lucide?
|
||||||
|
|
||||||
Lucide is an open-source icon library that provides 1000+ vector (svg) files for displaying icons and symbols in digital and non-digital projects. The library aims to make it easier for designers and developers to incorporate icons into their projects by providing several official [packages](/packages) to make it easier to use these icons in your project.
|
Lucide is an open-source icon library that provides 1000+ vector (svg) files for displaying icons and symbols in digital and non-digital projects. The library aims to make it easier for designers and developers to incorporate icons into their projects by providing several official [packages](/packages).
|
||||||
|
|
||||||
## Available Icons
|
## Available Icons
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide Angular
|
# Lucide Angular
|
||||||
|
|
||||||
Implementation of the lucide icon library for Angular applications.
|
Angular components and services for Lucide icons that integrate with Angular's dependency injection and component system. Provides both traditional module-based and modern standalone component approaches for maximum flexibility in Angular applications.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as Angular components with full dependency injection support
|
||||||
|
- Configure icons globally through Angular services and providers
|
||||||
|
- Choose from multiple component selectors (lucide-angular, lucide-icon, i-lucide, span-lucide)
|
||||||
|
- Integrate with Angular's reactive forms and data binding
|
||||||
|
- Build scalable applications with tree-shaken icon bundles and lazy loading support
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide Astro
|
# Lucide Astro
|
||||||
|
|
||||||
Implementation of the lucide icon library for Astro applications.
|
Astro components for Lucide icons that work perfectly with Astro's island architecture and multi-framework support. Each icon is an Astro component that renders as an inline SVG, providing excellent performance for static sites and server-side rendering scenarios.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as Astro components with zero JavaScript runtime overhead
|
||||||
|
- Build fast, static websites with optimized SVG icons
|
||||||
|
- Integrate seamlessly with Astro's component islands and partial hydration
|
||||||
|
- Create multi-framework applications where icons work across different UI libraries
|
||||||
|
- Optimize performance with direct icon imports and build-time rendering
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ title: Lucide Preact
|
|||||||
|
|
||||||
# Lucide Preact
|
# Lucide Preact
|
||||||
|
|
||||||
Implementation of the lucide icon library for preact applications.
|
Preact components for Lucide icons that provide React-like development experience with a smaller footprint. Each icon is a lightweight Preact component that renders as an inline SVG, perfect for applications that need React compatibility with minimal bundle size.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as Preact components with React-like syntax and patterns
|
||||||
|
- Build lightweight applications with Preact's smaller runtime
|
||||||
|
- Create fast, responsive interfaces with minimal JavaScript overhead
|
||||||
|
- Maintain React compatibility while reducing bundle size
|
||||||
|
- Integrate with existing Preact applications and component libraries
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide React Native
|
# Lucide React Native
|
||||||
|
|
||||||
Implementation of the lucide icon library for React Native applications
|
React Native components for Lucide icons that work seamlessly across iOS and Android platforms. Built on top of react-native-svg, each icon renders as a native SVG component, providing consistent visual appearance and performance across mobile devices.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as React Native components with platform-consistent rendering
|
||||||
|
- Build cross-platform mobile apps with scalable vector icons
|
||||||
|
- Create responsive interfaces that adapt to different screen densities
|
||||||
|
- Integrate with React Native's styling system and animation libraries
|
||||||
|
- Maintain consistent icon appearance across iOS and Android platforms
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide React
|
# Lucide React
|
||||||
|
|
||||||
Implementation of the lucide icon library for react applications
|
React components for Lucide icons that integrate seamlessly into your React applications. Each icon is a fully-typed React component that renders as an optimized inline SVG, giving you the flexibility of components with the performance of vector graphics.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Import icons as React components with full TypeScript support
|
||||||
|
- Pass props to customize size, color, stroke width, and other SVG attributes
|
||||||
|
- Use icons in JSX with the same ease as any other React component
|
||||||
|
- Benefit from automatic tree-shaking to include only the icons you use
|
||||||
|
- Create dynamic icon components that respond to state and user interactions
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -87,8 +94,7 @@ const App = () => (
|
|||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide Solid
|
# Lucide Solid
|
||||||
|
|
||||||
Implementation of the lucide icon library for solid applications.
|
SolidJS components for Lucide icons that leverage Solid's fine-grained reactivity system. Each icon is a reactive Solid component that renders as an inline SVG, providing exceptional performance through Solid's compile-time optimizations and reactive primitives.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as SolidJS components with fine-grained reactivity
|
||||||
|
- Create highly performant interfaces with Solid's reactive system
|
||||||
|
- Build dynamic icon components that respond to signals and stores
|
||||||
|
- Integrate seamlessly with Solid's JSX and component patterns
|
||||||
|
- Optimize performance with direct icon imports and minimal runtime overhead
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,47 @@
|
|||||||
# Lucide Static
|
# Lucide Static
|
||||||
|
|
||||||
This package include the following lucide implementations:
|
Static assets and utilities for Lucide icons that work without JavaScript frameworks. This package provides multiple formats including individual SVG files, SVG sprites, icon fonts, and Node.js utilities for server-side rendering and static site generation.
|
||||||
|
|
||||||
- All SVG files
|
**What you can accomplish:**
|
||||||
|
- Use individual SVG files as images or CSS background images
|
||||||
|
- Implement icon fonts for CSS-based icon systems
|
||||||
|
- Create SVG sprites for efficient icon loading in static sites
|
||||||
|
- Import SVG strings in Node.js applications and server-side rendering
|
||||||
|
- Build static websites and applications without JavaScript framework dependencies
|
||||||
|
|
||||||
|
This package includes the following implementations of Lucide icons:
|
||||||
|
|
||||||
|
- 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 +62,86 @@ 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 {
|
||||||
#### SVG file as string
|
background-image: url(https://unpkg.com/lucide-static@latest/icons/house.svg);
|
||||||
|
}
|
||||||
You can simply import each SVG by targeting `lucide-static/icons/{icon-name}.svg`.
|
|
||||||
To use SVGs in your project you can for example use a [SVG loader](https://v4.webpack.js.org/loaders/svg-inline-loader/).
|
|
||||||
|
|
||||||
```js
|
|
||||||
import arrowRightIcon from 'lucide-static/icons/arrow-right';
|
|
||||||
|
|
||||||
// return string of an SVG
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### SVG Sprite
|
:::
|
||||||
|
|
||||||
You may need additional loader for this.
|
Make sure you have the correct Webpack loader configured, such as [`url-loader`](https://v4.webpack.js.org/loaders/url-loader/).
|
||||||
|
|
||||||
|
### SVG file as string
|
||||||
|
|
||||||
|
To import an SVG as a string (e.g., for templating):
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```js [Webpack]
|
||||||
|
import arrowRightIcon from 'lucide-static/icons/arrow-right';
|
||||||
|
```
|
||||||
|
|
||||||
|
```js [Vite]
|
||||||
|
import arrowRightIcon from 'lucide-static/icons/arrow-right.svg?raw';
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
You'll need an SVG loader like [`svg-inline-loader`](https://v4.webpack.js.org/loaders/svg-inline-loader/).
|
||||||
|
|
||||||
|
|
||||||
|
### 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 +154,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 +174,79 @@ 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="#triangle-alert"
|
|
||||||
/>
|
|
||||||
</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
|
||||||
|
|
||||||
```js
|
You can also import Lucide icons in Node.js projects:
|
||||||
const { messageSquare } = require('lucide-static/lib');
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```js [ESM]
|
||||||
|
import {MessageSquare} from 'lucide-static';
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note: Each icon name is in camelCase.
|
```js [CommonJs]
|
||||||
|
const {MessageSquare} = require('lucide-static');
|
||||||
|
```
|
||||||
|
|
||||||
#### Example in node.js project
|
:::
|
||||||
|
|
||||||
|
> Note: Each icon name is in PascalCase.
|
||||||
|
|
||||||
|
#### Express app example in Node.js
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const express = require('express');
|
import express from 'express';
|
||||||
const { messageSquare } = require('lucide-static/lib');
|
import {MessageSquare} from 'lucide-static';
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = 3000;
|
const port = 3000;
|
||||||
|
|
||||||
@@ -181,7 +259,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>
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide Svelte
|
# Lucide Svelte
|
||||||
|
|
||||||
Implementation of the lucide icon library for svelte applications.
|
Svelte components for Lucide icons that work seamlessly with both Svelte 4 and Svelte 5. Each icon is a reactive Svelte component that renders as an inline SVG, providing excellent performance and integration with Svelte's reactive system and modern features.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as Svelte components with full reactivity and TypeScript support
|
||||||
|
- Bind icon properties to reactive variables and stores
|
||||||
|
- Create dynamic icon systems that respond to application state
|
||||||
|
- Build type-safe interfaces with comprehensive TypeScript definitions
|
||||||
|
- Optimize bundle sizes with direct icon imports and tree-shaking
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -296,7 +303,7 @@ The example below imports all ES Modules, so exercise caution when using it. Imp
|
|||||||
```svelte [Svelte 5]
|
```svelte [Svelte 5]
|
||||||
<script>
|
<script>
|
||||||
import * as icons from '@lucide/svelte';
|
import * as icons from '@lucide/svelte';
|
||||||
let { name } = $props();
|
let { name, ...props } = $props();
|
||||||
|
|
||||||
const Icon = icons[name];
|
const Icon = icons[name];
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide Vue Next
|
# Lucide Vue Next
|
||||||
|
|
||||||
Implementation of the lucide icon library for Vue 3 applications.
|
Vue 3 components for Lucide icons that leverage the Composition API and modern Vue features. Each icon is a reactive Vue component that renders as an inline SVG, providing excellent performance and developer experience in Vue 3 applications.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as Vue 3 components with full reactivity and TypeScript support
|
||||||
|
- Bind icon properties to reactive data and computed values
|
||||||
|
- Customize icons with props, slots, and Vue's powerful templating system
|
||||||
|
- Integrate seamlessly with Vue 3's Composition API and script setup syntax
|
||||||
|
- Build dynamic interfaces where icons respond to application state changes
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -54,7 +61,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
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide Vue
|
# Lucide Vue
|
||||||
|
|
||||||
Implementation of the lucide icon library for Vue applications.
|
Vue 2 components for Lucide icons that integrate with Vue's Options API and template system. Each icon is a Vue component that renders as an inline SVG, providing familiar Vue development patterns for legacy applications still using Vue 2.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as Vue 2 components with Options API integration
|
||||||
|
- Maintain legacy Vue 2 applications with modern icon components
|
||||||
|
- Integrate with Vue 2's template system and component lifecycle
|
||||||
|
- Build applications using Vue 2's familiar syntax and patterns
|
||||||
|
- Bridge the gap while planning migration to Vue 3
|
||||||
|
|
||||||
::: danger
|
::: danger
|
||||||
This package is deprecated. Vue 2 is EOF See [Announcement](https://v2.vuejs.org/eol/). Migrate to Vue 3.
|
This package is deprecated. Vue 2 is EOF See [Announcement](https://v2.vuejs.org/eol/). Migrate to Vue 3.
|
||||||
@@ -60,7 +67,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
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Lucide
|
# Lucide
|
||||||
|
|
||||||
Implementation of the lucide icon library for web applications.
|
The core Lucide package for vanilla JavaScript applications. This package allows you to easily add scalable vector icons to any web project without framework dependencies. Perfect for static websites, legacy applications, or when you need lightweight icon integration with maximum browser compatibility.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Add icons to HTML using simple data attributes
|
||||||
|
- Dynamically create and insert SVG icons with JavaScript
|
||||||
|
- Customize icon appearance with CSS classes and inline styles
|
||||||
|
- Tree-shake unused icons to keep bundle sizes minimal
|
||||||
|
- Use icons in any JavaScript environment or plain HTML
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -88,7 +95,12 @@ createIcons({
|
|||||||
|
|
||||||
### Additional Options
|
### Additional Options
|
||||||
|
|
||||||
In the `createIcons` function you can pass some extra parameters to adjust the `nameAttr` or add custom attributes like for example classes.
|
In the `createIcons` function you can pass some extra parameters:
|
||||||
|
|
||||||
|
- you can pass `nameAttr` to adjust the attribute name to replace for
|
||||||
|
- you can pass `attrs` to pass additional custom attributes, for instance CSS classes or stroke options.
|
||||||
|
- you can pass `root` to provide a custom DOM element the icons should be replaced in (useful when manipulating small sections of a large DOM or elements in the shadow DOM)
|
||||||
|
- you can pass `inTemplates: true` to also replace icons inside `<template>` tags.
|
||||||
|
|
||||||
Here is a full example:
|
Here is a full example:
|
||||||
|
|
||||||
@@ -101,7 +113,9 @@ createIcons({
|
|||||||
'stroke-width': 1,
|
'stroke-width': 1,
|
||||||
stroke: '#333'
|
stroke: '#333'
|
||||||
},
|
},
|
||||||
nameAttr: 'data-lucide' // attribute for the icon name.
|
nameAttr: 'data-lucide', // attribute for the icon name.
|
||||||
|
root: element, // DOM element to replace icons in.
|
||||||
|
inTemplates: true // Also replace icons inside <template> tags.
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -119,6 +133,34 @@ createIcons({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Custom Document root
|
||||||
|
|
||||||
|
Apply icons in a custom root element, for instance a shadow DOM root.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { createIcons } from 'lucide';
|
||||||
|
|
||||||
|
// Custom root element, for instance a shadow DOM root.
|
||||||
|
const shadowRoot = element.attachShadow({ mode: 'open' });
|
||||||
|
|
||||||
|
createIcons({
|
||||||
|
root: shadowRoot
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Apply icons inside `<template>` tags
|
||||||
|
|
||||||
|
By default icons inside `<template>` tags are not added.
|
||||||
|
By setting the `inTemplates` option to `true`, icons inside templates will also be replaced.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { createIcons } from 'lucide';
|
||||||
|
|
||||||
|
createIcons({
|
||||||
|
inTemplates: true
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### Custom Element binding
|
### Custom Element binding
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|||||||
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 |
@@ -49,6 +49,8 @@
|
|||||||
<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="M219 396.5L208 407.5L203 402.5" stroke="#36EA83" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M241.052 414H233.06V391.455H241.118C243.386 391.455 245.338 391.906 246.975 392.809C248.611 393.704 249.87 394.992 250.751 396.673C251.639 398.353 252.083 400.364 252.083 402.705C252.083 405.054 251.639 407.072 250.751 408.76C249.87 410.448 248.604 411.743 246.953 412.646C245.309 413.549 243.342 414 241.052 414ZM237.827 409.916H240.854C242.263 409.916 243.448 409.666 244.41 409.167C245.379 408.661 246.105 407.879 246.59 406.822C247.081 405.758 247.327 404.386 247.327 402.705C247.327 401.039 247.081 399.678 246.59 398.621C246.105 397.564 245.382 396.786 244.421 396.287C243.459 395.788 242.274 395.539 240.865 395.539H237.827V409.916ZM263.166 414.33C261.456 414.33 259.977 413.967 258.729 413.24C257.489 412.507 256.531 411.486 255.856 410.18C255.181 408.866 254.843 407.344 254.843 405.612C254.843 403.865 255.181 402.338 255.856 401.032C256.531 399.718 257.489 398.698 258.729 397.972C259.977 397.238 261.456 396.871 263.166 396.871C264.876 396.871 266.351 397.238 267.591 397.972C268.839 398.698 269.8 399.718 270.475 401.032C271.151 402.338 271.488 403.865 271.488 405.612C271.488 407.344 271.151 408.866 270.475 410.18C269.8 411.486 268.839 412.507 267.591 413.24C266.351 413.967 264.876 414.33 263.166 414.33ZM263.188 410.697C263.966 410.697 264.615 410.477 265.136 410.037C265.657 409.589 266.05 408.98 266.314 408.21C266.586 407.439 266.721 406.562 266.721 405.578C266.721 404.595 266.586 403.718 266.314 402.947C266.05 402.177 265.657 401.568 265.136 401.12C264.615 400.672 263.966 400.449 263.188 400.449C262.402 400.449 261.742 400.672 261.206 401.12C260.678 401.568 260.278 402.177 260.006 402.947C259.742 403.718 259.61 404.595 259.61 405.578C259.61 406.562 259.742 407.439 260.006 408.21C260.278 408.98 260.678 409.589 261.206 410.037C261.742 410.477 262.402 410.697 263.188 410.697ZM277.279 414.286C276.552 414.286 275.928 414.029 275.407 413.516C274.893 412.995 274.637 412.371 274.637 411.644C274.637 410.925 274.893 410.308 275.407 409.795C275.928 409.281 276.552 409.024 277.279 409.024C277.983 409.024 278.6 409.281 279.128 409.795C279.656 410.308 279.921 410.925 279.921 411.644C279.921 412.129 279.796 412.573 279.546 412.976C279.304 413.373 278.985 413.692 278.589 413.934C278.192 414.169 277.756 414.286 277.279 414.286Z" fill="#36EA83"/>
|
||||||
<g id="embed-lucide-copy" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
<g id="embed-lucide-copy" stroke="#3C3C43" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(120 120), scale(10)">
|
||||||
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
|
<rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
|
||||||
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
|
<path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
docs/public/company-logos/mdn-dark.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 361 104.2">
|
||||||
|
<g style="fill:#0F5DBD"><path d="M40.3 0 11.7 92.1H0L28.5 0h11.8zM50.7 0v92.1H40.3V0h10.4zM101.4 0v92.1H91V0h10.4zM91 0 62.5 92.1H50.8L79.3 0H91zM294 95.4h67v8.8h-67v-8.8z"/></g>
|
||||||
|
<g style="fill:#000"><path d="M198.7 72.8h-17.1v-5.5h3.8V51.5c0-3.7-.7-6.3-2.1-7.9-1.4-1.6-3.3-2.3-5.7-2.3-3.2 0-5.6 1.1-7.2 3.4s-2.4 4.6-2.5 6.9v15.6h6v5.5h-17.1v-5.5h3.8V51.5c0-3.8-.7-6.4-2.1-7.9-1.4-1.5-3.3-2.3-5.6-2.3-3.2 0-5.5 1.1-7.2 3.3-1.6 2.2-2.4 4.5-2.5 6.9v15.8h6.9v5.5h-20.2v-5.5h6V42h-6.1v-5.6h13.4v6.4c1.2-2.1 2.7-3.8 4.7-5.2 2-1.3 4.4-2 7.3-2 2.8 0 5.3.7 7.5 2.1 2.2 1.4 3.7 3.5 4.5 6.4 1.1-2.5 2.7-4.5 4.9-6.1 2.2-1.6 4.8-2.4 7.9-2.4 3.5 0 6.5 1.1 8.9 3.3 2.4 2.2 3.7 5.6 3.7 10.2v18.2h6.1v5.5zM241.2 72.8H228v-7.2c-1.2 2.2-2.8 4.1-4.9 5.6-2.1 1.6-4.8 2.4-8.3 2.4-4.8 0-8.7-1.6-11.6-4.9-2.9-3.2-4.3-7.7-4.3-13.3 0-5 1.3-9.6 4-13.7 2.6-4.1 6.9-6.2 12.8-6.2 5.7 0 9.8 2.2 12.3 6.5V22.3h-8.6v-5.6h15.8v50.6h6v5.5zM227.9 56v-4.4c-.1-3-1.2-5.5-3.2-7.3-2-1.8-4.4-2.8-7.2-2.8-3.6 0-6.3 1.3-8.2 3.9-1.9 2.6-2.8 5.8-2.8 9.6 0 4.1 1 7.3 3 9.5s4.5 3.3 7.4 3.3c3.2 0 5.8-1.3 7.8-3.8 2.1-2.6 3.1-5.3 3.2-8zM286.4 72.8h-19.3v-5.5h6V51.5c0-3.7-.7-6.3-2.2-7.9-1.4-1.6-3.4-2.3-5.7-2.3-3.1 0-5.6 1-7.4 3-1.8 2-2.8 4.4-2.9 7v15.9h6v5.5h-19.3v-5.5h6V42h-6.2v-5.6H255v6.2c2.6-4.6 6.8-6.9 12.7-6.9 3.6 0 6.7 1.1 9.2 3.3 2.5 2.2 3.7 5.6 3.7 10.2v18.2h6v5.4z"/></g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
4
docs/public/company-logos/mdn-light.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 361 104.2">
|
||||||
|
<g style="fill:#A4CEFE"><path d="M40.3 0 11.7 92.1H0L28.5 0h11.8zM50.7 0v92.1H40.3V0h10.4zM101.4 0v92.1H91V0h10.4zM91 0 62.5 92.1H50.8L79.3 0H91zM294 95.4h67v8.8h-67v-8.8z"/></g>
|
||||||
|
<g style="fill:#fff"><path d="M198.7 72.8h-17.1v-5.5h3.8V51.5c0-3.7-.7-6.3-2.1-7.9-1.4-1.6-3.3-2.3-5.7-2.3-3.2 0-5.6 1.1-7.2 3.4s-2.4 4.6-2.5 6.9v15.6h6v5.5h-17.1v-5.5h3.8V51.5c0-3.8-.7-6.4-2.1-7.9-1.4-1.5-3.3-2.3-5.6-2.3-3.2 0-5.5 1.1-7.2 3.3-1.6 2.2-2.4 4.5-2.5 6.9v15.8h6.9v5.5h-20.2v-5.5h6V42h-6.1v-5.6h13.4v6.4c1.2-2.1 2.7-3.8 4.7-5.2 2-1.3 4.4-2 7.3-2 2.8 0 5.3.7 7.5 2.1 2.2 1.4 3.7 3.5 4.5 6.4 1.1-2.5 2.7-4.5 4.9-6.1 2.2-1.6 4.8-2.4 7.9-2.4 3.5 0 6.5 1.1 8.9 3.3 2.4 2.2 3.7 5.6 3.7 10.2v18.2h6.1v5.5zM241.2 72.8H228v-7.2c-1.2 2.2-2.8 4.1-4.9 5.6-2.1 1.6-4.8 2.4-8.3 2.4-4.8 0-8.7-1.6-11.6-4.9-2.9-3.2-4.3-7.7-4.3-13.3 0-5 1.3-9.6 4-13.7 2.6-4.1 6.9-6.2 12.8-6.2 5.7 0 9.8 2.2 12.3 6.5V22.3h-8.6v-5.6h15.8v50.6h6v5.5zM227.9 56v-4.4c-.1-3-1.2-5.5-3.2-7.3-2-1.8-4.4-2.8-7.2-2.8-3.6 0-6.3 1.3-8.2 3.9-1.9 2.6-2.8 5.8-2.8 9.6 0 4.1 1 7.3 3 9.5s4.5 3.3 7.4 3.3c3.2 0 5.8-1.3 7.8-3.8 2.1-2.6 3.1-5.3 3.2-8zM286.4 72.8h-19.3v-5.5h6V51.5c0-3.7-.7-6.3-2.2-7.9-1.4-1.6-3.4-2.3-5.7-2.3-3.1 0-5.6 1-7.4 3-1.8 2-2.8 4.4-2.9 7v15.9h6v5.5h-19.3v-5.5h6V42h-6.2v-5.6H255v6.2c2.6-4.6 6.8-6.9 12.7-6.9 3.6 0 6.7 1.1 9.2 3.3 2.5 2.2 3.7 5.6 3.7 10.2v18.2h6v5.4z"/></g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
4
docs/public/company-logos/nuxt-dark.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="200" fill="none" class="text-highlighted block w-auto h-6" viewBox="0 0 800 200">
|
||||||
|
<path fill="#000" d="M377 200c2.16 0 4-1.791 4-4v-93s5 9 14 24l39 67c1.785 3.74 5.744 6 9 6h27V50h-27c-1.798 0-4 1.494-4 4v94l-18-32-36-61c-1.752-3.109-5.521-5-9-5h-26v150h27ZM726 92h13a6 6 0 0 0 6-6V60h28v32h27v24h-27v43c0 10.5 5.057 15 14 15h13v26h-17c-23.052 0-38-14.929-38-40v-44h-19V92ZM591 92v62c0 14.004-5.258 25.809-13 34-7.742 8.191-18.434 12-33 12-14.566 0-26.258-3.809-34-12-7.611-8.191-13-19.996-13-34V92h16c3.412 0 6.769.622 9 3 2.231 2.246 3 3.565 3 7v52c0 8.059.457 13.037 4 17 3.543 3.831 7.914 5 15 5 7.217 0 10.457-1.169 14-5 3.543-3.963 4-8.941 4-17v-52c0-3.435.769-5.622 3-8 1.96-2.09 4.028-2.04 7-2 .411.005 1.586 0 2 0h16ZM676 144l34-52h-26c-3.277 0-6.188 1.176-8 4l-16 24-15-23c-1.812-2.824-5.723-5-9-5h-25l34 51-37 57h26c3.25 0 6.182-3.213 8-6l18-27 19 28c1.818 2.787 4.75 5 8 5h26l-37-56Z"/>
|
||||||
|
<path fill="#00DC82" d="M168 200h111c3.542 0 6.932-1.244 10-3 3.068-1.756 6.23-3.959 8-7 1.77-3.041 3.002-6.49 3-10.001-.002-3.511-1.227-6.959-3-9.998L222 41c-1.77-3.04-3.933-5.245-7-7s-7.458-3-11-3-6.933 1.245-10 3-5.23 3.96-7 7l-19 33-38-64.002c-1.772-3.04-3.932-6.243-7-7.998s-6.458-2-10-2-6.932.245-10 2c-3.068 1.755-6.228 4.958-8 7.998L2 170c-1.773 3.039-1.998 6.487-2 9.998-.002 3.511.23 6.96 2 10.001 1.77 3.04 4.932 5.244 8 7 3.068 1.756 6.458 3 10 3h70c27.737 0 47.925-12.442 62-36l34-59 18-31 55 94h-73l-18 32Zm-79-32H40l73-126 37 63-24.509 42.725C116.144 163.01 105.488 168 89 168Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
4
docs/public/company-logos/nuxt-light.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="200" fill="none" class="text-highlighted block w-auto h-6" viewBox="0 0 800 200">
|
||||||
|
<path fill="#fff" d="M377 200c2.16 0 4-1.791 4-4v-93s5 9 14 24l39 67c1.785 3.74 5.744 6 9 6h27V50h-27c-1.798 0-4 1.494-4 4v94l-18-32-36-61c-1.752-3.109-5.521-5-9-5h-26v150h27ZM726 92h13a6 6 0 0 0 6-6V60h28v32h27v24h-27v43c0 10.5 5.057 15 14 15h13v26h-17c-23.052 0-38-14.929-38-40v-44h-19V92ZM591 92v62c0 14.004-5.258 25.809-13 34-7.742 8.191-18.434 12-33 12-14.566 0-26.258-3.809-34-12-7.611-8.191-13-19.996-13-34V92h16c3.412 0 6.769.622 9 3 2.231 2.246 3 3.565 3 7v52c0 8.059.457 13.037 4 17 3.543 3.831 7.914 5 15 5 7.217 0 10.457-1.169 14-5 3.543-3.963 4-8.941 4-17v-52c0-3.435.769-5.622 3-8 1.96-2.09 4.028-2.04 7-2 .411.005 1.586 0 2 0h16ZM676 144l34-52h-26c-3.277 0-6.188 1.176-8 4l-16 24-15-23c-1.812-2.824-5.723-5-9-5h-25l34 51-37 57h26c3.25 0 6.182-3.213 8-6l18-27 19 28c1.818 2.787 4.75 5 8 5h26l-37-56Z"/>
|
||||||
|
<path fill="#00DC82" d="M168 200h111c3.542 0 6.932-1.244 10-3 3.068-1.756 6.23-3.959 8-7 1.77-3.041 3.002-6.49 3-10.001-.002-3.511-1.227-6.959-3-9.998L222 41c-1.77-3.04-3.933-5.245-7-7s-7.458-3-11-3-6.933 1.245-10 3-5.23 3.96-7 7l-19 33-38-64.002c-1.772-3.04-3.932-6.243-7-7.998s-6.458-2-10-2-6.932.245-10 2c-3.068 1.755-6.228 4.958-8 7.998L2 170c-1.773 3.039-1.998 6.487-2 9.998-.002 3.511.23 6.96 2 10.001 1.77 3.04 4.932 5.244 8 7 3.068 1.756 6.458 3 10 3h70c27.737 0 47.925-12.442 62-36l34-59 18-31 55 94h-73l-18 32Zm-79-32H40l73-126 37 63-24.509 42.725C116.144 163.01 105.488 168 89 168Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
7
docs/public/framework-logos/slint.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<svg width="35" height="35" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs />
|
||||||
|
<path fill="#2379f4" stroke="none"
|
||||||
|
d="M 10.65 32.39 L 27.6 20.64 C 27.6 20.64 28.36 20.2 28.36 19.51 C 28.36 18.59 27.390001 18.29 27.390001 18.29 L 18.06 14.6 C 17.73 14.47 17.27 14.84 17.7 15.3 L 20.79 18.39 C 20.79 18.39 21.65 19.23 21.65 19.79 C 21.65 20.35 21.12 20.84 21.12 20.84 L 9.89 31.7 C 9.49 32.09 10.03 32.79 10.64 32.41 Z" />
|
||||||
|
<path fill="#2379f4" stroke="none"
|
||||||
|
d="M 24.35 2.61 L 7.4 14.35 C 7.4 14.35 6.64 14.789999 6.64 15.48 C 6.64 16.4 7.61 16.7 7.61 16.7 L 16.94 20.39 C 17.27 20.52 17.73 20.15 17.3 19.69 L 14.210001 16.59 C 14.210001 16.59 13.35 15.750001 13.35 15.19 C 13.35 14.630001 13.88 14.14 13.88 14.14 L 25.09 3.32 C 25.500002 2.93 24.96 2.23 24.340002 2.61 Z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 800 B |
BIN
docs/public/sponsors/fina-money.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
@@ -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}`,
|
||||||
|
|||||||
@@ -21,32 +21,29 @@
|
|||||||
"aliases": {
|
"aliases": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"oneOf": [
|
"type": "object",
|
||||||
{
|
"additionalProperties": false,
|
||||||
|
"required": ["name"],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
{
|
"deprecated": {
|
||||||
"type": "object",
|
"const": true
|
||||||
"properties": {
|
},
|
||||||
"name": {
|
"deprecationReason": {
|
||||||
"type": "string"
|
"$ref": "#/$defs/aliasDeprecationReasons"
|
||||||
},
|
},
|
||||||
"deprecated": {
|
"toBeRemovedInVersion": {
|
||||||
"const": true
|
"$ref": "#/$defs/versionNumber",
|
||||||
},
|
"description": "The version this icon will be removed in."
|
||||||
"deprecationReason": {
|
|
||||||
"$ref": "#/$defs/aliasDeprecationReasons"
|
|
||||||
},
|
|
||||||
"toBeRemovedInVersion": {
|
|
||||||
"$ref": "#/$defs/versionNumber",
|
|
||||||
"description": "The version this icon will be removed in."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependentRequired": {
|
|
||||||
"deprecated": ["deprecationReason", "toBeRemovedInVersion"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
},
|
||||||
|
"dependentRequired": {
|
||||||
|
"deprecated": ["deprecationReason", "toBeRemovedInVersion"],
|
||||||
|
"deprecationReason": ["deprecated"],
|
||||||
|
"toBeRemovedInVersion": ["deprecated"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"uniqueItems": true
|
"uniqueItems": true
|
||||||
},
|
},
|
||||||
@@ -130,7 +127,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependentRequired": {
|
"dependentRequired": {
|
||||||
"deprecated": ["deprecationReason", "toBeRemovedInVersion"]
|
"deprecated": ["deprecationReason", "toBeRemovedInVersion"],
|
||||||
|
"deprecationReason": ["deprecated"],
|
||||||
|
"toBeRemovedInVersion": ["deprecated"]
|
||||||
},
|
},
|
||||||
"$defs": {
|
"$defs": {
|
||||||
"iconDeprecationReasons": {
|
"iconDeprecationReasons": {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M3.5 13h6" />
|
|
||||||
<path d="m2 16 4.5-9 4.5 9" />
|
|
||||||
<path d="M18 7v9" />
|
|
||||||
<path d="m14 12 4 4 4-4" />
|
<path d="m14 12 4 4 4-4" />
|
||||||
|
<path d="M18 16V7" />
|
||||||
|
<path d="m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16" />
|
||||||
|
<path d="M3.304 13h6.392" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 349 B |
@@ -9,8 +9,8 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M3.5 13h6" />
|
|
||||||
<path d="m2 16 4.5-9 4.5 9" />
|
|
||||||
<path d="M18 16V7" />
|
|
||||||
<path d="m14 11 4-4 4 4" />
|
<path d="m14 11 4-4 4 4" />
|
||||||
|
<path d="M18 16V7" />
|
||||||
|
<path d="m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16" />
|
||||||
|
<path d="M3.304 13h6.392" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 319 B After Width: | Height: | Size: 349 B |
@@ -4,7 +4,9 @@
|
|||||||
"it-is-not",
|
"it-is-not",
|
||||||
"jguddas",
|
"jguddas",
|
||||||
"danielbayley",
|
"danielbayley",
|
||||||
"ericfennis"
|
"ericfennis",
|
||||||
|
"vichotech",
|
||||||
|
"karsa-mistmere"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"letter",
|
"letter",
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M21 14h-5" />
|
<path d="m15 16 2.536-7.328a1.02 1.02 1 0 1 1.928 0L22 16" />
|
||||||
<path d="M16 16v-3.5a2.5 2.5 0 0 1 5 0V16" />
|
<path d="M15.697 14h5.606" />
|
||||||
<path d="M4.5 13h6" />
|
<path d="m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16" />
|
||||||
<path d="m3 16 4.5-9 4.5 9" />
|
<path d="M3.304 13h6.392" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 390 B |
@@ -19,6 +19,11 @@
|
|||||||
"time"
|
"time"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"alarm-check"
|
{
|
||||||
|
"name": "alarm-check",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
"time"
|
"time"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"alarm-minus"
|
{
|
||||||
|
"name": "alarm-minus",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
"time"
|
"time"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"alarm-plus"
|
{
|
||||||
|
"name": "alarm-plus",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "../icon.schema.json",
|
|
||||||
"contributors": [
|
|
||||||
"colebemis",
|
|
||||||
"ericfennis"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"text",
|
|
||||||
"alignment",
|
|
||||||
"left",
|
|
||||||
"list"
|
|
||||||
],
|
|
||||||
"categories": [
|
|
||||||
"text"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,27 @@
|
|||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"fruit",
|
"fruit",
|
||||||
"food"
|
"food",
|
||||||
|
"healthy",
|
||||||
|
"snack",
|
||||||
|
"nutrition",
|
||||||
|
"fresh",
|
||||||
|
"produce",
|
||||||
|
"grocery",
|
||||||
|
"organic",
|
||||||
|
"harvest",
|
||||||
|
"vitamin",
|
||||||
|
"red",
|
||||||
|
"green",
|
||||||
|
"juicy",
|
||||||
|
"sweet",
|
||||||
|
"tart",
|
||||||
|
"bite",
|
||||||
|
"orchard",
|
||||||
|
"plant",
|
||||||
|
"core",
|
||||||
|
"raw",
|
||||||
|
"diet"
|
||||||
],
|
],
|
||||||
"categories": [
|
"categories": [
|
||||||
"food-beverage"
|
"food-beverage"
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M12 20.94c1.5 0 2.75 1.06 4 1.06 3 0 6-8 6-12.22A4.91 4.91 0 0 0 17 5c-2.22 0-4 1.44-5 2-1-.56-2.78-2-5-2a4.9 4.9 0 0 0-5 4.78C2 14 5 22 8 22c1.25 0 2.5-1.06 4-1.06Z" />
|
<path d="M12 6.528V3a1 1 0 0 1 1-1h0" />
|
||||||
<path d="M10 2c1 .5 2 2 2 5" />
|
<path d="M18.237 21A15 15 0 0 0 22 11a6 6 0 0 0-10-4.472A6 6 0 0 0 2 11a15.1 15.1 0 0 0 3.763 10 3 3 0 0 0 3.648.648 5.5 5.5 0 0 1 5.178 0A3 3 0 0 0 18.237 21" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 423 B After Width: | Height: | Size: 416 B |
@@ -2,7 +2,8 @@
|
|||||||
"$schema": "../icon.schema.json",
|
"$schema": "../icon.schema.json",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"danielbayley",
|
"danielbayley",
|
||||||
"karsa-mistmere"
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"backwards",
|
"backwards",
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M15 5H9" />
|
<path d="M15 11a1 1 0 0 0 1 1h2.939a1 1 0 0 1 .75 1.811l-6.835 6.836a1.207 1.207 0 0 1-1.707 0L4.31 13.81a1 1 0 0 1 .75-1.811H8a1 1 0 0 0 1-1V9a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1z" />
|
||||||
<path d="M15 9v3h4l-7 7-7-7h4V9z" />
|
<path d="M9 4h6" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 411 B |
@@ -3,7 +3,9 @@
|
|||||||
"contributors": [
|
"contributors": [
|
||||||
"Andreto",
|
"Andreto",
|
||||||
"mittalyashu",
|
"mittalyashu",
|
||||||
"danielbayley"
|
"danielbayley",
|
||||||
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"backwards",
|
"backwards",
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M15 6v6h4l-7 7-7-7h4V6h6z" />
|
<path d="M15 11a1 1 0 0 0 1 1h2.939a1 1 0 0 1 .75 1.811l-6.835 6.836a1.207 1.207 0 0 1-1.707 0L4.31 13.81a1 1 0 0 1 .75-1.811H8a1 1 0 0 0 1-1V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 389 B |
@@ -2,7 +2,8 @@
|
|||||||
"$schema": "../icon.schema.json",
|
"$schema": "../icon.schema.json",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"danielbayley",
|
"danielbayley",
|
||||||
"karsa-mistmere"
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"previous",
|
"previous",
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M19 15V9" />
|
<path d="M13 9a1 1 0 0 1-1-1V5.061a1 1 0 0 0-1.811-.75l-6.835 6.836a1.207 1.207 0 0 0 0 1.707l6.835 6.835a1 1 0 0 0 1.811-.75V16a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1z" />
|
||||||
<path d="M15 15h-3v4l-7-7 7-7v4h3v6z" />
|
<path d="M20 9v6" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 275 B After Width: | Height: | Size: 414 B |
@@ -4,7 +4,9 @@
|
|||||||
"Andreto",
|
"Andreto",
|
||||||
"mittalyashu",
|
"mittalyashu",
|
||||||
"ericfennis",
|
"ericfennis",
|
||||||
"danielbayley"
|
"danielbayley",
|
||||||
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"previous",
|
"previous",
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M18 15h-6v4l-7-7 7-7v4h6v6z" />
|
<path d="M13 9a1 1 0 0 1-1-1V5.061a1 1 0 0 0-1.811-.75l-6.835 6.836a1.207 1.207 0 0 0 0 1.707l6.835 6.835a1 1 0 0 0 1.811-.75V16a1 1 0 0 1 1-1h6a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 391 B |
@@ -2,7 +2,8 @@
|
|||||||
"$schema": "../icon.schema.json",
|
"$schema": "../icon.schema.json",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"danielbayley",
|
"danielbayley",
|
||||||
"karsa-mistmere"
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"next",
|
"next",
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M5 9v6" />
|
<path d="M11 9a1 1 0 0 0 1-1V5.061a1 1 0 0 1 1.811-.75l6.836 6.836a1.207 1.207 0 0 1 0 1.707l-6.836 6.835a1 1 0 0 1-1.811-.75V16a1 1 0 0 0-1-1H9a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1z" />
|
||||||
<path d="M9 9h3V5l7 7-7 7v-4H9V9z" />
|
<path d="M4 9v6" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 413 B |
@@ -4,7 +4,9 @@
|
|||||||
"Andreto",
|
"Andreto",
|
||||||
"mittalyashu",
|
"mittalyashu",
|
||||||
"ericfennis",
|
"ericfennis",
|
||||||
"danielbayley"
|
"danielbayley",
|
||||||
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"next",
|
"next",
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M6 9h6V5l7 7-7 7v-4H6V9z" />
|
<path d="M11 9a1 1 0 0 0 1-1V5.061a1 1 0 0 1 1.811-.75l6.836 6.836a1.207 1.207 0 0 1 0 1.707l-6.836 6.835a1 1 0 0 1-1.811-.75V16a1 1 0 0 0-1-1H5a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 248 B After Width: | Height: | Size: 391 B |
@@ -2,7 +2,8 @@
|
|||||||
"$schema": "../icon.schema.json",
|
"$schema": "../icon.schema.json",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"danielbayley",
|
"danielbayley",
|
||||||
"karsa-mistmere"
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"caps lock",
|
"caps lock",
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M9 19h6" />
|
<path d="M9 13a1 1 0 0 0-1-1H5.061a1 1 0 0 1-.75-1.811l6.836-6.835a1.207 1.207 0 0 1 1.707 0l6.835 6.835a1 1 0 0 1-.75 1.811H16a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1z" />
|
||||||
<path d="M9 15v-3H5l7-7 7 7h-4v3H9z" />
|
<path d="M9 20h6" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 273 B After Width: | Height: | Size: 413 B |
@@ -3,7 +3,9 @@
|
|||||||
"contributors": [
|
"contributors": [
|
||||||
"Andreto",
|
"Andreto",
|
||||||
"mittalyashu",
|
"mittalyashu",
|
||||||
"danielbayley"
|
"danielbayley",
|
||||||
|
"karsa-mistmere",
|
||||||
|
"jamiemlaw"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"shift",
|
"shift",
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M9 18v-6H5l7-7 7 7h-4v6H9z" />
|
<path d="M9 13a1 1 0 0 0-1-1H5.061a1 1 0 0 1-.75-1.811l6.836-6.835a1.207 1.207 0 0 1 1.707 0l6.835 6.835a1 1 0 0 1-.75 1.811H16a1 1 0 0 0-1 1v6a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 390 B |
@@ -21,6 +21,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"arrow-down-01"
|
{
|
||||||
|
"name": "arrow-down-01",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"arrow-down-10"
|
{
|
||||||
|
"name": "arrow-down-10",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"arrow-down-az"
|
{
|
||||||
|
"name": "arrow-down-az",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"sort-desc"
|
{
|
||||||
|
"name": "sort-desc",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"arrow-down-za"
|
{
|
||||||
|
"name": "arrow-down-za",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"arrow-up-01"
|
{
|
||||||
|
"name": "arrow-up-01",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"arrow-up-10"
|
{
|
||||||
|
"name": "arrow-up-10",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"arrow-up-az"
|
{
|
||||||
|
"name": "arrow-up-az",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
"arrows"
|
"arrows"
|
||||||
],
|
],
|
||||||
"aliases": [
|
"aliases": [
|
||||||
"sort-asc"
|
{
|
||||||
|
"name": "sort-asc",
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"deprecated": true,
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||