Compare commits
10 Commits
fix-stable
...
backwards-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba3d66dc53 | ||
|
|
c663a141b6 | ||
|
|
35a1ec15cc | ||
|
|
8a44e63e80 | ||
|
|
35afa59c99 | ||
|
|
c42676b0fd | ||
|
|
613cac84d0 | ||
|
|
cf48dbb2d3 | ||
|
|
4edcf24fc9 | ||
|
|
1efc9eb8b5 |
@@ -14,5 +14,5 @@
|
|||||||
<path d="M9 9h.01" />
|
<path d="M9 9h.01" />
|
||||||
<circle cx="20" cy="16" r="2" />
|
<circle cx="20" cy="16" r="2" />
|
||||||
<circle cx="9" cy="9" r="7" />
|
<circle cx="9" cy="9" r="7" />
|
||||||
<rect x="4" y="16" width="10" height="6" rx="2" />
|
<rect width="10" height="6" x="4" y="16" rx="2" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 439 B After Width: | Height: | Size: 439 B |
@@ -13,5 +13,5 @@
|
|||||||
<path d="M16 4h2a2 2 0 0 1 2 2v1.344" />
|
<path d="M16 4h2a2 2 0 0 1 2 2v1.344" />
|
||||||
<path d="m17 18 4-4-4-4" />
|
<path d="m17 18 4-4-4-4" />
|
||||||
<path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113" />
|
<path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113" />
|
||||||
<rect x="8" y="2" width="8" height="4" rx="1" />
|
<rect width="8" height="4" x="8" y="2" rx="1" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 435 B |
@@ -21,4 +21,4 @@
|
|||||||
<path d="m21.7 19.4-.9-.3" />
|
<path d="m21.7 19.4-.9-.3" />
|
||||||
<path d="M9 3v18" />
|
<path d="M9 3v18" />
|
||||||
<circle cx="18" cy="18" r="3" />
|
<circle cx="18" cy="18" r="3" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 617 B After Width: | Height: | Size: 618 B |
@@ -21,6 +21,6 @@
|
|||||||
<path d="M20 7h2" />
|
<path d="M20 7h2" />
|
||||||
<path d="M7 20v2" />
|
<path d="M7 20v2" />
|
||||||
<path d="M7 2v2" />
|
<path d="M7 2v2" />
|
||||||
<rect x="4" y="4" width="16" height="16" rx="2" />
|
<rect width="16" height="16" x="4" y="4" rx="2" />
|
||||||
<rect x="8" y="8" width="8" height="8" rx="1" />
|
<rect width="8" height="8" x="8" y="8" rx="1" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 590 B After Width: | Height: | Size: 590 B |
@@ -12,5 +12,5 @@
|
|||||||
<path d="m13 21-3-3 3-3" />
|
<path d="m13 21-3-3 3-3" />
|
||||||
<path d="M20 18H10" />
|
<path d="M20 18H10" />
|
||||||
<path d="M3 11h.01" />
|
<path d="M3 11h.01" />
|
||||||
<rect x="6" y="3" width="5" height="8" rx="2.5" />
|
<rect width="5" height="8" x="6" y="3" rx="2.5" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
@@ -12,6 +12,6 @@
|
|||||||
<path d="M10 18h10" />
|
<path d="M10 18h10" />
|
||||||
<path d="m17 21 3-3-3-3" />
|
<path d="m17 21 3-3-3-3" />
|
||||||
<path d="M3 11h.01" />
|
<path d="M3 11h.01" />
|
||||||
<rect x="15" y="3" width="5" height="8" rx="2.5" />
|
<rect width="5" height="8" x="15" y="3" rx="2.5" />
|
||||||
<rect x="6" y="3" width="5" height="8" rx="2.5" />
|
<rect width="5" height="8" x="6" y="3" rx="2.5" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
@@ -13,5 +13,5 @@
|
|||||||
<path d="M18 9V6a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v14" />
|
<path d="M18 9V6a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v14" />
|
||||||
<path d="M2 20h8" />
|
<path d="M2 20h8" />
|
||||||
<path d="M20 17v-2a2 2 0 1 0-4 0v2" />
|
<path d="M20 17v-2a2 2 0 1 0-4 0v2" />
|
||||||
<rect x="14" y="17" width="8" height="5" rx="1" />
|
<rect width="8" height="5" x="14" y="17" rx="1" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 407 B |
@@ -10,5 +10,5 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" />
|
<path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" />
|
||||||
<rect x="2" y="4" width="20" height="16" rx="2" />
|
<rect width="20" height="16" x="2" y="4" rx="2" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 316 B |
@@ -10,8 +10,8 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z" />
|
<path d="M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z" />
|
||||||
<circle cx="13.5" cy="6.5" r=".5" fill="currentColor" />
|
<circle cx="13.5" cy="6.5" r=".5" />
|
||||||
<circle cx="17.5" cy="10.5" r=".5" fill="currentColor" />
|
<circle cx="17.5" cy="10.5" r=".5" />
|
||||||
<circle cx="6.5" cy="12.5" r=".5" fill="currentColor" />
|
<circle cx="6.5" cy="12.5" r=".5" />
|
||||||
<circle cx="8.5" cy="7.5" r=".5" fill="currentColor" />
|
<circle cx="8.5" cy="7.5" r=".5" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 571 B After Width: | Height: | Size: 491 B |
@@ -15,5 +15,5 @@
|
|||||||
<path d="M20 8V4" />
|
<path d="M20 8V4" />
|
||||||
<path d="M4 8V4" />
|
<path d="M4 8V4" />
|
||||||
<path d="M8 15v-3.014" />
|
<path d="M8 15v-3.014" />
|
||||||
<rect x="3" y="12" width="18" height="7" rx="1" />
|
<rect width="18" height="7" x="3" y="12" rx="1" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 415 B After Width: | Height: | Size: 415 B |
@@ -13,4 +13,4 @@
|
|||||||
<path d="M5 17A12 12 0 0 1 17 5" />
|
<path d="M5 17A12 12 0 0 1 17 5" />
|
||||||
<circle cx="19" cy="5" r="2" />
|
<circle cx="19" cy="5" r="2" />
|
||||||
<circle cx="5" cy="19" r="2" />
|
<circle cx="5" cy="19" r="2" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 458 B After Width: | Height: | Size: 459 B |
@@ -11,4 +11,4 @@
|
|||||||
>
|
>
|
||||||
<path d="M16 12v2a2 2 0 0 1-2 2H9a1 1 0 0 0-1 1v3a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2h0" />
|
<path d="M16 12v2a2 2 0 0 1-2 2H9a1 1 0 0 0-1 1v3a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2h0" />
|
||||||
<path d="M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3a1 1 0 0 1-1 1h-5a2 2 0 0 0-2 2v2" />
|
<path d="M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3a1 1 0 0 1-1 1h-5a2 2 0 0 0-2 2v2" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 416 B After Width: | Height: | Size: 417 B |
@@ -20,4 +20,4 @@
|
|||||||
<path d="M4 16a2 2 0 0 1-2-2" />
|
<path d="M4 16a2 2 0 0 1-2-2" />
|
||||||
<path d="M8 10a2 2 0 0 1 2-2h5a1 1 0 0 1 1 1v5a2 2 0 0 1-2 2H9a1 1 0 0 1-1-1z" />
|
<path d="M8 10a2 2 0 0 1 2-2h5a1 1 0 0 1 1 1v5a2 2 0 0 1-2 2H9a1 1 0 0 1-1-1z" />
|
||||||
<path d="M8 2h2" />
|
<path d="M8 2h2" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 596 B After Width: | Height: | Size: 597 B |
@@ -15,4 +15,4 @@
|
|||||||
<path d="M20 8a2 2 0 0 1 2 2" />
|
<path d="M20 8a2 2 0 0 1 2 2" />
|
||||||
<path d="M22 14v2" />
|
<path d="M22 14v2" />
|
||||||
<path d="M22 20a2 2 0 0 1-2 2" />
|
<path d="M22 20a2 2 0 0 1-2 2" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 482 B |
@@ -10,4 +10,4 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3a1 1 0 0 0 1 1h3a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2v-3a1 1 0 0 0-1-1z" />
|
<path d="M4 16a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3a1 1 0 0 0 1 1h3a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2v-3a1 1 0 0 0-1-1z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 359 B After Width: | Height: | Size: 360 B |
@@ -39,6 +39,7 @@
|
|||||||
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts",
|
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts",
|
||||||
"build:bundles": "rollup -c ./rollup.config.mjs",
|
"build:bundles": "rollup -c ./rollup.config.mjs",
|
||||||
"test": "pnpm build:icons && vitest run",
|
"test": "pnpm build:icons && vitest run",
|
||||||
|
"test:update": "vitest run -u",
|
||||||
"version": "pnpm version --git-tag-version=false"
|
"version": "pnpm version --git-tag-version=false"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default async ({
|
|||||||
getSvg,
|
getSvg,
|
||||||
deprecated,
|
deprecated,
|
||||||
deprecationReason,
|
deprecationReason,
|
||||||
|
iconNameAliases,
|
||||||
}) => {
|
}) => {
|
||||||
const svgContents = await getSvg();
|
const svgContents = await getSvg();
|
||||||
const svgBase64 = base64SVG(svgContents);
|
const svgBase64 = base64SVG(svgContents);
|
||||||
@@ -26,7 +27,9 @@ import createLucideIcon from '../createLucideIcon';
|
|||||||
* @returns {JSX.Element} JSX Element
|
* @returns {JSX.Element} JSX Element
|
||||||
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||||
*/
|
*/
|
||||||
const ${componentName} = createLucideIcon('${iconName}', ${JSON.stringify(children)});
|
const ${componentName} = createLucideIcon('${componentName}', ${JSON.stringify(children)}${
|
||||||
|
iconNameAliases != null ? `, ${JSON.stringify(iconNameAliases)}` : ''
|
||||||
|
});
|
||||||
|
|
||||||
export default ${componentName};
|
export default ${componentName};
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { h, type JSX } from 'preact';
|
import { h, type JSX } from 'preact';
|
||||||
import { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';
|
import { createLucideClassNames, mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';
|
||||||
import Icon from './Icon';
|
import Icon from './Icon';
|
||||||
import type { IconNode, LucideIcon, LucideProps } from './types';
|
import type { IconNode, LucideIcon, LucideProps } from './types';
|
||||||
|
|
||||||
@@ -9,7 +9,12 @@ import type { IconNode, LucideIcon, LucideProps } from './types';
|
|||||||
* @param {array} iconNode
|
* @param {array} iconNode
|
||||||
* @returns {FunctionComponent} LucideIcon
|
* @returns {FunctionComponent} LucideIcon
|
||||||
*/
|
*/
|
||||||
const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => {
|
const createLucideIcon = (iconName: string, iconNode: IconNode, aliasNames: string[] = []): LucideIcon => {
|
||||||
|
const lucideClassNames = createLucideClassNames([
|
||||||
|
iconName,
|
||||||
|
...aliasNames,
|
||||||
|
]);
|
||||||
|
|
||||||
const Component = ({ class: classes = '', children, ...props }: LucideProps) =>
|
const Component = ({ class: classes = '', children, ...props }: LucideProps) =>
|
||||||
h(
|
h(
|
||||||
Icon,
|
Icon,
|
||||||
@@ -17,8 +22,8 @@ const createLucideIcon = (iconName: string, iconNode: IconNode): LucideIcon => {
|
|||||||
...props,
|
...props,
|
||||||
iconNode,
|
iconNode,
|
||||||
class: mergeClasses<string | JSX.SignalLike<string | undefined>>(
|
class: mergeClasses<string | JSX.SignalLike<string | undefined>>(
|
||||||
|
lucideClassNames,
|
||||||
`lucide-${toKebabCase(toPascalCase(iconName))}`,
|
`lucide-${toKebabCase(toPascalCase(iconName))}`,
|
||||||
`lucide-${toKebabCase(iconName)}`,
|
|
||||||
classes,
|
classes,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ exports[`Using createLucideIcon > should create a component from an iconNode wit
|
|||||||
|
|
||||||
exports[`Using createLucideIcon > should include backwards compatible className 1`] = `
|
exports[`Using createLucideIcon > should include backwards compatible className 1`] = `
|
||||||
<svg
|
<svg
|
||||||
class="lucide lucide-layout2 lucide-layout-2"
|
class="lucide lucide-layout-2 lucide-layout2"
|
||||||
fill="none"
|
fill="none"
|
||||||
height="24"
|
height="24"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
|
|||||||
stroke-width="4"
|
stroke-width="4"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
class="lucide lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-grid3x3 lucide-grid lucide-grid-3-x-3 lucide-grid3x3"
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@@ -40,7 +40,7 @@ exports[`Using lucide icon components > should not scale the strokeWidth when ab
|
|||||||
stroke-width="1"
|
stroke-width="1"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
class="lucide lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-grid3x3 lucide-grid lucide-grid-3-x-3 lucide-grid3x3"
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@@ -70,7 +70,7 @@ exports[`Using lucide icon components > should render an component 1`] = `
|
|||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
class="lucide lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-grid3x3 lucide-grid lucide-grid-3-x-3 lucide-grid3x3"
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
|
|||||||
@@ -70,6 +70,16 @@ describe('Using lucide icon components', () => {
|
|||||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
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', () => {
|
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<Grid
|
<Grid
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
"typecheck": "tsc",
|
"typecheck": "tsc",
|
||||||
"typecheck:watch": "tsc -w",
|
"typecheck:watch": "tsc -w",
|
||||||
"test": "pnpm build:icons && vitest run",
|
"test": "pnpm build:icons && vitest run",
|
||||||
|
"test:update": "vitest run -u",
|
||||||
"test:watch": "vitest watch",
|
"test:watch": "vitest watch",
|
||||||
"version": "pnpm version --git-tag-version=false"
|
"version": "pnpm version --git-tag-version=false"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default async ({
|
|||||||
getSvg,
|
getSvg,
|
||||||
deprecated,
|
deprecated,
|
||||||
deprecationReason,
|
deprecationReason,
|
||||||
|
iconNameAliases,
|
||||||
}) => {
|
}) => {
|
||||||
const svgContents = await getSvg();
|
const svgContents = await getSvg();
|
||||||
const svgBase64 = base64SVG(svgContents);
|
const svgBase64 = base64SVG(svgContents);
|
||||||
@@ -29,7 +30,9 @@ export const __iconNode: IconNode = ${JSON.stringify(children)}
|
|||||||
* @returns {JSX.Element} JSX Element
|
* @returns {JSX.Element} JSX Element
|
||||||
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||||
*/
|
*/
|
||||||
const ${componentName} = createLucideIcon('${iconName}', __iconNode);
|
const ${componentName} = createLucideIcon('${iconName}', __iconNode${
|
||||||
|
iconNameAliases != null ? `, ${JSON.stringify(iconNameAliases)}` : ''
|
||||||
|
});
|
||||||
|
|
||||||
export default ${componentName};
|
export default ${componentName};
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createElement, forwardRef } from 'react';
|
import { createElement, forwardRef } from 'react';
|
||||||
import { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';
|
import { mergeClasses, createLucideClassNames, toPascalCase, toKebabCase } from '@lucide/shared';
|
||||||
import { IconNode, LucideProps } from './types';
|
import { IconNode, LucideProps } from './types';
|
||||||
import Icon from './Icon';
|
import Icon from './Icon';
|
||||||
|
|
||||||
@@ -9,14 +9,19 @@ import Icon from './Icon';
|
|||||||
* @param {array} iconNode
|
* @param {array} iconNode
|
||||||
* @returns {ForwardRefExoticComponent} LucideIcon
|
* @returns {ForwardRefExoticComponent} LucideIcon
|
||||||
*/
|
*/
|
||||||
const createLucideIcon = (iconName: string, iconNode: IconNode) => {
|
const createLucideIcon = (iconName: string, iconNode: IconNode, aliasNames: string[] = []) => {
|
||||||
|
const lucideClassNames = createLucideClassNames([
|
||||||
|
iconName,
|
||||||
|
...aliasNames,
|
||||||
|
]);
|
||||||
|
|
||||||
const Component = forwardRef<SVGSVGElement, LucideProps>(({ className, ...props }, ref) =>
|
const Component = forwardRef<SVGSVGElement, LucideProps>(({ className, ...props }, ref) =>
|
||||||
createElement(Icon, {
|
createElement(Icon, {
|
||||||
ref,
|
ref,
|
||||||
iconNode,
|
iconNode,
|
||||||
className: mergeClasses(
|
className: mergeClasses(
|
||||||
`lucide-${toKebabCase(toPascalCase(iconName))}`,
|
`lucide-${toKebabCase(toPascalCase(iconName))}`,
|
||||||
`lucide-${iconName}`,
|
lucideClassNames,
|
||||||
className,
|
className,
|
||||||
),
|
),
|
||||||
...props,
|
...props,
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
exports[`Using createLucideIcon > should create a component from an iconNode 1`] = `
|
exports[`Using createLucideIcon > should create a component from an iconNode 1`] = `
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
class="lucide lucide-air-vent"
|
||||||
class="lucide lucide-air-vent lucide-AirVent"
|
|
||||||
fill="none"
|
fill="none"
|
||||||
height="24"
|
height="24"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
|
|||||||
stroke-width="4"
|
stroke-width="4"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
class="lucide lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-grid3x3 lucide-grid-3x3 lucide-grid lucide-grid-3-x-3"
|
||||||
aria-hidden="true"
|
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@@ -41,8 +40,7 @@ exports[`Using lucide icon components > should not scale the strokeWidth when ab
|
|||||||
stroke-width="1"
|
stroke-width="1"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
class="lucide lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-grid3x3 lucide-grid-3x3 lucide-grid lucide-grid-3-x-3"
|
||||||
aria-hidden="true"
|
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@@ -72,8 +70,7 @@ exports[`Using lucide icon components > should render an component 1`] = `
|
|||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
class="lucide lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-grid3x3 lucide-grid-3x3 lucide-grid lucide-grid-3-x-3"
|
||||||
aria-hidden="true"
|
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
|
|||||||
@@ -69,6 +69,16 @@ describe('Using lucide icon components', () => {
|
|||||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
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', () => {
|
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||||
const { container, getByTestId } = render(
|
const { container, getByTestId } = render(
|
||||||
<Grid
|
<Grid
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"build:bundle": "rollup -c rollup.config.mjs",
|
"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",
|
"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": "pnpm build:icons && vitest run",
|
||||||
|
"test:update": "vitest run -u",
|
||||||
"version": "pnpm version --git-tag-version=false"
|
"version": "pnpm version --git-tag-version=false"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export default async ({
|
|||||||
getSvg,
|
getSvg,
|
||||||
deprecated,
|
deprecated,
|
||||||
deprecationReason,
|
deprecationReason,
|
||||||
|
iconNameAliases,
|
||||||
}) => {
|
}) => {
|
||||||
const svgContents = await getSvg();
|
const svgContents = await getSvg();
|
||||||
const svgBase64 = base64SVG(svgContents);
|
const svgBase64 = base64SVG(svgContents);
|
||||||
@@ -30,7 +31,9 @@ const iconNode: IconNode = ${JSON.stringify(children)};
|
|||||||
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||||
*/
|
*/
|
||||||
const ${componentName} = (props: LucideProps) => (
|
const ${componentName} = (props: LucideProps) => (
|
||||||
<Icon {...props} iconNode={iconNode} name="${iconName}" />
|
<Icon {...props} name="${iconName}" iconNode={iconNode}${
|
||||||
|
iconNameAliases != null ? ` aliasNames={${JSON.stringify(iconNameAliases)}}` : ''
|
||||||
|
} />
|
||||||
)
|
)
|
||||||
|
|
||||||
export default ${componentName};
|
export default ${componentName};
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ import { For, splitProps } from 'solid-js';
|
|||||||
import { Dynamic } from 'solid-js/web';
|
import { Dynamic } from 'solid-js/web';
|
||||||
import defaultAttributes from './defaultAttributes';
|
import defaultAttributes from './defaultAttributes';
|
||||||
import { IconNode, LucideProps } from './types';
|
import { IconNode, LucideProps } from './types';
|
||||||
import { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';
|
import { mergeClasses, toKebabCase, createLucideClassNames, toPascalCase } from '@lucide/shared';
|
||||||
|
|
||||||
interface IconProps {
|
interface IconProps {
|
||||||
name?: string;
|
name?: string;
|
||||||
iconNode: IconNode;
|
iconNode: IconNode;
|
||||||
|
aliasNames?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Icon = (props: LucideProps & IconProps) => {
|
const Icon = (props: LucideProps & IconProps) => {
|
||||||
@@ -19,6 +20,7 @@ const Icon = (props: LucideProps & IconProps) => {
|
|||||||
'name',
|
'name',
|
||||||
'iconNode',
|
'iconNode',
|
||||||
'absoluteStrokeWidth',
|
'absoluteStrokeWidth',
|
||||||
|
'aliasNames'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -42,6 +44,7 @@ const Icon = (props: LucideProps & IconProps) => {
|
|||||||
`lucide-${toKebabCase(localProps.name)}`,
|
`lucide-${toKebabCase(localProps.name)}`,
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
localProps.aliasNames != null ? createLucideClassNames(localProps.aliasNames) : undefined,
|
||||||
localProps.class != null ? localProps.class : '',
|
localProps.class != null ? localProps.class : '',
|
||||||
)}
|
)}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
|
|||||||
height="48"
|
height="48"
|
||||||
stroke="red"
|
stroke="red"
|
||||||
stroke-width="4"
|
stroke-width="4"
|
||||||
class="lucide lucide-icon lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-icon lucide-grid3x3 lucide-grid lucide-grid-3-x-3"
|
||||||
data-testid="grid-icon"
|
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@@ -50,8 +49,7 @@ exports[`Using lucide icon components > should not scale the strokeWidth when ab
|
|||||||
height="48"
|
height="48"
|
||||||
stroke="red"
|
stroke="red"
|
||||||
stroke-width="1"
|
stroke-width="1"
|
||||||
class="lucide lucide-icon lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-icon lucide-grid3x3 lucide-grid lucide-grid-3-x-3"
|
||||||
data-testid="grid-icon"
|
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@@ -90,7 +88,7 @@ exports[`Using lucide icon components > should render a component 1`] = `
|
|||||||
height="24"
|
height="24"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
class="lucide lucide-icon lucide-grid3x3 lucide-grid-3x3"
|
class="lucide lucide-icon lucide-grid3x3 lucide-grid lucide-grid-3-x-3"
|
||||||
>
|
>
|
||||||
<rect width="18"
|
<rect width="18"
|
||||||
height="18"
|
height="18"
|
||||||
|
|||||||
@@ -10,31 +10,27 @@ describe('Using lucide icon components', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should adjust the size, stroke color and stroke width', async () => {
|
it('should adjust the size, stroke color and stroke width', async () => {
|
||||||
const testId = 'grid-icon';
|
|
||||||
const { container, getByTestId } = render(() => (
|
const { container, getByTestId } = render(() => (
|
||||||
<Grid
|
<Grid
|
||||||
data-testid={testId}
|
|
||||||
size={48}
|
size={48}
|
||||||
color="red"
|
color="red"
|
||||||
strokeWidth={4}
|
strokeWidth={4}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
const { attributes } = (await getByTestId(testId)) as unknown as {
|
const gridIcon = container.firstChild as SVGElement;
|
||||||
attributes: Record<string, { value: string }>;
|
|
||||||
};
|
expect(gridIcon).toHaveAttribute('width', '48');
|
||||||
expect(attributes.stroke.value).toBe('red');
|
expect(gridIcon).toHaveAttribute('height', '48');
|
||||||
expect(attributes.width.value).toBe('48');
|
expect(gridIcon).toHaveAttribute('stroke', 'red');
|
||||||
expect(attributes.height.value).toBe('48');
|
expect(gridIcon).toHaveAttribute('stroke-width', '4');
|
||||||
expect(attributes['stroke-width'].value).toBe('4');
|
|
||||||
expect(container.innerHTML).toMatchSnapshot();
|
expect(container.innerHTML).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render the alias icon', () => {
|
it('should render the alias icon', () => {
|
||||||
const testId = 'pen-icon';
|
|
||||||
const { container } = render(() => (
|
const { container } = render(() => (
|
||||||
<Pen
|
<Pen
|
||||||
data-testid={testId}
|
|
||||||
size={48}
|
size={48}
|
||||||
stroke="red"
|
stroke="red"
|
||||||
strokeWidth={4}
|
strokeWidth={4}
|
||||||
@@ -47,7 +43,6 @@ describe('Using lucide icon components', () => {
|
|||||||
|
|
||||||
const { container: Edit2Container } = render(() => (
|
const { container: Edit2Container } = render(() => (
|
||||||
<Edit2
|
<Edit2
|
||||||
data-testid={testId}
|
|
||||||
size={48}
|
size={48}
|
||||||
stroke="red"
|
stroke="red"
|
||||||
strokeWidth={4}
|
strokeWidth={4}
|
||||||
@@ -57,24 +52,31 @@ describe('Using lucide icon components', () => {
|
|||||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
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', () => {
|
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||||
const testId = 'grid-icon';
|
|
||||||
const { container, getByTestId } = render(() => (
|
const { container, getByTestId } = render(() => (
|
||||||
<Grid
|
<Grid
|
||||||
data-testid={testId}
|
|
||||||
size={48}
|
size={48}
|
||||||
color="red"
|
color="red"
|
||||||
absoluteStrokeWidth
|
absoluteStrokeWidth
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
const { attributes } = getByTestId(testId) as unknown as {
|
const gridIcon = container.firstChild as SVGElement;
|
||||||
attributes: Record<string, { value: string }>;
|
|
||||||
};
|
expect(gridIcon).toHaveAttribute('stroke-width', '1');
|
||||||
expect(attributes.stroke.value).toBe('red');
|
expect(gridIcon).toHaveAttribute('width', '48');
|
||||||
expect(attributes.width.value).toBe('48');
|
expect(gridIcon).toHaveAttribute('height', '48');
|
||||||
expect(attributes.height.value).toBe('48');
|
expect(gridIcon).toHaveAttribute('stroke', 'red');
|
||||||
expect(attributes['stroke-width'].value).toBe('1');
|
|
||||||
|
|
||||||
expect(container.innerHTML).toMatchSnapshot();
|
expect(container.innerHTML).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
|
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
|
||||||
|
|
||||||
export default async ({ componentName, iconName, getSvg, deprecated, deprecationReason }) => {
|
export default async ({ componentName, iconName, getSvg, deprecated, deprecationReason, iconNameAliases = [] }) => {
|
||||||
let svgContents = await getSvg();
|
let svgContents = await getSvg();
|
||||||
const svgBase64 = base64SVG(svgContents);
|
const svgBase64 = base64SVG(svgContents);
|
||||||
|
|
||||||
|
const iconClassNames = [iconName, ...iconNameAliases].map((aliasName) => `lucide-${aliasName}`).join(' ')
|
||||||
|
|
||||||
svgContents = svgContents.replace(
|
svgContents = svgContents.replace(
|
||||||
'<svg',
|
'<svg',
|
||||||
`
|
`
|
||||||
<svg
|
<svg
|
||||||
class="lucide lucide-${iconName}"`,
|
class="lucide ${iconClassNames}"`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export default async ({
|
|||||||
getSvg,
|
getSvg,
|
||||||
deprecated,
|
deprecated,
|
||||||
deprecationReason,
|
deprecationReason,
|
||||||
|
iconNameAliases
|
||||||
}) => {
|
}) => {
|
||||||
const svgContents = await getSvg();
|
const svgContents = await getSvg();
|
||||||
const svgBase64 = base64SVG(svgContents);
|
const svgBase64 = base64SVG(svgContents);
|
||||||
@@ -36,7 +37,9 @@ const iconNode: IconNode = ${JSON.stringify(children)};
|
|||||||
*/
|
*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Icon name="${iconName}" {...$$props} iconNode={iconNode}>
|
<Icon name="${iconName}" {...$$props} iconNode={iconNode}${
|
||||||
|
iconNameAliases != null ? ` aliasNames={${JSON.stringify(iconNameAliases)}}` : ''
|
||||||
|
}>
|
||||||
<slot/>
|
<slot/>
|
||||||
</Icon>
|
</Icon>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
export let strokeWidth: number | string = 2
|
export let strokeWidth: number | string = 2
|
||||||
export let absoluteStrokeWidth: boolean = false
|
export let absoluteStrokeWidth: boolean = false
|
||||||
export let iconNode: IconNode = []
|
export let iconNode: IconNode = []
|
||||||
|
export let aliasNames: string[] = []
|
||||||
|
|
||||||
const mergeClasses = <ClassType = string | undefined | null>(
|
const mergeClasses = <ClassType = string | undefined | null>(
|
||||||
...classes: ClassType[]
|
...classes: ClassType[]
|
||||||
@@ -34,6 +35,7 @@
|
|||||||
'lucide-icon',
|
'lucide-icon',
|
||||||
'lucide',
|
'lucide',
|
||||||
name ? `lucide-${name}`: '',
|
name ? `lucide-${name}`: '',
|
||||||
|
...aliasNames.map(alias => `lucide-${alias}`),
|
||||||
$$props.class
|
$$props.class
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,14 @@ describe('Using lucide icon components', () => {
|
|||||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
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', () => {
|
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||||
const testId = 'smile-icon';
|
const testId = 'smile-icon';
|
||||||
const { container, getByTestId } = render(Smile, {
|
const { container, getByTestId } = render(Smile, {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import Icon from './Icon';
|
|||||||
* @returns {FunctionalComponent} LucideIcon
|
* @returns {FunctionalComponent} LucideIcon
|
||||||
*/
|
*/
|
||||||
const createLucideIcon =
|
const createLucideIcon =
|
||||||
(iconName: string, iconNode: IconNode): FunctionalComponent<LucideProps> =>
|
(iconName: string, iconNode: IconNode, aliasNames: string[] = []): FunctionalComponent<LucideProps> =>
|
||||||
(props, { slots }) =>
|
(props, { slots }) =>
|
||||||
h(
|
h(
|
||||||
Icon,
|
Icon,
|
||||||
|
|||||||
@@ -50,6 +50,22 @@ export const mergeClasses = <ClassType = string | undefined | null>(...classes:
|
|||||||
.join(' ')
|
.join(' ')
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create list of lucide icon names
|
||||||
|
*
|
||||||
|
* @param {array} classes
|
||||||
|
* @returns {string} A string of classes
|
||||||
|
*/
|
||||||
|
export const createLucideClassNames = (iconNames?: string[]) => {
|
||||||
|
if (iconNames == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return iconNames
|
||||||
|
.map((aliasName) => `lucide-${toKebabCase(aliasName)}`)
|
||||||
|
.join(' ')
|
||||||
|
.trim();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a component has an accessibility prop
|
* Check if a component has an accessibility prop
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -40,6 +40,13 @@ function generateIconFiles({
|
|||||||
})
|
})
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
|
const iconNameAliases = iconMetaData[iconName]?.aliases?.map((alias) => {
|
||||||
|
if (typeof alias === 'string') {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
return alias.name;
|
||||||
|
});
|
||||||
|
|
||||||
const elementTemplate = await template({
|
const elementTemplate = await template({
|
||||||
componentName,
|
componentName,
|
||||||
iconName,
|
iconName,
|
||||||
@@ -47,6 +54,7 @@ function generateIconFiles({
|
|||||||
getSvg,
|
getSvg,
|
||||||
deprecated,
|
deprecated,
|
||||||
deprecationReason,
|
deprecationReason,
|
||||||
|
iconNameAliases
|
||||||
});
|
});
|
||||||
|
|
||||||
const output = pretty
|
const output = pretty
|
||||||
|
|||||||