@easyops-cn/a2ui-react 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/speckit.analyze.md +184 -0
- package/.claude/commands/speckit.checklist.md +294 -0
- package/.claude/commands/speckit.clarify.md +181 -0
- package/.claude/commands/speckit.constitution.md +82 -0
- package/.claude/commands/speckit.implement.md +135 -0
- package/.claude/commands/speckit.plan.md +89 -0
- package/.claude/commands/speckit.specify.md +256 -0
- package/.claude/commands/speckit.tasks.md +137 -0
- package/.claude/commands/speckit.taskstoissues.md +30 -0
- package/.github/workflows/deploy.yml +69 -0
- package/.husky/pre-commit +1 -0
- package/.prettierignore +4 -0
- package/.prettierrc +7 -0
- package/.specify/memory/constitution.md +73 -0
- package/.specify/scripts/bash/check-prerequisites.sh +166 -0
- package/.specify/scripts/bash/common.sh +156 -0
- package/.specify/scripts/bash/create-new-feature.sh +297 -0
- package/.specify/scripts/bash/setup-plan.sh +61 -0
- package/.specify/scripts/bash/update-agent-context.sh +799 -0
- package/.specify/templates/agent-file-template.md +28 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/plan-template.md +105 -0
- package/.specify/templates/spec-template.md +115 -0
- package/.specify/templates/tasks-template.md +250 -0
- package/CLAUDE.md +105 -0
- package/CONTRIBUTING.md +97 -0
- package/README.md +126 -0
- package/components.json +21 -0
- package/eslint.config.js +25 -0
- package/netlify.toml +50 -0
- package/package.json +94 -0
- package/playground/README.md +75 -0
- package/playground/index.html +22 -0
- package/playground/package.json +32 -0
- package/playground/public/favicon.svg +8 -0
- package/playground/src/App.css +256 -0
- package/playground/src/App.tsx +115 -0
- package/playground/src/assets/react.svg +1 -0
- package/playground/src/components/ErrorDisplay.tsx +13 -0
- package/playground/src/components/ExampleSelector.tsx +64 -0
- package/playground/src/components/Header.tsx +47 -0
- package/playground/src/components/JsonEditor.tsx +32 -0
- package/playground/src/components/Preview.tsx +78 -0
- package/playground/src/components/ThemeToggle.tsx +19 -0
- package/playground/src/data/examples.ts +1571 -0
- package/playground/src/hooks/useTheme.ts +55 -0
- package/playground/src/index.css +220 -0
- package/playground/src/main.tsx +10 -0
- package/playground/tsconfig.app.json +34 -0
- package/playground/tsconfig.json +13 -0
- package/playground/tsconfig.node.json +26 -0
- package/playground/vite.config.ts +31 -0
- package/specs/001-a2ui-renderer/checklists/requirements.md +41 -0
- package/specs/001-a2ui-renderer/data-model.md +140 -0
- package/specs/001-a2ui-renderer/plan.md +123 -0
- package/specs/001-a2ui-renderer/quickstart.md +141 -0
- package/specs/001-a2ui-renderer/research.md +140 -0
- package/specs/001-a2ui-renderer/spec.md +165 -0
- package/specs/001-a2ui-renderer/tasks.md +310 -0
- package/specs/002-playground/checklists/requirements.md +37 -0
- package/specs/002-playground/contracts/components.md +120 -0
- package/specs/002-playground/data-model.md +149 -0
- package/specs/002-playground/plan.md +73 -0
- package/specs/002-playground/quickstart.md +158 -0
- package/specs/002-playground/research.md +117 -0
- package/specs/002-playground/spec.md +109 -0
- package/specs/002-playground/tasks.md +224 -0
- package/src/0.8/A2UIRender.test.tsx +793 -0
- package/src/0.8/A2UIRender.tsx +142 -0
- package/src/0.8/components/ComponentRenderer.test.tsx +373 -0
- package/src/0.8/components/ComponentRenderer.tsx +163 -0
- package/src/0.8/components/UnknownComponent.tsx +49 -0
- package/src/0.8/components/display/AudioPlayerComponent.tsx +37 -0
- package/src/0.8/components/display/DividerComponent.tsx +23 -0
- package/src/0.8/components/display/IconComponent.tsx +137 -0
- package/src/0.8/components/display/ImageComponent.tsx +57 -0
- package/src/0.8/components/display/TextComponent.tsx +56 -0
- package/src/0.8/components/display/VideoComponent.tsx +31 -0
- package/src/0.8/components/display/display.test.tsx +660 -0
- package/src/0.8/components/display/index.ts +10 -0
- package/src/0.8/components/index.ts +14 -0
- package/src/0.8/components/interactive/ButtonComponent.tsx +44 -0
- package/src/0.8/components/interactive/CheckBoxComponent.tsx +45 -0
- package/src/0.8/components/interactive/DateTimeInputComponent.tsx +176 -0
- package/src/0.8/components/interactive/MultipleChoiceComponent.tsx +157 -0
- package/src/0.8/components/interactive/SliderComponent.tsx +53 -0
- package/src/0.8/components/interactive/TextFieldComponent.tsx +65 -0
- package/src/0.8/components/interactive/index.ts +10 -0
- package/src/0.8/components/interactive/interactive.test.tsx +618 -0
- package/src/0.8/components/layout/CardComponent.tsx +30 -0
- package/src/0.8/components/layout/ColumnComponent.tsx +93 -0
- package/src/0.8/components/layout/ListComponent.tsx +81 -0
- package/src/0.8/components/layout/ModalComponent.tsx +41 -0
- package/src/0.8/components/layout/RowComponent.tsx +94 -0
- package/src/0.8/components/layout/TabsComponent.tsx +59 -0
- package/src/0.8/components/layout/index.ts +10 -0
- package/src/0.8/components/layout/layout.test.tsx +558 -0
- package/src/0.8/contexts/A2UIProvider.test.tsx +226 -0
- package/src/0.8/contexts/A2UIProvider.tsx +54 -0
- package/src/0.8/contexts/ActionContext.test.tsx +242 -0
- package/src/0.8/contexts/ActionContext.tsx +105 -0
- package/src/0.8/contexts/ComponentsMapContext.tsx +125 -0
- package/src/0.8/contexts/DataModelContext.test.tsx +335 -0
- package/src/0.8/contexts/DataModelContext.tsx +184 -0
- package/src/0.8/contexts/SurfaceContext.test.tsx +339 -0
- package/src/0.8/contexts/SurfaceContext.tsx +197 -0
- package/src/0.8/hooks/useA2UIMessageHandler.test.tsx +399 -0
- package/src/0.8/hooks/useA2UIMessageHandler.ts +123 -0
- package/src/0.8/hooks/useComponent.test.tsx +148 -0
- package/src/0.8/hooks/useComponent.ts +39 -0
- package/src/0.8/hooks/useDataBinding.test.tsx +334 -0
- package/src/0.8/hooks/useDataBinding.ts +99 -0
- package/src/0.8/hooks/useDispatchAction.test.tsx +83 -0
- package/src/0.8/hooks/useDispatchAction.ts +35 -0
- package/src/0.8/hooks/useSurface.test.tsx +114 -0
- package/src/0.8/hooks/useSurface.ts +34 -0
- package/src/0.8/index.ts +38 -0
- package/src/0.8/schemas/client_to_server.json +50 -0
- package/src/0.8/schemas/server_to_client.json +148 -0
- package/src/0.8/schemas/standard_catalog_definition.json +661 -0
- package/src/0.8/types/index.ts +448 -0
- package/src/0.8/utils/dataBinding.test.ts +443 -0
- package/src/0.8/utils/dataBinding.ts +212 -0
- package/src/0.8/utils/pathUtils.test.ts +353 -0
- package/src/0.8/utils/pathUtils.ts +200 -0
- package/src/components/ui/button.tsx +62 -0
- package/src/components/ui/calendar.tsx +220 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/dialog.tsx +141 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +22 -0
- package/src/components/ui/native-select.tsx +53 -0
- package/src/components/ui/popover.tsx +46 -0
- package/src/components/ui/select.tsx +188 -0
- package/src/components/ui/separator.tsx +26 -0
- package/src/components/ui/slider.tsx +61 -0
- package/src/components/ui/tabs.tsx +64 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/index.ts +1 -0
- package/src/lib/utils.ts +6 -0
- package/tsconfig.json +28 -0
- package/vite.config.ts +29 -0
- package/vitest.config.ts +22 -0
- package/vitest.setup.ts +8 -0
- package/website/README.md +4 -0
- package/website/assets/favicon.svg +8 -0
- package/website/content/.gitkeep +0 -0
- package/website/content/index.md +122 -0
- package/website/global.d.ts +9 -0
- package/website/package.json +17 -0
- package/website/plain.config.js +28 -0
- package/website/serve.json +6 -0
- package/website/src/client/color-mode-switch.css +47 -0
- package/website/src/client/index.js +61 -0
- package/website/src/client/moon.svg +1 -0
- package/website/src/client/sun.svg +1 -0
- package/website/src/components/Footer.jsx +9 -0
- package/website/src/components/Header.jsx +44 -0
- package/website/src/components/Page.jsx +28 -0
- package/website/src/global.css +423 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Quickstart: A2UI Playground Development
|
|
2
|
+
|
|
3
|
+
**Feature**: 002-playground
|
|
4
|
+
**Date**: 2026-01-10
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
- Node.js 18+
|
|
9
|
+
- npm 9+
|
|
10
|
+
- Repository cloned with dependencies installed (`npm install` at root)
|
|
11
|
+
|
|
12
|
+
## Development Setup
|
|
13
|
+
|
|
14
|
+
### 1. Install Playground Dependencies
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# From repository root
|
|
18
|
+
npm install -w playground @uiw/react-codemirror @codemirror/lang-json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Link Main Library
|
|
22
|
+
|
|
23
|
+
The playground uses the main `@easyops-cn/a2ui-react` library as a workspace dependency. Ensure the library is built:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Build the main library
|
|
27
|
+
npm run build
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 3. Start Development Server
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Start playground dev server
|
|
34
|
+
npm run dev -w playground
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The playground will be available at `http://localhost:5173` (or next available port).
|
|
38
|
+
|
|
39
|
+
## Project Structure
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
playground/src/
|
|
43
|
+
├── components/ # React components
|
|
44
|
+
│ ├── Header.tsx # App header with title and theme toggle
|
|
45
|
+
│ ├── ThemeToggle.tsx # Sun/moon theme switch
|
|
46
|
+
│ ├── JsonEditor.tsx # CodeMirror JSON editor
|
|
47
|
+
│ ├── Preview.tsx # A2UIRender wrapper
|
|
48
|
+
│ ├── ExampleSelector.tsx # Example dropdown
|
|
49
|
+
│ └── ErrorDisplay.tsx # Error state component
|
|
50
|
+
├── data/
|
|
51
|
+
│ └── examples.ts # Pre-built A2UI examples
|
|
52
|
+
├── hooks/
|
|
53
|
+
│ └── useTheme.ts # Theme state hook
|
|
54
|
+
├── App.tsx # Main application
|
|
55
|
+
├── App.css # Layout styles
|
|
56
|
+
├── main.tsx # Entry point
|
|
57
|
+
└── index.css # Global/Tailwind styles
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Key Implementation Notes
|
|
61
|
+
|
|
62
|
+
### Theme System
|
|
63
|
+
|
|
64
|
+
The playground uses the same theme approach as the website:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// Set theme via data attribute
|
|
68
|
+
document.documentElement.dataset.theme = 'dark' // or 'light'
|
|
69
|
+
|
|
70
|
+
// CSS variables respond to theme
|
|
71
|
+
html[data-theme='dark'] {
|
|
72
|
+
--background-color: hsl(230, 25%, 18%);
|
|
73
|
+
--text-color: hsl(210, 50%, 96%);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### JSON Editor Integration
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import CodeMirror from '@uiw/react-codemirror'
|
|
81
|
+
import { json } from '@codemirror/lang-json'
|
|
82
|
+
|
|
83
|
+
<CodeMirror
|
|
84
|
+
value={jsonContent}
|
|
85
|
+
extensions={[json()]}
|
|
86
|
+
onChange={(value) => setJsonContent(value)}
|
|
87
|
+
/>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### A2UIRender Integration
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { A2UIRender, type A2UIMessage } from '@easyops-cn/a2ui-react/0.8'
|
|
94
|
+
|
|
95
|
+
// Parse JSON and render
|
|
96
|
+
const messages: A2UIMessage[] = JSON.parse(jsonContent)
|
|
97
|
+
<A2UIRender messages={messages} onAction={handleAction} />
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Error Boundary Pattern
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
class ErrorBoundary extends React.Component {
|
|
104
|
+
state = { hasError: false, error: null }
|
|
105
|
+
|
|
106
|
+
static getDerivedStateFromError(error) {
|
|
107
|
+
return { hasError: true, error }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
render() {
|
|
111
|
+
if (this.state.hasError) {
|
|
112
|
+
return <ErrorDisplay error={this.state.error} />
|
|
113
|
+
}
|
|
114
|
+
return this.props.children
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Testing
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Run tests (from root)
|
|
123
|
+
npm test -w playground
|
|
124
|
+
|
|
125
|
+
# Run specific test file
|
|
126
|
+
npm test -w playground -- JsonEditor.test.tsx
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Building for Production
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Build playground
|
|
133
|
+
npm run build -w playground
|
|
134
|
+
|
|
135
|
+
# Preview production build
|
|
136
|
+
npm run preview -w playground
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Output will be in `playground/dist/`.
|
|
140
|
+
|
|
141
|
+
## Common Tasks
|
|
142
|
+
|
|
143
|
+
### Adding a New Example
|
|
144
|
+
|
|
145
|
+
1. Edit `playground/src/data/examples.ts`
|
|
146
|
+
2. Add new example object with `id`, `title`, `description`, and `messages`
|
|
147
|
+
3. The example will automatically appear in the dropdown
|
|
148
|
+
|
|
149
|
+
### Modifying Theme Colors
|
|
150
|
+
|
|
151
|
+
1. Edit `playground/src/App.css` or `playground/src/index.css`
|
|
152
|
+
2. Update CSS custom properties for light/dark themes
|
|
153
|
+
3. Match website colors from `website/src/global.css`
|
|
154
|
+
|
|
155
|
+
### Updating CodeMirror Theme
|
|
156
|
+
|
|
157
|
+
1. Import desired theme: `import { oneDark } from '@codemirror/theme-one-dark'`
|
|
158
|
+
2. Add to extensions array: `extensions={[json(), oneDark]}`
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Research: A2UI Playground
|
|
2
|
+
|
|
3
|
+
**Feature**: 002-playground
|
|
4
|
+
**Date**: 2026-01-10
|
|
5
|
+
|
|
6
|
+
## JSON Editor Library Selection
|
|
7
|
+
|
|
8
|
+
### Decision
|
|
9
|
+
|
|
10
|
+
**CodeMirror 6** via `@uiw/react-codemirror` wrapper
|
|
11
|
+
|
|
12
|
+
### Rationale
|
|
13
|
+
|
|
14
|
+
- **Bundle size**: ~40-150KB gzipped (vs Monaco's 500KB+)
|
|
15
|
+
- **Performance**: Designed for real-time editing, used by Replit in production
|
|
16
|
+
- **React integration**: Clean wrapper with `@uiw/react-codemirror`
|
|
17
|
+
- **JSON support**: Official `@codemirror/lang-json` package with syntax highlighting
|
|
18
|
+
- **Modular**: Only include needed features
|
|
19
|
+
|
|
20
|
+
### Alternatives Considered
|
|
21
|
+
|
|
22
|
+
| Option | Bundle Size | Verdict |
|
|
23
|
+
| ------------------------ | ----------- | ------------------------------------ |
|
|
24
|
+
| Monaco Editor | 500KB+ | Too heavy for playground use case |
|
|
25
|
+
| Prism.js | 10-50KB | Read-only, no editing capability |
|
|
26
|
+
| react-simple-code-editor | ~5KB | Limited features, no JSON validation |
|
|
27
|
+
|
|
28
|
+
### Required Packages
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
@uiw/react-codemirror
|
|
32
|
+
@codemirror/lang-json
|
|
33
|
+
@codemirror/theme-one-dark (for dark mode)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Theme Implementation
|
|
37
|
+
|
|
38
|
+
### Decision
|
|
39
|
+
|
|
40
|
+
Reuse website's theme approach with `data-theme` attribute on `<html>` element
|
|
41
|
+
|
|
42
|
+
### Rationale
|
|
43
|
+
|
|
44
|
+
- Consistent with existing website implementation
|
|
45
|
+
- Uses CSS custom properties for theming
|
|
46
|
+
- localStorage persistence already proven pattern
|
|
47
|
+
- Sun/moon icons from lucide-react (already in main library dependencies)
|
|
48
|
+
|
|
49
|
+
### Implementation Pattern
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Theme stored in localStorage as 'theme' key
|
|
53
|
+
// Values: 'light' | 'dark'
|
|
54
|
+
// Applied via: document.documentElement.dataset.theme = theme
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## A2UI Library Integration
|
|
58
|
+
|
|
59
|
+
### Decision
|
|
60
|
+
|
|
61
|
+
Import from workspace dependency `@easyops-cn/a2ui-react/0.8`
|
|
62
|
+
|
|
63
|
+
### Rationale
|
|
64
|
+
|
|
65
|
+
- Playground is in same monorepo as library
|
|
66
|
+
- Vite workspace alias already configured
|
|
67
|
+
- Direct import ensures latest library version during development
|
|
68
|
+
|
|
69
|
+
### Integration Pattern
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { A2UIRender, type A2UIMessage } from '@easyops-cn/a2ui-react/0.8'
|
|
73
|
+
|
|
74
|
+
// Parse JSON string to A2UIMessage[]
|
|
75
|
+
// Pass to A2UIRender component
|
|
76
|
+
// Handle parse errors gracefully
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Example Categories
|
|
80
|
+
|
|
81
|
+
### Decision
|
|
82
|
+
|
|
83
|
+
Include 5 examples covering core A2UI capabilities
|
|
84
|
+
|
|
85
|
+
### Examples
|
|
86
|
+
|
|
87
|
+
1. **Hello World** - Basic Text component
|
|
88
|
+
2. **Layout Demo** - Column/Row with multiple children
|
|
89
|
+
3. **Button Actions** - Interactive Button with action handling
|
|
90
|
+
4. **Form Inputs** - TextField, Checkbox, Select components
|
|
91
|
+
5. **Data Binding** - Components with ValueSource path bindings
|
|
92
|
+
|
|
93
|
+
### Rationale
|
|
94
|
+
|
|
95
|
+
- Covers all component categories (display, layout, interactive)
|
|
96
|
+
- Progressive complexity for learning
|
|
97
|
+
- Demonstrates key A2UI concepts (actions, data binding)
|
|
98
|
+
|
|
99
|
+
## Error Handling
|
|
100
|
+
|
|
101
|
+
### Decision
|
|
102
|
+
|
|
103
|
+
Use React Error Boundary for preview panel with graceful fallback
|
|
104
|
+
|
|
105
|
+
### Rationale
|
|
106
|
+
|
|
107
|
+
- Prevents entire app crash on render errors
|
|
108
|
+
- Shows user-friendly error message
|
|
109
|
+
- Allows continued editing after errors
|
|
110
|
+
|
|
111
|
+
### Implementation Pattern
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// ErrorBoundary wraps A2UIRender
|
|
115
|
+
// Catches render errors, displays ErrorDisplay component
|
|
116
|
+
// JSON parse errors handled separately before render
|
|
117
|
+
```
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Feature Specification: A2UI Playground
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `002-playground`
|
|
4
|
+
**Created**: 2026-01-10
|
|
5
|
+
**Status**: Draft
|
|
6
|
+
**Input**: User description: "实现 playground,顶栏和 website 现在的 header 一致,包括标题和切换深/浅主题图标;内容区左侧为 json 编辑器,右侧为 A2UIRenderer 的实时预览;同时提供一些常见场景的示例作为 select 项"
|
|
7
|
+
|
|
8
|
+
## Clarifications
|
|
9
|
+
|
|
10
|
+
### Session 2026-01-10
|
|
11
|
+
|
|
12
|
+
- Q: What should users see when they first load the playground? → A: Load with first example pre-selected (editor populated, preview showing)
|
|
13
|
+
|
|
14
|
+
## User Scenarios & Testing _(mandatory)_
|
|
15
|
+
|
|
16
|
+
### User Story 1 - Live JSON Editing with Preview (Priority: P1)
|
|
17
|
+
|
|
18
|
+
A developer wants to experiment with A2UI message structures by editing JSON and seeing the rendered result immediately. They open the playground, type or paste A2UI JSON messages in the left editor panel, and see the corresponding UI rendered in real-time on the right panel.
|
|
19
|
+
|
|
20
|
+
**Why this priority**: This is the core value proposition of the playground - enabling rapid prototyping and learning of A2UI message structures without setting up a full development environment.
|
|
21
|
+
|
|
22
|
+
**Independent Test**: Can be fully tested by entering valid A2UI JSON and verifying the preview updates. Delivers immediate value for developers learning the A2UI protocol.
|
|
23
|
+
|
|
24
|
+
**Acceptance Scenarios**:
|
|
25
|
+
|
|
26
|
+
1. **Given** the playground is loaded, **When** a user types valid A2UI JSON in the editor, **Then** the preview panel displays the rendered components in real-time
|
|
27
|
+
2. **Given** valid JSON is in the editor, **When** the user modifies the JSON, **Then** the preview updates automatically without requiring manual refresh
|
|
28
|
+
3. **Given** invalid JSON is in the editor, **When** the user views the preview, **Then** the preview shows an appropriate error state without crashing
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### User Story 2 - Example Selection (Priority: P2)
|
|
33
|
+
|
|
34
|
+
A developer new to A2UI wants to learn by example. They select a pre-built example from a dropdown menu, which populates the JSON editor with a working A2UI message structure and displays the rendered result.
|
|
35
|
+
|
|
36
|
+
**Why this priority**: Examples accelerate learning and provide starting points for customization, but the core editing functionality must work first.
|
|
37
|
+
|
|
38
|
+
**Independent Test**: Can be tested by selecting each example from the dropdown and verifying both the JSON editor content and preview update correctly.
|
|
39
|
+
|
|
40
|
+
**Acceptance Scenarios**:
|
|
41
|
+
|
|
42
|
+
1. **Given** the playground is loaded, **When** a user selects an example from the dropdown, **Then** the JSON editor is populated with the example's A2UI messages
|
|
43
|
+
2. **Given** an example is selected, **When** the JSON editor is populated, **Then** the preview panel displays the rendered example
|
|
44
|
+
3. **Given** multiple examples exist, **When** a user switches between examples, **Then** both the editor and preview update to reflect the newly selected example
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### User Story 3 - Theme Switching (Priority: P3)
|
|
49
|
+
|
|
50
|
+
A developer wants to test how their A2UI components look in both light and dark modes. They click the theme toggle icon in the header to switch between light and dark themes, and the entire playground (including the preview) updates accordingly.
|
|
51
|
+
|
|
52
|
+
**Why this priority**: Theme consistency with the website is important for brand coherence, but it's a secondary concern after core functionality.
|
|
53
|
+
|
|
54
|
+
**Independent Test**: Can be tested by clicking the theme toggle and verifying the visual appearance changes for both the playground chrome and the preview area.
|
|
55
|
+
|
|
56
|
+
**Acceptance Scenarios**:
|
|
57
|
+
|
|
58
|
+
1. **Given** the playground is in light mode, **When** a user clicks the theme toggle, **Then** the playground switches to dark mode
|
|
59
|
+
2. **Given** the playground is in dark mode, **When** a user clicks the theme toggle, **Then** the playground switches to light mode
|
|
60
|
+
3. **Given** a theme preference is set, **When** the user returns to the playground later, **Then** the previously selected theme is restored
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### Edge Cases
|
|
65
|
+
|
|
66
|
+
- What happens when the JSON editor contains empty content? The preview should show an empty state.
|
|
67
|
+
- How does the system handle extremely large JSON payloads? The editor should remain responsive with reasonable-sized inputs (up to 100KB).
|
|
68
|
+
- What happens when the browser window is resized? The layout should adapt responsively, maintaining usability on different screen sizes.
|
|
69
|
+
- What happens when a user modifies an example after selecting it? The changes should be preserved until a new example is selected.
|
|
70
|
+
|
|
71
|
+
## Requirements _(mandatory)_
|
|
72
|
+
|
|
73
|
+
### Functional Requirements
|
|
74
|
+
|
|
75
|
+
- **FR-001**: System MUST display a header with the title "A2UI React Renderer" matching the website header design
|
|
76
|
+
- **FR-002**: System MUST provide a theme toggle icon (sun/moon) in the header that switches between light and dark modes
|
|
77
|
+
- **FR-003**: System MUST persist theme preference across browser sessions using localStorage
|
|
78
|
+
- **FR-004**: System MUST display a split-panel layout with JSON editor on the left and preview on the right
|
|
79
|
+
- **FR-005**: System MUST render A2UI components in the preview panel based on the JSON editor content
|
|
80
|
+
- **FR-006**: System MUST update the preview automatically when the JSON editor content changes
|
|
81
|
+
- **FR-007**: System MUST provide a dropdown/select control to choose from pre-built examples
|
|
82
|
+
- **FR-008**: System MUST include examples covering common A2UI scenarios: basic text display, layout containers, interactive buttons, form inputs, and data binding
|
|
83
|
+
- **FR-009**: System MUST display a clear error state in the preview when JSON is invalid or cannot be rendered
|
|
84
|
+
- **FR-010**: System MUST maintain responsive layout that works on screens 1024px wide and above
|
|
85
|
+
- **FR-011**: System MUST load with the first example pre-selected, showing populated editor and rendered preview on initial page load
|
|
86
|
+
|
|
87
|
+
### Key Entities
|
|
88
|
+
|
|
89
|
+
- **A2UI Messages**: Array of message objects following the A2UI protocol (beginRendering, surfaceUpdate, dataModelUpdate)
|
|
90
|
+
- **Example**: A named preset containing a title, description, and pre-configured A2UI messages array
|
|
91
|
+
- **Theme**: User preference for light or dark color scheme, stored in localStorage
|
|
92
|
+
|
|
93
|
+
## Success Criteria _(mandatory)_
|
|
94
|
+
|
|
95
|
+
### Measurable Outcomes
|
|
96
|
+
|
|
97
|
+
- **SC-001**: Users can see preview updates within 500ms of making JSON edits
|
|
98
|
+
- **SC-002**: All provided examples render correctly without errors
|
|
99
|
+
- **SC-003**: Theme toggle persists preference and applies consistently across the entire interface
|
|
100
|
+
- **SC-004**: Playground loads and becomes interactive within 3 seconds on standard broadband connection
|
|
101
|
+
- **SC-005**: 90% of first-time users can successfully modify an example and see the result without external documentation
|
|
102
|
+
|
|
103
|
+
## Assumptions
|
|
104
|
+
|
|
105
|
+
- The playground targets desktop users with screens 1024px or wider; mobile optimization is out of scope
|
|
106
|
+
- Users have basic familiarity with JSON syntax
|
|
107
|
+
- The A2UIRenderer component from the main library is stable and can be used directly
|
|
108
|
+
- Examples will be hardcoded initially; dynamic example loading is out of scope
|
|
109
|
+
- The JSON editor will use a standard code editor component with syntax highlighting (specific library choice is an implementation detail)
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Tasks: A2UI Playground
|
|
2
|
+
|
|
3
|
+
**Input**: Design documents from `/specs/002-playground/`
|
|
4
|
+
**Prerequisites**: plan.md, spec.md, research.md, data-model.md
|
|
5
|
+
|
|
6
|
+
**Tests**: Not explicitly requested in specification. Test tasks omitted.
|
|
7
|
+
|
|
8
|
+
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
|
|
9
|
+
|
|
10
|
+
## Format: `[ID] [P?] [Story] Description`
|
|
11
|
+
|
|
12
|
+
- **[P]**: Can run in parallel (different files, no dependencies)
|
|
13
|
+
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
|
|
14
|
+
- Include exact file paths in descriptions
|
|
15
|
+
|
|
16
|
+
## Path Conventions
|
|
17
|
+
|
|
18
|
+
Based on plan.md, the playground is a workspace within the monorepo:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
playground/
|
|
22
|
+
├── src/
|
|
23
|
+
│ ├── components/ # React components
|
|
24
|
+
│ ├── data/ # Example data
|
|
25
|
+
│ ├── hooks/ # Custom hooks
|
|
26
|
+
│ ├── App.tsx # Main application
|
|
27
|
+
│ └── ...
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Phase 1: Setup (Shared Infrastructure)
|
|
33
|
+
|
|
34
|
+
**Purpose**: Project initialization and dependency installation
|
|
35
|
+
|
|
36
|
+
- [x] T001 Install CodeMirror dependencies: `npm install -w playground @uiw/react-codemirror @codemirror/lang-json`
|
|
37
|
+
- [x] T002 Install lucide-react for icons: `npm install -w playground lucide-react`
|
|
38
|
+
- [x] T003 Configure Vite to resolve @easyops-cn/a2ui-react workspace dependency in playground/vite.config.ts
|
|
39
|
+
- [x] T004 [P] Create components directory structure in playground/src/components/
|
|
40
|
+
- [x] T005 [P] Create data directory structure in playground/src/data/
|
|
41
|
+
- [x] T006 [P] Create hooks directory structure in playground/src/hooks/
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Phase 2: Foundational (Blocking Prerequisites)
|
|
46
|
+
|
|
47
|
+
**Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented
|
|
48
|
+
|
|
49
|
+
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
|
|
50
|
+
|
|
51
|
+
- [x] T007 Create Example type definition in playground/src/data/examples.ts (interface only, no data yet)
|
|
52
|
+
- [x] T008 Create ErrorDisplay component for showing error messages in playground/src/components/ErrorDisplay.tsx
|
|
53
|
+
- [x] T009 Setup global CSS with theme variables (light/dark) matching website in playground/src/index.css
|
|
54
|
+
- [x] T010 Update playground/index.html with proper title and theme initialization script
|
|
55
|
+
|
|
56
|
+
**Checkpoint**: Foundation ready - user story implementation can now begin
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Phase 3: User Story 1 - Live JSON Editing with Preview (Priority: P1) 🎯 MVP
|
|
61
|
+
|
|
62
|
+
**Goal**: Enable developers to edit A2UI JSON and see real-time rendered preview
|
|
63
|
+
|
|
64
|
+
**Independent Test**: Enter valid A2UI JSON in editor, verify preview updates within 500ms. Enter invalid JSON, verify error state displays without crash.
|
|
65
|
+
|
|
66
|
+
### Implementation for User Story 1
|
|
67
|
+
|
|
68
|
+
- [x] T011 [P] [US1] Create JsonEditor component with CodeMirror integration in playground/src/components/JsonEditor.tsx
|
|
69
|
+
- [x] T012 [P] [US1] Create Preview component wrapping A2UIRender with error boundary in playground/src/components/Preview.tsx
|
|
70
|
+
- [x] T013 [US1] Create split-panel layout in playground/src/App.tsx with editor (left) and preview (right)
|
|
71
|
+
- [x] T014 [US1] Add layout styles for split-panel (50/50) in playground/src/App.css
|
|
72
|
+
- [x] T015 [US1] Implement JSON parsing with error handling in App.tsx (parse on change, update preview or show error)
|
|
73
|
+
- [x] T016 [US1] Add action handler to log dispatched actions to console in App.tsx
|
|
74
|
+
|
|
75
|
+
**Checkpoint**: User Story 1 complete - can edit JSON and see live preview with error handling
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Phase 4: User Story 2 - Example Selection (Priority: P2)
|
|
80
|
+
|
|
81
|
+
**Goal**: Provide pre-built examples that populate the editor and preview
|
|
82
|
+
|
|
83
|
+
**Independent Test**: Select each example from dropdown, verify editor content and preview both update correctly.
|
|
84
|
+
|
|
85
|
+
### Implementation for User Story 2
|
|
86
|
+
|
|
87
|
+
- [x] T017 [P] [US2] Create "Hello World" example (basic Text component) in playground/src/data/examples.ts
|
|
88
|
+
- [x] T018 [P] [US2] Create "Layout Demo" example (Column/Row with children) in playground/src/data/examples.ts
|
|
89
|
+
- [x] T019 [P] [US2] Create "Button Actions" example (Button with action) in playground/src/data/examples.ts
|
|
90
|
+
- [x] T020 [P] [US2] Create "Form Inputs" example (TextField, Checkbox) in playground/src/data/examples.ts
|
|
91
|
+
- [x] T021 [P] [US2] Create "Data Binding" example (ValueSource path bindings) in playground/src/data/examples.ts
|
|
92
|
+
- [x] T022 [US2] Create ExampleSelector dropdown component in playground/src/components/ExampleSelector.tsx
|
|
93
|
+
- [x] T023 [US2] Integrate ExampleSelector into App.tsx (place above editor, wire up selection handler)
|
|
94
|
+
- [x] T024 [US2] Implement initial load with first example pre-selected in App.tsx
|
|
95
|
+
|
|
96
|
+
**Checkpoint**: User Story 2 complete - can select examples and see them populate editor/preview
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Phase 5: User Story 3 - Theme Switching (Priority: P3)
|
|
101
|
+
|
|
102
|
+
**Goal**: Allow switching between light and dark themes with persistence
|
|
103
|
+
|
|
104
|
+
**Independent Test**: Click theme toggle, verify entire UI switches theme. Refresh page, verify theme persists.
|
|
105
|
+
|
|
106
|
+
### Implementation for User Story 3
|
|
107
|
+
|
|
108
|
+
- [x] T025 [P] [US3] Create useTheme hook with localStorage persistence in playground/src/hooks/useTheme.ts
|
|
109
|
+
- [x] T026 [P] [US3] Create ThemeToggle component (sun/moon icons) in playground/src/components/ThemeToggle.tsx
|
|
110
|
+
- [x] T027 [US3] Create Header component with title and ThemeToggle in playground/src/components/Header.tsx
|
|
111
|
+
- [x] T028 [US3] Integrate Header into App.tsx layout
|
|
112
|
+
- [x] T029 [US3] Add CodeMirror theme switching (light/dark) based on current theme in JsonEditor.tsx
|
|
113
|
+
- [x] T030 [US3] Style Header to match website design (primary color, font) in playground/src/App.css
|
|
114
|
+
|
|
115
|
+
**Checkpoint**: User Story 3 complete - theme toggle works with persistence
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Phase 6: Polish & Cross-Cutting Concerns
|
|
120
|
+
|
|
121
|
+
**Purpose**: Final improvements and validation
|
|
122
|
+
|
|
123
|
+
- [x] T031 Add responsive layout adjustments for 1024px+ screens in playground/src/App.css
|
|
124
|
+
- [ ] T032 Verify all examples render without errors (manual test each example)
|
|
125
|
+
- [ ] T033 Verify preview updates within 500ms of JSON edits (performance check)
|
|
126
|
+
- [x] T034 Run `npm run build -w playground` and verify production build succeeds
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Dependencies & Execution Order
|
|
131
|
+
|
|
132
|
+
### Phase Dependencies
|
|
133
|
+
|
|
134
|
+
- **Setup (Phase 1)**: No dependencies - can start immediately
|
|
135
|
+
- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
|
|
136
|
+
- **User Stories (Phase 3-5)**: All depend on Foundational phase completion
|
|
137
|
+
- User stories can proceed sequentially in priority order (P1 → P2 → P3)
|
|
138
|
+
- Or in parallel if multiple developers available
|
|
139
|
+
- **Polish (Phase 6)**: Depends on all user stories being complete
|
|
140
|
+
|
|
141
|
+
### User Story Dependencies
|
|
142
|
+
|
|
143
|
+
- **User Story 1 (P1)**: Can start after Foundational (Phase 2) - No dependencies on other stories
|
|
144
|
+
- **User Story 2 (P2)**: Can start after Foundational (Phase 2) - Integrates with US1 editor/preview but independently testable
|
|
145
|
+
- **User Story 3 (P3)**: Can start after Foundational (Phase 2) - Integrates with US1 editor but independently testable
|
|
146
|
+
|
|
147
|
+
### Within Each User Story
|
|
148
|
+
|
|
149
|
+
- Components before integration
|
|
150
|
+
- Core implementation before styling
|
|
151
|
+
- Story complete before moving to next priority
|
|
152
|
+
|
|
153
|
+
### Parallel Opportunities
|
|
154
|
+
|
|
155
|
+
**Phase 1 (Setup)**:
|
|
156
|
+
|
|
157
|
+
- T004, T005, T006 can run in parallel (directory creation)
|
|
158
|
+
|
|
159
|
+
**Phase 3 (US1)**:
|
|
160
|
+
|
|
161
|
+
- T011, T012 can run in parallel (JsonEditor and Preview are independent components)
|
|
162
|
+
|
|
163
|
+
**Phase 4 (US2)**:
|
|
164
|
+
|
|
165
|
+
- T017, T018, T019, T020, T021 can ALL run in parallel (each example is independent)
|
|
166
|
+
|
|
167
|
+
**Phase 5 (US3)**:
|
|
168
|
+
|
|
169
|
+
- T025, T026 can run in parallel (useTheme hook and ThemeToggle component are independent)
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Parallel Example: User Story 2
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Launch all example creation tasks together:
|
|
177
|
+
Task: "Create Hello World example in playground/src/data/examples.ts"
|
|
178
|
+
Task: "Create Layout Demo example in playground/src/data/examples.ts"
|
|
179
|
+
Task: "Create Button Actions example in playground/src/data/examples.ts"
|
|
180
|
+
Task: "Create Form Inputs example in playground/src/data/examples.ts"
|
|
181
|
+
Task: "Create Data Binding example in playground/src/data/examples.ts"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Implementation Strategy
|
|
187
|
+
|
|
188
|
+
### MVP First (User Story 1 Only)
|
|
189
|
+
|
|
190
|
+
1. Complete Phase 1: Setup (T001-T006)
|
|
191
|
+
2. Complete Phase 2: Foundational (T007-T010)
|
|
192
|
+
3. Complete Phase 3: User Story 1 (T011-T016)
|
|
193
|
+
4. **STOP and VALIDATE**: Test JSON editing and preview independently
|
|
194
|
+
5. Deploy/demo if ready - core playground functionality works
|
|
195
|
+
|
|
196
|
+
### Incremental Delivery
|
|
197
|
+
|
|
198
|
+
1. Complete Setup + Foundational → Foundation ready
|
|
199
|
+
2. Add User Story 1 → Test independently → **MVP Ready!**
|
|
200
|
+
3. Add User Story 2 → Test independently → Examples available
|
|
201
|
+
4. Add User Story 3 → Test independently → Theme switching works
|
|
202
|
+
5. Polish phase → Production ready
|
|
203
|
+
|
|
204
|
+
### Single Developer Strategy
|
|
205
|
+
|
|
206
|
+
Execute phases sequentially:
|
|
207
|
+
|
|
208
|
+
1. Phase 1: Setup (~10 min)
|
|
209
|
+
2. Phase 2: Foundational (~20 min)
|
|
210
|
+
3. Phase 3: User Story 1 (~45 min) → **MVP checkpoint**
|
|
211
|
+
4. Phase 4: User Story 2 (~30 min)
|
|
212
|
+
5. Phase 5: User Story 3 (~30 min)
|
|
213
|
+
6. Phase 6: Polish (~15 min)
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Notes
|
|
218
|
+
|
|
219
|
+
- [P] tasks = different files, no dependencies
|
|
220
|
+
- [Story] label maps task to specific user story for traceability
|
|
221
|
+
- Each user story should be independently completable and testable
|
|
222
|
+
- Commit after each task or logical group
|
|
223
|
+
- Stop at any checkpoint to validate story independently
|
|
224
|
+
- The playground workspace already exists with basic Vite setup; tasks build on existing structure
|