From 78352dd19314cce44722afa310b510fd564c750b Mon Sep 17 00:00:00 2001 From: cirry <812852553@qq.com> Date: Wed, 8 Jul 2026 11:08:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 61 +++++++++++++-------- src/components/DirectorySidebar.vue | 83 +---------------------------- src/components/MarkdownEditor.vue | 4 +- src/components/OutlinePanel.vue | 31 +++++------ 4 files changed, 54 insertions(+), 125 deletions(-) diff --git a/src/App.vue b/src/App.vue index 9fea10d..0cb82b7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -4,6 +4,7 @@ import {listen} from "@tauri-apps/api/event"; import {invoke} from "@tauri-apps/api/core"; import MarkdownEditor from "./components/MarkdownEditor.vue"; import DirectorySidebar from "./components/DirectorySidebar.vue"; +import OutlinePanel from "./components/OutlinePanel.vue"; const content = ref(""); const wordCount = ref(0); @@ -76,7 +77,7 @@ function onEditorWheel(e: WheelEvent) { } // ---- toolbar state ---- -const showThumbnail = ref(true); +const showOutline = ref(false); const documentMode = ref("edit"); const showMoreMenu = ref(false); const markdownEditorRef = ref<{ flushPendingChanges: () => string | undefined } | null>(null); @@ -295,9 +296,7 @@ listen("menu-event", (event) => { {
- + @@ -389,15 +383,25 @@ listen("menu-event", (event) => {
- +
+ + + + + +
@@ -445,6 +449,19 @@ listen("menu-event", (event) => { opacity: 0; } +.outline-slide-enter-active, +.outline-slide-leave-active { + transition: + width 0.18s ease, + opacity 0.18s ease; +} + +.outline-slide-enter-from, +.outline-slide-leave-to { + width: 0; + opacity: 0; +} + /* ── Toolbar ───────────────────────────────────────────────────── */ .toolbar-btn { diff --git a/src/components/DirectorySidebar.vue b/src/components/DirectorySidebar.vue index e013fa4..96e092f 100644 --- a/src/components/DirectorySidebar.vue +++ b/src/components/DirectorySidebar.vue @@ -13,17 +13,14 @@ const props = withDefaults( defineProps<{ folderPath: string; entries: DirEntry[]; - content?: string; currentFilePath?: string | null; }>(), { - content: "", currentFilePath: null, }, ); const emit = defineEmits<{ - headingClick: [heading: { text: string; level: number }]; openFolder: []; toggleFolder: [path: string]; openFile: [path: string]; @@ -44,7 +41,7 @@ const rootEntry = computed(() => { }); // ---- sidebar view mode ---- -type ViewMode = "folder" | "search" | "outline" | "setting"; +type ViewMode = "folder" | "search" | "setting"; const activeView = ref("folder"); const expanded = ref(true); @@ -57,33 +54,6 @@ function switchView(view: ViewMode) { } } -// ---- outline state ---- -interface OutlineItem { - text: string; - level: number; - id: string; -} - -const headings = computed(() => { - if (!props.content) return []; - const result: OutlineItem[] = []; - const regex = /^(#{1,3})\s+(.+)$/gm; - let match: RegExpExecArray | null; - while ((match = regex.exec(props.content)) !== null) { - const level = match[1].length; - // Strip any remaining markdown formatting from the heading text - const text = match[2].replace(/\*{1,3}|_{1,3}|`+|~~|\[([^\]]*)\]\([^)]*\)/g, (_, linkText) => linkText || "").trim(); - if (text) { - result.push({text, level, id: `heading-${result.length}`}); - } - } - return result; -}); - -function onHeadingClick(item: OutlineItem) { - emit("headingClick", {text: item.text, level: item.level}); -} - // ---- settings modal ---- const showSettings = ref(false); @@ -112,15 +82,6 @@ const showSettings = ref(false); > - -