Files
gongxue-base/apps/admin/src/components/AiChat/LiteMermaid.tsx

46 lines
1.5 KiB
TypeScript
Raw 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 { useEffect, useRef, useState } from 'react';
import { useIsMounted } from 'usehooks-ts';
interface LiteMermaidProps {
children: string;
}
/**
* 轻量 Mermaid 渲染:动态 import mermaid只有出现 mermaid 代码块时才加载
* mermaid 及其解析器/图布局依赖,避免随 AI 抽屉主包一起加载。
*/
export function LiteMermaid({ children }: LiteMermaidProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [error, setError] = useState<string | null>(null);
const isMounted = useIsMounted();
useEffect(() => {
const container = containerRef.current;
if (!container) return;
void (async () => {
try {
const mermaid = (await import('mermaid')).default;
mermaid.initialize({ startOnLoad: false, theme: 'neutral', securityLevel: 'strict' });
const { svg } = await mermaid.render(`mermaid-${crypto.randomUUID()}`, children);
if (isMounted()) {
const doc = new DOMParser().parseFromString(svg, 'image/svg+xml');
container.replaceChildren(doc.documentElement);
setError(null);
}
} catch (e) {
if (isMounted()) {
setError(e instanceof Error ? e.message : '图表渲染失败');
}
}
})();
}, [children]);
if (error) {
return (
<pre style={{ whiteSpace: 'pre-wrap', color: '#cf1322', fontSize: 12 }}>{children}</pre>
);
}
return <div ref={containerRef} className="ai-chat-mermaid" />;
}