@digdir/designsystemet 1.1.0 → 1.1.1

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.
@@ -1,6 +1,6 @@
1
1
  // src/tokens/build.ts
2
2
  import path from "path";
3
- import chalk5 from "chalk";
3
+ import chalk6 from "chalk";
4
4
  import * as R14 from "ramda";
5
5
 
6
6
  // src/utils.ts
@@ -43,233 +43,12 @@ var readFile = async (path2, dry, allowFileNotFound) => {
43
43
  }
44
44
  };
45
45
 
46
- // src/tokens/process/output/tailwind.ts
47
- var createTailwindCSSFiles = (cssFiles) => {
48
- console.log("\n\u{1F371} Creating Tailwind Config");
49
- return cssFiles.map((file) => {
50
- if (file.destination) {
51
- const tailwindConfig = generateTailwind(file.output);
52
- const tailwindFile = {
53
- destination: file.destination.replace(".css", ".tailwind.css"),
54
- output: tailwindConfig
55
- };
56
- return tailwindFile;
57
- }
58
- return void 0;
59
- }).filter((item) => item !== void 0);
60
- };
61
- var generateTailwind = (css) => {
62
- const tailwind = ["--font-sans: var(--ds-font-family)"];
63
- const tokens = Array.from(new Set(css.match(/--ds-[^:)]+/g)), (m) => m).sort(
64
- (a, b) => a.localeCompare(b, void 0, { numeric: true, sensitivity: "base" })
65
- );
66
- for (const token of tokens) {
67
- if (token.startsWith("--ds-color-") && !token.startsWith("--ds-color-focus")) {
68
- tailwind.push(`--color-${token.replace("--ds-color-", "")}: var(${token})`);
69
- } else if (token.startsWith("--ds-font-weight-")) {
70
- tailwind.push(`--font-weight-${token.replace("--ds-font-weight-", "")}: var(${token})`);
71
- } else if (token.match(/--ds-border-radius-(sm|md|lg|xl)/)) {
72
- tailwind.push(`--radius-${token.replace("--ds-border-radius-", "")}: var(${token})`);
73
- } else if (token.match(/--ds-body-(sm|mg|lg)-body-font-size/)) {
74
- tailwind.push(`--text-${token.replace("--ds-body-", "").replace("-font-size", "")}: var(${token})`);
75
- } else if (token.match(/^--ds-size-\d+$/)) {
76
- tailwind.push(`--spacing-${token.replace("--ds-size-", "")}: var(${token})`);
77
- }
78
- }
79
- const dynamicColors = `[data-color] {
80
- --color-background-default: var(--ds-color-background-default);
81
- --color-background-tinted: var(--ds-color-background-tinted);
82
- --color-surface-default: var(--ds-color-surface-default);
83
- --color-surface-tinted: var(--ds-color-surface-tinted);
84
- --color-surface-hover: var(--ds-color-surface-hover);
85
- --color-surface-active: var(--ds-color-surface-active);
86
- --color-border-subtle: var(--ds-color-border-subtle);
87
- --color-border-default: var(--ds-color-border-default);
88
- --color-border-strong: var(--ds-color-border-strong);
89
- --color-text-subtle: var(--ds-color-text-subtle);
90
- --color-text-default: var(--ds-color-text-default);
91
- --color-base-default: var(--ds-color-base-default);
92
- --color-base-hover: var(--ds-color-base-hover);
93
- --color-base-active: var(--ds-color-base-active);
94
- --color-base-contrast-subtle: var(--ds-color-base-contrast-subtle);
95
- --color-base-contrast-default: var(--ds-color-base-contrast-default);
96
- }`;
97
- return `@theme {${tailwind.map((str) => `
98
- ${str};`).join("")}
99
- }
100
- ${dynamicColors}`;
101
- };
102
-
103
- // src/tokens/process/output/theme.ts
104
- import chalk2 from "chalk";
105
- import * as R from "ramda";
106
-
107
- // package.json
108
- var package_default = {
109
- name: "@digdir/designsystemet",
110
- version: "1.1.0",
111
- description: "CLI for Designsystemet",
112
- author: "Designsystemet team",
113
- engines: {
114
- node: ">=22.16.0"
115
- },
116
- repository: {
117
- type: "git",
118
- url: "git+https://github.com/digdir/designsystemet.git"
119
- },
120
- homepage: "https://github.com/digdir/designsystemet/tree/main/packages/cli",
121
- license: "MIT",
122
- type: "module",
123
- main: "./dist/src/index.js",
124
- files: [
125
- "./dist/**",
126
- "./configs/**"
127
- ],
128
- bin: "dist/bin/designsystemet.js",
129
- exports: {
130
- ".": {
131
- import: "./dist/src/index.js"
132
- },
133
- "./color": {
134
- import: "./dist/src/colors/index.js"
135
- },
136
- "./tokens": {
137
- import: "./dist/src/tokens/index.js"
138
- }
139
- },
140
- publishConfig: {
141
- access: "public"
142
- },
143
- scripts: {
144
- designsystemet: "tsx ./bin/designsystemet.ts",
145
- build: "tsup && pnpm build:types && pnpm build:json-schema",
146
- "build:types": "tsc --emitDeclarationOnly --declaration",
147
- "build:json-schema": "tsx ./src/scripts/createJsonSchema.ts",
148
- types: "tsc --noEmit",
149
- "test:tokens-create-options": 'pnpm run designsystemet tokens create -m dominant:"#007682" -n "#003333" -b 99 -o ./temp/options/design-tokens --theme options --clean',
150
- "test:tokens-create-config": "pnpm run designsystemet tokens create --config ./configs/test-tokens.config.json",
151
- "test:tokens-build": "pnpm run designsystemet tokens build -t ./temp/options/design-tokens -o ./temp/options/build --clean",
152
- "test:tokens-build-tailwind": "pnpm run designsystemet tokens build -t ./temp/options/design-tokens -o ./temp/options/build --clean --experimental-tailwind",
153
- "test:tokens-build-config": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean",
154
- "test:tokens-build-config-tailwind": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean --experimental-tailwind",
155
- "test:tokens-create-and-build-options": "pnpm test:tokens-create-options && pnpm test:tokens-build",
156
- "test:tokens-create-and-build-config": "pnpm test:tokens-create-config && pnpm test:tokens-build-config",
157
- test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
158
- "digdir:tokens-build": "pnpm run designsystemet tokens build -t ../../internal/design-tokens -o ../../packages/theme/brand --clean --experimental-tailwind",
159
- "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
160
- "update:template": "tsx ./src/scripts/update-template.ts",
161
- "update:theme-digdir": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts && pnpm digdir:tokens-build",
162
- verify: "pnpm test && pnpm update:template && pnpm update:theme-digdir && pnpm build:tokens"
163
- },
164
- dependencies: {
165
- "@commander-js/extra-typings": "^14.0.0",
166
- "@tokens-studio/sd-transforms": "1.3.0",
167
- "apca-w3": "^0.1.9",
168
- chalk: "^5.4.1",
169
- "change-case": "^5.4.4",
170
- "chroma-js": "^3.1.2",
171
- "colorjs.io": "^0.6.0-alpha.1",
172
- commander: "^13.1.0",
173
- "fast-glob": "^3.3.3",
174
- hsluv: "^1.0.1",
175
- "object-hash": "^3.0.0",
176
- postcss: "^8.5.5",
177
- ramda: "^0.30.1",
178
- "style-dictionary": "^4.4.0",
179
- zod: "^3.25.64",
180
- "zod-validation-error": "^3.5.0"
181
- },
182
- devDependencies: {
183
- "@tokens-studio/types": "0.5.2",
184
- "@types/apca-w3": "^0.1.3",
185
- "@types/chroma-js": "^3.1.1",
186
- "@types/fs-extra": "^11.0.4",
187
- "@types/glob": "^8.1.0",
188
- "@types/node": "^22.15.31",
189
- "@types/object-hash": "^3.0.6",
190
- "@types/ramda": "^0.30.2",
191
- "fs-extra": "^11.3.0",
192
- tslib: "^2.8.1",
193
- tsup: "^8.5.0",
194
- tsx: "^4.20.3",
195
- typescript: "^5.8.3"
196
- }
197
- };
198
-
199
- // src/tokens/process/output/theme.ts
200
- var defaultFileHeader = `build: v${package_default.version}`;
201
- var createThemeCSSFiles = ({
202
- processedBuilds,
203
- fileHeader: fileHeader2 = defaultFileHeader
204
- }) => {
205
- const groupedByTheme = {};
206
- for (const [_, buildResults] of Object.entries(R.dissoc("types", processedBuilds))) {
207
- for (const buildResult of buildResults) {
208
- const themeName = buildResult.permutation.theme;
209
- const newOutputs = buildResult.formatted;
210
- if (R.isNotEmpty(newOutputs)) {
211
- const currentOutputs = groupedByTheme[themeName] ?? [];
212
- groupedByTheme[themeName] = R.concat(currentOutputs, newOutputs);
213
- }
214
- }
215
- }
216
- const sortOrder = [
217
- "color-scheme/light",
218
- "typography/secondary",
219
- "semantic",
220
- "color-scheme/dark",
221
- "color-scheme/contrast",
222
- "typography/primary",
223
- "color/"
224
- ];
225
- const sortByDefinedOrder = R.sortBy((file) => {
226
- const filePath = file.destination || "";
227
- const sortIndex = sortOrder.findIndex((sortElement) => {
228
- if (sortElement.endsWith("/")) {
229
- return filePath.includes(sortElement);
230
- }
231
- return filePath.includes(`${sortElement}.css`);
232
- });
233
- if (sortIndex === -1) {
234
- console.error(
235
- chalk2.yellow("WARNING: CSS section does not have a defined sort order:", filePath.replace(".css", ""))
236
- );
237
- console.log(
238
- chalk2.dim(
239
- `
240
- The section will currently be added to the end of the entry file, but the exact
241
- order may change due to nondeterminism.`.trim()
242
- )
243
- );
244
- return Infinity;
245
- }
246
- return sortIndex;
247
- });
248
- const header = `@charset "UTF-8";
249
- /*
250
- ${fileHeader2}
251
- */
252
-
253
- `;
254
- const sortAlphabetically = R.sort(R.ascend((x) => x.destination || ""));
255
- const pickOutputs = R.map(R.view(R.lensProp("output")));
256
- const themeCSSFile = R.pipe(
257
- sortAlphabetically,
258
- sortByDefinedOrder,
259
- pickOutputs,
260
- R.join("\n"),
261
- (content) => header + content
262
- );
263
- const themeCSSFiles = Object.entries(groupedByTheme).map(([theme, files]) => ({
264
- destination: `${theme}.css`,
265
- output: themeCSSFile(files)
266
- }));
267
- return themeCSSFiles;
268
- };
46
+ // src/tokens/process/output/declarations.ts
47
+ import chalk4 from "chalk";
269
48
 
