@digdir/designsystemet 1.0.8 → 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.
Files changed (65) hide show
  1. package/dist/bin/config.d.ts +3 -3
  2. package/dist/bin/config.d.ts.map +1 -1
  3. package/dist/bin/config.js +45 -45
  4. package/dist/bin/designsystemet.js +827 -748
  5. package/dist/config.schema.json +4 -4
  6. package/dist/src/colors/index.d.ts +2 -2
  7. package/dist/src/colors/index.d.ts.map +1 -1
  8. package/dist/src/colors/index.js +143 -143
  9. package/dist/src/colors/theme.d.ts +1 -2
  10. package/dist/src/colors/theme.d.ts.map +1 -1
  11. package/dist/src/config.d.ts +6 -21
  12. package/dist/src/config.d.ts.map +1 -1
  13. package/dist/src/config.js +43 -40
  14. package/dist/src/index.js +418 -430
  15. package/dist/src/scripts/createJsonSchema.js +23 -24
  16. package/dist/src/scripts/update-template.d.ts.map +1 -1
  17. package/dist/src/tokens/build.d.ts +1 -1
  18. package/dist/src/tokens/build.d.ts.map +1 -1
  19. package/dist/src/tokens/build.js +359 -280
  20. package/dist/src/tokens/create/generators/$designsystemet.js +16 -15
  21. package/dist/src/tokens/create/generators/color.js +21 -21
  22. package/dist/src/tokens/create/write.js +17 -16
  23. package/dist/src/tokens/create.d.ts +1 -0
  24. package/dist/src/tokens/create.d.ts.map +1 -1
  25. package/dist/src/tokens/create.js +22 -21
  26. package/dist/src/tokens/format.d.ts.map +1 -1
  27. package/dist/src/tokens/format.js +931 -944
  28. package/dist/src/tokens/index.d.ts +2 -2
  29. package/dist/src/tokens/index.d.ts.map +1 -1
  30. package/dist/src/tokens/index.js +295 -307
  31. package/dist/src/tokens/process/configs/color.d.ts.map +1 -1
  32. package/dist/src/tokens/process/configs/color.js +5 -5
  33. package/dist/src/tokens/process/configs/semantic.d.ts.map +1 -1
  34. package/dist/src/tokens/process/configs/semantic.js +5 -5
  35. package/dist/src/tokens/process/configs/storefront.d.ts.map +1 -1
  36. package/dist/src/tokens/process/configs/storefront.js +1 -1
  37. package/dist/src/tokens/process/configs/typography.d.ts.map +1 -1
  38. package/dist/src/tokens/process/configs/typography.js +5 -5
  39. package/dist/src/tokens/process/configs.d.ts.map +1 -1
  40. package/dist/src/tokens/process/configs.js +5 -5
  41. package/dist/src/tokens/process/formats/css/color.js +2 -2
  42. package/dist/src/tokens/process/formats/css/semantic.js +2 -2
  43. package/dist/src/tokens/process/formats/css/typography.js +1 -1
  44. package/dist/src/tokens/process/formats/css.js +5 -5
  45. package/dist/src/tokens/process/formats/js-tokens.js +1 -1
  46. package/dist/src/tokens/process/output/declarations.d.ts +4 -0
  47. package/dist/src/tokens/process/output/declarations.d.ts.map +1 -0
  48. package/dist/src/tokens/process/output/declarations.js +860 -0
  49. package/dist/src/tokens/process/output/tailwind.d.ts +3 -0
  50. package/dist/src/tokens/process/output/tailwind.d.ts.map +1 -0
  51. package/dist/src/tokens/process/output/tailwind.js +59 -0
  52. package/dist/src/tokens/process/{theme.d.ts → output/theme.d.ts} +2 -2
  53. package/dist/src/tokens/process/output/theme.d.ts.map +1 -0
  54. package/dist/src/tokens/process/{theme.js → output/theme.js} +20 -19
  55. package/dist/src/tokens/process/platform.d.ts +8 -4
  56. package/dist/src/tokens/process/platform.d.ts.map +1 -1
  57. package/dist/src/tokens/process/platform.js +27 -56
  58. package/dist/src/tokens/process/utils/getMultidimensionalThemes.d.ts +1 -0
  59. package/dist/src/tokens/process/utils/getMultidimensionalThemes.d.ts.map +1 -1
  60. package/dist/src/tokens/process/utils/getMultidimensionalThemes.js +12 -5
  61. package/dist/src/tokens/types.d.ts +1 -1
  62. package/dist/src/tokens/types.d.ts.map +1 -1
  63. package/dist/src/tokens/utils.d.ts.map +1 -1
  64. package/package.json +16 -15
  65. package/dist/src/tokens/process/theme.d.ts.map +0 -1
@@ -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,177 +43,12 @@ var readFile = async (path2, dry, allowFileNotFound) => {
43
43
  }
44
44
  };
45
45
 
