From 245b29d604f68226868e4cbecc4def2935c4ccf8 Mon Sep 17 00:00:00 2001
From: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Date: Wed, 22 Apr 2026 11:05:48 -0700
Subject: [PATCH] refactor(editor): render front-matter banner inside rich
editor shell (#943)
Pass FrontMatterBanner as headerSlot into RichMarkdownEditor so it renders
between the toolbar and the editor surface, keeping formatting controls at
the top of the pane.
---
src/renderer/src/components/editor/EditorContent.tsx | 6 +++++-
src/renderer/src/components/editor/RichMarkdownEditor.tsx | 8 +++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/renderer/src/components/editor/EditorContent.tsx b/src/renderer/src/components/editor/EditorContent.tsx
index 82c000ddc..1df6969ee 100644
--- a/src/renderer/src/components/editor/EditorContent.tsx
+++ b/src/renderer/src/components/editor/EditorContent.tsx
@@ -169,7 +169,6 @@ export function EditorContent({
return (
- {fm &&
}
{/* Why: same remount reasoning as MonacoEditor — see renderMonacoEditor.
The boundary contains a TipTap/ProseMirror render crash (e.g.
@@ -186,6 +185,11 @@ export function EditorContent({
onContentChange={onContentChangeWithFm}
onDirtyStateHint={handleDirtyStateHint}
onSave={onSaveWithFm}
+ // Why: render the front-matter banner below the editor toolbar
+ // (inside the editor shell) so formatting controls remain at
+ // the top of the pane — the banner is read-only context, not
+ // a header above the toolbar.
+ headerSlot={fm ? : null}
/>
diff --git a/src/renderer/src/components/editor/RichMarkdownEditor.tsx b/src/renderer/src/components/editor/RichMarkdownEditor.tsx
index 3cb7890bc..41a272ac3 100644
--- a/src/renderer/src/components/editor/RichMarkdownEditor.tsx
+++ b/src/renderer/src/components/editor/RichMarkdownEditor.tsx
@@ -41,6 +41,10 @@ type RichMarkdownEditorProps = {
onContentChange: (content: string) => void
onDirtyStateHint: (dirty: boolean) => void
onSave: (content: string) => void
+ // Why: front-matter is stripped from the rich editor's content but we still
+ // want it visible to the user. It renders between the toolbar and the editor
+ // surface so the formatting toolbar stays at the top of the pane.
+ headerSlot?: React.ReactNode
}
const richMarkdownExtensions = createRichMarkdownExtensions({
@@ -55,7 +59,8 @@ export default function RichMarkdownEditor({
scrollCacheKey,
onContentChange,
onDirtyStateHint,
- onSave
+ onSave,
+ headerSlot
}: RichMarkdownEditorProps): React.JSX.Element {
const rootRef = useRef
(null)
const editorFontZoomLevel = useAppStore((s) => s.editorFontZoomLevel)
@@ -495,6 +500,7 @@ export default function RichMarkdownEditor({
onToggleLink={toggleLinkFromToolbar}
onImagePick={handleLocalImagePick}
/>
+ {headerSlot}