@design-parity/diff 0.1.2 → 0.1.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/README.md +11 -2
- package/dist/design-system.d.ts +29 -0
- package/dist/design-system.d.ts.map +1 -0
- package/dist/design-system.js +53 -0
- package/dist/design-system.js.map +1 -0
- package/dist/diff.d.ts +7 -1
- package/dist/diff.d.ts.map +1 -1
- package/dist/diff.js +5 -3
- package/dist/diff.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/tokens.d.ts +17 -4
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +152 -11
- package/dist/tokens.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -35,8 +35,17 @@ are ordered a11y → token → semantic → visual; `verdict.visualScores` maps
|
|
|
35
35
|
targets, semantic roles/labels, and i18n risks. `defaultChecks` wires the real
|
|
36
36
|
package; inject a custom provider (or `checksConfig`) to override.
|
|
37
37
|
- **Token compliance** — flatten the candidate's tree tokens and compare against
|
|
38
|
-
the reference spec: numeric tokens honour a committed tolerance,
|
|
39
|
-
|
|
38
|
+
the reference spec: numeric tokens honour a committed tolerance, typography
|
|
39
|
+
matches exactly, colours match modulo a full-alpha suffix (with a same-role
|
|
40
|
+
value fallback). When the design and code token vocabularies differ, a
|
|
41
|
+
`design-map.json` `tokens` alias (code-name → design-name) canonicalises the
|
|
42
|
+
reference to code names first, so e.g. design `color/on-surface` lines up with
|
|
43
|
+
code `onSurface`.
|
|
44
|
+
- **Design system** — a whole-palette audit: the reference's resolved token
|
|
45
|
+
table (`DesignReference.themeTokens`, e.g. the Figma Variables) vs the code's
|
|
46
|
+
resolved theme (`SemanticTree.themeTokens`), keyed through the same alias.
|
|
47
|
+
Findings carry `detail.scope: "design-system"` so the orchestrator reports
|
|
48
|
+
each drift once per run, not once per screen.
|
|
40
49
|
- **Semantics** — theme-coverage and structural (role/label) deltas.
|
|
41
50
|
- **Visual** — per-pixel diff via `pixelmatch`, plus the triptych.
|
|
42
51
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design-system token-table audit (Phase 3).
|
|
3
|
+
*
|
|
4
|
+
* Where {@link diffTokens} compares a screen's *per-node* tokens, this compares
|
|
5
|
+
* the whole **design-system palette** — the design source's resolved token table
|
|
6
|
+
* ({@link DesignReference.themeTokens}, e.g. the Figma Variables) against the
|
|
7
|
+
* code's resolved theme ({@link SemanticTree.themeTokens}, the compose theme).
|
|
8
|
+
* It runs once per render, keyed through the same code↔design alias as Phase 1,
|
|
9
|
+
* so a palette mismatch (`onSurface` is `#161D1B` in design, `#101413` in code)
|
|
10
|
+
* is reported at the design-system altitude rather than once per screen.
|
|
11
|
+
*
|
|
12
|
+
* v1 audits colours. The design table keys colours `<name>.<mode>` (one per
|
|
13
|
+
* Variable mode); the code theme is already resolved to a single theme, so only
|
|
14
|
+
* the entries for the render's `theme` are compared.
|
|
15
|
+
*/
|
|
16
|
+
import type { DesignTokens, Finding, Theme, TokenAliasMap } from "@design-parity/core";
|
|
17
|
+
export interface DesignSystemOptions {
|
|
18
|
+
/** The render's theme; only design tokens for this mode are audited. */
|
|
19
|
+
theme?: Theme;
|
|
20
|
+
/** Code-name ↔ design-name aliases (the `design-map.json` `tokens` section). */
|
|
21
|
+
alias?: TokenAliasMap;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Compare the design-system palette against the code theme, returning findings
|
|
25
|
+
* tagged `detail.scope: "design-system"` so the orchestrator can report each
|
|
26
|
+
* once across the run. Empty when either table (or its colours) is absent.
|
|
27
|
+
*/
|
|
28
|
+
export declare function diffDesignSystem(designSystem: DesignTokens | undefined, codeTheme: DesignTokens | undefined, options?: DesignSystemOptions): Finding[];
|
|
29
|
+
//# sourceMappingURL=design-system.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-system.d.ts","sourceRoot":"","sources":["../src/design-system.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,KAAK,EACL,aAAa,EACd,MAAM,qBAAqB,CAAC;AAI7B,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gFAAgF;IAChF,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AASD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,SAAS,EAAE,YAAY,GAAG,SAAS,EACnC,OAAO,GAAE,mBAAwB,GAChC,OAAO,EAAE,CAuCX"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { aliasInverse, aliasKey, colorsEqual } from "./tokens.js";
|
|
2
|
+
/** Split a design colour key `<name>.<mode>` into its base and mode (if any). */
|
|
3
|
+
function splitMode(key) {
|
|
4
|
+
const dot = key.lastIndexOf(".");
|
|
5
|
+
if (dot <= 0)
|
|
6
|
+
return { base: key };
|
|
7
|
+
return { base: key.slice(0, dot), mode: key.slice(dot + 1).toLowerCase() };
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Compare the design-system palette against the code theme, returning findings
|
|
11
|
+
* tagged `detail.scope: "design-system"` so the orchestrator can report each
|
|
12
|
+
* once across the run. Empty when either table (or its colours) is absent.
|
|
13
|
+
*/
|
|
14
|
+
export function diffDesignSystem(designSystem, codeTheme, options = {}) {
|
|
15
|
+
const designColors = designSystem?.colors;
|
|
16
|
+
const codeColors = codeTheme?.colors;
|
|
17
|
+
if (!designColors || !codeColors)
|
|
18
|
+
return [];
|
|
19
|
+
const toCode = aliasInverse(options.alias?.colors);
|
|
20
|
+
const findings = [];
|
|
21
|
+
for (const [designKey, designValue] of Object.entries(designColors)) {
|
|
22
|
+
const { base, mode } = splitMode(designKey);
|
|
23
|
+
const codeName = toCode.get(aliasKey(base)) ?? base;
|
|
24
|
+
// Prefer a mode-suffixed code token (a code table that, like the design's,
|
|
25
|
+
// carries every mode). Otherwise the code theme is resolved to one theme, so
|
|
26
|
+
// only the render's mode lines up with the unsuffixed token.
|
|
27
|
+
let codeValue = mode ? codeColors[`${codeName}.${mode}`] : undefined;
|
|
28
|
+
if (codeValue === undefined) {
|
|
29
|
+
if (mode && options.theme && mode !== options.theme)
|
|
30
|
+
continue;
|
|
31
|
+
codeValue = codeColors[codeName];
|
|
32
|
+
}
|
|
33
|
+
if (codeValue === undefined)
|
|
34
|
+
continue; // not in the code theme — skip (v1)
|
|
35
|
+
if (colorsEqual(designValue, codeValue))
|
|
36
|
+
continue;
|
|
37
|
+
findings.push({
|
|
38
|
+
kind: "token",
|
|
39
|
+
severity: "warn",
|
|
40
|
+
message: `design-system colors.${codeName}: code ${codeValue} vs design ${designValue}` +
|
|
41
|
+
(mode ? ` (${mode})` : ""),
|
|
42
|
+
detail: {
|
|
43
|
+
scope: "design-system",
|
|
44
|
+
token: `colors.${codeName}`,
|
|
45
|
+
expected: designValue,
|
|
46
|
+
actual: codeValue,
|
|
47
|
+
...(mode ? { mode } : {}),
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return findings;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=design-system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-system.js","sourceRoot":"","sources":["../src/design-system.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AASlE,iFAAiF;AACjF,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACnC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;AAC7E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,YAAsC,EACtC,SAAmC,EACnC,UAA+B,EAAE;IAEjC,MAAM,YAAY,GAAG,YAAY,EAAE,MAAM,CAAC;IAC1C,MAAM,UAAU,GAAG,SAAS,EAAE,MAAM,CAAC;IACrC,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAE5C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,KAAK,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACpE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;QAEpD,2EAA2E;QAC3E,6EAA6E;QAC7E,6DAA6D;QAC7D,IAAI,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC,KAAK;gBAAE,SAAS;YAC9D,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,SAAS,KAAK,SAAS;YAAE,SAAS,CAAC,oCAAoC;QAC3E,IAAI,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC;YAAE,SAAS;QAElD,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,MAAM;YAChB,OAAO,EACL,wBAAwB,QAAQ,UAAU,SAAS,cAAc,WAAW,EAAE;gBAC9E,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,EAAE;gBACN,KAAK,EAAE,eAAe;gBACtB,KAAK,EAAE,UAAU,QAAQ,EAAE;gBAC3B,QAAQ,EAAE,WAAW;gBACrB,MAAM,EAAE,SAAS;gBACjB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1B;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/diff.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CandidateRender, DesignReference, Verdict } from "@design-parity/core";
|
|
1
|
+
import type { CandidateRender, DesignReference, TokenAliasMap, Verdict } from "@design-parity/core";
|
|
2
2
|
import { type ChecksConfig, type ChecksProvider } from "./checks.js";
|
|
3
3
|
import { type DiffConfig } from "./config.js";
|
|
4
4
|
export interface DiffOptions {
|
|
@@ -13,6 +13,12 @@ export interface DiffOptions {
|
|
|
13
13
|
checks?: ChecksProvider;
|
|
14
14
|
/** Committed a11y/i18n thresholds passed to the checks provider. */
|
|
15
15
|
checksConfig?: ChecksConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Design-name ↔ code-name token aliases (the repo's `design-map.json`
|
|
18
|
+
* `tokens` section). When set, token-compliance canonicalises the design-named
|
|
19
|
+
* reference spec to code names before comparing (issue #78).
|
|
20
|
+
*/
|
|
21
|
+
tokenAlias?: TokenAliasMap;
|
|
16
22
|
/**
|
|
17
23
|
* If set, triptych PNGs are written here as `triptych-<key>.png` and their
|
|
18
24
|
* paths land in {@link DiffResult.triptychs}. Omit to skip disk writes; the
|
package/dist/diff.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAGf,OAAO,EAER,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAGf,aAAa,EACb,OAAO,EAER,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAc7D,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,oEAAoE;IACpE,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,8CAA8C;AAC9C,MAAM,WAAW,QAAQ;IACvB,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAuDD;;;GAGG;AACH,wBAAsB,IAAI,CACxB,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,eAAe,EAC1B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAuFrB"}
|
package/dist/diff.js
CHANGED
|
@@ -11,6 +11,7 @@ import { mkdir, writeFile } from "node:fs/promises";
|
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { defaultChecks, } from "./checks.js";
|
|
13
13
|
import { resolveConfig } from "./config.js";
|
|
14
|
+
import { diffDesignSystem } from "./design-system.js";
|
|
14
15
|
import { diffSemantics } from "./semantic.js";
|
|
15
16
|
import { renderSummary } from "./summary.js";
|
|
16
17
|
import { collectTokens, diffTokens } from "./tokens.js";
|
|
@@ -72,8 +73,9 @@ export async function diff(reference, candidate, options = {}) {
|
|
|
72
73
|
candidate,
|
|
73
74
|
config: options.checksConfig ?? {},
|
|
74
75
|
});
|
|
75
|
-
// 2. token compliance.
|
|
76
|
-
const tokens = diffTokens(reference.tokens, candidateTokens, config);
|
|
76
|
+
// 2. token compliance: per-node tokens, then the design-system palette audit.
|
|
77
|
+
const tokens = diffTokens(reference.tokens, candidateTokens, config, options.tokenAlias);
|
|
78
|
+
const designSystem = diffDesignSystem(reference.themeTokens, candidate.semantics.themeTokens, { ...(candidate.semantics.theme ? { theme: candidate.semantics.theme } : {}), ...(options.tokenAlias ? { alias: options.tokenAlias } : {}) });
|
|
77
79
|
// 3. semantics (+ reference variants with no candidate counterpart).
|
|
78
80
|
const semantic = diffSemantics(reference, candidate);
|
|
79
81
|
const { pairs, unmatched } = pairImages(reference, candidate);
|
|
@@ -118,7 +120,7 @@ export async function diff(reference, candidate, options = {}) {
|
|
|
118
120
|
});
|
|
119
121
|
}
|
|
120
122
|
}
|
|
121
|
-
const findings = [...a11y, ...tokens, ...semantic, ...visualFindings];
|
|
123
|
+
const findings = [...a11y, ...tokens, ...designSystem, ...semantic, ...visualFindings];
|
|
122
124
|
const verdict = {
|
|
123
125
|
componentId: candidate.componentId,
|
|
124
126
|
status: statusFor(findings),
|
package/dist/diff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export type { DiffConfig } from "./config.js";
|
|
|
13
13
|
export { defaultChecks } from "./checks.js";
|
|
14
14
|
export type { ChecksProvider, ChecksInput, ChecksConfig } from "./checks.js";
|
|
15
15
|
export { collectTokens, diffTokens } from "./tokens.js";
|
|
16
|
+
export { diffDesignSystem } from "./design-system.js";
|
|
17
|
+
export type { DesignSystemOptions } from "./design-system.js";
|
|
16
18
|
export { diffSemantics, referenceThemes, candidateThemes } from "./semantic.js";
|
|
17
19
|
export { diffImagePair, imageKey } from "./visual.js";
|
|
18
20
|
export type { VisualResult } from "./visual.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEnE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export { diff } from "./diff.js";
|
|
|
10
10
|
export { defaultDiffConfig, resolveConfig } from "./config.js";
|
|
11
11
|
export { defaultChecks } from "./checks.js";
|
|
12
12
|
export { collectTokens, diffTokens } from "./tokens.js";
|
|
13
|
+
export { diffDesignSystem } from "./design-system.js";
|
|
13
14
|
export { diffSemantics, referenceThemes, candidateThemes } from "./semantic.js";
|
|
14
15
|
export { diffImagePair, imageKey } from "./visual.js";
|
|
15
16
|
export { renderSummary } from "./summary.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG/D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG/D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/tokens.d.ts
CHANGED
|
@@ -4,18 +4,31 @@
|
|
|
4
4
|
* A {@link DesignReference} carries one flat {@link DesignTokens} bag; a
|
|
5
5
|
* {@link CandidateRender} scatters tokens across its semantic tree. We flatten
|
|
6
6
|
* the candidate's tree into the same shape, then compare key-by-key against the
|
|
7
|
-
* reference spec. Numeric tokens honour a committed tolerance;
|
|
8
|
-
*
|
|
7
|
+
* reference spec. Numeric tokens honour a committed tolerance; typography must
|
|
8
|
+
* match exactly; colours match modulo a full-alpha suffix (`#RRGGBB` ==
|
|
9
|
+
* `#RRGGBBAA`). A spec token the candidate couldn't name falls back to a value
|
|
10
|
+
* match before being reported missing — same-role for colours, within-tolerance
|
|
11
|
+
* for spacing/radius — since the candidate carries resolved values under generic
|
|
12
|
+
* keys rather than the reference's names (compose-ai-tools#1897).
|
|
9
13
|
*/
|
|
10
|
-
import type
|
|
14
|
+
import { type DesignTokens, type Finding, type SemanticNode, type TokenAliasMap } from "@design-parity/core";
|
|
11
15
|
import type { DiffConfig } from "./config.js";
|
|
12
16
|
/** Deep-merge every node's tokens into one flat bag (children override parents). */
|
|
13
17
|
export declare function collectTokens(root: SemanticNode): DesignTokens;
|
|
18
|
+
/** Fold a token name to an alias-lookup key: last `/`-segment, lowercased. */
|
|
19
|
+
export declare function aliasKey(name: string): string;
|
|
20
|
+
/** Invert a code→design alias group into a design-key → code-name index. */
|
|
21
|
+
export declare function aliasInverse(group?: Record<string, string>): Map<string, string>;
|
|
14
22
|
/**
|
|
15
23
|
* Compare candidate tokens against the reference spec. Findings are emitted in
|
|
16
24
|
* a stable order — spacing, radius, colours, typography — so the verdict is
|
|
17
25
|
* reproducible. A reference token absent from the candidate is a `missing`
|
|
18
26
|
* finding; tokens the candidate adds beyond the spec are ignored.
|
|
27
|
+
*
|
|
28
|
+
* When a {@link TokenAliasMap} is supplied, the design-named spec is first
|
|
29
|
+
* canonicalised to code names so differing vocabularies still match.
|
|
19
30
|
*/
|
|
20
|
-
export declare function diffTokens(
|
|
31
|
+
export declare function diffTokens(specInput: DesignTokens | undefined, candidate: DesignTokens, config: DiffConfig, alias?: TokenAliasMap): Finding[];
|
|
32
|
+
/** Compare two colours, treating `#RRGGBB` and full-alpha `#RRGGBBAA` as equal. */
|
|
33
|
+
export declare function colorsEqual(a: string, b: string): boolean;
|
|
21
34
|
//# sourceMappingURL=tokens.d.ts.map
|
package/dist/tokens.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,EAInB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAQ9D;AAqBD,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOhF;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,YAAY,GAAG,SAAS,EACnC,SAAS,EAAE,YAAY,EACvB,MAAM,EAAE,UAAU,EAClB,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,EAAE,CA8DX;AAyFD,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAKzD"}
|
package/dist/tokens.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token collection + token-compliance diff.
|
|
3
|
+
*
|
|
4
|
+
* A {@link DesignReference} carries one flat {@link DesignTokens} bag; a
|
|
5
|
+
* {@link CandidateRender} scatters tokens across its semantic tree. We flatten
|
|
6
|
+
* the candidate's tree into the same shape, then compare key-by-key against the
|
|
7
|
+
* reference spec. Numeric tokens honour a committed tolerance; typography must
|
|
8
|
+
* match exactly; colours match modulo a full-alpha suffix (`#RRGGBB` ==
|
|
9
|
+
* `#RRGGBBAA`). A spec token the candidate couldn't name falls back to a value
|
|
10
|
+
* match before being reported missing — same-role for colours, within-tolerance
|
|
11
|
+
* for spacing/radius — since the candidate carries resolved values under generic
|
|
12
|
+
* keys rather than the reference's names (compose-ai-tools#1897).
|
|
13
|
+
*/
|
|
14
|
+
import { materialColorRole, materialTypeRole, } from "@design-parity/core";
|
|
1
15
|
/** Deep-merge every node's tokens into one flat bag (children override parents). */
|
|
2
16
|
export function collectTokens(root) {
|
|
3
17
|
const out = {};
|
|
@@ -28,40 +42,104 @@ function typographyEqual(a, b) {
|
|
|
28
42
|
a.lineHeight === b.lineHeight &&
|
|
29
43
|
a.letterSpacing === b.letterSpacing);
|
|
30
44
|
}
|
|
45
|
+
/** Fold a token name to an alias-lookup key: last `/`-segment, lowercased. */
|
|
46
|
+
export function aliasKey(name) {
|
|
47
|
+
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
/** Invert a code→design alias group into a design-key → code-name index. */
|
|
50
|
+
export function aliasInverse(group) {
|
|
51
|
+
const inv = new Map();
|
|
52
|
+
for (const [code, design] of Object.entries(group ?? {})) {
|
|
53
|
+
const key = aliasKey(design);
|
|
54
|
+
if (!inv.has(key))
|
|
55
|
+
inv.set(key, code); // first declaration wins, deterministically
|
|
56
|
+
}
|
|
57
|
+
return inv;
|
|
58
|
+
}
|
|
59
|
+
/** Rewrite a token group's keys from design names to code names via the alias. */
|
|
60
|
+
function remapKeys(group, alias) {
|
|
61
|
+
if (!group)
|
|
62
|
+
return group;
|
|
63
|
+
const inv = aliasInverse(alias);
|
|
64
|
+
if (inv.size === 0)
|
|
65
|
+
return group;
|
|
66
|
+
const out = {};
|
|
67
|
+
for (const [name, value] of Object.entries(group)) {
|
|
68
|
+
out[inv.get(aliasKey(name)) ?? name] = value;
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Canonicalise the design-named reference spec to code names via the alias map,
|
|
74
|
+
* so the key-by-key comparison below lines design tokens up with their code
|
|
75
|
+
* counterparts (issue #78). Groups without an alias pass through untouched.
|
|
76
|
+
*/
|
|
77
|
+
function applyAlias(spec, alias) {
|
|
78
|
+
return {
|
|
79
|
+
spacing: remapKeys(spec.spacing, alias.spacing),
|
|
80
|
+
radius: remapKeys(spec.radius, alias.radius),
|
|
81
|
+
colors: remapKeys(spec.colors, alias.colors),
|
|
82
|
+
typography: remapKeys(spec.typography, alias.typography),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
31
85
|
/**
|
|
32
86
|
* Compare candidate tokens against the reference spec. Findings are emitted in
|
|
33
87
|
* a stable order — spacing, radius, colours, typography — so the verdict is
|
|
34
88
|
* reproducible. A reference token absent from the candidate is a `missing`
|
|
35
89
|
* finding; tokens the candidate adds beyond the spec are ignored.
|
|
90
|
+
*
|
|
91
|
+
* When a {@link TokenAliasMap} is supplied, the design-named spec is first
|
|
92
|
+
* canonicalised to code names so differing vocabularies still match.
|
|
36
93
|
*/
|
|
37
|
-
export function diffTokens(
|
|
94
|
+
export function diffTokens(specInput, candidate, config, alias) {
|
|
38
95
|
const findings = [];
|
|
39
|
-
if (!
|
|
96
|
+
if (!specInput)
|
|
40
97
|
return findings;
|
|
98
|
+
const spec = alias ? applyAlias(specInput, alias) : specInput;
|
|
41
99
|
for (const [name, want] of Object.entries(spec.spacing ?? {})) {
|
|
42
|
-
|
|
43
|
-
numericFinding("spacing", name, want, got, config.spacingTolerance, findings);
|
|
100
|
+
numericFinding("spacing", name, want, candidate.spacing, config.spacingTolerance, findings);
|
|
44
101
|
}
|
|
45
102
|
for (const [name, want] of Object.entries(spec.radius ?? {})) {
|
|
46
|
-
|
|
47
|
-
numericFinding("radius", name, want, got, config.radiusTolerance, findings);
|
|
103
|
+
numericFinding("radius", name, want, candidate.radius, config.radiusTolerance, findings);
|
|
48
104
|
}
|
|
49
105
|
for (const [name, want] of Object.entries(spec.colors ?? {})) {
|
|
50
|
-
|
|
106
|
+
// Match a spec colour against the candidate in three tiers, most precise
|
|
107
|
+
// first. (1) Exact name — the explicit alias map has already canonicalised
|
|
108
|
+
// design names to code names (issue #78). (2) Material colour role — a
|
|
109
|
+
// reference token *named in design-system vocabulary* (`color/on-surface`)
|
|
110
|
+
// is recognised as the role it denotes (`onSurface`) and matched against the
|
|
111
|
+
// candidate's resolved role (compose-ai-tools#1897, issue #87); a low-
|
|
112
|
+
// confidence name match, so a mismatch is flagged `via: "role-heuristic"`.
|
|
113
|
+
// (3) Value match under the same generic role key (`fg`/`bg`) for an
|
|
114
|
+
// unresolved theme (issue #74).
|
|
115
|
+
const role = materialColorRole(name);
|
|
116
|
+
const byRole = role !== undefined ? candidate.colors?.[role] : undefined;
|
|
117
|
+
const got = candidate.colors?.[name] ?? byRole ?? roleMatch(name, want, candidate.colors);
|
|
51
118
|
if (got === undefined) {
|
|
52
119
|
findings.push(missing("colors", name, want));
|
|
53
120
|
}
|
|
54
|
-
else if (got
|
|
121
|
+
else if (!colorsEqual(got, want)) {
|
|
122
|
+
const viaRole = candidate.colors?.[name] === undefined && byRole === got;
|
|
55
123
|
findings.push({
|
|
56
124
|
kind: "token",
|
|
57
125
|
severity: "warn",
|
|
58
126
|
message: `colors.${name}: ${got} vs spec ${want}`,
|
|
59
|
-
detail: {
|
|
127
|
+
detail: {
|
|
128
|
+
token: `colors.${name}`,
|
|
129
|
+
expected: want,
|
|
130
|
+
actual: got,
|
|
131
|
+
...(viaRole ? { role, via: "role-heuristic" } : {}),
|
|
132
|
+
},
|
|
60
133
|
});
|
|
61
134
|
}
|
|
62
135
|
}
|
|
63
136
|
for (const [name, want] of Object.entries(spec.typography ?? {})) {
|
|
64
|
-
|
|
137
|
+
// Exact name first, then the Material type-scale role a design-vocabulary
|
|
138
|
+
// name denotes (`type/body/large` → `bodyLarge`) — the typography analogue
|
|
139
|
+
// of the colour role heuristic (issue #87).
|
|
140
|
+
const role = materialTypeRole(name);
|
|
141
|
+
const got = candidate.typography?.[name] ??
|
|
142
|
+
(role !== undefined ? candidate.typography?.[role] : undefined);
|
|
65
143
|
if (got === undefined) {
|
|
66
144
|
findings.push(missing("typography", name, JSON.stringify(want)));
|
|
67
145
|
}
|
|
@@ -76,7 +154,13 @@ export function diffTokens(spec, candidate, config) {
|
|
|
76
154
|
}
|
|
77
155
|
return findings;
|
|
78
156
|
}
|
|
79
|
-
function numericFinding(group, name, want,
|
|
157
|
+
function numericFinding(group, name, want, candidate, tolerance, findings) {
|
|
158
|
+
// Prefer an exact name match; otherwise fall back to a value match. The
|
|
159
|
+
// candidate carries resolved spacing/radius values under generic keys, not the
|
|
160
|
+
// reference's token names (compose-ai-tools#1897), so a spec token is satisfied
|
|
161
|
+
// by any candidate value within tolerance before it's reported missing — the
|
|
162
|
+
// numeric analogue of the colour role-match (issue #74).
|
|
163
|
+
const got = candidate?.[name] ?? numericValueMatch(want, tolerance, candidate);
|
|
80
164
|
if (got === undefined) {
|
|
81
165
|
findings.push(missing(group, name, String(want)));
|
|
82
166
|
return;
|
|
@@ -91,6 +175,63 @@ function numericFinding(group, name, want, got, tolerance, findings) {
|
|
|
91
175
|
});
|
|
92
176
|
}
|
|
93
177
|
}
|
|
178
|
+
/** The candidate value closest to `want` within `tolerance`, or `undefined`. */
|
|
179
|
+
function numericValueMatch(want, tolerance, candidate) {
|
|
180
|
+
if (!candidate)
|
|
181
|
+
return undefined;
|
|
182
|
+
let best;
|
|
183
|
+
let bestDelta = Infinity;
|
|
184
|
+
for (const value of Object.values(candidate)) {
|
|
185
|
+
const delta = Math.abs(value - want);
|
|
186
|
+
if (delta <= tolerance && delta < bestDelta) {
|
|
187
|
+
best = value;
|
|
188
|
+
bestDelta = delta;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return best;
|
|
192
|
+
}
|
|
193
|
+
/** A token name carries a foreground (text/icon) colour: `onPrimary`, `fg`. */
|
|
194
|
+
function isForegroundToken(name) {
|
|
195
|
+
return name === "fg" || /^on[A-Z]/.test(name);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Find a candidate colour matching `want` under the same role as the spec
|
|
199
|
+
* token `name`. The candidate's per-node colours collapse onto generic role
|
|
200
|
+
* keys (`fg`/`bg`) when its theme can't name them, so a foreground spec token
|
|
201
|
+
* is satisfied by any foreground candidate value of the same colour (and a
|
|
202
|
+
* background token likewise). Returns the matching value, or `undefined`.
|
|
203
|
+
*/
|
|
204
|
+
function roleMatch(name, want, candidate) {
|
|
205
|
+
if (!candidate)
|
|
206
|
+
return undefined;
|
|
207
|
+
const wantForeground = isForegroundToken(name);
|
|
208
|
+
for (const [key, value] of Object.entries(candidate)) {
|
|
209
|
+
if (isForegroundToken(key) === wantForeground && colorsEqual(value, want)) {
|
|
210
|
+
return value;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
/** Split a hex colour into lowercase `rgb` + `alpha`, or `undefined` if not hex. */
|
|
216
|
+
function parseHexColor(value) {
|
|
217
|
+
const hex = value.startsWith("#") ? value.slice(1) : value;
|
|
218
|
+
// Candidate values are `#RRGGBBAA` (alpha last, from `argbToCssHex`); the
|
|
219
|
+
// reference spec is typically `#RRGGBB`. Treat a 6-digit value as opaque.
|
|
220
|
+
if (/^[0-9a-fA-F]{6}$/.test(hex))
|
|
221
|
+
return { rgb: hex.toLowerCase(), alpha: "ff" };
|
|
222
|
+
if (/^[0-9a-fA-F]{8}$/.test(hex)) {
|
|
223
|
+
return { rgb: hex.slice(0, 6).toLowerCase(), alpha: hex.slice(6, 8).toLowerCase() };
|
|
224
|
+
}
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
/** Compare two colours, treating `#RRGGBB` and full-alpha `#RRGGBBAA` as equal. */
|
|
228
|
+
export function colorsEqual(a, b) {
|
|
229
|
+
const pa = parseHexColor(a);
|
|
230
|
+
const pb = parseHexColor(b);
|
|
231
|
+
if (!pa || !pb)
|
|
232
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
233
|
+
return pa.rgb === pb.rgb && pa.alpha === pb.alpha;
|
|
234
|
+
}
|
|
94
235
|
function missing(group, name, want) {
|
|
95
236
|
return {
|
|
96
237
|
kind: "token",
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design-parity/diff",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Source-agnostic diff engine: consume a (DesignReference, CandidateRender) pair and emit a deterministic Verdict — a11y + i18n first, then token compliance, then visual diff.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"test": "vitest run"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@design-parity/checks": "^0.1.
|
|
21
|
-
"@design-parity/core": "^0.1.
|
|
20
|
+
"@design-parity/checks": "^0.1.4",
|
|
21
|
+
"@design-parity/core": "^0.1.4",
|
|
22
22
|
"pixelmatch": "^7.1.0",
|
|
23
23
|
"pngjs": "^7.0.0"
|
|
24
24
|
},
|