@massimo-cassandro/minimo 1.35.0 → 1.36.0
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 +3 -1
- package/dev-tools/design-tokens-builder/build-tokens-src/build-source-modes.mjs +12 -2
- package/dev-tools/design-tokens-builder/build-tokens-src/config.mjs +13 -2
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/css.mjs +28 -4
- package/dev-tools/design-tokens-builder/build-tokens-src/formats/json.mjs +5 -1
- package/dev-tools/design-tokens-builder/build-tokens-src/merge-css.mjs +61 -9
- package/dev-tools/design-tokens-builder/build-tokens.mjs +1 -1
- package/dev-tools/design-tokens-builder/check-unresolved-custom-props.mjs +8 -4
- package/dev-tools/design-tokens-builder/tokens-config-sample.mjs +28 -9
- package/package.json +1 -1
|
@@ -161,7 +161,9 @@ 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
|
-
|
|
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
|
+
|
|
166
|
+
`customPropsGroups`, `mergeCustomProps`, `addLayer`, `pxToRem` etc. all apply the same way as with a single `source` (`mergeCustomProps` set to an array of strings/RegExps matches the token files of every mode). 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
|
---
|
|
167
169
|
|
|
@@ -44,7 +44,7 @@ import { LEGACY_TOKENS_PARSER_NAME } from './legacy-tokens-parser.mjs';
|
|
|
44
44
|
* @param {{name:string,prefixes:string[]}[]} opts.customPropsGroups
|
|
45
45
|
* @param {boolean} opts.pxToRem
|
|
46
46
|
* @param {string|null} opts.addLayer
|
|
47
|
-
* @param {boolean}
|
|
47
|
+
* @param {boolean|(string|RegExp)[]} opts.mergeCustomProps true = merge all sources, array = only the matching token source files
|
|
48
48
|
* @returns {Promise<{cssDestPath: string, totalCustomProps: number, jsonFilesByMode: Record<string, object[]>}>}
|
|
49
49
|
*/
|
|
50
50
|
export const buildSourceModes = async ({
|
|
@@ -66,7 +66,7 @@ export const buildSourceModes = async ({
|
|
|
66
66
|
// Read the pre-existing destFile (if any) BEFORE any Style Dictionary
|
|
67
67
|
// instance runs, since the first one to write would overwrite it.
|
|
68
68
|
if (mergeCustomProps) {
|
|
69
|
-
loadExistingCustomPropsScoped(path.join(buildPath, destFile), baseMode);
|
|
69
|
+
loadExistingCustomPropsScoped(path.join(buildPath, destFile), baseMode, mergeCustomProps);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const cssTransforms = pxToRem
|
|
@@ -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' },
|
|
@@ -84,8 +84,19 @@ export const pxToRem = buildConfig.pxToRem !== false;
|
|
|
84
84
|
|
|
85
85
|
// mergeCustomProps: if true, custom properties already present in the CSS
|
|
86
86
|
// destination file take priority over the ones generated by this build (see
|
|
87
|
-
// build-tokens-src/merge-css.mjs).
|
|
88
|
-
|
|
87
|
+
// build-tokens-src/merge-css.mjs). It can also be an array of strings/RegExps:
|
|
88
|
+
// only the properties generated by the token source files matching one of its
|
|
89
|
+
// entries are merged. An empty or invalid value means false. Default: false.
|
|
90
|
+
/** @type {boolean|(string|RegExp)[]} */
|
|
91
|
+
export const mergeCustomProps = (() => {
|
|
92
|
+
const value = buildConfig.mergeCustomProps;
|
|
93
|
+
if (value === true) return true;
|
|
94
|
+
if (Array.isArray(value)) {
|
|
95
|
+
const entries = value.filter((entry) => typeof entry === 'string' || entry instanceof RegExp);
|
|
96
|
+
return entries.length ? entries : false;
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
})();
|
|
89
100
|
|
|
90
101
|
// addLayer: wraps the generated custom properties inside a CSS `@layer`
|
|
91
102
|
// at-rule (see formats/css.mjs), e.g. `@layer project { :root { ... } }`.
|
|
@@ -189,8 +189,23 @@ 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.
|
|
195
|
+
// property name → token source file, used by mergeCustomProps when the
|
|
196
|
+
// merge is limited to some source files (a token may generate several
|
|
197
|
+
// properties, e.g. typography)
|
|
198
|
+
/** @type {Record<string,string>} */
|
|
199
|
+
const sourceFileMap = {};
|
|
200
|
+
const trackSource = (token, tokenLines) => {
|
|
201
|
+
for (const name of Object.keys(parseCustomProps(tokenLines.join('\n')))) {
|
|
202
|
+
sourceFileMap[name] = token.filePath;
|
|
203
|
+
}
|
|
204
|
+
return tokenLines;
|
|
205
|
+
};
|
|
206
|
+
|
|
192
207
|
const lines = dictionary.allTokens
|
|
193
|
-
.
|
|
208
|
+
.filter((token) => token.isSource !== false)
|
|
194
209
|
// .sort((a, b) => a.name.localeCompare(b.name, 'en', {numeric: true, sensitivity: 'base'}))
|
|
195
210
|
.sort((a, b) => sortFunction(a,b))
|
|
196
211
|
.flatMap((token) => {
|
|
@@ -204,7 +219,7 @@ StyleDictionary.registerFormat({
|
|
|
204
219
|
.split('\n')
|
|
205
220
|
.map((line) => `${line}${commentSuffix}`)
|
|
206
221
|
.join('\n');
|
|
207
|
-
return [typographyLines];
|
|
222
|
+
return trackSource(token, [typographyLines]);
|
|
208
223
|
}
|
|
209
224
|
|
|
210
225
|
let value;
|
|
@@ -247,7 +262,16 @@ StyleDictionary.registerFormat({
|
|
|
247
262
|
value = String(token.$value ?? token.value);
|
|
248
263
|
}
|
|
249
264
|
|
|
250
|
-
|
|
265
|
+
// Multi-line values (e.g. Open Props' linear() easings) are collapsed
|
|
266
|
+
// to a single line: declarations are parsed one line at a time (see
|
|
267
|
+
// parseCustomProps in ../merge-css.mjs), so a multi-line value would
|
|
268
|
+
// be truncated to its first line.
|
|
269
|
+
value = String(value)
|
|
270
|
+
.replace(/\s*\n\s*/g, ' ')
|
|
271
|
+
.replace(/\(\s+/g, '(')
|
|
272
|
+
.replace(/\s+\)/g, ')');
|
|
273
|
+
|
|
274
|
+
return trackSource(token, [` --${token.name}: ${value};${commentSuffix}`]);
|
|
251
275
|
});
|
|
252
276
|
|
|
253
277
|
// Build a name → declaration-tail map from the declarations generated
|
|
@@ -259,7 +283,7 @@ StyleDictionary.registerFormat({
|
|
|
259
283
|
// scopes the merge to that mode, so same-named props with different
|
|
260
284
|
// values across modes are never mixed up.
|
|
261
285
|
const generatedProps = parseCustomProps(lines.join('\n'));
|
|
262
|
-
const finalProps = mergeCustomProps(generatedProps, options.mode ?? null);
|
|
286
|
+
const finalProps = mergeCustomProps(generatedProps, options.mode ?? null, sourceFileMap);
|
|
263
287
|
|
|
264
288
|
// Final output is always sorted alphabetically ascending by property
|
|
265
289
|
// name, regardless of merge — this also keeps pre-existing-only
|
|
@@ -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
|
};
|
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
// mergeCustomProps(generatedMap) while building the output, right before
|
|
11
11
|
// serialising the final CSS text.
|
|
12
12
|
//
|
|
13
|
+
// `mergeCustomProps` may also be an array of strings/RegExps: in that case
|
|
14
|
+
// only the generated properties whose token source file matches one of the
|
|
15
|
+
// entries are merged (pre-existing value wins); the others are overwritten by
|
|
16
|
+
// the generated value. Pre-existing properties that are no longer generated
|
|
17
|
+
// (no token, hence no source file) are always kept. See matchesSource().
|
|
18
|
+
//
|
|
13
19
|
// Usage (sourceModes build, see build-source-modes.mjs):
|
|
14
20
|
// 1. Call loadExistingCustomPropsScoped(absDestPath, baseMode) BEFORE any
|
|
15
21
|
// of the per-mode Style Dictionary instances run.
|
|
@@ -36,7 +42,11 @@ export const parseCustomProps = (cssText) => {
|
|
|
36
42
|
/** @type {Record<string,string>} */
|
|
37
43
|
const map = {};
|
|
38
44
|
for (const match of cssText.matchAll(CUSTOM_PROP_RE)) {
|
|
39
|
-
|
|
45
|
+
let tail = match[2].trim();
|
|
46
|
+
// A multi-line comment is cut at the end of the line (only single-line
|
|
47
|
+
// declarations are parsed): close it, or the resulting CSS would be invalid
|
|
48
|
+
if (tail.lastIndexOf('/*') > tail.lastIndexOf('*/')) tail += ' */';
|
|
49
|
+
map[match[1]] = tail;
|
|
40
50
|
}
|
|
41
51
|
return map;
|
|
42
52
|
};
|
|
@@ -124,6 +134,32 @@ const splitModeScopes = (cssText) => {
|
|
|
124
134
|
return scopes;
|
|
125
135
|
};
|
|
126
136
|
|
|
137
|
+
// `true` = merge every source; an array = merge only the properties generated
|
|
138
|
+
// by the token source files matching one of its entries. Set by the
|
|
139
|
+
// loadExistingCustomProps*() functions.
|
|
140
|
+
/** @type {true|(string|RegExp)[]} */
|
|
141
|
+
let mergeSources = true;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Whether a token source file matches one of the `mergeCustomProps` array
|
|
145
|
+
* entries: a string matches if it is contained in the file path (path
|
|
146
|
+
* separators normalised to `/`), a RegExp if it tests true against it.
|
|
147
|
+
* @param {(string|RegExp)[]} sources
|
|
148
|
+
* @param {string|undefined} filePath token source file path
|
|
149
|
+
* @returns {boolean}
|
|
150
|
+
*/
|
|
151
|
+
const matchesSource = (sources, filePath) => {
|
|
152
|
+
if (!filePath) return false;
|
|
153
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
154
|
+
return sources.some((entry) => {
|
|
155
|
+
if (entry instanceof RegExp) {
|
|
156
|
+
entry.lastIndex = 0;
|
|
157
|
+
return entry.test(normalized);
|
|
158
|
+
}
|
|
159
|
+
return normalized.includes(entry.replace(/\\/g, '/'));
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
|
|
127
163
|
// null = merge disabled, or destination file not found yet (first build)
|
|
128
164
|
/** @type {Record<string,string>|null} */
|
|
129
165
|
let existingCustomProps = null;
|
|
@@ -137,9 +173,12 @@ let scopedExistingCustomProps = null;
|
|
|
137
173
|
* Reads the CSS destination file (if it exists) and stores a name → value
|
|
138
174
|
* map of its current custom properties for later merging.
|
|
139
175
|
* @param {string} absDestPath absolute path of the CSS file to read
|
|
176
|
+
* @param {true|(string|RegExp)[]} [sources] `true` merges every source, an
|
|
177
|
+
* array only the token source files matching one of its entries (default: true)
|
|
140
178
|
* @returns {Record<string,string>|null}
|
|
141
179
|
*/
|
|
142
|
-
export const loadExistingCustomProps = (absDestPath) => {
|
|
180
|
+
export const loadExistingCustomProps = (absDestPath, sources = true) => {
|
|
181
|
+
mergeSources = sources;
|
|
143
182
|
existingCustomProps = existsSync(absDestPath)
|
|
144
183
|
? parseCustomProps(readFileSync(absDestPath, 'utf8'))
|
|
145
184
|
: null;
|
|
@@ -154,9 +193,12 @@ export const loadExistingCustomProps = (absDestPath) => {
|
|
|
154
193
|
* @param {string} baseMode mode whose declarations live in the top-level,
|
|
155
194
|
* non-nested `:root { ... }` block (no default — always passed explicitly
|
|
156
195
|
* by build-source-modes.mjs, from the resolved sourceModesBase)
|
|
196
|
+
* @param {true|(string|RegExp)[]} [sources] `true` merges every source, an
|
|
197
|
+
* array only the token source files matching one of its entries (default: true)
|
|
157
198
|
* @returns {Record<string, Record<string,string>>|null}
|
|
158
199
|
*/
|
|
159
|
-
export const loadExistingCustomPropsScoped = (absDestPath, baseMode) => {
|
|
200
|
+
export const loadExistingCustomPropsScoped = (absDestPath, baseMode, sources = true) => {
|
|
201
|
+
mergeSources = sources;
|
|
160
202
|
if (!existsSync(absDestPath)) {
|
|
161
203
|
scopedExistingCustomProps = null;
|
|
162
204
|
return scopedExistingCustomProps;
|
|
@@ -177,16 +219,26 @@ export const loadExistingCustomPropsScoped = (absDestPath, baseMode) => {
|
|
|
177
219
|
* Merges freshly generated custom properties with the ones previously loaded
|
|
178
220
|
* via loadExistingCustomProps() / loadExistingCustomPropsScoped(). Pre-existing
|
|
179
221
|
* values take priority; custom properties found only in the pre-existing file
|
|
180
|
-
* (no longer generated) are kept as well.
|
|
222
|
+
* (no longer generated) are kept as well. When the merge is limited to some
|
|
223
|
+
* token source files (array option), a generated property whose source file
|
|
224
|
+
* does not match is not overridden by its pre-existing value.
|
|
181
225
|
* @param {Record<string,string>} generated name → value map produced by this build
|
|
182
226
|
* @param {string|null} [mode] when set (sourceModes build), looks up the
|
|
183
227
|
* pre-existing props scoped to this mode instead of the flat/global map (default: null)
|
|
228
|
+
* @param {Record<string,string>} [sourceFileMap] property name → token source
|
|
229
|
+
* file path, used only when the merge is limited to some sources (default: {})
|
|
184
230
|
* @returns {Record<string,string>}
|
|
185
231
|
*/
|
|
186
|
-
export const mergeCustomProps = (generated, mode = null) => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
232
|
+
export const mergeCustomProps = (generated, mode = null, sourceFileMap = {}) => {
|
|
233
|
+
const existing = mode !== null ? scopedExistingCustomProps?.[mode] : existingCustomProps;
|
|
234
|
+
if (!existing) return generated;
|
|
235
|
+
if (mergeSources === true) return { ...generated, ...existing };
|
|
236
|
+
|
|
237
|
+
const merged = { ...generated };
|
|
238
|
+
for (const [name, tail] of Object.entries(existing)) {
|
|
239
|
+
if (!(name in generated) || matchesSource(mergeSources, sourceFileMap[name])) {
|
|
240
|
+
merged[name] = tail;
|
|
241
|
+
}
|
|
190
242
|
}
|
|
191
|
-
return
|
|
243
|
+
return merged;
|
|
192
244
|
};
|
|
@@ -116,7 +116,7 @@ if (sourceModes) {
|
|
|
116
116
|
// pre-existing values take priority — right before serialising the final
|
|
117
117
|
// CSS output. See merge-css.mjs.
|
|
118
118
|
if (mergeCustomProps) {
|
|
119
|
-
loadExistingCustomProps(path.join(buildPath, destFile));
|
|
119
|
+
loadExistingCustomProps(path.join(buildPath, destFile), mergeCustomProps);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// Collect concrete source file paths (multi-file JSON mode only). Source
|
|
@@ -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".
|
|
@@ -106,13 +113,25 @@ const config = {
|
|
|
106
113
|
// are never touched regardless of this option.
|
|
107
114
|
pxToRem: false,
|
|
108
115
|
|
|
109
|
-
//
|
|
110
|
-
// (destFile, from a previous build)
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
+
// Preserves custom properties already present in the CSS destination file
|
|
117
|
+
// (destFile, from a previous build) across rebuilds: their values take
|
|
118
|
+
// priority over the ones generated by this build. Useful to keep manual
|
|
119
|
+
// overrides/additions made directly in the compiled CSS. Ignored on the
|
|
120
|
+
// first build, when destFile does not exist yet. Accepted values:
|
|
121
|
+
// false (default) - no merge: the destination file is fully regenerated
|
|
122
|
+
// true - merge all the sources
|
|
123
|
+
// array - strings and/or RegExps matched against the path of the
|
|
124
|
+
// token source files (those in `source` or `sourceModes`):
|
|
125
|
+
// only the properties generated by a matching file are
|
|
126
|
+
// merged, the others are overwritten by the generated value.
|
|
127
|
+
// A string matches if contained in the file path.
|
|
128
|
+
// An empty array is treated as false.
|
|
129
|
+
// e.g. ['/theme.minimo.tokens', /colors\.tokens\.(mjs|jsonc?)$/]
|
|
130
|
+
// With true or an array, properties found only in the pre-existing file (no
|
|
131
|
+
// longer generated, e.g. added by hand) are always kept.
|
|
132
|
+
// Comments at the end of a custom property line are preserved; full-line
|
|
133
|
+
// comments are lost, and a multi-line comment is cut at the end of its first
|
|
134
|
+
// line (and closed, to keep the CSS valid).
|
|
116
135
|
mergeCustomProps: false,
|
|
117
136
|
|
|
118
137
|
// Wraps the generated custom properties inside a CSS `@layer` at-rule,
|
|
@@ -195,11 +214,11 @@ const config = {
|
|
|
195
214
|
// Additional CSS files that define custom properties used in the project
|
|
196
215
|
// but not generated by build-tokens (e.g. third-party libraries)
|
|
197
216
|
extraCustomPropsFiles: [
|
|
198
|
-
//
|
|
217
|
+
// `${node_modules_path}/open-props/open-props.min.css`
|
|
199
218
|
],
|
|
200
219
|
|
|
201
220
|
// Directory containing the CSS files to scan for unresolved custom properties
|
|
202
|
-
dirToCheck: '
|
|
221
|
+
dirToCheck: '../../app',
|
|
203
222
|
|
|
204
223
|
// Regular expressions for custom property names to exclude from the check.
|
|
205
224
|
// Useful for intentionally private/internal props (e.g. prefixed with --_).
|