@adobe/design-data-spec 4.5.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 +44 -36
- 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/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 +2 -1
- package/schemas/platform-extension.json +73 -1
|
@@ -43,40 +43,48 @@ into the manifest before it's applied to the graph.
|
|
|
43
43
|
Rust SDK drives these fixtures in `sdk/core/src/lib.rs` via the
|
|
44
44
|
`manifest_extensions_conformance` (pass/fail + error message matching) and
|
|
45
45
|
`manifest_extensions_behavior` (post-apply graph predicates) test modules.
|
|
46
|
+
The boolean option regression test derives an invalid case from
|
|
47
|
+
`valid/injects-component-option-extension` and checks that value aliases fail
|
|
48
|
+
with an error naming the option and component.
|
|
46
49
|
|
|
47
|
-
| Case
|
|
48
|
-
|
|
|
49
|
-
| `valid/injects-component`
|
|
50
|
-
| `valid/injects-platform-extension`
|
|
51
|
-
| `valid/injects-
|
|
52
|
-
| `valid/injects-
|
|
53
|
-
| `valid/injects-
|
|
54
|
-
| `valid/injects-
|
|
55
|
-
| `valid/
|
|
56
|
-
| `valid/
|
|
57
|
-
| `valid/
|
|
58
|
-
| `valid/
|
|
59
|
-
| `valid/
|
|
60
|
-
| `valid/
|
|
61
|
-
| `valid/
|
|
62
|
-
| `valid/
|
|
63
|
-
| `valid/implementations-
|
|
64
|
-
| `valid/implementations-
|
|
65
|
-
| `valid/implementations-
|
|
66
|
-
| `valid/implementations-
|
|
67
|
-
| `
|
|
68
|
-
| `invalid/
|
|
69
|
-
| `invalid/
|
|
70
|
-
| `invalid/
|
|
71
|
-
| `invalid/
|
|
72
|
-
| `invalid/
|
|
73
|
-
| `invalid/
|
|
74
|
-
| `invalid/
|
|
75
|
-
| `invalid/
|
|
76
|
-
| `invalid/
|
|
77
|
-
| `invalid/
|
|
78
|
-
| `invalid/unknown-
|
|
79
|
-
| `invalid/
|
|
80
|
-
| `invalid/
|
|
81
|
-
| `invalid/
|
|
82
|
-
| `invalid/
|
|
50
|
+
| Case | Intent |
|
|
51
|
+
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `valid/injects-component` | A `components/` fragment is injected as a Platform-layer component. |
|
|
53
|
+
| `valid/injects-platform-extension` | A `platform-extensions/` fragment is injected. |
|
|
54
|
+
| `valid/injects-component-option-extension` | String value aliases and a boolean option name alias without `values` are injected via `componentOptions`. |
|
|
55
|
+
| `valid/injects-field` | A `fields/` fragment is injected. |
|
|
56
|
+
| `valid/injects-guideline` | A `guidelines/` fragment is injected. |
|
|
57
|
+
| `valid/injects-mode-set` | A `mode-sets/` fragment is injected (declare-or-replace by name). |
|
|
58
|
+
| `valid/injects-relationship` | A `relationships/` plain-add fragment is injected. |
|
|
59
|
+
| `valid/override-relationship-by-uuid` | An `op: "override"` entry replaces a plain add sharing its `uuid`, regardless of file sort order. |
|
|
60
|
+
| `valid/plain-add-uuid-collision-append` | Two plain adds sharing a `uuid` both append rather than one overwriting the other. |
|
|
61
|
+
| `valid/remove-relationship-by-uuid` | An `op: "remove"` entry deletes the matching relationship. |
|
|
62
|
+
| `valid/tokens-sorted-order` | Multiple `tokens/*.tokens.json` files concatenate in sorted path order. |
|
|
63
|
+
| `valid/later-file-wins` | Two `components/` fragments declaring the same component name dedupe to one, later file wins. |
|
|
64
|
+
| `valid/custom-extensions-dir` | The manifest's `extensionsDir` field is honored in place of the default `extensions/` name. |
|
|
65
|
+
| `valid/override-entry-skips-schema-validation` | An `op: "override"` relationship entry is not schema-validated against `relationship.schema.json` (only plain adds are). |
|
|
66
|
+
| `valid/implementations-upsert-foundation-row` | An `implementations/` row replaces the foundation default sharing its `importPath` and is stamped with the manifest `platform`. |
|
|
67
|
+
| `valid/implementations-later-file-wins` | Two fragments upserting the same stamped row dedupe by `implementation` id; the later file wins. |
|
|
68
|
+
| `valid/implementations-remove-row` | An `op: "remove"` selector deletes the matching foundation default. |
|
|
69
|
+
| `valid/implementations-platform-local-component` | A fragment may target a component added by the same manifest's `components/`. |
|
|
70
|
+
| `valid/implementations-other-owner-untouched` | A row stamped with a different `implementation` id is never matched by another owner's upsert. |
|
|
71
|
+
| `invalid/override-missing-uuid` | An `op: "override"` relationship entry missing `uuid` fails loudly. |
|
|
72
|
+
| `invalid/unknown-term-id` | A `platform-extensions/` fragment referencing a non-existent `termId` fails loudly. |
|
|
73
|
+
| `invalid/component-missing-name` | A `components/` fragment missing `name` fails Layer 1 fragment schema validation. |
|
|
74
|
+
| `invalid/field-invalid-kind` | A `fields/` fragment with an invalid `kind` enum value fails schema validation. |
|
|
75
|
+
| `invalid/guideline-invalid-category` | A `guidelines/` fragment with an invalid `category` enum value fails schema validation. |
|
|
76
|
+
| `invalid/mode-set-missing-default` | A `mode-sets/` fragment missing the required `default` field fails Layer 1 fragment schema validation. |
|
|
77
|
+
| `invalid/platform-extension-missing-extends` | A `platform-extensions/` fragment missing `extends` fails schema validation. |
|
|
78
|
+
| `invalid/component-option-extension-missing-component` | A `componentOptions[]` entry missing the required `component` field fails schema validation. |
|
|
79
|
+
| `invalid/component-option-extension-unknown-component` | A `componentOptions[]` entry referencing a component that doesn't exist fails loudly. |
|
|
80
|
+
| `invalid/component-option-extension-unknown-option` | A `componentOptions[]` entry referencing an option that doesn't exist on an existing component fails loudly. |
|
|
81
|
+
| `invalid/component-option-extension-unknown-canonical-value` | A `componentOptions[].values[]` entry must reference a value declared by the canonical component option. |
|
|
82
|
+
| `invalid/token-invalid-uuid` | A `tokens/*.tokens.json` fragment with a malformed `uuid` fails schema validation. |
|
|
83
|
+
| `invalid/relationship-missing-scope` | A `relationships/` plain-add fragment missing `scope` fails schema validation. |
|
|
84
|
+
| `invalid/extensions-dir-parent-traversal` | `extensionsDir` containing a `..` component is rejected. |
|
|
85
|
+
| `invalid/extensions-dir-absolute-path` | An absolute `extensionsDir` path is rejected. |
|
|
86
|
+
| `invalid/unknown-subdir-name` | An unrecognized subdirectory directly under `extensions/` (not one of the known categories) is rejected by name. |
|
|
87
|
+
| `invalid/implementations-unknown-component` | An `implementations/` fragment naming a component absent from the catalog fails loudly. |
|
|
88
|
+
| `invalid/implementations-remove-no-match` | An `op: "remove"` matching no owned row fails loudly. |
|
|
89
|
+
| `invalid/implementations-row-missing-reference` | A row with neither `package` nor `importPath` fails schema validation. |
|
|
90
|
+
| `invalid/implementations-unknown-op` | An `op` other than `"remove"` fails schema validation. |
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "errors": [{ "message_pattern": "not-a-real-component" }] }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "errors": [{ "message_pattern": "not-a-real-option" }] }
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
}
|
|
16
|
+
}
|
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": {
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"rules",
|
|
41
41
|
"schemas",
|
|
42
42
|
"spec",
|
|
43
|
+
"llms.txt",
|
|
43
44
|
"README.md"
|
|
44
45
|
]
|
|
45
46
|
}
|
|
@@ -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"],
|