Comments

GitHubEdit on GitHub
Preset Info
@univerjs/preset-sheets-thread-comment
Server Required
Optional

Comments allow users to add comments and replies within documents, facilitating communication and collaboration among team members.

Preset Mode

Installation

npm install @univerjs/preset-sheets-thread-comment

Usage

import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'
import { UniverSheetsThreadCommentPreset } from '@univerjs/preset-sheets-thread-comment'
import UniverPresetSheetsThreadCommentEnUS from '@univerjs/preset-sheets-thread-comment/locales/en-US'
import { createUniver, LocaleType, merge } from '@univerjs/presets'

import '@univerjs/preset-sheets-core/lib/index.css'
import '@univerjs/preset-sheets-thread-comment/lib/index.css'

const { univerAPI } = createUniver({
  locale: LocaleType.En_US,
  locales: {
    [LocaleType.En_US]: merge(
      {},
      UniverPresetSheetsCoreEnUS,
      UniverPresetSheetsThreadCommentEnUS, 
    ),
  },
  presets: [
    UniverSheetsCorePreset(),
    UniverSheetsThreadCommentPreset(), 
  ],
})

Using with Collaboration Feature

If you are using the collaboration feature with UniverSheetsCollaborationPreset, make sure to pass the collaboration: true option in UniverSheetsThreadCommentPreset:

UniverSheetsThreadCommentPreset({
  collaboration: true, 
})

Plugin Mode

Installation

npm install @univerjs/thread-comment @univerjs/thread-comment-ui @univerjs/sheets-thread-comment @univerjs/sheets-thread-comment-ui

Usage

import { LocaleType, merge, Univer } from '@univerjs/core'
import { UniverSheetsThreadCommentPlugin } from '@univerjs/sheets-thread-comment'
import { UniverSheetsThreadCommentUIPlugin } from '@univerjs/sheets-thread-comment-ui'
import SheetsThreadCommentUIEnUS from '@univerjs/sheets-thread-comment-ui/locale/en-US'
import { UniverThreadCommentPlugin } from '@univerjs/thread-comment'
import { UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui'
import ThreadCommentUIEnUS from '@univerjs/thread-comment-ui/locale/en-US'

import '@univerjs/thread-comment-ui/lib/index.css'

import '@univerjs/sheets-thread-comment/facade'

const univer = new Univer({
  locale: LocaleType.En_US,
  locales: {
    [LocaleType.En_US]: merge(
      {},
      ThreadCommentUIEnUS, 
      SheetsThreadCommentUIEnUS, 
    ),
  },
})

univer.registerPlugin(UniverThreadCommentPlugin) 
univer.registerPlugin(UniverThreadCommentUIPlugin) 
univer.registerPlugin(UniverSheetsThreadCommentPlugin) 
univer.registerPlugin(UniverSheetsThreadCommentUIPlugin) 

Using with Collaboration Feature

If you are using the collaboration feature, configure it as follows:

npm install @univerjs-pro/thread-comment-datasource
import { UniverThreadCommentDataSourcePlugin } from '@univerjs-pro/thread-comment-datasource'

univer.registerPlugin(UniverThreadCommentDataSourcePlugin) 

Facade API

Complete Facade API type definitions can be found in the FacadeAPI.

Create Cell Comment

You can create a new comment builder using univerAPI.newTheadComment(), which returns an instance of FTheadCommentBuilder. You can chain methods to set various properties of the comment.

The following are some member methods of FTheadCommentBuilder:

MethodDescription
setContentSet the content of the comment
setPersonIdSet the person ID for the comment
setDateTimeSet the date and 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 cell A1
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const cell = fWorksheet.getRange('A1')
const result = await cell.addCommentAsync(commentBuilder)

Get Cell Comments

You can retrieve comments using the following methods, which return an instance of FThreadComment. You can then perform operations such as updating, deleting, or resolving the comment.

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

The following are some member methods of FThreadComment:

MethodDescription
getIsRootWhether the comment is a root comment
getCommentDataGet the comment data
getRepliesGet the list of replies to the comment
getRangeGet the range of the comment
getRichTextGet the rich text content of the comment
deleteAsyncDelete the comment and its replies
updateAsyncUpdate the content of the comment
resolveAsyncResolve the comment
replyAsyncReply to the comment
// Get all comments in the workbook
const fWorkbook = univerAPI.getActiveWorkbook()
fWorkbook.getComments()

// Get all comments in the active worksheet
const fWorksheet = fWorkbook.getActiveSheet()
Worksheet.getComments()

const fRange = fWorksheet.getRange('A1:B2')
// Get the comment of cell A1
fRange.getComment()

// Get all comments in the range A1:B2
fRange.getComments()

Clear Cell Comments

  • FWorkbook.clearComments(): Clear all comments in the workbook
  • FWorksheet.clearComments(): Clear all comments in the worksheet
  • FRange.clearCommentAsync(): Clear the comment of the top-left cell in the range
  • FRange.clearCommentsAsync(): Clear all comments in the range
// Clear all comments in the workbook
const fWorkbook = univerAPI.getActiveWorkbook()
await fWorkbook.clearComments()

// Clear all comments in the active worksheet
const fWorksheet = fWorkbook.getActiveSheet()
await fWorksheet.clearComments()

const fRange = fWorksheet.getRange('A1:B2')

// Clear the comment of cell A1
await fRange.clearCommentAsync()

// Clear all comments in the range A1:B2
await fRange.clearCommentsAsync()

Get Comment Replies List

const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

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

Update/Delete/Resolve/Reply to Comments

const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

// Create a new comment and add it to cell A1
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 the comment and reply after 3 seconds
setTimeout(async () => {
  // Get the comment by ID and update its content
  const comment = fWorksheet.getCommentById('mock-comment-id')
  const newRichText = univerAPI.newRichText().insertText('Hello Univer AI')
  await comment.updateAsync(newRichText)

  // Create a new reply comment and set its content
  const replyText = univerAPI.newRichText().insertText('Hello Univer AI! GO! GO! GO!')
  const reply = univerAPI.newTheadComment().setContent(replyText)
  await comment.replyAsync(reply)
}, 3000)

// Resolve the comment and delete it after 6 seconds
setTimeout(async () => {
  const comment = fWorksheet.getCommentById('mock-comment-id')
  await comment.resolveAsync()
  await comment.deleteAsync()
}, 6000)

Event Listeners

Complete event type definitions can be found in Events.

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

Comment Addition 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
})

// 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

  // Cancel the comment addition 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
})

// 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

  // 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
})

// 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

  // Cancel the comment deletion operation
  params.cancel = true
})

// Remove the event listener, use `disposable.dispose()`

Comment Resolution Status Events

univerAPI.Event.CommentResolved: Triggered after the resolution status of a comment changes

const disposable = univerAPI.addEvent(univerAPI.Event.CommentResolved, (params) => {
  const { comment, row, col, resolved, workbook, worksheet } = params
})

// Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentResolve: Triggered before the resolution status of a comment changes

const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentResolve, (params) => {
  const { comment, row, col, resolved, workbook, worksheet } = params

  // Cancel the comment resolution operation
  params.cancel = true
})

// Remove the event listener, use `disposable.dispose()`

All events contain 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 (only commentId is included in deletion events)

Special parameters:

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

All Before prefixed event callback functions can return params.cancel = true to prevent the corresponding operation.