@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.
Files changed (124) hide show
  1. package/conformance/README.md +82 -10
  2. package/conformance/diff/cross-format/expected.json +27 -0
  3. package/conformance/diff/cross-format/new/tokens.tokens.json +8 -0
  4. package/conformance/diff/cross-format/old/tokens.json +7 -0
  5. package/conformance/diff/deprecated-new-token/expected.json +13 -0
  6. package/conformance/diff/deprecated-new-token/new/tokens.tokens.json +8 -0
  7. package/conformance/diff/deprecated-new-token/old/tokens.tokens.json +1 -0
  8. package/conformance/diff/deprecated-set-level/expected.json +13 -0
  9. package/conformance/diff/deprecated-set-level/new/tokens.tokens.json +10 -0
  10. package/conformance/diff/deprecated-set-level/old/tokens.tokens.json +1 -0
  11. package/conformance/diff/identical-tokens/expected.json +8 -0
  12. package/conformance/diff/identical-tokens/new/tokens.tokens.json +12 -0
  13. package/conformance/diff/identical-tokens/old/tokens.tokens.json +12 -0
  14. package/conformance/diff/matched-gaining-deprecated/expected.json +20 -0
  15. package/conformance/diff/matched-gaining-deprecated/new/tokens.tokens.json +8 -0
  16. package/conformance/diff/matched-gaining-deprecated/old/tokens.tokens.json +7 -0
  17. package/conformance/diff/property-nested-change/expected.json +27 -0
  18. package/conformance/diff/property-nested-change/new/tokens.tokens.json +10 -0
  19. package/conformance/diff/property-nested-change/old/tokens.tokens.json +10 -0
  20. package/conformance/diff/property-value-update/expected.json +21 -0
  21. package/conformance/diff/property-value-update/new/tokens.tokens.json +7 -0
  22. package/conformance/diff/property-value-update/old/tokens.tokens.json +7 -0
  23. package/conformance/diff/rename-by-uuid/expected.json +22 -0
  24. package/conformance/diff/rename-by-uuid/new/tokens.tokens.json +7 -0
  25. package/conformance/diff/rename-by-uuid/old/tokens.tokens.json +7 -0
  26. package/conformance/diff/rename-with-property-changes/expected.json +28 -0
  27. package/conformance/diff/rename-with-property-changes/new/tokens.tokens.json +7 -0
  28. package/conformance/diff/rename-with-property-changes/old/tokens.tokens.json +7 -0
  29. package/conformance/diff/replaced-by-pairing/expected.json +43 -0
  30. package/conformance/diff/replaced-by-pairing/new/tokens.tokens.json +7 -0
  31. package/conformance/diff/replaced-by-pairing/old/tokens.tokens.json +10 -0
  32. package/conformance/diff/reverted-token/expected.json +13 -0
  33. package/conformance/diff/reverted-token/new/tokens.tokens.json +7 -0
  34. package/conformance/diff/reverted-token/old/tokens.tokens.json +8 -0
  35. package/conformance/diff/simple-add-delete/expected.json +18 -0
  36. package/conformance/diff/simple-add-delete/new/tokens.tokens.json +7 -0
  37. package/conformance/diff/simple-add-delete/old/tokens.tokens.json +7 -0
  38. package/conformance/diff/uuid-backfill/expected.json +20 -0
  39. package/conformance/diff/uuid-backfill/new/tokens.tokens.json +7 -0
  40. package/conformance/diff/uuid-backfill/old/tokens.tokens.json +6 -0
  41. package/conformance/invalid/SPEC-008/dimension.json +5 -0
  42. package/conformance/invalid/SPEC-008/expected-errors.json +10 -0
  43. package/conformance/invalid/SPEC-008/tokens.tokens.json +15 -0
  44. package/conformance/invalid/SPEC-010/expected-errors.json +10 -0
  45. package/conformance/invalid/SPEC-010/tokens.tokens.json +9 -0
  46. package/conformance/invalid/SPEC-011/expected-errors.json +10 -0
  47. package/conformance/invalid/SPEC-011/tokens.tokens.json +22 -0
  48. package/conformance/invalid/SPEC-012/expected-errors.json +10 -0
  49. package/conformance/invalid/SPEC-012/tokens.tokens.json +13 -0
  50. package/conformance/invalid/SPEC-013/expected-errors.json +10 -0
  51. package/conformance/invalid/SPEC-013/tokens.tokens.json +8 -0
  52. package/conformance/query/and-conditions/expected.json +1 -0
  53. package/conformance/query/and-conditions/input/tokens.tokens.json +17 -0
  54. package/conformance/query/and-conditions/query.txt +1 -0
  55. package/conformance/query/and-or-precedence/expected.json +1 -0
  56. package/conformance/query/and-or-precedence/input/tokens.tokens.json +22 -0
  57. package/conformance/query/and-or-precedence/query.txt +1 -0
  58. package/conformance/query/empty-matches-all/expected.json +1 -0
  59. package/conformance/query/empty-matches-all/input/tokens.tokens.json +17 -0
  60. package/conformance/query/empty-matches-all/query.txt +1 -0
  61. package/conformance/query/negation/expected.json +1 -0
  62. package/conformance/query/negation/input/tokens.tokens.json +17 -0
  63. package/conformance/query/negation/query.txt +1 -0
  64. package/conformance/query/no-matches/expected.json +1 -0
  65. package/conformance/query/no-matches/input/tokens.tokens.json +7 -0
  66. package/conformance/query/no-matches/query.txt +1 -0
  67. package/conformance/query/or-conditions/expected.json +1 -0
  68. package/conformance/query/or-conditions/input/tokens.tokens.json +17 -0
  69. package/conformance/query/or-conditions/query.txt +1 -0
  70. package/conformance/query/schema-key/expected.json +1 -0
  71. package/conformance/query/schema-key/input/tokens.tokens.json +14 -0
  72. package/conformance/query/schema-key/query.txt +1 -0
  73. package/conformance/query/single-field/expected.json +1 -0
  74. package/conformance/query/single-field/input/tokens.tokens.json +17 -0
  75. package/conformance/query/single-field/query.txt +1 -0
  76. package/conformance/query/wildcard-prefix/expected.json +1 -0
  77. package/conformance/query/wildcard-prefix/input/tokens.tokens.json +17 -0
  78. package/conformance/query/wildcard-prefix/query.txt +1 -0
  79. package/conformance/query/wildcard-suffix/expected.json +1 -0
  80. package/conformance/query/wildcard-suffix/input/tokens.tokens.json +17 -0
  81. package/conformance/query/wildcard-suffix/query.txt +1 -0
  82. package/conformance/resolution/alias-resolved-after-cascade/dimensions/color-scheme.json +5 -0
  83. package/conformance/resolution/alias-resolved-after-cascade/expected.json +5 -0
  84. package/conformance/resolution/alias-resolved-after-cascade/input/tokens.tokens.json +12 -0
  85. package/conformance/resolution/alias-resolved-after-cascade/query.json +4 -0
  86. package/conformance/resolution/base-fallback/dimensions/color-scheme.json +5 -0
  87. package/conformance/resolution/base-fallback/expected.json +5 -0
  88. package/conformance/resolution/base-fallback/input/tokens.tokens.json +7 -0
  89. package/conformance/resolution/base-fallback/query.json +4 -0
  90. package/conformance/resolution/specificity-wins/dimensions/color-scheme.json +5 -0
  91. package/conformance/resolution/specificity-wins/expected.json +5 -0
  92. package/conformance/resolution/specificity-wins/input/tokens.tokens.json +12 -0
  93. package/conformance/resolution/specificity-wins/query.json +4 -0
  94. package/fields/anatomy.json +15 -0
  95. package/fields/color-scheme.json +15 -0
  96. package/fields/component.json +15 -0
  97. package/fields/contrast.json +15 -0
  98. package/fields/density.json +15 -0
  99. package/fields/object.json +15 -0
  100. package/fields/orientation.json +15 -0
  101. package/fields/position.json +15 -0
  102. package/fields/property.json +15 -0
  103. package/fields/scale.json +15 -0
  104. package/fields/shape.json +15 -0
  105. package/fields/size.json +15 -0
  106. package/fields/state.json +15 -0
  107. package/fields/structure.json +15 -0
  108. package/fields/substructure.json +15 -0
  109. package/fields/variant.json +15 -0
  110. package/package.json +3 -1
  111. package/rules/rules.yaml +56 -2
  112. package/schemas/cascade-file.schema.json +10 -0
  113. package/schemas/field.schema.json +85 -0
  114. package/schemas/manifest.schema.json +55 -1
  115. package/schemas/token.schema.json +89 -18
  116. package/spec/cascade.md +18 -2
  117. package/spec/diff.md +97 -0
  118. package/spec/dimensions.md +15 -6
  119. package/spec/evolution.md +98 -0
  120. package/spec/index.md +11 -8
  121. package/spec/manifest.md +15 -0
  122. package/spec/query.md +135 -0
  123. package/spec/taxonomy.md +173 -0
  124. package/spec/token-format.md +114 -19
