/
create.ts
108 lines (90 loc) · 3.41 KB
/
create.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
107
108
import fs from "fs-extra";
import path from "path";
import _ from "lodash";
import prettier from "prettier";
import { glob } from "./utils";
import { srcDir } from "./constants";
function toPascalCase(fileName): string {
if (fileName.match(/^[0-9]/)) {
const [first, second, ...remaining] = fileName.split("_");
fileName = `${second}_${first}${
remaining.length ? `_${remaining.join("_")}` : ""
}`;
}
return _.upperFirst(_.camelCase(fileName));
}
function createIconFile(componentName, children, iconType): string {
return prettier.format(
`// This is a generated file from running the "createIcons" script. This file should not be updated manually.
import React, { FC } from "react";
import { ${iconType}Icon, ${iconType}IconProps } from "@react-md/icon";
const ${componentName}${iconType}Icon: FC<${iconType}IconProps> = props => <${iconType}Icon {...props}>${children}</${iconType}Icon>;
export default ${componentName}${iconType}Icon;
`,
{ printWidth: 80, trailingComma: "es5", parser: "typescript" }
);
}
// kind of hacky, but each icon starts and ends the same way right now..
const SVG_ICON_PREFIX =
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">';
const SVG_ICON_SUFFIX = "</svg>";
async function parseSVGFileAndCreateComponents(
svgFilePath: string,
componentName: string,
iconName: string,
svgIconFile: string,
fontIconFile: string
): Promise<void> {
const svg = await fs.readFile(path.join(process.cwd(), svgFilePath), "utf8");
const contents = svg
.substring(SVG_ICON_PREFIX.length, svg.length - SVG_ICON_SUFFIX.length)
.replace(/fill-opacity/g, "fillOpacity")
// remove fill so the colors can be overridden in css
.replace(/ ?fill="#[A-Fa-f0-9]{3,6}"/g, "");
// eslint-disable-next-line no-console
console.log(contents.match(/fill/));
await Promise.all([
fs.outputFile(svgIconFile, createIconFile(componentName, contents, "SVG")),
fs.outputFile(
fontIconFile,
createIconFile(componentName, iconName, "Font")
),
]);
}
async function createIndexFile(components: string[]): Promise<void> {
const contents = `// This is a generated file from running the "createIcons" script. This file should not be updated manually.
${components.reduce(
(s, c) => `${s ? `${s}\n` : ""}export { default as ${c} } from "./${c}";`,
""
)}
`;
return fs.outputFile(path.join(srcDir, "index.ts"), contents);
}
// eslint-disable-next-line import/prefer-default-export
export async function create(): Promise<void> {
const svgFiles = await glob("svgs/*.svg");
await fs.remove(srcDir);
await fs.ensureDir(srcDir);
const components: string[] = [];
await Promise.all(
svgFiles.map(svgFilePath => {
const iconName = svgFilePath.replace(/.+\//, "").replace(/\.svg$/, "");
const componentName = toPascalCase(iconName);
const svgIconName = `${componentName}SVGIcon`;
const fontIconName = `${componentName}FontIcon`;
const svgIconFile = path.join(srcDir, `${svgIconName}.tsx`);
const fontIconFile = path.join(srcDir, `${fontIconName}.tsx`);
components.push(svgIconName, fontIconName);
return parseSVGFileAndCreateComponents(
svgFilePath,
componentName,
iconName,
svgIconFile,
fontIconFile
);
})
);
console.log("Updating the main index file to include all the components...");
await createIndexFile(components);
console.log("Done.");
}