Compare commits

...

17 Commits

Author SHA1 Message Date
Karsa
772c5be034 Fixes scaling, tag and tags to have the necessary rounding. (#1850)
* Fixes scaling, tag and tags to have the necessary rounding.

* Update tags.svg

* Update tag.svg

---------

Co-authored-by: Karsa <karsa@sztaki.hu>
2024-02-05 15:08:13 +01:00
Karsa
ee3483eb1b Adds handshake icon (#1835)
* Adds handshake icon

* update handshake icon

* Update handshake.svg

* Update icons/handshake.json

Co-authored-by: Jakob Guddas <github@jguddas.de>

---------

Co-authored-by: Rigó József Karsa <karsa@sztaki.hu>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Jakob Guddas <github@jguddas.de>
2024-02-01 16:37:10 +01:00
CokaKoala
9182c51962 feat: Adds Svelte 5 support (#1748)
* adds svelte 5 support

* Update package.json

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-02-01 16:36:27 +01:00
Han Yeong-woo
eb035fe370 Improve formatting (#1814)
* Ignore linting for examples in docs

* Formatting JSX single attribute per line

* Separte `format` and `lint:format` in package.json

* Bump prettier version

* Run format
2024-02-01 14:38:21 +01:00
Karsa
b96e6acd2e Fix plus/minus sign size in shield-plus/shield-minus (#1840)
* Update shield-plus to match other plus icons

* Update shield-minus to match other minus icons

---------

Co-authored-by: Rigó József Karsa <karsa@sztaki.hu>
2024-01-31 22:53:23 +01:00
Daniel Bayley
7b62649c39 Add smaller dots fill fix to VS Code snippets (#1837) 2024-01-31 09:02:07 +01:00
Daniel Bayley
10aff6cf7b Fix bolt missing metadata (#1836) 2024-01-31 08:42:01 +01:00
Jordan Long
cfa8924025 Update truck icon to match ambulance (#1838) 2024-01-31 08:36:17 +01:00
Eric Fennis
713e9b8a09 Add clipboard-plus and clipboard-minus icons (#1812)
* Add clipboard icons

* Switch to same plus minus as file icons

* update contributors

* center plus and minus paths
2024-01-31 08:35:00 +01:00
Eric Fennis
8ab6f80e4f Add headset icon (#1780)
* Add headset icon

* Fix lint errors

* Revert headset change
2024-01-30 10:08:59 +01:00
Jordan Long
a5221c236a Add story icon (#1820)
* Add story icon

* Split single path into multiple elements

* Refine icons/story.svg

Co-authored-by: Jakob Guddas <github@jguddas.de>

* Update contributors to icons/story.json

Co-authored-by: Jakob Guddas <github@jguddas.de>

* Change "story" icon name to "circle-fading-plus" and add to shapes category

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Jakob Guddas <github@jguddas.de>
2024-01-30 09:30:44 +01:00
Jordan Long
cdd32b5294 Add ambulance icon (#1819)
* Add ambulance icon

* Remove extra attributes and connect path under wheels

* Lift roof and "+" to adhere to 2px gap rule for icons/ambulance.svg

Co-authored-by: Jakob Guddas <github@jguddas.de>

* Increase cab height of ambulance

* Add contributors from truck icon

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
2024-01-29 19:50:04 +01:00
CokaKoala
54c8d4078d fix: Add the license banner inside of the script tag instead of an HTML comment (#1811)
* add banner inside of the script tag instead

* renamed script

* Update packages/lucide-svelte/scripts/license.mjs

Co-authored-by: Jakob Guddas <github@jguddas.de>

* Update packages/lucide-svelte/scripts/appendLicense.mjs

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* renamed file

---------

Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-29 19:48:14 +01:00
Daniel Bayley
3302870983 Refine helping-hand/add hand-* icons (#1328)
* Refine `helping-hand` icon

* Add `hand-platter` icon

* Add `hand-coins` (savings) icon

* Add `hand-heart` icon

* Fix/optimise `helping-hand` icon

* Fix/optimise `hand-coins` icon

* Fix/optimise `hand-heart` icon

* Rename `helping-hand` to `hand-helping`

* Fix/optimise `hand-platter` icon

* Add `thumbs-up-down` icon

* Improve `thumbs-up`/`down` icons metadata

* Improve metadata

* Delete thumbs-up-down icons

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-26 10:10:19 +01:00
Karsa
0f25ee86a0 Fix fills in smaller dots (#1436)
* Fixes palette

* Fixing fill on circles

* Fixing fills

* Revert tractor fill

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-26 09:58:05 +01:00
Jakob Guddas
28686b5bd5 feat: added webhook-off icon (#1566)
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2024-01-25 08:54:18 +01:00
Eric Fennis
8cc143915c Update JSdoc lucide svelte (#1826) 2024-01-25 08:23:34 +01:00
1555 changed files with 4120 additions and 3273 deletions

View File

@@ -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

View File

@@ -43,11 +43,14 @@ module.exports = {
'@html-eslint/no-inline-styles': 'error',
'@html-eslint/require-attrs': [
'error',
...Object.entries(DEFAULT_ATTRS)
.map(([attr, value]) => ({ tag: 'svg', attr, value: String(value) }))
...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',
}
},
},
],
};

View File

@@ -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

View File

@@ -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

View File

@@ -1,7 +1,7 @@
name: Close stale issues and PR
on:
schedule:
- cron: "45 1 * * *"
- cron: '45 1 * * *'
jobs:
stale:

View File

@@ -1,4 +1,4 @@
name: "Pull Request Labeler"
name: 'Pull Request Labeler'
on:
- pull_request_target

View File

@@ -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

View File

@@ -41,7 +41,8 @@ jobs:
strategy:
fail-fast: false
matrix:
package: [
package:
[
'lucide',
'lucide-react',
'lucide-react-native',
@@ -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

View File

@@ -1,5 +1,8 @@
pnpm-lock.yaml
# docs examples
docs/**/examples/
# lucide-angular
packages/lucide-angular/.angular/cache

11
.vscode/settings.json vendored
View File

@@ -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"
}

View File

@@ -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",

View File

@@ -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]),
);
});

View File

@@ -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');

View File

@@ -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' });

View File

@@ -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;
});

View File

@@ -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]
})
return [name, attrs];
});
acc[name] = newIconNode
acc[name] = newIconNode;
return acc
}, {})
})
return acc;
}, {});
});

