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

Alias support for lucide package #1592

Merged
merged 3 commits into from
Oct 17, 2023
Merged
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/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/lucide/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const configs = bundles
...(
format === 'umd' ? [
replace({
'icons = {}': 'icons = allIcons',
'icons = {}': 'icons = iconAndAliases',
delimiters: ['', ''],
preventAssignment: false,
}),
Expand Down
2 changes: 2 additions & 0 deletions packages/lucide/src/iconsAndAliases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './icons'
export * from './aliases'
4 changes: 2 additions & 2 deletions packages/lucide/src/lucide.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -43,5 +43,5 @@ export { default as createElement } from './createElement';
/*
Icons exports.
*/
export { allIcons as icons };
export { iconAndAliases as icons };
export * from './icons';
2 changes: 1 addition & 1 deletion packages/lucide/src/replaceElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions packages/lucide/tests/__snapshots__/lucide.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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>"`;
20 changes: 15 additions & 5 deletions packages/lucide/tests/lucide.spec.js
Original file line number Diff line number Diff line change
@@ -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 });
};
Expand Down Expand Up @@ -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()
});
});
48 changes: 32 additions & 16 deletions tools/build-icons/building/generateAliasesFile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default async function generateAliasesFile({
iconFileExtension = '.js',
aliases,
aliasImportFileExtension,
aliasNamesOnly = false,
separateAliasesFile = false,
showLog = true,
}) {
Expand All @@ -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(
Expand 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);
}),
);
Expand Down
2 changes: 2 additions & 0 deletions tools/build-icons/main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const {
importImportFileExtension = '',
exportFileName = 'index.js',
withAliases = false,
aliasNamesOnly = false,
withDynamicImports = false,
separateAliasesFile = false,
aliasesFileExtension = '.js',
Expand Down Expand Up @@ -66,6 +67,7 @@ async function buildIcons() {
await generateAliasesFile({
iconNodes: icons,
aliases,
aliasNamesOnly,
iconFileExtension,
outputDirectory: OUTPUT_DIR,
fileExtension: aliasesFileExtension,
Expand Down