Skip to content
cccskills
FreePublished on GitHub

x-card

Build interactive React cards and forms from JSON commands sent by an AI agent. Using @ant-design/x-card and A2UI, a protocol for describing interfaces, this skill covers data binding, user actions, custom components, and progressive rendering.

OriginalShow the original description

Use when building AI-driven UIs with @ant-design/x-card — covers XCard.Box, XCard.Card, A2UI v0.9 commands, data binding, catalogs, actions, and streaming patterns.

See how to install

Good for

  • Display interactive cards inside AI chat responses
  • Build forms driven by agent commands
  • Render an interface progressively as commands arrive
  • Migrate A2UI commands from v0.8 to v0.9

Files included (8)

  • SKILL.md10.3 KB
  • reference/ACTIONS.md7.4 KB
  • reference/API.md3.7 KB
  • reference/CATALOG.md5.6 KB
  • reference/COMMANDS.md5.5 KB
  • reference/DATA_BINDING.md4.5 KB
  • reference/INTRODUCTION.md13.8 KB
  • reference/USAGE.md6.1 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

🎯 Skill Positioning

This skill covers @ant-design/x-card — the React implementation of the A2UI protocol, enabling AI agents to dynamically render rich interactive UIs through structured JSON command streams.

It covers:

  • XCard.Box + XCard.Card component usage
  • A2UI v0.9 command types: createSurface, updateComponents, updateDataModel, deleteSurface
  • Custom component registration and catalog management
  • Data binding via JSON Pointer paths (RFC 6901)
  • Action handling — sending user events back to the agent
  • Streaming progressive rendering patterns
  • v0.8 ↔ v0.9 protocol differences

Scope: v0.9 is the recommended protocol. v0.8 is supported for backward compatibility only — prefer v0.9 for all new work.

Table of Contents

📦 Package Overview

PackageResponsibility
@ant-design/x-cardReact renderer for A2UI protocol — XCard.Box, XCard.Card, catalog APIs
@ant-design/xChat UI components (Bubble, Sender, etc.) — not covered here
@ant-design/x-sdkData providers, streaming — not covered here
npm install @ant-design/x-card

Exports:

import {
  XCard,
  registerCatalog,
  loadCatalog,
  validateComponent,
  clearCatalogCache,
} from '@ant-design/x-card';
import type {
  XAgentCommand_v0_9,
  XAgentCommand_v0_8,
  ActionPayload,
  Catalog,
  CatalogComponent,
} from '@ant-design/x-card';

// Subcomponents
XCard.Box; // Container: receives commands, owns catalog maps
XCard.Card; // Renderer: renders a single surface by id

🗂️ Component Architecture

XCard.Box
├── owns: catalogMap, surfaceCatalogMap
├── dispatches: commands → all XCard.Card children
├── aggregates: onAction events from all Cards
└── XCard.Card (id="surface-a")
│   ├── owns: component tree, data model, commandVersion
│   └── resolves: data bindings, triggers actions
└── XCard.Card (id="surface-b")
    └── ...

XCard.Box Props

interface BoxProps {
  commands?: (XAgentCommand_v0_9 | XAgentCommand_v0_8)[];
  /** Component names must start with an uppercase letter (React component convention) */
  components?: Record<string, React.ComponentType<any>>;
  onAction?: (payload: ActionPayload) => void;
  children?: React.ReactNode; // Should contain XCard.Card elements
}

XCard.Card Props

interface CardProps {
  id: string; // surfaceId to render
}

ActionPayload

interface ActionPayload {
  name: string; // from action.event.name
  surfaceId: string; // which surface triggered it
  /**
   * Context passed by component, with path references automatically resolved.
   *
   * For action.event.context fields using { path: "xxx" } format:
   * - X-Card automatically resolves them to { value: "actual_value" }
   * - Other properties (like label) are preserved
   *
   * Example input config:
   *   { username: { path: "/form/username", label: "用户名" } }
   *
   * Example resolved context:
   *   { username: { value: "张三", label: "用户名" } }
   */
  context: Record<string, any>;
}

