-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerator.js
More file actions
105 lines (92 loc) · 2.54 KB
/
Copy pathgenerator.js
File metadata and controls
105 lines (92 loc) · 2.54 KB
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
const fs = require('fs')
const path = require('path')
const axios = require('axios')
// Base url for icons
const iconURL = 'https://fonts.google.com/metadata/icons'
function setup() {
// Create types file
fs.writeFileSync(
path.join(__dirname, 'src', 'types.ts'),
'import React from "react" \nexport type IconProps = React.SVGProps<SVGSVGElement>'
)
}
/**
* Format name.
* Covert from snake case to camel case and prevent numbers at the beginning
*
* @param string - String to format
* @returns {string} - Formatted string
*/
function formatName(string) {
const formattedString = string
.replace(/_/g, ' ')
.replace(/\w\S*/g, (txt) => {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
})
.replace(/ /g, '')
return 'Icon' + formattedString
}
/**
* Component template for functional react icon component
*
* @param name - Component name
* @param svg - Icon SVG
* @returns {string} - Component
*/
function componentTemplate(name, svg) {
let component = "import React from 'react'\n"
component += "import { IconProps } from './types'\n\n"
component += `const ${name}: React.FC<IconProps> = (props) => (`
component += svg + ')\n\n'
component += `export { ${name} as default }`
return component
}
/**
* Generate React Icon components
*
* @param icon - Icon object
*/
function generateComponent(icon) {
icon.forEach(async (c) => {
const name = formatName(c.name)
const svg = await getSVGFile(c.name, c.version)
fs.writeFileSync(
path.join(__dirname, 'src', `${name}.tsx`),
componentTemplate(name, svg)
)
})
}
/**
* Get SVG data form google static fonts api
*
* @param icon - Icon name
* @param version - Icon Version
* @returns {Promise<any>} - SVG Data
*/
async function getSVGFile(icon, version) {
const svg = await axios.get(
`https://fonts.gstatic.com/s/i/materialicons/${icon}/v${version}/24px.svg`
)
return svg.data
.replace('height="24"', '')
.replace('width="24"', '{...props}')
.replace(/class/g, 'className')
.replace(/enable-background/g, 'enableBackground')
.replace(/clip-rule/g, 'clipRule')
.replace(/fill-rule/g, 'fillRule')
}
/**
* Main function
*/
;(async () => {
// Setup source folder
setup()
// Get icon information from google fonts
const res = await axios.get(iconURL)
// remove )]}' from the response
const data = res.data.substring(4)
// Parse response from json to js object
const icons = await JSON.parse(data)
// Generate icon components and Index
await generateComponent(icons.icons)
})()