Skip to content

Commit

Permalink
[Darkside] Moved contrast-tokens to text group
Browse files Browse the repository at this point in the history
feat: Moved contrast tokens to 'text' collection
feat: Added support for adding custom scopes for each token
  • Loading branch information
KenAJoh committed Oct 8, 2024
1 parent aac12fe commit 22be148
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 60 deletions.
6 changes: 3 additions & 3 deletions @navikt/core/tokens/darkside/create-configuration.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { contrastTokenConfig } from "./tokens/contrast";
import { globalColorDarkModeConfig } from "./tokens/global-dark";
import { globalColorLightModeConfig } from "./tokens/global-light";
import { radiusTokenConfig } from "./tokens/radius";
import { semanticTokenConfig } from "./tokens/semantic";
import { semanticTokensForAllRolesConfig } from "./tokens/semantic-roles";
import { spacingTokenConfig } from "./tokens/spacing";
import { textContrastTokenConfig } from "./tokens/text-contrast";
import { mergeConfigs, tokensWithPrefix } from "./util";

/**
Expand All @@ -17,7 +17,7 @@ export const lightModeTokens = () => {
return tokensWithPrefix(
mergeConfigs([
semanticTokensForAllRolesConfig(),
contrastTokenConfig(),
textContrastTokenConfig(),
semanticTokenConfig("light"),
globalColorLightModeConfig,
]),
Expand All @@ -32,7 +32,7 @@ export const darkModeTokens = () => {
return tokensWithPrefix(
mergeConfigs([
semanticTokensForAllRolesConfig(),
contrastTokenConfig(),
textContrastTokenConfig(),
semanticTokenConfig("dark"),
globalColorDarkModeConfig,
]),
Expand Down
54 changes: 30 additions & 24 deletions @navikt/core/tokens/darkside/figma/create-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,22 @@ export const getTokensForCollection = async (
*/
return reference.length > 0
? prepareToken(
{ ...token, alias: createTokenName(reference[0]) },
{
...(token as TransformedTokenWithScopes),
alias: createTokenName(reference[0]),
},
dictionary,
)
: prepareToken(token, dictionary);
: prepareToken(token as TransformedTokenWithScopes, dictionary);
});
};

type TransformedTokenWithScopes = TransformedToken & {
scopes: StyleDictionaryToken<TokenTypes>["scopes"];
};

