@adobe/design-data-spec 0.8.0 → 0.10.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 (180) hide show
  1. package/components/accordion.json +18 -1
  2. package/components/action-bar.json +12 -1
  3. package/components/action-button.json +19 -1
  4. package/components/action-group.json +12 -1
  5. package/components/alert-banner.json +11 -1
  6. package/components/alert-dialog.json +19 -1
  7. package/components/avatar-group.json +4 -1
  8. package/components/avatar.json +4 -1
  9. package/components/badge.json +4 -1
  10. package/components/body.json +3 -0
  11. package/components/bottom-navigation-android.json +17 -0
  12. package/components/breadcrumbs.json +19 -2
  13. package/components/button-group.json +12 -1
  14. package/components/button.json +21 -3
  15. package/components/calendar.json +22 -0
  16. package/components/cards.json +18 -1
  17. package/components/checkbox-group.json +17 -1
  18. package/components/checkbox.json +24 -1
  19. package/components/close-button.json +19 -1
  20. package/components/coach-indicator.json +4 -1
  21. package/components/coach-mark.json +13 -1
  22. package/components/code.json +3 -0
  23. package/components/color-area.json +24 -1
  24. package/components/color-handle.json +13 -1
  25. package/components/color-loupe.json +4 -1
  26. package/components/color-slider.json +24 -1
  27. package/components/color-wheel.json +24 -1
  28. package/components/combo-box.json +24 -1
  29. package/components/contextual-help.json +18 -1
  30. package/components/date-picker.json +23 -1
  31. package/components/detail.json +3 -0
  32. package/components/divider.json +4 -1
  33. package/components/drop-zone.json +18 -1
  34. package/components/field-label.json +4 -1
  35. package/components/heading.json +3 -0
  36. package/components/help-text.json +5 -2
  37. package/components/illustrated-message.json +4 -1
  38. package/components/in-field-progress-button.json +18 -0
  39. package/components/in-field-progress-circle.json +4 -1
  40. package/components/in-line-alert.json +11 -1
  41. package/components/link.json +19 -1
  42. package/components/list-view.json +18 -1
  43. package/components/menu.json +19 -1
  44. package/components/meter.json +4 -1
  45. package/components/number-field.json +24 -1
  46. package/components/opacity-checkerboard.json +4 -1
  47. package/components/picker.json +24 -1
  48. package/components/popover.json +12 -1
  49. package/components/progress-bar.json +4 -1
  50. package/components/progress-circle.json +4 -1
  51. package/components/radio-button.json +24 -1
  52. package/components/radio-group.json +17 -1
  53. package/components/rating.json +24 -1
  54. package/components/scroll-zoom-bar.json +12 -0
  55. package/components/search-field.json +28 -1
  56. package/components/segmented-control.json +18 -1
  57. package/components/select-box.json +18 -1
  58. package/components/side-navigation.json +18 -1
  59. package/components/slider.json +24 -1
  60. package/components/standard-dialog.json +19 -1
  61. package/components/standard-panel.json +3 -0
  62. package/components/status-light.json +4 -1
  63. package/components/steplist.json +18 -1
  64. package/components/swatch-group.json +12 -1
  65. package/components/swatch.json +18 -1
  66. package/components/switch.json +19 -1
  67. package/components/tab-bar-ios.json +17 -0
  68. package/components/table.json +23 -1
  69. package/components/tabs.json +18 -1
  70. package/components/tag-field.json +18 -1
  71. package/components/tag-group.json +18 -1
  72. package/components/tag.json +18 -1
  73. package/components/takeover-dialog.json +19 -1
  74. package/components/text-area.json +28 -1
  75. package/components/text-field.json +28 -1
  76. package/components/thumbnail.json +4 -1
  77. package/components/title.json +40 -10
  78. package/components/toast.json +13 -1
  79. package/components/tooltip.json +17 -1
  80. package/components/tray.json +11 -0
  81. package/components/tree-view.json +19 -1
  82. package/conformance/README.md +7 -7
  83. package/conformance/invalid/SPEC-001/dataset.json +10 -0
  84. package/conformance/invalid/SPEC-001/expected-errors.json +1 -1
  85. package/conformance/invalid/SPEC-002/dataset.json +16 -0
  86. package/conformance/invalid/SPEC-002/expected-errors.json +1 -1
  87. package/conformance/invalid/SPEC-003/dataset.json +15 -0
  88. package/conformance/invalid/SPEC-003/expected-errors.json +1 -1
  89. package/conformance/invalid/SPEC-004/dataset.json +15 -0
  90. package/conformance/invalid/SPEC-004/expected-errors.json +1 -1
  91. package/conformance/invalid/SPEC-005/dataset.json +11 -0
  92. package/conformance/invalid/SPEC-005/expected-errors.json +1 -1
  93. package/conformance/invalid/SPEC-006/dataset.json +15 -0
  94. package/conformance/invalid/SPEC-006/expected-errors.json +1 -1
  95. package/conformance/invalid/SPEC-007/dataset.json +9 -0
  96. package/conformance/invalid/SPEC-007/expected-errors.json +10 -0
  97. package/conformance/invalid/SPEC-008/dataset.json +25 -0
  98. package/conformance/invalid/SPEC-008/expected-errors.json +2 -1
  99. package/conformance/invalid/SPEC-009/dataset.json +12 -0
  100. package/conformance/invalid/SPEC-009/expected-errors.json +10 -0
  101. package/conformance/invalid/SPEC-010/dataset.json +12 -0
  102. package/conformance/invalid/SPEC-011/dataset.json +25 -0
  103. package/conformance/invalid/SPEC-012/dataset.json +16 -0
  104. package/conformance/invalid/SPEC-013/dataset.json +11 -0
  105. package/conformance/invalid/SPEC-014/dataset.json +12 -0
  106. package/conformance/invalid/SPEC-014/expected-errors.json +1 -1
  107. package/conformance/invalid/SPEC-015/dataset.json +22 -0
  108. package/conformance/invalid/SPEC-015/expected-errors.json +10 -0
  109. package/conformance/invalid/SPEC-015/tokens.tokens.json +19 -0
  110. package/conformance/invalid/SPEC-016/dataset.json +11 -0
  111. package/conformance/invalid/SPEC-016/expected-errors.json +2 -2
  112. package/conformance/invalid/SPEC-017/dataset.json +10 -0
  113. package/conformance/invalid/SPEC-024/dataset.json +4 -3
  114. package/conformance/invalid/SPEC-024/expected-errors.json +2 -2
  115. package/conformance/invalid/SPEC-025/dataset.json +12 -0
  116. package/conformance/invalid/SPEC-025/expected-errors.json +10 -0
  117. package/conformance/invalid/SPEC-026/dataset.json +18 -0
  118. package/conformance/invalid/SPEC-026/expected-errors.json +10 -0
  119. package/conformance/invalid/SPEC-028/dataset.json +21 -0
  120. package/conformance/invalid/SPEC-028/expected-errors.json +10 -0
  121. package/conformance/invalid/SPEC-029/dataset.json +20 -0
  122. package/conformance/invalid/SPEC-029/expected-errors.json +10 -0
  123. package/conformance/invalid/SPEC-030/dataset.json +15 -0
  124. package/conformance/invalid/SPEC-030/expected-errors.json +10 -0
  125. package/conformance/invalid/SPEC-031/dataset.json +17 -0
  126. package/conformance/invalid/SPEC-031/expected-errors.json +10 -0
  127. package/conformance/invalid/SPEC-032/dataset.json +27 -0
  128. package/conformance/invalid/SPEC-032/expected-errors.json +15 -0
  129. package/conformance/resolution/base-fallback/expected.json +1 -1
  130. package/conformance/resolution/product-layer-wins/expected.json +5 -0
  131. package/conformance/resolution/product-layer-wins/input/tokens.tokens.json +7 -0
  132. package/conformance/resolution/product-layer-wins/product-context.json +11 -0
  133. package/conformance/resolution/product-layer-wins/query.json +4 -0
  134. package/conformance/resolution/specificity-wins/expected.json +1 -1
  135. package/conformance/valid/SPEC-014/dataset.json +12 -0
  136. package/conformance/valid/SPEC-016/dataset.json +16 -0
  137. package/conformance/valid/SPEC-025/dataset.json +24 -0
  138. package/conformance/valid/SPEC-026/dataset.json +15 -0
  139. package/conformance/valid/SPEC-028/dataset.json +21 -0
  140. package/conformance/valid/SPEC-029/dataset.json +24 -0
  141. package/conformance/valid/SPEC-030/dataset.json +17 -0
  142. package/conformance/valid/SPEC-031/dataset.json +24 -0
  143. package/conformance/valid/SPEC-032/dataset.json +16 -0
  144. package/conformance/valid/component-refs/README.md +5 -0
  145. package/conformance/valid/component-with-accessibility.json +32 -0
  146. package/fields/color-scheme.json +2 -2
  147. package/fields/contrast.json +2 -2
  148. package/fields/density.json +1 -1
  149. package/fields/scale.json +2 -2
  150. package/fields/size.json +1 -1
  151. package/package.json +4 -13
  152. package/rules/rules.yaml +40 -4
  153. package/schemas/accessibility.schema.json +60 -0
  154. package/schemas/component.schema.json +19 -0
  155. package/schemas/field.schema.json +2 -2
  156. package/schemas/manifest.schema.json +1 -1
  157. package/schemas/{dimension.schema.json → mode-set.schema.json} +3 -3
  158. package/schemas/token.schema.json +5 -5
  159. package/schemas/value-types/README.md +20 -0
  160. package/schemas/value-types/drop-shadow.schema.json +5 -5
  161. package/schemas/value-types/typography-scale.schema.json +2 -2
  162. package/schemas/value-types/typography.schema.json +5 -5
  163. package/spec/accessibility-adapters.md +219 -0
  164. package/spec/accessibility.md +219 -0
  165. package/spec/agent-surface.md +4 -4
  166. package/spec/cascade.md +7 -7
  167. package/spec/component-format.md +32 -0
  168. package/spec/document-blocks.md +1 -1
  169. package/spec/index.md +28 -20
  170. package/spec/manifest.md +2 -2
  171. package/spec/mode-sets.md +64 -0
  172. package/spec/query.md +18 -18
  173. package/spec/taxonomy.md +5 -5
  174. package/spec/token-format.md +12 -12
  175. package/spec/dimensions.md +0 -64
  176. package/src/canonical.js +0 -61
  177. package/src/validate.js +0 -190
  178. /package/conformance/resolution/alias-resolved-after-cascade/{dimensions → mode-sets}/color-scheme.json +0 -0
  179. /package/conformance/resolution/base-fallback/{dimensions → mode-sets}/color-scheme.json +0 -0
  180. /package/conformance/resolution/specificity-wins/{dimensions → mode-sets}/color-scheme.json +0 -0
