import React, { useState } from 'react'; import { EditorContent, useEditor } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import { motion } from "framer-motion"; import { CharacterTokenExtension } from './CharacterToken'; import { ShotTitle } from './ShotTitle'; import { ReadonlyText } from './ReadonlyText'; const initialContent = { type: 'doc', content: [ { type: 'shotTitle', attrs: { title: `分镜1` }, }, { type: 'paragraph', content: [ { type: 'characterToken', attrs: { name: '张三', gender: '男', age: '28', avatar: 'https://i.pravatar.cc/40?u=z3' }}, { type: 'text', text: ' 从门口走来,皱着眉头说:“你怎么还在这里?”' } ] }, { type: 'shotTitle', attrs: { title: `分镜2` }, }, { type: 'paragraph', content: [ { type: 'characterToken', attrs: { name: '李四', gender: '女', age: '26', avatar: 'https://i.pravatar.cc/40?u=l4' }}, { type: 'text', text: ' 微微低头,没有说话。' } ] } ] }; interface ShotEditorProps { onAddSegment?: () => void; } const ShotEditor = React.forwardRef<{ addSegment: () => void }, ShotEditorProps>(function ShotEditor({ onAddSegment }, ref) { const [segments, setSegments] = useState(initialContent.content); const editor = useEditor({ extensions: [ StarterKit, CharacterTokenExtension, ShotTitle, ReadonlyText, ], content: { type: 'doc', content: segments }, editorProps: { attributes: { class: 'prose prose-invert max-w-none min-h-[150px] focus:outline-none' } }, immediatelyRender: false, onCreate: ({ editor }) => { editor.setOptions({ editable: true }) }, }) const addSegment = () => { if (!editor) return; // 自动编号(获取已有 shotTitle 节点数量) const doc = editor.state.doc; let shotCount = 0; doc.descendants((node) => { if (node.type.name === 'paragraph') { shotCount++; } }); editor.chain().focus('end').insertContent([ { type: 'shotTitle', attrs: { title: `分镜${shotCount + 1}` }, }, { type: 'paragraph', content: [ { type: 'text', text: '镜头描述' } ] } ]) .focus('end') // 聚焦到文档末尾 .run(); // 调用外部传入的回调函数 onAddSegment?.(); }; // 暴露 addSegment 方法给父组件 React.useImperativeHandle(ref, () => ({ addSegment })); if (!editor) { return null } return (