- CodeMirror 6 editor with a debounced Mermaid 11 preview (zoom, pan, auto fit-to-view and inline error reporting) - project start screen with recent projects, sidebar diagram explorer, toolbar and a Git panel (status, commit, history, branches) - SVG/PNG export, per-project theme switching, toasts - rune-based central store orchestrating all backend calls - view modes (Code / Split / Preview) plus a viewer mode with a slide-in quick-edit drawer (Cmd/Ctrl+E)
36 lines
995 B
TypeScript
36 lines
995 B
TypeScript
import mermaid from 'mermaid';
|
|
|
|
let currentTheme = '';
|
|
|
|
function configure(theme: string) {
|
|
if (theme === currentTheme) return;
|
|
currentTheme = theme;
|
|
mermaid.initialize({
|
|
startOnLoad: false,
|
|
theme: theme as any,
|
|
securityLevel: 'loose',
|
|
fontFamily: 'inherit',
|
|
flowchart: { useMaxWidth: true, htmlLabels: true },
|
|
});
|
|
}
|
|
|
|
let renderSeq = 0;
|
|
|
|
export type RenderResult = { svg: string } | { error: string };
|
|
|
|
/** Render Mermaid source to an SVG string, capturing syntax errors. */
|
|
export async function renderMermaid(code: string, theme: string): Promise<RenderResult> {
|
|
configure(theme);
|
|
if (!code.trim()) return { svg: '' };
|
|
const id = `mmx-render-${++renderSeq}`;
|
|
try {
|
|
const { svg } = await mermaid.render(id, code);
|
|
return { svg };
|
|
} catch (e) {
|
|
return { error: e instanceof Error ? e.message : String(e) };
|
|
} finally {
|
|
// Mermaid may leave a stray measurement node behind on failure.
|
|
document.getElementById(`d${id}`)?.remove();
|
|
}
|
|
}
|