Skip to content

Commit 26024a3

Browse files
committed
nicer chat markdown
1 parent d0982a2 commit 26024a3

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

docs-website/src/components/docs-chat.tsx

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ import { MarkdownRendererProps, RenderFormPreview } from 'contesto'
4444
import { ErrorPreview, EditorToolPreview, ToolPreviewContainer, Dot } from './chat-tool-previews'
4545
import { ShowMore } from './show-more'
4646
import { useDisableBodyScroll } from '../lib/hooks'
47+
import { RenderNode } from 'safe-mdx'
48+
import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock'
4749

4850
export function ChatDrawer({ loaderData }: { loaderData?: unknown }) {
4951
const chatId = usePersistentDocsState((x) => x.chatId)
@@ -307,7 +309,7 @@ function ChatTopBar() {
307309
)
308310
}
309311

310-
function Chat({}) {
312+
function Chat({ }) {
311313
return (
312314
<ScrollArea className='[&>div>div]:grow -mr-4 [scrollbar-gutter:stable_both-edges] pr-4 relative items-stretch rounded max-h-full flex flex-col grow justify-center '>
313315
<div className='flex flex-col gap-4 relative h-full justify-center'>
@@ -319,8 +321,57 @@ function Chat({}) {
319321
)
320322
}
321323

324+
325+
export const renderChatNode: RenderNode = (node, transform) => {
326+
// TODO only enable colored bold in chat?
327+
if (node.type === 'strong') {
328+
return <span className='dark:text-rose-200 font-mono'>{node.children?.map((child) => transform(child))}</span>
329+
}
330+
if (node.type === 'emphasis') {
331+
return <span className='dark:text-emerald-200 font-mono'>{node.children?.map((child) => transform(child))}</span>
332+
}
333+
if (node.type === 'delete') {
334+
return <span className='dark:text-red-200 font-mono line-through'>{node.children?.map((child) => transform(child))}</span>
335+
}
336+
if (node.type === 'inlineCode') {
337+
return (
338+
<span className='dark:text-red-200 dark:bg-red-950/30 px-1 rounded font-mono text-[0.9em]'>{node.value}</span>
339+
)
340+
}
341+
342+
if (
343+
node.type === 'heading'
344+
) {
345+
return (
346+
<span className='font-semibold font-mono dark:text-purple-300'>
347+
{node.children?.map((child) => transform(child))}
348+
</span>
349+
)
350+
}
351+
352+
if (node.type === 'code') {
353+
const language = node.lang || ''
354+
355+
const html = node.data?.['html']
356+
const props = {
357+
title: '',
358+
...(node.data?.hProperties ?? {}),
359+
360+
lang: language,
361+
}
362+
363+
return (
364+
<CodeBlock {...props}>
365+
<Pre>{html ? <div className='content' dangerouslySetInnerHTML={{ __html: html }}></div> : node.value}</Pre>
366+
</CodeBlock>
367+
)
368+
}
369+
}
370+
371+
372+
322373
export function ChatMarkdown({ ...rest }: MarkdownRendererProps) {
323-
return <MarkdownRuntime addMarkdownLineNumbers={false} isStreaming={true} {...rest} extension='md' />
374+
return <MarkdownRuntime addMarkdownLineNumbers={false} renderNode={renderChatNode} isStreaming={true} {...rest} extension='md' />
324375
}
325376

326377
function WelcomeMessage() {
@@ -615,7 +666,7 @@ function Footer() {
615666
.map((file) => `@${file.path.replace(/\.mdx\?$/, '')}`)
616667

617668
return (
618-
<AnimatePresence custom={false} onExitComplete={() => {}}>
669+
<AnimatePresence custom={false} onExitComplete={() => { }}>
619670
<div className=' sticky bottom-4 z-50 w-full mt-4'>
620671
<motion.div
621672
layoutId='textarea'

0 commit comments

Comments
 (0)