"use client"; import { useEditor, EditorContent } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import Image from "@tiptap/extension-image"; import Link from "@tiptap/extension-link"; import Placeholder from "@tiptap/extension-placeholder"; import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight"; import { common, createLowlight } from "lowlight"; import { Toggle } from "@/components/ui/toggle"; import dynamic from "next/dynamic"; import { Bold, Italic, Strikethrough, Code, Heading1, Heading2, Heading3, Quote, List, ListOrdered, Link as LinkIcon, ImageIcon, CodeSquare, Minus, Undo2, Redo2, Maximize2, Minimize2, FileText, } from "lucide-react"; const MarkdownEditor = dynamic(() => import("./MarkdownEditor"), { ssr: false }); const lowlight = createLowlight(common); interface RichEditorProps { value: string; onChange: (html: string) => void; placeholder?: string; isFullscreen?: boolean; isMarkdown?: boolean; onToggleFullscreen?: () => void; onSwitchToMarkdown?: () => void; } export default function RichEditor({ value, onChange, placeholder = "开始写文章...", isFullscreen, isMarkdown, onToggleFullscreen, onSwitchToMarkdown, }: RichEditorProps) { const editor = useEditor({ extensions: [ StarterKit.configure({ codeBlock: false, }), Image.configure({ HTMLAttributes: { class: "rounded-lg my-4" }, }), Link.configure({ openOnClick: false, HTMLAttributes: { class: "text-primary underline underline-offset-2", }, }), Placeholder.configure({ placeholder }), CodeBlockLowlight.configure({ lowlight }), ], content: value, onUpdate: ({ editor }) => { onChange(editor.getHTML()); }, editorProps: { attributes: { class: "prose-literary min-h-[300px] px-4 py-3 focus:outline-none", }, }, }); if (!editor) return null; function addLink() { const url = window.prompt("输入链接地址:"); if (url) { editor .chain() .focus() .extendMarkRange("link") .setLink({ href: url }) .run(); } } function addImage() { const url = window.prompt("输入图片地址:"); if (url) { editor.chain().focus().setImage({ src: url }).run(); } } const isFs = !!isFullscreen; return (