Skip to Content
🎉 Univer 0.6.7 is released.Read more →
GuidesUniver SheetsFeaturesThread Comment

Thread Comment 0.2.10+

Facade APIHas Paid PlanUniver ServerUniver on Node.jsPreset
-Optional-UniverSheetsThreadCommentPreset

The Comment plugin provides the ability to comment or annotate cells.

This feature includes the following plugin packages:

Presets Installation

import { createUniver, defaultTheme, LocaleType, merge } from '@univerjs/presets'; import { UniverSheetsCorePreset } from '@univerjs/presets/preset-sheets-core'; import UniverPresetSheetsCoreEnUS from '@univerjs/presets/preset-sheets-core/locales/en-US'; import { UniverSheetsThreadCommentPreset } from '@univerjs/presets/preset-sheets-thread-comment'; import UniverPresetSheetsThreadCommentEnUS from '@univerjs/presets/preset-sheets-thread-comment/locales/en-US'; import '@univerjs/presets/lib/styles/preset-sheets-thread-comment.css' const { univerAPI } = createUniver({ locale: LocaleType.EN_US, locales: { [LocaleType.EN_US]: merge( {}, UniverPresetSheetsCoreEnUS, UniverPresetSheetsThreadCommentEnUS ), }, theme: defaultTheme, collaboration: true, presets: [ UniverSheetsCorePreset(), UniverSheetsThreadCommentPreset(), ], });

Piecemeal Installation

