@digdir/designsystemet 1.13.2 → 1.14.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 (89) hide show
  1. package/dist/bin/config.js +50 -658
  2. package/dist/bin/designsystemet.d.ts.map +1 -1
  3. package/dist/bin/designsystemet.js +136 -4623
  4. package/dist/bin/options.js +22 -14
  5. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BorderValues.js +9 -0
  6. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BoxShadowTypes.js +8 -0
  7. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BoxShadowValues.js +13 -0
  8. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/ColorModifierTypes.js +10 -0
  9. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/ColorSpaceTypes.js +10 -0
  10. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/Properties.js +53 -0
  11. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/StrokeStyleValues.js +14 -0
  12. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenSetStatus.js +9 -0
  13. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenTypes.js +32 -0
  14. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TypographyValues.js +15 -0
  15. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/types/index.js +11 -0
  16. package/dist/package.js +5 -0
  17. package/dist/src/colors/colorMetadata.js +255 -261
  18. package/dist/src/colors/index.js +5 -522
  19. package/dist/src/colors/theme.js +104 -343
  20. package/dist/src/colors/types.js +22 -25
  21. package/dist/src/colors/utils.js +241 -154
  22. package/dist/src/config.js +103 -444
  23. package/dist/src/index.js +10 -3588
  24. package/dist/src/migrations/beta-to-v1.js +339 -537
  25. package/dist/src/migrations/codemods/css/plugins.js +31 -42
  26. package/dist/src/migrations/codemods/css/run.js +20 -151
  27. package/dist/src/migrations/color-rename-next49.js +44 -220
  28. package/dist/src/migrations/index.js +7 -577
  29. package/dist/src/scripts/update-preview-tokens.d.ts.map +1 -1
  30. package/dist/src/tokens/build.js +39 -1816
  31. package/dist/src/tokens/create/files.d.ts +10 -5
  32. package/dist/src/tokens/create/files.d.ts.map +1 -1
  33. package/dist/src/tokens/create/files.js +44 -601
  34. package/dist/src/tokens/create/generators/$designsystemet.js +8 -97
  35. package/dist/src/tokens/create/generators/$metadata.d.ts +7 -3
  36. package/dist/src/tokens/create/generators/$metadata.d.ts.map +1 -1
  37. package/dist/src/tokens/create/generators/$metadata.js +24 -21
  38. package/dist/src/tokens/create/generators/$themes.d.ts +2 -4
  39. package/dist/src/tokens/create/generators/$themes.d.ts.map +1 -1
  40. package/dist/src/tokens/create/generators/$themes.js +139 -312
  41. package/dist/src/tokens/create/generators/primitives/color-scheme.js +68 -443
  42. package/dist/src/tokens/create/generators/primitives/globals.js +141 -147
  43. package/dist/src/tokens/create/generators/primitives/size.js +146 -156
  44. package/dist/src/tokens/create/generators/primitives/typography.js +213 -217
  45. package/dist/src/tokens/create/generators/semantic/color-modes.js +24 -59
  46. package/dist/src/tokens/create/generators/semantic/color.js +42 -326
  47. package/dist/src/tokens/create/generators/semantic/style.js +379 -382
  48. package/dist/src/tokens/create/generators/themes/theme.js +108 -392
  49. package/dist/src/tokens/create.d.ts +2 -1
  50. package/dist/src/tokens/create.d.ts.map +1 -1
  51. package/dist/src/tokens/create.js +50 -1591
  52. package/dist/src/tokens/format.d.ts.map +1 -1
  53. package/dist/src/tokens/format.js +35 -3324
  54. package/dist/src/tokens/generate-config.js +155 -298
  55. package/dist/src/tokens/index.js +3 -3344
  56. package/dist/src/tokens/process/configs/color.js +50 -1085
  57. package/dist/src/tokens/process/configs/semantic.js +45 -1083
  58. package/dist/src/tokens/process/configs/shared.js +18 -109
  59. package/dist/src/tokens/process/configs/size-mode.js +27 -1082
  60. package/dist/src/tokens/process/configs/size.js +32 -1083
  61. package/dist/src/tokens/process/configs/type-scale.js +49 -1083
  62. package/dist/src/tokens/process/configs/typography.js +63 -1084
  63. package/dist/src/tokens/process/configs.js +91 -1224
  64. package/dist/src/tokens/process/formats/css/color.js +58 -1079
  65. package/dist/src/tokens/process/formats/css/semantic.js +27 -1081
  66. package/dist/src/tokens/process/formats/css/size-mode.js +43 -1077
  67. package/dist/src/tokens/process/formats/css/size.js +86 -1079
  68. package/dist/src/tokens/process/formats/css/type-scale.js +53 -1083
  69. package/dist/src/tokens/process/formats/css/typography.js +27 -1081
  70. package/dist/src/tokens/process/formats/css.js +18 -1081
  71. package/dist/src/tokens/process/output/declarations.js +18 -1201
  72. package/dist/src/tokens/process/output/tailwind.js +26 -40
  73. package/dist/src/tokens/process/output/theme.js +73 -206
  74. package/dist/src/tokens/process/platform.js +165 -1355
  75. package/dist/src/tokens/process/transformers.js +49 -89
  76. package/dist/src/tokens/process/utils/getMultidimensionalThemes.js +100 -1183
  77. package/dist/src/tokens/process/utils/kebab-case.js +7 -5
  78. package/dist/src/tokens/types.d.ts +6 -0
  79. package/dist/src/tokens/types.d.ts.map +1 -1
  80. package/dist/src/tokens/types.js +6 -7
  81. package/dist/src/tokens/utils.d.ts +2 -1
  82. package/dist/src/tokens/utils.d.ts.map +1 -1
  83. package/dist/src/tokens/utils.js +107 -93
  84. package/dist/src/types.js +1 -5
  85. package/dist/src/utils/filesystem.js +112 -124
  86. package/package.json +12 -15
  87. package/configs/test-tokens.config.json +0 -82
  88. package/dist/src/scripts/createJsonSchema.js +0 -409
  89. package/dist/src/scripts/update-preview-tokens.js +0 -3353
