forked from robcresswell/vue-material-design-icons
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.ts
executable file
·106 lines (91 loc) · 2.28 KB
/
build.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Imports
import { mkdir, writeFile } from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import pMap from 'p-map';
import icons from '@mdi/js';
import { existsSync } from 'fs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const dist = path.resolve(__dirname, 'dist');
function renderTemplate(title: string, svgPathData: string, name: string) {
return `<template>
<span v-bind="$attrs"
:aria-hidden="title ? null : true"
:aria-label="title"
class="material-design-icon ${title}-icon"
role="img"
@click="$emit('click', $event)">
<svg :fill="fillColor"
class="material-design-icon__svg"
:width="size"
:height="size"
viewBox="0 0 24 24">
<path d="${svgPathData}">
<title v-if="title">{{ title }}</title>
</path>
</svg>
</span>
</template>
<script>
export default {
name: "${name}Icon",
emits: ['click'],
props: {
title: {
type: String,
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
}
</script>`;
}
function getTemplateData(id: string) {
// Make sure we don't load other exports
if (!id.startsWith('mdi')) {
return {
name: null,
title: null,
svgPathData: null,
};
}
const splitID = id.split(/(?=[A-Z])/).slice(1);
const name = splitID.join('');
// This is a hacky way to remove the 'mdi' prefix, so "mdiAndroid" becomes
// "android", for example
const title = splitID.join('-').toLowerCase();
return {
name,
title,
// @ts-ignore
svgPathData: icons[id],
};
}
async function build() {
const iconIDs = Object.keys(icons);
if (!existsSync(dist)) {
await mkdir(dist);
}
const templateData = iconIDs.map(getTemplateData);
// Batch process promises to avoid overloading memory
await pMap(
templateData,
async ({ name, title, svgPathData }) => {
if (name === null) return;
const component = renderTemplate(title, svgPathData, name);
const filename = `${name}.vue`;
return writeFile(path.resolve(dist, filename), component);
},
{ concurrency: 20 },
);
}
build().catch((err: unknown) => {
console.log(err);
});