From cb2022cddf35c301e53e4443826bd5fb1acd1733 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 22 Dec 2023 17:02:37 +0100 Subject: [PATCH 1/8] Implement deprecate comment lucide-react --- icon.schema.json | 5 +++++ icons/chrome.json | 3 ++- icons/codepen.json | 3 ++- icons/codesandbox.json | 3 ++- icons/dribbble.json | 3 ++- icons/facebook.json | 3 ++- icons/figma.json | 3 ++- icons/framer.json | 3 ++- icons/github.json | 3 ++- icons/gitlab.json | 3 ++- icons/instagram.json | 3 ++- icons/pocket.json | 3 ++- icons/slack.json | 3 ++- icons/trello.json | 3 ++- icons/twitch.json | 3 ++- icons/twitter.json | 3 ++- icons/youtube.json | 3 ++- .../lucide-react/scripts/exportTemplate.mjs | 19 ++++++------------- .../scripts/getAliasesEntryNames.mjs | 4 ++-- packages/lucide-react/src/createLucideIcon.ts | 6 ++++-- .../building/generateAliasesFile.mjs | 4 ++-- .../building/generateIconFiles.mjs | 4 +++- tools/build-icons/main.mjs | 9 +++++---- tools/build-icons/utils/base64SVG.mjs | 11 +++++++++++ .../{getAliases.mjs => getIconMetaData.mjs} | 4 ++-- 25 files changed, 72 insertions(+), 42 deletions(-) create mode 100644 tools/build-icons/utils/base64SVG.mjs rename tools/build-icons/utils/{getAliases.mjs => getIconMetaData.mjs} (85%) diff --git a/icon.schema.json b/icon.schema.json index 2adb2c700c7..52ff1b36a44 100644 --- a/icon.schema.json +++ b/icon.schema.json @@ -47,6 +47,11 @@ }, "minItems": 1, "uniqueItems": true + }, + "deprecated": { + "type": "boolean", + "default": false, + "optional": true } }, "description": "A JSON Schema for icons defined by Lucide Icons." diff --git a/icons/chrome.json b/icons/chrome.json index ff9515a4cca..e07964cf5ec 100644 --- a/icons/chrome.json +++ b/icons/chrome.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "ericfennis" @@ -11,4 +12,4 @@ "categories": [ "brands" ] -} \ No newline at end of file +} diff --git a/icons/codepen.json b/icons/codepen.json index e0e8fa2ba17..05382b3df38 100644 --- a/icons/codepen.json +++ b/icons/codepen.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "ericfennis" @@ -11,4 +12,4 @@ "brands", "development" ] -} \ No newline at end of file +} diff --git a/icons/codesandbox.json b/icons/codesandbox.json index 68ae126d6c2..e09a3e3c4a3 100644 --- a/icons/codesandbox.json +++ b/icons/codesandbox.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -12,4 +13,4 @@ "brands", "development" ] -} \ No newline at end of file +} diff --git a/icons/dribbble.json b/icons/dribbble.json index 0179199c0cc..41b57423fb7 100644 --- a/icons/dribbble.json +++ b/icons/dribbble.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "ahtohbi4", "karsa-mistmere" @@ -13,4 +14,4 @@ "social", "design" ] -} \ No newline at end of file +} diff --git a/icons/facebook.json b/icons/facebook.json index 03db542948a..67852e58f66 100644 --- a/icons/facebook.json +++ b/icons/facebook.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -14,4 +15,4 @@ "social", "brands" ] -} \ No newline at end of file +} diff --git a/icons/figma.json b/icons/figma.json index 2c452b3c45f..b75bf2ba0aa 100644 --- a/icons/figma.json +++ b/icons/figma.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -15,4 +16,4 @@ "brands", "design" ] -} \ No newline at end of file +} diff --git a/icons/framer.json b/icons/framer.json index 2c452b3c45f..b75bf2ba0aa 100644 --- a/icons/framer.json +++ b/icons/framer.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -15,4 +16,4 @@ "brands", "design" ] -} \ No newline at end of file +} diff --git a/icons/github.json b/icons/github.json index 935104a204c..0111ffd989e 100644 --- a/icons/github.json +++ b/icons/github.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -14,4 +15,4 @@ "brands", "development" ] -} \ No newline at end of file +} diff --git a/icons/gitlab.json b/icons/gitlab.json index 935104a204c..0111ffd989e 100644 --- a/icons/gitlab.json +++ b/icons/gitlab.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -14,4 +15,4 @@ "brands", "development" ] -} \ No newline at end of file +} diff --git a/icons/instagram.json b/icons/instagram.json index 8e8c9364ee8..f8f9dc404ba 100644 --- a/icons/instagram.json +++ b/icons/instagram.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -15,4 +16,4 @@ "social", "photography" ] -} \ No newline at end of file +} diff --git a/icons/pocket.json b/icons/pocket.json index b23a8cf0d03..f2df830a569 100644 --- a/icons/pocket.json +++ b/icons/pocket.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -13,4 +14,4 @@ "brands", "development" ] -} \ No newline at end of file +} diff --git a/icons/slack.json b/icons/slack.json index d3aa1068c96..93a1ff1aa17 100644 --- a/icons/slack.json +++ b/icons/slack.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "ashygee", @@ -17,4 +18,4 @@ "brands", "development" ] -} \ No newline at end of file +} diff --git a/icons/trello.json b/icons/trello.json index 9d41a4a2b4e..bdda0eeff4a 100644 --- a/icons/trello.json +++ b/icons/trello.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "bdbch", "csandman", @@ -15,4 +16,4 @@ "brands", "development" ] -} \ No newline at end of file +} diff --git a/icons/twitch.json b/icons/twitch.json index f3d6e502dab..fe163ceb12b 100644 --- a/icons/twitch.json +++ b/icons/twitch.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "ahtohbi4", "johnletey" @@ -14,4 +15,4 @@ "account", "gaming" ] -} \ No newline at end of file +} diff --git a/icons/twitter.json b/icons/twitter.json index 0f81517a521..52003f20030 100644 --- a/icons/twitter.json +++ b/icons/twitter.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -15,4 +16,4 @@ "social", "account" ] -} \ No newline at end of file +} diff --git a/icons/youtube.json b/icons/youtube.json index cea2740af06..ead7e1d0333 100644 --- a/icons/youtube.json +++ b/icons/youtube.json @@ -1,5 +1,6 @@ { "$schema": "../icon.schema.json", + "deprecated": true, "contributors": [ "colebemis", "csandman", @@ -20,4 +21,4 @@ "text", "brands" ] -} \ No newline at end of file +} diff --git a/packages/lucide-react/scripts/exportTemplate.mjs b/packages/lucide-react/scripts/exportTemplate.mjs index b9c3d35af58..7ccb638e74f 100644 --- a/packages/lucide-react/scripts/exportTemplate.mjs +++ b/packages/lucide-react/scripts/exportTemplate.mjs @@ -1,16 +1,9 @@ -export default ({ componentName, iconName, children, getSvg }) => { - const svgContents = getSvg(); - - const svgBase64 = Buffer.from( - svgContents - .replace('\n', '') - .replace( - 'stroke="currentColor"', - 'stroke="#000" style="background-color: #fff; border-radius: 2px"', - ), - ).toString('base64'); +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; - // declarationFileContent += `\ +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); return ` import createLucideIcon from '../createLucideIcon'; @@ -24,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' : ''} */ const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); diff --git a/packages/lucide-react/scripts/getAliasesEntryNames.mjs b/packages/lucide-react/scripts/getAliasesEntryNames.mjs index 0930d61faa6..e67c535abd6 100644 --- a/packages/lucide-react/scripts/getAliasesEntryNames.mjs +++ b/packages/lucide-react/scripts/getAliasesEntryNames.mjs @@ -1,11 +1,11 @@ import path from 'path'; // eslint-disable-next-line import/no-extraneous-dependencies -import getAliases from '@lucide/build-icons/utils/getAliases.mjs'; +import getIconMetaData from '@lucide/build-icons/utils/getIconMetaData.mjs'; const ICONS_DIR = path.resolve(process.cwd(), '../../icons'); export default async function getAliasesEntryNames() { - const metaJsonFiles = await getAliases(ICONS_DIR); + const metaJsonFiles = await getIconMetaData(ICONS_DIR); const iconWithAliases = Object.values(metaJsonFiles).filter(({ aliases }) => aliases != null); diff --git a/packages/lucide-react/src/createLucideIcon.ts b/packages/lucide-react/src/createLucideIcon.ts index daf73e7e30e..b7c2b7c1f6a 100644 --- a/packages/lucide-react/src/createLucideIcon.ts +++ b/packages/lucide-react/src/createLucideIcon.ts @@ -35,8 +35,9 @@ export const toKebabCase = (string: string) => const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => { const Component = forwardRef( - ({ color = 'currentColor', size = 24, strokeWidth = 2, absoluteStrokeWidth, className = '', children, ...rest }, ref) => - createElement( + ({ color = 'currentColor', size = 24, strokeWidth = 2, absoluteStrokeWidth, className = '', children, ...rest }, ref) =>{ + + return createElement( 'svg', { ref, @@ -53,6 +54,7 @@ const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => { ...(Array.isArray(children) ? children : [children]), ] ) + } ); Component.displayName = `${iconName}`; diff --git a/tools/build-icons/building/generateAliasesFile.mjs b/tools/build-icons/building/generateAliasesFile.mjs index 47e7a31811f..73517281cd5 100644 --- a/tools/build-icons/building/generateAliasesFile.mjs +++ b/tools/build-icons/building/generateAliasesFile.mjs @@ -10,7 +10,7 @@ export default async function generateAliasesFile({ outputDirectory, fileExtension, iconFileExtension = '.js', - aliases, + iconMetaData, aliasImportFileExtension, aliasNamesOnly = false, separateAliasesFile = false, @@ -27,7 +27,7 @@ export default async function generateAliasesFile({ await Promise.all( icons.map(async (iconName, index) => { const componentName = toPascalCase(iconName); - const iconAliases = aliases[iconName]?.aliases; + const iconAliases = iconMetaData[iconName]?.aliases; let importString = ''; diff --git a/tools/build-icons/building/generateIconFiles.mjs b/tools/build-icons/building/generateIconFiles.mjs index 9540432939f..b4f04b6bd48 100644 --- a/tools/build-icons/building/generateIconFiles.mjs +++ b/tools/build-icons/building/generateIconFiles.mjs @@ -11,6 +11,7 @@ export default ({ iconFileExtension = '.js', pretty = true, iconsDir, + iconMetaData, }) => { const icons = Object.keys(iconNodes); const iconsDistDirectory = path.join(outputDirectory, `icons`); @@ -27,8 +28,9 @@ export default ({ children = children.map(({ name, attributes }) => [name, attributes]); const getSvg = () => readSvg(`${iconName}.svg`, iconsDir); + const { deprecated = false } = iconMetaData[iconName]; - const elementTemplate = template({ componentName, iconName, children, getSvg }); + const elementTemplate = template({ componentName, iconName, children, getSvg, deprecated }); const output = pretty ? prettier.format(elementTemplate, { singleQuote: true, diff --git a/tools/build-icons/main.mjs b/tools/build-icons/main.mjs index ff0e34b46ea..a5143ac2c20 100755 --- a/tools/build-icons/main.mjs +++ b/tools/build-icons/main.mjs @@ -9,7 +9,7 @@ import generateExportsFile from './building/generateExportsFile.mjs'; import { readSvgDirectory, getCurrentDirPath } from '../../scripts/helpers.mjs'; import generateAliasesFile from './building/generateAliasesFile.mjs'; -import getAliases from './utils/getAliases.mjs'; +import getIconMetaData from './utils/getIconMetaData.mjs'; import generateDynamicImports from './building/generateDynamicImports.mjs'; const cliArguments = getArgumentOptions(process.argv.slice(2)); @@ -50,6 +50,8 @@ async function buildIcons() { const { default: iconFileTemplate } = await import(path.resolve(process.cwd(), templateSrc)); + const iconMetaData = await getIconMetaData(ICONS_DIR); + // Generates iconsNodes files for each icon generateIconFiles({ iconNodes: icons, @@ -59,14 +61,13 @@ async function buildIcons() { iconFileExtension, pretty: JSON.parse(pretty), iconsDir: ICONS_DIR, + iconMetaData, }); if (withAliases) { - const aliases = await getAliases(ICONS_DIR); - await generateAliasesFile({ iconNodes: icons, - aliases, + iconMetaData, aliasNamesOnly, iconFileExtension, outputDirectory: OUTPUT_DIR, diff --git a/tools/build-icons/utils/base64SVG.mjs b/tools/build-icons/utils/base64SVG.mjs new file mode 100644 index 00000000000..b883d0fff9a --- /dev/null +++ b/tools/build-icons/utils/base64SVG.mjs @@ -0,0 +1,11 @@ +const base64SVG = (svgContents) => + Buffer.from( + svgContents + .replace('\n', '') + .replace( + 'stroke="currentColor"', + 'stroke="#000" style="background-color: #fff; border-radius: 2px"', + ), + ).toString('base64'); + +export default base64SVG; diff --git a/tools/build-icons/utils/getAliases.mjs b/tools/build-icons/utils/getIconMetaData.mjs similarity index 85% rename from tools/build-icons/utils/getAliases.mjs rename to tools/build-icons/utils/getIconMetaData.mjs index 91cc37989a0..e1ae610b0f0 100644 --- a/tools/build-icons/utils/getAliases.mjs +++ b/tools/build-icons/utils/getIconMetaData.mjs @@ -1,7 +1,7 @@ import path from 'path'; import { readSvgDirectory } from '../../../scripts/helpers.mjs'; -async function getAliases(iconDirectory) { +async function getIconMetaData(iconDirectory) { const iconJsons = readSvgDirectory(iconDirectory, '.json'); const aliasesEntries = await Promise.all( iconJsons.map(async (jsonFile) => { @@ -13,4 +13,4 @@ async function getAliases(iconDirectory) { return Object.fromEntries(aliasesEntries); } -export default getAliases +export default getIconMetaData From 4db0fff73bd97b6ecce3431e96738f6d7f8d1438 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Sat, 23 Dec 2023 16:27:54 +0100 Subject: [PATCH 2/8] Add export template with comment --- .../lucide-preact/scripts/exportTemplate.mjs | 21 ++++++++++++++++- .../scripts/exportTemplate.mjs | 21 ++++++++++++++++- .../lucide-solid/scripts/exportTemplate.mjs | 21 ++++++++++++++++- .../lucide-vue-next/scripts/buildTypes.mjs | 4 ++-- .../scripts/exportTemplate.mjs | 21 ++++++++++++++++- .../lucide-vue/scripts/exportTemplate.mjs | 23 +++++++++++++++++-- packages/lucide/scripts/exportTemplate.mjs | 20 +++++++++++++++- tools/build-icons/index.mjs | 2 +- 8 files changed, 123 insertions(+), 10 deletions(-) diff --git a/packages/lucide-preact/scripts/exportTemplate.mjs b/packages/lucide-preact/scripts/exportTemplate.mjs index ee09feaab7d..857ce67cca7 100644 --- a/packages/lucide-preact/scripts/exportTemplate.mjs +++ b/packages/lucide-preact/scripts/exportTemplate.mjs @@ -1,7 +1,26 @@ -export default ({ componentName, children }) => ` +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return ` import createLucideIcon from '../createLucideIcon'; +/** + * @component @name ${componentName} + * @description Lucide SVG icon component, renders SVG Element with children. + * + * @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName} + * @see https://lucide.dev/guide/packages/lucide-preact - Documentation + * + * @param {Object} props - Lucide icons props and any valid SVG attribute + * @returns {JSX.Element} JSX Element + * ${deprecated ? '@deprecated' : ''} + */ const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); export default ${componentName}; `; +}; diff --git a/packages/lucide-react-native/scripts/exportTemplate.mjs b/packages/lucide-react-native/scripts/exportTemplate.mjs index ee09feaab7d..ad1051c2a91 100644 --- a/packages/lucide-react-native/scripts/exportTemplate.mjs +++ b/packages/lucide-react-native/scripts/exportTemplate.mjs @@ -1,7 +1,26 @@ -export default ({ componentName, children }) => ` +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return ` import createLucideIcon from '../createLucideIcon'; +/** + * @component @name ${componentName} + * @description Lucide SVG icon component, renders SVG Element with children. + * + * @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName} + * @see https://lucide.dev/guide/packages/lucide-react-native - Documentation + * + * @param {Object} props - Lucide icons props and any valid SVG attribute + * @returns {JSX.Element} JSX Element + * ${deprecated ? '@deprecated' : ''} + */ const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); export default ${componentName}; `; +}; diff --git a/packages/lucide-solid/scripts/exportTemplate.mjs b/packages/lucide-solid/scripts/exportTemplate.mjs index 715f47719e1..72385eb3387 100644 --- a/packages/lucide-solid/scripts/exportTemplate.mjs +++ b/packages/lucide-solid/scripts/exportTemplate.mjs @@ -1,12 +1,31 @@ -export default ({ componentName, children }) => ` +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return ` import Icon from '../Icon'; import type { IconNode, LucideProps } from '../types'; const iconNode: IconNode = ${JSON.stringify(children)}; +/** + * @component @name ${componentName} + * @description Lucide SVG icon component, renders SVG Element with children. + * + * @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName} + * @see https://lucide.dev/guide/packages/lucide-solid - Documentation + * + * @param {Object} props - Lucide icons props and any valid SVG attribute + * @returns {JSX.Element} JSX Element + * ${deprecated ? '@deprecated' : ''} + */ const ${componentName} = (props: LucideProps) => ( ) export default ${componentName}; `; +}; diff --git a/packages/lucide-vue-next/scripts/buildTypes.mjs b/packages/lucide-vue-next/scripts/buildTypes.mjs index 028f7d29ed2..f8cd977ac95 100644 --- a/packages/lucide-vue-next/scripts/buildTypes.mjs +++ b/packages/lucide-vue-next/scripts/buildTypes.mjs @@ -1,6 +1,6 @@ import path from 'path'; // eslint-disable-next-line import/no-extraneous-dependencies -import { getAliases } from '@lucide/build-icons'; +import { getIconMetaData } from '@lucide/build-icons'; import { readSvgDirectory, resetFile, @@ -48,7 +48,7 @@ svgFiles.forEach((svgFile) => { declarationFileContent += getComponentImport(componentName); }); -const aliases = await getAliases(ICONS_DIR); +const aliases = await getIconMetaData(ICONS_DIR); declarationFileContent += `\n diff --git a/packages/lucide-vue-next/scripts/exportTemplate.mjs b/packages/lucide-vue-next/scripts/exportTemplate.mjs index 97b97310090..1c22ec9b1a7 100644 --- a/packages/lucide-vue-next/scripts/exportTemplate.mjs +++ b/packages/lucide-vue-next/scripts/exportTemplate.mjs @@ -1,7 +1,26 @@ -export default ({ componentName, children }) => ` +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return ` import createLucideIcon from '../createLucideIcon'; +/** + * @component @name ${componentName} + * @description Lucide SVG icon component, renders SVG Element with children. + * + * @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName} + * @see https://lucide.dev/guide/packages/lucide-vue-next - Documentation + * + * @param {Object} props - Lucide icons props and any valid SVG attribute + * @returns {FunctionalComponent} Vue component + * ${deprecated ? '@deprecated' : ''} + */ const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)}); export default ${componentName}; `; +}; diff --git a/packages/lucide-vue/scripts/exportTemplate.mjs b/packages/lucide-vue/scripts/exportTemplate.mjs index 650b4178263..3852e740eea 100644 --- a/packages/lucide-vue/scripts/exportTemplate.mjs +++ b/packages/lucide-vue/scripts/exportTemplate.mjs @@ -1,7 +1,26 @@ -export default ({ componentName, children }) => ` -import createVueComponent from '../createVueComponent'; +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return ` +import createLucideIcon from '../createLucideIcon'; + +/** + * @component @name ${componentName} + * @description Lucide SVG icon component, renders SVG Element with children. + * + * @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName} + * @see https://lucide.dev/guide/packages/lucide-vue - Documentation + * + * @param {Object} props - Lucide icons props and any valid SVG attribute + * @returns {Component} Vue Component + * ${deprecated ? '@deprecated' : ''} + */ const ${componentName} = createVueComponent('${componentName}Icon', ${JSON.stringify(children)}); export default ${componentName}; `; +}; diff --git a/packages/lucide/scripts/exportTemplate.mjs b/packages/lucide/scripts/exportTemplate.mjs index 282b62baeeb..bcd2ee9423d 100644 --- a/packages/lucide/scripts/exportTemplate.mjs +++ b/packages/lucide/scripts/exportTemplate.mjs @@ -1,7 +1,24 @@ -export default ({ componentName, children }) => ` +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return ` import defaultAttributes from '../defaultAttributes'; import type { IconNode } from '../types'; +/** + * @name ${iconName} + * @description Lucide SVG icon node. + * + * @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName} + * @see https://lucide.dev/guide/packages/lucide - Documentation + * + * @returns {Array} + * ${deprecated ? '@deprecated' : ''} + */ const ${componentName}: IconNode = [ 'svg', defaultAttributes, @@ -10,3 +27,4 @@ const ${componentName}: IconNode = [ export default ${componentName}; `; +}; diff --git a/tools/build-icons/index.mjs b/tools/build-icons/index.mjs index 923e98a8cce..3f7ddaca9e8 100644 --- a/tools/build-icons/index.mjs +++ b/tools/build-icons/index.mjs @@ -1,2 +1,2 @@ // eslint-disable-next-line import/prefer-default-export -export { default as getAliases } from './utils/getAliases.mjs'; +export { default as getIconMetaData } from './utils/getIconMetaData.mjs'; From 578959c95a5213388f9e952be629f46bfa005787 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 5 Jan 2024 10:47:39 +0100 Subject: [PATCH 3/8] Add block comment to Lucide Svelte --- packages/lucide-svelte/scripts/addLicense.mjs | 31 +++++++++++++++++-- .../lucide-svelte/scripts/exportTemplate.mjs | 24 ++++++++++++-- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/packages/lucide-svelte/scripts/addLicense.mjs b/packages/lucide-svelte/scripts/addLicense.mjs index c00a7287cc7..b31c87e8b30 100644 --- a/packages/lucide-svelte/scripts/addLicense.mjs +++ b/packages/lucide-svelte/scripts/addLicense.mjs @@ -24,6 +24,7 @@ for (const file of files) { if (filestat.isFile() === false || filestat.isDirectory()) continue; const contents = await readFile(filepath, { encoding: 'utf-8' }); + let newContents = contents; const ext = path.extname(filepath); let license; @@ -36,7 +37,31 @@ for (const file of files) { } if (license) { - await writeFile(filepath, license + contents, { encoding: 'utf-8' }); + newContents = license + contents; + + } + + // Places icon block comment at the top of the Svelte component class + if(/icons\/(.*?)\.svelte\.d\.ts/.test(filepath)) { + const svelteFilepath = filepath.replace('.d.ts', '') + let svelteFileContents = await readFile(svelteFilepath, { encoding: 'utf-8' }); + + const blockCommentRegex = /\/\*\*[\s\S]*?\*\//; + const blockCommentMatch = blockCommentRegex.exec(svelteFileContents); + + if (blockCommentMatch !== null) { + const blockComment = blockCommentMatch[0]; + + const exportClassRegex = /export default class (\w+) extends SvelteComponentTyped<(.*?)> {/; + + if (exportClassRegex.test(newContents)) { + newContents = newContents.replace(exportClassRegex, `${blockComment}\nexport default class $1 extends SvelteComponentTyped<$2> {`); + } + } + } + + if(newContents !== contents) { + await writeFile(filepath, newContents, { encoding: 'utf-8' }); } } @@ -48,8 +73,8 @@ function getJSBanner() { } function getSvelteBanner() { - return ` \n`; } diff --git a/packages/lucide-svelte/scripts/exportTemplate.mjs b/packages/lucide-svelte/scripts/exportTemplate.mjs index ec40bdd8eb1..6b76f64bc07 100644 --- a/packages/lucide-svelte/scripts/exportTemplate.mjs +++ b/packages/lucide-svelte/scripts/exportTemplate.mjs @@ -1,6 +1,11 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -export default ({ iconName, children }) => - `\ +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ iconName, children, componentName, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return `\ `; +}; From d0ac252395704fd9ef2abea5fb786d57d9d13346 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 5 Jan 2024 10:57:09 +0100 Subject: [PATCH 4/8] Add blockcomment to lucide-angular --- .../lucide-angular/scripts/exportTemplate.mjs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/lucide-angular/scripts/exportTemplate.mjs b/packages/lucide-angular/scripts/exportTemplate.mjs index 67ecb12d5ca..064d70ecb14 100644 --- a/packages/lucide-angular/scripts/exportTemplate.mjs +++ b/packages/lucide-angular/scripts/exportTemplate.mjs @@ -1,8 +1,26 @@ -export default ({ componentName, children }) => ` +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + const svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + return `\ import { LucideIconData } from './types'; -/* eslint-disable no-shadow-restricted-names */ -const ${componentName}: LucideIconData = ${JSON.stringify(children)}; +/** + * @component @name ${componentName} + * @description Lucide SVG icon component, renders SVG Element with children. + * + * @preview ![img](data:image/svg+xml;base64,${svgBase64}) - https://lucide.dev/icons/${iconName} + * @see https://lucide.dev/guide/packages/lucide-vue-next - Documentation + * + * @param {Object} props - Lucide icons props and any valid SVG attribute + * @returns {FunctionalComponent} Vue component + * ${deprecated ? '@deprecated' : ''} +*/ +const ${componentName}: LucideIconData = ${JSON.stringify(children)}; //eslint-disable-line no-shadow-restricted-names export default ${componentName}; -`; +` +}; From ae4842d148e2b5d3600c6cae2c9beb91ddc0eb6e Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 5 Jan 2024 11:36:16 +0100 Subject: [PATCH 5/8] Add block comment to lucide-static --- packages/lucide-static/package.json | 18 ++++-- packages/lucide-static/rollup.config.mjs | 59 +++++++++++++++++++ packages/lucide-static/scripts/buildLib.mjs | 18 ------ .../lucide-static/scripts/exportTemplate.mjs | 32 ++++++++++ packages/lucide-static/src/lucide-static.ts | 2 + packages/lucide-static/tsconfig.json | 17 ++++++ pnpm-lock.yaml | 18 +++++- 7 files changed, 139 insertions(+), 25 deletions(-) create mode 100644 packages/lucide-static/rollup.config.mjs create mode 100644 packages/lucide-static/scripts/exportTemplate.mjs create mode 100644 packages/lucide-static/src/lucide-static.ts create mode 100644 packages/lucide-static/tsconfig.json diff --git a/packages/lucide-static/package.json b/packages/lucide-static/package.json index 6723e5325e3..1ed292da23f 100644 --- a/packages/lucide-static/package.json +++ b/packages/lucide-static/package.json @@ -22,17 +22,27 @@ "Fontawesome", "Font Awesome" ], - "main": "lib/index.js", + "source": "src/lucide-static.js", + "main": "dist/cjs/lucide-static.js", + "module": "dist/esm/lucide-static.js", + "typings": "dist/lucide-static.d.ts", + "sideEffects": false, "scripts": { "copy:license": "cp ../../LICENSE ./LICENSE", - "build:tags": "node ../../scripts/migrateIconsToTags.mjs", - "build": "pnpm clean && pnpm copy:license && pnpm build:lib && pnpm build:tags", + "build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundles && pnpm build:lib && pnpm build:tags", + "build:tags": "bun ../../scripts/migrateIconsToTags.mjs", + "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --iconFileExtension=.ts --withAliases --aliasNamesOnly --aliasesFileExtension=.ts --exportFileName=index.ts", "build:lib": "node ./scripts/buildLib.mjs", + "build:bundles": "rollup -c rollup.config.mjs", "clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg", "version": "pnpm version --git-tag-version=false" }, "devDependencies": { "prettier": "^2.3.2", - "svgson": "^5.2.1" + "svgson": "^5.2.1", + "@lucide/build-icons": "workspace:*", + "@lucide/rollup-plugins": "workspace:*", + "rollup": "^4.9.2", + "rollup-plugin-dts": "^6.1.0" } } diff --git a/packages/lucide-static/rollup.config.mjs b/packages/lucide-static/rollup.config.mjs new file mode 100644 index 00000000000..fd90a529979 --- /dev/null +++ b/packages/lucide-static/rollup.config.mjs @@ -0,0 +1,59 @@ +import plugins from '@lucide/rollup-plugins'; +import dts from 'rollup-plugin-dts'; +import pkg from './package.json' assert { type: 'json' }; + +const outputFileName = pkg.name; +const outputDir = 'dist'; +const inputs = ['src/lucide-static.ts']; +const bundles = [ + { + format: 'cjs', + inputs, + outputDir, + }, + { + format: 'esm', + inputs, + outputDir, + preserveModules: true, + }, +]; + +const configs = bundles + .map(({ inputs, outputDir, format, minify, preserveModules }) => + inputs.map(input => ({ + input, + plugins: plugins(pkg, minify), + output: { + name: outputFileName, + ...(preserveModules + ? { + dir: `${outputDir}/${format}`, + } + : { + file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`, + }), + format, + sourcemap: true, + preserveModules, + }, + })), + ) + .flat(); + +const typesFileConfig = { + input: inputs[0], + output: [ + { + file: `${outputDir}/${outputFileName}.d.ts`, + format: 'esm', + }, + ], + plugins: [ + dts({ + include: ['src'], + }), + ], +}; + +export default [...configs, typesFileConfig]; diff --git a/packages/lucide-static/scripts/buildLib.mjs b/packages/lucide-static/scripts/buildLib.mjs index aa28c6169d3..7c5beb08b50 100644 --- a/packages/lucide-static/scripts/buildLib.mjs +++ b/packages/lucide-static/scripts/buildLib.mjs @@ -5,9 +5,7 @@ import getArgumentOptions from 'minimist'; import { parseSync } from 'svgson'; import { - appendFile, readSvgDirectory, - toCamelCase, getCurrentDirPath, } from '../../../scripts/helpers.mjs'; import readSvgs from './readSvgs.mjs'; @@ -39,22 +37,6 @@ createDirectory(ICON_MODULE_DIR); const svgFiles = readSvgDirectory(ICONS_DIR); const svgs = readSvgs(svgFiles, ICONS_DIR); -const jsLicense = `/**\n * ${license}\n */\n`; - -appendFile(jsLicense, `index.js`, LIB_DIR); - -svgs.forEach(({ name, contents }) => { - const componentName = toCamelCase(name); - const importString = `module.exports.${componentName} = require('./icons/${name}');\n`; - appendFile(importString, `index.js`, LIB_DIR); - - const svgContent = contents.replace(' ({ name, contents, diff --git a/packages/lucide-static/scripts/exportTemplate.mjs b/packages/lucide-static/scripts/exportTemplate.mjs new file mode 100644 index 00000000000..42e7a5f5f09 --- /dev/null +++ b/packages/lucide-static/scripts/exportTemplate.mjs @@ -0,0 +1,32 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs'; + +export default ({ componentName, iconName, children, getSvg, deprecated }) => { + let svgContents = getSvg(); + const svgBase64 = base64SVG(svgContents); + + svgContents = svgContents.replace( + ' Date: Fri, 5 Jan 2024 11:39:59 +0100 Subject: [PATCH 6/8] revert runtime change build:tags --- packages/lucide-static/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/lucide-static/package.json b/packages/lucide-static/package.json index 1ed292da23f..f3aacac132b 100644 --- a/packages/lucide-static/package.json +++ b/packages/lucide-static/package.json @@ -30,7 +30,7 @@ "scripts": { "copy:license": "cp ../../LICENSE ./LICENSE", "build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundles && pnpm build:lib && pnpm build:tags", - "build:tags": "bun ../../scripts/migrateIconsToTags.mjs", + "build:tags": "node ../../scripts/migrateIconsToTags.mjs", "build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --iconFileExtension=.ts --withAliases --aliasNamesOnly --aliasesFileExtension=.ts --exportFileName=index.ts", "build:lib": "node ./scripts/buildLib.mjs", "build:bundles": "rollup -c rollup.config.mjs", From 1ed280d1d09d5909b9d2df29413463215a77b0ba Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 5 Jan 2024 12:09:31 +0100 Subject: [PATCH 7/8] Fix failed tests --- packages/lucide-vue/scripts/exportTemplate.mjs | 2 +- .../src/{createVueComponent.ts => createLucideIcon.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/lucide-vue/src/{createVueComponent.ts => createLucideIcon.ts} (100%) diff --git a/packages/lucide-vue/scripts/exportTemplate.mjs b/packages/lucide-vue/scripts/exportTemplate.mjs index 3852e740eea..b58291f7975 100644 --- a/packages/lucide-vue/scripts/exportTemplate.mjs +++ b/packages/lucide-vue/scripts/exportTemplate.mjs @@ -19,7 +19,7 @@ import createLucideIcon from '../createLucideIcon'; * @returns {Component} Vue Component * ${deprecated ? '@deprecated' : ''} */ -const ${componentName} = createVueComponent('${componentName}Icon', ${JSON.stringify(children)}); +const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)}); export default ${componentName}; `; diff --git a/packages/lucide-vue/src/createVueComponent.ts b/packages/lucide-vue/src/createLucideIcon.ts similarity index 100% rename from packages/lucide-vue/src/createVueComponent.ts rename to packages/lucide-vue/src/createLucideIcon.ts From 97d492cf4726d129d3a2eb6d08c3e1a4652f09a1 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Fri, 5 Jan 2024 12:12:46 +0100 Subject: [PATCH 8/8] Remove optional property in icon schema --- icon.schema.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/icon.schema.json b/icon.schema.json index 52ff1b36a44..075930077e4 100644 --- a/icon.schema.json +++ b/icon.schema.json @@ -50,8 +50,7 @@ }, "deprecated": { "type": "boolean", - "default": false, - "optional": true + "default": false } }, "description": "A JSON Schema for icons defined by Lucide Icons."