mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-11 13:28:19 +00:00
Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9fdde2d09 | ||
|
|
5c494962e1 | ||
|
|
772c5be034 | ||
|
|
ee3483eb1b | ||
|
|
9182c51962 | ||
|
|
eb035fe370 | ||
|
|
b96e6acd2e | ||
|
|
7b62649c39 | ||
|
|
10aff6cf7b | ||
|
|
cfa8924025 | ||
|
|
713e9b8a09 | ||
|
|
8ab6f80e4f | ||
|
|
a5221c236a | ||
|
|
cdd32b5294 | ||
|
|
54c8d4078d |
+1
-2
@@ -6,6 +6,5 @@ tests
|
||||
node_modules
|
||||
.eslintrc.js
|
||||
docs/images
|
||||
docs/guide/basics/examples
|
||||
docs/guide/advanced/examples
|
||||
docs/**/examples/
|
||||
packages/lucide-react/dynamicIconImports.js
|
||||
|
||||
+8
-5
@@ -42,12 +42,15 @@ module.exports = {
|
||||
'@html-eslint/no-duplicate-attrs': 'error',
|
||||
'@html-eslint/no-inline-styles': 'error',
|
||||
'@html-eslint/require-attrs': [
|
||||
'error',
|
||||
...Object.entries(DEFAULT_ATTRS)
|
||||
.map(([attr, value]) => ({ tag: 'svg', attr, value: String(value) }))
|
||||
'error',
|
||||
...Object.entries(DEFAULT_ATTRS).map(([attr, value]) => ({
|
||||
tag: 'svg',
|
||||
attr,
|
||||
value: String(value),
|
||||
})),
|
||||
],
|
||||
'@html-eslint/indent': ['error', 2],
|
||||
"@html-eslint/no-multiple-empty-lines": ["error", { "max": 0 }],
|
||||
'@html-eslint/no-multiple-empty-lines': ['error', { max: 0 }],
|
||||
'@html-eslint/no-extra-spacing-attrs': [
|
||||
'error',
|
||||
{
|
||||
@@ -64,7 +67,7 @@ module.exports = {
|
||||
'@html-eslint/element-newline': 'error',
|
||||
'@html-eslint/no-trailing-spaces': 'error',
|
||||
'@html-eslint/quotes': 'error',
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: "Build and Test"
|
||||
description: "Builds and test a package"
|
||||
name: 'Build and Test'
|
||||
description: 'Builds and test a package'
|
||||
|
||||
inputs:
|
||||
name:
|
||||
@@ -7,7 +7,7 @@ inputs:
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: "Check icons"
|
||||
description: "Cross-checks icon and category references in JSON descriptors"
|
||||
name: 'Check icons'
|
||||
description: 'Cross-checks icon and category references in JSON descriptors'
|
||||
|
||||
inputs:
|
||||
name:
|
||||
@@ -7,7 +7,7 @@ inputs:
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
|
||||
+48
-48
@@ -1,92 +1,92 @@
|
||||
# For changed dependencies
|
||||
📦 dependencies:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- pnpm-lock.yaml
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- pnpm-lock.yaml
|
||||
|
||||
# For changes in documentation
|
||||
📖 documentation:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- docs/*.md
|
||||
- docs/**/*.md
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- docs/*.md
|
||||
- docs/**/*.md
|
||||
|
||||
# For changes in the site, but not markdown files
|
||||
🌍 site:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'docs/**'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'docs/**'
|
||||
|
||||
# For changes in the metadata
|
||||
🫧 metadata:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'icons/*.json'
|
||||
- categories/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'icons/*.json'
|
||||
- categories/*
|
||||
|
||||
# For changes or added icons
|
||||
🎨 icon:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'icons/*.svg'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'icons/*.svg'
|
||||
|
||||
# For changes in the lucide package
|
||||
🧳 lucide package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide/*'
|
||||
|
||||
# For changes in the lucide React package
|
||||
⚛️ react package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-react/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-react/*'
|
||||
|
||||
# For changes in the lucide React Native package
|
||||
⚛️ react native package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-react-native/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-react-native/*'
|
||||
|
||||
# For changes in the lucide vue packages
|
||||
💎 vue package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-vue/*'
|
||||
- 'packages/lucide-vue-next/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-vue/*'
|
||||
- 'packages/lucide-vue-next/*'
|
||||
|
||||
# For changes in the lucide angular package
|
||||
🅰️ angular package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-angular/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-angular/*'
|
||||
|
||||
# For changes in the lucide preact package
|
||||
⚛️ preact package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-preact/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-preact/*'
|
||||
|
||||
# For changes in the lucide svelte package
|
||||
🧣 svelte package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-svelte/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-svelte/*'
|
||||
|
||||
# For changes in the lucide solid package
|
||||
🪝 solid package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-solid/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-solid/*'
|
||||
|
||||
# For changes in the lucide static package
|
||||
🪨 static package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-static/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-static/*'
|
||||
|
||||
# For changes in the lucide flutter package
|
||||
🏹 flutter package:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-flutter/*'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'packages/lucide-flutter/*'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Close stale issues and PR
|
||||
on:
|
||||
schedule:
|
||||
- cron: "45 1 * * *"
|
||||
- cron: '45 1 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: "Pull Request Labeler"
|
||||
name: 'Pull Request Labeler'
|
||||
on:
|
||||
- pull_request_target
|
||||
- pull_request_target
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
@@ -9,4 +9,4 @@ jobs:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
- uses: actions/labeler@v5
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
- name: Create font in ./lucide-font
|
||||
run: pnpm build:font
|
||||
|
||||
- name: "Upload to Artifacts"
|
||||
- name: 'Upload to Artifacts'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: lucide-font
|
||||
|
||||
@@ -41,17 +41,18 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
package: [
|
||||
'lucide',
|
||||
'lucide-react',
|
||||
'lucide-react-native',
|
||||
'lucide-vue',
|
||||
'lucide-vue-next',
|
||||
'lucide-angular',
|
||||
'lucide-preact',
|
||||
'lucide-solid',
|
||||
'lucide-svelte',
|
||||
]
|
||||
package:
|
||||
[
|
||||
'lucide',
|
||||
'lucide-react',
|
||||
'lucide-react-native',
|
||||
'lucide-vue',
|
||||
'lucide-vue-next',
|
||||
'lucide-angular',
|
||||
'lucide-preact',
|
||||
'lucide-solid',
|
||||
'lucide-svelte',
|
||||
]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
@@ -136,7 +137,7 @@ jobs:
|
||||
- name: Create font in ./lucide-font
|
||||
run: pnpm build:font
|
||||
|
||||
- name: "Upload to Artifacts"
|
||||
- name: 'Upload to Artifacts'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: lucide-font
|
||||
@@ -145,10 +146,7 @@ jobs:
|
||||
post-release:
|
||||
if: github.repository == 'lucide-icons/lucide'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
pre-release,
|
||||
lucide-font,
|
||||
]
|
||||
needs: [pre-release, lucide-font]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
pnpm-lock.yaml
|
||||
|
||||
# docs examples
|
||||
docs/**/examples/
|
||||
|
||||
# lucide-angular
|
||||
packages/lucide-angular/.angular/cache
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -12,4 +12,4 @@
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-9
@@ -1,13 +1,6 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"devs",
|
||||
"preact",
|
||||
"Preact"
|
||||
],
|
||||
"cSpell.words": ["devs", "preact", "Preact"],
|
||||
"eslint.enable": true,
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"svg"
|
||||
],
|
||||
"eslint.validate": ["javascript", "svg"],
|
||||
"svg.preview.background": "transparent"
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -49,7 +49,7 @@
|
||||
"circle",
|
||||
"<circle"
|
||||
],
|
||||
"body": "<circle cx=\"${2:12}\" cy=\"${3:$2}\" r=\"${1|10,2,.5|}\" />"
|
||||
"body": "<circle cx=\"${2:12}\" cy=\"${3:$2}\" r=\"${1|10,2,.5\" fill=\"currentColor|}\" />"
|
||||
},
|
||||
"Ellipse": {
|
||||
"scope": "xml",
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Accessibility",
|
||||
"icon": "accessibility"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Accounts & access",
|
||||
"icon": "user"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Animals",
|
||||
"icon": "dog"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Arrows",
|
||||
"icon": "arrow-left-right"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Brands",
|
||||
"icon": "facebook"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Buildings",
|
||||
"icon": "building"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Charts",
|
||||
"icon": "pie-chart"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Communication",
|
||||
"icon": "message-circle"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Connectivity",
|
||||
"icon": "wifi"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Currency",
|
||||
"icon": "dollar-sign"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Cursors",
|
||||
"icon": "mouse-pointer-2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Design",
|
||||
"icon": "palette"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Devices",
|
||||
"icon": "smartphone"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Emoji",
|
||||
"icon": "smile"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "File icons",
|
||||
"icon": "panels-top-left"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Food & beverage",
|
||||
"icon": "coffee"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Furniture",
|
||||
"icon": "rocking-chair"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Gaming",
|
||||
"icon": "gamepad-2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Home",
|
||||
"icon": "home"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Layout",
|
||||
"icon": "panels-top-left"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Mail",
|
||||
"icon": "mail"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Maps",
|
||||
"icon": "map"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Maths",
|
||||
"icon": "divide"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Medical",
|
||||
"icon": "heart"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Money",
|
||||
"icon": "piggy-bank"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Multimedia",
|
||||
"icon": "play-circle"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Nature",
|
||||
"icon": "sprout"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Navigation",
|
||||
"icon": "compass"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Notifications",
|
||||
"icon": "alert-triangle"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "People",
|
||||
"icon": "person-standing"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Photography",
|
||||
"icon": "camera"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Science",
|
||||
"icon": "flask-conical"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Seasons",
|
||||
"icon": "leaf"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Security",
|
||||
"icon": "shield"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Shapes",
|
||||
"icon": "triangle"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Shopping",
|
||||
"icon": "shopping-bag"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Social",
|
||||
"icon": "thumbs-up"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Sports",
|
||||
"icon": "type"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Sustainability",
|
||||
"icon": "recycle"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Time & calendar",
|
||||
"icon": "calendar"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Tools",
|
||||
"icon": "hammer"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Transportation",
|
||||
"icon": "train-front"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Travel",
|
||||
"icon": "backpack"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Weather",
|
||||
"icon": "cloud-sun"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { eventHandler, setResponseHeader } from 'h3'
|
||||
import iconMetaData from '../../data/iconMetaData'
|
||||
import { eventHandler, setResponseHeader } from 'h3';
|
||||
import iconMetaData from '../../data/iconMetaData';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
setResponseHeader(event, 'Cache-Control', 'public, max-age=86400')
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*')
|
||||
setResponseHeader(event, 'Cache-Control', 'public, max-age=86400');
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*');
|
||||
|
||||
return Object.fromEntries(
|
||||
Object.entries(iconMetaData).map(([name, { categories }]) => [ name, categories ])
|
||||
)
|
||||
})
|
||||
Object.entries(iconMetaData).map(([name, { categories }]) => [name, categories]),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -37,13 +37,13 @@ export default eventHandler((event) => {
|
||||
backdropString,
|
||||
src,
|
||||
color: name in iconNodes ? 'red' : '#777',
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const svg = Buffer.from(
|
||||
// We can't use jsx here, is not supported here by nitro.
|
||||
renderToString(createElement(SvgPreview, { src, showGrid: true }, children))
|
||||
renderToString(createElement(SvgPreview, { src, showGrid: true }, children)),
|
||||
).toString('utf8');
|
||||
|
||||
defaultContentType(event, 'image/svg+xml');
|
||||
|
||||
@@ -28,7 +28,7 @@ export default eventHandler(async (event) => {
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
`
|
||||
`,
|
||||
);
|
||||
|
||||
const resvg = new Resvg(svg, { background: '#000' });
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { eventHandler, setResponseHeader, defaultContentType } from 'h3'
|
||||
import { renderToString } from 'react-dom/server'
|
||||
import { createElement } from 'react'
|
||||
import { eventHandler, setResponseHeader, defaultContentType } from 'h3';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { createElement } from 'react';
|
||||
import SvgPreview from '../../../lib/SvgPreview/index.tsx';
|
||||
import createLucideIcon, { IconNode } from 'lucide-react/src/createLucideIcon'
|
||||
import createLucideIcon, { IconNode } from 'lucide-react/src/createLucideIcon';
|
||||
import { parseSync } from 'svgson';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const { params } = event.context
|
||||
const { params } = event.context;
|
||||
|
||||
const [strokeWidth, svgData] = params.data.split('/');
|
||||
const data = svgData.slice(0, -4);
|
||||
@@ -16,8 +16,8 @@ export default eventHandler((event) => {
|
||||
const Icon = createLucideIcon(
|
||||
'icon',
|
||||
parseSync(src.includes('<svg') ? src : `<svg>${src}</svg>`).children.map(
|
||||
({ name, attributes }) => [name, attributes]
|
||||
) as IconNode
|
||||
({ name, attributes }) => [name, attributes],
|
||||
) as IconNode,
|
||||
);
|
||||
|
||||
const svg = Buffer.from(
|
||||
@@ -33,12 +33,12 @@ export default eventHandler((event) => {
|
||||
@media screen and (prefers-color-scheme: dark) {
|
||||
svg { stroke: #fff; fill: transparent !important; }
|
||||
}
|
||||
</style>`
|
||||
)
|
||||
</style>`,
|
||||
),
|
||||
).toString('utf8');
|
||||
|
||||
defaultContentType(event, 'image/svg+xml')
|
||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000')
|
||||
defaultContentType(event, 'image/svg+xml');
|
||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000');
|
||||
|
||||
return svg
|
||||
})
|
||||
return svg;
|
||||
});
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
import { eventHandler, getQuery, setResponseHeader } from 'h3'
|
||||
import iconNodes from '../../data/iconNodes'
|
||||
import { IconNodeWithKeys } from '../../theme/types'
|
||||
import { eventHandler, getQuery, setResponseHeader } from 'h3';
|
||||
import iconNodes from '../../data/iconNodes';
|
||||
import { IconNodeWithKeys } from '../../theme/types';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const query = getQuery(event)
|
||||
const query = getQuery(event);
|
||||
|
||||
const withUniqueKeys = query.withUniqueKeys === 'true'
|
||||
const withUniqueKeys = query.withUniqueKeys === 'true';
|
||||
|
||||
setResponseHeader(event, 'Cache-Control', 'public, max-age=86400')
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*')
|
||||
setResponseHeader(event, 'Cache-Control', 'public, max-age=86400');
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*');
|
||||
|
||||
if (withUniqueKeys) {
|
||||
return iconNodes
|
||||
return iconNodes;
|
||||
}
|
||||
|
||||
return Object.entries(iconNodes).reduce((acc, [name, iconNode]) => {
|
||||
if (withUniqueKeys) {
|
||||
return [name, iconNode]
|
||||
return [name, iconNode];
|
||||
}
|
||||
|
||||
const newIconNode = (iconNode as IconNodeWithKeys).map(([name, { key, ...attrs}]) => {
|
||||
return [name, attrs]
|
||||
})
|
||||
const newIconNode = (iconNode as IconNodeWithKeys).map(([name, { key, ...attrs }]) => {
|
||||
return [name, attrs];
|
||||
});
|
||||
|
||||
acc[name] = newIconNode
|
||||
acc[name] = newIconNode;
|
||||
|
||||
return acc
|
||||
}, {})
|
||||
})
|
||||
return acc;
|
||||
}, {});
|
||||
});
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import { eventHandler, getQuery, setResponseHeader, createError } from 'h3'
|
||||
import iconNodes from '../../data/iconNodes'
|
||||
import createLucideIcon from 'lucide-react/src/createLucideIcon'
|
||||
import { renderToString } from 'react-dom/server'
|
||||
import { createElement } from 'react'
|
||||
import { eventHandler, getQuery, setResponseHeader, createError } from 'h3';
|
||||
import iconNodes from '../../data/iconNodes';
|
||||
import createLucideIcon from 'lucide-react/src/createLucideIcon';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { createElement } from 'react';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const { params } = event.context
|
||||
const { params } = event.context;
|
||||
|
||||
const iconNode = iconNodes[params.iconName]
|
||||
const iconNode = iconNodes[params.iconName];
|
||||
|
||||
if (iconNode == null) {
|
||||
const error = createError({
|
||||
statusCode: 404,
|
||||
message: `Icon "${params.iconName}" not found`,
|
||||
})
|
||||
});
|
||||
|
||||
return sendError(event, error)
|
||||
return sendError(event, error);
|
||||
}
|
||||
|
||||
const width = getQuery(event).width || undefined
|
||||
const height = getQuery(event).height || undefined
|
||||
const color = getQuery(event).color || undefined
|
||||
const strokeWidth = getQuery(event).strokeWidth || undefined
|
||||
const width = getQuery(event).width || undefined;
|
||||
const height = getQuery(event).height || undefined;
|
||||
const color = getQuery(event).color || undefined;
|
||||
const strokeWidth = getQuery(event).strokeWidth || undefined;
|
||||
|
||||
const LucideIcon = createLucideIcon(params.iconName, iconNode)
|
||||
const LucideIcon = createLucideIcon(params.iconName, iconNode);
|
||||
|
||||
const svg = Buffer.from(
|
||||
renderToString(
|
||||
@@ -32,14 +32,13 @@ export default eventHandler((event) => {
|
||||
height,
|
||||
color: color ? `#${color}` : undefined,
|
||||
strokeWidth,
|
||||
}
|
||||
))
|
||||
}),
|
||||
),
|
||||
).toString('utf8');
|
||||
|
||||
defaultContentType(event, 'image/svg+xml')
|
||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000')
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*')
|
||||
defaultContentType(event, 'image/svg+xml');
|
||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000');
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*');
|
||||
|
||||
return svg
|
||||
|
||||
})
|
||||
return svg;
|
||||
});
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { eventHandler, setResponseHeader } from 'h3'
|
||||
import iconMetaData from '../../data/iconMetaData'
|
||||
import { eventHandler, setResponseHeader } from 'h3';
|
||||
import iconMetaData from '../../data/iconMetaData';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
setResponseHeader(event, 'Cache-Control', 'public, max-age=86400')
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*')
|
||||
setResponseHeader(event, 'Cache-Control', 'public, max-age=86400');
|
||||
setResponseHeader(event, 'Access-Control-Allow-Origin', '*');
|
||||
|
||||
return Object.fromEntries(
|
||||
Object.entries(iconMetaData).map(([name, { tags }]) => [ name, tags ])
|
||||
)
|
||||
})
|
||||
return Object.fromEntries(Object.entries(iconMetaData).map(([name, { tags }]) => [name, tags]));
|
||||
});
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export default eventHandler(() => {
|
||||
return { nitro: 'Is Awesome! asda' }
|
||||
})
|
||||
return { nitro: 'Is Awesome! asda' };
|
||||
});
|
||||
|
||||
+126
-81
@@ -1,10 +1,10 @@
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
import { defineConfig } from 'vitepress'
|
||||
import { fileURLToPath, URL } from 'node:url';
|
||||
import { defineConfig } from 'vitepress';
|
||||
import sidebar from './sidebar';
|
||||
|
||||
const title = "Lucide";
|
||||
const socialTitle = "Lucide Icons";
|
||||
const description = "Beautiful & consistent icon toolkit made by the community."
|
||||
const title = 'Lucide';
|
||||
const socialTitle = 'Lucide Icons';
|
||||
const description = 'Beautiful & consistent icon toolkit made by the community.';
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default defineConfig({
|
||||
@@ -19,86 +19,131 @@ export default defineConfig({
|
||||
{
|
||||
find: /^.*\/VPIconAlignLeft\.vue$/,
|
||||
replacement: fileURLToPath(
|
||||
new URL('./theme/components/overrides/VPIconAlignLeft.vue', import.meta.url)
|
||||
)
|
||||
new URL('./theme/components/overrides/VPIconAlignLeft.vue', import.meta.url),
|
||||
),
|
||||
},
|
||||
{
|
||||
find: /^.*\/VPFooter\.vue$/,
|
||||
replacement: fileURLToPath(
|
||||
new URL('./theme/components/overrides/VPFooter.vue', import.meta.url)
|
||||
)
|
||||
}
|
||||
]
|
||||
new URL('./theme/components/overrides/VPFooter.vue', import.meta.url),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
head: [
|
||||
[ 'script', {
|
||||
src: 'https://analytics.lucide.dev/js/script.js',
|
||||
'data-domain': 'lucide.dev',
|
||||
defer: ''
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:locale",
|
||||
content:"en_US"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:type",
|
||||
content:"website"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:site_name",
|
||||
content: title,
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:title",
|
||||
content: socialTitle,
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:description",
|
||||
content: description
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:url",
|
||||
content:"https://lucide.dev"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:image",
|
||||
content: "https://lucide.dev/og.png"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:image:width",
|
||||
content:"1200"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:image:height",
|
||||
content:"630"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"og:image:type",
|
||||
content:"image/png"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"twitter:card",
|
||||
content:"summary_large_image"
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"twitter:title",
|
||||
content: socialTitle,
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"twitter:description",
|
||||
content: description
|
||||
}],
|
||||
[ 'meta', {
|
||||
property:"twitter:image",
|
||||
content:"https://lucide.dev/og.png"
|
||||
}],
|
||||
[
|
||||
'script',
|
||||
{
|
||||
src: 'https://analytics.lucide.dev/js/script.js',
|
||||
'data-domain': 'lucide.dev',
|
||||
defer: '',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:locale',
|
||||
content: 'en_US',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:type',
|
||||
content: 'website',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:site_name',
|
||||
content: title,
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:title',
|
||||
content: socialTitle,
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:description',
|
||||
content: description,
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:url',
|
||||
content: 'https://lucide.dev',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:image',
|
||||
content: 'https://lucide.dev/og.png',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:image:width',
|
||||
content: '1200',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:image:height',
|
||||
content: '630',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'og:image:type',
|
||||
content: 'image/png',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'twitter:card',
|
||||
content: 'summary_large_image',
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'twitter:title',
|
||||
content: socialTitle,
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'twitter:description',
|
||||
content: description,
|
||||
},
|
||||
],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
property: 'twitter:image',
|
||||
content: 'https://lucide.dev/og.png',
|
||||
},
|
||||
],
|
||||
],
|
||||
themeConfig: {
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
logo: {
|
||||
light: '/logo.light.svg',
|
||||
dark: '/logo.dark.svg'
|
||||
dark: '/logo.dark.svg',
|
||||
},
|
||||
nav: [
|
||||
{ text: 'Icons', link: '/icons/' },
|
||||
@@ -110,21 +155,21 @@ export default defineConfig({
|
||||
sidebar,
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/lucide-icons/lucide' },
|
||||
{ icon: 'discord', link: 'https://discord.gg/EH6nSts' }
|
||||
{ icon: 'discord', link: 'https://discord.gg/EH6nSts' },
|
||||
],
|
||||
footer: {
|
||||
message: 'Released under the ISC License.',
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Lucide Contributors`
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Lucide Contributors`,
|
||||
},
|
||||
editLink: {
|
||||
pattern: 'https://github.com/lucide-icons/lucide/edit/main/docs/:path'
|
||||
pattern: 'https://github.com/lucide-icons/lucide/edit/main/docs/:path',
|
||||
},
|
||||
carbonAds: {
|
||||
code: 'CWYIC53U',
|
||||
placement: 'lucidedev'
|
||||
}
|
||||
placement: 'lucidedev',
|
||||
},
|
||||
},
|
||||
sitemap: {
|
||||
hostname: 'https://lucide.dev/'
|
||||
}
|
||||
})
|
||||
hostname: 'https://lucide.dev/',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,87 +3,171 @@
|
||||
"order": 0,
|
||||
"icon": "js",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide", "href": "https://www.npmjs.com/package/lucide" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide", "href": "https://www.npmjs.com/package/lucide" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide",
|
||||
"href": "https://www.npmjs.com/package/lucide"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide",
|
||||
"href": "https://www.npmjs.com/package/lucide"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-react": {
|
||||
"order": 1,
|
||||
"icon": "react",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-react", "href": "https://www.npmjs.com/package/lucide-react" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-react", "href": "https://www.npmjs.com/package/lucide-react" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-react",
|
||||
"href": "https://www.npmjs.com/package/lucide-react"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-react",
|
||||
"href": "https://www.npmjs.com/package/lucide-react"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-vue": {
|
||||
"order": 2,
|
||||
"icon": "vue",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-vue", "href": "https://www.npmjs.com/package/lucide-vue" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-vue", "href": "https://www.npmjs.com/package/lucide-vue" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-vue",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-vue",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-vue-next": {
|
||||
"order": 3,
|
||||
"icon": "vue-next",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-vue-next", "href": "https://www.npmjs.com/package/lucide-vue-next" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-vue-next", "href": "https://www.npmjs.com/package/lucide-vue-next" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-vue-next",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue-next"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-vue-next",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue-next"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-svelte": {
|
||||
"order": 4,
|
||||
"icon": "svelte",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-svelte", "href": "https://www.npmjs.com/package/lucide-svelte" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-svelte", "href": "https://www.npmjs.com/package/lucide-svelte" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-svelte",
|
||||
"href": "https://www.npmjs.com/package/lucide-svelte"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-svelte",
|
||||
"href": "https://www.npmjs.com/package/lucide-svelte"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-solid": {
|
||||
"order": 4,
|
||||
"icon": "solid",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-solid", "href": "https://www.npmjs.com/package/lucide-solid" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-solid", "href": "https://www.npmjs.com/package/lucide-solid" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-solid",
|
||||
"href": "https://www.npmjs.com/package/lucide-solid"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-solid",
|
||||
"href": "https://www.npmjs.com/package/lucide-solid"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-preact": {
|
||||
"order": 5,
|
||||
"icon": "preact",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-preact", "href": "https://www.npmjs.com/package/lucide-preact" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-preact", "href": "https://www.npmjs.com/package/lucide-preact" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-preact",
|
||||
"href": "https://www.npmjs.com/package/lucide-preact"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-preact",
|
||||
"href": "https://www.npmjs.com/package/lucide-preact"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-react-native": {
|
||||
"order": 6,
|
||||
"icon": "react-native",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-react-native", "href": "https://www.npmjs.com/package/lucide-react-native" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-react-native", "href": "https://www.npmjs.com/package/lucide-react-native" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-react-native",
|
||||
"href": "https://www.npmjs.com/package/lucide-react-native"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-react-native",
|
||||
"href": "https://www.npmjs.com/package/lucide-react-native"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-angular": {
|
||||
"order": 7,
|
||||
"icon": "angular",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-angular", "href": "https://www.npmjs.com/package/lucide-angular" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-angular", "href": "https://www.npmjs.com/package/lucide-angular" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-angular",
|
||||
"href": "https://www.npmjs.com/package/lucide-angular"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-angular",
|
||||
"href": "https://www.npmjs.com/package/lucide-angular"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-static": {
|
||||
"order": 8,
|
||||
"icon": "svg",
|
||||
"shields": [
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/v/lucide-static", "href": "https://www.npmjs.com/package/lucide-static" },
|
||||
{ "alt": "npm", "src": "https://img.shields.io/npm/dw/lucide-static", "href": "https://www.npmjs.com/package/lucide-static" }
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-static",
|
||||
"href": "https://www.npmjs.com/package/lucide-static"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-static",
|
||||
"href": "https://www.npmjs.com/package/lucide-static"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-flutter": {
|
||||
"order": 9,
|
||||
"icon": "flutter",
|
||||
"shields": [
|
||||
{ "alt": "flutter", "src": "https://img.shields.io/pub/v/lucide_icons", "href": "https://img.shields.io/pub/v/lucide_icons" }
|
||||
{
|
||||
"alt": "flutter",
|
||||
"src": "https://img.shields.io/pub/v/lucide_icons",
|
||||
"href": "https://img.shields.io/pub/v/lucide_icons"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,21 +17,62 @@ const Backdrop = ({ src, color = 'red', backdropString }: BackdropProps): JSX.El
|
||||
patternUnits="userSpaceOnUse"
|
||||
patternTransform="rotate(45 50 50)"
|
||||
>
|
||||
<line stroke={color} strokeWidth={0.1} y2={1} />
|
||||
<line stroke={color} strokeWidth={0.1} y2={1} />
|
||||
<line
|
||||
stroke={color}
|
||||
strokeWidth={0.1}
|
||||
y2={1}
|
||||
/>
|
||||
<line
|
||||
stroke={color}
|
||||
strokeWidth={0.1}
|
||||
y2={1}
|
||||
/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<mask id="svg-preview-backdrop-mask-outline" maskUnits="userSpaceOnUse">
|
||||
<g stroke="#fff" dangerouslySetInnerHTML={{ __html: backdropString }} />
|
||||
<g dangerouslySetInnerHTML={{ __html: src }} strokeWidth={2.05} />
|
||||
<mask
|
||||
id="svg-preview-backdrop-mask-outline"
|
||||
maskUnits="userSpaceOnUse"
|
||||
>
|
||||
<g
|
||||
stroke="#fff"
|
||||
dangerouslySetInnerHTML={{ __html: backdropString }}
|
||||
/>
|
||||
<g
|
||||
dangerouslySetInnerHTML={{ __html: src }}
|
||||
strokeWidth={2.05}
|
||||
/>
|
||||
</mask>
|
||||
<mask id="svg-preview-backdrop-mask-fill" maskUnits="userSpaceOnUse">
|
||||
<g stroke="#fff" dangerouslySetInnerHTML={{ __html: backdropString }} />
|
||||
<g dangerouslySetInnerHTML={{ __html: src }} strokeWidth={2.05} />
|
||||
<g strokeWidth={1.75} dangerouslySetInnerHTML={{ __html: backdropString }} />
|
||||
<mask
|
||||
id="svg-preview-backdrop-mask-fill"
|
||||
maskUnits="userSpaceOnUse"
|
||||
>
|
||||
<g
|
||||
stroke="#fff"
|
||||
dangerouslySetInnerHTML={{ __html: backdropString }}
|
||||
/>
|
||||
<g
|
||||
dangerouslySetInnerHTML={{ __html: src }}
|
||||
strokeWidth={2.05}
|
||||
/>
|
||||
<g
|
||||
strokeWidth={1.75}
|
||||
dangerouslySetInnerHTML={{ __html: backdropString }}
|
||||
/>
|
||||
</mask>
|
||||
<g strokeWidth={2.25} stroke="url(#pattern)" mask={'url(#svg-preview-backdrop-mask-outline)'}>
|
||||
<rect x="0" y="0" width="24" height="24" fill="url(#pattern)" opacity={0.5} stroke="none" />
|
||||
<g
|
||||
strokeWidth={2.25}
|
||||
stroke="url(#pattern)"
|
||||
mask={'url(#svg-preview-backdrop-mask-outline)'}
|
||||
>
|
||||
<rect
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="url(#pattern)"
|
||||
opacity={0.5}
|
||||
stroke="none"
|
||||
/>
|
||||
</g>
|
||||
<rect
|
||||
x="0"
|
||||
|
||||
@@ -10,7 +10,11 @@ const Grid = ({
|
||||
strokeWidth: number;
|
||||
radius: number;
|
||||
} & PathProps<'stroke', 'strokeWidth'>) => (
|
||||
<g className="svg-preview-grid-group" strokeLinecap="butt" {...props}>
|
||||
<g
|
||||
className="svg-preview-grid-group"
|
||||
strokeLinecap="butt"
|
||||
{...props}
|
||||
>
|
||||
<rect
|
||||
className="svg-preview-grid-rect"
|
||||
width={24 - props.strokeWidth}
|
||||
@@ -44,15 +48,21 @@ const Shadow = ({
|
||||
paths: Path[];
|
||||
} & PathProps<'stroke' | 'strokeWidth' | 'strokeOpacity', 'd'>) => {
|
||||
const groupedPaths = Object.entries(
|
||||
paths.reduce((groups, val) => {
|
||||
const key = val.c.id;
|
||||
groups[key] = [...(groups[key] || []), val];
|
||||
return groups;
|
||||
}, {} as Record<number, Path[]>)
|
||||
paths.reduce(
|
||||
(groups, val) => {
|
||||
const key = val.c.id;
|
||||
groups[key] = [...(groups[key] || []), val];
|
||||
return groups;
|
||||
},
|
||||
{} as Record<number, Path[]>,
|
||||
),
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<g className="svg-preview-shadow-mask-group" {...props}>
|
||||
<g
|
||||
className="svg-preview-shadow-mask-group"
|
||||
{...props}
|
||||
>
|
||||
{groupedPaths.map(([id, paths]) => (
|
||||
<mask
|
||||
id={`svg-preview-shadow-mask-${id}`}
|
||||
@@ -61,7 +71,15 @@ const Shadow = ({
|
||||
strokeWidth={props.strokeWidth}
|
||||
stroke="#000"
|
||||
>
|
||||
<rect x={0} y={0} width={24} height={24} fill="#fff" stroke="none" rx={radius} />
|
||||
<rect
|
||||
x={0}
|
||||
y={0}
|
||||
width={24}
|
||||
height={24}
|
||||
fill="#fff"
|
||||
stroke="none"
|
||||
rx={radius}
|
||||
/>
|
||||
<path
|
||||
d={paths
|
||||
.flatMap(({ prev, next }) => [
|
||||
@@ -74,9 +92,16 @@ const Shadow = ({
|
||||
</mask>
|
||||
))}
|
||||
</g>
|
||||
<g className="svg-preview-shadow-group" {...props}>
|
||||
<g
|
||||
className="svg-preview-shadow-group"
|
||||
{...props}
|
||||
>
|
||||
{paths.map(({ d, c: { id } }, i) => (
|
||||
<path key={i} mask={`url(#svg-preview-shadow-mask-${id})`} d={d} />
|
||||
<path
|
||||
key={i}
|
||||
mask={`url(#svg-preview-shadow-mask-${id})`}
|
||||
d={d}
|
||||
/>
|
||||
))}
|
||||
<path
|
||||
d={paths
|
||||
@@ -94,9 +119,16 @@ const ColoredPath = ({
|
||||
paths,
|
||||
...props
|
||||
}: { paths: Path[]; colors: string[] } & PathProps<never, 'd' | 'stroke'>) => (
|
||||
<g className="svg-preview-colored-path-group" {...props}>
|
||||
<g
|
||||
className="svg-preview-colored-path-group"
|
||||
{...props}
|
||||
>
|
||||
{paths.map(({ d, c }, i) => (
|
||||
<path key={i} d={d} stroke={colors[(c.name === 'path' ? i : c.id) % colors.length]} />
|
||||
<path
|
||||
key={i}
|
||||
d={d}
|
||||
stroke={colors[(c.name === 'path' ? i : c.id) % colors.length]}
|
||||
/>
|
||||
))}
|
||||
</g>
|
||||
);
|
||||
@@ -138,7 +170,15 @@ const ControlPath = ({
|
||||
key={i}
|
||||
maskUnits="userSpaceOnUse"
|
||||
>
|
||||
<rect x="0" y="0" width="24" height="24" fill="#fff" stroke="none" rx={radius} />
|
||||
<rect
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="#fff"
|
||||
stroke="none"
|
||||
rx={radius}
|
||||
/>
|
||||
<path d={`M${prev.x} ${prev.y}h.01`} />
|
||||
<path d={`M${next.x} ${next.y}h.01`} />
|
||||
</mask>
|
||||
@@ -146,7 +186,10 @@ const ControlPath = ({
|
||||
);
|
||||
})}
|
||||
</g>
|
||||
<g className="svg-preview-control-path-group" {...props}>
|
||||
<g
|
||||
className="svg-preview-control-path-group"
|
||||
{...props}
|
||||
>
|
||||
{controlPaths.map(({ d, showMarker }, i) => (
|
||||
<path
|
||||
key={i}
|
||||
@@ -155,18 +198,33 @@ const ControlPath = ({
|
||||
/>
|
||||
))}
|
||||
</g>
|
||||
<g className="svg-preview-control-path-marker-group" {...props}>
|
||||
<g
|
||||
className="svg-preview-control-path-marker-group"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d={controlPaths
|
||||
.flatMap(({ prev, next, showMarker }) =>
|
||||
showMarker ? [`M${prev.x} ${prev.y}h.01`, `M${next.x} ${next.y}h.01`] : []
|
||||
showMarker ? [`M${prev.x} ${prev.y}h.01`, `M${next.x} ${next.y}h.01`] : [],
|
||||
)
|
||||
.join('')}
|
||||
/>
|
||||
{controlPaths.map(({ d, prev, next, startMarker, endMarker }, i) => (
|
||||
<React.Fragment key={i}>
|
||||
{startMarker && <circle cx={prev.x} cy={prev.y} r={pointSize / 2} />}
|
||||
{endMarker && <circle cx={next.x} cy={next.y} r={pointSize / 2} />}
|
||||
{startMarker && (
|
||||
<circle
|
||||
cx={prev.x}
|
||||
cy={prev.y}
|
||||
r={pointSize / 2}
|
||||
/>
|
||||
)}
|
||||
{endMarker && (
|
||||
<circle
|
||||
cx={next.x}
|
||||
cy={next.y}
|
||||
r={pointSize / 2}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</g>
|
||||
@@ -182,15 +240,16 @@ const Radii = ({
|
||||
any
|
||||
>) => {
|
||||
return (
|
||||
<g className="svg-preview-radii-group" {...props}>
|
||||
<g
|
||||
className="svg-preview-radii-group"
|
||||
{...props}
|
||||
>
|
||||
{paths.map(
|
||||
({ c, prev, next, circle }, i) =>
|
||||
circle && (
|
||||
<React.Fragment key={i}>
|
||||
{c.name !== "circle" && (
|
||||
<path
|
||||
d={`M${prev.x} ${prev.y} ${circle.x} ${circle.y} ${next.x} ${next.y}`}
|
||||
/>
|
||||
{c.name !== 'circle' && (
|
||||
<path d={`M${prev.x} ${prev.y} ${circle.x} ${circle.y} ${next.x} ${next.y}`} />
|
||||
)}
|
||||
<circle
|
||||
cy={circle.y}
|
||||
@@ -200,7 +259,7 @@ const Radii = ({
|
||||
stroke={
|
||||
(Math.round(circle.x * 100) / 100) % 1 !== 0 ||
|
||||
(Math.round(circle.y * 100) / 100) % 1 !== 0
|
||||
? "red"
|
||||
? 'red'
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
@@ -208,11 +267,7 @@ const Radii = ({
|
||||
cy={circle.y}
|
||||
cx={circle.x}
|
||||
r={circle.r}
|
||||
stroke={
|
||||
(Math.round(circle.r * 1000) / 1000) % 1 !== 0
|
||||
? "red"
|
||||
: undefined
|
||||
}
|
||||
stroke={(Math.round(circle.r * 1000) / 1000) % 1 !== 0 ? 'red' : undefined}
|
||||
/>
|
||||
</React.Fragment>
|
||||
),
|
||||
@@ -230,13 +285,28 @@ const Handles = ({
|
||||
>) => {
|
||||
console.log(paths);
|
||||
return (
|
||||
<g className="svg-preview-handles-group" {...props}>
|
||||
<g
|
||||
className="svg-preview-handles-group"
|
||||
{...props}
|
||||
>
|
||||
{paths.map(({ c, prev, next, cp1, cp2 }) => (
|
||||
<>
|
||||
{cp1 && <path d={`M${prev.x} ${prev.y} ${cp1.x} ${cp1.y}`} />}
|
||||
{cp1 && <circle cy={cp1.y} cx={cp1.x} r={0.25} />}
|
||||
{cp1 && (
|
||||
<circle
|
||||
cy={cp1.y}
|
||||
cx={cp1.x}
|
||||
r={0.25}
|
||||
/>
|
||||
)}
|
||||
{cp2 && <path d={`M${next.x} ${next.y} ${cp2.x} ${cp2.y}`} />}
|
||||
{cp2 && <circle cy={cp2.y} cx={cp2.x} r={0.25} />}
|
||||
{cp2 && (
|
||||
<circle
|
||||
cy={cp2.y}
|
||||
cx={cp2.x}
|
||||
r={0.25}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</g>
|
||||
@@ -280,9 +350,27 @@ const SvgPreview = React.forwardRef<
|
||||
{...props}
|
||||
>
|
||||
<style>{darkModeCss}</style>
|
||||
{showGrid && <Grid strokeWidth={0.1} stroke="#777" strokeOpacity={0.3} radius={1} />}
|
||||
<Shadow paths={paths} strokeWidth={4} stroke="#777" radius={1} strokeOpacity={0.15} />
|
||||
<Handles paths={paths} strokeWidth={0.12} stroke="#777" strokeOpacity={0.6} />
|
||||
{showGrid && (
|
||||
<Grid
|
||||
strokeWidth={0.1}
|
||||
stroke="#777"
|
||||
strokeOpacity={0.3}
|
||||
radius={1}
|
||||
/>
|
||||
)}
|
||||
<Shadow
|
||||
paths={paths}
|
||||
strokeWidth={4}
|
||||
stroke="#777"
|
||||
radius={1}
|
||||
strokeOpacity={0.15}
|
||||
/>
|
||||
<Handles
|
||||
paths={paths}
|
||||
strokeWidth={0.12}
|
||||
stroke="#777"
|
||||
strokeOpacity={0.6}
|
||||
/>
|
||||
<ColoredPath
|
||||
paths={paths}
|
||||
colors={[
|
||||
@@ -307,8 +395,19 @@ const SvgPreview = React.forwardRef<
|
||||
stroke="#777"
|
||||
strokeOpacity={0.3}
|
||||
/>
|
||||
<ControlPath radius={1} paths={paths} pointSize={1} stroke="#fff" strokeWidth={0.125} />
|
||||
<Handles paths={paths} strokeWidth={0.12} stroke="#FFF" strokeOpacity={0.3} />
|
||||
<ControlPath
|
||||
radius={1}
|
||||
paths={paths}
|
||||
pointSize={1}
|
||||
stroke="#fff"
|
||||
strokeWidth={0.125}
|
||||
/>
|
||||
<Handles
|
||||
paths={paths}
|
||||
strokeWidth={0.12}
|
||||
stroke="#FFF"
|
||||
strokeOpacity={0.3}
|
||||
/>
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ export type Path = {
|
||||
|
||||
export type PathProps<
|
||||
RequiredProps extends keyof SVGProps<SVGPathElement | SVGRectElement | SVGCircleElement>,
|
||||
NeverProps extends keyof SVGProps<SVGPathElement | SVGRectElement | SVGCircleElement>
|
||||
NeverProps extends keyof SVGProps<SVGPathElement | SVGRectElement | SVGCircleElement>,
|
||||
> = Required<Pick<React.SVGProps<SVGElement & SVGRectElement & SVGCircleElement>, RequiredProps>> &
|
||||
Omit<
|
||||
React.SVGProps<SVGPathElement & SVGRectElement & SVGCircleElement>,
|
||||
|
||||
@@ -51,7 +51,7 @@ export const getCommands = (src: string) =>
|
||||
getNodes(src)
|
||||
.map(convertToPathNode)
|
||||
.flatMap(({ d, name }, idx) =>
|
||||
new SVGPathData(d).toAbs().commands.map((c, cIdx) => ({ ...c, id: idx, idx: cIdx, name }))
|
||||
new SVGPathData(d).toAbs().commands.map((c, cIdx) => ({ ...c, id: idx, idx: cIdx, name })),
|
||||
);
|
||||
|
||||
export const getPaths = (src: string) => {
|
||||
@@ -60,10 +60,10 @@ export const getPaths = (src: string) => {
|
||||
let prev: Point | undefined = undefined;
|
||||
let start: Point | undefined = undefined;
|
||||
const addPath = (
|
||||
c: typeof commands[number],
|
||||
c: (typeof commands)[number],
|
||||
next: Point,
|
||||
d?: string,
|
||||
extras?: { circle?: Path['circle']; cp1?: Path['cp1']; cp2?: Path['cp2'] }
|
||||
extras?: { circle?: Path['circle']; cp1?: Path['cp1']; cp2?: Path['cp2'] },
|
||||
) => {
|
||||
assert(prev);
|
||||
paths.push({
|
||||
@@ -153,7 +153,7 @@ export const getPaths = (src: string) => {
|
||||
{
|
||||
cp1: { x: prev.x - reflectedCp1.x, y: prev.y - reflectedCp1.y },
|
||||
cp2: { x: c.x2, y: c.y2 },
|
||||
}
|
||||
},
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -169,7 +169,7 @@ export const getPaths = (src: string) => {
|
||||
assert(prev);
|
||||
const backTrackCP = (
|
||||
index: number,
|
||||
currentPoint: { x: number; y: number }
|
||||
currentPoint: { x: number; y: number },
|
||||
): { x: number; y: number } => {
|
||||
const previousCommand = commands[index - 1];
|
||||
if (!previousCommand) {
|
||||
@@ -211,7 +211,7 @@ export const getPaths = (src: string) => {
|
||||
{
|
||||
cp1: { x: prevCP.x, y: prevCP.y },
|
||||
cp2: { x: prevCP.x, y: prevCP.y },
|
||||
}
|
||||
},
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -226,13 +226,13 @@ export const getPaths = (src: string) => {
|
||||
c.lArcFlag,
|
||||
c.sweepFlag,
|
||||
c.x,
|
||||
c.y
|
||||
c.y,
|
||||
);
|
||||
addPath(
|
||||
c,
|
||||
c,
|
||||
`M ${prev.x} ${prev.y} A${c.rX} ${c.rY} ${c.xRot} ${c.lArcFlag} ${c.sweepFlag} ${c.x} ${c.y}`,
|
||||
{ circle: c.rX === c.rY ? { ...center, r: c.rX } : undefined }
|
||||
{ circle: c.rX === c.rY ? { ...center, r: c.rX } : undefined },
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -253,7 +253,7 @@ export const arcEllipseCenter = (
|
||||
fa: number,
|
||||
fs: number,
|
||||
x2: number,
|
||||
y2: number
|
||||
y2: number,
|
||||
) => {
|
||||
const phi = (a * Math.PI) / 180;
|
||||
|
||||
@@ -280,7 +280,7 @@ export const arcEllipseCenter = (
|
||||
sign *
|
||||
Math.sqrt(
|
||||
Math.max(rx * rx * ry * ry - rx * rx * y1p * y1p - ry * ry * x1p * x1p, 0) /
|
||||
(rx * rx * y1p * y1p + ry * ry * x1p * x1p)
|
||||
(rx * rx * y1p * y1p + ry * ry * x1p * x1p),
|
||||
);
|
||||
|
||||
const V2 = [(rx * y1p) / ry, (-ry * x1p) / rx];
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import {Category, IconEntity} from "../theme/types";
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { Category, IconEntity } from '../theme/types';
|
||||
|
||||
const directory = path.join(process.cwd(), "../categories");
|
||||
const directory = path.join(process.cwd(), '../categories');
|
||||
|
||||
export function getAllCategoryFiles(): Category[] {
|
||||
const fileNames = fs.readdirSync(directory).filter((file) => path.extname(file) === '.json');
|
||||
|
||||
return fileNames.map((fileName) => {
|
||||
const name = path.basename(fileName, '.json')
|
||||
const fileContent = fs.readFileSync(path.join(directory, fileName), 'utf8')
|
||||
const name = path.basename(fileName, '.json');
|
||||
const fileContent = fs.readFileSync(path.join(directory, fileName), 'utf8');
|
||||
|
||||
const parsedFileContent = JSON.parse(fileContent)
|
||||
const parsedFileContent = JSON.parse(fileContent);
|
||||
|
||||
return {
|
||||
name,
|
||||
title: parsedFileContent.title,
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function mapCategoryIconCount(categories: Category[], icons: { categories: IconEntity['categories'] }[]) {
|
||||
export function mapCategoryIconCount(
|
||||
categories: Category[],
|
||||
icons: { categories: IconEntity['categories'] }[],
|
||||
) {
|
||||
return categories.map((category) => ({
|
||||
...category,
|
||||
iconCount: icons.reduce((acc, curr) => (curr.categories.includes(category.name) ? ++acc : acc), 0)
|
||||
}))
|
||||
iconCount: icons.reduce(
|
||||
(acc, curr) => (curr.categories.includes(category.name) ? ++acc : acc),
|
||||
0,
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
import {
|
||||
bundledLanguages,
|
||||
type ThemeRegistration
|
||||
} from 'shikiji'
|
||||
import {
|
||||
getHighlighter,
|
||||
} from 'shikiji'
|
||||
|
||||
import { bundledLanguages, type ThemeRegistration } from 'shikiji';
|
||||
import { getHighlighter } from 'shikiji';
|
||||
|
||||
type CodeExampleType = {
|
||||
title: string,
|
||||
language: string,
|
||||
code: string,
|
||||
}[]
|
||||
title: string;
|
||||
language: string;
|
||||
code: string;
|
||||
}[];
|
||||
|
||||
const getIconCodes = (): CodeExampleType => {
|
||||
return [
|
||||
{
|
||||
language: 'html',
|
||||
title: 'HTML',
|
||||
code: `<i data-lucide="Name"></i>`
|
||||
code: `<i data-lucide="Name"></i>`,
|
||||
},
|
||||
{
|
||||
language: 'tsx',
|
||||
@@ -109,36 +103,37 @@ import { LucideAngularModule, PascalCase } from 'lucide-angular';
|
||||
|
||||
<div class="icon-Name"></div>
|
||||
`,
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export type ThemeOptions =
|
||||
| ThemeRegistration
|
||||
| { light: ThemeRegistration; dark: ThemeRegistration }
|
||||
| { light: ThemeRegistration; dark: ThemeRegistration };
|
||||
|
||||
const highLightCode = async (code: string, lang: string, active?: boolean) => {
|
||||
const highlighter = await getHighlighter({
|
||||
themes: ['github-light', 'github-dark'],
|
||||
langs: Object.keys(bundledLanguages)
|
||||
})
|
||||
langs: Object.keys(bundledLanguages),
|
||||
});
|
||||
|
||||
const highlightedCode = highlighter.codeToHtml(code, {
|
||||
lang,
|
||||
themes: {
|
||||
light: 'github-light',
|
||||
dark: 'github-dark'
|
||||
},
|
||||
defaultColor: false
|
||||
}).replace('shiki-themes', 'shiki-themes vp-code')
|
||||
const highlightedCode = highlighter
|
||||
.codeToHtml(code, {
|
||||
lang,
|
||||
themes: {
|
||||
light: 'github-light',
|
||||
dark: 'github-dark',
|
||||
},
|
||||
defaultColor: false,
|
||||
})
|
||||
.replace('shiki-themes', 'shiki-themes vp-code');
|
||||
|
||||
return `<div class="language-${lang} ${active ? 'active' : ''}">
|
||||
<button title="Copy Code" class="copy"></button>
|
||||
<span class="lang">${lang}</span>
|
||||
${highlightedCode}
|
||||
</div>`
|
||||
}
|
||||
|
||||
</div>`;
|
||||
};
|
||||
|
||||
export default async function createCodeExamples() {
|
||||
const codes = getIconCodes();
|
||||
@@ -153,7 +148,7 @@ export default async function createCodeExamples() {
|
||||
language: language,
|
||||
code: codeString,
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
return Promise.all(codeExamplePromises);
|
||||
}
|
||||
|
||||
@@ -1,38 +1,42 @@
|
||||
import { promises as fs, constants } from 'fs';
|
||||
import path from 'path';
|
||||
import yaml from 'js-yaml'
|
||||
import yaml from 'js-yaml';
|
||||
import { PackageItem } from '../theme/types';
|
||||
|
||||
const fileExist = (filePath) => fs.access(filePath, constants.F_OK).then(() => true).catch(() => false)
|
||||
const fileExist = (filePath) =>
|
||||
fs
|
||||
.access(filePath, constants.F_OK)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
const fetchPackages = async (): Promise<PackageItem[]> => {
|
||||
const docsDir = path.resolve(process.cwd(), '../packages');
|
||||
const fileNames = await (await fs.readdir(docsDir)).map(filename => ({filename, directory: docsDir}))
|
||||
const fileNames = await (
|
||||
await fs.readdir(docsDir)
|
||||
).map((filename) => ({ filename, directory: docsDir }));
|
||||
|
||||
const packageJsons = await Promise.all(fileNames.map( async ({filename, directory}) => {
|
||||
const filePath = path.resolve(directory, filename)
|
||||
const fileStat = await fs.lstat(filePath);
|
||||
const packageJsons = await Promise.all(
|
||||
fileNames.map(async ({ filename, directory }) => {
|
||||
const filePath = path.resolve(directory, filename);
|
||||
const fileStat = await fs.lstat(filePath);
|
||||
|
||||
if(!fileStat.isDirectory()) return null;
|
||||
if (!fileStat.isDirectory()) return null;
|
||||
|
||||
const jsonFilePath = path.resolve(filePath, 'package.json')
|
||||
if (await fileExist(jsonFilePath)) {
|
||||
return JSON.parse(
|
||||
await fs.readFile(jsonFilePath, 'utf-8')
|
||||
)
|
||||
}
|
||||
const jsonFilePath = path.resolve(filePath, 'package.json');
|
||||
if (await fileExist(jsonFilePath)) {
|
||||
return JSON.parse(await fs.readFile(jsonFilePath, 'utf-8'));
|
||||
}
|
||||
|
||||
const ymlFilePath = path.resolve(filePath, 'pubspec.yaml')
|
||||
if(await fileExist(ymlFilePath)) {
|
||||
return yaml.load(
|
||||
await fs.readFile(ymlFilePath, 'utf-8')
|
||||
);
|
||||
}
|
||||
const ymlFilePath = path.resolve(filePath, 'pubspec.yaml');
|
||||
if (await fileExist(ymlFilePath)) {
|
||||
return yaml.load(await fs.readFile(ymlFilePath, 'utf-8'));
|
||||
}
|
||||
|
||||
return null
|
||||
}))
|
||||
return null;
|
||||
}),
|
||||
);
|
||||
|
||||
return packageJsons
|
||||
}
|
||||
return packageJsons;
|
||||
};
|
||||
|
||||
export default fetchPackages;
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
export type IconContent = [icon: string, src:string];
|
||||
export type IconContent = [icon: string, src: string];
|
||||
|
||||
async function generateZip(icons: IconContent[]) {
|
||||
const JSZip = (await import('jszip')).default
|
||||
const JSZip = (await import('jszip')).default;
|
||||
|
||||
const zip = new JSZip();
|
||||
|
||||
const addingZipPromises = icons.map(([name, src]) =>
|
||||
zip.file(`${name}.svg`, src),
|
||||
);
|
||||
const addingZipPromises = icons.map(([name, src]) => zip.file(`${name}.svg`, src));
|
||||
|
||||
await Promise.all(addingZipPromises)
|
||||
await Promise.all(addingZipPromises);
|
||||
|
||||
return zip.generateAsync({ type: 'blob' });
|
||||
}
|
||||
|
||||
export default generateZip
|
||||
export default generateZip;
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import { createLucideIcon } from "lucide-react/src/lucide-react"
|
||||
import { type LucideProps, type IconNode } from "lucide-react/src/createLucideIcon"
|
||||
import { IconEntity } from "../theme/types"
|
||||
import { createLucideIcon } from 'lucide-react/src/lucide-react';
|
||||
import { type LucideProps, type IconNode } from 'lucide-react/src/createLucideIcon';
|
||||
import { IconEntity } from '../theme/types';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { IconContent } from "./generateZip";
|
||||
import { IconContent } from './generateZip';
|
||||
|
||||
const getFallbackZip = (icons: IconEntity[], params: LucideProps) => {
|
||||
return icons
|
||||
.map<IconContent>((icon) => {
|
||||
const Icon = createLucideIcon(icon.name, icon.iconNode as IconNode)
|
||||
const src = renderToStaticMarkup(<Icon {...params} />)
|
||||
return [icon.name, src]
|
||||
})
|
||||
}
|
||||
return icons.map<IconContent>((icon) => {
|
||||
const Icon = createLucideIcon(icon.name, icon.iconNode as IconNode);
|
||||
const src = renderToStaticMarkup(<Icon {...params} />);
|
||||
return [icon.name, src];
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export default getFallbackZip
|
||||
export default getFallbackZip;
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { IconNodeWithKeys } from "../theme/types";
|
||||
import iconNodes from '../data/iconNodes'
|
||||
import releaseMeta from "../data/releaseMetaData.json";
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { IconNodeWithKeys } from '../theme/types';
|
||||
import iconNodes from '../data/iconNodes';
|
||||
import releaseMeta from '../data/releaseMetaData.json';
|
||||
|
||||
const DATE_OF_FORK = '2020-06-08T16:39:52+0100';
|
||||
|
||||
const directory = path.join(process.cwd(), "../icons");
|
||||
const directory = path.join(process.cwd(), '../icons');
|
||||
|
||||
export interface GetDataOptions {
|
||||
withChildKeys?: boolean
|
||||
withChildKeys?: boolean;
|
||||
}
|
||||
|
||||
export async function getData(name: string) {
|
||||
const jsonPath = path.join(directory, `${name}.json`);
|
||||
const jsonContent = fs.readFileSync(jsonPath, "utf8");
|
||||
const jsonContent = fs.readFileSync(jsonPath, 'utf8');
|
||||
const { tags, categories, contributors } = JSON.parse(jsonContent);
|
||||
|
||||
const iconNode = iconNodes[name]
|
||||
const iconNode = iconNodes[name];
|
||||
|
||||
const releaseData = releaseMeta?.[name] ?? {
|
||||
"createdRelease": {
|
||||
"version": "0.0.0",
|
||||
"date": DATE_OF_FORK
|
||||
createdRelease: {
|
||||
version: '0.0.0',
|
||||
date: DATE_OF_FORK,
|
||||
},
|
||||
"changedRelease": {
|
||||
"version": "0.0.0",
|
||||
"date": DATE_OF_FORK
|
||||
}
|
||||
}
|
||||
changedRelease: {
|
||||
version: '0.0.0',
|
||||
date: DATE_OF_FORK,
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
name,
|
||||
@@ -36,11 +36,11 @@ export async function getData(name: string) {
|
||||
categories,
|
||||
iconNode,
|
||||
contributors,
|
||||
...releaseData
|
||||
...releaseData,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getAllData(): Promise<{ name: string, iconNode: IconNodeWithKeys}[]> {
|
||||
export async function getAllData(): Promise<{ name: string; iconNode: IconNodeWithKeys }[]> {
|
||||
const names = Object.keys(iconNodes);
|
||||
|
||||
return Promise.all(names.map((name) => getData(name)));
|
||||
|
||||
+29
-31
@@ -1,31 +1,31 @@
|
||||
import { DefaultTheme, UserConfig } from "vitepress"
|
||||
import { DefaultTheme, UserConfig } from 'vitepress';
|
||||
|
||||
const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
||||
'guide':[
|
||||
guide: [
|
||||
{
|
||||
text: 'Introduction',
|
||||
items: [
|
||||
{ text: 'What is lucide?', link: '/guide/' },
|
||||
{ text: 'Installation', link: '/guide/installation' },
|
||||
{ text: 'Comparison', link: '/guide/comparison' }
|
||||
]
|
||||
{ text: 'Comparison', link: '/guide/comparison' },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Basics',
|
||||
items: [
|
||||
{
|
||||
text: 'Color',
|
||||
link: '/guide/basics/color'
|
||||
link: '/guide/basics/color',
|
||||
},
|
||||
{
|
||||
text: 'Sizing',
|
||||
link: '/guide/basics/sizing'
|
||||
link: '/guide/basics/sizing',
|
||||
},
|
||||
{
|
||||
text: 'Stroke width',
|
||||
link: '/guide/basics/stroke-width'
|
||||
link: '/guide/basics/stroke-width',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
// TODO: Add this section
|
||||
{
|
||||
@@ -37,14 +37,14 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
||||
// },
|
||||
{
|
||||
text: 'Global styling',
|
||||
link: '/guide/advanced/global-styling'
|
||||
link: '/guide/advanced/global-styling',
|
||||
},
|
||||
// {
|
||||
// text: 'Animations',
|
||||
// },
|
||||
{
|
||||
text: 'Filled icons',
|
||||
link: '/guide/advanced/filled-icons'
|
||||
link: '/guide/advanced/filled-icons',
|
||||
},
|
||||
// {
|
||||
// text: 'Combining icons',
|
||||
@@ -55,75 +55,73 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
||||
// {
|
||||
// text: 'Auto importing'
|
||||
// },
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Packages',
|
||||
items: [
|
||||
{
|
||||
text: 'Lucide',
|
||||
link: '/guide/packages/lucide'
|
||||
link: '/guide/packages/lucide',
|
||||
},
|
||||
{
|
||||
text: 'Lucide React',
|
||||
link: '/guide/packages/lucide-react'
|
||||
link: '/guide/packages/lucide-react',
|
||||
},
|
||||
{
|
||||
text: 'Lucide React Native',
|
||||
link: '/guide/packages/lucide-react-native'
|
||||
link: '/guide/packages/lucide-react-native',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Vue',
|
||||
link: '/guide/packages/lucide-vue-next'
|
||||
link: '/guide/packages/lucide-vue-next',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Svelte',
|
||||
link: '/guide/packages/lucide-svelte'
|
||||
link: '/guide/packages/lucide-svelte',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Solid',
|
||||
link: '/guide/packages/lucide-solid'
|
||||
link: '/guide/packages/lucide-solid',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Preact',
|
||||
link: '/guide/packages/lucide-preact'
|
||||
link: '/guide/packages/lucide-preact',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Angular',
|
||||
link: '/guide/packages/lucide-angular'
|
||||
link: '/guide/packages/lucide-angular',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Static',
|
||||
link: '/guide/packages/lucide-static'
|
||||
link: '/guide/packages/lucide-static',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Contributing',
|
||||
items: [
|
||||
{
|
||||
text: 'Icon Design Principles',
|
||||
link: '/guide/design/icon-design-guide'
|
||||
link: '/guide/design/icon-design-guide',
|
||||
},
|
||||
{
|
||||
text: 'Designing in Illustrator',
|
||||
link: '/guide/design/illustrator-guide'
|
||||
link: '/guide/design/illustrator-guide',
|
||||
},
|
||||
{
|
||||
text: 'Designing in InkScape',
|
||||
link: '/guide/design/inkscape-guide'
|
||||
link: '/guide/design/inkscape-guide',
|
||||
},
|
||||
{
|
||||
text: 'Designing in Figma',
|
||||
link: '/guide/design/figma-guide'
|
||||
link: '/guide/design/figma-guide',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
],
|
||||
// This should be here to keep the sidebar shown on the icons page
|
||||
'icons': [
|
||||
{ text: '', link: '/' },
|
||||
],
|
||||
}
|
||||
icons: [{ text: '', link: '/' }],
|
||||
};
|
||||
|
||||
export default sidebar
|
||||
export default sidebar;
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
export default {
|
||||
async load() {
|
||||
const version = await fetch('https://api.github.com/repos/lucide-icons/lucide/releases/latest').then(res => {
|
||||
if (res.ok) {
|
||||
const releaseData = res.json() as Promise<{ tag_name: string }>
|
||||
const version = await fetch('https://api.github.com/repos/lucide-icons/lucide/releases/latest')
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
const releaseData = res.json() as Promise<{ tag_name: string }>;
|
||||
|
||||
return releaseData
|
||||
}
|
||||
return null
|
||||
}).then(res => res.tag_name)
|
||||
return releaseData;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.then((res) => res.tag_name);
|
||||
|
||||
return {
|
||||
version
|
||||
}
|
||||
}
|
||||
}
|
||||
version,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import iconNodes from '../../../data/iconNodes'
|
||||
import iconNodes from '../../../data/iconNodes';
|
||||
|
||||
const getRandomItem = <Item>(items: Item[]): Item => items[Math.floor(Math.random()*items.length)];
|
||||
const getRandomItem = <Item>(items: Item[]): Item =>
|
||||
items[Math.floor(Math.random() * items.length)];
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
const icons = Object.entries(iconNodes).map(([name, iconNode]) => ({ name, iconNode }))
|
||||
const icons = Object.entries(iconNodes).map(([name, iconNode]) => ({ name, iconNode }));
|
||||
|
||||
const randomIcons = Array.from({ length: 200 }, () => getRandomItem(icons))
|
||||
const randomIcons = Array.from({ length: 200 }, () => getRandomItem(icons));
|
||||
|
||||
return {
|
||||
icons: randomIcons,
|
||||
iconsCount: icons.length,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
logo: '/framework-logos/flutter.svg',
|
||||
label: 'Lucide documentation for Flutter',
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { getAllData } from '../../../lib/icons';
|
||||
import { getAllCategoryFiles, mapCategoryIconCount } from '../../../lib/categories';
|
||||
import iconsMetaData from '../../../data/iconMetaData'
|
||||
|
||||
import iconsMetaData from '../../../data/iconMetaData';
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
let categories = getAllCategoryFiles()
|
||||
let categories = getAllCategoryFiles();
|
||||
|
||||
categories = mapCategoryIconCount(categories, Object.values(iconsMetaData))
|
||||
categories = mapCategoryIconCount(categories, Object.values(iconsMetaData));
|
||||
|
||||
return {
|
||||
categories,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
.confetti-button:before,
|
||||
.confetti-button:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
content: '';
|
||||
display: block;
|
||||
width: 140%;
|
||||
max-width: 160px;
|
||||
@@ -41,8 +41,16 @@
|
||||
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
|
||||
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
|
||||
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%);
|
||||
background-size: 10% 10%, 20% 20%, 15% 15%, 20% 20%, 18% 18%, 10% 10%, 15% 15%,
|
||||
10% 10%, 18% 18%;
|
||||
background-size:
|
||||
10% 10%,
|
||||
20% 20%,
|
||||
15% 15%,
|
||||
20% 20%,
|
||||
18% 18%,
|
||||
10% 10%,
|
||||
15% 15%,
|
||||
10% 10%,
|
||||
18% 18%;
|
||||
}
|
||||
|
||||
.confetti-button:after {
|
||||
@@ -55,7 +63,14 @@
|
||||
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
|
||||
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%),
|
||||
radial-gradient(circle, var(--confetti-color) 20%, transparent 20%);
|
||||
background-size: 15% 15%, 20% 20%, 18% 18%, 20% 20%, 15% 15%, 10% 10%, 20% 20%;
|
||||
background-size:
|
||||
15% 15%,
|
||||
20% 20%,
|
||||
18% 18%,
|
||||
20% 20%,
|
||||
15% 15%,
|
||||
10% 10%,
|
||||
20% 20%;
|
||||
}
|
||||
|
||||
.confetti-button.animate:before {
|
||||
@@ -70,35 +85,89 @@
|
||||
@keyframes topBubbles {
|
||||
0% {
|
||||
color: rgb(var(--text-color) / 0);
|
||||
background-position: 5% 90%, 10% 90%, 10% 90%, 15% 90%, 25% 90%, 25% 90%,
|
||||
40% 90%, 55% 90%, 70% 90%;
|
||||
background-position:
|
||||
5% 90%,
|
||||
10% 90%,
|
||||
10% 90%,
|
||||
15% 90%,
|
||||
25% 90%,
|
||||
25% 90%,
|
||||
40% 90%,
|
||||
55% 90%,
|
||||
70% 90%;
|
||||
}
|
||||
30% {
|
||||
color: rgb(var(--text-color) / 1);
|
||||
}
|
||||
50% {
|
||||
background-position: 0% 80%, 0% 20%, 10% 40%, 20% 0%, 30% 30%, 22% 50%,
|
||||
50% 50%, 65% 20%, 90% 30%;
|
||||
background-position:
|
||||
0% 80%,
|
||||
0% 20%,
|
||||
10% 40%,
|
||||
20% 0%,
|
||||
30% 30%,
|
||||
22% 50%,
|
||||
50% 50%,
|
||||
65% 20%,
|
||||
90% 30%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 70%, 0% 10%, 10% 30%, 20% -10%, 30% 20%, 22% 40%,
|
||||
50% 40%, 65% 10%, 90% 20%;
|
||||
background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%;
|
||||
background-position:
|
||||
0% 70%,
|
||||
0% 10%,
|
||||
10% 30%,
|
||||
20% -10%,
|
||||
30% 20%,
|
||||
22% 40%,
|
||||
50% 40%,
|
||||
65% 10%,
|
||||
90% 20%;
|
||||
background-size:
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%;
|
||||
color: rgb(var(--text-color) / 0);
|
||||
}
|
||||
}
|
||||
@keyframes bottomBubbles {
|
||||
0% {
|
||||
background-position: 10% -10%, 30% 10%, 55% -10%, 70% -10%, 85% -10%,
|
||||
70% -10%, 70% 0%;
|
||||
background-position:
|
||||
10% -10%,
|
||||
30% 10%,
|
||||
55% -10%,
|
||||
70% -10%,
|
||||
85% -10%,
|
||||
70% -10%,
|
||||
70% 0%;
|
||||
}
|
||||
50% {
|
||||
background-position: 0% 80%, 20% 80%, 45% 60%, 60% 100%, 75% 70%, 95% 60%,
|
||||
background-position:
|
||||
0% 80%,
|
||||
20% 80%,
|
||||
45% 60%,
|
||||
60% 100%,
|
||||
75% 70%,
|
||||
95% 60%,
|
||||
105% 0%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 90%, 20% 90%, 45% 70%, 60% 110%, 75% 80%, 95% 70%,
|
||||
background-position:
|
||||
0% 90%,
|
||||
20% 90%,
|
||||
45% 70%,
|
||||
60% 110%,
|
||||
75% 80%,
|
||||
95% 70%,
|
||||
110% 10%;
|
||||
background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%;
|
||||
background-size:
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%,
|
||||
0% 0%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import packageData from '../../../data/packageData.json';
|
||||
import thirdPartyPackages from '../../../data/packageData.thirdParty.json';
|
||||
import fetchPackages from "../../../lib/fetchPackages";
|
||||
import fetchPackages from '../../../lib/fetchPackages';
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
const packages = await fetchPackages();
|
||||
return {
|
||||
packages: packages
|
||||
.filter(p => p.name in packageData)
|
||||
.filter((p) => p.name in packageData)
|
||||
.map((pData) => ({
|
||||
...pData,
|
||||
...packageData[pData.name],
|
||||
documentation: `/guide/packages/${pData.name}`,
|
||||
source: `https://github.com/lucide-icons/lucide/tree/main/packages/${pData.name}`,
|
||||
icon: `/framework-logos/${packageData[pData.name].icon}.svg`,
|
||||
})).sort((a, b) => a.order - b.order),
|
||||
...pData,
|
||||
...packageData[pData.name],
|
||||
documentation: `/guide/packages/${pData.name}`,
|
||||
source: `https://github.com/lucide-icons/lucide/tree/main/packages/${pData.name}`,
|
||||
icon: `/framework-logos/${packageData[pData.name].icon}.svg`,
|
||||
}))
|
||||
.sort((a, b) => a.order - b.order),
|
||||
thirdPartyPackages,
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,69 +1,68 @@
|
||||
import { onMounted, onUpdated, onUnmounted } from 'vue';
|
||||
import { throttleAndDebounce } from 'vitepress/dist/client/theme-default/support/utils'
|
||||
import { throttleAndDebounce } from 'vitepress/dist/client/theme-default/support/utils';
|
||||
|
||||
/*
|
||||
* This file is compied and adjusted from vitepress/dist/client/theme-default/composables/useActiveAnchor.ts
|
||||
*/
|
||||
* This file is compied and adjusted from vitepress/dist/client/theme-default/composables/useActiveAnchor.ts
|
||||
*/
|
||||
|
||||
export function useActiveAnchor(container, marker) {
|
||||
const onScroll = throttleAndDebounce(setActiveLink, 100);
|
||||
let prevActiveLink = null;
|
||||
onMounted(() => {
|
||||
requestAnimationFrame(setActiveLink);
|
||||
window.addEventListener('scroll', onScroll);
|
||||
requestAnimationFrame(setActiveLink);
|
||||
window.addEventListener('scroll', onScroll);
|
||||
});
|
||||
onUpdated(() => {
|
||||
// sidebar update means a route change
|
||||
activateLink(location.hash);
|
||||
// sidebar update means a route change
|
||||
activateLink(location.hash);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
window.removeEventListener('scroll', onScroll);
|
||||
});
|
||||
function setActiveLink() {
|
||||
const links = [].slice.call(container.value.querySelectorAll('.outline-link'));
|
||||
const anchors = [].slice
|
||||
.call(document.querySelectorAll('.content .header-anchor'))
|
||||
.filter((anchor) => {
|
||||
return links.some((link) => {
|
||||
return link.hash === anchor.hash && anchor.offsetParent !== null;
|
||||
});
|
||||
const links = [].slice.call(container.value.querySelectorAll('.outline-link'));
|
||||
const anchors = [].slice
|
||||
.call(document.querySelectorAll('.content .header-anchor'))
|
||||
.filter((anchor) => {
|
||||
return links.some((link) => {
|
||||
return link.hash === anchor.hash && anchor.offsetParent !== null;
|
||||
});
|
||||
});
|
||||
const scrollY = window.scrollY;
|
||||
const innerHeight = window.innerHeight;
|
||||
const offsetHeight = document.body.offsetHeight;
|
||||
const isBottom = Math.abs(scrollY + innerHeight - offsetHeight) < 1;
|
||||
// page bottom - highlight last one
|
||||
if (anchors.length && isBottom) {
|
||||
activateLink(anchors[anchors.length - 1].hash);
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < anchors.length; i++) {
|
||||
const anchor = anchors[i];
|
||||
const nextAnchor = anchors[i + 1];
|
||||
const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor);
|
||||
if (isActive) {
|
||||
activateLink(hash);
|
||||
return;
|
||||
}
|
||||
const scrollY = window.scrollY;
|
||||
const innerHeight = window.innerHeight;
|
||||
const offsetHeight = document.body.offsetHeight;
|
||||
const isBottom = Math.abs(scrollY + innerHeight - offsetHeight) < 1;
|
||||
// page bottom - highlight last one
|
||||
if (anchors.length && isBottom) {
|
||||
activateLink(anchors[anchors.length - 1].hash);
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < anchors.length; i++) {
|
||||
const anchor = anchors[i];
|
||||
const nextAnchor = anchors[i + 1];
|
||||
const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor);
|
||||
if (isActive) {
|
||||
activateLink(hash);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
function activateLink(hash) {
|
||||
if (prevActiveLink) {
|
||||
prevActiveLink.classList.remove('active');
|
||||
}
|
||||
if (hash !== null) {
|
||||
prevActiveLink = container.value.querySelector(`a[href="${decodeURIComponent(hash)}"]`);
|
||||
}
|
||||
const activeLink = prevActiveLink;
|
||||
if (activeLink) {
|
||||
activeLink.classList.add('active');
|
||||
marker.value.style.top = activeLink.offsetTop + 5 + 'px';
|
||||
marker.value.style.opacity = '1';
|
||||
}
|
||||
else {
|
||||
marker.value.style.top = '33px';
|
||||
marker.value.style.opacity = '0';
|
||||
}
|
||||
if (prevActiveLink) {
|
||||
prevActiveLink.classList.remove('active');
|
||||
}
|
||||
if (hash !== null) {
|
||||
prevActiveLink = container.value.querySelector(`a[href="${decodeURIComponent(hash)}"]`);
|
||||
}
|
||||
const activeLink = prevActiveLink;
|
||||
if (activeLink) {
|
||||
activeLink.classList.add('active');
|
||||
marker.value.style.top = activeLink.offsetTop + 5 + 'px';
|
||||
marker.value.style.opacity = '1';
|
||||
} else {
|
||||
marker.value.style.top = '33px';
|
||||
marker.value.style.opacity = '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,13 +74,13 @@ function getAnchorTop(anchor) {
|
||||
function isAnchorActive(index, anchor, nextAnchor) {
|
||||
const scrollTop = window.scrollY;
|
||||
if (index === 0 && scrollTop === 0) {
|
||||
return [true, null];
|
||||
return [true, null];
|
||||
}
|
||||
if (scrollTop < getAnchorTop(anchor)) {
|
||||
return [false, null];
|
||||
return [false, null];
|
||||
}
|
||||
if (!nextAnchor || scrollTop < getAnchorTop(nextAnchor)) {
|
||||
return [true, anchor.hash];
|
||||
return [true, anchor.hash];
|
||||
}
|
||||
return [false, null];
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import {
|
||||
ref, inject, Ref
|
||||
} from 'vue';
|
||||
import { ref, inject, Ref } from 'vue';
|
||||
|
||||
export const CATEGORY_VIEW_CONTEXT = Symbol('categoryView');
|
||||
|
||||
interface CategoryViewContext {
|
||||
selectedCategory: Ref<string>
|
||||
categoryCounts: Ref<Record<string, number>>
|
||||
selectedCategory: Ref<string>;
|
||||
categoryCounts: Ref<Record<string, number>>;
|
||||
}
|
||||
|
||||
export const categoryViewContext = {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ref } from "vue";
|
||||
import { ref } from 'vue';
|
||||
|
||||
export default function useConfetti() {
|
||||
const animate = ref(false)
|
||||
const confettiText = ref('confetti!')
|
||||
const animate = ref(false);
|
||||
const confettiText = ref('confetti!');
|
||||
|
||||
function confetti() {
|
||||
animate.value = true;
|
||||
@@ -15,6 +15,6 @@ export default function useConfetti() {
|
||||
return {
|
||||
animate,
|
||||
confetti,
|
||||
confettiText
|
||||
}
|
||||
confettiText,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useFetch } from "@vueuse/core"
|
||||
import { useFetch } from '@vueuse/core';
|
||||
|
||||
const useFetchCategories = () => useFetch<Record<string, string[]>>(
|
||||
`${import.meta.env.DEV ? 'http://localhost:3000' : ''}/api/categories`,
|
||||
{
|
||||
immediate:
|
||||
typeof window !== 'undefined'
|
||||
&& new URLSearchParams(window.location.search).has('search'),
|
||||
}
|
||||
).json()
|
||||
const useFetchCategories = () =>
|
||||
useFetch<Record<string, string[]>>(
|
||||
`${import.meta.env.DEV ? 'http://localhost:3000' : ''}/api/categories`,
|
||||
{
|
||||
immediate:
|
||||
typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('search'),
|
||||
},
|
||||
).json();
|
||||
|
||||
export default useFetchCategories
|
||||
export default useFetchCategories;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useFetch } from "@vueuse/core"
|
||||
import { useFetch } from '@vueuse/core';
|
||||
|
||||
const useFetchTags = () => useFetch<Record<string, string[]>>(
|
||||
`${import.meta.env.DEV ? 'http://localhost:3000' : ''}/api/tags`,
|
||||
{
|
||||
immediate:
|
||||
typeof window !== 'undefined'
|
||||
&& new URLSearchParams(window.location.search).has('search'),
|
||||
}
|
||||
).json()
|
||||
const useFetchTags = () =>
|
||||
useFetch<Record<string, string[]>>(
|
||||
`${import.meta.env.DEV ? 'http://localhost:3000' : ''}/api/tags`,
|
||||
{
|
||||
immediate:
|
||||
typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('search'),
|
||||
},
|
||||
).json();
|
||||
|
||||
export default useFetchTags
|
||||
export default useFetchTags;
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import {
|
||||
ref, inject, Ref
|
||||
} from 'vue';
|
||||
import { ref, inject, Ref } from 'vue';
|
||||
|
||||
export const ICON_STYLE_CONTEXT = Symbol('size');
|
||||
|
||||
interface IconSizeContext {
|
||||
size: Ref<number>
|
||||
strokeWidth: Ref<number>
|
||||
color: Ref<string>
|
||||
absoluteStrokeWidth: Ref<boolean>
|
||||
size: Ref<number>;
|
||||
strokeWidth: Ref<number>;
|
||||
color: Ref<string>;
|
||||
absoluteStrokeWidth: Ref<boolean>;
|
||||
}
|
||||
|
||||
export const STYLE_DEFAULTS = {
|
||||
@@ -27,7 +25,7 @@ export const iconStyleContext = {
|
||||
absoluteStrokeWidth: ref(false),
|
||||
};
|
||||
|
||||
export function useIconStyleContext(): IconSizeContext{
|
||||
export function useIconStyleContext(): IconSizeContext {
|
||||
const context = inject<IconSizeContext>(ICON_STYLE_CONTEXT);
|
||||
|
||||
if (!context) {
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import Fuse from 'fuse.js';
|
||||
import { shallowRef, computed, Ref } from 'vue';
|
||||
|
||||
const useSearch = <T>(query: Ref<string>, collection: Ref<T[]>, keys: Fuse.FuseOptionKey<T>[] = []) => {
|
||||
const useSearch = <T>(
|
||||
query: Ref<string>,
|
||||
collection: Ref<T[]>,
|
||||
keys: Fuse.FuseOptionKey<T>[] = [],
|
||||
) => {
|
||||
const index = shallowRef(
|
||||
new Fuse(collection.value, {
|
||||
threshold: 0.2,
|
||||
keys,
|
||||
})
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
||||
const results = computed(() => {
|
||||
index.value.setCollection(collection.value);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { h } from 'vue'
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import './style.css'
|
||||
import { Theme } from 'vitepress'
|
||||
import IconsSidebarNavAfter from './layouts/IconsSidebarNavAfter.vue'
|
||||
import HomeHeroIconsCard from './components/home/HomeHeroIconsCard.vue'
|
||||
import HomeHeroBefore from "./components/home/HomeHeroBefore.vue";
|
||||
import { ICON_STYLE_CONTEXT, iconStyleContext } from './composables/useIconStyle'
|
||||
import { CATEGORY_VIEW_CONTEXT, categoryViewContext } from './composables/useCategoryView'
|
||||
import { h } from 'vue';
|
||||
import DefaultTheme from 'vitepress/theme';
|
||||
import './style.css';
|
||||
import { Theme } from 'vitepress';
|
||||
import IconsSidebarNavAfter from './layouts/IconsSidebarNavAfter.vue';
|
||||
import HomeHeroIconsCard from './components/home/HomeHeroIconsCard.vue';
|
||||
import HomeHeroBefore from './components/home/HomeHeroBefore.vue';
|
||||
import { ICON_STYLE_CONTEXT, iconStyleContext } from './composables/useIconStyle';
|
||||
import { CATEGORY_VIEW_CONTEXT, categoryViewContext } from './composables/useCategoryView';
|
||||
|
||||
const theme: Partial<Theme> = {
|
||||
extends: DefaultTheme,
|
||||
@@ -15,12 +15,12 @@ const theme: Partial<Theme> = {
|
||||
'home-hero-before': () => h(HomeHeroBefore),
|
||||
'sidebar-nav-after': () => h(IconsSidebarNavAfter),
|
||||
'home-hero-image': () => h(HomeHeroIconsCard),
|
||||
})
|
||||
});
|
||||
},
|
||||
enhanceApp({ app }) {
|
||||
app.provide(ICON_STYLE_CONTEXT, iconStyleContext)
|
||||
app.provide(CATEGORY_VIEW_CONTEXT, categoryViewContext)
|
||||
}
|
||||
}
|
||||
app.provide(ICON_STYLE_CONTEXT, iconStyleContext);
|
||||
app.provide(CATEGORY_VIEW_CONTEXT, categoryViewContext);
|
||||
},
|
||||
};
|
||||
|
||||
export default theme
|
||||
export default theme;
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
:root {
|
||||
--vp-c-brand: #F56565;
|
||||
--vp-c-brand-light: #F67373;
|
||||
--vp-c-brand-lighter: #F89191;
|
||||
--vp-c-brand-dark: #DC5A5A;
|
||||
--vp-c-brand-darker: #C45050;
|
||||
--vp-c-brand: #f56565;
|
||||
--vp-c-brand-light: #f67373;
|
||||
--vp-c-brand-lighter: #f89191;
|
||||
--vp-c-brand-dark: #dc5a5a;
|
||||
--vp-c-brand-darker: #c45050;
|
||||
|
||||
--vp-c-brand-1: #F67373;
|
||||
--vp-c-brand-2: #FF7070;
|
||||
--vp-c-brand-3: #F56565;
|
||||
--vp-c-brand-4: #DC5A5A;
|
||||
--vp-c-brand-5: #C45050;
|
||||
--vp-c-brand-1: #f67373;
|
||||
--vp-c-brand-2: #ff7070;
|
||||
--vp-c-brand-3: #f56565;
|
||||
--vp-c-brand-4: #dc5a5a;
|
||||
--vp-c-brand-5: #c45050;
|
||||
|
||||
--vp-c-bg-alt-up: #fff;
|
||||
--vp-c-bg-alt-down: #fff;
|
||||
|
||||
--vp-code-editor-plain: #24292E;
|
||||
--vp-code-editor-comment: #6A737D;
|
||||
--vp-code-editor-keyword: #D73A49;
|
||||
--vp-code-editor-tag: #22863A;
|
||||
--vp-code-editor-punctuation: #24292E;
|
||||
--vp-code-editor-definition: #6F42C1;
|
||||
--vp-code-editor-property: #005CC5;
|
||||
--vp-code-editor-static: #F78C6C;
|
||||
--vp-code-editor-string: #032F62;
|
||||
--vp-code-editor-plain: #24292e;
|
||||
--vp-code-editor-comment: #6a737d;
|
||||
--vp-code-editor-keyword: #d73a49;
|
||||
--vp-code-editor-tag: #22863a;
|
||||
--vp-code-editor-punctuation: #24292e;
|
||||
--vp-code-editor-definition: #6f42c1;
|
||||
--vp-code-editor-property: #005cc5;
|
||||
--vp-code-editor-static: #f78c6c;
|
||||
--vp-code-editor-string: #032f62;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--vp-c-bg-alt-up: #1B1B1D;
|
||||
--vp-c-bg-alt-down: #0F0F10;
|
||||
--vp-c-bg-alt-up: #1b1b1d;
|
||||
--vp-c-bg-alt-down: #0f0f10;
|
||||
|
||||
--vp-code-editor-plain: #E1E4E8;
|
||||
--vp-code-editor-comment: #6A737D;
|
||||
--vp-code-editor-keyword: #F97583;
|
||||
--vp-code-editor-tag: #85E89D;
|
||||
--vp-code-editor-punctuation: #9ECBFF;
|
||||
--vp-code-editor-definition: #B392F0;
|
||||
--vp-code-editor-property: #79B8FF;
|
||||
--vp-code-editor-static: #F78C6C;
|
||||
--vp-code-editor-string: #9ECBFF;
|
||||
--vp-code-editor-plain: #e1e4e8;
|
||||
--vp-code-editor-comment: #6a737d;
|
||||
--vp-code-editor-keyword: #f97583;
|
||||
--vp-code-editor-tag: #85e89d;
|
||||
--vp-code-editor-punctuation: #9ecbff;
|
||||
--vp-code-editor-definition: #b392f0;
|
||||
--vp-code-editor-property: #79b8ff;
|
||||
--vp-code-editor-static: #f78c6c;
|
||||
--vp-code-editor-string: #9ecbff;
|
||||
}
|
||||
|
||||
.VPNavBarTitle .logo {
|
||||
@@ -69,7 +69,6 @@
|
||||
|
||||
.VPHomeHero .container .main h1.name {
|
||||
color: var(--vp-c-text);
|
||||
|
||||
}
|
||||
.VPHomeHero .container .main h1.name .clip {
|
||||
color: inherit;
|
||||
@@ -82,7 +81,6 @@
|
||||
color: var(--vp-c-brand);
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
.VPHomeHero .container .image {
|
||||
margin: 0;
|
||||
@@ -101,14 +99,14 @@
|
||||
}
|
||||
|
||||
.VPFeature .icon {
|
||||
background-color: var(--vp-c-bg);;
|
||||
background-color: var(--vp-c-bg);
|
||||
}
|
||||
|
||||
.vp-doc[class*=" _icons_"] > div {
|
||||
.vp-doc[class*=' _icons_'] > div {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.VPDoc:has(.vp-doc[class*=" _icons_"]) > .container > .content{
|
||||
.VPDoc:has(.vp-doc[class*=' _icons_']) > .container > .content {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
@@ -120,7 +118,6 @@
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
|
||||
.VPHomeHero .container .image {
|
||||
order: 1;
|
||||
margin-bottom: auto;
|
||||
@@ -141,7 +138,6 @@
|
||||
}
|
||||
|
||||
.VPHomeHero .container .main h1.name {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,10 +194,10 @@ html:has(* .outline-link:target) {
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-tabs .sp-tab-button[data-active="true"] {
|
||||
.sp-wrapper .sp-tabs .sp-tab-button[data-active='true'] {
|
||||
color: var(--vp-code-tab-active-text-color);
|
||||
}
|
||||
|
||||
.sp-wrapper .sp-tabs .sp-tab-button[data-active="true"]:after {
|
||||
.sp-wrapper .sp-tabs .sp-tab-button[data-active='true']:after {
|
||||
background-color: var(--vp-code-tab-active-bar-color);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export type IconNode = [elementName: string, attrs: Record<string, string>][]
|
||||
export type IconNodeWithKeys = [elementName: string, attrs: Record<string, string>, key: string][]
|
||||
export type IconNode = [elementName: string, attrs: Record<string, string>][];
|
||||
export type IconNodeWithKeys = [elementName: string, attrs: Record<string, string>, key: string][];
|
||||
|
||||
export interface IconEntity {
|
||||
name: string;
|
||||
@@ -13,45 +13,44 @@ export interface IconEntity {
|
||||
}
|
||||
|
||||
export interface Category {
|
||||
name: string
|
||||
title: string
|
||||
icon?: string
|
||||
iconCount: number
|
||||
icons?: IconEntity[]
|
||||
name: string;
|
||||
title: string;
|
||||
icon?: string;
|
||||
iconCount: number;
|
||||
icons?: IconEntity[];
|
||||
}
|
||||
|
||||
interface Shield {
|
||||
alt: string
|
||||
src: string
|
||||
href: string
|
||||
alt: string;
|
||||
src: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
export interface PackageItem {
|
||||
name: string
|
||||
description: string
|
||||
icon: string
|
||||
iconDark: string
|
||||
shields: Shield[]
|
||||
source: string
|
||||
documentation: string
|
||||
order?: number
|
||||
private?: boolean
|
||||
flutter?: object
|
||||
name: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
iconDark: string;
|
||||
shields: Shield[];
|
||||
source: string;
|
||||
documentation: string;
|
||||
order?: number;
|
||||
private?: boolean;
|
||||
flutter?: object;
|
||||
}
|
||||
|
||||
|
||||
export interface Release {
|
||||
version: string
|
||||
date: string
|
||||
version: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
interface ShowcaseItemImage {
|
||||
light: string
|
||||
dark: string
|
||||
light: string;
|
||||
dark: string;
|
||||
}
|
||||
|
||||
export interface ShowcaseItem {
|
||||
name: string
|
||||
url: string
|
||||
image: ShowcaseItemImage
|
||||
name: string;
|
||||
url: string;
|
||||
image: ShowcaseItemImage;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default function downloadData(filename:string, data:string) {
|
||||
export default function downloadData(filename: string, data: string) {
|
||||
const link = document.createElement('a');
|
||||
link.download = filename;
|
||||
link.href = data
|
||||
link.href = data;
|
||||
link.click();
|
||||
}
|
||||
|
||||
@@ -9,26 +9,26 @@ const allowedAttrs = [
|
||||
'stroke-linecap',
|
||||
'stroke-linejoin',
|
||||
'class',
|
||||
]
|
||||
];
|
||||
|
||||
export default function getSVGIcon(element?: HTMLElement, attrs?: Record<string, string>) {
|
||||
const svg = element ?? document.querySelector('#previewer svg')
|
||||
if (!svg) return
|
||||
const svg = element ?? document.querySelector('#previewer svg');
|
||||
if (!svg) return;
|
||||
|
||||
const clonedSvg = svg.cloneNode(true) as SVGElement
|
||||
const clonedSvg = svg.cloneNode(true) as SVGElement;
|
||||
|
||||
// Filter out attributes that are not allowed in SVGs
|
||||
for (const attr of Array.from(clonedSvg.attributes)) {
|
||||
if (!allowedAttrs.includes(attr.name)) {
|
||||
clonedSvg.removeAttribute(attr.name)
|
||||
clonedSvg.removeAttribute(attr.name);
|
||||
}
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(attrs ?? {})) {
|
||||
clonedSvg.setAttribute(key, value)
|
||||
clonedSvg.setAttribute(key, value);
|
||||
}
|
||||
|
||||
const svgString = new XMLSerializer().serializeToString(clonedSvg)
|
||||
const svgString = new XMLSerializer().serializeToString(clonedSvg);
|
||||
|
||||
return svgString
|
||||
return svgString;
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# Aliased Names
|
||||
|
||||
Icons can have multiple names for the same icon. This is because we choose to rename some icons to make them more consistent with the rest of the icon set, or the name was not generic. For example, the `edit-2` icon is renamed to `pen` to make the name more generic, since it is just a pen icon.
|
||||
|
||||
Beside aliases names lucide also includes prefixed and suffixed names to use within your project. This is to prevent import name collisions with other libraries or your own code.
|
||||
|
||||
```tsx
|
||||
// These are all the same icon
|
||||
import {
|
||||
Home,
|
||||
HomeIcon,
|
||||
LucideHome,
|
||||
} from "lucide-react";
|
||||
```
|
||||
|
||||
|
||||
## Choosing import name style
|
||||
|
||||
|
||||
|
||||
```ts
|
||||
declare module "lucide-react" {
|
||||
export * from "lucide-react/dist/lucide-react.prefixed";
|
||||
}
|
||||
```
|
||||
+10
-11
@@ -1,23 +1,22 @@
|
||||
import relatedIcons from '../.vitepress/data/relatedIcons.json'
|
||||
import iconNodes from '../.vitepress/data/iconNodes'
|
||||
import * as iconDetails from '../.vitepress/data/iconDetails'
|
||||
import { IconEntity } from "../.vitepress/theme/types";
|
||||
import relatedIcons from '../.vitepress/data/relatedIcons.json';
|
||||
import iconNodes from '../.vitepress/data/iconNodes';
|
||||
import * as iconDetails from '../.vitepress/data/iconDetails';
|
||||
import { IconEntity } from '../.vitepress/theme/types';
|
||||
|
||||
export default {
|
||||
paths: async () => {
|
||||
return (Object.values(iconDetails) as unknown as IconEntity[]).map((iconEntity) => {
|
||||
|
||||
const params = {
|
||||
...iconEntity,
|
||||
relatedIcons: relatedIcons[iconEntity.name].map((name: string) => ({
|
||||
name,
|
||||
iconNode: iconNodes[name],
|
||||
}))
|
||||
}
|
||||
})),
|
||||
};
|
||||
|
||||
return {
|
||||
params,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { getAllCategoryFiles } from '../.vitepress/lib/categories'
|
||||
import iconMetaData from '../.vitepress/data/iconMetaData'
|
||||
import { getAllCategoryFiles } from '../.vitepress/lib/categories';
|
||||
import iconMetaData from '../.vitepress/data/iconMetaData';
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
return {
|
||||
categories: getAllCategoryFiles(),
|
||||
iconCategories: Object.fromEntries(
|
||||
Object.entries(iconMetaData).map(([name, { categories }]) => [name, categories])
|
||||
Object.entries(iconMetaData).map(([name, { categories }]) => [name, categories]),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import createCodeExamples from '../.vitepress/lib/createCodeExamples'
|
||||
import createCodeExamples from '../.vitepress/lib/createCodeExamples';
|
||||
|
||||
export default {
|
||||
async load() {
|
||||
const codeExamples = await createCodeExamples()
|
||||
const codeExamples = await createCodeExamples();
|
||||
|
||||
// const randomIcons = Array.from({ length: 200 }, () => getRandomItem(icons))
|
||||
|
||||
return {
|
||||
codeExamples,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user