### Setup and Build Commands Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/quickstart.md Commands to install dependencies, build the main library, and manage the development server for the playground workspace. ```bash npm install -w playground @uiw/react-codemirror @codemirror/lang-json npm run build npm run dev -w playground ``` -------------------------------- ### Install A2UI React SDK Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md Installs the A2UI React SDK version 0.9 using npm. This is the first step to integrate A2UI into your React application. ```bash npm install @easyops-cn/a2ui-react ``` -------------------------------- ### Basic A2UI Renderer Usage in React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md Demonstrates the basic setup for using the A2UI Renderer in a React application. It includes setting up the A2UIProvider with messages and an action handler, and rendering the A2UIRenderer component. Assumes the existence of `useState`, `useEffect`, and a `connectToServer` function. ```tsx import { A2UIProvider, A2UIRenderer, type A2UIMessage, type A2UIAction, } from '@easyops-cn/a2ui-react/0.9' function App() { const [messages, setMessages] = useState([]) const handleAction = (action: A2UIAction) => { console.log('Action dispatched:', action) // Send action to your server } // Example: Add messages from server stream useEffect(() => { const stream = connectToServer() stream.onMessage((msg) => { setMessages((prev) => [...prev, msg]) }) return () => stream.close() }, []) return ( ) } ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/CONTRIBUTING.md Installs all necessary dependencies for the monorepo using npm workspaces. ```bash npm install ``` -------------------------------- ### Installation Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/001-a2ui-renderer/quickstart.md Instructions on how to install the A2UI-React library using npm or pnpm. ```APIDOC ## Installation ```bash npm install @easyops-cn/a2ui-react # or pnpm add @easyops-cn/a2ui-react ``` ``` -------------------------------- ### A2UI Message: Create a Surface Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md An example A2UI message to create a new surface. It specifies the `surfaceId` and the `catalogId` for the surface's specification. ```json { "createSurface": { "surfaceId": "main", "catalogId": "https://a2ui.dev/specification/0.9/standard_catalog.json" } } ``` -------------------------------- ### Install @a2ui-sdk/utils Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/utils/README.md Installs the @a2ui-sdk/utils package using npm. This is the first step to using the utility functions in your project. ```bash npm install @a2ui-sdk/utils ``` -------------------------------- ### Testing and Production Build Commands Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/quickstart.md Commands for executing tests and generating production-ready builds for the playground workspace. ```bash npm test -w playground npm run build -w playground npm run preview -w playground ``` -------------------------------- ### A2UI Data Model Update for Dynamic Lists Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md Provides the data model to populate the dynamic list example. This JSON object updates the `/users` path in the data model, containing an array of user objects, each with a 'name' property. ```json { "updateDataModel": { "surfaceId": "main", "path": "/users", "value": [{ "name": "Alice" }, { "name": "Bob" }, { "name": "Charlie" }] } } ``` -------------------------------- ### Manage Website and Playground Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/CONTRIBUTING.md Commands to build and serve the documentation website and the live development playground. ```bash # Website npm run build -w website npm run serve -w website # Playground npm run dev -w playground npm run build -w playground ``` -------------------------------- ### Setup A2UI Provider and Renderer (v0.9) Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/website/content/index.mdx Shows the basic setup for using A2UIProvider and A2UIRenderer in version 0.9. It includes instructions for integrating with Tailwind CSS using the `@source` directive and handling A2UI messages via `useA2UIMessageHandler`. ```css @source "../node_modules/@a2ui-sdk/react"; ``` ```tsx import { A2UIProvider, A2UIRenderer, useA2UIMessageHandler, type A2UIMessage, type A2UIAction, } from '@a2ui-sdk/react/0.9' function App() { return ( ) } function MyApp() { const { processMessage } = useA2UIMessageHandler() useEffect(() => { const message: A2UIMessage = { // ... A2UI message from your backend } processMessage(message) }, [processMessage]) const handleAction = (action: A2UIAction) => { console.log('Action received:', action) } return ( ) } ``` -------------------------------- ### A2UI Message: Add Components to a Surface Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md An example A2UI message to update components within a specified surface. It defines a layout with a greeting, an input field, and a submit button, demonstrating component nesting and data binding. ```json { "updateComponents": { "surfaceId": "main", "components": [ { "id": "root", "component": "Column", "children": ["greeting", "input", "submit"] }, { "id": "greeting", "component": "Text", "text": "Hello, ${/user/name}!", "variant": "h2" }, { "id": "input", "component": "TextField", "label": "Your name", "value": { "path": "/user/name" } }, { "id": "submit", "component": "Button", "child": "submit_label", "action": { "name": "greet", "context": { "name": { "path": "/user/name" } } } }, { "id": "submit_label", "component": "Text", "text": "Say Hello" } ] } } ``` -------------------------------- ### Theme System Implementation Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/quickstart.md Demonstrates how to toggle themes using data attributes on the document root and define corresponding CSS variables for light and dark modes. ```typescript document.documentElement.dataset.theme = 'dark'; // or 'light' ``` ```css html[data-theme='dark'] { --background-color: hsl(230, 25%, 18%); --text-color: hsl(210, 50%, 96%); } ``` -------------------------------- ### Install A2UIRenderer SDK Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/001-a2ui-renderer/quickstart.md Instructions for installing the A2UIRenderer package using npm or pnpm package managers. ```bash npm install @easyops-cn/a2ui-react # or pnpm add @easyops-cn/a2ui-react ``` -------------------------------- ### Install A2UI SDK Types Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/types/README.md Install the package via npm to access the A2UI protocol type definitions. ```bash npm install @a2ui-sdk/types ``` -------------------------------- ### A2UI SDK v0.9 Setup and Usage (React) Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/README.md Details the setup and usage of A2UI SDK version 0.9. It includes instructions for configuring Tailwind CSS via the `@source` directive and demonstrates the basic structure for using `A2UIProvider` and `A2UIRenderer` to process messages and handle actions. This version introduces changes to the protocol and recommends v0.8 for production. ```css @source "../node_modules/@a2ui-sdk/react"; ``` ```tsx import { A2UIProvider, A2UIRenderer, useA2UIMessageHandler, type A2UIMessage, type A2UIAction, } from '@a2ui-sdk/react/0.9' function App() { return ( ) } function MyApp() { const { processMessage } = useA2UIMessageHandler() useEffect(() => { const message: A2UIMessage = { // ... A2UI message from your backend } processMessage(message) }, [processMessage]) const handleAction = (action: A2UIAction) => { console.log('Action received:', action) } return } ``` -------------------------------- ### Install A2UI React Package (Shell) Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/README.md Provides the command to install the `@a2ui-sdk/react` package using npm. This is a prerequisite for using the React components of the A2UI SDK. ```sh npm install @a2ui-sdk/react ``` -------------------------------- ### Import SDK modules Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/CLAUDE.md Examples of how to import specific versions and utilities from the SDK packages. ```javascript // React package import { v0_8 } from '@a2ui-sdk/react'; import { ... } from '@a2ui-sdk/react/0.8'; import { ... } from '@a2ui-sdk/react/0.9'; // Types package import { ... } from '@a2ui-sdk/types/0.8'; import { ... } from '@a2ui-sdk/types/0.9'; // Utils package import { ... } from '@a2ui-sdk/utils'; import { ... } from '@a2ui-sdk/utils/0.9'; ``` -------------------------------- ### Configure Multi-Surface Rendering Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md Demonstrates how to use the A2UIProvider and A2UIRenderer components to manage UI surfaces. It shows both automatic rendering of all surfaces and targeted rendering of specific surfaces by ID. ```tsx ``` -------------------------------- ### Build and Test Packages Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/CONTRIBUTING.md Builds individual packages in the correct dependency order and executes tests using Vitest. ```bash # Types package npm run build -w @a2ui-sdk/types # Utils package npm run build -w @a2ui-sdk/utils npm test -w @a2ui-sdk/utils # React package npm run build -w @a2ui-sdk/react npm run dev -w @a2ui-sdk/react npm test -w @a2ui-sdk/react npm run test:run -w @a2ui-sdk/react ``` -------------------------------- ### A2UI Message: Update Data Model Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md An example A2UI message to update the data model for a specific surface. This allows dynamic changes to the application's state, affecting data bindings in the UI. ```json { "updateDataModel": { "surfaceId": "main", "path": "/user", "value": { "name": "Alice" } } } ``` -------------------------------- ### A2UI Message: Validation with Checks Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md An example A2UI message defining a `TextField` with validation rules using the `checks` array. It includes 'required' and 'email' validation, specifying custom error messages. ```json { "id": "email_field", "component": "TextField", "label": "Email", "value": { "path": "/form/email" }, "variant": "shortText", "checks": [ { "call": "required", "args": { "value": { "path": "/form/email" } }, "message": "Email is required" }, { "call": "email", "args": { "value": { "path": "/form/email" } }, "message": "Please enter a valid email" } ] } ``` -------------------------------- ### Initialize A2UI Renderer in React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/README.md Basic setup using A2UIProvider and A2UIRenderer to display messages and handle actions. ```tsx import { A2UIProvider, A2UIRenderer, type A2UIMessage, type A2UIAction } from '@a2ui-sdk/react/0.9'; function App() { const messages: A2UIMessage[] = []; const handleAction = (action: A2UIAction) => { console.log('Action:', action.name, action.context); }; return ( ); } ``` -------------------------------- ### A2UIRenderer Integration Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/quickstart.md Shows how to parse JSON content into A2UIMessage objects and pass them to the A2UIRenderer component for display. ```typescript import { A2UIRenderer, type A2UIMessage } from '@easyops-cn/a2ui-react/0.8'; const messages: A2UIMessage[] = JSON.parse(jsonContent); ``` -------------------------------- ### Simple Path Interpolation with A2UI React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Demonstrates basic string interpolation using absolute paths to access data within a model. It shows how to interpolate single and multiple expressions. ```typescript import { interpolate } from '@easyops-cn/a2ui-react/0.9' const dataModel = { user: { name: 'John', age: 30 }, } // Absolute path interpolate('Hello, ${/user/name}!', dataModel) // → "Hello, John!" // Multiple expressions interpolate('${/user/name} is ${/user/age} years old', dataModel) // → "John is 30 years old" ``` -------------------------------- ### Implementing A2UI Renderer in React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/website/content/index.mdx Shows the setup of A2UIProvider and A2UIRenderer, including message processing and action handling within a React application. ```tsx import { A2UIProvider, A2UIRenderer, useA2UIMessageHandler, type A2UIMessage, type A2UIAction } from '@a2ui-sdk/react/0.8'; function App() { return ( ); } function MyApp() { const { processMessage } = useA2UIMessageHandler(); useEffect(() => { const message: A2UIMessage = { /* A2UI message from backend */ }; processMessage(message); }, [processMessage]); const handleAction = (action: A2UIAction) => { console.log('Action received:', action); }; return ; } ``` -------------------------------- ### UI Composition using Adjacency List Model Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/src/0.9/docs/a2ui_protocol.md Illustrates how the server streams UI components and how the client buffers and renders them. The example shows a root Column component with Text and Button children, demonstrating the implicit tree structure built via ID references. ```mermaid flowchart TD subgraph "Server Stream" A("updateComponents
components: [root, title, button]") end subgraph "Client-Side Buffer (Map)" C("root: {id: 'root', component: 'Column', children: ['title', 'button']}") D("title: {id: 'title', component: 'Text', text: 'Welcome'}") E("button: {id: 'button', component: 'Button', child: 'button_label'}") end subgraph "Rendered Widget Tree" F(Column) --> G(Text: 'Welcome') F --> H(Button) end A -- "Parsed and stored" --> C A -- "Parsed and stored" --> D A -- "Parsed and stored" --> E ``` -------------------------------- ### Manage Data and Actions with A2UI Hooks Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md Provides a set of React hooks to interact with the A2UI framework. These hooks enable data binding, form state management, action dispatching, and access to the global surface context. ```tsx const value = useDataBinding(surfaceId, { path: '/user/name' }, '') const [value, setValue] = useFormBinding(surfaceId, { path: '/form/email' }, '') const dispatch = useDispatchAction() dispatch(surfaceId, componentId, { name: 'custom', context: { key: 'value' } }) const { surfaces, getComponent, getDataModel, setDataValue } = useSurfaceContext() const dataModel = useDataModel(surfaceId) ``` -------------------------------- ### Run Linting and Formatting Commands Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/CONTRIBUTING.md Commands to ensure code quality and consistency across the entire project using ESLint and Prettier. ```bash npm run lint # Run ESLint across all packages npm run lint:fix # ESLint with auto-fix npm run format # Format code with Prettier npm run format:check # Check code formatting ``` -------------------------------- ### Contact Form Interaction Stream Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/src/0.9/docs/a2ui_protocol.md A complete JSONL stream example demonstrating the lifecycle of creating a surface, defining its component hierarchy, and initializing the data model for a contact form. ```jsonl {"createSurface":{"surfaceId":"contact_form_1","catalogId":"https://a2ui.dev/specification/0.9/standard_catalog.json"}} {"updateComponents":{"surfaceId":"contact_form_1","components":[{"id":"root","component":"Card","child":"form_container"},{"id":"form_container","component":"Column","children":["header_row","name_row","email_group","phone_group","pref_group","divider_1","newsletter_checkbox","submit_button"],"justify":"start","align":"stretch"},{"id":"header_row","component":"Row","children":["header_icon","header_text"],"align":"center"},{"id":"header_icon","component":"Icon","name":"mail"},{"id":"header_text","component":"Text","text":"# Contact Us","variant":"h2"},{"id":"name_row","component":"Row","children":["first_name_group","last_name_group"],"justify":"spaceBetween"},{"id":"first_name_group","component":"Column","children":["first_name_label","first_name_field"],"weight":1},{"id":"first_name_label","component":"Text","text":"First Name","variant":"caption"},{"id":"first_name_field","component":"TextField","label":"First Name","value":{"path":"/contact/firstName"},"variant":"shortText"},{"id":"last_name_group","component":"Column","children":["last_name_label","last_name_field"],"weight":1},{"id":"last_name_label","component":"Text","text":"Last Name","variant":"caption"},{"id":"last_name_field","component":"TextField","label":"Last Name","value":{"path":"/contact/lastName"},"variant":"shortText"},{"id":"email_group","component":"Column","children":["email_label","email_field"]},{"id":"email_label","component":"Text","text":"Email Address","variant":"caption"},{"id":"email_field","component":"TextField","label":"Email","value":{"path":"/contact/email"},"variant":"shortText","checks":[{"call":"required","message":"Email is required."},{"call":"email","message":"Please enter a valid email address."}]},{"id":"phone_group","component":"Column","children":["phone_label","phone_field"]},{"id":"phone_label","component":"Text","text":"Phone Number","variant":"caption"},{"id":"phone_field","component":"TextField","label":"Phone","value":{"path":"/contact/phone"},"variant":"shortText","checks":[{"call":"regex","args":{"pattern":"^\\d{10}$"},"message":"Phone number must be 10 digits."}]},{"id":"pref_group","component":"Column","children":["pref_label","pref_picker"]},{"id":"pref_label","component":"Text","text":"Preferred Contact Method","variant":"caption"},{"id":"pref_picker","component":"ChoicePicker","variant":"mutuallyExclusive","options":[{"label":"Email","value":"email"},{"label":"Phone","value":"phone"},{"label":"SMS","value":"sms"}],"value":{"path":"/contact/preference"}},{"id":"divider_1","component":"Divider","axis":"horizontal"},{"id":"newsletter_checkbox","component":"CheckBox","label":"Subscribe to our newsletter","value":{"path":"/contact/subscribe"}},{"id":"submit_button_label","component":"Text","text":"Send Message"},{"id":"submit_button","component":"Button","child":"submit_button_label","primary":true,"action":{"name":"submitContactForm","context":{"formId":"contact_form_1","clientTime":{"call":"now","returnType":"string"},"isNewsletterSubscribed":{"path":"/contact/subscribe"}}}}]}} {"updateDataModel":{"surfaceId":"contact_form_1","path":"/contact","value":{"firstName":"John","lastName":"Doe","email":"john.doe@example.com","phone":"1234567890","preference":["email"],"subscribe":true}}} ``` -------------------------------- ### Registering Custom Functions for Interpolation Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Demonstrates how to register custom functions for use within string interpolation by passing a function registry object to the `interpolate` function. ```typescript const customFunctions = { greet: (name: string) => `Hello, ${name}!`, multiply: (a: number, b: number) => a * b, } interpolate( '${greet(${/name})} Result: ${multiply(${/x}, ${/y})}', { name: 'World', x: 6, y: 7 }, null, customFunctions ) // → "Hello, World! Result: 42" ``` -------------------------------- ### Scope Resolution Example in JSON Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/src/0.9/docs/a2ui_protocol.md Demonstrates how A2UI resolves data paths within component definitions. It shows the difference between relative paths (e.g., '/employees/N/name') and absolute paths (e.g., '/company'). ```json { "company": "Acme Corp", "employees": [ { "name": "Alice", "role": "Engineer" }, { "name": "Bob", "role": "Designer" } ] } ``` ```json { "id": "employee_list", "component": "List", "children": { "path": "/employees", "componentId": "employee_card_template" } }, { "id": "employee_card_template", "component": "Column", "children": ["name_text", "company_text"] }, { "id": "name_text", "component": "Text", "text": { "path": "name" } // "name" is Relative. Resolves to /employees/N/name }, { "id": "company_text", "component": "Text", "text": { "path": "/company" } // "/company" is Absolute. Resolves to "Acme Corp" globally. } ``` -------------------------------- ### Relative Path Interpolation in A2UI React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Illustrates string interpolation using relative paths, particularly useful for iterating over collections. It shows how to specify a base path for collection elements. ```typescript const dataModel = { users: [{ name: 'Alice' }, { name: 'Bob' }], } // With base path for collection iteration interpolate('Name: ${name}', dataModel, '/users/0') // → "Name: Alice" interpolate('Name: ${name}', dataModel, '/users/1') // → "Name: Bob" ``` -------------------------------- ### String Interpolation with Function Calls in JSON Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/src/0.9/docs/a2ui_protocol.md Demonstrates string interpolation using client-side functions in A2UI. Examples include calling functions with no arguments and with nested arguments, showcasing dynamic content generation. ```json { "id": "user_welcome", "component": "Text", "text": "Current time: ${now()}. Formatted date: ${formatDate(${/currentDate}, 'yyyy-MM-dd')}." } ``` -------------------------------- ### Escaped Expressions in A2UI React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Explains how to output literal `${` sequences using a backslash (`\${`) and demonstrates mixing escaped and evaluated expressions in interpolation. ```typescript // Use \${ to output literal ${ interpolate('Template: \${variable}', {}) // → "Template: ${variable}" // Mixed escaped and evaluated interpolate('\${escaped} and ${/actual}', { actual: 'evaluated' }) // → "${escaped} and evaluated" ``` -------------------------------- ### Error Handling in A2UI String Interpolation Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Illustrates how the A2UI interpolation module handles errors such as unclosed expressions, unknown functions, and missing paths, typically by returning an empty string and logging warnings. ```typescript // Unclosed expression interpolate('Hello ${/name', { name: 'John' }) // Console: [A2UI] Parse error: Expected '}' at position 12 // → "Hello " // Unknown function interpolate('${unknownFunc()}', {}) // Console: [A2UI] Unknown function: unknownFunc // → "" // Missing path interpolate('Value: ${/nonexistent}', {}) // → "Value: " (no warning, this is normal) ``` -------------------------------- ### Parsing Interpolation AST with A2UI React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Shows how to use the `parseInterpolation` function to obtain the Abstract Syntax Tree (AST) of an interpolation expression without evaluating it. ```typescript import { parseInterpolation } from '@easyops-cn/a2ui-react/0.9' const ast = parseInterpolation('Hello, ${/name}!') // Returns: // { // type: 'interpolatedString', // parts: [ // { type: 'literal', value: 'Hello, ' }, // { type: 'path', path: '/name', absolute: true }, // { type: 'literal', value: '!' } // ] // } ``` -------------------------------- ### Extracting Dependencies from Interpolation AST Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Provides a TypeScript function `getDependencies` that traverses an interpolation AST to extract all referenced data model paths. ```typescript function getDependencies(ast: InterpolatedStringNode): string[] { const paths: string[] = [] function visit(node: ASTNode) { if (node.type === 'path') { paths.push(node.path) } else if (node.type === 'functionCall') { node.args.forEach(visit) } else if (node.type === 'interpolatedString') { node.parts.forEach(visit) } } ast.parts.forEach(visit) return paths } const ast = parseInterpolation('${/user/name} - ${/user/email}') getDependencies(ast) // → ['/user/name', '/user/email'] ``` -------------------------------- ### JSON Pointer Escape Sequences in A2UI React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Explains and demonstrates the use of JSON Pointer escape sequences (`~1` for `/` and `~0` for `~`) when data model keys contain these special characters. ```typescript const dataModel = { 'a/b': 'slash-key', // Key contains / 'm~n': 'tilde-key', // Key contains ~ 'x/y~z': 'mixed-key', // Key contains both } // Reference key containing / interpolate('${/a~1b}', dataModel) // → "slash-key" // Reference key containing ~ interpolate('${/m~0n}', dataModel) // → "tilde-key" // Reference key containing both interpolate('${/x~1y~0z}', dataModel) // → "mixed-key" ``` -------------------------------- ### Function Call Interpolation in A2UI React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Shows how to call functions within string interpolation expressions. This includes no-argument functions, functions with literal arguments, and functions with path arguments. ```typescript // No-argument function interpolate('Current time: ${now()}', {}) // → "Current time: 2026-01-13T10:30:00.000Z" // Function with literal arguments interpolate('Sum: ${add(5, 3)}', {}) // → "Sum: 8" // Function with path arguments (nested expression) const dataModel = { timestamp: '2026-01-13T00:00:00Z' } interpolate("Date: ${formatDate(${/timestamp}, 'yyyy-MM-dd')}", dataModel) // → "Date: 2026-01-13" ``` -------------------------------- ### Nested Expression Interpolation in A2UI React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Demonstrates how to use nested expressions within string interpolation, including function calls with path arguments and chained function calls. ```typescript const dataModel = { name: 'john', price: 100, tax: 15 } // Function with path argument interpolate('${upper(${/name})}', dataModel) // → "JOHN" // Chained functions interpolate('Total: ${formatCurrency(${add(${/price}, ${/tax})})}', dataModel) // → "Total: $115.00" ``` -------------------------------- ### Initialize Surface: v0.8.1 vs v0.9 Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/src/0.9/docs/evolution_guide.md Compares the initialization message structure. v0.9 replaces 'beginRendering' with 'createSurface', removes style information, and introduces a 'catalogId' requirement. ```json { "beginRendering": { "surfaceId": "user_profile_card", "root": "root", "styles": { "primaryColor": "#007bff" } } } ``` ```json { "createSurface": { "surfaceId": "user_profile_card", "catalogId": "https://a2ui.dev/specification/0.9/standard_catalog.json" } } ``` -------------------------------- ### Custom Component Implementation and Registration in React Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md Shows how to create and register custom components within the A2UI framework. It demonstrates using hooks like `useDataBinding` and `ComponentRenderer` for custom UI elements, and registering them via a `Map` passed to `A2UIProvider`. ```tsx import { A2UIProvider, A2UIRenderer, ComponentRenderer, useDataBinding, } from '@easyops-cn/a2ui-react/0.9' // Custom component using hooks function MyCustomCard({ surfaceId, component }) { const { child, title } = component const resolvedTitle = useDataBinding(surfaceId, title, '') return (

