@massimo-cassandro/minimo 1.19.2 → 1.19.4
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/design-tokens/README.md +17 -7
- package/design-tokens/tokens/src/components/snackbar/snackbar.minimo.tokens.jsonc +9 -1
- package/design-tokens/tokens-config-sample.mjs +10 -3
- package/design-tokens/utilities/build-tokens-src/config.mjs +3 -25
- package/design-tokens/utilities/build-tokens-src/formats/css.mjs +17 -4
- package/design-tokens/utilities/build-tokens-src/platforms.mjs +4 -2
- package/design-tokens/utilities/build-tokens-src/resolve-source-paths.mjs +33 -0
- package/design-tokens/utilities/check-unresolved-custom-props.mjs +116 -20
- package/dev-tools/starter-kit/starter-install.sh +1 -1
- package/dev-tools/starter-kit/templates/_gitignore +1 -0
- package/dev-tools/starter-kit/webpack.config.mjs +10 -15
- package/package.json +1 -1
- package/src/components/snackbar/snackbar.minimo.tokens.mjs +9 -1
- package/src/components/snackbar/snackbar.module.css +3 -1
- package/src/custom-properties.css +35 -0
- package/dev-tools/starter-kit/templates/tokens-config.mjs +0 -33
package/design-tokens/README.md
CHANGED
|
@@ -160,9 +160,12 @@ Alias references (`{color.brand.primary}`) are preserved in the output so Penpot
|
|
|
160
160
|
|
|
161
161
|
### `check-unresolved-custom-props.mjs`
|
|
162
162
|
|
|
163
|
-
Scans all `.css` files in `
|
|
163
|
+
Scans all `.css` files in `dirToCheck` (recursively) and reports:
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
- **unresolved properties** — `var(--...)` references that are not defined in the generated token CSS file or in any `extraCustomPropsFiles`
|
|
166
|
+
- **unused properties** — custom properties defined in the generated token CSS file (or an `extraCustomPropsFiles` entry) but never referenced via `var()` in any scanned CSS file. Only reported if `checkUnused: true` is set in the config, since it re-runs the Style Dictionary transform pipeline over the token sources to resolve, when possible, the `.mjs` source file for each unused property.
|
|
167
|
+
|
|
168
|
+
Results are written to `unresolved-unused-props.md` in the same directory as the config file.
|
|
166
169
|
|
|
167
170
|
#### Usage
|
|
168
171
|
|
|
@@ -172,11 +175,18 @@ npx checkUnresolvedProps --config ./path/to/tokens-config.mjs
|
|
|
172
175
|
|
|
173
176
|
#### Output
|
|
174
177
|
|
|
175
|
-
The script creates a `unresolved-props.md` file next to the config file. Each
|
|
178
|
+
The script creates a `unresolved-unused-props.md` file next to the config file (only if there is at least one unresolved or unused property). Each unresolved entry links to the file and line number where the property is used; each unused entry links to its `.mjs` token source file when it can be resolved, otherwise just the property name is reported:
|
|
176
179
|
|
|
177
180
|
```markdown
|
|
178
|
-
|
|
179
|
-
|
|
181
|
+
## Unresolved custom properties
|
|
182
|
+
|
|
183
|
+
* [components.css](../src/components.css#L42) -> `--color-action-hover`
|
|
184
|
+
* [layout.css](../src/layout.css#L17) -> `--spacing-missing`
|
|
185
|
+
|
|
186
|
+
## Unused custom properties
|
|
187
|
+
|
|
188
|
+
* [colors.minimo.tokens.mjs](../_src/colors.minimo.tokens.mjs) -> `--color-legacy-accent`
|
|
189
|
+
* `--manually-added-prop`
|
|
180
190
|
```
|
|
181
191
|
|
|
182
192
|
In VS Code, Option/Alt-clicking on the URL opens the file at the required line.
|
|
@@ -184,11 +194,11 @@ In VS Code, Option/Alt-clicking on the URL opens the file at the required line.
|
|
|
184
194
|
|
|
185
195
|
#### Excluding properties
|
|
186
196
|
|
|
187
|
-
Use `
|
|
197
|
+
Use `excludePattern` to suppress false positives — for example, internal/private custom properties that are defined dynamically or inline:
|
|
188
198
|
|
|
189
199
|
```js
|
|
190
200
|
// skips all custom props starting with `--_` or `--js-`
|
|
191
|
-
|
|
201
|
+
excludePattern: [
|
|
192
202
|
/^--_/,
|
|
193
203
|
/^--js-/,
|
|
194
204
|
]
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"$value": "none"
|
|
23
23
|
},
|
|
24
24
|
"border-radius": {
|
|
25
|
-
"$type": "
|
|
25
|
+
"$type": "dimension",
|
|
26
26
|
"$value": "{radius.xs}"
|
|
27
27
|
},
|
|
28
28
|
"padding": {
|
|
@@ -81,6 +81,14 @@
|
|
|
81
81
|
"color": {
|
|
82
82
|
"$type": "color",
|
|
83
83
|
"$value": "transparent"
|
|
84
|
+
},
|
|
85
|
+
"width": {
|
|
86
|
+
"$type": "dimension",
|
|
87
|
+
"$value": "{btn.close.border.width}"
|
|
88
|
+
},
|
|
89
|
+
"radius": {
|
|
90
|
+
"$type": "dimension",
|
|
91
|
+
"$value": "50%"
|
|
84
92
|
}
|
|
85
93
|
},
|
|
86
94
|
"hover": {
|
|
@@ -89,18 +89,25 @@ const config = {
|
|
|
89
89
|
// check-unresolved-custom-props.mjs settings
|
|
90
90
|
// ---------------------------------------------------------------------------
|
|
91
91
|
|
|
92
|
+
// If true, also reports custom properties that are defined (in destFile or
|
|
93
|
+
// an extraCustomPropsFiles entry) but never referenced via var() in any
|
|
94
|
+
// scanned CSS file. Opt-in because it re-runs the Style Dictionary
|
|
95
|
+
// transform pipeline over the token sources to resolve, when possible, the
|
|
96
|
+
// .mjs source file for each unused property. Default: false.
|
|
97
|
+
checkUnused: true,
|
|
98
|
+
|
|
92
99
|
// Additional CSS files that define custom properties used in the project
|
|
93
100
|
// but not generated by build-tokens (e.g. third-party libraries)
|
|
94
|
-
|
|
101
|
+
extraCustomPropsFiles: [
|
|
95
102
|
// '../../node_modules/open-props/open-props.min.css'
|
|
96
103
|
],
|
|
97
104
|
|
|
98
105
|
// Directory containing the CSS files to scan for unresolved custom properties
|
|
99
|
-
|
|
106
|
+
dirToCheck: '../../src',
|
|
100
107
|
|
|
101
108
|
// Regular expressions for custom property names to exclude from the check.
|
|
102
109
|
// Useful for intentionally private/internal props (e.g. prefixed with --_).
|
|
103
|
-
|
|
110
|
+
excludePattern: [
|
|
104
111
|
/^--_/,
|
|
105
112
|
],
|
|
106
113
|
};
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import * as path from 'node:path';
|
|
12
12
|
import { pathToFileURL } from 'node:url';
|
|
13
|
+
import { resolveSourcePaths } from './resolve-source-paths.mjs';
|
|
13
14
|
|
|
14
15
|
// ---------------------------------------------------------------------------
|
|
15
16
|
// Read the --config flag
|
|
@@ -83,34 +84,11 @@ export const mergeCustomProps = buildConfig.mergeCustomProps === true;
|
|
|
83
84
|
// ---------------------------------------------------------------------------
|
|
84
85
|
// Source: resolve patterns relative to the config directory and normalise to
|
|
85
86
|
// forward-slash absolute paths (fast-glob, used internally by Style Dictionary,
|
|
86
|
-
// requires forward slashes even on Windows).
|
|
87
|
-
//
|
|
88
|
-
// Glob patterns (containing *, ?, {, [) are NOT passed through path.join,
|
|
89
|
-
// because path.join can normalise/collapse sequences that carry syntactic
|
|
90
|
-
// meaning in a glob (e.g. "**"). They are only prefixed with configDir and
|
|
91
|
-
// converted to forward slashes.
|
|
92
|
-
// Concrete paths (no glob characters) are resolved canonically with path.resolve.
|
|
87
|
+
// requires forward slashes even on Windows). See resolve-source-paths.mjs.
|
|
93
88
|
//
|
|
94
89
|
// WARNING: in the project config file, avoid building glob patterns with
|
|
95
90
|
// path.join() — it may corrupt the pattern syntax. Use template literals:
|
|
96
91
|
// OK: `${minimo_path}/**/*.{json,mjs}`
|
|
97
92
|
// NO: path.join(minimo_path, '/**/*.{json,mjs}')
|
|
98
93
|
// ---------------------------------------------------------------------------
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
/** @param {string} s */
|
|
102
|
-
const resolveSource = (s) => {
|
|
103
|
-
if (path.isAbsolute(s)) {
|
|
104
|
-
// Already absolute: only normalise separators (needed on Windows)
|
|
105
|
-
return s.split(path.sep).join('/');
|
|
106
|
-
}
|
|
107
|
-
if (GLOB_CHARS.test(s)) {
|
|
108
|
-
// Glob pattern: prefix with configDir without touching the pattern
|
|
109
|
-
const prefix = configDir.split(path.sep).join('/');
|
|
110
|
-
return `${prefix}/${s}`;
|
|
111
|
-
}
|
|
112
|
-
// Concrete relative path: canonical resolution
|
|
113
|
-
return path.resolve(configDir, s).split(path.sep).join('/');
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export const source = buildConfig.source.map(resolveSource);
|
|
94
|
+
export const source = resolveSourcePaths(buildConfig.source, configDir);
|
|
@@ -236,11 +236,24 @@ StyleDictionary.registerFormat({
|
|
|
236
236
|
// Final output is always sorted alphabetically ascending by property
|
|
237
237
|
// name, regardless of merge — this also keeps pre-existing-only
|
|
238
238
|
// properties from merge-css.mjs in order instead of trailing at the end.
|
|
239
|
-
const
|
|
240
|
-
.sort(([a], [b]) => a.localeCompare(b, 'en', { numeric: true, sensitivity: 'base' }))
|
|
241
|
-
|
|
239
|
+
const sortedProps = Object.entries(finalProps)
|
|
240
|
+
.sort(([a], [b]) => a.localeCompare(b, 'en', { numeric: true, sensitivity: 'base' }));
|
|
241
|
+
|
|
242
|
+
// A blank line is inserted between blocks of properties sharing the same
|
|
243
|
+
// first hyphen-separated segment (e.g. all `btn-*` together), to visually
|
|
244
|
+
// group related custom properties in the generated file.
|
|
245
|
+
const outLines = [];
|
|
246
|
+
let prevPrefix = null;
|
|
247
|
+
for (const [name, tail] of sortedProps) {
|
|
248
|
+
const prefix = name.split('-')[0];
|
|
249
|
+
if (prevPrefix !== null && prefix !== prevPrefix) {
|
|
250
|
+
outLines.push('');
|
|
251
|
+
}
|
|
252
|
+
outLines.push(` --${name}: ${tail}`);
|
|
253
|
+
prevPrefix = prefix;
|
|
254
|
+
}
|
|
242
255
|
|
|
243
|
-
customPropsCount =
|
|
256
|
+
customPropsCount = sortedProps.length;
|
|
244
257
|
return `${selector} {\n${outLines.join('\n')}\n}\n`;
|
|
245
258
|
},
|
|
246
259
|
});
|
|
@@ -8,8 +8,10 @@ import { buildPenpotFiles } from './formats/penpot.mjs';
|
|
|
8
8
|
|
|
9
9
|
/** @typedef {import('style-dictionary/types').PlatformConfig} PlatformConfig */
|
|
10
10
|
|
|
11
|
-
// Transforms applied to the CSS platform
|
|
12
|
-
|
|
11
|
+
// Transforms applied to the CSS platform.
|
|
12
|
+
// Exported so other scripts (e.g. check-unresolved-custom-props.mjs) can
|
|
13
|
+
// build a Style Dictionary instance with matching transformed token names.
|
|
14
|
+
export const CSS_TRANSFORMS = [
|
|
13
15
|
'attribute/cti',
|
|
14
16
|
'name/kebab',
|
|
15
17
|
'time/seconds',
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// build-tokens-src/resolve-source-paths.mjs
|
|
2
|
+
// Pure helper: resolves Style Dictionary `source` glob patterns relative to a
|
|
3
|
+
// base directory, without touching glob syntax.
|
|
4
|
+
// Shared by config.mjs (build-tokens.mjs) and check-unresolved-custom-props.mjs.
|
|
5
|
+
//
|
|
6
|
+
// Glob patterns (containing *, ?, {, [) are NOT passed through path.join,
|
|
7
|
+
// because path.join can normalise/collapse sequences that carry syntactic
|
|
8
|
+
// meaning in a glob (e.g. "**"). They are only prefixed with baseDir and
|
|
9
|
+
// converted to forward slashes.
|
|
10
|
+
// Concrete paths (no glob characters) are resolved canonically with path.resolve.
|
|
11
|
+
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
|
|
14
|
+
const GLOB_CHARS = /[*?{[]/;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {string[]} source
|
|
18
|
+
* @param {string} baseDir
|
|
19
|
+
* @returns {string[]}
|
|
20
|
+
*/
|
|
21
|
+
export const resolveSourcePaths = (source, baseDir) => source.map((s) => {
|
|
22
|
+
if (path.isAbsolute(s)) {
|
|
23
|
+
// Already absolute: only normalise separators (needed on Windows)
|
|
24
|
+
return s.split(path.sep).join('/');
|
|
25
|
+
}
|
|
26
|
+
if (GLOB_CHARS.test(s)) {
|
|
27
|
+
// Glob pattern: prefix with baseDir without touching the pattern
|
|
28
|
+
const prefix = baseDir.split(path.sep).join('/');
|
|
29
|
+
return `${prefix}/${s}`;
|
|
30
|
+
}
|
|
31
|
+
// Concrete relative path: canonical resolution
|
|
32
|
+
return path.resolve(baseDir, s).split(path.sep).join('/');
|
|
33
|
+
});
|
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
/* eslint-disable no-console */
|
|
5
5
|
|
|
6
6
|
// check-unresolved-custom-props.mjs
|
|
7
|
-
// Scans CSS files in the configured directory and reports
|
|
8
|
-
// references (var(--...)) that
|
|
7
|
+
// Scans CSS files in the configured directory and reports:
|
|
8
|
+
// - unresolved properties: custom property references (var(--...)) that
|
|
9
|
+
// are not defined in the generated token file
|
|
10
|
+
// - unused properties: custom properties defined in the generated token
|
|
11
|
+
// file but never referenced via var() in any scanned CSS file
|
|
9
12
|
//
|
|
10
13
|
// Usage: node check-unresolved-custom-props.mjs --config ./path/to/config.mjs
|
|
11
14
|
|
|
@@ -18,6 +21,10 @@ import { /* fileURLToPath, */pathToFileURL } from 'node:url';
|
|
|
18
21
|
// import { dirname } from 'path';
|
|
19
22
|
import { glob } from 'node:fs/promises';
|
|
20
23
|
import { styleText } from 'node:util';
|
|
24
|
+
import StyleDictionary from 'style-dictionary';
|
|
25
|
+
import './build-tokens-src/transforms.mjs';
|
|
26
|
+
import { CSS_TRANSFORMS } from './build-tokens-src/platforms.mjs';
|
|
27
|
+
import { resolveSourcePaths } from './build-tokens-src/resolve-source-paths.mjs';
|
|
21
28
|
|
|
22
29
|
// const __filename = fileURLToPath(import.meta.url);
|
|
23
30
|
// const __dirname = dirname(__filename);
|
|
@@ -50,11 +57,11 @@ async function run() {
|
|
|
50
57
|
const custom_prop_filename = path.basename(custom_prop_file_path);
|
|
51
58
|
|
|
52
59
|
// Directory to scan for CSS files
|
|
53
|
-
const checkdir = path.resolve(configDir, config.
|
|
60
|
+
const checkdir = path.resolve(configDir, config.dirToCheck);
|
|
54
61
|
|
|
55
62
|
// Patterns for custom properties to exclude from the unresolved check
|
|
56
63
|
/** @type {RegExp[]} */
|
|
57
|
-
const exclude = config.
|
|
64
|
+
const exclude = config.excludePattern ?? [];
|
|
58
65
|
|
|
59
66
|
// Collect all .css files in the scan directory, excluding the token file itself
|
|
60
67
|
// and any file under a directory whose name starts with "TODO" (work-in-progress folders)
|
|
@@ -75,23 +82,40 @@ async function run() {
|
|
|
75
82
|
// ---------------------------------------------------------------------------
|
|
76
83
|
// 3. Build the list of defined custom properties
|
|
77
84
|
// ---------------------------------------------------------------------------
|
|
78
|
-
const cssContent = fs.readFileSync(custom_prop_file_path, 'utf-8');
|
|
79
85
|
const definitionRegex = /--([a-z0-9-]+)(?=\s*:)/g;
|
|
80
|
-
const propertyNamesList = [...cssContent.matchAll(definitionRegex)].map(m => `--${m[1]}`);
|
|
81
86
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
// defined_props keeps file/line info too, so unused properties (section 6)
|
|
88
|
+
// can be reported with a link back to their definition.
|
|
89
|
+
/** @type {{file: string, line: number, prop: string}[]} */
|
|
90
|
+
const defined_props = [];
|
|
91
|
+
|
|
92
|
+
const cssContent = fs.readFileSync(custom_prop_file_path, 'utf-8');
|
|
93
|
+
const custom_prop_relpath = path.relative(configDir, custom_prop_file_path);
|
|
94
|
+
[...cssContent.matchAll(definitionRegex)].forEach(m => {
|
|
95
|
+
const line = cssContent.substring(0, m.index).split('\n').length;
|
|
96
|
+
defined_props.push({ file: custom_prop_relpath, line, prop: `--${m[1]}` });
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Also include any extra CSS files declared in extraCustomPropsFiles
|
|
100
|
+
for (const extraFile of (config.extraCustomPropsFiles ?? [])) {
|
|
101
|
+
const extraFilePath = path.resolve(configDir, extraFile);
|
|
102
|
+
const extraContent = fs.readFileSync(extraFilePath, 'utf-8');
|
|
103
|
+
const extraRelpath = path.relative(configDir, extraFilePath);
|
|
104
|
+
[...extraContent.matchAll(definitionRegex)].forEach(m => {
|
|
105
|
+
const line = extraContent.substring(0, m.index).split('\n').length;
|
|
106
|
+
defined_props.push({ file: extraRelpath, line, prop: `--${m[1]}` });
|
|
107
|
+
});
|
|
87
108
|
}
|
|
88
109
|
|
|
110
|
+
const propertyNamesList = defined_props.map(item => item.prop);
|
|
111
|
+
|
|
89
112
|
// ---------------------------------------------------------------------------
|
|
90
113
|
// 4. Scan files for unresolved var() references
|
|
91
114
|
// ---------------------------------------------------------------------------
|
|
92
115
|
const usageRegex = /var\(\s*(--[a-z0-9-]+)\s*(,.*?)?\)/g;
|
|
93
116
|
/** @type {{file: string, line: number, prop: string}[]} */
|
|
94
117
|
const unresolved_props = [];
|
|
118
|
+
const used_props_set = new Set();
|
|
95
119
|
|
|
96
120
|
files.forEach(file => {
|
|
97
121
|
const fileContent = fs.readFileSync(file, 'utf-8');
|
|
@@ -104,6 +128,8 @@ async function run() {
|
|
|
104
128
|
const isDefined = propertyNamesList.includes(cprop);
|
|
105
129
|
const lineNumber = fileContent.substring(0, match.index).split('\n').length;
|
|
106
130
|
|
|
131
|
+
used_props_set.add(cprop);
|
|
132
|
+
|
|
107
133
|
if (!isExcluded && !isDefined) {
|
|
108
134
|
unresolved_props.push({ file: filename, line: lineNumber, prop: cprop });
|
|
109
135
|
}
|
|
@@ -112,25 +138,95 @@ async function run() {
|
|
|
112
138
|
|
|
113
139
|
unresolved_props.sort((a, b) => a.file.localeCompare(b.file));
|
|
114
140
|
|
|
141
|
+
// Unused-properties census is opt-in (config.checkUnused: true) since it
|
|
142
|
+
// re-runs the Style Dictionary transform pipeline over the token sources
|
|
143
|
+
// just to resolve source files, which adds a noticeable cost.
|
|
144
|
+
const checkUnused = config.checkUnused === true;
|
|
145
|
+
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// 5. Build the list of unused custom properties (defined but never
|
|
148
|
+
// referenced via var() in any scanned CSS file) — the opposite check
|
|
149
|
+
// of section 4.
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
const unused_props = checkUnused
|
|
152
|
+
? defined_props
|
|
153
|
+
.filter(item => !used_props_set.has(item.prop))
|
|
154
|
+
.sort((a, b) => a.prop.localeCompare(b.prop))
|
|
155
|
+
: [];
|
|
156
|
+
|
|
115
157
|
// ---------------------------------------------------------------------------
|
|
116
|
-
//
|
|
158
|
+
// 6. Best-effort: resolve the .mjs token source file for each unused
|
|
159
|
+
// property, by running the same transform pipeline used to generate the
|
|
160
|
+
// CSS (see build-tokens-src/formats/css.mjs) over the token sources
|
|
161
|
+
// declared in config.source. Properties that only exist in the generated
|
|
162
|
+
// CSS (or an extraCustomPropsFiles entry) — e.g. manual additions kept
|
|
163
|
+
// across rebuilds via the mergeCustomProps option — have no token source
|
|
164
|
+
// and are reported by name only.
|
|
117
165
|
// ---------------------------------------------------------------------------
|
|
118
|
-
|
|
166
|
+
/** @type {Map<string, string>} */
|
|
167
|
+
const sourceFileByProp = new Map();
|
|
168
|
+
|
|
169
|
+
if (checkUnused && Array.isArray(config.source) && config.source.length) {
|
|
170
|
+
try {
|
|
171
|
+
const tokenSourcePaths = resolveSourcePaths(config.source, configDir);
|
|
172
|
+
const sd = new StyleDictionary({
|
|
173
|
+
source: tokenSourcePaths,
|
|
174
|
+
log: { verbosity: 'silent' },
|
|
175
|
+
platforms: { css: { transforms: CSS_TRANSFORMS } },
|
|
176
|
+
});
|
|
177
|
+
const dictionary = await sd.getPlatformTokens('css');
|
|
178
|
+
|
|
179
|
+
for (const token of dictionary.allTokens) {
|
|
180
|
+
if (token.filePath) sourceFileByProp.set(`--${token.name}`, token.filePath);
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
// Non-fatal: unused properties will be reported by name only.
|
|
184
|
+
}
|
|
185
|
+
}
|
|
119
186
|
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// 7. Write the report
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
const result_file = path.resolve(configDir, 'unresolved-unused-props.md');
|
|
191
|
+
|
|
192
|
+
const logParts = [`${unresolved_props.length} unresolved custom properties found`];
|
|
193
|
+
if (checkUnused) {
|
|
194
|
+
logParts.push(`${unused_props.length} unused custom properties found`);
|
|
195
|
+
}
|
|
120
196
|
console.log(styleText(['green'],
|
|
121
|
-
`${
|
|
197
|
+
`${logParts.join(', ')} -> ${path.relative(process.cwd(), result_file)}`
|
|
122
198
|
));
|
|
123
199
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
200
|
+
const sections = [];
|
|
201
|
+
|
|
202
|
+
if (unresolved_props.length) {
|
|
203
|
+
sections.push(
|
|
204
|
+
'## Unresolved custom properties\n\n'
|
|
205
|
+
+ unresolved_props
|
|
128
206
|
.map(item =>
|
|
129
207
|
`* [${path.basename(item.file, '.css')}](${item.file}#L${item.line}) -> \`${item.prop}\``
|
|
130
208
|
)
|
|
131
|
-
.join('\n')
|
|
132
|
-
|
|
209
|
+
.join('\n')
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (unused_props.length) {
|
|
214
|
+
sections.push(
|
|
215
|
+
'## Unused custom properties\n\n'
|
|
216
|
+
+ unused_props
|
|
217
|
+
.map(item => {
|
|
218
|
+
const sourceFilePath = sourceFileByProp.get(item.prop);
|
|
219
|
+
if (!sourceFilePath) return `* \`${item.prop}\``;
|
|
220
|
+
|
|
221
|
+
const relSource = path.relative(configDir, sourceFilePath);
|
|
222
|
+
return `* [${path.basename(relSource)}](${relSource}) -> \`${item.prop}\``;
|
|
223
|
+
})
|
|
224
|
+
.join('\n')
|
|
133
225
|
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (sections.length) {
|
|
229
|
+
fs.writeFileSync(result_file, sections.join('\n\n'), 'utf-8');
|
|
134
230
|
} else {
|
|
135
231
|
if (fs.existsSync(result_file)) {
|
|
136
232
|
fs.unlinkSync(result_file);
|
|
@@ -130,7 +130,7 @@ safe_cat "${TEMPLATES_DIR}/_browserslistrc" .browserslistrc new
|
|
|
130
130
|
safe_cat "${TEMPLATES_DIR}/_editorconfig" .editorconfig new
|
|
131
131
|
safe_cat "${TEMPLATES_DIR}/_prettierrc" .prettierrc new
|
|
132
132
|
safe_cat "${TEMPLATES_DIR}/jsconfig.json" jsconfig.json new
|
|
133
|
-
safe_cat "${
|
|
133
|
+
safe_cat "${BASE_URL}/../../design-tokens/tokens-config-sample.mjs" tokens-config.mjs new
|
|
134
134
|
safe_cat "${TEMPLATES_DIR}/_root_htaccess" _root_htaccess
|
|
135
135
|
safe_cat "${TEMPLATES_DIR}/_root_robots.txt" _root_robots.txt
|
|
136
136
|
|
|
@@ -300,20 +300,6 @@ const config = {
|
|
|
300
300
|
splitChunks: {
|
|
301
301
|
cacheGroups: {
|
|
302
302
|
|
|
303
|
-
icons: {
|
|
304
|
-
test(module) {
|
|
305
|
-
return (
|
|
306
|
-
module.resource &&
|
|
307
|
-
module.resource.includes(`${path.sep}src${path.sep}icons${path.sep}`) &&
|
|
308
|
-
!module.resource.includes(`${path.sep}node_modules${path.sep}`)
|
|
309
|
-
);
|
|
310
|
-
},
|
|
311
|
-
name: 'icons',
|
|
312
|
-
chunks: 'all',
|
|
313
|
-
priority: 20,
|
|
314
|
-
enforce: true
|
|
315
|
-
},
|
|
316
|
-
|
|
317
303
|
shared: {
|
|
318
304
|
// vedi shared_chunk_paths sopra per la logica completa del test
|
|
319
305
|
// (path match + esclusione css quando PurgeCSS è attivo)
|
|
@@ -507,7 +493,16 @@ const config = {
|
|
|
507
493
|
],
|
|
508
494
|
deep: [
|
|
509
495
|
// css modules: prefisso `m_` della build di produzione (vedi css-rules.mjs),
|
|
510
|
-
// le classi
|
|
496
|
+
// le classi con hash non possono comparire nei file scansionati
|
|
497
|
+
/^m_/
|
|
498
|
+
],
|
|
499
|
+
keyframes: [
|
|
500
|
+
// stesso motivo dei selettori sopra, più un bug di purgecss: dentro un
|
|
501
|
+
// blocco `purgecss start/end ignore` la regola è preservata ma le sue
|
|
502
|
+
// dichiarazioni non vengono scansionate per l'uso di animation-name
|
|
503
|
+
// (vedi @keyframes slide-in/slide-out di minimo snackbar.module.css),
|
|
504
|
+
// quindi l'@keyframes verrebbe rimosso come "non referenziato" anche
|
|
505
|
+
// se in realtà è usato dalla regola stessa
|
|
511
506
|
/^m_/
|
|
512
507
|
],
|
|
513
508
|
greedy: [
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@ export default{
|
|
|
18
18
|
},
|
|
19
19
|
'border-radius': {
|
|
20
20
|
$value: '{radius.xs}',
|
|
21
|
-
$type: '
|
|
21
|
+
$type: 'dimension'
|
|
22
22
|
},
|
|
23
23
|
padding: {
|
|
24
24
|
block: {
|
|
@@ -79,6 +79,14 @@ export default{
|
|
|
79
79
|
color: {
|
|
80
80
|
$value: 'transparent',
|
|
81
81
|
$type: 'color'
|
|
82
|
+
},
|
|
83
|
+
width: {
|
|
84
|
+
$type: 'dimension',
|
|
85
|
+
$value: '{btn.close.border.width}'
|
|
86
|
+
},
|
|
87
|
+
radius: {
|
|
88
|
+
$type: 'dimension',
|
|
89
|
+
$value: '50%'
|
|
82
90
|
}
|
|
83
91
|
},
|
|
84
92
|
|
|
@@ -54,7 +54,9 @@
|
|
|
54
54
|
--btn-close-background-color: var(--snackbar-btn-close-background-color);
|
|
55
55
|
--btn-close-icon-color: var(--snackbar-btn-close-icon-color);
|
|
56
56
|
--btn-close-icon-bar-size: 2px;
|
|
57
|
-
|
|
57
|
+
--btn-close-border-color: var(--snackbar-btn-close-border-color);
|
|
58
|
+
--btn-close-border-width: var(--snackbar-btn-close-border-width);
|
|
59
|
+
--btn-close-border-radius: var(--snackbar-btn-close-border-radius);
|
|
58
60
|
|
|
59
61
|
--btn-close-hover-background-color: var(--snackbar-btn-close-hover-background-color);
|
|
60
62
|
--btn-close-hover-border-color: var(--snackbar-btn-close-hover-border-color);
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
--accent-100: #567d0d;
|
|
3
3
|
--accent-100-fg: #fff;
|
|
4
4
|
--accent-color: var(--accent-100);
|
|
5
|
+
|
|
5
6
|
--alert-border-radius: var(--radius-sm);
|
|
6
7
|
--alert-box-shadow: 0 0 .5rem 0 oklch(0% 0 0 / .5);
|
|
8
|
+
|
|
7
9
|
--badge-background-color: var(--primary-100);
|
|
8
10
|
--badge-color: var(--primary-100-fg);
|
|
9
11
|
--badge-font-size: var(--font-size-xs);
|
|
10
12
|
--badge-font-weight: var(--font-weight-semibold);
|
|
11
13
|
--badge-lg-font-size: var(--font-size-base);
|
|
12
14
|
--badge-lg-font-weight: var(--badge-font-weight);
|
|
15
|
+
|
|
13
16
|
--body-background-color: #fff;
|
|
14
17
|
--body-text: var(--text-color);
|
|
18
|
+
|
|
15
19
|
--box-shadow-base: 0 0 .75rem 0 rgb(0 0 0 / .25);
|
|
20
|
+
|
|
16
21
|
--btn-border-radius: var(--form-control-border-radius);
|
|
17
22
|
--btn-border-width: var(--form-control-border-width);
|
|
18
23
|
--btn-close-active-background-color: var(--btn-close-background-color);
|
|
@@ -89,7 +94,9 @@
|
|
|
89
94
|
--btn-xs-font-size: var(--font-size-xs);
|
|
90
95
|
--btn-xs-padding-block: var(--size-xxs);
|
|
91
96
|
--btn-xs-padding-inline: var(--size-xxs);
|
|
97
|
+
|
|
92
98
|
--flex-grid-gap: 1.5rem;
|
|
99
|
+
|
|
93
100
|
--font-family: sans-serif;
|
|
94
101
|
--font-family-mono: 'Monaspace Neon Var', 'Monaspace Neon', 'Aptos Mono', 'Roboto Mono', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Andale Mono', 'Courier New', monospace;
|
|
95
102
|
--font-size-2xl: clamp(2rem, .7692rem + 1.9231vw, 2.5rem);
|
|
@@ -110,6 +117,7 @@
|
|
|
110
117
|
--font-weight-xbold: 900;
|
|
111
118
|
--font-weight-xlight: 200;
|
|
112
119
|
--font-weight-xxlight: 100;
|
|
120
|
+
|
|
113
121
|
--form-control-background-color: var(--body-background-color);
|
|
114
122
|
--form-control-border-color: #666;
|
|
115
123
|
--form-control-border-radius: var(--radius-xxs);
|
|
@@ -170,8 +178,10 @@
|
|
|
170
178
|
--form-user-info-font-size: var(--font-size-xs);
|
|
171
179
|
--form-validation-outline-offset: -.1875rem;
|
|
172
180
|
--form-validation-outline-width: .1875rem;
|
|
181
|
+
|
|
173
182
|
--grid-cols: 3;
|
|
174
183
|
--grid-min-col-width: 6rem;
|
|
184
|
+
|
|
175
185
|
--headings-color: var(--text-color);
|
|
176
186
|
--headings-font-family: var(--font-family);
|
|
177
187
|
--headings-font-weight: var(--font-weight-semibold);
|
|
@@ -182,18 +192,23 @@
|
|
|
182
192
|
--headings-h4-font-size: var(--font-size-md);
|
|
183
193
|
--headings-line-height: var(--line-height-xs);
|
|
184
194
|
--headings-text-align: inherit;
|
|
195
|
+
|
|
185
196
|
--inner-nav-gap: var(--size-lg);
|
|
186
197
|
--inner-nav-margin-block: var(--size-base);
|
|
198
|
+
|
|
187
199
|
--layout-container-max-width: 80rem;
|
|
200
|
+
|
|
188
201
|
--line-height-base: 1.5;
|
|
189
202
|
--line-height-sm: 1.4;
|
|
190
203
|
--line-height-xs: 1.25;
|
|
204
|
+
|
|
191
205
|
--link-active-background-color: transparent;
|
|
192
206
|
--link-active-color: #51054c;
|
|
193
207
|
--link-color: #0d12ae;
|
|
194
208
|
--link-focus-outline-color: var(--link-color);
|
|
195
209
|
--link-focus-outline-width: .125rem;
|
|
196
210
|
--link-visited-color: #ae0da3;
|
|
211
|
+
|
|
197
212
|
--malert-backdrop: rgb(0 0 0 / .7);
|
|
198
213
|
--malert-background-color: #fff;
|
|
199
214
|
--malert-border-radius: var(--radius-xs);
|
|
@@ -215,6 +230,7 @@
|
|
|
215
230
|
--malert-text-font-size: var(--font-size-base);
|
|
216
231
|
--malert-warning-bg: var(--status-warning-background-color);
|
|
217
232
|
--malert-warning-fg: var(--status-warning-fg);
|
|
233
|
+
|
|
218
234
|
--mpopup-backdrop-color: rgb(0 0 0 / .6);
|
|
219
235
|
--mpopup-background-color: var(--body-background-color);
|
|
220
236
|
--mpopup-border-radius: var(--size-base);
|
|
@@ -236,11 +252,15 @@
|
|
|
236
252
|
--mpopup-min-height: 18.75rem;
|
|
237
253
|
--mpopup-min-width: 25rem;
|
|
238
254
|
--mpopup-width: max-content;
|
|
255
|
+
|
|
239
256
|
--neutral-100: #666;
|
|
240
257
|
--neutral-100-fg: #fff;
|
|
258
|
+
|
|
241
259
|
--overlay-color: rgb(0 0 0 / .6);
|
|
260
|
+
|
|
242
261
|
--primary-100: #083865;
|
|
243
262
|
--primary-100-fg: #fff;
|
|
263
|
+
|
|
244
264
|
--radius-base: var(--size-base);
|
|
245
265
|
--radius-lg: var(--size-lg);
|
|
246
266
|
--radius-md: var(--size-md);
|
|
@@ -249,14 +269,17 @@
|
|
|
249
269
|
--radius-xl: var(--size-xl);
|
|
250
270
|
--radius-xs: var(--size-xs);
|
|
251
271
|
--radius-xxs: var(--size-xxs);
|
|
272
|
+
|
|
252
273
|
--sdt-hover-background-color: var(--btn-primary-background-color);
|
|
253
274
|
--sdt-hover-color: var(--btn-primary-color);
|
|
254
275
|
--sdt-pagination-border: var(--btn-border-width) var(--neutral-100);
|
|
255
276
|
--sdt-pagination-padding-block: var(--size-xxs);
|
|
256
277
|
--sdt-pagination-padding-inline: var(--size-xs);
|
|
257
278
|
--sdt-thead-hover-background-color: color-mix(in srgb, var(--table-thead-background-color) 90%, var(--accent-100));
|
|
279
|
+
|
|
258
280
|
--secondary-100: #650853;
|
|
259
281
|
--secondary-100-fg: #fff;
|
|
282
|
+
|
|
260
283
|
--sf-macro-btn-close-background-color: var(--btn-close-background-color);
|
|
261
284
|
--sf-macro-btn-close-position-bottom: auto;
|
|
262
285
|
--sf-macro-btn-close-position-left: auto;
|
|
@@ -269,6 +292,7 @@
|
|
|
269
292
|
--sf-macro-rows-hover-background-color: color-mix(in srgb, var(--body-background-color) 95%, #000);
|
|
270
293
|
--sf-macro-rows-margin-block-end: var(--size-base);
|
|
271
294
|
--sf-macro-rows-padding: var(--size-xs);
|
|
295
|
+
|
|
272
296
|
--size-2xl: 3rem;
|
|
273
297
|
--size-3xl: 4rem;
|
|
274
298
|
--size-base: 1rem;
|
|
@@ -278,13 +302,17 @@
|
|
|
278
302
|
--size-xl: 2rem;
|
|
279
303
|
--size-xs: .5rem;
|
|
280
304
|
--size-xxs: .25rem;
|
|
305
|
+
|
|
281
306
|
--slide-duration: 500ms;
|
|
307
|
+
|
|
282
308
|
--snackbar-background-color: var(--secondary-100);
|
|
283
309
|
--snackbar-border-radius: var(--radius-xs);
|
|
284
310
|
--snackbar-btn-close-active-background-color: transparent;
|
|
285
311
|
--snackbar-btn-close-active-icon-color: var(--snackbar-text-color);
|
|
286
312
|
--snackbar-btn-close-background-color: transparent;
|
|
287
313
|
--snackbar-btn-close-border-color: transparent;
|
|
314
|
+
--snackbar-btn-close-border-radius: 50%;
|
|
315
|
+
--snackbar-btn-close-border-width: var(--btn-close-border-width);
|
|
288
316
|
--snackbar-btn-close-focus-outline-color: color-mix(in srgb, var(--snackbar-text-color) 50%, transparent);
|
|
289
317
|
--snackbar-btn-close-focus-outline-offset: .125rem;
|
|
290
318
|
--snackbar-btn-close-focus-outline-width: .125rem;
|
|
@@ -301,9 +329,11 @@
|
|
|
301
329
|
--snackbar-outer-padding-block: 0;
|
|
302
330
|
--snackbar-outer-padding-inline: 0;
|
|
303
331
|
--snackbar-text-color: var(--secondary-100-fg);
|
|
332
|
+
|
|
304
333
|
--spinner-color: var(--primary-100);
|
|
305
334
|
--spinner-size: var(--size-lg);
|
|
306
335
|
--spinner-stroke-width: .125rem;
|
|
336
|
+
|
|
307
337
|
--status-danger-background-color: var(--status-danger-color);
|
|
308
338
|
--status-danger-border-color: var(--status-danger-color);
|
|
309
339
|
--status-danger-color: #c00;
|
|
@@ -320,9 +350,11 @@
|
|
|
320
350
|
--status-warning-border-color: var(--status-warning-color);
|
|
321
351
|
--status-warning-color: #fc0;
|
|
322
352
|
--status-warning-fg: #4f2900;
|
|
353
|
+
|
|
323
354
|
--switch-background-color: var(--neutral-100);
|
|
324
355
|
--switch-checked-background-color: var(--primary-100);
|
|
325
356
|
--switch-cursor-background-color: var(--body-background-color);
|
|
357
|
+
|
|
326
358
|
--table-body-border-width: .0625rem;
|
|
327
359
|
--table-body-tr-alt-bg-color: #efefef;
|
|
328
360
|
--table-body-tr-hover-bg-color: #cbcbcb;
|
|
@@ -335,12 +367,14 @@
|
|
|
335
367
|
--table-tfoot-font-weight: var(--font-weight-semibold);
|
|
336
368
|
--table-thead-background-color: #ddd;
|
|
337
369
|
--table-thead-border-width: .1875rem;
|
|
370
|
+
|
|
338
371
|
--text-color: #000;
|
|
339
372
|
--text-dim: var(--text-muted);
|
|
340
373
|
--text-muted: var(--neutral-100);
|
|
341
374
|
--text-negative: #fff;
|
|
342
375
|
--text-selected-background-color: #ddd;
|
|
343
376
|
--text-selected-color: var(--body-text);
|
|
377
|
+
|
|
344
378
|
--uspg-bg-color: hsl(0deg 0% 0% / .7);
|
|
345
379
|
--uspg-credits-font-size: var(--font-size-xs);
|
|
346
380
|
--uspg-credits-font-weight: var(--font-weight-regular);
|
|
@@ -371,6 +405,7 @@
|
|
|
371
405
|
--uspg-link-visited-color: #ff117b;
|
|
372
406
|
--uspg-loader-color: hsl(0deg 0% 100% / .6);
|
|
373
407
|
--uspg-text-color: #fff;
|
|
408
|
+
|
|
374
409
|
--z-index-overlay: 99;
|
|
375
410
|
--z-index-snackbar: 100;
|
|
376
411
|
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
// import path from 'path';
|
|
3
|
-
|
|
4
|
-
// path relativi a questo file
|
|
5
|
-
|
|
6
|
-
const config = {
|
|
7
|
-
// build tokens
|
|
8
|
-
stylelintConfigPath: '../../stylelint.config.mjs',
|
|
9
|
-
buildPath: '../src/css',
|
|
10
|
-
destFile: 'custom-properties.css',
|
|
11
|
-
source: [
|
|
12
|
-
'../../node_modules/@massimo-cassandro/minimo/design-tokens/_src/**/*.tokens.{mjs,jsonc}',
|
|
13
|
-
'./figma-tokens-OK/*.{jsonc,mjs}',
|
|
14
|
-
],
|
|
15
|
-
|
|
16
|
-
colorScalePrefixes: ['primary', 'secondary', 'neutral'],
|
|
17
|
-
|
|
18
|
-
penpotFormat: 'jsonc',
|
|
19
|
-
penpotBuildPath: null,
|
|
20
|
-
penpotDestFile: null,
|
|
21
|
-
penpotExpressions: 'resolve',
|
|
22
|
-
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
// check-unresolved-custom-props.mjs settings
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
extra_custom_props_files: [],
|
|
27
|
-
dir_to_check: '../src', // percorso della dir che include i css da analizzare
|
|
28
|
-
exclude_pattern: [ // patterns per l'esclusione dal controllo unresolved-props
|
|
29
|
-
/^--_/,
|
|
30
|
-
]
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export default config;
|