From e2b46eac8eea8856313e88b9c93989db15b495e6 Mon Sep 17 00:00:00 2001 From: Karsa Date: Wed, 22 May 2024 13:08:34 +0200 Subject: [PATCH] feat(icons): add deprecationReason and alias deprecation feature (#1960) * feat(icons): add deprecationReason and alias deprecation feature * chore(tools): run prettier. again. * fix(scripts): overall alias as object support * fix(icon.schema.json): add dependentRequired on deprecated properties * fix(icon.schema.json): remove unicode for now * fix(icon.schema.json): use const true for deprecated * fix(build): convert deprecation reason to enum * fix(build): fix linting of icon.schema.json * fix(build): renamed gracePeriod => toBeRemovedInVersion * fix(build): fix aliases map in related icons generation * fix(build): deprecate aliases using numbers * feat(icon-schema): separate deprecation reason enumerations, extract removal notice * fix(icon-schema): fix linting * Update tools/build-icons/utils/deprecationReasonTemplate.mjs * fix(icons): add deprecation reason to some more icons * fix(docs): fix linting issue --------- Co-authored-by: Karsa Co-authored-by: Jakob Guddas --- docs/scripts/writeCategoriesMetadata.mjs | 3 +- icon.schema.json | 54 ++++++++++- icons/between-horizontal-end.json | 7 +- icons/between-horizontal-start.json | 7 +- icons/chrome.json | 2 + icons/circle-user-round.json | 7 +- icons/code-xml.json | 7 +- icons/codepen.json | 2 + icons/codesandbox.json | 2 + icons/contact-round.json | 7 +- icons/dribbble.json | 2 + icons/earth.json | 7 +- icons/facebook.json | 2 + icons/figma.json | 2 + icons/file-cog.json | 7 +- icons/folder-cog.json | 11 ++- icons/framer.json | 2 + icons/github.json | 2 + icons/gitlab.json | 2 + icons/ice-cream-bowl.json | 7 +- icons/instagram.json | 2 + icons/laptop-minimal.json | 7 +- icons/mic-vocal.json | 7 +- icons/pen-line.json | 7 +- icons/pen.json | 7 +- icons/pocket.json | 2 + icons/send-horizontal.json | 7 +- icons/slack.json | 2 + icons/square-user-round.json | 7 +- icons/trello.json | 2 + icons/twitch.json | 2 + icons/twitter.json | 2 + icons/university.json | 7 +- icons/user-round-check.json | 7 +- icons/user-round-cog.json | 7 +- icons/user-round-minus.json | 7 +- icons/user-round-plus.json | 7 +- icons/user-round-x.json | 7 +- icons/user-round.json | 7 +- icons/users-round.json | 7 +- icons/wallet-minimal.json | 7 +- icons/wand-sparkles.json | 7 +- icons/youtube.json | 2 + .../lucide-angular/scripts/exportTemplate.mjs | 4 +- .../lucide-preact/scripts/exportTemplate.mjs | 4 +- .../scripts/exportTemplate.mjs | 4 +- packages/lucide-react/package.json | 1 - .../lucide-react/scripts/exportTemplate.mjs | 4 +- .../scripts/getAliasesEntryNames.mjs | 4 +- .../lucide-solid/scripts/exportTemplate.mjs | 4 +- .../lucide-static/scripts/exportTemplate.mjs | 4 +- packages/lucide-svelte/scripts/buildTypes.mjs | 96 ------------------- .../lucide-svelte/scripts/exportTemplate.mjs | 4 +- .../scripts/exportTemplate.mjs | 4 +- .../lucide-vue/scripts/exportTemplate.mjs | 4 +- packages/lucide/scripts/exportTemplate.mjs | 4 +- scripts/generate/generateIcons.mjs | 2 + scripts/rename/renameIcon.function.mjs | 4 +- scripts/writeIconRelatedIcons.mjs | 5 +- scripts/writeReleaseMetadata.mjs | 20 ++-- .../building/generateAliasesFile.mjs | 45 +++++++-- .../building/generateIconFiles.mjs | 19 +++- .../utils/deprecationReasonTemplate.mjs | 17 ++++ 63 files changed, 352 insertions(+), 169 deletions(-) delete mode 100644 packages/lucide-svelte/scripts/buildTypes.mjs create mode 100644 tools/build-icons/utils/deprecationReasonTemplate.mjs diff --git a/docs/scripts/writeCategoriesMetadata.mjs b/docs/scripts/writeCategoriesMetadata.mjs index 45e87cb0ca..72492ddf36 100644 --- a/docs/scripts/writeCategoriesMetadata.mjs +++ b/docs/scripts/writeCategoriesMetadata.mjs @@ -23,7 +23,7 @@ function getAllCategoryFiles() { const categoriesFile = path.resolve(dataDirectory, `categoriesData.json`); -const categoriesData = getAllCategoryFiles() +const categoriesData = getAllCategoryFiles(); fs.promises .writeFile(categoriesFile, JSON.stringify(categoriesData, null, 2), 'utf-8') @@ -33,4 +33,3 @@ fs.promises .catch((error) => { throw new Error(`Something went wrong generating the categoriesData.json file,\n ${error}`); }); - diff --git a/icon.schema.json b/icon.schema.json index 075930077e..44026c3b8d 100644 --- a/icon.schema.json +++ b/icon.schema.json @@ -21,7 +21,32 @@ "aliases": { "type": "array", "items": { - "type": "string" + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "deprecated": { + "const": true + }, + "deprecationReason": { + "$ref": "#/$defs/aliasDeprecationReasons" + }, + "toBeRemovedInVersion": { + "$ref": "#/$defs/versionNumber", + "description": "The version this icon will be removed in." + } + }, + "dependentRequired": { + "deprecated": ["deprecationReason", "toBeRemovedInVersion"] + } + } + ] }, "uniqueItems": true }, @@ -49,8 +74,31 @@ "uniqueItems": true }, "deprecated": { - "type": "boolean", - "default": false + "const": true + }, + "deprecationReason": { + "$ref": "#/$defs/iconDeprecationReasons" + }, + "toBeRemovedInVersion": { + "$ref": "#/$defs/versionNumber", + "description": "The version this icon will be removed in." + } + }, + "dependentRequired": { + "deprecated": ["deprecationReason", "toBeRemovedInVersion"] + }, + "$defs": { + "iconDeprecationReasons": { + "type": "string", + "enum": ["icon.brand"] + }, + "aliasDeprecationReasons": { + "type": "string", + "enum": ["alias.typo", "alias.name"] + }, + "versionNumber": { + "type": "string", + "pattern": "v[0-9]+(\\.[0-9]+)+" } }, "description": "A JSON Schema for icons defined by Lucide Icons." diff --git a/icons/between-horizontal-end.json b/icons/between-horizontal-end.json index 507eca95c3..3421ae7146 100644 --- a/icons/between-horizontal-end.json +++ b/icons/between-horizontal-end.json @@ -33,6 +33,11 @@ "account" ], "aliases": [ - "between-horizonal-end" + { + "name": "between-horizonal-end", + "deprecated": true, + "deprecationReason": "alias.typo", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/between-horizontal-start.json b/icons/between-horizontal-start.json index c9d171ab68..c710705062 100644 --- a/icons/between-horizontal-start.json +++ b/icons/between-horizontal-start.json @@ -33,6 +33,11 @@ "account" ], "aliases": [ - "between-horizonal-start" + { + "name": "between-horizonal-start", + "deprecated": true, + "deprecationReason": "alias.typo", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/chrome.json b/icons/chrome.json index e07964cf5e..f3ac7389c3 100644 --- a/icons/chrome.json +++ b/icons/chrome.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "ericfennis" diff --git a/icons/circle-user-round.json b/icons/circle-user-round.json index 26a2c72c79..207d5f91ea 100644 --- a/icons/circle-user-round.json +++ b/icons/circle-user-round.json @@ -13,6 +13,11 @@ "shapes" ], "aliases": [ - "user-circle-2" + { + "name": "user-circle-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/code-xml.json b/icons/code-xml.json index addc1394a4..d4855e2951 100644 --- a/icons/code-xml.json +++ b/icons/code-xml.json @@ -15,6 +15,11 @@ "development" ], "aliases": [ - "code-2" + { + "name": "code-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/codepen.json b/icons/codepen.json index 05382b3df3..4cf193186c 100644 --- a/icons/codepen.json +++ b/icons/codepen.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "ericfennis" diff --git a/icons/codesandbox.json b/icons/codesandbox.json index e09a3e3c4a..6d90ae4c87 100644 --- a/icons/codesandbox.json +++ b/icons/codesandbox.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/contact-round.json b/icons/contact-round.json index 37340f9340..29cfaff2a5 100644 --- a/icons/contact-round.json +++ b/icons/contact-round.json @@ -19,6 +19,11 @@ "social" ], "aliases": [ - "contact-2" + { + "name": "contact-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/dribbble.json b/icons/dribbble.json index bf97ae40db..20899aeb2d 100644 --- a/icons/dribbble.json +++ b/icons/dribbble.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "ahtohbi4" ], diff --git a/icons/earth.json b/icons/earth.json index a97ab90d2e..912094ba68 100644 --- a/icons/earth.json +++ b/icons/earth.json @@ -17,6 +17,11 @@ "navigation" ], "aliases": [ - "globe-2" + { + "name": "globe-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/facebook.json b/icons/facebook.json index 67852e58f6..36924c7c43 100644 --- a/icons/facebook.json +++ b/icons/facebook.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/figma.json b/icons/figma.json index b75bf2ba0a..69145a2da2 100644 --- a/icons/figma.json +++ b/icons/figma.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/file-cog.json b/icons/file-cog.json index 78458b9cdf..213d85618d 100644 --- a/icons/file-cog.json +++ b/icons/file-cog.json @@ -15,6 +15,11 @@ "files" ], "aliases": [ - "file-cog-2" + { + "name": "file-cog-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/folder-cog.json b/icons/folder-cog.json index d14808362a..7e777fdd87 100644 --- a/icons/folder-cog.json +++ b/icons/folder-cog.json @@ -1,8 +1,5 @@ { "$schema": "../icon.schema.json", - "aliases": [ - "folder-cog-2" - ], "contributors": [ "karsa-mistmere" ], @@ -17,5 +14,13 @@ ], "categories": [ "files" + ], + "aliases": [ + { + "name": "folder-cog-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/framer.json b/icons/framer.json index b75bf2ba0a..69145a2da2 100644 --- a/icons/framer.json +++ b/icons/framer.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/github.json b/icons/github.json index 0111ffd989..b4a87aaed1 100644 --- a/icons/github.json +++ b/icons/github.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/gitlab.json b/icons/gitlab.json index 0111ffd989..b4a87aaed1 100644 --- a/icons/gitlab.json +++ b/icons/gitlab.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/ice-cream-bowl.json b/icons/ice-cream-bowl.json index 5e8e616688..4e46b33096 100644 --- a/icons/ice-cream-bowl.json +++ b/icons/ice-cream-bowl.json @@ -19,6 +19,11 @@ "food-beverage" ], "aliases": [ - "ice-cream-2" + { + "name": "ice-cream-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/instagram.json b/icons/instagram.json index f8f9dc404b..ca04380b9b 100644 --- a/icons/instagram.json +++ b/icons/instagram.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/laptop-minimal.json b/icons/laptop-minimal.json index 982c155ecc..a6fe37a069 100644 --- a/icons/laptop-minimal.json +++ b/icons/laptop-minimal.json @@ -12,6 +12,11 @@ "devices" ], "aliases": [ - "laptop-2" + { + "name": "laptop-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/mic-vocal.json b/icons/mic-vocal.json index bd139b364e..bdad3d573e 100644 --- a/icons/mic-vocal.json +++ b/icons/mic-vocal.json @@ -22,6 +22,11 @@ "multimedia" ], "aliases": [ - "mic-2" + { + "name": "mic-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/pen-line.json b/icons/pen-line.json index 22b17bab53..366bc58083 100644 --- a/icons/pen-line.json +++ b/icons/pen-line.json @@ -26,6 +26,11 @@ "tools" ], "aliases": [ - "edit-3" + { + "name": "edit-3", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/pen.json b/icons/pen.json index 3a9929f12b..bc5bc539fb 100644 --- a/icons/pen.json +++ b/icons/pen.json @@ -26,6 +26,11 @@ "tools" ], "aliases": [ - "edit-2" + { + "name": "edit-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/pocket.json b/icons/pocket.json index f2df830a56..2889d865ec 100644 --- a/icons/pocket.json +++ b/icons/pocket.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/send-horizontal.json b/icons/send-horizontal.json index 35a8fd0977..9eb146056c 100644 --- a/icons/send-horizontal.json +++ b/icons/send-horizontal.json @@ -17,6 +17,11 @@ "connectivity" ], "aliases": [ - "send-horizonal" + { + "name": "send-horizonal", + "deprecated": true, + "deprecationReason": "alias.typo", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/slack.json b/icons/slack.json index 93a1ff1aa1..ba0e2972cf 100644 --- a/icons/slack.json +++ b/icons/slack.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "ashygee", diff --git a/icons/square-user-round.json b/icons/square-user-round.json index 54b8c259ec..8604fccac9 100644 --- a/icons/square-user-round.json +++ b/icons/square-user-round.json @@ -13,6 +13,11 @@ "shapes" ], "aliases": [ - "user-square-2" + { + "name": "user-square-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/trello.json b/icons/trello.json index bdda0eeff4..6ea13c4be4 100644 --- a/icons/trello.json +++ b/icons/trello.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "bdbch", "csandman", diff --git a/icons/twitch.json b/icons/twitch.json index fe163ceb12..3be0b8d51f 100644 --- a/icons/twitch.json +++ b/icons/twitch.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "ahtohbi4", "johnletey" diff --git a/icons/twitter.json b/icons/twitter.json index 52003f2003..9f5fd78a59 100644 --- a/icons/twitter.json +++ b/icons/twitter.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/icons/university.json b/icons/university.json index 56c5077511..57c37261e9 100644 --- a/icons/university.json +++ b/icons/university.json @@ -14,6 +14,11 @@ "maps" ], "aliases": [ - "school-2" + { + "name": "school-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/user-round-check.json b/icons/user-round-check.json index 5cfc6b102b..76834d1356 100644 --- a/icons/user-round-check.json +++ b/icons/user-round-check.json @@ -16,6 +16,11 @@ "account" ], "aliases": [ - "user-check-2" + { + "name": "user-check-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/user-round-cog.json b/icons/user-round-cog.json index 03c6ce6a34..b9dfbfbb6a 100644 --- a/icons/user-round-cog.json +++ b/icons/user-round-cog.json @@ -13,6 +13,11 @@ "account" ], "aliases": [ - "user-cog-2" + { + "name": "user-cog-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/user-round-minus.json b/icons/user-round-minus.json index 3a504685f6..1f0d134d32 100644 --- a/icons/user-round-minus.json +++ b/icons/user-round-minus.json @@ -13,6 +13,11 @@ "account" ], "aliases": [ - "user-minus-2" + { + "name": "user-minus-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/user-round-plus.json b/icons/user-round-plus.json index acad3e4cd7..6269a5dcf4 100644 --- a/icons/user-round-plus.json +++ b/icons/user-round-plus.json @@ -14,6 +14,11 @@ "account" ], "aliases": [ - "user-plus-2" + { + "name": "user-plus-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/user-round-x.json b/icons/user-round-x.json index 2a63f698df..e0aa5928c7 100644 --- a/icons/user-round-x.json +++ b/icons/user-round-x.json @@ -14,6 +14,11 @@ "account" ], "aliases": [ - "user-x-2" + { + "name": "user-x-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/user-round.json b/icons/user-round.json index cd056c2dd3..e7d296de43 100644 --- a/icons/user-round.json +++ b/icons/user-round.json @@ -12,6 +12,11 @@ "account" ], "aliases": [ - "user-2" + { + "name": "user-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/users-round.json b/icons/users-round.json index a8b824740a..04e53ff094 100644 --- a/icons/users-round.json +++ b/icons/users-round.json @@ -11,6 +11,11 @@ "account" ], "aliases": [ - "users-2" + { + "name": "users-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/wallet-minimal.json b/icons/wallet-minimal.json index 4ab5c43563..f1d8ba3c6a 100644 --- a/icons/wallet-minimal.json +++ b/icons/wallet-minimal.json @@ -12,6 +12,11 @@ "money" ], "aliases": [ - "wallet-2" + { + "name": "wallet-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/wand-sparkles.json b/icons/wand-sparkles.json index 81b302652a..15a673c482 100644 --- a/icons/wand-sparkles.json +++ b/icons/wand-sparkles.json @@ -15,6 +15,11 @@ "photography" ], "aliases": [ - "wand-2" + { + "name": "wand-2", + "deprecated": true, + "deprecationReason": "alias.name", + "toBeRemovedInVersion": "v1.0" + } ] } diff --git a/icons/youtube.json b/icons/youtube.json index ead7e1d033..0b32378126 100644 --- a/icons/youtube.json +++ b/icons/youtube.json @@ -1,6 +1,8 @@ { "$schema": "../icon.schema.json", "deprecated": true, + "deprecationReason": "icon.brand", + "toBeRemovedInVersion": "v1.0", "contributors": [ "colebemis", "csandman", diff --git a/packages/lucide-angular/scripts/exportTemplate.mjs b/packages/lucide-angular/scripts/exportTemplate.mjs index a412a23fbe..2dee463dde 100644 --- a/packages/lucide-angular/scripts/exportTemplate.mjs +++ b/packages/lucide-angular/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -17,7 +17,7 @@ import { LucideIconData } from './types'; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {FunctionalComponent} Vue component - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName}: LucideIconData = ${JSON.stringify(children)}; //eslint-disable-line no-shadow-restricted-names diff --git a/packages/lucide-preact/scripts/exportTemplate.mjs b/packages/lucide-preact/scripts/exportTemplate.mjs index 857ce67cca..06b9c7f128 100644 --- a/packages/lucide-preact/scripts/exportTemplate.mjs +++ b/packages/lucide-preact/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon'; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {JSX.Element} JSX Element - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); diff --git a/packages/lucide-react-native/scripts/exportTemplate.mjs b/packages/lucide-react-native/scripts/exportTemplate.mjs index ad1051c2a9..3379b66eb4 100644 --- a/packages/lucide-react-native/scripts/exportTemplate.mjs +++ b/packages/lucide-react-native/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon'; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {JSX.Element} JSX Element - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); diff --git a/packages/lucide-react/package.json b/packages/lucide-react/package.json index e453e374f7..53a52d378b 100644 --- a/packages/lucide-react/package.json +++ b/packages/lucide-react/package.json @@ -40,7 +40,6 @@ "copy:license": "cp ../../LICENSE ./LICENSE", "clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.ts && rm -f dynamicIconImports.*", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --withDynamicImports --separateAliasesFile --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts", - "build:types": "node ./scripts/buildTypes.mjs", "build:bundles": "rollup -c ./rollup.config.mjs", "typecheck": "tsc", "typecheck:watch": "tsc -w", diff --git a/packages/lucide-react/scripts/exportTemplate.mjs b/packages/lucide-react/scripts/exportTemplate.mjs index 7ccb638e74..e6fd638fa8 100644 --- a/packages/lucide-react/scripts/exportTemplate.mjs +++ b/packages/lucide-react/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon'; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {JSX.Element} JSX Element - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); diff --git a/packages/lucide-react/scripts/getAliasesEntryNames.mjs b/packages/lucide-react/scripts/getAliasesEntryNames.mjs index e67c535abd..3f634c2eeb 100644 --- a/packages/lucide-react/scripts/getAliasesEntryNames.mjs +++ b/packages/lucide-react/scripts/getAliasesEntryNames.mjs @@ -11,5 +11,7 @@ export default async function getAliasesEntryNames() { const aliases = iconWithAliases.flatMap(({ aliases }) => aliases); - return aliases.map((alias) => path.join('src/icons', `${alias}.ts`)); + return aliases + .map((alias) => (typeof alias === 'string' ? alias : alias.name)) + .map((alias) => path.join('src/icons', `${alias}.ts`)); } diff --git a/packages/lucide-solid/scripts/exportTemplate.mjs b/packages/lucide-solid/scripts/exportTemplate.mjs index 72385eb338..b71d4bd1a4 100644 --- a/packages/lucide-solid/scripts/exportTemplate.mjs +++ b/packages/lucide-solid/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -20,7 +20,7 @@ const iconNode: IconNode = ${JSON.stringify(children)}; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {JSX.Element} JSX Element - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName} = (props: LucideProps) => ( diff --git a/packages/lucide-static/scripts/exportTemplate.mjs b/packages/lucide-static/scripts/exportTemplate.mjs index 42e7a5f5f0..2ef67ca54c 100644 --- a/packages/lucide-static/scripts/exportTemplate.mjs +++ b/packages/lucide-static/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { let svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -21,7 +21,7 @@ export default ({ componentName, iconName, children, getSvg, deprecated }) => { * @see https://lucide.dev/guide/packages/lucide-static - Documentation * * @returns {String} - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName}: string = \`\ ${svgContents}\ diff --git a/packages/lucide-svelte/scripts/buildTypes.mjs b/packages/lucide-svelte/scripts/buildTypes.mjs deleted file mode 100644 index 5bd29df771..0000000000 --- a/packages/lucide-svelte/scripts/buildTypes.mjs +++ /dev/null @@ -1,96 +0,0 @@ -import path from 'path'; -// eslint-disable-next-line import/no-extraneous-dependencies -import { getAliases } from '@lucide/build-icons'; -import { - writeFile, - readSvgDirectory, - resetFile, - toPascalCase, - getCurrentDirPath, -} from '../../../scripts/helpers.mjs'; - -const currentDir = getCurrentDirPath(import.meta.url); -const targetDirectory = path.join(currentDir, '../dist'); - -const writeDeclarationFile = (typesFile, directory, content) => { - resetFile(typesFile, directory); - writeFile(content, typesFile, directory); -}; - -const getComponentImport = (componentName) => - `export declare class ${componentName} extends SvelteComponent {}\n`; - -const ICONS_DIR = path.resolve(currentDir, '../../../icons'); -const TYPES_FILE = 'lucide-svelte.d.ts'; - -// Declare type definitions -let declarationFileContent = `\ -/// -/// -import { SvelteComponent } from "svelte"; - -interface IconProps extends Partial> { - color?: string - size?: number|string - strokeWidth?: number|string - absoluteStrokeWidth?: boolean - class?: string -} - -interface IconEvents { - [evt: string]: CustomEvent; -} - -export type Icon = SvelteComponent - -// Generated icons -`; - -const svgFiles = readSvgDirectory(ICONS_DIR); - -svgFiles.forEach((svgFile) => { - const iconName = path.basename(svgFile, '.svg'); - const componentName = toPascalCase(iconName); - - declarationFileContent += getComponentImport(componentName); -}); - -const aliases = await getAliases(ICONS_DIR); - -declarationFileContent += `\n - -// Generated icon aliases -`; - -let aliasesCount = 0; - -svgFiles.forEach((svgFile) => { - const iconName = path.basename(svgFile, '.svg'); - const componentName = toPascalCase(iconName); - const iconAliases = aliases[iconName]?.aliases; - - declarationFileContent += `// ${componentName} aliases\n`; - declarationFileContent += getComponentImport(`${componentName}Icon`); - declarationFileContent += getComponentImport(`Lucide${componentName}`); - - aliasesCount += 1; - if (iconAliases != null && Array.isArray(iconAliases)) { - iconAliases.forEach((alias) => { - const componentNameAlias = toPascalCase(alias); - declarationFileContent += getComponentImport(componentNameAlias); - - aliasesCount += 1; - }); - } - - declarationFileContent += '\n'; -}); - -writeDeclarationFile(TYPES_FILE, targetDirectory, declarationFileContent); -console.log( - `Generated ${TYPES_FILE} file with`, - svgFiles.length, - 'icons and with', - aliasesCount, - 'aliases', -); diff --git a/packages/lucide-svelte/scripts/exportTemplate.mjs b/packages/lucide-svelte/scripts/exportTemplate.mjs index afeff30a36..6dfd135435 100644 --- a/packages/lucide-svelte/scripts/exportTemplate.mjs +++ b/packages/lucide-svelte/scripts/exportTemplate.mjs @@ -2,7 +2,7 @@ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; import { getJSBanner } from './license.mjs'; -export default ({ iconName, children, componentName, getSvg, deprecated }) => { +export default ({ iconName, children, componentName, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -25,7 +25,7 @@ const iconNode: IconNode = ${JSON.stringify(children)}; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {FunctionalComponent} Svelte component - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ diff --git a/packages/lucide-vue-next/scripts/exportTemplate.mjs b/packages/lucide-vue-next/scripts/exportTemplate.mjs index 1c22ec9b1a..dde84202ac 100644 --- a/packages/lucide-vue-next/scripts/exportTemplate.mjs +++ b/packages/lucide-vue-next/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon'; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {FunctionalComponent} Vue component - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)}); diff --git a/packages/lucide-vue/scripts/exportTemplate.mjs b/packages/lucide-vue/scripts/exportTemplate.mjs index b58291f797..4241b7f382 100644 --- a/packages/lucide-vue/scripts/exportTemplate.mjs +++ b/packages/lucide-vue/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon'; * * @param {Object} props - Lucide icons props and any valid SVG attribute * @returns {Component} Vue Component - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)}); diff --git a/packages/lucide/scripts/exportTemplate.mjs b/packages/lucide/scripts/exportTemplate.mjs index bcd2ee9423..910dca9576 100644 --- a/packages/lucide/scripts/exportTemplate.mjs +++ b/packages/lucide/scripts/exportTemplate.mjs @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; -export default ({ componentName, iconName, children, getSvg, deprecated }) => { +export default ({ componentName, iconName, children, getSvg, deprecated, deprecationReason }) => { const svgContents = getSvg(); const svgBase64 = base64SVG(svgContents); @@ -17,7 +17,7 @@ import type { IconNode } from '../types'; * @see https://lucide.dev/guide/packages/lucide - Documentation * * @returns {Array} - * ${deprecated ? '@deprecated' : ''} + * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName}: IconNode = [ 'svg', diff --git a/scripts/generate/generateIcons.mjs b/scripts/generate/generateIcons.mjs index 672c2d30bb..b9eca03a05 100644 --- a/scripts/generate/generateIcons.mjs +++ b/scripts/generate/generateIcons.mjs @@ -22,6 +22,8 @@ const iconSvgTemplate = ` name !== newName); + jsonData.aliases = jsonData.aliases.filter( + (alias) => (typeof alias === 'string' ? alias : alias.name) !== newName, + ); jsonData.aliases.push(oldName); } else { jsonData.aliases = [oldName]; diff --git a/scripts/writeIconRelatedIcons.mjs b/scripts/writeIconRelatedIcons.mjs index 0fca01f191..f38b84b7b5 100644 --- a/scripts/writeIconRelatedIcons.mjs +++ b/scripts/writeIconRelatedIcons.mjs @@ -30,7 +30,10 @@ const arrayMatches = (a, b) => { }; const nameParts = (icon) => - [icon.name, ...(icon.aliases ?? [])] + [ + icon.name, + ...(icon.aliases?.map((alias) => (typeof alias === 'string' ? alias : alias.name)) ?? []), + ] .join('-') .split('-') .filter((word) => word.length > 2); diff --git a/scripts/writeReleaseMetadata.mjs b/scripts/writeReleaseMetadata.mjs index ba19c85e28..4cc3f89422 100644 --- a/scripts/writeReleaseMetadata.mjs +++ b/scripts/writeReleaseMetadata.mjs @@ -145,7 +145,7 @@ try { const iconName = path.basename(iconJsonFile, '.json'); const metaDir = path.resolve(releaseMetaDataDirectory, `${iconName}.json`); - if (iconName in newReleaseMetaData === false) { + if (!(iconName in newReleaseMetaData)) { console.error(`Could not find release metadata for icon '${iconName}'.`); } @@ -159,14 +159,16 @@ try { const aliases = iconMetaData.aliases ?? []; if (aliases.length) { - aliases.forEach((alias) => { - if (alias in newReleaseMetaData === false) { - return; - } - - contents.createdRelease = - newReleaseMetaData[alias].createdRelease ?? defaultReleaseMetaData.createdRelease; - }); + aliases + .map((alias) => (typeof alias === 'string' ? alias : alias.name)) + .forEach((alias) => { + if (!(alias in newReleaseMetaData)) { + return; + } + + contents.createdRelease = + newReleaseMetaData[alias].createdRelease ?? defaultReleaseMetaData.createdRelease; + }); } const output = JSON.stringify(contents, null, 2); diff --git a/tools/build-icons/building/generateAliasesFile.mjs b/tools/build-icons/building/generateAliasesFile.mjs index 73517281cd..54876105a8 100644 --- a/tools/build-icons/building/generateAliasesFile.mjs +++ b/tools/build-icons/building/generateAliasesFile.mjs @@ -1,9 +1,21 @@ import path from 'path'; import fs from 'fs'; import { toPascalCase, resetFile, appendFile } from '../../../scripts/helpers.mjs'; +import { deprecationReasonTemplate } from '../utils/deprecationReasonTemplate.mjs'; -const getImportString = (componentName, iconName, aliasImportFileExtension = '') => - `export { default as ${componentName} } from './icons/${iconName}${aliasImportFileExtension}';\n`; +const getImportString = ( + componentName, + iconName, + aliasImportFileExtension, + deprecated, + deprecationReason = '', +) => + deprecated + ? `export {\n` + + ` /** @deprecated ${deprecationReason} */\n` + + ` default as ${componentName}\n` + + `} from './icons/${iconName}${aliasImportFileExtension}';\n` + : `export { default as ${componentName} } from './icons/${iconName}${aliasImportFileExtension}';\n`; export default async function generateAliasesFile({ iconNodes, @@ -27,7 +39,15 @@ export default async function generateAliasesFile({ await Promise.all( icons.map(async (iconName, index) => { const componentName = toPascalCase(iconName); - const iconAliases = iconMetaData[iconName]?.aliases; + const iconAliases = iconMetaData[iconName]?.aliases?.map((alias) => { + if (typeof alias === 'string') { + return { + name: alias, + deprecated: false, + }; + } + return alias; + }); let importString = ''; @@ -51,11 +71,18 @@ export default async function generateAliasesFile({ if (iconAliases != null && Array.isArray(iconAliases)) { await Promise.all( iconAliases.map(async (alias) => { - const componentNameAlias = toPascalCase(alias); + const componentNameAlias = toPascalCase(alias.name); + const deprecationReason = alias.deprecated + ? deprecationReasonTemplate(alias.deprecationReason, { + componentName: toPascalCase(iconName), + iconName, + toBeRemovedInVersion: alias.toBeRemovedInVersion, + }) + : ''; if (separateAliasesFile) { const output = `export { default } from "./${iconName}"`; - const location = path.join(iconsDistDirectory, `${alias}${iconFileExtension}`); + const location = path.join(iconsDistDirectory, `${alias.name}${iconFileExtension}`); await fs.promises.writeFile(location, output, 'utf-8'); } @@ -65,12 +92,14 @@ export default async function generateAliasesFile({ return; } - const exportFileIcon = separateAliasesFile ? alias : iconName; + const exportFileIcon = separateAliasesFile ? alias.name : iconName; importString += getImportString( componentNameAlias, exportFileIcon, aliasImportFileExtension, + alias.deprecated, + deprecationReason, ); if (!aliasNamesOnly) { @@ -78,12 +107,16 @@ export default async function generateAliasesFile({ `${componentNameAlias}Icon`, exportFileIcon, aliasImportFileExtension, + alias.deprecated, + deprecationReason, ); importString += getImportString( `Lucide${componentNameAlias}`, exportFileIcon, aliasImportFileExtension, + alias.deprecated, + deprecationReason, ); } }), diff --git a/tools/build-icons/building/generateIconFiles.mjs b/tools/build-icons/building/generateIconFiles.mjs index b4f04b6bd4..d7453d1f13 100644 --- a/tools/build-icons/building/generateIconFiles.mjs +++ b/tools/build-icons/building/generateIconFiles.mjs @@ -2,6 +2,7 @@ import fs from 'fs'; import path from 'path'; import prettier from 'prettier'; import { readSvg, toPascalCase } from '../../../scripts/helpers.mjs'; +import { deprecationReasonTemplate } from '../utils/deprecationReasonTemplate.mjs'; export default ({ iconNodes, @@ -28,9 +29,23 @@ export default ({ children = children.map(({ name, attributes }) => [name, attributes]); const getSvg = () => readSvg(`${iconName}.svg`, iconsDir); - const { deprecated = false } = iconMetaData[iconName]; + const { deprecated = false, toBeRemovedInVersion = null } = iconMetaData[iconName]; + const deprecationReason = deprecated + ? deprecationReasonTemplate(iconMetaData[iconName].deprecationReason, { + componentName, + iconName, + toBeRemovedInVersion, + }) + : ''; - const elementTemplate = template({ componentName, iconName, children, getSvg, deprecated }); + const elementTemplate = template({ + componentName, + iconName, + children, + getSvg, + deprecated, + deprecationReason, + }); const output = pretty ? prettier.format(elementTemplate, { singleQuote: true, diff --git a/tools/build-icons/utils/deprecationReasonTemplate.mjs b/tools/build-icons/utils/deprecationReasonTemplate.mjs new file mode 100644 index 0000000000..a36ebbbebe --- /dev/null +++ b/tools/build-icons/utils/deprecationReasonTemplate.mjs @@ -0,0 +1,17 @@ +export function deprecationReasonTemplate( + deprecationReason, + { componentName, iconName, toBeRemovedInVersion }, +) { + const removalNotice = toBeRemovedInVersion + ? ` This ${deprecationReason.startsWith('icon') ? 'icon' : 'alias'} will be removed in ${toBeRemovedInVersion}` + : ''; + + switch (deprecationReason) { + case 'alias.typo': + return `Renamed because of typo, use {@link ${componentName}} instead.${removalNotice}`; + case 'alias.naming': + return `The name of this icon was changed because it didn't meet our guidelines anymore, use {@link ${componentName}} instead.${removalNotice}`; + case 'icon.brand': + return `Brand icons have been deprecated and are due to be removed, please refer to https://github.com/lucide-icons/lucide/issues/670. We recommend using https://simpleicons.org/?q=${iconName} instead.${removalNotice}`; + } +}