generateIconFiles.mjs142 lines · main
1import fs from 'fs'
2import path from 'path'
3import prettier from 'prettier'
4import { readSvg, toPascalCase } from '../utils/helpers.mjs'
5
6export default ({
7 iconNodes,
8 outputDirectory,
9 template,
10 showLog = true,
11 iconFileExtension = '.js',
12 pretty = true,
13 iconsDir,
14
15 // TO DO -- START
16 //
17 // move this to ./build-registry in design-system
18 // with all the other build scripts
19 // @mildtomato
20 registryDir,
21 // TO DO -- END
22
23 iconMetaData,
24}) => {
25 const icons = Object.keys(iconNodes)
26 const iconsDistDirectory = path.join(outputDirectory, `icons`)
27
28 if (!fs.existsSync(iconsDistDirectory)) {
29 fs.mkdirSync(iconsDistDirectory)
30 }
31
32 // TO DO -- START
33 //
34 // move this to ./build-registry in design-system
35 // with all the other build scripts
36 // @mildtomato
37 let registryIndex = `// @ts-nocheck
38// This file is autogenerated by icons-build/src/building/generateIconFiles.mjs
39// Do not edit this file directly.
40import * as React from "react"
41
42export const Index: Record<string, any> = [`
43 // TO DO -- END
44
45 const registryOutput = path.join(registryDir, 'index.tsx')
46
47 const writeIconFiles = icons.map(async (iconName, i) => {
48 const location = path.join(iconsDistDirectory, `${iconName}${iconFileExtension}`)
49
50 const componentName = toPascalCase(iconName)
51
52 let { children, attributes: rootAttributes } = iconNodes[iconName]
53 children = children.map(({ name, attributes }) => [name, attributes])
54
55 const STYLE_ATTRS = ['fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin']
56 const svgAttributes = {}
57 for (const attr of STYLE_ATTRS) {
58 if (attr in rootAttributes) {
59 const camelKey = attr.replace(/-([a-z])/g, (_, l) => l.toUpperCase())
60 svgAttributes[camelKey] = rootAttributes[attr]
61 }
62 }
63
64 const svgContent = readSvg(`${iconName}.svg`, iconsDir)
65 const getSvg = () => svgContent
66 // const { deprecated = false } = iconMetaData[iconName]
67 const deprecated = false
68
69 const elementTemplate = template({ componentName, iconName, children, getSvg, deprecated, svgAttributes })
70 const output = pretty
71 ? await prettier.format(elementTemplate, {
72 singleQuote: true,
73 trailingComma: 'all',
74 printWidth: 100,
75 parser: 'babel',
76 })
77 : elementTemplate
78
79 const rawSvg = JSON.stringify(readSvg(`${iconName}.svg`, iconsDir))
80
81 // TO DO -- START
82 //
83 // move this to ./build-registry in design-system
84 // with all the other build scripts
85 // @mildtomato
86 registryIndex += `\n{`
87 registryIndex += `
88 name: "${iconName}",
89 componentName: "${componentName}",
90 deprecated: ${deprecated},
91 raw: ${JSON.stringify(output)},
92 component: React.lazy(() => import('icons/src/icons/${iconName}')),
93 import: "import { ${componentName} } from 'icons'",
94 svg: ${JSON.stringify(readSvg(`${iconName}.svg`, iconsDir))},
95 jsx: ${JSON.stringify(`import { ${componentName} } from "icons"
96 <${componentName}/>
97 `)}`
98 if (i !== icons.length - 1) {
99 registryIndex += `\n},`
100 }
101 // TO DO -- END
102
103 console.log('Created ' + componentName)
104 await fs.promises.writeFile(location, output, 'utf-8')
105 })
106
107 // TO DO -- START
108 //
109 // move this to ./build-registry in design-system
110 // with all the other build scripts
111 // @mildtomato
112 async function writeRegistry() {
113 console.log(registryIndex)
114
115 registryIndex += `\n}`
116 // close index
117 registryIndex += `\n]`
118
119 await fs.promises.writeFile(registryOutput, registryIndex, 'utf-8')
120 console.log('Successfully created registry at', registryOutput)
121 }
122 // TO DO -- END
123
124 Promise.all(writeIconFiles)
125
126 // TO DO -- START
127 //
128 // move this to ./build-registry in design-system
129 // with all the other build scripts
130 // @mildtomato
131 .then(() => writeRegistry())
132 // TO DO -- END
133
134 .then(() => {
135 if (showLog) {
136 console.log('Successfully built', icons.length, 'icons.')
137 }
138 })
139 .catch((error) => {
140 throw new Error(`Something went wrong generating icon files,\n ${error}`)
141 })
142}