function prepareToken(
token: TransformedToken,
token: TransformedTokenWithScopes,
dictionary: Dictionary,
): FigmaToken {
const formatter = createPropertyFormatter({
Expand Down Expand Up @@ -109,35 +116,34 @@ export function figmaValue(token: TransformedToken): string | number {
* Scopes allows us to define where in Figma the token can be used.
* @see https://www.figma.com/plugin-docs/api/VariableScope
*/
function figmaSettings(token: TransformedToken): {
function figmaSettings(token: TransformedTokenWithScopes): {
figmaType: VariableResolvedDataType;
scopes: VariableScope[];
} {
let setting: ReturnType<typeof figmaSettings> | undefined;

if (isGlobalColor(token)) {
return createFigmaSettings("COLOR", ["ALL_FILLS", "STROKE_COLOR"]);
setting = createFigmaSettings("COLOR", ["ALL_FILLS", "STROKE_COLOR"]);
} else if (isTokenOfSemanticColorGroup(token, "background")) {
setting = createFigmaSettings("COLOR", ["FRAME_FILL", "SHAPE_FILL"]);
} else if (isTokenOfSemanticColorGroup(token, "border")) {
setting = createFigmaSettings("COLOR", ["STROKE_COLOR"]);
} else if (isTokenOfSemanticColorGroup(token, "text")) {
setting = createFigmaSettings("COLOR", ["SHAPE_FILL", "TEXT_FILL"]);
} else if (isRadiusToken(token)) {
setting = createFigmaSettings("FLOAT", ["CORNER_RADIUS"]);
} else if (isSpacingToken(token)) {
setting = createFigmaSettings("FLOAT", ["GAP"]);
}

if (isTokenOfSemanticColorGroup(token, "background")) {
return createFigmaSettings("COLOR", ["FRAME_FILL", "SHAPE_FILL"]);
}
if (isTokenOfSemanticColorGroup(token, "border")) {
return createFigmaSettings("COLOR", ["STROKE_COLOR"]);
}
if (
isTokenOfSemanticColorGroup(token, "contrast") ||
isTokenOfSemanticColorGroup(token, "text")
) {
return createFigmaSettings("COLOR", ["SHAPE_FILL", "TEXT_FILL"]);
}
if (isRadiusToken(token)) {
return createFigmaSettings("FLOAT", ["CORNER_RADIUS"]);
}
if (isSpacingToken(token)) {
return createFigmaSettings("FLOAT", ["GAP"]);
if (!setting) {
console.warn(`No fitting type or scope found for token: ${token.name}`);
return createFigmaSettings("STRING", []);
}

console.warn(`No fitting type or scope found for token: ${token.name}`);
return createFigmaSettings("STRING", []);
token.scopes && setting.scopes.push(...token.scopes);

return setting;
}

function createFigmaSettings(
Expand Down
12 changes: 8 additions & 4 deletions @navikt/core/tokens/darkside/tests/validate-config.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, expect, test } from "vitest";
import { contrastTokenConfig } from "../tokens/contrast";
import { globalColorDarkModeConfig } from "../tokens/global-dark";
import { globalColorLightModeConfig } from "../tokens/global-light";
import { radiusTokenConfig } from "../tokens/radius";
import { semanticTokenConfig } from "../tokens/semantic";
import { semanticTokensForAllRolesConfig } from "../tokens/semantic-roles";
import { spacingTokenConfig } from "../tokens/spacing";
import { textContrastTokenConfig } from "../tokens/text-contrast";

const configKeysWithGroup = ["value", "type", "group"];
const configKeys = ["value", "type"];
Expand All @@ -29,9 +29,9 @@ describe("Validate token configurations", () => {
).toBeTruthy();
});

test(`Contrast tokens`, () => {
test(`Text-contrast tokens`, () => {
expect(
validateConfig(contrastTokenConfig(), configKeysWithGroup),
validateConfig(textContrastTokenConfig(), configKeysWithGroup),
).toBeTruthy();
});

Expand Down Expand Up @@ -61,7 +61,11 @@ function validateConfig(
requiredKeys: string[],
): boolean {
for (const key in obj) {
if (typeof obj[key] === "object" && obj[key] !== null) {
if (
typeof obj[key] === "object" &&
obj[key] !== null &&
!Array.isArray(obj[key])
) {
if (!validateConfig(obj[key], requiredKeys)) {
return false;
}
Expand Down
14 changes: 14 additions & 0 deletions @navikt/core/tokens/darkside/tokens/semantic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ function semanticTokensDark(): StyleDictionaryTokenConfig<"color"> {
value: "#0E151F",
type: "color",
group: "background",
/**
* Allows token to be used on 'effect' properties in Figma,
* Bg-default is used between element and focus-marking.
*/
scopes: ["EFFECT_COLOR"],
},
raised: {
value: "{a.neutral.200.value}",
Expand Down Expand Up @@ -53,6 +58,11 @@ function semanticTokensLight(): StyleDictionaryTokenConfig<"color"> {
value: "{a.neutral.000.value}",
type: "color",
group: "background",
/**
* Allows token to be used on 'effect' properties in Figma,
* Bg-default is used between element and focus-marking.
*/
scopes: ["EFFECT_COLOR"],
},
input: {
value: "{a.neutral.000.value}",
Expand Down Expand Up @@ -99,6 +109,10 @@ function semanticTokensLight(): StyleDictionaryTokenConfig<"color"> {
value: "{a.accent.700.value}",
type: "color",
group: "border",
/**
* Allows token to be used on 'effect' properties in Figma, used for creating focus markings.
*/
scopes: ["EFFECT_COLOR"],
},
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,69 +1,69 @@
import { GlobalColorRoles, StyleDictionaryToken } from "../util";

export const contrastTokenConfig = (): {
contrast: {
[key in GlobalColorRoles]: StyleDictionaryToken<"color">;
export const textContrastTokenConfig = (): {
text: {
[key in `${GlobalColorRoles}-contrast`]: StyleDictionaryToken<"color">;
};
} => ({
contrast: {
text: {
/* core */
accent: {
"accent-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
neutral: {
"neutral-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
/* Status */
danger: {
"danger-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
info: {
"info-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
success: {
"success-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
warning: {
"warning-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
/* Brand */
brandOne: {
"brandOne-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
brandTwo: {
"brandTwo-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
brandThree: {
"brandThree-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
/* Data */
dataOne: {
"dataOne-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
dataTwo: {
"dataTwo-contrast": {
value: "{a.neutral.000.value}",
type: "color",
group: "contrast",
group: "text",
},
},
});
25 changes: 22 additions & 3 deletions @navikt/core/tokens/darkside/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,38 @@ export type TokenTypes =
| "global-radius"
| "global-spacing";

export type SemanticTokenGroups = "background" | "border" | "text" | "contrast";
type SemanticTokenGroupsWithRoles = Exclude<SemanticTokenGroups, "contrast">;
export type SemanticTokenGroups = "background" | "border" | "text";

export type TokenGroup =
| GlobalColorRoles
| SemanticTokenGroups
| `${SemanticTokenGroupsWithRoles}.${GlobalColorRoles}`;
| `${SemanticTokenGroups}.${GlobalColorRoles}`;

export type StyleDictionaryToken<T extends TokenTypes> = {
/**
* Token value
* @example "#000000"
* @example "1px"
* @example "{a.neutral.100.value}"
*/
value: string;
/**
* Token type
*/
type: T;
/**
* Group the token belongs to. Used for auto-documentation and categorization in Figma.
*/
group?: TokenGroup;
/**
* Optional comment for the token. Will be included in the generated documentation and in Figma.
*/
comment?: string;
/**
* Optional extra scopes for the token.
* Token will include all default scopes based on `type`, and any extra specified here.
*/
scopes?: VariableScope[];
};

export type StyleDictionaryTokenConfig<T extends TokenTypes> = {
Expand Down

0 comments on commit 22be148

Please sign in to comment.