npm install @univerjs/sheets-thread-comment @univerjs/sheets-thread-comment-ui @univerjs/thread-comment @univerjs/thread-comment-ui
import { LocaleType, merge, Univer } from '@univerjs/core'; import { defaultTheme } from "@univerjs/design"; import { UniverThreadCommentPlugin } from '@univerjs/thread-comment'; import { UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui'; import { UniverSheetsThreadCommentPlugin } from '@univerjs/sheets-thread-comment'; import { UniverSheetsThreadCommentUIPlugin } from '@univerjs/sheets-thread-comment-ui'; import ThreadCommentUIEnUS from '@univerjs/thread-comment-ui/locale/en-US'; import SheetsThreadCommentUIEnUS from '@univerjs/sheets-thread-comment-ui/locale/en-US'; import '@univerjs/thread-comment-ui/lib/index.css'; import '@univerjs/sheets-thread-comment/facade'; const univer = new Univer({ theme: defaultTheme, locale: LocaleType.EN_US, locales: { [LocaleType.EN_US]: merge( ThreadCommentUIEnUS, SheetsThreadCommentUIEnUS ), }, }); univer.registerPlugin(UniverThreadCommentPlugin); univer.registerPlugin(UniverThreadCommentUIPlugin); univer.registerPlugin(UniverSheetsThreadCommentPlugin); univer.registerPlugin(UniverSheetsThreadCommentUIPlugin);

Facade API

To get full definition of facade api, please refer to FacadeAPI

Add Cell Comment

univerAPI.newTheadComment() creates a new comment builder and returns an instance of FTheadCommentBuilder. You can chain methods to build the comment.

Here are some member methods on FTheadCommentBuilder:

MethodDescription
setContentSet the content of the comment
setPersonIdSet the person id of the comment
setDateTimeSet the date time of the comment
setIdSet the id of the comment
setThreadIdSet the thread id of the comment
// Create a new comment const richText = univerAPI.newRichText().insertText('hello univer'); const commentBuilder = univerAPI.newTheadComment() .setContent(richText); console.log(commentBuilder.content.toPlainText()); // Add the comment to the cell A1 const fWorkbook = univerAPI.getActiveWorkbook(); const fWorksheet = fWorkbook.getActiveSheet(); const cell = fWorksheet.getRange('A1'); const result = await cell.addCommentAsync(commentBuilder); console.log(result);

Get Cell Comment

You can get comments using the following methods, which return an instance of FThreadComment that can be used to update, delete, resolve comments, etc.

  • FWorkbook.getComments(): Get all comments of the workbook
  • FWorksheet.getComments(): Get all comments of the worksheet
  • FRange.getComment(): Get the comment of the top-left cell in the range
  • FRange.getComments(): Get comments of all cells in the range

Here are some member methods on FThreadComment:

MethodDescription
getIsRootWhether the comment is a root comment
getCommentDataGet the comment data
getRepliesGet the replies of the comment
getRangeGet the range of the comment
getRichTextGet the rich text of the comment
deleteAsyncDelete the comment and it’s replies
updateAsyncUpdate the comment content
resolveAsyncResolve the comment
replyAsyncReply to the comment
// Get all comments of the active workbook const fWorkbook = univerAPI.getActiveWorkbook(); console.log(fWorkbook.getComments()); // Get all comments of the active sheet const fWorksheet = fWorkbook.getActiveSheet(); console.log(fWorksheet.getComments()); const fRange = fWorksheet.getRange('A1:B2'); // Get comment of A1 cell console.log(fRange.getComment()); // Get comments of A1:B2 range console.log(fRange.getComments());

Clear Cell Comment

  • FWorkbook.clearComments(): Clear all comments of the workbook
  • FWorksheet.clearComments(): Clear all comments of the worksheet
  • FRange.clearCommentAsync(): Clear the comment of the top-left cell in the range
  • FRange.clearCommentsAsync(): Clear all comments of the range
// Clear all comments of the active workbook const fWorkbook = univerAPI.getActiveWorkbook(); await fWorkbook.clearComments(); // Clear all comments of the active sheet const fWorksheet = fWorkbook.getActiveSheet(); await fWorksheet.clearComments(); const fRange = fWorksheet.getRange('A1:B2'); // Clear the comment of A1 cell await fRange.clearCommentAsync(); // Clear all comments of A1:B2 range await fRange.clearCommentsAsync();

Get Comment Replies

const fWorkbook = univerAPI.getActiveWorkbook(); const fWorksheet = fWorkbook.getActiveSheet(); // Get all comments of the worksheet const comments = fWorksheet.getComments(); comments.forEach((comment) => { // If the comment is a root comment, get its reply list if (comment.getIsRoot()) { const replies = comment.getReplies(); replies.forEach((reply) => { console.log(reply.getCommentData()); }); } });

Update/Delete/Resolve/Reply Comment

const fWorkbook = univerAPI.getActiveWorkbook(); const fWorksheet = fWorkbook.getActiveSheet(); // Create a new comment and add it to A1 cell const richText = univerAPI.newRichText().insertText('hello univer'); const commentBuilder = univerAPI.newTheadComment() .setContent(richText) .setId('mock-comment-id'); const cell = fWorksheet.getRange('A1'); await cell.addCommentAsync(commentBuilder); // Update and reply the comment after 3 seconds setTimeout(async () => { // Update the comment const comment = fWorksheet.getCommentById('mock-comment-id'); const newRichText = univerAPI.newRichText().insertText('Hello Univer AI'); await comment.updateAsync(newRichText); // Reply to the comment const replyText = univerAPI.newRichText().insertText('Hello Univer AI! GO! GO! GO!'); const reply = univerAPI.newTheadComment().setContent(replyText); await comment.replyAsync(reply); }, 3000); // Resolve and delete the comment after 6 seconds setTimeout(async () => { const comment = fWorksheet.getCommentById('mock-comment-id'); await comment.resolveAsync(); await comment.deleteAsync(); }, 6000);

Event Listening

Full event type definitions, please refer to Events.

The comment module provides a series of events for monitoring comment additions, updates, deletions, and resolution status changes. All events can be listened to using univerAPI.addEvent().

Comment Add Events

univerAPI.Event.CommentAdded: Triggered after a comment is added

const disposable = univerAPI.addEvent(univerAPI.Event.CommentAdded, (params) => { const { comment, workbook, worksheet, row, col } = params; console.log(params); }); // Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentAdd: Triggered before a comment is added

const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentAdd, (params) => { const { comment, workbook, worksheet, row, col } = params; console.log(params); // Cancel the comment add operation params.cancel = true; }); // Remove the event listener, use `disposable.dispose()`

Comment Update Events

univerAPI.Event.CommentUpdated: Triggered after a comment is updated

const disposable = univerAPI.addEvent(univerAPI.Event.CommentUpdated, (params) => { const { comment, workbook, worksheet, row, col } = params; console.log(params); }); // Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentUpdate: Triggered before a comment is updated

const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentUpdate, (params) => { const { comment, workbook, worksheet, row, col, newContent } = params; console.log(params); // Cancel the comment update operation params.cancel = true; }); // Remove the event listener, use `disposable.dispose()`

Comment Deletion Events

univerAPI.Event.CommentDeleted: Triggered after a comment is deleted

const disposable = univerAPI.addEvent(univerAPI.Event.CommentDeleted, (params) => { const { commentId, workbook, worksheet } = params; console.log(params); }); // Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentDelete: Triggered before a comment is deleted

const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentDelete, (params) => { const { comment, workbook, worksheet, row, col } = params; console.log(params); // Cancel the comment delete operation params.cancel = true; }); // Remove the event listener, use `disposable.dispose()`

Comment Resolution Events

univerAPI.Event.CommentResolved: Triggered after a comment’s resolution status changes

const disposable = univerAPI.addEvent(univerAPI.Event.CommentResolved, (params) => { const { comment, row, col, resolved, workbook, worksheet } = params; console.log(params); }); // Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentResolve: Triggered before a comment’s resolution status changes

const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentResolve, (params) => { const { comment, row, col, resolved, workbook, worksheet } = params; console.log(params); // Cancel the comment resolve operation params.cancel = true; }); // Remove the event listener, use `disposable.dispose()`

Each event includes the following common parameters:

  • workbook: Current workbook instance
  • worksheet: Current worksheet instance
  • row: Row index of the comment
  • col: Column index of the comment
  • comment: Comment object (deletion event only includes commentId)

Special parameters:

  • BeforeCommentUpdate event includes newContent: New comment content (RichTextValue type)
  • CommentResolved and BeforeCommentResolve events include resolved: Comment resolution status

All event callbacks with the Before prefix can return params.cancel = true to prevent the corresponding operation.


Was this page helpful?
Last updated on