package/spec/index.md CHANGED
@@ -3,7 +3,7 @@
3
3
  **Version:** `1.0.0-draft`\
4
4
  **Status:** Draft — normative text and schemas may change before `1.0.0`.
5
5
 
6
- This document is the top-level overview for the **Design Data Specification**: a machine-readable model for Spectrum design tokens, dimensions, platform manifests, and validation.
6
+ This document is the top-level overview for the **Design Data Specification**: a machine-readable model for Spectrum design tokens, mode sets, platform manifests, and validation.
7
7
 
8
8
  ## Scope
9
9
 
@@ -12,14 +12,18 @@ The specification defines:
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
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)).
15
+ * **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
+ * **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
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)).
18
+ 5. **Mode Sets** — declared modes, defaults, and coverage expectations ([Mode Sets](mode-sets.md)).
19
19
  6. **Platform manifest** — how a platform repo pins foundation data, filters tokens, and applies typed overrides ([Manifest](manifest.md)).
20
20
  7. **Semantic diff** — change taxonomy, token identity rules, and property-level change tracking for comparing dataset versions ([Diff](diff.md)).
21
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)).
22
+ 9. **Accessibility** — component accessibility vocabulary: semantic role, interaction and keyboard intents, focus behavior, WCAG criteria, and state-level AT fields ([Accessibility](accessibility.md)).
23
+ * **Accessibility adapters** — informative platform adapter contracts: Web/ARIA, iOS UIAccessibility, Android AccessibilityNodeInfo, and voice/multimodal ([Accessibility adapters](accessibility-adapters.md)).
24
+ 10. **Document blocks** — typed prose blocks attachable to tokens, components, and anatomy parts; makes design guidance machine-readable and agent-queryable ([Document blocks](document-blocks.md)).
25
+ 11. **Agent-readable surface** — operations and transport contracts (CLI, MCP server, Agent Skill) for AI agents consuming spec-conformant design data; covers session primer, token resolution, validation, query, and component description ([Agent-readable surface](agent-surface.md)).
26
+ 12. **Evolution** — deprecation lifecycle, migration windows, change classification, and legacy format contract ([Evolution](evolution.md)).
23
27
 