@@ -1,321 +1,178 @@
1
- // src/tokens/generate-config.ts
2
- import path2 from "path";
3
- import pc2 from "picocolors";
4
-
5
- // src/utils/filesystem.ts
6
- import fs from "fs/promises";
7
- import path from "path";
1
+ import { dsfs } from "../utils/filesystem.js";
8
2
  import pc from "picocolors";
9
- var FileSystem = class {
10
- isInitialized = false;
11
- dry = false;
12
- verbose = false;
13
- /** Default working directory is where the process was started */
14
- workingDir = process.cwd();
15
- outDir = this.workingDir;
16
- /** Initialize the file system */
17
- init({ dry, outdir, verbose }) {
18
- if (this.isInitialized) {
19
- console.warn(pc.yellow("FileSystem is already initialized. Ignoring subsequent init call."));
20
- return;
21
- }
22
- if (dry) {
23
- console.log(pc.blue("Initializing FileSystem in dry-run mode. No files will be written."));
24
- }
25
- this.dry = dry ?? false;
26
- this.verbose = verbose ?? false;
27
- this.outDir = outdir ? path.isAbsolute(outdir) ? outdir : path.join(this.workingDir, outdir) : this.workingDir;
28
- if (this.verbose) {
29
- console.log(
30
- `FileSystem initialized with workingDir: ${pc.green(this.workingDir)}, outDir: ${pc.green(this.outDir)}`
31
- );
32
- }
33
- this.isInitialized = true;
34
- }
35
- /**
36
- * Creates a directory if it does not already exist.
37
- *
38
- * @param dir - The path of the directory to create.
39
- *
40
- * @returns A promise that resolves when the operation is complete.
41
- * If the directory already exists or `dry` is `true`, the promise resolves immediately.
42
- */
43
- mkdir = async (dir) => {
44
- if (this.dry) {
45
- console.log(`${pc.blue("mkdir")} ${dir}`);
46
- return Promise.resolve();
47
- }
48
- const exists = await fs.access(dir, fs.constants.F_OK).then(() => true).catch(() => false);
49
- if (exists) {
50
- return Promise.resolve();
51
- }
52
- return fs.mkdir(dir, { recursive: true });
53
- };
54
- writeFile = async (path3, data) => {
55
- if (this.dry) {
56
- console.log(`${pc.blue("writeFile")} ${path3}`);
57
- return Promise.resolve();
58
- }
59
- return fs.writeFile(path3, data, { encoding: "utf-8" }).catch((error) => {
60
- console.error(pc.red(`Error writing file: ${path3}`));
61
- console.error(pc.red(error));
62
- throw error;
63
- });
64
- };
65
- cp = async (src, dest, filter) => {
66
- if (this.dry) {
67
- console.log(`${pc.blue("cp")} ${src} ${dest}`);
68
- return Promise.resolve();
69
- }
70
- return fs.cp(src, dest, { recursive: true, filter });
71
- };
72
- copyFile = async (src, dest) => {
73
- if (this.dry) {
74
- console.log(`${pc.blue("copyFile")} ${src} to ${dest}`);
75
- return Promise.resolve();
76
- }
77
- return fs.copyFile(src, dest);
78
- };
79
- cleanDir = async (dir) => {
80
- if (this.dry) {
81
- console.log(`${pc.blue("cleanDir")} ${dir}`);
82
- return Promise.resolve();
83
- }
84
- console.log(`
85
- \u{1F525} Cleaning dir ${pc.red(`${dir.trim()}`)} `);
86
- return fs.rm(dir, { recursive: true, force: true });
87
- };
88
- readFile = async (path3, allowFileNotFound) => {
89
- if (this.dry) {
90
- console.log(`${pc.blue("readFile")} ${path3}`);
91
- }
92
- try {
93
- return await fs.readFile(path3, "utf-8");
94
- } catch (error) {
95
- if (allowFileNotFound && error.code === "ENOENT") {
96
- return "";
97
- }
98
- throw error;
99
- }
100
- };
101
- readdir = async (path3) => {
102
- if (this.dry) {
103
- console.log(`${pc.blue("readdir")} ${path3}`);
104
- }
105
- try {
106
- return await fs.readdir(path3);
107
- } catch (error) {
108
- if (error.code === "ENOENT") {
109
- return [];
110
- }
111
- throw error;
112
- }
113
- };
114
- writeFiles = async (files, outDir, log) => {
115
- for (const { destination: filename, output } of files) {
116
- if (filename) {
117
- const filePath = path.join(outDir, filename);
118
- const fileDir = path.dirname(filePath);
119
- if (log) {
120
- console.log(filename);
121
- }
122
- await this.mkdir(fileDir);
123
- await this.writeFile(filePath, output);
124
- }
125
- }
126
- };
127
- };
128
- var dsfs = new FileSystem();
129
-
130
- // src/tokens/generate-config.ts
3
+ import path from "node:path";
4
+ //#region src/tokens/generate-config.ts
5
+ /**
6
+ * Reads a JSON file and returns its content as an object
7
+ */
131
8
  async function readJsonFile(filePath) {
132
- try {
133
- const content = await dsfs.readFile(filePath);
134
- return JSON.parse(content);
135
- } catch (err) {
136
- throw new Error(`Failed to read token file at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
137
- }
9
+ try {
10
+ const content = await dsfs.readFile(filePath);
11
+ return JSON.parse(content);
12
+ } catch (err) {
13
+ throw new Error(`Failed to read token file at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
14
+ }
138
15
  }
16
+ /**
17
+ * Extract the base hex color from a color scale (color.12)
18
+ */
139
19
  function extractBaseColor(colorScale) {
140
- if ("12" in colorScale && typeof colorScale["12"] === "object" && "$value" in colorScale["12"]) {
141
- const token = colorScale["12"];
142
- if (token.$type === "color") {
143
- return token.$value;
144
- }
145
- }
146
- return null;
20
+ if ("12" in colorScale && typeof colorScale["12"] === "object" && "$value" in colorScale["12"]) {
21
+ const token = colorScale["12"];
22
+ if (token.$type === "color") return token.$value;
23
+ }
24
+ return null;
147
25
  }
26
+ /**
27
+ * Discovers theme names from the primitives/modes/color-scheme/light/
28
+ */
148
29
  async function discoverThemes(tokensDir) {
149
- const lightModePath = path2.join(tokensDir, "themes");
150
- try {
151
- const files = await dsfs.readdir(lightModePath);
152
- const themes = files.filter((file) => file.endsWith(".json")).map((file) => file.replace(".json", ""));
153
- return themes;
154
- } catch {
155
- throw new Error(`Could not find themes. Make sure ${pc2.blue(lightModePath)} exists and contains theme JSON files.`);
156
- }
30
+ const lightModePath = path.join(tokensDir, "themes");
31
+ try {
32
+ return (await dsfs.readdir(lightModePath)).filter((file) => file.endsWith(".json")).map((file) => file.replace(".json", ""));
33
+ } catch {
34
+ throw new Error(`Could not find themes. Make sure ${pc.blue(lightModePath)} exists and contains theme JSON files.`);
35
+ }
157
36
  }
37
+ /**
38
+ * Reads token information for a specific theme from primitives/modes/color-scheme/light/<theme>.json
39
+ */
158
40
  async function readThemeTokens(tokensDir, themeName) {
159
- const themePath = path2.join(tokensDir, "primitives", "modes", "color-scheme", "light", `${themeName}.json`);
160
- return readJsonFile(themePath);
41
+ return readJsonFile(path.join(tokensDir, "primitives", "modes", "color-scheme", "light", `${themeName}.json`));
161
42
  }
43
+ /**
44
+ * Reads the theme configuration from themes/<theme>.json
45
+ */
162
46
  async function readThemeConfig(tokensDir, themeName) {
163
- const themeConfigPath = path2.join(tokensDir, "themes", `${themeName}.json`);
164
- try {
165
- return await readJsonFile(themeConfigPath);
166
- } catch {
167
- return null;
168
- }
47
+ const themeConfigPath = path.join(tokensDir, "themes", `${themeName}.json`);
48
+ try {
49
+ return await readJsonFile(themeConfigPath);
50
+ } catch {
51
+ return null;
52
+ }
169
53
  }
54
+ /**
55
+ * Extract border-radius base value from theme config
56
+ */
170
57
  function extractBorderRadius(themeConfig) {
171
- if (!themeConfig || !("border-radius" in themeConfig)) {
172
- return void 0;
173
- }
174
- const borderRadius = themeConfig["border-radius"];
175
- if ("base" in borderRadius && typeof borderRadius.base === "object" && "$value" in borderRadius.base) {
176
- const token = borderRadius.base;
177
- return Number(token.$value);
178
- }
179
- return void 0;
58
+ if (!themeConfig || !("border-radius" in themeConfig)) return;
59
+ const borderRadius = themeConfig["border-radius"];
60
+ if ("base" in borderRadius && typeof borderRadius.base === "object" && "$value" in borderRadius.base) {
61
+ const token = borderRadius.base;
62
+ return Number(token.$value);
63
+ }
180
64
  }
65
+ /**
66
+ * Extract font family from theme config
67
+ */
181
68
  function extractFontFamily(themeConfig) {
182
- if (!themeConfig || !("font-family" in themeConfig)) {
183
- return void 0;
184
- }
185
- const fontFamily = themeConfig["font-family"];
186
- if (typeof fontFamily === "object" && "$value" in fontFamily) {
187
- const token = fontFamily;
188
- const value = token.$value;
189
- if (value.startsWith("{") && value.endsWith("}")) {
190
- return void 0;
191
- }
192
- return value;
193
- }
194
- return void 0;
69
+ if (!themeConfig || !("font-family" in themeConfig)) return;
70
+ const fontFamily = themeConfig["font-family"];
71
+ if (typeof fontFamily === "object" && "$value" in fontFamily) {
72
+ const value = fontFamily.$value;
73
+ if (value.startsWith("{") && value.endsWith("}")) return;
74
+ return value;
75
+ }
195
76
  }
77
+ /**
78
+ * Reads the typography configuration from primitives/modes/typography/primary/<theme>.json
79
+ */
196
80
  async function readTypographyConfig(tokensDir, themeName) {
197
- const typographyConfigPath = path2.join(
198
- tokensDir,
199
- "primitives",
200
- "modes",
201
- "typography",
202
- "primary",
203
- `${themeName}.json`
204
- );
205
- try {
206
- return await readJsonFile(typographyConfigPath);
207
- } catch {
208
- return null;
209
- }
81
+ const typographyConfigPath = path.join(tokensDir, "primitives", "modes", "typography", "primary", `${themeName}.json`);
82
+ try {
83
+ return await readJsonFile(typographyConfigPath);
84
+ } catch {
85
+ return null;
86
+ }
210
87
  }
88
+ /**
89
+ * Extract font family from typography primitives
90
+ */
211
91
  function extractFontFamilyFromPrimitives(typographyConfig, themeName) {
212
- if (!typographyConfig) {
213
- return void 0;
214
- }
215
- const themeTypography = typographyConfig[themeName];
216
- if (!themeTypography || !("font-family" in themeTypography)) {
217
- return void 0;
218
- }
219
- const fontFamily = themeTypography["font-family"];
220
- if (typeof fontFamily === "object" && "$value" in fontFamily) {
221
- const token = fontFamily;
222
- return token.$value;
223
- }
224
- return void 0;
92
+ if (!typographyConfig) return;
93
+ const themeTypography = typographyConfig[themeName];
94
+ if (!themeTypography || !("font-family" in themeTypography)) return;
95
+ const fontFamily = themeTypography["font-family"];
96
+ if (typeof fontFamily === "object" && "$value" in fontFamily) return fontFamily.$value;
225
97
  }
98
+ /**
99
+ * Categorizes colors into main, support, and neutral based on color names
100
+ */
226
101
  function categorizeColors(themeTokens, themeName) {
227
- const main = {};
228
- const support = {};
229
- let neutral = null;
230
- const builtInColors = ["neutral", "info", "success", "warning", "danger"];
231
- const specialKeys = ["link"];
232
- const themeColors = themeTokens[themeName];
233
- if (!themeColors) {
234
- return { main, support, neutral };
235
- }
236
- for (const [colorName, colorValue] of Object.entries(themeColors)) {
237
- if (specialKeys.includes(colorName)) {
238
- continue;
239
- }
240
- if (typeof colorValue === "object" && !("$value" in colorValue)) {
241
- const baseColor = extractBaseColor(colorValue);
242
- if (baseColor) {
243
- if (colorName === "neutral") {
244
- neutral = baseColor;
245
- } else if (builtInColors.includes(colorName)) {
246
- } else if (colorName === "accent") {
247
- main[colorName] = baseColor;
248
- } else {
249
- support[colorName] = baseColor;
250
- }
251
- }
252
- }
253
- }
254
- return { main, support, neutral };
102
+ const main = {};
103
+ const support = {};
104
+ let neutral = null;
105
+ const builtInColors = [
106
+ "neutral",
107
+ "info",
108
+ "success",
109
+ "warning",
110
+ "danger"
111
+ ];
112
+ const specialKeys = ["link"];
113
+ const themeColors = themeTokens[themeName];
114
+ if (!themeColors) return {
115
+ main,
116
+ support,
117
+ neutral
118
+ };
119
+ for (const [colorName, colorValue] of Object.entries(themeColors)) {
120
+ if (specialKeys.includes(colorName)) continue;
121
+ if (typeof colorValue === "object" && !("$value" in colorValue)) {
122
+ const baseColor = extractBaseColor(colorValue);
123
+ if (baseColor) if (colorName === "neutral") neutral = baseColor;
124
+ else if (builtInColors.includes(colorName)) {} else if (colorName === "accent") main[colorName] = baseColor;
125
+ else support[colorName] = baseColor;
126
+ }
127
+ }
128
+ return {
129
+ main,
130
+ support,
131
+ neutral
132
+ };
255
133
  }
134
+ /**
135
+ * Generates a config file from existing design tokens
136
+ */
256
137
  async function generateConfigFromTokens(options) {
257
- const { tokensDir } = options;
258
- console.log(`
259
- Reading tokens from ${pc2.blue(tokensDir)}`);
260
- const themes = await discoverThemes(tokensDir);
261
- if (themes.length === 0) {
262
- throw new Error(`
263
- No themes found in ${pc2.blue(tokensDir)}`);
264
- }
265
- console.log(`
266
- Found ${pc2.green(String(themes.length))} theme(s): ${themes.map((t) => pc2.cyan(t)).join(", ")}`);
267
- const config = {
268
- outDir: tokensDir,
269
- themes: {}
270
- };
271
- for (const themeName of themes) {
272
- console.log(`
273
- Processing theme ${pc2.cyan(themeName)}...`);
274
- const themeTokens = await readThemeTokens(tokensDir, themeName);
275
- const themeConfig = await readThemeConfig(tokensDir, themeName);
276
- const typographyConfig = await readTypographyConfig(tokensDir, themeName);
277
- const { main, support, neutral } = categorizeColors(themeTokens, themeName);
278
- if (Object.keys(main).length === 0) {
279
- console.warn(pc2.yellow(`
280
- Warning: No main colors found for theme ${themeName}`));
281
- }
282
- if (!neutral) {
283
- console.warn(pc2.yellow(`
284
- Warning: No neutral color found for theme ${themeName}`));
285
- continue;
286
- }
287
- const borderRadius = extractBorderRadius(themeConfig);
288
- const fontFamily = extractFontFamily(themeConfig) ?? extractFontFamilyFromPrimitives(typographyConfig, themeName);
289
- config.themes[themeName] = {
290
- colors: {
291
- main,
292
- support,
293
- neutral
294
- },
295
- borderRadius,
296
- typography: fontFamily ? { fontFamily } : void 0
297
- };
298
- console.log(
299
- `
300
- \u2705 Main colors: ${Object.keys(main).map((c) => pc2.cyan(c)).join(", ") || pc2.dim("none")}`
301
- );
302
- console.log(
303
- `
304
- \u2705 Support colors: ${Object.keys(support).map((c) => pc2.cyan(c)).join(", ") || pc2.dim("none")}`
305
- );
306
- console.log(`
307
- \u2705 Neutral: ${pc2.cyan(neutral)}`);
308
- if (borderRadius !== void 0) {
309
- console.log(`
310
- \u2705 Border radius: ${pc2.cyan(String(borderRadius))}`);
311
- }
312
- if (fontFamily) {
313
- console.log(`
314
- \u2705 Font family: ${pc2.cyan(fontFamily)}`);
315
- }
316
- }
317
- return config;
138
+ const { tokensDir } = options;
139
+ console.log(`\nReading tokens from ${pc.blue(tokensDir)}`);
140
+ const themes = await discoverThemes(tokensDir);
141
+ if (themes.length === 0) throw new Error(`\nNo themes found in ${pc.blue(tokensDir)}`);
142
+ console.log(`\nFound ${pc.green(String(themes.length))} theme(s): ${themes.map((t) => pc.cyan(t)).join(", ")}`);
143
+ const config = {
144
+ outDir: tokensDir,
145
+ themes: {}
146
+ };
147
+ for (const themeName of themes) {
148
+ console.log(`\nProcessing theme ${pc.cyan(themeName)}...`);
149
+ const themeTokens = await readThemeTokens(tokensDir, themeName);
150
+ const themeConfig = await readThemeConfig(tokensDir, themeName);
151
+ const typographyConfig = await readTypographyConfig(tokensDir, themeName);
152
+ const { main, support, neutral } = categorizeColors(themeTokens, themeName);
153
+ if (Object.keys(main).length === 0) console.warn(pc.yellow(`\nWarning: No main colors found for theme ${themeName}`));
154
+ if (!neutral) {
155
+ console.warn(pc.yellow(`\nWarning: No neutral color found for theme ${themeName}`));
156
+ continue;
157
+ }
158
+ const borderRadius = extractBorderRadius(themeConfig);
159
+ const fontFamily = extractFontFamily(themeConfig) ?? extractFontFamilyFromPrimitives(typographyConfig, themeName);
160
+ config.themes[themeName] = {
161
+ colors: {
162
+ main,
163
+ support,
164
+ neutral
165
+ },
166
+ borderRadius,
167
+ typography: fontFamily ? { fontFamily } : void 0
168
+ };
169
+ console.log(`\n✅ Main colors: ${Object.keys(main).map((c) => pc.cyan(c)).join(", ") || pc.dim("none")}`);
170
+ console.log(`\n✅ Support colors: ${Object.keys(support).map((c) => pc.cyan(c)).join(", ") || pc.dim("none")}`);
171
+ console.log(`\n✅ Neutral: ${pc.cyan(neutral)}`);
172
+ if (borderRadius !== void 0) console.log(`\n✅ Border radius: ${pc.cyan(String(borderRadius))}`);
173
+ if (fontFamily) console.log(`\n✅ Font family: ${pc.cyan(fontFamily)}`);
174
+ }
175
+ return config;
318
176
  }
319
- export {
320
- generateConfigFromTokens
321
- };
177
+ //#endregion
178
+ export { generateConfigFromTokens };