mirror of
https://github.com/lucide-icons/lucide.git
synced 2025-12-16 11:57:43 +01:00
Alias support for lucide package (#1592)
* Setup aliases for lucide * Make aliases work for lucide package
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundles",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
"clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.ts",
|
||||
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --iconFileExtension=.ts",
|
||||
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --iconFileExtension=.ts --withAliases --aliasNamesOnly --aliasesFileExtension=.ts --exportFileName=index.ts",
|
||||
"build:types": "node ./scripts/buildTypes.mjs",
|
||||
"build:bundles": "rollup -c rollup.config.mjs",
|
||||
"test": "vitest run",
|
||||
|
||||
@@ -40,7 +40,7 @@ const configs = bundles
|
||||
...(
|
||||
format === 'umd' ? [
|
||||
replace({
|
||||
'icons = {}': 'icons = allIcons',
|
||||
'icons = {}': 'icons = iconAndAliases',
|
||||
delimiters: ['', ''],
|
||||
preventAssignment: false,
|
||||
}),
|
||||
|
||||
2
packages/lucide/src/iconsAndAliases.ts
Normal file
2
packages/lucide/src/iconsAndAliases.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './icons'
|
||||
export * from './aliases'
|
||||
@@ -1,5 +1,5 @@
|
||||
import replaceElement from './replaceElement';
|
||||
import * as allIcons from './icons';
|
||||
import * as iconAndAliases from './iconsAndAliases';
|
||||
|
||||
/**
|
||||
* Replaces all elements with matching nameAttr with the defined icons
|
||||
@@ -43,5 +43,5 @@ export { default as createElement } from './createElement';
|
||||
/*
|
||||
Icons exports.
|
||||
*/
|
||||
export { allIcons as icons };
|
||||
export { iconAndAliases as icons };
|
||||
export * from './icons';
|
||||
|
||||
@@ -66,7 +66,7 @@ interface ReplaceElementOptions {
|
||||
const replaceElement = (element: Element, { nameAttr, icons, attrs }: ReplaceElementOptions) => {
|
||||
const iconName = element.getAttribute(nameAttr);
|
||||
|
||||
if(iconName == null) return
|
||||
if (iconName == null) return
|
||||
|
||||
const ComponentName = toPascalCase(iconName);
|
||||
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
|
||||
exports[`createIcons > should add custom attributes 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"black\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" data-lucide=\\"volume-2\\" class=\\"lucide lucide-volume-2 icon custom-class\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M15.54 8.46a5 5 0 0 1 0 7.07\\"></path><path d=\\"M19.07 4.93a10 10 0 0 1 0 14.14\\"></path></svg>"`;
|
||||
|
||||
exports[`createIcons > should read elements from DOM and replace icon with alias name 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" data-lucide=\\"grid\\" class=\\"lucide lucide-grid\\"><rect width=\\"18\\" height=\\"18\\" x=\\"3\\" y=\\"3\\" rx=\\"2\\"></rect><path d=\\"M3 9h18\\"></path><path d=\\"M3 15h18\\"></path><path d=\\"M9 3v18\\"></path><path d=\\"M15 3v18\\"></path></svg>"`;
|
||||
|
||||
exports[`createIcons > should read elements from DOM and replace it with icons 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" data-lucide=\\"volume-2\\" class=\\"lucide lucide-volume-2\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M15.54 8.46a5 5 0 0 1 0 7.07\\"></path><path d=\\"M19.07 4.93a10 10 0 0 1 0 14.14\\"></path></svg>"`;
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import * as icons from '../src/icons';
|
||||
import { createIcons } from '../src/lucide';
|
||||
import { createIcons, icons } from '../src/lucide';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { parseSync, stringify } from 'svgson';
|
||||
|
||||
const ICONS_DIR = path.resolve(__dirname, '../../../icons');
|
||||
|
||||
const getOriginalSvg = (iconName) => {
|
||||
const getOriginalSvg = (iconName, aliasName) => {
|
||||
const svgContent = fs.readFileSync(path.join(ICONS_DIR, `${iconName}.svg`), 'utf8');
|
||||
const svgParsed = parseSync(svgContent);
|
||||
|
||||
svgParsed.attributes['data-lucide'] = iconName;
|
||||
svgParsed.attributes['class'] = `lucide lucide-${iconName}`;
|
||||
svgParsed.attributes['data-lucide'] = aliasName ?? iconName;
|
||||
svgParsed.attributes['class'] = `lucide lucide-${aliasName ?? iconName}`;
|
||||
|
||||
return stringify(svgParsed, { selfClose: false });
|
||||
};
|
||||
@@ -86,4 +85,15 @@ describe('createIcons', () => {
|
||||
|
||||
expect(attributesAndValues).toEqual(expect.objectContaining(attrs));
|
||||
});
|
||||
|
||||
it('should read elements from DOM and replace icon with alias name', () => {
|
||||
document.body.innerHTML = `<i data-lucide="grid"></i>`;
|
||||
|
||||
createIcons({ icons });
|
||||
|
||||
const svg = getOriginalSvg('grid-3x3', 'grid');
|
||||
|
||||
expect(document.body.innerHTML).toBe(svg)
|
||||
expect(document.body.innerHTML).toMatchSnapshot()
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ export default async function generateAliasesFile({
|
||||
iconFileExtension = '.js',
|
||||
aliases,
|
||||
aliasImportFileExtension,
|
||||
aliasNamesOnly = false,
|
||||
separateAliasesFile = false,
|
||||
showLog = true,
|
||||
}) {
|
||||
@@ -24,14 +25,28 @@ export default async function generateAliasesFile({
|
||||
|
||||
// Generate Import for Icon VNodes
|
||||
await Promise.all(
|
||||
icons.map(async (iconName) => {
|
||||
icons.map(async (iconName, index) => {
|
||||
const componentName = toPascalCase(iconName);
|
||||
const iconAliases = aliases[iconName]?.aliases;
|
||||
|
||||
let importString = `// ${componentName} aliases\n`;
|
||||
let importString = '';
|
||||
|
||||
importString += getImportString(`${componentName}Icon`, iconName, aliasImportFileExtension);
|
||||
importString += getImportString(`Lucide${componentName}`, iconName, aliasImportFileExtension);
|
||||
if ((iconAliases != null && Array.isArray(iconAliases)) || !aliasNamesOnly) {
|
||||
if (index > 0) {
|
||||
importString += '\n';
|
||||
}
|
||||
|
||||
importString += `// ${componentName} aliases\n`;
|
||||
}
|
||||
|
||||
if (!aliasNamesOnly) {
|
||||
importString += getImportString(`${componentName}Icon`, iconName, aliasImportFileExtension);
|
||||
importString += getImportString(
|
||||
`Lucide${componentName}`,
|
||||
iconName,
|
||||
aliasImportFileExtension,
|
||||
);
|
||||
}
|
||||
|
||||
if (iconAliases != null && Array.isArray(iconAliases)) {
|
||||
await Promise.all(
|
||||
@@ -57,23 +72,24 @@ export default async function generateAliasesFile({
|
||||
exportFileIcon,
|
||||
aliasImportFileExtension,
|
||||
);
|
||||
importString += getImportString(
|
||||
`${componentNameAlias}Icon`,
|
||||
exportFileIcon,
|
||||
aliasImportFileExtension,
|
||||
);
|
||||
|
||||
importString += getImportString(
|
||||
`Lucide${componentNameAlias}`,
|
||||
exportFileIcon,
|
||||
aliasImportFileExtension,
|
||||
);
|
||||
if (!aliasNamesOnly) {
|
||||
importString += getImportString(
|
||||
`${componentNameAlias}Icon`,
|
||||
exportFileIcon,
|
||||
aliasImportFileExtension,
|
||||
);
|
||||
|
||||
importString += getImportString(
|
||||
`Lucide${componentNameAlias}`,
|
||||
exportFileIcon,
|
||||
aliasImportFileExtension,
|
||||
);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
importString += '\n';
|
||||
|
||||
appendFile(importString, fileName, outputDirectory);
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -31,6 +31,7 @@ const {
|
||||
importImportFileExtension = '',
|
||||
exportFileName = 'index.js',
|
||||
withAliases = false,
|
||||
aliasNamesOnly = false,
|
||||
withDynamicImports = false,
|
||||
separateAliasesFile = false,
|
||||
aliasesFileExtension = '.js',
|
||||
@@ -66,6 +67,7 @@ async function buildIcons() {
|
||||
await generateAliasesFile({
|
||||
iconNodes: icons,
|
||||
aliases,
|
||||
aliasNamesOnly,
|
||||
iconFileExtension,
|
||||
outputDirectory: OUTPUT_DIR,
|
||||
fileExtension: aliasesFileExtension,
|
||||
|
||||
Reference in New Issue
Block a user