@digdir/designsystemet 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/configs/test-tokens.config.json +15 -1
  2. package/dist/bin/config.js +14 -3
  3. package/dist/bin/designsystemet.js +105 -43
  4. package/dist/config.schema.json +52 -0
  5. package/dist/src/colors/colorMetadata.d.ts +1 -0
  6. package/dist/src/colors/colorMetadata.d.ts.map +1 -1
  7. package/dist/src/colors/colorMetadata.js +2 -0
  8. package/dist/src/colors/index.js +2 -0
  9. package/dist/src/colors/theme.js +1 -0
  10. package/dist/src/config.d.ts +70 -0
  11. package/dist/src/config.d.ts.map +1 -1
  12. package/dist/src/config.js +12 -1
  13. package/dist/src/index.js +90 -37
  14. package/dist/src/scripts/createJsonSchema.js +12 -1
  15. package/dist/src/scripts/update-preview-tokens.js +80 -28
  16. package/dist/src/tokens/build.js +45 -27
  17. package/dist/src/tokens/create/generators/$designsystemet.js +9 -9
  18. package/dist/src/tokens/create/generators/color.d.ts +2 -1
  19. package/dist/src/tokens/create/generators/color.d.ts.map +1 -1
  20. package/dist/src/tokens/create/generators/color.js +40 -6
  21. package/dist/src/tokens/create/write.js +9 -9
  22. package/dist/src/tokens/create.js +44 -10
  23. package/dist/src/tokens/format.js +89 -37
  24. package/dist/src/tokens/index.js +89 -37
  25. package/dist/src/tokens/process/configs/color.js +31 -13
  26. package/dist/src/tokens/process/configs/semantic.js +31 -13
  27. package/dist/src/tokens/process/configs/size-mode.js +31 -13
  28. package/dist/src/tokens/process/configs/size.js +31 -13
  29. package/dist/src/tokens/process/configs/type-scale.js +31 -13
  30. package/dist/src/tokens/process/configs/typography.js +31 -13
  31. package/dist/src/tokens/process/configs.js +36 -18
  32. package/dist/src/tokens/process/formats/css/color.js +31 -13
  33. package/dist/src/tokens/process/formats/css/semantic.js +31 -13
  34. package/dist/src/tokens/process/formats/css/size-mode.js +31 -13
  35. package/dist/src/tokens/process/formats/css/size.d.ts +4 -0
  36. package/dist/src/tokens/process/formats/css/size.d.ts.map +1 -1
  37. package/dist/src/tokens/process/formats/css/size.js +33 -14
  38. package/dist/src/tokens/process/formats/css/type-scale.d.ts.map +1 -1
  39. package/dist/src/tokens/process/formats/css/type-scale.js +31 -13
  40. package/dist/src/tokens/process/formats/css/typography.js +33 -15
  41. package/dist/src/tokens/process/formats/css.js +31 -13
  42. package/dist/src/tokens/process/output/declarations.js +40 -22
  43. package/dist/src/tokens/process/output/theme.js +9 -9
  44. package/dist/src/tokens/process/platform.js +36 -18
  45. package/dist/src/tokens/process/utils/getMultidimensionalThemes.js +31 -13
  46. package/dist/src/tokens/types.d.ts +1 -1
  47. package/dist/src/tokens/types.d.ts.map +1 -1
  48. package/package.json +9 -9
