@cloudcrane/app-spec 0.0.0-stage → 0.1.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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -2
  3. package/dist/src/a2ui.d.ts +12 -0
  4. package/dist/src/a2ui.js +89 -0
  5. package/dist/src/blueprint.d.ts +27 -0
  6. package/dist/src/blueprint.js +62 -0
  7. package/dist/src/canonical.d.ts +2 -0
  8. package/dist/src/canonical.js +8 -0
  9. package/dist/src/catalog.d.ts +7 -0
  10. package/dist/src/catalog.js +83 -0
  11. package/dist/src/index.d.ts +9 -0
  12. package/dist/src/index.js +11 -0
  13. package/dist/src/jsonschema.d.ts +2 -0
  14. package/dist/src/jsonschema.js +11 -0
  15. package/dist/src/leak.d.ts +3 -0
  16. package/dist/src/leak.js +138 -0
  17. package/dist/src/logic.d.ts +36 -0
  18. package/dist/src/logic.js +197 -0
  19. package/dist/src/schema.d.ts +418 -0
  20. package/dist/src/schema.js +137 -0
  21. package/dist/src/validate.d.ts +6 -0
  22. package/dist/src/validate.js +54 -0
  23. package/dist/vendor/a2ui/v0_9_1/catalogs/basic/catalog.json +1383 -0
  24. package/dist/vendor/a2ui/v0_9_1/common_types.json +305 -0
  25. package/dist/vendor/a2ui/v0_9_1/server_to_client.json +131 -0
  26. package/package.json +78 -3
  27. package/schema/app-spec.v1.json +460 -0
  28. package/vendor/a2ui/v0_9_1/LICENSE +227 -0
  29. package/vendor/a2ui/v0_9_1/VENDOR.json +6 -0
  30. package/vendor/a2ui/v0_9_1/catalogs/basic/catalog.json +1383 -0
  31. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/00_complex-layout.json +65 -0
  32. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/00_formatted-text.json +56 -0
  33. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/00_incremental.json +134 -0
  34. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/00_interactive-button.json +51 -0
  35. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/00_row-layout.json +40 -0
  36. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/00_simple-login-form.json +77 -0
  37. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/00_simple-text.json +27 -0
  38. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/01_flight-status.json +201 -0
  39. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/02_email-compose.json +185 -0
  40. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/03_calendar-day.json +166 -0
  41. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/04_weather-current.json +168 -0
  42. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/05_product-card.json +151 -0
  43. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/06_music-player.json +165 -0
  44. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/07_task-card.json +107 -0
  45. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/08_user-profile.json +190 -0
  46. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/09_login-form.json +214 -0
  47. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/10_notification-permission.json +105 -0
  48. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/11_purchase-complete.json +169 -0
  49. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/12_chat-message.json +144 -0
  50. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/13_coffee-order.json +253 -0
  51. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/14_sports-player.json +177 -0
  52. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/15_account-balance.json +126 -0
  53. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/16_workout-summary.json +160 -0
  54. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/17_event-detail.json +144 -0
  55. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/18_track-list.json +152 -0
  56. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/19_software-purchase.json +194 -0
  57. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/20_restaurant-card.json +140 -0
  58. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/21_shipping-status.json +137 -0
  59. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/22_credit-card.json +117 -0
  60. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/23_step-counter.json +149 -0
  61. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/24_recipe-card.json +204 -0
  62. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/25_contact-card.json +175 -0
  63. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/26_podcast-episode.json +123 -0
  64. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/27_stats-card.json +106 -0
  65. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/28_countdown-timer.json +135 -0
  66. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/29_movie-card.json +156 -0
  67. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/30_live-invitation-builder.json +205 -0
  68. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/31_incremental-dashboard.json +128 -0
  69. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/32_advanced-form-validator.json +166 -0
  70. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/33_financial-data-grid.json +171 -0
  71. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/34_child-list-template.json +80 -0
  72. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/35_markdown-text.json +44 -0
  73. package/vendor/a2ui/v0_9_1/catalogs/basic/examples/36_modal.json +65 -0
  74. package/vendor/a2ui/v0_9_1/client_capabilities.json +89 -0
  75. package/vendor/a2ui/v0_9_1/client_data_model.json +22 -0
  76. package/vendor/a2ui/v0_9_1/client_to_server.json +98 -0
  77. package/vendor/a2ui/v0_9_1/client_to_server_list.json +10 -0
  78. package/vendor/a2ui/v0_9_1/client_to_server_list_wrapper.json +14 -0
  79. package/vendor/a2ui/v0_9_1/common_types.json +305 -0
  80. package/vendor/a2ui/v0_9_1/sample.json +22 -0
  81. package/vendor/a2ui/v0_9_1/server_capabilities.json +26 -0
  82. package/vendor/a2ui/v0_9_1/server_to_client.json +132 -0
  83. package/vendor/a2ui/v0_9_1/server_to_client_list.json +10 -0
  84. package/vendor/a2ui/v0_9_1/server_to_client_list_wrapper.json +14 -0
