Skip to content

Commit 8fba99c

Browse files
committed
refactor(x-markdown-demo): optimize the style and interaction of the streaming rendering demo
1 parent 6f10556 commit 8fba99c

File tree

2 files changed

+68
-40
lines changed

2 files changed

+68
-40
lines changed

packages/x-markdown/src/XMarkdown/hooks/useStreaming.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ const recognize = (cache: StreamCache, tokenType: StreamCacheTokenType): void =>
125125

126126
if (token === tokenType && !recognizer.isStreamingValid(pending)) {
127127
const prefix = recognizer.getCommitPrefix?.(pending);
128-
if (prefix != null) {
128+
if (prefix) {
129129
cache.completeMarkdown += prefix;
130130
cache.pending = pending.slice(prefix.length);
131131
cache.token = StreamCacheTokenType.Text;

packages/x/docs/x-markdown/demo/streaming/format.tsx

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Welcome } from '@ant-design/x';
22
import XMarkdown, { type ComponentProps } from '@ant-design/x-markdown';
3-
import { Button, Card, Skeleton, theme } from 'antd';
3+
import { Button, Card, Segmented, Skeleton, theme } from 'antd';
44
import React, { useState } from 'react';
55

66
const demos = [
@@ -52,8 +52,7 @@ Provides a complete set of **tool APIs**. [Click here for details.](/x-sdks/intr
5252
},
5353
{
5454
title: 'Table',
55-
content: `
56-
| Repo | Description |
55+
content: `| Repo | Description |
5756
| ------ | ----------- |
5857
| @ant-design/x | A React UI library based on the Ant Design system. |
5958
| @ant-design/x-markdown | An optimized Markdown rendering solution for streaming content. |
@@ -139,6 +138,19 @@ const StreamDemo: React.FC<{ content: string }> = ({ content }) => {
139138
const [index, setIndex] = React.useState(0);
140139
const timer = React.useRef<NodeJS.Timeout | null>(null);
141140
const contentRef = React.useRef<HTMLDivElement>(null);
141+
const sourceRef = React.useRef<HTMLDivElement>(null);
142+
143+
const scrollToBottom = React.useCallback(
144+
(el: HTMLDivElement | null) => {
145+
if (el && index > 0) {
146+
const { scrollHeight, clientHeight } = el;
147+
if (scrollHeight > clientHeight) {
148+
el.scrollTo({ top: scrollHeight, behavior: 'smooth' });
149+
}
150+
}
151+
},
152+
[index],
153+
);
142154

143155
React.useEffect(() => {
144156
if (index >= content.length) {
@@ -159,32 +171,46 @@ const StreamDemo: React.FC<{ content: string }> = ({ content }) => {
159171
}, [index]);
160172

161173
React.useEffect(() => {
162-
if (contentRef.current && index > 0 && index < content.length) {
163-
const { scrollHeight, clientHeight } = contentRef.current;
164-
if (scrollHeight > clientHeight) {
165-
contentRef.current.scrollTo({
166-
top: scrollHeight,
167-
behavior: 'smooth',
168-
});
169-
}
174+
if (index > 0) {
175+
scrollToBottom(sourceRef.current);
176+
scrollToBottom(contentRef.current);
170177
}
171-
}, [index]);
178+
}, [index, scrollToBottom]);
179+
180+
const isLongContent = content.length > 500;
181+
const previewMinHeight = isLongContent ? 320 : 160;
182+
const previewMaxHeight = isLongContent ? 420 : 280;
172183

173184
return (
174-
<div style={{ display: 'flex', gap: 16, width: '100%' }}>
175-
<Card title="Markdown Source" size="small" style={{ flex: 1 }}>
185+
<div
186+
style={{
187+
display: 'flex',
188+
gap: 16,
189+
width: '100%',
190+
minHeight: previewMinHeight,
191+
maxHeight: previewMaxHeight,
192+
transition: 'max-height 0.25s ease',
193+
}}
194+
>
195+
<Card
196+
title="Markdown Source"
197+
size="small"
198+
style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}
199+
styles={{ body: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' } }}
200+
>
176201
<div
202+
ref={sourceRef}
177203
style={{
178-
background: '#f5f5f5',
204+
flex: 1,
205+
minHeight: 0,
206+
background: 'var(--ant-color-fill-quaternary)',
179207
padding: 12,
180-
borderRadius: 4,
181-
fontSize: 13,
182-
fontFamily: 'monospace',
208+
borderRadius: 6,
183209
whiteSpace: 'pre-wrap',
184210
wordBreak: 'break-word',
185-
margin: 0,
186-
height: 600,
187211
overflow: 'auto',
212+
fontSize: 12,
213+
lineHeight: 1.5,
188214
}}
189215
>
190216
{content.slice(0, index)}
@@ -194,26 +220,31 @@ const StreamDemo: React.FC<{ content: string }> = ({ content }) => {
194220
<Card
195221
title="Rendered Output"
196222
size="small"
197-
style={{ flex: 1, overflow: 'scroll' }}
223+
style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}
224+
styles={{ body: { flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' } }}
198225
extra={
199226
<Button
200-
type="primary"
201-
onClick={() => {
227+
onClick={(e) => {
228+
e.preventDefault();
202229
setIndex(0);
203230
setHasNextChunk(true);
204231
}}
232+
size="small"
205233
>
206234
Re-Render
207235
</Button>
208236
}
209237
>
210238
<div
239+
ref={contentRef}
211240
style={{
212-
border: '1px solid #f0f0f0',
213-
borderRadius: 4,
241+
flex: 1,
242+
minHeight: 0,
243+
overflow: 'auto',
214244
padding: 12,
215-
maxHeight: 800,
216-
overflow: 'scroll',
245+
borderRadius: 6,
246+
border: '1px solid var(--ant-color-border-secondary)',
247+
background: 'var(--ant-color-bg-container)',
217248
}}
218249
>
219250
<XMarkdown
@@ -243,18 +274,15 @@ const App = () => {
243274
const [currentDemo, setCurrentDemo] = useState(0);
244275

245276
return (
246-
<div style={{ padding: 24 }}>
247-
{demos.map((demo, index) => (
248-
<Button
249-
key={index}
250-
type={currentDemo === index ? 'primary' : 'default'}
251-
onClick={() => setCurrentDemo(index)}
252-
style={{ marginRight: 8, marginBottom: 8 }}
253-
>
254-
{demo.title}
255-
</Button>
256-
))}
257-
277+
<div style={{ maxWidth: 960, margin: '0 auto' }}>
278+
<div style={{ marginBottom: 16 }}>
279+
<Segmented
280+
value={currentDemo}
281+
onChange={(v) => setCurrentDemo(Number(v))}
282+
options={demos.map((demo, index) => ({ label: demo.title, value: index }))}
283+
block
284+
/>
285+
</div>
258286
<StreamDemo key={currentDemo} content={demos[currentDemo].content} />
259287
</div>
260288
);

0 commit comments

Comments
 (0)