50 lines
1.1 KiB
TypeScript
50 lines
1.1 KiB
TypeScript
/**
|
|
* TipTap mark extension for inline comments.
|
|
*
|
|
* Applies a highlight to selected text and associates it with a comment thread
|
|
* stored in Automerge. The mark position is synced via Yjs (as part of the doc content),
|
|
* while the thread data (messages, resolved state) lives in Automerge.
|
|
*/
|
|
|
|
import { Mark, mergeAttributes } from '@tiptap/core';
|
|
|
|
export const CommentMark = Mark.create({
|
|
name: 'comment',
|
|
|
|
addAttributes() {
|
|
return {
|
|
threadId: { default: null },
|
|
resolved: { default: false },
|
|
};
|
|
},
|
|
|
|
parseHTML() {
|
|
return [
|
|
{
|
|
tag: 'span[data-thread-id]',
|
|
getAttrs: (el) => {
|
|
const element = el as HTMLElement;
|
|
return {
|
|
threadId: element.getAttribute('data-thread-id'),
|
|
resolved: element.getAttribute('data-resolved') === 'true',
|
|
};
|
|
},
|
|
},
|
|
];
|
|
},
|
|
|
|
renderHTML({ HTMLAttributes }) {
|
|
return [
|
|
'span',
|
|
mergeAttributes(
|
|
{
|
|
class: `comment-highlight${HTMLAttributes.resolved ? ' resolved' : ''}`,
|
|
'data-thread-id': HTMLAttributes.threadId,
|
|
'data-resolved': HTMLAttributes.resolved ? 'true' : 'false',
|
|
},
|
|
),
|
|
0,
|
|
];
|
|
},
|
|
});
|