diff --git a/styles/package-lock.json b/styles/package-lock.json index c03c27c1e8..d1d0ed0eb8 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@tokens-studio/types": "^0.2.3", "@types/chroma-js": "^2.4.0", "@types/node": "^18.14.1", "ayu": "^8.0.1", @@ -53,6 +54,11 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@tokens-studio/types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@tokens-studio/types/-/types-0.2.3.tgz", + "integrity": "sha512-2KN3V0JPf+Zh8aoVMwykJq29Lsi7vYgKGYBQ/zQ+FbDEmrH6T/Vwn8kG7cvbTmW1JAAvgxVxMIivgC9PmFelNA==" + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -271,6 +277,11 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@tokens-studio/types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@tokens-studio/types/-/types-0.2.3.tgz", + "integrity": "sha512-2KN3V0JPf+Zh8aoVMwykJq29Lsi7vYgKGYBQ/zQ+FbDEmrH6T/Vwn8kG7cvbTmW1JAAvgxVxMIivgC9PmFelNA==" + }, "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", diff --git a/styles/package.json b/styles/package.json index 5f103c5d6c..2a0881863b 100644 --- a/styles/package.json +++ b/styles/package.json @@ -5,11 +5,13 @@ "main": "index.js", "scripts": { "build": "ts-node ./src/buildThemes.ts", - "build-licenses": "ts-node ./src/buildLicenses.ts" + "build-licenses": "ts-node ./src/buildLicenses.ts", + "build-tokens": "ts-node ./src/buildTokens.ts" }, "author": "", "license": "ISC", "dependencies": { + "@tokens-studio/types": "^0.2.3", "@types/chroma-js": "^2.4.0", "@types/node": "^18.14.1", "ayu": "^8.0.1", diff --git a/styles/src/buildTokens.ts b/styles/src/buildTokens.ts new file mode 100644 index 0000000000..81ffd3f3cb --- /dev/null +++ b/styles/src/buildTokens.ts @@ -0,0 +1,39 @@ +import * as fs from "fs" +import * as path from "path" +import { ColorScheme, createColorScheme } from "./common" +import { themes } from "./themes" +import { slugify } from "./utils/slugify" +import { colorSchemeTokens } from "./theme/tokens/colorScheme" + +const TOKENS_DIRECTORY = path.join(__dirname, "..", "target", "tokens") + +function clearTokens(tokensDirectory: string) { + if (!fs.existsSync(tokensDirectory)) { + fs.mkdirSync(tokensDirectory, { recursive: true }) + } else { + for (const file of fs.readdirSync(tokensDirectory)) { + if (file.endsWith(".json")) { + fs.unlinkSync(path.join(tokensDirectory, file)) + } + } + } +} + +function writeTokens(colorSchemes: ColorScheme[], tokensDirectory: string) { + clearTokens(tokensDirectory) + + for (const colorScheme of colorSchemes) { + const fileName = slugify(colorScheme.name) + const tokens = colorSchemeTokens(colorScheme) + const tokensJSON = JSON.stringify(tokens, null, 2) + const outPath = path.join(tokensDirectory, `${fileName}.json`) + fs.writeFileSync(outPath, tokensJSON) + console.log(`- ${outPath} created`) + } +} + +const colorSchemes: ColorScheme[] = themes.map((theme) => + createColorScheme(theme) +) + +writeTokens(colorSchemes, TOKENS_DIRECTORY) diff --git a/styles/src/theme/tokens/colorScheme.ts b/styles/src/theme/tokens/colorScheme.ts new file mode 100644 index 0000000000..eaf0705e14 --- /dev/null +++ b/styles/src/theme/tokens/colorScheme.ts @@ -0,0 +1,12 @@ +import { ColorScheme } from "../colorScheme" +import { PlayerTokens, players } from "./players" + +interface ColorSchemeTokens { + players: PlayerTokens +} + +export function colorSchemeTokens(colorScheme: ColorScheme): ColorSchemeTokens { + return { + players: players(colorScheme), + } +} diff --git a/styles/src/theme/tokens/players.ts b/styles/src/theme/tokens/players.ts new file mode 100644 index 0000000000..c65fb6885e --- /dev/null +++ b/styles/src/theme/tokens/players.ts @@ -0,0 +1,28 @@ +import { SingleColorToken } from "@tokens-studio/types" +import { ColorScheme, Players } from "../../common" +import { colorToken } from "./token" + +export type PlayerToken = Record<"selection" | "cursor", SingleColorToken> + +export type PlayerTokens = Record + +function buildPlayerToken(colorScheme: ColorScheme, index: number): PlayerToken { + + const playerNumber = index.toString() as keyof Players + + return { + selection: colorToken(`player${index}Selection`, colorScheme.players[playerNumber].selection), + cursor: colorToken(`player${index}Cursor`, colorScheme.players[playerNumber].cursor), + } +} + +export const players = (colorScheme: ColorScheme): PlayerTokens => ({ + "0": buildPlayerToken(colorScheme, 0), + "1": buildPlayerToken(colorScheme, 1), + "2": buildPlayerToken(colorScheme, 2), + "3": buildPlayerToken(colorScheme, 3), + "4": buildPlayerToken(colorScheme, 4), + "5": buildPlayerToken(colorScheme, 5), + "6": buildPlayerToken(colorScheme, 6), + "7": buildPlayerToken(colorScheme, 7) +}) diff --git a/styles/src/theme/tokens/token.ts b/styles/src/theme/tokens/token.ts new file mode 100644 index 0000000000..3e5187dd64 --- /dev/null +++ b/styles/src/theme/tokens/token.ts @@ -0,0 +1,14 @@ +import { SingleColorToken, TokenTypes } from "@tokens-studio/types" + +export function colorToken(name: string, value: string, description?: string): SingleColorToken { + const token: SingleColorToken = { + name, + type: TokenTypes.COLOR, + value, + description, + } + + if (!token.value || token.value === '') throw new Error("Color token must have a value") + + return token +} diff --git a/styles/src/utils/slugify.ts b/styles/src/utils/slugify.ts new file mode 100644 index 0000000000..62b226cd10 --- /dev/null +++ b/styles/src/utils/slugify.ts @@ -0,0 +1 @@ +export function slugify(t: string): string { return t.toString().toLowerCase().replace(/\s+/g, '-').replace(/[^\w\-]+/g, '').replace(/\-\-+/g, '-').replace(/^-+/, '').replace(/-+$/, '') }