46
- // src/tokens/process/theme.ts
47
- import * as R from "ramda";
48
- import chalk2 from "chalk";
49
-
50
- // package.json
51
- var package_default = {
52
- name: "@digdir/designsystemet",
53
- version: "1.0.8",
54
- description: "CLI for Designsystemet",
55
- author: "Designsystemet team",
56
- engines: {
57
- node: ">=22.16.0"
58
- },
59
- repository: {
60
- type: "git",
61
- url: "git+https://github.com/digdir/designsystemet.git"
62
- },
63
- homepage: "https://github.com/digdir/designsystemet/tree/main/scripts/cli",
64
- license: "MIT",
65
- type: "module",
66
- main: "./dist/src/index.js",
67
- files: [
68
- "./dist/**",
69
- "./configs/**"
70
- ],
71
- bin: "dist/bin/designsystemet.js",
72
- exports: {
73
- ".": {
74
- import: "./dist/src/index.js"
75
- },
76
- "./color": {
77
- import: "./dist/src/colors/index.js"
78
- },
79
- "./tokens": {
80
- import: "./dist/src/tokens/index.js"
81
- }
82
- },
83
- publishConfig: {
84
- access: "public"
85
- },
86
- scripts: {
87
- designsystemet: "tsx ./bin/designsystemet.ts",
88
- "build:tokens": "pnpm run designsystemet tokens build -p -t ../../internal/design-tokens -o ../../packages/theme/brand --clean",
89
- "build:tokens:debug": "tsx --inspect-brk ./bin/designsystemet.ts tokens build -p -t ../../internal/design-tokens -o ../../packages/theme/brand --clean",
90
- build: "tsup && pnpm build:types && pnpm build:json-schema",
91
- "build:types": "tsc --emitDeclarationOnly --declaration",
92
- "build:json-schema": "tsx ./src/scripts/createJsonSchema.ts",
93
- types: "tsc --noEmit",
94
- "test:tokens-create-options": 'pnpm run designsystemet tokens create -m dominant:"#007682" -n "#003333" -b 99 -o ./temp/options/design-tokens --theme options --clean',
95
- "test:tokens-create-config": "pnpm run designsystemet tokens create --config ./configs/test-tokens.config.json",
96
- "test:tokens-build": "pnpm run designsystemet tokens build -t ./temp/options/design-tokens -o ./temp/options/build --clean",
97
- "test:tokens-build-config": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean",
98
- "test:tokens-create-and-build-options": "pnpm test:tokens-create-options && pnpm test:tokens-build",
99
- "test:tokens-create-and-build-config": "pnpm test:tokens-create-config && pnpm test:tokens-build-config",
100
- test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
101
- "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
102
- "update:template": "tsx ./src/scripts/update-template.ts",
103
- "update:theme-digdir": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts",
104
- verify: "pnpm test && pnpm update:template && pnpm update:theme-digdir && pnpm build:tokens"
105
- },
106
- dependencies: {
107
- "@commander-js/extra-typings": "^13.1.0",
108
- "@tokens-studio/sd-transforms": "1.3.0",
109
- "apca-w3": "^0.1.9",
110
- chalk: "^5.4.1",
111
- "change-case": "^5.4.4",
112
- "chroma-js": "^3.1.2",
113
- "colorjs.io": "^0.6.0-alpha.1",
114
- commander: "^13.1.0",
115
- "fast-glob": "^3.3.3",
116
- hsluv: "^1.0.1",
117
- "object-hash": "^3.0.0",
118
- postcss: "^8.5.3",
119
- ramda: "^0.30.1",
120
- "style-dictionary": "^4.4.0",
121
- zod: "^3.25.30",
122
- "zod-validation-error": "^3.4.1"
123
- },
124
- devDependencies: {
125
- "@tokens-studio/types": "0.5.2",
126
- "@types/apca-w3": "^0.1.3",
127
- "@types/chroma-js": "^3.1.1",
128
- "@types/fs-extra": "^11.0.4",
129
- "@types/glob": "^8.1.0",
130
- "@types/jscodeshift": "^0.12.0",
131
- "@types/node": "^22.15.21",
132
- "@types/object-hash": "^3.0.6",
133
- "@types/ramda": "^0.30.2",
134
- "fs-extra": "^11.3.0",
135
- "ts-toolbelt": "^9.6.0",
136
- tslib: "^2.8.1",
137
- tsup: "^8.5.0",
138
- tsx: "^4.19.4",
139
- typescript: "^5.8.3"
140
- }
141
- };
142
-
143
- // src/tokens/process/theme.ts
144
- var defaultFileHeader = `build: v${package_default.version}`;
145
- var createThemeCSSFiles = ({
146
- processedBuilds,
147
- fileHeader: fileHeader2 = defaultFileHeader
148
- }) => {
149
- const groupedByTheme = {};
150
- for (const [_, buildResults] of Object.entries(R.dissoc("types", processedBuilds))) {
151
- for (const buildResult of buildResults) {
152
- const themeName = buildResult.permutation.theme;
153
- const newOutputs = buildResult.formatted;
154
- if (R.isNotEmpty(newOutputs)) {
155
- const currentOutputs = groupedByTheme[themeName] ?? [];
156
- groupedByTheme[themeName] = R.concat(currentOutputs, newOutputs);
157
- }
158
- }
159
- }
160
- const sortOrder = [
161
- "color-scheme/light",
162
- "typography/secondary",
163
- "semantic",
164
- "color-scheme/dark",
165
- "color-scheme/contrast",
166
- "typography/primary",
167
- "color/"
168
- ];
169
- const sortByDefinedOrder = R.sortBy((file) => {
170
- const filePath = file.destination || "";
171
- const sortIndex = sortOrder.findIndex((sortElement) => {
172
- if (sortElement.endsWith("/")) {
173
- return filePath.includes(sortElement);
174
- }
175
- return filePath.includes(`${sortElement}.css`);
176
- });
177
- if (sortIndex === -1) {
178
- console.error(
179
- chalk2.yellow("WARNING: CSS section does not have a defined sort order:", filePath.replace(".css", ""))
180
- );
181
- console.log(
182
- chalk2.dim(
183
- `
184
- The section will currently be added to the end of the entry file, but the exact
185
- order may change due to nondeterminism.`.trim()
186
- )
187
- );
188
- return Infinity;
189
- }
190
- return sortIndex;
191
- });
192
- const header = `@charset "UTF-8";
193
- /*
194
- ${fileHeader2}
195
- */
196
-
197
- `;
198
- const sortAlphabetically = R.sort(R.ascend((x) => x.destination || ""));
199
- const pickOutputs = R.map(R.view(R.lensProp("output")));
200
- const themeCSSFile = R.pipe(
201
- sortAlphabetically,
202
- sortByDefinedOrder,
203
- pickOutputs,
204
- R.join("\n"),
205
- (content) => header + content
206
- );
207
- const themeCSSFiles = Object.entries(groupedByTheme).map(([theme, files]) => ({
208
- destination: `${theme}.css`,
209
- output: themeCSSFile(files)
210
- }));
211
- return themeCSSFiles;
212
- };
46
+ // src/tokens/process/output/declarations.ts
47
+ import chalk4 from "chalk";
213
48
 
