-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcreateComponents.js
188 lines (172 loc) · 5.42 KB
/
createComponents.js
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
const fs = require('fs');
const path = require('path');
const { baseIcons } = require('./src/IconLists');
const { componentIcons } = require('./src/IconLists');
const { doctypeIcons } = require('./src/IconLists');
const { illustrativeIcons } = require('./src/IconLists');
const { logoIcons } = require('./src/IconLists');
const capitalize = ([first, ...rest]) =>
first.toUpperCase() + rest.join('').toLowerCase();
const iconTypes = ['base', 'component', 'doctype', 'illustrative', 'logo'];
const buildcontent = (componentName, iconType, iconName, interface, styles) => {
return `
import React from \'react\';
import { default as styled } from \'styled-components\';
import classnames from \'classnames\';
import { ${iconName} as ${componentName} } from \'../../svgrComponents/${iconType}Icons/';
import { ${styles} } from \'../utils/styles\';
import { ${interface} } from \'./iconInterface\';
import { baseClassName, cursorPointerClassName } from \'../utils/classes\';
import { ariaFocusableNoLabel, ariaLabelOrHidden } from \'../utils/aria\';
const Styled${iconName} = styled((props: ${interface}) => {
const { className, mousePointer, ariaLabel, color, fill, baseColor, highlightColor, ...passProps } =
props;
return (
<${componentName}
className={classnames(baseClassName, className, {
[cursorPointerClassName]: !!mousePointer
})}
{...passProps}
{...ariaLabelOrHidden(ariaLabel)}
{...ariaFocusableNoLabel(ariaLabel)}
/>
);
})\`
\${${styles}}
\`;
const ${iconName} = (props: ${interface}) => {
return <Styled${iconName} {...props}/>
}
${iconName}.displayName = \'Icon\';
export { ${iconName} };
`;
};
const createFolders = () => {
try {
iconTypes.forEach((type) => {
fs.mkdirSync(`src/${type}Icons`, { recursive: true });
});
} catch (error) {
console.error(error);
}
};
const getIconSet = (iconType) => {
switch (iconType) {
case 'base':
return baseIcons;
case 'illustrative':
return illustrativeIcons;
case 'component':
return componentIcons;
case 'doctype':
return doctypeIcons;
case 'logo':
return logoIcons;
default:
return [];
}
};
const getInterface = (iconType) => {
if (
iconType === 'illustrative' ||
iconType === 'component' ||
iconType === 'doctype'
)
return 'StaticIconProps';
if (iconType === 'logo') return 'LogoIconProps';
return 'BaseIconProps';
};
const getStyles = (iconType) => {
if (
iconType === 'illustrative' ||
iconType === 'component' ||
iconType === 'doctype'
)
return 'staticIconStyles';
if (iconType === 'logo') return 'logoIconStyles';
return 'baseIconStyles';
};
const copyInterface = (iconType) => {
const currentPath = path.join(__dirname, `src/utils/iconInterface.ts`);
const destinationPath = path.join(
__dirname,
`src/${iconType}Icons/iconInterface.ts`
);
fs.copyFile(currentPath, destinationPath, (err) => {
if (err) {
console.log(`Could not copy interface to ${iconType}Icons`);
return console.error(err);
}
});
};
const addInterfaceExports = () => {
try {
fs.appendFileSync(
`src/index.ts`,
`export type { BaseIconProps, StaticIconProps, LogoIconProps } from './utils/iconInterface';\n`
);
} catch (error) {
console.error(error);
}
};
// Create icon lists Typescript file and add exports to index.ts.
// This needs to be done so Typescript build has correct types for icons lists and keys
const addIconListExports = () => {
try {
let fileContent =
'/* NOTE: Do not modify this file manually! It is generated by `createComponents.js` when running `npm run generate` */ \n\n';
iconTypes.forEach((type) => {
const iconSet = getIconSet(type);
fileContent += `export const ${type}Icons = ${JSON.stringify(iconSet)}\n`;
fileContent += `const ${type}IconsList = ${JSON.stringify(iconSet)} as const\n`;
fileContent += `export type ${type}IconKeys = typeof ${type}IconsList[number]\n`;
});
fs.writeFileSync('src/iconLists.ts', `${fileContent}\n\n`);
fs.appendFileSync(
`src/index.ts`,
`export * from './iconLists';\n`
);
} catch (error) {
console.error(error);
}
};
// Create icons under corresponding icon type folders
const createIcons = () => {
iconTypes.forEach((type) => {
const iconSet = getIconSet(type);
try {
iconSet.forEach((icon) => {
const componentName = `${icon}`;
const iconName = `Icon${icon}`;
const interface = getInterface(type);
const styles = getStyles(type);
try {
// Create icon component
fs.writeFileSync(
`src/${type}Icons/${icon}.tsx`,
buildcontent(componentName, type, iconName, interface, styles)
);
// Add the component export to the corresponding index file
fs.appendFileSync(
`src/${type}Icons/index.ts`,
`export { ${iconName} } from './${icon}';\n`
);
fs.appendFileSync(
`src/index.ts`,
`export { ${iconName} } from './${type}Icons/';\n`
);
} catch (error) {
console.error(`Error creating ${icon} icon: `, error);
}
});
// Copy the interface file under the icon type folder
copyInterface(type);
} catch (error) {
console.error(`Error generating ${type}Icon files: `, error);
}
});
};
createFolders();
createIcons();
addInterfaceExports();
addIconListExports();