@@ -0,0 +1,185 @@
1
+ {
2
+ "name": "Email Compose",
3
+ "description": "Example of email compose",
4
+ "messages": [
5
+ {
6
+ "version": "v0.9",
7
+ "createSurface": {
8
+ "surfaceId": "gallery-email-compose",
9
+ "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json",
10
+ "sendDataModel": true
11
+ }
12
+ },
13
+ {
14
+ "version": "v0.9",
15
+ "updateComponents": {
16
+ "surfaceId": "gallery-email-compose",
17
+ "components": [
18
+ {
19
+ "id": "root",
20
+ "component": "Card",
21
+ "child": "main-column"
22
+ },
23
+ {
24
+ "id": "main-column",
25
+ "component": "Column",
26
+ "children": ["from-row", "to-row", "subject-row", "divider", "message", "actions"]
27
+ },
28
+ {
29
+ "id": "from-row",
30
+ "component": "Row",
31
+ "children": ["from-label", "from-value"],
32
+ "align": "center"
33
+ },
34
+ {
35
+ "id": "from-label",
36
+ "component": "Text",
37
+ "text": "FROM",
38
+ "variant": "caption"
39
+ },
40
+ {
41
+ "id": "from-value",
42
+ "component": "Text",
43
+ "text": {
44
+ "path": "/from"
45
+ },
46
+ "variant": "body"
47
+ },
48
+ {
49
+ "id": "to-row",
50
+ "component": "Row",
51
+ "children": ["to-label", "to-value"],
52
+ "align": "center"
53
+ },
54
+ {
55
+ "id": "to-label",
56
+ "component": "Text",
57
+ "text": "TO",
58
+ "variant": "caption"
59
+ },
60
+ {
61
+ "id": "to-value",
62
+ "component": "Text",
63
+ "text": {
64
+ "path": "/to"
65
+ },
66
+ "variant": "body"
67
+ },
68
+ {
69
+ "id": "subject-row",
70
+ "component": "Row",
71
+ "children": ["subject-label", "subject-value"],
72
+ "align": "center"
73
+ },
74
+ {
75
+ "id": "subject-label",
76
+ "component": "Text",
77
+ "text": "SUBJECT",
78
+ "variant": "caption"
79
+ },
80
+ {
81
+ "id": "subject-value",
82
+ "component": "Text",
83
+ "text": {
84
+ "path": "/subject"
85
+ },
86
+ "variant": "body"
87
+ },
88
+ {
89
+ "id": "divider",
90
+ "component": "Divider"
91
+ },
92
+ {
93
+ "id": "message",
94
+ "component": "Column",
95
+ "children": ["greeting", "body-text", "closing", "signature"]
96
+ },
97
+ {
98
+ "id": "greeting",
99
+ "component": "Text",
100
+ "text": {
101
+ "path": "/greeting"
102
+ },
103
+ "variant": "body"
104
+ },
105
+ {
106
+ "id": "body-text",
107
+ "component": "Text",
108
+ "text": {
109
+ "path": "/body"
110
+ },
111
+ "variant": "body"
112
+ },
113
+ {
114
+ "id": "closing",
115
+ "component": "Text",
116
+ "text": {
117
+ "path": "/closing"
118
+ },
119
+ "variant": "body"
120
+ },
121
+ {
122
+ "id": "signature",
123
+ "component": "Text",
124
+ "text": {
125
+ "path": "/signature"
126
+ },
127
+ "variant": "body"
128
+ },
129
+ {
130
+ "id": "actions",
131
+ "component": "Row",
132
+ "children": ["send-btn", "discard-btn"]
133
+ },
134
+ {
135
+ "id": "send-btn-text",
136
+ "component": "Text",
137
+ "text": "Send email"
138
+ },
139
+ {
140
+ "id": "send-btn",
141
+ "component": "Button",
142
+ "child": "send-btn-text",
143
+ "action": {
144
+ "event": {
145
+ "name": "send",
146
+ "context": {}
147
+ }
148
+ }
149
+ },
150
+ {
151
+ "id": "discard-btn-text",
152
+ "component": "Text",
153
+ "text": "Discard"
154
+ },
155
+ {
156
+ "id": "discard-btn",
157
+ "component": "Button",
158
+ "child": "discard-btn-text",
159
+ "action": {
160
+ "event": {
161
+ "name": "discard",
162
+ "context": {}
163
+ }
164
+ }
165
+ }
166
+ ]
167
+ }
168
+ },
169
+ {
170
+ "version": "v0.9",
171
+ "updateDataModel": {
172
+ "surfaceId": "gallery-email-compose",
173
+ "value": {
174
+ "from": "alex@acme.com",
175
+ "to": "jordan@acme.com",
176
+ "subject": "Q4 Revenue Forecast",
177
+ "greeting": "Hi Jordan,",
178
+ "body": "Following up on our call. Please review the attached Q4 forecast and let me know if you have questions before the board meeting.",
179
+ "closing": "Best,",
180
+ "signature": "Alex"
181
+ }
182
+ }
183
+ }
184
+ ]
185
+ }
@@ -0,0 +1,166 @@
1
+ {
2
+ "name": "Calendar Day",
3
+ "description": "Example of calendar day demonstrating dynamic templating, relative paths, and date formatting.",
4
+ "messages": [
5
+ {
6
+ "version": "v0.9",
7
+ "createSurface": {
8
+ "surfaceId": "gallery-calendar-day",
9
+ "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json",
10
+ "sendDataModel": true
11
+ }
12
+ },
13
+ {
14
+ "version": "v0.9",
15
+ "updateComponents": {
16
+ "surfaceId": "gallery-calendar-day",
17
+ "components": [
18
+ {
19
+ "id": "root",
20
+ "component": "Card",
21
+ "child": "main-column"
22
+ },
23
+ {
24
+ "id": "main-column",
25
+ "component": "Column",
26
+ "children": ["header-row", "divider", "actions"]
27
+ },
28
+ {
29
+ "id": "header-row",
30
+ "component": "Row",
31
+ "children": ["date-col", "events-col"]
32
+ },
33
+ {
34
+ "id": "date-col",
35
+ "component": "Column",
36
+ "children": ["day-name", "day-number"],
37
+ "align": "start"
38
+ },
39
+ {
40
+ "id": "day-name",
41
+ "component": "Text",
42
+ "text": {
43
+ "call": "formatDate",
44
+ "args": {
45
+ "value": {
46
+ "path": "/date"
47
+ },
48
+ "format": "EEEE"
49
+ },
50
+ "returnType": "string"
51
+ },
52
+ "variant": "caption"
53
+ },
54
+ {
55
+ "id": "day-number",
56
+ "component": "Text",
57
+ "text": {
58
+ "call": "formatDate",
59
+ "args": {
60
+ "value": {
61
+ "path": "/date"
62
+ },
63
+ "format": "d"
64
+ },
65
+ "returnType": "string"
66
+ },
67
+ "variant": "h1"
68
+ },
69
+ {
70
+ "id": "events-col",
71
+ "component": "Column",
72
+ "children": {
73
+ "path": "/events",
74
+ "componentId": "event-template"
75
+ }
76
+ },
77
+ {
78
+ "id": "event-template",
79
+ "component": "Column",
80
+ "children": ["event-title", "event-time"]
81
+ },
82
+ {
83
+ "id": "event-title",
84
+ "component": "Text",
85
+ "text": {
86
+ "path": "title"
87
+ },
88
+ "variant": "body"
89
+ },
90
+ {
91
+ "id": "event-time",
92
+ "component": "Text",
93
+ "text": {
94
+ "path": "time"
95
+ },
96
+ "variant": "caption"
97
+ },
98
+ {
99
+ "id": "divider",
100
+ "component": "Divider"
101
+ },
102
+ {
103
+ "id": "actions",
104
+ "component": "Row",
105
+ "children": ["add-btn", "discard-btn"]
106
+ },
107
+ {
108
+ "id": "add-btn-text",
109
+ "component": "Text",
110
+ "text": "Add to calendar"
111
+ },
112
+ {
113
+ "id": "add-btn",
114
+ "component": "Button",
115
+ "child": "add-btn-text",
116
+ "action": {
117
+ "event": {
118
+ "name": "add",
119
+ "context": {}
120
+ }
121
+ }
122
+ },
123
+ {
124
+ "id": "discard-btn-text",
125
+ "component": "Text",
126
+ "text": "Discard"
127
+ },
128
+ {
129
+ "id": "discard-btn",
130
+ "component": "Button",
131
+ "child": "discard-btn-text",
132
+ "action": {
133
+ "event": {
134
+ "name": "discard",
135
+ "context": {}
136
+ }
137
+ }
138
+ }
139
+ ]
140
+ }
141
+ },
142
+ {
143
+ "version": "v0.9",
144
+ "updateDataModel": {
145
+ "surfaceId": "gallery-calendar-day",
146
+ "value": {
147
+ "date": "2025-12-28",
148
+ "events": [
149
+ {
150
+ "title": "Lunch",
151
+ "time": "12:00 - 12:45 PM"
152
+ },
153
+ {
154
+ "title": "Q1 roadmap review",
155
+ "time": "1:00 - 2:00 PM"
156
+ },
157
+ {
158
+ "title": "Team standup",
159
+ "time": "3:30 - 4:00 PM"
160
+ }
161
+ ]
162
+ }
163
+ }
164
+ }
165
+ ]
166
+ }
@@ -0,0 +1,168 @@
1
+ {
2
+ "name": "Weather Current",
3
+ "description": "Example of weather current demonstrating templating and string formatting.",
4
+ "messages": [
5
+ {
6
+ "version": "v0.9",
7
+ "createSurface": {
8
+ "surfaceId": "gallery-weather-current",
9
+ "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json",
10
+ "sendDataModel": true
11
+ }
12
+ },
13
+ {
14
+ "version": "v0.9",
15
+ "updateComponents": {
16
+ "surfaceId": "gallery-weather-current",
17
+ "components": [
18
+ {
19
+ "id": "root",
20
+ "component": "Card",
21
+ "child": "main-column"
22
+ },
23
+ {
24
+ "id": "main-column",
25
+ "component": "Column",
26
+ "children": ["temp-row", "location", "description", "forecast-row"],
27
+ "align": "center"
28
+ },
29
+ {
30
+ "id": "temp-row",
31
+ "component": "Row",
32
+ "children": ["temp-high", "temp-low"],
33
+ "align": "start"
34
+ },
35
+ {
36
+ "id": "temp-high",
37
+ "component": "Text",
38
+ "text": {
39
+ "call": "formatString",
40
+ "args": {
41
+ "value": "${/tempHigh}°"
42
+ },
43
+ "returnType": "string"
44
+ },
45
+ "variant": "h1"
46
+ },
47
+ {
48
+ "id": "temp-low",
49
+ "component": "Text",
50
+ "text": {
51
+ "call": "formatString",
52
+ "args": {
53
+ "value": "${/tempLow}°"
54
+ },
55
+ "returnType": "string"
56
+ },
57
+ "variant": "h2"
58
+ },
59
+ {
60
+ "id": "location",
61
+ "component": "Text",
62
+ "text": {
63
+ "path": "/location"
64
+ },
65
+ "variant": "h3"
66
+ },
67
+ {
68
+ "id": "description",
69
+ "component": "Text",
70
+ "text": {
71
+ "path": "/description"
72
+ },
73
+ "variant": "caption"
74
+ },
75
+ {
76
+ "id": "forecast-row",
77
+ "component": "Row",
78
+ "children": {
79
+ "path": "/forecast",
80
+ "componentId": "forecast-day-template"
81
+ },
82
+ "justify": "spaceAround"
83
+ },
84
+ {
85
+ "id": "forecast-day-template",
86
+ "component": "Column",
87
+ "children": ["day-name", "day-icon", "day-temp"],
88
+ "align": "center"
89
+ },
90
+ {
91
+ "id": "day-name",
92
+ "component": "Text",
93
+ "text": {
94
+ "call": "formatDate",
95
+ "args": {
96
+ "value": {
97
+ "path": "date"
98
+ },
99
+ "format": "E"
100
+ },
101
+ "returnType": "string"
102
+ },
103
+ "variant": "caption"
104
+ },
105
+ {
106
+ "id": "day-icon",
107
+ "component": "Text",
108
+ "text": {
109
+ "path": "icon"
110
+ },
111
+ "variant": "h3"
112
+ },
113
+ {
114
+ "id": "day-temp",
115
+ "component": "Text",
116
+ "text": {
117
+ "call": "formatString",
118
+ "args": {
119
+ "value": "${temp}°"
120
+ },
121
+ "returnType": "string"
122
+ },
123
+ "variant": "caption"
124
+ }
125
+ ]
126
+ }
127
+ },
128
+ {
129
+ "version": "v0.9",
130
+ "updateDataModel": {
131
+ "surfaceId": "gallery-weather-current",
132
+ "value": {
133
+ "tempHigh": 72,
134
+ "tempLow": 58,
135
+ "location": "Austin, TX",
136
+ "description": "Clear skies with light breeze",
137
+ "forecast": [
138
+ {
139
+ "date": "2025-12-16",
140
+ "icon": "☀️",
141
+ "temp": 74
142
+ },
143
+ {
144
+ "date": "2025-12-17",
145
+ "icon": "☀️",
146
+ "temp": 76
147
+ },
148
+ {
149
+ "date": "2025-12-18",
150
+ "icon": "⛅",
151
+ "temp": 71
152
+ },
153
+ {
154
+ "date": "2025-12-19",
155
+ "icon": "☀️",
156
+ "temp": 73
157
+ },
158
+ {
159
+ "date": "2025-12-20",
160
+ "icon": "☀️",
161
+ "temp": 75
162
+ }
163
+ ]
164
+ }
165
+ }
166
+ }
167
+ ]
168
+ }
@@ -0,0 +1,151 @@
1
+ {
2
+ "name": "Product Card",
3
+ "description": "Example of product card demonstrating currency formatting and pluralization.",
4
+ "messages": [
5
+ {
6
+ "version": "v0.9",
7
+ "createSurface": {
8
+ "surfaceId": "gallery-product-card",
9
+ "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json",
10
+ "sendDataModel": true
11
+ }
12
+ },
13
+ {
14
+ "version": "v0.9",
15
+ "updateComponents": {
16
+ "surfaceId": "gallery-product-card",
17
+ "components": [
18
+ {
19
+ "id": "root",
20
+ "component": "Card",
21
+ "child": "main-column"
22
+ },
23
+ {
24
+ "id": "main-column",
25
+ "component": "Column",
26
+ "children": ["image", "details"]
27
+ },
28
+ {
29
+ "id": "image",
30
+ "component": "Image",
31
+ "url": {
32
+ "path": "/imageUrl"
33
+ },
34
+ "fit": "cover"
35
+ },
36
+ {
37
+ "id": "details",
38
+ "component": "Column",
39
+ "children": ["name", "rating-row", "price-row", "actions"]
40
+ },
41
+ {
42
+ "id": "name",
43
+ "component": "Text",
44
+ "text": {
45
+ "path": "/name"
46
+ },
47
+ "variant": "h3"
48
+ },
49
+ {
50
+ "id": "rating-row",
51
+ "component": "Row",
52
+ "children": ["stars", "reviews"],
53
+ "align": "center"
54
+ },
55
+ {
56
+ "id": "stars",
57
+ "component": "Text",
58
+ "text": {
59
+ "path": "/stars"
60
+ },
61
+ "variant": "body"
62
+ },
63
+ {
64
+ "id": "reviews",
65
+ "component": "Text",
66
+ "text": {
67
+ "call": "formatString",
68
+ "args": {
69
+ "value": "(${formatNumber(value: ${/reviewCount})} ${pluralize(value: ${/reviewCount}, one: 'review', other: 'reviews')})"
70
+ },
71
+ "returnType": "string"
72
+ },
73
+ "variant": "caption"
74
+ },
75
+ {
76
+ "id": "price-row",
77
+ "component": "Row",
78
+ "children": ["price", "original-price"],
79
+ "align": "start"
80
+ },
81
+ {
82
+ "id": "price",
83
+ "component": "Text",
84
+ "text": {
85
+ "call": "formatCurrency",
86
+ "args": {
87
+ "value": {
88
+ "path": "/price"
89
+ },
90
+ "currency": "USD"
91
+ },
92
+ "returnType": "string"
93
+ },
94
+ "variant": "h2"
95
+ },
96
+ {
97
+ "id": "original-price",
98
+ "component": "Text",
99
+ "text": {
100
+ "call": "formatCurrency",
101
+ "args": {
102
+ "value": {
103
+ "path": "/originalPrice"
104
+ },
105
+ "currency": "USD"
106
+ },
107
+ "returnType": "string"
108
+ },
109
+ "variant": "caption"
110
+ },
111
+ {
112
+ "id": "actions",
113
+ "component": "Row",
114
+ "children": ["add-cart-btn"]
115
+ },
116
+ {
117
+ "id": "add-cart-btn-text",
118
+ "component": "Text",
119
+ "text": "Add to Cart"
120
+ },
121
+ {
122
+ "id": "add-cart-btn",
123
+ "component": "Button",
124
+ "child": "add-cart-btn-text",
125
+ "variant": "primary",
126
+ "action": {
127
+ "event": {
128
+ "name": "addToCart",
129
+ "context": {}
130
+ }
131
+ }
132
+ }
133
+ ]
134
+ }
135
+ },
136
+ {
137
+ "version": "v0.9",
138
+ "updateDataModel": {
139
+ "surfaceId": "gallery-product-card",
140
+ "value": {
141
+ "imageUrl": "https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=300&h=200&fit=crop",
142
+ "name": "Wireless Headphones Pro",
143
+ "stars": "★★★★★",
144
+ "reviewCount": 2847,
145
+ "price": 199.99,
146
+ "originalPrice": 249.99
147
+ }
148
+ }
149
+ }
150
+ ]
151
+ }