214
49
  // src/tokens/process/platform.ts
215
- import chalk4 from "chalk";
216
- import * as R13 from "ramda";
50
+ import chalk3 from "chalk";
51
+ import * as R12 from "ramda";
217
52
  import StyleDictionary2 from "style-dictionary";
218
53
 
219
54
  // src/tokens/types.ts
@@ -224,30 +59,30 @@ var colorCategories = {
224
59
 
225
60
  // src/tokens/process/configs.ts
226
61
  import { register } from "@tokens-studio/sd-transforms";
227
- import * as R12 from "ramda";
62
+ import * as R11 from "ramda";
228
63
  import StyleDictionary from "style-dictionary";
229
64
 
230
65
  // src/tokens/utils.ts
231
- import * as R2 from "ramda";
232
- var mapToLowerCase = R2.map(R2.toLower);
233
- 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));
234
69
  var getType = (token) => (token.$type ?? token.type) || "";
235
70
  var getValue = (token) => token.$value ?? token.value;
236
- var typeEquals = R2.curry(
71
+ var typeEquals = R.curry(
237
72
  (types, token) => {
238
- if (R2.isNil(token)) {
73
+ if (R.isNil(token)) {
239
74
  return false;
240
75
  }
241
- 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]));
242
77
  }
243
78
  );
