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}