1
1
'use client' ;
2
2
3
3
import { cva } from 'class-variance-authority' ;
4
- import { memo , useCallback , useMemo } from 'react' ;
5
- import ReactMarkdown from 'react-markdown' ;
6
- import type { Components } from 'react-markdown/lib' ;
4
+ import { memo , useMemo } from 'react' ;
7
5
8
- import { PreviewGroup } from '@/Image' ;
9
- import Image from '@/mdx/mdxComponents/Image' ;
10
- import Link from '@/mdx/mdxComponents/Link' ;
11
- import Section from '@/mdx/mdxComponents/Section' ;
12
- import Video from '@/mdx/mdxComponents/Video' ;
13
-
14
- import { CodeFullFeatured , CodeLite } from './CodeBlock' ;
6
+ import SyntaxMarkdown from './SyntaxMarkdown' ;
15
7
import Typography from './Typography' ;
16
8
import { useStyles } from './style' ;
17
9
import type { MarkdownProps } from './type' ;
18
- import {
19
- addToCache ,
20
- contentCache ,
21
- createPlugins ,
22
- escapeBrackets ,
23
- escapeMhchem ,
24
- fixMarkdownBold ,
25
- transformCitations ,
26
- } from './utils' ;
27
10
28
11
const Markdown = memo < MarkdownProps > (
29
12
( {
@@ -33,6 +16,7 @@ const Markdown = memo<MarkdownProps>(
33
16
style,
34
17
fullFeaturedCodeBlock,
35
18
onDoubleClick,
19
+ animated,
36
20
enableLatex = true ,
37
21
enableMermaid = true ,
38
22
enableImageGallery = true ,
@@ -55,12 +39,13 @@ const Markdown = memo<MarkdownProps>(
55
39
...rest
56
40
} ) => {
57
41
const { cx, styles } = useStyles ( ) ;
58
- const isChatMode = variant === 'chat' ;
59
42
43
+ // Style variant handling
60
44
const variants = useMemo (
61
45
( ) =>
62
46
cva ( styles . root , {
63
47
defaultVariants : {
48
+ animated : false ,
64
49
enableLatex : true ,
65
50
variant : 'default' ,
66
51
} ,
@@ -74,158 +59,19 @@ const Markdown = memo<MarkdownProps>(
74
59
true : styles . latex ,
75
60
false : null ,
76
61
} ,
62
+ animated : {
63
+ true : styles . animated ,
64
+ false : null ,
65
+ } ,
77
66
} ,
78
67
/* eslint-enable sort-keys-fix/sort-keys-fix */
79
68
} ) ,
80
69
[ styles ] ,
81
70
) ;
82
71
83
- // 计算缓存键
84
- const cacheKey = useMemo ( ( ) => {
85
- return `${ children } -${ enableLatex } -${ enableCustomFootnotes } -${ citations ?. length || 0 } ` ;
86
- } , [ children , enableLatex , enableCustomFootnotes , citations ?. length ] ) ;
87
-
88
- // 处理内容并利用缓存避免重复计算
89
- const escapedContent = useMemo ( ( ) => {
90
- // 尝试从缓存获取
91
- if ( contentCache . has ( cacheKey ) ) {
92
- return contentCache . get ( cacheKey ) ;
93
- }
94
-
95
- // 处理新内容
96
- let processedContent ;
97
- if ( enableLatex ) {
98
- const baseContent = fixMarkdownBold ( escapeMhchem ( escapeBrackets ( children ) ) ) ;
99
- processedContent = enableCustomFootnotes
100
- ? transformCitations ( baseContent , citations ?. length )
101
- : baseContent ;
102
- } else {
103
- processedContent = fixMarkdownBold ( children ) ;
104
- }
105
-
106
- // 缓存处理结果
107
- addToCache ( cacheKey , processedContent ) ;
108
- return processedContent ;
109
- } , [ cacheKey , children , enableLatex , enableCustomFootnotes , citations ?. length ] ) ;
110
-
111
- // 创建插件
112
- const { rehypePluginsList, remarkPluginsList } = useMemo (
113
- ( ) =>
114
- createPlugins ( {
115
- allowHtml,
116
- enableCustomFootnotes,
117
- enableLatex,
118
- isChatMode,
119
- rehypePlugins,
120
- remarkPlugins,
121
- remarkPluginsAhead,
122
- } ) ,
123
- [
124
- allowHtml ,
125
- enableLatex ,
126
- enableCustomFootnotes ,
127
- isChatMode ,
128
- rehypePlugins ,
129
- remarkPlugins ,
130
- remarkPluginsAhead ,
131
- ] ,
132
- ) ;
133
-
134
- // 使用 useCallback 优化渲染子组件
135
- const renderLink = useCallback (
136
- ( props : any ) => < Link citations = { citations } { ...props } { ...componentProps ?. a } /> ,
137
- [ citations , componentProps ?. a ] ,
138
- ) ;
139
-
140
- const renderImage = useCallback (
141
- ( props : any ) => < Image { ...props } { ...componentProps ?. img } /> ,
142
- [ isChatMode , componentProps ?. img ] ,
143
- ) ;
144
-
145
- const renderCodeBlock = useCallback (
146
- ( props : any ) =>
147
- fullFeaturedCodeBlock ? (
148
- < CodeFullFeatured
149
- enableMermaid = { enableMermaid }
150
- highlight = { componentProps ?. highlight }
151
- mermaid = { componentProps ?. mermaid }
152
- { ...props }
153
- { ...componentProps ?. pre }
154
- />
155
- ) : (
156
- < CodeLite
157
- enableMermaid = { enableMermaid }
158
- highlight = { componentProps ?. highlight }
159
- mermaid = { componentProps ?. mermaid }
160
- { ...props }
161
- { ...componentProps ?. pre }
162
- />
163
- ) ,
164
- [
165
- enableMermaid ,
166
- fullFeaturedCodeBlock ,
167
- componentProps ?. highlight ,
168
- componentProps ?. mermaid ,
169
- componentProps ?. pre ,
170
- ] ,
171
- ) ;
172
-
173
- const renderSection = useCallback (
174
- ( props : any ) => < Section showCitations = { showFootnotes } { ...props } /> ,
175
- [ showFootnotes ] ,
176
- ) ;
177
-
178
- const renderVideo = useCallback (
179
- ( props : any ) => < Video { ...props } { ...componentProps ?. video } /> ,
180
- [ componentProps ?. video ] ,
181
- ) ;
182
-
183
- // 创建组件映射
184
- const memoComponents = useMemo (
185
- ( ) => ( {
186
- a : renderLink ,
187
- img : enableImageGallery ? renderImage : undefined ,
188
- pre : renderCodeBlock ,
189
- section : renderSection ,
190
- video : renderVideo ,
191
- ...components ,
192
- } ) ,
193
- [
194
- renderLink ,
195
- renderImage ,
196
- renderCodeBlock ,
197
- renderSection ,
198
- renderVideo ,
199
- enableImageGallery ,
200
- components ,
201
- ] ,
202
- ) as Components ;
203
-
204
- // 渲染默认内容
205
- const defaultDOM = useMemo (
206
- ( ) => (
207
- < PreviewGroup enable = { enableImageGallery } >
208
- < ReactMarkdown
209
- { ...reactMarkdownProps }
210
- components = { memoComponents }
211
- rehypePlugins = { rehypePluginsList }
212
- remarkPlugins = { remarkPluginsList }
213
- >
214
- { escapedContent }
215
- </ ReactMarkdown >
216
- </ PreviewGroup >
217
- ) ,
218
- [ escapedContent , memoComponents , rehypePluginsList , remarkPluginsList , enableImageGallery ] ,
219
- ) ;
220
-
221
- // 应用自定义渲染
222
- const markdownContent = customRender
223
- ? customRender ( defaultDOM , { text : escapedContent || '' } )
224
- : defaultDOM ;
225
-
226
72
return (
227
73
< Typography
228
- className = { cx ( variants ( { enableLatex, variant } ) , className ) }
74
+ className = { cx ( variants ( { animated , enableLatex, variant } ) , className ) }
229
75
data-code-type = "markdown"
230
76
fontSize = { fontSize }
231
77
headerMultiple = { headerMultiple }
@@ -236,7 +82,27 @@ const Markdown = memo<MarkdownProps>(
236
82
style = { style }
237
83
{ ...rest }
238
84
>
239
- { markdownContent }
85
+ < SyntaxMarkdown
86
+ allowHtml = { allowHtml }
87
+ animated = { animated }
88
+ citations = { citations }
89
+ componentProps = { componentProps }
90
+ components = { components }
91
+ customRender = { customRender }
92
+ enableCustomFootnotes = { enableCustomFootnotes }
93
+ enableImageGallery = { enableImageGallery }
94
+ enableLatex = { enableLatex }
95
+ enableMermaid = { enableMermaid }
96
+ fullFeaturedCodeBlock = { fullFeaturedCodeBlock }
97
+ reactMarkdownProps = { reactMarkdownProps }
98
+ rehypePlugins = { rehypePlugins }
99
+ remarkPlugins = { remarkPlugins }
100
+ remarkPluginsAhead = { remarkPluginsAhead }
101
+ showFootnotes = { showFootnotes }
102
+ variant = { variant }
103
+ >
104
+ { children }
105
+ </ SyntaxMarkdown >
240
106
</ Typography >
241
107
) ;
242
108
} ,
0 commit comments