@adobe/design-data-spec 0.0.1 → 0.1.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/conformance/README.md +82 -10
- package/conformance/diff/cross-format/expected.json +27 -0
- package/conformance/diff/cross-format/new/tokens.tokens.json +8 -0
- package/conformance/diff/cross-format/old/tokens.json +7 -0
- package/conformance/diff/deprecated-new-token/expected.json +13 -0
- package/conformance/diff/deprecated-new-token/new/tokens.tokens.json +8 -0
- package/conformance/diff/deprecated-new-token/old/tokens.tokens.json +1 -0
- package/conformance/diff/deprecated-set-level/expected.json +13 -0
- package/conformance/diff/deprecated-set-level/new/tokens.tokens.json +10 -0
- package/conformance/diff/deprecated-set-level/old/tokens.tokens.json +1 -0
- package/conformance/diff/identical-tokens/expected.json +8 -0
- package/conformance/diff/identical-tokens/new/tokens.tokens.json +12 -0
- package/conformance/diff/identical-tokens/old/tokens.tokens.json +12 -0
- package/conformance/diff/matched-gaining-deprecated/expected.json +20 -0
- package/conformance/diff/matched-gaining-deprecated/new/tokens.tokens.json +8 -0
- package/conformance/diff/matched-gaining-deprecated/old/tokens.tokens.json +7 -0
- package/conformance/diff/property-nested-change/expected.json +27 -0
- package/conformance/diff/property-nested-change/new/tokens.tokens.json +10 -0
- package/conformance/diff/property-nested-change/old/tokens.tokens.json +10 -0
- package/conformance/diff/property-value-update/expected.json +21 -0
- package/conformance/diff/property-value-update/new/tokens.tokens.json +7 -0
- package/conformance/diff/property-value-update/old/tokens.tokens.json +7 -0
- package/conformance/diff/rename-by-uuid/expected.json +22 -0
- package/conformance/diff/rename-by-uuid/new/tokens.tokens.json +7 -0
- package/conformance/diff/rename-by-uuid/old/tokens.tokens.json +7 -0
- package/conformance/diff/rename-with-property-changes/expected.json +28 -0
- package/conformance/diff/rename-with-property-changes/new/tokens.tokens.json +7 -0
- package/conformance/diff/rename-with-property-changes/old/tokens.tokens.json +7 -0
- package/conformance/diff/replaced-by-pairing/expected.json +43 -0
- package/conformance/diff/replaced-by-pairing/new/tokens.tokens.json +7 -0
- package/conformance/diff/replaced-by-pairing/old/tokens.tokens.json +10 -0
- package/conformance/diff/reverted-token/expected.json +13 -0
- package/conformance/diff/reverted-token/new/tokens.tokens.json +7 -0
- package/conformance/diff/reverted-token/old/tokens.tokens.json +8 -0
- package/conformance/diff/simple-add-delete/expected.json +18 -0
- package/conformance/diff/simple-add-delete/new/tokens.tokens.json +7 -0
- package/conformance/diff/simple-add-delete/old/tokens.tokens.json +7 -0
- package/conformance/diff/uuid-backfill/expected.json +20 -0
- package/conformance/diff/uuid-backfill/new/tokens.tokens.json +7 -0
- package/conformance/diff/uuid-backfill/old/tokens.tokens.json +6 -0
- package/conformance/invalid/SPEC-008/dimension.json +5 -0
- package/conformance/invalid/SPEC-008/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-008/tokens.tokens.json +15 -0
- package/conformance/invalid/SPEC-010/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-010/tokens.tokens.json +9 -0
- package/conformance/invalid/SPEC-011/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-011/tokens.tokens.json +22 -0
- package/conformance/invalid/SPEC-012/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-012/tokens.tokens.json +13 -0
- package/conformance/invalid/SPEC-013/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-013/tokens.tokens.json +8 -0
- package/conformance/query/and-conditions/expected.json +1 -0
- package/conformance/query/and-conditions/input/tokens.tokens.json +17 -0
- package/conformance/query/and-conditions/query.txt +1 -0
- package/conformance/query/and-or-precedence/expected.json +1 -0
- package/conformance/query/and-or-precedence/input/tokens.tokens.json +22 -0
- package/conformance/query/and-or-precedence/query.txt +1 -0
- package/conformance/query/empty-matches-all/expected.json +1 -0
- package/conformance/query/empty-matches-all/input/tokens.tokens.json +17 -0
- package/conformance/query/empty-matches-all/query.txt +1 -0
- package/conformance/query/negation/expected.json +1 -0
- package/conformance/query/negation/input/tokens.tokens.json +17 -0
- package/conformance/query/negation/query.txt +1 -0
- package/conformance/query/no-matches/expected.json +1 -0
- package/conformance/query/no-matches/input/tokens.tokens.json +7 -0
- package/conformance/query/no-matches/query.txt +1 -0
- package/conformance/query/or-conditions/expected.json +1 -0
- package/conformance/query/or-conditions/input/tokens.tokens.json +17 -0
- package/conformance/query/or-conditions/query.txt +1 -0
- package/conformance/query/schema-key/expected.json +1 -0
- package/conformance/query/schema-key/input/tokens.tokens.json +14 -0
- package/conformance/query/schema-key/query.txt +1 -0
- package/conformance/query/single-field/expected.json +1 -0
- package/conformance/query/single-field/input/tokens.tokens.json +17 -0
- package/conformance/query/single-field/query.txt +1 -0
- package/conformance/query/wildcard-prefix/expected.json +1 -0
- package/conformance/query/wildcard-prefix/input/tokens.tokens.json +17 -0
- package/conformance/query/wildcard-prefix/query.txt +1 -0
- package/conformance/query/wildcard-suffix/expected.json +1 -0
- package/conformance/query/wildcard-suffix/input/tokens.tokens.json +17 -0
- package/conformance/query/wildcard-suffix/query.txt +1 -0
- package/conformance/resolution/alias-resolved-after-cascade/dimensions/color-scheme.json +5 -0
- package/conformance/resolution/alias-resolved-after-cascade/expected.json +5 -0
- package/conformance/resolution/alias-resolved-after-cascade/input/tokens.tokens.json +12 -0
- package/conformance/resolution/alias-resolved-after-cascade/query.json +4 -0
- package/conformance/resolution/base-fallback/dimensions/color-scheme.json +5 -0
- package/conformance/resolution/base-fallback/expected.json +5 -0
- package/conformance/resolution/base-fallback/input/tokens.tokens.json +7 -0
- package/conformance/resolution/base-fallback/query.json +4 -0
- package/conformance/resolution/specificity-wins/dimensions/color-scheme.json +5 -0
- package/conformance/resolution/specificity-wins/expected.json +5 -0
- package/conformance/resolution/specificity-wins/input/tokens.tokens.json +12 -0
- package/conformance/resolution/specificity-wins/query.json +4 -0
- package/fields/anatomy.json +15 -0
- package/fields/color-scheme.json +15 -0
- package/fields/component.json +15 -0
- package/fields/contrast.json +15 -0
- package/fields/density.json +15 -0
- package/fields/object.json +15 -0
- package/fields/orientation.json +15 -0
- package/fields/position.json +15 -0
- package/fields/property.json +15 -0
- package/fields/scale.json +15 -0
- package/fields/shape.json +15 -0
- package/fields/size.json +15 -0
- package/fields/state.json +15 -0
- package/fields/structure.json +15 -0
- package/fields/substructure.json +15 -0
- package/fields/variant.json +15 -0
- package/package.json +3 -1
- package/rules/rules.yaml +56 -2
- package/schemas/cascade-file.schema.json +10 -0
- package/schemas/field.schema.json +85 -0
- package/schemas/manifest.schema.json +55 -1
- package/schemas/token.schema.json +89 -18
- package/spec/cascade.md +18 -2
- package/spec/diff.md +97 -0
- package/spec/dimensions.md +15 -6
- package/spec/evolution.md +98 -0
- package/spec/index.md +11 -8
- package/spec/manifest.md +15 -0
- package/spec/query.md +135 -0
- package/spec/taxonomy.md +173 -0
- package/spec/token-format.md +114 -19
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
3
|
+
"specVersion": "1.0.0-draft",
|
|
4
|
+
"name": "scale",
|
|
5
|
+
"description": "Platform density scale dimension (e.g. desktop, mobile). Drives cascade resolution.",
|
|
6
|
+
"kind": "dimension",
|
|
7
|
+
"registry": null,
|
|
8
|
+
"validation": "strict",
|
|
9
|
+
"serialization": {
|
|
10
|
+
"position": 14
|
|
11
|
+
},
|
|
12
|
+
"scope": null,
|
|
13
|
+
"required": false,
|
|
14
|
+
"valueType": "string"
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
3
|
+
"specVersion": "1.0.0-draft",
|
|
4
|
+
"name": "shape",
|
|
5
|
+
"description": "Overall component shape qualifier (e.g. uniform, rounded).",
|
|
6
|
+
"kind": "semantic",
|
|
7
|
+
"registry": "packages/design-system-registry/registry/shapes.json",
|
|
8
|
+
"validation": "advisory",
|
|
9
|
+
"serialization": {
|
|
10
|
+
"position": 11
|
|
11
|
+
},
|
|
12
|
+
"scope": null,
|
|
13
|
+
"required": false,
|
|
14
|
+
"valueType": "string"
|
|
15
|
+
}
|
package/fields/size.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
3
|
+
"specVersion": "1.0.0-draft",
|
|
4
|
+
"name": "size",
|
|
5
|
+
"description": "Relative t-shirt sizing of a component or token (e.g. small, medium, large, extra-large). Distinct from dimension scale.",
|
|
6
|
+
"kind": "semantic",
|
|
7
|
+
"registry": "packages/design-system-registry/registry/sizes.json",
|
|
8
|
+
"validation": "advisory",
|
|
9
|
+
"serialization": {
|
|
10
|
+
"position": 9
|
|
11
|
+
},
|
|
12
|
+
"scope": null,
|
|
13
|
+
"required": false,
|
|
14
|
+
"valueType": "string"
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
3
|
+
"specVersion": "1.0.0-draft",
|
|
4
|
+
"name": "state",
|
|
5
|
+
"description": "Interactive or semantic state (e.g. hover, focus, disabled, selected). Compound states use hyphenation (e.g. selected-hover).",
|
|
6
|
+
"kind": "semantic",
|
|
7
|
+
"registry": "packages/design-system-registry/registry/states.json",
|
|
8
|
+
"validation": "advisory",
|
|
9
|
+
"serialization": {
|
|
10
|
+
"position": 12
|
|
11
|
+
},
|
|
12
|
+
"scope": null,
|
|
13
|
+
"required": false,
|
|
14
|
+
"valueType": "string"
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
3
|
+
"specVersion": "1.0.0-draft",
|
|
4
|
+
"name": "structure",
|
|
5
|
+
"description": "Reusable visual pattern that occurs across many components (e.g. drop-shadow, overlay). Distinct from component.",
|
|
6
|
+
"kind": "semantic",
|
|
7
|
+
"registry": "packages/design-system-registry/registry/structures.json",
|
|
8
|
+
"validation": "advisory",
|
|
9
|
+
"serialization": {
|
|
10
|
+
"position": 2
|
|
11
|
+
},
|
|
12
|
+
"scope": null,
|
|
13
|
+
"required": false,
|
|
14
|
+
"valueType": "string"
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
3
|
+
"specVersion": "1.0.0-draft",
|
|
4
|
+
"name": "substructure",
|
|
5
|
+
"description": "Child element within a parent structure (e.g. item within list-item, cell within table).",
|
|
6
|
+
"kind": "semantic",
|
|
7
|
+
"registry": "packages/design-system-registry/registry/substructures.json",
|
|
8
|
+
"validation": "advisory",
|
|
9
|
+
"serialization": {
|
|
10
|
+
"position": 3
|
|
11
|
+
},
|
|
12
|
+
"scope": null,
|
|
13
|
+
"required": false,
|
|
14
|
+
"valueType": "string"
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
3
|
+
"specVersion": "1.0.0-draft",
|
|
4
|
+
"name": "variant",
|
|
5
|
+
"description": "Primary color or semantic variant (e.g. accent, negative, informative, neutral). Not for visual style treatment — see style field for that.",
|
|
6
|
+
"kind": "semantic",
|
|
7
|
+
"registry": "packages/design-system-registry/registry/variants.json",
|
|
8
|
+
"validation": "advisory",
|
|
9
|
+
"serialization": {
|
|
10
|
+
"position": 0
|
|
11
|
+
},
|
|
12
|
+
"scope": null,
|
|
13
|
+
"required": false,
|
|
14
|
+
"valueType": "string"
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/design-data-spec",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Design Data Specification — prose, JSON Schemas, rule catalog, and conformance fixtures for Spectrum design data",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"./package.json": "./package.json",
|
|
24
24
|
"./schemas/token.schema.json": "./schemas/token.schema.json",
|
|
25
25
|
"./schemas/dimension.schema.json": "./schemas/dimension.schema.json",
|
|
26
|
+
"./schemas/field.schema.json": "./schemas/field.schema.json",
|
|
26
27
|
"./schemas/manifest.schema.json": "./schemas/manifest.schema.json",
|
|
27
28
|
"./schemas/value-types/color.schema.json": "./schemas/value-types/color.schema.json",
|
|
28
29
|
"./rules/rules.yaml": "./rules/rules.yaml"
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"files": [
|
|
31
32
|
"spec",
|
|
32
33
|
"schemas",
|
|
34
|
+
"fields",
|
|
33
35
|
"rules",
|
|
34
36
|
"conformance",
|
|
35
37
|
"README.md"
|
package/rules/rules.yaml
CHANGED
|
@@ -51,8 +51,8 @@ rules:
|
|
|
51
51
|
name: specificity-correctness
|
|
52
52
|
severity: warning
|
|
53
53
|
category: type-safety
|
|
54
|
-
assert: When two tokens from the same layer match a context, the
|
|
55
|
-
message: "Ambiguous cascade resolution (specificity tie) for context {context}"
|
|
54
|
+
assert: When two tokens from the same layer match a context with equal specificity, the tie MUST be broken by document order (earlier in file wins; lexicographically earlier file path wins across files). Ties MUST be reported as warnings.
|
|
55
|
+
message: "Ambiguous cascade resolution (specificity tie) between {token_a} and {token_b} for context {context}; resolved by document order"
|
|
56
56
|
spec_ref: spec/cascade.md#semantic-specificity
|
|
57
57
|
introduced_in: "1.0.0-draft"
|
|
58
58
|
|
|
@@ -64,3 +64,57 @@ rules:
|
|
|
64
64
|
message: "Token '{token}' does not roundtrip through name-object generation rules"
|
|
65
65
|
spec_ref: spec/token-format.md#name-object
|
|
66
66
|
introduced_in: "1.0.0-draft"
|
|
67
|
+
|
|
68
|
+
- id: SPEC-008
|
|
69
|
+
name: cascade-completeness
|
|
70
|
+
severity: warning
|
|
71
|
+
category: completeness
|
|
72
|
+
assert: For every cascade token that has a non-default mode variant, a base/default variant (name object with no dimension fields for that dimension, or explicitly the default mode value) MUST also exist in the dataset. Ensures all consumers can resolve without a fallback gap.
|
|
73
|
+
message: "Token property '{property}' has mode variant '{mode}' but no base/default variant"
|
|
74
|
+
spec_ref: spec/cascade.md#coverage
|
|
75
|
+
introduced_in: "1.0.0-draft"
|
|
76
|
+
|
|
77
|
+
- id: SPEC-009
|
|
78
|
+
name: name-field-enum-sync
|
|
79
|
+
severity: warning
|
|
80
|
+
category: naming-consistency
|
|
81
|
+
assert: Recognized name object fields (component, state, variant, etc.) SHOULD use values drawn from the corresponding design-system-registry enums when those enums are available.
|
|
82
|
+
message: "Token name field '{field}' value '{value}' is not in the design-system-registry enum for '{field}'"
|
|
83
|
+
spec_ref: spec/token-format.md#name-object
|
|
84
|
+
introduced_in: "1.0.0-draft"
|
|
85
|
+
|
|
86
|
+
- id: SPEC-010
|
|
87
|
+
name: replaced-by-target-exists
|
|
88
|
+
severity: error
|
|
89
|
+
category: reference-integrity
|
|
90
|
+
assert: Every UUID in replaced_by MUST resolve to an existing token in the dataset.
|
|
91
|
+
message: "replaced_by target UUID not found: {uuid}"
|
|
92
|
+
spec_ref: spec/token-format.md#lifecycle-and-metadata
|
|
93
|
+
introduced_in: "1.0.0-draft"
|
|
94
|
+
|
|
95
|
+
- id: SPEC-011
|
|
96
|
+
name: replaced-by-array-requires-comment
|
|
97
|
+
severity: error
|
|
98
|
+
category: completeness
|
|
99
|
+
assert: When replaced_by is an array, deprecated_comment MUST be present to explain which replacement applies in which context.
|
|
100
|
+
message: "replaced_by is an array but deprecated_comment is missing on token {token}"
|
|
101
|
+
spec_ref: spec/token-format.md#lifecycle-and-metadata
|
|
102
|
+
introduced_in: "1.0.0-draft"
|
|
103
|
+
|
|
104
|
+
- id: SPEC-012
|
|
105
|
+
name: replaced-by-requires-deprecated
|
|
106
|
+
severity: error
|
|
107
|
+
category: completeness
|
|
108
|
+
assert: If replaced_by is present, deprecated MUST also be present.
|
|
109
|
+
message: "Token {token} has replaced_by but is not marked deprecated"
|
|
110
|
+
spec_ref: spec/token-format.md#lifecycle-and-metadata
|
|
111
|
+
introduced_in: "1.0.0-draft"
|
|
112
|
+
|
|
113
|
+
- id: SPEC-013
|
|
114
|
+
name: planned-removal-requires-deprecated
|
|
115
|
+
severity: error
|
|
116
|
+
category: completeness
|
|
117
|
+
assert: If plannedRemoval is present, deprecated MUST also be present.
|
|
118
|
+
message: "Token {token} has plannedRemoval but is not marked deprecated"
|
|
119
|
+
spec_ref: spec/token-format.md#lifecycle-and-metadata
|
|
120
|
+
introduced_in: "1.0.0-draft"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/cascade-file.schema.json",
|
|
4
|
+
"title": "Cascade token file",
|
|
5
|
+
"description": "Layer 1 — document envelope for cascade-format tokens. A cascade file is an ordered array of token objects; document order determines tie-breaking during cascade resolution.",
|
|
6
|
+
"type": "array",
|
|
7
|
+
"items": {
|
|
8
|
+
"$ref": "token.schema.json"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/field.schema.json",
|
|
4
|
+
"title": "Name-object field declaration",
|
|
5
|
+
"description": "Declares a single field on the token name object — its kind, vocabulary source, validation severity, and serialization position. Design systems provide a catalog of these declarations to make the name object schema configurable rather than hardcoded.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["name", "kind", "validation", "serialization"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"specVersion": {
|
|
13
|
+
"const": "1.0.0-draft"
|
|
14
|
+
},
|
|
15
|
+
"name": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"description": "Field key on the name object (e.g. 'property', 'component', 'scaleIndex')."
|
|
19
|
+
},
|
|
20
|
+
"description": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "Human-readable description of the field's purpose."
|
|
23
|
+
},
|
|
24
|
+
"kind": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"enum": ["semantic", "dimension"],
|
|
27
|
+
"description": "Whether this field participates in cascade resolution. 'dimension' fields drive cascade specificity; 'semantic' fields describe identity only."
|
|
28
|
+
},
|
|
29
|
+
"registry": {
|
|
30
|
+
"oneOf": [
|
|
31
|
+
{
|
|
32
|
+
"type": "string",
|
|
33
|
+
"minLength": 1,
|
|
34
|
+
"description": "Path to the registry file containing valid values for this field (relative to the design system root)."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "null",
|
|
38
|
+
"description": "No registry — field accepts free-form values."
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"validation": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"enum": ["strict", "advisory", "none"],
|
|
45
|
+
"description": "Validation severity when a value is not found in the registry. 'strict' = error, 'advisory' = warning, 'none' = no check."
|
|
46
|
+
},
|
|
47
|
+
"serialization": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"required": ["position"],
|
|
50
|
+
"properties": {
|
|
51
|
+
"position": {
|
|
52
|
+
"type": "integer",
|
|
53
|
+
"minimum": 0,
|
|
54
|
+
"description": "Default position in the serialized name string (0-based). Used when the platform manifest does not specify a custom conceptOrder."
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"additionalProperties": false
|
|
58
|
+
},
|
|
59
|
+
"scope": {
|
|
60
|
+
"oneOf": [
|
|
61
|
+
{
|
|
62
|
+
"type": "string",
|
|
63
|
+
"minLength": 1,
|
|
64
|
+
"description": "Restrict this field to a specific token type scope (e.g. 'typography', 'color'). Null = universal."
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "null",
|
|
68
|
+
"description": "Field applies to all token types."
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"required": {
|
|
73
|
+
"type": "boolean",
|
|
74
|
+
"description": "Whether this field must be present on every name object. Default: false.",
|
|
75
|
+
"default": false
|
|
76
|
+
},
|
|
77
|
+
"valueType": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"enum": ["string", "integer"],
|
|
80
|
+
"description": "Type of the field value. Default: 'string'.",
|
|
81
|
+
"default": "string"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"additionalProperties": false
|
|
85
|
+
}
|
|
@@ -64,7 +64,61 @@
|
|
|
64
64
|
},
|
|
65
65
|
"extensions": {
|
|
66
66
|
"type": "object",
|
|
67
|
-
"description": "Platform-local tokens
|
|
67
|
+
"description": "Platform-local tokens, dimensions, and formatting rules.",
|
|
68
|
+
"properties": {
|
|
69
|
+
"formatting": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"description": "Rules for serializing structured name objects into platform-specific token name strings.",
|
|
72
|
+
"properties": {
|
|
73
|
+
"conceptOrder": {
|
|
74
|
+
"type": "array",
|
|
75
|
+
"items": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"enum": [
|
|
78
|
+
"variant",
|
|
79
|
+
"component",
|
|
80
|
+
"structure",
|
|
81
|
+
"substructure",
|
|
82
|
+
"anatomy",
|
|
83
|
+
"object",
|
|
84
|
+
"property",
|
|
85
|
+
"orientation",
|
|
86
|
+
"position",
|
|
87
|
+
"size",
|
|
88
|
+
"density",
|
|
89
|
+
"shape",
|
|
90
|
+
"state"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"uniqueItems": true,
|
|
94
|
+
"description": "Ordered list of field names for serialization. Values must match declared field names from the design system's field catalog (field.schema.json declarations). Replaces the default serialization.position order from each field declaration."
|
|
95
|
+
},
|
|
96
|
+
"casing": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"enum": [
|
|
99
|
+
"kebab-case",
|
|
100
|
+
"camelCase",
|
|
101
|
+
"PascalCase",
|
|
102
|
+
"SCREAMING_SNAKE_CASE"
|
|
103
|
+
],
|
|
104
|
+
"description": "Casing style for serialized token names. Default: kebab-case."
|
|
105
|
+
},
|
|
106
|
+
"delimiter": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"minLength": 1,
|
|
109
|
+
"description": "Character(s) separating concepts in the serialized string. Default: -."
|
|
110
|
+
},
|
|
111
|
+
"abbreviations": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"additionalProperties": {
|
|
114
|
+
"type": "string"
|
|
115
|
+
},
|
|
116
|
+
"description": "Map of full term to abbreviated form, applied after ordering and before casing."
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"additionalProperties": false
|
|
120
|
+
}
|
|
121
|
+
},
|
|
68
122
|
"additionalProperties": true
|
|
69
123
|
}
|
|
70
124
|
},
|
|
@@ -15,30 +15,73 @@
|
|
|
15
15
|
"$defs": {
|
|
16
16
|
"nameObject": {
|
|
17
17
|
"type": "object",
|
|
18
|
-
"description": "Structured token identity;
|
|
18
|
+
"description": "Structured token identity. Semantic fields describe identity and structure; dimension fields drive cascade resolution. See spec/taxonomy.md and spec/token-format.md. Additional dimension keys MUST be strings.",
|
|
19
19
|
"required": ["property"],
|
|
20
20
|
"properties": {
|
|
21
21
|
"property": {
|
|
22
22
|
"type": "string",
|
|
23
|
-
"minLength": 1
|
|
23
|
+
"minLength": 1,
|
|
24
|
+
"description": "Semantic: the stylistic attribute being defined (e.g. color, width, padding, gap)."
|
|
24
25
|
},
|
|
25
26
|
"component": {
|
|
26
|
-
"type": "string"
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "Semantic: component scope (e.g. button, checkbox)."
|
|
29
|
+
},
|
|
30
|
+
"structure": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"description": "Semantic: reusable visual pattern (e.g. base, container, list). Distinct from component."
|
|
33
|
+
},
|
|
34
|
+
"substructure": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "Semantic: child within a parent structure (e.g. item in list-item)."
|
|
37
|
+
},
|
|
38
|
+
"anatomy": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"description": "Semantic: visible named part of a component (e.g. handle, icon, label)."
|
|
41
|
+
},
|
|
42
|
+
"object": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "Semantic: styling surface (e.g. background, border, edge, visual)."
|
|
27
45
|
},
|
|
28
46
|
"variant": {
|
|
29
|
-
"type": "string"
|
|
47
|
+
"type": "string",
|
|
48
|
+
"description": "Semantic: variant within a component (e.g. accent, negative, primary)."
|
|
30
49
|
},
|
|
31
50
|
"state": {
|
|
32
|
-
"type": "string"
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Semantic: interactive or semantic state (e.g. hover, focus, disabled)."
|
|
53
|
+
},
|
|
54
|
+
"orientation": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "Semantic: direction or order (e.g. vertical, horizontal)."
|
|
57
|
+
},
|
|
58
|
+
"position": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"description": "Semantic: location relative to another object (e.g. affixed, top, bottom)."
|
|
61
|
+
},
|
|
62
|
+
"size": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Semantic: relative t-shirt sizing (e.g. small, medium, large). Distinct from dimension scale."
|
|
65
|
+
},
|
|
66
|
+
"density": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "Semantic: space within or around component parts (e.g. spacious, compact)."
|
|
69
|
+
},
|
|
70
|
+
"shape": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"description": "Semantic: overall component shape (e.g. uniform)."
|
|
33
73
|
},
|
|
34
74
|
"colorScheme": {
|
|
35
|
-
"type": "string"
|
|
75
|
+
"type": "string",
|
|
76
|
+
"description": "Dimension: color scheme mode (e.g. light, dark, wireframe)."
|
|
36
77
|
},
|
|
37
78
|
"scale": {
|
|
38
|
-
"type": "string"
|
|
79
|
+
"type": "string",
|
|
80
|
+
"description": "Dimension: platform density scale (e.g. desktop, mobile)."
|
|
39
81
|
},
|
|
40
82
|
"contrast": {
|
|
41
|
-
"type": "string"
|
|
83
|
+
"type": "string",
|
|
84
|
+
"description": "Dimension: contrast level (e.g. regular, high)."
|
|
42
85
|
}
|
|
43
86
|
},
|
|
44
87
|
"additionalProperties": {
|
|
@@ -89,19 +132,33 @@
|
|
|
89
132
|
"type": "string"
|
|
90
133
|
},
|
|
91
134
|
"deprecated": {
|
|
92
|
-
"type": "
|
|
135
|
+
"type": "string",
|
|
136
|
+
"description": "Spec version when token was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
|
|
93
137
|
},
|
|
94
138
|
"deprecated_comment": {
|
|
95
139
|
"type": "string"
|
|
96
140
|
},
|
|
97
|
-
"
|
|
98
|
-
"
|
|
141
|
+
"replaced_by": {
|
|
142
|
+
"oneOf": [
|
|
143
|
+
{ "type": "string", "format": "uuid" },
|
|
144
|
+
{
|
|
145
|
+
"type": "array",
|
|
146
|
+
"items": { "type": "string", "format": "uuid" },
|
|
147
|
+
"minItems": 1
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"description": "UUID(s) of the replacement token(s). Array form requires deprecated_comment."
|
|
99
151
|
},
|
|
100
|
-
"
|
|
101
|
-
"type": "string"
|
|
152
|
+
"plannedRemoval": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"description": "Spec version when token will be removed."
|
|
102
155
|
},
|
|
103
156
|
"private": {
|
|
104
157
|
"type": "boolean"
|
|
158
|
+
},
|
|
159
|
+
"description": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"description": "Plain text describing the token's purpose (aligns with DTCG $description)."
|
|
105
162
|
}
|
|
106
163
|
},
|
|
107
164
|
"additionalProperties": false
|
|
@@ -132,19 +189,33 @@
|
|
|
132
189
|
"type": "string"
|
|
133
190
|
},
|
|
134
191
|
"deprecated": {
|
|
135
|
-
"type": "
|
|
192
|
+
"type": "string",
|
|
193
|
+
"description": "Spec version when token was deprecated (e.g. \"3.2.0\"). Truthy = deprecated."
|
|
136
194
|
},
|
|
137
195
|
"deprecated_comment": {
|
|
138
196
|
"type": "string"
|
|
139
197
|
},
|
|
140
|
-
"
|
|
141
|
-
"
|
|
198
|
+
"replaced_by": {
|
|
199
|
+
"oneOf": [
|
|
200
|
+
{ "type": "string", "format": "uuid" },
|
|
201
|
+
{
|
|
202
|
+
"type": "array",
|
|
203
|
+
"items": { "type": "string", "format": "uuid" },
|
|
204
|
+
"minItems": 1
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
"description": "UUID(s) of the replacement token(s). Array form requires deprecated_comment."
|
|
142
208
|
},
|
|
143
|
-
"
|
|
144
|
-
"type": "string"
|
|
209
|
+
"plannedRemoval": {
|
|
210
|
+
"type": "string",
|
|
211
|
+
"description": "Spec version when token will be removed."
|
|
145
212
|
},
|
|
146
213
|
"private": {
|
|
147
214
|
"type": "boolean"
|
|
215
|
+
},
|
|
216
|
+
"description": {
|
|
217
|
+
"type": "string",
|
|
218
|
+
"description": "Plain text describing the token's purpose (aligns with DTCG $description)."
|
|
148
219
|
}
|
|
149
220
|
},
|
|
150
221
|
"additionalProperties": false
|
package/spec/cascade.md
CHANGED
|
@@ -26,7 +26,12 @@ Design data is organized in three layers, ordered from lowest to highest precede
|
|
|
26
26
|
|
|
27
27
|
**NORMATIVE:** When two candidates from the **same layer** match the context, the candidate with **higher** specificity **MUST** win.
|
|
28
28
|
|
|
29
|
-
**NORMATIVE:** Ties on layer and specificity **MUST** be broken by
|
|
29
|
+
**NORMATIVE:** Ties on layer and specificity **MUST** be broken by **document order**:
|
|
30
|
+
|
|
31
|
+
1. Within a single source file, the token that appears **earlier** in the array **MUST** win.
|
|
32
|
+
2. Across multiple files, the file with the **lexicographically earlier path** within the dataset **MUST** win.
|
|
33
|
+
|
|
34
|
+
**NORMATIVE:** Validators **MUST** emit a SPEC-006 warning when a tie is detected, as ties indicate potential authoring mistakes.
|
|
30
35
|
|
|
31
36
|
## Context
|
|
32
37
|
|
|
@@ -40,10 +45,19 @@ The following outline is **RECOMMENDED** for conforming resolvers:
|
|
|
40
45
|
2. Filter to candidates at or below the requested layer.
|
|
41
46
|
3. Select the maximum **layer** precedence.
|
|
42
47
|
4. Within that layer, select the maximum **specificity**.
|
|
43
|
-
5. Break remaining ties by
|
|
48
|
+
5. Break remaining ties by document order (earlier in file wins; lexicographically earlier file path wins across files). Emit SPEC-006 warning.
|
|
49
|
+
6. If the winning candidate is an alias (`$ref`), **resolve the alias chain** to a literal value (see [Alias resolution](#alias-resolution)).
|
|
44
50
|
|
|
45
51
|
Exact matching rules for omitted dimensions are defined alongside dimension declarations in [Dimensions](dimensions.md).
|
|
46
52
|
|
|
53
|
+
## Alias resolution
|
|
54
|
+
|
|
55
|
+
**NORMATIVE:** Alias (`$ref`) resolution **MUST** occur **after** cascade selection. The resolution algorithm selects the winning candidate using layer, specificity, and tie-breaking rules before any alias chain is followed.
|
|
56
|
+
|
|
57
|
+
**NORMATIVE:** If the winning candidate is an alias, its `$ref` chain **MUST** be resolved to a literal value using the standard alias-resolution rules (SPEC-001 through SPEC-003 in `rules/rules.yaml`). The alias target is resolved within the same dataset (i.e. the same merged layer stack), not relative to any single layer.
|
|
58
|
+
|
|
59
|
+
**RATIONALE:** Aliases participate in cascade as opaque references — their target values are not examined during specificity calculation or layer comparison. This keeps resolution deterministic and allows aliases to be valid candidates at any specificity level.
|
|
60
|
+
|
|
47
61
|
## Cross-dimensional overrides
|
|
48
62
|
|
|
49
63
|
**NORMATIVE:** Overrides that combine multiple dimensions in a way not expressible by a single name object alone **MUST** use **explicit combination tokens** (tokens whose name object sets multiple non-default dimensions) as defined in the dataset; magic merging of unrelated tokens is **NOT** allowed.
|
|
@@ -52,3 +66,5 @@ Exact matching rules for omitted dimensions are defined alongside dimension decl
|
|
|
52
66
|
|
|
53
67
|
* [#646 — Token Schema Structure and Validation System](https://github.com/adobe/spectrum-design-data/discussions/646)
|
|
54
68
|
* [#714 — Design Data Specification](https://github.com/adobe/spectrum-design-data/discussions/714)
|
|
69
|
+
* [#757 — Phase 2: Cascade tie-breaking rule](https://github.com/adobe/spectrum-design-data/issues/757)
|
|
70
|
+
* [#758 — Phase 2: Alias resolution ordering in cascade context](https://github.com/adobe/spectrum-design-data/issues/758)
|