feat(renderer): Mermaid diagram rendering with dark theme (M10.7)

- Lazy-loads Mermaid.js on first ```mermaid block detected
- Dark theme with Bitcoin orange accent colors
- Cached renders to avoid re-rendering on scroll
- Error display inline without crashing app

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-03 23:57:41 +00:00
co-authored by Claude Opus 4.6
parent e7961c608b
commit 7c6a0565d5
4 changed files with 959 additions and 5 deletions
@@ -326,6 +326,7 @@
import { computed, ref, nextTick, watch } from 'vue'
import MarkdownIt from 'markdown-it'
import { hasMath, renderMathInHtml } from '@/composables/useMathRenderer'
import { hasMermaid, renderMermaidBlocks } from '@/composables/useMermaidRenderer'
import ContextMenu from '@/components/ui/ContextMenu.vue'
import ContextMenuItem from '@/components/ui/ContextMenuItem.vue'
import type { Message, WebSearchResult } from '@aiui/core/types/message'
@@ -497,14 +498,17 @@ const displayText = computed(() => {
const baseMarkdown = computed(() => md.render(displayText.value))
const renderedMarkdown = ref('')
// Render math after markdown, batch on content change
// Render math/mermaid after markdown, batch on content change
watch(baseMarkdown, async (html) => {
let result = html
renderedMarkdown.value = html // Show immediately
if (hasMath(displayText.value)) {
renderedMarkdown.value = html // Show immediately
renderedMarkdown.value = await renderMathInHtml(html)
} else {
renderedMarkdown.value = html
result = await renderMathInHtml(result)
}
if (hasMermaid(displayText.value)) {
result = await renderMermaidBlocks(result)
}
renderedMarkdown.value = result
}, { immediate: true })
const formattedTime = computed(() => {