2025-08-18 18:58:15 +08:00

61 lines
1.4 KiB
TypeScript

import { Node, mergeAttributes } from '@tiptap/core'
import { ReactNodeViewRenderer, NodeViewWrapper, ReactNodeViewProps } from '@tiptap/react'
interface HighlightTextAttributes {
type: string;
text: string;
color: string;
}
interface HighlightTextOptions {
type?: string;
text: string;
color: string;
}
export function HighlightText(props: ReactNodeViewProps) {
const { type, text: initialText, color } = props.node.attrs as HighlightTextAttributes
const isRoleName = type === 'role'
return (
<NodeViewWrapper
as="span"
data-alt="highlight-text"
contentEditable={!isRoleName}
suppressContentEditableWarning={true}
className={`relative inline text-${color}-400 hover:text-${color}-300 transition-colors duration-200 ${
isRoleName ? 'role-name-highlight' : ''
}`}
>
{initialText}
</NodeViewWrapper>
)
}
export const HighlightTextExtension = Node.create<HighlightTextOptions>({
name: 'highlightText',
group: 'inline',
inline: true,
atom: false,
addAttributes() {
return {
type: { default: null },
text: { default: '' },
color: { default: 'blue' },
};
},
parseHTML() {
return [{ tag: 'highlight-text' }];
},
renderHTML({ HTMLAttributes }) {
return ['highlight-text', mergeAttributes(HTMLAttributes)];
},
addNodeView() {
return ReactNodeViewRenderer(HighlightText);
},
});