import { Node, mergeAttributes } from '@tiptap/core' import { ReactNodeViewRenderer, NodeViewWrapper, ReactNodeViewProps } from '@tiptap/react' import { motion, AnimatePresence } from 'framer-motion' import { useState } from 'react' export const CharacterToken = Node.create({ name: 'characterToken', group: 'inline', inline: true, atom: true, selectable: true, addAttributes() { return { id: { default: null }, name: { default: 'Role name' }, avatar: { default: '' }, gender: { default: 'Unknown' }, age: { default: '-' }, } }, parseHTML() { return [{ tag: 'span[data-character]' }] }, renderHTML({ HTMLAttributes }) { return ['span', mergeAttributes({ 'data-character': '' }, HTMLAttributes), HTMLAttributes.name] }, addNodeView() { return ReactNodeViewRenderer(CharacterView) }, }) function CharacterView(props: ReactNodeViewProps) { const { node } = props; const [showCard, setShowCard] = useState(false) const { name, avatar, gender, age } = node.attrs const handleClick = () => { console.log('Click role:', name) alert(`Click role: ${name}`) } return ( setShowCard(true)} onMouseLeave={() => setShowCard(false)} onClick={handleClick} > {name} {showCard && (
{name}
{name}
{gender} / {age}
)}
) }