add: markdown viewer
This commit is contained in:
@@ -3,8 +3,7 @@
|
||||
@mousedown="handleCanvasMouseDown"
|
||||
@mousedown.middle.prevent="startMiddleDrag"
|
||||
@wheel.prevent="onZoom"
|
||||
@contextmenu.prevent="handleContextMenu">
|
||||
<!-- 工具栏 -->
|
||||
@contextmenu.prevent="handleContextMenu"> <!-- 工具栏 -->
|
||||
<div class="absolute top-2 right-2 flex gap-2 z-30">
|
||||
<button class="btn btn-sm btn-primary" @click="openDiagramFileSelector">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -23,6 +22,11 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
添加组件
|
||||
</button> <button class="btn btn-sm btn-primary" @click="emit('toggle-doc-panel')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
{{ props.showDocPanel ? '属性面板' : '文档' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -148,11 +152,12 @@ function handleContextMenu(e: MouseEvent) {
|
||||
}
|
||||
|
||||
// 定义组件发出的事件
|
||||
const emit = defineEmits(['diagram-updated', 'component-selected', 'component-moved', 'component-delete', 'wire-created', 'wire-deleted', 'load-component-module', 'open-components']);
|
||||
const emit = defineEmits(['diagram-updated', 'component-selected', 'component-moved', 'component-delete', 'wire-created', 'wire-deleted', 'load-component-module', 'open-components', 'toggle-doc-panel']);
|
||||
|
||||
// 定义组件接受的属性
|
||||
const props = defineProps<{
|
||||
componentModules: Record<string, any>
|
||||
componentModules: Record<string, any>;
|
||||
showDocPanel?: boolean; // 添加属性接收文档面板的显示状态
|
||||
}>();
|
||||
|
||||
// --- 画布状态 ---
|
||||
|
||||
207
src/components/MarkdownRenderer.vue
Normal file
207
src/components/MarkdownRenderer.vue
Normal file
@@ -0,0 +1,207 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { marked } from 'marked';
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const renderedContent = computed(() => {
|
||||
if (!props.content) return '<p>没有内容</p>';
|
||||
let processedContent = props.content;
|
||||
// 设置 marked 选项
|
||||
const renderer = new marked.Renderer();
|
||||
marked.setOptions({
|
||||
renderer: renderer,
|
||||
gfm: true,
|
||||
breaks: true
|
||||
});
|
||||
return marked(processedContent);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="markdown-content" v-html="renderedContent"></div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.markdown-content {
|
||||
color: hsl(var(--bc));
|
||||
line-height: 1.6;
|
||||
padding: 1rem 1.5rem;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown-content :deep(img) {
|
||||
max-width: 60%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 1rem auto;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.markdown-content :deep(h1) {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: hsl(var(--bc));
|
||||
font-weight: 700;
|
||||
font-size: 2rem;
|
||||
line-height: 1.3;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid hsl(var(--b2));
|
||||
}
|
||||
|
||||
.markdown-content :deep(h2) {
|
||||
margin-top: 1.8rem;
|
||||
margin-bottom: 0.8rem;
|
||||
color: hsl(var(--bc));
|
||||
font-weight: 600;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.4;
|
||||
padding-left: 0.5rem;
|
||||
border-left: 4px solid hsl(var(--p));
|
||||
}
|
||||
|
||||
.markdown-content :deep(h3) {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
color: hsl(var(--bc));
|
||||
font-weight: 600;
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.4;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.markdown-content :deep(h4),
|
||||
.markdown-content :deep(h5),
|
||||
.markdown-content :deep(h6) {
|
||||
margin-top: 1.2rem;
|
||||
margin-bottom: 0.6rem;
|
||||
color: hsl(var(--bc));
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.5;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.markdown-content :deep(p) {
|
||||
text-indent: 2em;
|
||||
margin: 1rem 0;
|
||||
color: hsl(var(--bc) / 0.8);
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.markdown-content :deep(ul),
|
||||
.markdown-content :deep(ol) {
|
||||
padding-left: 2em;
|
||||
margin: 0.75rem 0;
|
||||
color: hsl(var(--bc) / 0.8);
|
||||
}
|
||||
|
||||
.markdown-content :deep(li) {
|
||||
margin: 0.4rem 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.markdown-content :deep(ul ul),
|
||||
.markdown-content :deep(ul ol),
|
||||
.markdown-content :deep(ol ul),
|
||||
.markdown-content :deep(ol ol) {
|
||||
margin: 0.4rem 0 0.4rem 1rem;
|
||||
}
|
||||
|
||||
.markdown-content :deep(ul) {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.markdown-content :deep(ol) {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.markdown-content :deep(ul ul) {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.markdown-content :deep(ul ul ul) {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
.markdown-content :deep(ul li::marker) {
|
||||
color: hsl(var(--p));
|
||||
}
|
||||
|
||||
.markdown-content :deep(pre) {
|
||||
background-color: hsl(var(--b3));
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: auto;
|
||||
border: 1px solid hsl(var(--b2));
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.markdown-content :deep(code) {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
background-color: hsl(var(--b3));
|
||||
padding: 2px 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.9em;
|
||||
color: hsl(var(--p));
|
||||
}
|
||||
|
||||
.markdown-content :deep(table) {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 1rem 0;
|
||||
background-color: hsl(var(--b1));
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.markdown-content :deep(th),
|
||||
.markdown-content :deep(td) {
|
||||
border: 1px solid hsl(var(--b2));
|
||||
padding: 0.75rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown-content :deep(th) {
|
||||
background-color: hsl(var(--b2));
|
||||
font-weight: 500;
|
||||
color: hsl(var(--bc));
|
||||
}
|
||||
|
||||
.markdown-content :deep(td) {
|
||||
color: hsl(var(--bc) / 0.8);
|
||||
}
|
||||
|
||||
.markdown-content :deep(blockquote) {
|
||||
margin: 1rem 0;
|
||||
padding: 0.5rem 1rem;
|
||||
border-left: 4px solid hsl(var(--p));
|
||||
background-color: hsl(var(--b2));
|
||||
color: hsl(var(--bc) / 0.8);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.markdown-content :deep(hr) {
|
||||
border: none;
|
||||
border-top: 1px solid hsl(var(--b2));
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.markdown-content :deep(a) {
|
||||
color: hsl(var(--p));
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.markdown-content :deep(a:hover) {
|
||||
color: hsl(var(--pf));
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user