@adobe/design-data-spec 0.7.0 → 0.9.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/package.json +1 -1
- package/rules/rules.yaml +24 -0
- package/schemas/anatomy-part.schema.json +6 -0
- package/schemas/component.schema.json +11 -0
- package/schemas/document-block.schema.json +43 -0
- package/schemas/token.schema.json +12 -0
- package/spec/accessibility.md +219 -0
- package/spec/component-format.md +42 -10
- package/spec/document-blocks.md +182 -0
- package/spec/index.md +23 -17
package/package.json
CHANGED
package/rules/rules.yaml
CHANGED
|
@@ -244,3 +244,27 @@ rules:
|
|
|
244
244
|
message: "Component '{component}' tokenBindings references unknown token '{token}'"
|
|
245
245
|
spec_ref: spec/component-format.md#token-bindings
|
|
246
246
|
introduced_in: "1.0.0-draft"
|
|
247
|
+
|
|
248
|
+
- id: SPEC-028
|
|
249
|
+
name: document-block-agents-equals-content
|
|
250
|
+
severity: warning
|
|
251
|
+
category: completeness
|
|
252
|
+
assert: >
|
|
253
|
+
A document block's agents field, when present, SHOULD contain phrasing that differs from
|
|
254
|
+
content. An identical copy provides no agent-specific value and SHOULD be omitted or refined.
|
|
255
|
+
Applies to tokens, components, and anatomy parts.
|
|
256
|
+
message: "'{entity}' has a document block whose agents text is identical to content — tailor it for agent consumption or omit the agents field"
|
|
257
|
+
spec_ref: spec/document-blocks.md
|
|
258
|
+
introduced_in: "1.0.0-draft"
|
|
259
|
+
|
|
260
|
+
- id: SPEC-029
|
|
261
|
+
name: document-block-missing-purpose
|
|
262
|
+
severity: warning
|
|
263
|
+
category: completeness
|
|
264
|
+
assert: >
|
|
265
|
+
An entity that carries a non-empty documentBlocks array SHOULD include at least one block
|
|
266
|
+
with type 'purpose' to document the entity's intent.
|
|
267
|
+
Applies to tokens, components, and anatomy parts.
|
|
268
|
+
message: "'{entity}' has documentBlocks but no purpose block — add a block with type 'purpose'"
|
|
269
|
+
spec_ref: spec/document-blocks.md
|
|
270
|
+
introduced_in: "1.0.0-draft"
|
|
@@ -29,6 +29,12 @@
|
|
|
29
29
|
},
|
|
30
30
|
"uniqueItems": true,
|
|
31
31
|
"description": "Informative list of child anatomy part names nested within this part. Does not carry enforcement semantics."
|
|
32
|
+
},
|
|
33
|
+
"documentBlocks": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"items": { "$ref": "document-block.schema.json" },
|
|
36
|
+
"minItems": 1,
|
|
37
|
+
"description": "Typed prose blocks for this anatomy part. See spec/document-blocks.md (Phase 9)."
|
|
32
38
|
}
|
|
33
39
|
},
|
|
34
40
|
"additionalProperties": false
|
|
@@ -68,6 +68,12 @@
|
|
|
68
68
|
"type": "array",
|
|
69
69
|
"items": { "$ref": "#/$defs/tokenBinding" },
|
|
70
70
|
"description": "Tokens this component uses, including foundation/structure tokens not scoped to the component in their name-object. See spec/component-format.md#token-bindings (Phase 6.7)."
|
|
71
|
+
},
|
|
72
|
+
"documentBlocks": {
|
|
73
|
+
"type": "array",
|
|
74
|
+
"items": { "$ref": "document-block.schema.json" },
|
|
75
|
+
"minItems": 1,
|
|
76
|
+
"description": "Typed prose blocks for this component. See spec/document-blocks.md (Phase 9)."
|
|
71
77
|
}
|
|
72
78
|
},
|
|
73
79
|
"additionalProperties": false,
|
|
@@ -203,6 +209,11 @@
|
|
|
203
209
|
"type": "array",
|
|
204
210
|
"items": { "type": "string" },
|
|
205
211
|
"description": "Informative: anatomy part names nested within this part."
|
|
212
|
+
},
|
|
213
|
+
"documentBlocks": {
|
|
214
|
+
"type": "array",
|
|
215
|
+
"items": { "$ref": "document-block.schema.json" },
|
|
216
|
+
"description": "Typed prose blocks for this anatomy part. See spec/document-blocks.md (Phase 9)."
|
|
206
217
|
}
|
|
207
218
|
},
|
|
208
219
|
"additionalProperties": false
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/document-block.schema.json",
|
|
4
|
+
"title": "Document block",
|
|
5
|
+
"description": "A typed prose block attachable to tokens, components, or anatomy parts. See spec/document-blocks.md.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["type", "content"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"type": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"enum": ["purpose", "guideline", "accessibility", "do-dont", "examples"],
|
|
12
|
+
"description": "Block type. One of: purpose, guideline, accessibility, do-dont, examples."
|
|
13
|
+
},
|
|
14
|
+
"content": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"minLength": 1,
|
|
17
|
+
"description": "Human-readable prose for this block."
|
|
18
|
+
},
|
|
19
|
+
"agents": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"minLength": 1,
|
|
22
|
+
"description": "Optional LLM-tuned rephrasing of content for agent consumption. Should differ from content."
|
|
23
|
+
},
|
|
24
|
+
"do": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"minLength": 1,
|
|
27
|
+
"description": "Recommended practice. Meaningful only on do-dont blocks."
|
|
28
|
+
},
|
|
29
|
+
"dont": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"minLength": 1,
|
|
32
|
+
"description": "Anti-pattern to avoid. Meaningful only on do-dont blocks."
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"additionalProperties": false,
|
|
36
|
+
"if": {
|
|
37
|
+
"properties": { "type": { "const": "do-dont" } },
|
|
38
|
+
"required": ["type"]
|
|
39
|
+
},
|
|
40
|
+
"then": {
|
|
41
|
+
"anyOf": [{ "required": ["do"] }, { "required": ["dont"] }]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -180,6 +180,12 @@
|
|
|
180
180
|
"type": "array",
|
|
181
181
|
"items": { "$ref": "#/$defs/componentBinding" },
|
|
182
182
|
"description": "Reverse index: components that declare this token in their tokenBindings. Optional and derivable from component files."
|
|
183
|
+
},
|
|
184
|
+
"documentBlocks": {
|
|
185
|
+
"type": "array",
|
|
186
|
+
"items": { "$ref": "document-block.schema.json" },
|
|
187
|
+
"minItems": 1,
|
|
188
|
+
"description": "Typed prose blocks for this token. See spec/document-blocks.md (Phase 9)."
|
|
183
189
|
}
|
|
184
190
|
},
|
|
185
191
|
"additionalProperties": false
|
|
@@ -258,6 +264,12 @@
|
|
|
258
264
|
"type": "array",
|
|
259
265
|
"items": { "$ref": "#/$defs/componentBinding" },
|
|
260
266
|
"description": "Reverse index: components that declare this token in their tokenBindings. Optional and derivable from component files."
|
|
267
|
+
},
|
|
268
|
+
"documentBlocks": {
|
|
269
|
+
"type": "array",
|
|
270
|
+
"items": { "$ref": "document-block.schema.json" },
|
|
271
|
+
"minItems": 1,
|
|
272
|
+
"description": "Typed prose blocks for this token. See spec/document-blocks.md (Phase 9)."
|
|
261
273
|
}
|
|
262
274
|
},
|
|
263
275
|
"additionalProperties": false
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Accessibility
|
|
2
|
+
|
|
3
|
+
**Spec version:** `1.0.0-draft` (see [Overview](index.md))
|
|
4
|
+
|
|
5
|
+
This chapter defines the **semantic accessibility vocabulary** that component declarations carry at the foundation layer. A component's accessibility declaration expresses intent — its semantic role, interaction purposes, focus behavior, and applicable WCAG criteria — without encoding platform-specific APIs. Platform adapter repos translate this vocabulary to ARIA attributes, iOS UIAccessibility traits, Android AccessibilityNodeInfo properties, and other platform contracts.
|
|
6
|
+
|
|
7
|
+
This mirrors how the cascade defines foundation→platform layering for tokens: the spec ships the vocabulary; platform repos ship the mapping.
|
|
8
|
+
|
|
9
|
+
Scoped under planned RFC-B. See [rfc-coordination.md](../docs/rfc-coordination.md).
|
|
10
|
+
|
|
11
|
+
## Accessibility declaration
|
|
12
|
+
|
|
13
|
+
The `accessibility` object is an optional top-level field on a [component declaration](component-format.md). When present, it MUST conform to [`accessibility.schema.json`](../schemas/accessibility.schema.json) (schema added in Phase 7.3).
|
|
14
|
+
|
|
15
|
+
### Fields
|
|
16
|
+
|
|
17
|
+
| Field | Type | Required | Description |
|
|
18
|
+
| ----------------- | --------- | -------- | -------------------------------------------------------- |
|
|
19
|
+
| `role` | string | No | Semantic role from the canonical role vocabulary |
|
|
20
|
+
| `intents` | string\[] | No | Semantic interaction intents |
|
|
21
|
+
| `focusable` | boolean | No | Whether the component receives keyboard focus by default |
|
|
22
|
+
| `keyboardIntents` | string\[] | No | Keyboard interaction intents when focused |
|
|
23
|
+
| `wcag` | object\[] | No | Applicable WCAG 2.x success criteria |
|
|
24
|
+
|
|
25
|
+
**NORMATIVE:** An `accessibility` object SHOULD contain at least one field. An empty `accessibility` object provides no semantic value.
|
|
26
|
+
|
|
27
|
+
> **Note:** Anatomy parts (see [Anatomy format](anatomy-format.md)) do not carry an
|
|
28
|
+
> `accessibility` field at this spec version. Component-level accessibility applies to the
|
|
29
|
+
> component as a whole. Per-part accessibility semantics are deferred to Phase 7.3.
|
|
30
|
+
|
|
31
|
+
### `role`
|
|
32
|
+
|
|
33
|
+
The `role` field names the semantic role of the component. It maps conceptually to ARIA widget and landmark roles, iOS `UIAccessibilityTraits`, Android role descriptions, and equivalent constructs on other platforms — but it is **not** a direct ARIA attribute. Platform adapters perform the translation.
|
|
34
|
+
|
|
35
|
+
**NORMATIVE:** Custom values (outside the canonical vocabulary below) are permitted. When using a custom value, the component SHOULD include a `description` field that documents the role's semantics.
|
|
36
|
+
|
|
37
|
+
**Canonical role vocabulary:**
|
|
38
|
+
|
|
39
|
+
| Value | Semantic meaning |
|
|
40
|
+
| ------------ | --------------------------------------------------- |
|
|
41
|
+
| `button` | Triggers a discrete action |
|
|
42
|
+
| `checkbox` | Binary on/off selection |
|
|
43
|
+
| `combobox` | Combined text input with a selectable option list |
|
|
44
|
+
| `dialog` | Modal overlay requiring a user response |
|
|
45
|
+
| `link` | Navigates the user to another context |
|
|
46
|
+
| `listbox` | Selectable list of options |
|
|
47
|
+
| `menu` | List of commands or options |
|
|
48
|
+
| `menuitem` | Individual item within a menu |
|
|
49
|
+
| `radio` | Single-select option within a group |
|
|
50
|
+
| `slider` | Range input with a continuous value |
|
|
51
|
+
| `spinbutton` | Numeric input with increment and decrement controls |
|
|
52
|
+
| `switch` | Toggles between two states (on/off) |
|
|
53
|
+
| `tab` | Selects a panel within a tabbed interface |
|
|
54
|
+
| `textbox` | Accepts free-form text input |
|
|
55
|
+
| `tooltip` | Contextual information overlay; not interactive |
|
|
56
|
+
| `tree` | Hierarchical navigable list |
|
|
57
|
+
|
|
58
|
+
### `intents`
|
|
59
|
+
|
|
60
|
+
The `intents` array lists the semantic interaction purposes the component supports. Multiple intents are permitted — a combobox, for example, both accepts text input and selects from a list.
|
|
61
|
+
|
|
62
|
+
Platform adapters use `intents` to determine which ARIA properties, traits, or accessibility attributes to apply.
|
|
63
|
+
|
|
64
|
+
**Canonical intent vocabulary:**
|
|
65
|
+
|
|
66
|
+
| Value | Meaning |
|
|
67
|
+
| ---------- | ------------------------------------------ |
|
|
68
|
+
| `trigger` | Activates or invokes an action |
|
|
69
|
+
| `select` | Selects from a set of options |
|
|
70
|
+
| `navigate` | Moves the user to another context |
|
|
71
|
+
| `expand` | Reveals additional content |
|
|
72
|
+
| `collapse` | Conceals content |
|
|
73
|
+
| `input` | Accepts user-typed text |
|
|
74
|
+
| `choose` | Picks a value from a range or discrete set |
|
|
75
|
+
| `dismiss` | Closes or removes an element |
|
|
76
|
+
|
|
77
|
+
### `focusable`
|
|
78
|
+
|
|
79
|
+
The `focusable` boolean declares whether the component receives keyboard focus via the Tab key by default.
|
|
80
|
+
|
|
81
|
+
* `true` — the component is in the tab order; platform adapters set `tabindex="0"` or the platform equivalent.
|
|
82
|
+
* `false` — the component is not in the tab order; child elements may still be individually
|
|
83
|
+
focusable. Components that manage focus internally (radio groups, toolbars, tree views)
|
|
84
|
+
use the roving `tabindex` pattern — one child is focusable at a time. For these, set
|
|
85
|
+
`focusable: false`; the platform adapter manages which child holds `tabindex="0"`.
|
|
86
|
+
* When absent, focus behavior is unspecified at the foundation layer.
|
|
87
|
+
|
|
88
|
+
### `keyboardIntents`
|
|
89
|
+
|
|
90
|
+
The `keyboardIntents` array lists the keyboard interaction intents the component responds to when focused. Platform adapters use this to bind keyboard event handlers.
|
|
91
|
+
|
|
92
|
+
**RECOMMENDED:** Where a `keyboardIntents` value has a direct semantic equivalent in `intents`,
|
|
93
|
+
both SHOULD be declared. For example, a component with `expand` in `intents` SHOULD also include
|
|
94
|
+
`expand` in `keyboardIntents`. Keyboard-specific intents such as `activate`, `navigate-options`,
|
|
95
|
+
and `navigate-items` have no `intents` counterpart and are keyboard-only.
|
|
96
|
+
|
|
97
|
+
**Canonical keyboard intent vocabulary:**
|
|
98
|
+
|
|
99
|
+
| Value | Default key(s) | Meaning |
|
|
100
|
+
| ------------------ | ----------------------- | ------------------------------------------------------- |
|
|
101
|
+
| `activate` | Enter, Space | Triggers the component's primary action |
|
|
102
|
+
| `expand` | Space, Enter, ArrowDown | Reveals associated content |
|
|
103
|
+
| `collapse` | Escape, ArrowUp | Conceals associated content |
|
|
104
|
+
| `navigate-options` | ArrowUp, ArrowDown | Moves focus through a list of options |
|
|
105
|
+
| `navigate-items` | ArrowLeft, ArrowRight | Moves focus between peer elements (tabs, toolbar items) |
|
|
106
|
+
| `increment` | ArrowUp, ArrowRight | Increases a numeric or ranged value |
|
|
107
|
+
| `decrement` | ArrowDown, ArrowLeft | Decreases a numeric or ranged value |
|
|
108
|
+
| `dismiss` | Escape | Closes or cancels |
|
|
109
|
+
| `select-all` | Ctrl+A | Selects all items in a collection |
|
|
110
|
+
|
|
111
|
+
The "Default key(s)" column is informative. Platform adapters determine actual key bindings; the foundation layer declares intent only.
|
|
112
|
+
|
|
113
|
+
### `wcag`
|
|
114
|
+
|
|
115
|
+
The `wcag` array lists the WCAG 2.x success criteria applicable to this component. Entries are objects with the following fields:
|
|
116
|
+
|
|
117
|
+
| Field | Type | Required | Description |
|
|
118
|
+
| ----------- | ------ | -------- | -------------------------------------------- |
|
|
119
|
+
| `criterion` | string | Yes | WCAG criterion number, e.g. `"1.3.1"` |
|
|
120
|
+
| `level` | string | Yes | Conformance level: `"A"`, `"AA"`, or `"AAA"` |
|
|
121
|
+
| `title` | string | No | Human-readable criterion title |
|
|
122
|
+
|
|
123
|
+
**NORMATIVE:** `criterion` MUST be a valid WCAG 2.x criterion number in
|
|
124
|
+
`"<principle>.<guideline>.<criterion>"` format, where `<principle>` is 1–4 (matching WCAG 2.x
|
|
125
|
+
principles: Perceivable, Operable, Understandable, Robust). `level` MUST be one of `"A"`,
|
|
126
|
+
`"AA"`, or `"AAA"`.
|
|
127
|
+
|
|
128
|
+
Example `wcag` entry:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{ "criterion": "4.1.2", "level": "A", "title": "Name, Role, Value" }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## State-level accessibility fields
|
|
135
|
+
|
|
136
|
+
State declarations (see [State model](state-model.md)) MAY carry the following additional fields that describe how assistive technology responds to state transitions. These fields extend the base state declaration object defined in `spec/state-model.md`.
|
|
137
|
+
|
|
138
|
+
| Field | Type | Required | Description |
|
|
139
|
+
| ------------------- | ------- | -------- | --------------------------------------------------------- |
|
|
140
|
+
| `announce` | string | No | Screen-reader announcement hint for this state transition |
|
|
141
|
+
| `communicates` | string | No | Semantic meaning conveyed to AT when this state is active |
|
|
142
|
+
| `blocksInteraction` | boolean | No | Whether this state prevents all user interaction |
|
|
143
|
+
|
|
144
|
+
### `announce`
|
|
145
|
+
|
|
146
|
+
A hint string used by platform adapters to populate ARIA live regions or post accessibility notifications when the state is entered. The text is a template hint, not a final user-facing string — platform implementations localize and adapt it.
|
|
147
|
+
|
|
148
|
+
**RECOMMENDED:** Phrasing SHOULD be concise (under 10 words) and describe the transition, not the resulting state. Prefer `"Dialog opened"` over `"The dialog is now open"`.
|
|
149
|
+
|
|
150
|
+
### `communicates`
|
|
151
|
+
|
|
152
|
+
A string describing the semantic state the component is in after the transition. Platform adapters use this to set `aria-*` state attributes or equivalent:
|
|
153
|
+
|
|
154
|
+
| Example value | ARIA equivalent |
|
|
155
|
+
| ------------- | ---------------------- |
|
|
156
|
+
| `"selected"` | `aria-selected="true"` |
|
|
157
|
+
| `"expanded"` | `aria-expanded="true"` |
|
|
158
|
+
| `"checked"` | `aria-checked="true"` |
|
|
159
|
+
| `"invalid"` | `aria-invalid="true"` |
|
|
160
|
+
| `"required"` | `aria-required="true"` |
|
|
161
|
+
| `"busy"` | `aria-busy="true"` |
|
|
162
|
+
| `"pressed"` | `aria-pressed="true"` |
|
|
163
|
+
| `"disabled"` | `aria-disabled="true"` |
|
|
164
|
+
|
|
165
|
+
The ARIA mapping column is informative; the foundation layer declares semantic meaning only.
|
|
166
|
+
|
|
167
|
+
### `blocksInteraction`
|
|
168
|
+
|
|
169
|
+
A boolean declaring whether this state prevents all user interaction with the component.
|
|
170
|
+
|
|
171
|
+
* `true` — the component cannot be interacted with while in this state (e.g., `disabled`, `loading`); platform adapters SHOULD set `aria-disabled` or equivalent.
|
|
172
|
+
* `false` or absent — user interaction is not blocked by this state.
|
|
173
|
+
|
|
174
|
+
## Example
|
|
175
|
+
|
|
176
|
+
A `button` component with a complete accessibility declaration and two states carrying state-level accessibility fields:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"name": "button",
|
|
181
|
+
"displayName": "Button",
|
|
182
|
+
"meta": { "category": "actions", "documentationUrl": "https://spectrum.adobe.com/page/button/" },
|
|
183
|
+
"accessibility": {
|
|
184
|
+
"role": "button",
|
|
185
|
+
"intents": ["trigger"],
|
|
186
|
+
"focusable": true,
|
|
187
|
+
"keyboardIntents": ["activate"],
|
|
188
|
+
"wcag": [
|
|
189
|
+
{ "criterion": "4.1.2", "level": "A", "title": "Name, Role, Value" },
|
|
190
|
+
{ "criterion": "1.4.3", "level": "AA", "title": "Contrast (Minimum)" }
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
"states": [
|
|
194
|
+
{
|
|
195
|
+
"name": "disabled",
|
|
196
|
+
"trigger": { "type": "prop", "prop": "disabled" },
|
|
197
|
+
"announce": "Button disabled",
|
|
198
|
+
"communicates": "disabled",
|
|
199
|
+
"blocksInteraction": true
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"name": "loading",
|
|
203
|
+
"trigger": { "type": "prop", "prop": "pending" },
|
|
204
|
+
"announce": "Loading",
|
|
205
|
+
"communicates": "busy",
|
|
206
|
+
"blocksInteraction": true
|
|
207
|
+
}
|
|
208
|
+
]
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## SPEC rules
|
|
213
|
+
|
|
214
|
+
| Rule ID | Severity | Name | Assert |
|
|
215
|
+
| -------- | -------- | -------------------------- | -------------------------------------------------------------------------------------- |
|
|
216
|
+
| SPEC-030 | warning | accessibility-empty | When `accessibility` is declared with no fields, the object provides no semantic value |
|
|
217
|
+
| SPEC-031 | warning | accessibility-wcag-missing | When `accessibility` is declared, `wcag` SHOULD list at least one criterion |
|
|
218
|
+
|
|
219
|
+
Both rules are `warning` severity — they do not block validation. Rules are defined in `rules/rules.yaml` and implemented in the SDK in Phase 7.4.
|
package/spec/component-format.md
CHANGED
|
@@ -29,16 +29,17 @@ A component declaration **MUST** contain:
|
|
|
29
29
|
|
|
30
30
|
### Optional fields
|
|
31
31
|
|
|
32
|
-
| Field
|
|
33
|
-
|
|
|
34
|
-
| `specVersion`
|
|
35
|
-
| `description`
|
|
36
|
-
| `options`
|
|
37
|
-
| `slots`
|
|
38
|
-
| `anatomy`
|
|
39
|
-
| `states`
|
|
40
|
-
| `lifecycle`
|
|
41
|
-
| `tokenBindings`
|
|
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
|
+
| `tokenBindings` | array | Tokens this component uses — see [Token bindings](#token-bindings) (Phase 6.7). |
|
|
42
|
+
| `documentBlocks` | array | Typed prose blocks for this component — see [Document blocks](#document-blocks) (Phase 9). |
|
|
42
43
|
|
|
43
44
|
**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.
|
|
44
45
|
|
|
@@ -349,3 +350,34 @@ A complete button component declaration:
|
|
|
349
350
|
}
|
|
350
351
|
}
|
|
351
352
|
```
|
|
353
|
+
|
|
354
|
+
## Document blocks
|
|
355
|
+
|
|
356
|
+
**Phase 9.** Component declarations MAY carry a `documentBlocks` array at the top level, and individual anatomy parts MAY carry their own `documentBlocks` arrays. See [spec/document-blocks.md](document-blocks.md) for the full block schema, type vocabulary, and SPEC rules.
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
{
|
|
360
|
+
"name": "button",
|
|
361
|
+
"displayName": "Button",
|
|
362
|
+
"meta": { "category": "actions", "documentationUrl": "https://spectrum.adobe.com/page/button/" },
|
|
363
|
+
"documentBlocks": [
|
|
364
|
+
{
|
|
365
|
+
"type": "purpose",
|
|
366
|
+
"content": "Buttons trigger a discrete action or event.",
|
|
367
|
+
"agents": "Use Button when the user must trigger an action. For navigation, use Link."
|
|
368
|
+
}
|
|
369
|
+
],
|
|
370
|
+
"anatomy": [
|
|
371
|
+
{
|
|
372
|
+
"name": "label",
|
|
373
|
+
"required": true,
|
|
374
|
+
"documentBlocks": [
|
|
375
|
+
{
|
|
376
|
+
"type": "guideline",
|
|
377
|
+
"content": "Button labels should be action verbs (Save, Delete, Submit)."
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
]
|
|
382
|
+
}
|
|
383
|
+
```
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Document blocks
|
|
2
|
+
|
|
3
|
+
**Spec version:** `1.0.0-draft` (see [Overview](index.md))
|
|
4
|
+
|
|
5
|
+
This document defines **document blocks**: typed prose objects attachable to tokens, components, and anatomy parts. Blocks carry design guidance — intent, usage rules, accessibility notes, do/don't pairs, and examples — alongside the structured data they describe, making that guidance machine-readable and queryable by agents.
|
|
6
|
+
|
|
7
|
+
Design guidance like "accent backgrounds are for primary CTAs only" or "don't combine `negative` with `subtle`" previously lived in scattered Markdown documents invisible to the spec's resolver, validator, and agent surface. Document blocks attach that prose directly to the entities it describes so it cascades with the tokens and components it governs.
|
|
8
|
+
|
|
9
|
+
Inspired by the [Design System Documentation Spec (DSDS)](https://designsystemdocspec.org/) document-block model.
|
|
10
|
+
|
|
11
|
+
Scoped under RFC-D / Phase 9. See [rfc-coordination.md](../docs/rfc-coordination.md).
|
|
12
|
+
|
|
13
|
+
## Document block shape
|
|
14
|
+
|
|
15
|
+
A document block is a JSON object conforming to [`document-block.schema.json`](../schemas/document-block.schema.json).
|
|
16
|
+
|
|
17
|
+
### Required fields
|
|
18
|
+
|
|
19
|
+
| Field | Type | Description |
|
|
20
|
+
| --------- | ------ | ---------------------------------------- |
|
|
21
|
+
| `type` | string | Block type — one of the five types below |
|
|
22
|
+
| `content` | string | Human-readable prose for this block |
|
|
23
|
+
|
|
24
|
+
### Optional fields
|
|
25
|
+
|
|
26
|
+
| Field | Type | Description |
|
|
27
|
+
| -------- | ------ | ----------------------------------------------------------- |
|
|
28
|
+
| `agents` | string | LLM-tuned rephrasing of `content` for agent consumption |
|
|
29
|
+
| `do` | string | Recommended practice — meaningful only on `do-dont` blocks |
|
|
30
|
+
| `dont` | string | Anti-pattern to avoid — meaningful only on `do-dont` blocks |
|
|
31
|
+
|
|
32
|
+
**NORMATIVE:** `type` and `content` are required on every document block. A block with an empty string for either field **MUST** fail Layer 1 schema validation.
|
|
33
|
+
|
|
34
|
+
**NORMATIVE:** `do` and `dont` are defined on all block shapes (Layer 1 does not restrict them by type), but implementations SHOULD treat them as meaningful only on `do-dont` blocks. Using them on other block types is valid but has no defined semantics.
|
|
35
|
+
|
|
36
|
+
**RECOMMENDED:** When `agents` is present, its content SHOULD differ meaningfully from `content`. An `agents` value identical to `content` provides no agent-specific value and SHOULD be omitted or refined (see SPEC-028).
|
|
37
|
+
|
|
38
|
+
## Block types
|
|
39
|
+
|
|
40
|
+
### `purpose`
|
|
41
|
+
|
|
42
|
+
Describes the intent and design role of the entity. Answers "what is this for?"
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"type": "purpose",
|
|
47
|
+
"content": "Accent background tokens represent the primary brand call-to-action surface. They establish hierarchy by drawing attention to the most important interactive element on screen.",
|
|
48
|
+
"agents": "Use accent-background tokens on the highest-priority interactive element. They signal 'primary action here' to users."
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### `guideline`
|
|
53
|
+
|
|
54
|
+
A usage rule or constraint. Answers "how should this be used?"
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"type": "guideline",
|
|
59
|
+
"content": "Accent backgrounds should appear on no more than one element per focal area. Multiple accent surfaces compete for attention and dilute the hierarchy signal."
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `accessibility`
|
|
64
|
+
|
|
65
|
+
Accessibility notes specific to this entity — contrast behavior, screen reader considerations, or interaction semantics.
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"type": "accessibility",
|
|
70
|
+
"content": "Accent background tokens must maintain a minimum 3:1 contrast ratio against the surface they sit on in both light and dark schemes. The high-contrast dimension variant provides an alternative that meets 4.5:1."
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `do-dont`
|
|
75
|
+
|
|
76
|
+
A paired recommended practice and anti-pattern. The `do` and `dont` fields carry the pairing; `content` provides context or a summary heading.
|
|
77
|
+
|
|
78
|
+
**NORMATIVE:** A `do-dont` block **MUST** include at least one of `do` or `dont`. A `do-dont` block with neither field **MUST** fail Layer 1 schema validation.
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"type": "do-dont",
|
|
83
|
+
"content": "Combining semantic backgrounds",
|
|
84
|
+
"do": "Use accent-background for the primary CTA and informative-background for supporting UI.",
|
|
85
|
+
"dont": "Combine accent-background with negative-background in the same focal area — both are high-attention surfaces and the pairing creates visual conflict."
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `examples`
|
|
90
|
+
|
|
91
|
+
Concrete usage examples — code snippets, component references, or scenario descriptions.
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"type": "examples",
|
|
96
|
+
"content": "A primary Button uses accent-background-color-default. A disabled Button uses gray-background-color-default. A destructive Button uses negative-background-color-default."
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Attachment points
|
|
101
|
+
|
|
102
|
+
**NORMATIVE:** Document blocks MAY be attached to the following entities. When `documentBlocks` is present, it **MUST** contain at least one block — an empty array **MUST** fail Layer 1 schema validation.
|
|
103
|
+
|
|
104
|
+
### Tokens
|
|
105
|
+
|
|
106
|
+
Add a `documentBlocks` array at the top level of a token object:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"name": { "property": "background-color", "variant": "accent" },
|
|
111
|
+
"value": "#0265DC",
|
|
112
|
+
"documentBlocks": [
|
|
113
|
+
{
|
|
114
|
+
"type": "purpose",
|
|
115
|
+
"content": "Primary call-to-action background. Use for the most important interactive element in a focal area."
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"type": "guideline",
|
|
119
|
+
"content": "Limit to one accent background per focal area to preserve hierarchy."
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Components
|
|
126
|
+
|
|
127
|
+
Add a `documentBlocks` array at the top level of a component declaration:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"name": "button",
|
|
132
|
+
"displayName": "Button",
|
|
133
|
+
"meta": { "category": "actions", "documentationUrl": "https://spectrum.adobe.com/page/button/" },
|
|
134
|
+
"documentBlocks": [
|
|
135
|
+
{
|
|
136
|
+
"type": "purpose",
|
|
137
|
+
"content": "Buttons trigger an action or event, such as submitting a form, opening a dialog, or performing a destructive operation.",
|
|
138
|
+
"agents": "Use Button when the user needs to trigger a discrete action. For navigation, use a Link instead."
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Anatomy parts
|
|
145
|
+
|
|
146
|
+
Add a `documentBlocks` array within an anatomy part object:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"name": "label",
|
|
151
|
+
"required": true,
|
|
152
|
+
"description": "Button text visible to the user.",
|
|
153
|
+
"documentBlocks": [
|
|
154
|
+
{
|
|
155
|
+
"type": "guideline",
|
|
156
|
+
"content": "Button labels should be action verbs (Save, Delete, Submit). Avoid noun-only labels like 'Confirmation'."
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## SPEC rules
|
|
163
|
+
|
|
164
|
+
| Rule ID | Severity | Name | Assert |
|
|
165
|
+
| -------- | -------- | ------------------------------------ | ------------------------------------------------------------------------ |
|
|
166
|
+
| SPEC-028 | warning | document-block-agents-equals-content | A block's `agents` field SHOULD differ from `content` |
|
|
167
|
+
| SPEC-029 | warning | document-block-missing-purpose | An entity with `documentBlocks` SHOULD have at least one `purpose` block |
|
|
168
|
+
|
|
169
|
+
Both rules are `warning` severity — they do not block validation.
|
|
170
|
+
|
|
171
|
+
## `agents` field guidance
|
|
172
|
+
|
|
173
|
+
The `agents` field exists to let documentation authors provide LLM-optimized phrasing alongside human prose. Human content may use visual formatting cues, assumed visual context, or prose conventions that agents process poorly. The `agents` field carries alternative phrasing tuned for programmatic consumption.
|
|
174
|
+
|
|
175
|
+
**RECOMMENDED:** `agents` text SHOULD:
|
|
176
|
+
|
|
177
|
+
* Omit references to visual appearance that agents cannot act on ("the blue button")
|
|
178
|
+
* Use explicit, unambiguous phrasing ("Use Button when triggering an action, not Link")
|
|
179
|
+
* Include the token or component name explicitly rather than relying on surrounding context
|
|
180
|
+
* Be shorter and more directive than `content` where possible
|
|
181
|
+
|
|
182
|
+
When no agent-specific rephrasing is needed, omit the `agents` field entirely. A duplicate of `content` adds size with no benefit.
|
package/spec/index.md
CHANGED
|
@@ -12,14 +12,17 @@ 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
|
-
|
|
16
|
-
|
|
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
18
|
5. **Dimensions** — declared modes, defaults, and coverage expectations ([Dimensions](dimensions.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. **
|
|
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
|
+
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)).
|
|
24
|
+
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)).
|
|
25
|
+
12. **Evolution** — deprecation lifecycle, migration windows, change classification, and legacy format contract ([Evolution](evolution.md)).
|
|
23
26
|
|
|
24
27
|
## Conformance
|
|
25
28
|
|
|
@@ -53,20 +56,23 @@ Full governance (compatibility tiers, migration, CLI `--spec-version`) is discus
|
|
|
53
56
|
|
|
54
57
|
## Normative references (sibling documents)
|
|
55
58
|
|
|
56
|
-
| Document
|
|
57
|
-
|
|
|
58
|
-
| [Token format](token-format.md)
|
|
59
|
-
| [Taxonomy](taxonomy.md)
|
|
60
|
-
| [Component format](component-format.md)
|
|
61
|
-
| [Anatomy format](anatomy-format.md)
|
|
62
|
-
| [State model](state-model.md)
|
|
63
|
-
| [Cascade](cascade.md)
|
|
64
|
-
| [Dimensions](dimensions.md)
|
|
65
|
-
| [Manifest](manifest.md)
|
|
66
|
-
| [Product context](product-context.md)
|
|
67
|
-
| [Diff](diff.md)
|
|
68
|
-
| [Query](query.md)
|
|
69
|
-
| [
|
|
59
|
+
| Document | Role |
|
|
60
|
+
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
61
|
+
| [Token format](token-format.md) | Token `name`, `value` / `$ref`, value types, lifecycle metadata. |
|
|
62
|
+
| [Taxonomy](taxonomy.md) | Concept categories, vocabulary, formatting, anatomy vs objects. |
|
|
63
|
+
| [Component format](component-format.md) | Component declaration: options, slots, anatomy (→ anatomy-format.md), states (→ state-model.md), lifecycle. |
|
|
64
|
+
| [Anatomy format](anatomy-format.md) | Anatomy part declarations: field constraints, canonical vocabulary, SPEC-020/SPEC-023/SPEC-024/SPEC-025. |
|
|
65
|
+
| [State model](state-model.md) | State declarations: trigger semantics, precedence algorithm, canonical vocabulary, SPEC-022/SPEC-026. |
|
|
66
|
+
| [Cascade](cascade.md) | Layers, specificity, resolution algorithm. |
|
|
67
|
+
| [Dimensions](dimensions.md) | Dimension declarations, built-in dimensions, coverage. |
|
|
68
|
+
| [Manifest](manifest.md) | Platform manifest fields and validation expectations. |
|
|
69
|
+
| [Product context](product-context.md) | Product-layer context document: rationale, overrides, and extensions. |
|
|
70
|
+
| [Diff](diff.md) | Semantic diff change taxonomy, token identity, property changes. |
|
|
71
|
+
| [Query](query.md) | Filter notation for selecting tokens by structured fields. |
|
|
72
|
+
| [Accessibility](accessibility.md) | Component accessibility vocabulary: role, intents, focusable, keyboardIntents, wcag, and state-level AT fields (SPEC-030/031). |
|
|
73
|
+
| [Document blocks](document-blocks.md) | Typed prose blocks (purpose, guideline, accessibility, do-dont, examples) attachable to any entity. |
|
|
74
|
+
| [Agent-readable surface](agent-surface.md) | Transport contracts (CLI, MCP, Agent Skill) and operation catalog for AI agents consuming spec-conformant design data. |
|
|
75
|
+
| [Evolution](evolution.md) | Deprecation lifecycle, migration windows, change classification. |
|
|
70
76
|
|
|
71
77
|
## JSON Schema `$id` and versioning
|
|
72
78
|
|