package/dist/src/index.js CHANGED
@@ -253,6 +253,7 @@ var colorMetadataByNumber = R.indexBy((metadata) => metadata.number, Object.valu
253
253
  var getColorMetadataByNumber = (number) => {
254
254
  return colorMetadataByNumber[number];
255
255
  };
256
+ var colorNames = Object.keys(colorMetadata);
256
257
 
257
258
  // src/colors/theme.ts
258
259
  import chroma2 from "chroma-js";
@@ -1471,18 +1472,51 @@ var getDefaultToken = (tokenPath) => {
1471
1472
 
1472
1473
  // src/tokens/create/generators/color.ts
1473
1474
  import * as R4 from "ramda";
1474
- var generateColor = (colorArray) => {
1475
+ var generateColor = (colorArray, overrides) => {
1475
1476
  const obj = {};
1476
1477
  const $type = "color";
1477
1478
  for (const index in colorArray) {
1478
- obj[Number(index) + 1] = { $type, $value: colorArray[index].hex };
1479
+ const position = Number(index) + 1;
1480
+ const overrideValue = overrides?.[position];
1481
+ obj[position] = {
1482
+ $type,
1483
+ $value: overrideValue || colorArray[index].hex
1484
+ };
1479
1485
  }
1480
1486
  return obj;
1481
1487
  };
1482
- var generateColorScheme = (themeName, colorScheme2, colors) => {
1483
- const main = R4.map((color) => generateColor(generateColorScale(color, colorScheme2)), colors.main);
1484
- const support = R4.map((color) => generateColor(generateColorScale(color, colorScheme2)), colors.support);
1485
- const neutral = generateColor(generateColorScale(colors.neutral, colorScheme2));
1488
+ var generateColorScheme = (themeName, colorScheme2, colors, overrides) => {
1489
+ const createColorOverrides = (colorName) => {
1490
+ if (!overrides?.colors || !(colorName in overrides.colors)) {
1491
+ return void 0;
1492
+ }
1493
+ const colorOverrides = overrides.colors[colorName];
1494
+ const positionOverrides = {};
1495
+ Object.entries(colorOverrides).forEach(([semanticTokenName, modeOverrides]) => {
1496
+ const position = colorMetadata[semanticTokenName].number;
1497
+ if (position) {
1498
+ let overrideValue;
1499
+ if (colorScheme2 === "light" && modeOverrides.light) {
1500
+ overrideValue = modeOverrides.light;
1501
+ } else if (colorScheme2 === "dark" && modeOverrides.dark) {
1502
+ overrideValue = modeOverrides.dark;
1503
+ }
1504
+ if (overrideValue) {
1505
+ positionOverrides[position] = overrideValue;
1506
+ }
1507
+ }
1508
+ });
1509
+ return Object.keys(positionOverrides).length > 0 ? positionOverrides : void 0;
1510
+ };
1511
+ const main = R4.mapObjIndexed(
1512
+ (color, colorName) => generateColor(generateColorScale(color, colorScheme2), createColorOverrides(colorName)),
1513
+ colors.main
1514
+ );
1515
+ const support = R4.mapObjIndexed(
1516
+ (color, colorName) => generateColor(generateColorScale(color, colorScheme2), createColorOverrides(colorName)),
1517
+ colors.support
1518
+ );
1519
+ const neutral = generateColor(generateColorScale(colors.neutral, colorScheme2), createColorOverrides("neutral"));
1486
1520
  return {
1487
1521
  [themeName]: {
1488
1522
  ...main,
@@ -1947,8 +1981,8 @@ var generateSemantic = (colors) => {
1947
1981
  ["main-color", mainColorNames],
1948
1982
  ["support-color", supportColorNames]
1949
1983
  ];
1950
- for (const [colorCategory2, colorNames] of categories) {
1951
- for (const colorName of colorNames) {
1984
+ for (const [colorCategory2, colorNames2] of categories) {
1985
+ for (const colorName of colorNames2) {
1952
1986
  const category = colorCategory2.replace("-color", "");
1953
1987
  const customColorTokens = {
1954
1988
  color: {
@@ -2204,7 +2238,7 @@ var cliOptions = {
2204
2238
  }
2205
2239
  };
2206
2240
  var createTokens = async (opts) => {
2207
- const { colors, typography: typography2, name, borderRadius } = opts;
2241
+ const { colors, typography: typography2, name, borderRadius, overrides } = opts;
2208
2242
  const colorSchemes = ["light", "dark"];
2209
2243
  const semantic2 = generateSemantic(colors);
2210
2244
  const tokenSets = new Map([
@@ -2222,7 +2256,7 @@ var createTokens = async (opts) => {
2222
2256
  [`primitives/modes/typography/secondary/${name}`, generateTypography(name, typography2)],
2223
2257
  ...colorSchemes.flatMap((scheme) => [
2224
2258
  [`primitives/modes/color-scheme/${scheme}/global`, generateColorGlobal(scheme)],
2225
- [`primitives/modes/color-scheme/${scheme}/${name}`, generateColorScheme(name, scheme, colors)]
2259
+ [`primitives/modes/color-scheme/${scheme}/${name}`, generateColorScheme(name, scheme, colors, overrides)]
2226
2260
  ]),
2227
2261
  [`themes/${name}`, generateTheme(colors, name, borderRadius)],
2228
2262
  ["semantic/color", semantic2.color],
@@ -2576,11 +2610,11 @@ import * as R8 from "ramda";
2576
2610
  // package.json
2577
2611
  var package_default = {
2578
2612
  name: "@digdir/designsystemet",
2579
- version: "1.5.0",
2613
+ version: "1.6.0",
2580
2614
  description: "CLI for Designsystemet",
2581
2615
  author: "Designsystemet team",
2582
2616
  engines: {
2583
- node: ">=22.19.0"
2617
+ node: ">=20 <25"
2584
2618
  },
2585
2619
  repository: {
2586
2620
  type: "git",
@@ -2628,7 +2662,7 @@ var package_default = {
2628
2662
  "test:tokens-build-config-tailwind": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean --experimental-tailwind",
2629
2663
  "test:tokens-create-and-build-options": "pnpm test:tokens-create-options && pnpm test:tokens-build",
2630
2664
  "test:tokens-create-and-build-config": "pnpm test:tokens-create-config && pnpm test:tokens-build-config",
2631
- test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
2665
+ test: "node -v && pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
2632
2666
  "digdir:tokens-build": "pnpm run designsystemet tokens build -t ../../internal/design-tokens -o ../../packages/theme/brand --clean --experimental-tailwind",
2633
2667
  "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
2634
2668
  "update:template": "tsx ./src/scripts/update-template.ts",
@@ -2643,7 +2677,7 @@ var package_default = {
2643
2677
  "change-case": "^5.4.4",
2644
2678
  "chroma-js": "^3.1.2",
2645
2679
  "colorjs.io": "^0.6.0-alpha.1",
2646
- commander: "^14.0.0",
2680
+ commander: "^14.0.1",
2647
2681
  "fast-glob": "^3.3.3",
2648
2682
  hsluv: "^1.0.1",
2649
2683
  "object-hash": "^3.0.0",
@@ -2651,18 +2685,18 @@ var package_default = {
2651
2685
  postcss: "^8.5.6",
2652
2686
  ramda: "^0.31.3",
2653
2687
  "style-dictionary": "^5.0.4",
2654
- zod: "^4.1.5",
2655
- "zod-validation-error": "^4.0.1"
2688
+ zod: "^4.1.11",
2689
+ "zod-validation-error": "^4.0.2"
2656
2690
  },
2657
2691
  devDependencies: {
2658
2692
  "@tokens-studio/types": "0.5.2",
2659
2693
  "@types/apca-w3": "^0.1.3",
2660
2694
  "@types/chroma-js": "^3.1.1",
2661
2695
  "@types/fs-extra": "^11.0.4",
2662
- "@types/node": "^22.18.1",
2696
+ "@types/node": "^22.18.6",
2663
2697
  "@types/object-hash": "^3.0.6",
2664
- "@types/ramda": "^0.31.0",
2665
- "fs-extra": "^11.3.1",
2698
+ "@types/ramda": "^0.31.1",
2699
+ "fs-extra": "^11.3.2",
2666
2700
  tslib: "^2.8.1",
2667
2701
  tsup: "^8.5.0",
2668
2702
  tsx: "^4.20.5",
@@ -2725,11 +2759,11 @@ function isColorCategoryToken(token, category) {
2725
2759
  var isDigit = (s) => /^\d+$/.test(s);
2726
2760
  function traverseObj(obj, fn) {
2727
2761
  for (const key in obj) {
2728
- const prop4 = obj[key];
2729
- if (prop4 != null) {
2730
- fn.apply(null, [obj, key, prop4]);
2731
- if (typeof prop4 === "object") {
2732
- traverseObj(prop4, fn);
2762
+ const prop3 = obj[key];
2763
+ if (prop3 != null) {
2764
+ fn.apply(null, [obj, key, prop3]);
2765
+ if (typeof prop3 === "object") {
2766
+ traverseObj(prop3, fn);
2733
2767
  }
2734
2768
  }
2735
2769
  }
@@ -3260,13 +3294,33 @@ ${content}
3260
3294
  // src/tokens/process/formats/css/type-scale.ts
3261
3295
  import * as R15 from "ramda";
3262
3296
  import { createPropertyFormatter as createPropertyFormatter6 } from "style-dictionary/utils";
3263
- var typographyFontFamilyPredicate2 = R15.allPass([
3297
+ var isTypographyFontFamilyToken = R15.allPass([
3264
3298
  R15.pathSatisfies(R15.includes("typography"), ["path"]),
3265
3299
  R15.pathSatisfies(R15.includes("fontFamily"), ["path"])
3266
3300
  ]);
3267
- function formatTypographySizeToken(token) {
3268
- return { ...token, $value: `calc(${token.$value} * var(--_ds-font-size-factor))` };
3269
- }
3301
+ var formatTypographySizeToken = (format, token) => {
3302
+ const [name, value] = format(token).replace(/;$/, "").split(": ");
3303
+ let calc;
3304
+ let round;
3305
+ if (R15.startsWith(["font-size"], token.path)) {
3306
+ calc = `calc(${value} * var(--_ds-font-size-factor))`;
3307
+ round = `round(${calc}, 1px)`;
3308
+ } else {
3309
+ calc = value;
3310
+ }
3311
+ return { name, calc, round: round ?? calc };
3312
+ };
3313
+ var formatTypographySizeTokens = (format, tokens) => R15.reduce(
3314
+ (acc, token) => {
3315
+ const { name, calc, round } = formatTypographySizeToken(format, token);
3316
+ acc.tokens.push(token);
3317
+ acc.calc.push(`${name}: ${calc};`);
3318
+ acc.round.push(`${name}: ${round};`);
3319
+ return acc;
3320
+ },
3321
+ { tokens: [], calc: [], round: [] },
3322
+ tokens
3323
+ );
3270
3324
  var typeScale = {
3271
3325
  name: "ds/css-type-scale",
3272
3326
  format: async ({ dictionary, file, options, platform }) => {
@@ -3279,18 +3333,16 @@ var typeScale = {
3279
3333
  format: "css",
3280
3334
  usesDtcg
3281
3335
  });
3282
- const filteredTokens = R15.reject(typographyFontFamilyPredicate2, dictionary.allTokens);
3283
- const tokens = R15.map(formatTypographySizeToken, filteredTokens);
3284
- const formattedMap = tokens.map((token) => ({
3285
- token,
3286
- formatted: format(token)
3336
+ const filteredTokens = R15.reject(R15.anyPass([isTypographyFontFamilyToken]), dictionary.allTokens);
3337
+ const formattedTokens = formatTypographySizeTokens(format, filteredTokens);
3338
+ const formattedMap = formattedTokens.round.map((t, i) => ({
3339
+ token: formattedTokens.tokens[i],
3340
+ formatted: t
3287
3341
  }));
3288
3342
  buildOptions.buildTokenFormats[destination] = formattedMap;
3289
- const formattedTokens = formattedMap.map(R15.prop("formatted")).join("\n");
3290
3343
  const sizeFactor = ` --_ds-font-size-factor: calc(var(--ds-size-mode-font-size) / (var(--ds-size-base) / ${basePxFontSize}));`;
3291
3344
  const content = `${selector} {
3292
- ${sizeFactor}
3293
- ${formattedTokens}
3345
+ ${sizeFactor}${sizingTemplate(formattedTokens)}
3294
3346
  }`;
3295
3347
  const body = R15.isNotNil(layer) ? `@layer ${layer} {
3296
3348
  ${content}
@@ -3503,7 +3555,7 @@ var sizeModeVariables = ({ theme, size: size2 }) => {
3503
3555
  };
3504
3556
 
3505
3557
  // src/tokens/process/configs/type-scale.ts
3506
- var typeScaleVariables = ({ theme, size: size2 }) => {
3558
+ var typeScaleVariables = ({ theme }) => {
3507
3559
  const selector = ":root, [data-size]";
3508
3560
  const layer = `ds.theme.type-scale`;
3509
3561
  return {
@@ -3977,6 +4029,7 @@ export {
3977
4029
  canTextBeUsedOnColors,
3978
4030
  cliOptions,
3979
4031
  colorMetadata,
4032
+ colorNames,
3980
4033
  convertColor,
3981
4034
  convertToHex,
3982
4035
  createTokens,
@@ -254,6 +254,7 @@ var colorMetadata = {
254
254
  }
255
255
  };
256
256
  var colorMetadataByNumber = R.indexBy((metadata) => metadata.number, Object.values(colorMetadata));
257
+ var colorNames = Object.keys(colorMetadata);
257
258
 
258
259
  // src/colors/theme.ts
259
260
  import chroma2 from "chroma-js";
@@ -323,6 +324,15 @@ var colorCategorySchema = z.record(
323
324
  ).refine((colors) => !Object.keys(colors).some((key) => RESERVED_COLORS.includes(key.toLowerCase())), {
324
325
  error: `Color names cannot include reserved names: ${RESERVED_COLORS.join(", ")}`
325
326
  }).describe("An object with one or more color definitions. The property name is used as the color name.");
327
+ var colorModeOverrideSchema = z.object({
328
+ light: colorSchema.optional(),
329
+ dark: colorSchema.optional()
330
+ }).describe('Override values for semantic color tokens like "background-subtle", "border-default", etc.');
331
+ var colorWeightOverrideSchema = z.partialRecord(z.enum(colorNames), colorModeOverrideSchema).describe('The name of the color to add overrides for, e.g. "accent"');
332
+ var semanticColorOverrideSchema = z.record(z.string(), colorWeightOverrideSchema).describe("An object with color names as keys");
333
+ var overridesSchema = z.object({
334
+ colors: semanticColorOverrideSchema.optional()
335
+ }).describe("Overrides for generated design tokens. Currently only supports colors defined in your theme").optional();
326
336
  var themeSchema = z.object({
327
337
  colors: z.object({
328
338
  main: colorCategorySchema,
@@ -332,7 +342,8 @@ var themeSchema = z.object({
332
342
  typography: z.object({
333
343
  fontFamily: z.string().meta({ description: "Sets the font-family for this theme" })
334
344
  }).describe("Defines the typography for a given theme").optional(),
335
- borderRadius: z.number().meta({ description: "Defines the border-radius for this theme" }).optional()
345
+ borderRadius: z.number().meta({ description: "Defines the border-radius for this theme" }).optional(),
346
+ overrides: overridesSchema
336
347
  }).meta({ description: "An object defining a theme. The property name holding the object becomes the theme name." });
337
348
  var commonConfig = z.object({
338
349
  clean: z.boolean().meta({ description: "Delete the output directory before building or creating tokens" }).optional()
@@ -1648,6 +1648,7 @@ var colorMetadata = {
1648
1648
  }
1649
1649
  };
1650
1650
  var colorMetadataByNumber = R2.indexBy((metadata) => metadata.number, Object.values(colorMetadata));
1651
+ var colorNames = Object.keys(colorMetadata);
1651
1652
 
1652
1653
  // src/colors/theme.ts
1653
1654
  import chroma2 from "chroma-js";
@@ -1728,18 +1729,51 @@ var generateColorContrast = (color, type) => {
1728
1729
  };
1729
1730
 
1730
1731
  // src/tokens/create/generators/color.ts
1731
- var generateColor = (colorArray) => {
1732
+ var generateColor = (colorArray, overrides) => {
1732
1733
  const obj = {};
1733
1734
  const $type = "color";
1734
1735
  for (const index in colorArray) {
1735
- obj[Number(index) + 1] = { $type, $value: colorArray[index].hex };
1736
+ const position = Number(index) + 1;
1737
+ const overrideValue = overrides?.[position];
1738
+ obj[position] = {
1739
+ $type,
1740
+ $value: overrideValue || colorArray[index].hex
1741
+ };
1736
1742
  }
1737
1743
  return obj;
1738
1744
  };
1739
- var generateColorScheme = (themeName, colorScheme2, colors) => {
1740
- const main = R4.map((color) => generateColor(generateColorScale(color, colorScheme2)), colors.main);
1741
- const support = R4.map((color) => generateColor(generateColorScale(color, colorScheme2)), colors.support);
1742
- const neutral = generateColor(generateColorScale(colors.neutral, colorScheme2));
1745
+ var generateColorScheme = (themeName, colorScheme2, colors, overrides) => {
1746
+ const createColorOverrides = (colorName) => {
1747
+ if (!overrides?.colors || !(colorName in overrides.colors)) {
1748
+ return void 0;
1749
+ }
1750
+ const colorOverrides = overrides.colors[colorName];
1751
+ const positionOverrides = {};
1752
+ Object.entries(colorOverrides).forEach(([semanticTokenName, modeOverrides]) => {
1753
+ const position = colorMetadata[semanticTokenName].number;
1754
+ if (position) {
1755
+ let overrideValue;
1756
+ if (colorScheme2 === "light" && modeOverrides.light) {
1757
+ overrideValue = modeOverrides.light;
1758
+ } else if (colorScheme2 === "dark" && modeOverrides.dark) {
1759
+ overrideValue = modeOverrides.dark;
1760
+ }
1761
+ if (overrideValue) {
1762
+ positionOverrides[position] = overrideValue;
1763
+ }
1764
+ }
1765
+ });
1766
+ return Object.keys(positionOverrides).length > 0 ? positionOverrides : void 0;
1767
+ };
1768
+ const main = R4.mapObjIndexed(
1769
+ (color, colorName) => generateColor(generateColorScale(color, colorScheme2), createColorOverrides(colorName)),
1770
+ colors.main
1771
+ );
1772
+ const support = R4.mapObjIndexed(
1773
+ (color, colorName) => generateColor(generateColorScale(color, colorScheme2), createColorOverrides(colorName)),
1774
+ colors.support
1775
+ );
1776
+ const neutral = generateColor(generateColorScale(colors.neutral, colorScheme2), createColorOverrides("neutral"));
1743
1777
  return {
1744
1778
  [themeName]: {
1745
1779
  ...main,
@@ -2204,8 +2238,8 @@ var generateSemantic = (colors) => {
2204
2238
  ["main-color", mainColorNames],
2205
2239
  ["support-color", supportColorNames]
2206
2240
  ];
2207
- for (const [colorCategory2, colorNames] of categories) {
2208
- for (const colorName of colorNames) {
2241
+ for (const [colorCategory2, colorNames2] of categories) {
2242
+ for (const colorName of colorNames2) {
2209
2243
  const category = colorCategory2.replace("-color", "");
2210
2244
  const customColorTokens = {
2211
2245
  color: {
@@ -2445,7 +2479,7 @@ var generateTypography = (themeName, { fontFamily }) => {
2445
2479
 
2446
2480
  // src/tokens/create.ts
2447
2481
  var createTokens = async (opts) => {
2448
- const { colors, typography: typography2, name, borderRadius } = opts;
2482
+ const { colors, typography: typography2, name, borderRadius, overrides } = opts;
2449
2483
  const colorSchemes = ["light", "dark"];
2450
2484
  const semantic2 = generateSemantic(colors);
2451
2485
  const tokenSets = new Map([
@@ -2463,7 +2497,7 @@ var createTokens = async (opts) => {
2463
2497
  [`primitives/modes/typography/secondary/${name}`, generateTypography(name, typography2)],
2464
2498
  ...colorSchemes.flatMap((scheme) => [
2465
2499
  [`primitives/modes/color-scheme/${scheme}/global`, generateColorGlobal(scheme)],
2466
- [`primitives/modes/color-scheme/${scheme}/${name}`, generateColorScheme(name, scheme, colors)]
2500
+ [`primitives/modes/color-scheme/${scheme}/${name}`, generateColorScheme(name, scheme, colors, overrides)]
2467
2501
  ]),
2468
2502
  [`themes/${name}`, generateTheme(colors, name, borderRadius)],
2469
2503
  ["semantic/color", semantic2.color],
@@ -2539,11 +2573,11 @@ function isColorCategoryToken(token, category) {
2539
2573
  var isDigit = (s) => /^\d+$/.test(s);
2540
2574
  function traverseObj(obj, fn) {
2541
2575
  for (const key in obj) {
2542
- const prop4 = obj[key];
2543
- if (prop4 != null) {
2544
- fn.apply(null, [obj, key, prop4]);
2545
- if (typeof prop4 === "object") {
2546
- traverseObj(prop4, fn);
2576
+ const prop3 = obj[key];
2577
+ if (prop3 != null) {
2578
+ fn.apply(null, [obj, key, prop3]);
2579
+ if (typeof prop3 === "object") {
2580
+ traverseObj(prop3, fn);
2547
2581
  }
2548
2582
  }
2549
2583
  }
@@ -2982,13 +3016,33 @@ ${content}
2982
3016
  // src/tokens/process/formats/css/type-scale.ts
2983
3017
  import * as R14 from "ramda";
2984
3018
  import { createPropertyFormatter as createPropertyFormatter6 } from "style-dictionary/utils";
2985
- var typographyFontFamilyPredicate2 = R14.allPass([
3019
+ var isTypographyFontFamilyToken = R14.allPass([
2986
3020
  R14.pathSatisfies(R14.includes("typography"), ["path"]),
2987
3021
  R14.pathSatisfies(R14.includes("fontFamily"), ["path"])
2988
3022
  ]);
2989
- function formatTypographySizeToken(token) {
2990
- return { ...token, $value: `calc(${token.$value} * var(--_ds-font-size-factor))` };
2991
- }
3023
+ var formatTypographySizeToken = (format, token) => {
3024
+ const [name, value] = format(token).replace(/;$/, "").split(": ");
3025
+ let calc;
3026
+ let round;
3027
+ if (R14.startsWith(["font-size"], token.path)) {
3028
+ calc = `calc(${value} * var(--_ds-font-size-factor))`;
3029
+ round = `round(${calc}, 1px)`;
3030
+ } else {
3031
+ calc = value;
3032
+ }
3033
+ return { name, calc, round: round ?? calc };
3034
+ };
3035
+ var formatTypographySizeTokens = (format, tokens) => R14.reduce(
3036
+ (acc, token) => {
3037
+ const { name, calc, round } = formatTypographySizeToken(format, token);
3038
+ acc.tokens.push(token);
3039
+ acc.calc.push(`${name}: ${calc};`);
3040
+ acc.round.push(`${name}: ${round};`);
3041
+ return acc;
3042
+ },
3043
+ { tokens: [], calc: [], round: [] },
3044
+ tokens
3045
+ );
2992
3046
  var typeScale = {
2993
3047
  name: "ds/css-type-scale",
2994
3048
  format: async ({ dictionary, file, options, platform }) => {
@@ -3001,18 +3055,16 @@ var typeScale = {
3001
3055
  format: "css",
3002
3056
  usesDtcg
3003
3057
  });
3004
- const filteredTokens = R14.reject(typographyFontFamilyPredicate2, dictionary.allTokens);
3005
- const tokens = R14.map(formatTypographySizeToken, filteredTokens);
3006
- const formattedMap = tokens.map((token) => ({
3007
- token,
3008
- formatted: format(token)
3058
+ const filteredTokens = R14.reject(R14.anyPass([isTypographyFontFamilyToken]), dictionary.allTokens);
3059
+ const formattedTokens = formatTypographySizeTokens(format, filteredTokens);
3060
+ const formattedMap = formattedTokens.round.map((t, i) => ({
3061
+ token: formattedTokens.tokens[i],
3062
+ formatted: t
3009
3063
  }));
3010
3064
  buildOptions.buildTokenFormats[destination] = formattedMap;
3011
- const formattedTokens = formattedMap.map(R14.prop("formatted")).join("\n");
3012
3065
  const sizeFactor = ` --_ds-font-size-factor: calc(var(--ds-size-mode-font-size) / (var(--ds-size-base) / ${basePxFontSize}));`;
3013
3066
  const content = `${selector} {
3014
- ${sizeFactor}
3015
- ${formattedTokens}
3067
+ ${sizeFactor}${sizingTemplate(formattedTokens)}
3016
3068
  }`;
3017
3069
  const body = R14.isNotNil(layer) ? `@layer ${layer} {
3018
3070
  ${content}
@@ -3225,7 +3277,7 @@ var sizeModeVariables = ({ theme, size: size2 }) => {
3225
3277
  };
3226
3278
 
3227
3279
  // src/tokens/process/configs/type-scale.ts
3228
- var typeScaleVariables = ({ theme, size: size2 }) => {
3280
+ var typeScaleVariables = ({ theme }) => {
3229
3281
  const selector = ":root, [data-size]";
3230
3282
  const layer = `ds.theme.type-scale`;
3231
3283
  return {
@@ -49,11 +49,11 @@ import pc4 from "picocolors";
49
49
  // package.json
50
50
  var package_default = {
51
51
  name: "@digdir/designsystemet",
52
- version: "1.5.0",
52
+ version: "1.6.0",
53
53
  description: "CLI for Designsystemet",
54
54
  author: "Designsystemet team",
55
55
  engines: {
56
- node: ">=22.19.0"
56
+ node: ">=20 <25"
57
57
  },
58
58
  repository: {
59
59
  type: "git",
@@ -101,7 +101,7 @@ var package_default = {
101
101
  "test:tokens-build-config-tailwind": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean --experimental-tailwind",
102
102
  "test:tokens-create-and-build-options": "pnpm test:tokens-create-options && pnpm test:tokens-build",
103
103
  "test:tokens-create-and-build-config": "pnpm test:tokens-create-config && pnpm test:tokens-build-config",
104
- test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
104
+ test: "node -v && pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
105
105
  "digdir:tokens-build": "pnpm run designsystemet tokens build -t ../../internal/design-tokens -o ../../packages/theme/brand --clean --experimental-tailwind",
106
106
  "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
107
107
  "update:template": "tsx ./src/scripts/update-template.ts",
@@ -116,7 +116,7 @@ var package_default = {
116
116
  "change-case": "^5.4.4",
117
117
  "chroma-js": "^3.1.2",
118
118
  "colorjs.io": "^0.6.0-alpha.1",
119
- commander: "^14.0.0",
119
+ commander: "^14.0.1",
120
120
  "fast-glob": "^3.3.3",
121
121
  hsluv: "^1.0.1",
122
122
  "object-hash": "^3.0.0",
@@ -124,18 +124,18 @@ var package_default = {
124
124
  postcss: "^8.5.6",
125
125
  ramda: "^0.31.3",
126
126
  "style-dictionary": "^5.0.4",
127
- zod: "^4.1.5",
128
- "zod-validation-error": "^4.0.1"
127
+ zod: "^4.1.11",
128
+ "zod-validation-error": "^4.0.2"
129
129
  },
130
130
  devDependencies: {
131
131
  "@tokens-studio/types": "0.5.2",
132
132
  "@types/apca-w3": "^0.1.3",
133
133
  "@types/chroma-js": "^3.1.1",
134
134
  "@types/fs-extra": "^11.0.4",
135
- "@types/node": "^22.18.1",
135
+ "@types/node": "^22.18.6",
136
136
  "@types/object-hash": "^3.0.6",
137
- "@types/ramda": "^0.31.0",
138
- "fs-extra": "^11.3.1",
137
+ "@types/ramda": "^0.31.1",
138
+ "fs-extra": "^11.3.2",
139
139
  tslib: "^2.8.1",
140
140
  tsup: "^8.5.0",
141
141
  tsx: "^4.20.5",
@@ -206,11 +206,11 @@ function isColorCategoryToken(token, category) {
206
206
  var isDigit = (s) => /^\d+$/.test(s);
207
207
  function traverseObj(obj, fn) {
208
208
  for (const key in obj) {
209
- const prop4 = obj[key];
210
- if (prop4 != null) {
211
- fn.apply(null, [obj, key, prop4]);
212
- if (typeof prop4 === "object") {
213
- traverseObj(prop4, fn);
209
+ const prop3 = obj[key];
210
+ if (prop3 != null) {
211
+ fn.apply(null, [obj, key, prop3]);
212
+ if (typeof prop3 === "object") {
213
+ traverseObj(prop3, fn);
214
214
  }
215
215
  }
216
216
  }
@@ -649,13 +649,33 @@ ${content}
649
649
  // src/tokens/process/formats/css/type-scale.ts
650
650
  import * as R8 from "ramda";
651
651
  import { createPropertyFormatter as createPropertyFormatter6 } from "style-dictionary/utils";
652
- var typographyFontFamilyPredicate2 = R8.allPass([
652
+ var isTypographyFontFamilyToken = R8.allPass([
653
653
  R8.pathSatisfies(R8.includes("typography"), ["path"]),
654
654
  R8.pathSatisfies(R8.includes("fontFamily"), ["path"])
655
655
  ]);
656
- function formatTypographySizeToken(token) {
657
- return { ...token, $value: `calc(${token.$value} * var(--_ds-font-size-factor))` };
658
- }
656
+ var formatTypographySizeToken = (format, token) => {
657
+ const [name, value] = format(token).replace(/;$/, "").split(": ");
658
+ let calc;
659
+ let round;
660
+ if (R8.startsWith(["font-size"], token.path)) {
661
+ calc = `calc(${value} * var(--_ds-font-size-factor))`;
662
+ round = `round(${calc}, 1px)`;
663
+ } else {
664
+ calc = value;
665
+ }
666
+ return { name, calc, round: round ?? calc };
667
+ };
668
+ var formatTypographySizeTokens = (format, tokens) => R8.reduce(
669
+ (acc, token) => {
670
+ const { name, calc, round } = formatTypographySizeToken(format, token);
671
+ acc.tokens.push(token);
672
+ acc.calc.push(`${name}: ${calc};`);
673
+ acc.round.push(`${name}: ${round};`);
674
+ return acc;
675
+ },
676
+ { tokens: [], calc: [], round: [] },
677
+ tokens
678
+ );
659
679
  var typeScale = {
660
680
  name: "ds/css-type-scale",
661
681
  format: async ({ dictionary, file, options, platform }) => {
@@ -668,18 +688,16 @@ var typeScale = {
668
688
  format: "css",
669
689
  usesDtcg
670
690
  });
671
- const filteredTokens = R8.reject(typographyFontFamilyPredicate2, dictionary.allTokens);
672
- const tokens = R8.map(formatTypographySizeToken, filteredTokens);
673
- const formattedMap = tokens.map((token) => ({
674
- token,
675
- formatted: format(token)
691
+ const filteredTokens = R8.reject(R8.anyPass([isTypographyFontFamilyToken]), dictionary.allTokens);
692
+ const formattedTokens = formatTypographySizeTokens(format, filteredTokens);
693
+ const formattedMap = formattedTokens.round.map((t, i) => ({
694
+ token: formattedTokens.tokens[i],
695
+ formatted: t
676
696
  }));
677
697
  buildOptions.buildTokenFormats[destination] = formattedMap;
678
- const formattedTokens = formattedMap.map(R8.prop("formatted")).join("\n");
679
698
  const sizeFactor = ` --_ds-font-size-factor: calc(var(--ds-size-mode-font-size) / (var(--ds-size-base) / ${basePxFontSize}));`;
680
699
  const content = `${selector} {
681
- ${sizeFactor}
682
- ${formattedTokens}
700
+ ${sizeFactor}${sizingTemplate(formattedTokens)}
683
701
  }`;
684
702
  const body = R8.isNotNil(layer) ? `@layer ${layer} {
685
703
  ${content}
@@ -892,7 +910,7 @@ var sizeModeVariables = ({ theme, size: size2 }) => {
892
910
  };
893
911
 
894
912
  // src/tokens/process/configs/type-scale.ts
895
- var typeScaleVariables = ({ theme, size: size2 }) => {
913
+ var typeScaleVariables = ({ theme }) => {
896
914
  const selector = ":root, [data-size]";
897
915
  const layer = `ds.theme.type-scale`;
898
916
  return {
@@ -1,11 +1,11 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@digdir/designsystemet",
4
- version: "1.5.0",
4
+ version: "1.6.0",
5
5
  description: "CLI for Designsystemet",
6
6
  author: "Designsystemet team",
7
7
  engines: {
8
- node: ">=22.19.0"
8
+ node: ">=20 <25"
9
9
  },
10
10
  repository: {
11
11
  type: "git",
@@ -53,7 +53,7 @@ var package_default = {
53
53
  "test:tokens-build-config-tailwind": "pnpm run designsystemet tokens build -t ./temp/config/design-tokens -o ./temp/config/build --clean --experimental-tailwind",
54
54
  "test:tokens-create-and-build-options": "pnpm test:tokens-create-options && pnpm test:tokens-build",
55
55
  "test:tokens-create-and-build-config": "pnpm test:tokens-create-config && pnpm test:tokens-build-config",
56
- test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
56
+ test: "node -v && pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
57
57
  "digdir:tokens-build": "pnpm run designsystemet tokens build -t ../../internal/design-tokens -o ../../packages/theme/brand --clean --experimental-tailwind",
58
58
  "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
59
59
  "update:template": "tsx ./src/scripts/update-template.ts",
@@ -68,7 +68,7 @@ var package_default = {
68
68
  "change-case": "^5.4.4",
69
69
  "chroma-js": "^3.1.2",
70
70
  "colorjs.io": "^0.6.0-alpha.1",
71
- commander: "^14.0.0",
71
+ commander: "^14.0.1",
72
72
  "fast-glob": "^3.3.3",
73
73
  hsluv: "^1.0.1",
74
74
  "object-hash": "^3.0.0",
@@ -76,18 +76,18 @@ var package_default = {
76
76
  postcss: "^8.5.6",
77
77
  ramda: "^0.31.3",
78
78
  "style-dictionary": "^5.0.4",
79
- zod: "^4.1.5",
80
- "zod-validation-error": "^4.0.1"
79
+ zod: "^4.1.11",
80
+ "zod-validation-error": "^4.0.2"
81
81
  },
82
82
  devDependencies: {
83
83
  "@tokens-studio/types": "0.5.2",
84
84
  "@types/apca-w3": "^0.1.3",
85
85
  "@types/chroma-js": "^3.1.1",
86
86
  "@types/fs-extra": "^11.0.4",
87
- "@types/node": "^22.18.1",
87
+ "@types/node": "^22.18.6",
88
88
  "@types/object-hash": "^3.0.6",
89
- "@types/ramda": "^0.31.0",
90
- "fs-extra": "^11.3.1",
89
+ "@types/ramda": "^0.31.1",
90
+ "fs-extra": "^11.3.2",
91
91
  tslib: "^2.8.1",
92
92
  tsup: "^8.5.0",
93
93
  tsx: "^4.20.5",