Files
test1/components/nova-sdk/task-panel/Preview/MarkdownPreview.tsx
2026-03-20 07:33:46 +00:00

66 lines
1.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react'
import ReactMarkdown from 'react-markdown'
import { ScrollArea } from '@/components/ui/scroll-area'
import remarkGfm from 'remark-gfm'
import { cn } from '@/utils/cn'
export interface MarkdownPreviewProps {
/** Markdown 文件的 URL */
url: string
}
export interface MarkdownContentProps {
/** 直接传入 Markdown 字符串 */
content: string
className?: string
}
/**
* 内联 Markdown 渲染组件 - 接收字符串内容直接渲染
*/
export function MarkdownContent({ content, className }: MarkdownContentProps) {
return (
<div className={cn('prose prose-sm max-w-none dark:prose-invert break-words', className)}>
<ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>
</div>
)
}
/**
* Markdown 预览组件 - 接收 URLfetch 内容后渲染
*/
export function MarkdownPreview({ url }: MarkdownPreviewProps) {
const [content, setContent] = React.useState<string>('')
const [loading, setLoading] = React.useState(true)
React.useEffect(() => {
if (!url) return
setLoading(true)
fetch(url)
.then(res => res.text())
.then(text => setContent(text))
.catch(() => setContent('加载失败'))
.finally(() => setLoading(false))
}, [url])
if (loading) {
return (
<div className="flex-1 flex flex-col items-center justify-center p-8 text-muted-foreground h-full">
<div className="w-8 h-8 border-2 border-muted border-t-primary rounded-full animate-spin" />
<span className="text-sm mt-2">...</span>
</div>
)
}
return (
<ScrollArea className="h-full">
<div className="p-6 pt-14 prose prose-sm max-w-none dark:prose-invert">
<ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>
</div>
</ScrollArea>
)
}
export default MarkdownPreview