"use client" import { EditorContent, useEditor } from "@tiptap/react" import { useCallback, useEffect, useState } from "react" import { mdxToHtml } from "@/lib/mdx-converter" import type { ArticleGroup } from "@/models/article-group" import { editorExtensions } from "./editorExtensions" import EditorMenuBar from "./editorMenuBar" import EditorSidebar from "./editorSidebar" interface RichTextEditorProps { content?: string title?: string coverImage?: string groups: ArticleGroup[] groupId: string onCoverImageChange?: (url: string) => void onGroupChange: (groupId: string) => void onSave: (data: { title: string; content: string }) => Promise } export default function RichTextEditor({ content = "", title = "", coverImage = "", groups, groupId, onCoverImageChange, onGroupChange, onSave, }: RichTextEditorProps) { const [saving, setSaving] = useState(false) const [docTitle, setDocTitle] = useState(title) const [sectionTitle, setSectionTitle] = useState("") const [docCoverImage, setDocCoverImage] = useState(coverImage) const editor = useEditor({ extensions: editorExtensions, content, immediatelyRender: false, editorProps: { attributes: { class: "focus:outline-none w-full p-4", }, }, }) useEffect(() => { setDocTitle(title) }, [title]) useEffect(() => { setDocCoverImage(coverImage) }, [coverImage]) useEffect(() => { if (!editor || editor.isDestroyed) return const current = editor.getHTML() const target = content || "" if (target && current !== target) { editor.commands.setContent(target) } }, [content, editor]) const handleImportMdx = useCallback( (mdxContent: string) => { if (!editor || editor.isDestroyed) return const html = mdxToHtml(mdxContent) if (html) { editor.commands.setContent(html) } }, [editor], ) const handleSave = useCallback(async () => { if (!editor || editor.isDestroyed) return setSaving(true) try { await onSave({ title: docTitle, content: editor.getHTML(), }) } finally { setSaving(false) } }, [editor, docTitle, onSave]) return (
{})} onGroupChange={onGroupChange} />
{/* 固定标题区 */}
setDocTitle(e.target.value)} placeholder="输入文档标题..." className="w-full text-xl font-semibold bg-transparent border-none outline-none placeholder:text-muted-foreground" />
{/* 固定工具栏 */}
{/* 可滚动的内容区 */}
) }