Alias support for lucide package (#1592)

* Setup aliases for lucide

* Make aliases work for lucide package
This commit is contained in:
Eric Fennis
2023-10-17 21:27:46 +02:00
committed by GitHub
parent 52adb78df8
commit dbfce919fc
9 changed files with 58 additions and 26 deletions

View File

@@ -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",

View File

@@ -40,7 +40,7 @@ const configs = bundles
...(
format === 'umd' ? [
replace({
'icons = {}': 'icons = allIcons',
'icons = {}': 'icons = iconAndAliases',
delimiters: ['', ''],
preventAssignment: false,
}),

View File

@@ -0,0 +1,2 @@
export * from './icons'
export * from './aliases'

View File

@@ -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';

View File

@@ -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>"`;

View File

@@ -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()
});
});

View File

@@ -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 = '';
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);
importString += getImportString(
`Lucide${componentName}`,
iconName,
aliasImportFileExtension,
);
}
if (iconAliases != null && Array.isArray(iconAliases)) {
await Promise.all(
@@ -57,6 +72,8 @@ export default async function generateAliasesFile({
exportFileIcon,
aliasImportFileExtension,
);
if (!aliasNamesOnly) {
importString += getImportString(
`${componentNameAlias}Icon`,
exportFileIcon,
@@ -68,12 +85,11 @@ export default async function generateAliasesFile({
exportFileIcon,
aliasImportFileExtension,
);
}
}),
);
}
importString += '\n';
appendFile(importString, fileName, outputDirectory);
}),
);

View File

@@ -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,