Compare commits

...

12 Commits

Author SHA1 Message Date
Karsa
36f84a74f6 adds construction icon (#959)
Co-authored-by: Karsa <karsa@karsa.org>
2023-02-28 17:25:08 +01:00
Karsa
1479a9dbd8 Fixes pre-commit git hook to ensure the optimisation of staged icons (#958)
* testing

* Fixes pre-commit hook

* Removing checkIcons from pre commit hook because it might result in false positives and negatives on an unclean local repository

* Added checkIcons Github action

---------

Co-authored-by: Karsa <karsa@karsa.org>
2023-02-28 17:24:17 +01:00
gubser
2485f6117a Added filter-x icon (#954)
* Added filter-off icon

* Renamed filter-off to filter-x

* Update icons/filter-x.svg

---------

Co-authored-by: Elio Gubser <3030498-gubser@users.noreply.gitlab.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-02-22 22:29:14 +01:00
Eric Fennis
0bbaaa8abd Fix site build (#955)
* Fix prebuild

* remove env file
2023-02-21 17:33:29 +01:00
Patchethium
a82af02687 Add split-square icon (#952)
* add split-square

* add horizontal icon

* rename vertical icon

* split path
2023-02-21 08:14:27 +01:00
Lucide Bot
a5be1b4101 📦 Bump lucide package versions to 0.115.0 2023-02-16 11:51:55 +00:00
Eric Fennis
639c0e8d85 Add creative commons icon (#945) 2023-02-16 12:45:45 +01:00
Eric Fennis
b863445492 Add remove formatting icon (#944) 2023-02-16 12:44:43 +01:00
Karsa
8c4a41035b Deprecate tags.json (#896)
* Deprecates tags.json and icons.json

* Removed tags.json dependency from Figma plugin

* Add JSON descriptor information to readme

* Restore packages/index.tsx

* Update packages/lucide-figma/src/api/fetchIcons.ts

Add multiple fetches to `Promise.all`

* Added caching to API endpoints

* Updates pnpm-lock.yaml

* Add tags to static

* Trigger site build

* Added prebuild script to generate api caches at build time

* Migrated NextCache function from arrow to regular to simplify markup

* test if contents are read from cache

* Add cache clear to prebuild

* removes debug object

---------

Co-authored-by: Karsa <karsa@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2023-02-16 08:26:29 +01:00
Lucide Bot
4a55ae4b91 📦 Bump lucide package versions to 0.114.0 2023-02-14 06:17:46 +00:00
Karsa
30f683a192 Fixes outline path joins in cat (#947) 2023-02-14 07:11:42 +01:00
Lucide Bot
25e0aaf33c 📦 Bump lucide package versions to 0.113.0 2023-02-12 22:09:06 +00:00
66 changed files with 782 additions and 16231 deletions

View File

@@ -1,4 +0,0 @@
#!/bin/sh
pnpm run checkIcons
exit $?

View File

@@ -9,7 +9,7 @@ at https://github.com/lucide-icons/lucide/blob/main/docs/ICON_DESIGN_GUIDE.md be
and please fill everything below. --> and please fill everything below. -->
- **Name of the icon** : <!-- `icon` --> - **Name of the icon** : <!-- `icon` -->
- **Tags (alternative names for this icon)** (add them in tags.json) : - **Tags (alternative names for this icon)** (add them in as a separate json file using the same icon name) :
- **What is the purpose of this icon?** : <!-- Shows that one can click it to... / Is used to denote or label... --> - **What is the purpose of this icon?** : <!-- Shows that one can click it to... / Is used to denote or label... -->
- **100% scale preview** : <!-- upload an image --> - **100% scale preview** : <!-- upload an image -->
- **Have you considered alternative possibilities** for its naming or design? : - **Have you considered alternative possibilities** for its naming or design? :

41
.github/actions/check-icons.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: "Check icons"
description: "Cross-checks icon and category references in JSON descriptors"
inputs:
name:
description: “Name of the package”
required: true
runs:
using: "composite"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with:
version: 7
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-lucide-preact-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-lucide-preact-pnpm-store-
- name: Install dependencies
run: pnpm install --filter .
- name: Check icons and categories
run: pnpm checkIcons

2
.gitignore vendored
View File

@@ -18,3 +18,5 @@ packages/**/src/icons/*.ts
packages/**/src/icons/*.tsx packages/**/src/icons/*.tsx
packages/**/src/aliases.ts packages/**/src/aliases.ts
packages/**/LICENSE packages/**/LICENSE
categories.json
tags.json

5
.husky/pre-commit Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm lint-staged
pnpm checkIcons

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@
"type": "string" "type": "string"
}, },
"icon": { "icon": {
"$ref": "#/$defs/types/icon-reference" "type": "string"
}, },
"weight": { "weight": {
"type": "integer" "type": "integer"

View File

@@ -80,3 +80,21 @@ For each icon these attributes are applied, corresponding to the above rules.
Code of paths can get really big. Code of paths can get really big.
To reduce file size we like to minify the code. To reduce file size we like to minify the code.
We recommend to use the [SVGOMG](https://jakearchibald.github.io/svgomg/) to minify paths. We recommend to use the [SVGOMG](https://jakearchibald.github.io/svgomg/) to minify paths.
### JSON metadata descriptor
Each icon added must also come with a matching JSON file listing tags and categories for the icon.
Please use the following template:
```json
{
"$schema": "../icon.schema.json",
"tags": [
"foo",
"bar"
],
"categories": [
"devices"
]
}
```

9682
icons.json

File diff suppressed because it is too large Load Diff

View File

@@ -1,84 +0,0 @@
{
"$id": "https://lucide.dev/icons.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$vocabulary": {
"https://json-schema.org/draft/2020-12/vocab/core": true,
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
"https://json-schema.org/draft/2020-12/vocab/validation": true,
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
"https://json-schema.org/draft/2020-12/vocab/content": true
},
"title": "Lucide Icons schema",
"type": "object",
"properties": {
"icons": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/types/icon"
}
},
"categories": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/types/category"
}
}
},
"$defs": {
"types": {
"icon": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"categories": {
"type": "array",
"items": {
"$ref": "#/$defs/types/category-reference"
},
"uniqueItems": true
}
}
},
"category": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"icon": {
"$ref": "#/$defs/types/icon-reference"
},
"weight": {
"type": "integer"
}
},
"required": [
"title",
"icon"
]
},
"icon-reference": {
"type": "string",
"format": "uri-reference"
},
"category-reference": {
"type": "string",
"format": "uri-reference"
}
}
},
"description": "A JSON Schema for icons, tags & categories defined by Lucide Icons."
}

View File

@@ -9,9 +9,7 @@
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
> >
<path d="M14 5.256A8.148 8.148 0 0 0 12 5a9.04 9.04 0 0 0-2 .227M20.098 10c.572 1.068.902 2.24.902 3.444C21 17.89 16.97 21 12 21s-9-3-9-7.556c0-1.251.288-2.41.792-3.444" /> <path d="M12 5c.67 0 1.35.09 2 .26 1.78-2 5.03-2.84 6.42-2.26 1.4.58-.42 7-.42 7 .57 1.07 1 2.24 1 3.44C21 17.9 16.97 21 12 21s-9-3-9-7.56c0-1.25.5-2.4 1-3.44 0 0-1.89-6.42-.5-7 1.39-.58 4.72.23 6.5 2.23A9.04 9.04 0 0 1 12 5Z" />
<path d="M3.75 10S2.11 3.58 3.5 3C4.89 2.42 8 3 9.781 5" />
<path d="M20.172 10.002s1.64-6.42.25-7c-1.39-.58-4.5 0-6.282 2" />
<path d="M8 14v.5" /> <path d="M8 14v.5" />
<path d="M16 14v.5" /> <path d="M16 14v.5" />
<path d="M11.25 16.25h1.5L12 17l-.75-.75Z" /> <path d="M11.25 16.25h1.5L12 17l-.75-.75Z" />

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 537 B

View File

@@ -4,8 +4,7 @@
"arrow", "arrow",
"expand", "expand",
"horizontal", "horizontal",
"unfold", "unfold"
"horizonal"
], ],
"categories": [ "categories": [
"arrows" "arrows"

View File

@@ -4,8 +4,7 @@
"arrow", "arrow",
"collapse", "collapse",
"fold", "fold",
"horizontal", "horizontal"
"horizonal"
], ],
"categories": [ "categories": [
"arrows" "arrows"

12
icons/construction.json Normal file
View File

@@ -0,0 +1,12 @@
{
"$schema": "../icon.schema.json",
"tags": [
"roadwork",
"maintenance",
"blockade",
"barricade"
],
"categories": [
"development"
]
}

20
icons/construction.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="M21 6H3C2.44772 6 2 6.44772 2 7V13C2 13.5523 2.44772 14 3 14H21C21.5523 14 22 13.5523 22 13V7C22 6.44772 21.5523 6 21 6Z"/>
<path d="M17 14V21" />
<path d="M7 14V21" />
<path d="M17 3V6" />
<path d="M7 3V6" />
<path d="M2.5 6.5L10 14" />
<path d="M8 6L16 14" />
<path d="M14 6L21.5 13.5" />
</svg>

After

Width:  |  Height:  |  Size: 524 B

View File

@@ -1,7 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"tags": [ "tags": [
"licence" "licence",
"license"
], ],
"categories": [] "categories": []
} }