{resolvedTitle}

) } // Register custom components const customComponents = new Map([['MyCustomCard', MyCustomCard]]) function App() { return ( ) } ``` -------------------------------- ### JSON Editor Setup with CodeMirror 6 Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/research.md Demonstrates the integration of CodeMirror 6 for JSON editing using the `@uiw/react-codemirror` wrapper. This setup includes syntax highlighting for JSON and supports dark mode theming. It's designed to be lightweight and performant for real-time editing scenarios. ```typescript import CodeMirror from '@uiw/react-codemirror'; import { json } from '@codemirror/lang-json'; import { oneDark } from '@codemirror/theme-one-dark'; function MyEditor({ value, onChange }: { value: string; onChange: (value: string) => void; }) { return ( { onChange(editorView.state.doc.toString()); }} /> ); } ``` -------------------------------- ### Migrate Interpolation API from 0.8 to 0.9 Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/004-string-interpolation-parser/quickstart.md Demonstrates the transition from legacy interpolation functions to the new AST-based approach. The 0.9 API requires parsing the template into an AST first, allowing for more efficient dependency extraction and evaluation. ```typescript // Before (0.8 style) import { hasInterpolation, interpolate, getInterpolationDependencies, } from '...' if (hasInterpolation(template)) { const deps = getInterpolationDependencies(template, basePath) const result = interpolate(template, dataModel, basePath) } // After (0.9 refactored) import { parseInterpolation, interpolate } from '...' const ast = parseInterpolation(template) const deps = extractPathsFromAST(ast, basePath) // custom helper const result = interpolate(template, dataModel, basePath) ``` -------------------------------- ### JSON Editor Integration Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/quickstart.md Configures the CodeMirror component to handle JSON editing within the React application. ```typescript import CodeMirror from '@uiw/react-codemirror'; import { json } from '@codemirror/lang-json'; setJsonContent(value)} /> ``` -------------------------------- ### Error Boundary Component Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/quickstart.md A standard React error boundary implementation to catch and display runtime errors gracefully within the playground. ```typescript class ErrorBoundary extends React.Component { state = { hasError: false, error: null }; static getDerivedStateFromError(error) { return { hasError: true, error }; } render() { if (this.state.hasError) { return ; } return this.props.children; } } ``` -------------------------------- ### Use A2UI Data and Form Hooks Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/README.md Examples of using hooks for data binding, form state management, and action dispatching within A2UI components. ```tsx // Data Binding const value = useDataBinding({ path: '/user/name' }); // Form Binding const [formValue, setFormValue] = useFormBinding({ path: '/form/email' }); // Dispatch Action const dispatch = useDispatchAction(); dispatch({ name: 'submit', context: { formId: 'contact' } }); ``` -------------------------------- ### A2UI Message: Template Binding for Dynamic Lists Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/003-a2ui-0-9-renderer/quickstart.md Demonstrates dynamic list rendering using template binding in A2UI. A 'List' component iterates over a data path (`/users`), rendering a 'Text' component for each item, bound to the 'name' property. ```json { "id": "user_list", "component": "List", "children": { "componentId": "user_item", "path": "/users" } }, { "id": "user_item", "component": "Text", "text": { "path": "name" } } ``` -------------------------------- ### Implement Basic A2UIRenderer Usage Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/001-a2ui-renderer/quickstart.md Displays the minimal setup required to render A2UI messages and handle user actions within a React application. ```tsx import { A2UIRenderer, A2UIMessage, A2UIAction, } from '@easyops-cn/a2ui-react/0.8' function App() { const messages: A2UIMessage[] = [ // Messages from your A2UI server ] const handleAction = (action: A2UIAction) => { console.log('Action received:', action) // Handle the action (e.g., send to server) } return } ``` -------------------------------- ### JSON Button Validation Example Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/src/0.9/docs/a2ui_protocol.md Illustrates how to define validation checks for a Button component. If any check fails, the button is automatically disabled, allowing its state to depend on model data validity. ```json { "component": "Button", "text": "Submit", "checks": [ { "and": [ { "call": "required", "args": { "value": { "path": "/formData/terms" } } }, { "or": [ { "call": "required", "args": { "value": { "path": "/formData/email" } } }, { "call": "required", "args": { "value": { "path": "/formData/phone" } } } ] } ], "message": "You must accept terms AND provide either email or phone" } ] } ``` -------------------------------- ### Build and test packages Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/CLAUDE.md Commands to build and test specific packages within the monorepo using npm workspaces. ```bash npm run build -w @a2ui-sdk/types npm run build -w @a2ui-sdk/utils npm test -w @a2ui-sdk/utils npm run build -w @a2ui-sdk/react npm run dev -w @a2ui-sdk/react npm test -w @a2ui-sdk/react npm run test:run -w @a2ui-sdk/react ``` -------------------------------- ### POST createSurface Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/packages/react/src/0.9/docs/a2ui_protocol.md Signals the client to initialize a new UI surface and define the catalog to be used for rendering. ```APIDOC ## POST createSurface ### Description Signals the client to create a new surface and begin rendering it. This message MUST be sent before any updateComponents message referencing the surfaceId. ### Method POST ### Endpoint /createSurface ### Parameters #### Request Body - **surfaceId** (string) - Required - The unique identifier for the UI surface to be rendered. - **catalogId** (string) - Required - A unique identifier (URI) for the component catalog used for this surface. ### Request Example { "createSurface": { "surfaceId": "user_profile_card", "catalogId": "https://a2ui.dev/specification/0.9/standard_catalog.json" } } ``` -------------------------------- ### Define Data and Event Contracts Source: https://github.com/easyops-cn/a2ui-sdk/blob/main/specs/002-playground/contracts/components.md Core data structures and event handler types for the playground. These define the shape of example data and the signatures for user interaction events. ```typescript interface Example { id: string title: string description: string messages: A2UIMessage[] } type EditorChangeHandler = (newValue: string) => void type ExampleSelectHandler = (exampleId: string) => void type ThemeToggleHandler = () => void type ActionHandler = (action: A2UIAction) => void ```