@adobe/design-data-spec 1.0.0 → 1.2.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/invalid/SPEC-039-syntax-error/dataset.json +4 -0
- package/conformance/invalid/SPEC-039-syntax-error/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-039-syntax-error/manifest.json +5 -0
- package/conformance/invalid/SPEC-039-unknown-key/dataset.json +4 -0
- package/conformance/invalid/SPEC-039-unknown-key/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-039-unknown-key/manifest.json +5 -0
- package/conformance/invalid/SPEC-040/dataset.json +29 -0
- package/conformance/invalid/SPEC-040/expected-errors.json +10 -0
- package/conformance/valid/SPEC-039/dataset.json +4 -0
- package/conformance/valid/SPEC-039/expected-errors.json +4 -0
- package/conformance/valid/SPEC-039/manifest.json +10 -0
- package/conformance/valid/SPEC-040/dataset.json +37 -0
- package/conformance/valid/SPEC-040/expected-errors.json +4 -0
- package/fields/property.json +1 -1
- package/package.json +1 -1
- package/rules/rules.yaml +32 -0
- package/spec/component-format.md +13 -12
- package/spec/manifest.md +4 -2
- package/spec/taxonomy.md +15 -15
- package/spec/token-format.md +37 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tokens": [
|
|
3
|
+
{
|
|
4
|
+
"name": {
|
|
5
|
+
"component": "widget",
|
|
6
|
+
"style": "ghost",
|
|
7
|
+
"property": "background-color"
|
|
8
|
+
},
|
|
9
|
+
"value": "#0265dc"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"components": [
|
|
13
|
+
{
|
|
14
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/widget.json",
|
|
15
|
+
"name": "widget",
|
|
16
|
+
"displayName": "Widget",
|
|
17
|
+
"meta": {
|
|
18
|
+
"category": "actions",
|
|
19
|
+
"documentationUrl": "https://spectrum.adobe.com/page/widget/"
|
|
20
|
+
},
|
|
21
|
+
"options": {
|
|
22
|
+
"style": {
|
|
23
|
+
"type": "enum",
|
|
24
|
+
"values": [{ "value": "fill" }, { "value": "outline" }]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tokens": [
|
|
3
|
+
{
|
|
4
|
+
"name": {
|
|
5
|
+
"component": "widget",
|
|
6
|
+
"style": "fill",
|
|
7
|
+
"property": "background-color"
|
|
8
|
+
},
|
|
9
|
+
"value": "#0265dc"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": {
|
|
13
|
+
"component": "widget",
|
|
14
|
+
"style": "outline",
|
|
15
|
+
"property": "border-color"
|
|
16
|
+
},
|
|
17
|
+
"value": "#0265dc"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"components": [
|
|
21
|
+
{
|
|
22
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/widget.json",
|
|
23
|
+
"name": "widget",
|
|
24
|
+
"displayName": "Widget",
|
|
25
|
+
"meta": {
|
|
26
|
+
"category": "actions",
|
|
27
|
+
"documentationUrl": "https://spectrum.adobe.com/page/widget/"
|
|
28
|
+
},
|
|
29
|
+
"options": {
|
|
30
|
+
"style": {
|
|
31
|
+
"type": "enum",
|
|
32
|
+
"values": [{ "value": "fill" }, { "value": "outline" }]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
package/fields/property.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "property",
|
|
5
5
|
"description": "The stylistic attribute being defined (e.g. color, width, padding, gap). The only required field on every name object.",
|
|
6
6
|
"kind": "semantic",
|
|
7
|
-
"registry":
|
|
7
|
+
"registry": "packages/design-system-registry/registry/property-terms.json",
|
|
8
8
|
"validation": "advisory",
|
|
9
9
|
"serialization": {
|
|
10
10
|
"position": 6
|
package/package.json
CHANGED
package/rules/rules.yaml
CHANGED
|
@@ -383,3 +383,35 @@ rules:
|
|
|
383
383
|
message: "Component '{component}' option '{option}' uses the obsolete `enum` keyword; replace with a `values` array so per-value lifecycle metadata can be expressed"
|
|
384
384
|
spec_ref: spec/component-format.md#option-descriptor
|
|
385
385
|
introduced_in: "1.0.0-draft"
|
|
386
|
+
|
|
387
|
+
- id: SPEC-039
|
|
388
|
+
name: manifest-query-parseable
|
|
389
|
+
severity: error
|
|
390
|
+
layer: 2
|
|
391
|
+
category: manifest
|
|
392
|
+
rfc: "#715"
|
|
393
|
+
assert: >
|
|
394
|
+
Each entry in 'manifest.include' and 'manifest.exclude' MUST parse as a valid query
|
|
395
|
+
expression per spec/query.md and MUST use only the supported query keys.
|
|
396
|
+
Entries that fail to parse, or that reference unsupported keys, are Layer 2 errors.
|
|
397
|
+
This rule lifts the deferred 'treat as opaque' clause from earlier 1.0.0-draft revisions.
|
|
398
|
+
message: "Manifest {array}[{idx}] failed to parse as a query: {error}"
|
|
399
|
+
spec_ref: spec/manifest.md#include--exclude
|
|
400
|
+
introduced_in: "1.0.0-draft"
|
|
401
|
+
|
|
402
|
+
- id: SPEC-040
|
|
403
|
+
name: component-option-field-valid
|
|
404
|
+
severity: warning
|
|
405
|
+
layer: 2
|
|
406
|
+
category: component
|
|
407
|
+
rfc: "#806"
|
|
408
|
+
assert: >
|
|
409
|
+
For every token whose name object contains a key that is not a reserved name-object field
|
|
410
|
+
and that matches a declared component.options.<key> with a values[] list, the token's value
|
|
411
|
+
MUST appear in that values[] list. Reserved fields (component, variant, state, anatomy,
|
|
412
|
+
property, colorScheme, scale, contrast, uuid, object, category) are excluded; variant is
|
|
413
|
+
owned by SPEC-019. This rule generalises SPEC-019 to all remaining option-enum fields
|
|
414
|
+
(style, size, staticColor, etc.) at advisory severity.
|
|
415
|
+
message: "Token '{token}' has {field} '{value}' which is not declared on component '{component}'"
|
|
416
|
+
spec_ref: spec/component-format.md#options
|
|
417
|
+
introduced_in: "1.0.0-draft"
|
package/spec/component-format.md
CHANGED
|
@@ -110,7 +110,7 @@ Each entry in `values` is an object:
|
|
|
110
110
|
|
|
111
111
|
**NORMATIVE:** Boolean option names **MUST** begin with `is` or `has` (e.g. `isDisabled`, `hasIcon`).
|
|
112
112
|
|
|
113
|
-
**NORMATIVE:** When `values` is present, token name-object `variant` field values referencing this component **MUST** be drawn from the declared `variant` option `values` list (rule SPEC-019).
|
|
113
|
+
**NORMATIVE:** When `values` is present, token name-object `variant` field values referencing this component **MUST** be drawn from the declared `variant` option `values` list (rule SPEC-019, Error). Token name-object keys matching any other declared option's `values` list **SHOULD** be drawn from that list (rule SPEC-040, Warning). Both rules are silent when no `values` array is declared for the option.
|
|
114
114
|
|
|
115
115
|
**ADVISORY:** When a value in `values` carries a `lifecycle.deprecated` string and a non-deprecated token references that value via its `name` object field, SPEC-037 fires an advisory warning prompting migration or token deprecation.
|
|
116
116
|
|
|
@@ -314,17 +314,18 @@ The `context` field is informative. It is used by `describe_component` (Phase 8
|
|
|
314
314
|
|
|
315
315
|
The following rules are added to the Layer 2 rule catalog (`rules/rules.yaml`) by this chapter. New component cross-reference rules start at SPEC-018 to avoid collision with existing token rules (SPEC-001–SPEC-017).
|
|
316
316
|
|
|
317
|
-
| Rule ID | Name | Severity | Assert
|
|
318
|
-
| -------- | -------------------------------- | -------- |
|
|
319
|
-
| SPEC-018 | `component-name-exists` | error | Token `component` field value **MUST** match the `name` of a declared component in the dataset.
|
|
320
|
-
| SPEC-019 | `component-variant-valid` | error | Token `variant` field value **MUST** match a value in the declared `variant` option `values` list for the referenced component (when that list exists).
|
|
321
|
-
| SPEC-020 | `component-anatomy-valid` | error | Token `anatomy` field value **MUST** match the `name` of a declared anatomy part on the referenced component.
|
|
322
|
-
| SPEC-021 | `component-slot-vocabulary` | warning | Component `slots` entries with a `name` outside the canonical vocabulary **SHOULD** include a `description`. Custom slot names without descriptions are surfaced as warnings.
|
|
323
|
-
| SPEC-022 | `component-state-valid` | error | Token `state` field value **MUST** match the `name` of a declared state on the referenced component (when state declarations are present).
|
|
324
|
-
| SPEC-027 | `token-binding-token-exists` | error | Each `tokenBindings[].token` value **MUST** match the name of a declared token in the dataset (Phase 6.7).
|
|
325
|
-
| SPEC-036 | `component-deprecation-cascade` | warning | A non-deprecated token **SHOULD NOT** reference a deprecated component via `name.component`. Advisory warning prompts updating the component reference or marking the token deprecated.
|
|
326
|
-
| SPEC-037 | `sub-entity-deprecation-cascade` | warning | A non-deprecated token **SHOULD NOT** reference a deprecated anatomy part, state, or option value via `name.*`. Advisory warning prompts migration. Requires `lifecycle` on anatomy/state or `lifecycle` on the matching `values` entry on the option descriptor.
|
|
327
|
-
| SPEC-038 | `option-enum-obsolete` | warning | An option descriptor **SHOULD NOT** use the JSON Schema `enum` keyword. `additionalProperties: true` silently accepts `enum` at Layer 1; SPEC-038 flags it at Layer 2 so authors replace it with the `values` array.
|
|
317
|
+
| Rule ID | Name | Severity | Assert |
|
|
318
|
+
| -------- | -------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
319
|
+
| SPEC-018 | `component-name-exists` | error | Token `component` field value **MUST** match the `name` of a declared component in the dataset. |
|
|
320
|
+
| SPEC-019 | `component-variant-valid` | error | Token `variant` field value **MUST** match a value in the declared `variant` option `values` list for the referenced component (when that list exists). |
|
|
321
|
+
| SPEC-020 | `component-anatomy-valid` | error | Token `anatomy` field value **MUST** match the `name` of a declared anatomy part on the referenced component. |
|
|
322
|
+
| SPEC-021 | `component-slot-vocabulary` | warning | Component `slots` entries with a `name` outside the canonical vocabulary **SHOULD** include a `description`. Custom slot names without descriptions are surfaced as warnings. |
|
|
323
|
+
| SPEC-022 | `component-state-valid` | error | Token `state` field value **MUST** match the `name` of a declared state on the referenced component (when state declarations are present). |
|
|
324
|
+
| SPEC-027 | `token-binding-token-exists` | error | Each `tokenBindings[].token` value **MUST** match the name of a declared token in the dataset (Phase 6.7). |
|
|
325
|
+
| SPEC-036 | `component-deprecation-cascade` | warning | A non-deprecated token **SHOULD NOT** reference a deprecated component via `name.component`. Advisory warning prompts updating the component reference or marking the token deprecated. |
|
|
326
|
+
| SPEC-037 | `sub-entity-deprecation-cascade` | warning | A non-deprecated token **SHOULD NOT** reference a deprecated anatomy part, state, or option value via `name.*`. Advisory warning prompts migration. Requires `lifecycle` on anatomy/state or `lifecycle` on the matching `values` entry on the option descriptor. |
|
|
327
|
+
| SPEC-038 | `option-enum-obsolete` | warning | An option descriptor **SHOULD NOT** use the JSON Schema `enum` keyword. `additionalProperties: true` silently accepts `enum` at Layer 1; SPEC-038 flags it at Layer 2 so authors replace it with the `values` array. |
|
|
328
|
+
| SPEC-040 | `component-option-field-valid` | warning | Token name-object keys that match a declared `options.<key>` with a `values[]` list **SHOULD** use a value drawn from that list. Generalises SPEC-019 to non-`variant` option fields (e.g. `style`, `size`, `staticColor`). Advisory; silent when no `values` declared. |
|
|
328
329
|
|
|
329
330
|
## Full example
|
|
330
331
|
|
package/spec/manifest.md
CHANGED
|
@@ -26,9 +26,11 @@ A manifest **MUST** conform to [`manifest.schema.json`](../schemas/manifest.sche
|
|
|
26
26
|
|
|
27
27
|
### `include` / `exclude`
|
|
28
28
|
|
|
29
|
-
**NORMATIVE:**
|
|
29
|
+
**NORMATIVE:** Each entry **MUST** be a non-empty string that parses as a valid query expression per [Query](query.md). An entry that fails to parse, or that references a key outside the [supported query key list](query.md#supported-keys), is a Layer 2 conformance error (SPEC-039 `manifest-query-parseable`).
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
See [Query — Formal grammar](query.md#formal-grammar) for the EBNF and [Query — Supported keys](query.md#supported-keys) for the normative list of allowed keys.
|
|
32
|
+
|
|
33
|
+
> **Migration note (from earlier `1.0.0-draft` revisions):** Prior revisions instructed implementations to treat manifest query values as opaque identifiers. That clause is lifted as of this revision. Any manifest that uses non-query strings in `include`/`exclude` must be updated to use valid query notation; the SPEC-039 rule reports column-level parse errors to guide migration.
|
|
32
34
|
|
|
33
35
|
### `overrides`
|
|
34
36
|
|
package/spec/taxonomy.md
CHANGED
|
@@ -54,21 +54,21 @@ Concept categories for name-object fields are declared in the design system's **
|
|
|
54
54
|
|
|
55
55
|
The following concept categories are defined in Spectrum's foundation field catalog for semantic and layout tokens, ordered by default serialization position. This ordering is the **default serialization order** for legacy format output; it is not a conformance requirement for stored name objects.
|
|
56
56
|
|
|
57
|
-
**NORMATIVE:** Each category listed below corresponds to
|
|
58
|
-
|
|
59
|
-
| Category | Name object field | Answers | Description
|
|
60
|
-
| ------------- | ----------------- | --------- |
|
|
61
|
-
| Structure | `structure` | What? | Individual objects or object categories that have shared styling. Distinctly different from "components" in that they represent structures and visual patterns that can or do occur across many varieties of components.
|
|
62
|
-
| Sub-structure | `substructure` | What? | A structure within an element that should only exist within the context of its parent structure.
|
|
63
|
-
| Component | `component` | What? | Component scope when the token is component-scoped.
|
|
64
|
-
| Anatomy | `anatomy` | What? | A visible, named part of a component as defined by designers.
|
|
65
|
-
| Object | `object` | Where? | The styling surface to which a visual property is applied (e.g. background, border, edge).
|
|
66
|
-
| Property | `property` | Where? | The
|
|
67
|
-
| Orientation | `orientation` | When/Why? | The direction or order of structures and elements within a component or pattern.
|
|
68
|
-
| Position | `position` | When/Why? | The location of an object relative to another, with or without respect to directional order.
|
|
69
|
-
| Size | `size` | When/Why? | Relative terms used to create relationships and patterns of usage across multiple tokens and token types.
|
|
70
|
-
| Density | `density` | When/Why? | Options that create more or less space within or around the parts of a component.
|
|
71
|
-
| Shape | `shape` | When/Why? | Relative to the overall shape of a component (e.g. "uniform" creates a 1:1 padding ratio between horizontal and vertical padding).
|
|
57
|
+
**NORMATIVE:** Each category listed below corresponds to a field on the token [name object](token-format.md). Tokens **MAY** use any subset of these fields. Exception: `property` is REQUIRED on every name object — see [token-format.md](token-format.md#name-object).
|
|
58
|
+
|
|
59
|
+
| Category | Name object field | Answers | Description |
|
|
60
|
+
| ------------- | ----------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| Structure | `structure` | What? | Individual objects or object categories that have shared styling. Distinctly different from "components" in that they represent structures and visual patterns that can or do occur across many varieties of components. |
|
|
62
|
+
| Sub-structure | `substructure` | What? | A structure within an element that should only exist within the context of its parent structure. |
|
|
63
|
+
| Component | `component` | What? | Component scope when the token is component-scoped. |
|
|
64
|
+
| Anatomy | `anatomy` | What? | A visible, named part of a component as defined by designers. |
|
|
65
|
+
| Object | `object` | Where? | The styling surface to which a visual property is applied (e.g. background, border, edge). |
|
|
66
|
+
| Property | `property` | Where? | The CSS/styling attribute or design-system abstraction being defined (e.g. color, width, padding, gap). REQUIRED — see exception in preamble. Values SHOULD come from [`property-terms.json`](../../packages/design-system-registry/registry/property-terms.json). Anatomy parts and styling surfaces do NOT belong here — they belong in `anatomy` and `object` respectively. See [token-format.md — Name-object migration policy](token-format.md#name-object-migration-policy) for migration guidance. |
|
|
67
|
+
| Orientation | `orientation` | When/Why? | The direction or order of structures and elements within a component or pattern. |
|
|
68
|
+
| Position | `position` | When/Why? | The location of an object relative to another, with or without respect to directional order. |
|
|
69
|
+
| Size | `size` | When/Why? | Relative terms used to create relationships and patterns of usage across multiple tokens and token types. |
|
|
70
|
+
| Density | `density` | When/Why? | Options that create more or less space within or around the parts of a component. |
|
|
71
|
+
| Shape | `shape` | When/Why? | Relative to the overall shape of a component (e.g. "uniform" creates a 1:1 padding ratio between horizontal and vertical padding). |
|
|
72
72
|
|
|
73
73
|
Additional categories for variant and state are inherited from the existing name object:
|
|
74
74
|
|
package/spec/token-format.md
CHANGED
|
@@ -147,6 +147,43 @@ When migrating legacy-format tokens to cascade:
|
|
|
147
147
|
|
|
148
148
|
**RECOMMENDED:** Root token documents (when stored as standalone JSON files) include `specVersion` with const `1.0.0-draft` for self-identification. Embedded tokens inside larger files **MAY** omit it if the parent document carries version metadata.
|
|
149
149
|
|
|
150
|
+
### Name-object migration policy
|
|
151
|
+
|
|
152
|
+
This section defines the normative policy for migrating tokens from string-form names to structured name objects, and for narrowing the `property` field to its intended CSS/styling-attribute semantics.
|
|
153
|
+
|
|
154
|
+
#### String-name escape hatch — SPEC-017 severity schedule
|
|
155
|
+
|
|
156
|
+
String-named tokens (see [String-name escape hatch](#string-name-escape-hatch)) trigger SPEC-017 at **`warning`** severity through the current minor series. Authors **SHOULD** treat SPEC-017 warnings as actionable tech debt and maintain a remediation backlog (e.g. `packages/tokens/naming-exceptions.json`).
|
|
157
|
+
|
|
158
|
+
**NORMATIVE:** SPEC-017 **MUST** graduate from `warning` to `error` at spec version `2.0.0`, no earlier than two minor versions after the minor release that ships this section. This conforms to the [evolution policy](evolution.md) — rule severity tightening is a major change.
|
|
159
|
+
|
|
160
|
+
No string-named token may remain in a conforming dataset after the `2.0.0` cut without first being converted to a structured name object or removed.
|
|
161
|
+
|
|
162
|
+
#### Narrowed `property` semantics
|
|
163
|
+
|
|
164
|
+
The `property` field on a name object is the **CSS/styling attribute or design-system abstraction** being defined — not an anatomy part, not a styling surface, and not a legacy compound name string. Not all valid values are CSS property identifiers; design-system abstractions (e.g. `padding-horizontal`, `overlay-color`, `size`) are permitted.
|
|
165
|
+
|
|
166
|
+
**NORMATIVE:** Values for `property` **SHOULD** come from the [`property-terms`](../../packages/design-system-registry/registry/property-terms.json) registry. Non-registry values emit an advisory warning (SPEC-009 applied to the `property` field).
|
|
167
|
+
|
|
168
|
+
Examples of **valid** `property` values: `color`, `background-color`, `border-radius`, `font-size`, `gap`, `opacity`.
|
|
169
|
+
|
|
170
|
+
Examples of **invalid** `property` values (migration debt):
|
|
171
|
+
|
|
172
|
+
* Anatomy parts — use the `anatomy` field instead (`handle`, `icon`, `label`).
|
|
173
|
+
* Styling surfaces — use the `object` field instead (`background`, `border`, `edge`).
|
|
174
|
+
* Legacy compound names — split into structured fields (`focus-ring-color-key-focus` → `component + anatomy + object + property + state`).
|
|
175
|
+
|
|
176
|
+
#### Author migration guidance
|
|
177
|
+
|
|
178
|
+
When converting a string-named token to a structured name object:
|
|
179
|
+
|
|
180
|
+
1. Parse the legacy name string into its constituent segments using the [default serialization order](taxonomy.md#default-serialization-legacy-format).
|
|
181
|
+
2. Place the CSS/styling attribute in `property` (SHOULD be in `property-terms.json`).
|
|
182
|
+
3. Route anatomy parts to `anatomy` (validated against `anatomy-terms.json`).
|
|
183
|
+
4. Route styling surfaces (background, border, edge) to `object` (validated against `token-objects.json`).
|
|
184
|
+
5. Retain component, variant, state, and other structural fields as-is.
|
|
185
|
+
6. Remove the token from `naming-exceptions.json` after conversion.
|
|
186
|
+
|
|
150
187
|
## Document shape
|
|
151
188
|
|
|
152
189
|
Cascade-format tokens are stored in **JSON files** that conform to [`cascade-file.schema.json`](../schemas/cascade-file.schema.json) (canonical `$id`: `https://opensource.adobe.com/spectrum-design-data/schemas/v0/cascade-file.schema.json`).
|