Skip to content

Commit a5ad0c3

Browse files
authored
(Lit) Add restaurant sample v0.9 (#1105)
* Port the old shell app to the latest v0.9 renderer stack. (Lots of red!)
1 parent 526d624 commit a5ad0c3

20 files changed

Lines changed: 290 additions & 1730 deletions

samples/client/lit/package-lock.json

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

samples/client/lit/shell/README.md

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,44 @@ This is a UI to generate and visualize A2UI responses.
44

55
## Prerequisites
66

7-
1. [nodejs](https://nodejs.org/en)
7+
* [nodejs](https://nodejs.org/en)
8+
* [uv](https://docs.astral.sh/uv/getting-started/installation/)
89

910
## Running
1011

11-
This sample depends on the Lit renderer. Before running this sample, you need to build the renderer.
12+
### Configure Gemini API Key
1213

13-
1. **Build the renderer:**
14-
```bash
15-
cd ../../../renderers/web_core
16-
npm install
17-
npm run build
18-
cd ../lit
19-
npm install
20-
npm run build
21-
```
14+
This step is **required** for the backend to work.
2215

23-
2. **Run this sample:**
24-
```bash
25-
cd - # back to the sample directory
26-
npm install
27-
```
16+
- Navigate to the respective agent directory (e.g., `samples/agent/adk/restaurant_finder`
17+
or `samples/agent/adk/contact_lookup`).
18+
- Copy `.env.example` to `.env` and set your `GEMINI_API_KEY`.
2819

29-
3. **Run the servers:**
30-
- Run the [Restaurant Finder Agent](../../../agent/adk/restaurant_finder/) (Default): `npm run demo:restaurant`
31-
- Run the dev server: `npm run dev`
20+
(More details can be found in the READMEs of the [agent samples](/samples/agent/adk).)
3221

33-
### Running the Contact Sample
22+
### Run the Demo and Servers
3423

35-
The shell app supports multiple configured applications. To run the Contact sample:
24+
From the `samples/client/lit` directory:
3625

37-
1. **Start the Contact Agent:**
38-
```bash
39-
npm run demo:contact
40-
```
26+
- Run the **Restaurant Finder** demo (starts both the agent and the shell):
27+
```bash
28+
npm run demo:restaurant09
29+
```
30+
- Or run the **Contact Lookup** demo:
31+
```bash
32+
npm run demo:contact09
33+
```
4134

42-
2. **Open the Contact App:**
43-
- Open `http://localhost:5173/?app=contacts`
35+
### Open the Application
36+
37+
From a web browser:
38+
39+
- Open `http://localhost:5173/` for the default application (Restaurant Finder).
40+
- Open `http://localhost:5173/?app=contacts` for the Contact Lookup application.
4441

4542
> **Note:** The `?app=` query parameter only supports apps that are actively configured in `app.ts` (e.g., `restaurant`, `contacts`). You cannot run arbitrary agents by passing their URL as a query string without first adding them to the shell configuration.
4643
47-
After starting the dev server, you can open http://localhost:5173/ to view the sample.
44+
## Security Notice
4845

4946
Important: The sample code provided is for demonstration purposes and illustrates the mechanics of A2UI and the Agent-to-Agent (A2A) protocol. When building production applications, it is critical to treat any agent operating outside of your direct control as a potentially untrusted entity.
5047

Lines changed: 19 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,29 @@
1-
# A2UI Theming & Configuration Guide
1+
# A2UI Lit v0.9 Theming & Configuration Guide
22

3-
This guide explains how the Universal App Shell handles theming and how to add new sample applications seamlessly.
3+
This document describes the styling and configuration architecture for the v0.9 A2UI Lit Shell.
44

5-
## Architecture Overview
5+
## Architecture
66

7-
The styling system is built on two distinct layers:
7+
### Design Tokens and CSS Variables
88

9-
### 1. **Base Layer (`default-theme.ts`)**
9+
This application uses A2UI's "Basic Catalog", which has some theming features.
1010

11-
- **Role**: Structural & Functional Styles.
12-
- **What it does**: Maps A2UI components (like `Text`, `Card`, `Row`) to functional CSS utility classes (e.g., `layout-w-100`, `typography-f-sf`).
13-
- **When to touch**: Rarely. Only if you need to change the fundamental layout behavior of a component across all shell apps.
11+
Themes can be configured by overriding default CSS variables provided by the
12+
Lit renderer basic catalog implementation.
1413

15-
### 2. **Configuration Layer (`configs/*.ts`)**
14+
Design tokens are defined in two layers:
1615

17-
- **Role**: App Identity & Brand Overrides.
18-
- **What it does**: Allows for app-level theme overrides.
19-
- **Key Mechanism**: The `AppConfig` interface allows you to provide a new theme by setting items in the `theme` property.
20-
- **When to touch**: Whenever you add a new app and want to change an app's theme from the default theme provided with the shell.
16+
- **Web Core**: Supplies base design tokens (color palettes, typography, spacing)
17+
that are used by the A2UI-provided renderers via global CSS custom properties on the root element. See the [Basic Catalog default styles](renderers/web_core/src/v0_9/basic_catalog/styles/default.ts).
18+
- **Lit Renderer**: Each Basic Catalog component provided by the Lit renderer
19+
has additional design tokens to target more-specific properties (e.g., `--a2ui-button-background`). View available components and the tokens they
20+
expose in the [Lit Basic Catalog Components](renderers/lit/src/v0_9/catalogs/basic/components).
2121

22-
---
22+
### Application Configuration
2323

24-
## How to Add a New Sample App
24+
In this particular app:
2525

26-
Follow these steps to add a new application (e.g., "Flight Booker") with its own unique theme.
27-
28-
### Step 1: Create the Config
29-
30-
Create a new file `configs/flights.ts`:
31-
32-
```typescript
33-
import { AppConfig } from "./types.js";
34-
import { cloneDefaultTheme } from "../theme/clone-default-theme.js";
35-
36-
const theme = cloneDefaultTheme();
37-
// Set your variables, e.g., theme.components.Card = { 'color-bgc-n100': true }
38-
39-
export const config: AppConfig = {
40-
key: "flights",
41-
title: "Flight Booker",
42-
heroImage: "/hero-flights.png",
43-
heroImageDark: "/hero-flights-dark.png", // Optional
44-
placeholder: "Where do you want to go?",
45-
loadingText: ["Checking availability...", "Finding best rates..."],
46-
serverUrl: "http://localhost:10004", // Your agent's URL
47-
theme, // Apply the theme.
48-
};
49-
```
50-
51-
### Step 2: Register the Config
52-
53-
Update `app.ts` to include your new config:
54-
55-
```typescript
56-
import { config as flightsConfig } from "./configs/flights.js";
57-
58-
const configs: Record<string, AppConfig> = {
59-
restaurant: restaurantConfig,
60-
contacts: contactsConfig,
61-
flights: flightsConfig, // Add this line
62-
};
63-
```
64-
65-
### Step 3: Run It
66-
67-
Access your new app by adding the `app` query parameter:
68-
`http://localhost:5173/?app=flights`
69-
70-
The App Shell will automatically:
71-
72-
1. Load your `flights` config.
73-
2. Apply your theme to the A2UI root's theme context.
74-
3. Connect to your specified `serverUrl`.
75-
76-
---
77-
78-
## Reference: Styling Levers
79-
80-
This section lists the available styling "levers" (utility classes) you can use in your `theme.ts` file or directly in your components. These are defined in the core library (`renderers/lit/src/0.8/styles`).
81-
82-
### 1. Layout (`layout-`)
83-
84-
**Source:** `styles/layout.ts`
85-
86-
| Category | Prefix | Scale/Values | Examples |
87-
| :-------------- | :------------ | :------------------------------------------ | :---------------------------------------------------------- |
88-
| **Padding** | `layout-p-` | 0-24 (1 = 4px) | `layout-p-4` (16px), `layout-pt-2` (Top 8px), `layout-px-4` |
89-
| **Margin** | `layout-m-` | 0-24 (1 = 4px) | `layout-m-0`, `layout-mb-4` (Bottom 16px), `layout-mx-auto` |
90-
| **Gap** | `layout-g-` | 0-24 (1 = 4px) | `layout-g-2` (8px), `layout-g-4` (16px) |
91-
| **Width** | `layout-w-` | 10-100 (Percentage) | `layout-w-100` (100%), `layout-w-50` (50%) |
92-
| **Width (Px)** | `layout-wp-` | 0-15 (1 = 4px) | `layout-wp-10` (40px) |
93-
| **Height** | `layout-h-` | 10-100 (Percentage) | `layout-h-100` (100%) |
94-
| **Height (Px)** | `layout-hp-` | 0-15 (1 = 4px) | `layout-hp-10` (40px) |
95-
| **Display** | `layout-dsp-` | `none`, `block`, `grid`, `flex`, `iflex` | `layout-dsp-flexhor` (Row), `layout-dsp-flexvert` (Col) |
96-
| **Alignment** | `layout-al-` | `fs` (Start), `fe` (End), `c` (Center) | `layout-al-c` (Align Items Center) |
97-
| **Justify** | `layout-sp-` | `c` (Center), `bt` (Between), `ev` (Evenly) | `layout-sp-bt` (Justify Content Space Between) |
98-
| **Flex** | `layout-flx-` | `0` (None), `1` (Grow) | `layout-flx-1` (Flex Grow 1) |
99-
| **Position** | `layout-pos-` | `a` (Absolute), `rel` (Relative) | `layout-pos-rel` |
100-
101-
### 2. Colors (`color-`)
102-
103-
**Source:** `styles/colors.ts`
104-
105-
| Category | Prefix | Scale/Values | Examples |
106-
| :--------------- | :----------- | :------------------ | :-------------------------------------------------------------------- |
107-
| **Text Color** | `color-c-` | Palette Key + Shade | `color-c-p50` (Primary), `color-c-n10` (Black), `color-c-e40` (Error) |
108-
| **Background** | `color-bgc-` | Palette Key + Shade | `color-bgc-p100` (White/Lightest), `color-bgc-s30` (Secondary Dark) |
109-
| **Border Color** | `color-bc-` | Palette Key + Shade | `color-bc-p60` (Primary Border) |
110-
111-
**Palette Keys:**
112-
113-
- `p` = Primary (Brand)
114-
- `s` = Secondary
115-
- `t` = Tertiary
116-
- `n` = Neutral (Grays)
117-
- `nv` = Neutral Variant
118-
- `e` = Error
119-
120-
**Shades:** 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 95, 98, 99, 100
121-
122-
### 3. Typography (`typography-`)
123-
124-
**Source:** `styles/type.ts`
125-
126-
| Category | Prefix | Scale/Values | Examples |
127-
| :------------------ | :--------------- | :---------------------------------------- | :----------------------------------------------------------------------------------- |
128-
| **Font Family** | `typography-f-` | `sf` (Sans/Flex), `s` (Serif), `c` (Code) | `typography-f-sf` (System UI / Outfit) |
129-
| **Weight** | `typography-w-` | 100-900 | `typography-w-400` (Regular), `typography-w-500` (Medium), `typography-w-700` (Bold) |
130-
| **Size (Body)** | `typography-sz-` | `bs`, `bm`, `bl` | `typography-sz-bm` (Body Medium - 14px) |
131-
| **Size (Title)** | `typography-sz-` | `ts`, `tm`, `tl` | `typography-sz-tl` (Title Large - 22px) |
132-
| **Size (Headline)** | `typography-sz-` | `hs`, `hm`, `hl` | `typography-sz-hl` (Headline Large - 32px) |
133-
| **Size (Display)** | `typography-sz-` | `ds`, `dm`, `dl` | `typography-sz-dl` (Display Large - 57px) |
134-
| **Align** | `typography-ta-` | `s` (Start), `c` (Center) | `typography-ta-c` |
135-
136-
### 4. Borders (`border-`)
137-
138-
**Source:** `styles/border.ts`
139-
140-
| Category | Prefix | Scale/Values | Examples |
141-
| :--------- | :----------- | :------------- | :---------------------------------------------------- |
142-
| **Radius** | `border-br-` | 0-24 (1 = 4px) | `border-br-4` (16px), `border-br-50pc` (50% / Circle) |
143-
| **Width** | `border-bw-` | 0-24 (Pixels) | `border-bw-1` (1px), `border-bw-2` (2px) |
144-
| **Style** | `border-bs-` | `s` (Solid) | `border-bs-s` |
145-
146-
### 5. Behavior & Opacity
147-
148-
**Source:** `styles/behavior.ts`, `styles/opacity.ts`
149-
150-
| Category | Prefix | Scale/Values | Examples |
151-
| :---------------- | :------------- | :------------------------------------- | :-------------------------------------- |
152-
| **Hover Opacity** | `behavior-ho-` | 0-100 (Step 5) | `behavior-ho-80` (Opacity 0.8 on hover) |
153-
| **Opacity** | `opacity-el-` | 0-100 (Step 5) | `opacity-el-50` (Opacity 0.5) |
154-
| **Overflow** | `behavior-o-` | `s` (Scroll), `a` (Auto), `h` (Hidden) | `behavior-o-h` |
155-
| **Scrollbar** | `behavior-sw-` | `n` (None) | `behavior-sw-n` |
156-
157-
### 6. Icons
158-
159-
**Source:** `styles/icons.ts`
160-
161-
- Class: `.g-icon`
162-
- Variants: `.filled`, `.filled-heavy`
163-
- Usage: `<span class="g-icon">icon_name</span>`
26+
- Application themes are defined using `CSSStyleSheet` instances. See:
27+
- [Restaurants theme](theme/restaurant-theme.ts)
28+
- These stylesheets override the default component CSS variables specified above,
29+
and change the look and feel of the generated UI.

0 commit comments

Comments
 (0)