Render technical diagrams with mermaid
This commit is contained in:
94
docs/.vitepress/theme/components/MermaidDiagram.vue
Normal file
94
docs/.vitepress/theme/components/MermaidDiagram.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<script setup lang="ts">
|
||||
import mermaid from 'mermaid';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
chart: string;
|
||||
}>();
|
||||
|
||||
const svg = ref('');
|
||||
const error = ref('');
|
||||
|
||||
let initialized = false;
|
||||
let diagramId = 0;
|
||||
|
||||
function initMermaid() {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
theme: 'neutral',
|
||||
securityLevel: 'strict',
|
||||
fontFamily: 'Inter, Arial, sans-serif',
|
||||
flowchart: {
|
||||
useMaxWidth: true,
|
||||
htmlLabels: true,
|
||||
},
|
||||
});
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
const source = computed(() => props.chart.trim());
|
||||
|
||||
async function renderDiagram() {
|
||||
if (!import.meta.client) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
initMermaid();
|
||||
error.value = '';
|
||||
diagramId += 1;
|
||||
const { svg: result } = await mermaid.render(`mermaid-diagram-${diagramId}`, source.value);
|
||||
svg.value = result;
|
||||
} catch (cause) {
|
||||
svg.value = '';
|
||||
error.value = cause instanceof Error ? cause.message : 'Failed to render Mermaid diagram.';
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void renderDiagram();
|
||||
});
|
||||
|
||||
watch(source, () => {
|
||||
void renderDiagram();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mermaid-diagram">
|
||||
<div v-if="error" class="mermaid-diagram__error">{{ error }}</div>
|
||||
<div v-else class="mermaid-diagram__canvas" v-html="svg" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.mermaid-diagram {
|
||||
margin: 1.25rem 0 1.75rem;
|
||||
border: 1px solid #d9dee7;
|
||||
border-radius: 20px;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mermaid-diagram__canvas {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.mermaid-diagram__canvas :deep(svg) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.mermaid-diagram__error {
|
||||
padding: 1rem 1.25rem;
|
||||
color: #b42318;
|
||||
background: #fef3f2;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user