feat(frontend): Svelte editor, live preview and Git panel
- 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)
This commit is contained in:
35
src/lib/mermaid.ts
Normal file
35
src/lib/mermaid.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user