From 98856b39acefb26f28f8b855707a638204426e9a Mon Sep 17 00:00:00 2001 From: ManishMadan2882 Date: Tue, 6 May 2025 00:53:33 +0530 Subject: [PATCH] (feat:mermaid) zoom onhover, throw syntax errors --- frontend/src/components/MermaidRenderer.tsx | 46 +++++++++------------ 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/MermaidRenderer.tsx b/frontend/src/components/MermaidRenderer.tsx index d2ca1276..ef3e9222 100644 --- a/frontend/src/components/MermaidRenderer.tsx +++ b/frontend/src/components/MermaidRenderer.tsx @@ -4,19 +4,18 @@ import CopyButton from './CopyButton'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { oneLight, vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism'; import { MermaidRendererProps } from './types'; +import { useSelector } from 'react-redux'; +import { selectStatus } from '../conversation/conversationSlice'; const MermaidRenderer: React.FC = ({ code, isDarkTheme, }) => { const diagramId = useRef(`mermaid-${crypto.randomUUID()}`); - // const status = useSelector(selectStatus); - const [localStatus, setLocalStatus] = useState<'loading' | 'idle'>('loading'); - const [svgContent, setSvgContent] = useState(''); + const status = useSelector(selectStatus); const [error, setError] = useState(null); const [showCode, setShowCode] = useState(false); const [showDownloadMenu, setShowDownloadMenu] = useState(false); - const [zoomLevel, setZoomLevel] = useState(1); const downloadMenuRef = useRef(null); const containerRef = useRef(null); const [hoverPosition, setHoverPosition] = useState<{ x: number, y: number } | null>(null); @@ -43,11 +42,7 @@ const MermaidRenderer: React.FC = ({ return `${hoverPosition.x * 100}% ${hoverPosition.y * 100}%`; }; useEffect(() => { - if (!code) { - setLocalStatus('idle'); - return; - } - setLocalStatus('loading'); + if (status === 'loading' || !code) return; mermaid.initialize({ startOnLoad: true, @@ -58,10 +53,11 @@ const MermaidRenderer: React.FC = ({ const renderDiagram = async (): Promise => { try { + await mermaid.parse(code); //throws syntax errors + const element = document.getElementById(diagramId.current); if (element) { element.removeAttribute('data-processed'); - element.innerHTML = code; mermaid.contentLoaded(); const svgElement = element.querySelector('svg'); @@ -73,27 +69,22 @@ const MermaidRenderer: React.FC = ({ svgElement.removeAttribute('viewBox'); - setSvgContent(svgElement.outerHTML); } setError(null); - setLocalStatus('idle'); } } catch (err) { + setError( `Failed to render Mermaid diagram: ${err instanceof Error ? err.message : String(err)}` ); - setSvgContent(''); - setLocalStatus('idle'); } }; renderDiagram(); + }, [code, isDarkTheme]); - useEffect(() => { - setZoomLevel(1); - }, [code]); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { @@ -241,11 +232,13 @@ const MermaidRenderer: React.FC = ({ { label: 'Download as MMD', action: downloadMmd }, ]; - const showDiagramOptions = localStatus !== 'loading' && !error; - const errorRender = localStatus !== 'loading' && error; + const showDiagramOptions = status !== 'loading' && !error; + const errorRender = status !== 'loading' && error; + + return ( -
+
mermaid @@ -300,7 +293,7 @@ const MermaidRenderer: React.FC = ({
- {localStatus === 'loading' ? ( + {status === 'loading' ? (
Loading diagram... @@ -316,22 +309,23 @@ const MermaidRenderer: React.FC = ({ <>
-
= ({ }} > {code} -
+
{showCode && (