@massimo-cassandro/minimo 1.35.0 → 1.35.1
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/dev-tools/design-tokens-builder/README.md +2 -0
- package/dev-tools/design-tokens-builder/build-tokens-src/build-source-modes.mjs +10 -0
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/css.mjs +13 -1
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/json.mjs +5 -1
- package/dev-tools/design-tokens-builder/check-unresolved-custom-props.mjs +8 -4
- package/dev-tools/design-tokens-builder/tokens-config-sample.mjs +7 -0
- package/package.json +1 -1
|
@@ -161,6 +161,8 @@ When set, each mode has its own `source` array, and the generated CSS composes a
|
|
|
161
161
|
- the base mode's props go in a top-level `:root { ... }` block, with `color-scheme: <all modes>;` prepended
|
|
162
162
|
- every other mode's props go in `@media (prefers-color-scheme: <mode>) { :root { ... } }`, with `color-scheme: <mode>;` prepended
|
|
163
163
|
|
|
164
|
+
Tokens of a non-base mode can reference tokens defined in the base mode (e.g. a dark token using `{color.1}` defined in light, output as `var(--color-1)`). References to a non-base mode's tokens (from the base mode or from another non-base mode) fail with a "reference not defined" error, since the target would be undefined outside its own `@media` block.
|
|
165
|
+
|
|
164
166
|
`customPropsGroups`, `mergeCustomProps`, `addLayer`, `pxToRem` etc. all apply the same way as with a single `source`. The JSON output (when `jsonBuildPath` is set) is produced once per mode, with the mode name appended to each filename (e.g. `tokens-light.jsonc` / `tokens-dark.jsonc`).
|
|
165
167
|
|
|
166
168
|
---
|
|
@@ -80,7 +80,16 @@ export const buildSourceModes = async ({
|
|
|
80
80
|
const jsonFilesByMode = {};
|
|
81
81
|
|
|
82
82
|
for (const mode of modeNames) {
|
|
83
|
+
// Non-base modes may reference base-mode tokens (always defined, since
|
|
84
|
+
// the base block is the unconditional top-level `:root`). The base
|
|
85
|
+
// sources are passed as `include`: available for reference resolution
|
|
86
|
+
// but flagged isSource: false, and skipped by the css/json formats.
|
|
87
|
+
// Base-mode-only on purpose: a reference to a token that exists only in
|
|
88
|
+
// another `@media` block would build fine but be undefined at runtime.
|
|
89
|
+
const include = mode === baseMode ? [] : sourceModes[baseMode];
|
|
90
|
+
|
|
83
91
|
const sd = new StyleDictionary({
|
|
92
|
+
include,
|
|
84
93
|
source: sourceModes[mode],
|
|
85
94
|
parsers: [LEGACY_TOKENS_PARSER_NAME],
|
|
86
95
|
log: { verbosity: 'verbose' },
|
|
@@ -116,6 +125,7 @@ export const buildSourceModes = async ({
|
|
|
116
125
|
const files = buildJsonFiles(concreteFilePaths, jsonDestFile, jsonFormat, jsonExpression, `-${mode}`);
|
|
117
126
|
|
|
118
127
|
const jsonSd = new StyleDictionary({
|
|
128
|
+
include,
|
|
119
129
|
source: sourceModes[mode],
|
|
120
130
|
parsers: [LEGACY_TOKENS_PARSER_NAME],
|
|
121
131
|
log: { verbosity: 'silent' },
|
|
@@ -189,8 +189,11 @@ StyleDictionary.registerFormat({
|
|
|
189
189
|
return a.name.localeCompare(b.name, 'en', { numeric: true, sensitivity: 'base' });
|
|
190
190
|
};
|
|
191
191
|
|
|
192
|
+
// Tokens loaded via `include` (sourceModes: base-mode tokens made
|
|
193
|
+
// available to other modes) stay in tokenByPath, so references to them
|
|
194
|
+
// resolve to var(--name), but are not declared in this mode's block.
|
|
192
195
|
const lines = dictionary.allTokens
|
|
193
|
-
.
|
|
196
|
+
.filter((token) => token.isSource !== false)
|
|
194
197
|
// .sort((a, b) => a.name.localeCompare(b.name, 'en', {numeric: true, sensitivity: 'base'}))
|
|
195
198
|
.sort((a, b) => sortFunction(a,b))
|
|
196
199
|
.flatMap((token) => {
|
|
@@ -247,6 +250,15 @@ StyleDictionary.registerFormat({
|
|
|
247
250
|
value = String(token.$value ?? token.value);
|
|
248
251
|
}
|
|
249
252
|
|
|
253
|
+
// Multi-line values (e.g. Open Props' linear() easings) are collapsed
|
|
254
|
+
// to a single line: declarations are parsed one line at a time (see
|
|
255
|
+
// parseCustomProps in ../merge-css.mjs), so a multi-line value would
|
|
256
|
+
// be truncated to its first line.
|
|
257
|
+
value = String(value)
|
|
258
|
+
.replace(/\s*\n\s*/g, ' ')
|
|
259
|
+
.replace(/\(\s+/g, '(')
|
|
260
|
+
.replace(/\s+\)/g, ')');
|
|
261
|
+
|
|
250
262
|
return [` --${token.name}: ${value};${commentSuffix}`];
|
|
251
263
|
});
|
|
252
264
|
|
|
@@ -136,6 +136,10 @@ StyleDictionary.registerFormat({
|
|
|
136
136
|
const tokenMap = (expressionMode === 'resolve') ? makeTokenMap(dictionary) : null;
|
|
137
137
|
|
|
138
138
|
for (const token of dictionary.allTokens) {
|
|
139
|
+
// Tokens loaded via `include` (sourceModes: base-mode tokens made
|
|
140
|
+
// available to other modes for reference resolution) are not output.
|
|
141
|
+
if (token.isSource === false) continue;
|
|
142
|
+
|
|
139
143
|
// Rebuild the nested tree from the token path
|
|
140
144
|
let node = root;
|
|
141
145
|
for (let i = 0; i < token.path.length - 1; i++) {
|
|
@@ -205,7 +209,7 @@ export const collectConcreteFilePaths = async (sd) => {
|
|
|
205
209
|
await sd.hasInitialized;
|
|
206
210
|
const paths = new Set();
|
|
207
211
|
for (const token of sd.allTokens) {
|
|
208
|
-
if (token.filePath) paths.add(token.filePath);
|
|
212
|
+
if (token.filePath && token.isSource !== false) paths.add(token.filePath);
|
|
209
213
|
}
|
|
210
214
|
return [...paths].sort();
|
|
211
215
|
};
|
|
@@ -202,14 +202,17 @@ async function run() {
|
|
|
202
202
|
/** @type {Map<string, Map<string, string>>} */
|
|
203
203
|
const sourceFileByPropByMode = new Map();
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
// includePatterns: base-mode sources, passed as `include` for non-base
|
|
206
|
+
// modes so cross-mode references resolve (same as build-source-modes.mjs).
|
|
207
|
+
/** @param {string[]} sourcePatterns @param {string[]} [includePatterns] @returns {Promise<Map<string,string>>} */
|
|
208
|
+
const resolveSourceFileMap = async (sourcePatterns, includePatterns = []) => {
|
|
207
209
|
/** @type {Map<string, string>} */
|
|
208
210
|
const map = new Map();
|
|
209
211
|
const resolvedPaths = resolveSourcePaths(sourcePatterns, configDir);
|
|
210
212
|
if (!resolvedPaths.length) return map;
|
|
211
213
|
try {
|
|
212
214
|
const sd = new StyleDictionary({
|
|
215
|
+
include: resolveSourcePaths(includePatterns, configDir),
|
|
213
216
|
source: resolvedPaths,
|
|
214
217
|
parsers: [LEGACY_TOKENS_PARSER_NAME],
|
|
215
218
|
log: { verbosity: 'silent' },
|
|
@@ -217,7 +220,7 @@ async function run() {
|
|
|
217
220
|
});
|
|
218
221
|
const dictionary = await sd.getPlatformTokens('css');
|
|
219
222
|
for (const token of dictionary.allTokens) {
|
|
220
|
-
if (token.filePath) map.set(`--${token.name}`, token.filePath);
|
|
223
|
+
if (token.filePath && token.isSource !== false) map.set(`--${token.name}`, token.filePath);
|
|
221
224
|
}
|
|
222
225
|
} catch {
|
|
223
226
|
// Non-fatal: unused properties will be reported by name only.
|
|
@@ -227,7 +230,8 @@ async function run() {
|
|
|
227
230
|
|
|
228
231
|
if (checkUnused && config.sourceModes) {
|
|
229
232
|
for (const [mode, modeSource] of Object.entries(config.sourceModes)) {
|
|
230
|
-
|
|
233
|
+
const includePatterns = mode === sourceModesBase ? [] : config.sourceModes[sourceModesBase];
|
|
234
|
+
sourceFileByPropByMode.set(mode, await resolveSourceFileMap(modeSource, includePatterns));
|
|
231
235
|
}
|
|
232
236
|
} else if (checkUnused && Array.isArray(config.source) && config.source.length) {
|
|
233
237
|
const map = await resolveSourceFileMap(config.source);
|
|
@@ -77,6 +77,13 @@ const config = {
|
|
|
77
77
|
// customPropsGroups, mergeCustomProps, addLayer, pxToRem etc. all apply
|
|
78
78
|
// the same way as with a single `source`.
|
|
79
79
|
//
|
|
80
|
+
// Cross-mode references: tokens of a non-base mode can reference tokens
|
|
81
|
+
// defined in the base mode (e.g. a dark token using {color.1} defined in
|
|
82
|
+
// light); it resolves to var(--color-1). The reverse (or between two
|
|
83
|
+
// non-base modes) is not supported and fails with a "reference not
|
|
84
|
+
// defined" error, since the target would be undefined outside its own
|
|
85
|
+
// @media block.
|
|
86
|
+
//
|
|
80
87
|
// The JSON output (see JSON TOKENS OUTPUT below) is produced once per
|
|
81
88
|
// mode, with the mode name appended to each filename, e.g. with
|
|
82
89
|
// jsonDestFile: 'tokens' -> "tokens-light.jsonc", "tokens-dark.jsonc".
|