mirror of
https://github.com/lucide-icons/lucide.git
synced 2025-12-15 21:17:41 +01:00
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 <eric.fennis@gmail.com>
This commit is contained in:
@@ -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};
|
||||
`;
|
||||
|
||||
@@ -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<string | JSX.SignalLike<string | undefined>>(
|
||||
`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;
|
||||
};
|
||||
|
||||
@@ -27,3 +27,59 @@ exports[`Using createLucideIcon > should create a component from an iconNode 1`]
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using createLucideIcon > should create a component from an iconNode with iconName 1`] = `
|
||||
<svg
|
||||
class="lucide lucide-air-vent"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
|
||||
/>
|
||||
<path
|
||||
d="M6 8h12"
|
||||
/>
|
||||
<path
|
||||
d="M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12"
|
||||
/>
|
||||
<path
|
||||
d="M6.6 15.6A2 2 0 1 0 10 17v-5"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using createLucideIcon > should include backwards compatible className 1`] = `
|
||||
<svg
|
||||
class="lucide lucide-layout2 lucide-layout-2"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
|
||||
/>
|
||||
<path
|
||||
d="M6 8h12"
|
||||
/>
|
||||
<path
|
||||
d="M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12"
|
||||
/>
|
||||
<path
|
||||
d="M6.6 15.6A2 2 0 1 0 10 17v-5"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
@@ -40,7 +40,7 @@ exports[`Using lucide icon components > 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"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
@@ -70,7 +70,7 @@ exports[`Using lucide icon components > 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"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
|
||||
@@ -12,4 +12,22 @@ describe('Using createLucideIcon', () => {
|
||||
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(<AirVent />);
|
||||
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
expect(container.firstChild).toBeDefined();
|
||||
});
|
||||
|
||||
it('should include backwards compatible className', () => {
|
||||
const Layout2 = createLucideIcon('layout-2', airVent);
|
||||
|
||||
const { container } = render(<Layout2 />);
|
||||
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
expect(container.firstChild).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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};
|
||||
`;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Using createLucideIcon > should create a component from an iconNode 1`] = `
|
||||
<svg
|
||||
class="lucide lucide-air-vent lucide-AirVent"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
|
||||
/>
|
||||
<path
|
||||
d="M6 8h12"
|
||||
/>
|
||||
<path
|
||||
d="M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12"
|
||||
/>
|
||||
<path
|
||||
d="M6.6 15.6A2 2 0 1 0 10 17v-5"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using createLucideIcon > should create a component from an iconNode with iconName 1`] = `
|
||||
<svg
|
||||
class="lucide lucide-air-vent"
|
||||
fill="none"
|
||||
@@ -27,3 +55,31 @@ exports[`Using createLucideIcon > should create a component from an iconNode 1`]
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using createLucideIcon > should include backwards compatible className 1`] = `
|
||||
<svg
|
||||
class="lucide lucide-layout2 lucide-layout-2"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
|
||||
/>
|
||||
<path
|
||||
d="M6 8h12"
|
||||
/>
|
||||
<path
|
||||
d="M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12"
|
||||
/>
|
||||
<path
|
||||
d="M6.6 15.6A2 2 0 1 0 10 17v-5"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
@@ -40,7 +40,7 @@ exports[`Using lucide icon components > 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"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
@@ -70,7 +70,7 @@ exports[`Using lucide icon components > 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"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
|
||||
@@ -12,4 +12,22 @@ describe('Using createLucideIcon', () => {
|
||||
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(<AirVent />);
|
||||
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
expect(container.firstChild).toBeDefined();
|
||||
});
|
||||
|
||||
it('should include backwards compatible className', () => {
|
||||
const Layout2 = createLucideIcon('layout-2', airVent);
|
||||
|
||||
const { container } = render(<Layout2 />);
|
||||
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
expect(container.firstChild).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ const iconNode: IconNode = ${JSON.stringify(children)};
|
||||
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||
*/
|
||||
const ${componentName} = (props: LucideProps) => (
|
||||
<Icon {...props} name="${componentName}" iconNode={iconNode} />
|
||||
<Icon {...props} iconNode={iconNode} name="${iconName}" />
|
||||
)
|
||||
|
||||
export default ${componentName};
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
<rect width="18"
|
||||
@@ -50,7 +50,7 @@ exports[`Using lucide icon components > 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"
|
||||
>
|
||||
<rect width="18"
|
||||
@@ -90,7 +90,7 @@ exports[`Using lucide icon components > 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"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
|
||||
@@ -26,7 +26,7 @@ import createLucideIcon from '../createLucideIcon';
|
||||
* @returns {FunctionalComponent} Vue component
|
||||
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||
*/
|
||||
const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)});
|
||||
const ${componentName} = createLucideIcon('${iconName}', ${JSON.stringify(children)});
|
||||
|
||||
export default ${componentName};
|
||||
`;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type FunctionalComponent, h } from 'vue';
|
||||
import { toKebabCase } from '@lucide/shared';
|
||||
import { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';
|
||||
import defaultAttributes from './defaultAttributes';
|
||||
import { IconNode, LucideProps } from './types';
|
||||
|
||||
@@ -20,7 +20,12 @@ const Icon: FunctionalComponent<LucideProps & IconProps> = (
|
||||
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()] : [])],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`Using lucide icon components > should add a class to the element 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon my-icon"
|
||||
class="lucide lucide-smile-icon lucide-smile my-icon"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
@@ -41,7 +41,7 @@ exports[`Using lucide icon components > should add a class to the element 1`] =
|
||||
exports[`Using lucide icon components > should add a style attribute to the element 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
@@ -80,7 +80,7 @@ exports[`Using lucide icon components > should add a style attribute to the elem
|
||||
exports[`Using lucide icon components > should adjust the size, stroke color and stroke width 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="48"
|
||||
stroke="red"
|
||||
@@ -118,7 +118,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
|
||||
exports[`Using lucide icon components > should pass children to the icon slot 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
@@ -161,7 +161,7 @@ exports[`Using lucide icon components > should pass children to the icon slot 1`
|
||||
exports[`Using lucide icon components > should render an component 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
|
||||
Reference in New Issue
Block a user