76 lines
1.4 KiB
TypeScript

import { Node, mergeAttributes } from '@tiptap/core'
import React from 'react'
import { NodeViewWrapper, ReactNodeViewRenderer } from '@tiptap/react'
declare module '@tiptap/core' {
interface Commands<ReturnType> {
readonlyText: {
insertReadonlyText: (text: string) => ReturnType
}
}
}
export const ReadonlyText = Node.create({
name: 'readonlyText',
group: 'inline',
inline: true,
atom: true, // 不可拆分
selectable: false,
addAttributes() {
return {
text: {
default: '',
},
}
},
parseHTML() {
return [
{
tag: 'span[data-readonly-text]',
},
]
},
renderHTML({ HTMLAttributes }) {
return [
'span',
mergeAttributes(HTMLAttributes, {
'data-readonly-text': '',
}),
]
},
addNodeView() {
return ReactNodeViewRenderer(ReadonlyTextView)
},
addCommands() {
return {
insertReadonlyText:
(text: string) =>
({ commands }) => {
return commands.insertContent({
type: this.name,
attrs: { text },
})
},
}
},
})
const ReadonlyTextView = (props: any) => {
return (
<NodeViewWrapper
as="span"
className="text-gray-400 px-1 select-none pointer-events-none"
contentEditable={false}
data-readonly-text
>
{props.node.attrs.text}
</NodeViewWrapper>
)
}