Add support for alias classnames in lucide-solid

This commit is contained in:
Eric Fennis
2025-03-19 11:38:26 +01:00
parent cf48dbb2d3
commit 613cac84d0
5 changed files with 35 additions and 28 deletions

View File

@@ -66,6 +66,7 @@
"build:bundle": "rollup -c rollup.config.mjs",
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --separateAliasesFile --aliasesFileExtension=.ts --iconFileExtension=.tsx --exportFileName=index.ts",
"test": "pnpm build:icons && vitest run",
"test:update": "vitest run -u",
"version": "pnpm version --git-tag-version=false"
},
"devDependencies": {

View File

@@ -8,6 +8,7 @@ export default async ({
getSvg,
deprecated,
deprecationReason,
iconNameAliases,
}) => {
const svgContents = await getSvg();
const svgBase64 = base64SVG(svgContents);
@@ -30,7 +31,9 @@ const iconNode: IconNode = ${JSON.stringify(children)};
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
*/
const ${componentName} = (props: LucideProps) => (
<Icon {...props} name="${componentName}" iconNode={iconNode} />
<Icon {...props} name="${componentName}" iconNode={iconNode}${
iconNameAliases != null ? ` aliasNames={${JSON.stringify(iconNameAliases)}}` : ''
} />
)
export default ${componentName};

View File

@@ -2,11 +2,12 @@ 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, createLucideClassNames } from '@lucide/shared';
interface IconProps {
name?: string;
iconNode: IconNode;
aliasNames?: string[];
}
const Icon = (props: LucideProps & IconProps) => {
@@ -19,6 +20,7 @@ const Icon = (props: LucideProps & IconProps) => {
'name',
'iconNode',
'absoluteStrokeWidth',
'aliasNames'
]);
return (
@@ -37,6 +39,7 @@ const Icon = (props: LucideProps & IconProps) => {
'lucide',
'lucide-icon',
localProps.name != null ? `lucide-${toKebabCase(localProps?.name)}` : undefined,
localProps.aliasNames != null ? createLucideClassNames(localProps.aliasNames) : undefined,
localProps.class != null ? localProps.class : '',
)}
{...rest}

View File

@@ -10,8 +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"
data-testid="grid-icon"
class="lucide lucide-icon lucide-grid3x3 lucide-grid lucide-grid-3-x-3"
>
<rect width="18"
height="18"
@@ -50,8 +49,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"
data-testid="grid-icon"
class="lucide lucide-icon lucide-grid3x3 lucide-grid lucide-grid-3-x-3"
>
<rect width="18"
height="18"
@@ -90,7 +88,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 lucide-grid-3-x-3"
>
<rect width="18"
height="18"

View File

@@ -10,31 +10,27 @@ describe('Using lucide icon components', () => {
});
it('should adjust the size, stroke color and stroke width', async () => {
const testId = 'grid-icon';
const { container, getByTestId } = render(() => (
<Grid
data-testid={testId}
size={48}
color="red"
strokeWidth={4}
/>
));
const { attributes } = (await getByTestId(testId)) as unknown as {
attributes: Record<string, { value: string }>;
};
expect(attributes.stroke.value).toBe('red');
expect(attributes.width.value).toBe('48');
expect(attributes.height.value).toBe('48');
expect(attributes['stroke-width'].value).toBe('4');
const gridIcon = container.firstChild as SVGElement;
expect(gridIcon).toHaveAttribute('width', '48');
expect(gridIcon).toHaveAttribute('height', '48');
expect(gridIcon).toHaveAttribute('stroke', 'red');
expect(gridIcon).toHaveAttribute('stroke-width', '4');
expect(container.innerHTML).toMatchSnapshot();
});
it('should render the alias icon', () => {
const testId = 'pen-icon';
const { container } = render(() => (
<Pen
data-testid={testId}
size={48}
stroke="red"
strokeWidth={4}
@@ -47,7 +43,6 @@ describe('Using lucide icon components', () => {
const { container: Edit2Container } = render(() => (
<Edit2
data-testid={testId}
size={48}
stroke="red"
strokeWidth={4}
@@ -57,24 +52,31 @@ describe('Using lucide icon components', () => {
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
});
it('should render the alias icon name classNames', () => {
const { container } = render(() => (
<Pen />
));
const PenIcon = container.firstChild;
expect(PenIcon).toHaveClass('lucide-edit-2');
})
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
const testId = 'grid-icon';
const { container, getByTestId } = render(() => (
<Grid
data-testid={testId}
size={48}
color="red"
absoluteStrokeWidth
/>
));
const { attributes } = getByTestId(testId) as unknown as {
attributes: Record<string, { value: string }>;
};
expect(attributes.stroke.value).toBe('red');
expect(attributes.width.value).toBe('48');
expect(attributes.height.value).toBe('48');
expect(attributes['stroke-width'].value).toBe('1');
const gridIcon = container.firstChild as SVGElement;
expect(gridIcon).toHaveAttribute('stroke-width', '1');
expect(gridIcon).toHaveAttribute('width', '48');
expect(gridIcon).toHaveAttribute('height', '48');
expect(gridIcon).toHaveAttribute('stroke', 'red');
expect(container.innerHTML).toMatchSnapshot();
});