@web-padawan/wc-icons-tool 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # WC Icons Tool
2
+
3
+ CLI tool for the [Vaadin web components](https://github.com/vaadin/web-components) monorepo.
4
+
5
+ ## Usage
6
+
7
+ Create iconset for `packages/icons` and `packages/vaadin-lumo-styles`:
8
+
9
+ ```sh
10
+ npx wc-icons-tool
11
+ ```
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { generateIcons } from '../tasks/icons.js';
3
+ import { generateLumoFont } from '../tasks/lumo.js';
4
+
5
+ async function main() {
6
+ await generateIcons();
7
+ await generateLumoFont();
8
+ }
9
+
10
+ main()
11
+ .then(() => {
12
+ console.warn('done');
13
+ process.exit(0);
14
+ })
15
+ .catch((e) => {
16
+ console.error(e);
17
+ process.exit(1);
18
+ });
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@web-padawan/wc-icons-tool",
3
+ "version": "0.1.0",
4
+ "main": "./bin/wc-icons-tool",
5
+ "bin": {
6
+ "wc-icons-tool": "./bin/wc-icons-tool"
7
+ },
8
+ "type": "module",
9
+ "license": "Apache-2.0",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/web-padawan/wc-icons-tool.git"
13
+ },
14
+ "author": "Vaadin Ltd",
15
+ "description": "Tool for building Vaadin icons",
16
+ "files": [
17
+ "bin",
18
+ "tasks"
19
+ ],
20
+ "dependencies": {
21
+ "cheerio": "^1.0.0",
22
+ "glob": "^13.0.0",
23
+ "svgicons2svgfont": "^14.0.2",
24
+ "svg2ttf": "6.0.3",
25
+ "ttf2woff": "3.0.0"
26
+ }
27
+ }
package/tasks/icons.js ADDED
@@ -0,0 +1,45 @@
1
+ import { globSync } from 'glob';
2
+ import * as cheerio from 'cheerio';
3
+ import { readFileSync, writeFileSync } from 'node:fs';
4
+ import { basename } from 'node:path';
5
+
6
+ function createCopyright() {
7
+ return `/**
8
+ * @license
9
+ * Copyright (c) 2015 - ${new Date().getFullYear()} Vaadin Ltd.
10
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
11
+ */`;
12
+ }
13
+
14
+ export function generateIcons() {
15
+ const files = globSync(`${process.cwd()}/packages/icons/assets/svg/*.svg`).sort();
16
+
17
+ const contents = files
18
+ .map((file) => {
19
+ const id = basename(file, '.svg');
20
+ const content = readFileSync(file, 'utf-8');
21
+ const svg = cheerio.load(content, { xmlMode: true })('svg');
22
+ // Remove fill attributes.
23
+ svg.children('[fill]').removeAttr('fill');
24
+ // Add closing tags instead of self-closing.
25
+ const output = svg.children().toString().replace(/"\/>/gu, '"></path>');
26
+ // Output the "meat" of the SVG as group element.
27
+ return `<g id="vaadin:${id}">${output}</g>`;
28
+ })
29
+ .join('\n');
30
+
31
+ const iconset = `${createCopyright()}
32
+ import { Iconset } from '@vaadin/icon/vaadin-iconset.js';
33
+
34
+ const template = document.createElement('template');
35
+
36
+ template.innerHTML = \`<svg><defs>\n${contents}\n</defs></svg>\`;
37
+
38
+ Iconset.register('vaadin', 16, template);\n`;
39
+
40
+ writeFileSync(
41
+ `${process.cwd()}/packages/icons/vaadin-iconset.js`,
42
+ iconset,
43
+ 'utf-8'
44
+ );
45
+ }
package/tasks/lumo.js ADDED
@@ -0,0 +1,77 @@
1
+ import { execSync } from 'node:child_process';
2
+ import path from 'node:path';
3
+ import { readFileSync, unlinkSync, writeFileSync } from 'node:fs';
4
+ import * as cheerio from 'cheerio';
5
+
6
+ function createCopyright() {
7
+ return `/**
8
+ * @license
9
+ * Copyright (c) 2017 - 2025 Vaadin Ltd.
10
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
11
+ */`;
12
+ }
13
+
14
+ export function generateLumoFont() {
15
+ const FONT = `${process.cwd()}/packages/vaadin-lumo-styles/lumo-icons`;
16
+
17
+ // Create SVG font
18
+ const svgIcons2Font = path.normalize('./node_modules/.bin/svgicons2svgfont');
19
+ execSync(
20
+ `${svgIcons2Font} --fontname=lumo-icons --height=1000 --ascent=850 --descent=150 --normalize --fixedWidth --verbose -o ${FONT}.svg ${process.cwd()}/packages/vaadin-lumo-styles/icons/svg/*.svg`
21
+ );
22
+
23
+ // Convert SVG to TTF
24
+ const svg2TTF = path.normalize('./node_modules/.bin/svg2ttf');
25
+ execSync(`${svg2TTF} --ts=1 ${FONT}.svg ${FONT}.ttf`);
26
+
27
+ // Convert TTF to WOFF
28
+ const ttf2WOFF = path.normalize('./node_modules/.bin/ttf2woff');
29
+ execSync(`${ttf2WOFF} ${FONT}.ttf ${FONT}.woff`);
30
+
31
+ const content = readFileSync(`${FONT}.svg`, 'utf-8');
32
+ const svg = cheerio.load(content, { xmlMode: true })('font');
33
+ const glyphs = svg
34
+ .children('glyph')
35
+ .toArray()
36
+ .map((el) => {
37
+ return {
38
+ name: el.attribs['glyph-name'],
39
+ unicode: el.attribs.unicode,
40
+ };
41
+ });
42
+
43
+ const lumoIconsWoff = readFileSync(`${FONT}.woff`);
44
+
45
+ const glyphCSSProperties = glyphs.map((g) => {
46
+ const name = g.name.replace(/\s/gu, '-').toLowerCase();
47
+ const unicode = `\\${g.unicode[0].charCodeAt(0).toString(16)}`;
48
+ return `--lumo-icons-${name}: '${unicode}';`;
49
+ });
50
+
51
+ const outputCSS = `
52
+ @font-face {
53
+ font-family: 'lumo-icons';
54
+ src: url(data:application/font-woff;charset=utf-8;base64,${lumoIconsWoff.toString('base64')})
55
+ format('woff');
56
+ font-weight: normal;
57
+ font-style: normal;
58
+ }
59
+
60
+ :where(:root),
61
+ :where(:host) {
62
+ ${glyphCSSProperties.join('\n ')}
63
+ }
64
+ `;
65
+
66
+ // Write the output to src/props/icons.css
67
+ writeFileSync(`${process.cwd()}/packages/vaadin-lumo-styles/src/props/icons.css`, [createCopyright(), outputCSS.trimStart()].join('\n'));
68
+
69
+ // Write the list of glyphs for visual tests
70
+ const list = glyphs.map((g) => g.name);
71
+ writeFileSync(`${process.cwd()}/packages/vaadin-lumo-styles/test/glyphs.json`, JSON.stringify(list, null, 2));
72
+
73
+ // Cleanup temporary font files
74
+ unlinkSync(`${FONT}.svg`);
75
+ unlinkSync(`${FONT}.ttf`);
76
+ unlinkSync(`${FONT}.woff`);
77
+ }