Skip to content

Add 29 example layouts for the v0.9 basic catalog#761

Merged
jacobsimionato merged 1 commit intogoogle:mainfrom
jacobsimionato:composer-samples
Mar 3, 2026
Merged

Add 29 example layouts for the v0.9 basic catalog#761
jacobsimionato merged 1 commit intogoogle:mainfrom
jacobsimionato:composer-samples

Conversation

@jacobsimionato
Copy link
Collaborator

Description

This PR adds 29 example layouts to the v0.9 basic_catalog specification. The layouts were adapted from the gallery source code at tools/composer/src/data/gallery/** into the v0.9 server_to_client_list.json format.

Key mappings handled during the transformation:

  • Replaced ProgressBar with Slider
  • Mapped properties: alignment to align, distribution to justify, and usageHint to variant
  • Re-mapped baseline alignments to the supported start enum
  • Restructured action: 'name' strings into object structures {"event": {"name": "...", "context": {}}}

These example files provide integration scenarios and test beds for implementations of the v0.9 basic_catalog.

Pre-launch Checklist

@jacobsimionato jacobsimionato merged commit 18c94f6 into google:main Mar 3, 2026
8 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in A2UI Mar 3, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a great initiative to add a comprehensive set of 29 example layouts for the v0.9 basic catalog, which will be very valuable for integration and testing. Overall, the structure of the examples is good. However, I've identified a few critical issues and areas for improvement across the new files:

  • Schema Violations: There are widespread schema violations, particularly with invalid icon names and the incorrect use of the action property on TextField components. These are critical as they will cause rendering failures.
  • Security: The login form example has a security flaw where the password field is not obscured.
  • Maintainability & Scalability: Several examples use hardcoded lists of components instead of the more robust and scalable templating feature. This makes them brittle to changes in the data model.
  • Clarity: In one case, a component ID is misleading, which impacts code clarity.

I've provided specific comments and suggestions to address these points. Applying these changes will significantly improve the quality and correctness of these examples.

Note: Security Review has been skipped due to the limited scope of the PR.

Comment on lines +50 to +54
{
"id": "flight-indicator",
"component": "Icon",
"name": "flight"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The icon name "flight" is not valid according to the basic_catalog.json schema. Please use one of the icon names defined in the catalog's enum. For example, you could use send, which can represent a paper plane.

        {
          "id": "flight-indicator",
          "component": "Icon",
          "name": "send"
        }

Comment on lines +53 to +67
{
"id": "email-field",
"component": "TextField",
"value": {
"path": "/email"
},
"placeholder": "Email address",
"label": "Email",
"action": {
"event": {
"name": "updateEmail",
"context": {}
}
}
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The action property is not valid for a TextField component according to the basic_catalog.json schema. Input changes are handled via two-way data binding, and action is typically reserved for components like Button that trigger a specific event.

        {
          "id": "email-field",
          "component": "TextField",
          "value": {
            "path": "/email"
          },
          "placeholder": "Email address",
          "label": "Email"
        },

Comment on lines +68 to +82
{
"id": "password-field",
"component": "TextField",
"value": {
"path": "/password"
},
"placeholder": "Password",
"label": "Password",
"action": {
"event": {
"name": "updatePassword",
"context": {}
}
}
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The password-field component has two issues:

  1. It's a TextField for a password but doesn't use the obscured variant. This will cause the password to be displayed in plain text as the user types, which is a security vulnerability.
  2. The action property is not valid for a TextField component according to the basic_catalog.json schema. Input changes are handled via two-way data binding, and action is typically reserved for components like Button.
        {
          "id": "password-field",
          "component": "TextField",
          "value": {
            "path": "/password"
          },
          "placeholder": "Password",
          "label": "Password",
          "variant": "obscured"
        },

Comment on lines +71 to +75
{
"id": "location-icon",
"component": "Icon",
"name": "location_on"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The icon name "location_on" is not valid. It seems you are using snake_case, but the basic_catalog.json schema specifies icon names in camelCase. The correct name is locationOn. This casing issue is present for other icons in the examples as well.

        {
          "id": "location-icon",
          "component": "Icon",
          "name": "locationOn"
        }

Comment on lines +72 to +209
{
"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"
},
"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"
},
{
"id": "day4",
"component": "Column",
"children": [
"day4-icon",
"day4-temp"
],
"align": "center"
},
{
"id": "day4-icon",
"component": "Text",
"text": {
"path": "/forecast/3/icon"
},
"variant": "h3"
},
{
"id": "day4-temp",
"component": "Text",
"text": {
"path": "/forecast/3/temp"
},
"variant": "caption"
},
{
"id": "day5",
"component": "Column",
"children": [
"day5-icon",
"day5-temp"
],
"align": "center"
},
{
"id": "day5-icon",
"component": "Text",
"text": {
"path": "/forecast/4/icon"
},
"variant": "h3"
},
{
"id": "day5-temp",
"component": "Text",
"text": {
"path": "/forecast/4/temp"
},
"variant": "caption"
}
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The forecast-row component and its children (day1 through day5) are hardcoded to display a five-day forecast. This implementation is not scalable and will break or render incorrectly if the forecast data array has a different number of items.

A better approach is to use the dynamic list templating feature. This involves:

  1. Defining a single template component for a forecast day.
  2. Binding the children property of forecast-row to the /forecast data array, referencing the template.
  3. Using relative paths within the template to bind to item properties like icon and temp.

This makes the layout robust and adaptable to data of any length.

        {
          "id": "forecast-row",
          "component": "Row",
          "children": {
            "path": "/forecast",
            "componentId": "forecast-day-template"
          },
          "justify": "spaceAround"
        },
        {
          "id": "forecast-day-template",
          "component": "Column",
          "children": [
            "day-icon",
            "day-temp"
          ],
          "align": "center"
        },
        {
          "id": "day-icon",
          "component": "Text",
          "text": {
            "path": "icon"
          },
          "variant": "h3"
        },
        {
          "id": "day-temp",
          "component": "Text",
          "text": {
            "path": "temp"
          },
          "variant": "caption"
        }

Comment on lines +143 to +146
{
"id": "events-list",
"component": "Divider"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The component with id: "events-list" is a Divider. This name is misleading as it suggests a list of events, while the component is just a visual separator. For better clarity and maintainability, the ID should reflect its purpose (e.g., divider). Please also update the reference in the children array of the main-column component.

        {
          "id": "divider",
          "component": "Divider"
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants