Skip to content
Merged
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
520 changes: 406 additions & 114 deletions packages/x-markdown/src/XMarkdown/__test__/hooks.test.tsx

Large diffs are not rendered by default.

525 changes: 251 additions & 274 deletions packages/x-markdown/src/XMarkdown/hooks/useStreaming.ts

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion packages/x-markdown/src/XMarkdown/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ interface SteamingOption {
* @description Configuration for text appearance animation effects
*/
animationConfig?: AnimationConfig;
/**
* @description 未完成的 Markdown 格式转换为自定义加载组件的映射配置,用于在流式渲染过程中为未闭合的链接和图片提供自定义loading组件
* @description Mapping configuration to convert incomplete Markdown formats to custom loading components, used to provide custom loading components for unclosed links and images during streaming rendering
* @default { link: 'incomplete-link', image: 'incomplete-image' }
*/
incompleteMarkdownComponentMap?: {
link?: string;
image?: string;
};
}

type StreamStatus = 'loading' | 'done';
Expand Down Expand Up @@ -123,4 +132,4 @@ interface XMarkdownProps {
dompurifyConfig?: DOMPurifyConfig;
}

export type { XMarkdownProps, Token, Tokens, StreamStatus, ComponentProps };
export type { XMarkdownProps, Token, Tokens, StreamStatus, ComponentProps, SteamingOption };
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components-custom.en-US.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: Components
order: 2
order: 5
title: Custom Component
order: 4
---
Expand Down
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components-custom.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: 组件
order: 2
order: 5
title: Custom
subtitle: 自定义组件
order: 4
Expand Down
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components-data.en-US.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: Components
order: 2
order: 5
title: DataChart
order: 3
---
Expand Down
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components-data.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: 组件
order: 2
order: 5
title: DataChart
subtitle: 数据图表
order: 3
Expand Down
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components-think.en-US.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: Components
order: 2
order: 5
title: Think
order: 2
---
Expand Down
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components-think.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: 组件
order: 2
order: 5
title: Think
subtitle: 思考过程
order: 2
Expand Down
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components.en-US.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: Components
order: 2
order: 5
title: Overview
order: 1
---
Expand Down
2 changes: 1 addition & 1 deletion packages/x/docs/x-markdown/components.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
group:
title: 组件
order: 2
order: 5
title: 总览
order: 1
---
Expand Down
109 changes: 109 additions & 0 deletions packages/x/docs/x-markdown/demo/streaming/combined.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Bubble } from '@ant-design/x';
import XMarkdown from '@ant-design/x-markdown';
import { Button, Flex, Skeleton, Space, Switch, Typography } from 'antd';
import React, { useState } from 'react';
import { useMarkdownTheme } from '../_utils';
import '@ant-design/x-markdown/themes/light.css';
import '@ant-design/x-markdown/themes/dark.css';

const { Text } = Typography;

// 简化的示例文本
const text = `# Ant Design X

Ant Design X 是一款AI应用复合工具集,融合了 UI 组件库、流式 Markdown 渲染引擎和 AI SDK,为开发者提供构建下一代 AI 驱动应用的完整工具链。

![Ant Design X](https://mdn.alipayobjects.com/huamei_yz9z7c/afts/img/0lMhRYbo0-8AAAAAQDAAAAgADlJoAQFr/original)


基于 Ant Design 设计体系的 React UI 库、专为 AI 驱动界面设计,开箱即用的智能对话组件、无缝集成 API 服务,快速搭建智能应用界面,查看详情请点击 [Ant Design X](https://github.com/ant-design/x)。
`;

// 自定义加载组件
const LoadingComponents = {
'loading-link': () => (
<Skeleton.Button active size="small" style={{ margin: '4px 0', width: 16, height: 16 }} />
),
'loading-image': () => <Skeleton.Image active style={{ width: 60, height: 60 }} />,
};

const App: React.FC = () => {
const [enableAnimation, setEnableAnimation] = useState(true);
const [enableCache, setEnableCache] = useState(true);
const [isStreaming, setIsStreaming] = useState(false);
const [index, setIndex] = useState(0);
const [className] = useMarkdownTheme();
const timer = React.useRef<any>(-1);

const renderStream = () => {
if (index >= text.length) {
clearTimeout(timer.current);
setIsStreaming(false);
return;
}
timer.current = setTimeout(() => {
setIndex((prev) => prev + 1);
renderStream();
}, 50);
};

React.useEffect(() => {
if (index === text.length) return;
renderStream();
setIsStreaming(true);
return () => {
clearTimeout(timer.current);
};
}, [index]);

return (
<div style={{ padding: 24, maxWidth: 800, margin: '0 auto' }}>
<Flex vertical gap="middle">
<Flex gap="small" justify="end">
<Space>
<Text>动画</Text>
<Switch
checked={enableAnimation}
onChange={setEnableAnimation}
checkedChildren="开"
unCheckedChildren="关"
/>
</Space>
<Space>
<Text>语法处理</Text>
<Switch
checked={enableCache}
onChange={setEnableCache}
checkedChildren="开"
unCheckedChildren="关"
/>
</Space>
<Button style={{ alignSelf: 'flex-end' }} onClick={() => setIndex(0)}>
重新渲染
</Button>
</Flex>

<Bubble
content={text.slice(0, index)}
contentRender={(content) => (
<XMarkdown
className={className}
content={content as string}
streaming={{
hasNextChunk: isStreaming && enableCache,
enableAnimation,
incompleteMarkdownComponentMap: {
link: 'loading-link',
image: 'loading-image',
},
}}
components={LoadingComponents}
/>
)}
/>
</Flex>
</div>
);
};

export default App;
Loading
Loading