24
28
  ## Conformance
25
29
 
@@ -53,27 +57,31 @@ Full governance (compatibility tiers, migration, CLI `--spec-version`) is discus
53
57
 
54
58
  ## Normative references (sibling documents)
55
59
 
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
- | [Product context](product-context.md) | Product-layer context document: rationale, overrides, and extensions. |
67
- | [Diff](diff.md) | Semantic diff change taxonomy, token identity, property changes. |
68
- | [Query](query.md) | Filter notation for selecting tokens by structured fields. |
69
- | [Evolution](evolution.md) | Deprecation lifecycle, migration windows, change classification. |
60
+ | Document | Role |
61
+ | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
62
+ | [Token format](token-format.md) | Token `name`, `value` / `$ref`, value types, lifecycle metadata. |
63
+ | [Taxonomy](taxonomy.md) | Concept categories, vocabulary, formatting, anatomy vs objects. |
64
+ | [Component format](component-format.md) | Component declaration: options, slots, anatomy (→ anatomy-format.md), states (→ state-model.md), lifecycle. |
65
+ | [Anatomy format](anatomy-format.md) | Anatomy part declarations: field constraints, canonical vocabulary, SPEC-020/SPEC-023/SPEC-024/SPEC-025. |
66
+ | [State model](state-model.md) | State declarations: trigger semantics, precedence algorithm, canonical vocabulary, SPEC-022/SPEC-026. |
67
+ | [Cascade](cascade.md) | Layers, specificity, resolution algorithm. |
68
+ | [Mode Sets](mode-sets.md) | Mode set declarations, built-in mode sets, coverage. |
69
+ | [Manifest](manifest.md) | Platform manifest fields and validation expectations. |
70
+ | [Product context](product-context.md) | Product-layer context document: rationale, overrides, and extensions. |
71
+ | [Diff](diff.md) | Semantic diff change taxonomy, token identity, property changes. |
72
+ | [Query](query.md) | Filter notation for selecting tokens by structured fields. |
73
+ | [Accessibility](accessibility.md) | Component accessibility vocabulary: role, intents, focusable, keyboardIntents, wcag, and state-level AT fields (SPEC-030/031). |
74
+ | [Accessibility adapters](accessibility-adapters.md) | Informative platform adapter contracts mapping foundation accessibility vocabulary to Web/ARIA, iOS, Android, and voice surfaces. |
75
+ | [Document blocks](document-blocks.md) | Typed prose blocks (purpose, guideline, accessibility, do-dont, examples) attachable to any entity. |
76
+ | [Agent-readable surface](agent-surface.md) | Transport contracts (CLI, MCP, Agent Skill) and operation catalog for AI agents consuming spec-conformant design data. |
77
+ | [Evolution](evolution.md) | Deprecation lifecycle, migration windows, change classification. |
70
78
 
71
79
  ## JSON Schema `$id` and versioning
72
80
 
73
81
  **NORMATIVE:** Canonical schema documents use **versioned path** `$id` URIs so major revisions can coexist on the documentation host:
74
82
 
75
83
  * Base: `https://opensource.adobe.com/spectrum-design-data/schemas/v0/`
76
- * Examples: `.../v0/token.schema.json`, `.../v0/dimension.schema.json`, `.../v0/manifest.schema.json`
84
+ * Examples: `.../v0/token.schema.json`, `.../v0/mode-set.schema.json`, `.../v0/manifest.schema.json`
77
85
 
78
86
  The **`v0`** segment denotes the **draft / pre-1.0** schema family aligned with spec version `1.0.0-draft`. A future **1.0.0** stable release MAY introduce `v1` paths without reusing `v0` URLs for incompatible shapes.
