Skip to content

Commit 0585c9c

Browse files
committed
WIP generate icon components
1 parent 654711a commit 0585c9c

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/build-storybook.log
66
/.storybook/preview-head.html
77
/declarations/
8+
/addon/components/icons/
89

910
# dependencies
1011
/node_modules/

lib/generate-icon-components.mjs

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { pascalCase } from 'change-case';
2+
import { existsSync } from "node:fs";
3+
import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
4+
import { basename, dirname, extname, join } from "node:path";
5+
import { fileURLToPath } from 'node:url';
6+
7+
const __dirname = dirname(fileURLToPath(import.meta.url));
8+
9+
const ICON_FOLDER = join(__dirname, '..', 'public', 'icons')
10+
const COMPONENT_ICON_FOLDER = join(__dirname, '..', 'addon', 'components', 'icons');
11+
12+
const files = await readdir(ICON_FOLDER);
13+
const icons = files.filter(file => extname(file) === '.svg').map(svg => basename(svg, '.svg'));
14+
15+
await prepareOutputDir();
16+
17+
const promises = icons.map(svg => {
18+
return generateComponent(svg);
19+
});
20+
await Promise.all(promises);
21+
22+
async function generateComponent(iconName) {
23+
const componentName = pascalCase(iconName);
24+
25+
const iconContent = await readFile(join(ICON_FOLDER, iconName + '.svg'));
26+
const iconContentWithAttributes = iconContent.toString().replace('>', ' ...attributes>'); // We assume the first closing element is the svg element
27+
28+
const component = `// THIS FILE IS GENERATED. ANY CHANGES TO THIS FILE WILL BE LOST.
29+
import type { TOC } from '@ember/component/template-only';
30+
31+
export interface ${componentName}IconSignature {
32+
Element: SVGElement;
33+
}
34+
35+
export const ${componentName}Icon: TOC<${componentName}IconSignature> = <template>${iconContentWithAttributes}</template>;
36+
export default ${componentName}Icon;`
37+
38+
await writeFile(join(COMPONENT_ICON_FOLDER, iconName + '.gts'), component)
39+
}
40+
41+
async function prepareOutputDir() {
42+
if (existsSync(COMPONENT_ICON_FOLDER)) {
43+
await rm(COMPONENT_ICON_FOLDER, { recursive: true });
44+
}
45+
await mkdir(COMPONENT_ICON_FOLDER);
46+
}

package-lock.json

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
},
3434
"scripts": {
3535
"build": "run-s icons build-ember build-storybook",
36+
"build:icons": "node lib/generate-icon-components.mjs",
3637
"build:types": "glint -d",
3738
"lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
3839
"lint:css": "stylelint --allow-empty-input \"**/*.css\"",
@@ -135,6 +136,7 @@
135136
"@typescript-eslint/eslint-plugin": "^7.1.1",
136137
"@typescript-eslint/parser": "^7.1.1",
137138
"broccoli-asset-rev": "^3.0.0",
139+
"change-case": "^5.4.3",
138140
"chromatic": "^6.5.4",
139141
"concurrently": "^8.2.2",
140142
"ember-auto-import": "^2.7.0",

0 commit comments

Comments
 (0)