@@ -25,18 +25,40 @@ The **name object** identifies the token in a structured way. Implementations us
25
25
 
26
26
  **NORMATIVE fields** (all string unless noted):
27
27
 
28
+ The set of available name-object fields is declared in the design system's **field catalog** (`fields/` directory). Each field declaration conforms to [`field.schema.json`](../schemas/field.schema.json) and specifies its kind (`semantic` or `dimension`), vocabulary registry, validation severity, and default serialization position. See [Taxonomy](taxonomy.md) for the full concept category hierarchy, component anatomy vs. token objects, and serialization rules.
29
+
30
+ Fields are divided into **semantic fields** (identity, structure, intent) and **dimension fields** (axes of variation for cascade resolution). The tables below list Spectrum's foundation-standard fields as declared in the catalog.
31
+
32
+ #### Semantic fields
33
+
34
+ | Field | Status | Taxonomy category | Description |
35
+ | -------------- | -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
36
+ | `property` | REQUIRED | Property | The stylistic attribute being defined (e.g. `color`, `width`, `padding`, `gap`). |
37
+ | `component` | OPTIONAL | Component | Component name when the token is component-scoped. |
38
+ | `structure` | OPTIONAL | Structure | Reusable visual pattern or object category (e.g. `base`, `container`, `list`, `accessory`). Distinct from `component`. |
39
+ | `substructure` | OPTIONAL | Sub-structure | A structure that only exists within its parent structure (e.g. `item` in `list-item`). |
40
+ | `anatomy` | OPTIONAL | Anatomy | A visible, named part of a component as defined by designers (e.g. `handle`, `icon`, `label`). See [Taxonomy — Component anatomy](taxonomy.md#component-anatomy). |
41
+ | `object` | OPTIONAL | Object | Styling surface to which a visual property is applied (e.g. `background`, `border`, `edge`). See [Taxonomy — Token objects](taxonomy.md#token-objects-styling-surfaces). |
42
+ | `variant` | OPTIONAL | Variant | Variant within a component (e.g. `accent`, `negative`, `primary`). |
43
+ | `state` | OPTIONAL | State | Interactive or semantic state (e.g. `hover`, `focus`, `disabled`). |
44
+ | `orientation` | OPTIONAL | Orientation | Direction or order of structures and elements (e.g. `vertical`, `horizontal`). |
45
+ | `position` | OPTIONAL | Position | Location of an object relative to another (e.g. `affixed`). |
46
+ | `size` | OPTIONAL | Size | Relative t-shirt sizing for relationships across tokens (e.g. `small`, `medium`, `large`). |
47
+ | `density` | OPTIONAL | Density | Space within or around component parts (e.g. `spacious`, `compact`). |
48
+ | `shape` | OPTIONAL | Shape | Relative to overall component shape (e.g. `uniform`). |
49
+
50
+ #### Dimension fields
51
+
28
52
  | Field | Status | Description |
29
53
  | --------------- | -------- | ----------------------------------------------------------------------------------------------- |
30
- | `property` | REQUIRED | Stable property key (e.g. semantic role of the token). |
31
- | `component` | OPTIONAL | Component name when the token is component-scoped. |
32
- | `variant` | OPTIONAL | Variant within a component. |
33
- | `state` | OPTIONAL | Interactive or semantic state. |
34
54
  | `colorScheme` | OPTIONAL | Dimension: light / dark / wireframe / etc. |
35
- | `scale` | OPTIONAL | Dimension: t-shirt size or density scale. |
36
- | `contrast` | OPTIONAL | Dimension: contrast level. |
55
+ | `scale` | OPTIONAL | Dimension: platform density scale (e.g. `desktop`, `mobile`). Distinct from semantic `size`. |
56
+ | `contrast` | OPTIONAL | Dimension: contrast level (e.g. `regular`, `high`). |
37
57
  | Additional keys | OPTIONAL | Other dimensions declared in the dataset’s dimension catalog (see [Dimensions](dimensions.md)). |
38
58
 
39
- **RECOMMENDED:** Name objects use a consistent key ordering in authored files for diffs; this is not a conformance requirement.
59
+ **NORMATIVE:** Each field is validated according to the `validation` severity declared in its field declaration. Semantic fields typically use **advisory** severity (warning); dimension fields use **strict** severity (error). See [Taxonomy — Name object field categories](taxonomy.md#name-object-field-categories).
60
+
61
+ **RECOMMENDED:** Name objects use a consistent key ordering in authored files for diffs; this is not a conformance requirement. Concept ordering for serialized names is defined in [Taxonomy — Default serialization](taxonomy.md#default-serialization-legacy-format).
40
62
 
41
63
  ### Alias (`$ref`)
42
64
 
@@ -48,33 +70,106 @@ When **`value`** is present, it **MUST** conform to the declared value type for
48
70
 
49
71
  ### Lifecycle and metadata
50
72
 
51
- The following OPTIONAL fields align with token lifecycle discussions (e.g. [#623](https://github.com/adobe/spectrum-design-data/discussions/623)):
73
+ The following OPTIONAL fields implement the token lifecycle model described in [#623](https://github.com/adobe/spectrum-design-data/discussions/623) and the evolution policy in [Evolution](evolution.md). Inspired by Swift's `@available` attribute, Kotlin's `@Deprecated`, and OpenAPI 3.3's deprecation model.
74
+
75
+ | Field | Type | Description |
76
+ | -------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
77
+ | `uuid` | string (UUID) | Stable unique id for rename tracking and diffs. |
78
+ | `introduced` | string (version) | Spec version when the token was first added (e.g. `"1.0.0"`). |
79
+ | `deprecated` | string (version) | Spec version when the token was deprecated (e.g. `"3.2.0"`). Truthy = deprecated. |
80
+ | `deprecated_comment` | string | Human-readable deprecation explanation and migration guidance. |
81
+ | `replaced_by` | string (UUID) or array of string (UUID) | UUID(s) of the replacement token(s). Single string for 1:1 replacement; array for one-to-many splits. |
82
+ | `plannedRemoval` | string (version) | Spec version when the token will be removed. If omitted, defaults to the next major version after `deprecated`. |
83
+ | `private` | boolean | Not part of public API surface. |
84
+
85
+ #### Lifecycle example
86
+
87
+ ```json
88
+ {
89
+ "name": { "component": "button", "object": "background", "property": "color", "variant": "primary" },
90
+ "value": "#0265dc",
91
+ "uuid": "aaaaaaaa-0001-4000-8000-000000000001",
92
+ "introduced": "1.0.0",
93
+ "deprecated": "3.2.0",
94
+ "deprecated_comment": "Use action-background-default instead.",
95
+ "replaced_by": "bbbbbbbb-0002-4000-8000-000000000001",
96
+ "plannedRemoval": "4.0.0"
97
+ }
98
+ ```
99
+
100
+ #### Normative rules
101
+
102
+ **NORMATIVE:** If `deprecated` is present, `deprecated_comment` **SHOULD** be present.
103
+
104
+ **NORMATIVE:** If `replaced_by` is an array, `deprecated_comment` is **REQUIRED** — the comment **MUST** explain which replacement applies in which context.
105
+
106
+ **NORMATIVE:** If `replaced_by` is present, `deprecated` **MUST** be present.
107
+
108
+ **NORMATIVE:** If `plannedRemoval` is present, `deprecated` **MUST** be present, and the `plannedRemoval` version **MUST NOT** precede the `deprecated` version.
109
+
110
+ **NORMATIVE:** Each UUID in `replaced_by` **MUST** resolve to an existing token in the dataset (see rule `SPEC-010`).
111
+
112
+ #### Legacy format mapping
113
+
114
+ When generating legacy-format output from cascade tokens:
52
115
 
53
- | Field | Type | Description |
54
- | -------------------- | ------------- | ----------------------------------------------- |
55
- | `uuid` | string (UUID) | Stable unique id for rename tracking and diffs. |
56
- | `introduced` | string | Version or date token was introduced. |
57
- | `deprecated` | boolean | Marked deprecated. |
58
- | `deprecated_comment` | string | Human-readable deprecation note. |
59
- | `status` | string | e.g. `experimental`, `stable`. |
60
- | `renamed` | string | Previous name or id if renamed. |
61
- | `private` | boolean | Not part of public API surface. |
116
+ * `deprecated: "3.2.0"` maps to `deprecated: true`
117
+ * `replaced_by: "<uuid>"` maps to `renamed: "<target-token-name>"` (resolved via UUID lookup)
118
+ * `introduced` and `plannedRemoval` have no legacy equivalent and are not emitted
62
119
 
63
- **NORMATIVE:** If `deprecated` is `true`, `deprecated_comment` **SHOULD** be present.
120
+ When migrating legacy-format tokens to cascade:
121
+
122
+ * `deprecated: true` maps to `deprecated: "unknown"` (authors should backfill the actual version)
123
+ * `renamed: "<name>"` maps to `replaced_by: "<uuid>"` (resolved via name lookup across all files in the migrated input set). If the rename target is not found in the scanned corpus, the field is dropped — `replaced_by` must be set manually in that case
64
124
 
65
125
  ### `specVersion`
66
126
 
67
127
  **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.
68
128
 
129
+ ## Document shape
130
+
131
+ 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`).
132
+
133
+ **NORMATIVE:** A cascade file **MUST** be a JSON **array** of token objects. Each element **MUST** conform to [`token.schema.json`](../schemas/token.schema.json).
134
+
135
+ **NORMATIVE:** The array is **ordered**. Document order is used for tie-breaking during cascade resolution (earlier element wins); see [Cascade — Semantic specificity](cascade.md#semantic-specificity).
136
+
137
+ **RECOMMENDED:** A cascade file uses the `.tokens.json` extension to distinguish it from legacy set-format files.
138
+
139
+ Example:
140
+
141
+ ```json
142
+ [
143
+ { "name": { "object": "background", "property": "color" }, "value": "#f5f5f5", "uuid": "..." },
144
+ { "name": { "object": "background", "property": "color", "colorScheme": "dark" }, "value": "#1e1e1e", "uuid": "..." }
145
+ ]
146
+ ```
147
+
69
148
  ## Value types
70
149
 
71
150
  Individual types (color, dimension, opacity, etc.) **MUST** be defined as JSON Schemas under `schemas/value-types/` and **MUST** use `$id` under the same `v0` base path as [Overview — JSON Schema `$id`](index.md).
72
151
 
73
152
  ## Relationship to legacy Spectrum tokens
74
153
 
75
- The current `@adobe/spectrum-tokens` JSON uses **sets** (`color-set`, `scale-set`, …). This specification describes the **target** per-token model. Mapping from legacy to this format is out of scope for this document; see [#723](https://github.com/adobe/spectrum-design-data/issues/723).
154
+ The current `@adobe/spectrum-tokens` JSON uses **sets** (`color-set`, `scale-set`, …). This specification describes the **target** per-token model. Mapping from legacy to this format is out of scope for this document; see [#743](https://github.com/adobe/spectrum-design-data/issues/743).
155
+
156
+ ## Relationship to RFC [#646](https://github.com/adobe/spectrum-design-data/issues/646) token shape
157
+
158
+ [RFC #646](https://github.com/adobe/spectrum-design-data/discussions/646) proposed an analytical token shape during the design process. This spec defines the **canonical serialization format**. The two are related but not identical:
159
+
160
+ | Aspect | RFC [#646](https://github.com/adobe/spectrum-design-data/issues/646) shape | This spec |
161
+ | ------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
162
+ | Identity field | `id` | `uuid` |
163
+ | Name model | `name.original` (string) + `name.structure` (nested object) | Flat fields directly on `name` (`property`, `component`, `colorScheme`, …) |
164
+ | Complexity tracking | `name.semanticComplexity` (stored on token) | Computed at validation time from dimension declarations |
165
+
166
+ **NORMATIVE:** The flat `name` object defined in this spec is the authoritative serialization format. RFC [#646](https://github.com/adobe/spectrum-design-data/issues/646)'s `name.structure` / `name.original` shape is not a conformance target; it remains a useful reference for the analytical model that informed this design.
167
+
168
+ RFC [#646](https://github.com/adobe/spectrum-design-data/issues/646) remains open as a historical reference. It is not superseded; the spec evolved the format during Phase 2 based on implementation experience.
76
169
 
77
170
  ## References
78
171
 
79
172
  * [#646 — Token Schema Structure and Validation System](https://github.com/adobe/spectrum-design-data/discussions/646)
80
173
  * [#623 — Token Lifecycle Metadata](https://github.com/adobe/spectrum-design-data/discussions/623)
174
+ * [#756 — Phase 2: Cascade token file schema](https://github.com/adobe/spectrum-design-data/issues/756)
175
+ * [#759 — Phase 2: Token shape reconciliation](https://github.com/adobe/spectrum-design-data/issues/759)