openuispec 0.1.16 → 0.1.17
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/README.md +6 -3
- package/cli/init.ts +6 -4
- package/examples/taskflow/contracts/action_trigger.yaml +3 -6
- package/examples/taskflow/contracts/collection.yaml +3 -6
- package/examples/taskflow/contracts/data_display.yaml +3 -6
- package/examples/taskflow/contracts/feedback.yaml +3 -6
- package/examples/taskflow/contracts/input_field.yaml +22 -6
- package/examples/taskflow/contracts/nav_container.yaml +3 -6
- package/examples/taskflow/contracts/surface.yaml +3 -6
- package/package.json +1 -1
- package/schema/contract.schema.json +129 -0
- package/schema/validate.ts +7 -8
package/README.md
CHANGED
|
@@ -70,7 +70,8 @@ openuispec/
|
|
|
70
70
|
│ ├── flow.schema.json # Navigation flow schema
|
|
71
71
|
│ ├── platform.schema.json # Platform adaptation schema
|
|
72
72
|
│ ├── locale.schema.json # Locale file schema
|
|
73
|
-
│ ├──
|
|
73
|
+
│ ├── contract.schema.json # Standard contract extension schema
|
|
74
|
+
│ ├── custom-contract.schema.json # Custom contract extension schema (x_ prefixed)
|
|
74
75
|
│ ├── tokens/
|
|
75
76
|
│ │ ├── color.schema.json # Color token schema
|
|
76
77
|
│ │ ├── typography.schema.json # Typography token schema
|
|
@@ -99,7 +100,8 @@ openuispec/
|
|
|
99
100
|
│ │ ├── layout.yaml # Size classes, primitives, reflow rules
|
|
100
101
|
│ │ ├── themes.yaml # Light, dark, warm variants
|
|
101
102
|
│ │ └── icons.yaml # Icon registry with platform mappings
|
|
102
|
-
│ ├── contracts/ #
|
|
103
|
+
│ ├── contracts/ # Standard contract extensions + custom contracts
|
|
104
|
+
│ │ ├── input_field.yaml # Standard contract with cut_corner variant
|
|
103
105
|
│ │ └── x_media_player.yaml # Custom media player contract (Section 12)
|
|
104
106
|
│ ├── screens/
|
|
105
107
|
│ │ ├── home.yaml # Task list with search, filters, FAB, adaptive nav
|
|
@@ -138,7 +140,8 @@ Every file type has a corresponding JSON Schema in `schema/`. **Read the schema
|
|
|
138
140
|
| `flows/*.yaml` | `flow.schema.json` | `<flow_id>` | [create_task.yaml](./examples/taskflow/flows/create_task.yaml) |
|
|
139
141
|
| `platform/*.yaml` | `platform.schema.json` | `platform` | [ios.yaml](./examples/taskflow/platform/ios.yaml) |
|
|
140
142
|
| `locales/*.json` | `locale.schema.json` | (object) | [en.json](./examples/taskflow/locales/en.json) |
|
|
141
|
-
| `contracts
|
|
143
|
+
| `contracts/<name>.yaml` | `contract.schema.json` | `<contract_name>` | [input_field.yaml](./examples/taskflow/contracts/input_field.yaml) |
|
|
144
|
+
| `contracts/x_*.yaml` | `custom-contract.schema.json` | `<x_name>` | [x_media_player.yaml](./examples/taskflow/contracts/x_media_player.yaml) |
|
|
142
145
|
| `tokens/color.yaml` | `tokens/color.schema.json` | `color` | [color.yaml](./examples/taskflow/tokens/color.yaml) |
|
|
143
146
|
| `tokens/typography.yaml` | `tokens/typography.schema.json` | `typography` | [typography.yaml](./examples/taskflow/tokens/typography.yaml) |
|
|
144
147
|
| `tokens/spacing.yaml` | `tokens/spacing.schema.json` | `spacing` | [spacing.yaml](./examples/taskflow/tokens/spacing.yaml) |
|
package/cli/init.ts
CHANGED
|
@@ -137,7 +137,7 @@ OpenUISpec is a YAML-based format that describes your app's UI semantically —
|
|
|
137
137
|
| \`tokens/\` | Design tokens — colors, typography, spacing, elevation, motion, icons, themes |
|
|
138
138
|
| \`screens/\` | Screen definitions — one YAML file per screen |
|
|
139
139
|
| \`flows/\` | Navigation flows — multi-step user journeys |
|
|
140
|
-
| \`contracts/\` | Component contracts —
|
|
140
|
+
| \`contracts/\` | Component contracts — standard extensions (variants, tokens) and custom (\`x_\` prefixed) |
|
|
141
141
|
| \`platform/\` | Platform overrides — per-target (iOS, Android, Web) behaviors |
|
|
142
142
|
| \`locales/\` | Localization — i18n strings (JSON, ICU MessageFormat) |
|
|
143
143
|
|
|
@@ -222,7 +222,8 @@ Root keys: \`color\`, \`typography\`, \`spacing\`, \`elevation\`, \`motion\`, \`
|
|
|
222
222
|
| \`flows/*.yaml\` | \`flow.schema.json\` | \`<flow_id>\` |
|
|
223
223
|
| \`platform/*.yaml\` | \`platform.schema.json\` | \`platform\` |
|
|
224
224
|
| \`locales/*.json\` | \`locale.schema.json\` | (object) |
|
|
225
|
-
| \`contracts
|
|
225
|
+
| \`contracts/<name>.yaml\` | \`contract.schema.json\` | \`<contract_name>\` |
|
|
226
|
+
| \`contracts/x_*.yaml\` | \`custom-contract.schema.json\` | \`<x_name>\` |
|
|
226
227
|
| \`tokens/color.yaml\` | \`tokens/color.schema.json\` | \`color\` |
|
|
227
228
|
| \`tokens/typography.yaml\` | \`tokens/typography.schema.json\` | \`typography\` |
|
|
228
229
|
| \`tokens/spacing.yaml\` | \`tokens/spacing.schema.json\` | \`spacing\` |
|
|
@@ -300,7 +301,7 @@ OpenUISpec is a YAML-based spec format that describes an app's UI semantically
|
|
|
300
301
|
- Tokens: \`${specDir}/tokens/\` — colors, typography, spacing, motion, icons, themes
|
|
301
302
|
- Screens: \`${specDir}/screens/\` — one YAML file per screen
|
|
302
303
|
- Flows: \`${specDir}/flows/\` — multi-step navigation journeys
|
|
303
|
-
- Contracts: \`${specDir}/contracts/\` —
|
|
304
|
+
- Contracts: \`${specDir}/contracts/\` — standard extensions (variants, tokens) and custom (\`x_\` prefixed)
|
|
304
305
|
- Platform: \`${specDir}/platform/\` — per-target overrides (iOS, Android, Web)
|
|
305
306
|
- Locales: \`${specDir}/locales/\` — i18n strings (JSON, ICU MessageFormat)
|
|
306
307
|
|
|
@@ -373,7 +374,8 @@ Before creating or editing any spec file, read the corresponding JSON Schema. Do
|
|
|
373
374
|
| \`flows/*.yaml\` | \`flow.schema.json\` | \`<flow_id>\` |
|
|
374
375
|
| \`platform/*.yaml\` | \`platform.schema.json\` | \`platform\` |
|
|
375
376
|
| \`locales/*.json\` | \`locale.schema.json\` | (object) |
|
|
376
|
-
| \`contracts
|
|
377
|
+
| \`contracts/<name>.yaml\` | \`contract.schema.json\` | \`<contract_name>\` |
|
|
378
|
+
| \`contracts/x_*.yaml\` | \`custom-contract.schema.json\` | \`<x_name>\` |
|
|
377
379
|
| \`tokens/color.yaml\` | \`tokens/color.schema.json\` | \`color\` |
|
|
378
380
|
| \`tokens/typography.yaml\` | \`tokens/typography.schema.json\` | \`typography\` |
|
|
379
381
|
| \`tokens/spacing.yaml\` | \`tokens/spacing.schema.json\` | \`spacing\` |
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
# action_trigger contract
|
|
2
|
-
#
|
|
3
|
-
# The canonical definition lives in spec/openuispec-v0.1.md.
|
|
1
|
+
# action_trigger contract extension
|
|
2
|
+
# Base definition: spec Section 4.1
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
spec_section: "4"
|
|
7
|
-
source: "spec/openuispec-v0.1.md"
|
|
4
|
+
action_trigger: {}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
# collection contract
|
|
2
|
-
#
|
|
3
|
-
# The canonical definition lives in spec/openuispec-v0.1.md.
|
|
1
|
+
# collection contract extension
|
|
2
|
+
# Base definition: spec Section 4.7
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
spec_section: "4"
|
|
7
|
-
source: "spec/openuispec-v0.1.md"
|
|
4
|
+
collection: {}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
# data_display contract
|
|
2
|
-
#
|
|
3
|
-
# The canonical definition lives in spec/openuispec-v0.1.md.
|
|
1
|
+
# data_display contract extension
|
|
2
|
+
# Base definition: spec Section 4.2
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
spec_section: "4"
|
|
7
|
-
source: "spec/openuispec-v0.1.md"
|
|
4
|
+
data_display: {}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
# feedback contract
|
|
2
|
-
#
|
|
3
|
-
# The canonical definition lives in spec/openuispec-v0.1.md.
|
|
1
|
+
# feedback contract extension
|
|
2
|
+
# Base definition: spec Section 4.5
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
spec_section: "4"
|
|
7
|
-
source: "spec/openuispec-v0.1.md"
|
|
4
|
+
feedback: {}
|
|
@@ -1,7 +1,23 @@
|
|
|
1
|
-
# input_field contract
|
|
2
|
-
#
|
|
3
|
-
#
|
|
1
|
+
# input_field contract extension
|
|
2
|
+
# Base definition: spec Section 4.3
|
|
3
|
+
# Add project-specific variants, token overrides, and generation hints.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
input_field:
|
|
6
|
+
variants:
|
|
7
|
+
cut_corner:
|
|
8
|
+
semantic: "Angled corner input for branded forms"
|
|
9
|
+
tokens:
|
|
10
|
+
cut_size: "spacing.sm"
|
|
11
|
+
border: { color: "color.semantic.border", width: 1 }
|
|
12
|
+
background: "color.semantic.surface"
|
|
13
|
+
platform_mapping:
|
|
14
|
+
ios: { shape: "CutCornerShape", clip: true }
|
|
15
|
+
android: { shape: "CutCornerShape" }
|
|
16
|
+
web: { style: "clip-path" }
|
|
17
|
+
generation:
|
|
18
|
+
must_handle:
|
|
19
|
+
- "Cut top-right and bottom-left corners by cut_size"
|
|
20
|
+
- "Maintain focus ring that follows the cut shape"
|
|
21
|
+
- "Placeholder text must remain readable against background"
|
|
22
|
+
should_handle:
|
|
23
|
+
- "Animate corner cut on focus"
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
# nav_container contract
|
|
2
|
-
#
|
|
3
|
-
# The canonical definition lives in spec/openuispec-v0.1.md.
|
|
1
|
+
# nav_container contract extension
|
|
2
|
+
# Base definition: spec Section 4.4
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
spec_section: "4"
|
|
7
|
-
source: "spec/openuispec-v0.1.md"
|
|
4
|
+
nav_container: {}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
# surface contract
|
|
2
|
-
#
|
|
3
|
-
# The canonical definition lives in spec/openuispec-v0.1.md.
|
|
1
|
+
# surface contract extension
|
|
2
|
+
# Base definition: spec Section 4.6
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
spec_section: "4"
|
|
7
|
-
source: "spec/openuispec-v0.1.md"
|
|
4
|
+
surface: {}
|
package/package.json
CHANGED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openuispec.org/schema/contract.schema.json",
|
|
4
|
+
"title": "OpenUISpec Standard Contract Extension",
|
|
5
|
+
"description": "Extension file for a standard contract — add variants, override tokens, platform mapping, and generation hints",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"minProperties": 1,
|
|
8
|
+
"maxProperties": 1,
|
|
9
|
+
"propertyNames": {
|
|
10
|
+
"enum": [
|
|
11
|
+
"action_trigger",
|
|
12
|
+
"data_display",
|
|
13
|
+
"input_field",
|
|
14
|
+
"nav_container",
|
|
15
|
+
"feedback",
|
|
16
|
+
"surface",
|
|
17
|
+
"collection"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"additionalProperties": {
|
|
21
|
+
"$ref": "#/$defs/contract_extension"
|
|
22
|
+
},
|
|
23
|
+
"$defs": {
|
|
24
|
+
"contract_extension": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"description": "Extension definition — all fields are optional, they add to or override the spec-defined contract",
|
|
27
|
+
"properties": {
|
|
28
|
+
"variants": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"description": "Named style/behavior variants (e.g. cut_corner, branded, minimal)",
|
|
31
|
+
"additionalProperties": {
|
|
32
|
+
"$ref": "#/$defs/variant_def"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"additional_props": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"description": "Additional props beyond the spec definition",
|
|
38
|
+
"additionalProperties": {
|
|
39
|
+
"$ref": "https://openuispec.org/schema/custom-contract.schema.json#/$defs/prop_def"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"tokens": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"description": "Token overrides at the contract level",
|
|
45
|
+
"additionalProperties": true
|
|
46
|
+
},
|
|
47
|
+
"platform_mapping": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"description": "Platform mapping overrides",
|
|
50
|
+
"properties": {
|
|
51
|
+
"ios": { "type": "object", "additionalProperties": true },
|
|
52
|
+
"android": { "type": "object", "additionalProperties": true },
|
|
53
|
+
"web": { "type": "object", "additionalProperties": true }
|
|
54
|
+
},
|
|
55
|
+
"additionalProperties": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"additionalProperties": true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"generation": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"description": "AI generation compliance hints (merged with spec defaults)",
|
|
63
|
+
"properties": {
|
|
64
|
+
"must_handle": {
|
|
65
|
+
"type": "array",
|
|
66
|
+
"items": { "type": "string" }
|
|
67
|
+
},
|
|
68
|
+
"should_handle": {
|
|
69
|
+
"type": "array",
|
|
70
|
+
"items": { "type": "string" }
|
|
71
|
+
},
|
|
72
|
+
"may_handle": {
|
|
73
|
+
"type": "array",
|
|
74
|
+
"items": { "type": "string" }
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"additionalProperties": false
|
|
78
|
+
},
|
|
79
|
+
"test_cases": {
|
|
80
|
+
"type": "array",
|
|
81
|
+
"description": "Additional behavioral test cases",
|
|
82
|
+
"items": {
|
|
83
|
+
"$ref": "https://openuispec.org/schema/custom-contract.schema.json#/$defs/test_case"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"additionalProperties": false
|
|
88
|
+
},
|
|
89
|
+
"variant_def": {
|
|
90
|
+
"type": "object",
|
|
91
|
+
"description": "A named variant with semantic description, tokens, platform mapping, and generation hints",
|
|
92
|
+
"properties": {
|
|
93
|
+
"semantic": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"description": "Human-readable description of this variant"
|
|
96
|
+
},
|
|
97
|
+
"tokens": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"description": "Visual token bindings for this variant",
|
|
100
|
+
"additionalProperties": true
|
|
101
|
+
},
|
|
102
|
+
"platform_mapping": {
|
|
103
|
+
"type": "object",
|
|
104
|
+
"description": "Per-platform implementation hints for this variant",
|
|
105
|
+
"properties": {
|
|
106
|
+
"ios": { "type": "object", "additionalProperties": true },
|
|
107
|
+
"android": { "type": "object", "additionalProperties": true },
|
|
108
|
+
"web": { "type": "object", "additionalProperties": true }
|
|
109
|
+
},
|
|
110
|
+
"additionalProperties": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"additionalProperties": true
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"generation": {
|
|
116
|
+
"type": "object",
|
|
117
|
+
"description": "Generation hints specific to this variant",
|
|
118
|
+
"properties": {
|
|
119
|
+
"must_handle": { "type": "array", "items": { "type": "string" } },
|
|
120
|
+
"should_handle": { "type": "array", "items": { "type": "string" } },
|
|
121
|
+
"may_handle": { "type": "array", "items": { "type": "string" } }
|
|
122
|
+
},
|
|
123
|
+
"additionalProperties": false
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"additionalProperties": false
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
package/schema/validate.ts
CHANGED
|
@@ -275,18 +275,17 @@ const GROUPS: Record<string, ValidationGroup> = {
|
|
|
275
275
|
},
|
|
276
276
|
},
|
|
277
277
|
|
|
278
|
-
|
|
279
|
-
label: "
|
|
278
|
+
contracts: {
|
|
279
|
+
label: "Contracts",
|
|
280
280
|
run(ajv, projectDir, includes) {
|
|
281
281
|
let errors = 0;
|
|
282
282
|
const dir = resolveInclude(projectDir, includes.contracts);
|
|
283
283
|
for (const f of listFiles(dir, ".yaml")) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
);
|
|
284
|
+
const name = basename(f);
|
|
285
|
+
if (name.startsWith("x_")) {
|
|
286
|
+
errors += validateFile(ajv, f, `${BASE}custom-contract.schema.json`);
|
|
287
|
+
} else {
|
|
288
|
+
errors += validateFile(ajv, f, `${BASE}contract.schema.json`);
|
|
290
289
|
}
|
|
291
290
|
}
|
|
292
291
|
return errors;
|