material-icon-theme 4.23.1 → 4.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/.eslintrc.json +51 -51
  2. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +7 -0
  3. package/.github/workflows/build.yml +45 -45
  4. package/.github/workflows/color-check.yml +22 -22
  5. package/.github/workflows/release.yml +73 -73
  6. package/.vscodeignore +21 -21
  7. package/CHANGELOG.md +1305 -1292
  8. package/CONTRIBUTING.md +199 -29
  9. package/README.md +199 -199
  10. package/icons/craco.svg +45 -45
  11. package/icons/folder-changesets-open.svg +5 -5
  12. package/icons/folder-changesets.svg +2 -2
  13. package/icons/folder-decorators-open.svg +2 -2
  14. package/icons/folder-decorators.svg +5 -5
  15. package/icons/folder-supabase-open.svg +5 -5
  16. package/icons/folder-supabase.svg +2 -2
  17. package/icons/sonarcloud.svg +4 -4
  18. package/icons/stylable.svg +10 -10
  19. package/icons/supabase.svg +4 -4
  20. package/icons/vitest.svg +6 -6
  21. package/images/contributors.png +0 -0
  22. package/images/how-tos/folder-icon-parts.png +0 -0
  23. package/images/how-tos/pick-folder-colors.png +0 -0
  24. package/images/how-tos/pick-folder-colors.svg +301 -0
  25. package/images/how-tos/svg-folder-icon-with-correct-colors.png +0 -0
  26. package/images/how-tos/svg-folder-icon-with-wrong-colors.png +0 -0
  27. package/images/how-tos/svg-with-light-color.png +0 -0
  28. package/images/how-tos/svg-with-spacing.png +0 -0
  29. package/images/how-tos/svg-with-too-dark-color.png +0 -0
  30. package/images/how-tos/svg-with-wrong-color.png +0 -0
  31. package/images/how-tos/svg-without-spacing.png +0 -0
  32. package/package.json +252 -252
  33. package/package.nls.de.json +32 -32
  34. package/package.nls.es.json +29 -29
  35. package/package.nls.fr.json +29 -29
  36. package/package.nls.ja.json +32 -32
  37. package/package.nls.json +32 -32
  38. package/package.nls.nl.json +32 -32
  39. package/package.nls.pl.json +32 -32
  40. package/package.nls.pt-BR.json +29 -29
  41. package/package.nls.pt-PT.json +29 -29
  42. package/package.nls.ru.json +29 -29
  43. package/package.nls.zh-CN.json +29 -29
  44. package/package.nls.zh-TW.json +29 -29
  45. package/src/commands/activate.ts +28 -28
  46. package/src/commands/explorerArrows.ts +55 -55
  47. package/src/commands/folderColor.ts +96 -96
  48. package/src/commands/folders.ts +55 -55
  49. package/src/commands/grayscale.ts +55 -55
  50. package/src/commands/iconPacks.ts +64 -64
  51. package/src/commands/index.ts +30 -30
  52. package/src/commands/opacity.ts +46 -46
  53. package/src/commands/saturation.ts +46 -46
  54. package/src/extension.ts +37 -37
  55. package/src/helpers/customIcons.ts +8 -8
  56. package/src/helpers/index.ts +88 -88
  57. package/src/i18n/index.ts +78 -78
  58. package/src/i18n/lang-de.ts +43 -43
  59. package/src/i18n/lang-en.ts +43 -43
  60. package/src/i18n/lang-es.ts +43 -43
  61. package/src/i18n/lang-fr.ts +43 -43
  62. package/src/i18n/lang-ja.ts +43 -43
  63. package/src/i18n/lang-nl.ts +43 -43
  64. package/src/i18n/lang-pl.ts +43 -43
  65. package/src/i18n/lang-pt-br.ts +43 -43
  66. package/src/i18n/lang-pt-pt.ts +43 -43
  67. package/src/i18n/lang-ru.ts +43 -43
  68. package/src/i18n/lang-uk.ts +43 -43
  69. package/src/i18n/lang-zh-cn.ts +43 -43
  70. package/src/i18n/lang-zh-tw.ts +43 -43
  71. package/src/icons/fileIcons.ts +2206 -2197
  72. package/src/icons/folderIcons.ts +818 -806
  73. package/src/icons/generator/folderGenerator.ts +340 -340
  74. package/src/icons/generator/iconOpacity.ts +111 -111
  75. package/src/icons/generator/iconSaturation.ts +140 -140
  76. package/src/icons/generator/jsonGenerator.ts +191 -191
  77. package/src/icons/languageIcons.ts +141 -141
  78. package/src/models/i18n/translation.ts +41 -41
  79. package/src/models/iconConfiguration.ts +37 -37
  80. package/src/models/icons/iconJsonOptions.ts +21 -21
  81. package/src/models/index.ts +3 -3
  82. package/src/scripts/contributors/index.ts +138 -138
  83. package/src/scripts/helpers/screenshots.ts +32 -32
  84. package/src/scripts/icons/checks/checkIconAvailability.ts +215 -215
  85. package/src/scripts/icons/checks/checkIconConflicts.ts +152 -152
  86. package/src/scripts/icons/checks/checkIconUsage.ts +137 -137
  87. package/src/scripts/icons/checks/index.ts +7 -7
  88. package/src/scripts/preview/index.ts +40 -40
  89. package/src/scripts/preview/preview.ts +163 -163
  90. package/src/test/runTest.ts +26 -26
  91. package/src/test/spec/i18n/i18n.spec.ts +54 -54
  92. package/src/test/spec/icons/fileIcons.spec.ts +250 -250
  93. package/src/test/spec/icons/folderIcons.spec.ts +418 -418
  94. package/src/test/spec/icons/languageIcons.spec.ts +184 -184
