diff --git a/renderers/angular/a2ui_explorer/src/app/tests/utils/test_utils.ts b/renderers/angular/a2ui_explorer/src/app/tests/utils/test_utils.ts index c4de66f0a5..81f4e9d2b3 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/utils/test_utils.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/utils/test_utils.ts @@ -43,13 +43,7 @@ export async function loadExample(exampleName: string, version: Version = Versio fixture.detectChanges(); const examples = version === Version.V0_9 ? EXAMPLES_V09 : EXAMPLES_V08; - let example = examples.find(ex => ex.name === exampleName); - - if (version === Version.V0_8 && !example) { - example = - examples.find(ex => ex.name === `${exampleName} (basic)`) || - examples.find(ex => ex.name === `${exampleName} (minimal)`); - } + const example = examples.find(ex => ex.name === exampleName); expect(example).withContext(`Example not found: ${exampleName}`).toBeTruthy(); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/5_complex_layout.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_complex-layout.spec.ts similarity index 88% rename from renderers/angular/a2ui_explorer/src/app/tests/v0_8/5_complex_layout.spec.ts rename to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_complex-layout.spec.ts index ce9ca9e393..5551e278aa 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/5_complex_layout.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_complex-layout.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Complex Layout (minimal) (v0.8)', () => { +describe('Example: Complex Layout (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Complex Layout (minimal)', Version.V0_8); + await loadExample('Complex Layout', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/3_interactive_button.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_interactive-button.spec.ts similarity index 92% rename from renderers/angular/a2ui_explorer/src/app/tests/v0_8/3_interactive_button.spec.ts rename to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_interactive-button.spec.ts index 412c8c864b..58146499a6 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/3_interactive_button.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_interactive-button.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Interactive Button (minimal) (v0.8)', () => { +describe('Example: Interactive Button (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Interactive Button (minimal)', Version.V0_8); + fixture = await loadExample('Interactive Button', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/2_row_layout.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_row-layout.spec.ts similarity index 88% rename from renderers/angular/a2ui_explorer/src/app/tests/v0_8/2_row_layout.spec.ts rename to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_row-layout.spec.ts index 4349352282..aad383ce1b 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/2_row_layout.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_row-layout.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Row Layout (minimal) (v0.8)', () => { +describe('Example: Row Layout (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Row Layout (minimal)', Version.V0_8); + await loadExample('Row Layout', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/4_login_form.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-login-form.spec.ts similarity index 94% rename from renderers/angular/a2ui_explorer/src/app/tests/v0_8/4_login_form.spec.ts rename to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-login-form.spec.ts index 9252a0c827..ffcecd5fb6 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/4_login_form.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-login-form.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Login Form (minimal) (v0.8)', () => { +describe('Example: Simple Login Form (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Login Form (minimal)', Version.V0_8); + fixture = await loadExample('Simple Login Form', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/1_simple_text.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-text.spec.ts similarity index 88% rename from renderers/angular/a2ui_explorer/src/app/tests/v0_8/1_simple_text.spec.ts rename to renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-text.spec.ts index 5fb610da36..5556fa5742 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/1_simple_text.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/00_simple-text.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Simple Text (minimal) (v0.8)', () => { +describe('Example: Simple Text (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Simple Text (minimal)', Version.V0_8); + await loadExample('Simple Text', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/03_calendar-day.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/03_calendar-day.spec.ts index e5bd2ce359..5faabde14f 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/03_calendar-day.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/03_calendar-day.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Calendar Day (basic) (v0.8)', () => { +describe('Example: Calendar Day (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Calendar Day (basic)', Version.V0_8); + fixture = await loadExample('Calendar Day', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/04_weather-current.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/04_weather-current.spec.ts index 4459f16e55..5aa78dcbdc 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/04_weather-current.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/04_weather-current.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Weather Current (basic) (v0.8)', () => { +describe('Example: Weather Current (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Weather Current (basic)', Version.V0_8); + await loadExample('Weather Current', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/05_product-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/05_product-card.spec.ts index b8d58bdbbe..d8f60d2e6d 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/05_product-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/05_product-card.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Product Card (basic) (v0.8)', () => { +describe('Example: Product Card (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Product Card (basic)', Version.V0_8); + fixture = await loadExample('Product Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/06_music-player.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/06_music-player.spec.ts index eb6b43ccd0..df986938ff 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/06_music-player.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/06_music-player.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Music Player (basic) (v0.8)', () => { +describe('Example: Music Player (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Music Player (basic)', Version.V0_8); + fixture = await loadExample('Music Player', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/07_task-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/07_task-card.spec.ts index cdfd85a6ef..9fd1c81fe0 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/07_task-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/07_task-card.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Task Card (basic) (v0.8)', () => { +describe('Example: Task Card (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Task Card (basic)', Version.V0_8); + await loadExample('Task Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/08_user-profile.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/08_user-profile.spec.ts index 6cec44b8c9..be34ebda8f 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/08_user-profile.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/08_user-profile.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: User Profile (basic) (v0.8)', () => { +describe('Example: User Profile (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('User Profile (basic)', Version.V0_8); + fixture = await loadExample('User Profile', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/09_login-form.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/09_login-form.spec.ts index 749c192d85..b91304e906 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/09_login-form.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/09_login-form.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Login Form (basic) (v0.8)', () => { +describe('Example: Login Form (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Login Form (basic)', Version.V0_8); + fixture = await loadExample('Login Form', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/10_notification-permission.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/10_notification-permission.spec.ts index e6df06f5f3..83edcf6f8c 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/10_notification-permission.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/10_notification-permission.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Notification Permission (basic) (v0.8)', () => { +describe('Example: Notification Permission (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Notification Permission (basic)', Version.V0_8); + fixture = await loadExample('Notification Permission', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/11_purchase-complete.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/11_purchase-complete.spec.ts index f0eb69ce2e..c955082c52 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/11_purchase-complete.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/11_purchase-complete.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Purchase Complete (basic) (v0.8)', () => { +describe('Example: Purchase Complete (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Purchase Complete (basic)', Version.V0_8); + fixture = await loadExample('Purchase Complete', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/12_chat-message.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/12_chat-message.spec.ts index 0d751d2922..1fe0586ae3 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/12_chat-message.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/12_chat-message.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Chat Message (basic) (v0.8)', () => { +describe('Example: Chat Message (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Chat Message (basic)', Version.V0_8); + await loadExample('Chat Message', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/13_coffee-order.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/13_coffee-order.spec.ts index 976ce6609f..7dc2ae1518 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/13_coffee-order.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/13_coffee-order.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Coffee Order (basic) (v0.8)', () => { +describe('Example: Coffee Order (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Coffee Order (basic)', Version.V0_8); + fixture = await loadExample('Coffee Order', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/14_sports-player.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/14_sports-player.spec.ts index 31911f9ffd..93b47269d8 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/14_sports-player.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/14_sports-player.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Sports Player (basic) (v0.8)', () => { +describe('Example: Sports Player (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Sports Player (basic)', Version.V0_8); + await loadExample('Sports Player', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/15_account-balance.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/15_account-balance.spec.ts index 54e28bba1a..1f996fc5c4 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/15_account-balance.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/15_account-balance.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Account Balance (basic) (v0.8)', () => { +describe('Example: Account Balance (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Account Balance (basic)', Version.V0_8); + fixture = await loadExample('Account Balance', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/16_workout-summary.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/16_workout-summary.spec.ts index 1e329246eb..2271026447 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/16_workout-summary.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/16_workout-summary.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Workout Summary (basic) (v0.8)', () => { +describe('Example: Workout Summary (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Workout Summary (basic)', Version.V0_8); + await loadExample('Workout Summary', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/17_event-detail.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/17_event-detail.spec.ts index 50576ee895..f90c6cf251 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/17_event-detail.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/17_event-detail.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Event Detail (basic) (v0.8)', () => { +describe('Example: Event Detail (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Event Detail (basic)', Version.V0_8); + fixture = await loadExample('Event Detail', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/18_track-list.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/18_track-list.spec.ts index f5527692e4..95f1d961ea 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/18_track-list.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/18_track-list.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Track List (basic) (v0.8)', () => { +describe('Example: Track List (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Track List (basic)', Version.V0_8); + await loadExample('Track List', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/19_software-purchase.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/19_software-purchase.spec.ts index e257b99dc0..890418a00b 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/19_software-purchase.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/19_software-purchase.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Software Purchase (basic) (v0.8)', () => { +describe('Example: Software Purchase (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Software Purchase (basic)', Version.V0_8); + fixture = await loadExample('Software Purchase', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/20_restaurant-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/20_restaurant-card.spec.ts index fe415884dd..1404afe384 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/20_restaurant-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/20_restaurant-card.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Restaurant Card (basic) (v0.8)', () => { +describe('Example: Restaurant Card (v0.8)', () => { let fixture: ComponentFixture; let textContent: string; beforeEach(async () => { - fixture = await loadExample('Restaurant Card (basic)', Version.V0_8); + fixture = await loadExample('Restaurant Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/21_shipping-status.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/21_shipping-status.spec.ts index df6c708337..54660ebeac 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/21_shipping-status.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/21_shipping-status.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Shipping Status (basic) (v0.8)', () => { +describe('Example: Shipping Status (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Shipping Status (basic)', Version.V0_8); + await loadExample('Shipping Status', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/22_credit-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/22_credit-card.spec.ts index 3773ffca22..82d54c74ee 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/22_credit-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/22_credit-card.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Credit Card (basic) (v0.8)', () => { +describe('Example: Credit Card (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Credit Card (basic)', Version.V0_8); + await loadExample('Credit Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/23_step-counter.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/23_step-counter.spec.ts index d4b402f451..56e98643ca 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/23_step-counter.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/23_step-counter.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Step Counter (basic) (v0.8)', () => { +describe('Example: Step Counter (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Step Counter (basic)', Version.V0_8); + await loadExample('Step Counter', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/24_recipe-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/24_recipe-card.spec.ts index 55f5eeb793..9b79e67aa9 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/24_recipe-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/24_recipe-card.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Recipe Card (basic) (v0.8)', () => { +describe('Example: Recipe Card (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Recipe Card (basic)', Version.V0_8); + await loadExample('Recipe Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/25_contact-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/25_contact-card.spec.ts index 5107f6cf71..a7deb7c074 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/25_contact-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/25_contact-card.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Contact Card (basic) (v0.8)', () => { +describe('Example: Contact Card (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Contact Card (basic)', Version.V0_8); + fixture = await loadExample('Contact Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/26_podcast-episode.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/26_podcast-episode.spec.ts index 00fe1f3afe..612111741f 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/26_podcast-episode.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/26_podcast-episode.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Podcast Episode (basic) (v0.8)', () => { +describe('Example: Podcast Episode (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Podcast Episode (basic)', Version.V0_8); + fixture = await loadExample('Podcast Episode', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/27_stats-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/27_stats-card.spec.ts index bf40a89b54..c092ed95cf 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/27_stats-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/27_stats-card.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Stats Card (basic) (v0.8)', () => { +describe('Example: Stats Card (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Stats Card (basic)', Version.V0_8); + await loadExample('Stats Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/28_countdown-timer.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/28_countdown-timer.spec.ts index 2ca41a0cd0..82bf4244fa 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/28_countdown-timer.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/28_countdown-timer.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Countdown Timer (basic) (v0.8)', () => { +describe('Example: Countdown Timer (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Countdown Timer (basic)', Version.V0_8); + await loadExample('Countdown Timer', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/29_movie-card.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/29_movie-card.spec.ts index 95dbf6d6f5..6ea9e39f10 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/29_movie-card.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/29_movie-card.spec.ts @@ -16,11 +16,11 @@ import {Version, getCanvas, loadExample} from '../utils/test_utils'; -describe('Example: Movie Card (basic) (v0.8)', () => { +describe('Example: Movie Card (v0.8)', () => { let textContent: string; beforeEach(async () => { - await loadExample('Movie Card (basic)', Version.V0_8); + await loadExample('Movie Card', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/30_modal.spec.ts b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/30_modal.spec.ts index 2ed3aefb05..9884217df4 100644 --- a/renderers/angular/a2ui_explorer/src/app/tests/v0_8/30_modal.spec.ts +++ b/renderers/angular/a2ui_explorer/src/app/tests/v0_8/30_modal.spec.ts @@ -18,12 +18,12 @@ import {ComponentFixture} from '@angular/core/testing'; import {DemoComponent} from '../../demo.component'; import {Version, getCanvas, loadExample, wait} from '../utils/test_utils'; -describe('Example: Modal Sample (basic) (v0.8)', () => { +describe('Example: Modal Sample (v0.8)', () => { let textContent: string; let fixture: ComponentFixture; beforeEach(async () => { - fixture = await loadExample('Modal Sample (basic)', Version.V0_8); + fixture = await loadExample('Modal Sample', Version.V0_8); textContent = getCanvas().textContent; }); diff --git a/renderers/angular/scripts/generate-examples.mjs b/renderers/angular/scripts/generate-examples.mjs index 6b3a6efe8d..b5a6788e53 100644 --- a/renderers/angular/scripts/generate-examples.mjs +++ b/renderers/angular/scripts/generate-examples.mjs @@ -26,7 +26,7 @@ const DEFAULT_OUT_FILE = 'a2ui_explorer/src/app/generated/examples-bundle.ts'; /** * The default catalogs to generate examples for if none are specified. */ -const DEFAULT_CATALOGS = ['minimal', 'basic']; +const DEFAULT_CATALOGS = ['basic']; /** * The options that this script accepts. @@ -35,7 +35,6 @@ const options = { help: {type: 'boolean', short: 'h'}, 'out-file': {type: 'string', short: 'o', default: DEFAULT_OUT_FILE}, catalog: {type: 'string', short: 'c', multiple: true, default: DEFAULT_CATALOGS}, - 'override-minimal-catalog-id': {type: 'boolean', default: true}, }; /** @@ -46,35 +45,13 @@ const HELP_MESSAGE = `Usage: node generate-examples.mjs [options] Options: -o, --out-file Output file path (default: ${DEFAULT_OUT_FILE}) -c, --catalog Catalog names to include (can be specified multiple times) (default: ${DEFAULT_CATALOGS.join(', ')}) - --no-override-minimal-catalog-id Do not override catalog ID for minimal catalog -h, --help Show this help message `; -/** - * Overrides the catalog ID for minimal catalog to use basic catalog instead, - * preserving the version in the path. - */ -function overrideMessagesCatalogId(messages) { - const overrideCatalogId = catalogId => { - return catalogId.replace('catalogs/minimal/catalog.json', 'catalogs/basic/catalog.json'); - }; - for (const msg of messages) { - if (msg.createSurface && msg.createSurface.catalogId) { - // For v0.9 (and up?) - msg.createSurface.catalogId = overrideCatalogId(msg.createSurface.catalogId); - } - // The minimal catalog examples in 0.8 contain a catalogId (but not the basic - // catalog ones). That's probably copy-pasta from when catalogIds were - // introduced later, as the v0.8 renderers didn't use catalogIds. We don't - // need to handle the overrides of the catalogId for the beginRendering - // messages from the v0.8 spec. - } -} - /** * Reads examples for a given version and catalogs. */ -function readExamples(specPath, catalogs, overrideCatalogId, version) { +function readExamples(specPath, catalogs, version) { const examples = []; for (const catalog of catalogs) { @@ -100,7 +77,7 @@ function readExamples(specPath, catalogs, overrideCatalogId, version) { if (Array.isArray(data)) { example = { version: version, - name: version === '0.8' ? `${nameFromFile} (${catalog})` : nameFromFile, + name: nameFromFile, description: `Example from ${catalog} catalog`, messages: data, }; @@ -108,19 +85,12 @@ function readExamples(specPath, catalogs, overrideCatalogId, version) { example = { ...data, version: version, - name: - version === '0.8' - ? `${data.name || nameFromFile} (${catalog})` - : data.name || nameFromFile, + name: data.name || nameFromFile, description: data.description || `Example from ${catalog} catalog`, messages: data.messages || [], }; } - if (catalog === 'minimal' && overrideCatalogId) { - overrideMessagesCatalogId(example.messages); - } - examples.push(example); } catch (e) { throw new Error(`Error parsing ${filePath}`, {cause: e}); @@ -145,7 +115,6 @@ async function main() { const outPath = values['out-file']; const outDir = path.dirname(outPath); - const overrideCatalogId = values['override-minimal-catalog-id']; if (!fs.existsSync(outDir)) { fs.mkdirSync(outDir, {recursive: true}); @@ -153,18 +122,8 @@ async function main() { const catalogs = values.catalog; - const examplesV08 = readExamples( - '../../specification/v0_8/json/catalogs', - catalogs, - overrideCatalogId, - '0.8', - ); - const examplesV09 = readExamples( - '../../specification/v0_9/catalogs', - catalogs, - overrideCatalogId, - '0.9', - ); + const examplesV08 = readExamples('../../specification/v0_8/json/catalogs', catalogs, '0.8'); + const examplesV09 = readExamples('../../specification/v0_9/catalogs', catalogs, '0.9'); // Generate the file now! const tsContent = `/** diff --git a/renderers/lit/a2ui_explorer/README.md b/renderers/lit/a2ui_explorer/README.md index b27c866141..fa8a6d39cd 100644 --- a/renderers/lit/a2ui_explorer/README.md +++ b/renderers/lit/a2ui_explorer/README.md @@ -1,6 +1,6 @@ -# A2UI Local Gallery (Minimal v0.8) +# A2UI Local Gallery (Basic v0.9) -This is a standalone, agentless web application designed to render the A2UI v0.8 minimal examples directly from static JSON files. It serves as a focused environment for testing renderer subset compatibility and protocol compliance. +This is a standalone, agentless web application designed to render the A2UI v0.9 basic examples directly from static JSON files. It serves as a focused environment for testing renderer compatibility and protocol compliance. ## Prerequisites @@ -34,13 +34,12 @@ For more details on building the renderers, see: yarn dev ``` This command will: - - Sync all JSON examples from `specification/v0_8/json/catalogs/minimal/examples/`. - - Generate a manifest file (`index.json`) for dynamic discovery. + - Load all JSON examples from `specification/v0_9/catalogs/basic/examples/`. - Start the Vite server at `http://localhost:5173`. ## Architecture - **Agentless**: Unlike other samples, this does not require a running Python agent. It simulates agent responses locally for interactive components (like the Login Form). -- **Dynamic Loading**: The app automatically discovers and loads _all_ `.json` files present in the v0.8 minimal specification folder at build time. To add a new test case, simply drop a JSON file into that specification folder and restart the dev server. +- **Dynamic Loading**: The app automatically discovers and loads _all_ `.json` files present in the v0.9 basic specification folder at build time. To add a new test case, simply drop a JSON file into that specification folder and restart the dev server. - **Surface Isolation**: Each example is rendered into its own independent `a2ui-surface` with a unique ID derived from the filename. - **Mock Agent Console**: All user interactions (button clicks, form submissions) are intercepted and logged to a sidebar, demonstrating how the renderer resolves actions and contexts. diff --git a/specification/v0_8/json/catalogs/basic/examples/00_complex-layout.json b/specification/v0_8/json/catalogs/basic/examples/00_complex-layout.json new file mode 100644 index 0000000000..70dabf8dc5 --- /dev/null +++ b/specification/v0_8/json/catalogs/basic/examples/00_complex-layout.json @@ -0,0 +1,89 @@ +[ + { + "surfaceUpdate": { + "surfaceId": "gallery-complex-layout", + "components": [ + { + "id": "root", + "component": { + "Column": { + "children": { + "explicitList": ["header", "form_row", "footer"] + }, + "distribution": "spaceBetween", + "alignment": "stretch" + } + } + }, + { + "id": "header", + "component": { + "Text": { + "text": { + "literalString": "User Profile Form" + }, + "usageHint": "h1" + } + } + }, + { + "id": "form_row", + "component": { + "Row": { + "children": { + "explicitList": ["first_name", "last_name"] + }, + "distribution": "start", + "alignment": "start" + } + } + }, + { + "id": "first_name", + "weight": 1, + "component": { + "TextField": { + "label": { + "literalString": "First Name" + }, + "text": { + "path": "/firstName" + } + } + } + }, + { + "id": "last_name", + "weight": 1, + "component": { + "TextField": { + "label": { + "literalString": "Last Name" + }, + "text": { + "path": "/lastName" + } + } + } + }, + { + "id": "footer", + "component": { + "Text": { + "text": { + "literalString": "Please fill out all fields." + }, + "usageHint": "caption" + } + } + } + ] + } + }, + { + "beginRendering": { + "surfaceId": "gallery-complex-layout", + "root": "root" + } + } +] diff --git a/specification/v0_8/json/catalogs/basic/examples/00_interactive-button.json b/specification/v0_8/json/catalogs/basic/examples/00_interactive-button.json new file mode 100644 index 0000000000..93adc6e6fa --- /dev/null +++ b/specification/v0_8/json/catalogs/basic/examples/00_interactive-button.json @@ -0,0 +1,60 @@ +[ + { + "surfaceUpdate": { + "surfaceId": "gallery-interactive-button", + "components": [ + { + "id": "root", + "component": { + "Column": { + "children": { + "explicitList": ["title", "action_button"] + }, + "distribution": "center", + "alignment": "center" + } + } + }, + { + "id": "title", + "component": { + "Text": { + "text": { + "literalString": "Click the button below" + }, + "usageHint": "body" + } + } + }, + { + "id": "action_button", + "component": { + "Button": { + "child": "button_label", + "primary": true, + "action": { + "name": "button_clicked" + } + } + } + }, + { + "id": "button_label", + "component": { + "Text": { + "text": { + "literalString": "Click Me" + } + } + } + } + ] + } + }, + { + "beginRendering": { + "surfaceId": "gallery-interactive-button", + "root": "root" + } + } +] diff --git a/specification/v0_8/json/catalogs/basic/examples/00_row-layout.json b/specification/v0_8/json/catalogs/basic/examples/00_row-layout.json new file mode 100644 index 0000000000..2d55b4ef8e --- /dev/null +++ b/specification/v0_8/json/catalogs/basic/examples/00_row-layout.json @@ -0,0 +1,49 @@ +[ + { + "surfaceUpdate": { + "surfaceId": "gallery-row-layout", + "components": [ + { + "id": "root", + "component": { + "Row": { + "children": { + "explicitList": ["left_text", "right_text"] + }, + "distribution": "spaceBetween", + "alignment": "center" + } + } + }, + { + "id": "left_text", + "component": { + "Text": { + "text": { + "literalString": "Left Content" + }, + "usageHint": "body" + } + } + }, + { + "id": "right_text", + "component": { + "Text": { + "text": { + "literalString": "Right Content" + }, + "usageHint": "caption" + } + } + } + ] + } + }, + { + "beginRendering": { + "surfaceId": "gallery-row-layout", + "root": "root" + } + } +] diff --git a/specification/v0_8/json/catalogs/basic/examples/00_simple-login-form.json b/specification/v0_8/json/catalogs/basic/examples/00_simple-login-form.json new file mode 100644 index 0000000000..d1b016d824 --- /dev/null +++ b/specification/v0_8/json/catalogs/basic/examples/00_simple-login-form.json @@ -0,0 +1,118 @@ +[ + { + "dataModelUpdate": { + "surfaceId": "gallery-simple-login-form", + "path": "/", + "contents": [ + { + "key": "username", + "valueString": "" + }, + { + "key": "password", + "valueString": "" + } + ] + } + }, + { + "surfaceUpdate": { + "surfaceId": "gallery-simple-login-form", + "components": [ + { + "id": "root", + "component": { + "Column": { + "children": { + "explicitList": ["form_title", "username_field", "password_field", "submit_button"] + }, + "distribution": "start", + "alignment": "stretch" + } + } + }, + { + "id": "form_title", + "component": { + "Text": { + "text": { + "literalString": "Login" + }, + "usageHint": "h2" + } + } + }, + { + "id": "username_field", + "component": { + "TextField": { + "label": { + "literalString": "Username" + }, + "text": { + "path": "/username" + }, + "textFieldType": "shortText" + } + } + }, + { + "id": "password_field", + "component": { + "TextField": { + "label": { + "literalString": "Password" + }, + "text": { + "path": "/password" + }, + "textFieldType": "obscured" + } + } + }, + { + "id": "submit_button", + "component": { + "Button": { + "child": "submit_label", + "primary": true, + "action": { + "name": "login_submitted", + "context": [ + { + "key": "user", + "value": { + "path": "/username" + } + }, + { + "key": "pass", + "value": { + "path": "/password" + } + } + ] + } + } + } + }, + { + "id": "submit_label", + "component": { + "Text": { + "text": { + "literalString": "Sign In" + } + } + } + } + ] + } + }, + { + "beginRendering": { + "surfaceId": "gallery-simple-login-form", + "root": "root" + } + } +] diff --git a/specification/v0_8/json/catalogs/basic/examples/00_simple-text.json b/specification/v0_8/json/catalogs/basic/examples/00_simple-text.json new file mode 100644 index 0000000000..9670e5b2ee --- /dev/null +++ b/specification/v0_8/json/catalogs/basic/examples/00_simple-text.json @@ -0,0 +1,26 @@ +[ + { + "surfaceUpdate": { + "surfaceId": "gallery-simple-text", + "components": [ + { + "id": "root", + "component": { + "Text": { + "text": { + "literalString": "Hello, Minimal Catalog!" + }, + "usageHint": "h1" + } + } + } + ] + } + }, + { + "beginRendering": { + "surfaceId": "gallery-simple-text", + "root": "root" + } + } +] diff --git a/specification/v0_9/catalogs/basic/catalog.json b/specification/v0_9/catalogs/basic/catalog.json index cefc2b98bb..5e57459b8f 100644 --- a/specification/v0_9/catalogs/basic/catalog.json +++ b/specification/v0_9/catalogs/basic/catalog.json @@ -1240,6 +1240,30 @@ }, "required": ["call", "args"], "unevaluatedProperties": false + }, + "capitalize": { + "type": "object", + "description": "Converts an input string to a capitalized version.", + "properties": { + "call": { + "const": "capitalize" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v0_9/common_types.json#/$defs/DynamicString" + } + }, + "required": ["value"], + "unevaluatedProperties": false + }, + "returnType": { + "const": "string" + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false } }, "$defs": { @@ -1376,6 +1400,9 @@ }, { "$ref": "#/functions/not" + }, + { + "$ref": "#/functions/capitalize" } ] } diff --git a/specification/v0_9/catalogs/basic/examples/00_capitalized-text.json b/specification/v0_9/catalogs/basic/examples/00_capitalized-text.json new file mode 100644 index 0000000000..0b3de42f70 --- /dev/null +++ b/specification/v0_9/catalogs/basic/examples/00_capitalized-text.json @@ -0,0 +1,58 @@ +{ + "name": "Capitalized Text", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-capitalized-text", + "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json", + "sendDataModel": true + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-capitalized-text", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["input_field", "result_label", "result_text"], + "justify": "start", + "align": "stretch" + }, + { + "id": "input_field", + "component": "TextField", + "label": "Type something in lowercase:", + "value": { + "path": "/inputValue" + }, + "variant": "shortText" + }, + { + "id": "result_label", + "component": "Text", + "text": "Capitalized output:", + "variant": "caption" + }, + { + "id": "result_text", + "component": "Text", + "text": { + "call": "capitalize", + "args": { + "value": { + "path": "/inputValue" + } + }, + "returnType": "string" + }, + "variant": "h2" + } + ] + } + } + ] +} diff --git a/specification/v0_9/catalogs/basic/examples/00_complex-layout.json b/specification/v0_9/catalogs/basic/examples/00_complex-layout.json new file mode 100644 index 0000000000..2f36f8a679 --- /dev/null +++ b/specification/v0_9/catalogs/basic/examples/00_complex-layout.json @@ -0,0 +1,65 @@ +{ + "name": "Complex Layout", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-complex-layout", + "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json" + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-complex-layout", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["header", "form_row", "footer"], + "justify": "spaceBetween", + "align": "stretch" + }, + { + "id": "header", + "component": "Text", + "text": "User Profile Form", + "variant": "h1" + }, + { + "id": "form_row", + "component": "Row", + "children": ["first_name", "last_name"], + "justify": "start", + "align": "start" + }, + { + "id": "first_name", + "component": "TextField", + "label": "First Name", + "value": { + "path": "/firstName" + }, + "weight": 1 + }, + { + "id": "last_name", + "component": "TextField", + "label": "Last Name", + "value": { + "path": "/lastName" + }, + "weight": 1 + }, + { + "id": "footer", + "component": "Text", + "text": "Please fill out all fields.", + "variant": "caption" + } + ] + } + } + ] +} diff --git a/specification/v0_9/catalogs/basic/examples/00_incremental.json b/specification/v0_9/catalogs/basic/examples/00_incremental.json new file mode 100644 index 0000000000..c6e121dca4 --- /dev/null +++ b/specification/v0_9/catalogs/basic/examples/00_incremental.json @@ -0,0 +1,134 @@ +{ + "name": "Incremental", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-incremental", + "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json" + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "gallery-incremental", + "path": "/", + "value": { + "restaurants": [ + { + "title": "The Golden Fork", + "subtitle": "Fine Dining & Spirits", + "address": "123 Gastronomy Lane" + }, + { + "title": "Ocean's Bounty", + "subtitle": "Fresh Daily Seafood", + "address": "456 Shoreline Dr" + }, + { + "title": "Pizzeria Roma", + "subtitle": "Authentic Wood-Fired Pizza", + "address": "789 Napoli Way" + } + ] + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-incremental", + "components": [ + { + "id": "root", + "component": "Column", + "children": { + "path": "/restaurants", + "componentId": "restaurant_card" + } + } + ] + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-incremental", + "components": [ + { + "id": "restaurant_card", + "component": "Column", + "children": ["rc_title", "rc_subtitle", "rc_address"] + }, + { + "id": "rc_title", + "component": "Text", + "text": { + "path": "title" + } + }, + { + "id": "rc_subtitle", + "component": "Text", + "text": { + "path": "subtitle" + } + }, + { + "id": "rc_address", + "component": "Text", + "text": { + "path": "address" + } + } + ] + } + }, + { + "version": "v0.9", + "updateDataModel": { + "surfaceId": "gallery-incremental", + "path": "/restaurants/3", + "value": { + "title": "Spice Route", + "subtitle": "Exotic Flavors from the East", + "address": "101 Silk Road St" + } + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-incremental", + "components": [ + { + "id": "restaurant_card", + "component": "Column", + "children": ["rc_title", "rc_subtitle", "rc_address", "rc_button"] + }, + { + "id": "rc_button", + "component": "Button", + "child": "rc_button_label", + "action": { + "event": { + "name": "book_now", + "context": { + "restaurantName": { + "path": "title" + } + } + } + } + }, + { + "id": "rc_button_label", + "component": "Text", + "text": "Book now" + } + ] + } + } + ] +} diff --git a/specification/v0_9/catalogs/basic/examples/00_interactive-button.json b/specification/v0_9/catalogs/basic/examples/00_interactive-button.json new file mode 100644 index 0000000000..d1eec8b2c7 --- /dev/null +++ b/specification/v0_9/catalogs/basic/examples/00_interactive-button.json @@ -0,0 +1,51 @@ +{ + "name": "Interactive Button", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-interactive-button", + "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json" + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-interactive-button", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["title", "action_button"], + "justify": "center", + "align": "center" + }, + { + "id": "title", + "component": "Text", + "text": "Click the button below", + "variant": "body" + }, + { + "id": "action_button", + "component": "Button", + "child": "button_label", + "variant": "primary", + "action": { + "event": { + "name": "button_clicked", + "context": {} + } + } + }, + { + "id": "button_label", + "component": "Text", + "text": "Click Me" + } + ] + } + } + ] +} diff --git a/specification/v0_9/catalogs/basic/examples/00_row-layout.json b/specification/v0_9/catalogs/basic/examples/00_row-layout.json new file mode 100644 index 0000000000..4e43324984 --- /dev/null +++ b/specification/v0_9/catalogs/basic/examples/00_row-layout.json @@ -0,0 +1,40 @@ +{ + "name": "Row Layout", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-row-layout", + "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json" + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-row-layout", + "components": [ + { + "id": "root", + "component": "Row", + "children": ["left_text", "right_text"], + "justify": "spaceBetween", + "align": "center" + }, + { + "id": "left_text", + "component": "Text", + "text": "Left Content", + "variant": "body" + }, + { + "id": "right_text", + "component": "Text", + "text": "Right Content", + "variant": "caption" + } + ] + } + } + ] +} diff --git a/specification/v0_9/catalogs/basic/examples/00_simple-login-form.json b/specification/v0_9/catalogs/basic/examples/00_simple-login-form.json new file mode 100644 index 0000000000..aab65a76f9 --- /dev/null +++ b/specification/v0_9/catalogs/basic/examples/00_simple-login-form.json @@ -0,0 +1,77 @@ +{ + "name": "Simple Login Form", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-simple-login-form", + "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json", + "sendDataModel": true + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-simple-login-form", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["form_title", "username_field", "password_field", "submit_button"], + "justify": "start", + "align": "stretch" + }, + { + "id": "form_title", + "component": "Text", + "text": "Login", + "variant": "h2" + }, + { + "id": "username_field", + "component": "TextField", + "label": "Username", + "value": { + "path": "/username" + }, + "variant": "shortText" + }, + { + "id": "password_field", + "component": "TextField", + "label": "Password", + "value": { + "path": "/password" + }, + "variant": "obscured" + }, + { + "id": "submit_button", + "component": "Button", + "child": "submit_label", + "variant": "primary", + "action": { + "event": { + "name": "login_submitted", + "context": { + "user": { + "path": "/username" + }, + "pass": { + "path": "/password" + } + } + } + } + }, + { + "id": "submit_label", + "component": "Text", + "text": "Sign In" + } + ] + } + } + ] +} diff --git a/specification/v0_9/catalogs/basic/examples/00_simple-text.json b/specification/v0_9/catalogs/basic/examples/00_simple-text.json new file mode 100644 index 0000000000..81cab829f5 --- /dev/null +++ b/specification/v0_9/catalogs/basic/examples/00_simple-text.json @@ -0,0 +1,27 @@ +{ + "name": "Simple Text", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v0.9", + "createSurface": { + "surfaceId": "gallery-simple-text", + "catalogId": "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json" + } + }, + { + "version": "v0.9", + "updateComponents": { + "surfaceId": "gallery-simple-text", + "components": [ + { + "id": "root", + "component": "Text", + "text": "Hello, Minimal Catalog!", + "variant": "h1" + } + ] + } + } + ] +} diff --git a/specification/v0_9/docs/renderer_guide.md b/specification/v0_9/docs/renderer_guide.md index 86d5f0ed0f..468440850f 100644 --- a/specification/v0_9/docs/renderer_guide.md +++ b/specification/v0_9/docs/renderer_guide.md @@ -743,8 +743,8 @@ Thoroughly review: - `specification/v0_9/docs/a2ui_protocol.md` (protocol rules) - `specification/v0_9/json/common_types.json` (dynamic binding types) - `specification/v0_9/json/server_to_client.json` (message envelopes) -- `specification/v0_9/json/catalogs/minimal/minimal_catalog.json` (your initial target) -- `specification/v0_9/docs/basic_catalog_implementation_guide.md` (for rendering and spacing rules for when you get to the basic catalog) +- `specification/v0_9/catalogs/basic/catalog.json` (your target) +- `specification/v0_9/docs/basic_catalog_implementation_guide.md` (for rendering and spacing rules) ### 2. Key Architecture Decisions (Write a Plan Document) @@ -776,13 +776,13 @@ Implement the bridge between models and native UI (Section 5 & 6). - Implement the `Surface` view/widget that recurses through components. - Implement subscription lifecycle management (lazy mounting, unmounting disposal). -### 5. Minimal Catalog Support +### 5. Initial Basic Catalog Support -Target the `minimal_catalog.json` first. +Target a foundational subset of components in `basic/catalog.json` first to bootstrap your implementation. -- Implement the pure API schemas for `Text`, `Row`, `Column`, `Button`, `TextField`. +- Implement the pure API schemas for `Text`, `Row`, `Column`, `Button`, `TextField` (which are part of the standard Basic Catalog). - Implement the specific native UI rendering components for these. -- Implement the `capitalize` function. +- Implement the `formatString` function (which is required for basic text rendering, see Section 7). - Bundle these into a `Catalog`. - **Action**: Write unit tests verifying that properties update reactively when data changes. @@ -790,16 +790,15 @@ Target the `minimal_catalog.json` first. Build the Gallery App following the requirements in **Section 8**. -- Load JSON samples from `specification/v0_9/json/catalogs/minimal/examples/`. +- Load JSON samples from `specification/v0_9/catalogs/basic/examples/` (focusing on the simpler ones first, such as those using only the bootstrapped components). - Verify progressive rendering and reactivity. - **STOP HERE. Ask the user for approval of the architecture and gallery application before proceeding to step 7.** -### 7. Basic Catalog Support +### 7. Complete Basic Catalog Support -Once the minimal architecture is proven robust, refer to the [Basic Catalog Implementation Guide](basic_catalog_implementation_guide.md) and: +Once the initial architecture is proven robust, complete the implementation of the Basic Catalog: -- **Core Library**: Implement the full suite of basic functions. It is crucial to note that string interpolation and expression parsing should ONLY happen within the `formatString` function. Do not attempt to add global string interpolation to all strings. +- **Core Library**: Implement the remaining basic functions. It is crucial to note that string interpolation and expression parsing should ONLY happen within the `formatString` function. Do not attempt to add global string interpolation to all strings. - **Core Library**: Create definitions/binders for the remaining Basic Catalog components. - **Framework Library**: Implement all remaining UI widgets. - **Tests**: Look at existing reference implementations (e.g., `web_core`) to formulate and run comprehensive unit and integration test cases for data coercion and function logic. -- Update the Gallery App to load samples from `specification/v0_9/json/catalogs/basic/examples/`. diff --git a/specification/v1_0/catalogs/basic/catalog.json b/specification/v1_0/catalogs/basic/catalog.json index 9d9767e146..e49d7d177d 100644 --- a/specification/v1_0/catalogs/basic/catalog.json +++ b/specification/v1_0/catalogs/basic/catalog.json @@ -1219,6 +1219,28 @@ }, "required": ["call", "args"], "unevaluatedProperties": false + }, + "capitalize": { + "type": "object", + "description": "Converts an input string to a capitalized version.", + "returnType": "string", + "properties": { + "call": { + "const": "capitalize" + }, + "args": { + "type": "object", + "properties": { + "value": { + "$ref": "https://a2ui.org/specification/v1_0/common_types.json#/$defs/DynamicString" + } + }, + "required": ["value"], + "unevaluatedProperties": false + } + }, + "required": ["call", "args"], + "unevaluatedProperties": false } }, "$defs": { @@ -1350,6 +1372,9 @@ }, { "$ref": "#/functions/not" + }, + { + "$ref": "#/functions/capitalize" } ] } diff --git a/specification/v1_0/catalogs/basic/examples/00_capitalized-text.json b/specification/v1_0/catalogs/basic/examples/00_capitalized-text.json new file mode 100644 index 0000000000..e8a955dbc6 --- /dev/null +++ b/specification/v1_0/catalogs/basic/examples/00_capitalized-text.json @@ -0,0 +1,57 @@ +{ + "name": "Capitalized Text", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v1.0", + "createSurface": { + "surfaceId": "gallery-capitalized-text", + "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", + "sendDataModel": true + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-capitalized-text", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["input_field", "result_label", "result_text"], + "justify": "start", + "align": "stretch" + }, + { + "id": "input_field", + "component": "TextField", + "label": "Type something in lowercase:", + "value": { + "path": "/inputValue" + }, + "variant": "shortText" + }, + { + "id": "result_label", + "component": "Text", + "text": "Capitalized output:", + "variant": "caption" + }, + { + "id": "result_text", + "component": "Text", + "text": { + "call": "capitalize", + "args": { + "value": { + "path": "/inputValue" + } + } + }, + "variant": "h2" + } + ] + } + } + ] +} diff --git a/specification/v1_0/catalogs/basic/examples/00_complex-layout.json b/specification/v1_0/catalogs/basic/examples/00_complex-layout.json new file mode 100644 index 0000000000..7fc1311984 --- /dev/null +++ b/specification/v1_0/catalogs/basic/examples/00_complex-layout.json @@ -0,0 +1,65 @@ +{ + "name": "Complex Layout", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v1.0", + "createSurface": { + "surfaceId": "gallery-complex-layout", + "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json" + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-complex-layout", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["header", "form_row", "footer"], + "justify": "spaceBetween", + "align": "stretch" + }, + { + "id": "header", + "component": "Text", + "text": "User Profile Form", + "variant": "h1" + }, + { + "id": "form_row", + "component": "Row", + "children": ["first_name", "last_name"], + "justify": "start", + "align": "start" + }, + { + "id": "first_name", + "component": "TextField", + "label": "First Name", + "value": { + "path": "/firstName" + }, + "weight": 1 + }, + { + "id": "last_name", + "component": "TextField", + "label": "Last Name", + "value": { + "path": "/lastName" + }, + "weight": 1 + }, + { + "id": "footer", + "component": "Text", + "text": "Please fill out all fields.", + "variant": "caption" + } + ] + } + } + ] +} diff --git a/specification/v1_0/catalogs/basic/examples/00_incremental.json b/specification/v1_0/catalogs/basic/examples/00_incremental.json new file mode 100644 index 0000000000..86c11dbbc3 --- /dev/null +++ b/specification/v1_0/catalogs/basic/examples/00_incremental.json @@ -0,0 +1,134 @@ +{ + "name": "Incremental", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v1.0", + "createSurface": { + "surfaceId": "gallery-incremental", + "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json" + } + }, + { + "version": "v1.0", + "updateDataModel": { + "surfaceId": "gallery-incremental", + "path": "/", + "value": { + "restaurants": [ + { + "title": "The Golden Fork", + "subtitle": "Fine Dining & Spirits", + "address": "123 Gastronomy Lane" + }, + { + "title": "Ocean's Bounty", + "subtitle": "Fresh Daily Seafood", + "address": "456 Shoreline Dr" + }, + { + "title": "Pizzeria Roma", + "subtitle": "Authentic Wood-Fired Pizza", + "address": "789 Napoli Way" + } + ] + } + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-incremental", + "components": [ + { + "id": "root", + "component": "Column", + "children": { + "path": "/restaurants", + "componentId": "restaurant_card" + } + } + ] + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-incremental", + "components": [ + { + "id": "restaurant_card", + "component": "Column", + "children": ["rc_title", "rc_subtitle", "rc_address"] + }, + { + "id": "rc_title", + "component": "Text", + "text": { + "path": "title" + } + }, + { + "id": "rc_subtitle", + "component": "Text", + "text": { + "path": "subtitle" + } + }, + { + "id": "rc_address", + "component": "Text", + "text": { + "path": "address" + } + } + ] + } + }, + { + "version": "v1.0", + "updateDataModel": { + "surfaceId": "gallery-incremental", + "path": "/restaurants/3", + "value": { + "title": "Spice Route", + "subtitle": "Exotic Flavors from the East", + "address": "101 Silk Road St" + } + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-incremental", + "components": [ + { + "id": "restaurant_card", + "component": "Column", + "children": ["rc_title", "rc_subtitle", "rc_address", "rc_button"] + }, + { + "id": "rc_button", + "component": "Button", + "child": "rc_button_label", + "action": { + "event": { + "name": "book_now", + "context": { + "restaurantName": { + "path": "title" + } + } + } + } + }, + { + "id": "rc_button_label", + "component": "Text", + "text": "Book now" + } + ] + } + } + ] +} diff --git a/specification/v1_0/catalogs/basic/examples/00_interactive-button.json b/specification/v1_0/catalogs/basic/examples/00_interactive-button.json new file mode 100644 index 0000000000..c565fc1c87 --- /dev/null +++ b/specification/v1_0/catalogs/basic/examples/00_interactive-button.json @@ -0,0 +1,51 @@ +{ + "name": "Interactive Button", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v1.0", + "createSurface": { + "surfaceId": "gallery-interactive-button", + "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json" + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-interactive-button", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["title", "action_button"], + "justify": "center", + "align": "center" + }, + { + "id": "title", + "component": "Text", + "text": "Click the button below", + "variant": "body" + }, + { + "id": "action_button", + "component": "Button", + "child": "button_label", + "variant": "primary", + "action": { + "event": { + "name": "button_clicked", + "context": {} + } + } + }, + { + "id": "button_label", + "component": "Text", + "text": "Click Me" + } + ] + } + } + ] +} diff --git a/specification/v1_0/catalogs/basic/examples/00_row-layout.json b/specification/v1_0/catalogs/basic/examples/00_row-layout.json new file mode 100644 index 0000000000..dfb878ff84 --- /dev/null +++ b/specification/v1_0/catalogs/basic/examples/00_row-layout.json @@ -0,0 +1,40 @@ +{ + "name": "Row Layout", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v1.0", + "createSurface": { + "surfaceId": "gallery-row-layout", + "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json" + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-row-layout", + "components": [ + { + "id": "root", + "component": "Row", + "children": ["left_text", "right_text"], + "justify": "spaceBetween", + "align": "center" + }, + { + "id": "left_text", + "component": "Text", + "text": "Left Content", + "variant": "body" + }, + { + "id": "right_text", + "component": "Text", + "text": "Right Content", + "variant": "caption" + } + ] + } + } + ] +} diff --git a/specification/v1_0/catalogs/basic/examples/00_simple-login-form.json b/specification/v1_0/catalogs/basic/examples/00_simple-login-form.json new file mode 100644 index 0000000000..7c998ded2f --- /dev/null +++ b/specification/v1_0/catalogs/basic/examples/00_simple-login-form.json @@ -0,0 +1,77 @@ +{ + "name": "Simple Login Form", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v1.0", + "createSurface": { + "surfaceId": "gallery-simple-login-form", + "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json", + "sendDataModel": true + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-simple-login-form", + "components": [ + { + "id": "root", + "component": "Column", + "children": ["form_title", "username_field", "password_field", "submit_button"], + "justify": "start", + "align": "stretch" + }, + { + "id": "form_title", + "component": "Text", + "text": "Login", + "variant": "h2" + }, + { + "id": "username_field", + "component": "TextField", + "label": "Username", + "value": { + "path": "/username" + }, + "variant": "shortText" + }, + { + "id": "password_field", + "component": "TextField", + "label": "Password", + "value": { + "path": "/password" + }, + "variant": "obscured" + }, + { + "id": "submit_button", + "component": "Button", + "child": "submit_label", + "variant": "primary", + "action": { + "event": { + "name": "login_submitted", + "context": { + "user": { + "path": "/username" + }, + "pass": { + "path": "/password" + } + } + } + } + }, + { + "id": "submit_label", + "component": "Text", + "text": "Sign In" + } + ] + } + } + ] +} diff --git a/specification/v1_0/catalogs/basic/examples/00_simple-text.json b/specification/v1_0/catalogs/basic/examples/00_simple-text.json new file mode 100644 index 0000000000..d93d49c16a --- /dev/null +++ b/specification/v1_0/catalogs/basic/examples/00_simple-text.json @@ -0,0 +1,27 @@ +{ + "name": "Simple Text", + "description": "Simple example demonstrating basic catalog components.", + "messages": [ + { + "version": "v1.0", + "createSurface": { + "surfaceId": "gallery-simple-text", + "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json" + } + }, + { + "version": "v1.0", + "updateComponents": { + "surfaceId": "gallery-simple-text", + "components": [ + { + "id": "root", + "component": "Text", + "text": "Hello, Minimal Catalog!", + "variant": "h1" + } + ] + } + } + ] +}