@@ -863,9 +865,5 @@ export class GroupsDemoComponent implements OnInit, OnDestroy {
handleError(error: CometChat.CometChatException): void {
console.error('Error:', error);
}
-
- handleEmpty(): void {
- console.log('No groups found');
- }
}
```
diff --git a/ui-kit/angular/components/cometchat-image-bubble.mdx b/ui-kit/angular/components/cometchat-image-bubble.mdx
index cfdef4cb4..2d4601ec9 100644
--- a/ui-kit/angular/components/cometchat-image-bubble.mdx
+++ b/ui-kit/angular/components/cometchat-image-bubble.mdx
@@ -47,7 +47,7 @@ import { CometChatImageBubbleComponent, MessageBubbleAlignment } from '@cometcha
template: `
`
})
@@ -73,13 +73,13 @@ import { CometChatImageBubbleComponent, MessageBubbleAlignment } from '@cometcha
`
})
@@ -136,7 +136,8 @@ export class InteractiveMessageComponent {
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `message` | `CometChat.MediaMessage` | **required** | The CometChat.MediaMessage object to render. Contains image attachments, metadata, and sender information |
-| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages |
+| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages |
+| `disableInteraction` | `boolean` | `false` | When `true`, disables image click/viewer interaction so the bubble renders non-interactive. The image will not open the fullscreen gallery viewer on click |
## Events
@@ -312,6 +313,9 @@ cometchat-image-bubble {
| `--cometchat-text-color-white` | Overflow text color | `#FFFFFF` |
| `--cometchat-font-heading2-bold` | Overflow text font | `600 20px Roboto` |
+
+ In addition to the global theme tokens listed above, the Image Bubble exposes component-specific CSS custom properties prefixed with `--cometchat-image-bubble-`. These are scoped to the component and can be overridden on the `cometchat-image-bubble` selector to fine-tune the bubble's appearance independently of the global theme.
+
### Custom Color Schemes
diff --git a/ui-kit/angular/components/cometchat-message-bubble.mdx b/ui-kit/angular/components/cometchat-message-bubble.mdx
index 34f662d9d..6d917ab1c 100644
--- a/ui-kit/angular/components/cometchat-message-bubble.mdx
+++ b/ui-kit/angular/components/cometchat-message-bubble.mdx
@@ -185,9 +185,24 @@ export class InteractiveMessageComponent {
MessageBubbleAlignment = MessageBubbleAlignment;
messageOptions: CometChatActionsIcon[] = [
- new CometChatActionsIcon({ id: 'reply', title: 'Reply', iconURL: 'assets/reply.svg' }),
- new CometChatActionsIcon({ id: 'copy', title: 'Copy', iconURL: 'assets/copy.svg' }),
- new CometChatActionsIcon({ id: 'delete', title: 'Delete', iconURL: 'assets/delete.svg' }),
+ new CometChatActionsIcon({
+ id: 'reply',
+ title: 'Reply',
+ iconURL: 'assets/reply.svg',
+ onClick: (messageId) => { console.log('Reply on message:', messageId); }
+ }),
+ new CometChatActionsIcon({
+ id: 'copy',
+ title: 'Copy',
+ iconURL: 'assets/copy.svg',
+ onClick: (messageId) => { console.log('Copy message:', messageId); }
+ }),
+ new CometChatActionsIcon({
+ id: 'delete',
+ title: 'Delete',
+ iconURL: 'assets/delete.svg',
+ onClick: (messageId) => { console.log('Delete message:', messageId); }
+ }),
];
onOptionClick(option: any): void {
@@ -239,7 +254,9 @@ export class InteractiveMessageComponent {
| `hideTimestamp` | `boolean` | `false` | Whether to hide the timestamp |
| `showError` | `boolean` | `false` | Whether to show error state indicator |
| `hideModerationView` | `boolean` | `false` | Whether to hide moderation status indicators |
-| `disableInteraction` | `boolean` | `false` | When true, disables all interactive elements within the bubble (context menu, reactions, etc.) |
+| `hideThreadView` | `boolean` | `false` | Whether to hide the thread-replies view |
+| `hideStatusInfoView` | `boolean` | `false` | Whether to hide the status-info view (timestamp, receipts) |
+| `disableInteraction` | `boolean` | `false` | When true, disables most interactive elements within the bubble (context menu, reactions, etc.). Note: this is not a fully-inert guarantee — some interaction paths remain, such as thread clicks (which still emit `threadRepliesClick`) and the keyboard Space media toggle on media messages (which can still emit `mediaToggle`) |
### Events
@@ -1244,17 +1261,21 @@ export class GlobalCustomizationComponent implements AfterViewInit {
ngAfterViewInit(): void {
// Set global status info view for all message types
- this.bubbleConfigService.setGlobalStatusInfoView(this.globalStatusInfo);
+ this.bubbleConfigService.setGlobalView('statusInfoView', this.globalStatusInfo);
+
+ // Set multiple global view parts at once
+ this.bubbleConfigService.setGlobalViews({
+ statusInfoView: this.globalStatusInfo
+ });
// Set custom content view for text messages only
this.bubbleConfigService.setBubbleView('text_message', {
contentView: this.customTextContent
});
- // Set multiple message type customizations at once
- this.bubbleConfigService.setMessageTemplates({
- 'text_message': { contentView: this.customTextContent },
- 'image_message': { statusInfoView: this.globalStatusInfo }
+ // Set customizations for additional message types
+ this.bubbleConfigService.setBubbleView('image_message', {
+ statusInfoView: this.globalStatusInfo
});
}
}
@@ -1265,11 +1286,11 @@ export class GlobalCustomizationComponent implements AfterViewInit {
| Method | Parameters | Description |
|--------|------------|-------------|
| `setBubbleView` | `messageType: string, map: BubblePartMap` | Set custom views for a specific message type |
-| `setGlobalStatusInfoView` | `view: TemplateRef
` | Set status info view for all message types |
-| `setGlobalLeadingView` | `view: TemplateRef` | Set leading view for all message types |
-| `setGlobalHeaderView` | `view: TemplateRef` | Set header view for all message types |
-| `setMessageTemplates` | `maps: Record` | Set multiple message type customizations |
+| `setGlobalView` | `part: BubblePart, view: TemplateRef` | Set a single view part (e.g. `'statusInfoView'`) for all message types |
+| `setGlobalViews` | `views: Partial>>` | Set multiple view parts for all message types at once |
| `getView` | `messageType: string, part: BubblePart` | Get the configured view for a message type and part |
+| `clearType` | `messageType: string` | Clear configured views for a specific message type |
+| `clearGlobalViews` | none | Clear all globally configured views |
| `clearAll` | none | Clear all configured views |
### Scoping for Multiple Instances
@@ -1348,6 +1369,14 @@ The Message Bubble component uses CSS variables for consistent theming. Override
}
```
+### Component-Specific CSS Variables
+
+In addition to the global theme tokens above, the Message Bubble component exposes its own overridable CSS custom properties, prefixed with `--cometchat-message-bubble-`. Override these to customize appearance for this component specifically, independently of the global theme tokens.
+
+
+ The component exposes `--cometchat-message-bubble-` prefixed CSS custom properties that can be overridden. Inspect the rendered `.cometchat-message-bubble` element in your browser's developer tools to discover the exact variable names exposed by your installed version of the UI Kit.
+
+
### Dark Theme
```css expandable
diff --git a/ui-kit/angular/components/cometchat-message-composer.mdx b/ui-kit/angular/components/cometchat-message-composer.mdx
index bd2c4197b..fb9f76c29 100644
--- a/ui-kit/angular/components/cometchat-message-composer.mdx
+++ b/ui-kit/angular/components/cometchat-message-composer.mdx
@@ -16,7 +16,7 @@ The component follows a **Service-Based Architecture** where:
### Key Features
- **Auto-Expanding Text Input**: Textarea that grows with content up to a configurable maximum height
-- **Multiple Attachments**: Support for images, videos, audio, and files with drag-and-drop
+- **Attachments**: Support for images, videos, audio, and files (selected files are sent directly)
- **Rich Text Editing**: Optional rich text formatting using custom RichTextEditorService (bold, italic, lists, code blocks, etc.)
- **Emoji Picker**: Built-in emoji keyboard with category navigation
- **Voice Recording**: Record and send audio messages with waveform visualization
@@ -115,17 +115,14 @@ export class GroupChatComponent {
>
```
-### With Attachments and Drag-Drop
+### With Attachments
+
+Attachments are enabled by default through the attachment button. Selected files
+are sent directly in the current build — there is no queued preview before sending.
```typescript
```
@@ -304,11 +301,6 @@ Both layouts work seamlessly with rich text editing:
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `attachmentOptions` | `CometChatMessageComposerAction[]` | `undefined` | Custom attachment options for the attachment menu |
-| `maxAttachments` | `number` | `10` | Maximum number of attachments allowed |
-| `allowedFileTypes` | `string[]` | `undefined` | Allowed MIME types for attachments (e.g., `['image/*', 'application/pdf']`) |
-| `maxFileSize` | `number` | `undefined` | Maximum file size in bytes |
-| `showAttachmentPreview` | `boolean` | `true` | Show attachment preview thumbnails before sending |
-| `enableDragDrop` | `boolean` | `true` | Enable drag-and-drop file uploads |
### Hide Option Properties
@@ -343,10 +335,9 @@ Both layouts work seamlessly with rich text editing:
| Property | Type | Default | Description |
|----------|------|---------|-------------|
-| `enableRichText` | `boolean` | `true` | Enable rich text editing. When disabled, toolbar toggle button is hidden and pasting/adding content won't apply rich text formatting. Mentions and other formatters still work independently. |
-| `hideRichTextToolbar` | `boolean` | `false` | Hide the rich text formatting toolbar. When showToolbarToggle is enabled, the toggle overrides this setting. |
-| `showBubbleMenuOnSelection` | `boolean` | `true` | Show floating bubble menu when text is selected (Web/Desktop only) |
-| `showToolbarToggle` | `boolean` | `true` | Show a toggle button to show/hide the fixed toolbar. Emits toolbarToggleClick with 'active' or 'inactive' state. |
+| `enableRichText` | `boolean` | `true` | Enable rich text editing. When disabled, pasting/adding content won't apply rich text formatting. Mentions and other formatters still work independently. |
+| `hideRichTextToolbar` | `boolean` | `false` | Hide the rich text formatting toolbar. |
+| `showBubbleMenuOnSelection` | `boolean` | `false` | Show floating bubble menu when text is selected (Web/Desktop only) |
### Other Configuration Properties
@@ -354,12 +345,12 @@ Both layouts work seamlessly with rich text editing:
|----------|------|---------|-------------|
| `disableTypingEvents` | `boolean` | `false` | Disable sending typing indicator events |
| `disableSoundForMessage` | `boolean` | `false` | Disable sound when sending messages |
-| `customSoundForMessage` | `string` | `undefined` | Custom sound URL for message sent notification |
+| `customSoundForMessage` | `string` | `''` | Custom sound URL for message sent notification. Empty string falls back to the global/default sound. |
| `liveReactionIcon` | `string` | `undefined` | Custom icon for live reaction button |
| `messageToEdit` | `CometChat.BaseMessage` | `undefined` | Message to edit (enables edit mode) |
| `messageToReply` | `CometChat.BaseMessage` | `undefined` | Message to reply to (enables reply preview) |
| `textFormatters` | `CometChatTextFormatter[]` | `undefined` | Array of text formatters to apply |
-| `showToolbarToggle` | `boolean` | `true` | Whether to show the toolbar toggle button for expanding/collapsing the action toolbar |
+| `hideError` | `boolean` | `false` | Hides the built-in composer error UI (useful when using `(error)` or a custom `errorView`). |
### Template Properties
@@ -383,8 +374,6 @@ Both layouts work seamlessly with rich text editing:
| `sendButtonClick` | `CometChat.BaseMessage` | Emitted when a message is sent successfully |
| `error` | `CometChat.CometChatException` | Emitted when an error occurs |
| `closePreview` | `void` | Emitted when the reply/edit preview is closed |
-| `attachmentAdded` | `File` | Emitted when an attachment is added |
-| `attachmentRemoved` | `File` | Emitted when an attachment is removed |
| `mentionSelected` | `CometChat.User \| CometChat.GroupMember` | Emitted when a mention is selected |
## Usage Patterns
@@ -416,9 +405,9 @@ import {
],
template: `
-
+
+
@@ -429,11 +418,24 @@ import {
`,
})
-export class ChatComponent {
- onConversationClick(conversation: any): void {}
-}
+export class ChatComponent {}
```
+
+ If you need to observe `(itemClick)` yourself, you must set the active
+ conversation manually so the message components stay in sync:
+
+ ```typescript
+ import { ChatStateService } from '@cometchat/chat-uikit-angular';
+
+ constructor(private chatState: ChatStateService) {}
+
+ onConversationClick(conversation: any): void {
+ this.chatState.setActiveConversation(conversation);
+ }
+ ```
+
+
This is the recommended approach. The composer stays in sync with the conversation list without manual wiring.
@@ -483,9 +485,49 @@ For group conversations:
## Advanced Usage
-### Reply Mode (Threaded Messages)
+### Threaded Replies
+
+Set `parentMessageId` to make outgoing messages part of a thread. This controls
+the threaded **send** behavior (the thread parent for outgoing messages) — it does
+**not** render a quoted reply preview on its own.
+
+```typescript expandable
+import { Component } from '@angular/core';
+import { CometChat } from '@cometchat/chat-sdk-javascript';
+import { CometChatMessageComposerComponent } from '@cometchat/chat-uikit-angular';
+
+@Component({
+ selector: 'app-thread-composer',
+ standalone: true,
+ imports: [CometChatMessageComposerComponent],
+ template: `
+
+ `
+})
+export class ThreadComposerComponent {
+ selectedUser!: CometChat.User;
+ parentMessageId?: number;
+
+ openThread(message: CometChat.BaseMessage): void {
+ this.parentMessageId = message.getId();
+ }
+
+ onReplySent(message: CometChat.BaseMessage): void {
+ console.log('Threaded reply sent:', message);
+ }
+}
+```
+
+### Quoted Reply Preview
-Enable reply mode by setting the `parentMessageId` to reply to a specific message:
+To show the visible quoted reply preview UI, set `messageToReply`. This drives
+the preview and works with `(closePreview)`. Note that `parentMessageId` alone
+does not render the quoted preview — `messageToReply` is what drives the preview
+plus the `closePreview` event.
```typescript expandable
import { Component } from '@angular/core';
@@ -499,27 +541,27 @@ import { CometChatMessageComposerComponent } from '@cometchat/chat-uikit-angular
template: `
`
})
export class ReplyComposerComponent {
selectedUser!: CometChat.User;
- replyToMessageId?: number;
+ message?: CometChat.BaseMessage;
replyToMessage(message: CometChat.BaseMessage): void {
- this.replyToMessageId = message.getId();
+ this.message = message;
}
onReplySent(message: CometChat.BaseMessage): void {
console.log('Reply sent:', message);
- this.replyToMessageId = undefined;
+ this.clearReply();
}
- cancelReply(): void {
- this.replyToMessageId = undefined;
+ clearReply(): void {
+ this.message = undefined;
}
}
```
@@ -593,7 +635,9 @@ export class RichTextComposerComponent {
onMessageSent(message: CometChat.BaseMessage): void {
console.log('Rich text message sent:', message);
- // Message metadata will contain rich text formatting info
+ // Rich text formatting is serialized into the message text (as markdown-style
+ // content). Note: rich-text formatting is NOT attached as message metadata
+ // (there is no `message.getMetadata().richText`) in the current send path.
}
}
```
@@ -665,12 +709,13 @@ export class BubbleMenuComposerComponent {
#### Always-Visible Toolbar
-Keep the formatting toolbar visible at all times for improved discoverability:
+Keep the formatting toolbar visible at all times for improved discoverability.
```typescript
```
@@ -696,7 +741,6 @@ Use all rich text enhancements together:
This configuration provides:
- Floating bubble menu for quick text selection formatting
-- Toolbar toggle button for showing/hiding the fixed toolbar
- Full keyboard shortcut support
### @Mentions with Custom Request Builder
@@ -746,9 +790,11 @@ export class MentionsComposerComponent implements OnInit {
}
```
-### File Attachments with Validation
+### File Attachments
-Configure attachment handling with file type and size validation:
+Attachments are handled through the attachment button. Selected files are sent
+directly (there is no queued preview in the current build). Use the `(error)`
+output to surface any send failures:
```typescript expandable
import { Component } from '@angular/core';
@@ -762,40 +808,14 @@ import { CometChatMessageComposerComponent } from '@cometchat/chat-uikit-angular
template: `
`
})
export class AttachmentsComposerComponent {
selectedUser!: CometChat.User;
-
- // Allow images, PDFs, and common document types
- allowedTypes = [
- 'image/jpeg',
- 'image/png',
- 'image/gif',
- 'application/pdf',
- 'application/msword',
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- ];
-
- onAttachmentAdded(file: File): void {
- console.log('Attachment added:', file.name, file.size);
- }
-
- onAttachmentRemoved(file: File): void {
- console.log('Attachment removed:', file.name);
- }
onError(error: CometChat.CometChatException): void {
- // Handle file validation errors
console.error('Error:', error.message);
}
}
diff --git a/ui-kit/angular/components/cometchat-outgoing-call.mdx b/ui-kit/angular/components/cometchat-outgoing-call.mdx
index 73510c3b6..1921e8286 100644
--- a/ui-kit/angular/components/cometchat-outgoing-call.mdx
+++ b/ui-kit/angular/components/cometchat-outgoing-call.mdx
@@ -33,6 +33,12 @@ The CometChatOutgoingCall component renders a full-screen outgoing call overlay
## Basic Usage
+
+ When `` is used **standalone**, it is purely presentational. Its default cancel action only stops the local ringtone and emits `(callCanceled)` — it does **not** call the Chat SDK cancellation API. Your `(callCanceled)` handler must cancel the outgoing call itself via the Chat SDK (see the example below).
+
+ When the component is rendered inside ``, the buttons component performs the SDK cancellation for you, so you should **not** cancel the call again in your own handler.
+
+
```typescript expandable
import { Component } from '@angular/core';
import { CometChat } from '@cometchat/chat-sdk-javascript';
@@ -52,8 +58,13 @@ import { CometChatOutgoingCallComponent } from '@cometchat/chat-uikit-angular';
export class OutgoingCallDemoComponent {
outgoingCall!: CometChat.Call;
- onCallCanceled(): void {
- console.log('Outgoing call canceled');
+ // Standalone usage: the component does not cancel the call for you.
+ // Your handler must reject/cancel the call through the Chat SDK.
+ async onCallCanceled(): Promise
{
+ const sessionId = this.outgoingCall?.getSessionId();
+ if (sessionId) {
+ await CometChat.rejectCall(sessionId, CometChat.CALL_STATUS.CANCELLED);
+ }
}
}
```
@@ -125,7 +136,7 @@ cometchat-outgoing-call {
### ARIA Attributes
-- `role="alertdialog"` on the overlay container
+- `role="dialog"` on the overlay container
- `aria-labelledby` references the receiver name heading
- Focus is trapped within the dialog while visible
- Initial focus is set to the cancel button
diff --git a/ui-kit/angular/components/cometchat-text-bubble.mdx b/ui-kit/angular/components/cometchat-text-bubble.mdx
index d2def7876..2554b9abf 100644
--- a/ui-kit/angular/components/cometchat-text-bubble.mdx
+++ b/ui-kit/angular/components/cometchat-text-bubble.mdx
@@ -51,7 +51,7 @@ import { CometChatTextBubbleComponent, MessageBubbleAlignment } from '@cometchat
template: `
`
})
@@ -77,13 +77,13 @@ import { CometChatTextBubbleComponent, MessageBubbleAlignment } from '@cometchat
`
})
@@ -134,7 +134,7 @@ export class InteractiveMessageComponent {
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `message` | `CometChat.TextMessage` | **required** | The CometChat.TextMessage object to render. Contains text content, metadata, and sender information |
-| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages |
+| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages |
| `textFormatters` | `CometChatTextFormatter[]` | `[]` | Array of text formatters to apply to the message text. If empty, default formatters (mentions, URLs) will be used |
| `translatedTextOverride` | `string` | `undefined` | Override for the translated text display. When provided, this text is shown as the translation instead of the message's built-in translated text |
@@ -563,6 +563,10 @@ cometchat-text-bubble {
| `--cometchat-radius-2` | Border radius | `8px` |
| `--cometchat-border-color-light` | Border color | `#E0E0E0` |
+
+ In addition to the global theme tokens listed above, the Text Bubble exposes component-specific CSS custom properties prefixed with `--cometchat-text-bubble-`. These are scoped to the component and can be overridden on the `cometchat-text-bubble` selector to fine-tune the bubble's appearance independently of the global theme.
+
+
### Custom Color Schemes
```css expandable
diff --git a/ui-kit/angular/components/cometchat-users.mdx b/ui-kit/angular/components/cometchat-users.mdx
index fe8bb6265..671e47d29 100644
--- a/ui-kit/angular/components/cometchat-users.mdx
+++ b/ui-kit/angular/components/cometchat-users.mdx
@@ -131,7 +131,7 @@ export class UsersComponent {
| `disableLoadingState` | `boolean` | `false` | Disable loading state (maintains list during search) |
| `hideUserStatus` | `boolean` | `false` | Hide online/offline status indicators |
| `showScrollbar` | `boolean` | `false` | Show/hide scrollbar in user list |
-| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu and shows the custom context menu instead |
+| `disableDefaultContextMenu` | `boolean` | `true` | When true, prevents the browser's native context menu. Custom CometChat menu visibility depends on the component's context-menu options and interaction state. |
| `showSelectedUsersPreview` | `boolean` | `false` | Show selected users preview chips (multiple mode only) |
### Data Configuration Properties
diff --git a/ui-kit/angular/components/cometchat-video-bubble.mdx b/ui-kit/angular/components/cometchat-video-bubble.mdx
index 195d3e7ba..230b3cec4 100644
--- a/ui-kit/angular/components/cometchat-video-bubble.mdx
+++ b/ui-kit/angular/components/cometchat-video-bubble.mdx
@@ -48,7 +48,7 @@ import { CometChatVideoBubbleComponent, MessageBubbleAlignment } from '@cometcha
template: `
`
})
@@ -74,13 +74,13 @@ import { CometChatVideoBubbleComponent, MessageBubbleAlignment } from '@cometcha
`
})
@@ -136,7 +136,7 @@ export class InteractiveMessageComponent {
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `message` | `CometChat.MediaMessage` | **required** | The CometChat.MediaMessage object to render. Contains video attachments, metadata, and sender information |
-| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.LEFT` | The alignment of the message bubble. `LEFT` for incoming/receiver messages, `RIGHT` for outgoing/sender messages |
+| `alignment` | `MessageBubbleAlignment` | `MessageBubbleAlignment.left` | The alignment of the message bubble. `left` for incoming/receiver messages, `right` for outgoing/sender messages |
## Events
diff --git a/ui-kit/angular/components/components-overview.mdx b/ui-kit/angular/components/components-overview.mdx
index 2b10e53b8..47d44849e 100644
--- a/ui-kit/angular/components/components-overview.mdx
+++ b/ui-kit/angular/components/components-overview.mdx
@@ -76,8 +76,8 @@ import { CometChatMessageEvents } from '@cometchat/chat-uikit-angular';
import { Subscription } from 'rxjs';
// Subscribe in ngOnInit
-this.subscription = CometChatMessageEvents.ccMessageSent.subscribe((message) => {
- // react to sent message
+this.subscription = CometChatMessageEvents.ccMessageSent.subscribe(({ message, status }) => {
+ // react to sent message; `status` is inprogress, success, or error
});
// Cleanup in ngOnDestroy
diff --git a/ui-kit/angular/events.mdx b/ui-kit/angular/events.mdx
index 6475955f7..921d4ccc9 100644
--- a/ui-kit/angular/events.mdx
+++ b/ui-kit/angular/events.mdx
@@ -53,7 +53,6 @@ Events provide decoupled communication between UIKit components using a publish/
| **ccReplyToMessage** | Triggered when the user successfully replies to a message. |
| **ccMessageDeleted** | Triggered when the user successfully deletes a message. |
| **ccMessageRead** | Triggered when the sent message is read by the receiver. |
-| **ccLiveReaction** | Triggered when the user sends a live reaction. |
### SDK Listener Events
@@ -108,8 +107,9 @@ export class ChatComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.messageSubscription = CometChatMessageEvents.ccMessageSent.subscribe(
- (message) => {
- console.log('Message sent:', message);
+ ({ message, status }) => {
+ // `status` reflects the send lifecycle: inprogress, success, or error.
+ console.log('Message sent:', message, status);
}
);
}
@@ -143,8 +143,10 @@ export class ChatListenerComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.subscriptions.add(
- CometChatMessageEvents.ccMessageSent.subscribe((message) => {
- console.log('Message sent:', message);
+ CometChatMessageEvents.ccMessageSent.subscribe(({ message, status, parentMessageId }) => {
+ // `status` reflects the send lifecycle: inprogress, success, or error.
+ // `parentMessageId` is present for thread-scoped messages.
+ console.log('Message sent:', message, status, parentMessageId);
})
);
diff --git a/ui-kit/angular/guides/custom-message-types.mdx b/ui-kit/angular/guides/custom-message-types.mdx
index e776e1980..c4a2b2c9e 100644
--- a/ui-kit/angular/guides/custom-message-types.mdx
+++ b/ui-kit/angular/guides/custom-message-types.mdx
@@ -290,6 +290,9 @@ export class LocationDemoComponent implements OnInit, AfterViewInit {
```typescript expandable
+import { CometChat } from '@cometchat/chat-sdk-javascript';
+import { CometChatUIKit } from '@cometchat/chat-uikit-angular';
+
// Send a custom location message
const receiverID = 'uid';
const customData = {
@@ -305,11 +308,17 @@ const customMessage = new CometChat.CustomMessage(
customData
);
-CometChat.sendCustomMessage(customMessage).then(
+// Prefer the UI Kit wrapper so the message participates in UI Kit
+// message events and optimistic/send-status behavior.
+CometChatUIKit.sendCustomMessage(customMessage).then(
(message) => console.log('Location sent:', message),
(error) => console.error('Error:', error)
);
```
+
+
+`CometChatUIKit.sendCustomMessage` emits the `ccMessageSent` event through its lifecycle (in-progress, success, and error) and keeps UI Kit message state in sync, so the sent message appears optimistically and updates its send status in the UI. Use the raw SDK `CometChat.sendCustomMessage` only when you deliberately want to bypass UI Kit event/state synchronization.
+
@@ -355,16 +364,16 @@ CometChat.sendCustomMessage(customMessage).then(
## Next Steps
-
+
Customize the message bubble component.
-
+
Customize the conversations list.
-
+
Override text and translations.
-
+
Customize date and time display.
diff --git a/ui-kit/angular/guides/custom-text-formatter.mdx b/ui-kit/angular/guides/custom-text-formatter.mdx
index d7b31d5bb..deae6001a 100644
--- a/ui-kit/angular/guides/custom-text-formatter.mdx
+++ b/ui-kit/angular/guides/custom-text-formatter.mdx
@@ -27,7 +27,7 @@ description: "Extend the CometChatTextFormatter base class to implement custom i
| Key event callbacks | Hooks for `keyUp` and `keyDown` events |
-Always wrap formatted output in a `` with a unique CSS class (e.g. `"custom-hashtag"`). This tells the UI Kit to render it as-is instead of sanitizing it.
+Formatter output is always sanitized (via DOMPurify in the text bubble) before it is rendered — there is no way to bypass sanitization. Make sure your custom HTML is sanitizer-compatible (DOMPurify-safe). Wrapping formatted output in a `` with a CSS class (e.g. `"custom-hashtag"`) is only a styling and identification hook; it does NOT render the output as-is or bypass sanitization.
---
diff --git a/ui-kit/angular/guides/group-chat.mdx b/ui-kit/angular/guides/group-chat.mdx
index 8b302c2f5..e2891ee7d 100644
--- a/ui-kit/angular/guides/group-chat.mdx
+++ b/ui-kit/angular/guides/group-chat.mdx
@@ -83,7 +83,10 @@ export class CreateGroupComponent {
async handleSubmit(): Promise {
const guid = `group_${Date.now()}`;
- const group = new CometChat.Group(guid, this.groupName, this.groupType, this.groupPassword);
+ const group = new CometChat.Group(guid, this.groupName, this.groupType as CometChat.GroupType);
+ if (this.groupType === CometChat.GROUP_TYPE.PASSWORD && this.groupPassword) {
+ group.setPassword(this.groupPassword);
+ }
try {
const created = await CometChat.createGroup(group);
@@ -134,13 +137,17 @@ export class JoinGroupComponent {
async joinGroup(): Promise {
try {
const joinedGroup = await CometChat.joinGroup(
- this.group.getGuid(), this.group.getType(), this.password
+ this.group.getGuid(),
+ this.group.getType() as CometChat.GroupType,
+ this.password ?? ''
);
const loggedInUser = await CometChat.getLoggedinUser();
- CometChatGroupEvents.ccGroupMemberJoined.next({
- joinedGroup,
- joinedUser: loggedInUser
- });
+ if (loggedInUser) {
+ CometChatGroupEvents.ccGroupMemberJoined.next({
+ joinedGroup,
+ joinedUser: loggedInUser,
+ });
+ }
this.groupJoined.emit(joinedGroup);
} catch {
this.error = true;
@@ -149,6 +156,10 @@ export class JoinGroupComponent {
}
```
+
+Private groups cannot be joined with `joinGroup`. They require an invitation or an admin to add the member.
+
+
---
### 3. View Group Members
@@ -173,21 +184,31 @@ onMemberClick(member: CometChat.GroupMember): void {
### 4. Add Members
-`cometchat-add-members` is a sample-app component. Use `CometChat.addMembersToGroup()` to build your own add-members UI.
+`cometchat-add-members` is a sample-app reference component driven by `ChatStateService.activeGroup`. It has no `[group]` input and no `(addMembersClick)` output — it reads the active group from the state service. Use `CometChat.addMembersToGroup()` to build your own add-members UI.
Let admins select users and add them to the group.
```html
-
-
+
```
+When you add members with a raw SDK call, emit the `ccGroupMemberAdded` UI Kit event so the rest of the UI stays in sync. Raw SDK calls alone will not produce UI Kit action-message synchronization.
+
```typescript
-onMembersAdded(members: CometChat.User[]): void {
- console.log('Added members:', members.length);
+onMembersAdded(
+ members: CometChat.User[],
+ addedGroupMembers: CometChat.GroupMember[],
+ group: CometChat.Group
+): void {
+ const loggedInUser = CometChatUIKit.getLoggedInUser();
+ if (!loggedInUser) return;
+ CometChatGroupEvents.ccGroupMemberAdded.next({
+ messages: [],
+ usersAdded: members,
+ userAddedIn: group,
+ userAddedBy: loggedInUser,
+ });
}
```
@@ -225,19 +246,19 @@ async changeMemberScope(
group: CometChat.Group
): Promise {
try {
- await CometChat.updateGroupMemberScope(
+ const oldScope = member.getScope();
+ const message = await CometChat.updateGroupMemberScope(
+ group.getGuid(),
member.getUid(),
- newScope,
- group.getGuid()
+ newScope
);
- const loggedInUser = await CometChat.getLoggedinUser();
CometChatGroupEvents.ccGroupMemberScopeChanged.next({
- changedBy: loggedInUser!,
- changedUser: member,
- changedIn: group,
- newScope,
- oldScope: member.getScope()
+ message,
+ updatedUser: member,
+ scopeChangedTo: newScope,
+ scopeChangedFrom: oldScope,
+ group
});
} catch (error) {
console.error('Failed to update member scope:', error);
@@ -245,26 +266,27 @@ async changeMemberScope(
}
```
+
+The `ccGroupMemberScopeChanged` payload uses the Angular UI Kit event shape `{ message, updatedUser, scopeChangedTo, scopeChangedFrom, group }`. The `message` is the group action message for the scope change, and the actor is read from the message via `message.getActionBy()` — there is no top-level `changedBy` field.
+
+
---
### 7. Transfer Ownership
-`cometchat-transfer-ownership` is a sample-app component. Use `CometChat.transferGroupOwnership()` to build your own transfer-ownership UI.
+`cometchat-transfer-ownership` is a sample-app reference component driven by `ChatStateService.activeGroup`. It exposes only a `(closeClick)` output — there is no `[group]` input or `(transferOwnershipClick)` output. Use `CometChat.transferGroupOwnership()` to build your own transfer-ownership UI.
Let the current owner select a member and transfer ownership.
```html
-
-
+
```
```typescript
-onOwnershipTransferred(newOwner: CometChat.GroupMember): void {
- console.log('Ownership transferred to:', newOwner.getName());
+onClose(): void {
+ console.log('Transfer ownership dialog closed');
}
```
diff --git a/ui-kit/angular/guides/mentions-formatter.mdx b/ui-kit/angular/guides/mentions-formatter.mdx
index b9682ba01..a24fdc496 100644
--- a/ui-kit/angular/guides/mentions-formatter.mdx
+++ b/ui-kit/angular/guides/mentions-formatter.mdx
@@ -143,7 +143,7 @@ mentionsFormatter.setAllMentionConfig(true, 'everyone');
Browse all feature and formatter guides.
-
+
Auto-detect and style URLs as clickable links.
diff --git a/ui-kit/angular/guides/message-privately.mdx b/ui-kit/angular/guides/message-privately.mdx
index 94adc9a36..76f25f151 100644
--- a/ui-kit/angular/guides/message-privately.mdx
+++ b/ui-kit/angular/guides/message-privately.mdx
@@ -17,7 +17,9 @@ description: "Launch a direct 1:1 chat from a group member profile in CometChat
-Message Privately lets users start a direct 1:1 conversation with a group member without leaving the group context. The user can return to the group after the private chat.
+Message Privately lets users start a direct 1:1 conversation with another group member without leaving the group context. Selecting it opens a normal 1:1 user chat — the resulting conversation is not group-scoped. The user can return to the group after the private chat.
+
+`cometchat-message-list` provides this as a built-in action. The "Message Privately" option appears only in group chats, and only for messages sent by other users. It is controlled by the `hideMessagePrivatelyOption` property, which defaults to `false`, so the action is shown by default. When a user selects it, the `(messagePrivatelyClick)` output emits the target message and user.
Before starting, complete the [Integration Guide](/ui-kit/angular/integration).
@@ -27,18 +29,42 @@ Before starting, complete the [Integration Guide](/ui-kit/angular/integration).
| Component / Selector | Role |
|:---|:---|
-| `cometchat-group-members` | Displays group members with click handlers for private messaging |
+| `cometchat-message-list` | Emits the built-in "Message Privately" action via `(messagePrivatelyClick)` and displays private conversation messages |
| `cometchat-message-header` | Header showing private chat information |
-| `cometchat-message-list` | Displays private conversation messages |
| `cometchat-message-composer` | Input component for composing private messages |
+| `cometchat-group-members` | Optional alternative entry point: start a private chat from the member list |
---
## Implementation Steps
-### 1. Group Member Click Handler
+### 1. Handle the Built-in "Message Privately" Action (Canonical)
+
+The canonical way to launch a private chat is the built-in action on `cometchat-message-list`. Bind the `(messagePrivatelyClick)` output to open a 1:1 chat with the emitted user.
+
+```html
+
+
+```
+
+```ts
+openPrivateChat(event: { message: CometChat.BaseMessage; user: CometChat.User }) {
+ this.privateChatUser = event.user;
+}
+```
+
+Notes:
+
+- `hideMessagePrivatelyOption` defaults to `false`, so the action is shown by default. Set it to `true` to hide the option.
+- The action appears only in group chats, and only for messages sent by other users.
+- Selecting it opens a normal 1:1 user chat — it is not group-scoped.
+
+---
+
+### 2. Alternative: Group Member Click Handler
-When a group member is clicked, cast them to a `User` object and initiate a private chat. Save the current group so the user can return to it later.
+As a secondary route, you can also start a private chat from the group member list. When a group member is clicked, cast them to a `User` object and initiate a private chat. Save the current group so the user can return to it later.
```typescript expandable
import { Component, OnDestroy } from '@angular/core';
@@ -77,9 +103,9 @@ export class PrivateChatComponent implements OnDestroy {
---
-### 2. Group Members with Private Messaging Option
+### 3. Alternative: Group Members with Private Messaging Option
-Render `cometchat-group-members` and handle the `(itemClick)` output to trigger the private chat flow.
+For the group-members route, render `cometchat-group-members` and handle the `(itemClick)` output to trigger the private chat flow.
```html