View File

@@ -0,0 +1,8 @@
{
"$schema": "../icon.schema.json",
"tags": [
"licence",
"license"
],
"categories": []
}

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"
>
<circle cx="12" cy="12" r="10" />
<path d="M10 9.3a2.8 2.8 0 0 0-3.5 1 3.1 3.1 0 0 0 0 3.4 2.7 2.7 0 0 0 3.5 1" />
<path d="M17 9.3a2.8 2.8 0 0 0-3.5 1 3.1 3.1 0 0 0 0 3.4 2.7 2.7 0 0 0 3.5 1" />
</svg>

After

Width:  |  Height:  |  Size: 410 B

10
icons/filter-x.json Normal file
View File

@@ -0,0 +1,10 @@
{
"$schema": "../icon.schema.json",
"tags": [
"funnel",
"hopper"
],
"categories": [
"layout"
]
}

15
icons/filter-x.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="m13.013 3h-11.013l8 9.46v6.54l4 2v-8.54l0.89973-1.0554" />
<path d="m22 3-5 5" />
<path d="m17 3 5 5" />
</svg>

After

Width:  |  Height:  |  Size: 328 B

View File

@@ -10,6 +10,6 @@
stroke-linejoin="round" stroke-linejoin="round"
> >
<path d="M18 6H5a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h13l4-3.5L18 6Z" /> <path d="M18 6H5a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h13l4-3.5L18 6Z" />
<path d="M12 13v9" /> <path d="M12 13v8" />
<path d="M12 2v4" /> <path d="M12 3v3" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

View File

@@ -0,0 +1,17 @@
{
"$schema": "../icon.schema.json",
"tags": [
"text",
"font",
"typography",
"format",
"x",
"remove",
"delete",
"times",
"clear"
],
"categories": [
"text"
]
}

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="M4 7V4h16v3" />
<path d="M5 20h6" />
<path d="M13 4 8 20" />
<path d="m15 15 5 5" />
<path d="m20 15-5 5" />
</svg>

After

Width:  |  Height:  |  Size: 336 B

View File

@@ -0,0 +1,10 @@
{
"$schema": "../icon.schema.json",
"tags": [
"split",
"divide"
],
"categories": [
"layout"
]
}

View File

@@ -0,0 +1,14 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
>
<path d="M 8,19 H 5 C 4,19 3,18 3,17 V 7 C 3,6 4,5 5,5 h 3" />
<path d="m 16,5 h 3 c 1,0 2,1 2,2 v 10 c 0,1 -1,2 -2,2 h -3" />
<line x1="12" y1="4" x2="12" y2="20" />
</svg>

After

Width:  |  Height:  |  Size: 359 B

View File

@@ -0,0 +1,10 @@
{
"$schema": "../icon.schema.json",
"tags": [
"split",
"divide"
],
"categories": [
"layout"
]
}

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="M 5,8 V 5 C 5,4 6,3 7,3 h 10 c 1,0 2,1 2,2 v 3" />
<path d="m 19,16 v 3 c 0,1 -1,2 -2,2 H 7 C 6,21 5,20 5,19 v -3" />
<line x1="4" y1="12" x2="20" y2="12" />
</svg>

After

Width:  |  Height:  |  Size: 381 B

9
icons/subtitles.json Normal file
View File

@@ -0,0 +1,9 @@
{
"$schema": "../icon.schema.json",
"tags": [
"captions",
"closed captions",
"accessibility"
],
"categories": []
}

View File

@@ -16,16 +16,16 @@
"build:outline-icons": "pnpm --filter outline-svg start", "build:outline-icons": "pnpm --filter outline-svg start",
"generate:supersprite": "node ./scripts/generateSuperSVG.mjs", "generate:supersprite": "node ./scripts/generateSuperSVG.mjs",
"optimize": "node ./scripts/optimizeSvgs.mjs", "optimize": "node ./scripts/optimizeSvgs.mjs",
"addtags": "node ./scripts/addMissingKeysToTags.mjs", "addjsons": "node scripts/addMissingIconJsonFiles.mjs",
"checkIcons": "node scripts/checkIconsAndCategories.mjs --presets @babel/env", "checkIcons": "node scripts/checkIconsAndCategories.mjs --presets @babel/env",
"tags2icons": "node scripts/migrateTagsToIcons.mjs --presets @babel/env", "tags2icons": "node scripts/migrateTagsToIcons.mjs --presets @babel/env",
"icons2tags": "node scripts/migrateIconsToTags.mjs --presets @babel/env", "icons2tags": "node scripts/migrateIconsToTags.mjs --presets @babel/env",
"icons2categories": "node scripts/migrateIconsToCategories.mjs --presets @babel/env", "icons2categories": "node scripts/migrateIconsToCategories.mjs --presets @babel/env",
"categories2icons": "node scripts/migrateCategoriesToIcons.mjs --presets @babel/env", "categories2icons": "node scripts/migrateCategoriesToIcons.mjs --presets @babel/env",
"icons2files": "node scripts/migrateIconsToJsonFiles.mjs --presets @babel/env",
"generate:changelog": "node ./scripts/generateChangelog.mjs", "generate:changelog": "node ./scripts/generateChangelog.mjs",
"postinstall": "husky install", "postinstall": "husky install",
"lint": "eslint --ext .ts,.js,.mjs ./{packages/lucide,scripts}" "lint": "eslint --ext .ts,.js,.mjs ./{packages/lucide,scripts}",
"prepare": "husky install"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.26.0", "eslint": "^8.26.0",
@@ -41,11 +41,6 @@
"svgo": "^3.0.0", "svgo": "^3.0.0",
"svgson": "^5.2.1" "svgson": "^5.2.1"
}, },
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": { "lint-staged": {
"icons/*.svg": "node ./scripts/optimizeStagedSvgs.mjs" "icons/*.svg": "node ./scripts/optimizeStagedSvgs.mjs"
}, },

View File

@@ -1,7 +1,7 @@
{ {
"name": "lucide-angular", "name": "lucide-angular",
"description": "A Lucide icon library package for Angular applications", "description": "A Lucide icon library package for Angular applications",
"version": "0.112.0", "version": "0.115.0",
"author": "SMAH1", "author": "SMAH1",
"license": "ISC", "license": "ISC",
"homepage": "https://lucide.dev", "homepage": "https://lucide.dev",

View File

@@ -23,8 +23,10 @@ export const fetchIcons = async (cachedIcons? : LucideIcons): Promise<LucideIcon
return cachedIcons return cachedIcons
} }
const iconNodesResponse = await fetch(`https://unpkg.com/lucide-static@${packageJson.version}/icon-nodes.json`) const [iconNodesResponse, tagsResponse] = await Promise.all([
const tagsResponse = await fetch('https://unpkg.com/lucide-static@latest/tags.json') fetch('https://lucide.dev/api/icon-nodes'),
fetch('https://lucide.dev/api/tags')
])
const iconNodes = await iconNodesResponse.json(); const iconNodes = await iconNodesResponse.json();
const tags = await tagsResponse.json(); const tags = await tagsResponse.json();

View File

@@ -1,6 +1,6 @@
name: lucide_icons name: lucide_icons
description: A Lucide icon library package for Flutter applications. Fork of Feather Icons, open for anyone to contribute icons. description: A Lucide icon library package for Flutter applications. Fork of Feather Icons, open for anyone to contribute icons.
version: 0.112.0 version: 0.115.0
homepage: https://lucide.dev homepage: https://lucide.dev
repository: https://github.com/lucide-icons/lucide repository: https://github.com/lucide-icons/lucide

