Skip to content

Commit ed119d1

Browse files
committed
feat: add React renderer and sample clients
- Add @a2ui/react renderer with ShadCN-inspired Tailwind components - Implement core A2UI components: Text, Button, Card, Row, Column, List, etc. - Add A2UIProvider and ThemeProvider context providers - Add useA2UI and useDataBinding hooks for state management - Include 64 unit tests with full coverage - Add React sample clients: contact, restaurant, gallery, rizzcharts, orchestrator - Add a2a-chat-canvas component for chat interfaces
1 parent 3b98a43 commit ed119d1

File tree

147 files changed

+21115
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+21115
-0
lines changed

renderers/react/README.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# @a2ui/react
2+
3+
A React renderer for the A2UI protocol with ShadCN-style components and Tailwind CSS.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @a2ui/react
9+
```
10+
11+
### Peer Dependencies
12+
13+
This package requires the following peer dependencies:
14+
15+
```bash
16+
npm install react react-dom tailwindcss
17+
```
18+
19+
## Quick Start
20+
21+
### 1. Set up Tailwind CSS
22+
23+
Ensure your project has Tailwind CSS configured. Add the A2UI React components to your `tailwind.config.js`:
24+
25+
```js
26+
module.exports = {
27+
content: [
28+
// ... your content paths
29+
"./node_modules/@a2ui/react/**/*.{js,ts,jsx,tsx}",
30+
],
31+
// ... rest of config
32+
};
33+
```
34+
35+
### 2. Wrap your app with providers
36+
37+
```tsx
38+
import { A2UIProvider, ThemeProvider } from "@a2ui/react";
39+
40+
function App() {
41+
const handleAction = (action) => {
42+
// Send action to your server
43+
console.log("Action:", action);
44+
};
45+
46+
return (
47+
<A2UIProvider onAction={handleAction}>
48+
<ThemeProvider>
49+
<YourApp />
50+
</ThemeProvider>
51+
</A2UIProvider>
52+
);
53+
}
54+
```
55+
56+
### 3. Process messages and render
57+
58+
```tsx
59+
import { useA2UI, A2UIRenderer } from "@a2ui/react";
60+
import { useEffect } from "react";
61+
62+
function YourApp() {
63+
const { processMessages } = useA2UI();
64+
65+
useEffect(() => {
66+
// Fetch A2UI messages from your server
67+
fetch("/api/a2ui")
68+
.then((res) => res.json())
69+
.then((messages) => processMessages(messages));
70+
}, [processMessages]);
71+
72+
return <A2UIRenderer surfaceId="main" />;
73+
}
74+
```
75+
76+
## API Reference
77+
78+
### Providers
79+
80+
#### `<A2UIProvider>`
81+
82+
Main context provider for A2UI state management.
83+
84+
```tsx
85+
<A2UIProvider onAction={(action) => console.log(action)}>
86+
{children}
87+
</A2UIProvider>
88+
```
89+
90+
Props:
91+
- `onAction`: Callback when user triggers an action (e.g., button click)
92+
- `children`: React children
93+
94+
#### `<ThemeProvider>`
95+
96+
Provides CSS class mappings for styling components.
97+
98+
```tsx
99+
<ThemeProvider theme={customTheme}>
100+
{children}
101+
</ThemeProvider>
102+
```
103+
104+
Props:
105+
- `theme`: Optional custom theme object (defaults to ShadCN-style theme)
106+
- `children`: React children
107+
108+
### Hooks
109+
110+
#### `useA2UI()`
111+
112+
Main hook for interacting with A2UI.
113+
114+
```tsx
115+
const {
116+
surfaces, // Map of all surfaces
117+
getSurface, // Get a specific surface
118+
processMessages, // Process incoming A2UI messages
119+
sendAction, // Send an action to the server
120+
getComponentTree, // Get the root component tree for a surface
121+
clearSurfaces, // Clear all surfaces
122+
} = useA2UI();
123+
```
124+
125+
#### `useDataBinding(node, surfaceId)`
126+
127+
Hook for resolving data bindings in custom components.
128+
129+
```tsx
130+
const {
131+
resolveString, // Resolve a StringValue
132+
resolveNumber, // Resolve a NumberValue
133+
resolveBoolean, // Resolve a BooleanValue
134+
setValue, // Set a value in the data model
135+
getValue, // Get a value from the data model
136+
} = useDataBinding(node, surfaceId);
137+
```
138+
139+
### Components
140+
141+
#### `<A2UIRenderer>`
142+
143+
Main renderer component that renders an entire A2UI surface.
144+
145+
```tsx
146+
<A2UIRenderer
147+
surfaceId="main"
148+
className="my-surface"
149+
fallback={<Loading />}
150+
/>
151+
```
152+
153+
Props:
154+
- `surfaceId`: The ID of the surface to render
155+
- `className`: Optional CSS class for the root element
156+
- `fallback`: Optional fallback when surface is not found
157+
158+
### Standard Components
159+
160+
All 18 standard A2UI components are implemented:
161+
162+
**Content:**
163+
- `Text` - Text with markdown support and typography hints
164+
- `Image` - Images with fit and usage hints
165+
- `Icon` - Icons from Lucide React
166+
- `Video` - Video player
167+
- `AudioPlayer` - Audio player with description
168+
- `Divider` - Horizontal/vertical separator
169+
170+
**Layout:**
171+
- `Row` - Horizontal flex container
172+
- `Column` - Vertical flex container
173+
- `List` - Scrollable list (horizontal/vertical)
174+
- `Card` - Card container
175+
- `Tabs` - Tab navigation
176+
- `Modal` - Modal dialog
177+
178+
**Interactive:**
179+
- `Button` - Clickable button with action support
180+
- `CheckBox` - Checkbox with label
181+
- `TextField` - Text input (various types)
182+
- `DateTimeInput` - Date/time picker
183+
- `MultipleChoice` - Select dropdown
184+
- `Slider` - Range slider
185+
186+
## Custom Theming
187+
188+
You can customize the appearance by providing a custom theme:
189+
190+
```tsx
191+
import { ThemeProvider, defaultTheme } from "@a2ui/react";
192+
193+
const customTheme = {
194+
...defaultTheme,
195+
components: {
196+
...defaultTheme.components,
197+
Button: {
198+
"bg-blue-500": true,
199+
"text-white": true,
200+
"px-4": true,
201+
"py-2": true,
202+
"rounded": true,
203+
},
204+
},
205+
};
206+
207+
<ThemeProvider theme={customTheme}>
208+
{children}
209+
</ThemeProvider>
210+
```
211+
212+
## Streaming Messages
213+
214+
For streaming A2UI messages (e.g., from Server-Sent Events):
215+
216+
```tsx
217+
function StreamingApp() {
218+
const { processMessages } = useA2UI();
219+
220+
useEffect(() => {
221+
const eventSource = new EventSource("/api/a2ui/stream");
222+
223+
eventSource.onmessage = (event) => {
224+
const message = JSON.parse(event.data);
225+
processMessages([message]);
226+
};
227+
228+
return () => eventSource.close();
229+
}, [processMessages]);
230+
231+
return <A2UIRenderer surfaceId="main" />;
232+
}
233+
```
234+
235+
## TypeScript
236+
237+
This package is written in TypeScript and includes full type definitions. Types are re-exported from `@a2ui/lit`:
238+
239+
```tsx
240+
import { Types, Primitives, Data } from "@a2ui/react";
241+
242+
// Use types
243+
const surface: Types.Surface = ...;
244+
const message: Types.ServerToClientMessage = ...;
245+
```
246+
247+
## License
248+
249+
Apache-2.0

0 commit comments

Comments
 (0)