@adobe/design-data-spec 0.0.1 → 0.1.1
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/LICENSE +201 -0
- package/conformance/README.md +83 -10
- package/conformance/diff/cross-format/expected.json +27 -0
- package/conformance/diff/cross-format/new/tokens.tokens.json +8 -0
- package/conformance/diff/cross-format/old/tokens.json +7 -0
- package/conformance/diff/deprecated-new-token/expected.json +13 -0
- package/conformance/diff/deprecated-new-token/new/tokens.tokens.json +8 -0
- package/conformance/diff/deprecated-new-token/old/tokens.tokens.json +1 -0
- package/conformance/diff/deprecated-set-level/expected.json +13 -0
- package/conformance/diff/deprecated-set-level/new/tokens.tokens.json +10 -0
- package/conformance/diff/deprecated-set-level/old/tokens.tokens.json +1 -0
- package/conformance/diff/identical-tokens/expected.json +8 -0
- package/conformance/diff/identical-tokens/new/tokens.tokens.json +12 -0
- package/conformance/diff/identical-tokens/old/tokens.tokens.json +12 -0
- package/conformance/diff/matched-gaining-deprecated/expected.json +20 -0
- package/conformance/diff/matched-gaining-deprecated/new/tokens.tokens.json +8 -0
- package/conformance/diff/matched-gaining-deprecated/old/tokens.tokens.json +7 -0
- package/conformance/diff/property-nested-change/expected.json +27 -0
- package/conformance/diff/property-nested-change/new/tokens.tokens.json +10 -0
- package/conformance/diff/property-nested-change/old/tokens.tokens.json +10 -0
- package/conformance/diff/property-value-update/expected.json +21 -0
- package/conformance/diff/property-value-update/new/tokens.tokens.json +7 -0
- package/conformance/diff/property-value-update/old/tokens.tokens.json +7 -0
- package/conformance/diff/rename-by-uuid/expected.json +22 -0
- package/conformance/diff/rename-by-uuid/new/tokens.tokens.json +7 -0
- package/conformance/diff/rename-by-uuid/old/tokens.tokens.json +7 -0
- package/conformance/diff/rename-with-property-changes/expected.json +28 -0
- package/conformance/diff/rename-with-property-changes/new/tokens.tokens.json +7 -0
- package/conformance/diff/rename-with-property-changes/old/tokens.tokens.json +7 -0
- package/conformance/diff/replaced-by-pairing/expected.json +43 -0
- package/conformance/diff/replaced-by-pairing/new/tokens.tokens.json +7 -0
- package/conformance/diff/replaced-by-pairing/old/tokens.tokens.json +10 -0
- package/conformance/diff/reverted-token/expected.json +13 -0
- package/conformance/diff/reverted-token/new/tokens.tokens.json +7 -0
- package/conformance/diff/reverted-token/old/tokens.tokens.json +8 -0
- package/conformance/diff/simple-add-delete/expected.json +18 -0
- package/conformance/diff/simple-add-delete/new/tokens.tokens.json +7 -0
- package/conformance/diff/simple-add-delete/old/tokens.tokens.json +7 -0
- package/conformance/diff/uuid-backfill/expected.json +20 -0
- package/conformance/diff/uuid-backfill/new/tokens.tokens.json +7 -0
- package/conformance/diff/uuid-backfill/old/tokens.tokens.json +6 -0
- package/conformance/invalid/SPEC-008/dimension.json +5 -0
- package/conformance/invalid/SPEC-008/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-008/tokens.tokens.json +15 -0
- package/conformance/invalid/SPEC-010/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-010/tokens.tokens.json +9 -0
- package/conformance/invalid/SPEC-011/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-011/tokens.tokens.json +22 -0
- package/conformance/invalid/SPEC-012/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-012/tokens.tokens.json +13 -0
- package/conformance/invalid/SPEC-013/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-013/tokens.tokens.json +8 -0
- package/conformance/invalid/SPEC-014/expected-errors.json +10 -0
- package/conformance/invalid/SPEC-014/tokens.tokens.json +9 -0
- package/conformance/query/and-conditions/expected.json +1 -0
- package/conformance/query/and-conditions/input/tokens.tokens.json +17 -0
- package/conformance/query/and-conditions/query.txt +1 -0
- package/conformance/query/and-or-precedence/expected.json +1 -0
- package/conformance/query/and-or-precedence/input/tokens.tokens.json +22 -0
- package/conformance/query/and-or-precedence/query.txt +1 -0
- package/conformance/query/empty-matches-all/expected.json +1 -0
- package/conformance/query/empty-matches-all/input/tokens.tokens.json +17 -0
- package/conformance/query/empty-matches-all/query.txt +1 -0
- package/conformance/query/negation/expected.json +1 -0
- package/conformance/query/negation/input/tokens.tokens.json +17 -0
- package/conformance/query/negation/query.txt +1 -0
- package/conformance/query/no-matches/expected.json +1 -0
- package/conformance/query/no-matches/input/tokens.tokens.json +7 -0
- package/conformance/query/no-matches/query.txt +1 -0
- package/conformance/query/or-conditions/expected.json +1 -0
- package/conformance/query/or-conditions/input/tokens.tokens.json +17 -0
- package/conformance/query/or-conditions/query.txt +1 -0
- package/conformance/query/schema-key/expected.json +1 -0
- package/conformance/query/schema-key/input/tokens.tokens.json +14 -0
- package/conformance/query/schema-key/query.txt +1 -0
- package/conformance/query/single-field/expected.json +1 -0
- package/conformance/query/single-field/input/tokens.tokens.json +17 -0
- package/conformance/query/single-field/query.txt +1 -0
- package/conformance/query/wildcard-prefix/expected.json +1 -0
- package/conformance/query/wildcard-prefix/input/tokens.tokens.json +17 -0
- package/conformance/query/wildcard-prefix/query.txt +1 -0
- package/conformance/query/wildcard-suffix/expected.json +1 -0
- package/conformance/query/wildcard-suffix/input/tokens.tokens.json +17 -0
- package/conformance/query/wildcard-suffix/query.txt +1 -0
- package/conformance/resolution/alias-resolved-after-cascade/dimensions/color-scheme.json +5 -0
- package/conformance/resolution/alias-resolved-after-cascade/expected.json +5 -0
- package/conformance/resolution/alias-resolved-after-cascade/input/tokens.tokens.json +12 -0
- package/conformance/resolution/alias-resolved-after-cascade/query.json +4 -0
- package/conformance/resolution/base-fallback/dimensions/color-scheme.json +5 -0
- package/conformance/resolution/base-fallback/expected.json +5 -0
- package/conformance/resolution/base-fallback/input/tokens.tokens.json +7 -0
- package/conformance/resolution/base-fallback/query.json +4 -0
- package/conformance/resolution/specificity-wins/dimensions/color-scheme.json +5 -0
- package/conformance/resolution/specificity-wins/expected.json +5 -0
- package/conformance/resolution/specificity-wins/input/tokens.tokens.json +12 -0
- package/conformance/resolution/specificity-wins/query.json +4 -0
- package/conformance/valid/lifecycle-with-last-modified.json +12 -0
- package/fields/anatomy.json +15 -0
- package/fields/color-scheme.json +15 -0
- package/fields/component.json +15 -0
- package/fields/contrast.json +15 -0
- package/fields/density.json +15 -0
- package/fields/object.json +15 -0
- package/fields/orientation.json +15 -0
- package/fields/position.json +15 -0
- package/fields/property.json +15 -0
- package/fields/scale.json +15 -0
- package/fields/shape.json +15 -0
- package/fields/size.json +15 -0
- package/fields/state.json +15 -0
- package/fields/structure.json +15 -0
- package/fields/substructure.json +15 -0
- package/fields/variant.json +15 -0
- package/package.json +4 -3
- package/rules/rules.yaml +65 -2
- package/schemas/cascade-file.schema.json +10 -0
- package/schemas/field.schema.json +85 -0
- package/schemas/manifest.schema.json +55 -1
- package/schemas/token.schema.json +97 -18
- package/spec/cascade.md +18 -2
- package/spec/diff.md +97 -0
- package/spec/dimensions.md +15 -6
- package/spec/evolution.md +99 -0
- package/spec/index.md +11 -8
- package/spec/manifest.md +18 -1
- package/spec/query.md +135 -0
- package/spec/taxonomy.md +189 -0
- package/spec/token-format.md +118 -19
package/spec/query.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Query notation
|
|
2
|
+
|
|
3
|
+
**Spec version:** `1.0.0-draft` (see [Overview](index.md))
|
|
4
|
+
|
|
5
|
+
This document defines the **query filter notation**: a concise syntax for selecting tokens from a dataset by matching against structured token fields.
|
|
6
|
+
|
|
7
|
+
## Filter notation
|
|
8
|
+
|
|
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
|
+
|
|
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
|
+
|
|
19
|
+
## Supported keys
|
|
20
|
+
|
|
21
|
+
**NORMATIVE:** Implementations **MUST** support the following keys:
|
|
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). |
|
|
34
|
+
|
|
35
|
+
**NORMATIVE:** Implementations **MUST** reject filter expressions containing keys not listed above with a parse error. Future spec versions MAY add keys.
|
|
36
|
+
|
|
37
|
+
**RATIONALE:** Restricting keys to a known set ensures that typos are caught early and that all implementations agree on which fields are queryable. This also enables implementations to build indexes for supported keys.
|
|
38
|
+
|
|
39
|
+
## Formal grammar
|
|
40
|
+
|
|
41
|
+
The following EBNF defines the filter expression syntax:
|
|
42
|
+
|
|
43
|
+
```ebnf
|
|
44
|
+
filter-expr = or-expr ;
|
|
45
|
+
or-expr = and-expr { "|" and-expr } ;
|
|
46
|
+
and-expr = condition { "," condition } ;
|
|
47
|
+
condition = key operator value ;
|
|
48
|
+
key = (letter | "$") { letter | digit | "$" | "_" } ;
|
|
49
|
+
operator = "=" | "!=" ;
|
|
50
|
+
value = { value-char } ;
|
|
51
|
+
value-char = letter | digit | "-" | "_" | "." | "/" | ":" | "*" ;
|
|
52
|
+
letter = "A"-"Z" | "a"-"z" ;
|
|
53
|
+
digit = "0"-"9" ;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**NORMATIVE:** Whitespace around operators and delimiters is **NOT** significant and **MUST** be trimmed by the parser.
|
|
57
|
+
|
|
58
|
+
**NORMATIVE:** An empty filter expression **MUST** match all tokens (universal match).
|
|
59
|
+
|
|
60
|
+
## Operator precedence
|
|
61
|
+
|
|
62
|
+
**NORMATIVE:** The `,` (AND) operator binds more tightly than `|` (OR).
|
|
63
|
+
|
|
64
|
+
The expression `a=x,b=y|c=z` is equivalent to `(a=x AND b=y) OR (c=z)`.
|
|
65
|
+
|
|
66
|
+
**NORMATIVE:** Parentheses for grouping are **NOT** supported in `1.0.0-draft`. Implementations **MUST** reject parentheses with a parse error.
|
|
67
|
+
|
|
68
|
+
**RATIONALE:** Avoiding parentheses keeps the notation simple and shell-friendly. Most practical queries are either pure AND or pure OR; mixed expressions with the defined precedence cover the remaining common cases.
|
|
69
|
+
|
|
70
|
+
## Evaluation semantics
|
|
71
|
+
|
|
72
|
+
**NORMATIVE:** A filter expression is evaluated independently against each token in the dataset. A token is included in the result if and only if the expression evaluates to `true` for that token.
|
|
73
|
+
|
|
74
|
+
**NORMATIVE:** For equality (`=`), a condition matches when the token's field value equals the specified value. If the token does not have the field, the condition does **NOT** match.
|
|
75
|
+
|
|
76
|
+
**NORMATIVE:** For negation (`!=`), a condition matches when the token's field value does not equal the specified value **OR** the field is absent. A missing field satisfies `!=`.
|
|
77
|
+
|
|
78
|
+
**RATIONALE:** Negation matching absent fields follows the convention that "not equal to X" includes "does not exist" — the same semantics as label selectors in Kubernetes and CSS attribute selectors.
|
|
79
|
+
|
|
80
|
+
## Glob matching
|
|
81
|
+
|
|
82
|
+
**NORMATIVE:** The `*` character in a value is a **glob wildcard** matching zero or more characters.
|
|
83
|
+
|
|
84
|
+
**NORMATIVE:** Glob matching is **case-sensitive**.
|
|
85
|
+
|
|
86
|
+
**NORMATIVE:** Multiple `*` characters in a single value are permitted and each independently matches zero or more characters.
|
|
87
|
+
|
|
88
|
+
**NORMATIVE:** To match a literal `*` character, there is no escape mechanism in `1.0.0-draft`. Future versions MAY define one.
|
|
89
|
+
|
|
90
|
+
## Examples
|
|
91
|
+
|
|
92
|
+
### Select all tokens for a specific component
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
component=button
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Matches tokens whose `name.component` is `"button"`.
|
|
99
|
+
|
|
100
|
+
### Select tokens matching multiple criteria
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
component=button,state=hover
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Matches tokens where `name.component` is `"button"` **AND** `name.state` is `"hover"`.
|
|
107
|
+
|
|
108
|
+
### Select tokens for either of two properties
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
property=background-color|property=border-color
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Matches tokens whose `name.property` is `"background-color"` **OR** `"border-color"`.
|
|
115
|
+
|
|
116
|
+
### Select color tokens using wildcard
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
property=color-*
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Matches tokens whose `name.property` starts with `"color-"` (e.g. `color-default`, `color-hover`).
|
|
123
|
+
|
|
124
|
+
### Exclude a specific color scheme
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
component=button,colorScheme!=light
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Matches button tokens that are **not** in the `light` color scheme. Tokens without a `colorScheme` field also match (absent field satisfies `!=`).
|
|
131
|
+
|
|
132
|
+
## References
|
|
133
|
+
|
|
134
|
+
* [#714 — Design Data Specification](https://github.com/adobe/spectrum-design-data/discussions/714)
|
|
135
|
+
* [#777 — Phase 3: Query notation definition](https://github.com/adobe/spectrum-design-data/issues/777)
|
package/spec/taxonomy.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Taxonomy
|
|
2
|
+
|
|
3
|
+
**Spec version:** `1.0.0-draft` (see [Overview](index.md))
|
|
4
|
+
|
|
5
|
+
This document defines the **token taxonomy**: a hierarchical system of concept categories that classify design tokens, the **token term vocabulary** of allowed words within each category, and the **formatting style** rules that control serialization of structured token names into platform-consumable strings.
|
|
6
|
+
|
|
7
|
+
## Motivation
|
|
8
|
+
|
|
9
|
+
"Naming convention" is too broad a term when discussing malleability across platform teams. A token name like `accent-background-color-hover` embeds multiple independent decisions:
|
|
10
|
+
|
|
11
|
+
1. **Which concepts** are represented and in what hierarchy (taxonomy).
|
|
12
|
+
2. **Which words** describe each concept (vocabulary).
|
|
13
|
+
3. **How the words are rendered** — casing, delimiters, abbreviations, concept order (formatting).
|
|
14
|
+
|
|
15
|
+
Each layer has a different malleability profile: the taxonomy is shared across all platforms; the vocabulary is shared with platform-aware compromises; the formatting is platform-malleable.
|
|
16
|
+
|
|
17
|
+
## Three layers of naming
|
|
18
|
+
|
|
19
|
+
### Layer 1: Token taxonomy
|
|
20
|
+
|
|
21
|
+
A **token taxonomy** is a hierarchical set of concept categories for classifying design ideas and use cases. It creates a clear, consistent, and predictable shared language across disciplines and teams.
|
|
22
|
+
|
|
23
|
+
The taxonomy is **NORMATIVE** and **shared** — all platforms use the same concept categories in the same hierarchy. Changing the taxonomy changes the meaning of token names across the entire ecosystem.
|
|
24
|
+
|
|
25
|
+
Taxonomies are **scoped to specific token types** for clarity. The semantic/layout taxonomy defined in this document is one such scope; additional taxonomies (e.g. for color tokens) will be defined in future spec versions.
|
|
26
|
+
|
|
27
|
+
### Layer 2: Token term vocabulary
|
|
28
|
+
|
|
29
|
+
The **token term vocabulary** is the set of specific words used to describe each conceptual option within the taxonomy. The vocabulary creates a shared language across disciplines and teams.
|
|
30
|
+
|
|
31
|
+
The vocabulary is **NORMATIVE at the foundation level** — the foundation defines canonical terms. Platforms **MAY** declare vocabulary mappings (e.g. `hover` → `highlighted` for iOS) in their [manifest](manifest.md) for platform-specific consumption.
|
|
32
|
+
|
|
33
|
+
### Layer 3: Formatting style
|
|
34
|
+
|
|
35
|
+
**Formatting style** defines rules for altering the appearance of a token's name for platform-specific consumption and usability needs. This includes concept ordering, casing, delimiters, and abbreviations.
|
|
36
|
+
|
|
37
|
+
Formatting is **platform-malleable** — each platform manifest **MAY** declare its own formatting rules. The foundation defines a default formatting style for legacy compatibility.
|
|
38
|
+
|
|
39
|
+
**NORMATIVE:** The name object defined in [Token format](token-format.md) is unordered structured data. Concept ordering is purely a serialization concern and **MUST NOT** affect cascade resolution, specificity, or validation.
|
|
40
|
+
|
|
41
|
+
## Principles
|
|
42
|
+
|
|
43
|
+
The taxonomy is designed with three guiding principles:
|
|
44
|
+
|
|
45
|
+
1. **Object-oriented** — Designers and developers think in terms of how they would construct components, rather than abstract semantic ideas.
|
|
46
|
+
2. **Agnostic (with compromises)** — Platform-agnostic terms are used except when platforms have specific terms for the same concept. In those cases, the most common or clear term is used.
|
|
47
|
+
3. **Verified** — Multiple existing components must be rebuildable using the taxonomy system, and consumers must find them reasonably understandable or learnable.
|
|
48
|
+
|
|
49
|
+
## Semantic / layout token taxonomy
|
|
50
|
+
|
|
51
|
+
Concept categories for name-object fields are declared in the design system's **field catalog** — a set of field declarations in the `fields/` directory, each conforming to [`field.schema.json`](../schemas/field.schema.json). Each declaration specifies the field name, vocabulary registry, validation severity, and default serialization position.
|
|
52
|
+
|
|
53
|
+
**NORMATIVE:** The field catalog is the authoritative source for what fields exist on the name object. Tools, validators, and serializers **SHOULD** read the catalog rather than hardcoding field knowledge.
|
|
54
|
+
|
|
55
|
+
The following concept categories are defined in Spectrum's foundation field catalog for semantic and layout tokens, ordered by default serialization position. This ordering is the **default serialization order** for legacy format output; it is not a conformance requirement for stored name objects.
|
|
56
|
+
|
|
57
|
+
**NORMATIVE:** Each category listed below corresponds to an OPTIONAL field on the token [name object](token-format.md). Tokens **MAY** use any subset of these fields.
|
|
58
|
+
|
|
59
|
+
| Category | Name object field | Answers | Description |
|
|
60
|
+
| ------------- | ----------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
61
|
+
| Structure | `structure` | What? | Individual objects or object categories that have shared styling. Distinctly different from "components" in that they represent structures and visual patterns that can or do occur across many varieties of components. |
|
|
62
|
+
| Sub-structure | `substructure` | What? | A structure within an element that should only exist within the context of its parent structure. |
|
|
63
|
+
| Component | `component` | What? | Component scope when the token is component-scoped. |
|
|
64
|
+
| Anatomy | `anatomy` | What? | A visible, named part of a component as defined by designers. |
|
|
65
|
+
| Object | `object` | Where? | The styling surface to which a visual property is applied (e.g. background, border, edge). |
|
|
66
|
+
| Property | `property` | Where? | The stylistic attribute being defined (e.g. color, width, padding, gap). |
|
|
67
|
+
| Orientation | `orientation` | When/Why? | The direction or order of structures and elements within a component or pattern. |
|
|
68
|
+
| Position | `position` | When/Why? | The location of an object relative to another, with or without respect to directional order. |
|
|
69
|
+
| Size | `size` | When/Why? | Relative terms used to create relationships and patterns of usage across multiple tokens and token types. |
|
|
70
|
+
| Density | `density` | When/Why? | Options that create more or less space within or around the parts of a component. |
|
|
71
|
+
| Shape | `shape` | When/Why? | Relative to the overall shape of a component (e.g. "uniform" creates a 1:1 padding ratio between horizontal and vertical padding). |
|
|
72
|
+
|
|
73
|
+
Additional categories for variant and state are inherited from the existing name object:
|
|
74
|
+
|
|
75
|
+
| Category | Name object field | Description |
|
|
76
|
+
| -------- | ----------------- | ------------------------------------------------------------ |
|
|
77
|
+
| Variant | `variant` | Variant within a component (e.g. accent, negative, primary). |
|
|
78
|
+
| State | `state` | Interactive or semantic state (e.g. hover, focus, disabled). |
|
|
79
|
+
|
|
80
|
+
**NOTE:** The categories above are filtered for semantic and layout token taxonomies. Additional taxonomies for other token types (color, typography, motion) will be defined in future spec versions — see the open follow-up RFC discussion [#806](https://github.com/adobe/spectrum-design-data/discussions/806) (Q3, taxonomy scoping). The taxonomy is built to scale as new concepts and terms are identified.
|
|
81
|
+
|
|
82
|
+
### Structure vs. component — when does the line move?
|
|
83
|
+
|
|
84
|
+
The `structure` and `component` fields both answer "What?" but apply at different scopes. A useful rule of thumb:
|
|
85
|
+
|
|
86
|
+
* Use `component` when the token belongs to a specific component's surface (e.g. `button-background-color` — the background color of the Button component).
|
|
87
|
+
* Use `structure` when the token belongs to a reusable visual pattern that recurs **across** components (e.g. `container-padding` — padding for any container-shaped surface, regardless of which component owns it).
|
|
88
|
+
|
|
89
|
+
**Worked example — `card`:**
|
|
90
|
+
|
|
91
|
+
* As a `structure`: when "card" describes a layout primitive used inside many components (e.g. `card-padding-medium` on a list item, a popover body, or a modal header), the token is structure-scoped.
|
|
92
|
+
* As a `component`: when "card" describes the dedicated Card component's own surfaces (e.g. `card-background-color` on the Card root), the token is component-scoped.
|
|
93
|
+
|
|
94
|
+
The same word can validly appear in both fields across the dataset; they are independent. Authors choose based on whether the token's *meaning* generalizes across many components (structure) or is specific to one component's identity (component).
|
|
95
|
+
|
|
96
|
+
Source: Nate Baldwin, "Naming conventions & shared taxonomy" — Design Data & Platforms onsite, April 1, 2026.
|
|
97
|
+
|
|
98
|
+
## Component anatomy vs. token objects
|
|
99
|
+
|
|
100
|
+
Two concepts that are often conflated but serve different purposes:
|
|
101
|
+
|
|
102
|
+
### Component anatomy
|
|
103
|
+
|
|
104
|
+
**Component anatomy** refers to the visible, named parts of a component as defined by designers. These are the parts called out in component specification diagrams (e.g. icon, label, track, handle, hold icon).
|
|
105
|
+
|
|
106
|
+
Component anatomy is declared per component in [component schemas](../../component-schemas/) and validated against the anatomy registry. A token referencing a component's anatomy part (e.g. `slider` + `handle`) can be validated as a legitimate combination.
|
|
107
|
+
|
|
108
|
+
Anatomy parts fall into three tiers:
|
|
109
|
+
|
|
110
|
+
| Tier | Description | Examples |
|
|
111
|
+
| ------------------ | -------------------------------------- | ------------------------------------------------------------- |
|
|
112
|
+
| Primitive | Reusable across many components | icon, label, track, handle, fill, divider, title, description |
|
|
113
|
+
| Composite | Another component used as a named part | checkbox, close button, popover, avatar |
|
|
114
|
+
| Component-specific | Unique to one component | loupe, gripper, opacity checkerboard |
|
|
115
|
+
|
|
116
|
+
### Token objects (styling surfaces)
|
|
117
|
+
|
|
118
|
+
**Token objects** (or styling surfaces) describe *where* a visual property is applied on a UI element. These are NOT anatomy — they are abstract styling targets that exist on any element regardless of its component type.
|
|
119
|
+
|
|
120
|
+
| Object | Description |
|
|
121
|
+
| ------------ | ----------------------------------------------------- |
|
|
122
|
+
| `background` | Background surface or fill |
|
|
123
|
+
| `border` | Border or outline |
|
|
124
|
+
| `edge` | Outer boundary of component (used in spacing tokens) |
|
|
125
|
+
| `visual` | Visible graphic element area (may be inset from edge) |
|
|
126
|
+
| `content` | Main content area |
|
|
127
|
+
|
|
128
|
+
Token objects are stored in a separate registry from anatomy parts. Both may appear in the same token name — e.g. a token for the background color of a slider's handle would reference anatomy `handle` and object `background`.
|
|
129
|
+
|
|
130
|
+
## Name object field categories
|
|
131
|
+
|
|
132
|
+
Name object fields fall into two categories with different validation behavior:
|
|
133
|
+
|
|
134
|
+
### Semantic fields
|
|
135
|
+
|
|
136
|
+
Semantic fields describe identity, structure, and intent. They are used for querying and organization but do **not** participate in cascade resolution or specificity calculation.
|
|
137
|
+
|
|
138
|
+
**NORMATIVE:** Semantic field values are validated against their declared vocabulary registry with the severity specified in the field declaration (typically **advisory** — warning, not error). Values not in the registry are permitted but flagged.
|
|
139
|
+
|
|
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
|
+
|
|
142
|
+
### Dimension fields
|
|
143
|
+
|
|
144
|
+
Dimension fields represent axes of variation that drive the [cascade](cascade.md) resolution algorithm and [specificity](cascade.md#semantic-specificity) calculation.
|
|
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.
|
|
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`.
|
|
149
|
+
|
|
150
|
+
See [Dimensions](dimensions.md) for dimension declarations, modes, and defaults.
|
|
151
|
+
|
|
152
|
+
## Default serialization (legacy format)
|
|
153
|
+
|
|
154
|
+
The **default serialization** produces a kebab-case string from the name object by ordering fields according to their `serialization.position` values (ascending) as declared in the field catalog. Omitted fields are skipped.
|
|
155
|
+
|
|
156
|
+
For Spectrum's foundation catalog, this produces the following concept order:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
{variant}-{component}-{structure}-{substructure}-{anatomy}-{object}-{property}-{orientation}-{position}-{size}-{density}-{shape}-{state}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
All fields are independent — `variant` and `component` **MAY** both appear in the same token name (e.g. a token with `component: "button"` and `variant: "accent"` serializes as `accent-button-...`).
|
|
163
|
+
|
|
164
|
+
This ordering is preserved for backward compatibility with the current `@adobe/spectrum-tokens` package. It is a serialization convention, not a structural requirement.
|
|
165
|
+
|
|
166
|
+
**NORMATIVE:** A conforming formatter **MUST** produce deterministic output for a given name object and formatting configuration. Two name objects that differ only in field ordering **MUST** produce identical serialized strings.
|
|
167
|
+
|
|
168
|
+
## Platform formatting configuration
|
|
169
|
+
|
|
170
|
+
A platform [manifest](manifest.md) **MAY** declare formatting rules in its [`extensions.formatting`](manifest.md#extensionsformatting) section to control concept ordering, casing, delimiters, and abbreviations. The normative contract for these fields is defined in [Manifest — `extensions.formatting`](manifest.md#extensionsformatting).
|
|
171
|
+
|
|
172
|
+
When no platform formatting is declared, the default serialization above is used.
|
|
173
|
+
|
|
174
|
+
## Scalability
|
|
175
|
+
|
|
176
|
+
The taxonomy and terms are built to scale as new concepts and terms are identified:
|
|
177
|
+
|
|
178
|
+
* New concept categories **MAY** be added by creating a new field declaration file in the field catalog — no spec version change is required for the mechanism itself.
|
|
179
|
+
* New terms **MAY** be added to the vocabulary registry without spec version changes.
|
|
180
|
+
* New token type taxonomies (beyond semantic/layout) **MAY** be defined in future spec versions.
|
|
181
|
+
* Platform manifests **MAY** extend the vocabulary with platform-specific terms and formatting.
|
|
182
|
+
|
|
183
|
+
## References
|
|
184
|
+
|
|
185
|
+
* [#806 — Token Taxonomy, Vocabulary, and Formatting](https://github.com/adobe/spectrum-design-data/discussions/806)
|
|
186
|
+
* [#661 — Spectrum Design System Glossary](https://github.com/adobe/spectrum-design-data/discussions/661)
|
|
187
|
+
* [#646 — Token Schema Structure and Validation System](https://github.com/adobe/spectrum-design-data/discussions/646)
|
|
188
|
+
* [Manifest — `extensions.formatting`](manifest.md#extensionsformatting) — normative contract for platform formatting rules
|
|
189
|
+
* Nate Baldwin, "Naming conventions & shared taxonomy" — Design Data & Platforms onsite, April 1, 2026
|
package/spec/token-format.md
CHANGED
|
@@ -25,18 +25,40 @@ The **name object** identifies the token in a structured way. Implementations us
|
|
|
25
25
|
|
|
26
26
|
**NORMATIVE fields** (all string unless noted):
|
|
27
27
|
|
|
28
|
+
The set of available name-object fields is declared in the design system's **field catalog** (`fields/` directory). Each field declaration conforms to [`field.schema.json`](../schemas/field.schema.json) and specifies its kind (`semantic` or `dimension`), vocabulary registry, validation severity, and default serialization position. See [Taxonomy](taxonomy.md) for the full concept category hierarchy, component anatomy vs. token objects, and serialization rules.
|
|
29
|
+
|
|
30
|
+
Fields are divided into **semantic fields** (identity, structure, intent) and **dimension fields** (axes of variation for cascade resolution). The tables below list Spectrum's foundation-standard fields as declared in the catalog.
|
|
31
|
+
|
|
32
|
+
#### Semantic fields
|
|
33
|
+
|
|
34
|
+
| Field | Status | Taxonomy category | Description |
|
|
35
|
+
| -------------- | -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
36
|
+
| `property` | REQUIRED | Property | The stylistic attribute being defined (e.g. `color`, `width`, `padding`, `gap`). |
|
|
37
|
+
| `component` | OPTIONAL | Component | Component name when the token is component-scoped. |
|
|
38
|
+
| `structure` | OPTIONAL | Structure | Reusable visual pattern or object category (e.g. `base`, `container`, `list`, `accessory`). Distinct from `component`. |
|
|
39
|
+
| `substructure` | OPTIONAL | Sub-structure | A structure that only exists within its parent structure (e.g. `item` in `list-item`). |
|
|
40
|
+
| `anatomy` | OPTIONAL | Anatomy | A visible, named part of a component as defined by designers (e.g. `handle`, `icon`, `label`). See [Taxonomy — Component anatomy](taxonomy.md#component-anatomy). |
|
|
41
|
+
| `object` | OPTIONAL | Object | Styling surface to which a visual property is applied (e.g. `background`, `border`, `edge`). See [Taxonomy — Token objects](taxonomy.md#token-objects-styling-surfaces). |
|
|
42
|
+
| `variant` | OPTIONAL | Variant | Variant within a component (e.g. `accent`, `negative`, `primary`). |
|
|
43
|
+
| `state` | OPTIONAL | State | Interactive or semantic state (e.g. `hover`, `focus`, `disabled`). |
|
|
44
|
+
| `orientation` | OPTIONAL | Orientation | Direction or order of structures and elements (e.g. `vertical`, `horizontal`). |
|
|
45
|
+
| `position` | OPTIONAL | Position | Location of an object relative to another (e.g. `affixed`). |
|
|
46
|
+
| `size` | OPTIONAL | Size | Relative t-shirt sizing for relationships across tokens (e.g. `small`, `medium`, `large`). |
|
|
47
|
+
| `density` | OPTIONAL | Density | Space within or around component parts (e.g. `spacious`, `compact`). |
|
|
48
|
+
| `shape` | OPTIONAL | Shape | Relative to overall component shape (e.g. `uniform`). |
|
|
49
|
+
|
|
50
|
+
#### Dimension fields
|
|
51
|
+
|
|
28
52
|
| Field | Status | Description |
|
|
29
53
|
| --------------- | -------- | ----------------------------------------------------------------------------------------------- |
|
|
30
|
-
| `property` | REQUIRED | Stable property key (e.g. semantic role of the token). |
|
|
31
|
-
| `component` | OPTIONAL | Component name when the token is component-scoped. |
|
|
32
|
-
| `variant` | OPTIONAL | Variant within a component. |
|
|
33
|
-
| `state` | OPTIONAL | Interactive or semantic state. |
|
|
34
54
|
| `colorScheme` | OPTIONAL | Dimension: light / dark / wireframe / etc. |
|
|
35
|
-
| `scale` | OPTIONAL | Dimension:
|
|
36
|
-
| `contrast` | OPTIONAL | Dimension: contrast level.
|
|
55
|
+
| `scale` | OPTIONAL | Dimension: platform density scale (e.g. `desktop`, `mobile`). Distinct from semantic `size`. |
|
|
56
|
+
| `contrast` | OPTIONAL | Dimension: contrast level (e.g. `regular`, `high`). |
|
|
37
57
|
| Additional keys | OPTIONAL | Other dimensions declared in the dataset’s dimension catalog (see [Dimensions](dimensions.md)). |
|
|
38
58
|
|
|
39
|
-
**
|
|
59
|
+
**NORMATIVE:** Each field is validated according to the `validation` severity declared in its field declaration. Semantic fields typically use **advisory** severity (warning); dimension fields use **strict** severity (error). See [Taxonomy — Name object field categories](taxonomy.md#name-object-field-categories).
|
|
60
|
+
|
|
61
|
+
**RECOMMENDED:** Name objects use a consistent key ordering in authored files for diffs; this is not a conformance requirement. Concept ordering for serialized names is defined in [Taxonomy — Default serialization](taxonomy.md#default-serialization-legacy-format).
|
|
40
62
|
|
|
41
63
|
### Alias (`$ref`)
|
|
42
64
|
|
|
@@ -48,33 +70,110 @@ When **`value`** is present, it **MUST** conform to the declared value type for
|
|
|
48
70
|
|
|
49
71
|
### Lifecycle and metadata
|
|
50
72
|
|
|
51
|
-
The following OPTIONAL fields
|
|
73
|
+
The following OPTIONAL fields implement the token lifecycle model described in [#623](https://github.com/adobe/spectrum-design-data/discussions/623) and the evolution policy in [Evolution](evolution.md). Inspired by Swift's `@available` attribute, Kotlin's `@Deprecated`, and OpenAPI 3.3's deprecation model.
|
|
74
|
+
|
|
75
|
+
| Field | Type | Description |
|
|
76
|
+
| -------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
77
|
+
| `uuid` | string (UUID) | Stable unique id for rename tracking and diffs. |
|
|
78
|
+
| `introduced` | string (version) | Spec version when the token was first added (e.g. `"1.0.0"`). |
|
|
79
|
+
| `lastModified` | string (version) | Spec version when the token's value or metadata last changed (e.g. `"2.1.0"`). Updated on any non-formatting change. |
|
|
80
|
+
| `deprecated` | string (version) | Spec version when the token was deprecated (e.g. `"3.2.0"`). Truthy = deprecated. |
|
|
81
|
+
| `deprecated_comment` | string | Human-readable deprecation explanation and migration guidance. |
|
|
82
|
+
| `replaced_by` | string (UUID) or array of string (UUID) | UUID(s) of the replacement token(s). Single string for 1:1 replacement; array for one-to-many splits. |
|
|
83
|
+
| `plannedRemoval` | string (version) | Spec version when the token will be removed. If omitted, defaults to the next major version after `deprecated`. |
|
|
84
|
+
| `private` | boolean | Not part of public API surface. |
|
|
85
|
+
|
|
86
|
+
#### Lifecycle example
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"name": { "component": "button", "object": "background", "property": "color", "variant": "primary" },
|
|
91
|
+
"value": "#0265dc",
|
|
92
|
+
"uuid": "aaaaaaaa-0001-4000-8000-000000000001",
|
|
93
|
+
"introduced": "1.0.0",
|
|
94
|
+
"lastModified": "3.2.0",
|
|
95
|
+
"deprecated": "3.2.0",
|
|
96
|
+
"deprecated_comment": "Use action-background-default instead.",
|
|
97
|
+
"replaced_by": "bbbbbbbb-0002-4000-8000-000000000001",
|
|
98
|
+
"plannedRemoval": "4.0.0"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Normative rules
|
|
103
|
+
|
|
104
|
+
**NORMATIVE:** If `deprecated` is present, `deprecated_comment` **SHOULD** be present.
|
|
105
|
+
|
|
106
|
+
**NORMATIVE:** If `replaced_by` is an array, `deprecated_comment` is **REQUIRED** — the comment **MUST** explain which replacement applies in which context.
|
|
107
|
+
|
|
108
|
+
**NORMATIVE:** If `replaced_by` is present, `deprecated` **MUST** be present.
|
|
109
|
+
|
|
110
|
+
**NORMATIVE:** If `plannedRemoval` is present, `deprecated` **MUST** be present, and the `plannedRemoval` version **MUST NOT** precede the `deprecated` version.
|
|
111
|
+
|
|
112
|
+
**NORMATIVE:** Each UUID in `replaced_by` **MUST** resolve to an existing token in the dataset (see rule `SPEC-010`).
|
|
113
|
+
|
|
114
|
+
**NORMATIVE:** If `lastModified` is present, its version **MUST NOT** precede `introduced` (see rule `SPEC-014`). Authors **SHOULD** bump `lastModified` whenever a token's `value`, alias `$ref`, or non-formatting metadata changes; pure formatting or comment-only edits do not require a bump.
|
|
115
|
+
|
|
116
|
+
#### Legacy format mapping
|
|
117
|
+
|
|
118
|
+
When generating legacy-format output from cascade tokens:
|
|
52
119
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
| `introduced` | string | Version or date token was introduced. |
|
|
57
|
-
| `deprecated` | boolean | Marked deprecated. |
|
|
58
|
-
| `deprecated_comment` | string | Human-readable deprecation note. |
|
|
59
|
-
| `status` | string | e.g. `experimental`, `stable`. |
|
|
60
|
-
| `renamed` | string | Previous name or id if renamed. |
|
|
61
|
-
| `private` | boolean | Not part of public API surface. |
|
|
120
|
+
* `deprecated: "3.2.0"` maps to `deprecated: true`
|
|
121
|
+
* `replaced_by: "<uuid>"` maps to `renamed: "<target-token-name>"` (resolved via UUID lookup)
|
|
122
|
+
* `introduced`, `lastModified`, and `plannedRemoval` have no legacy equivalent and are not emitted
|
|
62
123
|
|
|
63
|
-
|
|
124
|
+
When migrating legacy-format tokens to cascade:
|
|
125
|
+
|
|
126
|
+
* `deprecated: true` maps to `deprecated: "unknown"` (authors should backfill the actual version)
|
|
127
|
+
* `renamed: "<name>"` maps to `replaced_by: "<uuid>"` (resolved via name lookup across all files in the migrated input set). If the rename target is not found in the scanned corpus, the field is dropped — `replaced_by` must be set manually in that case
|
|
64
128
|
|
|
65
129
|
### `specVersion`
|
|
66
130
|
|
|
67
131
|
**RECOMMENDED:** Root token documents (when stored as standalone JSON files) include `specVersion` with const `1.0.0-draft` for self-identification. Embedded tokens inside larger files **MAY** omit it if the parent document carries version metadata.
|
|
68
132
|
|
|
133
|
+
## Document shape
|
|
134
|
+
|
|
135
|
+
Cascade-format tokens are stored in **JSON files** that conform to [`cascade-file.schema.json`](../schemas/cascade-file.schema.json) (canonical `$id`: `https://opensource.adobe.com/spectrum-design-data/schemas/v0/cascade-file.schema.json`).
|
|
136
|
+
|
|
137
|
+
**NORMATIVE:** A cascade file **MUST** be a JSON **array** of token objects. Each element **MUST** conform to [`token.schema.json`](../schemas/token.schema.json).
|
|
138
|
+
|
|
139
|
+
**NORMATIVE:** The array is **ordered**. Document order is used for tie-breaking during cascade resolution (earlier element wins); see [Cascade — Semantic specificity](cascade.md#semantic-specificity).
|
|
140
|
+
|
|
141
|
+
**RECOMMENDED:** A cascade file uses the `.tokens.json` extension to distinguish it from legacy set-format files.
|
|
142
|
+
|
|
143
|
+
Example:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
[
|
|
147
|
+
{ "name": { "object": "background", "property": "color" }, "value": "#f5f5f5", "uuid": "..." },
|
|
148
|
+
{ "name": { "object": "background", "property": "color", "colorScheme": "dark" }, "value": "#1e1e1e", "uuid": "..." }
|
|
149
|
+
]
|
|
150
|
+
```
|
|
151
|
+
|
|
69
152
|
## Value types
|
|
70
153
|
|
|
71
154
|
Individual types (color, dimension, opacity, etc.) **MUST** be defined as JSON Schemas under `schemas/value-types/` and **MUST** use `$id` under the same `v0` base path as [Overview — JSON Schema `$id`](index.md).
|
|
72
155
|
|
|
73
156
|
## Relationship to legacy Spectrum tokens
|
|
74
157
|
|
|
75
|
-
The current `@adobe/spectrum-tokens` JSON uses **sets** (`color-set`, `scale-set`, …). This specification describes the **target** per-token model. Mapping from legacy to this format is out of scope for this document; see [#
|
|
158
|
+
The current `@adobe/spectrum-tokens` JSON uses **sets** (`color-set`, `scale-set`, …). This specification describes the **target** per-token model. Mapping from legacy to this format is out of scope for this document; see [#743](https://github.com/adobe/spectrum-design-data/issues/743).
|
|
159
|
+
|
|
160
|
+
## Relationship to RFC [#646](https://github.com/adobe/spectrum-design-data/issues/646) token shape
|
|
161
|
+
|
|
162
|
+
[RFC #646](https://github.com/adobe/spectrum-design-data/discussions/646) proposed an analytical token shape during the design process. This spec defines the **canonical serialization format**. The two are related but not identical:
|
|
163
|
+
|
|
164
|
+
| Aspect | RFC [#646](https://github.com/adobe/spectrum-design-data/issues/646) shape | This spec |
|
|
165
|
+
| ------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
166
|
+
| Identity field | `id` | `uuid` |
|
|
167
|
+
| Name model | `name.original` (string) + `name.structure` (nested object) | Flat fields directly on `name` (`property`, `component`, `colorScheme`, …) |
|
|
168
|
+
| Complexity tracking | `name.semanticComplexity` (stored on token) | Computed at validation time from dimension declarations |
|
|
169
|
+
|
|
170
|
+
**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.
|
|
171
|
+
|
|
172
|
+
RFC [#646](https://github.com/adobe/spectrum-design-data/issues/646) remains open as a historical reference. It is not superseded; the spec evolved the format during Phase 2 based on implementation experience.
|
|
76
173
|
|
|
77
174
|
## References
|
|
78
175
|
|
|
79
176
|
* [#646 — Token Schema Structure and Validation System](https://github.com/adobe/spectrum-design-data/discussions/646)
|
|
80
177
|
* [#623 — Token Lifecycle Metadata](https://github.com/adobe/spectrum-design-data/discussions/623)
|
|
178
|
+
* [#756 — Phase 2: Cascade token file schema](https://github.com/adobe/spectrum-design-data/issues/756)
|
|
179
|
+
* [#759 — Phase 2: Token shape reconciliation](https://github.com/adobe/spectrum-design-data/issues/759)
|