-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerator.js
More file actions
104 lines (86 loc) · 2.76 KB
/
Copy pathgenerator.js
File metadata and controls
104 lines (86 loc) · 2.76 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
const fs = require('fs')
const path = require('path')
const axios = require('axios')
const GOOGLE_FONTS_URL = 'https://fonts.google.com/metadata/icons'
const ICON_FAMILIES = [
{ id: 'materialicons', postfix: '' },
{ id: 'materialiconsoutlined', postfix: 'Outlined' },
{ id: 'materialiconsround', postfix: 'Round' },
{ id: 'materialiconssharp', postfix: 'Sharp' },
{ id: 'materialiconstwotone', postfix: 'TwoTone' },
]
;(async () => {
generateIconPropsFile()
const res = await axios.get(GOOGLE_FONTS_URL)
// remove )]}' from the response
const data = res.data.substring(4)
const icons = await JSON.parse(data)
for (let i = 0; i < icons.icons.length; i++) {
generateComponents(icons.icons[i])
}
})()
function generateIconPropsFile() {
const typesFile = `
import React from 'react'
export interface IconProps extends React.SVGProps<SVGSVGElement> {
title?: string
}
`
fs.writeFileSync(path.join(__dirname, 'src', 'types.ts'), typesFile)
}
async function generateComponents(icon) {
for (let i = 0; i < ICON_FAMILIES.length; i++) {
await generateComponent(icon, ICON_FAMILIES[i])
}
}
async function generateComponent(icon, family) {
try {
const name = formatName(icon.name, family.postfix)
const svg = await downloadSVG(icon.name, family.id, icon.version)
console.log(`Downloading ${name}`)
await fs.writeFileSync(
path.join(__dirname, 'src', `${name}.tsx`),
mapSVGToTemplate(name, svg)
)
} catch {
process.abort()
}
}
function formatName(string, familyPostfix) {
const formattedString = string
.replace(/_/g, ' ')
.replace(/\w\S*/g, (txt) => {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
})
.replace(/ /g, '')
return 'Icon' + formattedString + familyPostfix
}
async function downloadSVG(icon, familyId, version) {
const svg = await axios
.get(
`https://fonts.gstatic.com/s/i/${familyId}/${icon}/v${version}/24px.svg`
)
.catch((err) => console.log(err))
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')
.replace('>', '>{props.title && <title>{props.title}</title>}')
.replace(/style="enableBackground:(.*?);?"/g, 'enableBackground="$1"')
.replace(/style="fill:(.*?);?"/g, 'fill="$1"')
.replace(/xmlns:xlink/g, 'xmlnsXlink')
.replace(/xlink:href/g, 'xlinkHref')
}
function mapSVGToTemplate(name, svg) {
return `
import React from 'react'
import { IconProps } from './types'
const ${name}: React.FC<IconProps> = ({ ...props }) => (
${svg}
)
export { ${name} as default }
`
}