View File

@@ -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;
});

View File

@@ -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]));
});

View File

@@ -1,3 +1,3 @@
export default eventHandler(() => {
return { nitro: 'Is Awesome! asda' }
})
return { nitro: 'Is Awesome! asda' };
});

View File

@@ -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', {
[
'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",
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",
},
],
[
'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",
},
],
[
'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"
}],
},
],
[
'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/',
},
});

View File

@@ -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"
}
]
}
}

View File

@@ -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"

View File

@@ -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) => {
paths.reduce(
(groups, val) => {
const key = val.c.id;
groups[key] = [...(groups[key] || []), val];
return groups;
}, {} as Record<number, Path[]>)
},
{} 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>
);

View File

@@ -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>,

View File

@@ -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];

View File

@@ -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,
),
}));
}

View File

@@ -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, {
const highlightedCode = highlighter
.codeToHtml(code, {
lang,
themes: {
light: 'github-light',
dark: 'github-dark'
dark: 'github-dark',
},
defaultColor: false
}).replace('shiki-themes', 'shiki-themes vp-code')
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);
}

View File

@@ -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 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;
const jsonFilePath = path.resolve(filePath, 'package.json')
const jsonFilePath = path.resolve(filePath, 'package.json');
if (await fileExist(jsonFilePath)) {
return JSON.parse(
await fs.readFile(jsonFilePath, 'utf-8')
)
return JSON.parse(await fs.readFile(jsonFilePath, 'utf-8'));
}
const ymlFilePath = path.resolve(filePath, 'pubspec.yaml')
const ymlFilePath = path.resolve(filePath, 'pubspec.yaml');
if (await fileExist(ymlFilePath)) {
return yaml.load(
await fs.readFile(ymlFilePath, 'utf-8')
return yaml.load(await fs.readFile(ymlFilePath, 'utf-8'));
}
return null;
}),
);
}
return null
}))
return packageJsons
}
return packageJsons;
};
export default fetchPackages;

View File

@@ -1,17 +1,15 @@
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;

View File

@@ -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;

View File

@@ -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)));

View File

@@ -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;

View File

