@adobe/design-data-spec 4.4.0 → 4.6.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/conformance/manifest-extensions/README.md +55 -31
- package/conformance/manifest-extensions/base/dataset.json +36 -3
- package/conformance/manifest-extensions/invalid/component-option-extension-missing-component/expected-errors.json +6 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-missing-component/extensions/platform-extensions/broken.json +4 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-missing-component/manifest.json +4 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-canonical-value/expected-errors.json +5 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-canonical-value/extensions/components/button.json +16 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-canonical-value/extensions/platform-extensions/broken.json +12 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-canonical-value/manifest.json +4 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-component/expected-errors.json +1 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-component/extensions/platform-extensions/broken.json +6 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-component/manifest.json +4 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-option/expected-errors.json +1 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-option/extensions/components/button.json +16 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-option/extensions/platform-extensions/broken.json +4 -0
- package/conformance/manifest-extensions/invalid/component-option-extension-unknown-option/manifest.json +4 -0
- package/conformance/manifest-extensions/invalid/implementations-remove-no-match/expected-errors.json +10 -0
- package/conformance/manifest-extensions/invalid/implementations-remove-no-match/extensions/implementations/button.json +9 -0
- package/conformance/manifest-extensions/invalid/implementations-remove-no-match/manifest.json +5 -0
- package/conformance/manifest-extensions/invalid/implementations-row-missing-reference/expected-errors.json +7 -0
- package/conformance/manifest-extensions/invalid/implementations-row-missing-reference/extensions/implementations/button.json +9 -0
- package/conformance/manifest-extensions/invalid/implementations-row-missing-reference/manifest.json +5 -0
- package/conformance/manifest-extensions/invalid/implementations-unknown-component/expected-errors.json +10 -0
- package/conformance/manifest-extensions/invalid/implementations-unknown-component/extensions/implementations/nope.json +12 -0
- package/conformance/manifest-extensions/invalid/implementations-unknown-component/manifest.json +5 -0
- package/conformance/manifest-extensions/invalid/implementations-unknown-op/expected-errors.json +7 -0
- package/conformance/manifest-extensions/invalid/implementations-unknown-op/extensions/implementations/button.json +9 -0
- package/conformance/manifest-extensions/invalid/implementations-unknown-op/manifest.json +5 -0
- package/conformance/manifest-extensions/valid/implementations-later-file-wins/expected.json +19 -0
- package/conformance/manifest-extensions/valid/implementations-later-file-wins/extensions/implementations/a-button.json +11 -0
- package/conformance/manifest-extensions/valid/implementations-later-file-wins/extensions/implementations/b-button.json +11 -0
- package/conformance/manifest-extensions/valid/implementations-later-file-wins/manifest.json +5 -0
- package/conformance/manifest-extensions/valid/implementations-other-owner-untouched/expected.json +26 -0
- package/conformance/manifest-extensions/valid/implementations-other-owner-untouched/extensions/implementations/button.json +18 -0
- package/conformance/manifest-extensions/valid/implementations-other-owner-untouched/manifest.json +5 -0
- package/conformance/manifest-extensions/valid/implementations-platform-local-component/expected.json +12 -0
- package/conformance/manifest-extensions/valid/implementations-platform-local-component/extensions/components/tab-bar-ios.json +9 -0
- package/conformance/manifest-extensions/valid/implementations-platform-local-component/extensions/implementations/tab-bar-ios.json +10 -0
- package/conformance/manifest-extensions/valid/implementations-platform-local-component/manifest.json +5 -0
- package/conformance/manifest-extensions/valid/implementations-remove-row/expected.json +11 -0
- package/conformance/manifest-extensions/valid/implementations-remove-row/extensions/implementations/button.json +10 -0
- package/conformance/manifest-extensions/valid/implementations-remove-row/manifest.json +5 -0
- package/conformance/manifest-extensions/valid/implementations-upsert-foundation-row/expected.json +19 -0
- package/conformance/manifest-extensions/valid/implementations-upsert-foundation-row/extensions/implementations/button.json +12 -0
- package/conformance/manifest-extensions/valid/implementations-upsert-foundation-row/manifest.json +5 -0
- package/conformance/manifest-extensions/valid/injects-component-option-extension/expected.json +18 -0
- package/conformance/manifest-extensions/valid/injects-component-option-extension/extensions/components/button.json +20 -0
- package/conformance/manifest-extensions/valid/injects-component-option-extension/extensions/platform-extensions/web-components-button.json +18 -0
- package/conformance/manifest-extensions/valid/injects-component-option-extension/manifest.json +4 -0
- package/llms.txt +29 -0
- package/package.json +3 -1
- package/schemas/component.schema.json +8 -3
- package/schemas/implementation-mapping.schema.json +69 -0
- package/schemas/platform-extension.json +73 -1
- package/spec/component-format.md +40 -19
- package/spec/manifest.md +71 -19
package/conformance/manifest-extensions/valid/injects-component-option-extension/expected.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"componentOptionExtensions": {
|
|
3
|
+
"present": [
|
|
4
|
+
{
|
|
5
|
+
"platform": "Web Components",
|
|
6
|
+
"component": "button",
|
|
7
|
+
"option": "style",
|
|
8
|
+
"platformProp": "fillStyle"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"platform": "Web Components",
|
|
12
|
+
"component": "button",
|
|
13
|
+
"option": "isDisabled",
|
|
14
|
+
"platformProp": "disabled"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$id": "https://example.com/components/button",
|
|
3
|
+
"name": "button",
|
|
4
|
+
"displayName": "Button",
|
|
5
|
+
"meta": {
|
|
6
|
+
"category": "actions",
|
|
7
|
+
"documentationUrl": "https://example.com"
|
|
8
|
+
},
|
|
9
|
+
"options": {
|
|
10
|
+
"style": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"default": "fill",
|
|
13
|
+
"values": [{ "value": "fill" }, { "value": "outline" }]
|
|
14
|
+
},
|
|
15
|
+
"isDisabled": {
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"default": false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": "Web Components",
|
|
3
|
+
"componentOptions": [
|
|
4
|
+
{
|
|
5
|
+
"component": "button",
|
|
6
|
+
"option": "style",
|
|
7
|
+
"platformProp": "fillStyle",
|
|
8
|
+
"platformAttribute": "fill-style",
|
|
9
|
+
"values": [{ "value": "fill", "platformValue": "Fill" }]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"component": "button",
|
|
13
|
+
"option": "isDisabled",
|
|
14
|
+
"platformProp": "disabled",
|
|
15
|
+
"platformAttribute": "disabled"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# @adobe/design-data-spec
|
|
2
|
+
|
|
3
|
+
> Design Data Specification — prose, JSON Schemas, rule catalog, and conformance fixtures for the design data format
|
|
4
|
+
|
|
5
|
+
Normative **Design Data Specification** artifacts for Spectrum: human-readable spec (`spec/`), JSON Schemas (`schemas/`), validation rule catalog (`rules/`), and conformance fixtures (`conformance/`).
|
|
6
|
+
|
|
7
|
+
**Spec version:** `1.0.0-draft` — see [`spec/index.md`](spec/index.md).
|
|
8
|
+
|
|
9
|
+
See [`spec/manifest.md`](spec/manifest.md) for the platform manifest spec, including the
|
|
10
|
+
`extensions/` directory model.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
`npm install @adobe/design-data-spec`
|
|
15
|
+
|
|
16
|
+
## Documentation
|
|
17
|
+
|
|
18
|
+
- [README](https://github.com/adobe/spectrum-design-data/blob/main/packages/design-data-spec/README.md): usage and API overview
|
|
19
|
+
- [Layers](https://github.com/adobe/spectrum-design-data/blob/main/packages/design-data-spec/README.md#layers)
|
|
20
|
+
- [Package exports](https://github.com/adobe/spectrum-design-data/blob/main/packages/design-data-spec/README.md#package-exports)
|
|
21
|
+
- [Tasks](https://github.com/adobe/spectrum-design-data/blob/main/packages/design-data-spec/README.md#tasks)
|
|
22
|
+
- [References](https://github.com/adobe/spectrum-design-data/blob/main/packages/design-data-spec/README.md#references)
|
|
23
|
+
- [Repository index](https://github.com/adobe/spectrum-design-data/blob/main/docs/repo-index.md): how this package fits in the repository
|
|
24
|
+
|
|
25
|
+
## Optional
|
|
26
|
+
|
|
27
|
+
- [Changelog](https://github.com/adobe/spectrum-design-data/blob/main/packages/design-data-spec/CHANGELOG.md)
|
|
28
|
+
- [npm package](https://www.npmjs.com/package/@adobe/design-data-spec)
|
|
29
|
+
- [Source](https://github.com/adobe/spectrum-design-data/blob/main/packages/design-data-spec/)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/design-data-spec",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"description": "Design Data Specification — prose, JSON Schemas, rule catalog, and conformance fixtures for the design data format",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"./schemas/manifest.schema.json": "./schemas/manifest.schema.json",
|
|
27
27
|
"./schemas/value-types/color.schema.json": "./schemas/value-types/color.schema.json",
|
|
28
28
|
"./schemas/component.schema.json": "./schemas/component.schema.json",
|
|
29
|
+
"./schemas/implementation-mapping.schema.json": "./schemas/implementation-mapping.schema.json",
|
|
29
30
|
"./schemas/anatomy-part.schema.json": "./schemas/anatomy-part.schema.json",
|
|
30
31
|
"./schemas/state-declaration.schema.json": "./schemas/state-declaration.schema.json",
|
|
31
32
|
"./rules/rules.yaml": "./rules/rules.yaml",
|
|
@@ -39,6 +40,7 @@
|
|
|
39
40
|
"rules",
|
|
40
41
|
"schemas",
|
|
41
42
|
"spec",
|
|
43
|
+
"llms.txt",
|
|
42
44
|
"README.md"
|
|
43
45
|
]
|
|
44
46
|
}
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"items": {
|
|
43
43
|
"$ref": "#/$defs/implementation"
|
|
44
44
|
},
|
|
45
|
-
"description": "Known platform implementations of this component. Foundation
|
|
45
|
+
"description": "Known platform implementations of this component. Foundation data carries canonical default mappings; a platform manifest refines its own rows through extensions/implementations/. See spec/component-format.md#implementations."
|
|
46
46
|
},
|
|
47
47
|
"options": {
|
|
48
48
|
"$ref": "#/$defs/optionsMap"
|
|
@@ -115,6 +115,11 @@
|
|
|
115
115
|
"minLength": 1,
|
|
116
116
|
"description": "Target platform identifier (for example, 'web', 'ios', or 'android'). Multiple implementations may target the same platform when they have distinct packages."
|
|
117
117
|
},
|
|
118
|
+
"implementation": {
|
|
119
|
+
"type": "string",
|
|
120
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
121
|
+
"description": "Implementation project id from the platform-implementations registry (for example, 'react-spectrum' or 'web-components'). Distinguishes implementations that share a `platform` device target. A platform manifest stamps its own `platform` id here when merging extensions/implementations/ entries that omit it."
|
|
122
|
+
},
|
|
118
123
|
"componentName": {
|
|
119
124
|
"type": "string",
|
|
120
125
|
"minLength": 1,
|
|
@@ -123,7 +128,7 @@
|
|
|
123
128
|
"importPath": {
|
|
124
129
|
"type": "string",
|
|
125
130
|
"minLength": 1,
|
|
126
|
-
"description": "Importable module or source path for a platform implementation."
|
|
131
|
+
"description": "Importable module or source path for a platform implementation. When `package` is also set, this SHOULD be a subpath export of that package."
|
|
127
132
|
},
|
|
128
133
|
"package": {
|
|
129
134
|
"type": "string",
|
|
@@ -135,7 +140,7 @@
|
|
|
135
140
|
"description": "Optional implementation-specific usage or mapping notes."
|
|
136
141
|
}
|
|
137
142
|
},
|
|
138
|
-
"
|
|
143
|
+
"anyOf": [
|
|
139
144
|
{
|
|
140
145
|
"required": ["importPath"]
|
|
141
146
|
},
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://opensource.adobe.com/spectrum-design-data/schemas/v0/implementation-mapping.schema.json",
|
|
4
|
+
"title": "Platform implementation mapping",
|
|
5
|
+
"description": "Layer 1 schema for one platform manifest extensions/implementations/ fragment: the platform's own implementation rows for a single component, merged into that component's `implementations` array. See spec/manifest.md#extensionsimplementations.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["component", "implementations"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"format": "uri"
|
|
12
|
+
},
|
|
13
|
+
"component": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
16
|
+
"description": "Name of the component (foundation or platform-local) whose `implementations` this fragment refines."
|
|
17
|
+
},
|
|
18
|
+
"implementations": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"minItems": 1,
|
|
21
|
+
"items": {
|
|
22
|
+
"if": {
|
|
23
|
+
"required": ["op"]
|
|
24
|
+
},
|
|
25
|
+
"then": {
|
|
26
|
+
"$ref": "#/$defs/removeEntry"
|
|
27
|
+
},
|
|
28
|
+
"else": {
|
|
29
|
+
"$ref": "component.schema.json#/$defs/implementation"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"description": "Rows to upsert (implementation objects) or remove (`op: \"remove\"` selectors), applied in order."
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"additionalProperties": false,
|
|
36
|
+
"$defs": {
|
|
37
|
+
"removeEntry": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"description": "Removes every existing row of the component whose fields equal each selector field given here.",
|
|
40
|
+
"required": ["op", "componentName"],
|
|
41
|
+
"properties": {
|
|
42
|
+
"op": {
|
|
43
|
+
"const": "remove"
|
|
44
|
+
},
|
|
45
|
+
"platform": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"minLength": 1
|
|
48
|
+
},
|
|
49
|
+
"implementation": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"pattern": "^[a-z][a-z0-9-]*$"
|
|
52
|
+
},
|
|
53
|
+
"componentName": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"minLength": 1
|
|
56
|
+
},
|
|
57
|
+
"package": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"minLength": 1
|
|
60
|
+
},
|
|
61
|
+
"importPath": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"minLength": 1
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"additionalProperties": false
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
"title": "Platform Extension",
|
|
5
5
|
"description": "Schema for platform-specific terminology extensions",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": ["platform"
|
|
7
|
+
"required": ["platform"],
|
|
8
|
+
"anyOf": [
|
|
9
|
+
{ "required": ["extends", "extensions"] },
|
|
10
|
+
{ "required": ["componentOptions"] }
|
|
11
|
+
],
|
|
8
12
|
"properties": {
|
|
9
13
|
"$schema": {
|
|
10
14
|
"type": "string",
|
|
@@ -32,9 +36,77 @@
|
|
|
32
36
|
"items": {
|
|
33
37
|
"$ref": "#/$defs/extension"
|
|
34
38
|
}
|
|
39
|
+
},
|
|
40
|
+
"componentOptions": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"description": "Per-component option/value aliasing for this platform. Unlike `extensions` (which aliases a shared registry term everywhere it's used), these entries scope to one component's own `options` map — the right home for a naming difference that isn't backed by a shared registry (e.g. Button's `style` option vs. React's `fillStyle` prop).",
|
|
43
|
+
"items": {
|
|
44
|
+
"$ref": "#/$defs/componentOptionExtension"
|
|
45
|
+
}
|
|
35
46
|
}
|
|
36
47
|
},
|
|
37
48
|
"$defs": {
|
|
49
|
+
"componentOptionExtension": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"required": ["component", "option"],
|
|
52
|
+
"properties": {
|
|
53
|
+
"component": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"description": "Component `name` (as declared in its component.schema.json file, e.g. 'button') this extension applies to."
|
|
56
|
+
},
|
|
57
|
+
"option": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "Canonical option name from the component's `options` map (e.g. 'style')."
|
|
60
|
+
},
|
|
61
|
+
"platformProp": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"description": "This platform's name for the option (e.g. 'fillStyle')."
|
|
64
|
+
},
|
|
65
|
+
"platformAttribute": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"description": "This platform's HTML/DOM attribute name, when it differs from platformProp (e.g. Web Components' fill-style attribute vs. its fillStyle JS property). Omit if not applicable or identical to platformProp."
|
|
68
|
+
},
|
|
69
|
+
"platformAliases": {
|
|
70
|
+
"type": "array",
|
|
71
|
+
"description": "Other names this platform has used for the same concept (e.g. during a migration).",
|
|
72
|
+
"items": { "type": "string" }
|
|
73
|
+
},
|
|
74
|
+
"notes": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"description": "Free-text context for why the names differ."
|
|
77
|
+
},
|
|
78
|
+
"values": {
|
|
79
|
+
"type": "array",
|
|
80
|
+
"description": "Per-value aliasing, for options whose values differ in casing or spelling across platforms (e.g. size 's'|'m'|'l'|'xl' canonical vs. React's 'S'|'M'|'L'|'XL').",
|
|
81
|
+
"items": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"required": ["value", "platformValue"],
|
|
84
|
+
"properties": {
|
|
85
|
+
"value": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"description": "Canonical value, from the component's options[option].values."
|
|
88
|
+
},
|
|
89
|
+
"platformValue": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"description": "This platform's value for the same concept."
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"platformOnlyValues": {
|
|
97
|
+
"type": "array",
|
|
98
|
+
"description": "Values this platform's implementation accepts that have NO canonical/Figma counterpart (e.g. React Button's 'premium'/'genai' variants). Recorded here — not silently mapped to the nearest lookalike — so design-system drift between platforms is visible rather than papered over. A generator producing Code Connect templates from this data MUST NOT emit a figma.enum() entry for these; they can never appear in a Figma-driven example because no Figma variant represents them.",
|
|
99
|
+
"items": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"required": ["platformValue"],
|
|
102
|
+
"properties": {
|
|
103
|
+
"platformValue": { "type": "string" },
|
|
104
|
+
"notes": { "type": "string" }
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
38
110
|
"extension": {
|
|
39
111
|
"type": "object",
|
|
40
112
|
"required": ["termId"],
|
package/spec/component-format.md
CHANGED
|
@@ -84,30 +84,40 @@ where `{name}` matches the component's `name` field.
|
|
|
84
84
|
## Implementations
|
|
85
85
|
|
|
86
86
|
`implementations` declares the published platform implementations corresponding
|
|
87
|
-
to this design-system component
|
|
88
|
-
|
|
89
|
-
without platform-specific configuration.
|
|
87
|
+
to this design-system component, so consumers such as Code Connect generators
|
|
88
|
+
can resolve an implementation without platform-specific configuration.
|
|
90
89
|
|
|
91
|
-
Each entry **MUST** contain `platform` and `componentName`, plus
|
|
92
|
-
implementation reference: `package` for a published package or
|
|
93
|
-
for an importable module
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
Each entry **MUST** contain `platform` and `componentName`, plus at least one
|
|
91
|
+
implementation reference: `package` for a published package and/or
|
|
92
|
+
`importPath` for an importable module or source path. When both are present,
|
|
93
|
+
`importPath` **SHOULD** be a subpath export of `package`. `notes` is optional
|
|
94
|
+
context for consumers.
|
|
95
|
+
|
|
96
|
+
`platform` is a device target (`web`, `ios`, `android`), so several
|
|
97
|
+
implementations may share it. The optional `implementation` field names the
|
|
98
|
+
implementation project from the platform-implementations registry (for example
|
|
99
|
+
`react-spectrum` or `web-components`) to tell them apart.
|
|
96
100
|
|
|
97
101
|
```json
|
|
98
102
|
"implementations": [
|
|
99
103
|
{
|
|
100
104
|
"platform": "web",
|
|
105
|
+
"implementation": "web-components",
|
|
101
106
|
"componentName": "Button",
|
|
102
|
-
"package": "@spectrum-
|
|
107
|
+
"package": "@adobe/spectrum-wc",
|
|
108
|
+
"importPath": "@adobe/spectrum-wc/components/button"
|
|
103
109
|
}
|
|
104
110
|
]
|
|
105
111
|
```
|
|
106
112
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
113
|
+
### Layering
|
|
114
|
+
|
|
115
|
+
Foundation component data carries canonical **default** rows. A platform
|
|
116
|
+
manifest refines its own rows through
|
|
117
|
+
[`extensions/implementations/`](manifest.md#extensionsimplementations):
|
|
118
|
+
upserting rows it owns and removing stale ones, without restating the rest of
|
|
119
|
+
the component. Rows owned by another implementation are left untouched, so the
|
|
120
|
+
merged catalog still lists every implementation of the component.
|
|
111
121
|
|
|
112
122
|
## Options
|
|
113
123
|
|
|
@@ -426,13 +436,18 @@ A complete button component declaration:
|
|
|
426
436
|
}
|
|
427
437
|
],
|
|
428
438
|
"anatomy": [
|
|
429
|
-
{ "name": "icon",
|
|
439
|
+
{ "name": "icon", "description": "Leading icon." },
|
|
430
440
|
{ "name": "label", "description": "Button text.", "required": true }
|
|
431
441
|
],
|
|
432
442
|
"states": [
|
|
433
|
-
{ "name": "hover",
|
|
434
|
-
{
|
|
435
|
-
|
|
443
|
+
{ "name": "hover", "trigger": "interaction", "precedence": 50 },
|
|
444
|
+
{
|
|
445
|
+
"name": "focus",
|
|
446
|
+
"trigger": "interaction",
|
|
447
|
+
"precedence": 60,
|
|
448
|
+
"layered": true
|
|
449
|
+
},
|
|
450
|
+
{ "name": "disabled", "trigger": "prop", "precedence": 100 }
|
|
436
451
|
],
|
|
437
452
|
"lifecycle": {
|
|
438
453
|
"introduced": "1.0.0-draft"
|
|
@@ -448,7 +463,10 @@ A complete button component declaration:
|
|
|
448
463
|
{
|
|
449
464
|
"name": "button",
|
|
450
465
|
"displayName": "Button",
|
|
451
|
-
"meta": {
|
|
466
|
+
"meta": {
|
|
467
|
+
"category": "actions",
|
|
468
|
+
"documentationUrl": "https://spectrum.adobe.com/page/button/"
|
|
469
|
+
},
|
|
452
470
|
"accessibility": {
|
|
453
471
|
"role": "button",
|
|
454
472
|
"intents": ["trigger"],
|
|
@@ -479,7 +497,10 @@ A complete button component declaration:
|
|
|
479
497
|
{
|
|
480
498
|
"name": "button",
|
|
481
499
|
"displayName": "Button",
|
|
482
|
-
"meta": {
|
|
500
|
+
"meta": {
|
|
501
|
+
"category": "actions",
|
|
502
|
+
"documentationUrl": "https://spectrum.adobe.com/page/button/"
|
|
503
|
+
},
|
|
483
504
|
"documentBlocks": [
|
|
484
505
|
{
|
|
485
506
|
"type": "purpose",
|
package/spec/manifest.md
CHANGED
|
@@ -8,25 +8,26 @@ This document defines the **platform manifest**: how a platform implementation r
|
|
|
8
8
|
|
|
9
9
|
The manifest supports a fixed, enumerated set of operations against the foundation — it does **not** allow overriding, aliasing, or removing arbitrary foundation artifacts. Support is concentrated on tokens; translations and schemas have no manifest-level override mechanism at all.
|
|
10
10
|
|
|
11
|
-
| Operation | Supported? | Field | Applies to
|
|
12
|
-
| --------------------------------------------------- | ------------------------------------------------------------ | --------------------------------- |
|
|
13
|
-
| Remove / exclude | Yes | `exclude` | Tokens only
|
|
14
|
-
| Include / whitelist | Yes | `include` | Tokens only
|
|
15
|
-
| Override value (type-preserving) | Yes | `overrides[].value` | Tokens only
|
|
16
|
-
| Override → re-alias | Yes | `overrides[].$ref` | Tokens only
|
|
17
|
-
| Add new tokens (may alias via `$ref`) | Yes | `extensions/tokens/` | Tokens
|
|
18
|
-
| Add / replace components | Yes | `extensions/components/` | Components
|
|
19
|
-
| Add / replace field declarations | Yes | `extensions/fields/` | Fields
|
|
20
|
-
| Add / replace guideline documents | Yes | `extensions/guidelines/` | Guidelines
|
|
21
|
-
| Declare / replace platform-local mode set | Yes | `extensions/mode-sets/` | Mode sets
|
|
22
|
-
| Add / remove / retarget a single mode; remove a set | Yes | `extensions/mode-sets/` (`op`) | Mode sets
|
|
23
|
-
| Add relationships/CTRs; override/remove by `uuid` | Yes | `extensions/relationships/` | Relationships (CTRs)
|
|
24
|
-
| Add / remove naming exceptions | Yes | `namingExceptions` | Naming validation
|
|
25
|
-
| Annotate existing terminology (cannot add new ids) | Yes | `extensions/platform-extensions/` | Existing registry ids
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
| Override
|
|
11
|
+
| Operation | Supported? | Field | Applies to |
|
|
12
|
+
| --------------------------------------------------- | ------------------------------------------------------------ | --------------------------------- | --------------------------- |
|
|
13
|
+
| Remove / exclude | Yes | `exclude` | Tokens only |
|
|
14
|
+
| Include / whitelist | Yes | `include` | Tokens only |
|
|
15
|
+
| Override value (type-preserving) | Yes | `overrides[].value` | Tokens only |
|
|
16
|
+
| Override → re-alias | Yes | `overrides[].$ref` | Tokens only |
|
|
17
|
+
| Add new tokens (may alias via `$ref`) | Yes | `extensions/tokens/` | Tokens |
|
|
18
|
+
| Add / replace components | Yes | `extensions/components/` | Components |
|
|
19
|
+
| Add / replace field declarations | Yes | `extensions/fields/` | Fields |
|
|
20
|
+
| Add / replace guideline documents | Yes | `extensions/guidelines/` | Guidelines |
|
|
21
|
+
| Declare / replace platform-local mode set | Yes | `extensions/mode-sets/` | Mode sets |
|
|
22
|
+
| Add / remove / retarget a single mode; remove a set | Yes | `extensions/mode-sets/` (`op`) | Mode sets |
|
|
23
|
+
| Add relationships/CTRs; override/remove by `uuid` | Yes | `extensions/relationships/` | Relationships (CTRs) |
|
|
24
|
+
| Add / remove naming exceptions | Yes | `namingExceptions` | Naming validation |
|
|
25
|
+
| Annotate existing terminology (cannot add new ids) | Yes | `extensions/platform-extensions/` | Existing registry ids |
|
|
26
|
+
| Upsert / remove own implementation mappings | Yes | `extensions/implementations/` | Component `implementations` |
|
|
27
|
+
| Restrict allowed mode-set values | Yes | `modeSetRestrictions` | Mode sets |
|
|
28
|
+
| Reformat name serialization | Schema-declared only, not yet applied by the reference SDK | `formatting` | Token name strings |
|
|
29
|
+
| Override/remove/alias translations | No | — | — |
|
|
30
|
+
| Override Layer-1 schemas | No (decided; see [spike](manifest-schema-override-spike.md)) | — | — |
|
|
30
31
|
|
|
31
32
|
## Manifest document
|
|
32
33
|
|
|
@@ -112,6 +113,7 @@ extensions/
|
|
|
112
113
|
relationships/ <component>.json one CTR set per file
|
|
113
114
|
guidelines/ <topic>.json one guideline per file
|
|
114
115
|
platform-extensions/ <platform>-<registry>.json
|
|
116
|
+
implementations/ <component>.json one component's implementation rows
|
|
115
117
|
```
|
|
116
118
|
|
|
117
119
|
**NORMATIVE:** Each subdirectory is discovered by a recursive glob for `*.json` files (for
|
|
@@ -131,6 +133,9 @@ or empty subdirectory contributes nothing and is not an error.
|
|
|
131
133
|
injected into the corresponding catalog **add-or-replace by name** (for
|
|
132
134
|
`platform-extensions/`, by `termId`; see below). When two files declare the same name,
|
|
133
135
|
**the entry from the later file (in sorted path order) wins.**
|
|
136
|
+
* **`implementations/`** — one component's implementation rows per file, merged row-by-row into
|
|
137
|
+
that component's existing `implementations` array (never whole-array replaced). See
|
|
138
|
+
[`extensions/implementations/`](#extensionsimplementations) below.
|
|
134
139
|
|
|
135
140
|
**NORMATIVE:** Each fragment file **MUST** validate against its category's real JSON schema at
|
|
136
141
|
load time — this is enforced reference-SDK behavior, not an aspirational goal:
|
|
@@ -142,6 +147,8 @@ load time — this is enforced reference-SDK behavior, not an aspirational goal:
|
|
|
142
147
|
* **`relationships/`** → `relationship.schema.json` (see the Add/Override/remove rules above)
|
|
143
148
|
* **`platform-extensions/`** → `platform-extension.json` (see
|
|
144
149
|
[`extensions/platform-extensions/`](#extensionsplatform-extensions) below)
|
|
150
|
+
* **`implementations/`** → `implementation-mapping.schema.json` (see
|
|
151
|
+
[`extensions/implementations/`](#extensionsimplementations) below)
|
|
145
152
|
* **`tokens/`** → `cascade-file.schema.json` (see above)
|
|
146
153
|
|
|
147
154
|
A fragment that fails validation against its category schema is a manifest error — the
|
|
@@ -214,6 +221,51 @@ example, platform-specific state names). **NORMATIVE:** each file **MUST** valid
|
|
|
214
221
|
foundation registry — this mechanism annotates existing ids, it does **NOT** introduce new
|
|
215
222
|
ones.
|
|
216
223
|
|
|
224
|
+
#### `extensions/implementations/`
|
|
225
|
+
|
|
226
|
+
Platform-owned refinements of a component's
|
|
227
|
+
[`implementations`](component-format.md#implementations) — the packages, import paths, and
|
|
228
|
+
exported names a platform ships. Foundation component data carries canonical **default** rows;
|
|
229
|
+
a platform manifest refines only its own rows, so the implementation team that owns the
|
|
230
|
+
manifest also owns its mappings, and they travel with the manifest when it is ejected.
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"component": "button",
|
|
235
|
+
"implementations": [
|
|
236
|
+
{
|
|
237
|
+
"platform": "web",
|
|
238
|
+
"componentName": "Button",
|
|
239
|
+
"package": "@react-spectrum/s2"
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"op": "remove",
|
|
243
|
+
"componentName": "Button",
|
|
244
|
+
"package": "@react-spectrum/button"
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**NORMATIVE:** each file **MUST** validate against `implementation-mapping.schema.json`.
|
|
251
|
+
`component` **MUST** name a component in the catalog after `extensions/components/` has been
|
|
252
|
+
applied (so a fragment may target a platform-local component); an unknown component is a
|
|
253
|
+
manifest error. Entries apply in array order, files in sorted path order.
|
|
254
|
+
|
|
255
|
+
**NORMATIVE:** each entry has an *owner*: its own `implementation` field if present, otherwise
|
|
256
|
+
the manifest's top-level `platform` id. A manifest only matches rows its owner owns — rows
|
|
257
|
+
stamped with the same `implementation` id, or unstamped foundation defaults. Rows stamped with
|
|
258
|
+
a different `implementation` id are never modified or removed.
|
|
259
|
+
|
|
260
|
+
* **Upsert** (no `op`) — a full implementation row. When the entry omits `implementation` and
|
|
261
|
+
the manifest declares `platform`, the stored row is stamped with that id. The row replaces the
|
|
262
|
+
first existing row with the same `platform` and `componentName` that either carries the same
|
|
263
|
+
`implementation` id, or is an unstamped foundation default sharing a `package` or `importPath`
|
|
264
|
+
value. Otherwise it is appended.
|
|
265
|
+
* **Remove** (`"op": "remove"`) — a selector of `componentName` plus any of `platform`,
|
|
266
|
+
`implementation`, `package`, `importPath`. It deletes every owned row whose values equal every
|
|
267
|
+
selector field given. A remove that matches no owned row is a manifest error.
|
|
268
|
+
|
|
217
269
|
### `namingExceptions`
|
|
218
270
|
|
|
219
271
|
Platform-local overlay on the base naming-exceptions set used by naming validation.
|