42 lines
1.2 KiB
Vue
42 lines
1.2 KiB
Vue
<script setup>
|
|
import { ref, watch, onMounted } from 'vue'
|
|
import mermaid from 'mermaid'
|
|
|
|
mermaid.initialize({ startOnLoad: false, securityLevel: 'strict', theme: 'neutral' })
|
|
|
|
const props = defineProps({ code: { type: String, default: '' } })
|
|
const svg = ref('')
|
|
const fehler = ref(false)
|
|
let n = 0
|
|
|
|
// Async rendern; bricht das Mermaid-Parsing (kaputte Syntax) → Fallback statt Absturz.
|
|
async function render() {
|
|
const code = (props.code || '').trim()
|
|
svg.value = ''
|
|
fehler.value = false
|
|
if (!code) { fehler.value = true; return }
|
|
try {
|
|
const { svg: out } = await mermaid.render(`mmd-${Date.now()}-${n++}`, code)
|
|
svg.value = out
|
|
} catch {
|
|
fehler.value = true
|
|
}
|
|
}
|
|
|
|
watch(() => props.code, render)
|
|
onMounted(render)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="mermaid-view">
|
|
<div v-if="svg" v-html="svg"></div>
|
|
<p v-else class="mermaid-fallback">Grafik nicht verfügbar — Guide neu bauen.</p>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.mermaid-view { display: flex; justify-content: center; padding: 0.5rem 0; }
|
|
.mermaid-view :deep(svg) { max-width: 100%; height: auto; }
|
|
.mermaid-fallback { color: var(--text-muted); font-size: 0.85rem; padding: 1rem 0; }
|
|
</style>
|