Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
867 changes: 867 additions & 0 deletions docs/rfcs/0003-production-generative-ui.zh-CN.md

Large diffs are not rendered by default.

246 changes: 91 additions & 155 deletions packages/x-card/README.md
Original file line number Diff line number Diff line change
@@ -1,182 +1,118 @@
# @ant-design/x-card

React card loader for dynamic content loading and management.

## Features

- 🚀 **Dynamic Loading**: Load cards asynchronously with configurable concurrency
- 🔄 **Retry Mechanism**: Automatic retry with exponential backoff
- ⚡ **Performance**: Optimized for large datasets with virtual scrolling support
- 🎨 **Customizable**: Fully customizable card rendering and loading states
- 📱 **Responsive**: Mobile-friendly responsive design
- 🔧 **TypeScript**: Full TypeScript support
Render safe, declarative A2UI surfaces in React. The package supports A2UI v0.8 and v0.9 command streams, custom React component catalogs, data binding, actions, and an experimental headless Surface Runtime for validated transactional updates.

## Installation

```bash
npm install @ant-design/x-card
# or
yarn add @ant-design/x-card
# or
pnpm add @ant-design/x-card
npm install @ant-design/x-card antd
```

## Usage
React and React DOM are peer dependencies.

### Basic Usage
## Component renderer

```tsx
import React from 'react';
import { CardLoader } from '@ant-design/x-card';
Use `XCard.Box` to provide the command stream and component catalog, then render one or more surfaces with `XCard.Card`.

const App = () => {
const cards = [
{
id: '1',
title: 'Card 1',
content: 'This is card content',
},
{
id: '2',
title: 'Card 2',
content: 'Another card content',
```tsx
import XCard, { type XAgentCommand_v0_9 } from '@ant-design/x-card';
import { Button, Flex, Typography } from 'antd';

const Text = ({ text }: { text: string }) => <Typography.Text>{text}</Typography.Text>;

const commands: XAgentCommand_v0_9[] = [
{
version: 'v0.9',
createSurface: { surfaceId: 'welcome', catalogId: 'local://app' },
},
{
version: 'v0.9',
updateComponents: {
surfaceId: 'welcome',
components: [
{ id: 'root', component: 'Flex', children: ['title', 'confirm'], vertical: true },
{ id: 'title', component: 'Text', text: 'Ready to continue?' },
{
id: 'confirm',
component: 'Button',
child: 'confirm-label',
action: { event: { name: 'confirm' } },
},
{ id: 'confirm-label', component: 'Text', text: 'Confirm' },
],
},
];

return <CardLoader cards={cards} />;
};
},
];

export default () => (
<XCard.Box
commands={commands}
components={{ Button, Flex, Text }}
onAction={(action) => console.log(action)}
>
<XCard.Card id="welcome" />
</XCard.Box>
);
```

### Advanced Usage
For local or remote catalog setup, protocol command shapes, and complete demos, see the [x-card documentation](https://x.ant.design/x-cards/introduce).

```tsx
import React from 'react';
import { CardLoader, useCardLoader } from '@ant-design/x-card';