View File

@@ -1,7 +1,7 @@
{ {
"name": "lucide-preact", "name": "lucide-preact",
"description": "A Lucide icon library package for Preact applications", "description": "A Lucide icon library package for Preact applications",
"version": "0.112.0", "version": "0.115.0",
"license": "ISC", "license": "ISC",
"homepage": "https://lucide.dev", "homepage": "https://lucide.dev",
"bugs": "https://github.com/lucide-icons/lucide/issues", "bugs": "https://github.com/lucide-icons/lucide/issues",

View File

@@ -1,7 +1,7 @@
{ {
"name": "lucide-react-native", "name": "lucide-react-native",
"description": "A Lucide icon library package for React Native applications", "description": "A Lucide icon library package for React Native applications",
"version": "0.112.0", "version": "0.115.0",
"license": "ISC", "license": "ISC",
"homepage": "https://lucide.dev", "homepage": "https://lucide.dev",
"bugs": "https://github.com/lucide-icons/lucide/issues", "bugs": "https://github.com/lucide-icons/lucide/issues",

View File

@@ -1,7 +1,7 @@
{ {
"name": "lucide-react", "name": "lucide-react",
"description": "A Lucide icon library package for React applications", "description": "A Lucide icon library package for React applications",
"version": "0.112.0", "version": "0.115.0",
"license": "ISC", "license": "ISC",
"homepage": "https://lucide.dev", "homepage": "https://lucide.dev",
"bugs": "https://github.com/lucide-icons/lucide/issues", "bugs": "https://github.com/lucide-icons/lucide/issues",

View File

@@ -12,11 +12,11 @@
"main": "lib/index.js", "main": "lib/index.js",
"scripts": { "scripts": {
"copy:icons": "cp -r ../../icons icons", "copy:icons": "cp -r ../../icons icons",
"copy:tags": "cp ../../tags.json tags.json",
"copy:license": "cp ../../LICENSE ./LICENSE", "copy:license": "cp ../../LICENSE ./LICENSE",
"build": "pnpm clean && pnpm copy:license && pnpm copy:icons && pnpm copy:tags && pnpm build:lib", "build:tags": "node ../../scripts/migrateIconsToTags.mjs",
"build": "pnpm clean && pnpm copy:license && pnpm copy:icons && pnpm build:lib && pnpm build:tags",
"build:lib": "node ./scripts/buildLib.mjs", "build:lib": "node ./scripts/buildLib.mjs",
"clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg && rm -f tags.json", "clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg",
"version": "pnpm version --git-tag-version=false" "version": "pnpm version --git-tag-version=false"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,7 +1,7 @@
{ {
"name": "lucide-svelte", "name": "lucide-svelte",
"description": "A Lucide icon library package for Svelte applications", "description": "A Lucide icon library package for Svelte applications",
"version": "0.112.0", "version": "0.115.0",
"license": "ISC", "license": "ISC",
"homepage": "https://lucide.dev", "homepage": "https://lucide.dev",
"bugs": "https://github.com/lucide-icons/lucide/issues", "bugs": "https://github.com/lucide-icons/lucide/issues",

View File

@@ -1,6 +1,6 @@
{ {
"name": "lucide-vue-next", "name": "lucide-vue-next",
"version": "0.112.0", "version": "0.115.0",
"author": "Eric Fennis", "author": "Eric Fennis",
"description": "A Lucide icon library package for Vue 3 applications", "description": "A Lucide icon library package for Vue 3 applications",
"license": "ISC", "license": "ISC",

View File

@@ -1,6 +1,6 @@
{ {
"name": "lucide-vue", "name": "lucide-vue",
"version": "0.112.0", "version": "0.115.0",
"author": "Eric Fennis", "author": "Eric Fennis",
"description": "A Lucide icon library package for Vue 2 applications", "description": "A Lucide icon library package for Vue 2 applications",
"license": "ISC", "license": "ISC",

View File

@@ -1,7 +1,7 @@
{ {
"name": "lucide", "name": "lucide",
"description": "A Lucide icon library package for web and javascript applications.", "description": "A Lucide icon library package for web and javascript applications.",
"version": "0.112.0", "version": "0.115.0",
"license": "ISC", "license": "ISC",
"homepage": "https://lucide.dev", "homepage": "https://lucide.dev",
"bugs": "https://github.com/lucide-icons/lucide/issues", "bugs": "https://github.com/lucide-icons/lucide/issues",

281
pnpm-lock.yaml generated
View File

@@ -375,6 +375,7 @@ importers:
'@next/eslint-plugin-next': ^12.2.5 '@next/eslint-plugin-next': ^12.2.5
'@next/mdx': ^11.0.0 '@next/mdx': ^11.0.0
'@svgr/webpack': ^6.3.1 '@svgr/webpack': ^6.3.1
'@swc/core': ^1.3.35
'@testing-library/dom': ^7.31.2 '@testing-library/dom': ^7.31.2
'@testing-library/jest-dom': ^5.16.5 '@testing-library/jest-dom': ^5.16.5
'@testing-library/react': ^11.2.7 '@testing-library/react': ^11.2.7
@@ -400,6 +401,7 @@ importers:
lucide-react: ^0.94.0 lucide-react: ^0.94.0
next: '12' next: '12'
next-mdx-remote: ^3.0.2 next-mdx-remote: ^3.0.2
node-fetch: '2'
prettier: ^2.3.2 prettier: ^2.3.2
prism-react-renderer: ^1.2.1 prism-react-renderer: ^1.2.1
react: 17.0.2 react: 17.0.2
@@ -407,6 +409,9 @@ importers:
react-dom: 17.0.2 react-dom: 17.0.2
react-svg-loader: ^3.0.3 react-svg-loader: ^3.0.3
react-test-renderer: 17.0.2 react-test-renderer: 17.0.2
svgson: ^5.2.1
ts-node: ~10.9.1
tslib: ^2.4.0
typescript: ^4.3.5 typescript: ^4.3.5
dependencies: dependencies:
'@chakra-ui/react': 1.8.8_vt5jn3lkv6hocyebmjm7gusm6e '@chakra-ui/react': 1.8.8_vt5jn3lkv6hocyebmjm7gusm6e
@@ -431,8 +436,10 @@ importers:
react-color: 2.19.3_react@17.0.2 react-color: 2.19.3_react@17.0.2
react-dom: 17.0.2_react@17.0.2 react-dom: 17.0.2_react@17.0.2
react-svg-loader: 3.0.3 react-svg-loader: 3.0.3
svgson: 5.2.1
devDependencies: devDependencies:
'@next/eslint-plugin-next': 12.2.5 '@next/eslint-plugin-next': 12.2.5
'@swc/core': 1.3.35
'@testing-library/dom': 7.31.2 '@testing-library/dom': 7.31.2
'@testing-library/jest-dom': 5.16.5 '@testing-library/jest-dom': 5.16.5
'@testing-library/react': 11.2.7_sfoxds7t5ydpegc3knd667wn6m '@testing-library/react': 11.2.7_sfoxds7t5ydpegc3knd667wn6m
@@ -447,9 +454,12 @@ importers:
babel-loader: 8.2.5_webpack@5.74.0 babel-loader: 8.2.5_webpack@5.74.0
eslint: 8.22.0 eslint: 8.22.0
eslint-config-prettier: 8.5.0_eslint@8.22.0 eslint-config-prettier: 8.5.0_eslint@8.22.0
jest: 26.6.3 jest: 26.6.3_ts-node@10.9.1
node-fetch: 2.6.7
prettier: 2.7.1 prettier: 2.7.1
react-test-renderer: 17.0.2_react@17.0.2 react-test-renderer: 17.0.2_react@17.0.2
ts-node: 10.9.1_iuagarv54md6u2z4nbxsm6bl6u
tslib: 2.4.0
typescript: 4.8.4 typescript: 4.8.4
tools/build-icons: tools/build-icons:
@@ -7487,7 +7497,7 @@ packages:
slash: 3.0.0 slash: 3.0.0
dev: true dev: true
/@jest/core/26.6.3: /@jest/core/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==} resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
dependencies: dependencies:
@@ -7502,14 +7512,14 @@ packages:
exit: 0.1.2 exit: 0.1.2
graceful-fs: 4.2.10 graceful-fs: 4.2.10
jest-changed-files: 26.6.2 jest-changed-files: 26.6.2
jest-config: 26.6.3 jest-config: 26.6.3_ts-node@10.9.1
jest-haste-map: 26.6.2 jest-haste-map: 26.6.2
jest-message-util: 26.6.2 jest-message-util: 26.6.2
jest-regex-util: 26.0.0 jest-regex-util: 26.0.0
jest-resolve: 26.6.2 jest-resolve: 26.6.2
jest-resolve-dependencies: 26.6.3 jest-resolve-dependencies: 26.6.3
jest-runner: 26.6.3 jest-runner: 26.6.3_ts-node@10.9.1
jest-runtime: 26.6.3 jest-runtime: 26.6.3_ts-node@10.9.1
jest-snapshot: 26.6.2 jest-snapshot: 26.6.2
jest-util: 26.6.2 jest-util: 26.6.2
jest-validate: 26.6.2 jest-validate: 26.6.2
@@ -7632,15 +7642,15 @@ packages:
collect-v8-coverage: 1.0.1 collect-v8-coverage: 1.0.1
dev: true dev: true
/@jest/test-sequencer/26.6.3: /@jest/test-sequencer/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==} resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
dependencies: dependencies:
'@jest/test-result': 26.6.2 '@jest/test-result': 26.6.2
graceful-fs: 4.2.10 graceful-fs: 4.2.10
jest-haste-map: 26.6.2 jest-haste-map: 26.6.2
jest-runner: 26.6.3 jest-runner: 26.6.3_ts-node@10.9.1
jest-runtime: 26.6.3 jest-runtime: 26.6.3_ts-node@10.9.1
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
- canvas - canvas
@@ -9106,6 +9116,113 @@ packages:
- supports-color - supports-color
dev: false dev: false
/@swc/core-darwin-arm64/1.3.35:
resolution: {integrity: sha512-zQUFkHx4gZpu0uo2IspvPnKsz8bsdXd5bC33xwjtoAI1cpLerDyqo4v2zIahEp+FdKZjyVsLHtfJiQiA1Qka3A==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@swc/core-darwin-x64/1.3.35:
resolution: {integrity: sha512-oOSkSGWtALovaw22lNevKD434OQTPf8X+dVPvPMrJXJpJ34dWDlFWpLntoc+arvKLNZ7LQmTuk8rR1hkrAY7cw==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-arm-gnueabihf/1.3.35:
resolution: {integrity: sha512-Yie8k00O6O8BCATS/xeKStquV4OYSskUGRDXBQVDw1FrE23PHaSeHCgg4q6iNZjJzXCOJbaTCKnYoIDn9DMf7A==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-arm64-gnu/1.3.35:
resolution: {integrity: sha512-Zlv3WHa/4x2p51HSvjUWXHfSe1Gl2prqImUZJc8NZOlj75BFzVuR0auhQ+LbwvIQ3gaA1LODX9lyS9wXL3yjxA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-arm64-musl/1.3.35:
resolution: {integrity: sha512-u6tCYsrSyZ8U+4jLMA/O82veBfLy2aUpn51WxQaeH7wqZGy9TGSJXoO8vWxARQ6b72vjsnKDJHP4MD8hFwcctg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-x64-gnu/1.3.35:
resolution: {integrity: sha512-Dtxf2IbeH7XlNhP1Qt2/MvUPkpEbn7hhGfpSRs4ot8D3Vf5QEX4S/QtC1OsFWuciiYgHAT1Ybjt4xZic9DSkmA==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-linux-x64-musl/1.3.35:
resolution: {integrity: sha512-4XavNJ60GprjpTiESCu5daJUnmErixPAqDitJSMu4TV32LNIE8G00S9pDLXinDTW1rgcGtQdq1NLkNRmwwovtg==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@swc/core-win32-arm64-msvc/1.3.35:
resolution: {integrity: sha512-dNGfKCUSX2M4qVyaS80Lyos0FkXyHRCvrdQ2Y4Hrg3FVokiuw3yY6fLohpUfQ5ws3n2A39dh7jGDeh34+l0sGA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@swc/core-win32-ia32-msvc/1.3.35:
resolution: {integrity: sha512-ChuPSrDR+JBf7S7dEKPicnG8A3bM0uWPsW2vG+V2wH4iNfNxKVemESHosmYVeEZXqMpomNMvLyeHep1rjRsc0Q==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@swc/core-win32-x64-msvc/1.3.35:
resolution: {integrity: sha512-/RvphT4WfuGfIK84Ha0dovdPrKB1bW/mc+dtdmhv2E3EGkNc5FoueNwYmXWRimxnU7X0X7IkcRhyKB4G5DeAmg==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@swc/core/1.3.35:
resolution: {integrity: sha512-KmiBin0XSVzJhzX19zTiCqmLslZ40Cl7zqskJcTDeIrRhfgKdiAsxzYUanJgMJIRjYtl9Kcg1V/Ip2o2wL8v3w==}
engines: {node: '>=10'}
requiresBuild: true
optionalDependencies:
'@swc/core-darwin-arm64': 1.3.35
'@swc/core-darwin-x64': 1.3.35
'@swc/core-linux-arm-gnueabihf': 1.3.35
'@swc/core-linux-arm64-gnu': 1.3.35
'@swc/core-linux-arm64-musl': 1.3.35
'@swc/core-linux-x64-gnu': 1.3.35
'@swc/core-linux-x64-musl': 1.3.35
'@swc/core-win32-arm64-msvc': 1.3.35
'@swc/core-win32-ia32-msvc': 1.3.35
'@swc/core-win32-x64-msvc': 1.3.35
dev: true
/@swc/helpers/0.4.3: /@swc/helpers/0.4.3:
resolution: {integrity: sha512-6JrF+fdUK2zbGpJIlN7G3v966PQjyx/dPt1T9km2wj+EUBqgrxCk3uX4Kct16MIm9gGxfKRcfax2hVf5jvlTzA==} resolution: {integrity: sha512-6JrF+fdUK2zbGpJIlN7G3v966PQjyx/dPt1T9km2wj+EUBqgrxCk3uX4Kct16MIm9gGxfKRcfax2hVf5jvlTzA==}
dependencies: dependencies:
@@ -10147,14 +10264,6 @@ packages:
acorn: 8.8.1 acorn: 8.8.1
dev: true dev: true
/acorn-jsx/5.3.2_acorn@8.8.0:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
acorn: 8.8.0
dev: true
/acorn-jsx/5.3.2_acorn@8.8.1: /acorn-jsx/5.3.2_acorn@8.8.1:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies: peerDependencies:
@@ -10702,7 +10811,7 @@ packages:
loader-utils: 2.0.2 loader-utils: 2.0.2
make-dir: 3.1.0 make-dir: 3.1.0
schema-utils: 2.7.1 schema-utils: 2.7.1
webpack: 5.74.0 webpack: 5.74.0_@swc+core@1.3.35
dev: true dev: true
/babel-loader/8.2.5_xc6oct4hcywdrbo4ned6ytbybm: /babel-loader/8.2.5_xc6oct4hcywdrbo4ned6ytbybm:
@@ -14113,8 +14222,8 @@ packages:
resolution: {integrity: sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==} resolution: {integrity: sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies: dependencies:
acorn: 8.8.0 acorn: 8.8.1
acorn-jsx: 5.3.2_acorn@8.8.0 acorn-jsx: 5.3.2_acorn@8.8.1
eslint-visitor-keys: 3.3.0 eslint-visitor-keys: 3.3.0
dev: true dev: true
@@ -16097,12 +16206,12 @@ packages:
throat: 5.0.0 throat: 5.0.0
dev: true dev: true
/jest-cli/26.6.3: /jest-cli/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==} resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
hasBin: true hasBin: true
dependencies: dependencies:
'@jest/core': 26.6.3 '@jest/core': 26.6.3_ts-node@10.9.1
'@jest/test-result': 26.6.2 '@jest/test-result': 26.6.2
'@jest/types': 26.6.2 '@jest/types': 26.6.2
chalk: 4.1.2 chalk: 4.1.2
@@ -16110,7 +16219,7 @@ packages:
graceful-fs: 4.2.10 graceful-fs: 4.2.10
import-local: 3.1.0 import-local: 3.1.0
is-ci: 2.0.0 is-ci: 2.0.0
jest-config: 26.6.3 jest-config: 26.6.3_ts-node@10.9.1
jest-util: 26.6.2 jest-util: 26.6.2
jest-validate: 26.6.2 jest-validate: 26.6.2
prompts: 2.4.2 prompts: 2.4.2
@@ -16123,7 +16232,7 @@ packages:
- utf-8-validate - utf-8-validate
dev: true dev: true
/jest-config/26.6.3: /jest-config/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==} resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
peerDependencies: peerDependencies:
@@ -16133,7 +16242,7 @@ packages:
optional: true optional: true
dependencies: dependencies:
'@babel/core': 7.20.2 '@babel/core': 7.20.2
'@jest/test-sequencer': 26.6.3 '@jest/test-sequencer': 26.6.3_ts-node@10.9.1
'@jest/types': 26.6.2 '@jest/types': 26.6.2
babel-jest: 26.6.3_@babel+core@7.20.2 babel-jest: 26.6.3_@babel+core@7.20.2
chalk: 4.1.2 chalk: 4.1.2
@@ -16143,13 +16252,14 @@ packages:
jest-environment-jsdom: 26.6.2 jest-environment-jsdom: 26.6.2
jest-environment-node: 26.6.2 jest-environment-node: 26.6.2
jest-get-type: 26.3.0 jest-get-type: 26.3.0
jest-jasmine2: 26.6.3 jest-jasmine2: 26.6.3_ts-node@10.9.1
jest-regex-util: 26.0.0 jest-regex-util: 26.0.0
jest-resolve: 26.6.2 jest-resolve: 26.6.2
jest-util: 26.6.2 jest-util: 26.6.2
jest-validate: 26.6.2 jest-validate: 26.6.2
micromatch: 4.0.5 micromatch: 4.0.5
pretty-format: 26.6.2 pretty-format: 26.6.2
ts-node: 10.9.1_iuagarv54md6u2z4nbxsm6bl6u
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
- canvas - canvas
@@ -16278,7 +16388,7 @@ packages:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
/jest-jasmine2/26.6.3: /jest-jasmine2/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==} resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
dependencies: dependencies:
@@ -16295,7 +16405,7 @@ packages:
jest-each: 26.6.2 jest-each: 26.6.2
jest-matcher-utils: 26.6.2 jest-matcher-utils: 26.6.2
jest-message-util: 26.6.2 jest-message-util: 26.6.2
jest-runtime: 26.6.3 jest-runtime: 26.6.3_ts-node@10.9.1
jest-snapshot: 26.6.2 jest-snapshot: 26.6.2
jest-util: 26.6.2 jest-util: 26.6.2
pretty-format: 26.6.2 pretty-format: 26.6.2
@@ -16421,7 +16531,7 @@ packages:
slash: 3.0.0 slash: 3.0.0
dev: true dev: true
/jest-runner/26.6.3: /jest-runner/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==} resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
dependencies: dependencies:
@@ -16434,13 +16544,13 @@ packages:
emittery: 0.7.2 emittery: 0.7.2
exit: 0.1.2 exit: 0.1.2
graceful-fs: 4.2.10 graceful-fs: 4.2.10
jest-config: 26.6.3 jest-config: 26.6.3_ts-node@10.9.1
jest-docblock: 26.0.0 jest-docblock: 26.0.0
jest-haste-map: 26.6.2 jest-haste-map: 26.6.2
jest-leak-detector: 26.6.2 jest-leak-detector: 26.6.2
jest-message-util: 26.6.2 jest-message-util: 26.6.2
jest-resolve: 26.6.2 jest-resolve: 26.6.2
jest-runtime: 26.6.3 jest-runtime: 26.6.3_ts-node@10.9.1
jest-util: 26.6.2 jest-util: 26.6.2
jest-worker: 26.6.2 jest-worker: 26.6.2
source-map-support: 0.5.21 source-map-support: 0.5.21
@@ -16453,7 +16563,7 @@ packages:
- utf-8-validate - utf-8-validate
dev: true dev: true
/jest-runtime/26.6.3: /jest-runtime/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==} resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
hasBin: true hasBin: true
@@ -16473,7 +16583,7 @@ packages:
exit: 0.1.2 exit: 0.1.2
glob: 7.2.3 glob: 7.2.3
graceful-fs: 4.2.10 graceful-fs: 4.2.10
jest-config: 26.6.3 jest-config: 26.6.3_ts-node@10.9.1
jest-haste-map: 26.6.2 jest-haste-map: 26.6.2
jest-message-util: 26.6.2 jest-message-util: 26.6.2
jest-mock: 26.6.2 jest-mock: 26.6.2
@@ -16618,14 +16728,14 @@ packages:
supports-color: 8.1.1 supports-color: 8.1.1
dev: true dev: true
/jest/26.6.3: /jest/26.6.3_ts-node@10.9.1:
resolution: {integrity: sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==} resolution: {integrity: sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==}
engines: {node: '>= 10.14.2'} engines: {node: '>= 10.14.2'}
hasBin: true hasBin: true
dependencies: dependencies:
'@jest/core': 26.6.3 '@jest/core': 26.6.3_ts-node@10.9.1
import-local: 3.1.0 import-local: 3.1.0
jest-cli: 26.6.3 jest-cli: 26.6.3_ts-node@10.9.1
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
- canvas - canvas
@@ -22223,6 +22333,31 @@ packages:
supports-hyperlinks: 2.2.0 supports-hyperlinks: 2.2.0
dev: true dev: true
/terser-webpack-plugin/5.3.5_oogp7xv4rppobi5ktio24rc7mq:
resolution: {integrity: sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==}
engines: {node: '>= 10.13.0'}
peerDependencies:
'@swc/core': '*'
esbuild: '*'
uglify-js: '*'
webpack: ^5.1.0
peerDependenciesMeta:
'@swc/core':
optional: true
esbuild:
optional: true
uglify-js:
optional: true
dependencies:
'@jridgewell/trace-mapping': 0.3.15
'@swc/core': 1.3.35
jest-worker: 27.5.1
schema-utils: 3.1.1
serialize-javascript: 6.0.0
terser: 5.16.1
webpack: 5.74.0_@swc+core@1.3.35
dev: true
/terser-webpack-plugin/5.3.5_webpack@5.74.0: /terser-webpack-plugin/5.3.5_webpack@5.74.0:
resolution: {integrity: sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==} resolution: {integrity: sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA==}
engines: {node: '>= 10.13.0'} engines: {node: '>= 10.13.0'}
@@ -22243,7 +22378,7 @@ packages:
jest-worker: 27.5.1 jest-worker: 27.5.1
schema-utils: 3.1.1 schema-utils: 3.1.1
serialize-javascript: 6.0.0 serialize-javascript: 6.0.0
terser: 5.14.2 terser: 5.16.1
webpack: 5.74.0 webpack: 5.74.0
dev: true dev: true
@@ -22484,7 +22619,39 @@ packages:
'@tsconfig/node14': 1.0.3 '@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3 '@tsconfig/node16': 1.0.3
'@types/node': 18.11.4 '@types/node': 18.11.4
acorn: 8.8.0 acorn: 8.8.1
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 4.8.4
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
/ts-node/10.9.1_iuagarv54md6u2z4nbxsm6bl6u:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@swc/core': 1.3.35
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 14.18.25
acorn: 8.8.1
acorn-walk: 8.2.0 acorn-walk: 8.2.0
arg: 4.1.3 arg: 4.1.3
create-require: 1.1.1 create-require: 1.1.1
@@ -23620,6 +23787,46 @@ packages:
- uglify-js - uglify-js
dev: true dev: true
/webpack/5.74.0_@swc+core@1.3.35:
resolution: {integrity: sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
webpack-cli: '*'
peerDependenciesMeta:
webpack-cli:
optional: true
dependencies:
'@types/eslint-scope': 3.7.4
'@types/estree': 0.0.51
'@webassemblyjs/ast': 1.11.1
'@webassemblyjs/wasm-edit': 1.11.1
'@webassemblyjs/wasm-parser': 1.11.1
acorn: 8.8.1
acorn-import-assertions: 1.8.0_acorn@8.8.1
browserslist: 4.21.4
chrome-trace-event: 1.0.3
enhanced-resolve: 5.10.0
es-module-lexer: 0.9.3
eslint-scope: 5.1.1
events: 3.3.0
glob-to-regexp: 0.4.1
graceful-fs: 4.2.10
json-parse-even-better-errors: 2.3.1
loader-runner: 4.3.0
mime-types: 2.1.35
neo-async: 2.6.2
schema-utils: 3.1.1
tapable: 2.2.1
terser-webpack-plugin: 5.3.5_oogp7xv4rppobi5ktio24rc7mq
watchpack: 2.4.0
webpack-sources: 3.2.3
transitivePeerDependencies:
- '@swc/core'
- esbuild
- uglify-js
dev: true
/websocket-driver/0.7.4: /websocket-driver/0.7.4:
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}

View File

@@ -0,0 +1,21 @@
import path from 'path';
import {getCurrentDirPath, readAllMetadata, readSvgDirectory, writeFile} from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url);
const ICONS_DIR = path.resolve(currentDir, '../icons');
const icons = readAllMetadata(ICONS_DIR);
const svgFiles = readSvgDirectory(ICONS_DIR);
const iconNames = svgFiles.map((icon) => icon.split('.')[0]);
iconNames.forEach(iconName => {
if (typeof icons[iconName] === 'undefined') {
const iconContent = JSON.stringify({
"$schema": "../icon.schema.json",
"tags": [],
"categories": []
}, null, 2);
writeFile(iconContent, `${iconName}.json`, path.resolve(currentDir, '..'));
}
});

View File

@@ -1,42 +0,0 @@
import path from 'path';
import tags from '../tags.json' assert { type: 'json' };
import { readSvgDirectory, writeFile, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url);
const ICONS_DIR = path.resolve(currentDir, '../icons');
console.log(`Read all tags`);
const svgFiles = readSvgDirectory(ICONS_DIR);
const iconNames = svgFiles.map((icon) => icon.split('.')[0]);
const iconTags = iconNames
.map((iconName) => ({
name: iconName,
tags: tags[iconName] || [],
}))
.sort((a, b) => {
const nameA = a.name;
const nameB = b.name;
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
const newTags = iconTags.reduce((acc, { name, tags }) => {
acc[name] = tags;
return acc;
}, {});
const tagsContent = JSON.stringify(newTags, null, 2);
writeFile(tagsContent, 'tags.json', path.resolve(currentDir, '..'));

View File

@@ -1,50 +1,52 @@
import path from 'path'; import path from 'path';
import icons from '../icons.json' assert { type: 'json' }; import { readSvgDirectory, getCurrentDirPath, readAllMetadata } from './helpers.mjs';
import { readSvgDirectory, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url) const currentDir = getCurrentDirPath(import.meta.url)
const ICONS_DIR = path.resolve(currentDir, '../icons'); const ICONS_DIR = path.resolve(currentDir, '../icons');
const icons = readAllMetadata(ICONS_DIR);
const CATEGORIES_DIR = path.resolve(currentDir, '../categories');
const categories = readAllMetadata(CATEGORIES_DIR);
console.log(`Read all icons`); console.log('Reading all icons')
const svgFiles = readSvgDirectory(ICONS_DIR); const svgFiles = readSvgDirectory(ICONS_DIR);
const iconNames = svgFiles.map(icon => icon.split('.')[0]); const iconNames = svgFiles.map(icon => icon.split('.')[0]);
let error = false; let error = false;
iconNames.forEach(iconName => { iconNames.forEach(iconName => {
if (typeof icons.icons[iconName] === 'undefined') { if (typeof icons[iconName] === 'undefined') {
console.error(`'${iconName}.svg' is not present in 'icons.json'.`); console.error(`'${iconName}.svg' does not have a matching JSON file.`);
error = true; error = true;
} }
}); });
Object.keys(icons.icons).forEach(iconName => { Object.keys(icons).forEach(iconName => {
const icon = icons.icons[iconName]; const icon = icons[iconName];
if (iconNames.indexOf(iconName) === -1) { if (iconNames.indexOf(iconName) === -1) {
console.error(`'${iconName}.svg' does not exist.`); console.error(`'${iconName}.svg' does not exist.`);
error = true; error = true;
} }
icon.categories.forEach(categoryName => { icon.categories.forEach(categoryName => {
if (typeof icons.categories[categoryName] === 'undefined') { if (typeof categories[categoryName] === 'undefined') {
console.error(`Icon '${iconName}' refers to the non-existing category '${categoryName}'.`); console.error(`Icon '${iconName}' refers to the non-existing category '${categoryName}'.`);
error = true; error = true;
} }
}); });
}); });
Object.keys(icons.categories).forEach(categoryName => { Object.keys(categories).forEach(categoryName => {
const category = icons.categories[categoryName]; const category = categories[categoryName];
if (!category.icon) { if (!category.icon) {
console.error(`Category '${categoryName}' does not use an icon '${category.icon}'.`); console.error(`Category '${categoryName}' does not use an icon '${category.icon}'.`);
error = true; error = true;
} else if (typeof icons.icons[category.icon] === 'undefined') { } else if (typeof icons[category.icon] === 'undefined') {
console.error(`Category '${categoryName}' uses the non-existing icon '${category.icon}'.`); console.error(`Category '${categoryName}' uses the non-existing icon '${category.icon}'.`);
error = true; error = true;
} }
}); });
if (error) { if (error) {
throw new Error('At least one error in icons.json prevents from committing changes.'); console.error('At least one error in icon JSONs prevents from committing changes.');
process.exit(1);
} }

View File

@@ -70,6 +70,30 @@ export const appendFile = (content, fileName, outputDirectory) =>
export const writeFile = (content, fileName, outputDirectory) => export const writeFile = (content, fileName, outputDirectory) =>
fs.writeFileSync(path.join(outputDirectory, fileName), content, 'utf-8'); fs.writeFileSync(path.join(outputDirectory, fileName), content, 'utf-8');
/**
* Reads metadata from the icons/categories directories
*
* @param {string} directory
* @returns {object} A map of icon or category metadata
*/
export const readAllMetadata = (directory) =>
fs.readdirSync(directory).filter((file) => path.extname(file) === '.json').reduce(
(acc, fileName, i) => {
acc[path.basename(fileName, '.json')] = readMetadata(fileName, directory);
return acc;
}, {}
);
/**
* Reads metadata for an icon or category
*
* @param {string} fileName
* @param {string} directory
* @returns {object} The metadata for the icon or category
*/
export const readMetadata = (fileName, directory) =>
JSON.parse(fs.readFileSync(path.join(directory, fileName), 'utf-8'));
/** /**
* reads the icon directory * reads the icon directory
* *

View File

@@ -1,16 +1,19 @@
import path from 'path'; import path from 'path';
import icons from '../icons.json' assert { type: 'json' };
import categories from '../categories.json' assert { type: 'json' }; import categories from '../categories.json' assert { type: 'json' };
import { mergeArrays, writeFile, getCurrentDirPath } from './helpers.mjs'; import { mergeArrays, writeFile, readAllMetadata, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url) const currentDir = getCurrentDirPath(import.meta.url)
const ICONS_DIR = path.resolve(currentDir, '../icons');
const icons = readAllMetadata(ICONS_DIR);
Object.keys(categories).forEach(categoryName => { Object.keys(categories).forEach(categoryName => {
categories[categoryName].forEach(iconName => { categories[categoryName].forEach(iconName => {
mergeArrays(icons.icons[iconName].categories, [categoryName]); icons[iconName].categories = mergeArrays(icons[iconName].categories, [categoryName]);
}); });
}); });
const iconsContent = JSON.stringify(icons, null, 2); Object.keys(icons).forEach(iconName => {
const iconContent = JSON.stringify(icons[iconName], null, 2);
writeFile(iconContent, `${iconName}.json`, path.resolve(currentDir, '../icons'));
})
writeFile(iconsContent, 'icons.json', path.resolve(currentDir, '..'));

View File

@@ -1,12 +1,13 @@
import path from 'path'; import path from 'path';
import icons from '../icons.json' assert { type: 'json' }; import { writeFile, getCurrentDirPath, readAllMetadata } from './helpers.mjs';
import { writeFile, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url) const currentDir = getCurrentDirPath(import.meta.url)
const ICONS_DIR = path.resolve(currentDir, '../icons');
const icons = readAllMetadata(ICONS_DIR);
const newCategories = {}; const newCategories = {};
Object.keys(icons.icons).forEach(iconName => { Object.keys(icons).forEach(iconName => {
icons.icons[iconName].categories.forEach(categoryName => { icons[iconName].categories.forEach(categoryName => {
newCategories[categoryName] = newCategories[categoryName] || []; newCategories[categoryName] = newCategories[categoryName] || [];
newCategories[categoryName].push(iconName); newCategories[categoryName].push(iconName);
}); });

View File

@@ -1,23 +0,0 @@
import path from 'path';
import icons from '../icons.json' assert { type: 'json' };
import { writeFile, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url)
Object.keys(icons.icons).forEach(iconName => {
const icon = {
"$schema": "../icon.schema.json",
...icons.icons[iconName]
};
const iconContent = JSON.stringify(icon, null, 2);
writeFile(iconContent, 'icons/'+iconName+'.json', path.resolve(currentDir, '..'));
});
Object.keys(icons.categories).forEach(categoryName => {
const category = {
"$schema": "../category.schema.json",
...icons.categories[categoryName]
};
const categoryContent = JSON.stringify(category, null, 2);
writeFile(categoryContent, 'categories/'+categoryName+'.json', path.resolve(currentDir, '..'));
});

View File

@@ -1,44 +1,17 @@
import path from 'path'; import path from 'path';
import tags from '../tags.json' assert { type: 'json' }; import { writeFile, getCurrentDirPath, readAllMetadata } from './helpers.mjs';
import icons from '../icons.json' assert { type: 'json' };
import { readSvgDirectory, writeFile, mergeArrays, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url) const currentDir = getCurrentDirPath(import.meta.url);
const ICONS_DIR = path.resolve(currentDir, '../icons'); const ICONS_DIR = path.resolve(currentDir, '../icons');
const icons = readAllMetadata(ICONS_DIR);
console.log(`Read all icons`); const tags = Object.keys(icons)
.sort()
const svgFiles = readSvgDirectory(ICONS_DIR); .reduce((acc, iconName) => {
acc[iconName] = icons[iconName].tags;
const iconNames = svgFiles.map(icon => icon.split('.')[0]);
const iconList = iconNames
.map(iconName => ({
name: iconName,
icon: icons.icons[iconName] || { tags: [] },
tags: tags[iconName] || [],
}))
.sort((a, b) => {
const nameA = a.name;
const nameB = b.name;
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
const newTags = iconList.reduce((acc, { name, icon, tags }) => {
acc[name] = mergeArrays(icon.tags, tags);
return acc; return acc;
}, {}); }, {});
const tagsContent = JSON.stringify(newTags, null, 2); const tagsContent = JSON.stringify(tags, null, 2);
writeFile(tagsContent, 'tags.json', path.resolve(currentDir, '..')); writeFile(tagsContent, 'tags.json', path.resolve(process.cwd()));

View File

@@ -1,47 +1,21 @@
import path from 'path'; import path from 'path';
import tags from '../tags.json' assert { type: 'json' }; import tags from '../tags.json' assert { type: 'json' };
import icons from '../icons.json' assert { type: 'json' }; import { readSvgDirectory, readAllMetadata, writeFile, mergeArrays, getCurrentDirPath } from './helpers.mjs';
import { readSvgDirectory, writeFile, mergeArrays, getCurrentDirPath } from './helpers.mjs';
const currentDir = getCurrentDirPath(import.meta.url) const currentDir = getCurrentDirPath(import.meta.url)
const ICONS_DIR = path.resolve(currentDir, '../icons'); const ICONS_DIR = path.resolve(currentDir, '../icons');
const icons = readAllMetadata(ICONS_DIR);
console.log(`Read all icons`);
const svgFiles = readSvgDirectory(ICONS_DIR); const svgFiles = readSvgDirectory(ICONS_DIR);
const iconNames = svgFiles.map(icon => icon.split('.')[0]); const iconNames = svgFiles.map((icon) => icon.split('.')[0]);
const iconList = iconNames iconNames.forEach(iconName => {
.map(iconName => ({ icons[iconName] = icons[iconName] || {
name: iconName, "$schema": "../icon.schema.json",
icon: icons.icons[iconName] || { tags: [], categories: [] }, "tags": [],
tags: tags[iconName] || [], "categories": []
})) };
.sort((a, b) => { icons[iconName].tags = mergeArrays(icons[iconName].tags, tags[iconName]);
const nameA = a.name; const iconContent = JSON.stringify(icons[iconName], null, 2);
const nameB = b.name; writeFile(iconContent, `${iconName}.json`, path.resolve(currentDir, '../icons'));
})
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
const newIcons = icons;
newIcons.icons = iconList.reduce((acc, { name, icon, tags }) => {
acc[name] = icon;
acc[name].tags = mergeArrays(icon.tags, tags);
return acc;
}, {});
const iconsContent = JSON.stringify(newIcons, null, 2);
writeFile(iconsContent, 'icons.json', path.resolve(currentDir, '..'));

View File

@@ -1,10 +1,11 @@
import fs from 'fs'; import fs from 'fs';
import processSvg from './render/processSvg.mjs'; import processSvg from './render/processSvg.mjs';
const svgFiles = process.argv.slice(4); const svgFiles = process.argv.slice(2);
svgFiles.forEach(async (svgFile) => { svgFiles.forEach(async (svgFile) => {
console.log('Optimizing staged SVG file:', svgFile)
const content = fs.readFileSync(svgFile); const content = fs.readFileSync(svgFile);
const svg = await processSvg(content); const svg = await processSvg(content, svgFile);
fs.writeFileSync(svgFile, svg, 'utf-8'); fs.writeFileSync(svgFile, svg, 'utf-8');
}); });

View File

@@ -11,5 +11,5 @@ const svgFiles = readSvgDirectory(ICONS_DIR);
svgFiles.forEach((svgFile) => { svgFiles.forEach((svgFile) => {
const content = fs.readFileSync(path.join(ICONS_DIR, svgFile)); const content = fs.readFileSync(path.join(ICONS_DIR, svgFile));
processSvg(content).then((svg) => writeSvgFile(svgFile, ICONS_DIR, svg)); processSvg(content, svgFile).then((svg) => writeSvgFile(svgFile, ICONS_DIR, svg));
}); });

View File

@@ -8,8 +8,9 @@ import DEFAULT_ATTRS from './default-attrs.json' assert { type: 'json' };
* @param {string} svg - An SVG string. * @param {string} svg - An SVG string.
* @returns {Promise<string>} An optimized svg * @returns {Promise<string>} An optimized svg
*/ */
async function optimizeSvg(svg) { async function optimizeSvg(svg, path) {
const result = optimize(svg, { const result = optimize(svg, {
path,
plugins: [ plugins: [
{ {
name: 'preset-default', name: 'preset-default',
@@ -17,12 +18,15 @@ async function optimizeSvg(svg) {
overrides: { overrides: {
convertShapeToPath: false, convertShapeToPath: false,
mergePaths: false, mergePaths: false,
removeAttrs: { },
},
},
{
name: 'removeAttrs',
params: {
attrs: '(fill|stroke.*)', attrs: '(fill|stroke.*)',
}, }
}, }
},
},
], ],
}); });
@@ -47,9 +51,9 @@ function setAttrs(svg) {
* @param {string} svg An SVG string. * @param {string} svg An SVG string.
* @returns {Promise<string>} An optimized svg * @returns {Promise<string>} An optimized svg
*/ */
function processSvg(svg) { function processSvg(svg, path) {
return ( return (
optimizeSvg(svg) optimizeSvg(svg, path)
.then(setAttrs) .then(setAttrs)
.then((optimizedSvg) => .then((optimizedSvg) =>
prettier.format(optimizedSvg, {parser: 'babel'}), prettier.format(optimizedSvg, {parser: 'babel'}),

2
site/.gitignore vendored
View File

@@ -1,2 +1,4 @@
.idea .idea
public/docs/images public/docs/images
.vercel
.env

View File

@@ -1,12 +1,13 @@
{ {
"name": "@lucide/site",
"private": true, "private": true,
"name": "site",
"version": "1.0.0", "version": "1.0.0",
"author": "John Letey", "author": "John Letey",
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
"copy-assets": "mkdir -p ./public/docs/images && cp -rf ../docs/images ./public/docs", "copy-assets": "mkdir -p ./public/docs/images && cp -rf ../docs/images ./public/docs",
"build": "pnpm copy-assets && next build", "prebuild": "ts-node --swc scripts/preBuild.ts",
"build": "pnpm copy-assets && pnpm prebuild && next build",
"export": "next export -o build", "export": "next export -o build",
"deploy": "pnpm build && pnpm export", "deploy": "pnpm build && pnpm export",
"lint": "eslint .", "lint": "eslint .",
@@ -36,10 +37,12 @@
"react": "17.0.2", "react": "17.0.2",
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"react-svg-loader": "^3.0.3" "react-svg-loader": "^3.0.3",
"svgson": "^5.2.1"
}, },
"devDependencies": { "devDependencies": {
"@next/eslint-plugin-next": "^12.2.5", "@next/eslint-plugin-next": "^12.2.5",
"@swc/core": "^1.3.35",
"@testing-library/dom": "^7.31.2", "@testing-library/dom": "^7.31.2",
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^11.2.7", "@testing-library/react": "^11.2.7",
@@ -55,8 +58,11 @@
"eslint": "^8.22.0", "eslint": "^8.22.0",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"jest": "^26.5.2", "jest": "^26.5.2",
"node-fetch": "2",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"react-test-renderer": "17.0.2", "react-test-renderer": "17.0.2",
"ts-node": "~10.9.1",
"tslib": "^2.4.0",
"typescript": "^4.3.5" "typescript": "^4.3.5"
} }
} }

17
site/scripts/preBuild.ts Normal file
View File

@@ -0,0 +1,17 @@
import {fetchTags} from "../src/lib/fetchTags";
import {fetchIconNodes} from "../src/lib/fetchIconNodes";
import NextCache from "../src/lib/nextCache";
const clearCache = async () => {
await NextCache.clear('api-tags', 'api-icon-nodes')
}
const buildCache = async () => {
await Promise.all([fetchTags(), fetchIconNodes()])
}
const rebuildCache = async () => {
await Promise.all([clearCache(), buildCache()])
}
rebuildCache().then(() => null)

View File

@@ -40,7 +40,6 @@ const Header = ({ data }: HeaderProps) => {
const { iconsRef } = useCustomizeIconContext(); const { iconsRef } = useCustomizeIconContext();
const downloadAllIcons = async () => { const downloadAllIcons = async () => {
console.log(iconsRef);
setZippingIcons(true); setZippingIcons(true);
let iconEntries: IconContent[] = Object.entries(iconsRef.current).map(([name, svgEl]) => [ let iconEntries: IconContent[] = Object.entries(iconsRef.current).map(([name, svgEl]) => [

View File

@@ -2,6 +2,7 @@ import crypto from 'crypto';
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { Contributor } from '../types'; import { Contributor } from '../types';
import fetch, { Headers } from 'node-fetch'
const IGNORE_COMMIT_MESSAGES = ['fork', 'optimize']; const IGNORE_COMMIT_MESSAGES = ['fork', 'optimize'];

View File

@@ -0,0 +1,15 @@
import NextCache from './nextCache';
import {parseSync} from 'svgson';
import {getAllData} from './icons';
export type IconNode = [string, object, IconNode[]];
export type IconNodes = {[iconName: string]: IconNode};
export function fetchIconNodes(writeCache = true): Promise<IconNodes> {
return NextCache.resolve('api-icon-nodes', async () => {
return (await getAllData()).reduce((acc, icon) => {
acc[icon.name] = parseSync(icon.src).children.map(({name, attributes}) => [name, attributes]);
return acc;
}, {});
}, writeCache);
}

View File

@@ -0,0 +1,13 @@
import NextCache from './nextCache';
import {getAllData} from './icons';
export type Tags = {[iconName: string]: string[]};
export function fetchTags(writeCache = true): Promise<Tags> {
return NextCache.resolve('api-tags', async () => {
return (await getAllData()).reduce((acc, icon) => {
acc[icon.name] = icon.tags;
return acc;
}, {});
}, writeCache);
}

View File

@@ -1,31 +1,32 @@
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import { parseSync } from 'svgson';
import tags from '../../../tags.json';
import { IconEntity } from "../types"; import { IconEntity } from "../types";
import { getContributors } from "./fetchAllContributors"; import { getContributors } from "./fetchAllContributors";
const directory = path.join(process.cwd(), "../icons"); const directory = path.join(process.cwd(), "../icons");
export function getAllNames() { export function getAllNames() {
const fileNames = fs.readdirSync(directory).filter((file) => path.extname(file) === '.svg'); const fileNames = fs.readdirSync(directory).filter((file) => path.extname(file) === '.json');
return fileNames.map((fileName) => { return fileNames
return fileName.replace(/\.svg$/, ""); .filter((fileName) => fs.existsSync(directory + '/' + path.basename(fileName, '.json') + '.svg'))
}); .map((fileName) => path.basename(fileName, '.json'));
} }
export async function getData(name: string) { export async function getData(name: string) {
const fullPath = path.join(directory, `${name}.svg`); const svgPath = path.join(directory, `${name}.svg`);
const fileContent = fs.readFileSync(fullPath, "utf8"); const svgContent = fs.readFileSync(svgPath, "utf8");
const jsonPath = path.join(directory, `${name}.json`);
const jsonContent = fs.readFileSync(jsonPath, "utf8");
const iconJson = JSON.parse(jsonContent);
const contributors = await getContributors(name); const contributors = await getContributors(name);
return { return {
...iconJson,
name, name,
tags: tags[name] || [],
contributors, contributors,
src: fileContent src: svgContent
}; };
} }

64
site/src/lib/nextCache.ts Normal file
View File

@@ -0,0 +1,64 @@
import path from 'path';
import fs from 'fs';
const cacheDir = path.join(process.cwd(), '.next/cache');
const nextDir = path.join(process.cwd(), '.next');
const cachePath = (cacheKey: string) => path.join(cacheDir, `${cacheKey}.json`);
type AtomicCacheable = object|string|number|boolean|null;
type Cacheable = AtomicCacheable|AtomicCacheable[];
if (!fs.existsSync(nextDir)) {
fs.mkdirSync(nextDir)
}
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir)
}
function read<T extends Cacheable>(cacheKey: string): T {
if (fs.existsSync(cachePath(cacheKey))) {
const iconCache = fs.readFileSync(cachePath(cacheKey), "utf8")
return JSON.parse(iconCache)
}
return null
}
function write<T extends Cacheable>(cacheKey: string, content: T): void {
if (!fs.existsSync(path.join(cacheDir, cacheKey))) {
fs.mkdirSync(path.join(cacheDir, cacheKey))
}
fs.writeFileSync(cachePath(cacheKey), JSON.stringify(content), 'utf-8')
}
function clear(...cacheKeys: string[]) {
for (const cacheKey of cacheKeys) {
const itemCachePath = cachePath(cacheKey)
if (fs.existsSync(itemCachePath)) {
fs.unlinkSync(itemCachePath)
}
}
}
async function resolve<T extends Cacheable>(cacheKey: string, contentResolver: () => Promise<T>|T, writeCache = true): Promise<T> {
try {
let cacheItem = await read<T>(cacheKey)
if (cacheItem === null) {
cacheItem = await contentResolver()
if (writeCache) {
write(cacheKey, cacheItem)
}
}
return cacheItem;
} catch (error) {
throw new Error(error)
}
}
const NextCache = {read, write, resolve, clear}
export default NextCache

View File

@@ -0,0 +1,8 @@
import {fetchIconNodes} from '../../../lib/fetchIconNodes';
export default async function handler(req, res) {
res.setHeader(
'Cache-Control',
'public, max-age=86400'
).status(200).json(await fetchIconNodes(false));
}

View File

@@ -0,0 +1,8 @@
import {fetchTags} from '../../../lib/fetchTags';
export default async function handler(req, res) {
res.setHeader(
'Cache-Control',
'public, max-age=86400'
).status(200).json(await fetchTags(false));
}

View File

@@ -1,5 +1,13 @@
{ {
"ts-node": {
"esm": true,
"compilerOptions": { "compilerOptions": {
"baseUrl": ".",
"module": "nodenext",
}
},
"compilerOptions": {
"baseUrl": ".",
"target": "ESNext", "target": "ESNext",
"lib": [ "lib": [
"dom", "dom",

4640
tags.json

File diff suppressed because it is too large Load Diff