Skip to content

Commit 8d366d8

Browse files
author
Simon Planinschek
committed
update generator script to support all variants of icons
1 parent a3cfa94 commit 8d366d8

1 file changed

Lines changed: 51 additions & 58 deletions

File tree

generator.js

Lines changed: 51 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,39 @@ const fs = require('fs')
22
const path = require('path')
33
const axios = require('axios')
44

5-
// Base url for icons
6-
const iconURL = 'https://fonts.google.com/metadata/icons'
5+
// This is the number of icons each thread will be downloading
6+
const DOWNLOAD_CHUNK_SIZE = 500
7+
const GOOGLE_FONTS_URL = 'https://fonts.google.com/metadata/icons'
8+
const ICON_FAMILTIES = [
9+
{ id: 'materialicons', namePostfix: '' },
10+
{ id: 'materialiconsoutlined', namePostfix: 'Outlined' },
11+
{ id: 'materialiconsround', namePostfix: 'Round' },
12+
{ id: 'materialiconssharp', namePostfix: 'Sharp' },
13+
{ id: 'materialiconstwotone', namePostfix: 'TwoTone' },
14+
]
715

8-
function setup() {
16+
function generateIconPropsFile() {
917
const typesFile = `
1018
import React from 'react'
1119
export interface IconProps extends React.SVGProps<SVGSVGElement> {
1220
title?: string
1321
}
1422
`
1523

16-
// Create types file
1724
fs.writeFileSync(path.join(__dirname, 'src', 'types.ts'), typesFile)
1825
}
1926

20-
/**
21-
* Format name.
22-
* Covert from snake case to camel case and prevent numbers at the beginning
23-
*
24-
* @param string - String to format
25-
* @returns {string} - Formatted string
26-
*/
27-
function formatName(string) {
27+
function formatName(string, familyName) {
2828
const formattedString = string
2929
.replace(/_/g, ' ')
3030
.replace(/\w\S*/g, (txt) => {
3131
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
3232
})
3333
.replace(/ /g, '')
34-
return 'Icon' + formattedString
34+
35+
return 'Icon' + formattedString + familyName
3536
}
3637

37-
/**
38-
* Component template for functional react icon component
39-
*
40-
* @param name - Component name
41-
* @param svg - Icon SVG
42-
* @returns {string} - Component
43-
*/
4438
function componentTemplate(name, svg) {
4539
return `
4640
import React from 'react'
@@ -54,34 +48,12 @@ function componentTemplate(name, svg) {
5448
`
5549
}
5650

57-
/**
58-
* Generate React Icon components
59-
*
60-
* @param icon - Icon object
61-
*/
62-
function generateComponent(icon) {
63-
icon.forEach(async (c) => {
64-
const name = formatName(c.name)
65-
const svg = await getSVGFile(c.name, c.version)
66-
67-
fs.writeFileSync(
68-
path.join(__dirname, 'src', `${name}.tsx`),
69-
componentTemplate(name, svg)
51+
async function getSVGFile(icon, familyId, version) {
52+
const svg = await axios
53+
.get(
54+
`https://fonts.gstatic.com/s/i/${familyId}/${icon}/v${version}/24px.svg`
7055
)
71-
})
72-
}
73-
74-
/**
75-
* Get SVG data form google static fonts api
76-
*
77-
* @param icon - Icon name
78-
* @param version - Icon Version
79-
* @returns {Promise<any>} - SVG Data
80-
*/
81-
async function getSVGFile(icon, version) {
82-
const svg = await axios.get(
83-
`https://fonts.gstatic.com/s/i/materialicons/${icon}/v${version}/24px.svg`
84-
)
56+
.catch((err) => console.log(err))
8557

8658
return svg.data
8759
.replace('height="24"', '')
@@ -95,21 +67,42 @@ async function getSVGFile(icon, version) {
9567
.replace(/style="fill:(.*?);?"/g, 'fill="$1"')
9668
}
9769

98-
/**
99-
* Main function
100-
*/
70+
async function generateComponent(icons) {
71+
for (let i = 0; i < icons.length; i++) {
72+
const icon = icons[i]
73+
74+
for (let j = 0; j < ICON_FAMILTIES.length; j++) {
75+
const family = ICON_FAMILTIES[j]
76+
77+
const name = formatName(icon.name, family.namePostfix)
78+
const svg = await getSVGFile(icon.name, family.id, icon.version)
79+
80+
console.log(`Downloading ${name} (${i + 1}/${icons.length})`)
81+
82+
await fs.writeFileSync(
83+
path.join(__dirname, 'src', `${name}.tsx`),
84+
componentTemplate(name, svg)
85+
)
86+
}
87+
}
88+
}
89+
10190
;(async () => {
102-
// Setup source folder
103-
setup()
91+
generateIconPropsFile()
92+
93+
const res = await axios.get(GOOGLE_FONTS_URL)
10494

105-
// Get icon information from google fonts
106-
const res = await axios.get(iconURL)
10795
// remove )]}' from the response
10896
const data = res.data.substring(4)
109-
110-
// Parse response from json to js object
11197
const icons = await JSON.parse(data)
11298

113-
// Generate icon components and Index
114-
await generateComponent(icons.icons)
99+
const iconChunks = new Array(
100+
Math.ceil(icons.icons.length / DOWNLOAD_CHUNK_SIZE)
101+
)
102+
.fill()
103+
.map(() => icons.icons.splice(0, DOWNLOAD_CHUNK_SIZE))
104+
105+
for (let i = 0; i < iconChunks.length; i++) {
106+
generateComponent(iconChunks[i])
107+
}
115108
})()

0 commit comments

Comments
 (0)