@@ -1,340 +1,340 @@
1
- import { writeFileSync } from 'fs';
2
- import merge from 'lodash.merge';
3
- import { basename, join } from 'path';
4
- import { getFileConfigHash } from '../../helpers/fileConfig';
5
- import {
6
- DefaultIcon,
7
- FolderIcon,
8
- FolderTheme,
9
- IconAssociations,
10
- IconConfiguration,
11
- IconJsonOptions,
12
- } from '../../models/index';
13
- import {
14
- highContrastColorFileEnding,
15
- iconFolderPath,
16
- lightColorFileEnding,
17
- openedFolder,
18
- } from './constants';
19
-
20
- /**
21
- * Get the folder icon definitions as object.
22
- */
23
- export const loadFolderIconDefinitions = (
24
- folderThemes: FolderTheme[],
25
- config: IconConfiguration,
26
- options: IconJsonOptions
27
- ): IconConfiguration => {
28
- config = merge({}, config);
29
- config.hidesExplorerArrows = options.hidesExplorerArrows;
30
- const activeTheme = getEnabledFolderTheme(
31
- folderThemes,
32
- options.folders?.theme
33
- );
34
- if (!activeTheme) {
35
- return {};
36
- }
37
- const enabledIcons = disableIconsByPack(activeTheme, options.activeIconPack);
38
- const customIcons = getCustomIcons(options.folders?.associations);
39
- const allIcons = [...enabledIcons, ...customIcons];
40
-
41
- if (options.folders?.theme === 'none') {
42
- return config;
43
- }
44
-
45
- allIcons.forEach((icon) => {
46
- if (icon.disabled) return;
47
- config = setIconDefinitions(config, icon);
48
- config = merge({}, config, setFolderNames(icon.name, icon.folderNames));
49
- config.light = icon.light
50
- ? merge(
51
- {},
52
- config.light,
53
- setFolderNames(icon.name, icon.folderNames, lightColorFileEnding)
54
- )
55
- : config.light;
56
- config.highContrast = icon.highContrast
57
- ? merge(
58
- {},
59
- config.highContrast,
60
- setFolderNames(
61
- icon.name,
62
- icon.folderNames,
63
- highContrastColorFileEnding
64
- )
65
- )
66
- : config.highContrast;
67
- });
68
-
69
- config = setDefaultFolderIcons(activeTheme, config);
70
- return config;
71
- };
72
-
73
- /**
74
- * Set the default folder icons for the theme.
75
- */
76
- const setDefaultFolderIcons = (
77
- theme: FolderTheme,
78
- config: IconConfiguration
79
- ): IconConfiguration => {
80
- config = merge({}, config);
81
- const hasFolderIcons =
82
- !!theme.defaultIcon.name && theme.defaultIcon.name.length > 0;
83
- if (hasFolderIcons) {
84
- config = setIconDefinitions(config, theme.defaultIcon);
85
- }
86
- config = merge(
87
- {},
88
- config,
89
- createDefaultIconConfigObject(hasFolderIcons, theme, '')
90
- );
91
- config.light = theme.defaultIcon.light
92
- ? merge(
93
- {},
94
- config.light,
95
- createDefaultIconConfigObject(
96
- hasFolderIcons,
97
- theme,
98
- lightColorFileEnding
99
- )
100
- )
101
- : config.light;
102
- config.highContrast = theme.defaultIcon.highContrast
103
- ? merge(
104
- {},
105
- config.highContrast,
106
- createDefaultIconConfigObject(
107
- hasFolderIcons,
108
- theme,
109
- highContrastColorFileEnding
110
- )
111
- )
112
- : config.highContrast;
113
-
114
- config = merge(
115
- {},
116
- config,
117
- createRootIconConfigObject(hasFolderIcons, theme, '')
118
- );
119
- if (theme.rootFolder) {
120
- config = setIconDefinitions(config, theme.rootFolder);
121
- config.light = theme.rootFolder.light
122
- ? merge(
123
- {},
124
- config.light,
125
- createRootIconConfigObject(
126
- hasFolderIcons,
127
- theme,
128
- lightColorFileEnding
129
- )
130
- )
131
- : config.light;
132
- config.highContrast = theme.rootFolder.highContrast
133
- ? merge(
134
- {},
135
- config.highContrast,
136
- createRootIconConfigObject(
137
- hasFolderIcons,
138
- theme,
139
- highContrastColorFileEnding
140
- )
141
- )
142
- : config.highContrast;
143
- }
144
-
145
- return config;
146
- };
147
-
148
- /**
149
- * Get the object of the current enabled theme.
150
- */
151
- const getEnabledFolderTheme = (
152
- themes: FolderTheme[],
153
- enabledTheme: string | undefined
154
- ): FolderTheme | undefined => {
155
- return themes.find((theme) => theme.name === enabledTheme);
156
- };
157
-
158
- /**
159
- * Disable all file icons that are in a pack which is disabled.
160
- */
161
- const disableIconsByPack = (
162
- folderIcons: FolderTheme | undefined,
163
- activatedIconPack: string | undefined
164
- ): FolderIcon[] => {
165
- if (!folderIcons?.icons || folderIcons.icons.length === 0) {
166
- return [];
167
- }
168
- return folderIcons.icons.filter((icon) => {
169
- return !icon.enabledFor
170
- ? true
171
- : icon.enabledFor.some((p) => p === activatedIconPack);
172
- });
173
- };
174
-
175
- const setIconDefinitions = (
176
- config: IconConfiguration,
177
- icon: FolderIcon | DefaultIcon
178
- ) => {
179
- config = merge({}, config);
180
- config = createIconDefinitions(config, icon.name);
181
- if (icon.light) {
182
- config = merge(
183
- {},
184
- config,
185
- createIconDefinitions(config, icon.name, lightColorFileEnding)
186
- );
187
- }
188
- if (icon.highContrast) {
189
- config = merge(
190
- {},
191
- config,
192
- createIconDefinitions(config, icon.name, highContrastColorFileEnding)
193
- );
194
- }
195
- return config;
196
- };
197
-
198
- const createIconDefinitions = (
199
- config: IconConfiguration,
200
- iconName: string,
201
- appendix: string = ''
202
- ) => {
203
- config = merge({}, config);
204
- const fileConfigHash = getFileConfigHash(config.options ?? {});
205
- const configIconDefinitions = config.iconDefinitions;
206
- if (configIconDefinitions) {
207
- configIconDefinitions[iconName + appendix] = {
208
- iconPath: `${iconFolderPath}${iconName}${appendix}${fileConfigHash}.svg`,
209
- };
210
- configIconDefinitions[`${iconName}${openedFolder}${appendix}`] = {
211
- iconPath: `${iconFolderPath}${iconName}${openedFolder}${appendix}${fileConfigHash}.svg`,
212
- };
213
- }
214
- return config;
215
- };
216
-
217
- const setFolderNames = (
218
- iconName: string,
219
- folderNames: string[],
220
- appendix: string = ''
221
- ) => {
222
- const obj: Partial<IconConfiguration> = {
223
- folderNames: {},
224
- folderNamesExpanded: {},
225
- };
226
- folderNames.forEach((name) => {
227
- if (obj.folderNames) {
228
- obj.folderNames[name as keyof IconConfiguration] = iconName + appendix;
229
- }
230
- if (obj.folderNamesExpanded) {
231
- obj.folderNamesExpanded[
232
- name as keyof IconConfiguration
233
- ] = `${iconName}${openedFolder}${appendix}`;
234
- }
235
- });
236
- return obj;
237
- };
238
-
239
- const createDefaultIconConfigObject = (
240
- hasFolderIcons: boolean,
241
- theme: FolderTheme,
242
- appendix: string = ''
243
- ) => {
244
- const obj = {
245
- folder: '',
246
- folderExpanded: '',
247
- };
248
- obj.folder = hasFolderIcons ? theme.defaultIcon.name + appendix : '';
249
- obj.folderExpanded = hasFolderIcons
250
- ? `${theme.defaultIcon.name}${openedFolder}${appendix}`
251
- : '';
252
- return obj;
253
- };
254
-
255
- const createRootIconConfigObject = (
256
- hasFolderIcons: boolean,
257
- theme: FolderTheme,
258
- appendix: string = ''
259
- ) => {
260
- const obj = {
261
- rootFolder: '',
262
- rootFolderExpanded: '',
263
- };
264
- obj.rootFolder = hasFolderIcons
265
- ? theme.rootFolder
266
- ? theme.rootFolder.name + appendix
267
- : theme.defaultIcon.name + appendix
268
- : '';
269
- obj.rootFolderExpanded = hasFolderIcons
270
- ? theme.rootFolder
271
- ? `${theme.rootFolder.name}${openedFolder}${appendix}`
272
- : `${theme.defaultIcon.name}${openedFolder}${appendix}`
273
- : '';
274
- return obj;
275
- };
276
-
277
- const getCustomIcons = (folderAssociations: IconAssociations | undefined) => {
278
- if (!folderAssociations) return [];
279
-
280
- const icons: FolderIcon[] = Object.keys(folderAssociations).map((fa) => ({
281
- // use default folder if icon name is empty
282
- name:
283
- folderAssociations[fa].length > 0
284
- ? 'folder-' + folderAssociations[fa].toLowerCase()
285
- : 'folder',
286
- folderNames: [fa.toLowerCase()],
287
- }));
288
-
289
- return icons;
290
- };
291
-
292
- export const generateFolderIcons = (color: string | undefined) => {
293
- if (!color || !validateHEXColorCode(color)) {
294
- return console.error('Invalid color code for folder icons');
295
- }
296
-
297
- const folderIcon =
298
- 'M10 4H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8c0-1.11-.9-2-2-2h-8l-2-2z';
299
- const folderIconOpen =
300
- 'M19 20H4c-1.11 0-2-.9-2-2V6c0-1.11.89-2 2-2h6l2 2h7a2 2 0 0 1 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z';
301
- const rootFolderIcon =
302
- 'M12 20a8 8 0 0 1-8-8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 5a5 5 0 0 0-5 5 5 5 0 0 0 5 5 5 5 0 0 0 5-5 5 5 0 0 0-5-5z';
303
- const rootFolderIconOpen =
304
- 'M12 20a8 8 0 0 1-8-8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z';
305
-
306
- writeSVGFiles('folder', getSVG(getPath(folderIcon, color)));
307
- writeSVGFiles('folder-open', getSVG(getPath(folderIconOpen, color)));
308
- writeSVGFiles('folder-root', getSVG(getPath(rootFolderIcon, color)));
309
- writeSVGFiles('folder-root-open', getSVG(getPath(rootFolderIconOpen, color)));
310
- };
311
-
312
- const getPath = (d: string, color: string) =>
313
- `<path d="${d}" fill="${color}" />`;
314
- const getSVG = (path: string) =>
315
- `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">${path}</svg>`;
316
-
317
- const writeSVGFiles = (iconName: string, svg: string) => {
318
- let iconsPath;
319
- if (basename(__dirname) === 'dist') {
320
- iconsPath = join(__dirname, '..', 'icons');
321
- } else {
322
- // executed via script
323
- iconsPath = join(__dirname, '..', '..', '..', 'icons');
324
- }
325
- const iconsFolderPath = join(iconsPath, `${iconName}.svg`);
326
- try {
327
- writeFileSync(iconsFolderPath, svg);
328
- } catch (error) {
329
- console.error(error);
330
- }
331
- };
332
-
333
- /**
334
- * Validate the HEX color code
335
- * @param color HEX code
336
- */
337
- export const validateHEXColorCode = (color: string = '') => {
338
- const hexPattern = new RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/);
339
- return color.length > 0 && hexPattern.test(color);
340
- };
1
+ import { writeFileSync } from 'fs';
2
+ import merge from 'lodash.merge';
3
+ import { basename, join } from 'path';
4
+ import { getFileConfigHash } from '../../helpers/fileConfig';
5
+ import {
6
+ DefaultIcon,
7
+ FolderIcon,
8
+ FolderTheme,
9
+ IconAssociations,
10
+ IconConfiguration,
11
+ IconJsonOptions,
12
+ } from '../../models/index';
13
+ import {
14
+ highContrastColorFileEnding,
15
+ iconFolderPath,
16
+ lightColorFileEnding,
17
+ openedFolder,
18
+ } from './constants';
19
+
20
+ /**
21
+ * Get the folder icon definitions as object.
22
+ */
23
+ export const loadFolderIconDefinitions = (
24
+ folderThemes: FolderTheme[],
25
+ config: IconConfiguration,
26
+ options: IconJsonOptions
27
+ ): IconConfiguration => {
28
+ config = merge({}, config);
29
+ config.hidesExplorerArrows = options.hidesExplorerArrows;
30
+ const activeTheme = getEnabledFolderTheme(
31
+ folderThemes,
32
+ options.folders?.theme
33
+ );
34
+ if (!activeTheme) {
35
+ return {};
36
+ }
37
+ const enabledIcons = disableIconsByPack(activeTheme, options.activeIconPack);
38
+ const customIcons = getCustomIcons(options.folders?.associations);
39
+ const allIcons = [...enabledIcons, ...customIcons];
40
+
41
+ if (options.folders?.theme === 'none') {
42
+ return config;
43
+ }
44
+
45
+ allIcons.forEach((icon) => {
46
+ if (icon.disabled) return;
47
+ config = setIconDefinitions(config, icon);
48
+ config = merge({}, config, setFolderNames(icon.name, icon.folderNames));
49
+ config.light = icon.light
50
+ ? merge(
51
+ {},
52
+ config.light,
53
+ setFolderNames(icon.name, icon.folderNames, lightColorFileEnding)
54
+ )
55
+ : config.light;
56
+ config.highContrast = icon.highContrast
57
+ ? merge(
58
+ {},
59
+ config.highContrast,
60
+ setFolderNames(
61
+ icon.name,
62
+ icon.folderNames,
63
+ highContrastColorFileEnding
64
+ )
65
+ )
66
+ : config.highContrast;
67
+ });
68
+
69
+ config = setDefaultFolderIcons(activeTheme, config);
70
+ return config;
71
+ };
72
+
73
+ /**
74
+ * Set the default folder icons for the theme.
75
+ */
76
+ const setDefaultFolderIcons = (
77
+ theme: FolderTheme,
78
+ config: IconConfiguration
79
+ ): IconConfiguration => {
80
+ config = merge({}, config);
81
+ const hasFolderIcons =
82
+ !!theme.defaultIcon.name && theme.defaultIcon.name.length > 0;
83
+ if (hasFolderIcons) {
84
+ config = setIconDefinitions(config, theme.defaultIcon);
85
+ }
86
+ config = merge(
87
+ {},
88
+ config,
89
+ createDefaultIconConfigObject(hasFolderIcons, theme, '')
90
+ );
91
+ config.light = theme.defaultIcon.light
92
+ ? merge(
93
+ {},
94
+ config.light,
95
+ createDefaultIconConfigObject(
96
+ hasFolderIcons,
97
+ theme,
98
+ lightColorFileEnding
99
+ )
100
+ )
101
+ : config.light;
102
+ config.highContrast = theme.defaultIcon.highContrast
103
+ ? merge(
104
+ {},
105
+ config.highContrast,
106
+ createDefaultIconConfigObject(
107
+ hasFolderIcons,
108
+ theme,
109
+ highContrastColorFileEnding
110
+ )
111
+ )
112
+ : config.highContrast;
113
+
114
+ config = merge(
115
+ {},
116
+ config,
117
+ createRootIconConfigObject(hasFolderIcons, theme, '')
118
+ );
119
+ if (theme.rootFolder) {
120
+ config = setIconDefinitions(config, theme.rootFolder);
121
+ config.light = theme.rootFolder.light
122
+ ? merge(
123
+ {},
124
+ config.light,
125
+ createRootIconConfigObject(
126
+ hasFolderIcons,
127
+ theme,
128
+ lightColorFileEnding
129
+ )
130
+ )
131
+ : config.light;
132
+ config.highContrast = theme.rootFolder.highContrast
133
+ ? merge(
134
+ {},
135
+ config.highContrast,
136
+ createRootIconConfigObject(
137
+ hasFolderIcons,
138
+ theme,
139
+ highContrastColorFileEnding
140
+ )
141
+ )
142
+ : config.highContrast;
143
+ }
144
+
145
+ return config;
146
+ };
147
+
148
+ /**
149
+ * Get the object of the current enabled theme.
150
+ */
151
+ const getEnabledFolderTheme = (
152
+ themes: FolderTheme[],
153
+ enabledTheme: string | undefined
154
+ ): FolderTheme | undefined => {
155
+ return themes.find((theme) => theme.name === enabledTheme);
156
+ };
157
+
158
+ /**
159
+ * Disable all file icons that are in a pack which is disabled.
160
+ */
161
+ const disableIconsByPack = (
162
+ folderIcons: FolderTheme | undefined,
163
+ activatedIconPack: string | undefined
164
+ ): FolderIcon[] => {
165
+ if (!folderIcons?.icons || folderIcons.icons.length === 0) {
166
+ return [];
167
+ }
168
+ return folderIcons.icons.filter((icon) => {
169
+ return !icon.enabledFor
170
+ ? true
171
+ : icon.enabledFor.some((p) => p === activatedIconPack);
172
+ });
173
+ };
174
+
175
+ const setIconDefinitions = (
176
+ config: IconConfiguration,
177
+ icon: FolderIcon | DefaultIcon
178
+ ) => {
179
+ config = merge({}, config);
180
+ config = createIconDefinitions(config, icon.name);
181
+ if (icon.light) {
182
+ config = merge(
183
+ {},
184
+ config,
185
+ createIconDefinitions(config, icon.name, lightColorFileEnding)
186
+ );
187
+ }
188
+ if (icon.highContrast) {
189
+ config = merge(
190
+ {},
191
+ config,
192
+ createIconDefinitions(config, icon.name, highContrastColorFileEnding)
193
+ );
194
+ }
195
+ return config;
196
+ };
197
+
198
+ const createIconDefinitions = (
199
+ config: IconConfiguration,
200
+ iconName: string,
201
+ appendix: string = ''
202
+ ) => {
203
+ config = merge({}, config);
204
+ const fileConfigHash = getFileConfigHash(config.options ?? {});
205
+ const configIconDefinitions = config.iconDefinitions;
206
+ if (configIconDefinitions) {
207
+ configIconDefinitions[iconName + appendix] = {
208
+ iconPath: `${iconFolderPath}${iconName}${appendix}${fileConfigHash}.svg`,
209
+ };
210
+ configIconDefinitions[`${iconName}${openedFolder}${appendix}`] = {
211
+ iconPath: `${iconFolderPath}${iconName}${openedFolder}${appendix}${fileConfigHash}.svg`,
212
+ };
213
+ }
214
+ return config;
215
+ };
216
+
217
+ const setFolderNames = (
218
+ iconName: string,
219
+ folderNames: string[],
220
+ appendix: string = ''
221
+ ) => {
222
+ const obj: Partial<IconConfiguration> = {
223
+ folderNames: {},
224
+ folderNamesExpanded: {},
225
+ };
226
+ folderNames.forEach((name) => {
227
+ if (obj.folderNames) {
228
+ obj.folderNames[name as keyof IconConfiguration] = iconName + appendix;
229
+ }
230
+ if (obj.folderNamesExpanded) {
231
+ obj.folderNamesExpanded[
232
+ name as keyof IconConfiguration
233
+ ] = `${iconName}${openedFolder}${appendix}`;
234
+ }
235
+ });
236
+ return obj;
237
+ };
238
+
239
+ const createDefaultIconConfigObject = (
240
+ hasFolderIcons: boolean,
241
+ theme: FolderTheme,
242
+ appendix: string = ''
243
+ ) => {
244
+ const obj = {
245
+ folder: '',
246
+ folderExpanded: '',
247
+ };
248
+ obj.folder = hasFolderIcons ? theme.defaultIcon.name + appendix : '';
249
+ obj.folderExpanded = hasFolderIcons
250
+ ? `${theme.defaultIcon.name}${openedFolder}${appendix}`
251
+ : '';
252
+ return obj;
253
+ };
254
+
255
+ const createRootIconConfigObject = (
256
+ hasFolderIcons: boolean,
257
+ theme: FolderTheme,
258
+ appendix: string = ''
259
+ ) => {
260
+ const obj = {
261
+ rootFolder: '',
262
+ rootFolderExpanded: '',
263
+ };
264
+ obj.rootFolder = hasFolderIcons
265
+ ? theme.rootFolder
266
+ ? theme.rootFolder.name + appendix
267
+ : theme.defaultIcon.name + appendix
268
+ : '';
269
+ obj.rootFolderExpanded = hasFolderIcons
270
+ ? theme.rootFolder
271
+ ? `${theme.rootFolder.name}${openedFolder}${appendix}`
272
+ : `${theme.defaultIcon.name}${openedFolder}${appendix}`
273
+ : '';
274
+ return obj;
275
+ };
276
+
277
+ const getCustomIcons = (folderAssociations: IconAssociations | undefined) => {
278
+ if (!folderAssociations) return [];
279
+
280
+ const icons: FolderIcon[] = Object.keys(folderAssociations).map((fa) => ({
281
+ // use default folder if icon name is empty
282
+ name:
283
+ folderAssociations[fa].length > 0
284
+ ? 'folder-' + folderAssociations[fa].toLowerCase()
285
+ : 'folder',
286
+ folderNames: [fa.toLowerCase()],
287
+ }));
288
+
289
+ return icons;
290
+ };
291
+
292
+ export const generateFolderIcons = (color: string | undefined) => {
293
+ if (!color || !validateHEXColorCode(color)) {
294
+ return console.error('Invalid color code for folder icons');
295
+ }
296
+
297
+ const folderIcon =
298
+ 'M10 4H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8c0-1.11-.9-2-2-2h-8l-2-2z';
299
+ const folderIconOpen =
300
+ 'M19 20H4c-1.11 0-2-.9-2-2V6c0-1.11.89-2 2-2h6l2 2h7a2 2 0 0 1 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5z';
301
+ const rootFolderIcon =
302
+ 'M12 20a8 8 0 0 1-8-8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 5a5 5 0 0 0-5 5 5 5 0 0 0 5 5 5 5 0 0 0 5-5 5 5 0 0 0-5-5z';
303
+ const rootFolderIconOpen =
304
+ 'M12 20a8 8 0 0 1-8-8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z';
305
+
306
+ writeSVGFiles('folder', getSVG(getPath(folderIcon, color)));
307
+ writeSVGFiles('folder-open', getSVG(getPath(folderIconOpen, color)));
308
+ writeSVGFiles('folder-root', getSVG(getPath(rootFolderIcon, color)));
309
+ writeSVGFiles('folder-root-open', getSVG(getPath(rootFolderIconOpen, color)));
310
+ };
311
+
312
+ const getPath = (d: string, color: string) =>
313
+ `<path d="${d}" fill="${color}" />`;
314
+ const getSVG = (path: string) =>
315
+ `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">${path}</svg>`;
316
+
317
+ const writeSVGFiles = (iconName: string, svg: string) => {
318
+ let iconsPath;
319
+ if (basename(__dirname) === 'dist') {
320
+ iconsPath = join(__dirname, '..', 'icons');
321
+ } else {
322
+ // executed via script
323
+ iconsPath = join(__dirname, '..', '..', '..', 'icons');
324
+ }
325
+ const iconsFolderPath = join(iconsPath, `${iconName}.svg`);
326
+ try {
327
+ writeFileSync(iconsFolderPath, svg);
328
+ } catch (error) {
329
+ console.error(error);
330
+ }
331
+ };
332
+
333
+ /**
334
+ * Validate the HEX color code
335
+ * @param color HEX code
336
+ */
337
+ export const validateHEXColorCode = (color: string = '') => {
338
+ const hexPattern = new RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/);
339
+ return color.length > 0 && hexPattern.test(color);
340
+ };