Skip to content

Add a comments plugin to tiptap - #960

Open
domwhewell-sage wants to merge 4 commits into
GhostManager:masterfrom
domwhewell-sage:tiptap-comments-plugin
Open

Add a comments plugin to tiptap#960
domwhewell-sage wants to merge 4 commits into
GhostManager:masterfrom
domwhewell-sage:tiptap-comments-plugin

Conversation

@domwhewell-sage

@domwhewell-sage domwhewell-sage commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Add the ability to add inline comments as requested in this issue #425

This is a PR for a comments plugin, it follows the same pattern as #473 and I have tried to address the comments from that PR here (I am having trouble implementing nested comments though)

In any collaborative editor it will allow you to select and comment on text
image

Once a comment is created it will have the text background will be yellow and will be underlined red (Once resolved the background colour gets removed but is still underlined grey)
image

Selecting a comment brings up the model where an owner can edit their own comment and reply, other users cannot edit their comment but can reply
image

The added mark is displayed in the tiptap editor only and is not rendered in the generated docx since the reportwriter module strips any unknown HTML spans
image
image

Copilot AI lite review requested due to automatic review settings August 7, 2026 14:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an inline comment system to the Tiptap-based collaborative rich text editor to support QA-style comment threads on selected text (per issue #425), following the general approach explored in PR #473 but implemented as a Tiptap mark + toolbar/modal UI.

Changes:

  • Introduces a new gwComment Tiptap mark that serializes comment thread metadata into data-gw-comments attributes.
  • Adds a new “Comment” toolbar button that opens a modal for creating, replying to, editing, resolving, and removing comments on selected text.
  • Adds styling for commented text spans and the comment modal/cards.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
javascript/src/tiptap_gw/index.ts Registers the new GwComment extension in the shared Tiptap extension set.
javascript/src/tiptap_gw/comment.ts Implements the gwComment mark, attribute parsing/serialization, and commands.
javascript/src/frontend/collab_forms/rich_text_editor/index.tsx Adds the new comment toolbar button to the editor toolbar.
javascript/src/frontend/collab_forms/rich_text_editor/comment.tsx Implements the comment modal UI and mark application logic.
javascript/src/frontend/collab_forms/editor.scss Adds styling for comment highlights and modal comment cards.

Comment thread javascript/src/tiptap_gw/comment.ts
Comment thread javascript/src/frontend/collab_forms/rich_text_editor/comment.tsx
Comment thread javascript/src/frontend/collab_forms/rich_text_editor/comment.tsx

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (2)

javascript/src/frontend/collab_forms/editor.scss:499

  • The PR description says unresolved comments should be underlined red, but the stylesheet uses an orange underline (#f0ad00). If the intent is to match the described UI, update the unresolved underline color accordingly (resolved state can remain grey).
// Comment mark — active (unresolved) comments get a yellow background
.gw-comment {
    background-color: #fff3b0;
    border-bottom: 2px solid #f0ad00;
    cursor: pointer;
}

// Resolved comments lose the highlight but the data stays in the DOM
.gw-comment.gw-comment-resolved {
    background-color: transparent;
    border-bottom: 2px solid #aaa;
}

javascript/src/tiptap_gw/comment.ts:86

  • renderHTML spreads HTMLAttributes and then overwrites class, which can drop any existing classes (e.g., pasted markup or other extensions adding classes). Merge the existing class value with the gw-comment classes instead of replacing it.
    renderHTML({ HTMLAttributes }) {
        const resolved = "data-gw-comment-resolved" in HTMLAttributes;
        return [
            "span",
            {
                ...HTMLAttributes,
                class: resolved
                    ? "gw-comment gw-comment-resolved"
                    : "gw-comment",
            },

@domwhewell-sage
domwhewell-sage marked this pull request as ready for review August 10, 2026 18:55
@augmentcode

augmentcode Bot commented Aug 10, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: Adds inline, collaborative comments to Tiptap rich-text editors.

Changes:

  • Introduces a gwComment mark that serializes comment entries and resolution state into HTML data attributes.
  • Registers the mark in the shared Tiptap extension schema, including the collaboration server schema.
  • Adds a toolbar comment button and modal for creating, replying to, editing, deleting, resolving, and removing comments.
  • Stores author, text, and timestamp with each comment and displays commenter avatars in the modal.
  • Opens an existing thread when its marked text is clicked and visually distinguishes active and resolved ranges.
  • Adds editor SCSS for comment highlighting, cards, actions, and dark-theme variants.
Technical notes: Comment metadata is persisted as URI-encoded JSON on the mark, so it travels through the existing ProseMirror/Yjs HTML conversion path.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.


// Apply or remove the gwComment mark directly via ProseMirror transaction
function applyComment(entries: CommentEntry[], res: boolean) {
const range = savedRange.current;

@augmentcode augmentcode Bot Aug 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

savedRange contains raw document offsets captured before the modal opens, but Yjs can apply remote insertions/deletions while that modal is open. Those offsets are not mapped through subsequent transactions, so saving, resolving, or deleting a thread can remove/reapply the mark on different text than the thread the user opened.

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

)
);
}

@augmentcode augmentcode Bot Aug 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting the final entry makes comments empty before anything is dispatched; the subsequent render disables Save and hides the conditional Remove All button. As a result, a user cannot commit deletion of a one-comment thread unless they add a replacement comment.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

@chrismaddalena

Copy link
Copy Markdown
Collaborator

Hey @domwhewell-sage, I'm back from Black Hat USA now so just seeing this today. This looks very promising! Thanks for taking a crack at it. I'm very excited to take a look at this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants