Components

Comments Panel

Comments Panel component.

Client Only

The composer supports @ user mentions, an emoji picker, and a rich-formatting toggle (a plain textarea by default, switching to the markdown editor on demand — Teams-style). Comments are stored and rendered as markdown regardless of which mode authored them, so mentions and emoji round-trip everywhere.

Installation

pnpm dlx @docyrus/cli add @docyrus/ui-comments-panel
UI Primitives(8 components)
npx shadcn@latest add avatar button dropdown-menu input popover scroll-area separator skeleton
Required Packages(3 packages)
pnpm add react-markdown remark-gfm date-fns

Composes the Emoji Picker and Simple Markdown Editor components — the CLI installs them automatically as registry dependencies.

Usage

import { CommentsPanel } from "@docyrus/ui/components/comments-panel";
import type { CommentsPanelProps } from "@docyrus/ui/components/comments-panel";

const comments: CommentsPanelProps['comments'] = [
  { id: "c-1", message: "Looks good to me.", attachments: null, created_on: "2025-12-17T10:00:00Z", last_modified_on: "2025-12-17T10:00:00Z", created_by: "u-alice", record_id: "rec-1", parent_id: null }
];

function Demo() {
  return (
    <CommentsPanel
      comments={comments}
      currentUser={{ id: "u-alice", firstname: "Alice", lastname: "Johnson" }}
      users={[
        { id: "u-alice", firstname: "Alice", lastname: "Johnson" },
        { id: "u-bob", firstname: "Bob", lastname: "Smith" }
      ]}
      onCreateComment={({ message, mentions }) => console.log(message, mentions)}
      onUpdateComment={(id, message, mentions) => console.log(id, message, mentions)}
      onDeleteComment={(id) => console.log("delete", id)}
    />
  );
}

Mentions, emoji & rich formatting

  • @ mentions — typing @ opens a user picker sourced from the users prop. The selected user is stored inline as a markdown link ([@Name](mention://<userId>)) and rendered as a highlighted chip. onCreateComment / onUpdateComment receive the referenced user ids in mentions. Disable with enableMentions={false}.
  • Emoji — the composer's emoji button inserts native unicode at the caret in both plain and rich modes. Disable with enableEmoji={false}.
  • Rich formatting — a plain textarea by default; the Aa toggle switches to the markdown editor. The mode is authoring-only — the stored value is always markdown and always rendered as markdown, so a comment written in plain mode and one written in rich mode display identically. Control availability with enableRichFormatting, the initial mode with defaultRichFormatting, or persist the user's choice with the controlled richFormatting / onRichFormattingChange pair.

Attachments

The composer takes files three ways: the paperclip button, pasting (a copied screenshot lands on the clipboard as a file, not as text), and dragging them onto the composer, which shows a drop target while a file drag is over it. All three land in the same pending list under the input and reach onCreateComment as attachments — forward that array to your upload/create call, or the picked files are silently dropped on send.

API Reference

PropTypeDefault
commentsDocyrusComment[]—
currentUserCommentUser—
usersCommentUser[]—
titlestring"Comments"
editablebooleantrue
isLoadingbooleanfalse
maxHeightnumber | string'24rem'
onCreateComment({ message, parentId?, attachments?, mentions? }) => void | Promise<void>—
onUpdateComment(id: string, message: string, mentions?: string[]) => void | Promise<void>—
onDeleteComment(id: string) => void | Promise<void>—
onUploadFile(file: File) => Promise<CommentAttachment>—
isCreatePendingbooleanfalse
isDeletePendingbooleanfalse
enableRichFormattingbooleantrue
defaultRichFormattingbooleanfalse
richFormattingboolean— (controlled)
onRichFormattingChange(rich: boolean) => void—
enableEmojibooleantrue
enableMentionsbooleantrue
classNamestring—

Components

ComponentDescription
CommentsPanelPublic export
CommentComposerInternal — comment-composer.tsx (create / reply / edit)
CommentEmptyStateInternal — comment-empty-state.tsx
CommentItemInternal — comment-item.tsx
CommentThreadInternal — comment-thread.tsx
MentionListInternal — mention-list.tsx
useCommentMentionInternal — use-comment-mention.tsx

Type Exports

TypeDescription
CommentsPanelProps—
DocyrusComment—
CommentThread—
CommentAttachment—
CommentUser—

Type Reference

DocyrusComment

FieldTypeDescription
idstring—
messagestring—
attachmentsArray<CommentAttachment> | null—
created_onstringISO date string
last_modified_onstringISO date string
created_bystringuser id
record_idstring | null—
parent_idstring | nullreply to

CommentAttachment

FieldTypeDescription
idstring—
file_namestring—
file_typestringMIME type
file_sizenumberbytes
signed_urlstring | nulldownload URL

CommentUser

FieldTypeDescription
idstring—
firstnamestring | null—
lastnamestring | null—
photostring | nullavatar image URL (mention list + comment avatars)

CommentThread

FieldTypeDescription
commentDocyrusComment—
repliesArray<DocyrusComment>—

On this page