From 4835ae67a9ec3b934cd7db323a7871d5bb316c2c Mon Sep 17 00:00:00 2001 From: Dante Issaias Date: Fri, 21 Mar 2025 10:35:54 +0000 Subject: [PATCH] fix(packages): consistent icon name class (#2878) * fix: consistent icon name class * merge classes * fix vue-next * update test snapshots * fix vue-next * fix test * fix solid * proper deduplication * update snapshots * preact * refactor * deprecated * refactor tests --------- Co-authored-by: Eric Fennis --- .../lucide-preact/scripts/exportTemplate.mjs | 2 +- .../lucide-preact/src/createLucideIcon.ts | 5 +- .../createLucideIcon.spec.tsx.snap | 56 +++++++++++++++++++ .../__snapshots__/lucide-preact.spec.tsx.snap | 6 +- .../tests/createLucideIcon.spec.tsx | 18 ++++++ .../lucide-react/scripts/exportTemplate.mjs | 2 +- packages/lucide-react/src/createLucideIcon.ts | 10 +++- .../createLucideIcon.spec.tsx.snap | 56 +++++++++++++++++++ .../__snapshots__/lucide-react.spec.tsx.snap | 6 +- .../tests/createLucideIcon.spec.tsx | 18 ++++++ .../lucide-solid/scripts/exportTemplate.mjs | 2 +- packages/lucide-solid/src/Icon.tsx | 9 ++- .../__snapshots__/lucide-solid.spec.tsx.snap | 6 +- .../scripts/exportTemplate.mjs | 2 +- packages/lucide-vue-next/src/Icon.ts | 9 ++- .../lucide-vue-next.spec.ts.snap | 10 ++-- 16 files changed, 190 insertions(+), 27 deletions(-) diff --git a/packages/lucide-preact/scripts/exportTemplate.mjs b/packages/lucide-preact/scripts/exportTemplate.mjs index 42a9be1ff..1608ac7b7 100644 --- a/packages/lucide-preact/scripts/exportTemplate.mjs +++ b/packages/lucide-preact/scripts/exportTemplate.mjs @@ -26,7 +26,7 @@ import createLucideIcon from '../createLucideIcon'; * @returns {JSX.Element} JSX Element * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ -const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}); +const ${componentName} = createLucideIcon('${iconName}', ${JSON.stringify(children)}); export default ${componentName}; `; diff --git a/packages/lucide-preact/src/createLucideIcon.ts b/packages/lucide-preact/src/createLucideIcon.ts index 2ba13086f..b2e2fb300 100644 --- a/packages/lucide-preact/src/createLucideIcon.ts +++ b/packages/lucide-preact/src/createLucideIcon.ts @@ -1,5 +1,5 @@ import { h, type JSX } from 'preact'; -import { mergeClasses, toKebabCase } from '@lucide/shared'; +import { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared'; import Icon from './Icon'; import type { IconNode, LucideIcon, LucideProps } from './types'; @@ -17,6 +17,7 @@ const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => { ...props, iconNode, class: mergeClasses>( + `lucide-${toKebabCase(toPascalCase(iconName))}`, `lucide-${toKebabCase(iconName)}`, classes, ), @@ -24,7 +25,7 @@ const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => { children, ); - Component.displayName = `${iconName}`; + Component.displayName = toPascalCase(iconName); return Component; }; diff --git a/packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap b/packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap index acf4f9739..aeb02b395 100644 --- a/packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap +++ b/packages/lucide-preact/tests/__snapshots__/createLucideIcon.spec.tsx.snap @@ -27,3 +27,59 @@ exports[`Using createLucideIcon > should create a component from an iconNode 1`] /> `; + +exports[`Using createLucideIcon > should create a component from an iconNode with iconName 1`] = ` + + + + + + +`; + +exports[`Using createLucideIcon > should include backwards compatible className 1`] = ` + + + + + + +`; diff --git a/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap b/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap index a3cc08657..eacfae320 100644 --- a/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap +++ b/packages/lucide-preact/tests/__snapshots__/lucide-preact.spec.tsx.snap @@ -10,7 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and stroke-width="4" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3" + class="lucide lucide-grid3x3 lucide-grid-3x3" > should not scale the strokeWidth when ab stroke-width="1" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3" + class="lucide lucide-grid3x3 lucide-grid-3x3" > should render an component 1`] = ` stroke-width="2" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3" + class="lucide lucide-grid3x3 lucide-grid-3x3" > { expect(container.firstChild).toMatchSnapshot(); expect(container.firstChild).toBeDefined(); }); + + it('should create a component from an iconNode with iconName', () => { + const AirVent = createLucideIcon('air-vent', airVent); + + const { container } = render(); + + expect(container.firstChild).toMatchSnapshot(); + expect(container.firstChild).toBeDefined(); + }); + + it('should include backwards compatible className', () => { + const Layout2 = createLucideIcon('layout-2', airVent); + + const { container } = render(); + + expect(container.firstChild).toMatchSnapshot(); + expect(container.firstChild).toBeDefined(); + }); }); diff --git a/packages/lucide-react/scripts/exportTemplate.mjs b/packages/lucide-react/scripts/exportTemplate.mjs index e39cf0a6f..167d858a0 100644 --- a/packages/lucide-react/scripts/exportTemplate.mjs +++ b/packages/lucide-react/scripts/exportTemplate.mjs @@ -29,7 +29,7 @@ export const __iconNode: IconNode = ${JSON.stringify(children)} * @returns {JSX.Element} JSX Element * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ -const ${componentName} = createLucideIcon('${componentName}', __iconNode); +const ${componentName} = createLucideIcon('${iconName}', __iconNode); export default ${componentName}; `; diff --git a/packages/lucide-react/src/createLucideIcon.ts b/packages/lucide-react/src/createLucideIcon.ts index b20929382..bc453af84 100644 --- a/packages/lucide-react/src/createLucideIcon.ts +++ b/packages/lucide-react/src/createLucideIcon.ts @@ -1,5 +1,5 @@ import { createElement, forwardRef } from 'react'; -import { mergeClasses, toKebabCase } from '@lucide/shared'; +import { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared'; import { IconNode, LucideProps } from './types'; import Icon from './Icon'; @@ -14,12 +14,16 @@ const createLucideIcon = (iconName: string, iconNode: IconNode) => { createElement(Icon, { ref, iconNode, - className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className), + className: mergeClasses( + `lucide-${toKebabCase(toPascalCase(iconName))}`, + `lucide-${iconName}`, + className, + ), ...props, }), ); - Component.displayName = `${iconName}`; + Component.displayName = toPascalCase(iconName); return Component; }; diff --git a/packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap b/packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap index acf4f9739..a1f9dc728 100644 --- a/packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap +++ b/packages/lucide-react/tests/__snapshots__/createLucideIcon.spec.tsx.snap @@ -1,6 +1,34 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`Using createLucideIcon > should create a component from an iconNode 1`] = ` + + + + + + +`; + +exports[`Using createLucideIcon > should create a component from an iconNode with iconName 1`] = ` should create a component from an iconNode 1`] /> `; + +exports[`Using createLucideIcon > should include backwards compatible className 1`] = ` + + + + + + +`; diff --git a/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap b/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap index a3cc08657..eacfae320 100644 --- a/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap +++ b/packages/lucide-react/tests/__snapshots__/lucide-react.spec.tsx.snap @@ -10,7 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and stroke-width="4" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3" + class="lucide lucide-grid3x3 lucide-grid-3x3" > should not scale the strokeWidth when ab stroke-width="1" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3" + class="lucide lucide-grid3x3 lucide-grid-3x3" > should render an component 1`] = ` stroke-width="2" stroke-linecap="round" stroke-linejoin="round" - class="lucide lucide-grid3x3" + class="lucide lucide-grid3x3 lucide-grid-3x3" > { expect(container.firstChild).toMatchSnapshot(); expect(container.firstChild).toBeDefined(); }); + + it('should create a component from an iconNode with iconName', () => { + const AirVent = createLucideIcon('air-vent', airVent); + + const { container } = render(); + + expect(container.firstChild).toMatchSnapshot(); + expect(container.firstChild).toBeDefined(); + }); + + it('should include backwards compatible className', () => { + const Layout2 = createLucideIcon('layout-2', airVent); + + const { container } = render(); + + expect(container.firstChild).toMatchSnapshot(); + expect(container.firstChild).toBeDefined(); + }); }); diff --git a/packages/lucide-solid/scripts/exportTemplate.mjs b/packages/lucide-solid/scripts/exportTemplate.mjs index 116b257b5..5c1a4a686 100644 --- a/packages/lucide-solid/scripts/exportTemplate.mjs +++ b/packages/lucide-solid/scripts/exportTemplate.mjs @@ -30,7 +30,7 @@ const iconNode: IconNode = ${JSON.stringify(children)}; * ${deprecated ? `@deprecated ${deprecationReason}` : ''} */ const ${componentName} = (props: LucideProps) => ( - + ) export default ${componentName}; diff --git a/packages/lucide-solid/src/Icon.tsx b/packages/lucide-solid/src/Icon.tsx index d805f72ca..fb3f07713 100644 --- a/packages/lucide-solid/src/Icon.tsx +++ b/packages/lucide-solid/src/Icon.tsx @@ -2,7 +2,7 @@ import { For, splitProps } from 'solid-js'; import { Dynamic } from 'solid-js/web'; import defaultAttributes from './defaultAttributes'; import { IconNode, LucideProps } from './types'; -import { mergeClasses, toKebabCase } from '@lucide/shared'; +import { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared'; interface IconProps { name?: string; @@ -36,7 +36,12 @@ const Icon = (props: LucideProps & IconProps) => { class={mergeClasses( 'lucide', 'lucide-icon', - localProps.name != null ? `lucide-${toKebabCase(localProps?.name)}` : undefined, + ...(localProps.name != null + ? [ + `lucide-${toKebabCase(toPascalCase(localProps.name))}`, + `lucide-${toKebabCase(localProps.name)}`, + ] + : []), localProps.class != null ? localProps.class : '', )} {...rest} diff --git a/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap b/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap index 47ba999bf..73f49add4 100644 --- a/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap +++ b/packages/lucide-solid/tests/__snapshots__/lucide-solid.spec.tsx.snap @@ -10,7 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and height="48" stroke="red" stroke-width="4" - class="lucide lucide-icon lucide-grid3x3" + class="lucide lucide-icon lucide-grid3x3 lucide-grid-3x3" data-testid="grid-icon" > should not scale the strokeWidth when ab height="48" stroke="red" stroke-width="1" - class="lucide lucide-icon lucide-grid3x3" + class="lucide lucide-icon lucide-grid3x3 lucide-grid-3x3" data-testid="grid-icon" > should render a component 1`] = ` height="24" stroke="currentColor" stroke-width="2" - class="lucide lucide-icon lucide-grid3x3" + class="lucide lucide-icon lucide-grid3x3 lucide-grid-3x3" > = ( height: size || defaultAttributes.height, stroke: color || defaultAttributes.stroke, 'stroke-width': absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth, - class: ['lucide', `lucide-${toKebabCase(name ?? 'icon')}`], + class: mergeClasses( + 'lucide', + ...(name + ? [`lucide-${toKebabCase(toPascalCase(name))}-icon`, `lucide-${toKebabCase(name)}`] + : ['lucide-icon']), + ), ...props, }, [...iconNode.map((child) => h(...child)), ...(slots.default ? [slots.default()] : [])], diff --git a/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap b/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap index c9e6de197..88156ce1b 100644 --- a/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap +++ b/packages/lucide-vue-next/tests/__snapshots__/lucide-vue-next.spec.ts.snap @@ -3,7 +3,7 @@ exports[`Using lucide icon components > should add a class to the element 1`] = `
should add a class to the element 1`] = exports[`Using lucide icon components > should add a style attribute to the element 1`] = `
should add a style attribute to the elem exports[`Using lucide icon components > should adjust the size, stroke color and stroke width 1`] = `
should adjust the size, stroke color and exports[`Using lucide icon components > should pass children to the icon slot 1`] = `
should pass children to the icon slot 1` exports[`Using lucide icon components > should render an component 1`] = `