270
49
  // src/tokens/process/platform.ts
271
- import chalk4 from "chalk";
272
- import * as R13 from "ramda";
50
+ import chalk3 from "chalk";
51
+ import * as R12 from "ramda";
273
52
  import StyleDictionary2 from "style-dictionary";
274
53
 
275
54
  // src/tokens/types.ts
@@ -280,30 +59,30 @@ var colorCategories = {
280
59
 
281
60
  // src/tokens/process/configs.ts
282
61
  import { register } from "@tokens-studio/sd-transforms";
283
- import * as R12 from "ramda";
62
+ import * as R11 from "ramda";
284
63
  import StyleDictionary from "style-dictionary";
285
64
 
286
65
  // src/tokens/utils.ts
287
- import * as R2 from "ramda";
288
- var mapToLowerCase = R2.map(R2.toLower);
289
- var hasAnyTruth = R2.any(R2.equals(true));
66
+ import * as R from "ramda";
67
+ var mapToLowerCase = R.map(R.toLower);
68
+ var hasAnyTruth = R.any(R.equals(true));
290
69
  var getType = (token) => (token.$type ?? token.type) || "";
291
70
  var getValue = (token) => token.$value ?? token.value;
292
- var typeEquals = R2.curry(
71
+ var typeEquals = R.curry(
293
72
  (types, token) => {
294
- if (R2.isNil(token)) {
73
+ if (R.isNil(token)) {
295
74
  return false;
296
75
  }
297
- return R2.includes(R2.toLower(getType(token)), R2.map(R2.toLower, Array.isArray(types) ? types : [types]));
76
+ return R.includes(R.toLower(getType(token)), R.map(R.toLower, Array.isArray(types) ? types : [types]));
298
77
  }
299
78
  );
300
- var pathStartsWithOneOf = R2.curry(
79
+ var pathStartsWithOneOf = R.curry(
301
80
  (paths, token) => {
302
- if (R2.isNil(token)) {
81
+ if (R.isNil(token)) {
303
82
  return false;
304
83
  }
305
84
  const tokenPath = mapToLowerCase(token.path);
306
- const matchPathsStartingWith = R2.map((path2) => R2.startsWith([path2], tokenPath), mapToLowerCase(paths));
85
+ const matchPathsStartingWith = R.map((path2) => R.startsWith([path2], tokenPath), mapToLowerCase(paths));
307
86
  return hasAnyTruth(matchPathsStartingWith);
308
87
  }
309
88
  );
@@ -311,7 +90,7 @@ function isSemanticToken(token) {
311
90
  return token.filePath.includes("semantic/");
312
91
  }
313
92
  function isSemanticColorToken(token, color) {
314
- return token.filePath.includes("semantic/") && R2.startsWith(["color", color], token.path);
93
+ return token.filePath.includes("semantic/") && R.startsWith(["color", color], token.path);
315
94
  }
316
95
  function isGlobalColorToken(token) {
317
96
  return typeEquals("color", token) && pathStartsWithOneOf(["global"], token);
@@ -322,7 +101,7 @@ function isColorCategoryToken(token, category) {
322
101
  (colorCategory2) => isColorCategoryToken(token, colorCategory2)
323
102
  );
324
103
  }
325
- return R2.startsWith(["color", category], token.path);
104
+ return R.startsWith(["color", category], token.path);
326
105
  }
327
106
  var isDigit = (s) => /^\d+$/.test(s);
328
107
  function traverseObj(obj, fn) {
@@ -338,7 +117,7 @@ function traverseObj(obj, fn) {
338
117
  return obj;
339
118
  }
340
119
  function inlineTokens(shouldInline, tokens) {
341
- const [inlineableTokens, otherTokens] = R2.partition(shouldInline, tokens);
120
+ const [inlineableTokens, otherTokens] = R.partition(shouldInline, tokens);
342
121
  return otherTokens.map((token) => {
343
122
  let transformed = getValue(token.original);
344
123
  for (const ref of inlineableTokens) {
@@ -347,16 +126,16 @@ function inlineTokens(shouldInline, tokens) {
347
126
  transformed = transformed.replaceAll(`{${refName}}`, getValue(ref.original));
348
127
  }
349
128
  }
350
- const tokenWithInlinedRefs = R2.set(R2.lensPath(["original", "$value"]), transformed, token);
129
+ const tokenWithInlinedRefs = R.set(R.lensPath(["original", "$value"]), transformed, token);
351
130
  return tokenWithInlinedRefs;
352
131
  });
353
132
  }
354
133
 
355
134
  // src/tokens/process/configs/color.ts
356
- import * as R7 from "ramda";
135
+ import * as R6 from "ramda";
357
136
 
358
137
  // src/tokens/process/formats/css/color.ts
359
- import * as R3 from "ramda";
138
+ import * as R2 from "ramda";
360
139
  import { createPropertyFormatter } from "style-dictionary/utils";
361
140
  var prefersColorScheme = (colorScheme2, content) => `
362
141
  @media (prefers-color-scheme: ${colorScheme2}) {
@@ -380,8 +159,8 @@ var colorScheme = {
380
159
  color-scheme: ${colorScheme_};
381
160
  ` : "";
382
161
  const filteredAllTokens = allTokens.filter(
383
- R3.allPass([
384
- R3.anyPass([
162
+ R2.allPass([
163
+ R2.anyPass([
385
164
  // Include semantic tokens in the output
386
165
  isSemanticToken,
387
166
  // Include global color tokens
@@ -397,7 +176,7 @@ ${formattedTokens}
397
176
  ${colorSchemeProperty}}
398
177
  `;
399
178
  const autoSelectorContent = ["light", "dark"].includes(colorScheme_) ? prefersColorScheme(colorScheme_, content) : "";
400
- const body = R3.isNotNil(layer) ? `@layer ${layer} {
179
+ const body = R2.isNotNil(layer) ? `@layer ${layer} {
401
180
  ${selector} ${content} ${autoSelectorContent}
402
181
  }
403
182
  ` : `${selector} ${content} ${autoSelectorContent}
@@ -410,7 +189,7 @@ var colorCategory = {
410
189
  format: async ({ dictionary, options, platform }) => {
411
190
  const { outputReferences, usesDtcg } = options;
412
191
  const { selector, layer } = platform;
413
- const format = R3.compose(
192
+ const format = R2.compose(
414
193
  createPropertyFormatter({
415
194
  outputReferences,
416
195
  dictionary,
@@ -431,7 +210,7 @@ var colorCategory = {
431
210
  ${formattedTokens}
432
211
  }
433
212
  `;
434
- const body = R3.isNotNil(layer) ? `@layer ${layer} {
213
+ const body = R2.isNotNil(layer) ? `@layer ${layer} {
435
214
  ${selector} ${content}
436
215
  }
437
216
  ` : `${selector} ${content}
@@ -441,12 +220,12 @@ ${selector} ${content}
441
220
  };
442
221
 
443
222
  // src/tokens/process/formats/css/semantic.ts
444
- import * as R4 from "ramda";
223
+ import * as R3 from "ramda";
445
224
  import { createPropertyFormatter as createPropertyFormatter2 } from "style-dictionary/utils";
446
225
  var isNumericBorderRadiusToken = (t) => t.path[0] === "border-radius" && isDigit(t.path[1]);
447
226
  var isNumericSizeToken = (t) => pathStartsWithOneOf(["size"], t) && isDigit(t.path[1]);
448
227
  var isSizeToken = (t) => pathStartsWithOneOf(["size"], t);
449
- var isInlineTokens = R4.anyPass([isNumericBorderRadiusToken, isNumericSizeToken, isSizeToken]);
228
+ var isInlineTokens = R3.anyPass([isNumericBorderRadiusToken, isNumericSizeToken, isSizeToken]);
450
229
  var overrideSizingFormula = (format, token) => {
451
230
  const [name, value] = format(token).split(":");
452
231
  const calc = value.replace(`var(--ds-size-mode-font-size)`, "1em").replace(/floor\((.*)\);/, "calc($1)");
@@ -458,7 +237,7 @@ var overrideSizingFormula = (format, token) => {
458
237
  };
459
238
  };
460
239
  var formatSizingTokens = (format, tokens) => {
461
- const { round, calc } = R4.reduce(
240
+ const { round, calc } = R3.reduce(
462
241
  (acc, token) => {
463
242
  const { round: round2, calc: calc2, name } = overrideSizingFormula(format, token);
464
243
  return {
@@ -488,17 +267,17 @@ var semantic = {
488
267
  usesDtcg
489
268
  });
490
269
  const tokens = inlineTokens(isInlineTokens, dictionary.allTokens);
491
- const filteredTokens = R4.reject((token) => token.name.includes("ds-size-mode-font-size"), tokens);
492
- const [sizingTokens, restTokens] = R4.partition(
270
+ const filteredTokens = R3.reject((token) => token.name.includes("ds-size-mode-font-size"), tokens);
271
+ const [sizingTokens, restTokens] = R3.partition(
493
272
  (t) => pathStartsWithOneOf(["_size"], t) && isDigit(t.path[1]),
494
273
  filteredTokens
495
274
  );
496
- const formattedTokens = [R4.map(format, restTokens).join("\n"), formatSizingTokens(format, sizingTokens)];
275
+ const formattedTokens = [R3.map(format, restTokens).join("\n"), formatSizingTokens(format, sizingTokens)];
497
276
  const content = `{
498
277
  ${formattedTokens.join("\n")}
499
278
  }
500
279
  `;
501
- const body = R4.isNotNil(layer) ? `@layer ${layer} {
280
+ const body = R3.isNotNil(layer) ? `@layer ${layer} {
502
281
  ${selector} ${content}
503
282
  }
504
283
  ` : `${selector} ${content}
@@ -508,11 +287,11 @@ ${selector} ${content}
508
287
  };
509
288
 
510
289
  // src/tokens/process/formats/css/typography.ts
511
- import * as R5 from "ramda";
290
+ import * as R4 from "ramda";
512
291
  import { createPropertyFormatter as createPropertyFormatter3 } from "style-dictionary/utils";
513
- var typographyFontFamilyPredicate = R5.allPass([
514
- R5.pathSatisfies(R5.includes("typography"), ["path"]),
515
- R5.pathSatisfies(R5.includes("fontFamily"), ["path"])
292
+ var typographyFontFamilyPredicate = R4.allPass([
293
+ R4.pathSatisfies(R4.includes("typography"), ["path"]),
294
+ R4.pathSatisfies(R4.includes("fontFamily"), ["path"])
516
295
  ]);
517
296
  var typography = {
518
297
  name: "ds/css-typography",
@@ -525,12 +304,12 @@ var typography = {
525
304
  format: "css",
526
305
  usesDtcg
527
306
  });
528
- const filteredTokens = R5.reject(typographyFontFamilyPredicate, dictionary.allTokens);
529
- const formattedTokens = R5.pipe(R5.map(format), R5.join("\n"))(filteredTokens);
307
+ const filteredTokens = R4.reject(typographyFontFamilyPredicate, dictionary.allTokens);
308
+ const formattedTokens = R4.pipe(R4.map(format), R4.join("\n"))(filteredTokens);
530
309
  const content = selector ? `${selector} {
531
310
  ${formattedTokens}
532
311
  }` : formattedTokens;
533
- const body = R5.isNotNil(layer) ? `@layer ${layer} {
312
+ const body = R4.isNotNil(layer) ? `@layer ${layer} {
534
313
  ${content}
535
314
  }` : content;
536
315
  return body;
@@ -547,8 +326,8 @@ var formats = {
547
326
 
548
327
  // src/tokens/process/transformers.ts
549
328
  import { checkAndEvaluateMath } from "@tokens-studio/sd-transforms";
550
- import * as R6 from "ramda";
551
- var isPx = R6.test(/\b\d+px\b/g);
329
+ import * as R5 from "ramda";
330
+ var isPx = R5.test(/\b\d+px\b/g);
552
331
  var sizeRem = {
553
332
  name: "ds/size/toRem",
554
333
  type: "value",
@@ -638,7 +417,7 @@ var colorSchemeVariables = ({ "color-scheme": colorScheme2 = "light", theme }) =
638
417
  {
639
418
  destination: `color-scheme/${colorScheme2}.css`,
640
419
  format: formats.colorScheme.name,
641
- filter: (token) => typeEquals("color", token) && !R7.startsWith(["global"], token.path)
420
+ filter: (token) => typeEquals("color", token) && !R6.startsWith(["global"], token.path)
642
421
  }
643
422
  ],
644
423
  options: {
@@ -689,7 +468,7 @@ var colorCategoryVariables = (opts) => ({ "color-scheme": colorScheme2, theme, .
689
468
  };
690
469
 
691
470
  // src/tokens/process/configs/semantic.ts
692
- import * as R8 from "ramda";
471
+ import * as R7 from "ramda";
693
472
  import { outputReferencesFilter } from "style-dictionary/utils";
694
473
  var semanticVariables = ({ theme }) => {
695
474
  const selector = `:root`;
@@ -712,8 +491,8 @@ var semanticVariables = ({ theme }) => {
712
491
  destination: `semantic.css`,
713
492
  format: formats.semantic.name,
714
493
  filter: (token) => {
715
- const isUwantedToken = R8.anyPass([R8.includes("primitives/global")])(token.filePath);
716
- const isPrivateToken = R8.includes("_", token.path);
494
+ const isUwantedToken = R7.anyPass([R7.includes("primitives/global")])(token.filePath);
495
+ const isPrivateToken = R7.includes("_", token.path);
717
496
  const unwantedPaths = pathStartsWithOneOf(["font-size", "line-height", "letter-spacing"], token);
718
497
  const unwantedTypes = typeEquals(["color", "fontWeight", "fontFamily", "typography"], token);
719
498
  const unwantedTokens = !(unwantedPaths || unwantedTypes || isPrivateToken || isUwantedToken);
@@ -734,20 +513,20 @@ var semanticVariables = ({ theme }) => {
734
513
  };
735
514
 
736
515
  // src/tokens/process/configs/storefront.ts
737
- import * as R10 from "ramda";
516
+ import * as R9 from "ramda";
738
517
  import { outputReferencesFilter as outputReferencesFilter2 } from "style-dictionary/utils";
739
518
 
740
519
  // src/tokens/process/formats/js-tokens.ts
741
- import * as R9 from "ramda";
520
+ import * as R8 from "ramda";
742
521
  import { createPropertyFormatter as createPropertyFormatter4, fileHeader } from "style-dictionary/utils";
743
- var groupByType = R9.groupBy((token) => getType(token));
744
- var removeUnwatedTokens = R9.pipe(
745
- R9.reject((token) => isColorCategoryToken(token)),
746
- R9.reject((token) => R9.any((path2) => path2.startsWith("_"))(token.path))
522
+ var groupByType = R8.groupBy((token) => getType(token));
523
+ var removeUnwatedTokens = R8.pipe(
524
+ R8.reject((token) => isColorCategoryToken(token)),
525
+ R8.reject((token) => R8.any((path2) => path2.startsWith("_"))(token.path))
747
526
  );
748
- var dissocExtensions = R9.pipe(R9.dissoc("$extensions"), R9.dissocPath(["original", "$extensions"]));
749
- var removeUnwatedProps = R9.map((token) => dissocExtensions(token));
750
- var toCssVarName = R9.pipe(R9.split(":"), R9.head, R9.trim);
527
+ var dissocExtensions = R8.pipe(R8.dissoc("$extensions"), R8.dissocPath(["original", "$extensions"]));
528
+ var removeUnwatedProps = R8.map((token) => dissocExtensions(token));
529
+ var toCssVarName = R8.pipe(R8.split(":"), R8.head, R8.trim);
751
530
  var jsTokens = {
752
531
  name: "ds/js-tokens",
753
532
  format: async ({ dictionary, file, options }) => {
@@ -758,7 +537,7 @@ var jsTokens = {
758
537
  format: "css",
759
538
  usesDtcg
760
539
  });
761
- const formatTokens = R9.map((token) => {
540
+ const formatTokens = R8.map((token) => {
762
541
  if (pathStartsWithOneOf(["size", "_size"], token)) {
763
542
  const { calc, name } = overrideSizingFormula(format, token);
764
543
  return {
@@ -772,7 +551,7 @@ var jsTokens = {
772
551
  name: toCssVarName(format(token))
773
552
  };
774
553
  });
775
- const processTokens = R9.pipe(removeUnwatedTokens, removeUnwatedProps, formatTokens, groupByType);
554
+ const processTokens = R8.pipe(removeUnwatedTokens, removeUnwatedProps, formatTokens, groupByType);
776
555
  const tokens = processTokens(inlineTokens(isInlineTokens, dictionary.allTokens));
777
556
  const content = Object.entries(tokens).map(
778
557
  ([name, token]) => `export const ${name} = ${JSON.stringify(token, null, 2).replace(/"([^"]+)":/g, "$1:")}
@@ -797,9 +576,9 @@ var typescriptTokens = ({ "color-scheme": colorScheme2, theme }) => {
797
576
  destination: `${colorScheme2}.ts`,
798
577
  format: jsTokens.name,
799
578
  filter: (token) => {
800
- if (pathStartsWithOneOf(["border-width", "letter-spacing", "border-radius"], token) && !R10.includes("semantic", token.filePath))
579
+ if (pathStartsWithOneOf(["border-width", "letter-spacing", "border-radius"], token) && !R9.includes("semantic", token.filePath))
801
580
  return false;
802
- const isSemanticColor = R10.includes("semantic", token.filePath) && typeEquals(["color"], token);
581
+ const isSemanticColor = R9.includes("semantic", token.filePath) && typeEquals(["color"], token);
803
582
  const wantedTypes = typeEquals(["shadow", "dimension", "typography", "opacity"], token);
804
583
  return isSemanticColor || wantedTypes;
805
584
  }
@@ -1028,19 +807,19 @@ var TypographyValues;
1028
807
  })(TypographyValues || (TypographyValues = {}));
1029
808
 
1030
809
  // src/tokens/process/utils/getMultidimensionalThemes.ts
1031
- import chalk3 from "chalk";
810
+ import chalk2 from "chalk";
1032
811
  import { kebabCase } from "change-case";
1033
- import * as R11 from "ramda";
812
+ import * as R10 from "ramda";
1034
813
  var getMultidimensionalThemes = (processed$themes, dimensions) => {
1035
814
  const verboseLogging = buildOptions?.verbose;
1036
815
  const grouped$themes = groupThemes(processed$themes);
1037
816
  const permutations = permutateThemes(grouped$themes);
1038
817
  const ALL_DEPENDENT_ON = ["theme"];
1039
- const keys2 = R11.keys(grouped$themes);
818
+ const keys2 = R10.keys(grouped$themes);
1040
819
  const nonDependentKeys = keys2.filter((x) => ![...ALL_DEPENDENT_ON, ...dimensions].includes(x));
1041
820
  if (verboseLogging) {
1042
- console.log(chalk3.cyan(`\u{1F50E} Finding theme permutations for ${dimensions}`));
1043
- console.log(chalk3.cyan(` (ignoring permutations for ${nonDependentKeys})`));
821
+ console.log(chalk2.cyan(`\u{1F50E} Finding theme permutations for ${dimensions}`));
822
+ console.log(chalk2.cyan(` (ignoring permutations for ${nonDependentKeys})`));
1044
823
  }
1045
824
  return permutations.filter((val) => {
1046
825
  const filters = nonDependentKeys.map((x) => val.permutation[x] === grouped$themes[x][0].name);
@@ -1076,7 +855,7 @@ function groupThemes(themes) {
1076
855
  }
1077
856
  return groups;
1078
857
  }
1079
- var hasUnknownProps = R11.pipe(R11.values, R11.none(R11.equals("unknown")), R11.not);
858
+ var hasUnknownProps = R10.pipe(R10.values, R10.none(R10.equals("unknown")), R10.not);
1080
859
  function permutateThemes(groups) {
1081
860
  const separator = "_";
1082
861
  const permutations = cartesian(Object.values(groups));
@@ -1086,8 +865,8 @@ function permutateThemes(groups) {
1086
865
  const { group, name, selectedTokenSets } = theme;
1087
866
  let updatedPermutation = acc.permutation;
1088
867
  if (group) {
1089
- const groupProp = R11.lensProp(group);
1090
- updatedPermutation = R11.set(groupProp, name, updatedPermutation);
868
+ const groupProp = R10.lensProp(group);
869
+ updatedPermutation = R10.set(groupProp, name, updatedPermutation);
1091
870
  }
1092
871
  const updatedName = `${String(acc.name)}${acc ? separator : ""}${name}`;
1093
872
  const sets = [...acc.selectedTokenSets, ...filterTokenSets(selectedTokenSets)];
@@ -1133,6 +912,12 @@ function filterTokenSets(tokensets) {
1133
912
  function cartesian(a) {
1134
913
  return a.reduce((a2, b) => a2.flatMap((d) => b.map((e) => [d, e].flat())));
1135
914
  }
915
+ var getCustomColors = (processed$themes, colorGroups) => processed$themes.filter((x) => {
916
+ if (!x.group) {
917
+ return false;
918
+ }
919
+ return colorGroups.includes(x.group);
920
+ }).map((x) => x.name);
1136
921
 
1137
922
  // src/tokens/process/configs.ts
1138
923
  void register(StyleDictionary, { withSDBuiltins: false });
@@ -1171,7 +956,7 @@ var getConfigsForThemeDimensions = (getConfig, processed$themes, dimensions, opt
1171
956
  obj.filePath = tokenSet;
1172
957
  }
1173
958
  });
1174
- tokenSource.tokens = R12.mergeDeepRight(tokenSource.tokens, tokensWithFilePath);
959
+ tokenSource.tokens = R11.mergeDeepRight(tokenSource.tokens, tokensWithFilePath);
1175
960
  }
1176
961
  }
1177
962
  } else {
@@ -1215,12 +1000,6 @@ var initResult = {
1215
1000
  };
1216
1001
  var buildOptions;
1217
1002
  var sd = new StyleDictionary2();
1218
- var getCustomColors = (processed$themes, colorGroups) => processed$themes.filter((x) => {
1219
- if (!x.group) {
1220
- return false;
1221
- }
1222
- return colorGroups.includes(x.group);
1223
- }).map((x) => x.name);
1224
1003
  var buildConfigs = {
1225
1004
  typography: { getConfig: configs.typographyVariables, dimensions: ["typography"] },
1226
1005
  "color-scheme": { getConfig: configs.colorSchemeVariables, dimensions: ["color-scheme"] },
@@ -1261,46 +1040,54 @@ var buildConfigs = {
1261
1040
  // },
1262
1041
  };
1263
1042
  async function processPlatform(options) {
1264
- const { type, $themes } = options;
1043
+ const { type, processed$themes } = options;
1265
1044
  const platform = "css";
1266
1045
  const tokenSets = type === "format" ? options.tokenSets : void 0;
1267
1046
  const tokensDir = type === "build" ? options.tokensDir : void 0;
1268
1047
  const UNSAFE_DEFAULT_COLOR = process.env.UNSAFE_DEFAULT_COLOR ?? "";
1269
1048
  if (UNSAFE_DEFAULT_COLOR) {
1270
1049
  console.warn(
1271
- chalk4.yellow(
1050
+ chalk3.yellow(
1272
1051
  `
1273
- \u26A0\uFE0F UNSAFE_DEFAULT_COLOR is set to ${chalk4.blue(UNSAFE_DEFAULT_COLOR)}. This will override the default color.`
1052
+ \u26A0\uFE0F UNSAFE_DEFAULT_COLOR is set to ${chalk3.blue(UNSAFE_DEFAULT_COLOR)}. This will override the default color.`
1274
1053
  )
1275
1054
  );
1276
1055
  }
1277
1056
  const UNSAFE_COLOR_GROUPS = Array.from(process.env.UNSAFE_COLOR_GROUPS?.split(",") ?? []);
1278
1057
  if (UNSAFE_COLOR_GROUPS.length > 0) {
1279
1058
  console.warn(
1280
- chalk4.yellow(
1059
+ chalk3.yellow(
1281
1060
  `
1282
- \u26A0\uFE0F UNSAFE_COLOR_GROUPS is set to ${chalk4.blue(`[${UNSAFE_COLOR_GROUPS.join(", ")}]`)}. This will override the default color groups.`
1061
+ \u26A0\uFE0F UNSAFE_COLOR_GROUPS is set to ${chalk3.blue(`[${UNSAFE_COLOR_GROUPS.join(", ")}]`)}. This will override the default color groups.`
1283
1062
  )
1284
1063
  );
1285
1064
  }
1286
1065
  const colorGroups = UNSAFE_COLOR_GROUPS.length > 0 ? UNSAFE_COLOR_GROUPS : [colorCategories.main, colorCategories.support].map((c) => `${c}-color`);
1287
1066
  buildOptions = options;
1288
1067
  buildOptions.defaultColor = UNSAFE_DEFAULT_COLOR;
1289
- const processed$themes = $themes.map(processThemeObject).filter((theme) => R13.not(theme.group === "size" && theme.name !== "medium"));
1290
- const customColors = getCustomColors(processed$themes, colorGroups);
1068
+ buildOptions.colorGroups = colorGroups;
1069
+ const filteredProcessed$themes = processed$themes.filter(
1070
+ (theme) => R12.not(theme.group === "size" && theme.name !== "medium")
1071
+ );
1072
+ const customColors = getCustomColors(filteredProcessed$themes, colorGroups);
1291
1073
  if (!buildOptions.defaultColor) {
1292
- const firstMainColor = R13.head(customColors);
1074
+ const firstMainColor = R12.head(customColors);
1293
1075
  buildOptions.defaultColor = firstMainColor;
1294
1076
  }
1295
1077
  if (buildOptions.defaultColor) {
1296
1078
  console.log(`
1297
- \u{1F3A8} Using ${chalk4.blue(buildOptions.defaultColor)} as default color`);
1079
+ \u{1F3A8} Using ${chalk3.blue(buildOptions.defaultColor)} as default color`);
1298
1080
  }
1299
- const buildAndSdConfigs = R13.map((buildConfig) => {
1300
- const sdConfigs = getConfigsForThemeDimensions(buildConfig.getConfig, processed$themes, buildConfig.dimensions, {
1301
- tokensDir,
1302
- tokenSets
1303
- });
1081
+ const buildAndSdConfigs = R12.map((buildConfig) => {
1082
+ const sdConfigs = getConfigsForThemeDimensions(
1083
+ buildConfig.getConfig,
1084
+ filteredProcessed$themes,
1085
+ buildConfig.dimensions,
1086
+ {
1087
+ tokensDir,
1088
+ tokenSets
1089
+ }
1090
+ );
1304
1091
  const unknownConfigs = buildConfig.dimensions.map(
1305
1092
  (dimension) => sdConfigs.filter((x) => x.permutation[dimension] === "unknown")
1306
1093
  );
@@ -1324,23 +1111,22 @@ async function processPlatform(options) {
1324
1111
  "warning-color": [initResult],
1325
1112
  "info-color": [initResult],
1326
1113
  semantic: [initResult],
1327
- typography: [initResult],
1328
- types: [initResult]
1114
+ typography: [initResult]
1329
1115
  };
1330
1116
  try {
1331
- for (const [buildName, { buildConfig, sdConfigs }] of R13.toPairs(buildAndSdConfigs)) {
1117
+ for (const [buildName, { buildConfig, sdConfigs }] of R12.toPairs(buildAndSdConfigs)) {
1332
1118
  if (!(buildConfig.enabled?.() ?? true)) {
1333
1119
  continue;
1334
1120
  }
1335
1121
  if (sdConfigs.length > 0) {
1336
1122
  console.log(`
1337
- \u{1F371} Building ${chalk4.green(buildConfig.name ?? buildName)}`);
1123
+ \u{1F371} Building ${chalk3.green(buildConfig.name ?? buildName)}`);
1338
1124
  const results = await Promise.all(
1339
1125
  sdConfigs.map(async (sdConfig) => {
1340
1126
  const { config, permutation } = sdConfig;
1341
1127
  const modes = ["theme", ...buildConfig.dimensions];
1342
1128
  const modeMessage = modes.map((x) => permutation[x]).join(" - ");
1343
- const logMessage = R13.isNil(buildConfig.log) ? modeMessage : buildConfig?.log(sdConfig);
1129
+ const logMessage = R12.isNil(buildConfig.log) ? modeMessage : buildConfig?.log(sdConfig);
1344
1130
  console.log(logMessage);
1345
1131
  const sdOptions = { cache: true };
1346
1132
  const sdExtended = await sd.extend(config);
@@ -1360,17 +1146,22 @@ async function processPlatform(options) {
1360
1146
  }
1361
1147
  throw err;
1362
1148
  }
1363
- const colorsFileName = "colors.d.ts";
1364
- const reactColorTypes = await createColorTypeDeclaration(customColors);
1365
- processedBuilds.types = [
1149
+ return processedBuilds;
1150
+ }
1151
+
1152
+ // src/tokens/process/output/declarations.ts
1153
+ var createTypeDeclarationFiles = (processed$themes) => {
1154
+ const colorGroups = buildOptions?.colorGroups || [];
1155
+ const customColors = getCustomColors(processed$themes, colorGroups);
1156
+ const typeDeclaration = createColorTypeDeclaration(customColors);
1157
+ return [
1366
1158
  {
1367
- ...initResult,
1368
- formatted: [{ output: reactColorTypes, destination: colorsFileName }]
1159
+ output: typeDeclaration,
1160
+ destination: "colors.d.ts"
1369
1161
  }
1370
1162
  ];
1371
- return processedBuilds;
1372
- }
1373
- async function createColorTypeDeclaration(colors) {
1163
+ };
1164
+ function createColorTypeDeclaration(colors) {
1374
1165
  console.log(`
1375
1166
  \u{1F371} Building ${chalk4.green("type declarations")}`);
1376
1167
  const typeDeclaration = `
@@ -1385,6 +1176,232 @@ ${colors.map((color) => ` ${color}: never;`).join("\n")}
1385
1176
  return typeDeclaration;
1386
1177
  }
1387
1178
 
1179
+ // src/tokens/process/output/tailwind.ts
1180
+ var createTailwindCSSFiles = (cssFiles) => {
1181
+ console.log("\n\u{1F371} Creating Tailwind Config");
1182
+ return cssFiles.map((file) => {
1183
+ if (file.destination) {
1184
+ const tailwindConfig = generateTailwind(file.output);
1185
+ const tailwindFile = {
1186
+ destination: file.destination.replace(".css", ".tailwind.css"),
1187
+ output: tailwindConfig
1188
+ };
1189
+ return tailwindFile;
1190
+ }
1191
+ return void 0;
1192
+ }).filter((item) => item !== void 0);
1193
+ };
1194
+ var generateTailwind = (css) => {
1195
+ const tailwind = ["--font-sans: var(--ds-font-family)"];
1196
+ const tokens = Array.from(new Set(css.match(/--ds-[^:)]+/g)), (m) => m).sort(
1197
+ (a, b) => a.localeCompare(b, void 0, { numeric: true, sensitivity: "base" })
1198
+ );
1199
+ for (const token of tokens) {
1200
+ if (token.startsWith("--ds-color-") && !token.startsWith("--ds-color-focus")) {
1201
+ tailwind.push(`--color-${token.replace("--ds-color-", "")}: var(${token})`);
1202
+ } else if (token.startsWith("--ds-font-weight-")) {
1203
+ tailwind.push(`--font-weight-${token.replace("--ds-font-weight-", "")}: var(${token})`);
1204
+ } else if (token.match(/--ds-border-radius-(sm|md|lg|xl)/)) {
1205
+ tailwind.push(`--radius-${token.replace("--ds-border-radius-", "")}: var(${token})`);
1206
+ } else if (token.match(/--ds-body-(sm|mg|lg)-body-font-size/)) {
1207
+ tailwind.push(`--text-${token.replace("--ds-body-", "").replace("-font-size", "")}: var(${token})`);
1208
+ } else if (token.match(/^--ds-size-\d+$/)) {
1209
+ tailwind.push(`--spacing-${token.replace("--ds-size-", "")}: var(${token})`);
1210
+ }
1211
+ }
1212
+ const dynamicColors = `[data-color] {
1213
+ --color-background-default: var(--ds-color-background-default);
1214
+ --color-background-tinted: var(--ds-color-background-tinted);
1215
+ --color-surface-default: var(--ds-color-surface-default);
1216
+ --color-surface-tinted: var(--ds-color-surface-tinted);
1217
+ --color-surface-hover: var(--ds-color-surface-hover);
1218
+ --color-surface-active: var(--ds-color-surface-active);
1219
+ --color-border-subtle: var(--ds-color-border-subtle);
1220
+ --color-border-default: var(--ds-color-border-default);
1221
+ --color-border-strong: var(--ds-color-border-strong);
1222
+ --color-text-subtle: var(--ds-color-text-subtle);
1223
+ --color-text-default: var(--ds-color-text-default);
1224
+ --color-base-default: var(--ds-color-base-default);
1225
+ --color-base-hover: var(--ds-color-base-hover);
1226
+ --color-base-active: var(--ds-color-base-active);
1227
+ --color-base-contrast-subtle: var(--ds-color-base-contrast-subtle);
1228
+ --color-base-contrast-default: var(--ds-color-base-contrast-default);
1229
+ }`;
1230
+ return `@theme {${tailwind.map((str) => `
1231
+ ${str};`).join("")}
1232
+ }
1233
+ ${dynamicColors}`;
1234
+ };
1235
+
1236
+ // src/tokens/process/output/theme.ts
1237
+ import chalk5 from "chalk";
1238
+ import * as R13 from "ramda";
1239
+
1240
+ // package.json
1241
+ var package_default = {
1242
+ name: "@digdir/designsystemet",
1243
+ version: "1.1.1",
1244
+ description: "CLI for Designsystemet",
1245
+ author: "Designsystemet team",
1246
+ engines: {
1247
+ node: ">=22.16.0"
1248
+ },
1249
+ repository: {
1250
+ type: "git",
1251
+ url: "git+https://github.com/digdir/designsystemet.git"
1252
+ },
1253
+ homepage: "https://github.com/digdir/designsystemet/tree/main/packages/cli",
1254
+ license: "MIT",
1255
+ type: "module",
1256
+ main: "./dist/src/index.js",
1257
+ files: [
1258
+ "./dist/**",
1259
+ "./configs/**"
1260
+ ],
1261
+ bin: "dist/bin/designsystemet.js",
1262
+ exports: {
1263
+ ".": {
1264
+ import: "./dist/src/index.js"
1265
+ },
1266
+ "./color": {
1267
+ import: "./dist/src/colors/index.js"
1268
+ },
1269
+ "./tokens": {
1270
+ import: "./dist/src/tokens/index.js"
1271
+ }
1272
+ },
1273
+ publishConfig: {
1274
+ access: "public"
1275
+ },
1276
+ scripts: {
1277
+ designsystemet: "tsx ./bin/designsystemet.ts",
1278
+ "designsystemet:inspect": "tsx --inspect-brk ./bin/designsystemet.ts",
1279
+ build: "tsup && pnpm build:types && pnpm build:json-schema",
1280
+ "build:types": "tsc --emitDeclarationOnly --declaration",
1281
+ "build:json-schema": "tsx ./src/scripts/createJsonSchema.ts",
1282
+ types: "tsc --noEmit",
1283
+ "test:tokens-create-options": 'pnpm run designsystemet tokens create -m dominant:"#007682" -n "#003333" -b 99 -o ./temp/options/design-tokens --theme options --clean',
1284
+ "test:tokens-create-config": "pnpm run designsystemet tokens create --config ./configs/test-tokens.config.json",
1285
+ "test:tokens-build": "pnpm run designsystemet tokens build -t ./temp/options/design-tokens -o ./temp/options/build --clean",
1286
+ "test:tokens-build-tailwind": "pnpm run designsystemet tokens build -t ./temp/options/design-tokens -o ./temp/options/build --clean --experimental-tailwind",
1287
+ "test:tokens-build-config": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean",
1288
+ "test:tokens-build-config:inspect": "pnpm run designsystemet:inspect tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean",
1289
+ "test:tokens-build-config-tailwind": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean --experimental-tailwind",
1290
+ "test:tokens-create-and-build-options": "pnpm test:tokens-create-options && pnpm test:tokens-build",
1291
+ "test:tokens-create-and-build-config": "pnpm test:tokens-create-config && pnpm test:tokens-build-config",
1292
+ test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
1293
+ "digdir:tokens-build": "pnpm run designsystemet tokens build -t ../../internal/design-tokens -o ../../packages/theme/brand --clean --experimental-tailwind",
1294
+ "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
1295
+ "update:template": "tsx ./src/scripts/update-template.ts",
1296
+ "update:theme-digdir": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts && pnpm digdir:tokens-build",
1297
+ verify: "pnpm test && pnpm update:template && pnpm update:theme-digdir && pnpm build:tokens"
1298
+ },
1299
+ dependencies: {
1300
+ "@commander-js/extra-typings": "^14.0.0",
1301
+ "@tokens-studio/sd-transforms": "1.3.0",
1302
+ "apca-w3": "^0.1.9",
1303
+ chalk: "^5.4.1",
1304
+ "change-case": "^5.4.4",
1305
+ "chroma-js": "^3.1.2",
1306
+ "colorjs.io": "^0.6.0-alpha.1",
1307
+ commander: "^14.0.0",
1308
+ "fast-glob": "^3.3.3",
1309
+ hsluv: "^1.0.1",
1310
+ "object-hash": "^3.0.0",
1311
+ postcss: "^8.5.6",
1312
+ ramda: "^0.30.1",
1313
+ "style-dictionary": "^5.0.0",
1314
+ zod: "^3.25.67",
1315
+ "zod-validation-error": "^3.5.2"
1316
+ },
1317
+ devDependencies: {
1318
+ "@tokens-studio/types": "0.5.2",
1319
+ "@types/apca-w3": "^0.1.3",
1320
+ "@types/chroma-js": "^3.1.1",
1321
+ "@types/fs-extra": "^11.0.4",
1322
+ "@types/glob": "^8.1.0",
1323
+ "@types/node": "^22.15.32",
1324
+ "@types/object-hash": "^3.0.6",
1325
+ "@types/ramda": "^0.30.2",
1326
+ "fs-extra": "^11.3.0",
1327
+ tslib: "^2.8.1",
1328
+ tsup: "^8.5.0",
1329
+ tsx: "^4.20.3",
1330
+ typescript: "^5.8.3"
1331
+ }
1332
+ };
1333
+
1334
+ // src/tokens/process/output/theme.ts
1335
+ var defaultFileHeader = `build: v${package_default.version}`;
1336
+ var createThemeCSSFiles = ({
1337
+ processedBuilds,
1338
+ fileHeader: fileHeader2 = defaultFileHeader
1339
+ }) => {
1340
+ const groupedByTheme = {};
1341
+ for (const [_, buildResults] of Object.entries(processedBuilds)) {
1342
+ for (const buildResult of buildResults) {
1343
+ const themeName = buildResult.permutation.theme;
1344
+ const newOutputs = buildResult.formatted;
1345
+ if (R13.isNotEmpty(newOutputs)) {
1346
+ const currentOutputs = groupedByTheme[themeName] ?? [];
1347
+ groupedByTheme[themeName] = R13.concat(currentOutputs, newOutputs);
1348
+ }
1349
+ }
1350
+ }
1351
+ const sortOrder = [
1352
+ "color-scheme/light",
1353
+ "typography/secondary",
1354
+ "semantic",
1355
+ "color-scheme/dark",
1356
+ "color-scheme/contrast",
1357
+ "typography/primary",
1358
+ "color/"
1359
+ ];
1360
+ const sortByDefinedOrder = R13.sortBy((file) => {
1361
+ const filePath = file.destination || "";
1362
+ const sortIndex = sortOrder.findIndex((sortElement) => {
1363
+ if (sortElement.endsWith("/")) {
1364
+ return filePath.includes(sortElement);
1365
+ }
1366
+ return filePath.includes(`${sortElement}.css`);
1367
+ });
1368
+ if (sortIndex === -1) {
1369
+ console.error(
1370
+ chalk5.yellow("WARNING: CSS section does not have a defined sort order:", filePath.replace(".css", ""))
1371
+ );
1372
+ console.log(
1373
+ chalk5.dim(
1374
+ `
1375
+ The section will currently be added to the end of the entry file, but the exact
1376
+ order may change due to nondeterminism.`.trim()
1377
+ )
1378
+ );
1379
+ return Infinity;
1380
+ }
1381
+ return sortIndex;
1382
+ });
1383
+ const header = `@charset "UTF-8";
1384
+ /*
1385
+ ${fileHeader2}
1386
+ */
1387
+
1388
+ `;
1389
+ const sortAlphabetically = R13.sort(R13.ascend((x) => x.destination || ""));
1390
+ const pickOutputs = R13.map(R13.view(R13.lensProp("output")));
1391
+ const themeCSSFile = R13.pipe(
1392
+ sortAlphabetically,
1393
+ sortByDefinedOrder,
1394
+ pickOutputs,
1395
+ R13.join("\n"),
1396
+ (content) => header + content
1397
+ );
1398
+ const themeCSSFiles = Object.entries(groupedByTheme).map(([theme, files]) => ({
1399
+ destination: `${theme}.css`,
1400
+ output: themeCSSFile(files)
1401
+ }));
1402
+ return themeCSSFiles;
1403
+ };
1404
+
1388
1405
  // src/tokens/build.ts
1389
1406
  async function write(files, outDir, dry) {
1390
1407
  for (const { destination, output } of files) {
@@ -1401,6 +1418,7 @@ var buildTokens = async (options) => {
1401
1418
  const outDir = path.resolve(options.outDir);
1402
1419
  const tokensDir = path.resolve(options.tokensDir);
1403
1420
  const $themes = JSON.parse(await readFile(`${tokensDir}/$themes.json`));
1421
+ const processed$themes = $themes.map(processThemeObject);
1404
1422
  let $designsystemet;
1405
1423
  try {
1406
1424
  const $designsystemetContent = await readFile(`${tokensDir}/$designsystemet.json`);
@@ -1408,30 +1426,30 @@ var buildTokens = async (options) => {
1408
1426
  } catch (_error) {
1409
1427
  }
1410
1428
  console.log(`
1411
- \u{1F3D7}\uFE0F Start building tokens in ${chalk5.green(tokensDir)}`);
1429
+ \u{1F3D7}\uFE0F Start building tokens in ${chalk6.green(tokensDir)}`);
1412
1430
  const processedBuilds = await processPlatform({
1413
1431
  ...options,
1414
1432
  outDir,
1415
1433
  tokensDir,
1416
1434
  type: "build",
1417
- $themes
1435
+ processed$themes
1418
1436
  });
1419
1437
  const fileHeader2 = R14.join("")([
1420
1438
  defaultFileHeader,
1421
1439
  $designsystemet ? `
1422
1440
  design-tokens: v${$designsystemet.version}` : ""
1423
1441
  ]);
1424
- let cssFiles = createThemeCSSFiles({ processedBuilds, fileHeader: fileHeader2 });
1442
+ let files = [];
1443
+ const declarationFiles = createTypeDeclarationFiles(processed$themes);
1444
+ const cssFiles = createThemeCSSFiles({ processedBuilds, fileHeader: fileHeader2 });
1445
+ files = [...declarationFiles, ...cssFiles];
1425
1446
  if (options.tailwind) {
1426
1447
  const tailwindFiles = createTailwindCSSFiles(cssFiles);
1427
- cssFiles = cssFiles.concat(tailwindFiles.filter(Boolean));
1448
+ files = files.concat(tailwindFiles.filter(Boolean));
1428
1449
  }
1429
1450
  console.log(`
1430
- \u{1F4BE} Writing build to ${chalk5.green(outDir)}`);
1431
- for (const { formatted } of processedBuilds.types) {
1432
- await write(formatted, outDir, options.dry);
1433
- }
1434
- await write(cssFiles, outDir, options.dry);
1451
+ \u{1F4BE} Writing build to ${chalk6.green(outDir)}`);
1452
+ await write(files, outDir, options.dry);
1435
1453
  console.log(`
1436
1454
  \u2705 Finished building tokens!`);
1437
1455
  return processedBuilds;