"use client"; import { EditorContent, useEditor } from '@tiptap/react'; import { StarterKit } from '@tiptap/starter-kit'; import { Image } from '@tiptap/extension-image'; import { TaskItem, TaskList } from '@tiptap/extension-list'; import { TextAlign } from '@tiptap/extension-text-align'; import { Typography } from '@tiptap/extension-typography'; import { Highlight } from '@tiptap/extension-highlight'; import { Subscript } from '@tiptap/extension-subscript'; import { Superscript } from '@tiptap/extension-superscript'; import { HorizontalRule } from '@/components/tiptap-node/horizontal-rule-node/horizontal-rule-node-extension'; import { useEffect } from 'react'; // 导入必要的样式 import '@/components/tiptap-node/blockquote-node/blockquote-node.scss'; import '@/components/tiptap-node/code-block-node/code-block-node.scss'; import '@/components/tiptap-node/horizontal-rule-node/horizontal-rule-node.scss'; import '@/components/tiptap-node/list-node/list-node.scss'; import '@/components/tiptap-node/image-node/image-node.scss'; import '@/components/tiptap-node/heading-node/heading-node.scss'; import '@/components/tiptap-node/paragraph-node/paragraph-node.scss'; interface BlogViewerProps { content: any; onContentReady?: () => void; } export default function BlogViewer({ content, onContentReady }: BlogViewerProps) { const editor = useEditor({ immediatelyRender: false, editable: false, editorProps: { attributes: { class: 'simple-editor prose prose-gray max-w-none dark:prose-invert', }, }, extensions: [ StarterKit.configure({ horizontalRule: false, link: { openOnClick: true, enableClickSelection: false, }, }), HorizontalRule, TextAlign.configure({ types: ['heading', 'paragraph'] }), TaskList, TaskItem.configure({ nested: true }), Highlight.configure({ multicolor: true }), Image, Typography, Superscript, Subscript, ], content: content || '', }); // 为标题添加 ID,并在内容加载完成后通知父组件 useEffect(() => { if (editor && editor.view.dom) { // 等待 DOM 更新 setTimeout(() => { const headings = editor.view.dom.querySelectorAll('h1, h2, h3, h4, h5, h6'); headings.forEach((heading, index) => { const element = heading as HTMLElement; if (!element.id) { const text = element.textContent || ''; let id = text .toLowerCase() .replace(/[^\w\s-]/g, '') .replace(/[\s_-]+/g, '-') .replace(/^-+|-+$/g, ''); // 确保 ID 唯一 let uniqueId = id; let counter = 1; while (document.getElementById(uniqueId)) { uniqueId = `${id}-${counter}`; counter++; } element.id = uniqueId; } }); // 通知父组件内容已准备好 onContentReady?.(); }, 100); } }, [editor, content, onContentReady]); return (
); }