@@ -115,133 +115,7 @@ export const ChatHistoryComponent: React.FC<ChatHistoryComponentProps> = ({
115115
116116 < div className = "aiMarkup lh-base text-wrap" >
117117 { msg . role === 'assistant' ? (
118- < ReactMarkdown
119- remarkPlugins = { [ [ remarkGfm , { } ] ] }
120- remarkRehypeOptions = { {
121- } }
122- rehypePlugins = { [ rehypeRaw , rehypeSanitize ] }
123- linkTarget = "_blank"
124- components = { {
125- // Code blocks and inline code
126- code ( { node, inline, className, children, ...props } ) {
127- const text = String ( children ) . replace ( / \n $ / , '' )
128- const match = / l a n g u a g e - ( \w + ) / . exec ( className || '' )
129- const language = match ? match [ 1 ] : ''
130- if ( inline ) {
131- return (
132- < code className = "ai-inline-code" { ...props } >
133- { text }
134- </ code >
135- )
136- }
137- return (
138- < div className = "ai-code-block-wrapper" >
139- { language && (
140- < div className = { `ai-code-header ${ theme === 'Dark' ? 'text-white' : 'text-dark' } ` } >
141- < span className = "ai-code-language" > { language } </ span >
142- < button
143- type = "button"
144- className = "btn btn-sm btn-outline-info border border-info"
145- onClick = { ( ) => copy ( text ) }
146- title = "Copy code"
147- >
148- < i className = "fa-regular fa-copy" > </ i >
149- </ button >
150- </ div >
151- ) }
152- { ! language && (
153- < button
154- type = "button"
155- className = "ai-copy-btn ai-copy-btn-absolute"
156- onClick = { ( ) => copy ( text ) }
157- title = "Copy code"
158- >
159- < i className = "fa-regular fa-copy" > </ i >
160- </ button >
161- ) }
162- < pre className = "ai-code-pre" >
163- < code className = { className } > { text } </ code >
164- </ pre >
165- </ div >
166- )
167- } ,
168- // Paragraphs
169- p : ( { node, ...props } ) => (
170- < p className = "ai-paragraph" { ...props } />
171- ) ,
172- // Headings
173- h1 : ( { node, ...props } ) => (
174- < h1 className = "ai-heading ai-h1 fs-5 mb-1" { ...props } />
175- ) ,
176- h2 : ( { node, ...props } ) => (
177- < h2 className = "ai-heading ai-h2 fs-5 mb-1" { ...props } />
178- ) ,
179- h3 : ( { node, ...props } ) => (
180- < h3 className = "ai-heading ai-h3 fs-5 mb-1" { ...props } />
181- ) ,
182- h4 : ( { node, ...props } ) => (
183- < h4 className = "ai-heading ai-h4 fs-6 mb-1" { ...props } />
184- ) ,
185- h5 : ( { node, ...props } ) => (
186- < h5 className = "ai-heading ai-h5 fs-6 mb-1" { ...props } />
187- ) ,
188- h6 : ( { node, ...props } ) => (
189- < h6 className = "ai-heading ai-h6 fs-6 mb-1" { ...props } />
190- ) ,
191- // Lists
192- ul : ( { node, ...props } ) => (
193- < ul className = "ai-list ai-list-unordered" { ...props } />
194- ) ,
195- ol : ( { node, ...props } ) => (
196- < ol className = "ai-list ai-list-ordered" { ...props } />
197- ) ,
198- li : ( { node, ...props } ) => (
199- < li className = "ai-list-item" { ...props } />
200- ) ,
201- // Links
202- a : ( { node, ...props } ) => (
203- < a className = "ai-link" target = "_blank" rel = "noopener noreferrer" { ...props } />
204- ) ,
205- // Blockquotes
206- blockquote : ( { node, ...props } ) => (
207- < blockquote className = "ai-blockquote" { ...props } />
208- ) ,
209- // Tables
210- table : ( { node, ...props } ) => (
211- < div className = "ai-table-wrapper" >
212- < table className = "ai-table" { ...props } />
213- </ div >
214- ) ,
215- thead : ( { node, ...props } ) => (
216- < thead className = "ai-table-head" { ...props } />
217- ) ,
218- tbody : ( { node, ...props } ) => (
219- < tbody className = "ai-table-body" { ...props } />
220- ) ,
221- tr : ( { node, ...props } ) => (
222- < tr className = "ai-table-row" { ...props } />
223- ) ,
224- th : ( { node, ...props } ) => (
225- < th className = "ai-table-header-cell" { ...props } />
226- ) ,
227- td : ( { node, ...props } ) => (
228- < td className = "ai-table-cell" { ...props } />
229- ) ,
230- // Horizontal rule
231- hr : ( { node, ...props } ) => (
232- < hr className = "ai-divider" { ...props } />
233- ) ,
234- // Strong and emphasis
235- strong : ( { node, ...props } ) => (
236- < strong className = "ai-strong" { ...props } />
237- ) ,
238- em : ( { node, ...props } ) => (
239- < em className = "ai-emphasis" { ...props } />
240- )
241- } }
242- >
243- { normalizeMarkdown ( msg . content ) }
244- </ ReactMarkdown >
118+ RemixMarkdownViewer ( theme , msg . content )
245119 ) : (
246120 msg . content
247121 ) }
@@ -297,3 +171,132 @@ export const ChatHistoryComponent: React.FC<ChatHistoryComponentProps> = ({
297171 )
298172}
299173
174+ function RemixMarkdownViewer ( theme : string , markDownContent : string ) : React . ReactNode {
175+ return < ReactMarkdown
176+ remarkPlugins = { [ [ remarkGfm , { } ] ] }
177+ remarkRehypeOptions = { { } }
178+ rehypePlugins = { [ rehypeRaw , rehypeSanitize ] }
179+ linkTarget = "_blank"
180+ components = { {
181+ // Code blocks and inline code
182+ code ( { node, inline, className, children, ...props } ) {
183+ const text = String ( children ) . replace ( / \n $ / , '' )
184+ const match = / l a n g u a g e - ( \w + ) / . exec ( className || '' )
185+ const language = match ? match [ 1 ] : ''
186+ if ( inline ) {
187+ return (
188+ < code className = "ai-inline-code" { ...props } >
189+ { text }
190+ </ code >
191+ )
192+ }
193+ return (
194+ < div className = "ai-code-block-wrapper" >
195+ { language && (
196+ < div className = { `ai-code-header ${ theme === 'Dark' ? 'text-white' : 'text-dark' } ` } >
197+ < span className = "ai-code-language" > { language } </ span >
198+ < button
199+ type = "button"
200+ className = "btn btn-sm btn-outline-info border border-info"
201+ onClick = { ( ) => copy ( text ) }
202+ title = "Copy code"
203+ >
204+ < i className = "fa-regular fa-copy" > </ i >
205+ </ button >
206+ </ div >
207+ ) }
208+ { ! language && (
209+ < button
210+ type = "button"
211+ className = "ai-copy-btn ai-copy-btn-absolute"
212+ onClick = { ( ) => copy ( text ) }
213+ title = "Copy code"
214+ >
215+ < i className = "fa-regular fa-copy" > </ i >
216+ </ button >
217+ ) }
218+ < pre className = "ai-code-pre" >
219+ < code className = { className } > { text } </ code >
220+ </ pre >
221+ </ div >
222+ )
223+ } ,
224+ // Paragraphs
225+ p : ( { node, ...props } ) => (
226+ < p className = "ai-paragraph" { ...props } />
227+ ) ,
228+ // Headings
229+ h1 : ( { node, ...props } ) => (
230+ < h1 className = "ai-heading ai-h1 fs-5 mb-1" { ...props } />
231+ ) ,
232+ h2 : ( { node, ...props } ) => (
233+ < h2 className = "ai-heading ai-h2 fs-5 mb-1" { ...props } />
234+ ) ,
235+ h3 : ( { node, ...props } ) => (
236+ < h3 className = "ai-heading ai-h3 fs-5 mb-1" { ...props } />
237+ ) ,
238+ h4 : ( { node, ...props } ) => (
239+ < h4 className = "ai-heading ai-h4 fs-6 mb-1" { ...props } />
240+ ) ,
241+ h5 : ( { node, ...props } ) => (
242+ < h5 className = "ai-heading ai-h5 fs-6 mb-1" { ...props } />
243+ ) ,
244+ h6 : ( { node, ...props } ) => (
245+ < h6 className = "ai-heading ai-h6 fs-6 mb-1" { ...props } />
246+ ) ,
247+ // Lists
248+ ul : ( { node, ...props } ) => (
249+ < ul className = "ai-list ai-list-unordered" { ...props } />
250+ ) ,
251+ ol : ( { node, ...props } ) => (
252+ < ol className = "ai-list ai-list-ordered" { ...props } />
253+ ) ,
254+ li : ( { node, ...props } ) => (
255+ < li className = "ai-list-item" { ...props } />
256+ ) ,
257+ // Links
258+ a : ( { node, ...props } ) => (
259+ < a className = "ai-link" target = "_blank" rel = "noopener noreferrer" { ...props } />
260+ ) ,
261+ // Blockquotes
262+ blockquote : ( { node, ...props } ) => (
263+ < blockquote className = "ai-blockquote" { ...props } />
264+ ) ,
265+ // Tables
266+ table : ( { node, ...props } ) => (
267+ < div className = "ai-table-wrapper" >
268+ < table className = "ai-table" { ...props } />
269+ </ div >
270+ ) ,
271+ thead : ( { node, ...props } ) => (
272+ < thead className = "ai-table-head" { ...props } />
273+ ) ,
274+ tbody : ( { node, ...props } ) => (
275+ < tbody className = "ai-table-body" { ...props } />
276+ ) ,
277+ tr : ( { node, ...props } ) => (
278+ < tr className = "ai-table-row" { ...props } />
279+ ) ,
280+ th : ( { node, ...props } ) => (
281+ < th className = "ai-table-header-cell" { ...props } />
282+ ) ,
283+ td : ( { node, ...props } ) => (
284+ < td className = "ai-table-cell" { ...props } />
285+ ) ,
286+ // Horizontal rule
287+ hr : ( { node, ...props } ) => (
288+ < hr className = "ai-divider" { ...props } />
289+ ) ,
290+ // Strong and emphasis
291+ strong : ( { node, ...props } ) => (
292+ < strong className = "ai-strong" { ...props } />
293+ ) ,
294+ em : ( { node, ...props } ) => (
295+ < em className = "ai-emphasis" { ...props } />
296+ )
297+ } }
298+ >
299+ { normalizeMarkdown ( markDownContent ) }
300+ </ ReactMarkdown >
301+ }
302+
0 commit comments