Skip to content

Commit 20c982a

Browse files
author
Simon Planinschek
committed
Add component generator
1 parent 7ffbc05 commit 20c982a

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

generator.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
const axios = require('axios');
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
// Base url for icons
6+
const iconURL = "https://fonts.google.com/metadata/icons";
7+
8+
/**
9+
* Format name.
10+
* Covert from snake case to camel case and prevent numbers at the beginning
11+
*
12+
* @param string - String to format
13+
* @returns {string} - Formatted string
14+
*/
15+
function formatName(string) {
16+
const formattedString = string
17+
.replace(/_/g, ' ')
18+
.replace(/\w\S*/g, (txt) => {
19+
return txt
20+
.charAt(0)
21+
.toUpperCase() + txt.substr(1)
22+
.toLowerCase();
23+
})
24+
.replace(/ /g, '');
25+
return 'Icon' + formattedString;
26+
}
27+
28+
29+
/**
30+
* Component template for functional react icon component
31+
*
32+
* @param name - Component name
33+
* @param svg - Icon SVG
34+
* @returns {string} - Component
35+
*/
36+
function componentTemplate(name, svg) {
37+
let component = "import React from 'react'\n";
38+
component += "import { IconProps } from './types'\n";
39+
component += `const ${name}: React.FC<IconProps> = (props) => (`;
40+
component += svg + "\n\n";
41+
component += `export { ${name} }`;
42+
43+
return component;
44+
45+
}
46+
47+
/**
48+
* Generate React Icon components
49+
*
50+
* @param icon - Icon object
51+
*/
52+
function generateComponent(icon) {
53+
icon.forEach(async c => {
54+
const name = formatName(c.name);
55+
const svg = await getSVGFile(c.name, c.version);
56+
57+
fs.writeFileSync(
58+
path.join(__dirname, './components', `${name}.tsx`),
59+
componentTemplate(name, svg)
60+
)
61+
});
62+
}
63+
64+
/**
65+
* Get SVG data form google static fonts api
66+
*
67+
* @param icon - Icon name
68+
* @param version - Icon Version
69+
* @returns {Promise<any>} - SVG Data
70+
*/
71+
async function getSVGFile(icon, version) {
72+
const svg = await axios.get(`https://fonts.gstatic.com/s/i/materialicons/${icon}/v${version}/24px.svg`);
73+
74+
return svg
75+
.data
76+
.replace('height="24"', '')
77+
.replace('width="24"', '{...props}');
78+
}
79+
80+
81+
(async () => {
82+
// Get icon information from google fonts
83+
const res = await axios.get(iconURL);
84+
// remove )]}' from the response
85+
const data = res.data.substring(4);
86+
87+
// Parse response from json to js object
88+
const icons = await JSON.parse(data);
89+
90+
// Used form development only
91+
const icr = [];
92+
for(let i = 0; i < 2; i++) {
93+
icr.push(icons.icons[i])
94+
}
95+
96+
await generateComponent(icr);
97+
98+
})();

0 commit comments

Comments
 (0)