@@ -1,16 +1,18 @@
export default {
async load() {
const version = await fetch('https://api.github.com/repos/lucide-icons/lucide/releases/latest').then(res => {
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 releaseData = res.json() as Promise<{ tag_name: string }>;
return releaseData
return releaseData;
}
return null
}).then(res => res.tag_name)
return null;
})
.then((res) => res.tag_name);
return {
version
}
}
}
version,
};
},
};

View File

@@ -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,
}
}
}
};
},
};

View File

@@ -47,7 +47,7 @@ export default {
logo: '/framework-logos/flutter.svg',
label: 'Lucide documentation for Flutter',
},
]
}
}
}
],
};
},
};

View File

@@ -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,
}
}
}
};
},
};

View File

@@ -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%;
}
}

View File

@@ -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),
}))
.sort((a, b) => a.order - b.order),
thirdPartyPackages,
};
}
}
},
};

View File

@@ -1,5 +1,5 @@
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
@@ -59,8 +59,7 @@ export function useActiveAnchor(container, marker) {
activeLink.classList.add('active');
marker.value.style.top = activeLink.offsetTop + 5 + 'px';
marker.value.style.opacity = '1';
}
else {
} else {
marker.value.style.top = '33px';
marker.value.style.opacity = '0';
}

View File

@@ -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 = {

View File

@@ -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,
};
}

View File

@@ -1,12 +1,12 @@
import { useFetch } from "@vueuse/core"
import { useFetch } from '@vueuse/core';
const useFetchCategories = () => useFetch<Record<string, string[]>>(
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()
typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('search'),
},
).json();
export default useFetchCategories
export default useFetchCategories;

View File

@@ -1,12 +1,12 @@
import { useFetch } from "@vueuse/core"
import { useFetch } from '@vueuse/core';
const useFetchTags = () => useFetch<Record<string, string[]>>(
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()
typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('search'),
},
).json();
export default useFetchTags
export default useFetchTags;

View File

@@ -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 = {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -1,6 +1,6 @@
export default function downloadData(filename: string, data: string) {
const link = document.createElement('a');
link.download = filename;
link.href = data
link.href = data;
link.click();
}

View File

@@ -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;
}

View File

@@ -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,
}
})
}
}
};
});
},
};

View File

@@ -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]),
),
}
}
}
};
},
};

View File

@@ -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,
}
}
}
};
},
};

View File

@@ -1,9 +1,9 @@
import iconNodes from '../.vitepress/data/iconNodes'
import iconNodes from '../.vitepress/data/iconNodes';
export default {
async load() {
return {
icons: Object.entries(iconNodes).map(([name, iconNode]) => ({ name, iconNode })),
}
}
}
};
},
};

View File

@@ -4,6 +4,6 @@
"jsx": "react",
"allowImportingTsExtensions": true,
"allowSyntheticDefaultImports": true,
"noEmit": true
}
"noEmit": true,
},
}

30
icons/ambulance.json Normal file
View File

@@ -0,0 +1,30 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"jordan808",
"jguddas",
"colebemis",
"ahtohbi4",
"ericfennis",
"Andreto",
"csandman",
"karsa-mistmere",
"danielbayley"
],
"tags": [
"ambulance",
"emergency",
"medical",
"vehicle",
"siren",
"healthcare",
"transportation",
"rescue",
"urgent",
"first aid"
],
"categories": [
"medical",
"transportation"
]
}

20
icons/ambulance.svg Normal file
View File

@@ -0,0 +1,20 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M10 10H6" />
<path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2" />
<path
d="M19 18h2a1 1 0 0 0 1-1v-3.28a1 1 0 0 0-.684-.948l-1.923-.641a1 1 0 0 1-.578-.502l-1.539-3.076A1 1 0 0 0 16.382 8H14" />
<path d="M8 8v4" />
<path d="M9 18h6" />
<circle cx="17" cy="18" r="2" />
<circle cx="7" cy="18" r="2" />
</svg>

After

Width:  |  Height:  |  Size: 553 B

View File

