@adobe/design-data-spec 0.15.0 → 1.0.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 (84) hide show
  1. package/components/accordion.json +27 -4
  2. package/components/action-button.json +27 -4
  3. package/components/action-group.json +51 -10
  4. package/components/alert-banner.json +15 -2
  5. package/components/alert-dialog.json +18 -8
  6. package/components/avatar-group.json +24 -2
  7. package/components/avatar.json +72 -13
  8. package/components/badge.json +120 -31
  9. package/components/body.json +24 -2
  10. package/components/bottom-navigation-android.json +18 -4
  11. package/components/breadcrumbs.json +34 -7
  12. package/components/button-group.json +32 -5
  13. package/components/button.json +50 -10
  14. package/components/calendar.json +9 -2
  15. package/components/cards.json +21 -9
  16. package/components/checkbox-group.json +27 -6
  17. package/components/checkbox.json +15 -2
  18. package/components/close-button.json +24 -4
  19. package/components/coach-indicator.json +40 -14
  20. package/components/code.json +18 -2
  21. package/components/color-handle.json +24 -10
  22. package/components/color-slider.json +33 -12
  23. package/components/combo-box.json +48 -8
  24. package/components/contextual-help.json +78 -27
  25. package/components/date-picker.json +12 -2
  26. package/components/detail.json +24 -4
  27. package/components/divider.json +21 -4
  28. package/components/drop-zone.json +12 -2
  29. package/components/field-label.json +33 -6
  30. package/components/heading.json +36 -4
  31. package/components/help-text.json +25 -5
  32. package/components/illustrated-message.json +21 -4
  33. package/components/in-field-progress-button.json +29 -3
  34. package/components/in-field-progress-circle.json +23 -3
  35. package/components/in-line-alert.json +33 -11
  36. package/components/link.json +18 -4
  37. package/components/list-view.json +12 -2
  38. package/components/menu.json +42 -5
  39. package/components/meter.json +30 -4
  40. package/components/number-field.json +32 -5
  41. package/components/opacity-checkerboard.json +25 -2
  42. package/components/picker.json +41 -7
  43. package/components/popover.json +69 -25
  44. package/components/progress-bar.json +39 -8
  45. package/components/progress-circle.json +21 -4
  46. package/components/radio-group.json +42 -8
  47. package/components/scroll-zoom-bar.json +21 -4
  48. package/components/search-field.json +15 -2
  49. package/components/segmented-control.json +27 -6
  50. package/components/select-box.json +9 -2
  51. package/components/side-navigation.json +12 -2
  52. package/components/slider.json +17 -3
  53. package/components/standard-dialog.json +12 -2
  54. package/components/standard-panel.json +33 -6
  55. package/components/status-light.json +87 -28
  56. package/components/steplist.json +9 -2
  57. package/components/swatch-group.json +48 -8
  58. package/components/swatch.json +39 -9
  59. package/components/switch.json +15 -2
  60. package/components/tab-bar-ios.json +18 -4
  61. package/components/table.json +24 -4
  62. package/components/tabs.json +9 -2
  63. package/components/tag-field.json +27 -4
  64. package/components/tag-group.json +21 -4
  65. package/components/takeover-dialog.json +9 -2
  66. package/components/text-area.json +50 -7
  67. package/components/text-field.json +32 -5
  68. package/components/thumbnail.json +38 -1
  69. package/components/title.json +24 -2
  70. package/components/toast.json +15 -2
  71. package/components/tooltip.json +27 -4
  72. package/components/tree-view.json +42 -8
  73. package/conformance/invalid/SPEC-019/dataset.json +14 -1
  74. package/conformance/invalid/SPEC-037/dataset.json +14 -6
  75. package/conformance/invalid/SPEC-038/dataset.json +20 -0
  76. package/conformance/invalid/SPEC-038/expected-errors.json +10 -0
  77. package/conformance/valid/SPEC-037/dataset.json +20 -8
  78. package/conformance/valid/SPEC-038/dataset.json +29 -0
  79. package/conformance/valid/component-refs/dataset.json +41 -7
  80. package/package.json +1 -1
  81. package/rules/rules.yaml +17 -4
  82. package/schemas/component.schema.json +25 -11
  83. package/spec/agent-surface.md +1 -1
  84. package/spec/component-format.md +67 -33
