@digdir/designsystemet 0.1.0-alpha.9 → 0.1.0-next.21
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.
- package/dist/bin/designsystemet.js +34 -0
- package/dist/src/colors/colorUtils.js +242 -0
- package/dist/src/colors/index.js +3 -0
- package/dist/src/colors/themeUtils.js +245 -0
- package/dist/src/colors/types.js +0 -0
- package/dist/src/init/createTokensPackage.js +250 -0
- package/dist/src/init/generateMetadataJson.js +19 -0
- package/dist/src/init/generateThemesJson.js +52 -0
- package/dist/src/init/index.js +10 -0
- package/dist/src/init/nextStepsMarkdown.js +92 -0
- package/dist/src/init/template/default-files/README.md +10 -0
- package/dist/src/init/template/default-files/design-tokens/README.md +3 -0
- package/dist/src/init/template/default-files/design-tokens/primitives/globals.json +197 -0
- package/dist/src/init/template/default-files/design-tokens/primitives/typography/default.json +86 -0
- package/dist/src/init/template/default-files/design-tokens/semantic/color.json +562 -0
- package/dist/src/init/template/default-files/design-tokens/semantic/style.json +543 -0
- package/dist/src/init/template/prettier.config.js +5 -0
- package/dist/src/init/template/template-files/design-tokens/primitives/colors/contrast/global.json +376 -0
- package/dist/src/init/template/template-files/design-tokens/primitives/colors/contrast/theme-template.json +314 -0
- package/dist/src/init/template/template-files/design-tokens/primitives/colors/dark/global.json +376 -0
- package/dist/src/init/template/template-files/design-tokens/primitives/colors/dark/theme-template.json +314 -0
- package/dist/src/init/template/template-files/design-tokens/primitives/colors/light/global.json +376 -0
- package/dist/src/init/template/template-files/design-tokens/primitives/colors/light/theme-template.json +314 -0
- package/dist/src/init/template/template-files/design-tokens/themes/theme-template.json +314 -0
- package/dist/src/init/template/template-files/package.json +24 -0
- package/dist/src/init/utils.js +15 -0
- package/dist/src/migrations/beta-to-v1.js +344 -0
- package/dist/src/migrations/codemods/css/plugins.js +47 -0
- package/dist/src/migrations/codemods/css/run.js +19 -0
- package/dist/src/migrations/codemods/jsx/classname-prefix.js +63 -0
- package/dist/src/migrations/codemods/jsx/run.js +22 -0
- package/dist/src/migrations/index.js +9 -0
- package/dist/src/migrations/react-beta-to-v1.js +5 -0
- package/dist/src/tokens/actions.js +33 -0
- package/dist/src/tokens/build.js +74 -0
- package/dist/src/tokens/configs.js +223 -0
- package/dist/src/tokens/formats/css.js +170 -0
- package/dist/src/tokens/formats/js-tokens.js +31 -0
- package/dist/src/tokens/transformers.js +47 -0
- package/dist/src/tokens/utils/noCase.js +24 -0
- package/dist/src/tokens/utils/permutateThemes.js +64 -0
- package/dist/src/tokens/utils/utils.js +14 -0
- package/package.json +21 -13
- package/LICENSE +0 -7
- package/dist/build/bin/designsystemet.js +0 -50
- package/dist/build/src/colors/colorUtils.js +0 -314
- package/dist/build/src/colors/index.js +0 -3
- package/dist/build/src/colors/themeUtils.js +0 -290
- package/dist/build/src/colors/types.js +0 -1
- package/dist/build/src/migrations/beta-to-v1.js +0 -341
- package/dist/build/src/migrations/codemods/css/plugins.js +0 -45
- package/dist/build/src/migrations/codemods/css/run.js +0 -17
- package/dist/build/src/migrations/codemods/jsx/classname-prefix.js +0 -80
- package/dist/build/src/migrations/codemods/jsx/run.js +0 -19
- package/dist/build/src/migrations/index.js +0 -6
- package/dist/build/src/migrations/react-beta-to-v1.js +0 -2
- package/dist/build/src/test/jsx-test.js +0 -10
- package/dist/build/src/tokens/actions.js +0 -20
- package/dist/build/src/tokens/build.js +0 -63
- package/dist/build/src/tokens/configs.js +0 -229
- package/dist/build/src/tokens/formats/css-classes.js +0 -50
- package/dist/build/src/tokens/formats/css-variables.js +0 -39
- package/dist/build/src/tokens/formats/js-tokens.js +0 -29
- package/dist/build/src/tokens/transformers.js +0 -42
- package/dist/build/src/tokens/utils/noCase.js +0 -30
- package/dist/build/src/tokens/utils/permutateThemes.js +0 -56
- package/dist/build/src/tokens/utils/utils.js +0 -21
- package/dist/build/tsconfig.tsbuildinfo +0 -1
- package/dist/types/bin/designsystemet.d.ts +0 -3
- package/dist/types/bin/designsystemet.d.ts.map +0 -1
- package/dist/types/src/colors/colorUtils.d.ts +0 -118
- package/dist/types/src/colors/colorUtils.d.ts.map +0 -1
- package/dist/types/src/colors/index.d.ts +0 -4
- package/dist/types/src/colors/index.d.ts.map +0 -1
- package/dist/types/src/colors/themeUtils.d.ts +0 -101
- package/dist/types/src/colors/themeUtils.d.ts.map +0 -1
- package/dist/types/src/colors/types.d.ts +0 -16
- package/dist/types/src/colors/types.d.ts.map +0 -1
- package/dist/types/src/migrations/beta-to-v1.d.ts +0 -3
- package/dist/types/src/migrations/beta-to-v1.d.ts.map +0 -1
- package/dist/types/src/migrations/codemods/css/plugins.d.ts +0 -6
- package/dist/types/src/migrations/codemods/css/plugins.d.ts.map +0 -1
- package/dist/types/src/migrations/codemods/css/run.d.ts +0 -8
- package/dist/types/src/migrations/codemods/css/run.d.ts.map +0 -1
- package/dist/types/src/migrations/codemods/jsx/classname-prefix.d.ts +0 -10
- package/dist/types/src/migrations/codemods/jsx/classname-prefix.d.ts.map +0 -1
- package/dist/types/src/migrations/codemods/jsx/run.d.ts +0 -7
- package/dist/types/src/migrations/codemods/jsx/run.d.ts.map +0 -1
- package/dist/types/src/migrations/index.d.ts +0 -6
- package/dist/types/src/migrations/index.d.ts.map +0 -1
- package/dist/types/src/migrations/react-beta-to-v1.d.ts +0 -3
- package/dist/types/src/migrations/react-beta-to-v1.d.ts.map +0 -1
- package/dist/types/src/test/jsx-test.d.ts +0 -4
- package/dist/types/src/test/jsx-test.d.ts.map +0 -1
- package/dist/types/src/tokens/actions.d.ts +0 -3
- package/dist/types/src/tokens/actions.d.ts.map +0 -1
- package/dist/types/src/tokens/build.d.ts +0 -11
- package/dist/types/src/tokens/build.d.ts.map +0 -1
- package/dist/types/src/tokens/configs.d.ts +0 -23
- package/dist/types/src/tokens/configs.d.ts.map +0 -1
- package/dist/types/src/tokens/formats/css-classes.d.ts +0 -6
- package/dist/types/src/tokens/formats/css-classes.d.ts.map +0 -1
- package/dist/types/src/tokens/formats/css-variables.d.ts +0 -3
- package/dist/types/src/tokens/formats/css-variables.d.ts.map +0 -1
- package/dist/types/src/tokens/formats/js-tokens.d.ts +0 -6
- package/dist/types/src/tokens/formats/js-tokens.d.ts.map +0 -1
- package/dist/types/src/tokens/transformers.d.ts +0 -5
- package/dist/types/src/tokens/transformers.d.ts.map +0 -1
- package/dist/types/src/tokens/utils/noCase.d.ts +0 -11
- package/dist/types/src/tokens/utils/noCase.d.ts.map +0 -1
- package/dist/types/src/tokens/utils/permutateThemes.d.ts +0 -7
- package/dist/types/src/tokens/utils/permutateThemes.d.ts.map +0 -1
- package/dist/types/src/tokens/utils/utils.d.ts +0 -17
- package/dist/types/src/tokens/utils/utils.d.ts.map +0 -1
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import prompts from "prompts";
|
|
5
|
+
import generateMetadata from "./generateMetadataJson.js";
|
|
6
|
+
import generateThemes from "./generateThemesJson.js";
|
|
7
|
+
import { nextStepsMarkdown } from "./nextStepsMarkdown.js";
|
|
8
|
+
import packageJsonTemplate from "./template/template-files/package.json" with { type: "json" };
|
|
9
|
+
import { normalizeTokenSetName, toGeneratedCssFileName, toValidPackageName } from "./utils.js";
|
|
10
|
+
const MODES = ["Light", "Dark", "Contrast"];
|
|
11
|
+
const promptOptions = {
|
|
12
|
+
onCancel: () => {
|
|
13
|
+
console.log(`${chalk.red("\u2716")} Operation cancelled`);
|
|
14
|
+
process.exit();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
async function createTokensPackage(targetDir) {
|
|
18
|
+
const DIRNAME = import.meta.dirname || __dirname;
|
|
19
|
+
const DEFAULT_FILES_PATH = path.join(DIRNAME, "./template/default-files");
|
|
20
|
+
const TOKEN_TEMPLATE_FILES_PATH = path.join(DIRNAME, "./template/template-files/design-tokens");
|
|
21
|
+
const TARGET_DIR = path.resolve(process.cwd(), targetDir);
|
|
22
|
+
const initialPackageName = toValidPackageName(path.basename(TARGET_DIR));
|
|
23
|
+
let isTargetDirEmpty = true;
|
|
24
|
+
try {
|
|
25
|
+
const files = await fs.readdir(TARGET_DIR);
|
|
26
|
+
isTargetDirEmpty = files.length === 0;
|
|
27
|
+
} catch (err) {
|
|
28
|
+
if (err.code === "ENOENT") {
|
|
29
|
+
} else {
|
|
30
|
+
console.error(err);
|
|
31
|
+
console.log("Continuing...");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const { directoryAction } = await prompts(
|
|
35
|
+
{
|
|
36
|
+
name: "directoryAction",
|
|
37
|
+
type: isTargetDirEmpty ? null : "select",
|
|
38
|
+
message: "Target directory is not empty. How should we proceed?",
|
|
39
|
+
choices: [
|
|
40
|
+
{
|
|
41
|
+
title: "Clean",
|
|
42
|
+
value: "clean",
|
|
43
|
+
description: "Empty the directory and continue"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: "Ignore",
|
|
47
|
+
value: "ignore",
|
|
48
|
+
description: "Keep directory as is. Files may be overwritten with new output."
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
title: "Exit",
|
|
52
|
+
value: "exit",
|
|
53
|
+
description: "Exit without doing anything."
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
promptOptions
|
|
58
|
+
);
|
|
59
|
+
if (directoryAction === "exit") {
|
|
60
|
+
process.exit();
|
|
61
|
+
}
|
|
62
|
+
const { packageName } = await prompts(
|
|
63
|
+
[
|
|
64
|
+
{
|
|
65
|
+
name: "packageName",
|
|
66
|
+
type: "text",
|
|
67
|
+
message: "Enter a package name (for package.json)",
|
|
68
|
+
initial: initialPackageName
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
promptOptions
|
|
72
|
+
);
|
|
73
|
+
const { modes, themeCount, tokensDir } = await prompts(
|
|
74
|
+
[
|
|
75
|
+
{
|
|
76
|
+
name: "themeCount",
|
|
77
|
+
type: "number",
|
|
78
|
+
message: "How many themes do you want?",
|
|
79
|
+
initial: 1,
|
|
80
|
+
min: 1
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "modes",
|
|
84
|
+
type: "multiselect",
|
|
85
|
+
choices: MODES.filter((x) => x !== "Light").map((mode) => ({
|
|
86
|
+
title: mode,
|
|
87
|
+
value: mode
|
|
88
|
+
})),
|
|
89
|
+
message: "Which color modes do you want?",
|
|
90
|
+
instructions: `
|
|
91
|
+
Instructions:
|
|
92
|
+
\u2191/\u2193: Highlight option
|
|
93
|
+
\u2190/\u2192/[space]: Toggle selection
|
|
94
|
+
a: Toggle all
|
|
95
|
+
enter/return: Complete answer
|
|
96
|
+
${chalk.green("\u25C9")} Light ${chalk.dim("- This is the default mode, and cannot be disabled")}`,
|
|
97
|
+
onState: (obj) => {
|
|
98
|
+
obj.value.unshift({ title: "Light", value: "Light", selected: true });
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "tokensDir",
|
|
103
|
+
type: "text",
|
|
104
|
+
initial: "design-tokens",
|
|
105
|
+
message: `Enter the desired path for the design tokens`
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
promptOptions
|
|
109
|
+
);
|
|
110
|
+
const themes = [];
|
|
111
|
+
const TOKENS_TARGET_DIR = path.join(TARGET_DIR, tokensDir);
|
|
112
|
+
for (let n = 1; n <= themeCount; n++) {
|
|
113
|
+
const theme = await prompts(
|
|
114
|
+
[
|
|
115
|
+
{
|
|
116
|
+
name: "name",
|
|
117
|
+
type: "text",
|
|
118
|
+
message: `Enter the name of the ${ordinal(n)} theme`,
|
|
119
|
+
validate: (value) => isValidThemeName(themes, value)
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
promptOptions
|
|
123
|
+
);
|
|
124
|
+
themes.push(theme.name);
|
|
125
|
+
}
|
|
126
|
+
const { defaultTheme = themes[0] } = await prompts(
|
|
127
|
+
{
|
|
128
|
+
name: "defaultTheme",
|
|
129
|
+
type: themeCount === 1 ? null : "select",
|
|
130
|
+
message: "Select the default theme to export in package.json",
|
|
131
|
+
choices: themes.map((theme) => ({ title: theme, value: theme })),
|
|
132
|
+
initial: 0
|
|
133
|
+
},
|
|
134
|
+
promptOptions
|
|
135
|
+
);
|
|
136
|
+
console.log(
|
|
137
|
+
`
|
|
138
|
+
Will now create the following:
|
|
139
|
+
${chalk.bold("Package name")}: ${packageName}
|
|
140
|
+
${chalk.bold("Directory")}: ${TARGET_DIR}
|
|
141
|
+
${chalk.bold("Tokens directory")}: ${TOKENS_TARGET_DIR}
|
|
142
|
+
${chalk.bold("Themes")}: ${themes.join(", ")}
|
|
143
|
+
${chalk.bold("Default theme")}: ${defaultTheme}
|
|
144
|
+
${chalk.bold("Color modes")}: ${modes.join(", ")}
|
|
145
|
+
`
|
|
146
|
+
);
|
|
147
|
+
if (directoryAction === "clean") {
|
|
148
|
+
console.log(chalk.bold.red(`Warning: Contents of ${TARGET_DIR} will be deleted`));
|
|
149
|
+
}
|
|
150
|
+
if (directoryAction === "ignore") {
|
|
151
|
+
console.log(chalk.bold.yellow(`Warning: Existing files in ${TARGET_DIR} may be overwritten`));
|
|
152
|
+
}
|
|
153
|
+
const res = await prompts(
|
|
154
|
+
{
|
|
155
|
+
name: "proceed",
|
|
156
|
+
type: "confirm",
|
|
157
|
+
message: "Proceed?",
|
|
158
|
+
initial: directoryAction === void 0
|
|
159
|
+
// default to proceeding if the output directory is empty
|
|
160
|
+
},
|
|
161
|
+
promptOptions
|
|
162
|
+
);
|
|
163
|
+
if (!res.proceed) {
|
|
164
|
+
process.exit();
|
|
165
|
+
}
|
|
166
|
+
if (directoryAction === "clean") {
|
|
167
|
+
await fs.rm(TARGET_DIR, { recursive: true });
|
|
168
|
+
}
|
|
169
|
+
await fs.cp(DEFAULT_FILES_PATH, path.join(TARGET_DIR), {
|
|
170
|
+
recursive: true
|
|
171
|
+
});
|
|
172
|
+
if (tokensDir !== "design-tokens") {
|
|
173
|
+
await fs.rename(path.join(TARGET_DIR, "design-tokens"), path.join(TOKENS_TARGET_DIR));
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
await fs.mkdir(path.join(TOKENS_TARGET_DIR, "themes"));
|
|
177
|
+
} catch {
|
|
178
|
+
}
|
|
179
|
+
for (const theme of themes.map(normalizeTokenSetName)) {
|
|
180
|
+
for (const mode of modes.map(normalizeTokenSetName)) {
|
|
181
|
+
await fs.cp(
|
|
182
|
+
path.join(TOKEN_TEMPLATE_FILES_PATH, `primitives/colors/${mode}/global.json`),
|
|
183
|
+
path.join(TOKENS_TARGET_DIR, `primitives/colors/${mode}/global.json`),
|
|
184
|
+
{ recursive: true }
|
|
185
|
+
);
|
|
186
|
+
const template2 = await fs.readFile(
|
|
187
|
+
path.join(TOKEN_TEMPLATE_FILES_PATH, `primitives/colors/${mode}/theme-template.json`)
|
|
188
|
+
);
|
|
189
|
+
await fs.writeFile(
|
|
190
|
+
path.join(TOKENS_TARGET_DIR, `primitives/colors/${mode}/${theme}.json`),
|
|
191
|
+
template2.toString("utf-8").replaceAll("<theme>", theme)
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
const template = await fs.readFile(path.join(TOKEN_TEMPLATE_FILES_PATH, `themes/theme-template.json`));
|
|
195
|
+
await fs.writeFile(
|
|
196
|
+
path.join(TOKENS_TARGET_DIR, `themes/${theme}.json`),
|
|
197
|
+
template.toString("utf-8").replaceAll("<theme>", theme)
|
|
198
|
+
);
|
|
199
|
+
await fs.writeFile(
|
|
200
|
+
path.join(TOKENS_TARGET_DIR, "$metadata.json"),
|
|
201
|
+
JSON.stringify(generateMetadata(modes, themes), void 0, 2)
|
|
202
|
+
);
|
|
203
|
+
await fs.writeFile(
|
|
204
|
+
path.join(TOKENS_TARGET_DIR, "$themes.json"),
|
|
205
|
+
JSON.stringify(generateThemes(modes, themes), void 0, 2)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
packageJsonTemplate.name = packageName;
|
|
209
|
+
packageJsonTemplate.main = packageJsonTemplate.main.replaceAll(
|
|
210
|
+
"<default-theme>",
|
|
211
|
+
toGeneratedCssFileName(defaultTheme)
|
|
212
|
+
);
|
|
213
|
+
await fs.writeFile(path.join(TARGET_DIR, "package.json"), JSON.stringify(packageJsonTemplate, void 0, 2));
|
|
214
|
+
const readmePath = path.join(TARGET_DIR, "README.md");
|
|
215
|
+
const currentReadme = await fs.readFile(readmePath);
|
|
216
|
+
await fs.writeFile(
|
|
217
|
+
readmePath,
|
|
218
|
+
[currentReadme.toString("utf-8"), nextStepsMarkdown(themes, modes, tokensDir, packageName)].join("\n")
|
|
219
|
+
);
|
|
220
|
+
console.log("\u{1F389} Files successfully generated!");
|
|
221
|
+
console.log(`Read about the next steps in the generated README at ${readmePath}`);
|
|
222
|
+
}
|
|
223
|
+
function isValidThemeName(themes, value) {
|
|
224
|
+
const s = value.trim();
|
|
225
|
+
if (s.length === 0) {
|
|
226
|
+
return "Theme name cannot be empty.";
|
|
227
|
+
}
|
|
228
|
+
if (themes.includes(s)) {
|
|
229
|
+
return "Theme names must be unique.";
|
|
230
|
+
}
|
|
231
|
+
if (/[^a-zæøå0-9 _-]/i.test(s)) {
|
|
232
|
+
return "Theme name can only contain letters, numbers, dashes and underscores.";
|
|
233
|
+
}
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
function ordinal(n) {
|
|
237
|
+
switch (n) {
|
|
238
|
+
case 1:
|
|
239
|
+
return "1st";
|
|
240
|
+
case 2:
|
|
241
|
+
return "2nd";
|
|
242
|
+
case 3:
|
|
243
|
+
return "3rd";
|
|
244
|
+
default:
|
|
245
|
+
return `${n}th`;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
export {
|
|
249
|
+
createTokensPackage
|
|
250
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { normalizeTokenSetName } from "./utils.js";
|
|
2
|
+
function generateMetadataJson(modes, themes) {
|
|
3
|
+
return {
|
|
4
|
+
tokenSetOrder: [
|
|
5
|
+
"primitives/globals",
|
|
6
|
+
"primitives/typography/default",
|
|
7
|
+
...modes.flatMap((mode) => [
|
|
8
|
+
`primitives/colors/${normalizeTokenSetName(mode)}/global`,
|
|
9
|
+
...themes.map((theme) => `primitives/colors/${normalizeTokenSetName(mode)}/${normalizeTokenSetName(theme)}`)
|
|
10
|
+
]),
|
|
11
|
+
...themes.map((theme) => `themes/${normalizeTokenSetName(theme)}`),
|
|
12
|
+
"semantic/color",
|
|
13
|
+
"semantic/style"
|
|
14
|
+
]
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
generateMetadataJson as default
|
|
19
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { TokenSetStatus } from "@tokens-studio/types";
|
|
3
|
+
import { normalizeTokenSetName } from "./utils.js";
|
|
4
|
+
function generateThemesJson(modes, themes) {
|
|
5
|
+
return [...generateModesGroup(modes, themes), ...generateThemesGroup(themes), generateSemanticGroup()];
|
|
6
|
+
}
|
|
7
|
+
function generateModesGroup(modes, themes) {
|
|
8
|
+
return modes.map(
|
|
9
|
+
(mode) => ({
|
|
10
|
+
id: randomUUID(),
|
|
11
|
+
name: mode,
|
|
12
|
+
selectedTokenSets: Object.fromEntries([
|
|
13
|
+
[`primitives/colors/${normalizeTokenSetName(mode)}/global`, TokenSetStatus.ENABLED],
|
|
14
|
+
...themes.map(
|
|
15
|
+
(theme) => [
|
|
16
|
+
`primitives/colors/${normalizeTokenSetName(mode)}/${normalizeTokenSetName(theme)}`,
|
|
17
|
+
TokenSetStatus.ENABLED
|
|
18
|
+
]
|
|
19
|
+
)
|
|
20
|
+
]),
|
|
21
|
+
group: "Mode"
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
function generateThemesGroup(themes) {
|
|
26
|
+
return themes.map(
|
|
27
|
+
(theme) => ({
|
|
28
|
+
id: randomUUID(),
|
|
29
|
+
name: theme,
|
|
30
|
+
selectedTokenSets: {
|
|
31
|
+
[`themes/${normalizeTokenSetName(theme)}`]: TokenSetStatus.ENABLED
|
|
32
|
+
},
|
|
33
|
+
group: "Theme"
|
|
34
|
+
})
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
function generateSemanticGroup() {
|
|
38
|
+
return {
|
|
39
|
+
id: randomUUID(),
|
|
40
|
+
name: "Semantic",
|
|
41
|
+
selectedTokenSets: {
|
|
42
|
+
"semantic/style": TokenSetStatus.ENABLED,
|
|
43
|
+
"semantic/color": TokenSetStatus.ENABLED,
|
|
44
|
+
"primitives/globals": TokenSetStatus.SOURCE,
|
|
45
|
+
"primitives/typography/default": TokenSetStatus.SOURCE
|
|
46
|
+
},
|
|
47
|
+
group: "Semantic"
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
generateThemesJson as default
|
|
52
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Argument } from "@commander-js/extra-typings";
|
|
2
|
+
import { createTokensPackage } from "./createTokensPackage.js";
|
|
3
|
+
function makeInitCommand(command) {
|
|
4
|
+
return command.showHelpAfterError().description("create an initial token structure for Designsystemet").addArgument(new Argument("<targetDir>", "Target directory for the generated code")).action(async (targetDir) => {
|
|
5
|
+
await createTokensPackage(targetDir);
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
makeInitCommand
|
|
10
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { normalizeTokenSetName, toGeneratedCssFileName } from "./utils.js";
|
|
2
|
+
function nextStepsMarkdown(themes, modes, tokensTargetDir, packageName) {
|
|
3
|
+
const themeModeCombinations = themes.flatMap(
|
|
4
|
+
(theme) => modes.map((mode) => [theme, mode])
|
|
5
|
+
);
|
|
6
|
+
const themeOrThemes = `theme${themes.length > 1 ? "s" : ""}`;
|
|
7
|
+
const isOrAre = themes.length > 1 ? "are" : "is";
|
|
8
|
+
return `
|
|
9
|
+
## Next steps
|
|
10
|
+
|
|
11
|
+
### Using the ${themeOrThemes} in Figma
|
|
12
|
+
|
|
13
|
+
1. Initialise a git repository in the current directory
|
|
14
|
+
2. Push the tokens to GitHub, GitLab or Azure DevOps
|
|
15
|
+
3. [Open the Figma component library](https://www.figma.com/community/file/1322138390374166141/designsystemet-core-ui-kit) and save it to your project
|
|
16
|
+
4. Install the [Tokens Studio plugin](https://www.figma.com/community/plugin/843461159747178978/Tokens-Studio-for-Figma-(Figma-Tokens)) in Figma
|
|
17
|
+
5. [Set up sync](https://docs.tokens.studio/sync/sync) in Tokens Studio for Figma
|
|
18
|
+
6. Use the ["Create variables" action](https://docs.tokens.studio/variables/creating-variables) in Tokens Studio
|
|
19
|
+
7. Push the resulting variables from Tokens Studio to Git
|
|
20
|
+
|
|
21
|
+
### Customizing the ${themeOrThemes}
|
|
22
|
+
|
|
23
|
+
1. Go to https://theme.designsystemet.no and set up a color theme
|
|
24
|
+
2. Press "Kopier tema"
|
|
25
|
+
3. Under "Json til Figma", copy the contents under ${modes.join(" / ")} to
|
|
26
|
+
the corresponding file under \`${tokensTargetDir}\`:
|
|
27
|
+
${themeModeCombinations.map(([theme, mode]) => ` **${theme}, ${mode}**: \`primitives/colors/${normalizeTokenSetName(mode)}/${normalizeTokenSetName(theme)}.json\` `).join("\n")}
|
|
28
|
+
This can also be done in Tokens Studio for Figma.
|
|
29
|
+
4. **IMPORTANT!** In the JSON data you copied, replace \`theme\` on line 2
|
|
30
|
+
with the correct theme identifier, depending on the theme you're customizing.
|
|
31
|
+
This is the same as the json filename without extension (e.g. ${themes.map((x) => `\`${normalizeTokenSetName(x)}\``).join(", ")}).
|
|
32
|
+
${themes.length > 1 ? "5. Repeat steps 1\u20144 for the remaining themes" : ""}
|
|
33
|
+
|
|
34
|
+
### Using the correct ${themeOrThemes} in Figma components
|
|
35
|
+
|
|
36
|
+
The "Designsystemet - Core UI Kit" component library is set up with the themes
|
|
37
|
+
"Theme1" and "Theme2" by default. To ensure our custom ${themeOrThemes} ${isOrAre} used, follow these steps:
|
|
38
|
+
|
|
39
|
+
1. Open your copy of "Designsystemet - Core UI Kit" in Figma
|
|
40
|
+
2. Pull any changes from Git using Tokens Studio
|
|
41
|
+
3. Update the Figma variables using the "Styles & Variables" > "Sync variables" action in Tokens Studio
|
|
42
|
+
4. Access the [Variables modal](https://help.figma.com/hc/en-us/articles/15145852043927-Create-and-manage-variables)
|
|
43
|
+
5. Select the "Theme" collection in the upper left dropdown
|
|
44
|
+
6. Select "All variables"
|
|
45
|
+
7. Right click the modes "Theme1" and click "Delete mode"
|
|
46
|
+
8. Repeat for "Theme2"
|
|
47
|
+
9. Publish the library
|
|
48
|
+
|
|
49
|
+
### Updating the Figma components after theme changes
|
|
50
|
+
|
|
51
|
+
1. Open your copy of "Designsystemet - Core UI Kit" in Figma
|
|
52
|
+
2. Pull any changes from Git using Tokens Studio
|
|
53
|
+
3. Update the Figma variables using the "Styles & Variables" > "Sync variables" action in Tokens Studio
|
|
54
|
+
4. Publish the library
|
|
55
|
+
|
|
56
|
+
### Using the ${themeOrThemes} in code
|
|
57
|
+
|
|
58
|
+
The current directory is set up to easily publish the ${themeOrThemes} as an npm package.
|
|
59
|
+
|
|
60
|
+
1. Check that the package.json file is set up to your liking
|
|
61
|
+
2. \`npm install\`
|
|
62
|
+
3. \`npm run build\` - builds the css files for each theme and outputs them to \`./dist\`
|
|
63
|
+
4. \`npm publish\` - publishes the package to npm as \`${packageName}\`, unless you manually changed \`package.json\`
|
|
64
|
+
|
|
65
|
+
In a different npm package (e.g. a frontend web app), follow the "Get started"
|
|
66
|
+
instructions at https://github.com/digdir/designsystemet but replace
|
|
67
|
+
\`@digdir/designsystemet-theme\` with \`${packageName}\`. In short:
|
|
68
|
+
|
|
69
|
+
#### Install packages
|
|
70
|
+
|
|
71
|
+
\`\`\`
|
|
72
|
+
npm i ${packageName} @digdir/designsystemet-css @digdir/designsystemet-react
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
#### Import the default theme and use components
|
|
76
|
+
|
|
77
|
+
\`\`\`js
|
|
78
|
+
import '${packageName}';
|
|
79
|
+
import '@digdir/designsystemet-css';
|
|
80
|
+
import { Button } from '@digdir/designsystemet-react';
|
|
81
|
+
\`\`\`
|
|
82
|
+
|
|
83
|
+
${themes.length > 1 ? `
|
|
84
|
+
#### Or import a specific theme
|
|
85
|
+
\`\`\`js
|
|
86
|
+
import '${packageName}/${toGeneratedCssFileName(themes[1])}';
|
|
87
|
+
\`\`\`
|
|
88
|
+
`.trim() : ""}`;
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
nextStepsMarkdown
|
|
92
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
{
|
|
2
|
+
"border-width": {
|
|
3
|
+
"1": {
|
|
4
|
+
"type": "borderWidth",
|
|
5
|
+
"value": "1px"
|
|
6
|
+
},
|
|
7
|
+
"2": {
|
|
8
|
+
"type": "borderWidth",
|
|
9
|
+
"value": "2px"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"shadow": {
|
|
13
|
+
"100": {
|
|
14
|
+
"type": "boxShadow",
|
|
15
|
+
"value": [
|
|
16
|
+
{
|
|
17
|
+
"color": "rgba(0,0,0,0.16)",
|
|
18
|
+
"type": "dropShadow",
|
|
19
|
+
"x": "0",
|
|
20
|
+
"y": "0",
|
|
21
|
+
"blur": "1",
|
|
22
|
+
"spread": "0"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"x": "0",
|
|
26
|
+
"y": "1",
|
|
27
|
+
"blur": "2",
|
|
28
|
+
"spread": "0",
|
|
29
|
+
"color": "rgba(0,0,0,0.12)",
|
|
30
|
+
"type": "dropShadow"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"200": {
|
|
35
|
+
"type": "boxShadow",
|
|
36
|
+
"value": [
|
|
37
|
+
{
|
|
38
|
+
"color": "rgba(0,0,0,0.15)",
|
|
39
|
+
"type": "dropShadow",
|
|
40
|
+
"x": "0",
|
|
41
|
+
"y": "0",
|
|
42
|
+
"blur": "1",
|
|
43
|
+
"spread": "0"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"color": "rgba(0,0,0,0.12)",
|
|
47
|
+
"type": "dropShadow",
|
|
48
|
+
"x": "0",
|
|
49
|
+
"y": "1",
|
|
50
|
+
"blur": "2",
|
|
51
|
+
"spread": "0"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"x": "0",
|
|
55
|
+
"y": "2",
|
|
56
|
+
"blur": "4",
|
|
57
|
+
"spread": "0",
|
|
58
|
+
"color": "rgba(0,0,0,0.1)",
|
|
59
|
+
"type": "dropShadow"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"300": {
|
|
64
|
+
"type": "boxShadow",
|
|
65
|
+
"value": [
|
|
66
|
+
{
|
|
67
|
+
"color": "rgba(0,0,0,0.14)",
|
|
68
|
+
"type": "dropShadow",
|
|
69
|
+
"x": "0",
|
|
70
|
+
"y": "0",
|
|
71
|
+
"blur": "1",
|
|
72
|
+
"spread": "0"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"color": "rgba(0,0,0,0.12)",
|
|
76
|
+
"type": "dropShadow",
|
|
77
|
+
"x": "0",
|
|
78
|
+
"y": "2",
|
|
79
|
+
"blur": "4",
|
|
80
|
+
"spread": "0"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"x": "0",
|
|
84
|
+
"y": "4",
|
|
85
|
+
"blur": "8",
|
|
86
|
+
"spread": "0",
|
|
87
|
+
"color": "rgba(0,0,0,0.12)",
|
|
88
|
+
"type": "dropShadow"
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
"400": {
|
|
93
|
+
"type": "boxShadow",
|
|
94
|
+
"value": [
|
|
95
|
+
{
|
|
96
|
+
"color": "rgba(0,0,0,0.13)",
|
|
97
|
+
"type": "dropShadow",
|
|
98
|
+
"x": "0",
|
|
99
|
+
"y": "0",
|
|
100
|
+
"blur": "1",
|
|
101
|
+
"spread": "0"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"color": "rgba(0,0,0,0.13)",
|
|
105
|
+
"type": "dropShadow",
|
|
106
|
+
"x": "0",
|
|
107
|
+
"y": "3",
|
|
108
|
+
"blur": "5",
|
|
109
|
+
"spread": "0"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"x": "0",
|
|
113
|
+
"y": "6",
|
|
114
|
+
"blur": "12",
|
|
115
|
+
"spread": "0",
|
|
116
|
+
"color": "rgba(0,0,0,0.14)",
|
|
117
|
+
"type": "dropShadow"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
"500": {
|
|
122
|
+
"type": "boxShadow",
|
|
123
|
+
"value": [
|
|
124
|
+
{
|
|
125
|
+
"color": "rgba(0,0,0,0.12)",
|
|
126
|
+
"type": "dropShadow",
|
|
127
|
+
"x": "0",
|
|
128
|
+
"y": "0",
|
|
129
|
+
"blur": "1",
|
|
130
|
+
"spread": "0"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"color": "rgba(0,0,0,0.16)",
|
|
134
|
+
"type": "dropShadow",
|
|
135
|
+
"x": "0",
|
|
136
|
+
"y": "4",
|
|
137
|
+
"blur": "8",
|
|
138
|
+
"spread": "0"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"x": "0",
|
|
142
|
+
"y": "12",
|
|
143
|
+
"blur": "24",
|
|
144
|
+
"spread": "0",
|
|
145
|
+
"color": "rgba(0,0,0,0.16)",
|
|
146
|
+
"type": "dropShadow"
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"border-radius": {
|
|
152
|
+
"2": {
|
|
153
|
+
"type": "borderRadius",
|
|
154
|
+
"value": "2"
|
|
155
|
+
},
|
|
156
|
+
"4": {
|
|
157
|
+
"type": "borderRadius",
|
|
158
|
+
"value": "4"
|
|
159
|
+
},
|
|
160
|
+
"8": {
|
|
161
|
+
"type": "borderRadius",
|
|
162
|
+
"value": "8"
|
|
163
|
+
},
|
|
164
|
+
"12": {
|
|
165
|
+
"type": "borderRadius",
|
|
166
|
+
"value": "12"
|
|
167
|
+
},
|
|
168
|
+
"16": {
|
|
169
|
+
"type": "borderRadius",
|
|
170
|
+
"value": "16"
|
|
171
|
+
},
|
|
172
|
+
"24": {
|
|
173
|
+
"type": "borderRadius",
|
|
174
|
+
"value": "24"
|
|
175
|
+
},
|
|
176
|
+
"32": {
|
|
177
|
+
"type": "borderRadius",
|
|
178
|
+
"value": "32"
|
|
179
|
+
},
|
|
180
|
+
"9999": {
|
|
181
|
+
"type": "borderRadius",
|
|
182
|
+
"value": "9999"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"opacity": {
|
|
186
|
+
"30": {
|
|
187
|
+
"type": "opacity",
|
|
188
|
+
"value": "30%"
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"sizing": {
|
|
192
|
+
"base": {
|
|
193
|
+
"type": "sizing",
|
|
194
|
+
"value": "4"
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|