@@ -4,7 +4,9 @@
"karsa-mistmere",
"jguddas"
],
"aliases": ["verified"],
"aliases": [
"verified"
],
"tags": [
"verified",
"check"

View File

@@ -1,5 +1,8 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"nut",
"screw",

View File

@@ -1,6 +1,8 @@
{
"$schema": "../icon.schema.json",
"contributors": ["danielbayley"],
"contributors": [
"danielbayley"
],
"tags": [
"code",
"coding",

View File

@@ -4,7 +4,9 @@
"danielbayley",
"karsa-mistmere"
],
"aliases": ["curly-braces"],
"aliases": [
"curly-braces"
],
"tags": [
"json",
"code",

View File

@@ -0,0 +1,22 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"jordan808",
"jguddas"
],
"tags": [
"stories",
"social media",
"instagram",
"facebook",
"meta",
"snapchat",
"sharing",
"content"
],
"categories": [
"communication",
"social",
"shapes"
]
}

View File

@@ -0,0 +1,19 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 2a10 10 0 0 1 7.38 16.75" />
<path d="M12 8v8" />
<path d="M16 12H8" />
<path d="M2.5 8.875a10 10 0 0 0-.5 3" />
<path d="M2.83 16a10 10 0 0 0 2.43 3.4" />
<path d="M4.636 5.235a10 10 0 0 1 .891-.857" />
<path d="M8.644 21.42a10 10 0 0 0 7.631-.38" />
</svg>

After

Width:  |  Height:  |  Size: 486 B

View File

@@ -0,0 +1,23 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"colebemis",
"csandman",
"ericfennis",
"karsa-mistmere"
],
"tags": [
"copy",
"delete",
"remove",
"erase",
"document",
"medical",
"report",
"doctor"
],
"categories": [
"text",
"medical"
]
}

View File

@@ -9,6 +9,7 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="m3 15 5.12-5.12A3 3 0 0 1 10.24 9H13a2 2 0 1 1 0 4h-2.5m4-.68 4.17-4.89a1.88 1.88 0 0 1 2.92 2.36l-4.2 5.94A3 3 0 0 1 14.96 17H9.83a2 2 0 0 0-1.42.59L7 19" />
<path d="m2 14 6 6" />
<rect width="8" height="4" x="8" y="2" rx="1" ry="1" />
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" />
<path d="M9 14h6" />
</svg>

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 377 B

24
icons/clipboard-plus.json Normal file
View File

@@ -0,0 +1,24 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"colebemis",
"csandman",
"ericfennis",
"karsa-mistmere"
],
"tags": [
"copy",
"paste",
"add",
"create",
"new",
"document",
"medical",
"report",
"doctor"
],
"categories": [
"text",
"medical"
]
}

16
icons/clipboard-plus.svg Normal file
View File

@@ -0,0 +1,16 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="8" height="4" x="8" y="2" rx="1" ry="1" />
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" />
<path d="M9 14h6" />
<path d="M12 17v-6" />
</svg>

After

Width:  |  Height:  |  Size: 402 B

View File

@@ -1,6 +1,8 @@
{
"$schema": "../icon.schema.json",
"contributors": ["danielbayley"],
"contributors": [
"danielbayley"
],
"tags": [
"projects",
"manage",
@@ -20,5 +22,10 @@
"code",
"coding"
],
"categories": ["charts", "time", "development", "design"]
"categories": [
"charts",
"time",
"development",
"design"
]
}

View File

@@ -11,7 +11,7 @@
>
<path d="m20 7 1.7-1.7a1 1 0 0 0 0-1.4l-1.6-1.6a1 1 0 0 0-1.4 0L17 4v3Z" />
<path d="m17 7-5.1 5.1" />
<circle cx="11.5" cy="12.5" r=".5" />
<circle cx="11.5" cy="12.5" r=".5" fill="currentColor" />
<path d="M6 12a2 2 0 0 0 1.8-1.2l.4-.9C8.7 8.8 9.8 8 11 8c2.8 0 5 2.2 5 5 0 1.2-.8 2.3-1.9 2.8l-.9.4A2 2 0 0 0 12 18a4 4 0 0 1-4 4c-3.3 0-6-2.7-6-6a4 4 0 0 1 4-4" />
<path d="m6 16 2 2" />
</svg>

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 568 B

27
icons/hand-coins.json Normal file
View File

@@ -0,0 +1,27 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley",
"kayleyhill"
],
"tags": [
"savings",
"banking",
"money",
"finance",
"offers",
"mortgage",
"payment",
"received",
"wage",
"payroll",
"allowance",
"pocket money",
"handout",
"pennies"
],
"categories": [
"money",
"account"
]
}

