import React, { useEffect, useRef, useState, useCallback } from 'react'; import mermaid, { MermaidConfig } from 'mermaid'; import { SxProps } from '@mui/material/styles'; import { Box } from '@mui/material'; import { useResizeObserverAndMutationObserver } from '../hooks/useAutoScrollToBottom'; const defaultMermaidConfig : MermaidConfig = { startOnLoad: true, securityLevel: 'loose', fontFamily: 'Fira Code', }; interface MermaidProps { chart: string; sx?: SxProps; className?: string; mermaidConfig?: MermaidConfig; } const Mermaid: React.FC = (props: MermaidProps) => { const { chart, sx, className, mermaidConfig } = props; const [ visible, setVisible] = useState(false); const containerRef = useRef(null); const checkVisible = useCallback(() => { if (containerRef.current) { const { width, height } = containerRef.current.getBoundingClientRect(); if (width > 0 && height > 0) { setVisible(true); } } }, [containerRef, setVisible]); useEffect(() => { const renderMermaid = async () => { if (containerRef.current && visible && chart) { try { await mermaid.initialize(mermaidConfig || defaultMermaidConfig); await mermaid.run({ nodes: [containerRef.current] }); } catch (e) { console.error("Mermaid render error:", e, containerRef.current); } } } renderMermaid(); }, [containerRef, mermaidConfig, visible, chart]); // Observe container and TextField size, plus DOM changes useResizeObserverAndMutationObserver(containerRef, null, checkVisible); return {chart} ; }; export { Mermaid };