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 (
);
};