17
icons/hand-coins.svg Normal file
View File

@@ -0,0 +1,17 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M11 15h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 17" />
<path d="m7 21 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9" />
<path d="m2 16 6 6" />
<circle cx="16" cy="9" r="2.9" />
<circle cx="6" cy="5" r="3" />
</svg>

After

Width:  |  Height:  |  Size: 473 B

15
icons/hand-heart.json Normal file
View File

@@ -0,0 +1,15 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley",
"kayleyhill"
],
"tags": [
"love",
"like",
"emotion"
],
"categories": [
"social"
]
}

16
icons/hand-heart.svg Normal file
View File

@@ -0,0 +1,16 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M11 14h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 16" />
<path d="m7 20 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9" />
<path d="m2 15 6 6" />
<path d="M19.5 8.5c.7-.7 1.5-1.6 1.5-2.7A2.73 2.73 0 0 0 16 4a2.78 2.78 0 0 0-5 1.8c0 1.2.8 2 1.5 2.8L16 12Z" />
</svg>

After

Width:  |  Height:  |  Size: 519 B

View File

@@ -2,7 +2,8 @@
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere",
"jguddas"
"jguddas",
"danielbayley"
],
"tags": [
"agreement",
@@ -14,5 +15,8 @@
],
"categories": [
"emoji"
],
"aliases": [
"helping-hand"
]
}

15
icons/hand-helping.svg Normal file
View File

@@ -0,0 +1,15 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M11 12h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 14" />
<path d="m7 18 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9" />
<path d="m2 13 6 6" />
</svg>

After

Width:  |  Height:  |  Size: 404 B

22
icons/hand-platter.json Normal file
View File

@@ -0,0 +1,22 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"danielbayley"
],
"tags": [
"waiter",
"waitress",
"restaurant",
"table service",
"served",
"dinner",
"dining",
"meal",
"course",
"luxury"
],
"categories": [
"food-beverage",
"people"
]
}

18
icons/hand-platter.svg Normal file
View File

@@ -0,0 +1,18 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 3V2" />
<path d="M5 10a7.1 7.1 0 0 1 14 0" />
<path d="M4 10h16" />
<path d="M2 14h12a2 2 0 1 1 0 4h-2" />
<path d="m15.4 17.4 3.2-2.8a2 2 0 0 1 2.8 2.9l-3.6 3.3c-.7.8-1.7 1.2-2.8 1.2h-4c-1.1 0-2.1-.4-2.8-1.2L5 18" />
<path d="M5 14v7H2" />
</svg>

After

Width:  |  Height:  |  Size: 474 B

25
icons/handshake.json Normal file
View File

@@ -0,0 +1,25 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere",
"ericfennis"
],
"tags": [
"agreement",
"partnership",
"deal",
"business",
"assistance",
"cooperation",
"friendship",
"union",
"terms"
],
"categories": [
"account",
"social",
"communication",
"money",
"security"
]
}

17
icons/handshake.svg Normal file
View File

@@ -0,0 +1,17 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="m11 17 2 2a1 1 0 1 0 3-3" />
<path d="m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4" />
<path d="m21 3 1 11h-2" />
<path d="M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3" />
<path d="M3 4h8" />
</svg>

After

Width:  |  Height:  |  Size: 505 B

27
icons/headset.json Normal file
View File

@@ -0,0 +1,27 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"ericfennis"
],
"tags": [
"music",
"audio",
"sound",
"gaming",
"headphones",
"headset",
"call",
"center",
"phone",
"telephone",
"voip",
"video"
],
"categories": [
"multimedia",
"connectivity",
"devices",
"files",
"gaming"
]
}

14
icons/headset.svg Normal file
View File

@@ -0,0 +1,14 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M3 11h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5Zm0 0a9 9 0 1 1 18 0m0 0v5a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3Z" />
<path d="M21 16v2a4 4 0 0 1-4 4h-5" />
</svg>

After

Width:  |  Height:  |  Size: 398 B

View File

@@ -10,5 +10,5 @@
stroke-linejoin="round"
>
<path d="M2 18v3c0 .6.4 1 1 1h4v-3h3v-3h2l1.4-1.4a6.5 6.5 0 1 0-4-4Z" />
<circle cx="16.5" cy="7.5" r=".5" />
<circle cx="16.5" cy="7.5" r=".5" fill="currentColor" />
</svg>

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 342 B

