Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: consistent icon name class #2878

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/lucide-preact/scripts/exportTemplate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
`;
Expand Down
5 changes: 3 additions & 2 deletions packages/lucide-preact/src/createLucideIcon.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -17,14 +17,15 @@ const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => {
...props,
iconNode,
class: mergeClasses<string | JSX.SignalLike<string | undefined>>(
`lucide-${toKebabCase(toPascalCase(iconName))}`,
`lucide-${toKebabCase(iconName)}`,
classes,
),
},
children,
);

Component.displayName = `${iconName}`;
Component.displayName = toPascalCase(iconName);

return Component;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
18 changes: 18 additions & 0 deletions packages/lucide-preact/tests/createLucideIcon.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
2 changes: 1 addition & 1 deletion packages/lucide-react/scripts/exportTemplate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
`;
Expand Down
10 changes: 7 additions & 3 deletions packages/lucide-react/src/createLucideIcon.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
18 changes: 18 additions & 0 deletions packages/lucide-react/tests/createLucideIcon.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
2 changes: 1 addition & 1 deletion packages/lucide-solid/scripts/exportTemplate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
9 changes: 7 additions & 2 deletions packages/lucide-solid/src/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion packages/lucide-vue-next/scripts/exportTemplate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
`;
Expand Down
9 changes: 7 additions & 2 deletions packages/lucide-vue-next/src/Icon.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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()] : [])],
Expand Down
Loading