@@ -2,45 +2,39 @@ const fs = require('fs')
22const path = require ( 'path' )
33const 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- */
4438function 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 ( / s t y l e = " f i l l : ( .* ?) ; ? " / 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