View File

@@ -9,9 +9,9 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="13.5" cy="6.5" r=".5" />
<circle cx="17.5" cy="10.5" r=".5" />
<circle cx="8.5" cy="7.5" r=".5" />
<circle cx="6.5" cy="12.5" r=".5" />
<circle cx="13.5" cy="6.5" r=".5" fill="currentColor" />
<circle cx="17.5" cy="10.5" r=".5" fill="currentColor" />
<circle cx="8.5" cy="7.5" r=".5" fill="currentColor" />
<circle cx="6.5" cy="12.5" r=".5" fill="currentColor" />
<path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z" />
</svg>

Before

Width:  |  Height:  |  Size: 596 B

After

Width:  |  Height:  |  Size: 676 B

View File

@@ -9,8 +9,8 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M21 3 9 15" />
<path d="M12 3H3v18h18v-9" />
<path d="M16 3h5v5" />
<path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
<path d="M14 15H9v-5" />
<path d="M16 3h5v5" />
<path d="M21 3 9 15" />
</svg>

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 360 B

View File

@@ -9,10 +9,10 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="7.5" cy="7.5" r=".5" />
<circle cx="18.5" cy="5.5" r=".5" />
<circle cx="11.5" cy="11.5" r=".5" />
<circle cx="7.5" cy="16.5" r=".5" />
<circle cx="17.5" cy="14.5" r=".5" />
<circle cx="7.5" cy="7.5" r=".5" fill="currentColor" />
<circle cx="18.5" cy="5.5" r=".5" fill="currentColor" />
<circle cx="11.5" cy="11.5" r=".5" fill="currentColor" />
<circle cx="7.5" cy="16.5" r=".5" fill="currentColor" />
<circle cx="17.5" cy="14.5" r=".5" fill="currentColor" />
<path d="M3 3v18h18" />
</svg>

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 530 B

View File

@@ -1,6 +1,8 @@
{
"$schema": "../icon.schema.json",
"contributors": ["danielbayley"],
"contributors": [
"danielbayley"
],
"tags": [
"unshielded",
"cybersecurity",

View File

@@ -10,5 +10,5 @@
stroke-linejoin="round"
>
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
<path d="M8 11h8" />
<path d="M9 11h6" />
</svg>

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 289 B

View File

@@ -50,6 +50,7 @@
"account",
"security",
"development",
"gaming"
"gaming",
"medical"
]
}

View File

@@ -10,6 +10,6 @@
stroke-linejoin="round"
>
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10" />
<path d="M8 11h8" />
<path d="M12 15V7" />
<path d="M9 11h6" />
<path d="M12 8v6" />
</svg>

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -3,7 +3,9 @@
"contributors": [
"karsa-mistmere"
],
"aliases": ["stars"],
"aliases": [
"stars"
],
"tags": [
"stars",
"effect",

View File

@@ -9,6 +9,6 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 2H2v10l9.29 9.29c.94.94 2.48.94 3.42 0l6.58-6.58c.94-.94.94-2.48 0-3.42L12 2Z" />
<path d="M7 7h.01" />
<path d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z" />
<circle cx="7.5" cy="7.5" r=".5" fill="currentColor" />
</svg>

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 430 B

View File

@@ -9,7 +9,7 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M9 5H2v7l6.29 6.29c.94.94 2.48.94 3.42 0l3.58-3.58c.94-.94.94-2.48 0-3.42L9 5Z" />
<path d="M6 9.01V9" />
<path d="m15 5 6.3 6.3a2.4 2.4 0 0 1 0 3.4L17 19" />
<path d="M9.586 5.586A2 2 0 0 0 8.172 5H3a1 1 0 0 0-1 1v5.172a2 2 0 0 0 .586 1.414L8.29 18.29a2.426 2.426 0 0 0 3.42 0l3.58-3.58a2.426 2.426 0 0 0 0-3.42z" />
<circle cx="6.5" cy="9.5" r=".5" fill="currentColor" />
</svg>

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 482 B

View File

@@ -13,6 +13,7 @@
],
"categories": [
"account",
"social"
"social",
"emoji"
]
}

View File

@@ -13,6 +13,7 @@
],
"categories": [
"account",
"social"
"social",
"emoji"
]
}

View File