@@ -16,7 +16,14 @@
16
16
  "labelPosition": {
17
17
  "type": "string",
18
18
  "default": "top",
19
- "enum": ["top", "side"]
19
+ "values": [
20
+ {
21
+ "value": "top"
22
+ },
23
+ {
24
+ "value": "side"
25
+ }
26
+ ]
20
27
  },
21
28
  "hideLabel": {
22
29
  "type": "boolean",
@@ -31,13 +38,33 @@
31
38
  },
32
39
  "size": {
33
40
  "type": "string",
34
- "enum": ["s", "m", "l", "xl"],
35
- "default": "m"
41
+ "default": "m",
42
+ "values": [
43
+ {
44
+ "value": "s"
45
+ },
46
+ {
47
+ "value": "m"
48
+ },
49
+ {
50
+ "value": "l"
51
+ },
52
+ {
53
+ "value": "xl"
54
+ }
55
+ ]
36
56
  },
37
57
  "necessityIndicator": {
38
58
  "type": "string",
39
- "enum": ["text", "icon"],
40
- "default": "icon"
59
+ "default": "icon",
60
+ "values": [
61
+ {
62
+ "value": "text"
63
+ },
64
+ {
65
+ "value": "icon"
66
+ }
67
+ ]
41
68
  },
42
69
  "isRequired": {
43
70
  "type": "boolean",
@@ -12,7 +12,44 @@
12
12
  "options": {
13
13
  "size": {
14
14
  "type": "number",
15
- "enum": [50, 75, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
15
+ "values": [
16
+ {
17
+ "value": 50
18
+ },
19
+ {
20
+ "value": 75
21
+ },
22
+ {
23
+ "value": 100
24
+ },
25
+ {
26
+ "value": 200
27
+ },
28
+ {
29
+ "value": 300
30
+ },
31
+ {
32
+ "value": 400
33
+ },
34
+ {
35
+ "value": 500
36
+ },
37
+ {
38
+ "value": 600
39
+ },
40
+ {
41
+ "value": 700
42
+ },
43
+ {
44
+ "value": 800
45
+ },
46
+ {
47
+ "value": 900
48
+ },
49
+ {
50
+ "value": 1000
51
+ }
52
+ ]
16
53
  }
17
54
  },
18
55
  "states": [
@@ -18,8 +18,30 @@
18
18
  },
19
19
  "size": {
20
20
  "type": "string",
21
- "enum": ["xs", "s", "m", "l", "xl", "xxl", "xxxl"],
22
- "default": "m"
21
+ "default": "m",
22
+ "values": [
23
+ {
24
+ "value": "xs"
25
+ },
26
+ {
27
+ "value": "s"
28
+ },
29
+ {
30
+ "value": "m"
31
+ },
32
+ {
33
+ "value": "l"
34
+ },
35
+ {
36
+ "value": "xl"
37
+ },
38
+ {
39
+ "value": "xxl"
40
+ },
41
+ {
42
+ "value": "xxxl"
43
+ }
44
+ ]
23
45
  }
24
46
  },
25
47
  "lifecycle": {
@@ -15,8 +15,21 @@
15
15
  },
16
16
  "variant": {
17
17
  "type": "string",
18
- "enum": ["neutral", "informative", "positive", "negative"],
19
- "default": "neutral"
18
+ "default": "neutral",
19
+ "values": [
20
+ {
21
+ "value": "neutral"
22
+ },
23
+ {
24
+ "value": "informative"
25
+ },
26
+ {
27
+ "value": "positive"
28
+ },
29
+ {
30
+ "value": "negative"
31
+ }
32
+ ]
20
33
  },
21
34
  "actionLabel": {
22
35
  "type": "string",
@@ -15,8 +15,18 @@
15
15
  },
16
16
  "variant": {
17
17
  "type": "string",
18
- "enum": ["neutral", "informative", "negative"],
19
- "default": "neutral"
18
+ "default": "neutral",
19
+ "values": [
20
+ {
21
+ "value": "neutral"
22
+ },
23
+ {
24
+ "value": "informative"
25
+ },
26
+ {
27
+ "value": "negative"
28
+ }
29
+ ]
20
30
  },
21
31
  "hasIcon": {
22
32
  "type": "boolean",
@@ -30,8 +40,21 @@
30
40
  },
31
41
  "placement": {
32
42
  "type": "string",
33
- "enum": ["top", "bottom", "left", "right"],
34
- "default": "top"
43
+ "default": "top",
44
+ "values": [
45
+ {
46
+ "value": "top"
47
+ },
48
+ {
49
+ "value": "bottom"
50
+ },
51
+ {
52
+ "value": "left"
53
+ },
54
+ {
55
+ "value": "right"
56
+ }
57
+ ]
35
58
  },
36
59
  "shouldFlip": {
37
60
  "type": "boolean",
@@ -12,8 +12,21 @@
12
12
  "options": {
13
13
  "size": {
14
14
  "type": "string",
15
- "enum": ["s", "m", "l", "xl"],
16
- "default": "m"
15
+ "default": "m",
16
+ "values": [
17
+ {
18
+ "value": "s"
19
+ },
20
+ {
21
+ "value": "m"
22
+ },
23
+ {
24
+ "value": "l"
25
+ },
26
+ {
27
+ "value": "xl"
28
+ }
29
+ ]
17
30
  },
18
31
  "isDetached": {
19
32
  "type": "boolean",
@@ -29,18 +42,39 @@
29
42
  },
30
43
  "selectionMode": {
31
44
  "type": "string",
32
- "enum": ["single", "multiple"],
33
- "default": "multiple"
45
+ "default": "multiple",
46
+ "values": [
47
+ {
48
+ "value": "single"
49
+ },
50
+ {
51
+ "value": "multiple"
52
+ }
53
+ ]
34
54
  },
35
55
  "selectionStyle": {
36
56
  "type": "string",
37
- "enum": ["checkbox", "highlight"],
38
- "default": "checkbox"
57
+ "default": "checkbox",
58
+ "values": [
59
+ {
60
+ "value": "checkbox"
61
+ },
62
+ {
63
+ "value": "highlight"
64
+ }
65
+ ]
39
66
  },
40
67
  "selectionBehavior": {
41
68
  "type": "string",
42
- "enum": ["toggle", "replace"],
43
- "default": "toggle"
69
+ "default": "toggle",
70
+ "values": [
71
+ {
72
+ "value": "toggle"
73
+ },
74
+ {
75
+ "value": "replace"
76
+ }
77
+ ]
44
78
  }
45
79
  },
46
80
  "states": [
@@ -21,7 +21,20 @@
21
21
  "options": {
22
22
  "variant": {
23
23
  "type": "string",
24
- "enum": ["accent", "negative", "primary", "secondary"]
24
+ "values": [
25
+ {
26
+ "value": "accent"
27
+ },
28
+ {
29
+ "value": "negative"
30
+ },
31
+ {
32
+ "value": "primary"
33
+ },
34
+ {
35
+ "value": "secondary"
36
+ }
37
+ ]
25
38
  }
26
39
  }
27
40
  }
@@ -64,13 +64,21 @@
64
64
  "options": {
65
65
  "variant": {
66
66
  "type": "string",
67
- "enum": ["primary", "secondary", "cta"],
68
- "deprecatedEnumValues": {
69
- "cta": {
70
- "deprecated": "1.0.0-draft",
71
- "deprecatedComment": "Use primary instead."
67
+ "values": [
68
+ {
69
+ "value": "primary"
70
+ },
71
+ {
72
+ "value": "secondary"
73
+ },
74
+ {
75
+ "value": "cta",
76
+ "lifecycle": {
77
+ "deprecated": "1.0.0-draft",
78
+ "deprecatedComment": "Use primary instead."
79
+ }
72
80
  }
73
- }
81
+ ]
74
82
  }
75
83
  }
76
84
  }
@@ -0,0 +1,20 @@
1
+ {
2
+ "tokens": {},
3
+ "components": [
4
+ {
5
+ "$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/badge.json",
6
+ "name": "badge",
7
+ "displayName": "Badge",
8
+ "meta": {
9
+ "category": "status",
10
+ "documentationUrl": "https://spectrum.adobe.com/page/badge/"
11
+ },
12
+ "options": {
13
+ "variant": {
14
+ "type": "string",
15
+ "enum": ["neutral", "informative", "positive", "negative"]
16
+ }
17
+ }
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "layer": 2,
3
+ "errors": [
4
+ {
5
+ "rule_id": "SPEC-038",
6
+ "severity": "warning",
7
+ "message_pattern": ".*obsolete.*enum.*"
8
+ }
9
+ ]
10
+ }
@@ -62,7 +62,9 @@
62
62
  "documentationUrl": "https://spectrum.adobe.com/page/slider/"
63
63
  },
64
64
  "anatomy": [
65
- { "name": "track" },
65
+ {
66
+ "name": "track"
67
+ },
66
68
  {
67
69
  "name": "handle",
68
70
  "lifecycle": {
@@ -81,7 +83,9 @@
81
83
  "documentationUrl": "https://spectrum.adobe.com/page/button/"
82
84
  },
83
85
  "states": [
84
- { "name": "hover" },
86
+ {
87
+ "name": "hover"
88
+ },
85
89
  {
86
90
  "name": "pressed",
87
91
  "lifecycle": {
@@ -93,13 +97,21 @@
93
97
  "options": {
94
98
  "variant": {
95
99
  "type": "string",
96
- "enum": ["primary", "secondary", "cta"],
97
- "deprecatedEnumValues": {
98
- "cta": {
99
- "deprecated": "1.0.0-draft",
100
- "deprecatedComment": "Use primary instead."
100
+ "values": [
101
+ {
102
+ "value": "primary"
103
+ },
104
+ {
105
+ "value": "secondary"
106
+ },
107
+ {
108
+ "value": "cta",
109
+ "lifecycle": {
110
+ "deprecated": "1.0.0-draft",
111
+ "deprecatedComment": "Use primary instead."
112
+ }
101
113
  }
102
- }
114
+ ]
103
115
  }
104
116
  }
105
117
  }
@@ -0,0 +1,29 @@
1
+ {
2
+ "tokens": {},
3
+ "components": [
4
+ {
5
+ "$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/components/button.json",
6
+ "name": "button",
7
+ "displayName": "Button",
8
+ "meta": {
9
+ "category": "actions",
10
+ "documentationUrl": "https://spectrum.adobe.com/page/button/"
11
+ },
12
+ "options": {
13
+ "variant": {
14
+ "type": "string",
15
+ "values": [
16
+ { "value": "primary" },
17
+ { "value": "secondary" },
18
+ { "value": "accent" }
19
+ ],
20
+ "default": "accent"
21
+ },
22
+ "isDisabled": {
23
+ "type": "boolean",
24
+ "default": false
25
+ }
26
+ }
27
+ }
28
+ ]
29
+ }
@@ -37,26 +37,60 @@
37
37
  "options": {
38
38
  "variant": {
39
39
  "type": "string",
40
- "enum": ["accent", "negative", "primary", "secondary"]
40
+ "values": [
41
+ {
42
+ "value": "accent"
43
+ },
44
+ {
45
+ "value": "negative"
46
+ },
47
+ {
48
+ "value": "primary"
49
+ },
50
+ {
51
+ "value": "secondary"
52
+ }
53
+ ]
41
54
  }
42
55
  },
43
56
  "slots": [
44
- { "name": "default", "description": "Text label of the button." },
45
- { "name": "icon", "description": "Leading icon." }
57
+ {
58
+ "name": "default",
59
+ "description": "Text label of the button."
60
+ },
61
+ {
62
+ "name": "icon",
63
+ "description": "Leading icon."
64
+ }
46
65
  ],
47
66
  "anatomy": [
48
- { "name": "icon", "description": "Leading icon." },
49
- { "name": "label", "description": "Button text.", "required": true }
67
+ {
68
+ "name": "icon",
69
+ "description": "Leading icon."
70
+ },
71
+ {
72
+ "name": "label",
73
+ "description": "Button text.",
74
+ "required": true
75
+ }
50
76
  ],
51
77
  "states": [
52
- { "name": "hover", "trigger": "interaction", "precedence": 50 },
78
+ {
79
+ "name": "hover",
80
+ "trigger": "interaction",
81
+ "precedence": 50
82
+ },
53
83
  {
54
84
  "name": "focus",
55
85
  "trigger": "interaction",
56
86
  "precedence": 60,
57
87
  "layered": true
58
88
  },
59
- { "name": "disabled", "trigger": "prop", "precedence": 100 }
89
+ {
90
+ "name": "disabled",
91
+ "trigger": "prop",
92
+ "precedence": 100
93
+ }
60
94
  ]
61
95
  }
62
96
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-spec",
3
- "version": "0.15.0",
3
+ "version": "1.0.0",
4
4
  "description": "Design Data Specification — prose, JSON Schemas, rule catalog, and conformance fixtures for Spectrum design data",
5
5
  "type": "module",
6
6
  "repository": {
package/rules/rules.yaml CHANGED
@@ -168,7 +168,7 @@ rules:
168
168
  name: component-variant-valid
169
169
  severity: error
170
170
  category: reference-integrity
171
- assert: Token name-object 'variant' field value MUST match a value in the declared 'variant' option enum for the referenced component, when that enum exists.
171
+ assert: Token name-object 'variant' field value MUST match a value in the declared 'variant' option `values` list for the referenced component, when that list exists.
172
172
  message: "Token '{token}' has variant '{variant}' which is not declared on component '{component}'"
173
173
  spec_ref: spec/component-format.md#options
174
174
  introduced_in: "1.0.0-draft"
@@ -362,11 +362,24 @@ rules:
362
362
  category: reference-integrity
363
363
  assert: >
364
364
  Tokens SHOULD NOT reference a deprecated anatomy part, deprecated component state, or
365
- deprecated option-enum value via their `name` object unless the token is itself deprecated.
365
+ deprecated option value via their `name` object unless the token is itself deprecated.
366
366
  Non-deprecated tokens referencing deprecated sub-entities are surfaced as warnings to
367
367
  prompt authors to update the reference or mark the token deprecated.
368
- Requires `lifecycle.deprecated` on anatomy parts and states, and `deprecatedEnumValues`
369
- on option descriptors (introduced in this version of the schema).
368
+ Deprecation is declared via `lifecycle.deprecated` on anatomy parts, states, and individual
369
+ option values within the `values` array on option descriptors.
370
370
  message: "Token '{token}' references deprecated {kind} '{value}' on component '{component}' (deprecated since {version}); update the reference or mark the token deprecated"
371
371
  spec_ref: spec/component-format.md#lifecycle
372
372
  introduced_in: "1.0.0-draft"
373
+
374
+ - id: SPEC-038
375
+ name: option-enum-obsolete
376
+ severity: warning
377
+ category: component-contract
378
+ assert: >
379
+ Option descriptors SHOULD NOT use the JSON Schema `enum` keyword. The `enum` field is
380
+ silently accepted at Layer 1 (optionDescriptor uses additionalProperties: true) but has
381
+ no effect on SDK rules or lifecycle cascade. Use `values` instead so per-value lifecycle
382
+ metadata can be attached to individual values.
383
+ message: "Component '{component}' option '{option}' uses the obsolete `enum` keyword; replace with a `values` array so per-value lifecycle metadata can be expressed"
384
+ spec_ref: spec/component-format.md#option-descriptor
385
+ introduced_in: "1.0.0-draft"
@@ -108,7 +108,8 @@
108
108
  },
109
109
  "optionDescriptor": {
110
110
  "type": "object",
111
- "description": "JSON Schema-compatible descriptor for a single component option. Standard JSON Schema keywords (type, enum, default, description, pattern, minimum, maximum, items, properties, etc.) are all permitted.",
111
+ "description": "Descriptor for a single component option. The `type` keyword follows JSON Schema conventions. Use `values` (not `enum`) to declare permitted values — the structured array allows per-value lifecycle metadata. Other JSON Schema keywords (default, description, pattern, minimum, maximum, items, properties, $ref) are permitted as needed.",
112
+ "$comment": "additionalProperties: true is required to allow JSON Schema passthrough keywords (pattern, minimum, etc.). This means the legacy `enum` keyword is silently accepted at Layer 1; SPEC-038 closes the gap at Layer 2 by warning when `enum` is present.",
112
113
  "properties": {
113
114
  "type": {
114
115
  "oneOf": [
@@ -142,10 +143,12 @@
142
143
  }
143
144
  ]
144
145
  },
145
- "enum": {
146
+ "values": {
146
147
  "type": "array",
147
148
  "minItems": 1,
148
- "description": "Exhaustive list of permitted values."
149
+ "uniqueItems": true,
150
+ "items": { "$ref": "#/$defs/optionValue" },
151
+ "description": "Exhaustive list of permitted values for this option, each with optional per-value metadata. Use this instead of the JSON Schema `enum` keyword so that lifecycle annotations can be attached to individual values. Consumed by SPEC-019 (variant validation) and SPEC-037 (deprecation cascade)."
149
152
  },
150
153
  "default": {
151
154
  "description": "Default value when the option is not specified."
@@ -158,18 +161,29 @@
158
161
  "type": "string",
159
162
  "format": "uri-reference",
160
163
  "description": "Reference to a shared type schema."
161
- },
162
- "deprecatedEnumValues": {
163
- "type": "object",
164
- "description": "Per-enum-value lifecycle metadata keyed by enum value string. Values absent from this map are not deprecated. Consumed by SPEC-037.",
165
- "$comment": "Keys are not validated against sibling 'enum' — JSON Schema cannot cross-reference sibling values without unevaluatedProperties. Entries for values absent from 'enum' are silently ignored by validators. A future SPEC rule may close this gap.",
166
- "additionalProperties": {
167
- "$ref": "#/$defs/lifecycle"
168
- }
169
164
  }
170
165
  },
171
166
  "additionalProperties": true
172
167
  },
168
+ "optionValue": {
169
+ "type": "object",
170
+ "required": ["value"],
171
+ "description": "A single permitted value for a component option, with optional per-value metadata.",
172
+ "properties": {
173
+ "value": {
174
+ "description": "The permitted option value. Typically a string; the schema does not constrain the type so booleans and numbers remain expressible."
175
+ },
176
+ "description": {
177
+ "type": "string",
178
+ "description": "Plain-text description of what this value means."
179
+ },
180
+ "lifecycle": {
181
+ "$ref": "#/$defs/lifecycle",
182
+ "description": "Version lifecycle metadata for this value. Set lifecycle.deprecated to signal that tokens referencing this value should migrate (SPEC-037)."
183
+ }
184
+ },
185
+ "additionalProperties": false
186
+ },
173
187
  "slotDeclaration": {
174
188
  "type": "object",
175
189
  "required": ["name"],
@@ -96,7 +96,7 @@ The `describe_component` tool returns the component declaration object as stored
96
96
  "displayName": "Button",
97
97
  "meta": { "category": "actions", "documentationUrl": "https://spectrum.adobe.com/page/button/" },
98
98
  "options": {
99
- "variant": { "type": "string", "enum": ["accent", "negative", "primary", "secondary"], "default": "accent" }
99
+ "variant": { "type": "string", "values": [{"value": "accent"}, {"value": "negative"}, {"value": "primary"}, {"value": "secondary"}], "default": "accent" }
100
100
  },
101
101
  "anatomy": [
102
102
  { "name": "icon", "description": "Leading icon." },