diff --git a/specification/v0_9/json/catalogs/basic/examples/01_flight-status.json b/specification/v0_9/json/catalogs/basic/examples/01_flight-status.json index 544de7d3e..6789e35dd 100644 --- a/specification/v0_9/json/catalogs/basic/examples/01_flight-status.json +++ b/specification/v0_9/json/catalogs/basic/examples/01_flight-status.json @@ -1,6 +1,6 @@ { "name": "Flight Status", - "description": "Example of flight status", + "description": "Example of flight status demonstrating date formatting.", "messages": [ { "version": "v0.9", @@ -67,7 +67,14 @@ "id": "date", "component": "Text", "text": { - "path": "/date" + "call": "formatDate", + "args": { + "value": { + "path": "/date" + }, + "format": "E, MMM d" + }, + "returnType": "string" }, "variant": "caption" }, @@ -136,7 +143,14 @@ "id": "departure-time", "component": "Text", "text": { - "path": "/departureTime" + "call": "formatDate", + "args": { + "value": { + "path": "/departureTime" + }, + "format": "h:mm a" + }, + "returnType": "string" }, "variant": "h3" }, @@ -182,7 +196,14 @@ "id": "arrival-time", "component": "Text", "text": { - "path": "/arrivalTime" + "call": "formatDate", + "args": { + "value": { + "path": "/arrivalTime" + }, + "format": "h:mm a" + }, + "returnType": "string" }, "variant": "h3" } @@ -195,12 +216,12 @@ "surfaceId": "gallery-flight-status", "value": { "flightNumber": "OS 87", - "date": "Mon, Dec 15", + "date": "2025-12-15", "origin": "Vienna", "destination": "New York", - "departureTime": "10:15 AM", + "departureTime": "2025-12-15T10:15:00Z", "status": "On Time", - "arrivalTime": "2:30 PM" + "arrivalTime": "2025-12-15T14:30:00Z" } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/03_calendar-day.json b/specification/v0_9/json/catalogs/basic/examples/03_calendar-day.json index e9776b68e..fb29644c8 100644 --- a/specification/v0_9/json/catalogs/basic/examples/03_calendar-day.json +++ b/specification/v0_9/json/catalogs/basic/examples/03_calendar-day.json @@ -1,6 +1,6 @@ { "name": "Calendar Day", - "description": "Example of calendar day", + "description": "Example of calendar day demonstrating dynamic templating, relative paths, and date formatting.", "messages": [ { "version": "v0.9", @@ -50,7 +50,14 @@ "id": "day-name", "component": "Text", "text": { - "path": "/dayName" + "call": "formatDate", + "args": { + "value": { + "path": "/date" + }, + "format": "EEEE" + }, + "returnType": "string" }, "variant": "caption" }, @@ -58,88 +65,46 @@ "id": "day-number", "component": "Text", "text": { - "path": "/dayNumber" + "call": "formatDate", + "args": { + "value": { + "path": "/date" + }, + "format": "d" + }, + "returnType": "string" }, "variant": "h1" }, { "id": "events-col", "component": "Column", - "children": [ - "event1", - "event2", - "event3" - ] - }, - { - "id": "event1", - "component": "Column", - "children": [ - "event1-title", - "event1-time" - ] - }, - { - "id": "event1-title", - "component": "Text", - "text": { - "path": "/event1/title" - }, - "variant": "body" - }, - { - "id": "event1-time", - "component": "Text", - "text": { - "path": "/event1/time" - }, - "variant": "caption" - }, - { - "id": "event2", - "component": "Column", - "children": [ - "event2-title", - "event2-time" - ] - }, - { - "id": "event2-title", - "component": "Text", - "text": { - "path": "/event2/title" - }, - "variant": "body" - }, - { - "id": "event2-time", - "component": "Text", - "text": { - "path": "/event2/time" - }, - "variant": "caption" + "children": { + "path": "/events", + "componentId": "event-template" + } }, { - "id": "event3", + "id": "event-template", "component": "Column", "children": [ - "event3-title", - "event3-time" + "event-title", + "event-time" ] }, { - "id": "event3-title", + "id": "event-title", "component": "Text", "text": { - "path": "/event3/title" + "path": "title" }, "variant": "body" }, { - "id": "event3-time", + "id": "event-time", "component": "Text", "text": { - "path": "/event3/time" + "path": "time" }, "variant": "caption" }, @@ -195,20 +160,21 @@ "updateDataModel": { "surfaceId": "gallery-calendar-day", "value": { - "dayName": "Friday", - "dayNumber": "28", - "event1": { - "title": "Lunch", - "time": "12:00 - 12:45 PM" - }, - "event2": { - "title": "Q1 roadmap review", - "time": "1:00 - 2:00 PM" - }, - "event3": { - "title": "Team standup", - "time": "3:30 - 4:00 PM" - } + "date": "2025-12-28", + "events": [ + { + "title": "Lunch", + "time": "12:00 - 12:45 PM" + }, + { + "title": "Q1 roadmap review", + "time": "1:00 - 2:00 PM" + }, + { + "title": "Team standup", + "time": "3:30 - 4:00 PM" + } + ] } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/04_weather-current.json b/specification/v0_9/json/catalogs/basic/examples/04_weather-current.json index c6f50f525..7e434bdbf 100644 --- a/specification/v0_9/json/catalogs/basic/examples/04_weather-current.json +++ b/specification/v0_9/json/catalogs/basic/examples/04_weather-current.json @@ -1,6 +1,6 @@ { "name": "Weather Current", - "description": "Example of weather current", + "description": "Example of weather current demonstrating templating and string formatting.", "messages": [ { "version": "v0.9", @@ -44,7 +44,11 @@ "id": "temp-high", "component": "Text", "text": { - "path": "/tempHigh" + "call": "formatString", + "args": { + "value": "${/tempHigh}°" + }, + "returnType": "string" }, "variant": "h1" }, @@ -52,7 +56,11 @@ "id": "temp-low", "component": "Text", "text": { - "path": "/tempLow" + "call": "formatString", + "args": { + "value": "${/tempLow}°" + }, + "returnType": "string" }, "variant": "h2" }, @@ -75,137 +83,54 @@ { "id": "forecast-row", "component": "Row", - "children": [ - "day1", - "day2", - "day3", - "day4", - "day5" - ], - "justify": "spaceAround" - }, - { - "id": "day1", - "component": "Column", - "children": [ - "day1-icon", - "day1-temp" - ], - "align": "center" - }, - { - "id": "day1-icon", - "component": "Text", - "text": { - "path": "/forecast/0/icon" + "children": { + "path": "/forecast", + "componentId": "forecast-day-template" }, - "variant": "h3" - }, - { - "id": "day1-temp", - "component": "Text", - "text": { - "path": "/forecast/0/temp" - }, - "variant": "caption" - }, - { - "id": "day2", - "component": "Column", - "children": [ - "day2-icon", - "day2-temp" - ], - "align": "center" - }, - { - "id": "day2-icon", - "component": "Text", - "text": { - "path": "/forecast/1/icon" - }, - "variant": "h3" - }, - { - "id": "day2-temp", - "component": "Text", - "text": { - "path": "/forecast/1/temp" - }, - "variant": "caption" - }, - { - "id": "day3", - "component": "Column", - "children": [ - "day3-icon", - "day3-temp" - ], - "align": "center" - }, - { - "id": "day3-icon", - "component": "Text", - "text": { - "path": "/forecast/2/icon" - }, - "variant": "h3" - }, - { - "id": "day3-temp", - "component": "Text", - "text": { - "path": "/forecast/2/temp" - }, - "variant": "caption" + "justify": "spaceAround" }, { - "id": "day4", + "id": "forecast-day-template", "component": "Column", "children": [ - "day4-icon", - "day4-temp" + "day-name", + "day-icon", + "day-temp" ], "align": "center" }, { - "id": "day4-icon", + "id": "day-name", "component": "Text", "text": { - "path": "/forecast/3/icon" - }, - "variant": "h3" - }, - { - "id": "day4-temp", - "component": "Text", - "text": { - "path": "/forecast/3/temp" + "call": "formatDate", + "args": { + "value": { + "path": "date" + }, + "format": "E" + }, + "returnType": "string" }, "variant": "caption" }, { - "id": "day5", - "component": "Column", - "children": [ - "day5-icon", - "day5-temp" - ], - "align": "center" - }, - { - "id": "day5-icon", + "id": "day-icon", "component": "Text", "text": { - "path": "/forecast/4/icon" + "path": "icon" }, "variant": "h3" }, { - "id": "day5-temp", + "id": "day-temp", "component": "Text", "text": { - "path": "/forecast/4/temp" + "call": "formatString", + "args": { + "value": "${temp}°" + }, + "returnType": "string" }, "variant": "caption" } @@ -217,30 +142,35 @@ "updateDataModel": { "surfaceId": "gallery-weather-current", "value": { - "tempHigh": "72\u00b0", - "tempLow": "58\u00b0", + "tempHigh": 72, + "tempLow": 58, "location": "Austin, TX", "description": "Clear skies with light breeze", "forecast": [ { - "icon": "\u2600\ufe0f", - "temp": "74\u00b0" + "date": "2025-12-16", + "icon": "☀️", + "temp": 74 }, { - "icon": "\u2600\ufe0f", - "temp": "76\u00b0" + "date": "2025-12-17", + "icon": "☀️", + "temp": 76 }, { - "icon": "\u26c5", - "temp": "71\u00b0" + "date": "2025-12-18", + "icon": "⛅", + "temp": 71 }, { - "icon": "\u2600\ufe0f", - "temp": "73\u00b0" + "date": "2025-12-19", + "icon": "☀️", + "temp": 73 }, { - "icon": "\u2600\ufe0f", - "temp": "75\u00b0" + "date": "2025-12-20", + "icon": "☀️", + "temp": 75 } ] } diff --git a/specification/v0_9/json/catalogs/basic/examples/05_product-card.json b/specification/v0_9/json/catalogs/basic/examples/05_product-card.json index eb584e025..55b2061ab 100644 --- a/specification/v0_9/json/catalogs/basic/examples/05_product-card.json +++ b/specification/v0_9/json/catalogs/basic/examples/05_product-card.json @@ -1,6 +1,6 @@ { "name": "Product Card", - "description": "Example of product card", + "description": "Example of product card demonstrating currency formatting and pluralization.", "messages": [ { "version": "v0.9", @@ -75,7 +75,11 @@ "id": "reviews", "component": "Text", "text": { - "path": "/reviews" + "call": "formatString", + "args": { + "value": "(${formatNumber(value: ${/reviewCount})} ${pluralize(value: ${/reviewCount}, one: 'review', other: 'reviews')})" + }, + "returnType": "string" }, "variant": "caption" }, @@ -92,7 +96,14 @@ "id": "price", "component": "Text", "text": { - "path": "/price" + "call": "formatCurrency", + "args": { + "value": { + "path": "/price" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "h2" }, @@ -100,7 +111,14 @@ "id": "original-price", "component": "Text", "text": { - "path": "/originalPrice" + "call": "formatCurrency", + "args": { + "value": { + "path": "/originalPrice" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "caption" }, @@ -137,10 +155,10 @@ "value": { "imageUrl": "https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=300&h=200&fit=crop", "name": "Wireless Headphones Pro", - "stars": "\u2605\u2605\u2605\u2605\u2605", - "reviews": "(2,847 reviews)", - "price": "$199.99", - "originalPrice": "$249.99" + "stars": "★★★★★", + "reviewCount": 2847, + "price": 199.99, + "originalPrice": 249.99 } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/07_task-card.json b/specification/v0_9/json/catalogs/basic/examples/07_task-card.json index 94fa31032..8343f7a55 100644 --- a/specification/v0_9/json/catalogs/basic/examples/07_task-card.json +++ b/specification/v0_9/json/catalogs/basic/examples/07_task-card.json @@ -1,6 +1,6 @@ { "name": "Task Card", - "description": "Example of task card", + "description": "Example of task card demonstrating CheckBox and DateTimeInput.", "messages": [ { "version": "v0.9", @@ -24,11 +24,20 @@ "id": "main-row", "component": "Row", "children": [ + "status-checkbox", "content", "priority" ], "align": "start" }, + { + "id": "status-checkbox", + "component": "CheckBox", + "label": "", + "value": { + "path": "/completed" + } + }, { "id": "content", "component": "Column", @@ -58,17 +67,20 @@ "id": "meta-row", "component": "Row", "children": [ - "due-date", + "due-date-input", "project" - ] + ], + "align": "center" }, { - "id": "due-date", - "component": "Text", - "text": { + "id": "due-date-input", + "component": "DateTimeInput", + "label": "Due", + "value": { "path": "/dueDate" }, - "variant": "caption" + "enableDate": true, + "enableTime": true }, { "id": "project", @@ -93,9 +105,10 @@ "updateDataModel": { "surfaceId": "gallery-task-card", "value": { + "completed": false, "title": "Review pull request", "description": "Review and approve the authentication module changes.", - "dueDate": "Today", + "dueDate": "2025-12-15T17:00:00Z", "project": "Backend", "priorityIcon": "priority_high" } diff --git a/specification/v0_9/json/catalogs/basic/examples/08_user-profile.json b/specification/v0_9/json/catalogs/basic/examples/08_user-profile.json index ed145de4b..c36976ee7 100644 --- a/specification/v0_9/json/catalogs/basic/examples/08_user-profile.json +++ b/specification/v0_9/json/catalogs/basic/examples/08_user-profile.json @@ -1,6 +1,6 @@ { "name": "User Profile", - "description": "Example of user profile", + "description": "Example of user profile demonstrating number formatting.", "messages": [ { "version": "v0.9", @@ -97,7 +97,13 @@ "id": "followers-count", "component": "Text", "text": { - "path": "/followers" + "call": "formatNumber", + "args": { + "value": { + "path": "/followers" + } + }, + "returnType": "string" }, "variant": "h3" }, @@ -120,7 +126,13 @@ "id": "following-count", "component": "Text", "text": { - "path": "/following" + "call": "formatNumber", + "args": { + "value": { + "path": "/following" + } + }, + "returnType": "string" }, "variant": "h3" }, @@ -143,7 +155,13 @@ "id": "posts-count", "component": "Text", "text": { - "path": "/posts" + "call": "formatNumber", + "args": { + "value": { + "path": "/posts" + } + }, + "returnType": "string" }, "variant": "h3" }, @@ -183,9 +201,9 @@ "name": "Sarah Chen", "username": "@sarahchen", "bio": "Product Designer at Tech Co. Creating delightful experiences.", - "followers": "12.4K", - "following": "892", - "posts": "347", + "followers": 12400, + "following": 892, + "posts": 347, "followText": "Follow" } } diff --git a/specification/v0_9/json/catalogs/basic/examples/09_login-form.json b/specification/v0_9/json/catalogs/basic/examples/09_login-form.json index 17b54757f..ed4d2639d 100644 --- a/specification/v0_9/json/catalogs/basic/examples/09_login-form.json +++ b/specification/v0_9/json/catalogs/basic/examples/09_login-form.json @@ -1,6 +1,6 @@ { "name": "Login Form", - "description": "Example of login form", + "description": "Example of login form demonstrating validation checks and logic.", "messages": [ { "version": "v0.9", @@ -59,7 +59,31 @@ "value": { "path": "/email" }, - "label": "Email" + "label": "Email", + "checks": [ + { + "condition": { + "call": "required", + "args": { + "value": { + "path": "/email" + } + } + }, + "message": "Email is required" + }, + { + "condition": { + "call": "email", + "args": { + "value": { + "path": "/email" + } + } + }, + "message": "Please enter a valid email address" + } + ] }, { "id": "password-field", @@ -68,7 +92,32 @@ "path": "/password" }, "label": "Password", - "variant": "obscured" + "variant": "obscured", + "checks": [ + { + "condition": { + "call": "required", + "args": { + "value": { + "path": "/password" + } + } + }, + "message": "Password is required" + }, + { + "condition": { + "call": "length", + "args": { + "value": { + "path": "/password" + }, + "min": 8 + } + }, + "message": "Password must be at least 8 characters long" + } + ] }, { "id": "login-btn-text", @@ -79,10 +128,43 @@ "id": "login-btn", "component": "Button", "child": "login-btn-text", + "checks": [ + { + "condition": { + "call": "and", + "args": { + "values": [ + { + "call": "email", + "args": { + "value": { + "path": "/email" + } + } + }, + { + "call": "length", + "args": { + "value": { + "path": "/password" + }, + "min": 8 + } + } + ] + } + }, + "message": "Please fix errors before signing in" + } + ], "action": { "event": { "name": "login", - "context": {} + "context": { + "email": { + "path": "/email" + } + } } } }, diff --git a/specification/v0_9/json/catalogs/basic/examples/11_purchase-complete.json b/specification/v0_9/json/catalogs/basic/examples/11_purchase-complete.json index c7b007726..7e1e30d21 100644 --- a/specification/v0_9/json/catalogs/basic/examples/11_purchase-complete.json +++ b/specification/v0_9/json/catalogs/basic/examples/11_purchase-complete.json @@ -1,6 +1,6 @@ { "name": "Purchase Complete", - "description": "Example of purchase complete", + "description": "Example of purchase complete demonstrating currency formatting.", "messages": [ { "version": "v0.9", @@ -81,7 +81,14 @@ "id": "product-price", "component": "Text", "text": { - "path": "/price" + "call": "formatCurrency", + "args": { + "value": { + "path": "/price" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "body" }, @@ -167,7 +174,7 @@ "value": { "productImage": "https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=100&h=100&fit=crop", "productName": "Wireless Headphones Pro", - "price": "$199.99", + "price": 199.99, "deliveryDate": "Arrives Dec 18 - Dec 20", "seller": "TechStore Official" } diff --git a/specification/v0_9/json/catalogs/basic/examples/12_chat-message.json b/specification/v0_9/json/catalogs/basic/examples/12_chat-message.json index 53a12bfc8..b98d1f6de 100644 --- a/specification/v0_9/json/catalogs/basic/examples/12_chat-message.json +++ b/specification/v0_9/json/catalogs/basic/examples/12_chat-message.json @@ -1,6 +1,6 @@ { "name": "Chat Message", - "description": "Example of chat message", + "description": "Example of chat message demonstrating templating and relative paths.", "messages": [ { "version": "v0.9", @@ -26,7 +26,7 @@ "children": [ "header", "divider", - "messages" + "messages-list" ] }, { @@ -56,129 +56,77 @@ "component": "Divider" }, { - "id": "messages", + "id": "messages-list", "component": "Column", - "children": [ - "message1", - "message2" - ], - "align": "start" - }, - { - "id": "message1", - "component": "Row", - "children": [ - "avatar1", - "msg1-content" - ], - "align": "start" - }, - { - "id": "avatar1", - "component": "Image", - "url": { - "path": "/message1/avatar" - }, - "fit": "cover", - "variant": "avatar" - }, - { - "id": "msg1-content", - "component": "Column", - "children": [ - "msg1-header", - "msg1-text" - ] - }, - { - "id": "msg1-header", - "component": "Row", - "children": [ - "msg1-username", - "msg1-time" - ], - "align": "center" - }, - { - "id": "msg1-username", - "component": "Text", - "text": { - "path": "/message1/username" - }, - "variant": "h4" - }, - { - "id": "msg1-time", - "component": "Text", - "text": { - "path": "/message1/time" - }, - "variant": "caption" - }, - { - "id": "msg1-text", - "component": "Text", - "text": { - "path": "/message1/text" + "children": { + "path": "/messages", + "componentId": "message-template" }, - "variant": "body" + "align": "start" }, { - "id": "message2", + "id": "message-template", "component": "Row", "children": [ - "avatar2", - "msg2-content" + "msg-avatar", + "msg-content" ], "align": "start" }, { - "id": "avatar2", + "id": "msg-avatar", "component": "Image", "url": { - "path": "/message2/avatar" + "path": "avatar" }, "fit": "cover", "variant": "avatar" }, { - "id": "msg2-content", + "id": "msg-content", "component": "Column", "children": [ - "msg2-header", - "msg2-text" + "msg-header", + "msg-text" ] }, { - "id": "msg2-header", + "id": "msg-header", "component": "Row", "children": [ - "msg2-username", - "msg2-time" + "msg-username", + "msg-time" ], "align": "center" }, { - "id": "msg2-username", + "id": "msg-username", "component": "Text", "text": { - "path": "/message2/username" + "path": "username" }, "variant": "h4" }, { - "id": "msg2-time", + "id": "msg-time", "component": "Text", "text": { - "path": "/message2/time" + "call": "formatDate", + "args": { + "value": { + "path": "timestamp" + }, + "format": "h:mm a" + }, + "returnType": "string" }, "variant": "caption" }, { - "id": "msg2-text", + "id": "msg-text", "component": "Text", "text": { - "path": "/message2/text" + "path": "text" }, "variant": "body" } @@ -191,18 +139,20 @@ "surfaceId": "gallery-chat-message", "value": { "channelName": "project-updates", - "message1": { - "avatar": "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=40&h=40&fit=crop", - "username": "Mike Chen", - "time": "10:32 AM", - "text": "Just pushed the new API changes. Ready for review." - }, - "message2": { - "avatar": "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=40&h=40&fit=crop", - "username": "Sarah Kim", - "time": "10:45 AM", - "text": "Great! I'll take a look after standup." - } + "messages": [ + { + "avatar": "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=40&h=40&fit=crop", + "username": "Mike Chen", + "timestamp": "2025-12-15T10:32:00Z", + "text": "Just pushed the new API changes. Ready for review." + }, + { + "avatar": "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=40&h=40&fit=crop", + "username": "Sarah Kim", + "timestamp": "2025-12-15T10:45:00Z", + "text": "Great! I'll take a look after standup." + } + ] } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/13_coffee-order.json b/specification/v0_9/json/catalogs/basic/examples/13_coffee-order.json index 1539de593..21ddefb38 100644 --- a/specification/v0_9/json/catalogs/basic/examples/13_coffee-order.json +++ b/specification/v0_9/json/catalogs/basic/examples/13_coffee-order.json @@ -1,6 +1,6 @@ { "name": "Coffee Order", - "description": "Example of coffee order", + "description": "Example of coffee order demonstrating templating and currency formatting.", "messages": [ { "version": "v0.9", @@ -25,7 +25,7 @@ "component": "Column", "children": [ "header", - "items", + "items-list", "divider", "totals", "actions" @@ -54,94 +54,59 @@ "variant": "h3" }, { - "id": "items", + "id": "items-list", "component": "Column", - "children": [ - "item1", - "item2" - ] - }, - { - "id": "item1", - "component": "Row", - "children": [ - "item1-details", - "item1-price" - ], - "justify": "spaceBetween", - "align": "start" - }, - { - "id": "item1-details", - "component": "Column", - "children": [ - "item1-name", - "item1-size" - ] - }, - { - "id": "item1-name", - "component": "Text", - "text": { - "path": "/item1/name" - }, - "variant": "body" - }, - { - "id": "item1-size", - "component": "Text", - "text": { - "path": "/item1/size" - }, - "variant": "caption" - }, - { - "id": "item1-price", - "component": "Text", - "text": { - "path": "/item1/price" - }, - "variant": "body" + "children": { + "path": "/items", + "componentId": "order-item-template" + } }, { - "id": "item2", + "id": "order-item-template", "component": "Row", "children": [ - "item2-details", - "item2-price" + "item-details", + "item-price" ], "justify": "spaceBetween", "align": "start" }, { - "id": "item2-details", + "id": "item-details", "component": "Column", "children": [ - "item2-name", - "item2-size" + "item-name", + "item-size" ] }, { - "id": "item2-name", + "id": "item-name", "component": "Text", "text": { - "path": "/item2/name" + "path": "name" }, "variant": "body" }, { - "id": "item2-size", + "id": "item-size", "component": "Text", "text": { - "path": "/item2/size" + "path": "size" }, "variant": "caption" }, { - "id": "item2-price", + "id": "item-price", "component": "Text", "text": { - "path": "/item2/price" + "call": "formatCurrency", + "args": { + "value": { + "path": "price" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "body" }, @@ -177,7 +142,14 @@ "id": "subtotal-value", "component": "Text", "text": { - "path": "/subtotal" + "call": "formatCurrency", + "args": { + "value": { + "path": "/subtotal" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "body" }, @@ -200,7 +172,14 @@ "id": "tax-value", "component": "Text", "text": { - "path": "/tax" + "call": "formatCurrency", + "args": { + "value": { + "path": "/tax" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "body" }, @@ -223,7 +202,14 @@ "id": "total-value", "component": "Text", "text": { - "path": "/total" + "call": "formatCurrency", + "args": { + "value": { + "path": "/total" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "h4" }, @@ -276,19 +262,21 @@ "surfaceId": "gallery-coffee-order", "value": { "storeName": "Sunrise Coffee", - "item1": { - "name": "Oat Milk Latte", - "size": "Grande, Extra Shot", - "price": "$6.45" - }, - "item2": { - "name": "Chocolate Croissant", - "size": "Warmed", - "price": "$4.25" - }, - "subtotal": "$10.70", - "tax": "$0.96", - "total": "$11.66" + "items": [ + { + "name": "Oat Milk Latte", + "size": "Grande, Extra Shot", + "price": 6.45 + }, + { + "name": "Chocolate Croissant", + "size": "Warmed", + "price": 4.25 + } + ], + "subtotal": 10.70, + "tax": 0.96, + "total": 11.66 } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/15_account-balance.json b/specification/v0_9/json/catalogs/basic/examples/15_account-balance.json index 5e033e724..4e6f630ee 100644 --- a/specification/v0_9/json/catalogs/basic/examples/15_account-balance.json +++ b/specification/v0_9/json/catalogs/basic/examples/15_account-balance.json @@ -1,6 +1,6 @@ { "name": "Account Balance", - "description": "Example of account balance", + "description": "Example of account balance demonstrating currency formatting.", "messages": [ { "version": "v0.9", @@ -57,7 +57,14 @@ "id": "balance", "component": "Text", "text": { - "path": "/balance" + "call": "formatCurrency", + "args": { + "value": { + "path": "/balance" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "h1" }, @@ -122,7 +129,7 @@ "surfaceId": "gallery-account-balance", "value": { "accountName": "Primary Checking", - "balance": "$12,458.32", + "balance": 12458.32, "lastUpdated": "Updated just now" } } diff --git a/specification/v0_9/json/catalogs/basic/examples/16_workout-summary.json b/specification/v0_9/json/catalogs/basic/examples/16_workout-summary.json index ebb914a1d..7f7dd4875 100644 --- a/specification/v0_9/json/catalogs/basic/examples/16_workout-summary.json +++ b/specification/v0_9/json/catalogs/basic/examples/16_workout-summary.json @@ -1,6 +1,6 @@ { "name": "Workout Summary", - "description": "Example of workout summary", + "description": "Example of workout summary demonstrating number and date formatting.", "messages": [ { "version": "v0.9", @@ -102,7 +102,13 @@ "id": "calories-value", "component": "Text", "text": { - "path": "/calories" + "call": "formatNumber", + "args": { + "value": { + "path": "/calories" + } + }, + "returnType": "string" }, "variant": "h3" }, @@ -125,7 +131,11 @@ "id": "distance-value", "component": "Text", "text": { - "path": "/distance" + "call": "formatString", + "args": { + "value": "${/distance} km" + }, + "returnType": "string" }, "variant": "h3" }, @@ -139,7 +149,14 @@ "id": "date", "component": "Text", "text": { - "path": "/date" + "call": "formatDate", + "args": { + "value": { + "path": "/date" + }, + "format": "EEEE, MMM d 'at' h:mm a" + }, + "returnType": "string" }, "variant": "caption" } @@ -154,9 +171,9 @@ "icon": "directions_run", "workoutType": "Morning Run", "duration": "32:15", - "calories": "385", - "distance": "5.2 km", - "date": "Today at 7:30 AM" + "calories": 385, + "distance": 5.2, + "date": "2025-12-15T07:30:00Z" } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/17_event-detail.json b/specification/v0_9/json/catalogs/basic/examples/17_event-detail.json index a6ad57611..193a4371c 100644 --- a/specification/v0_9/json/catalogs/basic/examples/17_event-detail.json +++ b/specification/v0_9/json/catalogs/basic/examples/17_event-detail.json @@ -1,6 +1,6 @@ { "name": "Event Detail", - "description": "Example of event detail", + "description": "Example of event detail demonstrating date and string formatting.", "messages": [ { "version": "v0.9", @@ -58,7 +58,11 @@ "id": "time-text", "component": "Text", "text": { - "path": "/dateTime" + "call": "formatString", + "args": { + "value": "${formatDate(value: ${/start}, format: 'E, MMM d')} • ${formatDate(value: ${/start}, format: 'h:mm a')} - ${formatDate(value: ${/end}, format: 'h:mm a')}" + }, + "returnType": "string" }, "variant": "body" }, @@ -145,7 +149,8 @@ "surfaceId": "gallery-event-detail", "value": { "title": "Product Launch Meeting", - "dateTime": "Thu, Dec 19 \u2022 2:00 PM - 3:30 PM", + "start": "2025-12-19T14:00:00Z", + "end": "2025-12-19T15:30:00Z", "location": "Conference Room A, Building 2", "description": "Review final product specs and marketing materials before the Q1 launch." } diff --git a/specification/v0_9/json/catalogs/basic/examples/18_track-list.json b/specification/v0_9/json/catalogs/basic/examples/18_track-list.json index 84b47ffc6..9324b7929 100644 --- a/specification/v0_9/json/catalogs/basic/examples/18_track-list.json +++ b/specification/v0_9/json/catalogs/basic/examples/18_track-list.json @@ -1,6 +1,6 @@ { "name": "Track List", - "description": "Example of track list", + "description": "Example of track list demonstrating templating, relative paths, and number formatting.", "messages": [ { "version": "v0.9", @@ -26,7 +26,7 @@ "children": [ "header", "divider", - "tracks" + "tracks-list" ] }, { @@ -56,182 +56,75 @@ "component": "Divider" }, { - "id": "tracks", + "id": "tracks-list", "component": "Column", - "children": [ - "track1", - "track2", - "track3" - ] + "children": { + "path": "/tracks", + "componentId": "track-item-template" + } }, { - "id": "track1", + "id": "track-item-template", "component": "Row", "children": [ - "track1-num", - "track1-art", - "track1-info", - "track1-duration" + "track-num", + "track-art", + "track-info", + "track-duration" ], "align": "center" }, { - "id": "track1-num", - "component": "Text", - "text": "1", - "variant": "caption" - }, - { - "id": "track1-art", - "component": "Image", - "url": { - "path": "/track1/art" - }, - "fit": "cover" - }, - { - "id": "track1-info", - "component": "Column", - "children": [ - "track1-title", - "track1-artist" - ] - }, - { - "id": "track1-title", - "component": "Text", - "text": { - "path": "/track1/title" - }, - "variant": "body" - }, - { - "id": "track1-artist", + "id": "track-num", "component": "Text", "text": { - "path": "/track1/artist" + "call": "formatNumber", + "args": { + "value": { + "path": "number" + } + }, + "returnType": "string" }, "variant": "caption" }, { - "id": "track1-duration", - "component": "Text", - "text": { - "path": "/track1/duration" - }, - "variant": "caption" - }, - { - "id": "track2", - "component": "Row", - "children": [ - "track2-num", - "track2-art", - "track2-info", - "track2-duration" - ], - "align": "center" - }, - { - "id": "track2-num", - "component": "Text", - "text": "2", - "variant": "caption" - }, - { - "id": "track2-art", + "id": "track-art", "component": "Image", "url": { - "path": "/track2/art" + "path": "art" }, "fit": "cover" }, { - "id": "track2-info", + "id": "track-info", "component": "Column", "children": [ - "track2-title", - "track2-artist" + "track-title", + "track-artist" ] }, { - "id": "track2-title", + "id": "track-title", "component": "Text", "text": { - "path": "/track2/title" + "path": "title" }, "variant": "body" }, { - "id": "track2-artist", + "id": "track-artist", "component": "Text", "text": { - "path": "/track2/artist" + "path": "artist" }, "variant": "caption" }, { - "id": "track2-duration", + "id": "track-duration", "component": "Text", "text": { - "path": "/track2/duration" - }, - "variant": "caption" - }, - { - "id": "track3", - "component": "Row", - "children": [ - "track3-num", - "track3-art", - "track3-info", - "track3-duration" - ], - "align": "center" - }, - { - "id": "track3-num", - "component": "Text", - "text": "3", - "variant": "caption" - }, - { - "id": "track3-art", - "component": "Image", - "url": { - "path": "/track3/art" - }, - "fit": "cover" - }, - { - "id": "track3-info", - "component": "Column", - "children": [ - "track3-title", - "track3-artist" - ] - }, - { - "id": "track3-title", - "component": "Text", - "text": { - "path": "/track3/title" - }, - "variant": "body" - }, - { - "id": "track3-artist", - "component": "Text", - "text": { - "path": "/track3/artist" - }, - "variant": "caption" - }, - { - "id": "track3-duration", - "component": "Text", - "text": { - "path": "/track3/duration" + "path": "duration" }, "variant": "caption" } @@ -244,24 +137,29 @@ "surfaceId": "gallery-track-list", "value": { "playlistName": "Focus Flow", - "track1": { - "art": "https://images.unsplash.com/photo-1470225620780-dba8ba36b745?w=50&h=50&fit=crop", - "title": "Weightless", - "artist": "Marconi Union", - "duration": "8:09" - }, - "track2": { - "art": "https://images.unsplash.com/photo-1511379938547-c1f69419868d?w=50&h=50&fit=crop", - "title": "Clair de Lune", - "artist": "Debussy", - "duration": "5:12" - }, - "track3": { - "art": "https://images.unsplash.com/photo-1507838153414-b4b713384a76?w=50&h=50&fit=crop", - "title": "Ambient Light", - "artist": "Brian Eno", - "duration": "6:45" - } + "tracks": [ + { + "number": 1, + "art": "https://images.unsplash.com/photo-1470225620780-dba8ba36b745?w=50&h=50&fit=crop", + "title": "Weightless", + "artist": "Marconi Union", + "duration": "8:09" + }, + { + "number": 2, + "art": "https://images.unsplash.com/photo-1511379938547-c1f69419868d?w=50&h=50&fit=crop", + "title": "Clair de Lune", + "artist": "Debussy", + "duration": "5:12" + }, + { + "number": 3, + "art": "https://images.unsplash.com/photo-1507838153414-b4b713384a76?w=50&h=50&fit=crop", + "title": "Ambient Light", + "artist": "Brian Eno", + "duration": "6:45" + } + ] } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/19_software-purchase.json b/specification/v0_9/json/catalogs/basic/examples/19_software-purchase.json index 01bcb1f75..5318be0fe 100644 --- a/specification/v0_9/json/catalogs/basic/examples/19_software-purchase.json +++ b/specification/v0_9/json/catalogs/basic/examples/19_software-purchase.json @@ -1,6 +1,6 @@ { "name": "Software Purchase", - "description": "Example of software purchase", + "description": "Example of software purchase demonstrating currency formatting and ChoicePicker.", "messages": [ { "version": "v0.9", @@ -88,7 +88,7 @@ "component": "Row", "children": [ "period-label", - "period-value" + "period-picker" ], "justify": "spaceBetween", "align": "center" @@ -100,12 +100,23 @@ "variant": "body" }, { - "id": "period-value", - "component": "Text", - "text": { + "id": "period-picker", + "component": "ChoicePicker", + "options": [ + { + "label": "Annual", + "value": "annual" + }, + { + "label": "Monthly", + "value": "monthly" + } + ], + "value": { "path": "/billingPeriod" }, - "variant": "h4" + "variant": "mutuallyExclusive", + "displayStyle": "chips" }, { "id": "divider2", @@ -131,7 +142,11 @@ "id": "total-value", "component": "Text", "text": { - "path": "/total" + "call": "formatString", + "args": { + "value": "${formatCurrency(value: ${/total}, currency: 'USD')}/year" + }, + "returnType": "string" }, "variant": "h2" }, @@ -185,8 +200,8 @@ "value": { "productName": "Design Suite Pro", "seats": "10 seats", - "billingPeriod": "Annual", - "total": "$1,188/year" + "billingPeriod": ["annual"], + "total": 1188.00 } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/21_shipping-status.json b/specification/v0_9/json/catalogs/basic/examples/21_shipping-status.json index 658b2f8a0..f1babbe66 100644 --- a/specification/v0_9/json/catalogs/basic/examples/21_shipping-status.json +++ b/specification/v0_9/json/catalogs/basic/examples/21_shipping-status.json @@ -1,6 +1,6 @@ { "name": "Shipping Status", - "description": "Example of shipping status", + "description": "Example of shipping status demonstrating templating and relative paths.", "messages": [ { "version": "v0.9", @@ -27,7 +27,7 @@ "header", "tracking-number", "divider", - "steps", + "steps-list", "eta" ] }, @@ -64,96 +64,36 @@ "component": "Divider" }, { - "id": "steps", + "id": "steps-list", "component": "Column", - "children": [ - "step1", - "step2", - "step3", - "step4" - ] - }, - { - "id": "step1", - "component": "Row", - "children": [ - "step1-icon", - "step1-text" - ], - "align": "center" - }, - { - "id": "step1-icon", - "component": "Icon", - "name": "check" - }, - { - "id": "step1-text", - "component": "Text", - "text": "Order Placed", - "variant": "body" - }, - { - "id": "step2", - "component": "Row", - "children": [ - "step2-icon", - "step2-text" - ], - "align": "center" - }, - { - "id": "step2-icon", - "component": "Icon", - "name": "check" - }, - { - "id": "step2-text", - "component": "Text", - "text": "Shipped", - "variant": "body" + "children": { + "path": "/steps", + "componentId": "step-item-template" + } }, { - "id": "step3", + "id": "step-item-template", "component": "Row", "children": [ - "step3-icon", - "step3-text" + "step-icon", + "step-text" ], "align": "center" }, { - "id": "step3-icon", + "id": "step-icon", "component": "Icon", "name": { - "path": "/currentStepIcon" + "path": "icon" } }, { - "id": "step3-text", - "component": "Text", - "text": "Out for Delivery", - "variant": "h4" - }, - { - "id": "step4", - "component": "Row", - "children": [ - "step4-icon", - "step4-text" - ], - "align": "center" - }, - { - "id": "step4-icon", - "component": "Icon", - "name": "check" - }, - { - "id": "step4-text", + "id": "step-text", "component": "Text", - "text": "Delivered", - "variant": "caption" + "text": { + "path": "label" + }, + "variant": "body" }, { "id": "eta", @@ -186,7 +126,24 @@ "surfaceId": "gallery-shipping-status", "value": { "trackingNumber": "Tracking: 1Z999AA10123456784", - "currentStepIcon": "send", + "steps": [ + { + "icon": "check", + "label": "Order Placed" + }, + { + "icon": "check", + "label": "Shipped" + }, + { + "icon": "send", + "label": "Out for Delivery" + }, + { + "icon": "check", + "label": "Delivered" + } + ], "eta": "Estimated delivery: Today by 8 PM" } } diff --git a/specification/v0_9/json/catalogs/basic/examples/23_step-counter.json b/specification/v0_9/json/catalogs/basic/examples/23_step-counter.json index a57e4eb8e..3a8474b25 100644 --- a/specification/v0_9/json/catalogs/basic/examples/23_step-counter.json +++ b/specification/v0_9/json/catalogs/basic/examples/23_step-counter.json @@ -1,6 +1,6 @@ { "name": "Step Counter", - "description": "Example of step counter", + "description": "Example of step counter demonstrating number formatting.", "messages": [ { "version": "v0.9", @@ -56,7 +56,13 @@ "id": "steps-display", "component": "Text", "text": { - "path": "/steps" + "call": "formatNumber", + "args": { + "value": { + "path": "/steps" + } + }, + "returnType": "string" }, "variant": "h1" }, @@ -64,7 +70,11 @@ "id": "goal-text", "component": "Text", "text": { - "path": "/goalProgress" + "call": "formatString", + "args": { + "value": "${/progress}% of ${formatNumber(value: ${/goal})} goal" + }, + "returnType": "string" }, "variant": "body" }, @@ -94,7 +104,11 @@ "id": "distance-value", "component": "Text", "text": { - "path": "/distance" + "call": "formatString", + "args": { + "value": "${/distance} mi" + }, + "returnType": "string" }, "variant": "h3" }, @@ -117,7 +131,13 @@ "id": "calories-value", "component": "Text", "text": { - "path": "/calories" + "call": "formatNumber", + "args": { + "value": { + "path": "/calories" + } + }, + "returnType": "string" }, "variant": "h3" }, @@ -135,10 +155,11 @@ "updateDataModel": { "surfaceId": "gallery-step-counter", "value": { - "steps": "8,432", - "goalProgress": "84% of 10,000 goal", - "distance": "3.8 mi", - "calories": "312" + "steps": 8432, + "goal": 10000, + "progress": 84, + "distance": 3.8, + "calories": 312 } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/24_recipe-card.json b/specification/v0_9/json/catalogs/basic/examples/24_recipe-card.json index cd133d8d8..9b5eff354 100644 --- a/specification/v0_9/json/catalogs/basic/examples/24_recipe-card.json +++ b/specification/v0_9/json/catalogs/basic/examples/24_recipe-card.json @@ -1,6 +1,6 @@ { "name": "Recipe Card", - "description": "Example of recipe card", + "description": "Example of recipe card demonstrating Tabs and pluralization.", "messages": [ { "version": "v0.9", @@ -18,14 +18,32 @@ { "id": "root", "component": "Card", - "child": "main-column" + "child": "tabs-container" + }, + { + "id": "tabs-container", + "component": "Tabs", + "tabs": [ + { + "title": "Overview", + "child": "overview-col" + }, + { + "title": "Ingredients", + "child": "ingredients-list" + }, + { + "title": "Instructions", + "child": "instructions-list" + } + ] }, { - "id": "main-column", + "id": "overview-col", "component": "Column", "children": [ "recipe-image", - "content" + "overview-content" ] }, { @@ -37,7 +55,7 @@ "fit": "cover" }, { - "id": "content", + "id": "overview-content", "component": "Column", "children": [ "title", @@ -81,7 +99,11 @@ "id": "review-count", "component": "Text", "text": { - "path": "/reviewCount" + "call": "formatString", + "args": { + "value": "(${formatNumber(value: ${/reviewCount})} ${pluralize(value: ${/reviewCount}, one: 'review', other: 'reviews')})" + }, + "returnType": "string" }, "variant": "caption" }, @@ -144,6 +166,30 @@ "path": "/servings" }, "variant": "caption" + }, + { + "id": "ingredients-list", + "component": "Column", + "children": { + "path": "/ingredients", + "componentId": "item-template" + } + }, + { + "id": "instructions-list", + "component": "Column", + "children": { + "path": "/instructions", + "componentId": "item-template" + } + }, + { + "id": "item-template", + "component": "Text", + "text": { + "path": "text" + }, + "variant": "body" } ] } @@ -156,10 +202,22 @@ "image": "https://images.unsplash.com/photo-1546069901-ba9599a7e63c?w=300&h=180&fit=crop", "title": "Mediterranean Quinoa Bowl", "rating": "4.9", - "reviewCount": "(1,247 reviews)", + "reviewCount": 1247, "prepTime": "15 min prep", "cookTime": "20 min cook", - "servings": "Serves 4" + "servings": "Serves 4", + "ingredients": [ + { "text": "1 cup quinoa" }, + { "text": "2 cups water" }, + { "text": "1 cucumber, diced" }, + { "text": "1 cup cherry tomatoes, halved" } + ], + "instructions": [ + { "text": "1. Rinse quinoa and bring to a boil in water." }, + { "text": "2. Reduce heat and simmer for 15 minutes." }, + { "text": "3. Fluff with a fork and let cool." }, + { "text": "4. Mix with diced vegetables." } + ] } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/26_podcast-episode.json b/specification/v0_9/json/catalogs/basic/examples/26_podcast-episode.json index 15a702fdf..dac189f18 100644 --- a/specification/v0_9/json/catalogs/basic/examples/26_podcast-episode.json +++ b/specification/v0_9/json/catalogs/basic/examples/26_podcast-episode.json @@ -1,6 +1,6 @@ { "name": "Podcast Episode", - "description": "Example of podcast episode", + "description": "Example of podcast episode demonstrating AudioPlayer and date formatting.", "messages": [ { "version": "v0.9", @@ -45,7 +45,7 @@ "episode-title", "meta-row", "description", - "play-btn" + "audio-player" ] }, { @@ -84,7 +84,14 @@ "id": "date", "component": "Text", "text": { - "path": "/date" + "call": "formatDate", + "args": { + "value": { + "path": "/date" + }, + "format": "MMM d, yyyy" + }, + "returnType": "string" }, "variant": "caption" }, @@ -97,19 +104,13 @@ "variant": "body" }, { - "id": "play-btn-text", - "component": "Text", - "text": "Play Episode" - }, - { - "id": "play-btn", - "component": "Button", - "child": "play-btn-text", - "action": { - "event": { - "name": "play", - "context": {} - } + "id": "audio-player", + "component": "AudioPlayer", + "url": { + "path": "/audioUrl" + }, + "description": { + "path": "/episodeTitle" } } ] @@ -124,8 +125,9 @@ "showName": "Tech Talk Daily", "episodeTitle": "The Future of AI in Product Design", "duration": "45 min", - "date": "Dec 15, 2024", - "description": "How AI is transforming the way we design and build products." + "date": "2024-12-15", + "description": "How AI is transforming the way we design and build products.", + "audioUrl": "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/27_stats-card.json b/specification/v0_9/json/catalogs/basic/examples/27_stats-card.json index d824b7c87..3fed8bf39 100644 --- a/specification/v0_9/json/catalogs/basic/examples/27_stats-card.json +++ b/specification/v0_9/json/catalogs/basic/examples/27_stats-card.json @@ -1,6 +1,6 @@ { "name": "Stats Card", - "description": "Example of stats card", + "description": "Example of stats card demonstrating currency and number formatting.", "messages": [ { "version": "v0.9", @@ -57,7 +57,14 @@ "id": "value", "component": "Text", "text": { - "path": "/value" + "call": "formatCurrency", + "args": { + "value": { + "path": "/value" + }, + "currency": "USD" + }, + "returnType": "string" }, "variant": "h1" }, @@ -81,7 +88,11 @@ "id": "trend-text", "component": "Text", "text": { - "path": "/trendText" + "call": "formatString", + "args": { + "value": "+${/trendPercent}% from last month" + }, + "returnType": "string" }, "variant": "body" } @@ -95,9 +106,9 @@ "value": { "icon": "trending_up", "metricName": "Monthly Revenue", - "value": "$48,294", + "value": 48294, "trendIcon": "arrow_upward", - "trendText": "+12.5% from last month" + "trendPercent": 12.5 } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/28_countdown-timer.json b/specification/v0_9/json/catalogs/basic/examples/28_countdown-timer.json index c615ee06e..4793e636b 100644 --- a/specification/v0_9/json/catalogs/basic/examples/28_countdown-timer.json +++ b/specification/v0_9/json/catalogs/basic/examples/28_countdown-timer.json @@ -1,6 +1,6 @@ { "name": "Countdown Timer", - "description": "Example of countdown timer", + "description": "Example of countdown timer demonstrating date formatting.", "messages": [ { "version": "v0.9", @@ -121,7 +121,14 @@ "id": "target-date", "component": "Text", "text": { - "path": "/targetDate" + "call": "formatDate", + "args": { + "value": { + "path": "/targetDate" + }, + "format": "MMMM d, yyyy" + }, + "returnType": "string" }, "variant": "body" } @@ -137,7 +144,7 @@ "days": "14", "hours": "08", "minutes": "32", - "targetDate": "January 15, 2025" + "targetDate": "2025-01-15" } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/29_movie-card.json b/specification/v0_9/json/catalogs/basic/examples/29_movie-card.json index f494c032f..96eab4b30 100644 --- a/specification/v0_9/json/catalogs/basic/examples/29_movie-card.json +++ b/specification/v0_9/json/catalogs/basic/examples/29_movie-card.json @@ -1,6 +1,6 @@ { "name": "Movie Card", - "description": "Example of movie card", + "description": "Example of movie card demonstrating Modal and Video components.", "messages": [ { "version": "v0.9", @@ -25,7 +25,8 @@ "component": "Column", "children": [ "poster", - "content" + "content", + "trailer-modal" ] }, { @@ -43,7 +44,8 @@ "title-row", "genre", "rating-row", - "runtime" + "runtime", + "watch-trailer-btn" ] }, { @@ -122,6 +124,34 @@ "path": "/runtime" }, "variant": "caption" + }, + { + "id": "watch-trailer-btn-text", + "component": "Text", + "text": "Watch Trailer" + }, + { + "id": "watch-trailer-btn", + "component": "Button", + "child": "watch-trailer-btn-text", + "action": { + "event": { + "name": "open_trailer" + } + } + }, + { + "id": "trailer-modal", + "component": "Modal", + "trigger": "watch-trailer-btn", + "content": "trailer-video" + }, + { + "id": "trailer-video", + "component": "Video", + "url": { + "path": "/trailerUrl" + } } ] } @@ -134,9 +164,10 @@ "poster": "https://images.unsplash.com/photo-1536440136628-849c177e76a1?w=200&h=300&fit=crop", "title": "Interstellar", "year": "(2014)", - "genre": "Sci-Fi \u2022 Adventure \u2022 Drama", + "genre": "Sci-Fi • Adventure • Drama", "rating": "8.7/10", - "runtime": "2h 49min" + "runtime": "2h 49min", + "trailerUrl": "https://www.w3schools.com/html/mov_bbb.mp4" } } } diff --git a/specification/v0_9/json/catalogs/basic/examples/30_live-invitation-builder.json b/specification/v0_9/json/catalogs/basic/examples/30_live-invitation-builder.json new file mode 100644 index 000000000..333a52d26 --- /dev/null +++ b/specification/v0_9/json/catalogs/basic/examples/30_live-invitation-builder.json @@ -0,0 +1,217 @@ +{ + "name": "Live Invitation Builder", + "description": "Demonstrates reactive two-way binding where editor inputs update a live preview in real-time.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-invitation-builder", + "catalogId": "https://a2ui.org/specification/v0_9/basic_catalog.json", + "sendDataModel": true + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-invitation-builder", + "components": [ + { + "id": "root", + "component": "Column", + "children": [ + "header", + "main-content" + ], + "align": "stretch" + }, + { + "id": "header", + "component": "Text", + "text": "# Invitation Builder", + "variant": "h1" + }, + { + "id": "main-content", + "component": "Row", + "children": [ + "editor-col", + "preview-col" + ], + "align": "start" + }, + { + "id": "editor-col", + "component": "Column", + "children": [ + "editor-title", + "event-name-input", + "guest-input", + "date-input", + "location-picker" + ], + "weight": 1, + "align": "stretch" + }, + { + "id": "editor-title", + "component": "Text", + "text": "Customize your invitation", + "variant": "h3" + }, + { + "id": "event-name-input", + "component": "TextField", + "label": "Event Name", + "value": { + "path": "/event/name" + } + }, + { + "id": "guest-input", + "component": "TextField", + "label": "Guest of Honor", + "value": { + "path": "/event/guest" + } + }, + { + "id": "date-input", + "component": "DateTimeInput", + "label": "Event Date & Time", + "value": { + "path": "/event/date" + }, + "enableDate": true, + "enableTime": true + }, + { + "id": "location-picker", + "component": "ChoicePicker", + "label": "Location", + "options": [ + { "label": "Grand Ballroom", "value": "ballroom" }, + { "label": "Sunset Terrace", "value": "terrace" }, + { "label": "Garden Pavillion", "value": "garden" } + ], + "value": { + "path": "/event/location" + }, + "variant": "mutuallyExclusive", + "displayStyle": "chips" + }, + { + "id": "preview-col", + "component": "Column", + "children": [ + "preview-title", + "invitation-card" + ], + "weight": 1, + "align": "center" + }, + { + "id": "preview-title", + "component": "Text", + "text": "Live Preview", + "variant": "caption" + }, + { + "id": "invitation-card", + "component": "Card", + "child": "invitation-content" + }, + { + "id": "invitation-content", + "component": "Column", + "children": [ + "invite-image", + "invite-event-name", + "invite-guest-row", + "invite-date-text", + "invite-location-text" + ], + "align": "center" + }, + { + "id": "invite-image", + "component": "Image", + "url": "https://images.unsplash.com/photo-1511795409834-ef04bbd61622?w=400&h=200&fit=crop", + "variant": "mediumFeature" + }, + { + "id": "invite-event-name", + "component": "Text", + "text": { + "path": "/event/name" + }, + "variant": "h2" + }, + { + "id": "invite-guest-row", + "component": "Row", + "children": [ + "invite-for-text", + "invite-guest-name" + ], + "align": "center" + }, + { + "id": "invite-for-text", + "component": "Text", + "text": "Celebrating", + "variant": "body" + }, + { + "id": "invite-guest-name", + "component": "Text", + "text": { + "path": "/event/guest" + }, + "variant": "h3" + }, + { + "id": "invite-date-text", + "component": "Text", + "text": { + "call": "formatDate", + "args": { + "value": { + "path": "/event/date" + }, + "format": "EEEE, MMMM d, yyyy 'at' h:mm a" + }, + "returnType": "string" + }, + "variant": "body" + }, + { + "id": "invite-location-text", + "component": "Text", + "text": { + "call": "formatString", + "args": { + "value": "Location: ${/event/location/0}" + }, + "returnType": "string" + }, + "variant": "caption" + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "gallery-invitation-builder", + "value": { + "event": { + "name": "Summer Gala", + "guest": "Alex Johnson", + "date": "2025-07-15T19:00:00Z", + "location": ["terrace"] + } + } + } + } + ] +} \ No newline at end of file diff --git a/specification/v0_9/json/catalogs/basic/examples/31_incremental-dashboard.json b/specification/v0_9/json/catalogs/basic/examples/31_incremental-dashboard.json new file mode 100644 index 000000000..04392cd91 --- /dev/null +++ b/specification/v0_9/json/catalogs/basic/examples/31_incremental-dashboard.json @@ -0,0 +1,134 @@ +{ + "name": "Incremental Dashboard", + "description": "Demonstrates structural evolution of a UI where loading placeholders are incrementally replaced by actual components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-incremental-dashboard", + "catalogId": "https://a2ui.org/specification/v0_9/basic_catalog.json" + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-incremental-dashboard", + "components": [ + { + "id": "root", + "component": "Column", + "children": [ + "header", + "content-grid" + ], + "align": "stretch" + }, + { + "id": "header", + "component": "Text", + "text": "System Dashboard", + "variant": "h2" + }, + { + "id": "content-grid", + "component": "Row", + "children": [ + "left-panel", + "right-panel" + ] + }, + { + "id": "left-panel", + "component": "Column", + "children": ["panel-a-loading"], + "weight": 1 + }, + { + "id": "right-panel", + "component": "Column", + "children": ["panel-b-loading"], + "weight": 1 + }, + { + "id": "panel-a-loading", + "component": "Text", + "text": "Loading analytics...", + "variant": "caption" + }, + { + "id": "panel-b-loading", + "component": "Text", + "text": "Loading logs...", + "variant": "caption" + } + ] + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-incremental-dashboard", + "components": [ + { + "id": "left-panel", + "component": "Column", + "children": ["analytics-card"], + "weight": 1 + }, + { + "id": "analytics-card", + "component": "Card", + "child": "analytics-text" + }, + { + "id": "analytics-text", + "component": "Text", + "text": "Analytics are ready.", + "variant": "body" + } + ] + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-incremental-dashboard", + "components": [ + { + "id": "right-panel", + "component": "Column", + "children": ["logs-list"], + "weight": 1 + }, + { + "id": "logs-list", + "component": "List", + "children": { + "path": "/logs", + "componentId": "log-template" + } + }, + { + "id": "log-template", + "component": "Text", + "text": { "path": "message" }, + "variant": "caption" + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "gallery-incremental-dashboard", + "value": { + "logs": [ + { "message": "System boot complete." }, + { "message": "All services healthy." }, + { "message": "Waiting for user input." } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/specification/v0_9/json/catalogs/basic/examples/32_advanced-form-validator.json b/specification/v0_9/json/catalogs/basic/examples/32_advanced-form-validator.json new file mode 100644 index 000000000..9ea75036b --- /dev/null +++ b/specification/v0_9/json/catalogs/basic/examples/32_advanced-form-validator.json @@ -0,0 +1,148 @@ +{ + "name": "Advanced Form Validator", + "description": "Demonstrates complex validation logic and deeply nested formatting functions.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-advanced-validator", + "catalogId": "https://a2ui.org/specification/v0_9/basic_catalog.json", + "sendDataModel": true + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-advanced-validator", + "components": [ + { + "id": "root", + "component": "Card", + "child": "main-column" + }, + { + "id": "main-column", + "component": "Column", + "children": [ + "welcome-text", + "email-field", + "phone-field", + "zip-field", + "terms-checkbox", + "submit-btn" + ], + "align": "stretch" + }, + { + "id": "welcome-text", + "component": "Text", + "text": { + "call": "formatString", + "args": { + "value": "Hello! Today is ${formatDate(value: ${/now}, format: 'EEEE, MMMM d')}." + }, + "returnType": "string" + }, + "variant": "h3" + }, + { + "id": "email-field", + "component": "TextField", + "label": "Email Address", + "value": { "path": "/formData/email" }, + "checks": [ + { + "condition": { "call": "email", "args": { "value": { "path": "/formData/email" } } }, + "message": "Invalid email format" + } + ] + }, + { + "id": "phone-field", + "component": "TextField", + "label": "Phone Number", + "value": { "path": "/formData/phone" }, + "checks": [ + { + "condition": { "call": "regex", "args": { "value": { "path": "/formData/phone" }, "pattern": "^\\+?[0-9]{10,15}$" } }, + "message": "Invalid phone format" + } + ] + }, + { + "id": "zip-field", + "component": "TextField", + "label": "Zip Code", + "value": { "path": "/formData/zip" }, + "checks": [ + { + "condition": { "call": "regex", "args": { "value": { "path": "/formData/zip" }, "pattern": "^[0-9]{5}$" } }, + "message": "Must be exactly 5 digits" + } + ] + }, + { + "id": "terms-checkbox", + "component": "CheckBox", + "label": "I agree to the terms and conditions", + "value": { "path": "/formData/agree" } + }, + { + "id": "submit-btn-text", + "component": "Text", + "text": "Submit Registration" + }, + { + "id": "submit-btn", + "component": "Button", + "child": "submit-btn-text", + "checks": [ + { + "condition": { + "call": "and", + "args": { + "values": [ + { "path": "/formData/agree" }, + { + "call": "or", + "args": { + "values": [ + { "call": "required", "args": { "value": { "path": "/formData/email" } } }, + { "call": "required", "args": { "value": { "path": "/formData/phone" } } } + ] + } + }, + { "call": "required", "args": { "value": { "path": "/formData/zip" } } } + ] + } + }, + "message": "You must agree to terms AND provide either Email or Phone, plus a Zip code." + } + ], + "action": { + "event": { + "name": "register", + "context": { "data": { "path": "/formData" } } + } + } + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "gallery-advanced-validator", + "value": { + "now": "2025-12-15T12:00:00Z", + "formData": { + "email": "", + "phone": "", + "zip": "", + "agree": false + } + } + } + } + ] +} \ No newline at end of file diff --git a/specification/v0_9/json/catalogs/basic/examples/33_financial-data-grid.json b/specification/v0_9/json/catalogs/basic/examples/33_financial-data-grid.json new file mode 100644 index 000000000..da3492c7f --- /dev/null +++ b/specification/v0_9/json/catalogs/basic/examples/33_financial-data-grid.json @@ -0,0 +1,166 @@ +{ + "name": "Financial Data Grid", + "description": "Demonstrates complex layout weighting and alignment using Rows and Columns with templates.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-financial-grid", + "catalogId": "https://a2ui.org/specification/v0_9/basic_catalog.json", + "sendDataModel": true + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-financial-grid", + "components": [ + { + "id": "root", + "component": "Card", + "child": "main-column" + }, + { + "id": "main-column", + "component": "Column", + "children": [ + "header-row", + "grid-list" + ], + "align": "stretch" + }, + { + "id": "header-row", + "component": "Row", + "children": [ + "col-asset", + "col-price", + "col-change", + "col-market-cap" + ], + "align": "center" + }, + { + "id": "col-asset", + "component": "Text", + "text": "Asset", + "variant": "caption", + "weight": 2 + }, + { + "id": "col-price", + "component": "Text", + "text": "Price", + "variant": "caption", + "weight": 1 + }, + { + "id": "col-change", + "component": "Text", + "text": "24h Change", + "variant": "caption", + "weight": 1 + }, + { + "id": "col-market-cap", + "component": "Text", + "text": "Market Cap", + "variant": "caption", + "weight": 1.5 + }, + { + "id": "grid-list", + "component": "List", + "children": { + "path": "/assets", + "componentId": "row-template" + } + }, + { + "id": "row-template", + "component": "Row", + "children": [ + "asset-info", + "asset-price", + "asset-change", + "asset-market-cap" + ], + "align": "center" + }, + { + "id": "asset-info", + "component": "Row", + "children": ["asset-icon", "asset-name-col"], + "weight": 2, + "align": "center" + }, + { + "id": "asset-icon", + "component": "Icon", + "name": "payment" + }, + { + "id": "asset-name-col", + "component": "Column", + "children": ["asset-name", "asset-symbol"] + }, + { + "id": "asset-name", + "component": "Text", + "text": { "path": "name" }, + "variant": "body" + }, + { + "id": "asset-symbol", + "component": "Text", + "text": { "path": "symbol" }, + "variant": "caption" + }, + { + "id": "asset-price", + "component": "Text", + "text": { + "call": "formatCurrency", + "args": { "value": { "path": "price" }, "currency": "USD" }, + "returnType": "string" + }, + "weight": 1 + }, + { + "id": "asset-change", + "component": "Text", + "text": { + "call": "formatString", + "args": { "value": "${change}%" }, + "returnType": "string" + }, + "weight": 1 + }, + { + "id": "asset-market-cap", + "component": "Text", + "text": { + "call": "formatCurrency", + "args": { "value": { "path": "marketCap" }, "currency": "USD" }, + "returnType": "string" + }, + "weight": 1.5 + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "gallery-financial-grid", + "value": { + "assets": [ + { "name": "Bitcoin", "symbol": "BTC", "price": 43500.25, "change": 1.2, "marketCap": 850000000000 }, + { "name": "Ethereum", "symbol": "ETH", "price": 2250.50, "change": -0.5, "marketCap": 270000000000 }, + { "name": "Solana", "symbol": "SOL", "price": 95.80, "change": 5.4, "marketCap": 40000000000 } + ] + } + } + } + ] +} \ No newline at end of file