@@ -7,7 +7,8 @@
"Andreto",
"csandman",
"karsa-mistmere",
"danielbayley"
"danielbayley",
"jordan808"
],
"tags": [
"delivery",

View File

@@ -9,9 +9,9 @@
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M5 18H3c-.6 0-1-.4-1-1V7c0-.6.4-1 1-1h10c.6 0 1 .4 1 1v11" />
<path d="M14 9h4l4 4v4c0 .6-.4 1-1 1h-2" />
<circle cx="7" cy="18" r="2" />
<path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2" />
<path d="M15 18H9" />
<path d="M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14" />
<circle cx="17" cy="18" r="2" />
<circle cx="7" cy="18" r="2" />
</svg>

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 468 B

View File

@@ -10,13 +10,13 @@
stroke-linejoin="round"
>
<rect width="18" height="18" x="3" y="3" rx="2" />
<circle cx="7.5" cy="7.5" r=".5" />
<circle cx="7.5" cy="7.5" r=".5" fill="currentColor" />
<path d="m7.9 7.9 2.7 2.7" />
<circle cx="16.5" cy="7.5" r=".5" />
<circle cx="16.5" cy="7.5" r=".5" fill="currentColor" />
<path d="m13.4 10.6 2.7-2.7" />
<circle cx="7.5" cy="16.5" r=".5" />
<circle cx="7.5" cy="16.5" r=".5" fill="currentColor" />
<path d="m7.9 16.1 2.7-2.7" />
<circle cx="16.5" cy="16.5" r=".5" />
<circle cx="16.5" cy="16.5" r=".5" fill="currentColor" />
<path d="m13.4 13.4 2.7 2.7" />
<circle cx="12" cy="12" r="2" />
</svg>

Before

Width:  |  Height:  |  Size: 585 B

After

Width:  |  Height:  |  Size: 665 B

17
icons/webhook-off.json Normal file
View File

@@ -0,0 +1,17 @@
{
"$schema": "../icon.schema.json",
"contributors": [
"karsa-mistmere",
"jguddas"
],
"tags": [
"push api",
"interface",
"callback"
],
"categories": [
"development",
"social",
"account"
]
}

19
icons/webhook-off.svg Normal file
View File

@@ -0,0 +1,19 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M17 17h-5c-1.09-.02-1.94.92-2.5 1.9A3 3 0 1 1 2.57 15" />
<path d="M9 3.4a4 4 0 0 1 6.52.66" />
<path d="m6 17 3.1-5.8a2.5 2.5 0 0 0 .057-2.05" />
<path d="M20.3 20.3a4 4 0 0 1-2.3.7" />
<path d="M18.6 13a4 4 0 0 1 3.357 3.414" />
<path d="m12 6 .6 1" />
<path d="m2 2 20 20" />
</svg>

After

Width:  |  Height:  |  Size: 510 B

View File

@@ -30,11 +30,12 @@
"generate:nextJSAliases": "node ./scripts/generateNextJSAliases.mjs",
"postinstall": "husky install",
"lint:es": "eslint .",
"lint:format": "prettier \"**/*.{js,mjs,ts,jsx,tsx,html,css,scss,json,yml,yaml}\" --write",
"lint:format": "prettier \"**/*.{js,mjs,ts,jsx,tsx,html,css,scss,json,yml,yaml}\" --check",
"lint:json:icons": "ajv --spec=draft2020 -s icon.schema.json -d 'icons/*.json' > /dev/null",
"lint:json:categories": "ajv --spec=draft2020 -s category.schema.json -d 'categories/*.json' > /dev/null",
"lint:json": "pnpm run lint:json:icons && pnpm run lint:json:categories",
"lint": "pnpm lint:es && pnpm lint:format && pnpm lint:json",
"format": "prettier \"**/*.{js,mjs,ts,jsx,tsx,html,css,scss,json,yml,yaml}\" --write",
"prepare": "husky install",
"gi": "node ./scripts/generate/generateIcons.mjs"
},
@@ -58,7 +59,7 @@
"minimist": "^1.2.8",
"node-fetch": "^3.3.2",
"p-memoize": "^7.1.1",
"prettier": "3.1.1",
"prettier": "3.2.4",
"semver": "^7.5.4",
"simple-git": "^3.21.0",
"svgo": "^3.1.0",

Some files were not shown because too many files have changed in this diff Show More