@adobe/design-data-spec 0.2.0 → 0.3.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/README.md +3 -3
- package/components/button.json +70 -0
- package/conformance/README.md +26 -26
- package/conformance/invalid/SPEC-014/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-014/tokens.tokens.json +9 -0
- package/conformance/invalid/SPEC-018/dataset.json +9 -0
- package/conformance/invalid/SPEC-018/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-019/dataset.json +29 -0
- package/conformance/invalid/SPEC-019/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-020/dataset.json +27 -0
- package/conformance/invalid/SPEC-020/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-021/dataset.json +18 -0
- package/conformance/invalid/SPEC-021/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-022/dataset.json +33 -0
- package/conformance/invalid/SPEC-022/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-023/dataset.json +18 -0
- package/conformance/invalid/SPEC-023/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-024/dataset.json +18 -0
- package/conformance/invalid/SPEC-024/expected-errors.json +10 -0
- package/conformance/valid/component-refs/dataset.json +63 -0
- package/conformance/valid/lifecycle-with-last-modified.json +12 -0
- package/package.json +18 -6
- package/rules/rules.yaml +81 -0
- package/schemas/anatomy-part.schema.json +35 -0
- package/schemas/component.schema.json +267 -0
- package/schemas/state-declaration.schema.json +36 -0
- package/spec/agent-surface.md +116 -0
- package/spec/anatomy-format.md +167 -0
- package/spec/component-format.md +326 -0
- package/spec/evolution.md +32 -32
- package/spec/index.md +27 -21
- package/spec/manifest.md +3 -1
- package/spec/state-model.md +245 -0
- package/spec/taxonomy.md +17 -1
- package/spec/token-format.md +1 -1
- package/src/canonical.js +61 -0
- package/src/validate.js +166 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# Component format
|
|
2
|
+
|
|
3
|
+
**Spec version:** `1.0.0-draft` (see [Overview](index.md))
|
|
4
|
+
|
|
5
|
+
This document defines the normative **component declaration** object: identity (`$id`, `name`, `displayName`), component metadata (`meta`), API options (`options`), named content slots (`slots`), anatomy parts (`anatomy`), state model (`states`), and lifecycle metadata.
|
|
6
|
+
|
|
7
|
+
Component declarations close the structural gap between the token name-object's `component`, `variant`, `anatomy`, and `state` fields and the declared surface of each component. Before this chapter, a token referencing `component: "button"` with `variant: "foo"` was undetectable as invalid because no machine-readable component contract existed in the same spec. After this chapter, validators enforce cross-reference rules (see [SPEC rules](#spec-rules)).
|
|
8
|
+
|
|
9
|
+
Scoped under [RFC-A — Component Contract in Design Data Spec](https://github.com/adobe/spectrum-design-data/discussions/832). See also [rfc-coordination.md](../docs/rfc-coordination.md).
|
|
10
|
+
|
|
11
|
+
## Document shape
|
|
12
|
+
|
|
13
|
+
A component declaration is a **single JSON object** in a `.json` file. One file per component. Files live under a `components/` directory within a design-data package.
|
|
14
|
+
|
|
15
|
+
**NORMATIVE:** Each component declaration file **MUST** validate against the Layer 1 schema [`component.schema.json`](../schemas/component.schema.json) (canonical `$id`: `https://opensource.adobe.com/spectrum-design-data/schemas/v0/component.schema.json`). Layer 1 and Layer 2 validation are defined in the [validation layers](index.md#validation-layers) section of the overview.
|
|
16
|
+
|
|
17
|
+
## Component object
|
|
18
|
+
|
|
19
|
+
### Required fields
|
|
20
|
+
|
|
21
|
+
A component declaration **MUST** contain:
|
|
22
|
+
|
|
23
|
+
| Field | Type | Description |
|
|
24
|
+
| ------------- | ----------------- | ------------------------------------------------------------------------------------- |
|
|
25
|
+
| `$id` | URI string | Canonical identifier for this component declaration. |
|
|
26
|
+
| `name` | kebab-case string | Machine identifier; used as the value of the `component` field in token name objects. |
|
|
27
|
+
| `displayName` | string | Human-readable component name (e.g. `"Button"`). |
|
|
28
|
+
| `meta` | object | Category and documentation link — see [Meta](#meta). |
|
|
29
|
+
|
|
30
|
+
### Optional fields
|
|
31
|
+
|
|
32
|
+
| Field | Type | Description |
|
|
33
|
+
| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
34
|
+
| `specVersion` | string | Declares which spec version this document targets. Currently `"1.0.0-draft"`; future stable releases will accept their own version string. |
|
|
35
|
+
| `description` | string | Plain-text description of the component's purpose. |
|
|
36
|
+
| `options` | object | Component API options — see [Options](#options). |
|
|
37
|
+
| `slots` | array | Named content injection points — see [Slots](#slots). |
|
|
38
|
+
| `anatomy` | array | Named anatomy parts — see [Anatomy (stub)](#anatomy-stub). |
|
|
39
|
+
| `states` | array | Per-component state declarations — see [States (stub)](#states-stub). |
|
|
40
|
+
| `lifecycle` | object | Version lifecycle metadata — see [Lifecycle](#lifecycle). |
|
|
41
|
+
|
|
42
|
+
**NORMATIVE:** No properties beyond those listed above are permitted at the top level of a component declaration. Additional fields **MUST** cause a Layer 1 schema error.
|
|
43
|
+
|
|
44
|
+
### `$id`
|
|
45
|
+
|
|
46
|
+
**NORMATIVE:** The `$id` **MUST** be a valid URI identifying this component declaration document. The recommended pattern is:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/{name}.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
where `{name}` matches the component's `name` field.
|
|
53
|
+
|
|
54
|
+
### `name`
|
|
55
|
+
|
|
56
|
+
**NORMATIVE:** `name` **MUST** match the pattern `^[a-z][a-z0-9-]*$` — lower-case kebab-case, non-empty.
|
|
57
|
+
|
|
58
|
+
**NORMATIVE:** `name` **MUST** be unique within a dataset. No two component declarations in the same design-data package may share a `name` value.
|
|
59
|
+
|
|
60
|
+
**NORMATIVE:** Token name-object `component` field values **MUST** match the `name` of a declared component in the dataset (rule SPEC-018). An undeclared `component` value is a validation error.
|
|
61
|
+
|
|
62
|
+
### Meta
|
|
63
|
+
|
|
64
|
+
**NORMATIVE:** `meta` **MUST** contain:
|
|
65
|
+
|
|
66
|
+
| Field | Type | Values |
|
|
67
|
+
| ------------------ | ------------- | --------------------------------------------------------------------------------------------------------- |
|
|
68
|
+
| `category` | string (enum) | `actions`, `containers`, `data visualization`, `feedback`, `inputs`, `navigation`, `status`, `typography` |
|
|
69
|
+
| `documentationUrl` | URI string | Link to the component's documentation page. |
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
"meta": {
|
|
73
|
+
"category": "actions",
|
|
74
|
+
"documentationUrl": "https://spectrum.adobe.com/page/button/"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Options
|
|
79
|
+
|
|
80
|
+
The `options` block declares the component's API surface — the configurable properties that affect its appearance or behavior. It mirrors the shape of `@adobe/spectrum-component-api-schemas` for backward compatibility.
|
|
81
|
+
|
|
82
|
+
**NORMATIVE:** `options` **MUST** be a JSON object. Each key is an option name; each value is an **option descriptor**.
|
|
83
|
+
|
|
84
|
+
### Option descriptor
|
|
85
|
+
|
|
86
|
+
An option descriptor is a JSON object with the following fields:
|
|
87
|
+
|
|
88
|
+
| Field | Type | Required | Description |
|
|
89
|
+
| ------------- | --------------- | -------- | -------------------------------------------------------------------------------- |
|
|
90
|
+
| `type` | string or array | OPTIONAL | JSON Schema primitive type(s): `"string"`, `"boolean"`, `"number"`, `"integer"`. |
|
|
91
|
+
| `enum` | array | OPTIONAL | Exhaustive list of permitted values. |
|
|
92
|
+
| `default` | any | OPTIONAL | Default value when the option is not specified. |
|
|
93
|
+
| `description` | string | OPTIONAL | Plain-text description of what the option controls. |
|
|
94
|
+
| `$ref` | URI string | OPTIONAL | Reference to a shared type schema (e.g. `workflow-icon.json`). |
|
|
95
|
+
|
|
96
|
+
**NORMATIVE:** Each key in `options` **MUST** be camelCase.
|
|
97
|
+
|
|
98
|
+
**NORMATIVE:** Boolean option names **MUST** begin with `is` or `has` (e.g. `isDisabled`, `hasIcon`).
|
|
99
|
+
|
|
100
|
+
**NORMATIVE:** When `enum` is present, token name-object `variant` field values referencing this component **MUST** be drawn from the declared `variant` option enum (rule SPEC-019). Other option enums are informative for tooling but do not currently drive SPEC rules.
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
"options": {
|
|
104
|
+
"variant": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"enum": ["accent", "negative", "primary", "secondary"],
|
|
107
|
+
"default": "accent",
|
|
108
|
+
"description": "Visual emphasis level."
|
|
109
|
+
},
|
|
110
|
+
"size": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"enum": ["s", "m", "l", "xl"],
|
|
113
|
+
"default": "m"
|
|
114
|
+
},
|
|
115
|
+
"isDisabled": {
|
|
116
|
+
"type": "boolean",
|
|
117
|
+
"default": false
|
|
118
|
+
},
|
|
119
|
+
"icon": {
|
|
120
|
+
"$ref": "https://opensource.adobe.com/spectrum-design-data/schemas/types/workflow-icon.json",
|
|
121
|
+
"description": "Icon placed at the start of the button. Required when hideLabel is true."
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Slots
|
|
127
|
+
|
|
128
|
+
The `slots` block declares the component's named **content injection points** — the positions where consumers place child content. Slot declarations are derived from the cross-platform audit in [`audits/slots.audit.md`](../audits/slots.audit.md).
|
|
129
|
+
|
|
130
|
+
**NORMATIVE:** `slots` **MUST** be a JSON array. Each element is a **slot declaration**.
|
|
131
|
+
|
|
132
|
+
### Slot declaration
|
|
133
|
+
|
|
134
|
+
| Field | Type | Required | Description |
|
|
135
|
+
| ------------- | ------- | -------- | --------------------------------------------------------------------------- |
|
|
136
|
+
| `name` | string | REQUIRED | Slot identifier. **SHOULD** come from the canonical vocabulary (see below). |
|
|
137
|
+
| `description` | string | OPTIONAL | Plain-text description of what content goes in this slot. |
|
|
138
|
+
| `required` | boolean | OPTIONAL | Whether consumers **MUST** populate this slot. Default: `false`. |
|
|
139
|
+
|
|
140
|
+
### Canonical slot vocabulary
|
|
141
|
+
|
|
142
|
+
The following slot names are defined by the cross-platform audit and **SHOULD** be used in preference to custom names:
|
|
143
|
+
|
|
144
|
+
| Name | Semantics |
|
|
145
|
+
| -------------------- | ----------------------------------------------------------------------- |
|
|
146
|
+
| `default` | Primary content (text, children). The main content slot. |
|
|
147
|
+
| `icon` | Decorative icon at the leading edge of the component. |
|
|
148
|
+
| `label` | Human-readable identifier / placeholder text (distinct from `default`). |
|
|
149
|
+
| `help-text` | Non-error guidance text below a form field. |
|
|
150
|
+
| `negative-help-text` | Validation error message for a form field. |
|
|
151
|
+
| `action` | Secondary interactive button or call-to-action. |
|
|
152
|
+
| `heading` | Section or dialog heading. |
|
|
153
|
+
| `description` | Section or dialog body text (distinct from `help-text`). |
|
|
154
|
+
| `hero` | Large header media (e.g. dialog hero image). |
|
|
155
|
+
| `footer` | Below-content supplemental area (e.g. dialog footer). |
|
|
156
|
+
| `tooltip` | Floating annotation attached to the component. |
|
|
157
|
+
|
|
158
|
+
**NORMATIVE:** Custom slot names are permitted but **SHOULD** be documented in the slot's `description` field (rule SPEC-021 fires a warning for undocumented custom names).
|
|
159
|
+
|
|
160
|
+
**RECOMMENDED:** Components **SHOULD** declare a `default` slot when they accept primary child content.
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
"slots": [
|
|
164
|
+
{
|
|
165
|
+
"name": "default",
|
|
166
|
+
"description": "Text label of the button.",
|
|
167
|
+
"required": false
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"name": "icon",
|
|
171
|
+
"description": "Icon placed at the start of the button. Required when isLabelHidden is true."
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Anatomy (stub)
|
|
177
|
+
|
|
178
|
+
The `anatomy` block declares the component's named **visual parts** — the anatomy terms used in token name-object `anatomy` fields. Full normative definition is in [`spec/anatomy-format.md`](anatomy-format.md) (Phase 6.2).
|
|
179
|
+
|
|
180
|
+
**NORMATIVE:** `anatomy` **MUST** be a JSON array. Each element is an anatomy part object.
|
|
181
|
+
|
|
182
|
+
**NORMATIVE:** Token name-object `anatomy` field values referencing this component **MUST** match the `name` of a declared anatomy part (rule SPEC-020).
|
|
183
|
+
|
|
184
|
+
Each anatomy part carries at minimum:
|
|
185
|
+
|
|
186
|
+
| Field | Type | Required | Description |
|
|
187
|
+
| ------------- | ---------------- | -------- | -------------------------------------------------------------- |
|
|
188
|
+
| `name` | string | REQUIRED | Anatomy part identifier (e.g. `icon`, `label`, `handle`). |
|
|
189
|
+
| `description` | string | OPTIONAL | Plain-text description of the part. |
|
|
190
|
+
| `required` | boolean | OPTIONAL | Whether this part is always present. Default: `false`. |
|
|
191
|
+
| `contains` | array of strings | OPTIONAL | Informative: other anatomy part names nested within this part. |
|
|
192
|
+
|
|
193
|
+
See [`spec/anatomy-format.md`](anatomy-format.md) for constraints, cross-field validation, and the full anatomy part schema.
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
"anatomy": [
|
|
197
|
+
{ "name": "icon", "description": "Leading icon." },
|
|
198
|
+
{ "name": "label", "description": "Button text.", "required": true }
|
|
199
|
+
]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## States (stub)
|
|
203
|
+
|
|
204
|
+
The `states` block declares the component's **interactive and semantic states** — the state terms used in token name-object `state` fields. Full normative definition is in [`spec/state-model.md`](state-model.md) (Phase 6.3).
|
|
205
|
+
|
|
206
|
+
**NORMATIVE:** `states` **MUST** be a JSON array. Each element is a state declaration object.
|
|
207
|
+
|
|
208
|
+
Each state carries at minimum:
|
|
209
|
+
|
|
210
|
+
| Field | Type | Required | Description |
|
|
211
|
+
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
212
|
+
| `name` | string | REQUIRED | State identifier (e.g. `hover`, `focus`, `disabled`). |
|
|
213
|
+
| `trigger` | string | OPTIONAL | `"prop"` for persistent prop-driven states (e.g. `isDisabled`) or `"interaction"` for runtime interaction states (hover, focus, pressed). |
|
|
214
|
+
| `precedence` | integer | OPTIONAL | Resolution precedence; higher integer wins when multiple states are active. |
|
|
215
|
+
| `layered` | boolean | OPTIONAL | `true` for states that compose with others (e.g. focus ring over hover). Default: `false`. |
|
|
216
|
+
|
|
217
|
+
See [`spec/state-model.md`](state-model.md) for the full state resolution algorithm, trigger semantics, and precedence rules.
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
"states": [
|
|
221
|
+
{ "name": "hover", "trigger": "interaction", "precedence": 50 },
|
|
222
|
+
{ "name": "focus", "trigger": "interaction", "precedence": 60, "layered": true },
|
|
223
|
+
{ "name": "disabled", "trigger": "prop", "precedence": 100 }
|
|
224
|
+
]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Lifecycle
|
|
228
|
+
|
|
229
|
+
The `lifecycle` block tracks a component declaration's version history. It mirrors the per-token lifecycle pattern from [`spec/token-format.md`](token-format.md#lifecycle-and-metadata).
|
|
230
|
+
|
|
231
|
+
| Field | Type | Description |
|
|
232
|
+
| ------------------- | --------------- | ------------------------------------------------------------------------------ |
|
|
233
|
+
| `introduced` | string | Spec version when this component declaration was added (e.g. `"1.0.0-draft"`). |
|
|
234
|
+
| `deprecated` | string | Spec version when this component was deprecated. Truthy = deprecated. |
|
|
235
|
+
| `deprecatedComment` | string | Human-readable explanation of the deprecation and migration path. |
|
|
236
|
+
| `replacedBy` | string or array | `name` value(s) of the replacement component(s). |
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
"lifecycle": {
|
|
240
|
+
"introduced": "1.0.0-draft"
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## SPEC rules
|
|
245
|
+
|
|
246
|
+
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).
|
|
247
|
+
|
|
248
|
+
| Rule ID | Name | Severity | Assert |
|
|
249
|
+
| -------- | --------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
250
|
+
| SPEC-018 | `component-name-exists` | error | Token `component` field value **MUST** match the `name` of a declared component in the dataset. |
|
|
251
|
+
| SPEC-019 | `component-variant-valid` | error | Token `variant` field value **MUST** match a value in the declared `variant` option enum for the referenced component (when that enum exists). |
|
|
252
|
+
| SPEC-020 | `component-anatomy-valid` | error | Token `anatomy` field value **MUST** match the `name` of a declared anatomy part on the referenced component. |
|
|
253
|
+
| 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. |
|
|
254
|
+
| 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). |
|
|
255
|
+
|
|
256
|
+
## Full example
|
|
257
|
+
|
|
258
|
+
A complete button component declaration:
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
{
|
|
262
|
+
"$schema": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/component.schema.json",
|
|
263
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/button.json",
|
|
264
|
+
"specVersion": "1.0.0-draft",
|
|
265
|
+
"name": "button",
|
|
266
|
+
"displayName": "Button",
|
|
267
|
+
"description": "Buttons allow users to perform an action or to navigate to another page.",
|
|
268
|
+
"meta": {
|
|
269
|
+
"category": "actions",
|
|
270
|
+
"documentationUrl": "https://spectrum.adobe.com/page/button/"
|
|
271
|
+
},
|
|
272
|
+
"options": {
|
|
273
|
+
"variant": {
|
|
274
|
+
"type": "string",
|
|
275
|
+
"enum": ["accent", "negative", "primary", "secondary"],
|
|
276
|
+
"default": "accent",
|
|
277
|
+
"description": "Visual emphasis level."
|
|
278
|
+
},
|
|
279
|
+
"style": {
|
|
280
|
+
"type": "string",
|
|
281
|
+
"enum": ["fill", "outline"],
|
|
282
|
+
"default": "fill"
|
|
283
|
+
},
|
|
284
|
+
"size": {
|
|
285
|
+
"type": "string",
|
|
286
|
+
"enum": ["s", "m", "l", "xl"],
|
|
287
|
+
"default": "m"
|
|
288
|
+
},
|
|
289
|
+
"isDisabled": { "type": "boolean", "default": false },
|
|
290
|
+
"isPending": { "type": "boolean", "default": false },
|
|
291
|
+
"isLabelHidden": { "type": "boolean", "default": false },
|
|
292
|
+
"icon": {
|
|
293
|
+
"$ref": "https://opensource.adobe.com/spectrum-design-data/schemas/types/workflow-icon.json",
|
|
294
|
+
"description": "Icon placed at the start of the button. Required when isLabelHidden is true."
|
|
295
|
+
},
|
|
296
|
+
"staticColor": {
|
|
297
|
+
"type": "string",
|
|
298
|
+
"enum": ["white", "black"],
|
|
299
|
+
"description": "Static color for use on colored backgrounds. Must not be set for the default variant."
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
"slots": [
|
|
303
|
+
{
|
|
304
|
+
"name": "default",
|
|
305
|
+
"description": "Text label of the button.",
|
|
306
|
+
"required": false
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"name": "icon",
|
|
310
|
+
"description": "Icon placed at the start of the button."
|
|
311
|
+
}
|
|
312
|
+
],
|
|
313
|
+
"anatomy": [
|
|
314
|
+
{ "name": "icon", "description": "Leading icon." },
|
|
315
|
+
{ "name": "label", "description": "Button text.", "required": true }
|
|
316
|
+
],
|
|
317
|
+
"states": [
|
|
318
|
+
{ "name": "hover", "trigger": "interaction", "precedence": 50 },
|
|
319
|
+
{ "name": "focus", "trigger": "interaction", "precedence": 60, "layered": true },
|
|
320
|
+
{ "name": "disabled", "trigger": "prop", "precedence": 100 }
|
|
321
|
+
],
|
|
322
|
+
"lifecycle": {
|
|
323
|
+
"introduced": "1.0.0-draft"
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
package/spec/evolution.md
CHANGED
|
@@ -12,13 +12,13 @@ Tokens progress through the following lifecycle stages:
|
|
|
12
12
|
introduced → active → deprecated → planned removal → removed
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
| Stage | Token state
|
|
16
|
-
| ------------------- |
|
|
17
|
-
| **Introduced** | Token first appears in the dataset. `introduced` field records the version.
|
|
18
|
-
| **Active** | Token is current and recommended for use. No `deprecated` field.
|
|
15
|
+
| Stage | Token state |
|
|
16
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
17
|
+
| **Introduced** | Token first appears in the dataset. `introduced` field records the version. |
|
|
18
|
+
| **Active** | Token is current and recommended for use. No `deprecated` field. |
|
|
19
19
|
| **Deprecated** | Token is no longer recommended. `deprecated` records the version. Consumers receive warnings. `replaced_by` points to the successor token(s) when a direct replacement exists. |
|
|
20
|
-
| **Planned removal** | `plannedRemoval` records the target version. The token remains in the dataset but consumers should complete migration.
|
|
21
|
-
| **Removed** | Token is deleted from the dataset. Consumers that still reference it will break.
|
|
20
|
+
| **Planned removal** | `plannedRemoval` records the target version. The token remains in the dataset but consumers should complete migration. |
|
|
21
|
+
| **Removed** | Token is deleted from the dataset. Consumers that still reference it will break. |
|
|
22
22
|
|
|
23
23
|
### Lifecycle fields
|
|
24
24
|
|
|
@@ -28,10 +28,10 @@ See [Token format — Lifecycle and metadata](token-format.md#lifecycle-and-meta
|
|
|
28
28
|
|
|
29
29
|
When a token carries `replaced_by`:
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
* Each target UUID **MUST** resolve to an existing token in the dataset (rule `SPEC-010`).
|
|
32
|
+
* The target token **SHOULD NOT** itself be deprecated. Chains of replacements (A replaced by B, B replaced by C) are discouraged; authors should point directly to the final replacement.
|
|
33
|
+
* For a single UUID (1:1 replacement), consumers can mechanically rewrite references.
|
|
34
|
+
* For an array of UUIDs (one-to-many split), the `deprecated_comment` **MUST** explain which replacement applies in which context.
|
|
35
35
|
|
|
36
36
|
## Migration windows
|
|
37
37
|
|
|
@@ -49,27 +49,27 @@ The specification follows [Semantic Versioning](https://semver.org/) for its pub
|
|
|
49
49
|
|
|
50
50
|
### Minor changes (backward compatible)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
* New tokens added to the dataset
|
|
53
|
+
* New optional fields added to token schema
|
|
54
|
+
* New validation rules added to the rule catalog
|
|
55
|
+
* Tokens deprecated (with `deprecated` field)
|
|
56
|
+
* Rule severity relaxed (error → warning)
|
|
57
|
+
* New enum values added to registries
|
|
58
58
|
|
|
59
59
|
### Major changes (breaking)
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
* Tokens removed from the dataset
|
|
62
|
+
* Required fields added to token schema
|
|
63
|
+
* Existing fields removed or type-changed
|
|
64
|
+
* Rule severity tightened (warning → error)
|
|
65
|
+
* Enum values removed from registries
|
|
66
|
+
* Constraint tightening (e.g. stricter value validation)
|
|
67
67
|
|
|
68
68
|
### Patch changes (clarifications)
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
* Typo fixes in spec prose
|
|
71
|
+
* Clarifications to normative text that do not change conformance behavior
|
|
72
|
+
* Test fixture additions or corrections
|
|
73
73
|
|
|
74
74
|
## Legacy format contract
|
|
75
75
|
|
|
@@ -79,13 +79,13 @@ The `@adobe/spectrum-tokens` package continues to publish tokens in the **legacy
|
|
|
79
79
|
|
|
80
80
|
### Lifecycle field mapping
|
|
81
81
|
|
|
82
|
-
| Cascade format
|
|
83
|
-
|
|
|
84
|
-
| `deprecated: "3.2.0"` (version string) | `deprecated: true` (boolean)
|
|
85
|
-
| `replaced_by: "<uuid>"` | `renamed: "<target-token-name>"`
|
|
86
|
-
| `introduced`
|
|
87
|
-
| `plannedRemoval`
|
|
88
|
-
| `deprecated_comment`
|
|
82
|
+
| Cascade format | Legacy format |
|
|
83
|
+
| -------------------------------------- | ------------------------------------- |
|
|
84
|
+
| `deprecated: "3.2.0"` (version string) | `deprecated: true` (boolean) |
|
|
85
|
+
| `replaced_by: "<uuid>"` | `renamed: "<target-token-name>"` |
|
|
86
|
+
| `introduced` | Not emitted |
|
|
87
|
+
| `plannedRemoval` | Not emitted |
|
|
88
|
+
| `deprecated_comment` | `deprecated_comment` (passed through) |
|
|
89
89
|
|
|
90
90
|
### Coexistence during migration
|
|
91
91
|
|
package/spec/index.md
CHANGED
|
@@ -11,12 +11,15 @@ The specification defines:
|
|
|
11
11
|
|
|
12
12
|
1. **Token format** — structured token identity (`name`), literal `value` or alias `$ref`, and lifecycle metadata ([Token format](token-format.md)).
|
|
13
13
|
2. **Taxonomy** — concept categories, token term vocabulary, formatting style, and the distinction between component anatomy and token objects ([Taxonomy](taxonomy.md)).
|
|
14
|
-
3. **
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
3. **Component format** — component declaration shape: API options, named content slots, anatomy parts, state model, and cross-reference validation rules ([Component format](component-format.md)).
|
|
15
|
+
3a. **Anatomy format** — anatomy part declaration shape: field constraints, canonical anatomy vocabulary, and cross-reference rules for token `anatomy` field values ([Anatomy format](anatomy-format.md)).
|
|
16
|
+
3b. **State model** — state declaration shape: trigger semantics, precedence and resolution algorithm, canonical state vocabulary, and cross-reference rules for token `state` field values ([State model](state-model.md)).
|
|
17
|
+
4. **Cascade and resolution** — layered data (foundation, platform, product), specificity, and how a context picks a winning value ([Cascade](cascade.md)).
|
|
18
|
+
5. **Dimensions** — declared modes, defaults, and coverage expectations ([Dimensions](dimensions.md)).
|
|
19
|
+
6. **Platform manifest** — how a platform repo pins foundation data, filters tokens, and applies typed overrides ([Manifest](manifest.md)).
|
|
20
|
+
7. **Semantic diff** — change taxonomy, token identity rules, and property-level change tracking for comparing dataset versions ([Diff](diff.md)).
|
|
21
|
+
8. **Query notation** — filter syntax for selecting tokens by structured fields ([Query](query.md)).
|
|
22
|
+
9. **Evolution** — deprecation lifecycle, migration windows, change classification, and legacy format contract ([Evolution](evolution.md)).
|
|
20
23
|
|
|
21
24
|
## Conformance
|
|
22
25
|
|
|
@@ -50,16 +53,19 @@ Full governance (compatibility tiers, migration, CLI `--spec-version`) is discus
|
|
|
50
53
|
|
|
51
54
|
## Normative references (sibling documents)
|
|
52
55
|
|
|
53
|
-
| Document
|
|
54
|
-
|
|
|
55
|
-
| [Token format](token-format.md)
|
|
56
|
-
| [Taxonomy](taxonomy.md)
|
|
57
|
-
| [
|
|
58
|
-
| [
|
|
59
|
-
| [
|
|
60
|
-
| [
|
|
61
|
-
| [
|
|
62
|
-
| [
|
|
56
|
+
| Document | Role |
|
|
57
|
+
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| [Token format](token-format.md) | Token `name`, `value` / `$ref`, value types, lifecycle metadata. |
|
|
59
|
+
| [Taxonomy](taxonomy.md) | Concept categories, vocabulary, formatting, anatomy vs objects. |
|
|
60
|
+
| [Component format](component-format.md) | Component declaration: options, slots, anatomy (→ anatomy-format.md), states (→ state-model.md), lifecycle. |
|
|
61
|
+
| [Anatomy format](anatomy-format.md) | Anatomy part declarations: field constraints, canonical vocabulary, SPEC-020/SPEC-023/SPEC-024/SPEC-025. |
|
|
62
|
+
| [State model](state-model.md) | State declarations: trigger semantics, precedence algorithm, canonical vocabulary, SPEC-022/SPEC-026. |
|
|
63
|
+
| [Cascade](cascade.md) | Layers, specificity, resolution algorithm. |
|
|
64
|
+
| [Dimensions](dimensions.md) | Dimension declarations, built-in dimensions, coverage. |
|
|
65
|
+
| [Manifest](manifest.md) | Platform manifest fields and validation expectations. |
|
|
66
|
+
| [Diff](diff.md) | Semantic diff change taxonomy, token identity, property changes. |
|
|
67
|
+
| [Query](query.md) | Filter notation for selecting tokens by structured fields. |
|
|
68
|
+
| [Evolution](evolution.md) | Deprecation lifecycle, migration windows, change classification. |
|
|
63
69
|
|
|
64
70
|
## JSON Schema `$id` and versioning
|
|
65
71
|
|
|
@@ -76,11 +82,11 @@ Packaged copies in this repository live under `packages/design-data-spec/schemas
|
|
|
76
82
|
|
|
77
83
|
## Relationship to existing Adobe packages
|
|
78
84
|
|
|
79
|
-
| Package / area | Relationship
|
|
80
|
-
| --------------------------------------- |
|
|
81
|
-
| `@adobe/spectrum-tokens` | **Current** token JSON under `packages/tokens/` is the **legacy** shape (e.g. `color-set`, `scale-set`). This spec defines the **target** format; backward-compat schemas and migration are Phase 1 ([#723](https://github.com/adobe/spectrum-design-data/issues/723)).
|
|
82
|
-
| `@adobe/design-system-registry` | Registry enums and component metadata MAY be referenced by validation rules (e.g. component association); exact coupling is Layer 2.
|
|
83
|
-
| `@adobe/spectrum-component-api-schemas` |
|
|
85
|
+
| Package / area | Relationship |
|
|
86
|
+
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
87
|
+
| `@adobe/spectrum-tokens` | **Current** token JSON under `packages/tokens/` is the **legacy** shape (e.g. `color-set`, `scale-set`). This spec defines the **target** format; backward-compat schemas and migration are Phase 1 ([#723](https://github.com/adobe/spectrum-design-data/issues/723)). |
|
|
88
|
+
| `@adobe/design-system-registry` | Registry enums and component metadata MAY be referenced by validation rules (e.g. component association); exact coupling is Layer 2. |
|
|
89
|
+
| `@adobe/spectrum-component-api-schemas` | Will become a thin adapter over component declarations in `packages/design-data-spec/components/` (Phase 6.5). Until migration, existing schemas remain authoritative. Cross-reference rules SPEC-018–SPEC-020 apply when component declarations are present in the dataset. |
|
|
84
90
|
|
|
85
91
|
## Umbrella discussions
|
|
86
92
|
|
package/spec/manifest.md
CHANGED
|
@@ -26,7 +26,9 @@ A manifest **MUST** conform to [`manifest.schema.json`](../schemas/manifest.sche
|
|
|
26
26
|
|
|
27
27
|
### `include` / `exclude`
|
|
28
28
|
|
|
29
|
-
**NORMATIVE:** Entries **MUST** be non-empty strings.
|
|
29
|
+
**NORMATIVE:** Entries **MUST** be non-empty strings.
|
|
30
|
+
|
|
31
|
+
> **Note:** Query notation syntax is fully defined in [Query](query.md) and is normative for programmatic use. Its normative use in manifest `include`/`exclude` is deferred to a post-`1.0.0-draft` revision pending conformance fixtures; until then, implementations **MUST** treat manifest query values as opaque identifiers.
|
|
30
32
|
|
|
31
33
|
### `overrides`
|
|
32
34
|
|