From 5fe2c23fa8cef6a45ee80649f80d369bce1a0f7b Mon Sep 17 00:00:00 2001 From: octo-patch Date: Sat, 25 Apr 2026 10:50:08 +0800 Subject: [PATCH] fix: correct outline active heading detection and scroll-to-center on click (fixes #1039) When scrolling, the outline panel was iterating headings forward and returning the first heading above the viewport instead of the last (most recently passed) heading. This caused the highlight to always show the topmost heading rather than the one currently visible. Also fixed scrollToHeading to use scrollIntoView({ block: 'center' }) so the selected heading is centered in the editor rather than appearing at the bottom edge of the visible area. Co-Authored-By: Octopus --- src/app/core/main/editor/markdown/outline.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/app/core/main/editor/markdown/outline.tsx b/src/app/core/main/editor/markdown/outline.tsx index 3361374e..568cd14c 100644 --- a/src/app/core/main/editor/markdown/outline.tsx +++ b/src/app/core/main/editor/markdown/outline.tsx @@ -229,8 +229,9 @@ export function Outline({ const scrollTop = editorElement.scrollTop const viewportTop = scrollTop + 100 // Add some offset for better UX - // Find the first heading that is above or near the viewport top - for (const heading of headings) { + // Find the last heading that is above or near the viewport top (iterate in reverse) + for (let i = headings.length - 1; i >= 0; i--) { + const heading = headings[i] const domNode = editor.view.nodeDOM(heading.pos) as HTMLElement | undefined if (domNode) { const rect = domNode.getBoundingClientRect() @@ -296,10 +297,15 @@ export function Outline({ // Then set the selection to the heading position editor.commands.setTextSelection(targetPos) - // Then scroll into view + // Then scroll into view, centering the heading in the editor // Use setTimeout to ensure the selection is applied first setTimeout(() => { - editor.commands.scrollIntoView() + const domNode = editor.view.nodeDOM(targetPos) as HTMLElement | undefined + if (domNode) { + domNode.scrollIntoView({ behavior: 'smooth', block: 'center' }) + } else { + editor.commands.scrollIntoView() + } }, 0) onHeadingSelect?.()