Skip to content

Commit e0f7e78

Browse files
author
Simon Planinschek
committed
Renamed generator to bootstrapper.js and move it into source folder
1 parent daac250 commit e0f7e78

2 files changed

Lines changed: 166 additions & 116 deletions

File tree

generator.js

Lines changed: 0 additions & 116 deletions
This file was deleted.

src/bootstrapper.js

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
const fs = require('fs')
2+
const path = require('path')
3+
const axios = require('axios')
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.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
20+
})
21+
.replace(/ /g, '')
22+
return 'Icon' + formattedString
23+
}
24+
25+
/**
26+
* Setup the dist folder and some static files
27+
*/
28+
function setup() {
29+
// Create the dist folder
30+
fs.mkdirSync(path.join(__dirname, '..', 'dist'))
31+
32+
// Create the components folder
33+
fs.mkdirSync(path.join(__dirname, '..', 'dist', 'components'))
34+
35+
// Add the type declaration file to the components folder
36+
fs.writeFileSync(
37+
path.join(__dirname, '..', 'dist', 'components', 'types.d.ts'),
38+
'/// <reference types="react" />\nexport type IconProps = React.SVGProps<SVGSVGElement>\n'
39+
)
40+
41+
// Add type file to the components folder
42+
fs.writeFileSync(
43+
path.join(__dirname, '..', 'dist', 'components', 'types.js'),
44+
'"use strict"\nexports.__esModule = true;'
45+
)
46+
}
47+
48+
/**
49+
* Component template for functional Javascript react icon component
50+
*
51+
* @param name - Component name
52+
* @param svg - Icon SVG
53+
* @returns {string} - Component
54+
*/
55+
function componentJSTemplate(name, svg) {
56+
let component = "import React from 'react'\n"
57+
component += `const ${name} = (props) => (`
58+
component += svg + ')\n\n'
59+
component += `export { ${name} }`
60+
61+
return component
62+
}
63+
64+
/**
65+
* Generate Declaration file for icon components
66+
*
67+
* @param name - Icon name
68+
* @returns {string} - Declaration file template
69+
*/
70+
function componentDeclarationTemplate(name) {
71+
let declaration = "import React from 'react';\n"
72+
declaration += "import { IconProps } from './types';\n\n"
73+
declaration += `declare const ${name}: React.FC<IconProps>;\n\n`
74+
declaration += `export { ${name} };`
75+
76+
return declaration;
77+
}
78+
79+
/**
80+
* Generate React Icon components
81+
*
82+
* @param icon - Icon object
83+
*/
84+
function generateComponent(icon) {
85+
icon.forEach(async (c) => {
86+
const name = formatName(c.name)
87+
const svg = await getSVGFile(c.name, c.version)
88+
89+
// Generate js component
90+
fs.writeFileSync(
91+
path.join(__dirname, '..', 'dist', 'components', `${name}.jsx`),
92+
componentJSTemplate(name, svg)
93+
)
94+
95+
// Generate ts declaration file for js component
96+
fs.writeFileSync(
97+
path.join(__dirname, '..', 'dist', 'components', `${name}.d.ts`),
98+
componentDeclarationTemplate(name)
99+
)
100+
})
101+
}
102+
103+
/**
104+
* Generate index tsx file for easy import
105+
*
106+
* @param icons - Array of icons
107+
*/
108+
function generateIndex(icons) {
109+
let imports = ''
110+
let exports = 'export {\n'
111+
112+
icons.forEach((icon) => {
113+
const name = formatName(icon.name)
114+
imports += `import { ${name} } from './components/${name}'\n`
115+
exports += ` ${name},\n`
116+
})
117+
exports += '}'
118+
119+
// Write js index
120+
fs.writeFileSync(
121+
path.join(__dirname, '..', 'dist', 'index.js'),
122+
imports + '\n' + exports
123+
)
124+
125+
// Write ts index
126+
fs.writeFileSync(
127+
path.join(__dirname, '..', 'dist', 'index.d.ts'),
128+
imports + '\n' + exports
129+
)
130+
}
131+
132+
/**
133+
* Get SVG data form google static fonts api
134+
*
135+
* @param icon - Icon name
136+
* @param version - Icon Version
137+
* @returns {Promise<any>} - SVG Data
138+
*/
139+
async function getSVGFile(icon, version) {
140+
const svg = await axios.get(
141+
`https://fonts.gstatic.com/s/i/materialicons/${icon}/v${version}/24px.svg`
142+
)
143+
144+
return svg.data.replace('height="24"', '').replace('width="24"', '{...props}')
145+
}
146+
147+
/**
148+
* Main function
149+
*/
150+
;(async function () {
151+
// Setup environment
152+
setup()
153+
154+
// Get icon information from google fonts
155+
const res = await axios.get(iconURL)
156+
157+
// remove )]}' from the response
158+
const data = res.data.substring(4)
159+
160+
// Parse response from json to js object
161+
const icons = await JSON.parse(data)
162+
// Generate icon components and Index
163+
164+
await generateComponent(icons.icons)
165+
await generateIndex(icons.icons)
166+
})()

0 commit comments

Comments
 (0)