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 <karsa@sztaki.hu>
Co-authored-by: Jakob Guddas <github@jguddas.de>
This commit is contained in:
Karsa
2024-05-22 13:08:34 +02:00
committed by GitHub
parent 1b3173b17b
commit e2b46eac8e
63 changed files with 351 additions and 168 deletions

View File

@@ -23,7 +23,7 @@ function getAllCategoryFiles() {
const categoriesFile = path.resolve(dataDirectory, `categoriesData.json`); const categoriesFile = path.resolve(dataDirectory, `categoriesData.json`);
const categoriesData = getAllCategoryFiles() const categoriesData = getAllCategoryFiles();
fs.promises fs.promises
.writeFile(categoriesFile, JSON.stringify(categoriesData, null, 2), 'utf-8') .writeFile(categoriesFile, JSON.stringify(categoriesData, null, 2), 'utf-8')
@@ -33,4 +33,3 @@ fs.promises
.catch((error) => { .catch((error) => {
throw new Error(`Something went wrong generating the categoriesData.json file,\n ${error}`); throw new Error(`Something went wrong generating the categoriesData.json file,\n ${error}`);
}); });

View File

@@ -21,7 +21,32 @@
"aliases": { "aliases": {
"type": "array", "type": "array",
"items": { "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 "uniqueItems": true
}, },
@@ -49,8 +74,31 @@
"uniqueItems": true "uniqueItems": true
}, },
"deprecated": { "deprecated": {
"type": "boolean", "const": true
"default": false },
"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." "description": "A JSON Schema for icons defined by Lucide Icons."

View File

@@ -33,6 +33,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"between-horizonal-end" {
"name": "between-horizonal-end",
"deprecated": true,
"deprecationReason": "alias.typo",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -33,6 +33,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"between-horizonal-start" {
"name": "between-horizonal-start",
"deprecated": true,
"deprecationReason": "alias.typo",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"ericfennis" "ericfennis"

View File

@@ -13,6 +13,11 @@
"shapes" "shapes"
], ],
"aliases": [ "aliases": [
"user-circle-2" {
"name": "user-circle-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -15,6 +15,11 @@
"development" "development"
], ],
"aliases": [ "aliases": [
"code-2" {
"name": "code-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"ericfennis" "ericfennis"

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -19,6 +19,11 @@
"social" "social"
], ],
"aliases": [ "aliases": [
"contact-2" {
"name": "contact-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"ahtohbi4" "ahtohbi4"
], ],

View File

@@ -17,6 +17,11 @@
"navigation" "navigation"
], ],
"aliases": [ "aliases": [
"globe-2" {
"name": "globe-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -15,6 +15,11 @@
"files" "files"
], ],
"aliases": [ "aliases": [
"file-cog-2" {
"name": "file-cog-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,8 +1,5 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"aliases": [
"folder-cog-2"
],
"contributors": [ "contributors": [
"karsa-mistmere" "karsa-mistmere"
], ],
@@ -17,5 +14,13 @@
], ],
"categories": [ "categories": [
"files" "files"
],
"aliases": [
{
"name": "folder-cog-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -19,6 +19,11 @@
"food-beverage" "food-beverage"
], ],
"aliases": [ "aliases": [
"ice-cream-2" {
"name": "ice-cream-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -12,6 +12,11 @@
"devices" "devices"
], ],
"aliases": [ "aliases": [
"laptop-2" {
"name": "laptop-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -22,6 +22,11 @@
"multimedia" "multimedia"
], ],
"aliases": [ "aliases": [
"mic-2" {
"name": "mic-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -26,6 +26,11 @@
"tools" "tools"
], ],
"aliases": [ "aliases": [
"edit-3" {
"name": "edit-3",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -26,6 +26,11 @@
"tools" "tools"
], ],
"aliases": [ "aliases": [
"edit-2" {
"name": "edit-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -17,6 +17,11 @@
"connectivity" "connectivity"
], ],
"aliases": [ "aliases": [
"send-horizonal" {
"name": "send-horizonal",
"deprecated": true,
"deprecationReason": "alias.typo",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"ashygee", "ashygee",

View File

@@ -13,6 +13,11 @@
"shapes" "shapes"
], ],
"aliases": [ "aliases": [
"user-square-2" {
"name": "user-square-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"bdbch", "bdbch",
"csandman", "csandman",

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"ahtohbi4", "ahtohbi4",
"johnletey" "johnletey"

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -14,6 +14,11 @@
"maps" "maps"
], ],
"aliases": [ "aliases": [
"school-2" {
"name": "school-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -16,6 +16,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"user-check-2" {
"name": "user-check-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -13,6 +13,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"user-cog-2" {
"name": "user-cog-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -13,6 +13,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"user-minus-2" {
"name": "user-minus-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -14,6 +14,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"user-plus-2" {
"name": "user-plus-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -14,6 +14,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"user-x-2" {
"name": "user-x-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -12,6 +12,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"user-2" {
"name": "user-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -11,6 +11,11 @@
"account" "account"
], ],
"aliases": [ "aliases": [
"users-2" {
"name": "users-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -12,6 +12,11 @@
"money" "money"
], ],
"aliases": [ "aliases": [
"wallet-2" {
"name": "wallet-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -15,6 +15,11 @@
"photography" "photography"
], ],
"aliases": [ "aliases": [
"wand-2" {
"name": "wand-2",
"deprecated": true,
"deprecationReason": "alias.name",
"toBeRemovedInVersion": "v1.0"
}
] ]
} }

View File

@@ -1,6 +1,8 @@
{ {
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"deprecated": true, "deprecated": true,
"deprecationReason": "icon.brand",
"toBeRemovedInVersion": "v1.0",
"contributors": [ "contributors": [
"colebemis", "colebemis",
"csandman", "csandman",

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -17,7 +17,7 @@ import { LucideIconData } from './types';
* *
* @param {Object} props - Lucide icons props and any valid SVG attribute * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {FunctionalComponent} Vue component * @returns {FunctionalComponent} Vue component
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName}: LucideIconData = ${JSON.stringify(children)}; //eslint-disable-line no-shadow-restricted-names const ${componentName}: LucideIconData = ${JSON.stringify(children)}; //eslint-disable-line no-shadow-restricted-names

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon';
* *
* @param {Object} props - Lucide icons props and any valid SVG attribute * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element * @returns {JSX.Element} JSX Element
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)});

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon';
* *
* @param {Object} props - Lucide icons props and any valid SVG attribute * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element * @returns {JSX.Element} JSX Element
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)});

View File

@@ -40,7 +40,6 @@
"copy:license": "cp ../../LICENSE ./LICENSE", "copy:license": "cp ../../LICENSE ./LICENSE",
"clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.ts && rm -f dynamicIconImports.*", "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: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", "build:bundles": "rollup -c ./rollup.config.mjs",
"typecheck": "tsc", "typecheck": "tsc",
"typecheck:watch": "tsc -w", "typecheck:watch": "tsc -w",

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon';
* *
* @param {Object} props - Lucide icons props and any valid SVG attribute * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element * @returns {JSX.Element} JSX Element
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)});

View File

@@ -11,5 +11,7 @@ export default async function getAliasesEntryNames() {
const aliases = iconWithAliases.flatMap(({ aliases }) => aliases); 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`));
} }

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); 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 * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {JSX.Element} JSX Element * @returns {JSX.Element} JSX Element
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName} = (props: LucideProps) => ( const ${componentName} = (props: LucideProps) => (
<Icon {...props} name="${componentName}" iconNode={iconNode} /> <Icon {...props} name="${componentName}" iconNode={iconNode} />

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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(); let svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -21,7 +21,7 @@ export default ({ componentName, iconName, children, getSvg, deprecated }) => {
* @see https://lucide.dev/guide/packages/lucide-static - Documentation * @see https://lucide.dev/guide/packages/lucide-static - Documentation
* *
* @returns {String} * @returns {String}
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName}: string = \`\ const ${componentName}: string = \`\
${svgContents}\ ${svgContents}\

View File

@@ -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<IconProps, IconEvents, {}> {}\n`;
const ICONS_DIR = path.resolve(currentDir, '../../../icons');
const TYPES_FILE = 'lucide-svelte.d.ts';
// Declare type definitions
let declarationFileContent = `\
/// <reference types="svelte" />
/// <reference types="svelte-check/dist/src/svelte-jsx" />
import { SvelteComponent } from "svelte";
interface IconProps extends Partial<svelte.JSX.SVGProps<SVGSVGElement>> {
color?: string
size?: number|string
strokeWidth?: number|string
absoluteStrokeWidth?: boolean
class?: string
}
interface IconEvents {
[evt: string]: CustomEvent<any>;
}
export type Icon = SvelteComponent<IconProps, IconEvents, {}>
// 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',
);

View File

@@ -2,7 +2,7 @@
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
import { getJSBanner } from './license.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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); 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 * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {FunctionalComponent} Svelte component * @returns {FunctionalComponent} Svelte component
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
</script> </script>

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon';
* *
* @param {Object} props - Lucide icons props and any valid SVG attribute * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {FunctionalComponent} Vue component * @returns {FunctionalComponent} Vue component
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)}); const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)});

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -17,7 +17,7 @@ import createLucideIcon from '../createLucideIcon';
* *
* @param {Object} props - Lucide icons props and any valid SVG attribute * @param {Object} props - Lucide icons props and any valid SVG attribute
* @returns {Component} Vue Component * @returns {Component} Vue Component
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)}); const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)});

View File

@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable import/no-extraneous-dependencies */
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; 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 svgContents = getSvg();
const svgBase64 = base64SVG(svgContents); const svgBase64 = base64SVG(svgContents);
@@ -17,7 +17,7 @@ import type { IconNode } from '../types';
* @see https://lucide.dev/guide/packages/lucide - Documentation * @see https://lucide.dev/guide/packages/lucide - Documentation
* *
* @returns {Array} * @returns {Array}
* ${deprecated ? '@deprecated' : ''} * ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/ */
const ${componentName}: IconNode = [ const ${componentName}: IconNode = [
'svg', 'svg',

View File

@@ -22,6 +22,8 @@ const iconSvgTemplate = `<svg
const iconJsonTemplate = `{ const iconJsonTemplate = `{
"$schema": "../icon.schema.json", "$schema": "../icon.schema.json",
"contributors": [
],
"tags": [ "tags": [
], ],
"categories": [ "categories": [

View File

@@ -46,7 +46,9 @@ export async function renameIcon(ICONS_DIR, oldName, newName, logInfo = true, ad
const json = fs.readFileSync(newJsonPath, 'utf8'); const json = fs.readFileSync(newJsonPath, 'utf8');
const jsonData = JSON.parse(json); const jsonData = JSON.parse(json);
if (Array.isArray(jsonData.aliases)) { if (Array.isArray(jsonData.aliases)) {
jsonData.aliases = jsonData.aliases.filter((name) => name !== newName); jsonData.aliases = jsonData.aliases.filter(
(alias) => (typeof alias === 'string' ? alias : alias.name) !== newName,
);
jsonData.aliases.push(oldName); jsonData.aliases.push(oldName);
} else { } else {
jsonData.aliases = [oldName]; jsonData.aliases = [oldName];

View File

@@ -30,7 +30,10 @@ const arrayMatches = (a, b) => {
}; };
const nameParts = (icon) => const nameParts = (icon) =>
[icon.name, ...(icon.aliases ?? [])] [
icon.name,
...(icon.aliases?.map((alias) => (typeof alias === 'string' ? alias : alias.name)) ?? []),
]
.join('-') .join('-')
.split('-') .split('-')
.filter((word) => word.length > 2); .filter((word) => word.length > 2);

View File

@@ -145,7 +145,7 @@ try {
const iconName = path.basename(iconJsonFile, '.json'); const iconName = path.basename(iconJsonFile, '.json');
const metaDir = path.resolve(releaseMetaDataDirectory, `${iconName}.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}'.`); console.error(`Could not find release metadata for icon '${iconName}'.`);
} }
@@ -159,14 +159,16 @@ try {
const aliases = iconMetaData.aliases ?? []; const aliases = iconMetaData.aliases ?? [];
if (aliases.length) { if (aliases.length) {
aliases.forEach((alias) => { aliases
if (alias in newReleaseMetaData === false) { .map((alias) => (typeof alias === 'string' ? alias : alias.name))
return; .forEach((alias) => {
} if (!(alias in newReleaseMetaData)) {
return;
}
contents.createdRelease = contents.createdRelease =
newReleaseMetaData[alias].createdRelease ?? defaultReleaseMetaData.createdRelease; newReleaseMetaData[alias].createdRelease ?? defaultReleaseMetaData.createdRelease;
}); });
} }
const output = JSON.stringify(contents, null, 2); const output = JSON.stringify(contents, null, 2);

View File

@@ -1,9 +1,21 @@
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
import { toPascalCase, resetFile, appendFile } from '../../../scripts/helpers.mjs'; import { toPascalCase, resetFile, appendFile } from '../../../scripts/helpers.mjs';
import { deprecationReasonTemplate } from '../utils/deprecationReasonTemplate.mjs';
const getImportString = (componentName, iconName, aliasImportFileExtension = '') => const getImportString = (
`export { default as ${componentName} } from './icons/${iconName}${aliasImportFileExtension}';\n`; 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({ export default async function generateAliasesFile({
iconNodes, iconNodes,
@@ -27,7 +39,15 @@ export default async function generateAliasesFile({
await Promise.all( await Promise.all(
icons.map(async (iconName, index) => { icons.map(async (iconName, index) => {
const componentName = toPascalCase(iconName); 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 = ''; let importString = '';
@@ -51,11 +71,18 @@ export default async function generateAliasesFile({
if (iconAliases != null && Array.isArray(iconAliases)) { if (iconAliases != null && Array.isArray(iconAliases)) {
await Promise.all( await Promise.all(
iconAliases.map(async (alias) => { 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) { if (separateAliasesFile) {
const output = `export { default } from "./${iconName}"`; 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'); await fs.promises.writeFile(location, output, 'utf-8');
} }
@@ -65,12 +92,14 @@ export default async function generateAliasesFile({
return; return;
} }
const exportFileIcon = separateAliasesFile ? alias : iconName; const exportFileIcon = separateAliasesFile ? alias.name : iconName;
importString += getImportString( importString += getImportString(
componentNameAlias, componentNameAlias,
exportFileIcon, exportFileIcon,
aliasImportFileExtension, aliasImportFileExtension,
alias.deprecated,
deprecationReason,
); );
if (!aliasNamesOnly) { if (!aliasNamesOnly) {
@@ -78,12 +107,16 @@ export default async function generateAliasesFile({
`${componentNameAlias}Icon`, `${componentNameAlias}Icon`,
exportFileIcon, exportFileIcon,
aliasImportFileExtension, aliasImportFileExtension,
alias.deprecated,
deprecationReason,
); );
importString += getImportString( importString += getImportString(
`Lucide${componentNameAlias}`, `Lucide${componentNameAlias}`,
exportFileIcon, exportFileIcon,
aliasImportFileExtension, aliasImportFileExtension,
alias.deprecated,
deprecationReason,
); );
} }
}), }),

View File

@@ -2,6 +2,7 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import prettier from 'prettier'; import prettier from 'prettier';
import { readSvg, toPascalCase } from '../../../scripts/helpers.mjs'; import { readSvg, toPascalCase } from '../../../scripts/helpers.mjs';
import { deprecationReasonTemplate } from '../utils/deprecationReasonTemplate.mjs';
export default ({ export default ({
iconNodes, iconNodes,
@@ -28,9 +29,23 @@ export default ({
children = children.map(({ name, attributes }) => [name, attributes]); children = children.map(({ name, attributes }) => [name, attributes]);
const getSvg = () => readSvg(`${iconName}.svg`, iconsDir); 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 const output = pretty
? prettier.format(elementTemplate, { ? prettier.format(elementTemplate, {
singleQuote: true, singleQuote: true,

View File

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