Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 'use client' import { useEffect, useRef, useState } from 'react' import { css } from '../../../styled-system/css' interface MermaidViewerProps { /** Raw mermaid content */ mermaidContent: string } /** * Simple mermaid diagram viewer without node highlighting. * Used for static display of flowcharts. */ export function MermaidViewer({ mermaidContent }: MermaidViewerProps) { const containerRef = useRef<HTMLDivElement>(null) const [error, setError] = useState<string | null>(null) useEffect(() => { if (!containerRef.current || !mermaidContent) return const render = async () => { const mermaid = (await import('mermaid')).default // Initialize mermaid with basic settings mermaid.initialize({ startOnLoad: false, theme: 'base', themeVariables: { primaryColor: '#e3f2fd', primaryTextColor: '#1a1a1a', primaryBorderColor: '#90caf9', lineColor: '#444444', secondaryColor: '#fff8e1', tertiaryColor: '#e8f5e9', }, flowchart: { curve: 'basis', nodeSpacing: 30, rankSpacing: 50, padding: 20, }, securityLevel: 'loose', }) // Generate unique ID for this render const id = `mermaid-${Date.now()}` try { // Sanitize content: convert escaped quotes that might have leaked through JSON parsing const sanitizedContent = mermaidContent .replace(/\\"/g, "'") // Convert \" to ' .replace(/\\'/g, "'") // Convert \' to ' const { svg } = await mermaid.render(id, sanitizedContent) if (containerRef.current) { containerRef.current.innerHTML = svg setError(null) } } catch (err) { console.error('Mermaid render error:', err) setError(err instanceof Error ? err.message : 'Failed to render diagram') } finally { // Clean up any orphaned mermaid elements in document.body // Mermaid creates hidden divs for rendering that can persist on error const orphanedElement = document.getElementById(id) if (orphanedElement && orphanedElement.parentElement === document.body) { orphanedElement.remove() } } } render() }, [mermaidContent]) if (error) { return ( <div className={css({ padding: '4', color: { base: 'red.600', _dark: 'red.400' }, fontSize: 'sm', textAlign: 'center', })} > <p>Failed to render flowchart:</p> <p className={css({ fontSize: 'xs', marginTop: '1' })}>{error}</p> </div> ) } return ( <div ref={containerRef} data-component="mermaid-viewer" className={css({ width: '100%', minHeight: '200px', display: 'flex', justifyContent: 'center', '& svg': { maxWidth: '100%', height: 'auto', }, })} /> ) } |