Skip to content

Commit 5586d42

Browse files
authored
Darkside role theming refactor (#3575)
* ✨ Added themed roles config to darkside * ♻️ Rename breakpint config * 🚚 Move files * 🐛 Update renamed import * 🐛 Build theme-files before readig them * ♻️ Refactored color-tokens setup * ♻️ Updated setup and imports * ♻️ Hide unwanted tokenfiles * 🐛 Update imports for refactored colors * 📝 Clarify tests * 📝 config -> configs
1 parent 94e3bd7 commit 5586d42

16 files changed

+530
-524
lines changed

@navikt/core/tokens/darkside/index.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import {
1717
rootTokens,
1818
} from "./tokens.config";
1919
import { tokensWithPrefix } from "./tokens.util";
20-
import { globalColorLightModeConfig } from "./tokens/global";
21-
import { configForRole, themedConfigForRole } from "./tokens/semantic-roles";
20+
import { globalLightTokens } from "./tokens/colors/global.tokens";
21+
import { semanticTokensForRole } from "./tokens/colors/semantic-role.tokens";
22+
import { semanticThemedBaseTokens } from "./tokens/colors/semantic-themed-base.tokens";
2223

2324
/* Temporary project location */
2425
const DARKSIDE_DIST = "./dist/darkside/";
@@ -211,9 +212,9 @@ const themedRoleConfig = async (role: SemanticColorRoles) => {
211212
const SDDictionary = new StyleDictionary({
212213
tokens: tokensWithPrefix(
213214
[
214-
globalColorLightModeConfig,
215-
configForRole(role),
216-
themedConfigForRole(role),
215+
globalLightTokens,
216+
semanticTokensForRole(role),
217+
semanticThemedBaseTokens(role),
217218
].reduce((acc, config) => _.merge(acc, config), {}),
218219
),
219220
/* We get warnings for filtering out referenced tokens now */

@navikt/core/tokens/darkside/tests/validate-config.test.ts

+12-29
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,41 @@
11
import { describe, expect, test } from "vitest";
2+
import { radiusTokenConfig } from "../tokens/border-radius";
23
import {
3-
globalColorDarkModeConfig,
4-
globalColorLightModeConfig,
5-
} from "../tokens/global";
6-
import { radiusTokenConfig } from "../tokens/radius";
7-
import { semanticTokenConfig } from "../tokens/semantic";
8-
import { semanticTokensForAllRolesConfig } from "../tokens/semantic-roles";
4+
globalDarkTokens,
5+
globalLightTokens,
6+
} from "../tokens/colors/global.tokens";
7+
import { semanticTokensForAllRoles } from "../tokens/colors/semantic-role.tokens";
8+
import { semanticRootTokens } from "../tokens/colors/semantic-root.tokens";
99
import { spaceTokenConfig } from "../tokens/space";
10-
import { textContrastTokenConfig } from "../tokens/text-contrast";
1110

1211
const configKeysWithGroup = ["value", "type", "group"];
1312
const configKeys = ["value", "type"];
1413

1514
describe("Validate token configurations", () => {
1615
test(`Semantic tokens lightmode`, () => {
1716
expect(
18-
validateConfig(semanticTokenConfig("light"), configKeysWithGroup),
17+
validateConfig(semanticRootTokens("light"), configKeysWithGroup),
1918
).toBeTruthy();
2019
});
2120

2221
test(`Semantic tokens darkmode`, () => {
2322
expect(
24-
validateConfig(semanticTokenConfig("dark"), configKeysWithGroup),
23+
validateConfig(semanticRootTokens("dark"), configKeysWithGroup),
2524
).toBeTruthy();
2625
});
2726

28-
test(`Semantic tokens for all roles: Lightmode`, () => {
27+
test(`Semantic tokens for all roles`, () => {
2928
expect(
30-
validateConfig(semanticTokensForAllRolesConfig(), configKeysWithGroup),
31-
).toBeTruthy();
32-
});
33-
34-
test(`Semantic tokens for all roles: Darkmode`, () => {
35-
expect(
36-
validateConfig(semanticTokensForAllRolesConfig(), configKeysWithGroup),
37-
).toBeTruthy();
38-
});
39-
40-
test(`Text-contrast tokens`, () => {
41-
expect(
42-
validateConfig(textContrastTokenConfig, configKeysWithGroup),
29+
validateConfig(semanticTokensForAllRoles(), configKeysWithGroup),
4330
).toBeTruthy();
4431
});
4532

4633
test(`Global lightmode scale`, () => {
47-
expect(
48-
validateConfig(globalColorLightModeConfig, configKeysWithGroup),
49-
).toBeTruthy();
34+
expect(validateConfig(globalLightTokens, configKeysWithGroup)).toBeTruthy();
5035
});
5136

5237
test(`Global darkmode scale`, () => {
53-
expect(
54-
validateConfig(globalColorDarkModeConfig, configKeysWithGroup),
55-
).toBeTruthy();
38+
expect(validateConfig(globalDarkTokens, configKeysWithGroup)).toBeTruthy();
5639
});
5740

5841
test(`Space scale`, () => {
+42-65
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,64 @@
1-
import _ from "lodash";
2-
import {
3-
StyleDictionaryTokenConfig,
4-
TokenTypes,
5-
tokensWithPrefix,
6-
} from "./tokens.util";
1+
import { mergeConfigs, tokensWithPrefix } from "./tokens.util";
2+
import { radiusTokenConfig } from "./tokens/border-radius";
73
import { breakpointTokenConfig } from "./tokens/breakpoint";
8-
import { fontTokenConfig } from "./tokens/font";
94
import {
10-
globalColorDarkModeConfig,
11-
globalColorLightModeConfig,
12-
} from "./tokens/global";
5+
globalDarkTokens,
6+
globalLightTokens,
7+
} from "./tokens/colors/global.tokens";
8+
import { semanticTokensForAllRoles } from "./tokens/colors/semantic-role.tokens";
9+
import { semanticRootTokens } from "./tokens/colors/semantic-root.tokens";
10+
import { fontTokenConfig } from "./tokens/font";
1311
import { opacityTokenConfig } from "./tokens/opacity";
14-
import { radiusTokenConfig } from "./tokens/radius";
15-
import { semanticTokenConfig } from "./tokens/semantic";
16-
import { semanticTokensForAllRolesConfig } from "./tokens/semantic-roles";
1712
import { shadowTokenConfig } from "./tokens/shadow";
1813
import { spaceTokenConfig } from "./tokens/space";
19-
import { textContrastTokenConfig } from "./tokens/text-contrast";
2014

21-
const mergeConfigs = (
22-
configs: StyleDictionaryTokenConfig<TokenTypes>[],
23-
): StyleDictionaryTokenConfig<TokenTypes> => {
24-
return configs.reduce((acc, config) => _.merge(acc, config), {});
25-
};
26-
27-
/**
28-
* Collection of configs for:
29-
* - Global lightmode colors
30-
* - Semantic tokens for each color-role
31-
* - Semantic tokens for standalone colors
32-
*/
3315
export const lightModeTokens = () => {
34-
return tokensWithPrefix(
35-
mergeConfigs([
36-
shadowTokenConfig("light"),
37-
opacityTokenConfig("light"),
38-
semanticTokensForAllRolesConfig(),
39-
textContrastTokenConfig,
40-
semanticTokenConfig("light"),
41-
globalColorLightModeConfig,
42-
]),
43-
);
16+
const configs = [
17+
shadowTokenConfig("light"),
18+
opacityTokenConfig("light"),
19+
semanticTokensForAllRoles(),
20+
semanticRootTokens("light"),
21+
globalLightTokens,
22+
];
23+
24+
return tokensWithPrefix(mergeConfigs(configs));
4425
};
4526

46-
/**
47-
* Collection of configs for:
48-
* - Global darkmode colors
49-
*/
5027
export const darkModeTokens = () => {
51-
return tokensWithPrefix(
52-
mergeConfigs([
53-
shadowTokenConfig("dark"),
54-
opacityTokenConfig("dark"),
55-
semanticTokensForAllRolesConfig(),
56-
textContrastTokenConfig,
57-
semanticTokenConfig("dark"),
58-
globalColorDarkModeConfig,
59-
]),
60-
);
28+
const configs = [
29+
shadowTokenConfig("dark"),
30+
opacityTokenConfig("dark"),
31+
semanticTokensForAllRoles(),
32+
semanticRootTokens("dark"),
33+
globalDarkTokens,
34+
];
35+
36+
return tokensWithPrefix(mergeConfigs(configs));
6137
};
6238

6339
/**
64-
* Collection of configs for:
65-
* - Space
66-
* - Radius
40+
* We deliberately extract space and border-radius tokens from other "root" tokens like breakline, font etc
41+
* so we can use the fuction for creating Figma-variables
6742
*/
6843
export const scaleTokens = () => {
69-
return tokensWithPrefix(mergeConfigs([spaceTokenConfig, radiusTokenConfig]));
44+
const configs = [spaceTokenConfig, radiusTokenConfig];
45+
46+
return tokensWithPrefix(mergeConfigs(configs));
7047
};
7148

7249
export const rootTokens = () => {
73-
return tokensWithPrefix(
74-
mergeConfigs([scaleTokens().ax, breakpointTokenConfig, fontTokenConfig]),
75-
);
50+
const configs = [scaleTokens().ax, breakpointTokenConfig, fontTokenConfig];
51+
52+
return tokensWithPrefix(mergeConfigs(configs));
7653
};
7754

7855
export const allTokens = () => {
79-
return tokensWithPrefix(
80-
mergeConfigs([
81-
lightModeTokens().ax,
82-
scaleTokens().ax,
83-
breakpointTokenConfig,
84-
fontTokenConfig,
85-
]),
86-
);
56+
const configs = [
57+
lightModeTokens().ax,
58+
scaleTokens().ax,
59+
breakpointTokenConfig,
60+
fontTokenConfig,
61+
];
62+
63+
return tokensWithPrefix(mergeConfigs(configs));
8764
};

@navikt/core/tokens/darkside/tokens.util.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import _ from "lodash";
12
import type { GlobalColorRoles, SemanticColorRoles } from "../types";
23

34
export type GlobalColorEntry = {
@@ -85,3 +86,9 @@ export type StyleDictionaryTokenConfig<T extends TokenTypes> = {
8586
export const tokensWithPrefix = <T>(input: T): Record<"ax", T> => {
8687
return { ax: input };
8788
};
89+
90+
export const mergeConfigs = (
91+
configs: StyleDictionaryTokenConfig<TokenTypes>[],
92+
): StyleDictionaryTokenConfig<TokenTypes> => {
93+
return configs.reduce((acc, config) => _.merge(acc, config), {});
94+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { GlobalColorRoles, GlobalColorScale } from "../../../types";
2+
import { GlobalColorEntry } from "../../tokens.util";
3+
4+
export type GlobalConfigWithAlpha = Record<
5+
Extract<GlobalColorRoles, "neutral">,
6+
Record<GlobalColorScale, GlobalColorEntry>
7+
> &
8+
Record<
9+
Exclude<GlobalColorRoles, "neutral">,
10+
Record<Exclude<GlobalColorScale, "000">, GlobalColorEntry>
11+
>;
12+
13+
export type GlobalConfigWithoutAlpha = Record<
14+
GlobalColorRoles,
15+
Record<
16+
Exclude<GlobalColorScale, "000" | "100A" | "200A" | "300A" | "400A">,
17+
GlobalColorEntry
18+
>
19+
> & {
20+
neutral: {
21+
[key in Extract<GlobalColorScale, "000">]: GlobalColorEntry;
22+
};
23+
};

@navikt/core/tokens/darkside/tokens/global.ts @navikt/core/tokens/darkside/tokens/colors/create-alpha.ts

+13-25
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,8 @@
11
import Color from "colorjs.io";
2-
import {
3-
type ColorTheme,
4-
type GlobalColorRoles,
5-
type GlobalColorScale,
6-
} from "../../types";
7-
import { type GlobalColorEntry } from "../tokens.util";
8-
import { globalColorDarkModeConfigWithoutAlpha } from "./global-dark";
9-
import { globalColorLightModeConfigWithoutAlpha } from "./global-light";
10-
import { semanticTokenConfig } from "./semantic";
11-
12-
export const globalColorDarkModeConfig = globalColorConfigWithAlphaTokens(
13-
globalColorDarkModeConfigWithoutAlpha,
14-
"dark",
15-
);
16-
17-
export const globalColorLightModeConfig = globalColorConfigWithAlphaTokens(
18-
globalColorLightModeConfigWithoutAlpha,
19-
"light",
20-
);
2+
import { ColorTheme, GlobalColorRoles, GlobalColorScale } from "../../../types";
3+
import { GlobalColorEntry } from "../../tokens.util";
4+
import { GlobalConfigWithoutAlpha } from "./colors.types";
5+
import { semanticRootTokens } from "./semantic-root.tokens";
216

227
type GlobalConfigWithAlpha = Record<
238
Extract<GlobalColorRoles, "neutral">,
@@ -32,10 +17,13 @@ type GlobalConfigWithAlpha = Record<
3217
* To avoid having to use 3rd party websites for generating alpha tokens,
3318
* we add alpha tokens by calulating them ourselves.
3419
*/
35-
function globalColorConfigWithAlphaTokens(
36-
globalConfig: typeof globalColorLightModeConfigWithoutAlpha,
37-
theme: ColorTheme,
38-
): GlobalConfigWithAlpha {
20+
export function globalConfigWithAlphaTokens({
21+
config: globalConfig,
22+
theme,
23+
}: {
24+
config: GlobalConfigWithoutAlpha;
25+
theme: ColorTheme;
26+
}): GlobalConfigWithAlpha {
3927
const localConfig = structuredClone(globalConfig) as GlobalConfigWithAlpha;
4028

4129
Object.keys(globalConfig).forEach((key) => {
@@ -63,8 +51,8 @@ function globalColorConfigWithAlphaTokens(
6351
return localConfig;
6452
}
6553

66-
export function createAlphaColor(targetColor: string, theme: ColorTheme) {
67-
const backgroundColor = semanticTokenConfig(theme).bg.default.value;
54+
function createAlphaColor(targetColor: string, theme: ColorTheme) {
55+
const backgroundColor = semanticRootTokens(theme).bg.default.value;
6856

6957
const [r, g, b, a] = getAlphaColor(
7058
new Color(targetColor).to("srgb").coords,

0 commit comments

Comments
 (0)