@digdir/designsystemet 0.1.0-next.21 → 0.1.0-next.22
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 +2 -2
- package/dist/src/migrations/codemods/css/plugins.js +14 -15
- package/dist/src/migrations/codemods/jsx/classname-prefix.js +8 -7
- package/dist/src/tokens/actions.js +1 -1
- package/dist/src/tokens/build.js +26 -15
- package/dist/src/tokens/configs.js +20 -16
- package/dist/src/tokens/formats/css.js +36 -23
- package/dist/src/tokens/formats/js-tokens.js +8 -4
- package/dist/src/tokens/transformers.js +7 -3
- package/dist/src/tokens/utils/entryfile.js +31 -0
- package/dist/src/tokens/utils/permutateThemes.js +2 -2
- package/dist/src/tokens/utils/utils.js +11 -0
- package/dist/types/bin/designsystemet.d.ts +3 -0
- package/dist/types/bin/designsystemet.d.ts.map +1 -0
- package/dist/types/src/colors/colorUtils.d.ts +126 -0
- package/dist/types/src/colors/colorUtils.d.ts.map +1 -0
- package/dist/types/src/colors/index.d.ts +4 -0
- package/dist/types/src/colors/index.d.ts.map +1 -0
- package/dist/types/src/colors/themeUtils.d.ts +102 -0
- package/dist/types/src/colors/themeUtils.d.ts.map +1 -0
- package/dist/types/src/colors/types.d.ts +16 -0
- package/dist/types/src/colors/types.d.ts.map +1 -0
- package/dist/types/src/init/createTokensPackage.d.ts +5 -0
- package/dist/types/src/init/createTokensPackage.d.ts.map +1 -0
- package/dist/types/src/init/generateMetadataJson.d.ts +6 -0
- package/dist/types/src/init/generateMetadataJson.d.ts.map +1 -0
- package/dist/types/src/init/generateThemesJson.d.ts +3 -0
- package/dist/types/src/init/generateThemesJson.d.ts.map +1 -0
- package/dist/types/src/init/index.d.ts +3 -0
- package/dist/types/src/init/index.d.ts.map +1 -0
- package/dist/types/src/init/nextStepsMarkdown.d.ts +3 -0
- package/dist/types/src/init/nextStepsMarkdown.d.ts.map +1 -0
- package/dist/types/src/init/template/prettier.config.d.mts +9 -0
- package/dist/types/src/init/template/prettier.config.d.mts.map +1 -0
- package/dist/types/src/init/utils.d.ts +4 -0
- package/dist/types/src/init/utils.d.ts.map +1 -0
- package/dist/types/src/migrations/beta-to-v1.d.ts +3 -0
- package/dist/types/src/migrations/beta-to-v1.d.ts.map +1 -0
- package/dist/types/src/migrations/codemods/css/plugins.d.ts +6 -0
- package/dist/types/src/migrations/codemods/css/plugins.d.ts.map +1 -0
- package/dist/types/src/migrations/codemods/css/run.d.ts +8 -0
- package/dist/types/src/migrations/codemods/css/run.d.ts.map +1 -0
- package/dist/types/src/migrations/codemods/jsx/classname-prefix.d.ts +10 -0
- package/dist/types/src/migrations/codemods/jsx/classname-prefix.d.ts.map +1 -0
- package/dist/types/src/migrations/codemods/jsx/run.d.ts +7 -0
- package/dist/types/src/migrations/codemods/jsx/run.d.ts.map +1 -0
- package/dist/types/src/migrations/index.d.ts +6 -0
- package/dist/types/src/migrations/index.d.ts.map +1 -0
- package/dist/types/src/migrations/react-beta-to-v1.d.ts +3 -0
- package/dist/types/src/migrations/react-beta-to-v1.d.ts.map +1 -0
- package/dist/types/src/tokens/actions.d.ts +6 -0
- package/dist/types/src/tokens/actions.d.ts.map +1 -0
- package/dist/types/src/tokens/build.d.ts +11 -0
- package/dist/types/src/tokens/build.d.ts.map +1 -0
- package/dist/types/src/tokens/configs.d.ts +31 -0
- package/dist/types/src/tokens/configs.d.ts.map +1 -0
- package/dist/types/src/tokens/formats/css.d.ts +5 -0
- package/dist/types/src/tokens/formats/css.d.ts.map +1 -0
- package/dist/types/src/tokens/formats/js-tokens.d.ts +6 -0
- package/dist/types/src/tokens/formats/js-tokens.d.ts.map +1 -0
- package/dist/types/src/tokens/transformers.d.ts +5 -0
- package/dist/types/src/tokens/transformers.d.ts.map +1 -0
- package/dist/types/src/tokens/utils/entryfile.d.ts +11 -0
- package/dist/types/src/tokens/utils/entryfile.d.ts.map +1 -0
- package/dist/types/src/tokens/utils/noCase.d.ts +11 -0
- package/dist/types/src/tokens/utils/noCase.d.ts.map +1 -0
- package/dist/types/src/tokens/utils/permutateThemes.d.ts +17 -0
- package/dist/types/src/tokens/utils/permutateThemes.d.ts.map +1 -0
- package/dist/types/src/tokens/utils/utils.d.ts +25 -0
- package/dist/types/src/tokens/utils/utils.d.ts.map +1 -0
- package/package.json +24 -22
|
@@ -15,9 +15,9 @@ program.command("tokens").showHelpAfterError().description("run Designsystemet t
|
|
|
15
15
|
program.command("migrate").showHelpAfterError().description("run a Designsystemet migration").addArgument(new Argument("[migration]", "Available migrations").choices(Object.keys(migrations))).option("-l --list", "List available migrations").option("-g --glob <glob>", "Glob for files upon which to apply the migration", "./**/*.(tsx|css)").action((migrationKey, opts) => {
|
|
16
16
|
const { glob, list } = opts;
|
|
17
17
|
if (list) {
|
|
18
|
-
Object.keys(migrations)
|
|
18
|
+
for (const key of Object.keys(migrations)) {
|
|
19
19
|
console.log(key);
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
21
|
} else if (migrationKey) {
|
|
22
22
|
const migration = migrations[migrationKey];
|
|
23
23
|
if (!migration) {
|
|
@@ -8,11 +8,11 @@ const cssClassRename = (dictionary) => ({
|
|
|
8
8
|
Rule(rule) {
|
|
9
9
|
const selector = rule.selector;
|
|
10
10
|
if (!selector) return;
|
|
11
|
-
|
|
11
|
+
for (const [from, to] of Object.entries(dictionary)) {
|
|
12
12
|
if (!selector.includes(from)) return;
|
|
13
13
|
const newSelector = selector.replace(new RegExp(from, "g"), to);
|
|
14
14
|
rule.selector = newSelector;
|
|
15
|
-
}
|
|
15
|
+
}
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
18
|
const cssVarRename = (dictionary) => ({
|
|
@@ -20,22 +20,21 @@ const cssVarRename = (dictionary) => ({
|
|
|
20
20
|
Declaration(decl) {
|
|
21
21
|
const { value, prop } = decl;
|
|
22
22
|
const deleted = /* @__PURE__ */ new Set();
|
|
23
|
-
|
|
23
|
+
for (const [from, to] of Object.entries(dictionary)) {
|
|
24
24
|
if (!R.isEmpty(to)) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
25
|
+
if (R.includes(from, value)) {
|
|
26
|
+
if (to === "[delete]") {
|
|
27
|
+
deleted.add(deleteMsg(decl, from));
|
|
28
|
+
}
|
|
29
|
+
decl.value = value.replace(from, to);
|
|
30
|
+
} else if (R.includes(from, prop) && decl.variable) {
|
|
31
|
+
if (to === "[delete]") {
|
|
32
|
+
deleted.add(deleteMsg(decl, from));
|
|
33
|
+
}
|
|
34
|
+
decl.prop = prop.replace(from, to);
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
|
-
}
|
|
37
|
+
}
|
|
39
38
|
if (deleted.size > 0) {
|
|
40
39
|
Array.from(deleted).forEach(printDelete);
|
|
41
40
|
}
|
|
@@ -5,11 +5,11 @@ const replaceInLiteral = (node) => {
|
|
|
5
5
|
return node;
|
|
6
6
|
};
|
|
7
7
|
const replaceInTemplateLiteral = (node) => {
|
|
8
|
-
|
|
8
|
+
for (const element of node) {
|
|
9
9
|
const value = element.value.raw;
|
|
10
|
-
if (typeof value !== "string")
|
|
10
|
+
if (typeof value !== "string") continue;
|
|
11
11
|
element.value.raw = replaceInLiteral(value);
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
};
|
|
14
14
|
const processNode = (node) => {
|
|
15
15
|
if (!node) return;
|
|
@@ -46,11 +46,12 @@ const processNode = (node) => {
|
|
|
46
46
|
function replaceClassNamePrefix(file, api) {
|
|
47
47
|
const j = api.jscodeshift;
|
|
48
48
|
const root = j(file.source);
|
|
49
|
-
root.find(j.JSXElement).
|
|
50
|
-
j(path).find(j.JSXAttribute, { name: { name: "className" } })
|
|
49
|
+
for (const path of root.find(j.JSXElement).paths()) {
|
|
50
|
+
const nodes = j(path).find(j.JSXAttribute, { name: { name: "className" } });
|
|
51
|
+
for (const nodePath of nodes.paths()) {
|
|
51
52
|
processNode(nodePath.value.value);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
54
55
|
return root.toSource({
|
|
55
56
|
quote: "single",
|
|
56
57
|
reuseWhitespace: true,
|
|
@@ -18,7 +18,7 @@ const makeEntryFile = {
|
|
|
18
18
|
}
|
|
19
19
|
const generateImportUrls = R.pipe(
|
|
20
20
|
sortLightmodeFirst,
|
|
21
|
-
R.map((file) => `@import url('
|
|
21
|
+
R.map((file) => `@import url('${theme}/${file.toString()}');`),
|
|
22
22
|
R.join("\n")
|
|
23
23
|
);
|
|
24
24
|
const files = await glob(`**/*`, { cwd: platform.buildPath });
|
package/dist/src/tokens/build.js
CHANGED
|
@@ -4,12 +4,13 @@ import chalk from "chalk";
|
|
|
4
4
|
import * as R from "ramda";
|
|
5
5
|
import StyleDictionary from "style-dictionary";
|
|
6
6
|
import * as configs from "./configs.js";
|
|
7
|
+
import { makeEntryFile } from "./utils/entryfile.js";
|
|
7
8
|
const { permutateThemes, getConfigs } = configs;
|
|
8
9
|
const sd = new StyleDictionary();
|
|
9
10
|
async function run(options) {
|
|
10
11
|
const tokensDir = options.tokens;
|
|
11
12
|
const storefrontOutDir = path.resolve("../../apps/storefront/tokens");
|
|
12
|
-
const
|
|
13
|
+
const outPath = path.resolve(options.out);
|
|
13
14
|
const $themes = JSON.parse(fs.readFileSync(path.resolve(`${tokensDir}/$themes.json`), "utf-8"));
|
|
14
15
|
const relevant$themes = $themes.filter((theme) => {
|
|
15
16
|
const group = R.toLower(R.defaultTo("")(theme.group));
|
|
@@ -20,9 +21,9 @@ async function run(options) {
|
|
|
20
21
|
const typographyThemes = R.filter((val) => val.mode === "light", themes);
|
|
21
22
|
const colormodeThemes = R.filter((val) => val.typography === "primary", themes);
|
|
22
23
|
const semanticThemes = R.filter((val) => val.mode === "light" && val.typography === "primary", themes);
|
|
23
|
-
const colorModeConfigs = getConfigs(configs.colorModeVariables,
|
|
24
|
-
const semanticConfigs = getConfigs(configs.semanticVariables,
|
|
25
|
-
const typographyConfigs = getConfigs(configs.typographyCSS,
|
|
24
|
+
const colorModeConfigs = getConfigs(configs.colorModeVariables, outPath, tokensDir, colormodeThemes);
|
|
25
|
+
const semanticConfigs = getConfigs(configs.semanticVariables, outPath, tokensDir, semanticThemes);
|
|
26
|
+
const typographyConfigs = getConfigs(configs.typographyCSS, outPath, tokensDir, typographyThemes);
|
|
26
27
|
const storefrontConfigs = getConfigs(configs.typescriptTokens, storefrontOutDir, tokensDir, colormodeThemes);
|
|
27
28
|
if (typographyConfigs.length > 0) {
|
|
28
29
|
console.log(`
|
|
@@ -35,17 +36,6 @@ async function run(options) {
|
|
|
35
36
|
})
|
|
36
37
|
);
|
|
37
38
|
}
|
|
38
|
-
if (semanticConfigs.length > 0) {
|
|
39
|
-
console.log(`
|
|
40
|
-
\u{1F371} Building ${chalk.green("semantic")}`);
|
|
41
|
-
await Promise.all(
|
|
42
|
-
semanticConfigs.map(async ({ theme, config, semantic }) => {
|
|
43
|
-
console.log(`\u{1F477} ${theme} - ${semantic}`);
|
|
44
|
-
const typographyClasses = await sd.extend(config);
|
|
45
|
-
return typographyClasses.buildAllPlatforms();
|
|
46
|
-
})
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
39
|
if (colorModeConfigs.length > 0) {
|
|
50
40
|
console.log(`
|
|
51
41
|
\u{1F371} Building ${chalk.green("color-mode")}`);
|
|
@@ -57,6 +47,17 @@ async function run(options) {
|
|
|
57
47
|
})
|
|
58
48
|
);
|
|
59
49
|
}
|
|
50
|
+
if (semanticConfigs.length > 0) {
|
|
51
|
+
console.log(`
|
|
52
|
+
\u{1F371} Building ${chalk.green("semantic")}`);
|
|
53
|
+
await Promise.all(
|
|
54
|
+
semanticConfigs.map(async ({ theme, config, semantic }) => {
|
|
55
|
+
console.log(`\u{1F477} ${theme} - ${semantic}`);
|
|
56
|
+
const typographyClasses = await sd.extend(config);
|
|
57
|
+
return typographyClasses.buildAllPlatforms();
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
}
|
|
60
61
|
if (storefrontConfigs.length > 0 && options.preview) {
|
|
61
62
|
console.log(`
|
|
62
63
|
\u{1F371} Building ${chalk.green("Storefront preview tokens")}`);
|
|
@@ -68,6 +69,16 @@ async function run(options) {
|
|
|
68
69
|
})
|
|
69
70
|
);
|
|
70
71
|
}
|
|
72
|
+
if (semanticConfigs.length > 0) {
|
|
73
|
+
console.log(`
|
|
74
|
+
\u{1F371} Building ${chalk.green("CSS file")}`);
|
|
75
|
+
await Promise.all(
|
|
76
|
+
semanticConfigs.map(async ({ theme }) => {
|
|
77
|
+
console.log(`\u{1F477} ${theme}.css`);
|
|
78
|
+
return makeEntryFile({ theme, outPath, buildPath: path.resolve(`${outPath}/${theme}`) });
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
}
|
|
71
82
|
}
|
|
72
83
|
export {
|
|
73
84
|
run
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { register } from "@tokens-studio/sd-transforms";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
import StyleDictionary from "style-dictionary";
|
|
4
4
|
import { outputReferencesFilter } from "style-dictionary/utils";
|
|
5
|
-
import { makeEntryFile } from "./actions.js";
|
|
6
5
|
import * as formats from "./formats/css.js";
|
|
7
6
|
import { jsTokens } from "./formats/js-tokens.js";
|
|
8
7
|
import { nameKebab, sizeRem, typographyShorthand } from "./transformers.js";
|
|
9
8
|
import { permutateThemes as permutateThemes_ } from "./utils/permutateThemes.js";
|
|
10
|
-
import { typeEquals } from "./utils/utils.js";
|
|
11
|
-
void
|
|
9
|
+
import { pathStartsWithOneOf, typeEquals } from "./utils/utils.js";
|
|
10
|
+
void register(StyleDictionary, { withSDBuiltins: false });
|
|
11
|
+
const usesDtcg = true;
|
|
12
12
|
const prefix = "ds";
|
|
13
13
|
const basePxFontSize = 16;
|
|
14
14
|
const separator = "_";
|
|
@@ -20,7 +20,6 @@ StyleDictionary.registerFormat(jsTokens);
|
|
|
20
20
|
StyleDictionary.registerFormat(formats.colormode);
|
|
21
21
|
StyleDictionary.registerFormat(formats.semantic);
|
|
22
22
|
StyleDictionary.registerFormat(formats.typography);
|
|
23
|
-
StyleDictionary.registerAction(makeEntryFile);
|
|
24
23
|
const dsTransformers = [
|
|
25
24
|
nameKebab.name,
|
|
26
25
|
`ts/resolveMath`,
|
|
@@ -31,7 +30,7 @@ const dsTransformers = [
|
|
|
31
30
|
"ts/color/modifiers",
|
|
32
31
|
"ts/color/css/hexrgba",
|
|
33
32
|
"ts/size/lineheight",
|
|
34
|
-
"
|
|
33
|
+
"shadow/css/shorthand"
|
|
35
34
|
];
|
|
36
35
|
const paritionPrimitives = R.partition(R.test(/(?!.*global\.json).*primitives.*/));
|
|
37
36
|
const hasUnknownProps = R.pipe(R.values, R.none(R.equals("unknown")), R.not);
|
|
@@ -48,6 +47,7 @@ const colorModeVariables = ({ mode = "light", outPath, theme }) => {
|
|
|
48
47
|
const selector = `${mode === "light" ? ":root, " : ""}[data-ds-color-mode="${mode}"]`;
|
|
49
48
|
const layer = `ds.theme.color-mode.${mode}`;
|
|
50
49
|
return {
|
|
50
|
+
usesDtcg,
|
|
51
51
|
log: { verbosity: "silent" },
|
|
52
52
|
preprocessors: ["tokens-studio"],
|
|
53
53
|
platforms: {
|
|
@@ -62,7 +62,6 @@ const colorModeVariables = ({ mode = "light", outPath, theme }) => {
|
|
|
62
62
|
prefix,
|
|
63
63
|
buildPath: `${outPath}/${theme}/`,
|
|
64
64
|
transforms: dsTransformers,
|
|
65
|
-
actions: [makeEntryFile.name],
|
|
66
65
|
files: [
|
|
67
66
|
{
|
|
68
67
|
destination: `color-mode/${mode}.css`,
|
|
@@ -81,8 +80,9 @@ const colorModeVariables = ({ mode = "light", outPath, theme }) => {
|
|
|
81
80
|
const semanticVariables = ({ outPath, theme }) => {
|
|
82
81
|
const selector = `:root`;
|
|
83
82
|
const layer = `ds.theme.semantic`;
|
|
84
|
-
const isCalculatedToken = (token) =>
|
|
83
|
+
const isCalculatedToken = (token) => pathStartsWithOneOf(["spacing", "sizing", "border-radius"], token);
|
|
85
84
|
return {
|
|
85
|
+
usesDtcg,
|
|
86
86
|
log: { verbosity: "silent" },
|
|
87
87
|
preprocessors: ["tokens-studio"],
|
|
88
88
|
platforms: {
|
|
@@ -98,12 +98,11 @@ const semanticVariables = ({ outPath, theme }) => {
|
|
|
98
98
|
prefix,
|
|
99
99
|
buildPath: `${outPath}/${theme}/`,
|
|
100
100
|
transforms: dsTransformers,
|
|
101
|
-
actions: [makeEntryFile.name],
|
|
102
101
|
files: [
|
|
103
102
|
{
|
|
104
103
|
destination: `semantic.css`,
|
|
105
104
|
format: formats.semantic.name,
|
|
106
|
-
filter: (token) => (!token.isSource || isCalculatedToken(token)) && !typeEquals(["color", "
|
|
105
|
+
filter: (token) => (!token.isSource || isCalculatedToken(token)) && !typeEquals(["color", "fontWeight", "fontFamily"], token)
|
|
107
106
|
}
|
|
108
107
|
],
|
|
109
108
|
options: {
|
|
@@ -116,6 +115,7 @@ const semanticVariables = ({ outPath, theme }) => {
|
|
|
116
115
|
};
|
|
117
116
|
const typescriptTokens = ({ mode = "unknown", outPath, theme }) => {
|
|
118
117
|
return {
|
|
118
|
+
usesDtcg,
|
|
119
119
|
log: { verbosity: "silent" },
|
|
120
120
|
preprocessors: ["tokens-studio"],
|
|
121
121
|
platforms: {
|
|
@@ -130,9 +130,8 @@ const typescriptTokens = ({ mode = "unknown", outPath, theme }) => {
|
|
|
130
130
|
format: jsTokens.name,
|
|
131
131
|
outputReferences: outputColorReferences,
|
|
132
132
|
filter: (token) => {
|
|
133
|
-
if (R.test(/primitives\/modes|\/themes/, token.filePath))
|
|
134
|
-
|
|
135
|
-
}
|
|
133
|
+
if (R.test(/primitives\/modes|\/themes/, token.filePath)) return false;
|
|
134
|
+
if (pathStartsWithOneOf(["border-width"], token)) return false;
|
|
136
135
|
if (R.test(/accent|neutral|brand1|brand2|brand3|success|danger|warning/, token.name) || R.includes("semantic", token.filePath)) {
|
|
137
136
|
return true;
|
|
138
137
|
}
|
|
@@ -151,6 +150,7 @@ const typographyCSS = ({ outPath, theme, typography }) => {
|
|
|
151
150
|
const selector = `${typography === "primary" ? ":root, " : ""}[data-ds-typography="${typography}"]`;
|
|
152
151
|
const layer = `ds.theme.typography.${typography}`;
|
|
153
152
|
return {
|
|
153
|
+
usesDtcg: true,
|
|
154
154
|
log: { verbosity: "silent" },
|
|
155
155
|
preprocessors: ["tokens-studio"],
|
|
156
156
|
platforms: {
|
|
@@ -167,10 +167,14 @@ const typographyCSS = ({ outPath, theme, typography }) => {
|
|
|
167
167
|
destination: `typography/${typography}.css`,
|
|
168
168
|
format: formats.typography.name,
|
|
169
169
|
filter: (token) => {
|
|
170
|
-
|
|
171
|
-
["typography", "
|
|
170
|
+
const included = typeEquals(
|
|
171
|
+
["typography", "fontweight", "fontFamily", "lineheight", "fontsize", "dimension", "font"],
|
|
172
|
+
token
|
|
173
|
+
);
|
|
174
|
+
return included && !pathStartsWithOneOf(
|
|
175
|
+
["spacing", "sizing", "border-width", "border-radius", "theme", "theme2", "theme3", "theme4"],
|
|
172
176
|
token
|
|
173
|
-
)
|
|
177
|
+
);
|
|
174
178
|
}
|
|
175
179
|
}
|
|
176
180
|
],
|
|
@@ -11,14 +11,15 @@ const colormode = {
|
|
|
11
11
|
name: "ds/css-colormode",
|
|
12
12
|
format: async ({ dictionary, file, options, platform }) => {
|
|
13
13
|
const { allTokens } = dictionary;
|
|
14
|
-
const { outputReferences } = options;
|
|
14
|
+
const { outputReferences, usesDtcg } = options;
|
|
15
15
|
const { selector, mode, layer } = platform;
|
|
16
16
|
const mode_ = mode;
|
|
17
17
|
const header = await fileHeader({ file });
|
|
18
18
|
const format = createPropertyFormatter({
|
|
19
19
|
outputReferences,
|
|
20
20
|
dictionary,
|
|
21
|
-
format: "css"
|
|
21
|
+
format: "css",
|
|
22
|
+
usesDtcg
|
|
22
23
|
});
|
|
23
24
|
const colorSchemeProperty = mode_ === "dark" || mode_ === "light" ? `color-scheme: ${mode_};
|
|
24
25
|
` : "";
|
|
@@ -27,10 +28,12 @@ ${allTokens.map(format).join("\n")}
|
|
|
27
28
|
${colorSchemeProperty}}
|
|
28
29
|
`;
|
|
29
30
|
const autoSelectorContent = ["light", "dark"].includes(mode_) ? prefersColorScheme(mode_, content) : "";
|
|
30
|
-
|
|
31
|
+
const body = R.isNotNil(layer) ? `@layer ${layer} {
|
|
31
32
|
${selector} ${content} ${autoSelectorContent}
|
|
32
33
|
}
|
|
34
|
+
` : `${selector} ${content} ${autoSelectorContent}
|
|
33
35
|
`;
|
|
36
|
+
return header + body;
|
|
34
37
|
}
|
|
35
38
|
};
|
|
36
39
|
const calculatedVariable = R.pipe(R.split(/:(.*?);/g), (split) => `${split[0]}: calc(${R.trim(split[1])});`);
|
|
@@ -38,13 +41,14 @@ const semantic = {
|
|
|
38
41
|
name: "ds/css-semantic",
|
|
39
42
|
format: async ({ dictionary, file, options, platform }) => {
|
|
40
43
|
const { allTokens } = dictionary;
|
|
41
|
-
const { outputReferences } = options;
|
|
44
|
+
const { outputReferences, usesDtcg } = options;
|
|
42
45
|
const { selector, isCalculatedToken, layer } = platform;
|
|
43
46
|
const header = await fileHeader({ file });
|
|
44
47
|
const format = createPropertyFormatter({
|
|
45
48
|
outputReferences,
|
|
46
49
|
dictionary,
|
|
47
|
-
format: "css"
|
|
50
|
+
format: "css",
|
|
51
|
+
usesDtcg
|
|
48
52
|
});
|
|
49
53
|
const formatTokens = R.map((token) => {
|
|
50
54
|
const originalValue = getValue(token.original);
|
|
@@ -60,13 +64,15 @@ const semantic = {
|
|
|
60
64
|
${formattedVariables.join("\n")}
|
|
61
65
|
}
|
|
62
66
|
`;
|
|
63
|
-
|
|
67
|
+
const body = R.isNotNil(layer) ? `@layer ${layer} {
|
|
64
68
|
${selector} ${content}
|
|
65
69
|
}
|
|
70
|
+
` : `${selector} ${content}
|
|
66
71
|
`;
|
|
72
|
+
return header + body;
|
|
67
73
|
}
|
|
68
74
|
};
|
|
69
|
-
const sortByType = R.sortBy((token) => token
|
|
75
|
+
const sortByType = R.sortBy((token) => token?.$type === "typography");
|
|
70
76
|
const getVariableName = R.pipe(
|
|
71
77
|
R.split(":"),
|
|
72
78
|
R.head,
|
|
@@ -92,20 +98,21 @@ const sortTypographyLast = R.sortWith([
|
|
|
92
98
|
const typography = {
|
|
93
99
|
name: "ds/css-typography",
|
|
94
100
|
format: async ({ dictionary, file, options, platform }) => {
|
|
95
|
-
const { outputReferences } = options;
|
|
101
|
+
const { outputReferences, usesDtcg } = options;
|
|
96
102
|
const { selector, layer } = platform;
|
|
97
103
|
const header = await fileHeader({ file });
|
|
98
104
|
const format = createPropertyFormatter({
|
|
99
105
|
outputReferences,
|
|
100
106
|
dictionary,
|
|
101
|
-
format: "css"
|
|
107
|
+
format: "css",
|
|
108
|
+
usesDtcg
|
|
102
109
|
});
|
|
103
110
|
const sortedTokens = sortTypographyLast(dictionary.allTokens);
|
|
104
111
|
const formattedTokens = R.pipe(
|
|
105
112
|
sortByType,
|
|
106
113
|
R.reduce(
|
|
107
114
|
(acc, token) => {
|
|
108
|
-
if (typeEquals("
|
|
115
|
+
if (typeEquals("fontweight", token)) {
|
|
109
116
|
const className = `
|
|
110
117
|
.${classSelector(token)} {
|
|
111
118
|
font-weight: ${getValue(token)};
|
|
@@ -116,7 +123,7 @@ const typography = {
|
|
|
116
123
|
classes: [...acc.classes, className]
|
|
117
124
|
};
|
|
118
125
|
}
|
|
119
|
-
if (typeEquals("
|
|
126
|
+
if (typeEquals("lineheight", token)) {
|
|
120
127
|
const className = `
|
|
121
128
|
.${classSelector(token)} {
|
|
122
129
|
line-height: ${getValue(token)};
|
|
@@ -128,21 +135,27 @@ const typography = {
|
|
|
128
135
|
};
|
|
129
136
|
}
|
|
130
137
|
if (typeEquals("typography", token)) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
138
|
+
let references = [];
|
|
139
|
+
try {
|
|
140
|
+
references = getReferences(getValue(token.original), dictionary.tokens);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error("Error getting references", error);
|
|
143
|
+
throw new Error(JSON.stringify(token, null, 2));
|
|
144
|
+
}
|
|
145
|
+
const fontweight = R.find(typeEquals(["fontweight"]))(references);
|
|
146
|
+
const lineheight = R.find(typeEquals(["lineheight"]))(references);
|
|
147
|
+
const fontsize = R.find(typeEquals(["fontsize"]))(references);
|
|
148
|
+
const letterSpacing = R.find(typeEquals(["dimension"]))(references);
|
|
136
149
|
const fontSizeVar = fontsize ? getVariableName(format(fontsize)) : null;
|
|
137
150
|
const fontWeightVar = fontweight ? getVariableName(format(fontweight)) : null;
|
|
138
151
|
const lineheightVar = lineheight ? getVariableName(format(lineheight)) : null;
|
|
139
152
|
const letterSpacingVar = letterSpacing ? getVariableName(format(letterSpacing)) : null;
|
|
140
153
|
const className = `
|
|
141
154
|
.${classSelector(token)} {
|
|
142
|
-
${fontSizeVar
|
|
143
|
-
${lineheightVar
|
|
144
|
-
${fontWeightVar
|
|
145
|
-
${letterSpacingVar
|
|
155
|
+
${fontSizeVar ? `font-size: ${fontSizeVar};` : ""}
|
|
156
|
+
${lineheightVar ? `line-height: ${lineheightVar};` : ""}
|
|
157
|
+
${fontWeightVar ? `font-weight: ${fontWeightVar};` : ""}
|
|
158
|
+
${letterSpacingVar ? `letter-spacing: ${letterSpacingVar};` : ""}
|
|
146
159
|
}`;
|
|
147
160
|
return { ...acc, classes: [className, ...acc.classes] };
|
|
148
161
|
}
|
|
@@ -157,10 +170,10 @@ const typography = {
|
|
|
157
170
|
${variables}
|
|
158
171
|
${classes}
|
|
159
172
|
}` : classes;
|
|
160
|
-
|
|
173
|
+
const body = R.isNotNil(layer) ? `@layer ${layer} {
|
|
161
174
|
${content}
|
|
162
|
-
}
|
|
163
|
-
|
|
175
|
+
}` : content;
|
|
176
|
+
return header + body;
|
|
164
177
|
}
|
|
165
178
|
};
|
|
166
179
|
export {
|
|
@@ -3,21 +3,25 @@ import { createPropertyFormatter, fileHeader } from "style-dictionary/utils";
|
|
|
3
3
|
import { getType } from "../utils/utils.js";
|
|
4
4
|
const groupByType = R.groupBy((token) => getType(token));
|
|
5
5
|
const removeUnwatedTokens = R.filter(
|
|
6
|
-
(token) => !["
|
|
6
|
+
(token) => !["ds-base-spacing", "ds-base-sizing"].includes(token.name)
|
|
7
7
|
);
|
|
8
|
+
const dissocExtensions = R.pipe(R.dissoc("$extensions"), R.dissocPath(["original", "$extensions"]));
|
|
9
|
+
const removeUnwatedProps = R.map((token) => dissocExtensions(token));
|
|
8
10
|
const toCssVarName = R.pipe(R.split(":"), R.head, R.trim);
|
|
9
11
|
const jsTokens = {
|
|
10
12
|
name: "ds/js-tokens",
|
|
11
|
-
format: async ({ dictionary, file }) => {
|
|
13
|
+
format: async ({ dictionary, file, options }) => {
|
|
14
|
+
const { usesDtcg } = options;
|
|
12
15
|
const format = createPropertyFormatter({
|
|
13
16
|
dictionary,
|
|
14
|
-
format: "css"
|
|
17
|
+
format: "css",
|
|
18
|
+
usesDtcg
|
|
15
19
|
});
|
|
16
20
|
const formatTokens = R.map((token) => ({
|
|
17
21
|
...token,
|
|
18
22
|
name: toCssVarName(format(token))
|
|
19
23
|
}));
|
|
20
|
-
const processTokens = R.pipe(removeUnwatedTokens, formatTokens, groupByType);
|
|
24
|
+
const processTokens = R.pipe(removeUnwatedTokens, removeUnwatedProps, formatTokens, groupByType);
|
|
21
25
|
const tokens = processTokens(dictionary.allTokens);
|
|
22
26
|
const content = Object.entries(tokens).map(
|
|
23
27
|
([name, token]) => `export const ${name} = ${JSON.stringify(token, null, 2).replace(/"([^"]+)":/g, "$1:")}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
import { noCase } from "./utils/noCase.js";
|
|
3
|
-
import { getValue, typeEquals } from "./utils/utils.js";
|
|
3
|
+
import { getValue, pathStartsWithOneOf, typeEquals } from "./utils/utils.js";
|
|
4
4
|
const isPx = R.test(/\b\d+px\b/g);
|
|
5
5
|
const sizeRem = {
|
|
6
6
|
name: "ds/size/toRem",
|
|
7
7
|
type: "value",
|
|
8
8
|
transitive: true,
|
|
9
|
-
filter: (token) =>
|
|
9
|
+
filter: (token) => {
|
|
10
|
+
const hasWantedType = typeEquals(["dimension", "fontsize"], token);
|
|
11
|
+
const hasWantedPath = pathStartsWithOneOf(["spacing", "sizing", "border-radius", "font-size"], token);
|
|
12
|
+
return hasWantedType && hasWantedPath;
|
|
13
|
+
},
|
|
10
14
|
transform: (token, config) => {
|
|
11
15
|
const value = getValue(token);
|
|
12
16
|
if (isPx(value)) {
|
|
@@ -34,7 +38,7 @@ const typographyShorthand = {
|
|
|
34
38
|
name: "typography/shorthand",
|
|
35
39
|
type: "value",
|
|
36
40
|
transitive: true,
|
|
37
|
-
filter: (token) =>
|
|
41
|
+
filter: (token) => typeEquals("typography", token),
|
|
38
42
|
transform: (token) => {
|
|
39
43
|
const typography = getValue(token);
|
|
40
44
|
return `${typography.fontWeight} ${typography.fontSize}/${typography.lineHeight} '${typography.fontFamily}'`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import glob from "fast-glob";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import * as R from "ramda";
|
|
4
|
+
const sortLightmodeFirst = R.sortWith([R.descend(R.includes("light")), R.descend(R.includes("secondary"))]);
|
|
5
|
+
const header = `@charset "UTF-8";
|
|
6
|
+
|
|
7
|
+
@layer ds.reset, ds.theme, ds.base, ds.utilities, ds.components;
|
|
8
|
+
|
|
9
|
+
`;
|
|
10
|
+
const sortAndConcat = R.pipe(
|
|
11
|
+
sortLightmodeFirst,
|
|
12
|
+
R.map((file) => {
|
|
13
|
+
try {
|
|
14
|
+
const content = fs.readFileSync(file, "utf-8").toString();
|
|
15
|
+
return content;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.error(`Error reading file: ${file}`);
|
|
18
|
+
return "";
|
|
19
|
+
}
|
|
20
|
+
}),
|
|
21
|
+
R.join("\n")
|
|
22
|
+
);
|
|
23
|
+
const makeEntryFile = async ({ outPath, buildPath, theme }) => {
|
|
24
|
+
const writePath = `${outPath}/${theme}.css`;
|
|
25
|
+
const files = await glob(`**/*`, { cwd: buildPath });
|
|
26
|
+
const content = header + sortAndConcat(files.map((file) => `${buildPath}/${file}`));
|
|
27
|
+
await fs.writeFile(writePath, content);
|
|
28
|
+
};
|
|
29
|
+
export {
|
|
30
|
+
makeEntryFile
|
|
31
|
+
};
|
|
@@ -8,7 +8,7 @@ function permutateThemes(themes, { separator = "-" } = {}) {
|
|
|
8
8
|
return mapThemesToSetsObject(themes);
|
|
9
9
|
}
|
|
10
10
|
const groups = {};
|
|
11
|
-
|
|
11
|
+
for (const theme of themes) {
|
|
12
12
|
if (theme.group) {
|
|
13
13
|
groups[theme.group] = [...groups[theme.group] ?? [], theme];
|
|
14
14
|
} else {
|
|
@@ -16,7 +16,7 @@ function permutateThemes(themes, { separator = "-" } = {}) {
|
|
|
16
16
|
`Theme ${theme.name} does not have a group property, which is required for multi-dimensional theming.`
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
|
-
}
|
|
19
|
+
}
|
|
20
20
|
if (Object.keys(groups).length <= 1) {
|
|
21
21
|
return mapThemesToSetsObject(themes);
|
|
22
22
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
|
+
const mapToLowerCase = R.map(R.toLower);
|
|
3
|
+
const hasAnyTruth = R.any(R.equals(true));
|
|
2
4
|
const getType = (token) => (token.$type ?? token.type) || "";
|
|
3
5
|
const getValue = (token) => token.$value ?? token.value;
|
|
4
6
|
const typeEquals = R.curry((types, token) => {
|
|
@@ -7,8 +9,17 @@ const typeEquals = R.curry((types, token) => {
|
|
|
7
9
|
}
|
|
8
10
|
return R.includes(R.toLower(getType(token)), R.map(R.toLower, Array.isArray(types) ? types : [types]));
|
|
9
11
|
});
|
|
12
|
+
const pathStartsWithOneOf = R.curry((paths, token) => {
|
|
13
|
+
if (R.isNil(token)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
const tokenPath = mapToLowerCase(token.path);
|
|
17
|
+
const matchPathsStartingWith = R.map((path) => R.startsWith([path], tokenPath), mapToLowerCase(paths));
|
|
18
|
+
return hasAnyTruth(matchPathsStartingWith);
|
|
19
|
+
});
|
|
10
20
|
export {
|
|
11
21
|
getType,
|
|
12
22
|
getValue,
|
|
23
|
+
pathStartsWithOneOf,
|
|
13
24
|
typeEquals
|
|
14
25
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"designsystemet.d.ts","sourceRoot":"","sources":["../../../bin/designsystemet.ts"],"names":[],"mappings":""}
|