79
87
 
package/spec/manifest.md CHANGED
@@ -22,7 +22,7 @@ A manifest **MUST** conform to [`manifest.schema.json`](../schemas/manifest.sche
22
22
  | `include` | array of string | Semantic **queries** selecting subsets of foundation tokens to materialize. |
23
23
  | `exclude` | array of string | Queries removing tokens from the included set. |
24
24
  | `overrides` | array of object | Typed overrides; each entry **MUST** preserve the target token’s **value type**. |
25
- | `extensions` | object | New tokens or dimensions introduced at the platform layer. |
25
+ | `extensions` | object | New tokens or mode sets introduced at the platform layer. |
26
26
 
27
27
  ### `include` / `exclude`
28
28
 
@@ -38,7 +38,7 @@ Each override object **MUST** include enough information to identify a target to
38
38
 
39
39
  ### `extensions`
40
40
 
41
- **RECOMMENDED:** `extensions` follows the same structural conventions as foundation token files (tokens, dimensions) and **SHOULD** be validated with the same Layer 1 and Layer 2 rules.
41
+ **RECOMMENDED:** `extensions` follows the same structural conventions as foundation token files (tokens, mode sets) and **SHOULD** be validated with the same Layer 1 and Layer 2 rules.
42
42
 
43
43
  #### `extensions.formatting`
44
44
 
@@ -0,0 +1,64 @@
1
+ # Mode Sets
2
+
3
+ **Spec version:** `1.0.0-draft` (see [Overview](index.md))
4
+
5
+ This document defines how **mode sets** (axes such as color scheme, scale, contrast) are **declared**, assigned **defaults**, and validated for **coverage**.
6
+
7
+ ## Mode Set declaration
8
+
9
+ A **mode set declaration** is a JSON object describing one axis of variation. It **MUST** conform to [`mode-set.schema.json`](../schemas/mode-set.schema.json) (canonical `$id`: `https://opensource.adobe.com/spectrum-design-data/schemas/v0/mode-set.schema.json`).
10
+
11
+ ### Required fields
12
+
13
+ | Field | Description |
14
+ | --------- | -------------------------------------------------------- |
15
+ | `name` | Stable identifier for the mode set (e.g. `colorScheme`). |
16
+ | `modes` | Array of allowed mode values (strings). |
17
+ | `default` | Default mode; **MUST** be a member of `modes`. |
18
+
19
+ ### Optional fields
20
+
21
+ | Field | Description |
22
+ | ------------- | ------------------------------------ |
23
+ | `description` | Human-readable documentation. |
24
+ | `coverage` | Rules for mode coverage (see below). |
25
+
26
+ ## Built-in mode sets
27
+
28
+ These mode sets are declared in the `mode-sets/` catalog (see [Mode Set catalog](#mode-set-catalog)) and **SHOULD** be used consistently across Spectrum-compatible datasets:
29
+
30
+ | `name` | `modes` | `default` | Notes |
31
+ | ------------- | ---------------------------- | --------- | --------------------------------------------------------------------------------- |
32
+ | `colorScheme` | `light`, `dark`, `wireframe` | `light` | Theme / appearance. |
33
+ | `scale` | `desktop`, `mobile` | `desktop` | Density scale. Legacy names; desktop = medium, mobile = large in W3C terminology. |
34
+ | `contrast` | `regular`, `high` | `regular` | Accessibility contrast level. |
35
+
36
+ ## Mode Set catalog
37
+
38
+ The Spectrum foundation publishes mode set declarations as JSON files under `packages/design-data-spec/mode-sets/`. Each file conforms to [`mode-set.schema.json`](../schemas/mode-set.schema.json).
39
+
40
+ **NORMATIVE:** Tooling (validators, resolution engine) **MUST** load mode set declarations from the dataset's mode set catalog before performing specificity calculations or coverage validation.
41
+
42
+ **RECOMMENDED:** The catalog directory is named `mode-sets/` and is co-located with the dataset's spec package or manifest.
43
+
44
+ ## Optional mode sets
45
+
46
+ Additional mode sets (e.g. `language`, `motion`) **MAY** be declared in a dataset's mode set catalog. Token name objects **MAY** include keys matching declared mode set names.
47
+
48
+ ## Defaults and specificity
49
+
50
+ **NORMATIVE:** A token name object **omitting** a mode set field implies the token applies under the mode set's **`default`** mode for specificity and matching purposes unless the spec for that mode set states otherwise.
51
+
52
+ **NORMATIVE:** Only **non-default** mode set fields on the name object increase **semantic specificity** (see [Cascade](cascade.md)).
53
+
54
+ ## Coverage validation
55
+
56
+ **RECOMMENDED:** If a mode set's `coverage` requires **peer modes** (e.g. defining `dark` requires `light`), validators implement rule **`SPEC-005`** (see `rules/rules.yaml`).
57
+
58
+ **RECOMMENDED:** Explicit **combination** tokens are used for rare cross-mode-set cases instead of inferring Cartesian products.
59
+
60
+ ## References
61
+
62
+ * [#646 — Token Schema Structure and Validation System](https://github.com/adobe/spectrum-design-data/discussions/646)
63
+ * [#714 — Design Data Specification](https://github.com/adobe/spectrum-design-data/discussions/714)
64
+ * [#746 — Phase 2: Mode Set declarations (machine-readable)](https://github.com/adobe/spectrum-design-data/issues/746)
package/spec/query.md CHANGED
@@ -8,29 +8,29 @@ This document defines the **query filter notation**: a concise syntax for select
8
8
 
9
9
  A **filter expression** is a string that describes a set of conditions a token must satisfy to be included in the result. The notation uses `key=value` pairs combined with logical operators.
10
10
 
11
- | Operator | Syntax | Meaning |
12
- | -------- | ---------------- | ------------------------------------------------------- |
13
- | `=` | `key=value` | Field `key` equals `value`. |
14
- | `!=` | `key!=value` | Field `key` does not equal `value`. |
15
- | `,` | `a=x,b=y` | Logical AND — both conditions must match. |
16
- | `\|` | `a=x\|b=y` | Logical OR — at least one condition must match. |
17
- | `*` | `key=patt*ern` | Glob wildcard — `*` matches zero or more characters. |
11
+ | Operator | Syntax | Meaning |
12
+ | -------- | -------------- | ---------------------------------------------------- |
13
+ | `=` | `key=value` | Field `key` equals `value`. |
14
+ | `!=` | `key!=value` | Field `key` does not equal `value`. |
15
+ | `,` | `a=x,b=y` | Logical AND — both conditions must match. |
16
+ | `\|` | `a=x\|b=y` | Logical OR — at least one condition must match. |
17
+ | `*` | `key=patt*ern` | Glob wildcard — `*` matches zero or more characters. |
18
18
 
19
19
  ## Supported keys
20
20
 
21
21
  **NORMATIVE:** Implementations **MUST** support the following keys:
22
22
 
23
- | Key | Source | Description |
24
- | ---------------- | --------------------------- | ------------------------------------------------ |
25
- | `property` | `name.property` | Token property identifier. |
26
- | `component` | `name.component` | Associated component name. |
27
- | `variant` | `name.variant` | Component variant. |
28
- | `state` | `name.state` | Component or interaction state. |
29
- | `colorScheme` | `name.colorScheme` | Color scheme dimension value. |
30
- | `scale` | `name.scale` | Scale dimension value. |
31
- | `contrast` | `name.contrast` | Contrast dimension value. |
32
- | `uuid` | `uuid` | Token UUID (top-level field). |
33
- | `$schema` | `$schema` | Token schema URL (top-level field). |
23
+ | Key | Source | Description |
24
+ | ------------- | ------------------ | ----------------------------------- |
25
+ | `property` | `name.property` | Token property identifier. |
26
+ | `component` | `name.component` | Associated component name. |
27
+ | `variant` | `name.variant` | Component variant. |
28
+ | `state` | `name.state` | Component or interaction state. |
29
+ | `colorScheme` | `name.colorScheme` | Color scheme mode set value. |
30
+ | `scale` | `name.scale` | Scale mode set value. |
31
+ | `contrast` | `name.contrast` | Contrast mode set value. |
32
+ | `uuid` | `uuid` | Token UUID (top-level field). |
33
+ | `$schema` | `$schema` | Token schema URL (top-level field). |
34
34
 
35
35
  **NORMATIVE:** Implementations **MUST** reject filter expressions containing keys not listed above with a parse error. Future spec versions MAY add keys.
36
36
 
package/spec/taxonomy.md CHANGED
@@ -139,15 +139,15 @@ Semantic fields describe identity, structure, and intent. They are used for quer
139
139
 
140
140
  Semantic fields are those declared with `kind: "semantic"` in the field catalog. In Spectrum's foundation catalog, these are: `structure`, `substructure`, `component`, `anatomy`, `object`, `property`, `variant`, `state`, `orientation`, `position`, `size`, `density`, `shape`.
141
141
 
142
- ### Dimension fields
142
+ ### Mode-set fields
143
143
 
144
- Dimension fields represent axes of variation that drive the [cascade](cascade.md) resolution algorithm and [specificity](cascade.md#semantic-specificity) calculation.
144
+ Mode-set fields represent axes of variation that drive the [cascade](cascade.md) resolution algorithm and [specificity](cascade.md#semantic-specificity) calculation.
145
145
 
146
- **NORMATIVE:** Dimension field values are validated against declared [dimension](dimensions.md) modes with **strict** severity (error). An invalid mode value would silently fail to match any context during cascade resolution.
146
+ **NORMATIVE:** Mode-set field values are validated against declared [mode set](mode-sets.md) modes with **strict** severity (error). An invalid mode value would silently fail to match any context during cascade resolution.
147
147
 
148
- Dimension fields are those declared with `kind: "dimension"` in the field catalog, plus any additional dimension keys from the dataset's [dimension declarations](dimensions.md). In Spectrum's foundation catalog, the standard dimension fields are: `colorScheme`, `scale`, `contrast`.
148
+ Mode-set fields are those declared with `kind: "mode-set"` in the field catalog, plus any additional mode set keys from the dataset's [mode set declarations](mode-sets.md). In Spectrum's foundation catalog, the standard mode-set fields are: `colorScheme`, `scale`, `contrast`.
149
149
 
150
- See [Dimensions](dimensions.md) for dimension declarations, modes, and defaults.
150
+ See [Mode Sets](mode-sets.md) for mode set declarations, modes, and defaults.
151
151
 
152
152
  ## Default serialization (legacy format)
153
153
 
@@ -35,7 +35,7 @@ A token's `name` field **MAY** be a non-empty plain string instead of a name obj
35
35
 
36
36
  **NORMATIVE:** String-named tokens **MUST** trigger rule SPEC-017 (severity: `warning`, category: `tech-debt`). The warning surfaces the token as tracked debt requiring future remediation.
37
37
 
38
- **NORMATIVE:** String-named tokens **MUST NOT** participate in name-object cascade dimension matching, specificity calculation, or registry vocabulary checks (SPEC-009 does not apply).
38
+ **NORMATIVE:** String-named tokens **MUST NOT** participate in name-object cascade mode-set matching, specificity calculation, or registry vocabulary checks (SPEC-009 does not apply).
39
39
 
40
40
  **RECOMMENDED:** Authors **SHOULD** treat string names as a temporary escape hatch and track a remediation plan. Each string-named token **SHOULD** eventually be given a structured name object, at which point SPEC-017 no longer fires.
41
41
 
@@ -45,9 +45,9 @@ The **name object** identifies the token in a structured way. Implementations us
45
45
 
46
46
  **NORMATIVE fields** (all string unless noted):
47
47
 
48
- 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.
48
+ 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 `mode-set`), 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.
49
49
 
50
- 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.
50
+ Fields are divided into **semantic fields** (identity, structure, intent) and **mode-set fields** (axes of variation for cascade resolution). The tables below list Spectrum's foundation-standard fields as declared in the catalog.
51
51
 
52
52
  #### Semantic fields
53
53
 
@@ -67,16 +67,16 @@ Fields are divided into **semantic fields** (identity, structure, intent) and **
67
67
  | `density` | OPTIONAL | Density | Space within or around component parts (e.g. `spacious`, `compact`). |
68
68
  | `shape` | OPTIONAL | Shape | Relative to overall component shape (e.g. `uniform`). |
69
69
 
70
- #### Dimension fields
70
+ #### Mode-set fields
71
71
 
72
- | Field | Status | Description |
73
- | --------------- | -------- | ----------------------------------------------------------------------------------------------- |
74
- | `colorScheme` | OPTIONAL | Dimension: light / dark / wireframe / etc. |
75
- | `scale` | OPTIONAL | Dimension: platform density scale (e.g. `desktop`, `mobile`). Distinct from semantic `size`. |
76
- | `contrast` | OPTIONAL | Dimension: contrast level (e.g. `regular`, `high`). |
77
- | Additional keys | OPTIONAL | Other dimensions declared in the dataset’s dimension catalog (see [Dimensions](dimensions.md)). |
72
+ | Field | Status | Description |
73
+ | --------------- | -------- | ------------------------------------------------------------------------------------------- |
74
+ | `colorScheme` | OPTIONAL | Mode set: light / dark / wireframe / etc. |
75
+ | `scale` | OPTIONAL | Mode set: platform density scale (e.g. `desktop`, `mobile`). Distinct from semantic `size`. |
76
+ | `contrast` | OPTIONAL | Mode set: contrast level (e.g. `regular`, `high`). |
77
+ | Additional keys | OPTIONAL | Other mode sets declared in the dataset’s mode set catalog (see [Mode Sets](mode-sets.md)). |
78
78
 
79
- **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).
79
+ **NORMATIVE:** Each field is validated according to the `validation` severity declared in its field declaration. Semantic fields typically use **advisory** severity (warning); mode-set fields use **strict** severity (error). See [Taxonomy — Name object field categories](taxonomy.md#name-object-field-categories).
80
80
 
81
81
  **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).
82
82
 
@@ -249,7 +249,7 @@ The current `@adobe/spectrum-tokens` JSON uses **sets** (`color-set`, `scale-set
249
249
  | ------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
250
250
  | Identity field | `id` | `uuid` |
251
251
  | Name model | `name.original` (string) + `name.structure` (nested object) | Flat fields directly on `name` (`property`, `component`, `colorScheme`, …) |
252
- | Complexity tracking | `name.semanticComplexity` (stored on token) | Computed at validation time from dimension declarations |
252
+ | Complexity tracking | `name.semanticComplexity` (stored on token) | Computed at validation time from mode set declarations |
253
253
 
254
254
  **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.
255
255
 
@@ -1,64 +0,0 @@
1
- # Dimensions
2
-
3
- **Spec version:** `1.0.0-draft` (see [Overview](index.md))
4
-
5
- This document defines how **dimensions** (modes such as color scheme, scale, contrast) are **declared**, assigned **defaults**, and validated for **coverage**.
6
-
7
- ## Dimension declaration
8
-
9
- A **dimension declaration** is a JSON object describing one axis of variation. It **MUST** conform to [`dimension.schema.json`](../schemas/dimension.schema.json) (canonical `$id`: `https://opensource.adobe.com/spectrum-design-data/schemas/v0/dimension.schema.json`).
10
-
11
- ### Required fields
12
-
13
- | Field | Description |
14
- | --------- | --------------------------------------------------------- |
15
- | `name` | Stable identifier for the dimension (e.g. `colorScheme`). |
16
- | `modes` | Array of allowed mode values (strings). |
17
- | `default` | Default mode; **MUST** be a member of `modes`. |
18
-
19
- ### Optional fields
20
-
21
- | Field | Description |
22
- | ------------- | ------------------------------------ |
23
- | `description` | Human-readable documentation. |
24
- | `coverage` | Rules for mode coverage (see below). |
25
-
26
- ## Built-in dimensions
27
-
28
- These dimensions are declared in the `dimensions/` catalog (see [Dimension catalog](#dimension-catalog)) and **SHOULD** be used consistently across Spectrum-compatible datasets:
29
-
30
- | `name` | `modes` | `default` | Notes |
31
- | ------------- | ---------------------------- | --------- | --------------------------------------------------------------------------------- |
32
- | `colorScheme` | `light`, `dark`, `wireframe` | `light` | Theme / appearance. |
33
- | `scale` | `desktop`, `mobile` | `desktop` | Density scale. Legacy names; desktop = medium, mobile = large in W3C terminology. |
34
- | `contrast` | `regular`, `high` | `regular` | Accessibility contrast level. |
35
-
36
- ## Dimension catalog
37
-
38
- The Spectrum foundation publishes dimension declarations as JSON files under `packages/design-data-spec/dimensions/`. Each file conforms to [`dimension.schema.json`](../schemas/dimension.schema.json).
39
-
40
- **NORMATIVE:** Tooling (validators, resolution engine) **MUST** load dimension declarations from the dataset’s dimension catalog before performing specificity calculations or coverage validation.
41
-
42
- **RECOMMENDED:** The catalog directory is named `dimensions/` and is co-located with the dataset’s spec package or manifest.
43
-
44
- ## Optional dimensions
45
-
46
- Additional dimensions (e.g. `language`, `motion`) **MAY** be declared in a dataset’s dimension catalog. Token name objects **MAY** include keys matching declared dimension names.
47
-
48
- ## Defaults and specificity
49
-
50
- **NORMATIVE:** A token name object **omitting** a dimension field implies the token applies under the dimension’s **`default`** mode for specificity and matching purposes unless the spec for that dimension states otherwise.
51
-
52
- **NORMATIVE:** Only **non-default** dimension fields on the name object increase **semantic specificity** (see [Cascade](cascade.md)).
53
-
54
- ## Coverage validation
55
-
56
- **RECOMMENDED:** If a dimension’s `coverage` requires **peer modes** (e.g. defining `dark` requires `light`), validators implement rule **`SPEC-005`** (see `rules/rules.yaml`).
57
-
58
- **RECOMMENDED:** Explicit **combination** tokens are used for rare cross-dimensional cases instead of inferring Cartesian products.
59
-
60
- ## References
61
-
62
- * [#646 — Token Schema Structure and Validation System](https://github.com/adobe/spectrum-design-data/discussions/646)
63
- * [#714 — Design Data Specification](https://github.com/adobe/spectrum-design-data/discussions/714)
64
- * [#746 — Phase 2: Dimension declarations (machine-readable)](https://github.com/adobe/spectrum-design-data/issues/746)
package/src/canonical.js DELETED
@@ -1,61 +0,0 @@
1
- /*
2
- Copyright 2026 Adobe. All rights reserved.
3
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License. You may obtain a copy
5
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6
-
7
- Unless required by applicable law or agreed to in writing, software distributed under
8
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- OF ANY KIND, either express or implied. See the License for the specific language
10
- governing permissions and limitations under the License.
11
- */
12
-
13
- // Canonical vocabulary sets derived from spec chapters.
14
- // Sources: spec/component-format.md, spec/anatomy-format.md, spec/state-model.md
15
-
16
- export const CANONICAL_SLOTS = new Set([
17
- "default",
18
- "icon",
19
- "label",
20
- "help-text",
21
- "negative-help-text",
22
- "action",
23
- "heading",
24
- "description",
25
- "hero",
26
- "footer",
27
- "tooltip",
28
- ]);
29
-
30
- export const CANONICAL_ANATOMY_PARTS = new Set([
31
- "body",
32
- "checkmark",
33
- "disclosure-triangle",
34
- "field",
35
- "handle",
36
- "header",
37
- "icon",
38
- "label",
39
- "picker",
40
- "progress-bar",
41
- "swatch",
42
- "thumbnail",
43
- "track",
44
- "value",
45
- ]);
46
-
47
- export const CANONICAL_STATES = new Set([
48
- "default",
49
- "hover",
50
- "focus",
51
- "focus-visible",
52
- "active",
53
- "pressed",
54
- "selected",
55
- "indeterminate",
56
- "disabled",
57
- "read-only",
58
- "invalid",
59
- "valid",
60
- "dragging",
61
- ]);
package/src/validate.js DELETED
@@ -1,190 +0,0 @@
1
- /*
2
- Copyright 2026 Adobe. All rights reserved.
3
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License. You may obtain a copy
5
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6
-
7
- Unless required by applicable law or agreed to in writing, software distributed under
8
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- OF ANY KIND, either express or implied. See the License for the specific language
10
- governing permissions and limitations under the License.
11
- */
12
-
13
- /**
14
- * Layer 2 cross-reference validator for design-data-spec.
15
- *
16
- * Implements SPEC-018 through SPEC-027: semantic rules that validate token
17
- * name-object fields against component declarations, validate component
18
- * declarations internally, and validate tokenBindings references.
19
- *
20
- * @see spec/component-format.md#spec-rules
21
- * @see spec/anatomy-format.md#spec-rules
22
- * @see spec/state-model.md#spec-rules
23
- */
24
-
25
- import {
26
- CANONICAL_SLOTS,
27
- CANONICAL_ANATOMY_PARTS,
28
- CANONICAL_STATES,
29
- } from "./canonical.js";
30
-
31
- /**
32
- * @typedef {{ ruleId: string, severity: 'error'|'warning', message: string, tokenName?: string, componentName?: string }} Diagnostic
33
- * @typedef {{ name: string|object, [key: string]: unknown }} Token
34
- * @typedef {{ name: string, options?: object, anatomy?: Array<{name:string,description?:string}>, slots?: Array<{name:string,description?:string}>, states?: Array<{name:string,trigger?:string,precedence?:number,layered?:boolean,description?:string}> }} ComponentDeclaration
35
- * @typedef {{ tokens?: Token[], components?: ComponentDeclaration[] }} Dataset
36
- */
37
-
38
- /**
39
- * Validate a dataset for SPEC-018 through SPEC-024 compliance.
40
- *
41
- * @param {Dataset} dataset
42
- * @returns {Diagnostic[]}
43
- */
44
- export function validateDataset(dataset) {
45
- const tokens = dataset.tokens ?? [];
46
- const components = dataset.components ?? [];
47
-
48
- // Build component lookup map keyed by name.
49
- const componentMap = new Map(components.map((c) => [c.name, c]));
50
-
51
- const diagnostics = [];
52
-
53
- // --- Token cross-reference rules ---
54
- for (const token of tokens) {
55
- const name = token.name;
56
- // String names (SPEC-017 escape hatch) skip cross-reference checks.
57
- if (typeof name !== "object" || name === null) continue;
58
-
59
- const tokenLabel = JSON.stringify(name);
60
-
61
- if (name.component != null) {
62
- // SPEC-018: component name must be declared
63
- if (!componentMap.has(name.component)) {
64
- diagnostics.push({
65
- ruleId: "SPEC-018",
66
- severity: "error",
67
- message: `Token '${tokenLabel}' references undeclared component '${name.component}'`,
68
- tokenName: tokenLabel,
69
- });
70
- // Can't validate further fields without a component declaration.
71
- continue;
72
- }
73
-
74
- const component = componentMap.get(name.component);
75
-
76
- // SPEC-019: variant must be in component's variant option enum
77
- if (name.variant != null) {
78
- const variantEnum = component.options?.variant?.enum;
79
- if (Array.isArray(variantEnum) && !variantEnum.includes(name.variant)) {
80
- diagnostics.push({
81
- ruleId: "SPEC-019",
82
- severity: "error",
83
- message: `Token '${tokenLabel}' has variant '${name.variant}' which is not declared on component '${name.component}'`,
84
- tokenName: tokenLabel,
85
- componentName: name.component,
86
- });
87
- }
88
- }
89
-
90
- // SPEC-020: anatomy must match a declared anatomy part name
91
- if (name.anatomy != null) {
92
- const declaredParts = new Set(
93
- (component.anatomy ?? []).map((p) => p.name),
94
- );
95
- if (declaredParts.size > 0 && !declaredParts.has(name.anatomy)) {
96
- diagnostics.push({
97
- ruleId: "SPEC-020",
98
- severity: "error",
99
- message: `Token '${tokenLabel}' references undeclared anatomy part '${name.anatomy}' on component '${name.component}'`,
100
- tokenName: tokenLabel,
101
- componentName: name.component,
102
- });
103
- }
104
- }
105
-
106
- // SPEC-022: state must match a declared state name (only when states are declared)
107
- if (name.state != null) {
108
- const declaredStates = new Set(
109
- (component.states ?? []).map((s) => s.name),
110
- );
111
- if (declaredStates.size > 0 && !declaredStates.has(name.state)) {
112
- diagnostics.push({
113
- ruleId: "SPEC-022",
114
- severity: "error",
115
- message: `Token '${tokenLabel}' references undeclared state '${name.state}' on component '${name.component}'`,
116
- tokenName: tokenLabel,
117
- componentName: name.component,
118
- });
119
- }
120
- }
121
- }
122
- }
123
-
124
- // --- Component declaration internal rules ---
125
- for (const component of components) {
126
- const cName = component.name;
127
-
128
- // SPEC-021: custom slot names should have descriptions
129
- for (const slot of component.slots ?? []) {
130
- if (!CANONICAL_SLOTS.has(slot.name) && !slot.description) {
131
- diagnostics.push({
132
- ruleId: "SPEC-021",
133
- severity: "warning",
134
- message: `Component '${cName}' has custom slot '${slot.name}' with no description — add a description or use a canonical slot name`,
135
- componentName: cName,
136
- });
137
- }
138
- }
139
-
140
- // SPEC-023: custom anatomy part names should have descriptions
141
- for (const part of component.anatomy ?? []) {
142
- if (!CANONICAL_ANATOMY_PARTS.has(part.name) && !part.description) {
143
- diagnostics.push({
144
- ruleId: "SPEC-023",
145
- severity: "warning",
146
- message: `Component '${cName}' has custom anatomy part '${part.name}' with no description`,
147
- componentName: cName,
148
- });
149
- }
150
- }
151
-
152
- // SPEC-024: custom state names should have descriptions
153
- for (const state of component.states ?? []) {
154
- if (!CANONICAL_STATES.has(state.name) && !state.description) {
155
- diagnostics.push({
156
- ruleId: "SPEC-024",
157
- severity: "warning",
158
- message: `Component '${cName}' has custom state '${state.name}' with no description`,
159
- componentName: cName,
160
- });
161
- }
162
- }
163
- }
164
-
165
- // --- Token binding rules ---
166
-
167
- // SPEC-027: each tokenBindings[].token must resolve to a known token name.
168
- // String-named tokens are matched directly. Name-object tokens are skipped
169
- // here because tokenBindings always reference tokens by their string name.
170
- const tokenNameSet = new Set(
171
- tokens
172
- .map((t) => (typeof t.name === "string" ? t.name : null))
173
- .filter(Boolean),
174
- );
175
-
176
- for (const component of components) {
177
- for (const binding of component.tokenBindings ?? []) {
178
- if (!tokenNameSet.has(binding.token)) {
179
- diagnostics.push({
180
- ruleId: "SPEC-027",
181
- severity: "error",
182
- message: `Component '${component.name}' tokenBindings references unknown token '${binding.token}'`,
183
- componentName: component.name,
184
- });
185
- }
186
- }
187
- }
188
-
189
- return diagnostics;
190
- }