244
- var pathStartsWithOneOf = R2.curry(
79
+ var pathStartsWithOneOf = R.curry(
245
80
  (paths, token) => {
246
- if (R2.isNil(token)) {
81
+ if (R.isNil(token)) {
247
82
  return false;
248
83
  }
249
84
  const tokenPath = mapToLowerCase(token.path);
250
- const matchPathsStartingWith = R2.map((path2) => R2.startsWith([path2], tokenPath), mapToLowerCase(paths));
85
+ const matchPathsStartingWith = R.map((path2) => R.startsWith([path2], tokenPath), mapToLowerCase(paths));
251
86
  return hasAnyTruth(matchPathsStartingWith);
252
87
  }
253
88
  );
@@ -255,7 +90,7 @@ function isSemanticToken(token) {
255
90
  return token.filePath.includes("semantic/");
256
91
  }
257
92
  function isSemanticColorToken(token, color) {
258
- return token.filePath.includes("semantic/") && R2.startsWith(["color", color], token.path);
93
+ return token.filePath.includes("semantic/") && R.startsWith(["color", color], token.path);
259
94
  }
260
95
  function isGlobalColorToken(token) {
261
96
  return typeEquals("color", token) && pathStartsWithOneOf(["global"], token);
@@ -266,7 +101,7 @@ function isColorCategoryToken(token, category) {
266
101
  (colorCategory2) => isColorCategoryToken(token, colorCategory2)
267
102
  );
268
103
  }
269
- return R2.startsWith(["color", category], token.path);
104
+ return R.startsWith(["color", category], token.path);
270
105
  }
271
106
  var isDigit = (s) => /^\d+$/.test(s);
272
107
  function traverseObj(obj, fn) {
@@ -282,7 +117,7 @@ function traverseObj(obj, fn) {
282
117
  return obj;
283
118
  }
284
119
  function inlineTokens(shouldInline, tokens) {
285
- const [inlineableTokens, otherTokens] = R2.partition(shouldInline, tokens);
120
+ const [inlineableTokens, otherTokens] = R.partition(shouldInline, tokens);
286
121
  return otherTokens.map((token) => {
287
122
  let transformed = getValue(token.original);
288
123
  for (const ref of inlineableTokens) {
@@ -291,16 +126,16 @@ function inlineTokens(shouldInline, tokens) {
291
126
  transformed = transformed.replaceAll(`{${refName}}`, getValue(ref.original));
292
127
  }
293
128
  }
294
- const tokenWithInlinedRefs = R2.set(R2.lensPath(["original", "$value"]), transformed, token);
129
+ const tokenWithInlinedRefs = R.set(R.lensPath(["original", "$value"]), transformed, token);
295
130
  return tokenWithInlinedRefs;
296
131
  });
297
132
  }
298
133
 
299
134
  // src/tokens/process/configs/color.ts
300
- import * as R7 from "ramda";
135
+ import * as R6 from "ramda";
301
136
 
302
137
  // src/tokens/process/formats/css/color.ts
303
- import * as R3 from "ramda";
138
+ import * as R2 from "ramda";
304
139
  import { createPropertyFormatter } from "style-dictionary/utils";
305
140
  var prefersColorScheme = (colorScheme2, content) => `
306
141
  @media (prefers-color-scheme: ${colorScheme2}) {
@@ -309,7 +144,7 @@ var prefersColorScheme = (colorScheme2, content) => `
309
144
  `;
310
145
  var colorScheme = {
311
146
  name: "ds/css-colorscheme",
312
- format: async ({ dictionary, file, options, platform }) => {
147
+ format: async ({ dictionary, options, platform }) => {
313
148
  const { allTokens } = dictionary;
314
149
  const { outputReferences, usesDtcg } = options;
315
150
  const { selector, colorScheme: colorScheme2, layer } = platform;
@@ -324,8 +159,8 @@ var colorScheme = {
324
159
  color-scheme: ${colorScheme_};
325
160
  ` : "";
326
161
  const filteredAllTokens = allTokens.filter(
327
- R3.allPass([
328
- R3.anyPass([
162
+ R2.allPass([
163
+ R2.anyPass([
329
164
  // Include semantic tokens in the output
330
165
  isSemanticToken,
331
166
  // Include global color tokens
@@ -341,7 +176,7 @@ ${formattedTokens}
341
176
  ${colorSchemeProperty}}
342
177
  `;
343
178
  const autoSelectorContent = ["light", "dark"].includes(colorScheme_) ? prefersColorScheme(colorScheme_, content) : "";
344
- const body = R3.isNotNil(layer) ? `@layer ${layer} {
179
+ const body = R2.isNotNil(layer) ? `@layer ${layer} {
345
180
  ${selector} ${content} ${autoSelectorContent}
346
181
  }
347
182
  ` : `${selector} ${content} ${autoSelectorContent}
@@ -351,10 +186,10 @@ ${selector} ${content} ${autoSelectorContent}
351
186
  };
352
187
  var colorCategory = {
353
188
  name: "ds/css-colorcategory",
354
- format: async ({ dictionary, file, options, platform }) => {
189
+ format: async ({ dictionary, options, platform }) => {
355
190
  const { outputReferences, usesDtcg } = options;
356
191
  const { selector, layer } = platform;
357
- const format = R3.compose(
192
+ const format = R2.compose(
358
193
  createPropertyFormatter({
359
194
  outputReferences,
360
195
  dictionary,
@@ -375,7 +210,7 @@ var colorCategory = {
375
210
  ${formattedTokens}
376
211
  }
377
212
  `;
378
- const body = R3.isNotNil(layer) ? `@layer ${layer} {
213
+ const body = R2.isNotNil(layer) ? `@layer ${layer} {
379
214
  ${selector} ${content}
380
215
  }
381
216
  ` : `${selector} ${content}
@@ -385,16 +220,16 @@ ${selector} ${content}
385
220
  };
386
221
 
387
222
  // src/tokens/process/formats/css/semantic.ts
388
- import * as R4 from "ramda";
223
+ import * as R3 from "ramda";
389
224
  import { createPropertyFormatter as createPropertyFormatter2 } from "style-dictionary/utils";
390
225
  var isNumericBorderRadiusToken = (t) => t.path[0] === "border-radius" && isDigit(t.path[1]);
391
226
  var isNumericSizeToken = (t) => pathStartsWithOneOf(["size"], t) && isDigit(t.path[1]);
392
227
  var isSizeToken = (t) => pathStartsWithOneOf(["size"], t);
393
- var isInlineTokens = R4.anyPass([isNumericBorderRadiusToken, isNumericSizeToken, isSizeToken]);
228
+ var isInlineTokens = R3.anyPass([isNumericBorderRadiusToken, isNumericSizeToken, isSizeToken]);
394
229
  var overrideSizingFormula = (format, token) => {
395
230
  const [name, value] = format(token).split(":");
396
231
  const calc = value.replace(`var(--ds-size-mode-font-size)`, "1em").replace(/floor\((.*)\);/, "calc($1)");
397
- const round = `round(down, ${calc}, 0.0625rem)`;
232
+ const round = `round(down, ${calc}, 1px)`;
398
233
  return {
399
234
  name,
400
235
  round,
@@ -402,7 +237,7 @@ var overrideSizingFormula = (format, token) => {
402
237
  };
403
238
  };
404
239
  var formatSizingTokens = (format, tokens) => {
405
- const { round, calc } = R4.reduce(
240
+ const { round, calc } = R3.reduce(
406
241
  (acc, token) => {
407
242
  const { round: round2, calc: calc2, name } = overrideSizingFormula(format, token);
408
243
  return {
@@ -422,7 +257,7 @@ ${round.join("\n")}
422
257
  };
423
258
  var semantic = {
424
259
  name: "ds/css-semantic",
425
- format: async ({ dictionary, file, options, platform }) => {
260
+ format: async ({ dictionary, options, platform }) => {
426
261
  const { outputReferences, usesDtcg } = options;
427
262
  const { selector, layer } = platform;
428
263
  const format = createPropertyFormatter2({
@@ -432,17 +267,17 @@ var semantic = {
432
267
  usesDtcg
433
268
  });
434
269
  const tokens = inlineTokens(isInlineTokens, dictionary.allTokens);
435
- const filteredTokens = R4.reject((token) => token.name.includes("ds-size-mode-font-size"), tokens);
436
- 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(
437
272
  (t) => pathStartsWithOneOf(["_size"], t) && isDigit(t.path[1]),
438
273
  filteredTokens
439
274
  );
440
- const formattedTokens = [R4.map(format, restTokens).join("\n"), formatSizingTokens(format, sizingTokens)];
275
+ const formattedTokens = [R3.map(format, restTokens).join("\n"), formatSizingTokens(format, sizingTokens)];
441
276
  const content = `{
442
277
  ${formattedTokens.join("\n")}
443
278
  }
444
279
  `;
445
- const body = R4.isNotNil(layer) ? `@layer ${layer} {
280
+ const body = R3.isNotNil(layer) ? `@layer ${layer} {
446
281
  ${selector} ${content}
447
282
  }
448
283
  ` : `${selector} ${content}
@@ -452,15 +287,15 @@ ${selector} ${content}
452
287
  };
453
288
 
454
289
  // src/tokens/process/formats/css/typography.ts
455
- import * as R5 from "ramda";
290
+ import * as R4 from "ramda";
456
291
  import { createPropertyFormatter as createPropertyFormatter3 } from "style-dictionary/utils";
457
- var typographyFontFamilyPredicate = R5.allPass([
458
- R5.pathSatisfies(R5.includes("typography"), ["path"]),
459
- 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"])
460
295
  ]);
461
296
  var typography = {
462
297
  name: "ds/css-typography",
463
- format: async ({ dictionary, file, options, platform }) => {
298
+ format: async ({ dictionary, options, platform }) => {
464
299
  const { outputReferences, usesDtcg } = options;
465
300
  const { selector, layer } = platform;
466
301
  const format = createPropertyFormatter3({
@@ -469,12 +304,12 @@ var typography = {
469
304
  format: "css",
470
305
  usesDtcg
471
306
  });
472
- const filteredTokens = R5.reject(typographyFontFamilyPredicate, dictionary.allTokens);
473
- 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);
474
309
  const content = selector ? `${selector} {
475
310
  ${formattedTokens}
476
311
  }` : formattedTokens;
477
- const body = R5.isNotNil(layer) ? `@layer ${layer} {
312
+ const body = R4.isNotNil(layer) ? `@layer ${layer} {
478
313
  ${content}
479
314
  }` : content;
480
315
  return body;
@@ -491,8 +326,8 @@ var formats = {
491
326
 
492
327
  // src/tokens/process/transformers.ts
493
328
  import { checkAndEvaluateMath } from "@tokens-studio/sd-transforms";
494
- import * as R6 from "ramda";
495
- 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);
496
331
  var sizeRem = {
497
332
  name: "ds/size/toRem",
498
333
  type: "value",
@@ -582,7 +417,7 @@ var colorSchemeVariables = ({ "color-scheme": colorScheme2 = "light", theme }) =
582
417
  {
583
418
  destination: `color-scheme/${colorScheme2}.css`,
584
419
  format: formats.colorScheme.name,
585
- filter: (token) => typeEquals("color", token) && !R7.startsWith(["global"], token.path)
420
+ filter: (token) => typeEquals("color", token) && !R6.startsWith(["global"], token.path)
586
421
  }
587
422
  ],
588
423
  options: {
@@ -633,7 +468,7 @@ var colorCategoryVariables = (opts) => ({ "color-scheme": colorScheme2, theme, .
633
468
  };
634
469
 
635
470
  // src/tokens/process/configs/semantic.ts
636
- import * as R8 from "ramda";
471
+ import * as R7 from "ramda";
637
472
  import { outputReferencesFilter } from "style-dictionary/utils";
638
473
  var semanticVariables = ({ theme }) => {
639
474
  const selector = `:root`;
@@ -656,8 +491,8 @@ var semanticVariables = ({ theme }) => {
656
491
  destination: `semantic.css`,
657
492
  format: formats.semantic.name,
658
493
  filter: (token) => {
659
- const isUwantedToken = R8.anyPass([R8.includes("primitives/global")])(token.filePath);
660
- const isPrivateToken = R8.includes("_", token.path);
494
+ const isUwantedToken = R7.anyPass([R7.includes("primitives/global")])(token.filePath);
495
+ const isPrivateToken = R7.includes("_", token.path);
661
496
  const unwantedPaths = pathStartsWithOneOf(["font-size", "line-height", "letter-spacing"], token);
662
497
  const unwantedTypes = typeEquals(["color", "fontWeight", "fontFamily", "typography"], token);
663
498
  const unwantedTokens = !(unwantedPaths || unwantedTypes || isPrivateToken || isUwantedToken);
@@ -678,20 +513,20 @@ var semanticVariables = ({ theme }) => {
678
513
  };
679
514
 
680
515
  // src/tokens/process/configs/storefront.ts
681
- import * as R10 from "ramda";
516
+ import * as R9 from "ramda";
682
517
  import { outputReferencesFilter as outputReferencesFilter2 } from "style-dictionary/utils";
683
518
 
684
519
  // src/tokens/process/formats/js-tokens.ts
685
- import * as R9 from "ramda";
520
+ import * as R8 from "ramda";
686
521
  import { createPropertyFormatter as createPropertyFormatter4, fileHeader } from "style-dictionary/utils";
687
- var groupByType = R9.groupBy((token) => getType(token));
688
- var removeUnwatedTokens = R9.pipe(
689
- R9.reject((token) => isColorCategoryToken(token)),
690
- 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))
691
526
  );
692
- var dissocExtensions = R9.pipe(R9.dissoc("$extensions"), R9.dissocPath(["original", "$extensions"]));
693
- var removeUnwatedProps = R9.map((token) => dissocExtensions(token));
694
- 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);
695
530
  var jsTokens = {
696
531
  name: "ds/js-tokens",
697
532
  format: async ({ dictionary, file, options }) => {
@@ -702,7 +537,7 @@ var jsTokens = {
702
537
  format: "css",
703
538
  usesDtcg
704
539
  });
705
- const formatTokens = R9.map((token) => {
540
+ const formatTokens = R8.map((token) => {
706
541
  if (pathStartsWithOneOf(["size", "_size"], token)) {
707
542
  const { calc, name } = overrideSizingFormula(format, token);
708
543
  return {
@@ -716,7 +551,7 @@ var jsTokens = {
716
551
  name: toCssVarName(format(token))
717
552
  };
718
553
  });
719
- const processTokens = R9.pipe(removeUnwatedTokens, removeUnwatedProps, formatTokens, groupByType);
554
+ const processTokens = R8.pipe(removeUnwatedTokens, removeUnwatedProps, formatTokens, groupByType);
720
555
  const tokens = processTokens(inlineTokens(isInlineTokens, dictionary.allTokens));
721
556
  const content = Object.entries(tokens).map(
722
557
  ([name, token]) => `export const ${name} = ${JSON.stringify(token, null, 2).replace(/"([^"]+)":/g, "$1:")}
@@ -741,9 +576,9 @@ var typescriptTokens = ({ "color-scheme": colorScheme2, theme }) => {
741
576
  destination: `${colorScheme2}.ts`,
742
577
  format: jsTokens.name,
743
578
  filter: (token) => {
744
- 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))
745
580
  return false;
746
- const isSemanticColor = R10.includes("semantic", token.filePath) && typeEquals(["color"], token);
581
+ const isSemanticColor = R9.includes("semantic", token.filePath) && typeEquals(["color"], token);
747
582
  const wantedTypes = typeEquals(["shadow", "dimension", "typography", "opacity"], token);
748
583
  return isSemanticColor || wantedTypes;
749
584
  }
@@ -972,19 +807,19 @@ var TypographyValues;
972
807
  })(TypographyValues || (TypographyValues = {}));
973
808
 
974
809
  // src/tokens/process/utils/getMultidimensionalThemes.ts
975
- import chalk3 from "chalk";
810
+ import chalk2 from "chalk";
976
811
  import { kebabCase } from "change-case";
977
- import * as R11 from "ramda";
812
+ import * as R10 from "ramda";
978
813
  var getMultidimensionalThemes = (processed$themes, dimensions) => {
979
814
  const verboseLogging = buildOptions?.verbose;
980
815
  const grouped$themes = groupThemes(processed$themes);
981
816
  const permutations = permutateThemes(grouped$themes);
982
817
  const ALL_DEPENDENT_ON = ["theme"];
983
- const keys2 = R11.keys(grouped$themes);
818
+ const keys2 = R10.keys(grouped$themes);
984
819
  const nonDependentKeys = keys2.filter((x) => ![...ALL_DEPENDENT_ON, ...dimensions].includes(x));
985
820
  if (verboseLogging) {
986
- console.log(chalk3.cyan(`\u{1F50E} Finding theme permutations for ${dimensions}`));
987
- 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})`));
988
823
  }
989
824
  return permutations.filter((val) => {
990
825
  const filters = nonDependentKeys.map((x) => val.permutation[x] === grouped$themes[x][0].name);
@@ -1020,7 +855,7 @@ function groupThemes(themes) {
1020
855
  }
1021
856
  return groups;
1022
857
  }
1023
- 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);
1024
859
  function permutateThemes(groups) {
1025
860
  const separator = "_";
1026
861
  const permutations = cartesian(Object.values(groups));
@@ -1030,8 +865,8 @@ function permutateThemes(groups) {
1030
865
  const { group, name, selectedTokenSets } = theme;
1031
866
  let updatedPermutation = acc.permutation;
1032
867
  if (group) {
1033
- const groupProp = R11.lensProp(group);
1034
- updatedPermutation = R11.set(groupProp, name, updatedPermutation);
868
+ const groupProp = R10.lensProp(group);
869
+ updatedPermutation = R10.set(groupProp, name, updatedPermutation);
1035
870
  }
1036
871
  const updatedName = `${String(acc.name)}${acc ? separator : ""}${name}`;
1037
872
  const sets = [...acc.selectedTokenSets, ...filterTokenSets(selectedTokenSets)];
@@ -1077,6 +912,12 @@ function filterTokenSets(tokensets) {
1077
912
  function cartesian(a) {
1078
913
  return a.reduce((a2, b) => a2.flatMap((d) => b.map((e) => [d, e].flat())));
1079
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);
1080
921
 
1081
922
  // src/tokens/process/configs.ts
1082
923
  void register(StyleDictionary, { withSDBuiltins: false });
@@ -1115,7 +956,7 @@ var getConfigsForThemeDimensions = (getConfig, processed$themes, dimensions, opt
1115
956
  obj.filePath = tokenSet;
1116
957
  }
1117
958
  });
1118
- tokenSource.tokens = R12.mergeDeepRight(tokenSource.tokens, tokensWithFilePath);
959
+ tokenSource.tokens = R11.mergeDeepRight(tokenSource.tokens, tokensWithFilePath);
1119
960
  }
1120
961
  }
1121
962
  } else {
@@ -1159,12 +1000,6 @@ var initResult = {
1159
1000
  };
1160
1001
  var buildOptions;
1161
1002
  var sd = new StyleDictionary2();
1162
- var getCustomColors = (processed$themes, colorGroups) => processed$themes.filter((x) => {
1163
- if (!x.group) {
1164
- return false;
1165
- }
1166
- return colorGroups.includes(x.group);
1167
- }).map((x) => x.name);
1168
1003
  var buildConfigs = {
1169
1004
  typography: { getConfig: configs.typographyVariables, dimensions: ["typography"] },
1170
1005
  "color-scheme": { getConfig: configs.colorSchemeVariables, dimensions: ["color-scheme"] },
@@ -1205,46 +1040,54 @@ var buildConfigs = {
1205
1040
  // },
1206
1041
  };
1207
1042
  async function processPlatform(options) {
1208
- const { type, $themes } = options;
1043
+ const { type, processed$themes } = options;
1209
1044
  const platform = "css";
1210
1045
  const tokenSets = type === "format" ? options.tokenSets : void 0;
1211
1046
  const tokensDir = type === "build" ? options.tokensDir : void 0;
1212
1047
  const UNSAFE_DEFAULT_COLOR = process.env.UNSAFE_DEFAULT_COLOR ?? "";
1213
1048
  if (UNSAFE_DEFAULT_COLOR) {
1214
1049
  console.warn(
1215
- chalk4.yellow(
1050
+ chalk3.yellow(
1216
1051
  `
1217
- \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.`
1218
1053
  )
1219
1054
  );
1220
1055
  }
1221
1056
  const UNSAFE_COLOR_GROUPS = Array.from(process.env.UNSAFE_COLOR_GROUPS?.split(",") ?? []);
1222
1057
  if (UNSAFE_COLOR_GROUPS.length > 0) {
1223
1058
  console.warn(
1224
- chalk4.yellow(
1059
+ chalk3.yellow(
1225
1060
  `
1226
- \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.`
1227
1062
  )
1228
1063
  );
1229
1064
  }
1230
1065
  const colorGroups = UNSAFE_COLOR_GROUPS.length > 0 ? UNSAFE_COLOR_GROUPS : [colorCategories.main, colorCategories.support].map((c) => `${c}-color`);
1231
1066
  buildOptions = options;
1232
1067
  buildOptions.defaultColor = UNSAFE_DEFAULT_COLOR;
1233
- const processed$themes = $themes.map(processThemeObject).filter((theme) => R13.not(theme.group === "size" && theme.name !== "medium"));
1234
- 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);
1235
1073
  if (!buildOptions.defaultColor) {
1236
- const firstMainColor = R13.head(customColors);
1074
+ const firstMainColor = R12.head(customColors);
1237
1075
  buildOptions.defaultColor = firstMainColor;
1238
1076
  }
1239
1077
  if (buildOptions.defaultColor) {
1240
1078
  console.log(`
1241
- \u{1F3A8} Using ${chalk4.blue(buildOptions.defaultColor)} as default color`);
1079
+ \u{1F3A8} Using ${chalk3.blue(buildOptions.defaultColor)} as default color`);
1242
1080
  }
1243
- const buildAndSdConfigs = R13.map((buildConfig) => {
1244
- const sdConfigs = getConfigsForThemeDimensions(buildConfig.getConfig, processed$themes, buildConfig.dimensions, {
1245
- tokensDir,
1246
- tokenSets
1247
- });
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
+ );
1248
1091
  const unknownConfigs = buildConfig.dimensions.map(
1249
1092
  (dimension) => sdConfigs.filter((x) => x.permutation[dimension] === "unknown")
1250
1093
  );
@@ -1268,23 +1111,22 @@ async function processPlatform(options) {
1268
1111
  "warning-color": [initResult],
1269
1112
  "info-color": [initResult],
1270
1113
  semantic: [initResult],
1271
- typography: [initResult],
1272
- types: [initResult]
1114
+ typography: [initResult]
1273
1115
  };
1274
1116
  try {
1275
- for (const [buildName, { buildConfig, sdConfigs }] of R13.toPairs(buildAndSdConfigs)) {
1117
+ for (const [buildName, { buildConfig, sdConfigs }] of R12.toPairs(buildAndSdConfigs)) {
1276
1118
  if (!(buildConfig.enabled?.() ?? true)) {
1277
1119
  continue;
1278
1120
  }
1279
1121
  if (sdConfigs.length > 0) {
1280
1122
  console.log(`
1281
- \u{1F371} Building ${chalk4.green(buildConfig.name ?? buildName)}`);
1123
+ \u{1F371} Building ${chalk3.green(buildConfig.name ?? buildName)}`);
1282
1124
  const results = await Promise.all(
1283
1125
  sdConfigs.map(async (sdConfig) => {
1284
1126
  const { config, permutation } = sdConfig;
1285
1127
  const modes = ["theme", ...buildConfig.dimensions];
1286
1128
  const modeMessage = modes.map((x) => permutation[x]).join(" - ");
1287
- const logMessage = R13.isNil(buildConfig.log) ? modeMessage : buildConfig?.log(sdConfig);
1129
+ const logMessage = R12.isNil(buildConfig.log) ? modeMessage : buildConfig?.log(sdConfig);
1288
1130
  console.log(logMessage);
1289
1131
  const sdOptions = { cache: true };
1290
1132
  const sdExtended = await sd.extend(config);
@@ -1304,17 +1146,22 @@ async function processPlatform(options) {
1304
1146
  }
1305
1147
  throw err;
1306
1148
  }
1307
- const colorsFileName = "colors.d.ts";
1308
- const reactColorTypes = await createColorTypeDeclaration(customColors);
1309
- 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 [
1310
1158
  {
1311
- ...initResult,
1312
- formatted: [{ output: reactColorTypes, destination: colorsFileName }]
1159
+ output: typeDeclaration,
1160
+ destination: "colors.d.ts"
1313
1161
  }
1314
1162
  ];
1315
- return processedBuilds;
1316
- }
1317
- async function createColorTypeDeclaration(colors) {
1163
+ };
1164
+ function createColorTypeDeclaration(colors) {
1318
1165
  console.log(`
1319
1166
  \u{1F371} Building ${chalk4.green("type declarations")}`);
1320
1167
  const typeDeclaration = `
@@ -1329,6 +1176,232 @@ ${colors.map((color) => ` ${color}: never;`).join("\n")}
1329
1176
  return typeDeclaration;
1330
1177
  }
1331
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
+
1332
1405
  // src/tokens/build.ts
1333
1406
  async function write(files, outDir, dry) {
1334
1407
  for (const { destination, output } of files) {
@@ -1345,32 +1418,38 @@ var buildTokens = async (options) => {
1345
1418
  const outDir = path.resolve(options.outDir);
1346
1419
  const tokensDir = path.resolve(options.tokensDir);
1347
1420
  const $themes = JSON.parse(await readFile(`${tokensDir}/$themes.json`));
1421
+ const processed$themes = $themes.map(processThemeObject);
1348
1422
  let $designsystemet;
1349
1423
  try {
1350
1424
  const $designsystemetContent = await readFile(`${tokensDir}/$designsystemet.json`);
1351
1425
  $designsystemet = JSON.parse($designsystemetContent);
1352
- } catch (error) {
1426
+ } catch (_error) {
1353
1427
  }
1354
1428
  console.log(`
1355
- \u{1F3D7}\uFE0F Start building tokens in ${chalk5.green(tokensDir)}`);
1429
+ \u{1F3D7}\uFE0F Start building tokens in ${chalk6.green(tokensDir)}`);
1356
1430
  const processedBuilds = await processPlatform({
1357
1431
  ...options,
1358
1432
  outDir,
1359
1433
  tokensDir,
1360
1434
  type: "build",
1361
- $themes
1435
+ processed$themes
1362
1436
  });
1363
- console.log(`
1364
- \u{1F4BE} Writing build to ${chalk5.green(outDir)}`);
1365
- for (const { formatted } of processedBuilds.types) {
1366
- await write(formatted, outDir, options.dry);
1367
- }
1368
1437
  const fileHeader2 = R14.join("")([
1369
1438
  defaultFileHeader,
1370
1439
  $designsystemet ? `
1371
1440
  design-tokens: v${$designsystemet.version}` : ""
1372
1441
  ]);
1373
- await write(createThemeCSSFiles({ processedBuilds, fileHeader: fileHeader2 }), outDir, options.dry);
1442
+ let files = [];
1443
+ const declarationFiles = createTypeDeclarationFiles(processed$themes);
1444
+ const cssFiles = createThemeCSSFiles({ processedBuilds, fileHeader: fileHeader2 });
1445
+ files = [...declarationFiles, ...cssFiles];
1446
+ if (options.tailwind) {
1447
+ const tailwindFiles = createTailwindCSSFiles(cssFiles);
1448
+ files = files.concat(tailwindFiles.filter(Boolean));
1449
+ }
1450
+ console.log(`
1451
+ \u{1F4BE} Writing build to ${chalk6.green(outDir)}`);
1452
+ await write(files, outDir, options.dry);
1374
1453
  console.log(`
1375
1454
  \u2705 Finished building tokens!`);
1376
1455
  return processedBuilds;