import Placeholder from "@tiptap/extension-placeholder"; import { useEditor, EditorContent } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import { useEffect } from "react"; import { HighlightTextExtension } from "../ui/main-editor/HighlightText"; /** * 高亮编辑器组件 * 使用 Tiptap 实现高亮和文本编辑功能 * 让 文本中的xxxx标签高亮 */ export const HighlightEditor = ({ content, onContentChange, type, placeholder, }: { /** 内容 */ content: string; /** 内容变化回调 */ onContentChange: (content: string) => void; /** 标签类型*/ type: string; /**提示语 */ placeholder: string; }) => { const editor = useEditor({ extensions: [ StarterKit, HighlightTextExtension, Placeholder.configure({ placeholder, emptyEditorClass: "is-editor-empty", }), ], content: "", onUpdate: ({ editor }) => { const textContent = editor.getText(); if (!textContent.trim()) { onContentChange(""); return; } // 直接传递文本内容,不进行复杂的标签重建 onContentChange(textContent); }, editorProps: { handleKeyDown: (view, event) => { const { from, to } = view.state.selection; const doc = view.state.doc; // 检查光标前后是否有标签 const textBefore = from > 0 ? doc.textBetween(Math.max(0, from - 50), from) : ""; const textAfter = to < doc.content.size ? doc.textBetween(to, Math.min(doc.content.size, to + 50)) : ""; const beforeMatch = textBefore.match(new RegExp(`<${type}[^>]*>[^<]*$`)); const afterMatch = textAfter.match(new RegExp(`^[^>]*<\\/${type}>`)); // 只允许删除操作) if (beforeMatch || afterMatch) { if (event.key !== "Backspace" && event.key !== "Delete") { event.preventDefault(); return true; } } return false; }, }, immediatelyRender: false, }); useEffect(() => { if (editor) { if (!content || content.trim() === "") { editor.commands.clearContent(true); return; } // 将带标签的内容转换为高亮显示(支持新的标签格式) const htmlContent = content.replace( new RegExp(`<${type}[^>]*>([^<]+)<\/${type}>`, "g"), '$1' ); editor.commands.setContent(htmlContent, { emitUpdate: false }); } }, [content, editor]); return (
); };