const App = () => {
const { state, actions } = useCardLoader({
config: {
maxConcurrent: 5,
retryCount: 3,
timeout: 10000,
},
customLoader: async (card) => {
// Custom loading logic
const response = await fetch(`/api/cards/${card.id}`);
const data = await response.json();
return data.content;
## Experimental Surface Runtime

The headless Runtime normalizes protocol-specific commands into immutable Surface snapshots and validates every transaction against a strict catalog before commit.

```ts
import { experimentalRuntime } from '@ant-design/x-card';

const catalogId = 'local://app';
const catalogs = experimentalRuntime.createSurfaceCatalogRegistry({
catalogs: [
{
$id: catalogId,
components: {
Text: {
type: 'object',
required: ['text'],
properties: { text: {} },
additionalProperties: false,
},
},
},
});

React.useEffect(() => {
actions.loadCards([
{ id: '1', title: 'Dynamic Card 1' },
{ id: '2', title: 'Dynamic Card 2' },
]);
}, []);

return (
<CardLoader
cards={state.cards}
renderLoading={(card) => <div>Loading {card.title}...</div>}
renderError={(error, card) => <div>Error: {error.message}</div>}
/>
);
};
],
});

const runtime = experimentalRuntime.createSurfaceRuntime({
catalogs,
adapters: [experimentalRuntime.a2uiV09Adapter],
});

await runtime.dispatch({
protocol: 'a2ui',
version: 'v0.9',
payload: {
version: 'v0.9',
createSurface: { surfaceId: 'welcome', catalogId },
},
});
```

### Using Hooks
The Runtime API is experimental and may change before it becomes a stable top-level export.

```tsx
import React from 'react';
import { useCardLoader } from '@ant-design/x-card';

const App = () => {
const { state, actions } = useCardLoader();

const addNewCard = () => {
actions.addCard({
id: Date.now().toString(),
title: 'New Card',
content: 'Dynamic content',
});
};

return (
<div>
<button onClick={addNewCard}>Add Card</button>
{state.cards.map((card) => (
<div key={card.id}>
<h3>{card.title}</h3>
<p>{card.content}</p>
</div>
))}
</div>
);
};
```
## Exports

## API

### CardLoader Props

| Property | Type | Default | Description |
| ---------------- | ------------------ | ------- | ----------------------------- |
| cards | CardLoaderConfig[] | [] | Array of card configurations |
| config | CardLoaderConfig | - | Loader configuration |
| customLoader | function | - | Custom card loading function |
| renderEmpty | function | - | Custom empty state renderer |
| renderLoading | function | - | Custom loading state renderer |
| renderError | function | - | Custom error state renderer |
| onLoadingChange | function | - | Loading state change callback |
| onCardLoad | function | - | Card load success callback |
| onCardError | function | - | Card load error callback |
| onAllCardsLoaded | function | - | All cards loaded callback |

### CardLoaderConfig

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| id | string | - | Unique card identifier |
| title | string | - | Card title |
| content | ReactNode | - | Card content |
| type | 'default' \| 'info' \| 'success' \| 'warning' \| 'error' | 'default' | Card type |
| loading | boolean | false | Loading state |
| closable | boolean | false | Whether card can be closed |
| size | 'small' \| 'middle' \| 'large' | 'middle' | Card size |
| disabled | boolean | false | Whether card is disabled |
| className | string | - | Custom CSS class |
| style | CSSProperties | - | Custom inline style |
| extra | ReactNode | - | Extra content in card header |

### useCardLoader Hook

Returns an object with:

- `state`: Current loader state
- `actions`: Available actions
- `addCard(card)`: Add a new card
- `removeCard(id)`: Remove a card
- `updateCard(id, updates)`: Update a card
- `reloadCard(id)`: Reload a card
- `clearCards()`: Clear all cards
- `getCardState(id)`: Get card state
- `loadCards(cards)`: Load multiple cards
| Export | Purpose |
| --- | --- |
| `XCard`, `Box`, `Card` | React A2UI rendering components |
| `registerCatalog`, `loadCatalog`, `validateComponent` | Renderer catalog utilities |
| `XAgentCommand_v0_8`, `XAgentCommand_v0_9` | Protocol command types |
| `experimentalRuntime` | Headless adapters, catalogs, transactions, snapshots, and rollback |

## Development

```bash
# Install dependencies
npm install

# Start development
npm run start

# Run tests
npm test

# Build
npm run compile
npm run tsc --workspace packages/x-card
npm test --workspace packages/x-card
npm run compile --workspace packages/x-card
```

## License
Expand Down
8 changes: 5 additions & 3 deletions packages/x-card/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
{
"name": "@ant-design/x-card",
"version": "2.8.0",
"description": "React card loader for dynamic content loading and management",
"description": "A2UI dynamic surfaces and production runtime for React",
"keywords": [
"A2UI",
"loader",
"agent UI",
"generative UI",
"runtime",
"react",
"ant-design"
],
"homepage": "https://x.ant.design/x-card",
"homepage": "https://x.ant.design/x-cards/introduce",
"bugs": {
"url": "https://github.com/ant-design/x/issues"
},
Expand Down
15 changes: 8 additions & 7 deletions packages/x-card/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
export { default as version } from './version';
export {
default as XCard,
type XAgentCommand_v0_9,
type XAgentCommand_v0_8,
type ActionPayload,
type Catalog,
type CatalogComponent,
registerCatalog,
clearCatalogCache,
default as XCard,
loadCatalog,
registerCatalog,
validateComponent,
clearCatalogCache,
type XAgentCommand_v0_8,
type XAgentCommand_v0_9,
} from './A2UI';
export { default as Card } from './A2UI/Card';
export { default as Box } from './A2UI/Box';
export { default as Card } from './A2UI/Card';
export * as experimentalRuntime from './runtime';
export { default as version } from './version';
Loading
Loading