From 6cc9c06eae89da633f2b35cd53b445e5ea70b82b Mon Sep 17 00:00:00 2001 From: Matthew Connelly Date: Tue, 3 Feb 2026 13:20:00 -0500 Subject: [PATCH] feat: allow custom accept/reject handlers for TC bubbles --- .../CommentsLayer/CommentDialog.vue | 32 +++++++++++++------ packages/superdoc/src/core/SuperDoc.js | 6 ++++ .../src/dev/components/SuperdocDev.vue | 11 +++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue b/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue index 5444eb9c08..eb49fd86e9 100644 --- a/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue +++ b/packages/superdoc/src/components/CommentsLayer/CommentDialog.vue @@ -219,7 +219,12 @@ const handleAddComment = () => { }; const handleReject = () => { - if (props.comment.trackedChange) { + const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleReject; + + if (props.comment.trackedChange && typeof customHandler === 'function') { + // Custom handler replaces default behavior + customHandler(props.comment, proxy.$superdoc.activeEditor); + } else if (props.comment.trackedChange) { props.comment.resolveComment({ email: superdocStore.user.email, name: superdocStore.user.name, @@ -230,6 +235,7 @@ const handleReject = () => { commentsStore.deleteComment({ superdoc: proxy.$superdoc, commentId: props.comment.commentId }); } + // Always cleanup the dialog state nextTick(() => { commentsStore.lastUpdate = new Date(); activeComment.value = null; @@ -238,16 +244,24 @@ const handleReject = () => { }; const handleResolve = () => { - if (props.comment.trackedChange) { - proxy.$superdoc.activeEditor.commands.acceptTrackedChangeById(props.comment.commentId); - } + const customHandler = proxy.$superdoc.config.onTrackedChangeBubbleAccept; - props.comment.resolveComment({ - email: superdocStore.user.email, - name: superdocStore.user.name, - superdoc: proxy.$superdoc, - }); + if (props.comment.trackedChange && typeof customHandler === 'function') { + // Custom handler replaces default behavior + customHandler(props.comment, proxy.$superdoc.activeEditor); + } else { + if (props.comment.trackedChange) { + proxy.$superdoc.activeEditor.commands.acceptTrackedChangeById(props.comment.commentId); + } + + props.comment.resolveComment({ + email: superdocStore.user.email, + name: superdocStore.user.name, + superdoc: proxy.$superdoc, + }); + } + // Always cleanup the dialog state nextTick(() => { commentsStore.lastUpdate = new Date(); activeComment.value = null; diff --git a/packages/superdoc/src/core/SuperDoc.js b/packages/superdoc/src/core/SuperDoc.js index 7e3f94d642..ce045e6267 100644 --- a/packages/superdoc/src/core/SuperDoc.js +++ b/packages/superdoc/src/core/SuperDoc.js @@ -107,6 +107,12 @@ export class SuperDoc extends EventEmitter { onListDefinitionsChange: () => null, onTransaction: () => null, onFontsResolved: null, + + // Tracked change bubble handlers - replace default accept/reject behavior + // Only fires from bubble buttons, not toolbar or context menu + // Signature: (comment, editor) => void + onTrackedChangeBubbleAccept: null, + onTrackedChangeBubbleReject: null, // Image upload handler // async (file) => url; handleImageUpload: null, diff --git a/packages/superdoc/src/dev/components/SuperdocDev.vue b/packages/superdoc/src/dev/components/SuperdocDev.vue index d5265acc2c..abae6bcacd 100644 --- a/packages/superdoc/src/dev/components/SuperdocDev.vue +++ b/packages/superdoc/src/dev/components/SuperdocDev.vue @@ -364,6 +364,17 @@ const init = async () => { onEditorCreate, onContentError, // handleImageUpload: async (file) => url, + + // Tracked change bubble button handlers - replace default accept/reject behavior + // Only fires from bubble buttons, not toolbar or context menu + // onTrackedChangeBubbleAccept: (comment, editor) => { + // console.log('Custom accept handler', comment); + // editor.commands.acceptTrackedChangeById(comment.commentId); + // }, + // onTrackedChangeBubbleReject: (comment, editor) => { + // console.log('Custom reject handler', comment); + // editor.commands.rejectTrackedChangeById(comment.commentId); + // }, // Override icons. toolbarIcons: {}, onCommentsUpdate,