🚀 Quick Start Decision Guide

If you need to...Read first
Set up XCard.Box + XCard.CardUSAGE.md → Basic Setup
Send commands from agent to cardCOMMANDS.md
Register a custom component catalogCATALOG.md → Local Catalog
Bind component props to live dataDATA_BINDING.md
Handle user interactions / form submitACTIONS.md
Build a streaming progressive UIUSAGE.md → Streaming
Migrate from v0.8 to v0.9COMMANDS.md → v0.8 vs v0.9
Look up full prop typesAPI.md

🛠 Recommended Workflow

  1. Define your catalog — register a local catalog or use the A2UI Basic Catalog URL.
  2. Register custom components — pass them via XCard.Box components prop.
  3. Create the React tree — wrap surfaces with XCard.Box, add XCard.Card per surface.
  4. Feed commands — push XAgentCommand_v0_9[] into commands prop (typically from streaming agent response).
  5. Handle actions — receive ActionPayload in onAction, update commands in response.

Minimal Working Example

import React, { useState } from 'react';
import { XCard, registerCatalog } from '@ant-design/x-card';
import type { XAgentCommand_v0_9, ActionPayload, Catalog } from '@ant-design/x-card';

// 1. Define and register local catalog
const myCatalog: Catalog = {
  catalogId: 'local://my_catalog.json',
  components: {
    Text: {
      type: 'object',
      properties: { text: { type: 'string' }, variant: { type: 'string' } },
      required: ['text'],
    },
    Button: {
      type: 'object',
      properties: { text: { type: 'string' }, action: {} },
      required: ['text'],
    },
  },
};
registerCatalog(myCatalog);

// 2. Custom component implementations
const Text: React.FC<{ text: string; variant?: string }> = ({ text, variant }) => (
  <p className={`text-${variant ?? 'body'}`}>{text}</p>
);

const Button: React.FC<{ text: string; onAction?: (ctx: any) => void; action?: any }> = ({
  text,
  onAction,
  action,
}) => <button onClick={() => onAction?.(action?.event?.context ?? {})}>{text}</button>;

// 3. Build commands (from agent stream)
const commands: XAgentCommand_v0_9[] = [
  {
    version: 'v0.9',
    createSurface: {
      surfaceId: 'welcome',
      catalogId: 'local://my_catalog.json',
    },
  },
  {
    version: 'v0.9',
    updateComponents: {
      surfaceId: 'welcome',
      components: [
        { id: 'root', component: 'Column', children: ['title', 'btn'] },
        { id: 'title', component: 'Text', text: { path: '/user/name' }, variant: 'h1' },
        {
          id: 'btn',
          component: 'Button',
          text: 'Start',
          action: { event: { name: 'start', context: {} } },
        },
      ],
    },
  },
  {
    version: 'v0.9',
    updateDataModel: {
      surfaceId: 'welcome',
      path: '/user/name',
      value: 'Alice',
    },
  },
];

// 4. Render
export default function App() {
  const [cmdQueue, setCmdQueue] = useState<XAgentCommand_v0_9[]>(commands);

  const handleAction = (payload: ActionPayload) => {
    console.log('Action:', payload.name, payload.context);
    // Append new commands based on agent response
    setCmdQueue((prev) => [...prev /* new commands */]);
  };

  return (
    <XCard.Box commands={cmdQueue} components={{ Text, Button }} onAction={handleAction}>
      <XCard.Card id="welcome" />
    </XCard.Box>
  );
}

🚨 Development Rules

  • Always include "version": "v0.9" on every command — omitting it causes protocol rejection.
  • One and only one id: "root" component per surface's component tree — this is the tree root.
  • Flat adjacency list only — never nest component objects inside other component objects; always reference children by id string.
  • Separate structure from data — updateComponents for layout, updateDataModel for content/state.
  • Register catalog before mounting — call registerCatalog() before the component tree renders.
  • Pass components map to XCard.Box, not to XCard.Card — Box distributes to all Cards.
  • Never recreate the components object inline — keep it stable with useMemo or module-level constant to avoid re-renders.
  • Input components require value: { path: "..." } for two-way binding — literal values do not update the data model.
  • For streaming: append new commands to the array rather than replacing it — Card processes the diff incrementally.
  • action.event.context paths are write targets — they point to where user-entered data lives in the data model; do not resolve them as read sources.
  • Path references in action context are automatically resolved — when an action is triggered, X-Card converts { path: "xxx" } in the action config to { value: "actual_value" } in the onAction payload. This works for both v0.9 (action.event.context = { key: { path } }) and v0.8 (action.context = [{ key, value: { path } }]) formats.

🤝 Skill Collaboration

ScenarioSkill combination
AI chat with structured card responsesuse-x-chat + x-components + x-card
Standalone agent form UIx-card only
Streaming Markdown + card side-panelx-markdown + x-card
HTTP streaming from agent into cardx-request → feed response as commands

🔗 Reference Resources

  • USAGE.md — Setup guide, streaming pattern, multi-surface examples
  • COMMANDS.md — All four A2UI v0.9 command types, v0.8 vs v0.9 diff
  • DATA_BINDING.md — JSON Pointer paths, dynamic types, two-way binding, template iteration
  • ACTIONS.md — Action definitions, ActionPayload, form submission pattern
  • CATALOG.md — Local catalog registration, remote URL loading, custom component schema
  • API.md — Full TypeScript types for Box, Card, commands, catalog, actions

Official Documentation

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

use-x-chat

FreeSummary

Implement AI chat behavior with useXChat, a React function for managing chat state. Connect Providers that handle API communication, manage messages and errors, regenerate or cancel replies, and support multiple conversations with separate state.

  • Connect chat messages to Bubble.List and Sender
  • Handle network errors and canceled replies
  • Add message deletion and reply regeneration
ant-design/x4.8KUpdated Oct 12, 2026

use-x-chat

FreeSummary

Implement AI chat behavior with useXChat, a React function for managing chat state. Connect Providers that handle API communication, manage messages and errors, regenerate or cancel replies, and support multiple conversations with separate state.

  • Connect chat messages to Bubble.List and Sender
  • Handle network errors and canceled replies
  • Add message deletion and reply regeneration
ant-design/x4.8KUpdated Oct 12, 2026

x-card

FreeSummary

Build interactive cards and forms in React from an AI agent’s structured JSON commands. The skill guides component registration, connections between data and interface elements, user action handling, and progressive rendering with @ant-design/x-card.

  • Build an interactive form controlled by an AI agent
  • Update cards progressively as agent commands arrive
  • Connect form inputs to data and return user actions
ant-design/x4.8KUpdated Oct 12, 2026

x-chat-provider

FreeSummary

Connect streaming APIs to Ant Design X by implementing a Chat Provider, an adapter for request and message formats. Choose built-in providers where suitable, transform custom responses, and configure authentication, retries, and stream parsing.

  • Connect a private streaming API to Ant Design X
  • Choose a provider for OpenAI or DeepSeek
  • Convert responses containing multiple fields
ant-design/x4.8KUpdated Oct 12, 2026

x-chat-provider

FreeSummary

Adapt a streaming API to Ant Design X by selecting or implementing a Chat Provider, the layer that converts requests and responses into chat messages. Includes custom formats, incremental message assembly, and nonstandard stream handling.

  • Choose a built-in provider for OpenAI or DeepSeek
  • Connect a private SSE API to Ant Design X
  • Convert responses with multiple fields into chat messages
ant-design/x4.8KUpdated Oct 12, 2026

x-components

FreeSummary

Build AI chat screens in React with @ant-design/x. This skill guides component selection, API usage, and page composition for message bubbles, input boxes, conversation lists, attachments, source references, and other chat interface elements.

  • Build a chat screen with message bubbles and an input box
  • Add conversation lists and switching
  • Display attachments and source references
ant-design/x4.8KUpdated Oct 12, 2026

See all skills by ant-design

Report a problem with this skill