diff --git a/docs.json b/docs.json index bd1ec7e32..50c8578ce 100644 --- a/docs.json +++ b/docs.json @@ -450,7 +450,7 @@ "icon": "/images/icons/react.svg", "versions": [ { - "version": "v6", + "version": "v7", "default": true, "groups": [ { @@ -463,7 +463,7 @@ { "group": "React.js", "pages": [ - "ui-kit/react/react-js-integration", + "ui-kit/react/integration-react", "ui-kit/react/react-conversation", "ui-kit/react/react-one-to-one-chat", "ui-kit/react/react-tab-based-chat" @@ -472,16 +472,16 @@ { "group": "Next.js", "pages": [ - "ui-kit/react/next-js-integration", + "ui-kit/react/integration-nextjs", "ui-kit/react/next-conversation", "ui-kit/react/next-one-to-one-chat", "ui-kit/react/next-tab-based-chat" ] }, { - "group": "React-Router", + "group": "React Router", "pages": [ - "ui-kit/react/react-router-integration", + "ui-kit/react/integration-react-router", "ui-kit/react/react-router-conversation", "ui-kit/react/react-router-one-to-one-chat", "ui-kit/react/react-router-tab-based-chat" @@ -490,7 +490,7 @@ { "group": "Astro", "pages": [ - "ui-kit/react/astro-integration", + "ui-kit/react/integration-astro", "ui-kit/react/astro-conversation", "ui-kit/react/astro-one-to-one-chat", "ui-kit/react/astro-tab-based-chat" @@ -515,66 +515,96 @@ ] }, { - "group": "Theming", + "group": "Components", "pages": [ - "ui-kit/react/theme", - "ui-kit/react/theme/color-resources", - "ui-kit/react/theme/message-bubble-styling", - "ui-kit/react/localize", - "ui-kit/react/sound-manager" + "ui-kit/react/components-overview", + "ui-kit/react/components/conversations", + "ui-kit/react/components/users", + "ui-kit/react/components/groups", + "ui-kit/react/components/group-members", + "ui-kit/react/components/message-header", + "ui-kit/react/components/message-list", + "ui-kit/react/components/message-composer", + { + "group": "Message Bubbles", + "pages": [ + "ui-kit/react/components/message-bubble", + "ui-kit/react/components/text-bubble", + "ui-kit/react/components/image-bubble", + "ui-kit/react/components/video-bubble", + "ui-kit/react/components/audio-bubble", + "ui-kit/react/components/file-bubble", + "ui-kit/react/components/poll-bubble", + "ui-kit/react/components/sticker-bubble", + "ui-kit/react/components/collaborative-document-bubble", + "ui-kit/react/components/collaborative-whiteboard-bubble", + "ui-kit/react/components/call-bubble", + "ui-kit/react/components/call-action-bubble", + "ui-kit/react/components/group-action-bubble", + "ui-kit/react/components/delete-bubble" + ] + }, + "ui-kit/react/components/thread-header", + "ui-kit/react/components/message-information", + "ui-kit/react/components/reactions", + "ui-kit/react/components/reaction-list", + "ui-kit/react/components/flag-message-dialog", + "ui-kit/react/components/call-buttons", + "ui-kit/react/components/incoming-call", + "ui-kit/react/components/outgoing-call", + "ui-kit/react/components/call-logs", + "ui-kit/react/components/search", + "ui-kit/react/components/ai-assistant-chat", + "ui-kit/react/components/notification-feed" ] }, { - "group": "Components", + "group": "Plugins", "pages": [ - "ui-kit/react/components-overview", - "ui-kit/react/conversations", - "ui-kit/react/users", - "ui-kit/react/groups", - "ui-kit/react/group-members", - "ui-kit/react/message-header", - "ui-kit/react/message-list", - "ui-kit/react/message-composer", - "ui-kit/react/compact-message-composer", - "ui-kit/react/message-template", - "ui-kit/react/thread-header", - "ui-kit/react/incoming-call", - "ui-kit/react/outgoing-call", - "ui-kit/react/call-buttons", - "ui-kit/react/call-logs", - "ui-kit/react/search", - "ui-kit/react/ai-assistant-chat", - "ui-kit/react/notification-feed" + "ui-kit/react/plugins/overview", + "ui-kit/react/plugins/custom-plugin", + "ui-kit/react/plugins/text-formatters" ] }, { - "group": "Reference", + "group": "Architecture", + "pages": [ + "ui-kit/react/cometchat-provider", + "ui-kit/react/event-system" + ] + }, + { + "group": "Customization", "pages": [ - "ui-kit/react/methods", - "ui-kit/react/events" + "ui-kit/react/theming", + "ui-kit/react/theme/color-resources", + "ui-kit/react/theme/message-bubble-styling", + "ui-kit/react/localization", + "ui-kit/react/sound-manager" ] }, { "group": "Guides", "pages": [ - "ui-kit/react/guide-overview", - "ui-kit/react/guide-threaded-messages", "ui-kit/react/guide-block-unblock-user", - "ui-kit/react/guide-new-chat", - "ui-kit/react/guide-message-privately", + "ui-kit/react/guide-group-chat-setup", + "ui-kit/react/guide-threaded-messages", "ui-kit/react/guide-search-messages", - "ui-kit/react/guide-call-log-details", - "ui-kit/react/guide-group-chat", - "ui-kit/react/custom-text-formatter-guide", - "ui-kit/react/mentions-formatter-guide", - "ui-kit/react/url-formatter-guide", - "ui-kit/react/shortcut-formatter-guide" + "ui-kit/react/guide-new-chat-creation", + "ui-kit/react/guide-message-privately" + ] + }, + { + "group": "Reference", + "pages": [ + "ui-kit/react/methods" ] }, { "group": "Migration Guide", "pages": [ - "ui-kit/react/upgrading-from-v5" + "ui-kit/react/migration-overview", + "ui-kit/react/migration-property-changes" ] }, "ui-kit/react/troubleshooting", @@ -586,53 +616,53 @@ ] }, { - "version": "v7", + "version": "v6", "default": false, "groups": [ { "group": " ", "pages": [ - "ui-kit/react/v7/overview", + "ui-kit/react/v6/overview", { "group": "Getting Started", "pages": [ { "group": "React.js", "pages": [ - "ui-kit/react/v7/integration-react", - "ui-kit/react/v7/react-conversation", - "ui-kit/react/v7/react-one-to-one-chat", - "ui-kit/react/v7/react-tab-based-chat" + "ui-kit/react/v6/react-js-integration", + "ui-kit/react/v6/react-conversation", + "ui-kit/react/v6/react-one-to-one-chat", + "ui-kit/react/v6/react-tab-based-chat" ] }, { "group": "Next.js", "pages": [ - "ui-kit/react/v7/integration-nextjs", - "ui-kit/react/v7/next-conversation", - "ui-kit/react/v7/next-one-to-one-chat", - "ui-kit/react/v7/next-tab-based-chat" + "ui-kit/react/v6/next-js-integration", + "ui-kit/react/v6/next-conversation", + "ui-kit/react/v6/next-one-to-one-chat", + "ui-kit/react/v6/next-tab-based-chat" ] }, { - "group": "React Router", + "group": "React-Router", "pages": [ - "ui-kit/react/v7/integration-react-router", - "ui-kit/react/v7/react-router-conversation", - "ui-kit/react/v7/react-router-one-to-one-chat", - "ui-kit/react/v7/react-router-tab-based-chat" + "ui-kit/react/v6/react-router-integration", + "ui-kit/react/v6/react-router-conversation", + "ui-kit/react/v6/react-router-one-to-one-chat", + "ui-kit/react/v6/react-router-tab-based-chat" ] }, { "group": "Astro", "pages": [ - "ui-kit/react/v7/integration-astro", - "ui-kit/react/v7/astro-conversation", - "ui-kit/react/v7/astro-one-to-one-chat", - "ui-kit/react/v7/astro-tab-based-chat" + "ui-kit/react/v6/astro-integration", + "ui-kit/react/v6/astro-conversation", + "ui-kit/react/v6/astro-one-to-one-chat", + "ui-kit/react/v6/astro-tab-based-chat" ] }, - "ui-kit/react/v7/calling-integration" + "ui-kit/react/v6/calling-integration" ] }, { @@ -641,97 +671,82 @@ { "group": "Chat", "pages": [ - "ui-kit/react/v7/core-features", - "ui-kit/react/v7/extensions", - "ui-kit/react/v7/ai-features" + "ui-kit/react/v6/core-features", + "ui-kit/react/v6/extensions", + "ui-kit/react/v6/ai-features" ] }, - "ui-kit/react/v7/call-features" - ] - }, - { - "group": "Components", - "pages": [ - "ui-kit/react/v7/components-overview", - "ui-kit/react/v7/components/conversations", - "ui-kit/react/v7/components/users", - "ui-kit/react/v7/components/groups", - "ui-kit/react/v7/components/group-members", - "ui-kit/react/v7/components/message-header", - "ui-kit/react/v7/components/message-list", - "ui-kit/react/v7/components/message-composer", - "ui-kit/react/v7/components/message-bubble", - "ui-kit/react/v7/components/thread-header", - "ui-kit/react/v7/components/message-information", - "ui-kit/react/v7/components/reactions", - "ui-kit/react/v7/components/reaction-list", - "ui-kit/react/v7/components/action-bubble", - "ui-kit/react/v7/components/incoming-call", - "ui-kit/react/v7/components/outgoing-call", - "ui-kit/react/v7/components/call-logs", - "ui-kit/react/v7/components/search", - "ui-kit/react/v7/components/ai-assistant-chat" + "ui-kit/react/v6/call-features", + "ui-kit/react/v6/campaigns" ] }, { - "group": "Plugins", + "group": "Theming", "pages": [ - "ui-kit/react/v7/plugins/overview", - "ui-kit/react/v7/plugins/text", - "ui-kit/react/v7/plugins/image", - "ui-kit/react/v7/plugins/video", - "ui-kit/react/v7/plugins/file", - "ui-kit/react/v7/plugins/audio", - "ui-kit/react/v7/plugins/stickers", - "ui-kit/react/v7/plugins/polls", - "ui-kit/react/v7/plugins/collaborative-document", - "ui-kit/react/v7/plugins/collaborative-whiteboard", - "ui-kit/react/v7/plugins/ai", - "ui-kit/react/v7/plugins/message-translation", - "ui-kit/react/v7/plugins/group-action", - "ui-kit/react/v7/plugins/call-action", - "ui-kit/react/v7/plugins/delete", - "ui-kit/react/v7/plugins/custom-plugin", - "ui-kit/react/v7/plugins/text-formatters" + "ui-kit/react/v6/theme", + "ui-kit/react/v6/theme/color-resources", + "ui-kit/react/v6/theme/message-bubble-styling", + "ui-kit/react/v6/localize", + "ui-kit/react/v6/sound-manager" ] }, { - "group": "Architecture", + "group": "Components", "pages": [ - "ui-kit/react/v7/cometchat-provider", - "ui-kit/react/v7/event-system" + "ui-kit/react/v6/components-overview", + "ui-kit/react/v6/conversations", + "ui-kit/react/v6/users", + "ui-kit/react/v6/groups", + "ui-kit/react/v6/group-members", + "ui-kit/react/v6/message-header", + "ui-kit/react/v6/message-list", + "ui-kit/react/v6/message-composer", + "ui-kit/react/v6/compact-message-composer", + "ui-kit/react/v6/message-template", + "ui-kit/react/v6/thread-header", + "ui-kit/react/v6/incoming-call", + "ui-kit/react/v6/outgoing-call", + "ui-kit/react/v6/call-buttons", + "ui-kit/react/v6/call-logs", + "ui-kit/react/v6/search", + "ui-kit/react/v6/ai-assistant-chat", + "ui-kit/react/v6/notification-feed" ] }, { - "group": "Customization", + "group": "Reference", "pages": [ - "ui-kit/react/v7/theming", - "ui-kit/react/v7/theme/color-resources", - "ui-kit/react/v7/theme/message-bubble-styling", - "ui-kit/react/v7/localization", - "ui-kit/react/v7/sound-manager" + "ui-kit/react/v6/methods", + "ui-kit/react/v6/events" ] }, { "group": "Guides", "pages": [ - "ui-kit/react/v7/guide-block-unblock-user", - "ui-kit/react/v7/guide-group-chat-setup", - "ui-kit/react/v7/guide-threaded-messages", - "ui-kit/react/v7/guide-search-messages", - "ui-kit/react/v7/guide-new-chat-creation", - "ui-kit/react/v7/guide-message-privately" + "ui-kit/react/v6/guide-overview", + "ui-kit/react/v6/guide-threaded-messages", + "ui-kit/react/v6/guide-block-unblock-user", + "ui-kit/react/v6/guide-new-chat", + "ui-kit/react/v6/guide-message-privately", + "ui-kit/react/v6/guide-search-messages", + "ui-kit/react/v6/guide-call-log-details", + "ui-kit/react/v6/guide-group-chat", + "ui-kit/react/v6/custom-text-formatter-guide", + "ui-kit/react/v6/mentions-formatter-guide", + "ui-kit/react/v6/url-formatter-guide", + "ui-kit/react/v6/shortcut-formatter-guide" ] }, { - "group": "Reference", + "group": "Migration Guide", "pages": [ - "ui-kit/react/v7/methods" + "ui-kit/react/v6/upgrading-from-v5" ] }, - "ui-kit/react/v7/troubleshooting", - "ui-kit/react/v7/link/sample", - "ui-kit/react/v7/link/figma" + "ui-kit/react/v6/troubleshooting", + "ui-kit/react/v6/link/sample", + "ui-kit/react/v6/link/changelog", + "ui-kit/react/v6/link/figma" ] } ] @@ -816,9 +831,9 @@ "ui-kit/react/v5/property-changes" ] }, - "ui-kit/react/link/sample", - "ui-kit/react/link/changelog", - "ui-kit/react/link/figma" + "ui-kit/react/v5/link/sample", + "ui-kit/react/v5/link/changelog", + "ui-kit/react/v5/link/figma" ] } ] @@ -1012,9 +1027,9 @@ "ui-kit/react/v4/property-changes" ] }, - "ui-kit/react/link/sample", - "ui-kit/react/link/changelog", - "ui-kit/react/link/figma" + "ui-kit/react/v4/link/sample", + "ui-kit/react/v4/link/changelog", + "ui-kit/react/v4/link/figma" ] } ] diff --git a/ui-kit/react/ai-assistant-chat.mdx b/ui-kit/react/ai-assistant-chat.mdx deleted file mode 100644 index 50b37fbea..000000000 --- a/ui-kit/react/ai-assistant-chat.mdx +++ /dev/null @@ -1,957 +0,0 @@ ---- -title: "AI Assistant Chat" -description: "Composite AI agent chat with streaming responses, quick suggestions, new-chat reset, and chat history sidebar." ---- - -```json -{ - "component": "CometChatAIAssistantChat", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatAIAssistantChat } from \"@cometchat/chat-uikit-react\";", - "description": "Composite AI agent chat with streaming responses, quick suggestions, new-chat reset, and chat history sidebar.", - "cssRootClass": ".cometchat-ai-assistant-chat", - "requiredProps": { - "user": "CometChat.User — the AI agent user object" - }, - "optionalProps": { - "streamingSpeed": "number", - "suggestedMessages": "string[]", - "hideSuggestedMessages": "boolean", - "hideNewChat": "boolean", - "hideChatHistory": "boolean", - "showBackButton": "boolean", - "showCloseButton": "boolean", - "loadLastAgentConversation": "boolean", - "parentMessageId": "number", - "aiAssistantTools": "CometChatAIAssistantTools", - "templates": "CometChatMessageTemplate[]", - "headerItemView": "JSX.Element", - "headerTitleView": "JSX.Element", - "headerSubtitleView": "JSX.Element", - "headerLeadingView": "JSX.Element", - "headerTrailingView": "JSX.Element", - "headerAuxiliaryButtonView": "JSX.Element", - "emptyChatImageView": "JSX.Element", - "emptyChatGreetingView": "JSX.Element", - "emptyChatIntroMessageView": "JSX.Element", - "emptyView": "JSX.Element", - "loadingView": "JSX.Element", - "errorView": "JSX.Element" - }, - "callbacks": { - "onBackButtonClicked": "() => void", - "onCloseButtonClicked": "() => void", - "onSendButtonClick": "(message: CometChat.BaseMessage, previewMessageMode?: PreviewMessageMode) => void", - "onError": "(e: CometChat.CometChatException) => void" - }, - "events": null, - "minimalExample": "" -} -``` - - -## Where It Fits - -`CometChatAIAssistantChat` is a standalone AI chat panel. It composes an internal message header, message list, and message composer into a self-contained AI conversation experience. It requires a `CometChat.User` representing the AI agent. - - -**1:1 conversations only.** AI Agents currently respond only in one-on-one conversations between an end user and the agent user. They do not respond to messages sent in groups, even if the agent user is added as a member or owner. Group support is on the roadmap — share your use case on [feedback.cometchat.com](https://feedback.cometchat.com). - - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantPanel() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( -
- -
- ); -} -``` - - - - - ---- - -## Minimal Render - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantDemo() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ; -} -``` - -Root CSS class: `.cometchat-ai-assistant-chat` - ---- - -## Actions and Events - -### Callback Props - -#### onBackButtonClicked - -Fires when the header back button is clicked. Requires `showBackButton={true}`. - -| Detail | Value | -| --- | --- | -| When it fires | User clicks the back button | -| Payload type | `() => void` | - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantWithBack() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - console.log("Back clicked")} - /> - ); -} -``` - -#### onCloseButtonClicked - -Fires when the header close button is clicked. Requires `showCloseButton={true}`. - -| Detail | Value | -| --- | --- | -| When it fires | User clicks the close button | -| Payload type | `() => void` | - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantWithClose() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - console.log("Close clicked")} - /> - ); -} -``` - -#### onSendButtonClick - -Fires when the composer send button is clicked. - -| Detail | Value | -| --- | --- | -| When it fires | User clicks the send button | -| Payload type | `(message: CometChat.BaseMessage, previewMessageMode?: PreviewMessageMode) => void` | - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantWithSend() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - console.log("Sent:", message)} - /> - ); -} -``` - -#### onError - -Fires when the component encounters an internal error. - -| Detail | Value | -| --- | --- | -| When it fires | Any internal error during rendering or data fetching | -| Payload type | `(error: CometChat.CometChatException) => void` | - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantWithError() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - console.error("AI chat error:", error)} - /> - ); -} -``` - -### Global UI Events - -The AI Assistant Chat component does not emit global UI events. Interaction handling uses the callback props above. - -### SDK Events (Real-Time, Automatic) - -The component internally manages SDK communication for AI streaming. No manual listener attachment needed. - ---- - -## Custom View Slots - -| Slot | Type | Replaces | -| --- | --- | --- | -| `headerItemView` | `JSX.Element` | Entire header list item | -| `headerTitleView` | `JSX.Element` | Header title text | -| `headerSubtitleView` | `JSX.Element` | Header subtitle text | -| `headerLeadingView` | `JSX.Element` | Header avatar / left section | -| `headerTrailingView` | `JSX.Element` | Header right section | -| `headerAuxiliaryButtonView` | `JSX.Element` | Header auxiliary buttons (New Chat, History) | -| `emptyChatImageView` | `JSX.Element` | Empty state image | -| `emptyChatGreetingView` | `JSX.Element` | Empty state greeting title | -| `emptyChatIntroMessageView` | `JSX.Element` | Empty state intro subtitle | -| `emptyView` | `JSX.Element` | Message list empty state | -| `loadingView` | `JSX.Element` | Loading state | -| `errorView` | `JSX.Element` | Error state | -| `aiAssistantTools` | `CometChatAIAssistantTools` | Tool/function call handlers | -| `templates` | `CometChatMessageTemplate[]` | Message bubble templates | - -### emptyChatImageView - - - - - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantCustomImage() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - } - /> - ); -} -``` - -### emptyChatGreetingView - - - - - - - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantCustomGreeting() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - - Free Plan . - Upgrade - - } - /> - ); -} -``` - - -```css lines -.cometchat-ai-assistant-chat__empty-chat-greeting { - display: flex; - padding: 8px 20px; - justify-content: center; - align-items: center; - gap: 8px; - border-radius: 6px; - border: 1px solid #e8e8e8; - background: #f5f5f5; - width: fit-content; - align-self: center; -} - -.cometchat-ai-assistant-chat__empty-chat-greeting .upgrade-button { - color: #6852d6; -} -``` - - - -### emptyChatIntroMessageView - - - - - - - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function AIAssistantCustomIntro() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - - Hey, nice to see you What's new? - - } - /> - ); -} -``` - - -```css lines -.cometchat-ai-assistant-chat__empty-chat-intro { - display: flex; - padding: 12px; - justify-content: center; - align-items: center; - gap: 10px; - border-radius: 12px; - background: #f9f8fd; - width: 172px; - color: #141414; - text-align: center; - font-size: 16px; - font-weight: 400; - line-height: 140%; - margin: 10px 0; -} -``` - - - -### aiAssistantTools - -Pass a `CometChatAIAssistantTools` instance to enable tool/function calls during assistant replies. - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatAIAssistantChat, - CometChatAIAssistantTools, -} from "@cometchat/chat-uikit-react"; - -function AIAssistantWithTools() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - const tools = new CometChatAIAssistantTools({ - getCurrentWeather: ({ location }: { location: string }) => { - console.log("Fetching weather for", location); - }, - createTicket: ({ title }: { title: string }) => { - console.log("Create ticket:", title); - }, - }); - - if (!agent) return null; - - return ; -} -``` - -### templates - -Custom message templates to control message bubble rendering. See [CometChatMessageTemplate](/ui-kit/react/message-template). - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatAIAssistantChat, - ChatConfigurator, -} from "@cometchat/chat-uikit-react"; - -function AIAssistantWithTemplates() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - const getTemplates = () => { - const templates = ChatConfigurator.getDataSource().getAllMessageTemplates(); - templates.map((data) => { - data.footerView = (message) => null; - }); - return templates; - }; - - if (!agent) return null; - - return ; -} -``` - ---- - -## Common Patterns - -### AI assistant with suggestions and history - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function FullFeaturedAssistant() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - console.log("Navigate back")} - /> - ); -} -``` - -### Minimal assistant — no chrome - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAIAssistantChat } from "@cometchat/chat-uikit-react"; - -function MinimalAssistant() { - const [agent, setAgent] = useState(); - - useEffect(() => { - CometChat.getUser("assistant_uid").then((u) => setAgent(u)); - }, []); - - if (!agent) return null; - - return ( - - ); -} -``` - ---- - -## CSS Architecture - -The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade: - -1. Global tokens (e.g., `--cometchat-primary-color`, `--cometchat-background-color-01`) set on the `.cometchat` root wrapper. -2. Component CSS (`.cometchat-ai-assistant-chat`) consumes these tokens via `var()`. -3. Overrides target `.cometchat-ai-assistant-chat` descendant selectors. - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-ai-assistant-chat` | -| Wrapper | `.cometchat-ai-assistant-chat__wrapper` | -| Header wrapper | `.cometchat-ai-assistant-chat__header-wrapper` | -| Header auxiliary view | `.cometchat-ai-assistant-chat__header-auxiliary-view` | -| Message list wrapper | `.cometchat-ai-assistant-chat__message-list-wrapper` | -| Composer wrapper | `.cometchat-ai-assistant-chat__composer-wrapper` | -| Send button | `.cometchat-ai-assistant-chat__send-button-view` | -| Send button (active) | `.cometchat-ai-assistant-chat__send-button-view--active` | -| Send button (streaming) | `.cometchat-ai-assistant-chat__send-button-view--streaming` | -| Empty state | `.cometchat-ai-assistant-chat__empty-state` | -| Empty state content | `.cometchat-ai-assistant-chat__empty-state-content` | -| Empty state icon | `.cometchat-ai-assistant-chat__empty-state-icon` | -| Greeting message | `.cometchat-ai-assistant-chat__empty-state-greeting-message` | -| Intro message | `.cometchat-ai-assistant-chat__empty-state-intro-message` | -| Suggested messages | `.cometchat-ai-assistant-chat__empty-state-suggested-messages` | -| Suggestion pill | `.cometchat-ai-assistant-chat__suggested-message-pill` | -| Suggestion icon | `.cometchat-ai-assistant-chat__suggested-message-icon` | -| Chat history sidebar | `.cometchat-ai-assistant-chat__sidebar` | -| Sidebar open | `.cometchat-ai-assistant-chat__sidebar--open` | -| Sidebar overlay | `.cometchat-ai-assistant-chat__sidebar-overlay` | -| Copy button | `.cometchat-ai-assistant-message-bubble__copy` | - -### Example: Brand-themed AI assistant - - - - - -```css lines -.cometchat-ai-assistant-chat - .cometchat-ai-assistant-chat__suggested-message-pill { - background: #30a46c; - color: #ffffff; - font-size: 9px; -} - -.cometchat-ai-assistant-chat - .cometchat-ai-assistant-chat__suggested-message-pill - .cometchat-ai-assistant-chat__suggested-message-icon { - background: #ffffff; - width: 9.55px; - height: 9.55px; -} - -.cometchat-ai-assistant-chat - .cometchat-ai-assistant-chat__header-auxiliary-view - .cometchat-button - .cometchat-button__icon-default { - background: #30a46c; -} -``` - -### Customization Matrix - -| What to change | Where | Property/API | Example | -| --- | --- | --- | --- | -| Override behavior on user interaction | Component props | `on` callbacks | `onBackButtonClicked={() => navigate(-1)}` | -| Toggle visibility of UI elements | Component props | `hide` / `show` boolean props | `hideNewChat={true}` | -| Replace a section of the UI | Component props | View slot props | `emptyChatGreetingView={
Hello
}` | -| Change colors, fonts, spacing | Global CSS | Target `.cometchat-ai-assistant-chat` class | `.cometchat-ai-assistant-chat .cometchat-ai-assistant-chat__suggested-message-pill { background: #30a46c; }` | - ---- - -## Props - -### aiAssistantTools - -| Key | Value | -| --- | --- | -| Type | `CometChatAIAssistantTools` | -| Default | `undefined` | - -Tool/function call handlers for the AI assistant. - ---- - -### emptyView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Custom empty state for the message list. - ---- - -### emptyChatGreetingView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Custom greeting title in the empty chat state. Default uses agent metadata `greetingMessage` or user name. - ---- - -### emptyChatImageView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Custom image in the empty chat state. - ---- - -### emptyChatIntroMessageView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Custom intro subtitle in the empty chat state. Default uses agent metadata `introductoryMessage`. - ---- - -### errorView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Custom error state view. - ---- - -### headerAuxiliaryButtonView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Replaces the header auxiliary buttons (New Chat, History). - ---- - -### headerItemView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Replaces the entire header list item. - ---- - -### headerLeadingView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Replaces the header avatar / left section. - ---- - -### headerSubtitleView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Replaces the header subtitle text. - ---- - -### headerTitleView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Replaces the header title text. - ---- - -### headerTrailingView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Replaces the header right section. - ---- - -### hideChatHistory - -| Key | Value | -| --- | --- | -| Type | `boolean` | -| Default | `undefined` | - -Hides the History button/sidebar. - ---- - -### hideNewChat - -| Key | Value | -| --- | --- | -| Type | `boolean` | -| Default | `undefined` | - -Hides the New Chat button in header. - ---- - -### hideSuggestedMessages - -| Key | Value | -| --- | --- | -| Type | `boolean` | -| Default | `undefined` | - -Hides the suggested messages section in the empty state. - ---- - -### loadLastAgentConversation - -| Key | Value | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - -Loads the most recent existing agent conversation on mount. - ---- - -### loadingView - -| Key | Value | -| --- | --- | -| Type | `React.JSX.Element` | -| Default | `undefined` | - -Custom loading state view. - ---- - -### onBackButtonClicked - -| Key | Value | -| --- | --- | -| Type | `() => void` | -| Default | `undefined` | - -Fires when the header back button is clicked. Requires `showBackButton={true}`. - ---- - -### onCloseButtonClicked - -| Key | Value | -| --- | --- | -| Type | `() => void` | -| Default | `undefined` | - -Fires when the header close button is clicked. Requires `showCloseButton={true}`. - ---- - -### onError - -| Key | Value | -| --- | --- | -| Type | `(e: CometChat.CometChatException) => void` | -| Default | `undefined` | - -Fires on internal errors. - ---- - -### onSendButtonClick - -| Key | Value | -| --- | --- | -| Type | `(message: CometChat.BaseMessage, previewMessageMode?: PreviewMessageMode) => void` | -| Default | `undefined` | - -Fires when the composer send button is clicked. - ---- - -### parentMessageId - -| Key | Value | -| --- | --- | -| Type | `number` | -| Default | `undefined` | - -Loads a specific agent conversation. Takes priority over `loadLastAgentConversation`. - ---- - -### showBackButton - -| Key | Value | -| --- | --- | -| Type | `boolean` | -| Default | `undefined` | - -Shows back button in header. - ---- - -### showCloseButton - -| Key | Value | -| --- | --- | -| Type | `boolean` | -| Default | `undefined` | - -Shows close button in header. - ---- - -### streamingSpeed - -| Key | Value | -| --- | --- | -| Type | `number` | -| Default | `undefined` | - -Characters-per-second speed for streaming replies. - ---- - -### suggestedMessages - -| Key | Value | -| --- | --- | -| Type | `string[]` | -| Default | `undefined` | - -Quick prompt suggestions displayed in the empty state. - ---- - -### templates - -| Key | Value | -| --- | --- | -| Type | `CometChatMessageTemplate[]` | -| Default | `undefined` | - -Custom message bubble templates. See [CometChatMessageTemplate](/ui-kit/react/message-template). - ---- - -### user - -| Key | Value | -| --- | --- | -| Type | `CometChat.User` | -| Default | — (required) | - -The AI agent user object. Must be fetched via `CometChat.getUser()` before passing. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-ai-assistant-chat` | -| Wrapper | `.cometchat-ai-assistant-chat__wrapper` | -| Header wrapper | `.cometchat-ai-assistant-chat__header-wrapper` | -| Header auxiliary view | `.cometchat-ai-assistant-chat__header-auxiliary-view` | -| Message list wrapper | `.cometchat-ai-assistant-chat__message-list-wrapper` | -| Composer wrapper | `.cometchat-ai-assistant-chat__composer-wrapper` | -| Send button | `.cometchat-ai-assistant-chat__send-button-view` | -| Send button (active) | `.cometchat-ai-assistant-chat__send-button-view--active` | -| Send button (streaming) | `.cometchat-ai-assistant-chat__send-button-view--streaming` | -| Empty state | `.cometchat-ai-assistant-chat__empty-state` | -| Empty state content | `.cometchat-ai-assistant-chat__empty-state-content` | -| Empty state icon | `.cometchat-ai-assistant-chat__empty-state-icon` | -| Greeting message | `.cometchat-ai-assistant-chat__empty-state-greeting-message` | -| Intro message | `.cometchat-ai-assistant-chat__empty-state-intro-message` | -| Suggested messages | `.cometchat-ai-assistant-chat__empty-state-suggested-messages` | -| Suggestion pill | `.cometchat-ai-assistant-chat__suggested-message-pill` | -| Suggestion icon | `.cometchat-ai-assistant-chat__suggested-message-icon` | -| Chat history sidebar | `.cometchat-ai-assistant-chat__sidebar` | -| Sidebar open | `.cometchat-ai-assistant-chat__sidebar--open` | -| Sidebar overlay | `.cometchat-ai-assistant-chat__sidebar-overlay` | -| Copy button | `.cometchat-ai-assistant-message-bubble__copy` | diff --git a/ui-kit/react/ai-features.mdx b/ui-kit/react/ai-features.mdx index e929a26f5..d2109453c 100644 --- a/ui-kit/react/ai-features.mdx +++ b/ui-kit/react/ai-features.mdx @@ -8,9 +8,9 @@ description: "AI-powered features in CometChat's React UI Kit: Conversation Star | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Required setup | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` + AI features enabled in [CometChat Dashboard](/fundamentals/ai-user-copilot/overview) | +| Required setup | Wrap app in `CometChatProvider` with valid credentials + AI features enabled in [CometChat Dashboard](/fundamentals/ai-user-copilot/overview) | | AI features | Conversation Starter, Smart Replies, Conversation Summary | -| Key components | `CometChatMessageList` → [Message List](/ui-kit/react/message-list) (Conversation Starter), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/message-composer) (Smart Replies, Summary), `CometChatAIAssistantChat` → [AI Assistant Chat](/ui-kit/react/ai-assistant-chat) | +| Key components | `CometChatMessageList` → [Message List](/ui-kit/react/components/message-list) (Conversation Starter), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/components/message-composer) (Smart Replies, Summary), `CometChatAIAssistantChat` → [AI Assistant Chat](/ui-kit/react/components/ai-assistant-chat) | | Activation | Enable each AI feature from the CometChat Dashboard — UI Kit auto-integrates them, no additional code required | @@ -19,13 +19,14 @@ description: "AI-powered features in CometChat's React UI Kit: Conversation Star CometChat AI features enhance user interaction by providing contextual suggestions and summaries. Each feature is activated from the Dashboard and auto-integrates into UI Kit components. + ## Smart Chat Features ### Conversation Starter Displays AI-generated opening lines when a user starts a new chat. See [Conversation Starter](/fundamentals/ai-user-copilot/conversation-starter). -Auto-integrates into [MessageList](/ui-kit/react/message-list) when activated. +Auto-integrates into [MessageList](/ui-kit/react/components/message-list) when activated. @@ -35,7 +36,7 @@ Auto-integrates into [MessageList](/ui-kit/react/message-list) when activated. AI-generated response suggestions based on conversation context. See [Smart Replies](/fundamentals/ai-user-copilot/smart-replies). -Auto-integrates into the Action Sheet of [MessageComposer](/ui-kit/react/message-composer) when activated. +Auto-integrates into the Action Sheet of [MessageComposer](/ui-kit/react/components/message-composer) when activated. @@ -45,7 +46,7 @@ Auto-integrates into the Action Sheet of [MessageComposer](/ui-kit/react/message AI-generated recap of long conversations. See [Conversation Summary](/fundamentals/ai-user-copilot/conversation-summary). -Auto-integrates into the Action Sheet of [MessageComposer](/ui-kit/react/message-composer) when activated. +Auto-integrates into the Action Sheet of [MessageComposer](/ui-kit/react/components/message-composer) when activated. @@ -54,13 +55,13 @@ Auto-integrates into the Action Sheet of [MessageComposer](/ui-kit/react/message ## Next Steps - + AI-powered assistant component - + Customize the message list where AI features appear - + Customize the composer with Smart Replies and Summary diff --git a/ui-kit/react/astro-conversation.mdx b/ui-kit/react/astro-conversation.mdx index 975ac29b3..22f15a876 100644 --- a/ui-kit/react/astro-conversation.mdx +++ b/ui-kit/react/astro-conversation.mdx @@ -1,7 +1,7 @@ --- title: "Conversation List + Message View" sidebarTitle: "Conversation List + Message View" -description: "Build CometChat UI Kit conversation list and message view layouts in Astro with navigation, headers, lists, and composers." +description: "Build a two-panel conversation list + message view layout in Astro with CometChat UI Kit." --- @@ -9,23 +9,24 @@ description: "Build CometChat UI Kit conversation list and message view layouts | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Framework | Astro (with `@astrojs/react` islands) | +| Framework | Astro | | Components | `CometChatConversations`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | | Layout | Two-panel — conversation list (left) + message view (right) | -| Prerequisite | Complete [Astro Integration](/ui-kit/react/astro-integration) Steps 1–5 first | -| SSR | `client:only="react"` directive — CometChat requires browser APIs | +| Prerequisite | Complete [Astro Integration](/ui-kit/react/integration-astro) first | +| SSR | React island with `client:only="react"` directive | | Pattern | WhatsApp Web, Slack, Microsoft Teams | -This guide builds a two-panel chat layout — conversation list on the left, messages on the right. Users tap a conversation to open it. +This guide builds a two-panel chat layout — conversation list on the left, messages on the right. Users click a conversation to open it. -This assumes you've already completed [Astro Integration](/ui-kit/react/astro-integration) (project created, React added, UI Kit installed). +This assumes you've already completed [Astro Integration](/ui-kit/react/integration-astro) (project created, UI Kit installed, init + login working). - + + --- ## What You're Building @@ -38,233 +39,156 @@ Three sections working together: --- -## Step 1 — Create the React Island - -Create a `ChatApp` component inside `src/components/`. This is a React island that handles init, login, and renders the full chat experience. - - - - - - - - - +## Full Code - - +Create a React island component with the chat UI, then render it in an Astro page with `client:only="react"`. -```tsx title="ChatApp.tsx" lines highlight={15-17, 20} +```tsx title="src/components/ConversationChat.tsx" import { useEffect, useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; import { + CometChatUIKit, + UIKitSettingsBuilder, + CometChatProvider, CometChatConversations, - CometChatMessageComposer, CometChatMessageHeader, CometChatMessageList, - CometChatUIKit, - UIKitSettingsBuilder, + CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import "@cometchat/chat-uikit-react/css-variables.css"; -import "./ChatApp.css"; - -const COMETCHAT_CONSTANTS = { - APP_ID: "", // Replace with your App ID - REGION: "", // Replace with your Region - AUTH_KEY: "", // Replace with your Auth Key (dev only) -}; -const UID = "cometchat-uid-1"; // Replace with your actual UID - -export default function ChatApp() { - const [user, setUser] = useState(undefined); +export default function ConversationChat() { + const [ready, setReady] = useState(false); const [selectedUser, setSelectedUser] = useState(undefined); const [selectedGroup, setSelectedGroup] = useState(undefined); useEffect(() => { - const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") .subscribePresenceForAllUsers() .build(); - CometChatUIKit.init(UIKitSettings) - .then(() => { - console.log("Initialization completed successfully"); - CometChatUIKit.getLoggedinUser().then((loggedInUser) => { - if (!loggedInUser) { - CometChatUIKit.login(UID) - .then((u) => { - console.log("Login Successful", { u }); - setUser(u); - }) - .catch((error) => console.error("Login failed", error)); - } else { - console.log("Already logged-in", { loggedInUser }); - setUser(loggedInUser); - } - }); - }) - .catch((error) => console.error("Initialization failed", error)); + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + setReady(true); + }); }, []); - if (!user) return
Initializing Chat...
; + if (!ready) return
Loading chat...
; - return ( -
-
- { - let item: any = activeItem; - if (activeItem instanceof CometChat.Conversation) { - item = activeItem.getConversationWith(); - } - if (item instanceof CometChat.User) { - setSelectedUser(item); - setSelectedGroup(undefined); - } else if (item instanceof CometChat.Group) { - setSelectedUser(undefined); - setSelectedGroup(item); - } else { - setSelectedUser(undefined); - setSelectedGroup(undefined); - } - }} - /> -
+ const handleConversationClick = (conversation: CometChat.Conversation) => { + const entity = conversation.getConversationWith(); + if (conversation.getConversationType() === "user") { + setSelectedUser(entity as CometChat.User); + setSelectedGroup(undefined); + } else { + setSelectedGroup(entity as CometChat.Group); + setSelectedUser(undefined); + } + }; - {selectedUser || selectedGroup ? ( -
- - - + return ( + +
+
+
- ) : ( -
Select a conversation to start chatting
- )} -
- ); -} -``` - - - -```css title="ChatApp.css" lines -.conversations-with-messages { - display: flex; - height: 100%; - width: 100%; -} - -.conversations-wrapper { - height: 100%; - width: 480px; - overflow: hidden; - display: flex; - flex-direction: column; -} - -.conversations-wrapper > .cometchat { - overflow: hidden; -} - -.messages-wrapper { - width: calc(100% - 480px); - height: 100%; - display: flex; - flex-direction: column; -} - -.empty-conversation { - height: 100%; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - background: var(--cometchat-background-color-03, #F5F5F5); - color: var(--cometchat-text-color-secondary, #727272); - font: var(--cometchat-font-body-regular, 400 14px Roboto); -} - -.cometchat .cometchat-message-composer { - border-radius: 0px; + {selectedUser || selectedGroup ? ( +
+ + + +
+ ) : ( +
+ Select a conversation to start chatting +
+ )} +
+ + ); } ``` - - - -**How it works**: -- Init and login happen inside `useEffect` — the component only renders chat UI after login resolves. -- When a conversation is tapped, the `User` or `Group` is extracted from the `Conversation` object. -- `selectedUser` / `selectedGroup` state drives which chat is displayed — pass either `user` or `group` to the message components, never both. - +```astro title="src/pages/chat.astro" --- - -## Step 2 — Render the Astro Page - -Import the island and hydrate it client-side using `client:only="react"`. - -```astro title="src/pages/index.astro" lines ---- -import ChatApp from "../components/ChatApp.tsx"; -import "../styles/globals.css"; +import ConversationChat from '../components/ConversationChat.tsx'; --- - CometChat + Astro + + Chat - - + + ``` -The `client:only="react"` directive ensures the component skips SSR entirely and only renders in the browser — required because CometChat needs `window` and `WebSocket`. +--- + +## How It Works + +1. **`client:only="react"`** tells Astro to skip server-rendering and hydrate the component entirely on the client. This is required because CometChat uses browser APIs. +2. **React island** — the CometChat UI lives in a self-contained React component. Astro handles the page shell, React handles the interactive chat. +3. **CometChatProvider** wraps the entire tree — it supplies theme, locale, and event context to all CometChat components. +4. **CometChatConversations** renders the sidebar list. When a user clicks a conversation, `onItemClick` fires with the `Conversation` object. +5. **handleConversationClick** extracts the `User` or `Group` from the conversation and stores it in state. +6. **Message components** (`MessageHeader`, `MessageList`, `MessageComposer`) receive either `user` or `group` as a prop — never both at the same time. --- -## Step 3 — Run the Project +## Run - - -```bash lines +```bash npm run dev ``` - - -```bash lines -pnpm dev -``` - - -```bash lines -yarn dev -``` - - -You should see the conversation list on the left. Tap any conversation to load messages on the right. +Open `http://localhost:4321/chat`. You should see the conversation list on the left. Click any conversation to load messages on the right. --- ## Next Steps - - Customize colors, fonts, and styles to match your brand + + Single chat window without a sidebar + + + Tabbed navigation with Chats, Calls, Users Browse all prebuilt UI components - } href="/ui-kit/react/astro-integration"> - Back to the main setup guide - - - Chat features included out of the box + + Customize colors, fonts, and styles diff --git a/ui-kit/react/astro-integration.mdx b/ui-kit/react/astro-integration.mdx deleted file mode 100644 index df460f8f8..000000000 --- a/ui-kit/react/astro-integration.mdx +++ /dev/null @@ -1,329 +0,0 @@ ---- -title: "Astro Integration" -sidebarTitle: "Integration" -description: "Integrate CometChat React UI Kit with Astro using client-only rendering, app credentials, package setup, initialization, and login." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Peer deps | `react` >=18, `react-dom` >=18, `@astrojs/react` | -| Init | `CometChatUIKit.init(UIKitSettings)` — must resolve before `login()` | -| Login | `CometChatUIKit.login("UID")` — must resolve before rendering components | -| Order | `init()` → `login()` → render. Breaking this order = blank screen | -| Auth Key | Dev/testing only. Use Auth Token in production | -| SSR | CometChat requires browser APIs — use `client:only="react"` directive on Astro islands | -| CSS | `import "@cometchat/chat-uikit-react/css-variables.css"` in your React island | -| Calling | Optional. Install `@cometchat/calls-sdk-javascript` to enable | -| Other frameworks | [React.js](/ui-kit/react/react-js-integration) · [Next.js](/ui-kit/react/next-js-integration) · [React Router](/ui-kit/react/react-router-integration) | -| AI Skills | `npx @cometchat/skills add` — [GitHub](https://github.com/cometchat/cometchat-skills) | - - - -This guide walks you through adding CometChat to an Astro app using React islands. By the end you'll have a working chat UI. - - -CometChat UI Kit requires browser APIs (`window`, `WebSocket`, `document`). In Astro, always load CometChat components using the `client:only="react"` directive so they only render client-side. - - ---- - -## Integrate with AI Coding Agents - -Skip the manual steps — use [CometChat Skills](https://github.com/cometchat/cometchat-skills) to integrate via your AI coding agent. Your agent has a short conversation with you to understand your project and chat requirements, then writes production-grade integration code tailored to the files you already have. - -```bash -npx @cometchat/skills add -``` - -Use `--ide ` to target a specific IDE (e.g. `--ide cursor`), or `--ide all` for all supported IDEs. - -Then in your IDE: - -``` -/cometchat add chat to my app -``` - -The skill detects Astro, verifies `@astrojs/react` is configured, and reads your routes, nav, and components before proposing a placement. It onboards you to CometChat directly in the terminal — signup, login, and app creation all via the CLI. It shows the plan and waits for your approval before writing code. - -After the first integration, re-run `/cometchat` to access the iteration menu: theme presets, 40+ features, component customization, floating widget, production auth, user management, and diagnostics. - -Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and [30+ more agents](https://github.com/cometchat/cometchat-skills). - ---- - -## Prerequisites - -You need three things from the [CometChat Dashboard](https://app.cometchat.com/): - -| Credential | Where to find it | -| --- | --- | -| App ID | Dashboard → Your App → Credentials | -| Auth Key | Dashboard → Your App → Credentials | -| Region | Dashboard → Your App → Credentials (e.g. `us`, `eu`, `in`) | - -You also need Node.js (v16+) and npm/yarn installed. - - -Auth Key is for development only. In production, generate Auth Tokens server-side via the [REST API](/rest-api/chat-apis) and use [`loginWithAuthToken()`](/ui-kit/react/methods#login-using-auth-token). Never ship Auth Keys in client code. - - ---- - -## Step 1 — Create an Astro Project - - - -```bash lines -npm create astro@latest my-app -cd my-app -``` - - -```bash lines -pnpm create astro@latest my-app -cd my-app -``` - - -```bash lines -yarn create astro my-app -cd my-app -``` - - - ---- - -## Step 2 — Add React and Install the UI Kit - -First, add the React integration to Astro: - -```bash lines -npx astro add react -``` - -This updates your `astro.config.mjs` automatically. Verify it includes: - -```js title="astro.config.mjs" lines -import { defineConfig } from "astro/config"; -import react from "@astrojs/react"; - -export default defineConfig({ - integrations: [react()], -}); -``` - -Then install the UI Kit: - - - -```bash lines -npm install @cometchat/chat-uikit-react -``` - - -```bash lines -yarn add @cometchat/chat-uikit-react -``` - - - -This installs the UI Kit and its dependency `@cometchat/chat-sdk-javascript` automatically. - -If you want voice/video calling, also install: - -```bash lines -npm install @cometchat/calls-sdk-javascript -``` - ---- - -## Step 3 — Initialize CometChat - -In Astro, CometChat init and login happen inside your React island component (since they need browser APIs). Here's the pattern: - -```tsx lines highlight={7-9} -import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; - -/** - * CometChat Constants - Replace with your actual credentials - */ -const COMETCHAT_CONSTANTS = { - APP_ID: "APP_ID", // Replace with your actual App ID from CometChat - REGION: "REGION", // Replace with your App's Region - AUTH_KEY: "AUTH_KEY", // Replace with your Auth Key (leave blank if using Auth Token) -}; - -const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) - .subscribePresenceForAllUsers() - .build(); - -CometChatUIKit.init(UIKitSettings) - .then(() => { - console.log("CometChat UI Kit initialized successfully."); - }) - .catch((error) => { - console.error("CometChat UI Kit initialization failed:", error); - }); -``` - - -`init()` must resolve before you call `login()`. If you call `login()` before init completes, it will fail silently. - - ---- - -## Step 4 — Login - -After init resolves, log the user in. For development, use one of the pre-created test UIDs: - -`cometchat-uid-1` · `cometchat-uid-2` · `cometchat-uid-3` · `cometchat-uid-4` · `cometchat-uid-5` - -```ts lines highlight={3} -import { CometChatUIKit } from "@cometchat/chat-uikit-react"; - -const UID = "UID"; // Replace with your actual UID - -CometChatUIKit.getLoggedinUser().then((user) => { - if (!user) { - CometChatUIKit.login(UID) - .then((user) => { - console.log("Login Successful:", { user }); - // Mount your app - }) - .catch(console.log); - } else { - // Already logged in — mount your app - } -}); -``` - -Key points: -- `getLoggedinUser()` checks for an existing session so you don't re-login unnecessarily. -- `login(uid)` skips the API call if a session already exists and returns the cached user. -- Components must not render until login resolves — use a state flag to gate rendering. - - -For production, use [`loginWithAuthToken()`](/ui-kit/react/methods#login-using-auth-token) instead of Auth Key. Generate tokens server-side via the REST API. - - ---- - -## Step 5 — Add the CSS Import - -Import the CometChat CSS inside your React island component: - -```tsx lines -import "@cometchat/chat-uikit-react/css-variables.css"; -``` - -Also ensure your global CSS sets `height: 100%` on the root elements. Create or update `src/styles/globals.css`: - -```css title="src/styles/globals.css" lines -html, -body { - margin: 0; - padding: 0; - height: 100%; -} -``` - -Without the CSS import, components will render with broken or missing styles. Without the height rules, the chat UI won't fill the viewport. - ---- - -## Step 6 — Choose a Chat Experience - -Integrate a conversation view that suits your app's UX. Each option below includes a step-by-step guide. - -### Conversation List + Message View - -Two-panel layout — conversation list on the left, messages on the right. Think WhatsApp Web or Slack. - -- Two-panel layout with conversation list and active chat window -- Switch between one-to-one and group conversations -- Tap-to-view on mobile — tapping a conversation opens the message view -- Real-time updates and message sync across sessions - - - - - - - Step-by-step guide to build this layout - - ---- - -### One-to-One / Group Chat - -Single chat window — no sidebar. Good for support chat, embedded widgets, or focused messaging. - -- Dedicated chat window for one-on-one or group messaging -- No conversation list — users go directly into the chat -- Full-screen experience optimized for mobile -- Ideal for support chat or community messaging - - - - - - - Step-by-step guide to build this layout - - ---- - -### Tab-Based Chat - -Tabbed navigation — Chat, Call Logs, Users, Settings in separate tabs. Good for full-featured apps. - -- Tab navigation between Chat, Call Logs, Users, and Settings -- Full-screen messaging within each tab -- Unified experience for conversations, call history, and settings -- Scales well for adding future features like notifications or contacts - - - - - - - Step-by-step guide to build this layout - - ---- - -## Build Your Own Chat Experience - -Need full control over the UI? Use individual components, customize themes, and wire up your own layouts. - -- [Sample App](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) — Working reference app to compare against -- [Components](/ui-kit/react/components-overview) — All prebuilt UI elements with props and customization options -- [Core Features](/ui-kit/react/core-features) — Messaging, real-time updates, and other capabilities -- [Theming](/ui-kit/react/theme) — Colors, fonts, dark mode, and custom styling -- [Build Your Own UI](/sdk/javascript/overview) — Skip the UI Kit entirely and build on the raw SDK - ---- - -## Next Steps - - - - Browse all prebuilt UI components - - - Customize colors, fonts, and styles - - - Chat features included out of the box - - - Common issues and fixes - - diff --git a/ui-kit/react/astro-one-to-one-chat.mdx b/ui-kit/react/astro-one-to-one-chat.mdx index 99d45e160..a3829dc32 100644 --- a/ui-kit/react/astro-one-to-one-chat.mdx +++ b/ui-kit/react/astro-one-to-one-chat.mdx @@ -1,7 +1,7 @@ --- title: "One-to-One / Group Chat" sidebarTitle: "One-to-One / Group Chat" -description: "Build focused CometChat UI Kit chat screens in Astro with headers, message lists, composers, users, groups, and direct navigation." +description: "Build a single chat window for one-to-one or group messaging in Astro with CometChat UI Kit." --- @@ -9,23 +9,24 @@ description: "Build focused CometChat UI Kit chat screens in Astro with headers, | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Framework | Astro (with `@astrojs/react` islands) | +| Framework | Astro | | Components | `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | | Layout | Single chat window — no sidebar, no conversation list | -| Prerequisite | Complete [Astro Integration](/ui-kit/react/astro-integration) Steps 1–5 first | -| SSR | `client:only="react"` directive — CometChat requires browser APIs | +| Prerequisite | Complete [Astro Integration](/ui-kit/react/integration-astro) first | +| SSR | React island with `client:only="react"` directive | | Pattern | Support chat, embedded widgets, focused messaging | This guide builds a single chat window — no sidebar, no conversation list. Users go directly into a one-to-one or group chat. Good for support chat, embedded widgets, or any focused messaging experience. -This assumes you've already completed [Astro Integration](/ui-kit/react/astro-integration) (project created, React added, UI Kit installed). +This assumes you've already completed [Astro Integration](/ui-kit/react/integration-astro) (project created, UI Kit installed, init + login working). - + + --- ## What You're Building @@ -38,225 +39,159 @@ Three components stacked vertically: --- -## Step 1 — Create the React Island - -Create a `OneToOneChat` component inside `src/components/`. This handles init, login, fetches the target user, and renders the chat UI. +## Full Code - - - - - - - - +Create a React island component with the chat UI, then render it in an Astro page with `client:only="react"`. - - - -```tsx title="OneToOneChat.tsx" lines highlight={14-16, 37, 55, 62} +```tsx title="src/components/DirectChat.tsx" import { useEffect, useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; import { - CometChatMessageComposer, - CometChatMessageHeader, - CometChatMessageList, CometChatUIKit, UIKitSettingsBuilder, + CometChatProvider, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import "@cometchat/chat-uikit-react/css-variables.css"; -import "./OneToOneChat.css"; -const COMETCHAT_CONSTANTS = { - APP_ID: "", // Replace with your App ID - REGION: "", // Replace with your Region - AUTH_KEY: "", // Replace with your Auth Key (dev only) -}; +const RECIPIENT_UID = "cometchat-uid-2"; // Replace with the UID you want to chat with -export default function OneToOneChat() { - const [user, setUser] = useState(undefined); - const [selectedUser, setSelectedUser] = useState(undefined); - const [selectedGroup, setSelectedGroup] = useState(undefined); +export default function DirectChat() { + const [ready, setReady] = useState(false); + const [chatUser, setChatUser] = useState(undefined); useEffect(() => { - const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") .subscribePresenceForAllUsers() .build(); - CometChatUIKit.init(UIKitSettings) - .then(() => { - console.log("Initialization completed successfully"); - CometChatUIKit.getLoggedinUser().then((loggedInUser) => { - if (!loggedInUser) { - CometChatUIKit.login("cometchat-uid-2") - .then((u) => { - console.log("Login Successful", { u }); - setUser(u); - }) - .catch((error) => console.error("Login failed", error)); - } else { - console.log("Already logged-in", { loggedInUser }); - setUser(loggedInUser); - } - }); - }) - .catch((error) => console.error("Initialization failed", error)); + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + const user = await CometChat.getUser(RECIPIENT_UID); + setChatUser(user); + setReady(true); + }); }, []); - useEffect(() => { - if (user) { - // Fetch the user whose chat you want to load - const UID = "cometchat-uid-1"; - CometChat.getUser(UID).then( - (u) => setSelectedUser(u), - (error) => console.log("User fetching failed with error:", error) - ); - - // To load a group chat instead, uncomment below: - // const GUID = "GUID"; - // CometChat.getGroup(GUID).then( - // (group) => setSelectedGroup(group), - // (error) => console.log("Group fetching failed with error:", error) - // ); - } - }, [user]); - - if (!user) return
Initializing Chat...
; + if (!ready || !chatUser) return
Loading chat...
; return ( - <> - {selectedUser || selectedGroup ? ( -
- - - -
- ) : ( -
- Set a user or group UID in OneToOneChat.tsx to start chatting -
- )} - + +
+ + + +
+
); } ``` -
- - -```css title="OneToOneChat.css" lines -.messages-wrapper { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; -} - -.empty-conversation { - height: 100%; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - background: var(--cometchat-background-color-03, #F5F5F5); - color: var(--cometchat-text-color-secondary, #727272); - font: var(--cometchat-font-body-regular, 400 14px Roboto); -} +```astro title="src/pages/chat.astro" +--- +import DirectChat from '../components/DirectChat.tsx'; +--- -.cometchat .cometchat-message-composer { - border-radius: 0px; -} + + + + + Chat + + + + + ``` - -
- Key points: -- `CometChat.getUser(UID)` fetches the user object from the SDK — you need a real user object, not a manually constructed one. +- `client:only="react"` ensures the component only runs in the browser — no server-side rendering. +- `CometChat.getUser(UID)` fetches the full user object from the SDK — you need a real user object, not a manually constructed one. - Pass either `user` or `group` to the message components, never both. -- The highlighted lines show where to set your credentials and target UID. +- The `RECIPIENT_UID` should be a user that exists in your CometChat app. Use one of the pre-created test UIDs: `cometchat-uid-1` through `cometchat-uid-5`. --- -## Switching Between User and Group Chat +## Switching to Group Chat -To load a group chat instead of one-to-one, replace the `getUser` call with `getGroup`: +To load a group chat instead of one-to-one, fetch a `Group` object and pass it to the message components: -```tsx lines highlight={1} -const GUID = "GUID"; // Replace with your actual Group ID +```tsx title="src/components/DirectChat.tsx" +import { useEffect, useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatUIKit, + UIKitSettingsBuilder, + CometChatProvider, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, +} from "@cometchat/chat-uikit-react"; -CometChat.getGroup(GUID) - .then((group) => setSelectedGroup(group)) - .catch((error) => console.error("Failed to fetch group:", error)); -``` +const GROUP_ID = "cometchat-guid-1"; // Replace with your Group ID ---- +export default function DirectChat() { + const [ready, setReady] = useState(false); + const [chatGroup, setChatGroup] = useState(undefined); -## Step 2 — Render the Astro Page + useEffect(() => { + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .build(); -Import the island and hydrate it client-side using `client:only="react"`. + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + const group = await CometChat.getGroup(GROUP_ID); + setChatGroup(group); + setReady(true); + }); + }, []); -```astro title="src/pages/index.astro" lines ---- -import OneToOneChat from "../components/OneToOneChat.tsx"; -import "../styles/globals.css"; ---- + if (!ready || !chatGroup) return
Loading chat...
; - - - - One-to-One Chat - - - - - + return ( + +
+ + + +
+
+ ); +} ``` -The `client:only="react"` directive ensures the component skips SSR entirely and only renders in the browser. +The only difference: use `CometChat.getGroup(GUID)` instead of `CometChat.getUser(UID)`, and pass `group` instead of `user`. --- -## Step 3 — Run the Project +## Run - - -```bash lines +```bash npm run dev ``` - - -```bash lines -pnpm dev -``` - - -```bash lines -yarn dev -``` - - -You should see the chat window load with the conversation for the UID you set. +Open `http://localhost:4321/chat`. You should see the chat window load with the conversation for the UID or GUID you set. --- ## Next Steps - - Customize colors, fonts, and styles to match your brand + + Two-panel layout with a sidebar + + + Tabbed navigation with Chats, Calls, Users Browse all prebuilt UI components - } href="/ui-kit/react/astro-integration"> - Back to the main setup guide - - - Chat features included out of the box - diff --git a/ui-kit/react/astro-tab-based-chat.mdx b/ui-kit/react/astro-tab-based-chat.mdx index d8912dd91..3d6b45ee0 100644 --- a/ui-kit/react/astro-tab-based-chat.mdx +++ b/ui-kit/react/astro-tab-based-chat.mdx @@ -1,7 +1,7 @@ --- title: "Tab-Based Chat" sidebarTitle: "Tab-Based Chat" -description: "Build a tab-based messaging UI with chats, calls, users, and groups in Astro with CometChat React UI Kit." +description: "Build a tab-based chat interface with Chat, Call Logs, and Users tabs in Astro." --- @@ -9,528 +9,308 @@ description: "Build a tab-based messaging UI with chats, calls, users, and group | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Framework | Astro (with `@astrojs/react` islands) | -| Components | `CometChatConversations`, `CometChatCallLogs`, `CometChatUsers`, `CometChatGroups`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | -| Layout | Tabbed sidebar (Chats, Calls, Users, Groups) + message view | -| Prerequisite | Complete [Astro Integration](/ui-kit/react/astro-integration) Steps 1–5 first | -| SSR | `client:only="react"` directive — CometChat requires browser APIs | +| Framework | Astro | +| Components | `CometChatConversations`, `CometChatCallLogs`, `CometChatUsers`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | +| Layout | Tabbed sidebar (Chat, Calls, Users) + message view | +| Prerequisite | Complete [Astro Integration](/ui-kit/react/integration-astro) first | +| SSR | React island with `client:only="react"` directive | | Pattern | Full-featured messaging app with multiple sections | -This guide builds a tabbed messaging UI — Chats, Calls, Users, and Groups tabs in the sidebar, with a message view on the right. Good for full-featured apps that need more than just conversations. +This guide builds a tabbed messaging UI — Chat, Calls, and Users tabs in the sidebar, with a message view on the right. Good for full-featured apps that need more than just conversations. -This assumes you've already completed [Astro Integration](/ui-kit/react/astro-integration) (project created, React added, UI Kit installed). +This assumes you've already completed [Astro Integration](/ui-kit/react/integration-astro) (project created, UI Kit installed, init + login working). - + + --- ## What You're Building Three sections working together: -1. **Tab bar** — switches between Chats, Calls, Users, and Groups +1. **Tab bar** — switches between Chat, Calls, and Users 2. **Sidebar** — renders the list for the active tab 3. **Message view** — header + messages + composer for the selected item - ---- - -## Step 1 — Create the Tab Component - - - - - - - - - - - - -Tab icons need to be placed in `public/assets/`. Download them from the [CometChat UI Kit assets folder on GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app/src/assets). - - - - - - - - - - - - - - - -```tsx title="CometChatTabs.tsx" lines -import { useState } from "react"; -import "./CometChatTabs.css"; - -const chatsIcon = "/assets/chats.svg"; -const callsIcon = "/assets/calls.svg"; -const usersIcon = "/assets/users.svg"; -const groupsIcon = "/assets/groups.svg"; - -export const CometChatTabs = (props: { - onTabClicked?: (tabItem: { name: string; icon?: string }) => void; - activeTab?: string; -}) => { - const { onTabClicked = () => {}, activeTab } = props; - const [hoverTab, setHoverTab] = useState(""); - - const tabItems = [ - { name: "CHATS", icon: chatsIcon }, - { name: "CALLS", icon: callsIcon }, - { name: "USERS", icon: usersIcon }, - { name: "GROUPS", icon: groupsIcon }, - ]; - - return ( -
- {tabItems.map((tabItem) => { - const isActive = - activeTab === tabItem.name.toLowerCase() || - hoverTab === tabItem.name.toLowerCase(); - - return ( -
onTabClicked(tabItem)} - > -
setHoverTab(tabItem.name.toLowerCase())} - onMouseLeave={() => setHoverTab("")} - /> -
setHoverTab(tabItem.name.toLowerCase())} - onMouseLeave={() => setHoverTab("")} - > - {tabItem.name} -
-
- ); - })} -
- ); -}; -``` - - - - -```css title="CometChatTabs.css" lines -.cometchat-tab-component { - display: flex; - width: 100%; - padding: 0px 8px; - align-items: flex-start; - gap: 8px; - border-top: 1px solid var(--cometchat-border-color-light, #F5F5F5); - border-right: 1px solid var(--cometchat-border-color-light, #F5F5F5); - background: var(--cometchat-background-color-01, #FFF); -} - -.cometchat-tab-component__tab { - display: flex; - padding: 12px 0px 10px 0px; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 4px; - flex: 1 0 0; - min-height: 48px; -} - -.cometchat-tab-component__tab-icon { - display: flex; - width: 32px; - height: 32px; - justify-content: center; - align-items: center; - background: var(--cometchat-icon-color-secondary); - -webkit-mask-size: contain; - -webkit-mask-position: center; - -webkit-mask-repeat: no-repeat; - mask-size: contain; - mask-position: center; - mask-repeat: no-repeat; - cursor: pointer; -} - -.cometchat-tab-component__tab-text { - color: var(--cometchat-text-color-secondary, #727272); - text-align: center; - font: var(--cometchat-font-caption1-medium, 500 12px Roboto); - cursor: pointer; -} - -.cometchat-tab-component__tab-icon-active { - background: var(--cometchat-icon-color-highlight); -} - -.cometchat-tab-component__tab-text-active { - color: var(--cometchat-text-color-highlight); -} -``` - - - - - --- -## Step 2 — Create the Sidebar Component - -The sidebar renders the list for whichever tab is active, plus the tab bar at the bottom. +## Full Code - - - - - - - - - - +Create a React island component with the tabbed UI, then render it in an Astro page with `client:only="react"`. - - - -```tsx title="CometChatSelector.tsx" lines -import { useEffect, useState } from "react"; -import { Call, Conversation, Group, User, CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCallLogs, CometChatConversations, CometChatGroups, CometChatUIKitLoginListener, CometChatUsers } from "@cometchat/chat-uikit-react"; -import { CometChatTabs } from "../CometChatTabs/CometChatTabs"; - -interface SelectorProps { - onSelectorItemClicked?: (input: User | Group | Conversation | Call, type: string) => void; -} - -export const CometChatSelector = (props: SelectorProps) => { - const { onSelectorItemClicked = () => {} } = props; - const [loggedInUser, setLoggedInUser] = useState(); - const [activeItem, setActiveItem] = useState(); - const [activeTab, setActiveTab] = useState("chats"); - - useEffect(() => { - const user = CometChatUIKitLoginListener.getLoggedInUser(); - setLoggedInUser(user); - }, []); - - return ( - <> - {loggedInUser && ( - <> - {activeTab === "chats" && ( - { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItem"); }} - /> - )} - {activeTab === "calls" && ( - { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItemCall"); }} - /> - )} - {activeTab === "users" && ( - { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItemUser"); }} - /> - )} - {activeTab === "groups" && ( - { setActiveItem(item); onSelectorItemClicked(item, "updateSelectedItemGroup"); }} - /> - )} - - )} - setActiveTab(item.name.toLowerCase())} /> - - ); -}; -``` - - - - -```css title="CometChatSelector.css" lines -.selector-wrapper .cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon { - background: var(--cometchat-icon-color-primary); -} -.cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon:hover { - background: var(--cometchat-icon-color-highlight); -} -.cometchat-list__header-search-bar { border-right: none; } -.cometchat .cometchat-menu-list__sub-menu-list-item { text-align: left; } -.cometchat .cometchat-conversations .cometchat-menu-list__sub-menu-list { - width: 212px; top: 40px !important; left: 172px !important; -} -#logged-in-user { border-bottom: 2px solid var(--cometchat-border-color-default, #E8E8E8); } -#logged-in-user .cometchat-menu-list__sub-menu-item-title, -#logged-in-user .cometchat-menu-list__sub-menu-list-item { cursor: default; } -.cometchat-menu-list__sub-menu-list-item-icon-log-out { background-color: var(--cometchat-error-color, #F44649); } -.cometchat-menu-list__sub-menu-item-title-log-out { color: var(--cometchat-error-color, #F44649); } -.chat-menu .cometchat .cometchat-menu-list__sub-menu-item-title { cursor: pointer; } -.chat-menu .cometchat .cometchat-menu-list__sub-menu { box-shadow: none; } -.chat-menu .cometchat .cometchat-menu-list__sub-menu-icon { - background-color: var(--cometchat-icon-color-primary, #141414); width: 24px; height: 24px; -} -``` - - - - -Key points: -- The `activeTab` state drives which list component renders — `CometChatConversations`, `CometChatCallLogs`, `CometChatUsers`, or `CometChatGroups`. -- Each list component passes its selection back to the parent via `onSelectorItemClicked`. -- `CometChatTabs` renders at the bottom of the sidebar. - - ---- - -## Step 3 — Create the TabbedChat Island - -This component handles init, login, and renders the full tabbed chat experience. It runs client-side only via `client:only="react"`. - - - - - - - - - - - - - -```tsx title="TabbedChat.tsx" lines highlight={15-17, 20} +```tsx title="src/components/TabbedChat.tsx" import { useEffect, useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; import { - CometChatMessageComposer, - CometChatMessageHeader, - CometChatMessageList, CometChatUIKit, UIKitSettingsBuilder, + CometChatProvider, + CometChatConversations, + CometChatUsers, + CometChatCallLogs, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatSelector } from "./CometChatSelector/CometChatSelector"; -import "@cometchat/chat-uikit-react/css-variables.css"; -import "./TabbedChat.css"; - -const COMETCHAT_CONSTANTS = { - APP_ID: "", // Replace with your App ID - REGION: "", // Replace with your Region - AUTH_KEY: "", // Replace with your Auth Key (dev only) -}; -const UID = "cometchat-uid-4"; // Replace with your actual UID +type Tab = "chat" | "calls" | "users"; export default function TabbedChat() { - const [user, setUser] = useState(undefined); + const [ready, setReady] = useState(false); + const [activeTab, setActiveTab] = useState("chat"); const [selectedUser, setSelectedUser] = useState(undefined); const [selectedGroup, setSelectedGroup] = useState(undefined); useEffect(() => { - const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") .subscribePresenceForAllUsers() .build(); - CometChatUIKit.init(UIKitSettings) - .then(() => { - console.log("Initialization completed successfully"); - CometChatUIKit.getLoggedinUser().then((loggedInUser) => { - if (!loggedInUser) { - CometChatUIKit.login(UID) - .then((u) => { - console.log("Login Successful", { u }); - setUser(u); - }) - .catch((error) => console.error("Login failed", error)); - } else { - console.log("Already logged-in", { loggedInUser }); - setUser(loggedInUser); - } - }); - }) - .catch((error) => console.error("Initialization failed", error)); + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + setReady(true); + }); }, []); - if (!user) return
Initializing Chat...
; + if (!ready) return
Loading chat...
; + + const handleConversationClick = (conversation: CometChat.Conversation) => { + const entity = conversation.getConversationWith(); + if (conversation.getConversationType() === "user") { + setSelectedUser(entity as CometChat.User); + setSelectedGroup(undefined); + } else { + setSelectedGroup(entity as CometChat.Group); + setSelectedUser(undefined); + } + }; + + const handleUserClick = (user: CometChat.User) => { + setSelectedUser(user); + setSelectedGroup(undefined); + }; + + const handleCallClick = (call: any) => { + const initiator = call.getInitiator(); + const receiver = call.getReceiver(); + + // Determine the other party in the call + if (receiver instanceof CometChat.User) { + setSelectedUser(receiver); + setSelectedGroup(undefined); + } else if (receiver instanceof CometChat.Group) { + setSelectedUser(undefined); + setSelectedGroup(receiver); + } else if (initiator instanceof CometChat.User) { + setSelectedUser(initiator); + setSelectedGroup(undefined); + } + }; return ( -
-
- { - let item: any = activeItem; - if (activeItem instanceof CometChat.Conversation) { - item = activeItem.getConversationWith(); - } - if (item instanceof CometChat.User) { - setSelectedUser(item); - setSelectedGroup(undefined); - } else if (item instanceof CometChat.Group) { - setSelectedUser(undefined); - setSelectedGroup(item); - } else { - setSelectedUser(undefined); - setSelectedGroup(undefined); - } - }} - /> -
+ +
+
+
+ + + +
- {selectedUser || selectedGroup ? ( -
- - - +
+ {activeTab === "chat" && ( + + )} + {activeTab === "calls" && ( + + )} + {activeTab === "users" && ( + + )} +
- ) : ( -
Select a conversation to start chatting
- )} -
- ); -} -``` - - - -```css title="TabbedChat.css" lines -.conversations-with-messages { - display: flex; - height: 100%; - width: 100%; -} -.conversations-wrapper { - height: 100%; - width: 480px; - overflow: hidden; - display: flex; - flex-direction: column; -} -.conversations-wrapper > .cometchat { overflow: hidden; } -.messages-wrapper { - width: calc(100% - 480px); - height: 100%; - display: flex; - flex-direction: column; -} -.empty-conversation { - height: 100%; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - background: var(--cometchat-background-color-03, #F5F5F5); - color: var(--cometchat-text-color-secondary, #727272); - font: var(--cometchat-font-body-regular, 400 14px Roboto); + {selectedUser || selectedGroup ? ( +
+ + + +
+ ) : ( +
+ Select a conversation to start chatting +
+ )} +
+
+ ); } -.cometchat .cometchat-message-composer { border-radius: 0px; } ``` - - - -How it works: -- Selections from any tab (Chats, Calls, Users, Groups) flow through the same `onSelectorItemClicked` callback. -- Conversation items are unwrapped via `getConversationWith()` to extract the underlying `User` or `Group`. -- Only one of `selectedUser` / `selectedGroup` is set at a time — the other is cleared. - ---- - -## Step 4 — Render the Astro Page - -Import the island and hydrate it client-side using `client:only="react"`. - -```astro title="src/pages/index.astro" lines +```astro title="src/pages/chat.astro" --- -import TabbedChat from "../components/TabbedChat.tsx"; -import "../styles/globals.css"; +import TabbedChat from '../components/TabbedChat.tsx'; --- - Tabbed Messaging UI + + Chat - + ``` -The `client:only="react"` directive ensures the component skips SSR entirely and only renders in the browser. +--- + +## How It Works + +1. **`client:only="react"`** tells Astro to skip server-rendering and hydrate the component entirely on the client. This is required because CometChat uses browser APIs. +2. **React island** — the CometChat UI lives in a self-contained React component. Astro handles the page shell, React handles the interactive chat. +3. **Tab state** — `activeTab` controls which list component renders in the sidebar. +4. **Conditional rendering** — only the active tab's component mounts. Switching tabs unmounts the previous list and mounts the new one. +5. **Unified selection** — all three tabs feed into the same `selectedUser` / `selectedGroup` state. Clicking any item (conversation, call log, or user) updates the message panel. +6. **Call log handling** — when a call log is clicked, the receiver (user or group) is extracted and passed to the message components. --- -## Step 5 — Run the Project +## Adding More Tabs + +To add a Groups tab, import `CometChatGroups` and add another tab button + conditional render: + +```tsx +import { CometChatGroups } from "@cometchat/chat-uikit-react"; + +// Add to Tab type: +type Tab = "chat" | "calls" | "users" | "groups"; + +// Add button in the tab bar: + + +// Add in the sidebar list: +{activeTab === "groups" && ( + { + setSelectedGroup(group); + setSelectedUser(undefined); + }} + /> +)} +``` + +You can follow the same pattern for any additional tabs (Settings, Contacts, etc.). - - -```bash lines +--- + +## Run + +```bash npm run dev ``` - - -```bash lines -pnpm dev -``` - - -```bash lines -yarn dev -``` - - -You should see the tab bar at the bottom of the sidebar. Switch between Chats, Calls, Users, and Groups — tapping any item loads the message view on the right. +Open `http://localhost:4321/chat`. You should see the tab bar at the top of the sidebar. Switch between Chats, Calls, and Users — clicking any item loads the message view on the right. --- ## Next Steps - - Customize colors, fonts, and styles to match your brand + + Two-panel layout without tabs Browse all prebuilt UI components - } href="/ui-kit/react/astro-integration"> - Back to the main setup guide - - - Chat features included out of the box + + Customize colors, fonts, and styles diff --git a/ui-kit/react/call-buttons.mdx b/ui-kit/react/call-buttons.mdx deleted file mode 100644 index 361a67a37..000000000 --- a/ui-kit/react/call-buttons.mdx +++ /dev/null @@ -1,529 +0,0 @@ ---- -title: "Call Buttons" -description: "Add CometChat React UI Kit call buttons for voice and video calls with user or group targets, click callbacks, and error handling." ---- - -```json -{ - "component": "CometChatCallButtons", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatCallButtons } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", - "description": "Voice and video call initiation buttons for user or group conversations.", - "cssRootClass": ".cometchat-call-button", - "primaryOutput": { - "description": "Initiates calls via SDK, emits CometChatCallEvents" - }, - "props": { - "data": { - "user": { - "type": "CometChat.User", - "default": "undefined", - "note": "Pass either user or group, not both" - }, - "group": { - "type": "CometChat.Group", - "default": "undefined", - "note": "Pass either user or group, not both" - } - }, - "callbacks": { - "onError": "((error: CometChat.CometChatException) => void) | null", - "onVoiceCallClick": "(user?: CometChat.User, group?: CometChat.Group) => void", - "onVideoCallClick": "(user?: CometChat.User, group?: CometChat.Group) => void" - }, - "visibility": { - "hideVoiceCallButton": { "type": "boolean", "default": false }, - "hideVideoCallButton": { "type": "boolean", "default": false } - }, - "configuration": { - "callSettingsBuilder": "(isAudioOnlyCall: boolean, user?: CometChat.User, group?: CometChat.Group) => typeof CometChatUIKitCalls.CallSettingsBuilder", - "outgoingCallConfiguration": { - "type": "OutgoingCallConfiguration", - "default": "new OutgoingCallConfiguration({})", - "properties": { - "disableSoundForCalls": "boolean", - "customSoundForCalls": "string", - "onError": "(error: CometChat.CometChatException) => void", - "onCallCanceled": "Function", - "titleView": "(call: CometChat.Call) => JSX.Element", - "subtitleView": "(call: CometChat.Call) => JSX.Element", - "avatarView": "(call: CometChat.Call) => JSX.Element", - "cancelButtonView": "(call: CometChat.Call) => JSX.Element" - } - } - } - }, - "events": [ - { - "name": "CometChatCallEvents.ccOutgoingCall", - "payload": "CometChat.Call", - "description": "Call initiated" - }, - { - "name": "CometChatCallEvents.ccCallRejected", - "payload": "CometChat.Call", - "description": "Call rejected/cancelled" - }, - { - "name": "CometChatCallEvents.ccCallEnded", - "payload": "CometChat.Call", - "description": "Call session ends" - }, - { - "name": "CometChatMessageEvents.ccMessageSent", - "payload": "IMessages", - "description": "Group call message sent" - } - ], - "sdkListeners": [ - "onIncomingCallReceived", - "onIncomingCallCancelled", - "onOutgoingCallRejected", - "onOutgoingCallAccepted" - ], - "compositionExample": { - "description": "Standalone call buttons or embedded in MessageHeader auxiliary view", - "components": ["CometChatCallButtons", "CometChatOutgoingCall", "CometChatOngoingCall"], - "flow": "user/group prop -> click button -> SDK initiateCall -> CometChatOutgoingCall overlay -> onOutgoingCallAccepted -> CometChatOngoingCall" - } -} -``` - - -## Where It Fits - -`CometChatCallButtons` renders voice and video call buttons. Pass a `user` for 1-on-1 calls or a `group` for group calls. Typically embedded in `CometChatMessageHeader`'s auxiliary view or used standalone. The component handles call initiation, renders `CometChatOutgoingCall` internally, and manages the full call lifecycle. - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function CallButtonsDemo() { - const [chatUser, setChatUser] = useState(); - - useEffect(() => { - CometChat.getUser("uid").then((user) => setChatUser(user)); - }, []); - - return chatUser ? : null; -} - -export default CallButtonsDemo; -``` - - - - - ---- - -## Minimal Render - -```tsx lines -import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function CallButtonsMinimal() { - return ; -} -``` - -Root CSS class: `.cometchat-call-button` - ---- - -## Actions and Events - -### Callback Props - -#### onVoiceCallClick - -Overrides the default voice call initiation behavior. When set, clicking the voice button invokes this callback instead of initiating a call via the SDK. - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; - -function CallButtonsVoiceOverride() { - const [chatUser, setChatUser] = useState(); - - useEffect(() => { - CometChat.getUser("uid").then((user) => setChatUser(user)); - }, []); - - return ( - { - console.log("Custom voice call logic"); - }} - /> - ); -} -``` - -#### onVideoCallClick - -Overrides the default video call initiation behavior. - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; - -function CallButtonsVideoOverride() { - const [chatUser, setChatUser] = useState(); - - useEffect(() => { - CometChat.getUser("uid").then((user) => setChatUser(user)); - }, []); - - return ( - { - console.log("Custom video call logic"); - }} - /> - ); -} -``` - -#### onError - -Fires on internal errors during call initiation. - -```tsx lines -import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function CallButtonsWithError() { - return ( - { - console.error("CallButtons error:", error); - }} - /> - ); -} -``` - -### Global UI Events - -`CometChatCallEvents` emits call lifecycle events subscribable from anywhere. - -| Event | Fires when | Payload | -| --- | --- | --- | -| `ccOutgoingCall` | User initiates a voice/video call | `CometChat.Call` | -| `ccCallRejected` | Initiated call is rejected/cancelled | `CometChat.Call` | -| `ccCallEnded` | Call session ends | `CometChat.Call` | - -```tsx lines -import { useEffect } from "react"; -import { CometChatCallEvents } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function useCallButtonEvents() { - useEffect(() => { - const outgoingSub = CometChatCallEvents.ccOutgoingCall.subscribe( - (call: CometChat.Call) => { - console.log("Outgoing call:", call.getSessionId()); - } - ); - const rejectedSub = CometChatCallEvents.ccCallRejected.subscribe( - (call: CometChat.Call) => { - console.log("Call rejected:", call.getSessionId()); - } - ); - const endedSub = CometChatCallEvents.ccCallEnded.subscribe( - (call: CometChat.Call) => { - console.log("Call ended:", call.getSessionId()); - } - ); - - return () => { - outgoingSub?.unsubscribe(); - rejectedSub?.unsubscribe(); - endedSub?.unsubscribe(); - }; - }, []); -} -``` - -### SDK Events (Real-Time, Automatic) - -The component attaches SDK call listeners internally: - -| SDK Listener | Internal behavior | -| --- | --- | -| `onIncomingCallReceived` | Disables call buttons to prevent concurrent calls | -| `onIncomingCallCancelled` | Re-enables call buttons | -| `onOutgoingCallRejected` | Hides outgoing call screen, re-enables buttons | -| `onOutgoingCallAccepted` | Transitions to ongoing call screen | - ---- - -## Configuring the Outgoing Call Sub-Component - -`CometChatCallButtons` renders `CometChatOutgoingCall` internally. Customize it via `outgoingCallConfiguration`. - -```tsx lines -import { CometChatCallButtons, OutgoingCallConfiguration } from "@cometchat/chat-uikit-react"; - -function CallButtonsCustomOutgoing() { - return ( -
{call.getCallReceiver().getName()}
, - }) - } - /> - ); -} -``` - -`OutgoingCallConfiguration` properties: - -| Property | Type | Description | -| --- | --- | --- | -| `disableSoundForCalls` | `boolean` | Disables outgoing call ringtone | -| `customSoundForCalls` | `string` | Custom ringtone URL | -| `onError` | `(error: CometChat.CometChatException) => void` | Error callback | -| `onCallCanceled` | `Function` | Cancel button callback | -| `titleView` | `(call: CometChat.Call) => JSX.Element` | Custom title | -| `subtitleView` | `(call: CometChat.Call) => JSX.Element` | Custom subtitle | -| `avatarView` | `(call: CometChat.Call) => JSX.Element` | Custom avatar | -| `cancelButtonView` | `(call: CometChat.Call) => JSX.Element` | Custom cancel button | - -Refer to [CometChatOutgoingCall](/ui-kit/react/outgoing-call) for details on each view slot. - ---- - -## Call Settings - -Customize the calling experience via `callSettingsBuilder`. - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCallButtons, CometChatUIKitCalls } from "@cometchat/chat-uikit-react"; - -function CallButtonsCustomSettings() { - return ( - - new CometChatUIKitCalls.CallSettingsBuilder() - .enableDefaultLayout(true) - .setIsAudioOnlyCall(isAudioOnlyCall) - } - /> - ); -} -``` - ---- - -## Common Patterns - -### Voice-only call button - -```tsx lines -import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; - -function VoiceOnlyCallButtons() { - return ; -} -``` - -### Group call buttons - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; - -function GroupCallButtons() { - const [group, setGroup] = useState(); - - useEffect(() => { - CometChat.getGroup("guid").then((g) => setGroup(g)); - }, []); - - return group ? : null; -} -``` - ---- - -## CSS Architecture - -The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade: - -1. Global tokens set on the `.cometchat` root wrapper. -2. Component CSS (`.cometchat-call-button`) consumes these tokens via `var()`. -3. Overrides target `.cometchat-call-button` descendant selectors. - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-call-button` | -| Voice button wrapper | `.cometchat-call-button__voice` | -| Video button wrapper | `.cometchat-call-button__video` | -| Button element | `.cometchat-call-button .cometchat-button` | -| Button icon | `.cometchat-call-button .cometchat-button__icon` | -| Outgoing call backdrop | `.cometchat-outgoing-call__backdrop` | - -### Example: Themed call buttons - - - - - -```css lines -.cometchat-call-button { - display: flex; - padding: 8px 16px; - justify-content: center; - align-items: center; - background: #fff; -} - -.cometchat .cometchat-button { - border-radius: 8px; - border: 1px solid #e8e8e8; - background: #edeafa; -} - -.cometchat-call-button .cometchat-call-button__video .cometchat-button__icon, -.cometchat-call-button .cometchat-call-button__voice .cometchat-button__icon { - background-color: #6852d6; -} -``` - -### Customization Matrix - -| What to change | Where | Property/API | Example | -| --- | --- | --- | --- | -| Override call initiation | Component props | `onVoiceCallClick` / `onVideoCallClick` | `onVoiceCallClick={() => customCall()}` | -| Hide a call button | Component props | `hideVoiceCallButton` / `hideVideoCallButton` | `hideVideoCallButton={true}` | -| Customize outgoing call UI | Component props | `outgoingCallConfiguration` | `outgoingCallConfiguration={new OutgoingCallConfiguration({...})}` | -| Customize call settings | Component props | `callSettingsBuilder` | `callSettingsBuilder={(audio) => builder}` | -| Change colors, fonts, spacing | Global CSS | Target `.cometchat-call-button` class | `.cometchat-call-button .cometchat-button__icon { background: red; }` | - ---- - -## Props - -All props are optional. Sorted alphabetically. - -### callSettingsBuilder - -Builder function for customizing call settings. - -| | | -| --- | --- | -| Type | `(isAudioOnlyCall: boolean, user?: CometChat.User, group?: CometChat.Group) => typeof CometChatUIKitCalls.CallSettingsBuilder` | -| Default | `undefined` | - ---- - -### group - -The group for group call buttons. Pass either `user` or `group`, not both. - -| | | -| --- | --- | -| Type | `CometChat.Group` | -| Default | `undefined` | - ---- - -### hideVideoCallButton - -Hides the video call button. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideVoiceCallButton - -Hides the voice call button. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### onError - -Callback fired when the component encounters an error. - -| | | -| --- | --- | -| Type | `((error: CometChat.CometChatException) => void) \| null` | -| Default | `undefined` | - ---- - -### outgoingCallConfiguration - -Configuration object for the internal `CometChatOutgoingCall` sub-component. - -| | | -| --- | --- | -| Type | `OutgoingCallConfiguration` | -| Default | `new OutgoingCallConfiguration({})` | - -See [Configuring the Outgoing Call Sub-Component](#configuring-the-outgoing-call-sub-component) for properties. - ---- - -### user - -The user for 1-on-1 call buttons. Pass either `user` or `group`, not both. - -| | | -| --- | --- | -| Type | `CometChat.User` | -| Default | `undefined` | - ---- - -## Events - -| Event | Payload | Fires when | -| --- | --- | --- | -| `CometChatCallEvents.ccOutgoingCall` | `CometChat.Call` | Call initiated | -| `CometChatCallEvents.ccCallRejected` | `CometChat.Call` | Call rejected/cancelled | -| `CometChatCallEvents.ccCallEnded` | `CometChat.Call` | Call session ends | -| `CometChatMessageEvents.ccMessageSent` | `IMessages` | Group call message sent | - -All call events are `Subject` from RxJS. Subscribe with `.subscribe()`, unsubscribe with the returned subscription's `.unsubscribe()`. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-call-button` | -| Voice button wrapper | `.cometchat-call-button__voice` | -| Video button wrapper | `.cometchat-call-button__video` | -| Button element | `.cometchat-call-button .cometchat-button` | -| Button icon | `.cometchat-call-button .cometchat-button__icon` | -| Outgoing call backdrop | `.cometchat-outgoing-call__backdrop` | diff --git a/ui-kit/react/call-features.mdx b/ui-kit/react/call-features.mdx index 885bd6fa5..73ec76530 100644 --- a/ui-kit/react/call-features.mdx +++ b/ui-kit/react/call-features.mdx @@ -8,31 +8,45 @@ description: "Overview of CometChat React UI Kit calling features, including inc | Field | Value | | --- | --- | | Packages | `@cometchat/chat-uikit-react` + `@cometchat/calls-sdk-javascript` (`npm install @cometchat/calls-sdk-javascript`) | -| Required setup | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` — Calls SDK must also be installed | -| Call features | Incoming Call, Outgoing Call, Call Logs, Call Buttons | -| Key components | `CometChatCallButtons` → [Call Buttons](/ui-kit/react/call-buttons), `CometChatIncomingCall` → [Incoming Call](/ui-kit/react/incoming-call), `CometChatOutgoingCall` → [Outgoing Call](/ui-kit/react/outgoing-call), `CometChatCallLogs` → [Call Logs](/ui-kit/react/call-logs) | -| Auto-detection | UI Kit automatically detects the Calls SDK and enables call UI components | +| Required setup | Call `.setCallingEnabled(true)` on `UIKitSettingsBuilder` during init — Calls SDK must also be installed | +| Call features | Incoming Call, Outgoing Call, Call Logs, Call Buttons (in Message Header) | +| Key components | `CometChatMessageHeader` → [Message Header](/ui-kit/react/components/message-header) (includes call buttons), `CometChatIncomingCall` → [Incoming Call](/ui-kit/react/components/incoming-call), `CometChatOutgoingCall` → [Outgoing Call](/ui-kit/react/components/outgoing-call), `CometChatCallLogs` → [Call Logs](/ui-kit/react/components/call-logs) | +| Enabling | Set `.setCallingEnabled(true)` on `UIKitSettingsBuilder` to activate call UI components | | CSS class prefix | `.cometchat-` | ## Overview -CometChat Calls integrates 1:1 and group audio/video calling into the React UI Kit. Install the Calls SDK and the UI Kit auto-detects it, enabling call components. +CometChat Calls integrates 1:1 and group audio/video calling into the React UI Kit. Install the Calls SDK and enable calling via `.setCallingEnabled(true)` on `UIKitSettingsBuilder` to activate call components. -Ensure `CometChatUIKit.init(UIKitSettings)` has completed and the user is logged in via `CometChatUIKit.login("UID")`. See [React.js Integration](/ui-kit/react/react-js-integration). +Ensure you have called `CometChatUIKit.init()` with `.setCallingEnabled(true)` and `CometChatUIKit.login()` before rendering. See [React.js Integration](/ui-kit/react/integration-react). ## Integration -Install the Calls SDK: +Install the Calls SDK and enable calling: ```bash lines npm install @cometchat/calls-sdk-javascript ``` -The React UI Kit auto-detects the SDK and activates calling features. [CallButtons](/ui-kit/react/call-buttons) renders in [MessageHeader](/ui-kit/react/message-header). +Then set `.setCallingEnabled(true)` on your `UIKitSettingsBuilder`: + +```tsx +const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .setCallingEnabled(true) + .build(); + +await CometChatUIKit.init(settings); +await CometChatUIKit.login("cometchat-uid-1"); +``` + +Call buttons render inside [MessageHeader](/ui-kit/react/components/message-header) when calling is enabled. @@ -42,7 +56,7 @@ The React UI Kit auto-detects the SDK and activates calling features. [CallButto ### Incoming Call -The [Incoming Call](/ui-kit/react/incoming-call) component displays a call screen when a call is received, showing caller info with accept/reject options. +The [Incoming Call](/ui-kit/react/components/incoming-call) component displays a call screen when a call is received, showing caller info with accept/reject options. @@ -50,7 +64,7 @@ The [Incoming Call](/ui-kit/react/incoming-call) component displays a call scree ### Outgoing Call -The [Outgoing Call](/ui-kit/react/outgoing-call) component displays an outgoing call screen with recipient info and call status. Transitions to the ongoing call screen when the receiver accepts. +The [Outgoing Call](/ui-kit/react/components/outgoing-call) component displays an outgoing call screen with recipient info and call status. Transitions to the ongoing call screen when the receiver accepts. @@ -58,7 +72,7 @@ The [Outgoing Call](/ui-kit/react/outgoing-call) component displays an outgoing ### Call Logs -The [Call Logs](/ui-kit/react/call-logs) component displays call history — caller, time, and duration. +The [Call Logs](/ui-kit/react/components/call-logs) component displays call history — caller, time, and duration. @@ -67,13 +81,13 @@ The [Call Logs](/ui-kit/react/call-logs) component displays call history — cal ## Next Steps - - Audio and video call buttons + + Message header with integrated call buttons - + Incoming call notifications and UI - + Call history and details diff --git a/ui-kit/react/call-logs.mdx b/ui-kit/react/call-logs.mdx deleted file mode 100644 index 9218d65b2..000000000 --- a/ui-kit/react/call-logs.mdx +++ /dev/null @@ -1,671 +0,0 @@ ---- -title: "Call Logs" -description: "Display CometChat React UI Kit call logs with call type, duration, participants, timestamps, request builders, and selection callbacks." ---- - -```json -{ - "component": "CometChatCallLogs", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatCallLogs } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", - "description": "Scrollable list of call history entries with filtering, call-back actions, and custom views.", - "cssRootClass": ".cometchat-call-logs", - "primaryOutput": { - "prop": "onItemClick", - "type": "(call: any) => void" - }, - "props": { - "data": { - "callLogRequestBuilder": { - "type": "any (CallLogRequestBuilder)", - "default": "SDK default (30 per page)" - }, - "activeCall": { - "type": "any", - "default": "undefined" - }, - "callInitiatedDateTimeFormat": { - "type": "CalendarObject", - "default": "DD MMM, hh:mm A" - } - }, - "callbacks": { - "onItemClick": "(call: any) => void", - "onCallButtonClicked": "(call: any) => void", - "onError": "((error: CometChat.CometChatException) => void) | null" - }, - "visibility": { - "showScrollbar": { "type": "boolean", "default": false } - }, - "viewSlots": { - "itemView": "(call: any) => JSX.Element", - "leadingView": "(call: any) => JSX.Element", - "titleView": "(call: any) => JSX.Element", - "subtitleView": "(call: any) => JSX.Element", - "trailingView": "(call: any) => JSX.Element", - "loadingView": "JSX.Element", - "emptyView": "JSX.Element", - "errorView": "JSX.Element" - } - }, - "events": [ - { - "name": "CometChatMessageEvents.ccMessageSent", - "payload": "IMessages", - "description": "Call message sent" - } - ], - "types": { - "CalendarObject": { - "today": "string | undefined", - "yesterday": "string | undefined", - "lastWeek": "string | undefined", - "otherDays": "string | undefined" - } - } -} -``` - - -## Where It Fits - -`CometChatCallLogs` is a standalone list component that renders call history entries. Each entry shows the caller/callee, call type (audio/video), direction (incoming/outgoing/missed), and timestamp. The `onItemClick` callback emits the selected call log, and `onCallButtonClicked` fires when the call-back button is tapped. - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function CallLogPanel() { - return ( -
- { - console.log("Call log selected:", callLog); - }} - onCallButtonClicked={(callLog: any) => { - console.log("Call back:", callLog); - }} - /> -
- ); -} -``` - - - - - ---- - -## Minimal Render - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function CallLogsDemo() { - return ( -
- -
- ); -} - -export default CallLogsDemo; -``` - -Root CSS class: `.cometchat-call-logs` - ---- - -## Filtering Call Logs - -Pass a `CallLogRequestBuilder` from `@cometchat/calls-sdk-javascript` to `callLogRequestBuilder`. - -```tsx lines -import { CallLogRequestBuilder } from "@cometchat/calls-sdk-javascript"; -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function FilteredCallLogs() { - return ( - - ); -} -``` - -### Filter Recipes - -| Recipe | Code | -| --- | --- | -| Limit to 5 per page | `new CallLogRequestBuilder().setAuthToken(token).setLimit(5)` | -| Cancelled calls only | `new CallLogRequestBuilder().setAuthToken(token).setCallStatus("cancelled")` | -| Video calls only | `new CallLogRequestBuilder().setAuthToken(token).setCallType("video")` | -| Calls with recordings | `new CallLogRequestBuilder().setAuthToken(token).setHasRecording(true)` | -| Calls for a specific user | `new CallLogRequestBuilder().setAuthToken(token).setUid("user_uid")` | -| Calls for a specific group | `new CallLogRequestBuilder().setAuthToken(token).setGuid("group_guid")` | - -Refer to [CallLogRequestBuilder](/sdk/javascript/call-logs) for the full builder API. - ---- - -## Actions and Events - -### Callback Props - -#### onItemClick - -Fires when a call log entry is tapped. - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function CallLogsWithClick() { - return ( - { - console.log("Selected call log:", callLog); - }} - /> - ); -} -``` - -#### onCallButtonClicked - -Fires when the call-back button in the trailing view is tapped. - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function CallLogsWithCallback() { - return ( - { - console.log("Call back:", callLog); - }} - /> - ); -} -``` - -#### onError - -Fires on internal errors (network failure, auth issue, SDK exception). - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function CallLogsWithError() { - return ( - { - console.error("CometChatCallLogs error:", error); - }} - /> - ); -} -``` - -### Global UI Events - -The component subscribes to `CometChatMessageEvents.ccMessageSent` to detect when a call message is sent and refresh the list. - -### SDK Events (Real-Time, Automatic) - -The component listens to SDK call events internally for real-time updates. No manual attachment needed. - - -In React 18 StrictMode, `useEffect` runs twice on mount in development. The component handles listener cleanup internally. - - ---- - -## Custom View Slots - -Each slot replaces a section of the default UI. Slots that accept a call log parameter receive the call log object for that row. - -| Slot | Signature | Replaces | -| --- | --- | --- | -| `itemView` | `(call: any) => JSX.Element` | Entire list item row | -| `leadingView` | `(call: any) => JSX.Element` | Avatar / left section | -| `titleView` | `(call: any) => JSX.Element` | Name / title text | -| `subtitleView` | `(call: any) => JSX.Element` | Call type, direction, timestamp | -| `trailingView` | `(call: any) => JSX.Element` | Call-back button area | -| `loadingView` | `JSX.Element` | Loading spinner | -| `emptyView` | `JSX.Element` | Empty state | -| `errorView` | `JSX.Element` | Error state | - -### itemView - -Replace the entire call log list item. - - - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function CustomItemViewCallLogs() { - const getItemView = (callLog: any) => { - return ( -
-
- {callLog?.getInitiator()?.getName()} -
-
- {callLog?.getStatus()} -
-
- ); - }; - - return ; -} -``` -
- -```css lines -.custom-call-log-item { - display: flex; - align-items: center; - justify-content: space-between; - padding: 8px 16px; - border-bottom: 1px solid var(--cometchat-border-color-light); -} - -.custom-call-log-item__name { - font: var(--cometchat-font-heading4-medium); - color: var(--cometchat-text-color-primary); -} - -.custom-call-log-item__status { - font: var(--cometchat-font-body-regular); - color: var(--cometchat-text-color-secondary); -} -``` - -
- -### subtitleView - -Replace the subtitle text (call type, duration). - - - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function SubtitleCallLogs() { - const getSubtitleView = (callLog: any) => { - return ( -
- {callLog?.getStatus()} • {callLog?.getType()} -
- ); - }; - - return ; -} -``` -
- -```css lines -.custom-call-log-subtitle { - font: var(--cometchat-font-body-regular); - color: var(--cometchat-text-color-secondary); -} -``` - -
- -### trailingView - -Replace the right section (call-back button area). - - - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function TrailingViewCallLogs() { - const getTrailingView = (callLog: any) => { - return ( -
- -
- ); - }; - - return ; -} -``` -
- -```css lines -.custom-call-log-trailing button { - background: var(--cometchat-primary-color); - color: var(--cometchat-static-white); - border: none; - border-radius: var(--cometchat-radius-2); - padding: 4px 12px; - cursor: pointer; -} -``` - -
- -### callInitiatedDateTimeFormat - -Customize the call initiated timestamp format using a `CalendarObject`. - -```tsx lines -import { - CometChatCallLogs, - CalendarObject, -} from "@cometchat/chat-uikit-react"; - -function CustomDateCallLogs() { - const dateFormat = new CalendarObject({ - today: "hh:mm A", - yesterday: "[yesterday]", - otherDays: "DD MM YYYY", - }); - - return ; -} -``` - - -If no property is passed in the [CalendarObject](/ui-kit/react/localize#calendarobject), the component checks the [global configuration](/ui-kit/react/localize#customisation) first. If also missing there, the component's default formatting applies. - - ---- - -## Common Patterns - -### Custom empty state - -```tsx lines -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function EmptyStateCallLogs() { - return ( - -

No call history

-
- } - /> - ); -} -``` - -### Filtered to video calls only - -```tsx lines -import { CallLogRequestBuilder } from "@cometchat/calls-sdk-javascript"; -import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; - -function VideoCallLogs({ authToken }: { authToken: string }) { - return ( - - ); -} -``` - ---- - -## CSS Architecture - -The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade: - -1. Global tokens are set on the `.cometchat` root wrapper. -2. Component CSS (`.cometchat-call-logs`) consumes these tokens via `var()` with fallback values. -3. Overrides target `.cometchat-call-logs` descendant selectors in a global stylesheet. - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-call-logs` | -| List item | `.cometchat-call-logs .cometchat-list-item` | -| Active item | `.cometchat-call-logs__list-item-active .cometchat-list-item` | -| Trailing view (video) | `.cometchat-call-logs__list-item-trailing-view-video` | -| Trailing view (audio) | `.cometchat-call-logs__list-item-trailing-view-audio` | -| Subtitle | `.cometchat-call-logs__list-item-subtitle` | -| Subtitle date | `.cometchat-call-logs__list-item-subtitle .cometchat-date` | -| Missed call icon | `.cometchat-call-logs__list-item-subtitle-icon-missed-call` | -| Outgoing call icon | `.cometchat-call-logs__list-item-subtitle-icon-outgoing-call` | -| Incoming call icon | `.cometchat-call-logs__list-item-subtitle-icon-incoming-call` | -| Empty state | `.cometchat-call-logs__empty-state-view` | -| Error state | `.cometchat-call-logs__error-state-view` | -| Shimmer loading | `.cometchat-call-logs__shimmer` | -| Outgoing call overlay | `.cometchat-call-logs__outgoing-call` | - -### Customization Matrix - -| What to change | Where | Property/API | Example | -| --- | --- | --- | --- | -| Override behavior on user interaction | Component props | `on` callbacks | `onItemClick={(c) => showDetails(c)}` | -| Filter which call logs appear | Component props | `callLogRequestBuilder` | `callLogRequestBuilder={new CallLogRequestBuilder().setLimit(5)}` | -| Replace a section of the list item | Component props | `View` render props | `subtitleView={(c) =>
{c.getStatus()}
}` | -| Change colors, fonts, spacing | Global CSS | Target `.cometchat-call-logs` class | `.cometchat-call-logs .cometchat-list-item { background: #f9f8fd; }` | - ---- - -## Props - -All props are optional. - ---- - -### activeCall - -Highlights the currently active/selected call log entry. - -| | | -| --- | --- | -| Type | `any` | -| Default | `undefined` | - ---- - -### callInitiatedDateTimeFormat - -Format for displaying the call initiated timestamp. - -| | | -| --- | --- | -| Type | `CalendarObject` | -| Default | Component default (`DD MMM, hh:mm A`) | - -Falls back to [global calendar configuration](/ui-kit/react/localize#customisation) if not set. - ---- - -### callLogRequestBuilder - -Controls which call logs load and in what order. - -| | | -| --- | --- | -| Type | `any` (CallLogRequestBuilder from `@cometchat/calls-sdk-javascript`) | -| Default | SDK default (30 per page) | - ---- - -### emptyView - -Custom component displayed when there are no call logs. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in empty state | - ---- - -### errorView - -Custom component displayed when an error occurs. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in error state | - ---- - -### itemView - -Custom renderer for the entire call log list item. - -| | | -| --- | --- | -| Type | `(call: any) => JSX.Element` | -| Default | Built-in list item | - ---- - -### leadingView - -Custom renderer for the avatar / left section. - -| | | -| --- | --- | -| Type | `(call: any) => JSX.Element` | -| Default | Built-in avatar | - ---- - -### loadingView - -Custom component displayed during the loading state. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in shimmer | - ---- - -### onCallButtonClicked - -Callback fired when the call-back button is clicked. - -| | | -| --- | --- | -| Type | `(call: any) => void` | -| Default | `undefined` | - ---- - -### onError - -Callback fired when the component encounters an error. - -| | | -| --- | --- | -| Type | `((error: CometChat.CometChatException) => void) \| null` | -| Default | `undefined` | - ---- - -### onItemClick - -Callback fired when a call log entry is clicked. - -| | | -| --- | --- | -| Type | `(call: any) => void` | -| Default | `undefined` | - ---- - -### showScrollbar - -Shows the scrollbar in the call log list. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### subtitleView - -Custom renderer for the subtitle text. - -| | | -| --- | --- | -| Type | `(call: any) => JSX.Element` | -| Default | Built-in subtitle | - ---- - -### titleView - -Custom renderer for the name / title text. - -| | | -| --- | --- | -| Type | `(call: any) => JSX.Element` | -| Default | Built-in title | - ---- - -### trailingView - -Custom renderer for the right section. - -| | | -| --- | --- | -| Type | `(call: any) => JSX.Element` | -| Default | Built-in trailing view | - ---- - -## Events - -| Event | Payload | Fires when | -| --- | --- | --- | -| `CometChatMessageEvents.ccMessageSent` | `IMessages` | Call message sent | - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-call-logs` | -| List item | `.cometchat-call-logs .cometchat-list-item` | -| Active item | `.cometchat-call-logs__list-item-active .cometchat-list-item` | -| Trailing view (video) | `.cometchat-call-logs__list-item-trailing-view-video` | -| Trailing view (audio) | `.cometchat-call-logs__list-item-trailing-view-audio` | -| Subtitle | `.cometchat-call-logs__list-item-subtitle` | -| Subtitle date | `.cometchat-call-logs__list-item-subtitle .cometchat-date` | -| Missed call icon | `.cometchat-call-logs__list-item-subtitle-icon-missed-call` | -| Outgoing call icon | `.cometchat-call-logs__list-item-subtitle-icon-outgoing-call` | -| Incoming call icon | `.cometchat-call-logs__list-item-subtitle-icon-incoming-call` | -| Empty state | `.cometchat-call-logs__empty-state-view` | -| Error state | `.cometchat-call-logs__error-state-view` | -| Shimmer loading | `.cometchat-call-logs__shimmer` | -| Outgoing call overlay | `.cometchat-call-logs__outgoing-call` | diff --git a/ui-kit/react/calling-integration.mdx b/ui-kit/react/calling-integration.mdx index 4760a85b9..48857f176 100644 --- a/ui-kit/react/calling-integration.mdx +++ b/ui-kit/react/calling-integration.mdx @@ -1,28 +1,251 @@ --- title: "Calling Integration" -description: "Add voice and video calling to CometChat React UI Kit with Calls SDK installation, setup checks, and CallButtons verification." +description: "Step-by-step guide to integrate voice and video calling into your React app using CometChat UI Kit v7." --- -## Overview +## Goal -This guide walks you through adding voice and video calling capabilities to your React application using the CometChat UI Kit. +By the end of this guide you will have voice and video calling working in your React app — including the `CometChatCallButtons` component, incoming call notifications, and outgoing call screens. - -Make sure you've completed the [Getting Started](/ui-kit/react/react-js-integration) guide before proceeding. - +## Prerequisites -## Add the Calls SDK +- A working CometChat React UI Kit v7 setup (completed the [Integration Guide](/ui-kit/react/integration-react)) +- `CometChatUIKit.init()` and `login()` completed before rendering +- A CometChat plan that includes calling features enabled in your [dashboard](https://app.cometchat.com) -Install the CometChat Calls SDK: +## Step 1: Install the Calls SDK -```bash +The calling feature requires the optional `@cometchat/calls-sdk-javascript` peer dependency: + + + +```bash npm npm install @cometchat/calls-sdk-javascript ``` -## Verify Integration +```bash yarn +yarn add @cometchat/calls-sdk-javascript +``` + +```bash pnpm +pnpm add @cometchat/calls-sdk-javascript +``` + + + +This package provides the WebRTC layer for voice and video calls. It is loaded lazily by the UI Kit — no additional bundle cost until calling is actually used. + +## Step 2: Enable Calling in UIKitSettingsBuilder + +Set `.setCallingEnabled(true)` on your `UIKitSettingsBuilder` during initialization: + +```tsx title="src/main.tsx" +import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; + +const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .setCallingEnabled(true) + .build(); + +CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + // Render your app +}); +``` + +When calling is enabled, the UI Kit: +- Registers the `CallingPlugin` for call-related message rendering +- Lazy-loads call components (`CometChatIncomingCall`, `CometChatOutgoingCall`, `CometChatOngoingCall`) only when needed +- Enables the `CometChatCallButtons` component to initiate calls + +When calling is not enabled (the default), call components are not loaded and `CometChatCallButtons` renders nothing. + +## Step 3: Configure call settings + +The Calls SDK uses the same `appId` and `region` from your `UIKitSettings` — no separate configuration is needed. The UI Kit passes these credentials to the Calls SDK automatically when calling is enabled. + + +The `config` prop on `CometChatProvider` accepts a `CometChatGlobalConfig` object for UI/behavior flags (`hideReceipts`, `hideUserStatus`, `disableSoundForCalls`, `customSoundForCalls`, `callSettingsBuilder`). It does **not** take a separate calling app ID or region. + + +## Step 4: Add Call Buttons via CometChatMessageHeader + +`CometChatMessageHeader` automatically renders voice and video call buttons when calling is enabled. No extra configuration needed — just render the header with a `user` or `group`: + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, +} from "@cometchat/chat-uikit-react"; + +function ChatPanel({ user }: { user: CometChat.User }) { + return ( +
+ + + +
+ ); +} +``` + +The header shows call buttons by default. To hide them, use `hideVoiceCallButton` or `hideVideoCallButton`: + +```tsx + +``` + +For group calls, pass the `group` prop instead: + +```tsx + +``` + + +`CometChatMessageHeader` renders its call buttons automatically (via the `CometChatMessageHeader.CallButtons` sub-component) — you don't import or render that sub-component separately. If you need call buttons **outside** the header, use the standalone [`CometChatCallButtons`](/ui-kit/react/components/call-buttons) component. + + +## Step 5: Verify with a voice call + +With the setup complete, test a voice call: + +1. Open your app with two different users in separate browser tabs +2. Click the **voice call** button (phone icon) in the chat header +3. The caller sees the `CometChatOutgoingCall` screen with a "Calling..." indicator +4. The receiver sees the `CometChatIncomingCall` overlay with accept/reject buttons +5. Once accepted, both users enter the `CometChatOngoingCall` view with live audio + +```tsx +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatProvider, + CometChatConversations, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, +} from "@cometchat/chat-uikit-react"; + +export default function App() { + const [user, setUser] = useState(null); + + const handleConversationClick = (conversation: CometChat.Conversation) => { + const conversationWith = conversation.getConversationWith(); + if (conversationWith instanceof CometChat.User) { + setUser(conversationWith); + } + }; + + return ( + +
+
+ +
+
+ {user && ( + <> + + + + + )} +
+
+
+ ); +} +``` + +## Step 6: Verify with a video call + +Video calls work identically — click the **video call** button (camera icon) instead. The `CometChatOngoingCall` component renders a full video interface with: + +- Local and remote video streams +- Mute/unmute audio toggle +- Camera on/off toggle +- End call button + +No additional configuration is needed to switch between audio-only and video calls. The call type is determined by which button the user clicks. + +## Step 7: Render CometChatIncomingCall + +`CometChatIncomingCall` must be rendered in your app — it is NOT auto-rendered by the UI Kit. Place it at the root level of your authenticated layout so it can display the incoming call overlay from anywhere: + +```tsx +import { + CometChatProvider, + CometChatIncomingCall, + CometChatConversations, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, +} from "@cometchat/chat-uikit-react"; + +export default function App() { + const [user, setUser] = useState(null); + + const handleConversationClick = (conversation: CometChat.Conversation) => { + const conversationWith = conversation.getConversationWith(); + if (conversationWith instanceof CometChat.User) { + setUser(conversationWith); + } + }; + + return ( + +
+
+ +
+
+ {user && ( + <> + + + + + )} +
+
+ + {/* Incoming call overlay — renders at root level, listens for call events */} + +
+ ); +} +``` + +`CometChatIncomingCall` listens for incoming call events and displays an accept/reject overlay. When the user accepts, it transitions to the `CometChatOngoingCall` screen internally. You can customize its behavior with callbacks: + +```tsx + console.log("Call accepted:", call)} + onDecline={(call) => console.log("Call declined:", call)} +/> +``` + +`CometChatOutgoingCall` is rendered automatically by the `CometChatCallButtons` component when the user initiates a call — you do not need to place it manually. + +## Summary + +| Step | Action | +|------|--------| +| 1 | Install `@cometchat/calls-sdk-javascript` | +| 2 | Set `.setCallingEnabled(true)` on `UIKitSettingsBuilder` | +| 3 | (Optional) Configure call behavior via `config` prop on `CometChatProvider` | +| 4 | Call buttons appear in `CometChatMessageHeader` automatically | +| 5 | Test voice calls between two users | +| 6 | Test video calls between two users | +| 7 | (Optional) Customize incoming/outgoing call handlers | -After adding the dependency, the React UI Kit will automatically detect it and activate calling features. You will see [CallButtons](/ui-kit/react/call-buttons) rendered in the [MessageHeader](/ui-kit/react/message-header) component. +## Next Steps - - - +- [Message Header](/ui-kit/react/components/message-header) — full props reference including call button visibility +- [Call Logs](/ui-kit/react/components/call-logs) — display call history +- [CometChatProvider](/ui-kit/react/cometchat-provider) — all provider configuration options diff --git a/ui-kit/react/campaigns.mdx b/ui-kit/react/campaigns.mdx index 989cdb05e..71080b1ec 100644 --- a/ui-kit/react/campaigns.mdx +++ b/ui-kit/react/campaigns.mdx @@ -6,7 +6,7 @@ description: "Deliver targeted, rich notifications to users via an in-app notifi CometChat Campaigns enables you to send rich, interactive notifications to users through an in-app notification feed. Each notification is rendered as a native card using the **CometChat Cards** library — supporting images, text, buttons, layouts, and interactive actions. -Before proceeding, ensure you have completed the [UI Kit integration](/ui-kit/react/getting-started) and the [Dashboard Setup](/campaigns#setup-flow) for Campaigns. +Before proceeding, ensure you have completed the [UI Kit integration](/ui-kit/react/integration-react) and the [Dashboard Setup](/campaigns#setup-flow) for Campaigns. @@ -153,7 +153,7 @@ When a campaign push notification arrives via Web Push or FCM, you should: 2. **Report click** — Call `CometChat.markPushNotificationClicked()` when the user clicks the notification 3. **Deep link** — Use the announcement ID from the push payload to fetch the full item via `CometChat.getNotificationFeedItem(id)` and display it -```tsx lines +```tsx import { CometChat } from "@cometchat/chat-sdk-javascript"; // When push notification is received (e.g., in service worker) @@ -181,9 +181,8 @@ Before integrating the frontend, you need to set up channels, categories, templa The easiest way to add a notification feed to your app is the `CometChatNotificationFeed` component. It handles fetching, rendering, pagination, filtering, real-time updates, and engagement reporting out of the box. -```tsx lines +```tsx import { CometChatNotificationFeed } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function NotificationsScreen() { return ( @@ -199,7 +198,7 @@ function NotificationsScreen() { } ``` -See the full [CometChatNotificationFeed component documentation](/ui-kit/react/notification-feed) for all configuration options, styling, and customization. +See the full [CometChatNotificationFeed component documentation](/ui-kit/react/components/notification-feed) for all configuration options, styling, and customization. --- @@ -209,7 +208,7 @@ See the full [CometChatNotificationFeed component documentation](/ui-kit/react/n Full API reference for feed items, categories, engagement, and push tracking - + Ready-to-use component with filtering, real-time updates, and styling diff --git a/ui-kit/react/cometchat-provider.mdx b/ui-kit/react/cometchat-provider.mdx new file mode 100644 index 000000000..47229eba4 --- /dev/null +++ b/ui-kit/react/cometchat-provider.mdx @@ -0,0 +1,220 @@ +--- +title: "CometChatProvider" +description: "The root provider that composes all internal contexts (plugin registry, theme, locale, global config, events) for the React UI Kit." +--- + +## Overview + +Every CometChat component must be rendered inside a `` which supplies theme, locale, plugin registry, global config, and real-time events to the component tree. + +`CometChatProvider` does **not** handle SDK initialization or user login. You must call `CometChatUIKit.init()` and `CometChatUIKit.login()` (or `loginWithAuthToken()`) imperatively before mounting the provider. + +--- + +## Setup Pattern + +The setup is always the same: initialize, login, then render. + +```tsx title="src/main.tsx" +import ReactDOM from "react-dom/client"; +import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; +import App from "./App"; + +const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("us") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .setCallingEnabled(true) + .build(); + +CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + ReactDOM.createRoot(document.getElementById("root")!).render(); +}); +``` + +```tsx title="src/App.tsx" +import { CometChatProvider, CometChatConversations } from "@cometchat/chat-uikit-react"; + +function App() { + return ( + + + + ); +} + +export default App; +``` + +For production, use `CometChatUIKit.loginWithAuthToken(token)` instead of `login(uid)`. + +--- + +## Props + +| Prop | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `plugins` | `CometChatMessagePlugin[]` | No | — | Additional plugins beyond the defaults | +| `config` | `CometChatGlobalConfig` | No | `{}` | Global flags (`hideReceipts`, `hideUserStatus`, etc.) | +| `theme` | `"light" \| "dark"` | No | `"light"` | Active theme | +| `locale` | `string` | No | `"en-us"` | Language code for localization | +| `children` | `ReactNode` | Yes | — | Your app content | + +--- + +## With Custom Theme and Locale + +```tsx + + + +``` + +--- + +## With Additional Plugins + +All default plugins (text, image, file, audio, video, AI, etc.) are always included. Pass your own custom plugins via the `plugins` prop: + +```tsx +import { CometChatProvider } from "@cometchat/chat-uikit-react"; +import { MyCustomPlugin } from "./plugins/MyCustomPlugin"; + + + + +``` + +--- + +## With Global Config + +```tsx + + + +``` + +--- + +## Accessing the Logged-In User + +Inside your components (children of `CometChatProvider`), access the logged-in user via the `useLoggedInUser()` hook or `CometChatUIKit.getLoggedInUser()`: + +```tsx +import { useLoggedInUser } from "@cometchat/chat-uikit-react"; + +function MyComponent() { + const loggedInUser = useLoggedInUser(); + + if (!loggedInUser) return
Loading...
; + + return
Welcome, {loggedInUser.getName()}
; +} +``` + +--- + +## Internal Architecture + +`CometChatProvider` composes these internal providers in order: + +``` +CometChatProvider + └─ PluginRegistryContext — plugin registry from CometChatUIKit + └─ GlobalConfigProvider — hideReceipts, hideUserStatus, etc. + └─ ThemeProvider — data-theme attribute + CSS variables + └─ LocaleProvider — localization translations + └─ EventsProvider — SDK listeners + UI events + └─ {children} +``` + +--- + +## Next.js App Router + +`CometChatProvider` uses browser APIs internally, so it must be placed inside a Client Component. Additionally, init and login must happen client-side. + +```tsx title="app/providers.tsx" +"use client"; + +import { useEffect, useState } from "react"; +import { CometChatUIKit, UIKitSettingsBuilder, CometChatProvider } from "@cometchat/chat-uikit-react"; + +export function ChatProviders({ children }: { children: React.ReactNode }) { + const [ready, setReady] = useState(false); + + useEffect(() => { + const settings = new UIKitSettingsBuilder() + .setAppId(process.env.NEXT_PUBLIC_COMETCHAT_APP_ID!) + .setRegion(process.env.NEXT_PUBLIC_COMETCHAT_REGION!) + .setAuthKey(process.env.NEXT_PUBLIC_COMETCHAT_AUTH_KEY!) + .setCallingEnabled(true) + .build(); + + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.loginWithAuthToken(getAuthToken()); + setReady(true); + }); + }, []); + + if (!ready) return null; + + return ( + + {children} + + ); +} +``` + +--- + +## Migration from v6 + +In v6, initialization was imperative — call `init()` then `login()`, then render. v7 works the same way: + +```tsx title="v6 (before)" +import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; + +const settings = new UIKitSettingsBuilder() + .setAppId("APP_ID") + .setRegion("REGION") + .setAuthKey("AUTH_KEY") + .build(); + +await CometChatUIKit.init(settings); +await CometChatUIKit.login("USER_ID"); +// Then render your app +``` + +```tsx title="v7 (after)" +import { CometChatUIKit, UIKitSettingsBuilder, CometChatProvider } from "@cometchat/chat-uikit-react"; + +const settings = new UIKitSettingsBuilder() + .setAppId("APP_ID") + .setRegion("REGION") + .setAuthKey("AUTH_KEY") + .build(); + +await CometChatUIKit.init(settings); +await CometChatUIKit.login("USER_ID"); + +// Then render with CometChatProvider wrapping your components +function App() { + return ( + + + + ); +} +``` + +Key differences: +- v7 uses `CometChatProvider` to supply React context (theme, locale, plugins, events) +- Init and login are still imperative — same as v6 +- Default plugins are included automatically +- Theme and locale are props on the provider +- Real-time events are managed internally (no RxJS, no manual listener setup) diff --git a/ui-kit/react/compact-message-composer.mdx b/ui-kit/react/compact-message-composer.mdx deleted file mode 100644 index 6f8ee5365..000000000 --- a/ui-kit/react/compact-message-composer.mdx +++ /dev/null @@ -1,1264 +0,0 @@ ---- -title: "Compact Message Composer" -description: "A compact, single-line message input component with rich text formatting, attachments, mentions, and voice recording support." ---- - - - -```json -{ - "component": "CometChatCompactMessageComposer", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatCompactMessageComposer } from \"@cometchat/chat-uikit-react\";", - "description": "Compact single-line message input with optional rich text formatting (bold, italic, underline, strikethrough, code, links, lists, blockquotes), attachments, mentions, voice recording, and message editing support.", - "primaryOutput": { - "prop": "onSendButtonClick", - "type": "(message: CometChat.BaseMessage) => void" - }, - "props": { - "data": { - "user": { "type": "CometChat.User", "default": "undefined" }, - "group": { "type": "CometChat.Group", "default": "undefined" }, - "parentMessageId": { "type": "number", "default": "undefined" }, - "initialComposerText": { "type": "string", "default": "\"\"" }, - "placeholderText": { "type": "string", "default": "\"Type a message...\"" } - }, - "callbacks": { - "onSendButtonClick": "(message: CometChat.BaseMessage) => void", - "onTextChange": "(text: string) => void", - "onError": "(error: CometChat.CometChatException) => void" - }, - "visibility": { - "hideImageAttachmentOption": { "type": "boolean", "default": false }, - "hideVideoAttachmentOption": { "type": "boolean", "default": false }, - "hideAudioAttachmentOption": { "type": "boolean", "default": false }, - "hideFileAttachmentOption": { "type": "boolean", "default": false }, - "hidePollsOption": { "type": "boolean", "default": false }, - "hideCollaborativeDocumentOption": { "type": "boolean", "default": false }, - "hideCollaborativeWhiteboardOption": { "type": "boolean", "default": false }, - "hideAttachmentButton": { "type": "boolean", "default": false }, - "hideVoiceRecordingButton": { "type": "boolean", "default": false }, - "hideEmojiKeyboardButton": { "type": "boolean", "default": false }, - "hideStickersButton": { "type": "boolean", "default": false }, - "hideSendButton": { "type": "boolean", "default": false } - }, - "richText": { - "enableRichTextEditor": { "type": "boolean", "default": false }, - "hideRichTextFormattingOptions": { "type": "boolean", "default": false }, - "showToolbarOnSelection": { "type": "boolean", "default": false }, - "enterKeyBehavior": { "type": "EnterKeyBehavior", "default": "EnterKeyBehavior.SendMessage" } - }, - "behavior": { - "disableTypingEvents": { "type": "boolean", "default": false }, - "disableMentions": { "type": "boolean", "default": false }, - "disableMentionAll": { "type": "boolean", "default": false }, - "mentionAllLabel": { "type": "string", "default": "\"all\"" }, - "disableSoundForMessage": { "type": "boolean", "default": false }, - "showScrollbar": { "type": "boolean", "default": false } - }, - "viewSlots": { - "headerView": "JSX.Element", - "auxiliaryButtonView": "JSX.Element", - "sendButtonView": "JSX.Element" - }, - "formatting": { - "textFormatters": { - "type": "CometChatTextFormatter[]", - "default": "default formatters from data source" - }, - "attachmentOptions": { - "type": "CometChatMessageComposerAction[]", - "note": "Custom attachment options list (replaces defaults)" - } - } - }, - "events": [ - { - "name": "ccMessageSent", - "payload": "{ message: CometChat.BaseMessage, status: string }", - "description": "Triggers when a message is sent with status: inProgress, success, or error" - }, - { - "name": "ccMessageEdited", - "payload": "{ message: CometChat.BaseMessage, status: string }", - "description": "Triggers when a message is edited with status: inProgress, success, or error" - }, - { - "name": "ccReplyToMessage", - "payload": "{ message: CometChat.BaseMessage, status: string }", - "description": "Triggers when a user replies to a message with status: inProgress, success, or error" - } - ], - "compositionExample": { - "description": "Compact message composer wired with message header and list for complete chat view", - "components": [ - "CometChatMessageHeader", - "CometChatMessageList", - "CometChatCompactMessageComposer" - ], - "flow": "Pass user or group prop to composer -> onSendButtonClick fires with CometChat.BaseMessage -> message appears in MessageList" - } -} -``` - - -## Overview - -`CometChatCompactMessageComposer` is a [Component](/ui-kit/react/components-overview#components) that provides a compact, single-line message input with optional rich text formatting capabilities. It supports bold, italic, underline, strikethrough, code, links, lists, and blockquotes. - -This is a compact variant of [CometChatMessageComposer](/ui-kit/react/message-composer). It shares a similar props API but provides a streamlined, single-line interface with rich text formatting controls. - -Wire it alongside `CometChatMessageHeader` and `CometChatMessageList` to build a standard chat view. - -Features such as **Rich Text Formatting**, **Attachments**, **Message Editing**, **Mentions**, **Link Previews**, and **Voice Recording** are supported. - - - - - - -**Before using this component:** Ensure `CometChatUIKit.init(UIKitSettings)` has completed and the user is logged in via `CometChatUIKit.login("UID")`. See [React.js Integration](/ui-kit/react/react-js-integration). - - - -**Available via:** [UI Kits](/ui-kit/react/overview) | [SDK](/sdk/javascript/overview) - - ---- - -## Minimal Render - -```tsx -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -function CompactComposerDemo() { - return ; -} - -export default CompactComposerDemo; -``` - ---- - -## Usage - -### Integration - -The following code snippet illustrates how you can directly incorporate the CompactMessageComposer component into your app. - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(); - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- - -```jsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(null); - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- -
- -**Expected result:** -- The `CometChatCompactMessageComposer` component renders a compact, single-line message input -- The input supports typing, sending messages, attachments, emoji, stickers, and voice recording -- Clicking the send button dispatches the message to the specified `user` - ---- - -## Actions and Events - -### Callback Props - -[Actions](/ui-kit/react/components-overview#actions) dictate how a component functions. They are divided into two types: Predefined and User-defined. You can override either type, allowing you to tailor the behavior of the component to fit your specific needs. - -#### onSendButtonClick - -Fires when the send message button is clicked. Overrides the default send behavior. - -```tsx -onSendButtonClick?: (message: CometChat.BaseMessage) => void -``` - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - function handleSendButtonClick(message: CometChat.BaseMessage): void { - console.log("your custom on send button click action"); - } - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- - -```jsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(null); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - function handleSendButtonClick(message) { - console.log("your custom on send button click action"); - } - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- -
- -#### onError - -Fires on internal errors (network failure, auth issue, SDK exception). This action doesn't change the behavior of the component but rather listens for any errors that occur in the CompactMessageComposer component. - -```tsx -onError?: (error: CometChat.CometChatException) => void -``` - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - function handleError(error: CometChat.CometChatException) { - throw new Error("your custom error action"); - } - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- - -```jsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(null); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - function handleError(error) { - throw new Error("your custom error action"); - } - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- -
- -#### onTextChange - -Fires as the user types in the composer input. - -```tsx -onTextChange?: (text: string) => void -``` - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - function handleTextChange(text: string) { - console.log("onTextChange", text); - } - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- - -```jsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(null); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - function handleTextChange(text) { - console.log("onTextChange", text); - } - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- -
- -#### Custom Mentions Request Builders - -You can customize how mentioned users and group members are fetched by providing custom request builders. - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(); - const [chatGroup, setChatGroup] = React.useState(); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - CometChat.getGroup("guid").then((group) => { - setChatGroup(group); - }); - }, []); - - // Custom Users Request Builder for mentions - const mentionsUsersRequestBuilder = new CometChat.UsersRequestBuilder() - .setLimit(10) - .setSearchKeyword("") - .setRoles(["default", "moderator"]); - - // Custom Group Members Request Builder for group mentions - const mentionsGroupMembersRequestBuilder = new CometChat.GroupMembersRequestBuilder("guid") - .setLimit(15) - .setSearchKeyword("") - .setScopes(["admin", "moderator", "participant"]); - - return chatUser ? ( -
- {/* For user chat with custom users mentions */} - - - {/* For group chat with custom group members mentions */} - {chatGroup && ( - - )} -
- ) : null; -} -``` - -
- - -```jsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(null); - const [chatGroup, setChatGroup] = React.useState(null); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - CometChat.getGroup("guid").then((group) => { - setChatGroup(group); - }); - }, []); - - // Custom Users Request Builder for mentions - const mentionsUsersRequestBuilder = new CometChat.UsersRequestBuilder() - .setLimit(10) - .setSearchKeyword("") - .setRoles(["default", "moderator"]); - - // Custom Group Members Request Builder for group mentions - const mentionsGroupMembersRequestBuilder = new CometChat.GroupMembersRequestBuilder("guid") - .setLimit(15) - .setSearchKeyword("") - .setScopes(["admin", "moderator", "participant"]); - - return chatUser ? ( -
- {/* For user chat with custom users mentions */} - - - {/* For group chat with custom group members mentions */} - {chatGroup && ( - - )} -
- ) : null; -} -``` - -
- -
- -*** - -### Filters - -CompactMessageComposer component does not have any available filters. - -*** - -### Global UI Events - -[Events](/ui-kit/react/components-overview#events) are emitted by a `Component`. By using events you can extend existing functionality. Being global events, they can be applied in multiple locations and are capable of being added or removed. - -`CometChatMessageEvents` emits events subscribable from anywhere in the application. Add listeners and remove them on cleanup. - -| Event | Fires when | Payload | -| --- | --- | --- | -| **ccMessageSent** | A message is sent | `{ message: CometChat.BaseMessage, status: string }` | -| **ccMessageEdited** | A message is edited | `{ message: CometChat.BaseMessage, status: string }` | -| **ccReplyToMessage** | A user replies to a message | `{ message: CometChat.BaseMessage, status: string }` | - -Each event has three states: `inProgress`, `success`, and `error`. - -When to use: sync external UI with message state changes. For example, update a notification badge when messages are sent, or trigger analytics when a message is edited. - - - -```tsx -import React, { useEffect } from "react"; -import { CometChatMessageEvents } from "@cometchat/chat-uikit-react"; - -function useCompactComposerEvents() { - useEffect(() => { - const ccMessageEdited = CometChatMessageEvents.ccMessageEdited.subscribe( - (item) => { - console.log("Message edited:", item); - } - ); - - const ccReplyToMessage = CometChatMessageEvents.ccReplyToMessage.subscribe( - (item) => { - console.log("Reply to message:", item); - } - ); - - const ccMessageSent = CometChatMessageEvents.ccMessageSent.subscribe( - (item) => { - console.log("Message sent:", item); - } - ); - - // Cleanup on unmount - return () => { - ccMessageEdited?.unsubscribe(); - ccReplyToMessage?.unsubscribe(); - ccMessageSent?.unsubscribe(); - }; - }, []); -} -``` - - - - -```jsx -import React, { useEffect } from "react"; -import { CometChatMessageEvents } from "@cometchat/chat-uikit-react"; - -function useCompactComposerEvents() { - useEffect(() => { - const ccMessageEdited = CometChatMessageEvents.ccMessageEdited.subscribe( - (item) => { - console.log("Message edited:", item); - } - ); - - const ccReplyToMessage = CometChatMessageEvents.ccReplyToMessage.subscribe( - (item) => { - console.log("Reply to message:", item); - } - ); - - const ccMessageSent = CometChatMessageEvents.ccMessageSent.subscribe( - (item) => { - console.log("Message sent:", item); - } - ); - - // Cleanup on unmount - return () => { - ccMessageEdited?.unsubscribe(); - ccReplyToMessage?.unsubscribe(); - ccMessageSent?.unsubscribe(); - }; - }, []); -} -``` - - - - - - -In React 18 StrictMode, `useEffect` runs twice on mount in development. The component handles listener cleanup internally, but any additional listeners added alongside the component need cleanup in the `useEffect` return function to avoid duplicate event handling. - - -*** - -## Customization - -To fit your app's design requirements, you can customize the appearance of the CompactMessageComposer component. We provide exposed methods that allow you to modify the experience and behavior according to your specific needs. - - - -*** - -### Functionality - -These are a set of small functional customizations that allow you to fine-tune the overall experience of the component. With these, you can change text, set custom icons, and toggle the visibility of UI elements. - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -; -``` - - - - - -Below is a list of customizations along with corresponding code snippets - -| Property | Type | Default | Description | Code | -| --- | --- | --- | --- | --- | -| **user** | `CometChat.User` | `undefined` | Specifies the recipient of the message (user object). | `user={chatUser}` | -| **group** | `CometChat.Group` | `undefined` | Specifies the group to send messages to. Used if the `user` prop is not provided. | `group={chatGroup}` | -| **parentMessageId** | `number` | `undefined` | Specifies the ID of the parent message for threading or replying to a specific message. | `parentMessageId={12345}` | -| **initialComposerText** | `string` | `""` | The initial text pre-filled in the message input when the component mounts. | `initialComposerText="Hello"` | -| **placeholderText** | `string` | `"Type a message..."` | The placeholder text displayed in the message input when it is empty. | `placeholderText="Type a message..."` | -| **disableTypingEvents** | `boolean` | `false` | Disables the typing indicator for the current message composer. | `disableTypingEvents={true}` | -| **disableMentions** | `boolean` | `false` | Disables the mentions functionality in the message composer. | `disableMentions={true}` | -| **disableMentionAll** | `boolean` | `false` | Controls whether group mentions like @all appear in suggestions. | `disableMentionAll={true}` | -| **mentionAllLabel** | `string` | `"all"` | Allows setting a custom alias label for group mentions (@channel, @everyone, etc.). | `mentionAllLabel="all"` | -| **mentionsUsersRequestBuilder** | `CometChat.UsersRequestBuilder` | `undefined` | Provides a custom UsersRequestBuilder to control how the mentioned users list is fetched. | `mentionsUsersRequestBuilder={usersRequestBuilder}` | -| **mentionsGroupMembersRequestBuilder** | `CometChat.GroupMembersRequestBuilder` | `undefined` | Provides a custom GroupMembersRequestBuilder to customize how mentioned group members are retrieved. | `mentionsGroupMembersRequestBuilder={groupMembersRequestBuilder}` | -| **enableRichTextEditor** | `boolean` | `false` | Master switch to enable rich text formatting. When false, the composer works as plain text only. | `enableRichTextEditor={true}` | -| **showToolbarOnSelection** | `boolean` | `false` | Shows a floating toolbar when text is selected. Ignored on mobile devices. | `showToolbarOnSelection={true}` | -| **hideRichTextFormattingOptions** | `boolean` | `false` | Hides the rich text formatting toolbar. Keyboard shortcuts still work. | `hideRichTextFormattingOptions={true}` | -| **hideImageAttachmentOption** | `boolean` | `false` | Hides the image attachment option in the message composer. | `hideImageAttachmentOption={true}` | -| **hideVideoAttachmentOption** | `boolean` | `false` | Hides the video attachment option in the message composer. | `hideVideoAttachmentOption={true}` | -| **hideAudioAttachmentOption** | `boolean` | `false` | Hides the audio attachment option in the message composer. | `hideAudioAttachmentOption={true}` | -| **hideFileAttachmentOption** | `boolean` | `false` | Hides the file attachment option in the message composer. | `hideFileAttachmentOption={true}` | -| **hidePollsOption** | `boolean` | `false` | Hides the polls option in the message composer. | `hidePollsOption={true}` | -| **hideCollaborativeDocumentOption** | `boolean` | `false` | Hides the collaborative document option in the message composer. | `hideCollaborativeDocumentOption={true}` | -| **hideCollaborativeWhiteboardOption** | `boolean` | `false` | Hides the collaborative whiteboard option in the message composer. | `hideCollaborativeWhiteboardOption={true}` | -| **hideAttachmentButton** | `boolean` | `false` | Hides the attachment button in the message composer. | `hideAttachmentButton={true}` | -| **hideVoiceRecordingButton** | `boolean` | `false` | Hides the voice recording button in the message composer. | `hideVoiceRecordingButton={true}` | -| **hideEmojiKeyboardButton** | `boolean` | `false` | Hides the emoji keyboard button in the message composer. | `hideEmojiKeyboardButton={true}` | -| **hideStickersButton** | `boolean` | `false` | Hides the stickers button in the message composer. | `hideStickersButton={true}` | -| **hideSendButton** | `boolean` | `false` | Hides the send button in the message composer. | `hideSendButton={true}` | -| **showScrollbar** | `boolean` | `false` | Controls the visibility of the scrollbar in the composer. | `showScrollbar={true}` | -| **enterKeyBehavior** | `EnterKeyBehavior` | `EnterKeyBehavior.SendMessage` | Determines the behavior of the Enter key (e.g., send message or add a new line). | `enterKeyBehavior={EnterKeyBehavior.SendMessage}` | -| **disableSoundForMessage** | `boolean` | `false` | Disables sound for incoming messages. | `disableSoundForMessage={true}` | -| **customSoundForMessage** | `string` | `undefined` | Specifies a custom audio sound for incoming messages. | `customSoundForMessage="sound.mp3"` | - -*** - -## Rich Text Formatting - -The CompactMessageComposer includes a built-in rich text editor. Rich text must be explicitly enabled via `enableRichTextEditor={true}` (defaults to `false`). - -### Formatting Toolbar - -The toolbar provides the following formatting tools in a fixed order: - -| Tool | Icon | Shortcut | Description | -|------|------|----------|-------------| -| Bold | B | Cmd/Ctrl+B | Bold text | -| Italic | I | Cmd/Ctrl+I | Italic text | -| Underline | U | Cmd/Ctrl+U | Underline text | -| Strikethrough | S | Cmd/Ctrl+Shift+S | Strikethrough text | -| Inline Code | `` | Cmd/Ctrl+E | Inline code | -| Code Block | ``` | Cmd/Ctrl+Shift+C | Multi-line code block | -| Link | 🔗 | Cmd/Ctrl+K | Add/edit hyperlink | -| Bullet List | • | Cmd/Ctrl+Shift+8 | Unordered list | -| Ordered List | 1. | Cmd/Ctrl+Shift+7 | Numbered list | -| Blockquote | ❝ | Cmd/Ctrl+Shift+9 | Quote block | - -### Toolbar Visibility Modes - -The toolbar supports multiple display modes controlled via props. When multiple props are set, they follow this priority order: - -1. `enableRichTextEditor={false}` — Highest priority, disables all rich text features (plain text only) -2. `hideRichTextFormattingOptions={true}` — Toolbar visible by default above input -3. `showToolbarOnSelection={true}` — Floating toolbar appears on text selection (desktop only) - -If none of the toolbar props are enabled, the toolbar is hidden but keyboard shortcuts still work. - -### Behavior Matrix - -| `enableRichTextEditor` | `hideRichTextFormattingOptions` | `showToolbarOnSelection` | Result | -|------------------------|-------------------------------|--------------------------|--------| -| `false` | - | - | Plain text, no formatting UI | -| `true` | `false` | `true` | Floating toolbar appears on text selection (desktop) | -| `true` | `true` | `false` | Toolbar visible by default above input | -| `true` | `false` | `false` | No toolbar UI, only keyboard shortcuts work | - -### Mobile Behavior - -On mobile devices, only the fixed toolbar is supported. The floating selection toolbar is disabled for better touch UX. - -| Props | Mobile Behavior | -|-------|-----------------| -| `showToolbarOnSelection={true}` | **Ignored on mobile** — Falls back to fixed toolbar | -| `hideRichTextFormattingOptions={true}` | Fixed toolbar visible by default above input | - -### Toolbar Configuration Examples - - - -```tsx -// Floating toolbar appears on text selection (desktop only) - -``` - - - - -```tsx -// Toolbar visible by default above input - -``` - - - - -```tsx -// Rich text enabled but no toolbar (keyboard shortcuts only) - -``` - - - - -```tsx -// Selection toolbar + always-visible toolbar - -``` - - - - - -*** - -## Custom View Slots - -Each slot replaces a section of the default UI. Slots that accept parameters receive the relevant data for customization. - -| Slot | Type | Replaces | -| --- | --- | --- | -| `headerView` | `JSX.Element` | Area above the composer input | -| `auxiliaryButtonView` | `JSX.Element` | Sticker and AI button area | -| `sendButtonView` | `JSX.Element` | Send button | -| `attachmentOptions` | `CometChatMessageComposerAction[]` | Default attachment options list (replaces defaults) | -| `textFormatters` | `CometChatTextFormatter[]` | Text formatting in composer | - -### Advanced - -For advanced-level customization, you can set custom views to the component. This lets you tailor each aspect of the component to fit your exact needs and application aesthetics. You can create and define your views, layouts, and UI elements and then incorporate those into the component. - -*** - -#### AttachmentOptions - -By using `attachmentOptions`, you can set a list of custom `MessageComposerActions` for the CompactMessageComposer Component. This will override the existing list of `MessageComposerActions`. - - - - - -Use the following code to achieve the customization shown above. - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatCompactMessageComposer, - CometChatMessageComposerAction, -} from "@cometchat/chat-uikit-react"; - -function getAttachments() { - return [ - new CometChatMessageComposerAction({ - id: "custom1", - title: "Custom Option 1", - iconURL: "Icon URL", - }), - new CometChatMessageComposerAction({ - id: "custom2", - title: "Custom Option 2", - iconURL: "Icon URL", - }), - new CometChatMessageComposerAction({ - id: "custom3", - title: "Custom Option 3", - iconURL: "Icon URL", - }), - new CometChatMessageComposerAction({ - id: "custom4", - title: "Custom Option 4", - iconURL: "Icon URL", - }), - ]; -} - -; -``` - - - - -```css -.cometchat-compact-message-composer__secondary-button-view-attachment-button - .cometchat-action-sheet { - border: none; - border-radius: inherit; - background: transparent; - box-shadow: none; - width: 100%; -} - -.cometchat-compact-message-composer__secondary-button-view-attachment-button - .cometchat-popover__content - > .cometchat { - border-radius: inherit; -} - -.cometchat-compact-message-composer__secondary-button-view-attachment-button - .cometchat-popover__content { - height: 240px; -} - -.cometchat-compact-message-composer__secondary-button-view-attachment-button - .cometchat-action-sheet__item-icon { - background: #141414; -} -``` - - - - - -**Expected result:** The default attachment options (image, video, audio, file, polls, etc.) are replaced with four custom options. The action sheet styling is customized with transparent background and custom icon colors. - -*** - -#### AuxiliaryButtonView - -You can insert a custom view into the CompactMessageComposer component to add additional functionality using the following method. - - -The CompactMessageComposer Component utilizes the AuxiliaryButton to provide sticker and AI functionality. Overriding the AuxiliaryButton will subsequently replace the sticker functionality. - - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatCompactMessageComposer, - CometChatButton, -} from "@cometchat/chat-uikit-react"; - -const auxiliaryButtonView = ( - { - // logic here - }} - /> -); - -; -``` - - - - - -*** - -#### SendButtonView - -You can set a custom view in place of the already existing send button view. - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatCompactMessageComposer, - CometChatButton, -} from "@cometchat/chat-uikit-react"; - -const sendButtonView = ( - { - // logic here - }} - /> -); - -; -``` - - - - -```css -.cometchat-compact-message-composer - div:not([class]) - .cometchat-compact-message-composer__send-button - .cometchat-button { - background: #edeafa; -} - -.cometchat-compact-message-composer - div:not([class]) - .cometchat-compact-message-composer__send-button - .cometchat-button__icon { - background: #6852d6; -} -``` - - - - - -**Expected result:** The default send button is replaced with a custom button. The CSS overrides give the button a light purple background (#edeafa) with a purple icon (#6852d6). - -*** - -#### HeaderView - -You can set custom headerView to the CompactMessageComposer component using the following method. - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; - -const getHeaderView = () => { - return ( -
-
-
- User has paused their notifications -
-
- ); -}; - -; -``` - -
- - -```css -.cometchat-compact-message-composer .compact-composer__header-view { - display: flex; - align-items: center; - align-content: center; - gap: 8px var(--cometchat-padding-2, 8px); - align-self: stretch; - flex-wrap: wrap; - width: 100%; -} - -.cometchat-compact-message-composer__header { - background: #dcd7f6; - border-radius: var(--cometchat-radius-max, 1000px); - padding: var(--cometchat-padding-2, 8px) var(--cometchat-padding-5, 20px); -} - -.cometchat-compact-message-composer - .compact-composer__header-view - .compact-composer__header-view-text { - overflow: hidden; - color: var(--cometchat-text-color-primary, #141414); - text-overflow: ellipsis; - font: var(--cometchat-font-body-regular); -} - -.cometchat-compact-message-composer - .compact-composer__header-view - .compact-composer__header-view-icon { - display: flex; - width: 24px; - height: 24px; - justify-content: center; - align-items: center; - background: var(--cometchat-primary-color); - -webkit-mask: url("icon url") center center no-repeat; - -webkit-mask-size: contain; - mask: url("icon url") center center no-repeat; - mask-size: contain; -} -``` - - - -
- -**Expected result:** A custom header bar appears above the composer input with an icon and notification text ("User has paused their notifications"), styled with a light purple background and rounded corners. - -*** - -#### TextFormatters - -Assigns the list of text formatters. If the provided list is not null, it sets the list. Otherwise, it assigns the default text formatters retrieved from the data source. To configure the existing Mentions look and feel check out [CometChatMentionsFormatter](/ui-kit/react/mentions-formatter-guide) - - - -```ts -import { CometChatTextFormatter } from "@cometchat/chat-uikit-react"; -import DialogHelper from "./Dialog"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -class ShortcutFormatter extends CometChatTextFormatter { - private shortcuts: { [key: string]: string } = {}; - private dialogIsOpen: boolean = false; - private dialogHelper = new DialogHelper(); - private currentShortcut: string | null = null; - - constructor() { - super(); - this.setTrackingCharacter("!"); - CometChat.callExtension("message-shortcuts", "GET", "v1/fetch", undefined) - .then((data: any) => { - if (data && data.shortcuts) { - this.shortcuts = data.shortcuts; - } - }) - .catch((error) => console.log("error fetching shortcuts", error)); - } - - onKeyDown(event: KeyboardEvent) { - const caretPosition = - this.currentCaretPosition instanceof Selection - ? this.currentCaretPosition.anchorOffset - : 0; - const textBeforeCaret = this.getTextBeforeCaret(caretPosition); - - const match = textBeforeCaret.match(/!([a-zA-Z]+)$/); - if (match) { - const shortcut = match[0]; - const replacement = this.shortcuts[shortcut]; - if (replacement) { - if (this.dialogIsOpen && this.currentShortcut !== shortcut) { - this.closeDialog(); - } - this.openDialog(replacement, shortcut); - } - } - } - - getCaretPosition() { - if (!this.currentCaretPosition?.rangeCount) return { x: 0, y: 0 }; - const range = this.currentCaretPosition?.getRangeAt(0); - const rect = range.getBoundingClientRect(); - return { - x: rect.left, - y: rect.top, - }; - } - - openDialog(buttonText: string, shortcut: string) { - this.dialogHelper.createDialog( - () => this.handleButtonClick(buttonText), - buttonText - ); - this.dialogIsOpen = true; - this.currentShortcut = shortcut; - } - - closeDialog() { - this.dialogHelper.closeDialog(); - this.dialogIsOpen = false; - this.currentShortcut = null; - } - - handleButtonClick = (buttonText: string) => { - if (this.currentCaretPosition && this.currentRange) { - const shortcut = Object.keys(this.shortcuts).find( - (key) => this.shortcuts[key] === buttonText - ); - if (shortcut) { - const replacement = this.shortcuts[shortcut]; - this.addAtCaretPosition( - replacement, - this.currentCaretPosition, - this.currentRange - ); - } - } - if (this.dialogIsOpen) { - this.closeDialog(); - } - }; - - getFormattedText(text: string): string { - return text; - } - - private getTextBeforeCaret(caretPosition: number): string { - if ( - this.currentRange && - this.currentRange.startContainer && - typeof this.currentRange.startContainer.textContent === "string" - ) { - const textContent = this.currentRange.startContainer.textContent; - if (textContent.length >= caretPosition) { - return textContent.substring(0, caretPosition); - } - } - return ""; - } -} - -export default ShortcutFormatter; -``` - - - - -```tsx -import React from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatCompactMessageComposer } from "@cometchat/chat-uikit-react"; -import ShortcutFormatter from "./ShortCutFormatter"; - -export function CompactComposerDemo() { - const [chatUser, setChatUser] = React.useState(); - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }); - }, []); - - return chatUser ? ( -
- -
- ) : null; -} -``` - -
- -
- -*** - - - ---- - -## Next Steps - - - - Full-featured multi-line message composer component. - - - Display messages with real-time updates. - - - Implement @mentions in your chat application. - - - Customize colors, fonts, and styling. - - diff --git a/ui-kit/react/components-overview.mdx b/ui-kit/react/components-overview.mdx index 4418f1c8d..b30e86e52 100644 --- a/ui-kit/react/components-overview.mdx +++ b/ui-kit/react/components-overview.mdx @@ -1,92 +1,219 @@ --- title: "Overview" -description: "Browse all prebuilt UI components in the CometChat React UI Kit — conversations, messages, users, groups, calls, search, and AI." +description: "Understand the component architecture, usage patterns, and all available components in the CometChat React UI Kit." --- - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Required setup | `CometChatUIKit.init()` + `CometChatUIKit.login()` before rendering any component | -| Callback actions | `on={(param) => {}}` | -| Data filtering | `RequestBuilder={new CometChat.RequestBuilder()}` | -| Toggle features | `hide={true}` or `show={true}` | -| Custom rendering | `View={() => JSX}` | -| CSS overrides | Target `.cometchat-` class in global CSS | -| Calling | Requires separate `@cometchat/calls-sdk-javascript` package | - - - ## Architecture -The UI Kit is a set of independent components that compose into chat layouts. A typical two-panel layout uses four core components: +The UI Kit provides a set of independent, composable React components that wire together into complete chat layouts. A typical two-panel layout uses four core components: -- **CometChatConversations** — sidebar listing recent conversations (users and groups) -- **CometChatMessageHeader** — toolbar showing avatar, name, online status, and typing indicator +- **CometChatConversations** — sidebar listing recent conversations +- **CometChatMessageHeader** — toolbar showing avatar, name, status, and typing indicator - **CometChatMessageList** — scrollable message feed with reactions, receipts, and threads - **CometChatMessageComposer** — rich text input with attachments, mentions, and voice notes -Data flow: selecting a conversation in CometChatConversations yields a `CometChat.User` or `CometChat.Group` object. That object is passed as a prop (`user` or `group`) to CometChatMessageHeader, CometChatMessageList, and CometChatMessageComposer. The message components use the SDK internally — CometChatMessageComposer sends messages, CometChatMessageList receives them via real-time listeners. +Data flow: selecting a conversation yields a `CometChat.User` or `CometChat.Group` object. Pass that object as a prop (`user` or `group`) to the message components. They handle SDK calls internally — the composer sends messages, the list receives them via real-time listeners. + +All components must be rendered inside a `` which provides shared context (theme, locale, events). SDK initialization and login must be completed before the provider mounts. + + + + + +```tsx +import { + CometChatProvider, + CometChatConversations, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, +} from "@cometchat/chat-uikit-react"; + +function ChatApp() { + const [user, setUser] = useState(); + + return ( + +
+ setUser(conv.getConversationWith())} /> +
+ + + +
+
+
+ ); +} +``` + +--- + +## Flat API + +All components — both feature and base — support the flat API. Render them in a single line with props, and they handle their layout internally. + +```tsx + +``` + +This is the quickest way to get started. The component renders all its default sub-components (header, list, empty state, loading state, etc.) automatically. + +--- + +## Compound Composition + +For full layout control, use the compound pattern. Each feature component is a namespace with sub-components: + +```tsx + + {/* Only render what you need, and omit sub-components to hide them */} + + + +``` + +Key principles: +- **Root** initializes state, fetches data, and provides context to children. +- **Sub-components** read from context and render when their state is active. +- **Omit a sub-component** to hide it, no boolean props needed. +- **Add custom elements** anywhere inside Root alongside the sub-components. + +Both APIs produce the same result. The flat API is shorthand for rendering Root with all sub-components in their default order. + +--- + +## Component Categories + +Components are organized into three categories: + +### Feature Components + +Feature components integrate with the CometChat SDK for data fetching, real-time events, and state management. They follow the compound pattern and support both flat and compound APIs. -Components communicate through a publish/subscribe event bus (`CometChatMessageEvents`, `CometChatConversationEvents`, `CometChatGroupEvents`, etc.). A component emits events that other components or application code can subscribe to without direct references. See [Events](/ui-kit/react/events) for the full list. +Feature components: +- Own their data lifecycle (fetch, paginate, refresh) +- Subscribe to real-time SDK events (new messages, presence changes, typing indicators) +- Manage complex state via hooks and reducers +- Provide context to their sub-components -Each component accepts callback props (`on`), view slot props (`View`) for replacing UI sections, `RequestBuilder` props for data filtering, and CSS variable overrides on `.cometchat-` classes. +### Base Components + +Base components are pure UI building blocks with no SDK integration. They accept props and render UI — no network calls, no real-time events. Feature components compose these internally. Base components support both flat API and compound composition. --- -## Component Catalog +## Feature Components -All components are imported from `@cometchat/chat-uikit-react`. +All feature components are imported from `@cometchat/chat-uikit-react`. ### Conversations and Lists -| Component | Purpose | Key Props | Page | -| --- | --- | --- | --- | -| CometChatConversations | Scrollable list of recent conversations | `conversationsRequestBuilder`, `onItemClick`, `onError` | [Conversations](/ui-kit/react/conversations) | -| CometChatUsers | Scrollable list of users | `usersRequestBuilder`, `onItemClick`, `onError` | [Users](/ui-kit/react/users) | -| CometChatGroups | Scrollable list of groups | `groupsRequestBuilder`, `onItemClick`, `onError` | [Groups](/ui-kit/react/groups) | -| CometChatGroupMembers | Scrollable list of group members | `group`, `groupMemberRequestBuilder`, `onItemClick` | [Group Members](/ui-kit/react/group-members) | +| Component | Purpose | Page | +| --- | --- | --- | +| `CometChatConversations` | Scrollable list of recent conversations with real-time updates | [Conversations](/ui-kit/react/components/conversations) | +| `CometChatUsers` | Searchable list of users with selection support | [Users](/ui-kit/react/components/cometchat-users) | +| `CometChatGroups` | Searchable list of groups with selection support | [Groups](/ui-kit/react/components/cometchat-groups) | +| `CometChatGroupMembers` | List of group members with role-based actions | [Group Members](/ui-kit/react/components/cometchat-group-members) | ### Messages -| Component | Purpose | Key Props | Page | +| Component | Purpose | Page | +| --- | --- | --- | +| `CometChatMessageHeader` | Toolbar with avatar, name, status, typing indicator, and call buttons | [Message Header](/ui-kit/react/components/message-header) | +| `CometChatMessageList` | Scrollable message feed with plugin-based bubble rendering | [Message List](/ui-kit/react/components/message-list) | +| `CometChatMessageComposer` | Rich text input with attachments, emoji, voice recording, and formatting | [Message Composer](/ui-kit/react/components/message-composer) | +| `CometChatMessageBubble` | Message bubble container with alignment, receipts, options, and reactions | [Message Bubble](/ui-kit/react/components/message-bubble) | +| `CometChatThreadHeader` | Parent message bubble and reply count for threaded conversations | [Thread Header](/ui-kit/react/components/thread-header) | +| `CometChatMessageInformation` | Message delivery and read receipt details panel | [Message Information](/ui-kit/react/components/message-information) | +| `CometChatReactions` | Reaction chips bar with reactor list popover | [Reactions](/ui-kit/react/components/reactions) | +| `CometChatReactionList` | Full reactor list with tabs and pagination | [Reaction List](/ui-kit/react/components/reaction-list) | +| `CometChatFlagMessageDialog` | Modal dialog for reporting/flagging messages with reason selection | [Flag Message Dialog](/ui-kit/react/components/flag-message-dialog) | + +### Message Bubbles + +Message bubble components accept a `message` object and self-extract all required data (text, attachments, metadata, sender info). Unlike v6 where bubbles were purely presentational, v7 bubbles are self-contained — they derive their rendering state directly from the SDK message. + +| Component | Message Type | Purpose | Page | | --- | --- | --- | --- | -| CometChatMessageHeader | Toolbar with avatar, name, status, typing indicator | `user`, `group`, `enableAutoSummaryGeneration` | [Message Header](/ui-kit/react/message-header) | -| CometChatMessageList | Scrollable message list with reactions, receipts, threads | `user`, `group`, `messagesRequestBuilder`, `goToMessageId` (string) | [Message List](/ui-kit/react/message-list) | -| CometChatMessageComposer | Rich text input with attachments, mentions, voice notes | `user`, `group`, `onSendButtonClick`, `placeholderText` | [Message Composer](/ui-kit/react/message-composer) | -| CometChatMessageTemplate | Pre-defined structure for custom message bubbles | `type`, `category`, `contentView`, `headerView`, `footerView` | [Message Template](/ui-kit/react/message-template) | -| CometChatThreadHeader | Parent message bubble and reply count for threaded view | `parentMessage`, `onClose`, `hideReceipts`, `textFormatters` | [Thread Header](/ui-kit/react/thread-header) | +| `CometChatTextBubble` | `text` | Formatted text with mentions, URLs, markdown, and link previews | [Text Bubble](/ui-kit/react/components/text-bubble) | +| `CometChatImageBubble` | `image` | Image grid with captions and click-to-fullscreen | [Image Bubble](/ui-kit/react/components/image-bubble) | +| `CometChatVideoBubble` | `video` | Video player with thumbnail and caption | [Video Bubble](/ui-kit/react/components/video-bubble) | +| `CometChatAudioBubble` | `audio` | Waveform audio player with caption | [Audio Bubble](/ui-kit/react/components/audio-bubble) | +| `CometChatFileBubble` | `file` | File card with name, size, and download button | [File Bubble](/ui-kit/react/components/file-bubble) | +| `CometChatPollBubble` | `extension_poll` | Poll with options, voting, and results | [Poll Bubble](/ui-kit/react/components/poll-bubble) | +| `CometChatStickerBubble` | `extension_sticker` | Sticker image display | [Sticker Bubble](/ui-kit/react/components/sticker-bubble) | +| `CometChatCollaborativeDocumentBubble` | `extension_document` | Document collaboration link with join button | [Collaborative Document Bubble](/ui-kit/react/components/collaborative-document-bubble) | +| `CometChatCollaborativeWhiteboardBubble` | `extension_whiteboard` | Whiteboard collaboration link with join button | [Collaborative Whiteboard Bubble](/ui-kit/react/components/collaborative-whiteboard-bubble) | +| `CometChatGroupActionBubble` | `groupMember` | Group membership system messages (joined, left, kicked, banned, scope change) | [Group Action Bubble](/ui-kit/react/components/group-action-bubble) | +| `CometChatCallActionBubble` | `audio`, `video` (call category) | Call status system messages (missed, outgoing, incoming, ended) | [Call Action Bubble](/ui-kit/react/components/call-action-bubble) | +| `CometChatCallBubble` | `meeting` (custom) | Direct call / meeting invitation bubble | [Call Bubble](/ui-kit/react/components/call-bubble) | ### Calling -| Component | Purpose | Key Props | Page | -| --- | --- | --- | --- | -| CometChatCallButtons | Voice and video call initiation buttons | `user`, `group`, `onVoiceCallClick`, `onVideoCallClick` | [Call Buttons](/ui-kit/react/call-buttons) | -| CometChatIncomingCall | Incoming call notification with accept/decline | `call`, `onAccept(call)`, `onDecline(call)` | [Incoming Call](/ui-kit/react/incoming-call) | -| CometChatOutgoingCall | Outgoing call screen with cancel control | `call`, `onCloseClicked` | [Outgoing Call](/ui-kit/react/outgoing-call) | -| CometChatCallLogs | Scrollable list of call history | `callLogsRequestBuilder`, `onItemClick` | [Call Logs](/ui-kit/react/call-logs) | +| Component | Purpose | Page | +| --- | --- | --- | +| `CometChatCallButtons` | Voice and video call initiation buttons | [Call Buttons](/ui-kit/react/components/call-buttons) | +| `CometChatIncomingCall` | Incoming call notification with accept/decline | [Incoming Call](/ui-kit/react/components/incoming-call) | +| `CometChatOutgoingCall` | Outgoing call screen with cancel control | [Outgoing Call](/ui-kit/react/components/outgoing-call) | +| `CometChatCallLogs` | Scrollable list of call history | [Call Logs](/ui-kit/react/components/call-logs) | ### Search and AI -| Component | Purpose | Key Props | Page | -| --- | --- | --- | --- | -| CometChatSearch | Real-time search across conversations and messages | `onConversationClicked(conversation, searchKeyword?)`, `onMessageClicked(message, searchKeyword?)`, `uid`, `guid`, `textFormatters` | [Search](/ui-kit/react/search) | -| CometChatAIAssistantChat | AI agent chat with streaming, suggestions, history | `user`, `onSendButtonClick(message, previewMessageMode?)`, `aiAssistantTools` | [AI Assistant Chat](/ui-kit/react/ai-assistant-chat) | +| Component | Purpose | Page | +| --- | --- | --- | +| `CometChatSearch` | Unified search across conversations and messages | [Search](/ui-kit/react/components/search) | +| `CometChatAIAssistantChat` | AI agent chat with streaming, suggestions, and history | [AI Assistant](/ui-kit/react/components/ai-assistant) | -## Component API Pattern +--- -All components share a consistent API surface. +## Base Components -### Actions +Base components are imported from `@cometchat/chat-uikit-react`. They don't have individual doc pages — use the source types and Storybook for reference. + +| Component | Purpose | +| --- | --- | +| `CometChatActionBubble` | Reusable pill-shaped system message bubble (used by GroupActionBubble and CallActionBubble) | +| `CometChatActionSheet` | Bottom sheet with grouped action items | +| `CometChatAvatar` | User/group avatar with image and initials fallback | +| `CometChatButton` | Styled button with icon, text, loading, and variant support | +| `CometChatChangeScope` | Group member role/scope change selector | +| `CometChatCheckbox` | Checkbox input with label and controlled/uncontrolled support | +| `CometChatConfirmDialog` | Confirmation dialog with customizable message and buttons | +| `CometChatContextMenu` | Options menu with top-row icons and overflow dropdown | +| `CometChatConversationStarter` | AI-generated conversation starter suggestions as clickable pills | +| `CometChatConversationSummary` | AI-generated conversation summary display | +| `CometChatDate` | Formatted date/time display with temporal bucketing | +| `CometChatDeleteBubble` | "This message was deleted" placeholder bubble | +| `CometChatDownloadButton` | Download button for file and media attachments | +| `CometChatEmojiKeyboard` | Emoji picker with category tabs and search | +| `CometChatErrorBoundary` | Error isolation wrapper with fallback UI and retry | +| `CometChatFormattingToolbar` | Rich text formatting toolbar (bold, italic, lists, links, code) | +| `CometChatFullScreenViewer` | Full-screen image/media viewer with download | +| `CometChatLinkDialog` | Dialog for inserting or editing hyperlinks | +| `CometChatLinkPopover` | Popover for previewing and editing links inline | +| `CometChatListItem` | Standardized list item with avatar, title, subtitle, and tail | +| `CometChatMediaRecorder` | Audio recording with timer, preview, and submit | +| `CometChatModerationView` | Content moderation indicator and action view | +| `CometChatPopover` | Positioning utility component for popovers and dropdowns | +| `CometChatRadioButton` | Radio button input with label support | +| `CometChatSearchBar` | Search input with clear button and keyboard handling | +| `CometChatSmartReplies` | AI-powered reply suggestions as clickable chips | +| `CometChatThreadView` | Inline thread reply indicator with reply count and unread dot | +| `CometChatToast` | Toast notification for transient feedback messages | +| `CometChatTypingIndicator` | Animated typing indicator with user attribution | -Actions control component behavior. They split into two categories: +--- + +## Component API Pattern -**Predefined Actions** are built into the component and execute automatically on user interaction (e.g., clicking send dispatches the message). No configuration needed. +All components share a consistent API surface for customization. -**User-Defined Actions** are callback props that fire on specific events. Override them to customize behavior: +### Actions (Callbacks) -```tsx lines +Callback props fire on user interactions. Override them to customize behavior: + +```tsx openThreadPanel(message)} @@ -94,74 +221,67 @@ Actions control component behavior. They split into two categories: /> ``` -### Events - -Events enable decoupled communication between components. A component emits events that other parts of the application can subscribe to without direct references. +### Filters (RequestBuilder) -```tsx lines -import { CometChatMessageEvents } from "@cometchat/chat-uikit-react"; +List components accept `RequestBuilder` props to control which data loads: -const sub = CometChatMessageEvents.ccMessageSent.subscribe((message) => { - // react to sent message -}); - -// cleanup -sub?.unsubscribe(); +```tsx + ``` -Each component page documents its emitted events in the Events section. +Pass the builder instance — not the result of `.build()`. -### Filters +### View Props -List-based components accept `RequestBuilder` props to control which data loads: +View props replace the visual content inside a component slot while keeping the default behavior wired: -```tsx lines -} + headerView={} + auxiliaryButtonView={} /> ``` -### Custom View Slots +For deeper control, use compound composition to replace entire slots including their behavior. -Components expose named view slots to replace sections of the default UI: +### CSS Styling -```tsx lines -} - subtitleView={} - leadingView={} -/> -``` +Components use CSS custom properties (design tokens). Override them on the `.cometchat` root or on component-specific selectors: -### CSS Overrides - -Every component has a root CSS class (`.cometchat-`) for style customization: +```css +.cometchat { + --cometchat-primary-color: #6851d6; + --cometchat-font-family: "Inter", sans-serif; +} -```css lines -.cometchat-message-list .cometchat-text-bubble__body-text { - font-family: "SF Pro"; +.cometchat-message-list { + --cometchat-background-color-01: #fafafa; } ``` +Component class names follow BEM convention: `.cometchat-component-name__element--modifier`. + --- ## Next Steps - - Chat features included out of the box + + Customize colors, fonts, and spacing with CSS variables - - Customize colors, fonts, and styles + + Customize message rendering with the plugin system - - Add-on features like polls, stickers, and translation + + Subscribe to real-time events across components - + Task-oriented tutorials for common patterns diff --git a/ui-kit/react/v7/components/ai-assistant-chat.mdx b/ui-kit/react/components/ai-assistant-chat.mdx similarity index 98% rename from ui-kit/react/v7/components/ai-assistant-chat.mdx rename to ui-kit/react/components/ai-assistant-chat.mdx index e0b13a988..090a1c8ec 100644 --- a/ui-kit/react/v7/components/ai-assistant-chat.mdx +++ b/ui-kit/react/components/ai-assistant-chat.mdx @@ -9,7 +9,6 @@ description: "AI agent chat interface with streaming responses, suggested messag "component": "CometChatAIAssistantChat", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatAIAssistantChat } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "AI agent chat interface with streaming responses, suggested messages, tool calling, and conversation history.", "cssRootClass": ".cometchat-ai-assistant-chat", "primaryOutput": { @@ -788,13 +787,13 @@ Custom auxiliary button view for the header. Replaces the default New Chat + His ## Next Steps - + Display messages in a conversation - + Compose and send messages - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/audio-bubble.mdx b/ui-kit/react/components/audio-bubble.mdx new file mode 100644 index 000000000..789c504ae --- /dev/null +++ b/ui-kit/react/components/audio-bubble.mdx @@ -0,0 +1,138 @@ +--- +title: "Audio Bubble" +sidebarTitle: "Audio Bubble" +description: "A self-extracting bubble that renders an audio attachment with play/pause controls, a progress bar, duration, and download." +--- + + +```json +{ + "component": "CometChatAudioBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatAudioBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting audio bubble. Extracts the audio attachment and caption from a MediaMessage and renders inline playback controls.", + "cssRootClass": ".cometchat-audio-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.MediaMessage", "required": true, "note": "Drives extraction of audio attachments and caption." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "textFormatters": { "type": "CometChatTextFormatter[]" }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatAudioBubble` renders an audio attachment with inline playback. It is **self-extracting**: pass the SDK `message` and the bubble derives the audio attachment(s) and caption itself, reading alignment and localization from hooks, so it works standalone. It shows play/pause controls, a seekable progress bar, elapsed/total time, and a download control. + + +**Live Preview** — interact with the audio bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-audio--default) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatAudioBubble } from "@cometchat/chat-uikit-react"; + +function AudioMessage({ message }: { message: CometChat.MediaMessage }) { + return ; +} +``` + +--- + +## Props + +### message + +The audio message. The bubble extracts attachments and caption from it. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.MediaMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### textFormatters + +Text formatters applied to the caption (mentions, URLs). + +| | | +| --- | --- | +| Type | `CometChatTextFormatter[]` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-audio-bubble` | +| Sender / receiver | `.cometchat-audio-bubble--sender` / `.cometchat-audio-bubble--receiver` | +| Play button | `.cometchat-audio-bubble__play-button` | +| Pause button | `.cometchat-audio-bubble__pause-button` | +| Progress (foreground) | `.cometchat-audio-bubble__progress-fg` | +| Time | `.cometchat-audio-bubble__time` | +| Download button | `.cometchat-audio-bubble__download-button` | +| Caption | `.cometchat-audio-bubble__caption` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Render generic file attachments + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/components/call-action-bubble.mdx b/ui-kit/react/components/call-action-bubble.mdx new file mode 100644 index 000000000..16032d5a1 --- /dev/null +++ b/ui-kit/react/components/call-action-bubble.mdx @@ -0,0 +1,179 @@ +--- +title: "Call Action Bubble" +sidebarTitle: "Call Action Bubble" +description: "A self-extracting bubble that renders call status system messages like 'Missed Call', 'Call Ended', and 'Outgoing Call' from an SDK call message." +--- + + +```json +{ + "component": "CometChatCallActionBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatCallActionBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting bubble for call status system messages. Derives the status text, icon, and error color from the SDK call message and the logged-in user.", + "cssRootClass": ".cometchat-action-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "required": true, "note": "The call message (audio/video) in the 'call' category. Drives all extraction." }, + "className": { "type": "string", "default": "undefined", "note": "Additional CSS class for the root element" } + } + }, + "rendersThrough": "CometChatActionBubble (base primitive)", + "usedBy": ["CometChatCallActionPlugin"] +} +``` + + +## Overview + +`CometChatCallActionBubble` renders a centered, pill-shaped call status system message — "Missed Call", "Call Ended", "Outgoing Call", etc. It is **self-extracting**: pass the SDK call message and the bubble derives the status text, the status icon, and whether to use the error (missed-call) color itself, reading the logged-in user and locale from hooks. This means it works standalone — no plugin required. + +It is the component the [Call Action Plugin](/ui-kit/react/plugins/overview#built-in-plugins) forwards to, and it renders through the presentational `CometChatActionBubble` base primitive. + + +**Live Preview** — interact with the call action bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-call-action-bubble--outgoing-calls) + + + + +> The component renders nothing while the logged-in user is unavailable. + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCallActionBubble } from "@cometchat/chat-uikit-react"; + +function CallStatusMessage({ message }: { message: CometChat.BaseMessage }) { + return ; +} +``` + +--- + +## What It Derives + +The bubble inspects the call's status and whether it was initiated by the logged-in user to pick the text, icon, and color. + +### Status Text + +**Sent by the logged-in user:** + +| Call status | Text | +| --- | --- | +| `initiated` | Outgoing Call | +| `ongoing` | Answered Call | +| `ended` | Call Ended | +| `cancelled` | Cancelled Call | +| `rejected` | Rejected Call | +| `unanswered` | Unanswered Call | +| `busy` | Missed Call | + +**Received:** + +| Call status | Text | +| --- | --- | +| `initiated` | Incoming Call | +| `ongoing` | Answered Call | +| `ended` | Call Ended | +| `unanswered` / `cancelled` | Missed Call | +| `busy` | Busy Call | +| `rejected` | Rejected Call | + +All text is localized. + +### Status Icon + +| Condition | Icon class | +| --- | --- | +| Missed (received `busy` / `unanswered` / `cancelled`) | `--missed-video` / `--missed-audio` | +| Ended | `--call-ended` | +| Sent by me (other statuses) | `--outgoing-video` / `--outgoing-audio` | +| Received (other statuses) | `--incoming-video` / `--incoming-audio` | + +Missed calls additionally render in the error (red) color. Icons are rendered via CSS `mask-image` — override the mask in your own CSS to use custom icons. + +--- + +## Props + +### message + +The call message (audio/video) in the `call` category. The bubble extracts the status, icon, and text from it. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | +| Required | Yes | + +--- + +### className + +Additional CSS class name applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +The bubble renders through the `CometChatActionBubble` primitive, so it uses the action-bubble selectors. + +| Target | Selector | +| --- | --- | +| Root container | `.cometchat-action-bubble` | +| Icon element | `.cometchat-action-bubble__icon` | +| Icon (error state) | `.cometchat-action-bubble__icon--error` | +| Text element | `.cometchat-action-bubble__text` | +| Text (error state) | `.cometchat-action-bubble__text--error` | +| Missed video icon | `.cometchat-action-bubble__icon--missed-video` | +| Missed audio icon | `.cometchat-action-bubble__icon--missed-audio` | +| Outgoing video icon | `.cometchat-action-bubble__icon--outgoing-video` | +| Outgoing audio icon | `.cometchat-action-bubble__icon--outgoing-audio` | +| Incoming video icon | `.cometchat-action-bubble__icon--incoming-video` | +| Incoming audio icon | `.cometchat-action-bubble__icon--incoming-audio` | +| Call ended icon | `.cometchat-action-bubble__icon--call-ended` | + +Override a specific icon's mask: + +```css +.cometchat-action-bubble__icon--missed-video { + -webkit-mask-image: url('/my-custom-missed-video.svg'); + mask-image: url('/my-custom-missed-video.svg'); +} +``` + +--- + +## Next Steps + + + + How call status messages are resolved and rendered in the message list + + + System messages for group membership changes + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/components/call-bubble.mdx b/ui-kit/react/components/call-bubble.mdx new file mode 100644 index 000000000..8a5bd8541 --- /dev/null +++ b/ui-kit/react/components/call-bubble.mdx @@ -0,0 +1,143 @@ +--- +title: "Call Bubble" +sidebarTitle: "Call Bubble" +description: "A self-extracting bubble for direct-call / meeting messages, with a call icon, title, timestamp, and a Join button." +--- + + +```json +{ + "component": "CometChatCallBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatCallBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting call bubble for meeting / direct-call custom messages. Derives the call type, session ID, title, icon, and timestamp from the message.", + "cssRootClass": ".cometchat-call-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "required": true, "note": "The meeting/direct-call message; drives extraction." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "onJoinClick": { "type": "(sessionId: string) => void" }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatCallBubble` renders a direct-call / meeting message — a call icon, a title, a timestamp subtitle, and a **Join** button. It is **self-extracting**: pass the SDK `message` and the bubble derives the call type, session ID, title, icon, and timestamp itself, so it works standalone. Use `onJoinClick` to start the call when the user taps Join. + + +**Live Preview** — interact with the call bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-call-bubble--audio-call-outgoing) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCallBubble } from "@cometchat/chat-uikit-react"; + +function MeetingMessage({ message }: { message: CometChat.BaseMessage }) { + return ( + { + // Start / join the call session + }} + /> + ); +} +``` + +--- + +## Props + +### message + +The meeting / direct-call custom message. The bubble extracts the call type, session ID, title, icon, and timestamp from it. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### onJoinClick + +Callback when the Join button is clicked. Receives the session ID. + +| | | +| --- | --- | +| Type | `(sessionId: string) => void` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-call-bubble` | +| Incoming / outgoing | `.cometchat-call-bubble-incoming` / `.cometchat-call-bubble-outgoing` | +| Icon wrapper | `.cometchat-call-bubble__icon-wrapper` | +| Title | `.cometchat-call-bubble__body-content-title` | +| Subtitle | `.cometchat-call-bubble__body-content-subtitle` | +| Join button | `.cometchat-call-bubble__button` | + +--- + +## Next Steps + + + + Call status system messages (missed, ended, etc.) + + + Browse call history and re-initiate calls + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/components/call-buttons.mdx b/ui-kit/react/components/call-buttons.mdx new file mode 100644 index 000000000..33e323647 --- /dev/null +++ b/ui-kit/react/components/call-buttons.mdx @@ -0,0 +1,577 @@ +--- +title: "Call Buttons" +description: "Voice and video call buttons for user or group conversations, with click overrides, custom button views, and full call lifecycle handling." +--- + + +```json +{ + "component": "CometChatCallButtons", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatCallButtons } from \"@cometchat/chat-uikit-react\";", + "description": "Voice and video call initiation buttons for user or group conversations. Manages the full call lifecycle (outgoing + ongoing) internally.", + "cssRootClass": ".cometchat-call-buttons", + "primaryOutput": { + "description": "Initiates calls via the SDK and renders the outgoing/ongoing call screens" + }, + "props": { + "data": { + "user": { + "type": "CometChat.User", + "default": "undefined", + "note": "Pass either user or group, not both" + }, + "group": { + "type": "CometChat.Group", + "default": "undefined", + "note": "Pass either user or group, not both" + } + }, + "callbacks": { + "onVoiceCallClick": "(entity: CometChat.User | CometChat.Group) => void", + "onVideoCallClick": "(entity: CometChat.User | CometChat.Group) => void", + "onCallEnded": "() => void", + "onError": "((error: CometChat.CometChatException) => void) | null" + }, + "visibility": { + "hideVoiceCallButton": { "type": "boolean", "default": false }, + "hideVideoCallButton": { "type": "boolean", "default": false } + }, + "viewSlots": { + "voiceCallButtonView": "ReactNode", + "videoCallButtonView": "ReactNode" + }, + "configuration": { + "callSettingsBuilder": "(isAudioOnlyCall: boolean, user?: CometChat.User, group?: CometChat.Group) => CallSettingsBuilder", + "className": "string" + } + }, + "eventsEmitted": [ + { + "name": "ui:call/outgoing", + "payload": "{ call }", + "description": "User initiates a 1-on-1 voice/video call" + }, + { + "name": "ui:message/sent", + "payload": "{ message, status }", + "description": "Group call meeting message sent" + } + ], + "eventsReceived": [ + { + "name": "ui:call/rejected", + "payload": "{ call }", + "description": "Re-enables call buttons after the call is rejected" + }, + { + "name": "ui:call/ended", + "payload": "{}", + "description": "Resets all call state when the call ends" + } + ], + "sdkListeners": [ + "onIncomingCallReceived", + "onIncomingCallCancelled", + "onOutgoingCallAccepted", + "onOutgoingCallRejected" + ], + "compositionExample": { + "description": "Standalone call buttons or embedded in the MessageHeader auxiliary view", + "components": ["CometChatCallButtons", "CometChatOutgoingCall", "CometChatOngoingCall"], + "flow": "user/group prop -> click button -> SDK initiateCall -> CometChatOutgoingCall overlay -> onOutgoingCallAccepted -> CometChatOngoingCall" + } +} +``` + + +## Where It Fits + +`CometChatCallButtons` renders voice and video call buttons. Pass a `user` for 1-on-1 calls or a `group` for group calls. It is typically embedded in `CometChatMessageHeader`'s auxiliary view or used standalone. The component is self-contained: clicking a button initiates the call, renders `CometChatOutgoingCall` internally while waiting for an answer, transitions to `CometChatOngoingCall` on acceptance, and cleans up when the call ends. + + +**Live Preview** — interact with the call buttons component. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-calls-cometchatcallbuttons--default) + + + + +```tsx +import { useState, useEffect } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function CallButtonsDemo() { + const [chatUser, setChatUser] = useState(); + + useEffect(() => { + CometChat.getUser("uid").then((user) => setChatUser(user)); + }, []); + + return chatUser ? : null; +} + +export default CallButtonsDemo; +``` + + + + + +--- + +## Minimal Render + +```tsx +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function CallButtonsMinimal({ chatUser }: { chatUser: CometChat.User }) { + return ; +} +``` + +Root CSS class: `.cometchat-call-buttons` + +--- + +## Actions and Events + +### Callback Props + +#### onVoiceCallClick + +Overrides the default voice call initiation behavior. When set, clicking the voice button invokes this callback (with the active `user` or `group` entity) instead of initiating a call via the SDK. + +```tsx +import { useState, useEffect } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function CallButtonsVoiceOverride() { + const [chatUser, setChatUser] = useState(); + + useEffect(() => { + CometChat.getUser("uid").then((user) => setChatUser(user)); + }, []); + + return ( + { + console.log("Custom voice call logic for", entity.getName()); + }} + /> + ); +} +``` + +#### onVideoCallClick + +Overrides the default video call initiation behavior. + +```tsx +import { useState, useEffect } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function CallButtonsVideoOverride() { + const [chatUser, setChatUser] = useState(); + + useEffect(() => { + CometChat.getUser("uid").then((user) => setChatUser(user)); + }, []); + + return ( + { + console.log("Custom video call logic for", entity.getName()); + }} + /> + ); +} +``` + +#### onCallEnded + +Fires after an ongoing call session ends and the component has reset its internal state. + +```tsx +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function CallButtonsWithEndHandler({ chatUser }: { chatUser: CometChat.User }) { + return ( + { + console.log("Call ended"); + }} + /> + ); +} +``` + +#### onError + +Fires on internal errors during call initiation. + +```tsx +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; + +function CallButtonsWithError({ chatUser }: { chatUser: CometChat.User }) { + return ( + { + console.error("CallButtons error:", error); + }} + /> + ); +} +``` + +### Events Emitted + +UI events this component publishes during the call lifecycle: + +| Event | Payload | Fires when | +| --- | --- | --- | +| `ui:call/outgoing` | `{ call }` | A 1-on-1 voice/video call is initiated | +| `ui:message/sent` | `{ message, status }` | A group call meeting message is sent | + +### Events Received + +UI events this component subscribes to (published by other components): + +| Event | Payload | Behavior | +| --- | --- | --- | +| `ui:call/rejected` | `{ call }` | Clears the active call and re-enables the buttons | +| `ui:call/ended` | `{}` | Clears the active call and resets all call state | + +### SDK Listeners (Real-Time, Automatic) + +The component attaches SDK call listeners internally: + +| SDK Listener | Internal behavior | +| --- | --- | +| `onIncomingCallReceived` | Disables call buttons to prevent concurrent calls | +| `onIncomingCallCancelled` | Re-enables call buttons | +| `onOutgoingCallAccepted` | Transitions to the ongoing call screen | +| `onOutgoingCallRejected` | Clears the active call and resets state | + +--- + +## Call Settings + +Customize the calling experience via `callSettingsBuilder`. The builder is forwarded to the internal `CometChatOngoingCall` session. + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCallButtons, CometChatUIKitCalls } from "@cometchat/chat-uikit-react"; + +function CallButtonsCustomSettings({ chatUser }: { chatUser: CometChat.User }) { + return ( + + new CometChatUIKitCalls.CallSettingsBuilder() + .enableDefaultLayout(true) + .setIsAudioOnlyCall(isAudioOnlyCall) + } + /> + ); +} +``` + +--- + +## Customization + +### Custom Button Views + +Use `voiceCallButtonView` and `videoCallButtonView` to replace the default buttons while keeping the component's call lifecycle behavior intact. + +```tsx +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function CallButtonsCustomViews({ chatUser }: { chatUser: CometChat.User }) { + return ( + Voice} + videoCallButtonView={} + /> + ); +} +``` + +| Slot | Type | Replaces | +| --- | --- | --- | +| `voiceCallButtonView` | `ReactNode` | Default voice call button | +| `videoCallButtonView` | `ReactNode` | Default video call button | + +--- + +## Common Patterns + +### Voice-only call button + +```tsx +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function VoiceOnlyCallButtons({ chatUser }: { chatUser: CometChat.User }) { + return ; +} +``` + +### Group call buttons + +```tsx +import { useState, useEffect } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCallButtons } from "@cometchat/chat-uikit-react"; + +function GroupCallButtons() { + const [group, setGroup] = useState(); + + useEffect(() => { + CometChat.getGroup("guid").then((g) => setGroup(g)); + }, []); + + return group ? : null; +} +``` + +--- + +## CSS Architecture + +The component uses CSS custom properties (design tokens) provided by the UI Kit. The cascade: + +1. Global tokens set on the `.cometchat` root wrapper. +2. Component CSS (`.cometchat-call-buttons`) consumes these tokens via `var()`. +3. Overrides target `.cometchat-call-buttons` descendant selectors. + +### Key Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-call-buttons` | +| Button element | `.cometchat-call-buttons__button` | +| Button icon | `.cometchat-call-buttons__button-icon` | +| Voice button icon | `.cometchat-call-buttons__button-icon--voice` | +| Video button icon | `.cometchat-call-buttons__button-icon--video` | + +### Example: Themed call buttons + + + + + +```css +.cometchat-call-buttons { + display: flex; + padding: 8px 16px; + justify-content: center; + align-items: center; + gap: 4px; + background: #fff; +} + +.cometchat-call-buttons__button { + border-radius: 8px; + border: 1px solid #e8e8e8; + background: #edeafa; +} + +.cometchat-call-buttons__button-icon--voice, +.cometchat-call-buttons__button-icon--video { + background-color: #6852d6; +} +``` + +### Customization Matrix + +| What to change | Where | Property/API | Example | +| --- | --- | --- | --- | +| Override call initiation | Component props | `onVoiceCallClick` / `onVideoCallClick` | `onVoiceCallClick={(entity) => customCall(entity)}` | +| Hide a call button | Component props | `hideVoiceCallButton` / `hideVideoCallButton` | `hideVideoCallButton={true}` | +| Replace a button view | Component props | `voiceCallButtonView` / `videoCallButtonView` | `voiceCallButtonView={}` | +| Customize call settings | Component props | `callSettingsBuilder` | `callSettingsBuilder={(audio) => builder}` | +| Change colors, fonts, spacing | Global CSS | Target `.cometchat-call-buttons` class | `.cometchat-call-buttons__button-icon { background: red; }` | + +--- + +## Props + +All props are optional. Sorted alphabetically. + +### callSettingsBuilder + +Builder function for customizing the ongoing call settings. + +| | | +| --- | --- | +| Type | `(isAudioOnlyCall: boolean, user?: CometChat.User, group?: CometChat.Group) => CallSettingsBuilder` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class name applied to the root container. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +### group + +The group for group call buttons. Pass either `user` or `group`, not both. + +| | | +| --- | --- | +| Type | `CometChat.Group` | +| Default | `undefined` | + +--- + +### hideVideoCallButton + +Hides the video call button. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### hideVoiceCallButton + +Hides the voice call button. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### onCallEnded + +Callback fired after an ongoing call ends and the component resets its state. + +| | | +| --- | --- | +| Type | `() => void` | +| Default | `undefined` | + +--- + +### onError + +Callback fired when the component encounters an error. + +| | | +| --- | --- | +| Type | `((error: CometChat.CometChatException) => void) \| null` | +| Default | `undefined` | + +--- + +### onVideoCallClick + +Overrides the default video call initiation. Receives the active `user` or `group` entity. + +| | | +| --- | --- | +| Type | `(entity: CometChat.User \| CometChat.Group) => void` | +| Default | `undefined` | + +--- + +### onVoiceCallClick + +Overrides the default voice call initiation. Receives the active `user` or `group` entity. + +| | | +| --- | --- | +| Type | `(entity: CometChat.User \| CometChat.Group) => void` | +| Default | `undefined` | + +--- + +### user + +The user for 1-on-1 call buttons. Pass either `user` or `group`, not both. + +| | | +| --- | --- | +| Type | `CometChat.User` | +| Default | `undefined` | + +--- + +### videoCallButtonView + +Custom view that replaces the default video call button. + +| | | +| --- | --- | +| Type | `ReactNode` | +| Default | `undefined` | + +--- + +### voiceCallButtonView + +Custom view that replaces the default voice call button. + +| | | +| --- | --- | +| Type | `ReactNode` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-call-buttons` | +| Button element | `.cometchat-call-buttons__button` | +| Button icon | `.cometchat-call-buttons__button-icon` | +| Voice button icon | `.cometchat-call-buttons__button-icon--voice` | +| Video button icon | `.cometchat-call-buttons__button-icon--video` | + +--- + +## Next Steps + + + + Customize the outgoing call screen shown while waiting for an answer + + + Handle incoming call notifications with accept/decline actions + + + Browse call history and re-initiate calls + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/v7/components/call-logs.mdx b/ui-kit/react/components/call-logs.mdx similarity index 91% rename from ui-kit/react/v7/components/call-logs.mdx rename to ui-kit/react/components/call-logs.mdx index 37cc424d8..5f30f2500 100644 --- a/ui-kit/react/v7/components/call-logs.mdx +++ b/ui-kit/react/components/call-logs.mdx @@ -9,7 +9,6 @@ description: "Scrollable list of call history with call details, duration, and t "component": "CometChatCallLogs", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatCallLogs } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Scrollable list of call history with call details, duration, and the ability to initiate new calls.", "cssRootClass": ".cometchat-call-logs", "primaryOutput": { @@ -143,10 +142,7 @@ function CallHistory() { ```tsx import { useState } from "react"; -import { - CometChatCallLogs, - CometChatOutgoingCall, -} from "@cometchat/chat-uikit-react"; +import { CometChatCallLogs } from "@cometchat/chat-uikit-react"; function CallsTab() { const [selectedCall, setSelectedCall] = useState(null); @@ -162,8 +158,11 @@ function CallsTab() { }} />
-
- {selectedCall && } +
+ {selectedCall && ( + // Render your own details panel for the selected call log +
{JSON.stringify(selectedCall, null, 2)}
+ )}
); @@ -174,16 +173,17 @@ function CallsTab() { ## Filtering -Pass a custom `callLogRequestBuilder` to control which call logs are fetched. The default fetches up to 30 call logs with category "call". +Pass a custom `callLogRequestBuilder` to control which call logs are fetched. The default fetches up to 30 call logs with category "call". Refer to [CallLogRequestBuilder](/sdk/javascript/call-logs) for the full builder API. ```tsx -import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatUIKitCalls } from "@cometchat/chat-uikit-react"; ``` @@ -192,7 +192,8 @@ import { CometChat } from "@cometchat/chat-sdk-javascript"; | Recipe | Code | | --- | --- | -| Increase page size | `new CometChat.MessagesRequestBuilder().setLimit(50).setCategory("call")` | +| Increase page size | `new CometChatUIKitCalls.CallLogRequestBuilder().setLimit(50).setCallCategory("call")` | +| Calls with a specific user | `new CometChatUIKitCalls.CallLogRequestBuilder().setUid("uid").setAuthToken(authToken)` | | Only missed calls | Custom filtering via `itemView` with conditional rendering | --- @@ -474,13 +475,13 @@ Show the native scrollbar on the call logs list. ## Next Steps - + Handle incoming call notifications with accept/decline actions - + Display the outgoing call screen while waiting for the receiver to answer - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/collaborative-document-bubble.mdx b/ui-kit/react/components/collaborative-document-bubble.mdx new file mode 100644 index 000000000..daeeef335 --- /dev/null +++ b/ui-kit/react/components/collaborative-document-bubble.mdx @@ -0,0 +1,149 @@ +--- +title: "Collaborative Document Bubble" +sidebarTitle: "Collaborative Document Bubble" +description: "A self-extracting bubble that renders a collaborative document card with a banner and an 'Open Document' button." +--- + + +```json +{ + "component": "CometChatCollaborativeDocumentBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatCollaborativeDocumentBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting collaborative document bubble. Extracts the document URL from the message metadata and opens it on click.", + "cssRootClass": ".cometchat-collaborative-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "required": true, "note": "Drives extraction of the document URL." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "onButtonClick": { "type": "(url: string) => void", "note": "Defaults to window.open." }, + "disabled": { "type": "boolean", "default": false }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatCollaborativeDocumentBubble` renders a collaborative document card — a banner image, a title, a subtitle, and an "Open Document" button. It is **self-extracting**: pass the SDK `message` and the bubble reads the document URL from the message's extension metadata (`@injected.extensions.document.document_url`), so it works standalone. Clicking the button opens the document (by default in a new window). + + +**Live Preview** — interact with the collaborative document bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--collaborative-document-message) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCollaborativeDocumentBubble } from "@cometchat/chat-uikit-react"; + +function DocumentMessage({ message }: { message: CometChat.BaseMessage }) { + return ; +} +``` + +--- + +## Props + +### message + +The collaborative-document message. The bubble extracts the URL from its metadata. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### onButtonClick + +Click handler for the action button. Receives the document URL. Defaults to `window.open`. + +| | | +| --- | --- | +| Type | `(url: string) => void` | +| Default | `window.open` | + +--- + +### disabled + +Disable the action button (e.g. for a thread header preview). + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-collaborative-bubble` | +| Document modifier | `.cometchat-collaborative-bubble--document` | +| Incoming / outgoing | `.cometchat-collaborative-bubble--incoming` / `.cometchat-collaborative-bubble--outgoing` | +| Banner image | `.cometchat-collaborative-bubble__banner-image` | +| Title | `.cometchat-collaborative-bubble__body-content-name` | +| Subtitle | `.cometchat-collaborative-bubble__body-content-description` | +| Open button | `.cometchat-collaborative-bubble__button` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Render collaborative whiteboard messages + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/components/collaborative-whiteboard-bubble.mdx b/ui-kit/react/components/collaborative-whiteboard-bubble.mdx new file mode 100644 index 000000000..7ad4dd731 --- /dev/null +++ b/ui-kit/react/components/collaborative-whiteboard-bubble.mdx @@ -0,0 +1,149 @@ +--- +title: "Collaborative Whiteboard Bubble" +sidebarTitle: "Collaborative Whiteboard Bubble" +description: "A self-extracting bubble that renders a collaborative whiteboard card with a banner and an 'Open Whiteboard' button." +--- + + +```json +{ + "component": "CometChatCollaborativeWhiteboardBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatCollaborativeWhiteboardBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting collaborative whiteboard bubble. Extracts the board URL from the message metadata and opens it on click.", + "cssRootClass": ".cometchat-collaborative-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "required": true, "note": "Drives extraction of the board URL." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "onButtonClick": { "type": "(url: string) => void", "note": "Defaults to window.open." }, + "disabled": { "type": "boolean", "default": false }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatCollaborativeWhiteboardBubble` renders a collaborative whiteboard card — a banner image, a title, a subtitle, and an "Open Whiteboard" button. It is **self-extracting**: pass the SDK `message` and the bubble reads the board URL from the message's extension metadata (`@injected.extensions.whiteboard.board_url`), so it works standalone. Clicking the button opens the whiteboard (by default in a new window). + + +**Live Preview** — interact with the collaborative whiteboard bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--collaborative-whiteboard-message) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatCollaborativeWhiteboardBubble } from "@cometchat/chat-uikit-react"; + +function WhiteboardMessage({ message }: { message: CometChat.BaseMessage }) { + return ; +} +``` + +--- + +## Props + +### message + +The collaborative-whiteboard message. The bubble extracts the URL from its metadata. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### onButtonClick + +Click handler for the action button. Receives the board URL. Defaults to `window.open`. + +| | | +| --- | --- | +| Type | `(url: string) => void` | +| Default | `window.open` | + +--- + +### disabled + +Disable the action button (e.g. for a thread header preview). + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-collaborative-bubble` | +| Whiteboard modifier | `.cometchat-collaborative-bubble--whiteboard` | +| Incoming / outgoing | `.cometchat-collaborative-bubble--incoming` / `.cometchat-collaborative-bubble--outgoing` | +| Banner image | `.cometchat-collaborative-bubble__banner-image` | +| Title | `.cometchat-collaborative-bubble__body-content-name` | +| Subtitle | `.cometchat-collaborative-bubble__body-content-description` | +| Open button | `.cometchat-collaborative-bubble__button` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Render collaborative document messages + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/v7/components/conversations.mdx b/ui-kit/react/components/conversations.mdx similarity index 93% rename from ui-kit/react/v7/components/conversations.mdx rename to ui-kit/react/components/conversations.mdx index de328d2f4..37424cbd1 100644 --- a/ui-kit/react/v7/components/conversations.mdx +++ b/ui-kit/react/components/conversations.mdx @@ -9,7 +9,6 @@ description: "Scrollable list of recent one-on-one and group conversations for t "component": "CometChatConversations", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatConversations } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Scrollable list of recent one-on-one and group conversations for the logged-in user with real-time updates.", "cssRootClass": ".cometchat-conversations", "primaryOutput": { @@ -77,7 +76,8 @@ description: "Scrollable list of recent one-on-one and group conversations for t "searchView": "ReactNode", "loadingView": "ReactNode", "emptyView": "ReactNode", - "errorView": "ReactNode" + "errorView": "ReactNode", + "options": "(conversation: CometChat.Conversation) => CometChatConversationOption[]" } }, "events": [ @@ -244,7 +244,7 @@ function ChatApp() { ## Filtering -Pass a `CometChat.ConversationsRequestBuilder` to `conversationsRequestBuilder` to control which conversations load. Pass the builder instance — not the result of `.build()`. +Pass a `CometChat.ConversationsRequestBuilder` to `conversationsRequestBuilder` to control which conversations load. Pass the builder instance — not the result of `.build()`. Refer to [ConversationsRequestBuilder](/sdk/javascript/retrieve-conversations) for the full builder API. ```tsx
+#### options + +Replace the context menu / hover actions on each conversation item. + +Default: + + + + + +Customized: + + + + + + + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatConversations, + type CometChatConversationOption, +} from "@cometchat/chat-uikit-react"; + +function CustomOptionsConversations() { + const getOptions = (conversation: CometChat.Conversation): CometChatConversationOption[] => [ + { + id: "delete", + title: "Delete", + onClick: (conv) => { /* delete logic */ }, + }, + { + id: "mute", + title: "Mute Notification", + onClick: (conv) => { /* mute logic */ }, + }, + { + id: "unread", + title: "Mark as Unread", + onClick: (conv) => { /* mark unread logic */ }, + }, + { + id: "block", + title: "Block", + onClick: (conv) => { /* block logic */ }, + }, + ]; + + return ; +} +``` + + +```css +.cometchat-conversations .cometchat-menu-list__main-menu-item-icon-delete { + background: red; +} + +.cometchat-conversations .cometchat-menu-list__sub-menu { + background: transparent; + box-shadow: none; +} +``` + + + ### Compound Composition For full layout control, use sub-components. Omit any sub-component to hide it: @@ -1027,6 +1094,36 @@ Custom sound URL to play when new messages arrive (replaces the built-in sound). --- +### options + +Function that returns context menu options for each conversation item (shown on hover/swipe). + +| | | +| --- | --- | +| Type | `(conversation: CometChat.Conversation) => CometChatConversationOption[]` | +| Default | Default options (delete) | + +```tsx + [ + { + id: "pin", + title: "Pin", + iconURL: pinIcon, + onClick: (conv) => pinConversation(conv), + }, + { + id: "mute", + title: "Mute", + iconURL: muteIcon, + onClick: (conv) => muteConversation(conv), + }, + ]} +/> +``` + +--- + ### onItemClick Callback when a conversation item is clicked. @@ -1171,16 +1268,16 @@ Overrides survive component updates because the component never sets inline styl ## Next Steps - + Browse and select users for new conversations - + Display messages for the selected conversation - + Search across conversations and messages - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/delete-bubble.mdx b/ui-kit/react/components/delete-bubble.mdx new file mode 100644 index 000000000..87511df46 --- /dev/null +++ b/ui-kit/react/components/delete-bubble.mdx @@ -0,0 +1,117 @@ +--- +title: "Delete Bubble" +sidebarTitle: "Delete Bubble" +description: "A presentational bubble that renders a 'This message was deleted' placeholder." +--- + + +```json +{ + "component": "CometChatDeleteBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatDeleteBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Presentational placeholder bubble for deleted messages.", + "cssRootClass": ".cometchat-delete-bubble", + "props": { + "data": { + "isSentByMe": { "type": "boolean", "note": "Affects sent vs received styling." }, + "text": { "type": "string", "note": "Defaults to localized \"This message was deleted\"." }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatDeleteBubble` renders the placeholder shown in place of a deleted message — italic, muted text reading "This message was deleted". It is a presentational component: pass `isSentByMe` for sent-vs-received styling and an optional `text` override. The [Delete Plugin](/ui-kit/react/plugins/overview#built-in-plugins) renders it automatically for any message whose `getDeletedAt()` is non-null. + + +**Live Preview** — interact with the delete bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/base-elements-delete-bubble--default) + + + + +--- + +## Usage + +```tsx +import { CometChatDeleteBubble } from "@cometchat/chat-uikit-react"; + +function DeletedMessage() { + return ; +} +``` + +--- + +## Props + +### isSentByMe + +Whether the deleted message was sent by the logged-in user. Affects styling. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `undefined` | + +--- + +### text + +Optional custom text override. Defaults to the localized "This message was deleted". + +| | | +| --- | --- | +| Type | `string` | +| Default | localized default | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-delete-bubble` | +| Sender / receiver | `.cometchat-delete-bubble--sender` / `.cometchat-delete-bubble--receiver` | +| Icon | `.cometchat-delete-bubble__icon` | +| Placeholder text | `.cometchat-delete-bubble__text` | + +--- + +## Next Steps + + + + How deleted messages are resolved and rendered + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/components/file-bubble.mdx b/ui-kit/react/components/file-bubble.mdx new file mode 100644 index 000000000..eef4c8d72 --- /dev/null +++ b/ui-kit/react/components/file-bubble.mdx @@ -0,0 +1,137 @@ +--- +title: "File Bubble" +sidebarTitle: "File Bubble" +description: "A self-extracting bubble that renders a file attachment with its name, size, type icon, and a download action." +--- + + +```json +{ + "component": "CometChatFileBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatFileBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting file bubble. Extracts the file attachment (url, name, size, extension) and caption from a MediaMessage.", + "cssRootClass": ".cometchat-file-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.MediaMessage", "required": true, "note": "Drives extraction of the file attachment and caption." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "textFormatters": { "type": "CometChatTextFormatter[]" }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatFileBubble` renders a file attachment. It is **self-extracting**: pass the SDK `message` and the bubble derives the file's URL, name, size, and extension (plus any caption) itself, so it works standalone. It shows a type icon, the file name and size, and a download control. + + +**Live Preview** — interact with the file bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-file--default) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatFileBubble } from "@cometchat/chat-uikit-react"; + +function FileMessage({ message }: { message: CometChat.MediaMessage }) { + return ; +} +``` + +--- + +## Props + +### message + +The file message. The bubble extracts the attachment (url, name, size, extension) and caption from it. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.MediaMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### textFormatters + +Text formatters applied to the extracted caption. + +| | | +| --- | --- | +| Type | `CometChatTextFormatter[]` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-file-bubble` | +| Sender / receiver | `.cometchat-file-bubble--sender` / `.cometchat-file-bubble--receiver` | +| Type icon | `.cometchat-file-bubble__icon` | +| File name | `.cometchat-file-bubble__filename` | +| File size | `.cometchat-file-bubble__filesize` | +| Download | `.cometchat-file-bubble__download` | +| Caption | `.cometchat-file-bubble__caption` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Render audio attachments + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/components/flag-message-dialog.mdx b/ui-kit/react/components/flag-message-dialog.mdx new file mode 100644 index 000000000..b5d5ef220 --- /dev/null +++ b/ui-kit/react/components/flag-message-dialog.mdx @@ -0,0 +1,376 @@ +--- +title: "Flag Message Dialog" +sidebarTitle: "Flag Message Dialog" +description: "A dialog for reporting inappropriate messages with reason selection, an optional remark, and submission handling." +--- + + +```json +{ + "component": "CometChatFlagMessageDialog", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatFlagMessageDialog } from \"@cometchat/chat-uikit-react\";", + "description": "Dialog for reporting/flagging an inappropriate message. Fetches flag reasons from the SDK, captures an optional remark, and submits the report.", + "cssRootClass": ".cometchat-flag-message-dialog", + "primaryOutput": { + "prop": "onSubmit", + "type": "(messageId: string, reasonId: string, remark?: string) => Promise" + }, + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "note": "Required. The message being flagged." }, + "isOpen": { "type": "boolean", "note": "When provided, the dialog is controlled." } + }, + "callbacks": { + "onSubmit": { "type": "(messageId: string, reasonId: string, remark?: string) => Promise", "note": "Return true to close, false to keep open and show an error." }, + "onClose": { "type": "() => void" }, + "onError": { "type": "((error: CometChat.CometChatException) => void) | null" } + }, + "config": { + "closeOnOutsideClick": { "type": "boolean", "default": true }, + "className": { "type": "string" } + } + }, + "types": { + "CometChatFlagMessageDialogRootProps": "Root overlay props", + "CometChatFlagMessageDialogHeaderProps": "Header sub-component props", + "CometChatFlagMessageDialogReasonsProps": "Reasons list sub-component props", + "CometChatFlagMessageDialogRemarkProps": "Remark input sub-component props", + "CometChatFlagMessageDialogActionsProps": "Actions (cancel/submit) sub-component props", + "CometChatFlagMessageDialogContextValue": "Full context value" + } +} +``` + + +## Where It Fits + +`CometChatFlagMessageDialog` is a modal dialog that lets a user report an inappropriate message. When it opens, it fetches the available report reasons from the SDK (`CometChat.getFlagReasons`), renders them as a single-select list, captures an optional free-text remark, and—on submit—invokes your `onSubmit` handler with the message ID, the selected reason ID, and the remark. + + +**Live Preview** — interact with the flag message dialog. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-misc-flag-message-dialog--default) + + + + +Use it when a user chooses "Report" on a message. The parent owns the open state and decides what happens with the report inside `onSubmit` (e.g., calling a moderation backend). + +```tsx lines +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatFlagMessageDialog } from "@cometchat/chat-uikit-react"; + +function FlagMessageExample({ message }: { message: CometChat.BaseMessage }) { + const [open, setOpen] = useState(false); + + const handleSubmit = async ( + messageId: string, + reasonId: string, + remark?: string + ) => { + // Report the message to your backend / moderation service. + console.log("Reporting", { messageId, reasonId, remark }); + return true; // return false to keep the dialog open and show an error + }; + + return ( + <> + + + setOpen(false)} + onSubmit={handleSubmit} + /> + + ); +} +``` + +## Minimal Render + +```tsx lines +import { CometChatFlagMessageDialog } from "@cometchat/chat-uikit-react"; + +function Demo({ message }) { + return ; +} +``` + +Root CSS class: `.cometchat-flag-message-dialog` + +## Sub-Components + +`CometChatFlagMessageDialog` is a compound component with these sub-components: + +| Sub-Component | Purpose | +| --- | --- | +| `Root` | Overlay and context provider. Manages open/close state, focus trap, outside-click/Escape, reason fetching, and submission. Renders the default layout when no children are passed. | +| `Header` | Title and subtitle. Defaults to a localized "Report a Message" heading. | +| `Reasons` | Single-select list of report reasons fetched from the SDK. | +| `Remark` | Optional free-text input with a character counter (default max 500). | +| `Actions` | Cancel and submit (Report) buttons. | + +### Custom Layout + +Compose sub-components to customize the layout — for example, omit `Remark` to collect only a reason: + +```tsx lines + setOpen(false)} + onSubmit={handleSubmit} +> + + + + + +``` + +### Custom Header + +Pass `title`/`subtitle` for text changes, or `children` for fully custom header content: + +```tsx lines + + +
+

Custom Report Header

+

This uses children instead of title/subtitle props.

+
+
+ + +
+``` + +Sub-component props: + +| Sub-component | Prop | Type | Default | +| --- | --- | --- | --- | +| `Header` | `title` | `string` | `"Report a Message"` (localized) | +| `Header` | `subtitle` | `string` | Localized description | +| `Remark` | `label` | `string` | `"Reason"` (localized) | +| `Remark` | `placeholder` | `string` | Localized placeholder | +| `Remark` | `maxLength` | `number` | `500` | +| `Actions` | `cancelText` | `string` | `"Cancel"` (localized) | +| `Actions` | `submitText` | `string` | `"Report"` (localized) | + +Every sub-component also accepts `children` (where applicable) and a `className`. + +## Actions and Events + +### Callback Props + +#### onSubmit + +Called when the user clicks Report with a reason selected. Receives the message ID, the selected reason ID, and the optional remark. Return `true` to close the dialog, or `false` to keep it open and show an inline error. + +```tsx lines + setOpen(false)} + onSubmit={async (messageId, reasonId, remark) => { + const ok = await reportToBackend({ messageId, reasonId, remark }); + return ok; + }} +/> +``` + +#### onClose + +Called when the dialog requests to close — via the cancel button, the Escape key, or an outside click. In controlled mode you own the open state, so update it here. + +```tsx lines + setOpen(false)} +/> +``` + +#### onError + +Called when an SDK error occurs (e.g., while fetching reasons or during submission). + +```tsx lines + setOpen(false)} + onError={(error) => console.error("Flag message error:", error)} +/> +``` + +## Behavior Details + +### Controlled vs Uncontrolled + +- **Controlled** — pass `isOpen` and `onClose`. You own the open state (recommended for most apps). +- **Uncontrolled** — omit `isOpen`. The dialog manages its own internal open state and closes itself on cancel, Escape, outside click, or a successful submit. + +### Reason Fetching + +On open, the dialog calls `CometChat.getFlagReasons()` and renders the result as a single-select list. While loading, a loading state is shown. If the call fails, `onError` is invoked. + +### Remark + +The remark is optional. It is trimmed before submission, and an empty remark is passed as `undefined` to `onSubmit`. A character counter enforces `maxLength` (default 500). + +### Submission + +The submit button is disabled until a reason is selected. On submit: +1. `onSubmit` is awaited. +2. Returning `false` (or throwing) keeps the dialog open and shows an inline error banner. +3. Returning `true` closes the dialog. + +### Focus & Keyboard + +The Root traps focus within the dialog while open, moves focus to the first focusable element on open, restores focus to the previously focused element on close, cycles focus with `Tab` / `Shift+Tab`, and closes on `Escape`. + +## CSS Architecture + +The component uses CSS custom properties provided by the UI Kit. + +### Key Selectors + +| Target | Selector | +| --- | --- | +| Backdrop | `.cometchat-flag-message-dialog__backdrop` | +| Dialog container | `.cometchat-flag-message-dialog` | +| Error banner | `.cometchat-flag-message-dialog__error` | +| Header | `.cometchat-flag-message-dialog__header` | +| Header title | `.cometchat-flag-message-dialog__header-title` | +| Header subtitle | `.cometchat-flag-message-dialog__header-subtitle` | +| Reasons list | `.cometchat-flag-message-dialog__reasons` | +| Reason item | `.cometchat-flag-message-dialog__reason` | +| Reason item (selected) | `.cometchat-flag-message-dialog__reason--selected` | +| Reasons loading | `.cometchat-flag-message-dialog__reasons-loading` | +| Remark wrapper | `.cometchat-flag-message-dialog__remark` | +| Remark label | `.cometchat-flag-message-dialog__remark-label` | +| Remark input | `.cometchat-flag-message-dialog__remark-input` | +| Remark counter | `.cometchat-flag-message-dialog__remark-counter` | +| Remark counter (at limit) | `.cometchat-flag-message-dialog__remark-counter--limit` | +| Actions container | `.cometchat-flag-message-dialog__actions` | +| Cancel button | `.cometchat-flag-message-dialog__actions-cancel` | +| Submit button | `.cometchat-flag-message-dialog__actions-submit` | + +### Example: Custom styling + +```css lines title="App.css" +.cometchat-flag-message-dialog { + --cometchat-background-color-01: #ffffff; + --cometchat-text-color-primary: #141414; +} + +.cometchat-flag-message-dialog__reason--selected { + border-color: var(--my-brand-color); +} + +.cometchat-flag-message-dialog__actions-submit { + background: var(--my-brand-color); +} +``` + +## Props + +The `message` prop is required. All other props are optional. The props below belong to `Root` (and to the flat `CometChatFlagMessageDialog`, which forwards them). + +--- + +### message + +The message being flagged. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | +| Default | — | + +--- + +### isOpen + +Whether the dialog is open. When provided, the component is controlled. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `undefined` (uncontrolled) | + +--- + +### onClose + +Callback invoked when the dialog requests to close (outside click, Escape, or cancel). + +| | | +| --- | --- | +| Type | `() => void` | +| Default | `undefined` | + +--- + +### closeOnOutsideClick + +Whether clicking outside the dialog closes it. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `true` | + +--- + +### onSubmit + +Custom submit handler. Receives the message ID, the selected reason ID, and the optional remark. Return `true` on success (the dialog closes) or `false` to keep it open and show an error. + +| | | +| --- | --- | +| Type | `(messageId: string, reasonId: string, remark?: string) => Promise` | +| Default | `undefined` | + +--- + +### onError + +Callback when an SDK error occurs. + +| | | +| --- | --- | +| Type | `((error: CometChat.CometChatException) => void) \| null` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class applied to the dialog backdrop. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +## Accessibility + +- Root has `role="dialog"` with `aria-modal="true"`. +- The dialog is labelled by its title (`aria-labelledby`) and described by its subtitle (`aria-describedby`). +- Focus moves into the dialog on open and is restored to the previously focused element on close. +- Focus is trapped within the dialog; `Tab` / `Shift+Tab` cycle through focusable elements. +- `Escape` closes the dialog. +- The error banner uses `role="alert"` with `aria-live="assertive"`. diff --git a/ui-kit/react/components/group-action-bubble.mdx b/ui-kit/react/components/group-action-bubble.mdx new file mode 100644 index 000000000..64b9882e5 --- /dev/null +++ b/ui-kit/react/components/group-action-bubble.mdx @@ -0,0 +1,132 @@ +--- +title: "Group Action Bubble" +sidebarTitle: "Group Action Bubble" +description: "A self-extracting bubble that renders group action system messages like 'Alice joined' and 'Bob was kicked' from an SDK group-action message." +--- + + +```json +{ + "component": "CometChatGroupActionBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatGroupActionBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting bubble for group membership system messages. Derives the localized action text from the SDK group-action message.", + "cssRootClass": ".cometchat-action-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "required": true, "note": "The group-action message (member joined/left/added/kicked/banned/scope change). Drives all extraction." }, + "className": { "type": "string", "default": "undefined", "note": "Additional CSS class for the root element" } + } + }, + "rendersThrough": "CometChatActionBubble (base primitive)", + "usedBy": ["CometChatGroupActionPlugin"] +} +``` + + +## Overview + +`CometChatGroupActionBubble` renders a centered, pill-shaped group action system message — "Alice joined", "Admin kicked Bob", "Admin made Bob a moderator", etc. It is **self-extracting**: pass the SDK group-action message and the bubble derives the localized action text itself (via the shared action-text utility), reading the locale from hooks. This means it works standalone — no plugin required. + +It is the component the [Group Action Plugin](/ui-kit/react/plugins/overview#built-in-plugins) forwards to, and it renders through the presentational `CometChatActionBubble` base primitive. Group action bubbles have no icon and no sender attribution. + + +**Live Preview** — interact with the group action bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-group-action-bubble--all-actions) + + + + +> The component renders nothing if the derived action text is empty. + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatGroupActionBubble } from "@cometchat/chat-uikit-react"; + +function GroupActionMessage({ message }: { message: CometChat.BaseMessage }) { + return ; +} +``` + +--- + +## Supported Actions + +The bubble derives localized text for each group membership change: + +| Action | Example text | +| --- | --- | +| Member joined | "Alice joined" | +| Member left | "Bob left" | +| Member kicked | "Admin kicked Bob" | +| Member banned | "Admin banned Charlie" | +| Member unbanned | "Admin unbanned Charlie" | +| Scope changed | "Admin made Bob a moderator" | +| Member added | "Admin added Dave" | + +--- + +## Props + +### message + +The group-action message (member joined / left / added / kicked / banned / scope change). The bubble extracts the localized action text from it. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | +| Required | Yes | + +--- + +### className + +Additional CSS class name applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +The bubble renders through the `CometChatActionBubble` primitive, so it uses the action-bubble selectors. + +| Target | Selector | +| --- | --- | +| Root container | `.cometchat-action-bubble` | +| Action text | `.cometchat-action-bubble__text` | + +--- + +## Next Steps + + + + How group membership messages are resolved and rendered in the message list + + + System messages for call status + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/v7/components/group-members.mdx b/ui-kit/react/components/group-members.mdx similarity index 94% rename from ui-kit/react/v7/components/group-members.mdx rename to ui-kit/react/components/group-members.mdx index 7230f929d..385e4febb 100644 --- a/ui-kit/react/v7/components/group-members.mdx +++ b/ui-kit/react/components/group-members.mdx @@ -9,7 +9,6 @@ description: "Scrollable list of members for a specific group with role-based ac "component": "CometChatGroupMembers", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatGroupMembers } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Scrollable list of members for a specific group with role-based actions like kick, ban, and scope change.", "cssRootClass": ".cometchat-group-members", "primaryOutput": { @@ -93,6 +92,11 @@ description: "Scrollable list of members for a specific group with role-based ac "name": "ui:group/member-scope-changed", "payload": "{ group: CometChat.Group, user: CometChat.User, newScope: string }", "description": "Updates the member's scope/role display" + }, + { + "name": "ui:group/ownership-changed", + "payload": "{ group: CometChat.Group, newOwner: CometChat.User, previousOwnerUid: string }", + "description": "Updates new owner's scope to owner and demotes previous owner to admin" } ], "sdkListeners": [ @@ -169,8 +173,8 @@ import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; function MemberList({ group }: { group: CometChat.Group }) { return ( - - + + @@ -221,7 +225,7 @@ function GroupDetailsPanel({ group }: { group: CometChat.Group }) { ## Filtering -Pass a `CometChat.GroupMembersRequestBuilder` to `groupMemberRequestBuilder` to control which members load. Pass the builder instance — not the result of `.build()`. +Pass a `CometChat.GroupMembersRequestBuilder` to `groupMemberRequestBuilder` to control which members load. Pass the builder instance — not the result of `.build()`. Refer to [GroupMembersRequestBuilder](/sdk/javascript/retrieve-group-members) for the full builder API. ```tsx -View slot props (`headerView`, `searchView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. In compound composition mode, use the corresponding sub-components directly. +View slot props (`headerView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. The search input is the `SearchBar` sub-component (with a `placeholder` prop), not a view slot. In compound composition mode, use the corresponding sub-components directly. --- @@ -906,16 +911,16 @@ Callback when the back button in the header is clicked. ## Next Steps - + Browse and select groups - + View and unban banned group members - + Add new members to a group - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/v7/components/groups.mdx b/ui-kit/react/components/groups.mdx similarity index 95% rename from ui-kit/react/v7/components/groups.mdx rename to ui-kit/react/components/groups.mdx index faa878a6a..c9595f707 100644 --- a/ui-kit/react/v7/components/groups.mdx +++ b/ui-kit/react/components/groups.mdx @@ -9,7 +9,6 @@ description: "Searchable, scrollable list of groups with selection support and r "component": "CometChatGroups", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatGroups } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Searchable, scrollable list of groups with selection support and real-time membership updates.", "cssRootClass": ".cometchat-groups", "primaryOutput": { @@ -111,7 +110,7 @@ description: "Searchable, scrollable list of groups with selection support and r }, { "name": "ui:group/ownership-changed", - "payload": "{ group: CometChat.Group }", + "payload": "{ group: CometChat.Group, newOwner: CometChat.User, previousOwnerUid: string }", "description": "Updates the group" } ], @@ -237,7 +236,7 @@ function GroupChat() { ## Filtering -Pass a `CometChat.GroupsRequestBuilder` to `groupsRequestBuilder` to control which groups load. Pass the builder instance — not the result of `.build()`. +Pass a `CometChat.GroupsRequestBuilder` to `groupsRequestBuilder` to control which groups load. Pass the builder instance — not the result of `.build()`. Refer to [GroupsRequestBuilder](/sdk/javascript/retrieve-groups) for the full builder API. ```tsx -View slot props (`headerView`, `searchView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. In compound composition mode, use the corresponding sub-components directly. +View slot props (`headerView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. The search input is the `SearchBar` sub-component (with a `placeholder` prop), not a view slot. In compound composition mode, use the corresponding sub-components directly. --- @@ -781,16 +780,16 @@ Callback when the group list is empty after the initial fetch completes. ## Next Steps - + View and manage members of a group - + View recent conversations including group chats - + Display messages for the selected group - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/image-bubble.mdx b/ui-kit/react/components/image-bubble.mdx new file mode 100644 index 000000000..31f9ea946 --- /dev/null +++ b/ui-kit/react/components/image-bubble.mdx @@ -0,0 +1,165 @@ +--- +title: "Image Bubble" +sidebarTitle: "Image Bubble" +description: "A self-extracting bubble that renders one or more image attachments with grid layouts, a caption, and a fullscreen viewer." +--- + + +```json +{ + "component": "CometChatImageBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatImageBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting image bubble. Extracts image attachments and caption from a MediaMessage; supports single/grid layouts and a fullscreen viewer.", + "cssRootClass": ".cometchat-image-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.MediaMessage", "required": true, "note": "Drives extraction of attachments and caption." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "textFormatters": { "type": "CometChatTextFormatter[]" }, + "placeholderImage": { "type": "string" }, + "onImageClicked": { "type": "(attachment, index) => void" }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatImageBubble` renders the image attachment(s) of a media message. It is **self-extracting**: pass the SDK `message` and the bubble derives its attachments, caption, and alignment itself, so it works standalone. + +It supports multiple images with automatic layouts (single, grid, 2×2, and an overflow tile for extra images) and opens a fullscreen viewer when an image is clicked. + + +**Live Preview** — interact with the image bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-image--default) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatImageBubble } from "@cometchat/chat-uikit-react"; + +function ImageMessage({ message }: { message: CometChat.MediaMessage }) { + return ; +} +``` + +--- + +## Props + +### message + +The image message. The bubble extracts its attachments and caption. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.MediaMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### textFormatters + +Text formatters for caption rendering (mentions, URLs). + +| | | +| --- | --- | +| Type | `CometChatTextFormatter[]` | +| Default | `undefined` | + +--- + +### placeholderImage + +Custom placeholder image URL shown while the image loads. Falls back to a default photo icon. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +### onImageClicked + +Fires when an image is clicked (in addition to opening the fullscreen viewer). + +| | | +| --- | --- | +| Type | `(attachment: CometChatImageBubbleAttachment, index: number) => void` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-image-bubble` | +| Incoming / outgoing | `.cometchat-image-bubble--incoming` / `.cometchat-image-bubble--outgoing` | +| Single image | `.cometchat-image-bubble--single` | +| Container | `.cometchat-image-bubble__container` | +| Grid | `.cometchat-image-bubble__grid` | +| Image | `.cometchat-image-bubble__image` | +| Overflow overlay | `.cometchat-image-bubble__overflow-overlay` | +| Placeholder | `.cometchat-image-bubble__placeholder` | +| Caption | `.cometchat-image-bubble__caption` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Render video attachments + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/v7/components/incoming-call.mdx b/ui-kit/react/components/incoming-call.mdx similarity index 96% rename from ui-kit/react/v7/components/incoming-call.mdx rename to ui-kit/react/components/incoming-call.mdx index db57f429c..31ae55f5d 100644 --- a/ui-kit/react/v7/components/incoming-call.mdx +++ b/ui-kit/react/components/incoming-call.mdx @@ -9,7 +9,6 @@ description: "Displays an incoming call notification with caller info, accept/de "component": "CometChatIncomingCall", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatIncomingCall } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Displays an incoming call notification with caller info, accept/decline buttons, and transitions to the ongoing call screen.", "cssRootClass": ".cometchat-incoming-call", "primaryOutput": { @@ -100,7 +99,7 @@ The component handles: > **Placement:** Render `CometChatIncomingCall` at your app's root level. It manages its own visibility internally and only appears when an incoming call is detected. -> **Note:** In v7, `CallButtons` is not a standalone component — call button functionality is part of `CometChatMessageHeader`. Use `CometChatIncomingCall` separately to handle the incoming call notification flow. +> **Note:** Call **initiation** buttons are provided by the standalone [`CometChatCallButtons`](/ui-kit/react/components/call-buttons) component (also rendered automatically inside `CometChatMessageHeader`). `CometChatIncomingCall` is separate — it handles the incoming call notification flow. --- @@ -499,13 +498,13 @@ Additional CSS class name applied to the root element. ## Next Steps - + Display the outgoing call screen while waiting for the receiver to answer - + Browse call history and re-initiate calls - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/message-bubble.mdx b/ui-kit/react/components/message-bubble.mdx new file mode 100644 index 000000000..ff35e8223 --- /dev/null +++ b/ui-kit/react/components/message-bubble.mdx @@ -0,0 +1,317 @@ +--- +title: "Message Bubble" +description: "A shared wrapper component that renders all message types with common chrome — avatar, sender name, bubble background, timestamp, receipts, thread replies, and context menu." +--- + + +```json +{ + "component": "CometChatMessageBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatMessageBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Layout shell that wraps plugin-rendered bubble content with shared chrome — avatar, sender name, bubble background, timestamp, receipts, thread replies, reactions, and context menu.", + "cssRootClass": ".cometchat-message-bubble", + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "required": true }, + "alignment": { "type": "'left' | 'right' | 'center'", "required": true }, + "contentView": { "type": "ReactNode", "required": true, "note": "Inner content from the plugin's renderBubble()." }, + "group": { "type": "CometChat.Group" }, + "options": { "type": "CometChatMessageOption[]" }, + "quickOptionsCount": { "type": "number", "default": 2 } + }, + "visibility": { + "hideAvatar": { "type": "boolean", "default": false }, + "forceShowAvatar": { "type": "boolean", "default": false }, + "hideSenderName": { "type": "boolean", "default": false }, + "hideTimestamp": { "type": "boolean", "default": false }, + "hideThreadView": { "type": "boolean", "default": false }, + "hideReceipts": { "type": "boolean", "note": "Reads from GlobalConfig if not set." }, + "showError": { "type": "boolean", "default": false }, + "disableInteraction": { "type": "boolean", "default": false } + }, + "config": { + "messageSentAtDateTimeFormat": { "type": "CometChatDateFormatConfig" }, + "isSelected": { "type": "boolean" }, + "ariaPosinset": { "type": "number" }, + "ariaSetsize": { "type": "number" }, + "className": { "type": "string" }, + "setRef": { "type": "Ref" }, + "includeBottomViewHeight": { "type": "boolean", "default": false }, + "toggleOptionsVisibility": { "type": "boolean" } + }, + "viewSlots": { + "leadingView": "((message) => ReactNode) | null", + "headerView": "((message) => ReactNode) | null", + "statusInfoView": "((message) => ReactNode) | null", + "footerView": "((message) => ReactNode) | null", + "threadView": "((message) => ReactNode) | null", + "replyView": "ReactNode | null", + "bottomView": "((message) => ReactNode) | null" + }, + "callbacks": { + "onAvatarClick": "(user: CometChat.User) => void", + "onThreadRepliesClick": "(message: CometChat.BaseMessage) => void", + "onOptionClick": "(option: CometChatMessageOption, message: CometChat.BaseMessage) => void", + "onReactionChipClick": "(messageId: number, emoji: string) => void", + "onReactorClick": "(reaction: CometChat.Reaction, message: CometChat.BaseMessage) => void" + } + } +} +``` + + +## Where It Fits + +`CometChatMessageBubble` is the layout shell for every message in the message list. The plugin system's `renderBubble()` produces the inner content (text, image, video, etc.), and the bubble wraps it with shared chrome. + + +**Live Preview** — interact with the message bubble component. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--default) + + + + +```tsx lines +import { + CometChatMessageBubble, + CometChatTextBubble, +} from "@cometchat/chat-uikit-react"; + +function MessageItem({ message, alignment }) { + return ( + + } + /> + ); +} +``` + + +Message bubbles are **self-extracting**: each bubble takes the SDK `message` and derives its own content (text, attachments, caption, poll data, call info, action text), reading the logged-in user, theme, and locale from hooks. Pass just `message` to render a bubble standalone — no plugin or pre-extracted props required. `CometChatTextBubble` also accepts an optional `text` override so media bubbles can render captions through it. + + +## Shared Chrome Elements + +| Element | When Shown | Source | +| --- | --- | --- | +| Avatar | Incoming + group + `!hideAvatar` | `message.getSender().getAvatar()` | +| Sender name | Incoming + group + `!hideSenderName` | `message.getSender().getName()` | +| Bubble background | Always | Type-specific: primary for outgoing, neutral for incoming | +| Timestamp | `!hideTimestamp` | `message.getSentAt()` via `CometChatDate` | +| Receipts | Outgoing + `!hideReceipts` | `message.getReadAt()` / `getDeliveredAt()` | +| Edited indicator | `message.getEditedAt()` truthy | "(edited)" text | +| Thread replies | `message.getReplyCount() > 0` + `!hideThreadView` | Reply count button | +| Context menu | `options.length > 0` + `!disableInteraction` | Hover/click | + +## GlobalConfig Integration + +`hideReceipts` reads from `GlobalConfigContext` when the prop is not explicitly set: + +```tsx lines + + {/* All bubbles hide receipts unless overridden */} + {/* This one shows receipts */} + +``` + +## Props + +### message + +The SDK message object. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | + +--- + +### alignment + +Bubble alignment: `'left'` (incoming), `'right'` (outgoing), `'center'` (action). + +| | | +| --- | --- | +| Type | `'left' \| 'right' \| 'center'` | + +--- + +### contentView + +The inner content from the plugin's `renderBubble()`. **Required.** + +| | | +| --- | --- | +| Type | `ReactNode` | + +--- + +### group + +Group context. Enables avatar and sender name display. + +| | | +| --- | --- | +| Type | `CometChat.Group` | +| Default | `undefined` | + +--- + +### hideAvatar / hideSenderName / hideTimestamp / hideThreadView + +Per-bubble display controls. Not in GlobalConfig. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### hideReceipts + +Hide receipt indicators. Reads from GlobalConfig if not set. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `undefined` (falls back to GlobalConfig, then `false`) | + +--- + +### showError + +Show error receipt icon instead of normal receipts. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### disableInteraction + +Disable hover options and keyboard interactions. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### options + +Context menu options for this message (the hover/overflow actions). + +| | | +| --- | --- | +| Type | `CometChatMessageOption[]` | +| Default | `undefined` | + +--- + +### quickOptionsCount + +Number of quick options shown directly; the rest move to the overflow menu. + +| | | +| --- | --- | +| Type | `number` | +| Default | `2` | + +--- + +### forceShowAvatar + +Force-show the avatar for incoming messages even in 1:1 chats (used by agent chat). + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### messageSentAtDateTimeFormat + +Override the date format for the sent-at timestamp shown beside the bubble. + +| | | +| --- | --- | +| Type | `CometChatDateFormatConfig` | +| Default | `undefined` | + +--- + +### View override props + +Render-prop overrides for each region of the bubble. Semantics for all of them: omit (`undefined`) to use the built-in default, pass `null` to suppress the region, or pass a function/node to override it. + +| Prop | Type | Overrides | +| --- | --- | --- | +| `leadingView` | `((message) => ReactNode) \| null` | Leading view (avatar area) | +| `headerView` | `((message) => ReactNode) \| null` | Header view (sender name area) | +| `statusInfoView` | `((message) => ReactNode) \| null` | Status info (timestamp + receipts) | +| `footerView` | `((message) => ReactNode) \| null` | Footer (reactions area) | +| `threadView` | `((message) => ReactNode) \| null` | Thread reply view | +| `replyView` | `ReactNode \| null` | Reply preview (quoted message) above content | +| `bottomView` | `((message) => ReactNode) \| null` | View below the bubble (e.g. moderation footer) | + +--- + +### Callback props + +| Prop | Signature | Fires when | +| --- | --- | --- | +| `onAvatarClick` | `(user: CometChat.User) => void` | The avatar is clicked | +| `onThreadRepliesClick` | `(message: CometChat.BaseMessage) => void` | The thread view is clicked | +| `onOptionClick` | `(option: CometChatMessageOption, message: CometChat.BaseMessage) => void` | A context menu option is clicked | +| `onReactionChipClick` | `(messageId: number, emoji: string) => void` | A reaction chip is clicked (toggle add/remove) | +| `onReactorClick` | `(reaction: CometChat.Reaction, message: CometChat.BaseMessage) => void` | A reactor in the reaction list is clicked | + +--- + +### Accessibility & advanced props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `isSelected` | `boolean` | `false` | Whether this message is selected | +| `ariaPosinset` | `number` | — | Position in the message list (1-indexed) | +| `ariaSetsize` | `number` | — | Total messages in the list | +| `className` | `string` | — | Additional CSS class on the root element | +| `setRef` | `Ref` | — | Ref to the outermost wrapper div (`role="article"`) | +| `includeBottomViewHeight` | `boolean` | `false` | Use `fit-content` height for the options toolbar (useful with a `bottomView`) | +| `toggleOptionsVisibility` | `boolean` | `undefined` | Explicitly control options toolbar visibility (`true` = always, `false` = never, `undefined` = hover-based) | + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Wrapper | `.cometchat-message-bubble__wrapper` | +| Outgoing wrapper | `.cometchat-message-bubble__wrapper--outgoing` | +| Avatar area | `.cometchat-message-bubble__leading-view` | +| Bubble container | `.cometchat-message-bubble` | +| Incoming | `.cometchat-message-bubble-incoming` | +| Outgoing | `.cometchat-message-bubble-outgoing` | +| Action (center) | `.cometchat-message-bubble-action` | +| Sender name | `.cometchat-message-bubble__sender-name` | +| Body | `.cometchat-message-bubble__body` | +| Content | `.cometchat-message-bubble__body-content-view` | +| Status info | `.cometchat-message-bubble__body-status-info-view` | +| Receipts | `.cometchat-receipts` | +| Thread button | `.cometchat-message-bubble__thread-button` | diff --git a/ui-kit/react/v7/components/message-composer.mdx b/ui-kit/react/components/message-composer.mdx similarity index 98% rename from ui-kit/react/v7/components/message-composer.mdx rename to ui-kit/react/components/message-composer.mdx index d4c815383..34312bb7c 100644 --- a/ui-kit/react/v7/components/message-composer.mdx +++ b/ui-kit/react/components/message-composer.mdx @@ -9,7 +9,6 @@ description: "Rich text input with attachments, emoji, voice recording, mentions "component": "CometChatMessageComposer", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatMessageComposer } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Rich text input with attachments, emoji, voice recording, mentions, and formatting for sending messages.", "cssRootClass": ".cometchat-message-composer", "primaryOutput": { @@ -337,7 +336,10 @@ function ComposerCustomAttachments({ chatUser }: { chatUser: CometChat.User }) { return ( openPhotoPicker() }, + { id: "file", title: "Document", iconURL: fileIcon, onClick: () => openFilePicker() }, + ]} /> ); } @@ -1120,13 +1122,13 @@ Called when a mention is selected from the suggestions list. ## Next Steps - + Display messages for the selected conversation - + Show threaded replies for a parent message - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/v7/components/message-header.mdx b/ui-kit/react/components/message-header.mdx similarity index 96% rename from ui-kit/react/v7/components/message-header.mdx rename to ui-kit/react/components/message-header.mdx index 4e805aee5..5a507f97f 100644 --- a/ui-kit/react/v7/components/message-header.mdx +++ b/ui-kit/react/components/message-header.mdx @@ -9,7 +9,6 @@ description: "Toolbar displaying conversation details with avatar, name, presenc "component": "CometChatMessageHeader", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatMessageHeader } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Toolbar displaying conversation details with avatar, name, presence status, typing indicator, and call buttons.", "cssRootClass": ".cometchat-message-header", "primaryOutput": { @@ -117,7 +116,7 @@ description: "Toolbar displaying conversation details with avatar, name, presenc }, { "name": "ui:group/ownership-changed", - "payload": "{ group }", + "payload": "{ group: CometChat.Group, newOwner: CometChat.User, previousOwnerUid: string }", "description": "Updates group member count" }, { @@ -322,7 +321,7 @@ UI events this component subscribes to (published by other components): | `ui:group/member-banned` | `{ group, user, message }` | Updates group member count | | `ui:group/left` | `{ group }` | Updates group member count | | `ui:group/member-joined` | `{ joinedGroup }` | Updates group member count | -| `ui:group/ownership-changed` | `{ group }` | Updates group member count | +| `ui:group/ownership-changed` | `{ group, newOwner, previousOwnerUid }` | Updates group member count | | `ui:group/member-scope-changed` | `{ group, user, newScope }` | Updates group member count | ### SDK Listeners (Automatic) @@ -359,7 +358,9 @@ Use view props to replace sections of the default UI while keeping the component | `trailingView` | `ReactNode` | Call buttons + overflow menu | | `auxiliaryButtonView` | `ReactNode` | Auxiliary button area | -#### itemView +#### Custom item layout + +Combine `leadingView`, `titleView`, and `subtitleView` to fully replace the header's item area. @@ -560,7 +561,7 @@ Override design tokens on the component selector: All props are optional (but you need either `user` or `group` for the component to display anything). -View slot props (`headerView`, `searchView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. In compound composition mode, use the corresponding sub-components directly. +View slot props (`leadingView`, `titleView`, `subtitleView`, `trailingView`, `auxiliaryButtonView`) are convenience props available only on the flat API. In compound composition mode, use the corresponding sub-components directly. --- @@ -794,16 +795,16 @@ Callback when an SDK error occurs during call operations or other internal proce ## Next Steps - + Display messages for the active conversation - + Compose and send messages - + Header for threaded message views - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/v7/components/message-information.mdx b/ui-kit/react/components/message-information.mdx similarity index 86% rename from ui-kit/react/v7/components/message-information.mdx rename to ui-kit/react/components/message-information.mdx index 0d81be6a0..13aafd2e0 100644 --- a/ui-kit/react/v7/components/message-information.mdx +++ b/ui-kit/react/components/message-information.mdx @@ -9,7 +9,6 @@ description: "Displays detailed message information including delivery and read "component": "CometChatMessageInformation", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatMessageInformation } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Displays detailed message information including delivery and read receipts for 1-on-1 and group conversations.", "cssRootClass": ".cometchat-message-information", "primaryOutput": { @@ -19,9 +18,11 @@ description: "Displays detailed message information including delivery and read "props": { "data": { "message": { "type": "CometChat.BaseMessage", "note": "Required. The message to show information for." }, - "dateTimeFormat": { "type": "CometChatMessageInformationCalendarObject", "note": "Custom date format for receipt timestamps." }, + "messageInfoDateTimeFormat": { "type": "CometChatMessageInformationCalendarObject", "note": "Custom date format for receipt timestamps (read/delivered)." }, + "messageSentAtDateTimeFormat": { "type": "CometChatMessageInformationCalendarObject", "note": "Format for the sent-at timestamp on the message bubble preview." }, "textFormatters": { "type": "CometChatTextFormatter[]", "note": "Text formatters for the message bubble preview." }, - "mockReceipts": { "type": "CometChatUserReceiptInfo[]", "note": "Mock receipts for Storybook/testing. Skips SDK fetch." } + "showScrollbar": { "type": "boolean", "default": false, "note": "Whether to show the scrollbar in the content area." }, + "className": { "type": "string", "note": "Optional custom className for the root element." } }, "callbacks": { "onClose": { "type": "() => void", "note": "Called when the panel close button is clicked." }, @@ -72,7 +73,6 @@ It offers **two usage modes**: ```tsx import { CometChatMessageInformation } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function MessageInfoPanel({ message, onClose }) { return ( @@ -101,7 +101,6 @@ When using `` directly (without `.Root`), these a ```tsx import { CometChatMessageInformation } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function MessageInfoPanel({ message, onClose }) { return ( @@ -122,7 +121,6 @@ function MessageInfoPanel({ message, onClose }) { ```tsx import { CometChatMessageInformation } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function Demo({ message }) { return ; @@ -137,7 +135,7 @@ Root CSS class: `.cometchat-message-information` | Sub-Component | Purpose | | --- | --- | -| `Root` | Context provider. Accepts `message`, `onClose`, `onError`, `dateTimeFormat`, `textFormatters`, `showScrollbar`, `mockReceipts`. Renders default layout when no children provided. | +| `Root` | Context provider. Accepts `message`, `onClose`, `onError`, `messageInfoDateTimeFormat`, `messageSentAtDateTimeFormat`, `textFormatters`, `showScrollbar`, `className`. Renders default layout when no children provided. | | `Header` | Title ("Message Information") and close button. | | `MessagePreview` | Message bubble preview area. | | `ReceiptList` | Receipt display. Group: user list with avatars and timestamps. 1-on-1: Read/Delivered sections. | @@ -165,10 +163,10 @@ Compose only the sub-components you need: | `message` | `CometChat.BaseMessage` | — | **Required.** The message to show information for. | | `onClose` | `() => void` | — | Called when the close button is clicked. | | `onError` | `(error: unknown) => void` | — | Called when an SDK error occurs. | -| `dateTimeFormat` | `CometChatMessageInformationCalendarObject` | `{ today: 'hh:mm A', ... }` | Custom date format for receipt timestamps. | +| `messageInfoDateTimeFormat` | `CometChatMessageInformationCalendarObject` | `{ today: 'hh:mm A', ... }` | Custom date format for receipt timestamps (read/delivered). | +| `messageSentAtDateTimeFormat` | `CometChatMessageInformationCalendarObject` | — | Format for the sent-at timestamp on the message bubble preview. | | `textFormatters` | `CometChatTextFormatter[]` | `[]` | Text formatters for the message bubble preview. | | `showScrollbar` | `boolean` | `false` | Whether to show the scrollbar in the content area. | -| `mockReceipts` | `CometChatUserReceiptInfo[]` | — | Mock receipts for testing. Skips SDK fetch when provided. | | `className` | `string` | — | Additional CSS class. | ## Keyboard Accessibility diff --git a/ui-kit/react/v7/components/message-list.mdx b/ui-kit/react/components/message-list.mdx similarity index 98% rename from ui-kit/react/v7/components/message-list.mdx rename to ui-kit/react/components/message-list.mdx index 6f2f8294e..74d698780 100644 --- a/ui-kit/react/v7/components/message-list.mdx +++ b/ui-kit/react/components/message-list.mdx @@ -9,7 +9,6 @@ description: "Scrollable message feed with plugin-based bubble rendering, reacti "component": "CometChatMessageList", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatMessageList } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Scrollable message feed with plugin-based bubble rendering, reactions, receipts, threads, and real-time updates.", "cssRootClass": ".cometchat-message-list", "primaryOutput": { @@ -346,7 +345,7 @@ function ChatApp() { ## Filtering -Pass a `CometChat.MessagesRequestBuilder` to `messagesRequestBuilder` to control which messages load. Pass the builder instance — not the result of `.build()`. +Pass a `CometChat.MessagesRequestBuilder` to `messagesRequestBuilder` to control which messages load. Pass the builder instance — not the result of `.build()`. Refer to [MessagesRequestBuilder](/sdk/javascript/message-filtering) for the full builder API. ```tsx -View slot props (`headerView`, `searchView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. In compound composition mode, use the corresponding sub-components directly. +View slot props (`bubbleView`, `headerView`, `footerView`, `loadingView`, `emptyView`, `errorView`) are convenience props available only on the flat API. In compound composition mode, use the corresponding sub-components directly. --- @@ -1383,16 +1382,16 @@ Custom error state shown when message fetching fails. ## Next Steps - + Add a composer below the message list for sending messages - + Display thread context above a threaded message list - + Learn how plugins register custom bubble renderers - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/notification-feed.mdx b/ui-kit/react/components/notification-feed.mdx similarity index 66% rename from ui-kit/react/notification-feed.mdx rename to ui-kit/react/components/notification-feed.mdx index f963cfc39..79711463c 100644 --- a/ui-kit/react/notification-feed.mdx +++ b/ui-kit/react/components/notification-feed.mdx @@ -9,13 +9,11 @@ description: "Full-screen notification feed component with category filtering, c "component": "CometChatNotificationFeed", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatNotificationFeed } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Full-screen notification feed with category filtering, timestamp grouping, card rendering via @cometchat/cards-react, real-time updates, and automatic engagement reporting.", "cssRootClass": ".cometchat-notification-feed", "props": { "data": { "title": { "type": "string", "default": "\"Notifications\"" }, - "scrollToItemId": { "type": "string", "default": "undefined", "note": "Deep link to a specific feed item" }, "notificationFeedRequestBuilder": { "type": "NotificationFeedRequestBuilder", "default": "SDK default (20 per page)" }, "notificationCategoriesRequestBuilder": { "type": "NotificationCategoriesRequestBuilder", "default": "SDK default (50 per page)" } }, @@ -31,39 +29,15 @@ description: "Full-screen notification feed component with category filtering, c "showFilterChips": { "type": "boolean", "default": true } }, "viewSlots": { - "headerView": "React.ReactNode", - "emptyStateView": "React.ReactNode", - "errorStateView": "React.ReactNode", - "loadingStateView": "React.ReactNode" + "headerView": "ReactNode", + "emptyView": "ReactNode", + "errorView": "ReactNode", + "loadingView": "ReactNode", + "itemView": "(item: NotificationFeedItem) => ReactNode" }, "cards": { "cardThemeMode": { "type": "\"auto\" | \"light\" | \"dark\"", "default": "\"auto\"" }, - "cardThemeOverride": { "type": "Record", "default": "undefined" } - }, - "style": { - "type": "CometChatNotificationFeedStyle", - "properties": { - "backgroundColor": "string", - "width": "string", - "height": "string", - "headerTitleColor": "string", - "headerTitleFont": "string", - "chipActiveBackgroundColor": "string", - "chipActiveTextColor": "string", - "chipInactiveBackgroundColor": "string", - "chipInactiveTextColor": "string", - "chipBorderColor": "string", - "badgeBackgroundColor": "string", - "badgeTextColor": "string", - "separatorColor": "string", - "timestampTextColor": "string", - "timestampFont": "string", - "cardBackgroundColor": "string", - "cardBorderColor": "string", - "cardBorderRadius": "number", - "cardBorderWidth": "number", - "unreadIndicatorColor": "string" - } + "cardThemeOverride": { "type": "Record", "default": "undefined" } } }, "automaticBehaviors": [ @@ -74,11 +48,9 @@ description: "Full-screen notification feed component with category filtering, c "Infinite scroll pagination", "Timestamp grouping (Today, Yesterday, day name, date)", "Category filter chips with unread badges", - "Mark all read button", - "Offline connectivity banner" + "Mark all read button" ], "additionalExports": { - "CometChatNotificationBadge": "Standalone unread count badge component", "useNotificationUnreadCount": "Hook for tracking unread count with shared polling" } } @@ -91,15 +63,29 @@ description: "Full-screen notification feed component with category filtering, c + +**Live Preview** — interact with the notification feed component. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-notification-feed-cometchat-notification-feed--default) + + + + --- ## Where It Fits `CometChatNotificationFeed` is a full-screen component. Drop it into a page or route. It manages its own data fetching, state, and real-time listeners — you just handle navigation callbacks. -```tsx lines +```tsx import { CometChatNotificationFeed } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function NotificationsPage() { return ( @@ -118,9 +104,8 @@ function NotificationsPage() { ## Minimal Render -```tsx lines +```tsx import { CometChatNotificationFeed } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function NotificationsDemo() { return ( @@ -143,7 +128,7 @@ Root CSS class: `.cometchat-notification-feed` Control what loads using custom request builders: -```tsx lines +```tsx import { CometChatNotificationFeed } from "@cometchat/chat-uikit-react"; import { CometChat } from "@cometchat/chat-sdk-javascript"; @@ -184,7 +169,7 @@ function UnreadNotifications() { Fires when a feed item card is clicked. -```tsx lines +```tsx { console.log("Item clicked:", item.getId()); @@ -196,13 +181,13 @@ Fires when a feed item card is clicked. Fires when an interactive element (button, link) inside a card is clicked. The `action` object contains the action type, parameters, and the element ID that triggered it. -```tsx lines +```tsx { const { type, params, elementId } = action; switch (type) { case "openUrl": - window.open(params.url, "_blank"); + window.open(params.url as string, "_blank"); break; case "chatWithUser": // Navigate to chat with params.uid @@ -219,7 +204,7 @@ Fires when an interactive element (button, link) inside a card is clicked. The ` Fires when an internal error occurs (network failure, SDK exception). -```tsx lines +```tsx { console.error("Feed error:", error.message); @@ -231,7 +216,7 @@ Fires when an internal error occurs (network failure, SDK exception). Fires when the back button in the header is clicked. -```tsx lines +```tsx window.history.back()} @@ -252,108 +237,69 @@ The component handles these automatically — no manual setup needed: | Timestamp grouping | Groups items as "Today", "Yesterday", day name, or date | | Category filtering | Filter chips row with per-category unread badges | | Mark all read | Header button to mark all notifications as read | -| Offline banner | Shows connectivity warning when offline | --- -## Custom View Slots +## Customization -### headerView +### View Props -Replace the entire header: - -```tsx lines +```tsx -

My Notifications

-
- } + headerView={} + emptyView={} + loadingView={} + errorView={} + itemView={(item) => } /> ``` -### State Views - -```tsx lines - -

No notifications yet

- - } - errorStateView={ -
-

Something went wrong

-
- } - loadingStateView={ -
-
-
- } -/> +| Slot | Signature | Replaces | +| --- | --- | --- | +| `headerView` | `ReactNode` | Entire header bar | +| `loadingView` | `ReactNode` | Loading state | +| `emptyView` | `ReactNode` | Empty state | +| `errorView` | `ReactNode` | Error state | +| `itemView` | `(item: NotificationFeedItem) => ReactNode` | Individual feed item rendering | + +### Compound Composition + +For full layout control, use sub-components. Omit any sub-component to hide it: + +```tsx + + + + + ``` ---- - -## Styling +Available sub-components: -The component uses CSS variables from the CometChat theme system. Pass a `style` prop for programmatic overrides, or use CSS classes for full control. - -### Style Prop - -```tsx lines -import { CometChatNotificationFeed } from "@cometchat/chat-uikit-react"; - -function StyledNotifications() { - return ( - - ); +| Sub-component | Description | Props | Flat API equivalent | +| --- | --- | --- | --- | +| `Root` | Context provider and container | All Root props + `children` | — | +| `Header` | Header bar with title + mark-all-read | `title`, `showBackButton`, `onBackPress`, `children` | `headerView` | +| `FilterChips` | Category filter chips | `children` | — | +| `List` | Scrollable feed list | `itemView` | `itemView` | +| `Item` | Individual feed item | `item`, `cardThemeMode`, `cardThemeOverride` | — | +| `EmptyState` | Empty state | `children` | `emptyView` | +| `ErrorState` | Error state | `children` | `errorView` | +| `LoadingState` | Loading state | `children` | `loadingView` | + +### CSS Styling + +Override design tokens on the component selector: + +```css +.cometchat-notification-feed { + --cometchat-background-color-01: #1a1a2e; + --cometchat-text-color-primary: #ffffff; } ``` -### Style Properties - -| Property | Type | Description | -| --- | --- | --- | -| `backgroundColor` | string | Root container background | -| `width` | string | Container width | -| `height` | string | Container height | -| `headerTitleColor` | string | Header title text color | -| `headerTitleFont` | string | Header title font | -| `chipActiveBackgroundColor` | string | Selected filter chip background | -| `chipActiveTextColor` | string | Selected filter chip text color | -| `chipInactiveBackgroundColor` | string | Unselected filter chip background | -| `chipInactiveTextColor` | string | Unselected filter chip text color | -| `chipBorderColor` | string | Inactive chip border color | -| `badgeBackgroundColor` | string | Badge background color | -| `badgeTextColor` | string | Badge text color | -| `separatorColor` | string | Separator between items | -| `timestampTextColor` | string | Timestamp text color | -| `timestampFont` | string | Timestamp font | -| `cardBackgroundColor` | string | Card container background | -| `cardBorderColor` | string | Card border color | -| `cardBorderRadius` | number | Card corner radius | -| `cardBorderWidth` | number | Card border width | -| `unreadIndicatorColor` | string | Unread dot color | - ### CSS Classes -Override styles using these CSS classes: - | Class | Description | | --- | --- | | `.cometchat-notification-feed` | Root container | @@ -365,22 +311,16 @@ Override styles using these CSS classes: | `.cometchat-notification-feed__chip` | Individual filter chip | | `.cometchat-notification-feed__chip--active` | Active filter chip | | `.cometchat-notification-feed__chip--inactive` | Inactive filter chip | -| `.cometchat-notification-feed__chip--inactive-with-badge` | Inactive chip with unread badge | | `.cometchat-notification-feed__chip-badge` | Chip unread badge | -| `.cometchat-notification-feed__chip-badge--active` | Active chip badge | -| `.cometchat-notification-feed__chip-badge--inactive` | Inactive chip badge | | `.cometchat-notification-feed__content` | Scrollable content area | | `.cometchat-notification-feed__item` | Feed item container | | `.cometchat-notification-feed__item--unread` | Unread feed item | | `.cometchat-notification-feed__unread-indicator` | Unread dot indicator | | `.cometchat-notification-feed__item-meta` | Item metadata row (category + time) | -| `.cometchat-notification-feed__item-category` | Category label | -| `.cometchat-notification-feed__item-time` | Timestamp | | `.cometchat-notification-feed__card-container` | Card wrapper | | `.cometchat-notification-feed__loading` | Loading state | | `.cometchat-notification-feed__empty` | Empty state | | `.cometchat-notification-feed__error` | Error state | -| `.cometchat-notification-feed__connectivity-banner` | Offline banner | --- @@ -388,69 +328,60 @@ Override styles using these CSS classes: All props are optional. -### cardThemeMode - -Theme mode for the card renderer (`@cometchat/cards-react`). - -| | | -| --- | --- | -| Type | `"auto" \| "light" \| "dark"` | -| Default | `"auto"` | - --- -### cardThemeOverride +### title -Custom theme override passed to the card renderer. +Header title text. | | | | --- | --- | -| Type | `Record` | -| Default | `undefined` | +| Type | `string` | +| Default | `"Notifications"` | --- -### emptyStateView +### showHeader -Custom component displayed when there are no notifications. +Shows/hides the entire header. | | | | --- | --- | -| Type | `React.ReactNode` | -| Default | Built-in empty state with illustration | +| Type | `boolean` | +| Default | `true` | --- -### errorStateView +### showBackButton -Custom component displayed when an error occurs. +Shows/hides the back button in the header. | | | | --- | --- | -| Type | `React.ReactNode` | -| Default | Built-in error state with retry button | +| Type | `boolean` | +| Default | `false` | --- -### headerView +### showFilterChips -Custom component replacing the entire header. +Shows/hides the category filter chips row. | | | | --- | --- | -| Type | `React.ReactNode` | -| Default | Built-in header with title and mark-all-read button | +| Type | `boolean` | +| Default | `true` | --- -### loadingStateView +### notificationFeedRequestBuilder -Custom component displayed during the initial loading state. +Custom request builder for fetching feed items. | | | | --- | --- | -| Type | `React.ReactNode` | -| Default | Built-in loading spinner | +| Type | `CometChat.NotificationFeedRequestBuilder` | +| Default | SDK default (20 per page) | --- @@ -465,14 +396,14 @@ Custom request builder for fetching categories. --- -### notificationFeedRequestBuilder +### onItemClick -Custom request builder for fetching feed items. +Callback fired when a feed item card is clicked. | | | | --- | --- | -| Type | `CometChat.NotificationFeedRequestBuilder` | -| Default | SDK default (20 per page) | +| Type | `(feedItem: NotificationFeedItem) => void` | +| Default | `undefined` | --- @@ -492,143 +423,112 @@ The `CardAction` object contains: --- -### onBackPress +### onError -Callback fired when the back button is pressed. +Callback fired when the component encounters an error. | | | | --- | --- | -| Type | `() => void` | +| Type | `(error: CometChat.CometChatException) => void` | | Default | `undefined` | --- -### onError +### onBackPress -Callback fired when the component encounters an error. +Callback fired when the back button is pressed. | | | | --- | --- | -| Type | `(error: CometChat.CometChatException) => void` | +| Type | `() => void` | | Default | `undefined` | --- -### onItemClick +### cardThemeMode -Callback fired when a feed item card is clicked. +Theme mode for the card renderer (`@cometchat/cards-react`). | | | | --- | --- | -| Type | `(feedItem: NotificationFeedItem) => void` | -| Default | `undefined` | +| Type | `"auto" \| "light" \| "dark"` | +| Default | `"auto"` | --- -### scrollToItemId +### cardThemeOverride -Deep link to a specific feed item by ID. The component scrolls to the item once loaded. +Custom theme override passed to the card renderer. | | | | --- | --- | -| Type | `string` | +| Type | `Record` | | Default | `undefined` | --- -### showBackButton +### headerView -Shows/hides the back button in the header. +Custom component replacing the entire header. | | | | --- | --- | -| Type | `boolean` | -| Default | `false` | +| Type | `ReactNode` | +| Default | Built-in header with title and mark-all-read button | --- -### showFilterChips +### loadingView -Shows/hides the category filter chips row. +Custom component displayed during the initial loading state. | | | | --- | --- | -| Type | `boolean` | -| Default | `true` | +| Type | `ReactNode` | +| Default | Built-in loading state | --- -### showHeader +### errorView -Shows/hides the entire header. +Custom component displayed when an error occurs. | | | | --- | --- | -| Type | `boolean` | -| Default | `true` | +| Type | `ReactNode` | +| Default | Built-in error state with retry button | --- -### style +### emptyView -Style customization object. +Custom component displayed when there are no notifications. | | | | --- | --- | -| Type | `CometChatNotificationFeedStyle` | -| Default | `undefined` | +| Type | `ReactNode` | +| Default | Built-in empty state with illustration | --- -### title +### itemView -Header title text. +Custom renderer for each feed item. | | | | --- | --- | -| Type | `string` | -| Default | `"Notifications"` | +| Type | `(item: NotificationFeedItem) => ReactNode` | +| Default | Built-in card renderer | --- ## Additional Exports -### CometChatNotificationBadge - -A standalone badge component that displays the unread notification count. Uses a shared polling singleton — multiple badges share one interval and listener. - -```tsx lines -import { CometChatNotificationBadge } from "@cometchat/chat-uikit-react"; - -function NavBar() { - return ( - - ); -} -``` - -#### Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `category` | string | undefined | Filter count by category | -| `max` | number | 99 | Maximum count before showing "N+" | -| `style.backgroundColor` | string | `"#6852D6"` | Badge background color | -| `style.textColor` | string | `"#fff"` | Badge text color | -| `style.fontSize` | string | `"11px"` | Badge font size | -| `style.borderRadius` | string | `"9999px"` | Badge border radius | - ---- - ### useNotificationUnreadCount A React hook for tracking unread notification count. Uses a shared singleton — multiple components share one polling interval and WebSocket listener. -```tsx lines +```tsx import { useNotificationUnreadCount } from "@cometchat/chat-uikit-react"; function NotificationIcon() { @@ -642,6 +542,13 @@ function NotificationIcon() { } ``` +#### Options + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `category` | string | undefined | Filter count by category | +| `pollingInterval` | number | 30000 | Polling interval in milliseconds | + #### Return Value | Field | Type | Description | @@ -650,20 +557,13 @@ function NotificationIcon() { | `refresh` | `() => Promise` | Manually refresh the count | | `isLoading` | boolean | Whether the initial fetch is in progress | -#### Options - -| Option | Type | Default | Description | -| --- | --- | --- | --- | -| `category` | string | undefined | Filter count by category | -| `pollingInterval` | number | 30000 | Polling interval in milliseconds | - --- ## Common Patterns ### Show only unread items -```tsx lines +```tsx ``` -### Deep link to a specific notification - -```tsx lines - -``` - ### Embed in a sidebar -```tsx lines +```tsx import { CometChatNotificationFeed } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function NotificationsSidebar() { return ( @@ -710,21 +601,22 @@ function NotificationsSidebar() { ### Add notification badge to navigation -```tsx lines +```tsx +import { useState } from "react"; import { CometChatNotificationFeed, - CometChatNotificationBadge, + useNotificationUnreadCount, } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function App() { const [showFeed, setShowFeed] = useState(false); + const { count } = useNotificationUnreadCount(); return ( <> {showFeed && ( @@ -749,7 +641,7 @@ function App() { Low-level SDK APIs for feed items, categories, and engagement - + Customize colors, fonts, and appearance diff --git a/ui-kit/react/v7/components/outgoing-call.mdx b/ui-kit/react/components/outgoing-call.mdx similarity index 97% rename from ui-kit/react/v7/components/outgoing-call.mdx rename to ui-kit/react/components/outgoing-call.mdx index 923c3ba6a..aee19e4ea 100644 --- a/ui-kit/react/v7/components/outgoing-call.mdx +++ b/ui-kit/react/components/outgoing-call.mdx @@ -9,7 +9,6 @@ description: "Displays the outgoing call screen with receiver info and a cancel "component": "CometChatOutgoingCall", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatOutgoingCall } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Displays the outgoing call screen with receiver info and a cancel button while waiting for the call to be answered.", "cssRootClass": ".cometchat-outgoing-call", "primaryOutput": { @@ -467,13 +466,13 @@ Additional CSS class name applied to the root element. ## Next Steps - + Handle incoming call notifications with accept/decline actions - + Browse call history and re-initiate calls - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/poll-bubble.mdx b/ui-kit/react/components/poll-bubble.mdx new file mode 100644 index 000000000..5d0304e1d --- /dev/null +++ b/ui-kit/react/components/poll-bubble.mdx @@ -0,0 +1,167 @@ +--- +title: "Poll Bubble" +sidebarTitle: "Poll Bubble" +description: "A self-extracting bubble that renders a poll with its question, selectable options, live vote counts, percentages, and voter avatars." +--- + + +```json +{ + "component": "CometChatPollBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatPollBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting poll bubble. Derives the question, options, vote counts, totals, and the logged-in user's vote from the message metadata.", + "cssRootClass": ".cometchat-poll-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.CustomMessage", "required": true, "note": "Contains poll data in its metadata; drives all extraction." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "disableInteraction": { "type": "boolean", "default": false }, + "onVoteSubmit": { "type": "(event: CometChatPollVoteEvent) => void" }, + "onVoteError": { "type": "(event: CometChatPollVoteErrorEvent) => void" }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatPollBubble` renders a poll. It is **self-extracting**: pass the SDK custom `message` and the bubble derives the question, options, per-option vote counts, total votes, and the logged-in user's selected option entirely from the message metadata. Selecting an option submits a vote; the bar fills and counts/avatars update. + + +**Live Preview** — interact with the poll bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--poll-message) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatPollBubble } from "@cometchat/chat-uikit-react"; + +function PollMessage({ message }: { message: CometChat.CustomMessage }) { + return ( + console.log("Voted:", e.optionText)} + /> + ); +} +``` + +--- + +## Props + +### message + +The custom message containing poll data in its metadata. Drives all extraction. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.CustomMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### disableInteraction + +Disable all interaction (e.g. for a thread header preview). + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### onVoteSubmit + +Callback when a vote is submitted successfully. + +| | | +| --- | --- | +| Type | `(event: CometChatPollVoteEvent) => void` | +| Default | `undefined` | + +--- + +### onVoteError + +Callback when a vote submission fails. + +| | | +| --- | --- | +| Type | `(event: CometChatPollVoteErrorEvent) => void` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-poll-bubble` | +| Incoming / outgoing | `.cometchat-poll-bubble--incoming` / `.cometchat-poll-bubble--outgoing` | +| Option | `.cometchat-poll-bubble__option` | +| Option text | `.cometchat-poll-bubble__option-text` | +| Option count | `.cometchat-poll-bubble__option-count` | +| Option progress bar | `.cometchat-poll-bubble__option-progress-bar` | +| Option radio | `.cometchat-poll-bubble__option-radio` | +| Voter avatars | `.cometchat-poll-bubble__option-avatars` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Render sticker messages + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/v7/components/reaction-list.mdx b/ui-kit/react/components/reaction-list.mdx similarity index 97% rename from ui-kit/react/v7/components/reaction-list.mdx rename to ui-kit/react/components/reaction-list.mdx index e5f34c654..26e56de93 100644 --- a/ui-kit/react/v7/components/reaction-list.mdx +++ b/ui-kit/react/components/reaction-list.mdx @@ -9,7 +9,6 @@ description: "Standalone panel showing who reacted to a message, with emoji tab "component": "CometChatReactionList", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatReactionList } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Standalone panel showing who reacted to a message, with emoji tab filtering, pagination, and optimistic removal for the current user.", "cssRootClass": ".cometchat-reaction-list", "primaryOutput": { @@ -65,7 +64,6 @@ The parent component (typically `CometChatMessageList`) owns the SDK reaction ad ```tsx lines import { CometChatReactionList } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function ReactionPanel({ message, onClose }) { return ( @@ -85,7 +83,6 @@ function ReactionPanel({ message, onClose }) { ```tsx lines import { CometChatReactionList } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function Demo({ message }) { return ; @@ -223,7 +220,7 @@ const builder = new CometChat.ReactionsRequestBuilder().setLimit(50); ## CSS Architecture -The component uses CSS custom properties defined in `@cometchat/chat-uikit-react/css-variables.css`. +The component uses CSS custom properties provided by the UI Kit. ### Key Selectors diff --git a/ui-kit/react/v7/components/reactions.mdx b/ui-kit/react/components/reactions.mdx similarity index 92% rename from ui-kit/react/v7/components/reactions.mdx rename to ui-kit/react/components/reactions.mdx index 11530cf99..193d56f04 100644 --- a/ui-kit/react/v7/components/reactions.mdx +++ b/ui-kit/react/components/reactions.mdx @@ -9,7 +9,6 @@ description: "Displays emoji reaction chips on message bubbles with hover toolti "component": "CometChatReactions", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatReactions } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Displays emoji reaction chips on message bubbles with hover tooltips, a full reactor list, and overflow handling.", "cssRootClass": ".cometchat-reactions", "primaryOutput": { @@ -26,6 +25,9 @@ description: "Displays emoji reaction chips on message bubbles with hover toolti "onReactionClick": { "type": "(emoji: string, message: CometChat.BaseMessage) => void" }, "onReactorClick": { "type": "(reaction: CometChat.Reaction, message: CometChat.BaseMessage) => void" }, "onError": { "type": "(error: unknown) => void" } + }, + "config": { + "hoverDebounceTime": { "type": "number", "note": "Debounce (ms) before showing the hover tooltip." } } }, "types": { @@ -33,7 +35,6 @@ description: "Displays emoji reaction chips on message bubbles with hover toolti "CometChatReactionsBarProps": "Reaction chips bar props", "CometChatReactionsChipProps": "Single reaction chip props", "CometChatReactionsInfoProps": "Hover tooltip props", - "CometChatReactionsListProps": "Full reactor list props", "CometChatReactionsOverflowProps": "Overflow button props" } } @@ -61,7 +62,6 @@ description: "Displays emoji reaction chips on message bubbles with hover toolti ```tsx lines import { CometChatReactions } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function MessageBubbleFooter({ message, onReactionClick }) { return ( @@ -78,7 +78,6 @@ function MessageBubbleFooter({ message, onReactionClick }) { ```tsx lines import { CometChatReactions } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; function Demo({ message }) { return ; @@ -97,7 +96,6 @@ Root CSS class: `.cometchat-reactions` | `Bar` | Reaction chips container with `role="group"`. Auto-calculates overflow via ResizeObserver. | | `Chip` | Single reaction button with emoji, count, and `aria-pressed`. | | `Info` | Hover tooltip showing who reacted with a specific emoji. | -| `List` | Full reactor list popover with tab filtering and pagination. | | `Overflow` | "+N more" button for overflow reactions. | ### Custom Layout @@ -110,15 +108,9 @@ Compose sub-components to customize the layout: ``` -### Standalone List - -Use the List sub-component independently: - -```tsx lines - - - -``` + +For a standalone reactor list (the full list of who reacted, with tab filtering and pagination), use the dedicated [`CometChatReactionList`](/ui-kit/react/components/reaction-list) component — it is separate from `CometChatReactions`. + ## Actions and Events @@ -163,7 +155,7 @@ Called when an error occurs during reactor detail fetching. ## CSS Architecture -The component uses CSS custom properties defined in `@cometchat/chat-uikit-react/css-variables.css`. +The component uses CSS custom properties provided by the UI Kit. ### Key Selectors @@ -235,6 +227,17 @@ Custom request builder for fetching reactor details. --- +### hoverDebounceTime + +Debounce delay (in milliseconds) before the hover tooltip (`Info`) appears when hovering a reaction chip. + +| | | +| --- | --- | +| Type | `number` | +| Default | `undefined` | + +--- + ### onReactionClick Called when a reaction chip is clicked. Parent handles the SDK call. diff --git a/ui-kit/react/v7/components/search.mdx b/ui-kit/react/components/search.mdx similarity index 98% rename from ui-kit/react/v7/components/search.mdx rename to ui-kit/react/components/search.mdx index 6b1142f60..fa56f643b 100644 --- a/ui-kit/react/v7/components/search.mdx +++ b/ui-kit/react/components/search.mdx @@ -9,7 +9,6 @@ description: "Unified search across conversations and messages with filter chips "component": "CometChatSearch", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatSearch } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Unified search across conversations and messages with filter chips, scoped search, and customizable result views.", "cssRootClass": ".cometchat-search", "primaryOutput": { @@ -920,13 +919,13 @@ Callback when an SDK error occurs during search. ## Next Steps - + Display the conversation list alongside search - + Navigate to matched messages in the message list - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/sticker-bubble.mdx b/ui-kit/react/components/sticker-bubble.mdx new file mode 100644 index 000000000..786f159aa --- /dev/null +++ b/ui-kit/react/components/sticker-bubble.mdx @@ -0,0 +1,121 @@ +--- +title: "Sticker Bubble" +sidebarTitle: "Sticker Bubble" +description: "A self-extracting bubble that renders a sticker image from a sticker custom message." +--- + + +```json +{ + "component": "CometChatStickerBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatStickerBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting sticker bubble. Extracts the sticker image URL and name from the message metadata.", + "cssRootClass": ".cometchat-sticker-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.CustomMessage", "required": true, "note": "The sticker custom message; drives extraction of the image URL and name." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatStickerBubble` renders a sticker. It is **self-extracting**: pass the SDK custom `message` and the bubble extracts the sticker image URL and name from its metadata, so it works standalone. + + +**Live Preview** — interact with the sticker bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--sticker-message) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatStickerBubble } from "@cometchat/chat-uikit-react"; + +function StickerMessage({ message }: { message: CometChat.CustomMessage }) { + return ; +} +``` + +--- + +## Props + +### message + +The sticker custom message. The bubble extracts the image URL and name from its metadata. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.CustomMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-sticker-bubble` | +| Incoming / outgoing | `.cometchat-sticker-bubble--incoming` / `.cometchat-sticker-bubble--outgoing` | +| Sticker image | `.cometchat-sticker-bubble__image` | + +--- + +## Next Steps + + + + Plugin behavior, keyboard, and conversation preview + + + Render poll messages + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/components/text-bubble.mdx b/ui-kit/react/components/text-bubble.mdx new file mode 100644 index 000000000..2e6b421cb --- /dev/null +++ b/ui-kit/react/components/text-bubble.mdx @@ -0,0 +1,170 @@ +--- +title: "Text Bubble" +sidebarTitle: "Text Bubble" +description: "A self-extracting bubble that renders text messages with markdown, mentions, clickable URLs, link previews, and read-more truncation." +--- + + +```json +{ + "component": "CometChatTextBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatTextBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting text bubble. Renders message text through the formatter pipeline (markdown, mentions, URLs), with optional read-more truncation.", + "cssRootClass": ".cometchat-text-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.BaseMessage", "note": "When set (and text omitted), the bubble extracts content via message.getText() and configures mention formatting." }, + "text": { "type": "string", "note": "Explicit text override (used for media captions). At least one of text / message should be set." }, + "isSentByMe": { "type": "boolean", "default": true }, + "textFormatters": { "type": "CometChatTextFormatter[]" }, + "disableTruncation": { "type": "boolean", "default": false }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatTextBubble` renders a text message. It is **self-extracting**: pass the SDK `message` and the bubble reads the text via `message.getText()` and configures mention formatting from the message itself, so it works standalone. It also accepts an explicit `text` override, which is how media bubbles render their captions through it. + +Text is run through the formatter pipeline — markdown (`**bold**`, `_italic_`, `~~strike~~`, `` `code` ``, lists, blockquotes), `<@uid:xxx>` mentions resolved to styled chips, and bare URLs converted to clickable links. Long messages are truncated with a "Read more" toggle unless `disableTruncation` is set. + + +**Live Preview** — interact with the text bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-text--default) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatTextBubble } from "@cometchat/chat-uikit-react"; + +function TextMessage({ message }: { message: CometChat.BaseMessage }) { + return ; +} +``` + +Render explicit text (e.g. a caption) instead of extracting from a message: + +```tsx + +``` + +--- + +## Props + +### message + +The message to render. When `text` is omitted, the bubble extracts the content and mention formatting from it. + +| | | +| --- | --- | +| Type | `CometChat.BaseMessage` | +| Default | `undefined` | + +--- + +### text + +Explicit text to display. Overrides `message.getText()` when provided. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +### isSentByMe + +Whether the message was sent by the logged-in user (affects styling). + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `true` | + +--- + +### textFormatters + +Text formatters to apply (mentions, URLs, custom syntax). + +| | | +| --- | --- | +| Type | `CometChatTextFormatter[]` | +| Default | `undefined` | + +--- + +### disableTruncation + +Disable the read-more / show-less truncation. + +| | | +| --- | --- | +| Type | `boolean` | +| Default | `false` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-text-bubble` | +| Incoming / outgoing | `.cometchat-text-bubble--incoming` / `.cometchat-text-bubble--outgoing` | +| Single emoji | `.cometchat-text-bubble--single-emoji` | +| Text content | `.cometchat-text-bubble__text` | +| Mention chip | `.cometchat-text-bubble__mention` | +| Link | `.cometchat-link` | +| Read-more button | `.cometchat-text-bubble__read-more-button` | +| Link preview | `.cometchat-text-bubble__link-preview` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Build custom mention / URL / markdown formatters + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/v7/components/thread-header.mdx b/ui-kit/react/components/thread-header.mdx similarity index 98% rename from ui-kit/react/v7/components/thread-header.mdx rename to ui-kit/react/components/thread-header.mdx index 32e616d87..c217723ca 100644 --- a/ui-kit/react/v7/components/thread-header.mdx +++ b/ui-kit/react/components/thread-header.mdx @@ -9,7 +9,6 @@ description: "Displays the parent message bubble and reply count for threaded co "component": "CometChatThreadHeader", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatThreadHeader } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Displays the parent message bubble and reply count for threaded conversations.", "cssRootClass": ".cometchat-thread-header", "primaryOutput": { @@ -529,13 +528,13 @@ Custom subtitle view below the title. ## Next Steps - + Display threaded replies below the parent message - + Compose replies in the thread - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/v7/components/users.mdx b/ui-kit/react/components/users.mdx similarity index 96% rename from ui-kit/react/v7/components/users.mdx rename to ui-kit/react/components/users.mdx index 8464abfcf..44e988e5d 100644 --- a/ui-kit/react/v7/components/users.mdx +++ b/ui-kit/react/components/users.mdx @@ -9,7 +9,6 @@ description: "Searchable, scrollable list of users with selection support and re "component": "CometChatUsers", "package": "@cometchat/chat-uikit-react", "import": "import { CometChatUsers } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", "description": "Searchable, scrollable list of users with selection support and real-time presence updates.", "cssRootClass": ".cometchat-users", "primaryOutput": { @@ -205,7 +204,7 @@ function NewChat() { ## Filtering -Pass a `CometChat.UsersRequestBuilder` to `usersRequestBuilder` to control which users load. Pass the builder instance — not the result of `.build()`. +Pass a `CometChat.UsersRequestBuilder` to `usersRequestBuilder` to control which users load. Pass the builder instance — not the result of `.build()`. Refer to [UsersRequestBuilder](/sdk/javascript/retrieve-users) for the full builder API. ```tsx -View slot props (`headerView`, `searchView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. In compound composition mode, use the corresponding sub-components directly. +View slot props (`headerView`, `loadingView`, `emptyView`, `errorView`, `itemView`, `leadingView`, `titleView`, `subtitleView`, `trailingView`) are convenience props available only on the flat API. The search input is the `SearchBar` sub-component (with a `placeholder` prop), not a view slot. In compound composition mode, use the corresponding sub-components directly. --- @@ -830,16 +829,16 @@ Callback when the user list is empty after the initial fetch completes. ## Next Steps - + View recent conversations for the logged-in user - + Browse and join groups - + Display messages for the selected user - + Customize colors, fonts, and spacing diff --git a/ui-kit/react/components/video-bubble.mdx b/ui-kit/react/components/video-bubble.mdx new file mode 100644 index 000000000..ef506d87f --- /dev/null +++ b/ui-kit/react/components/video-bubble.mdx @@ -0,0 +1,138 @@ +--- +title: "Video Bubble" +sidebarTitle: "Video Bubble" +description: "A self-extracting bubble that renders video attachments with thumbnails, a play overlay, duration badge, and caption." +--- + + +```json +{ + "component": "CometChatVideoBubble", + "package": "@cometchat/chat-uikit-react", + "import": "import { CometChatVideoBubble } from \"@cometchat/chat-uikit-react\";", + "description": "Self-extracting video bubble. Extracts video attachments, thumbnails, and caption from a MediaMessage.", + "cssRootClass": ".cometchat-video-bubble", + "selfExtracting": true, + "props": { + "data": { + "message": { "type": "CometChat.MediaMessage", "required": true, "note": "Drives extraction of video attachments, thumbnails, and caption." }, + "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." }, + "textFormatters": { "type": "CometChatTextFormatter[]" }, + "className": { "type": "string" } + } + } +} +``` + + +## Overview + +`CometChatVideoBubble` renders the video attachment(s) of a media message. It is **self-extracting**: pass the SDK `message` and the bubble derives the video URLs, thumbnails, caption, and alignment itself, so it works standalone. A single video shows its thumbnail as a poster with a play overlay; multiple videos lay out in a grid with an overflow tile. + + +**Live Preview** — interact with the video bubble. + +[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-video--default) + + + + +--- + +## Usage + +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { CometChatVideoBubble } from "@cometchat/chat-uikit-react"; + +function VideoMessage({ message }: { message: CometChat.MediaMessage }) { + return ; +} +``` + +--- + +## Props + +### message + +The media message. Drives extraction of video attachments, thumbnails, caption, and sender name. **Required.** + +| | | +| --- | --- | +| Type | `CometChat.MediaMessage` | +| Required | Yes | + +--- + +### alignment + +Override incoming/outgoing alignment. Defaults to sender-vs-logged-in-user. + +| | | +| --- | --- | +| Type | `"left" \| "right"` | +| Default | derived | + +--- + +### textFormatters + +Text formatters for caption rendering (mentions, URLs). + +| | | +| --- | --- | +| Type | `CometChatTextFormatter[]` | +| Default | `undefined` | + +--- + +### className + +Additional CSS class applied to the root element. + +| | | +| --- | --- | +| Type | `string` | +| Default | `undefined` | + +--- + +## CSS Selectors + +| Target | Selector | +| --- | --- | +| Root | `.cometchat-video-bubble` | +| Incoming / outgoing | `.cometchat-video-bubble--incoming` / `.cometchat-video-bubble--outgoing` | +| Single video | `.cometchat-video-bubble--single` | +| Container | `.cometchat-video-bubble__container` | +| Grid | `.cometchat-video-bubble__grid` | +| Play overlay | `.cometchat-video-bubble__play-overlay` | +| Duration badge | `.cometchat-video-bubble__duration-badge` | +| Caption | `.cometchat-video-bubble__caption` | + +--- + +## Next Steps + + + + Plugin behavior, context menu, and conversation preview + + + Render image attachments + + + The wrapper that hosts bubble content + + + Customize colors, fonts, and spacing + + diff --git a/ui-kit/react/conversations.mdx b/ui-kit/react/conversations.mdx deleted file mode 100644 index b664728b4..000000000 --- a/ui-kit/react/conversations.mdx +++ /dev/null @@ -1,1567 +0,0 @@ ---- -title: "Conversations" -description: "Display CometChat React UI Kit conversations with last messages, unread counts, typing indicators, presence, filters, and item callbacks." ---- - -```json -{ - "component": "CometChatConversations", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatConversations } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", - "description": "Scrollable list of recent one-on-one and group conversations for the logged-in user.", - "cssRootClass": ".cometchat-conversations", - "primaryOutput": { - "prop": "onItemClick", - "type": "(conversation: CometChat.Conversation) => void" - }, - "props": { - "data": { - "conversationsRequestBuilder": { - "type": "CometChat.ConversationsRequestBuilder", - "default": "SDK default (30 per page)", - "note": "Pass the builder, not the result of .build()" - }, - "activeConversation": { - "type": "CometChat.Conversation", - "default": "undefined" - }, - "lastMessageDateTimeFormat": { - "type": "CalendarObject", - "default": "Component default (hh:mm A today, [yesterday], DD/MM/YYYY other days)", - "note": "Falls back to global CometChatLocalize.calendarObject if not set" - } - }, - "callbacks": { - "onItemClick": "(conversation: CometChat.Conversation) => void", - "onSelect": "(conversation: CometChat.Conversation, selected: boolean) => void", - "onError": "((error: CometChat.CometChatException) => void) | null", - "onSearchBarClicked": "() => void" - }, - "visibility": { - "hideReceipts": { "type": "boolean", "default": false }, - "hideError": { "type": "boolean", "default": false }, - "hideDeleteConversation": { "type": "boolean", "default": false }, - "hideUserStatus": { "type": "boolean", "default": false }, - "hideGroupType": { "type": "boolean", "default": false }, - "showSearchBar": { "type": "boolean", "default": false }, - "showScrollbar": { "type": "boolean", "default": false } - }, - "sound": { - "disableSoundForMessages": { "type": "boolean", "default": false }, - "customSoundForMessages": { "type": "string", "default": "built-in" } - }, - "selection": { - "selectionMode": { - "type": "SelectionMode", - "values": ["SelectionMode.single (0)", "SelectionMode.multiple (1)", "SelectionMode.none (2)"], - "default": "SelectionMode.none" - } - }, - "viewSlots": { - "itemView": "(conversation: CometChat.Conversation) => JSX.Element", - "leadingView": "(conversation: CometChat.Conversation) => JSX.Element", - "titleView": "(conversation: CometChat.Conversation) => JSX.Element", - "subtitleView": "(conversation: CometChat.Conversation) => JSX.Element", - "trailingView": "(conversation: CometChat.Conversation) => JSX.Element", - "headerView": "JSX.Element", - "searchView": "JSX.Element", - "loadingView": "JSX.Element", - "emptyView": "JSX.Element", - "errorView": "JSX.Element", - "options": "((conversation: CometChat.Conversation) => CometChatOption[]) | null" - }, - "formatting": { - "textFormatters": { - "type": "CometChatTextFormatter[]", - "default": "default formatters from data source" - } - } - }, - "events": [ - { - "name": "CometChatConversationEvents.ccConversationDeleted", - "payload": "CometChat.Conversation", - "description": "Conversation deleted from list" - }, - { - "name": "CometChatConversationEvents.ccUpdateConversation", - "payload": "CometChat.Conversation", - "description": "Conversation updated" - }, - { - "name": "CometChatConversationEvents.ccMarkConversationAsRead", - "payload": "CometChat.Conversation", - "description": "Conversation marked as read" - } - ], - "sdkListeners": [ - "onTextMessageReceived", - "onMediaMessageReceived", - "onCustomMessageReceived", - "onTypingStarted", - "onTypingEnded", - "onMessagesDelivered", - "onMessagesRead", - "onMessagesDeliveredToAll", - "onMessagesReadByAll", - "onUserOnline", - "onUserOffline", - "onGroupMemberJoined", - "onGroupMemberLeft", - "onGroupMemberKicked", - "onGroupMemberBanned", - "onMemberAddedToGroup" - ], - "compositionExample": { - "description": "Sidebar conversations wired to message view", - "components": [ - "CometChatConversations", - "CometChatMessageHeader", - "CometChatMessageList", - "CometChatMessageComposer" - ], - "flow": "onItemClick emits CometChat.Conversation -> extract User/Group via getConversationWith() -> pass to MessageHeader, MessageList, MessageComposer" - }, - "types": { - "CalendarObject": { - "today": "string | undefined", - "yesterday": "string | undefined", - "lastWeek": "string | undefined", - "otherDays": "string | undefined", - "relativeTime": { - "minute": "string | undefined", - "minutes": "string | undefined", - "hour": "string | undefined", - "hours": "string | undefined" - } - }, - "CometChatOption": { - "id": "string | undefined", - "title": "string | undefined", - "iconURL": "string | undefined", - "onClick": "(() => void) | undefined" - }, - "SelectionMode": { - "single": 0, - "multiple": 1, - "none": 2 - } - } -} -``` - - -## Where It Fits - -`CometChatConversations` is a sidebar list component. It renders recent conversations and emits the selected `CometChat.Conversation` via `onItemClick`. Wire it to `CometChatMessageHeader`, `CometChatMessageList`, and `CometChatMessageComposer` to build a standard two-panel chat layout. - -```tsx lines -import { useState } from "react"; -import { - CometChatConversations, - CometChatMessageHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function ChatApp() { - const [selectedUser, setSelectedUser] = useState(); - const [selectedGroup, setSelectedGroup] = useState(); - - const handleItemClick = (conversation: CometChat.Conversation) => { - const entity = conversation.getConversationWith(); - if (entity instanceof CometChat.User) { - setSelectedUser(entity); - setSelectedGroup(undefined); - } else if (entity instanceof CometChat.Group) { - setSelectedGroup(entity); - setSelectedUser(undefined); - } - }; - - return ( -
-
- -
- {selectedUser || selectedGroup ? ( -
- - - -
- ) : ( -
- Select a conversation -
- )} -
- ); -} -``` - -[Open in CodeSandbox](https://link.cometchat.com/react-conversation-list-message) - - - - - ---- - -## Minimal Render - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function ConversationsDemo() { - return ( -
- -
- ); -} - -export default ConversationsDemo; -``` - - - - - -Root CSS class: `.cometchat-conversations` - ---- - -## Filtering Conversations - -Pass a `CometChat.ConversationsRequestBuilder` to `conversationsRequestBuilder`. Pass the builder instance — not the result of `.build()`. - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function FilteredConversations() { - return ( - - ); -} -``` - -### Filter Recipes - -| Recipe | Code | -| --- | --- | -| Only user conversations | `new CometChat.ConversationsRequestBuilder().setConversationType("user")` | -| Only group conversations | `new CometChat.ConversationsRequestBuilder().setConversationType("group")` | -| Limit to 10 per page | `new CometChat.ConversationsRequestBuilder().setLimit(10)` | -| With specific tags | `new CometChat.ConversationsRequestBuilder().setTags(["vip"])` | -| Filter by user tags | `new CometChat.ConversationsRequestBuilder().withUserAndGroupTags(true).setUserTags(["premium"])` | -| Filter by group tags | `new CometChat.ConversationsRequestBuilder().withUserAndGroupTags(true).setGroupTags(["support"])` | - -Default page size is 30. The component uses infinite scroll — the next page loads as the user scrolls to the bottom. - -Refer to [ConversationRequestBuilder](/sdk/javascript/retrieve-conversations) for the full builder API. - ---- - -## Actions and Events - -### Callback Props - -#### onItemClick - -Fires when a conversation row is tapped. Primary navigation hook — set the active conversation and render the message view. - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function ConversationsWithClick() { - const handleItemClick = (conversation: CometChat.Conversation) => { - console.log("Selected:", conversation.getConversationId()); - }; - - return ; -} -``` - -#### onSelect - -Fires when a conversation is checked/unchecked in multi-select mode. Requires `selectionMode` to be set. - -```tsx lines -import { useState } from "react"; -import { - CometChatConversations, - SelectionMode, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function BatchSelectDemo() { - const [selected, setSelected] = useState>(new Set()); - - const handleSelect = (conversation: CometChat.Conversation, isSelected: boolean) => { - setSelected((prev) => { - const next = new Set(prev); - const id = conversation.getConversationId(); - isSelected ? next.add(id) : next.delete(id); - return next; - }); - }; - - return ( - - ); -} -``` - -#### onError - -Fires on internal errors (network failure, auth issue, SDK exception). - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function ConversationsWithErrorHandler() { - return ( - { - console.error("CometChatConversations error:", error); - }} - /> - ); -} -``` - -#### onSearchBarClicked - -Fires when the search bar is clicked. Requires `showSearchBar={true}`. - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; - -function ConversationsWithSearch() { - return ( - { - console.log("Search bar clicked"); - }} - /> - ); -} -``` - -### Global UI Events - -`CometChatConversationEvents` emits events subscribable from anywhere in the application. Subscribe in a `useEffect` and unsubscribe on cleanup. - -| Event | Fires when | Payload | -| --- | --- | --- | -| `ccConversationDeleted` | A conversation is deleted from the list | `CometChat.Conversation` | -| `ccUpdateConversation` | A conversation is updated (last message change, metadata update) | `CometChat.Conversation` | -| `ccMarkConversationAsRead` | A conversation is marked as read | `CometChat.Conversation` | - -When to use: sync external UI with conversation state changes. For example, update an unread count badge in a tab bar when `ccMarkConversationAsRead` fires, or remove a conversation from a custom sidebar when `ccConversationDeleted` fires. - -```tsx lines -import { useEffect } from "react"; -import { CometChatConversationEvents } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function useConversationEvents() { - useEffect(() => { - const deletedSub = CometChatConversationEvents.ccConversationDeleted.subscribe( - (conversation: CometChat.Conversation) => { - console.log("Deleted:", conversation.getConversationId()); - } - ); - const updatedSub = CometChatConversationEvents.ccUpdateConversation.subscribe( - (conversation: CometChat.Conversation) => { - console.log("Updated:", conversation.getConversationId()); - } - ); - const readSub = CometChatConversationEvents.ccMarkConversationAsRead.subscribe( - (conversation: CometChat.Conversation) => { - console.log("Marked as read:", conversation.getConversationId()); - } - ); - - return () => { - deletedSub?.unsubscribe(); - updatedSub?.unsubscribe(); - readSub?.unsubscribe(); - }; - }, []); -} -``` - -### SDK Events (Real-Time, Automatic) - -The component listens to these SDK events internally. No manual attachment needed unless additional side effects are required. - -| SDK Listener | Internal behavior | -| --- | --- | -| `onTextMessageReceived` / `onMediaMessageReceived` / `onCustomMessageReceived` | Moves conversation to top, updates last message preview and unread count | -| `onTypingStarted` / `onTypingEnded` | Shows/hides typing indicator in the subtitle | -| `onMessagesDelivered` / `onMessagesRead` / `onMessagesDeliveredToAll` / `onMessagesReadByAll` | Updates receipt ticks (unless `hideReceipts={true}`) | -| `onUserOnline` / `onUserOffline` | Updates online/offline status dot (unless `hideUserStatus={true}`) | -| `onGroupMemberJoined` / `onGroupMemberLeft` / `onGroupMemberKicked` / `onGroupMemberBanned` / `onMemberAddedToGroup` | Updates group conversation metadata | - -Automatic: new messages, typing indicators, receipts, user presence, group membership changes. - -Manual: deleting a conversation via the SDK directly (not through the component's context menu) requires emitting `CometChatConversationEvents.ccConversationDeleted` for the UI to update. - - -In React 18 StrictMode, `useEffect` runs twice on mount in development. The component handles listener cleanup internally, but any additional listeners added alongside the component need cleanup in the `useEffect` return function to avoid duplicate event handling. - - ---- - -## Custom View Slots - -Each slot replaces a section of the default UI. Slots that accept a conversation parameter receive the `CometChat.Conversation` object for that row. - -| Slot | Signature | Replaces | -| --- | --- | --- | -| `itemView` | `(conversation: CometChat.Conversation) => JSX.Element` | Entire list item row | -| `leadingView` | `(conversation: CometChat.Conversation) => JSX.Element` | Avatar / left section | -| `titleView` | `(conversation: CometChat.Conversation) => JSX.Element` | Name / title text | -| `subtitleView` | `(conversation: CometChat.Conversation) => JSX.Element` | Last message preview | -| `trailingView` | `(conversation: CometChat.Conversation) => JSX.Element` | Timestamp / badge / right section | -| `headerView` | `JSX.Element` | Entire header bar | -| `searchView` | `JSX.Element` | Search bar | -| `loadingView` | `JSX.Element` | Loading spinner | -| `emptyView` | `JSX.Element` | Empty state | -| `errorView` | `JSX.Element` | Error state | -| `options` | `(conversation: CometChat.Conversation) => CometChatOption[]` | Context menu / hover actions | - -### itemView - -Replace the entire list item row. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatListItem, - CometChatConversations, - CometChatDate, -} from "@cometchat/chat-uikit-react"; - -function CustomItemViewConversations() { - const getItemView = (conversation: CometChat.Conversation) => { - const title = conversation.getConversationWith().getName(); - const timestamp = conversation?.getLastMessage()?.getSentAt(); - - return ( - } - onListItemClicked={() => { - // handle click - }} - /> - ); - }; - - return ; -} -``` - - -```css lines -.cometchat-conversations .cometchat-avatar { - border-radius: 8px; - width: 32px; - height: 32px; -} - -.cometchat-conversations .cometchat-list-item { - gap: 4px; -} -``` - - - -### leadingView - -Replace the avatar / left section. Typing-aware avatar example. - - - - - -```tsx lines -import { useEffect, useRef, useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatConversations, - CometChatAvatar, - CometChatUIKitLoginListener, -} from "@cometchat/chat-uikit-react"; - -function TypingAwareConversations() { - const [isTyping, setIsTyping] = useState(false); - const typingObjRef = useRef(null); - const loggedInUser = CometChatUIKitLoginListener.getLoggedInUser(); - - useEffect(() => { - const listenerId = "typing_demo_" + Date.now(); - CometChat.addMessageListener( - listenerId, - new CometChat.MessageListener({ - onTypingStarted: (typingIndicator: CometChat.TypingIndicator) => { - typingObjRef.current = typingIndicator; - setIsTyping(true); - }, - onTypingEnded: (typingIndicator: CometChat.TypingIndicator) => { - if ( - typingObjRef.current && - typingObjRef.current.getSender().getUid() === - typingIndicator.getSender().getUid() - ) { - typingObjRef.current = null; - setIsTyping(false); - } - }, - }) - ); - return () => { - CometChat.removeMessageListener(listenerId); - }; - }, []); - - const getLeadingView = (conversation: CometChat.Conversation) => { - const entity = conversation.getConversationWith(); - const isUser = entity instanceof CometChat.User; - const isGroup = entity instanceof CometChat.Group; - - const isMyTyping = isUser - ? (entity as CometChat.User).getUid() === - typingObjRef.current?.getSender().getUid() && - loggedInUser?.getUid() === typingObjRef.current?.getReceiverId() - : isGroup && - (entity as CometChat.Group).getGuid() === - typingObjRef.current?.getReceiverId(); - - const avatar = isUser - ? (entity as CometChat.User).getAvatar() - : (entity as CometChat.Group).getIcon(); - - return ( -
- -
- ); - }; - - return ; -} -``` - -### trailingView - -Replace the timestamp / badge / right section. Relative time badge example. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatConversations } from "@cometchat/chat-uikit-react"; - -function RelativeTimeConversations() { - const getTrailingView = (conv: CometChat.Conversation) => { - if (!conv.getLastMessage()) return <>; - - const timestamp = conv.getLastMessage()?.getSentAt() * 1000; - const now = Date.now(); - const diffInMinutes = Math.floor((now - timestamp) / (1000 * 60)); - const diffInHours = Math.floor((now - timestamp) / (1000 * 60 * 60)); - - let className = "conversations__trailing-view-min"; - let topLabel = `${diffInMinutes}`; - let bottomLabel = diffInMinutes === 1 ? "Min ago" : "Mins ago"; - - if (diffInHours >= 1 && diffInHours <= 10) { - className = "conversations__trailing-view-hour"; - topLabel = `${diffInHours}`; - bottomLabel = diffInHours === 1 ? "Hour ago" : "Hours ago"; - } else if (diffInHours > 10) { - className = "conversations__trailing-view-date"; - const time = new Date(timestamp); - topLabel = time.toLocaleDateString("en-US", { day: "numeric" }); - bottomLabel = time.toLocaleDateString("en-US", { month: "short", year: "numeric" }); - } - - return ( -
- {topLabel} - {bottomLabel} -
- ); - }; - - return ; -} -``` -
- -```css lines -.conversations__trailing-view { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 55px; - height: 40px; - border-radius: 8px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.conversations__trailing-view-min { background-color: #e0d4f7; } -.conversations__trailing-view-hour { background-color: #fff3cd; } -.conversations__trailing-view-date { background-color: #f8d7da; } - -.conversations__trailing-view-time { - font: 600 18px Roboto; - color: #4a3f99; - margin-bottom: 4px; -} - -.conversations__trailing-view-status { - font: 600 8px Roboto; - color: #6a5b99; -} - -.cometchat-conversations .cometchat-list-item__trailing-view { - height: 50px; -} -``` - -
- -### titleView - -Replace the name / title text. Inline user status example. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatConversations } from "@cometchat/chat-uikit-react"; - -function StatusTitleConversations() { - const getTitleView = (conversation: CometChat.Conversation) => { - const user = - conversation.getConversationType() === "user" - ? (conversation.getConversationWith() as CometChat.User) - : undefined; - - return ( -
- - {user - ? conversation.getConversationWith().getName() + " · " - : conversation.getConversationWith().getName()} - - {user && ( - - {user.getStatusMessage()} - - )} -
- ); - }; - - return ; -} -``` -
- -```css lines -.cometchat-conversations .conversations__title-view { - display: flex; - gap: 4px; - width: 100%; -} - -.conversations__title-view-name { - color: #141414; - font: 500 16px/19.2px Roboto; -} - -.conversations__title-view-status { - color: #6852d6; - font: 400 16px/19.2px Roboto; -} -``` - -
- -### subtitleView - -Replace the last message preview text. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatConversations } from "@cometchat/chat-uikit-react"; - -function formatTimestamp(timestamp: number): string { - return new Date(timestamp * 1000).toLocaleString(); -} - -function SubtitleConversations() { - const getSubtitleView = (conversation: CometChat.Conversation) => { - if (conversation.getConversationType() === "user") { - return ( - <> - Last active:{" "} - {formatTimestamp( - (conversation.getConversationWith() as CometChat.User).getLastActiveAt() - )} - - ); - } - return ( - <> - Created:{" "} - {formatTimestamp( - (conversation.getConversationWith() as CometChat.Group).getCreatedAt() - )} - - ); - }; - - return ; -} -``` - - -```css lines -.cometchat-conversations .cometchat-list-item__body-subtitle { - overflow: hidden; - color: var(--cometchat-text-color-secondary, #727272); - text-overflow: ellipsis; - white-space: nowrap; - font: var(--cometchat-font-body-regular); -} -``` - - - -### headerView - -Replace the entire header bar. - - - - - - - -```tsx lines -import { - CometChatButton, - CometChatConversations, - getLocalizedString, -} from "@cometchat/chat-uikit-react"; - -function CustomHeaderConversations() { - return ( - -
- {getLocalizedString("CHATS")} -
- { /* handle click */ }} /> -
- } - /> - ); -} -``` -
- -```css lines -.conversations__header { - display: flex; - width: 100%; - padding: 8px 16px; - align-items: center; - justify-content: space-between; - gap: 12px; - border-radius: 10px; - border: 1px solid #e8e8e8; - background: #edeafa; -} - -.conversations__header__title { - overflow: hidden; - color: #141414; - text-overflow: ellipsis; - font: 700 24px Roboto; -} - -.conversations__header .cometchat-button .cometchat-button__icon { - background: #141414; -} - -.conversations__header .cometchat-button { - width: 24px; - border: none; - background: transparent; - border-radius: 0; -} -``` - -
- -### options - -Replace the context menu / hover actions on each conversation item. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatOption, - CometChatConversations, -} from "@cometchat/chat-uikit-react"; - -function CustomOptionsConversations() { - const getOptions = (conversation: CometChat.Conversation) => [ - new CometChatOption({ - title: "Delete", - id: "delete", - onClick: () => { /* delete logic */ }, - }), - new CometChatOption({ - title: "Mute Notification", - id: "mute", - onClick: () => { /* mute logic */ }, - }), - new CometChatOption({ - title: "Mark as Unread", - id: "unread", - onClick: () => { /* mark unread logic */ }, - }), - new CometChatOption({ - title: "Block", - id: "block", - onClick: () => { /* block logic */ }, - }), - ]; - - return ; -} -``` - - -```css lines -.cometchat-conversations .cometchat-menu-list__main-menu-item-icon-delete { - background: red; -} - -.cometchat-conversations .cometchat-menu-list__sub-menu { - background: transparent; - box-shadow: none; -} -``` - - - -```ts lines -// CometChatOption interface -interface CometChatOption { - id?: string; // Unique identifier - title?: string; // Display text - iconURL?: string; // Icon asset URL - onClick?: () => void; // Click handler -} -``` - -### textFormatters - -Custom text formatters for the conversation subtitle. Array of `CometChatTextFormatter` instances. If not provided, default formatters from the data source are used. - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; -import ShortcutFormatter from "./ShortCutFormatter"; - -function FormattedConversations() { - return ( - - ); -} -``` - -See [CometChatMentionsFormatter](/ui-kit/react/mentions-formatter-guide) for mention formatting. - -### lastMessageDateTimeFormat - -Customize the last message timestamp format using a `CalendarObject`. - -```ts lines -// CalendarObject interface (from source) -class CalendarObject { - today?: string; - yesterday?: string; - lastWeek?: string; - otherDays?: string; - relativeTime?: { - minute?: string; - minutes?: string; - hour?: string; - hours?: string; - }; -} -``` - -```tsx lines -import { - CometChatConversations, - CalendarObject, -} from "@cometchat/chat-uikit-react"; - -function CustomDateConversations() { - const dateFormat = new CalendarObject({ - today: "DD MMM, hh:mm A", - yesterday: "DD MMM, hh:mm A", - otherDays: "DD MMM, hh:mm A", - }); - - return ; -} -``` - - -If no property is passed in the [CalendarObject](/ui-kit/react/localize#calendarobject), the component checks the [global configuration](/ui-kit/react/localize#customisation) first. If also missing there, the component's default formatting applies. - - ---- - -## Common Patterns - -### Custom empty state with CTA - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; - -function EmptyStateConversations() { - return ( - -

No conversations yet

- - - } - /> - ); -} -``` - -### Hide all chrome — minimal list - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; - -function MinimalConversations() { - return ( - - ); -} -``` - -### Conversations with search - -```tsx lines -import { CometChatConversations } from "@cometchat/chat-uikit-react"; - -function SearchableConversations() { - return ( - - ); -} -``` - ---- - -## CSS Architecture - -The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade: - -1. Global tokens (e.g., `--cometchat-primary-color`, `--cometchat-background-color-01`) are set on the `.cometchat` root wrapper. -2. Component CSS (`.cometchat-conversations`) consumes these tokens via `var()` with fallback values. -3. Overrides target `.cometchat-conversations` descendant selectors in a global stylesheet. - -To scope overrides to a single instance when multiple `CometChatConversations` exist on the same page, wrap the component in a container and scope selectors: - -```css lines -.sidebar-left .cometchat-conversations .cometchat-badge { - background: #e5484d; -} -``` - -Overrides survive component updates because the component never sets inline styles on these elements — all styling flows through CSS classes and custom properties. - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-conversations` | -| Header title | `.cometchat-conversations .cometchat-list__header-title` | -| List item | `.cometchat-conversations .cometchat-list-item` | -| Body title | `.cometchat-conversations .cometchat-list-item__body-title` | -| Avatar | `.cometchat-conversations .cometchat-avatar` | -| Avatar text | `.cometchat-conversations .cometchat-avatar__text` | -| Unread badge | `.cometchat-conversations .cometchat-badge` | -| Subtitle text | `.cometchat-conversations .cometchat-conversations__subtitle-text` | -| Status indicator | `.cometchat-conversations .cometchat-status-indicator` | -| Read receipts | `.cometchat-conversations .cometchat-receipts-read` | -| Active item | `.cometchat-conversations__list-item-active .cometchat-list-item` | -| Typing indicator | `.cometchat-conversations__subtitle-typing` | -| Trailing view | `.cometchat-conversations__trailing-view` | - -### Example: Brand-themed conversations - - - - - -```css lines -.cometchat-conversations .cometchat-list-item__body-title, -.cometchat-conversations .cometchat-list__header-title, -.cometchat-conversations .cometchat-avatar__text, -.cometchat-conversations .cometchat-badge, -.cometchat-conversations .cometchat-conversations__subtitle-text { - font-family: "SF Pro"; -} - -.cometchat-conversations .cometchat-list__header-title { - background: #fef8f8; - border-bottom: 2px solid #f4b6b8; -} - -.cometchat-conversations .cometchat-avatar { - background: #f0999b; -} - -.cometchat-conversations .cometchat-status-indicator { - min-width: 10px; - height: 10px; -} - -.cometchat-conversations .cometchat-badge { - background: #e5484d; -} - -.cometchat-conversations .cometchat-receipts-read { - background: #e96b6f; -} -``` - -### Customization Matrix - -| What to change | Where | Property/API | Example | -| --- | --- | --- | --- | -| Override behavior on user interaction | Component props | `on` callbacks | `onItemClick={(c) => setActive(c)}` | -| Filter which conversations appear | Component props | `conversationsRequestBuilder` | `conversationsRequestBuilder={new CometChat.ConversationsRequestBuilder().setLimit(10)}` | -| Toggle visibility of UI elements | Component props | `hide` boolean props | `hideReceipts={true}` | -| Replace a section of the list item | Component props | `View` render props | `itemView={(conversation) =>
...
}` | -| Change colors, fonts, spacing | Global CSS | Target `.cometchat-conversations` class | `.cometchat-conversations .cometchat-badge { background: #e5484d; }` | - ---- - -## Props - -All props are optional. Sorted alphabetically. - -### activeConversation - -Highlights the specified conversation in the list. - -| | | -| --- | --- | -| Type | `CometChat.Conversation` | -| Default | `undefined` | - -Must be a reference-equal object from the SDK; a manually constructed object will not match. - ---- - -### conversationsRequestBuilder - -Controls which conversations load and in what order. - -| | | -| --- | --- | -| Type | `CometChat.ConversationsRequestBuilder` | -| Default | SDK default (30 per page) | - -Pass the builder instance, not the result of `.build()`. - ---- - -### customSoundForMessages - -URL to a custom audio file for incoming message notifications. - -| | | -| --- | --- | -| Type | `string` | -| Default | Built-in sound | - -Must be a valid audio URL accessible from the browser. - ---- - -### disableSoundForMessages - -Disables the notification sound for incoming messages. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### emptyView - -Custom component displayed when there are no conversations. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in empty state | - ---- - -### errorView - -Custom component displayed when an error occurs. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in error state | - -Hidden when `hideError={true}`. - ---- - -### headerView - -Custom component rendered as the entire header bar. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in header with title | - ---- - -### hideDeleteConversation - -Hides the delete option in the context menu. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideError - -Hides the default and custom error views. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - -Also suppresses `errorView` if set. - ---- - -### hideGroupType - -Hides the group type icon (public/private/password). - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideReceipts - -Hides message read/delivery receipt indicators. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideUserStatus - -Hides the online/offline status indicator. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### itemView - -Custom renderer for the entire list item row. - -| | | -| --- | --- | -| Type | `(conversation: CometChat.Conversation) => JSX.Element` | -| Default | Built-in list item | - ---- - -### lastMessageDateTimeFormat - -Format for displaying the timestamp of the last message. - -| | | -| --- | --- | -| Type | `CalendarObject` | -| Default | Component default (`hh:mm A` today, `[yesterday]`, `DD/MM/YYYY` other days) | - -```ts lines -class CalendarObject { - today?: string; - yesterday?: string; - lastWeek?: string; - otherDays?: string; - relativeTime?: { - minute?: string; - minutes?: string; - hour?: string; - hours?: string; - }; -} -``` - -Falls back to [global calendar configuration](/ui-kit/react/localize#customisation) if not set. - ---- - -### leadingView - -Custom renderer for the avatar / left section. - -| | | -| --- | --- | -| Type | `(conversation: CometChat.Conversation) => JSX.Element` | -| Default | Built-in avatar | - ---- - -### loadingView - -Custom component displayed during the loading state. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in shimmer | - ---- - -### onError - -Callback fired when the component encounters an error. - -| | | -| --- | --- | -| Type | `((error: CometChat.CometChatException) => void) \| null` | -| Default | `undefined` | - ---- - -### onItemClick - -Callback fired when a conversation row is clicked. - -| | | -| --- | --- | -| Type | `(conversation: CometChat.Conversation) => void` | -| Default | `undefined` | - ---- - -### onSearchBarClicked - -Callback fired when the search bar is clicked. Requires `showSearchBar={true}`. - -| | | -| --- | --- | -| Type | `() => void` | -| Default | `undefined` | - ---- - -### onSelect - -Callback fired when a conversation is selected/deselected. Requires `selectionMode` to be set. - -| | | -| --- | --- | -| Type | `(conversation: CometChat.Conversation, selected: boolean) => void` | -| Default | `undefined` | - ---- - -### options - -Custom context menu / hover actions for each conversation item. - -| | | -| --- | --- | -| Type | `((conversation: CometChat.Conversation) => CometChatOption[]) \| null` | -| Default | Built-in delete option | - -```ts lines -class CometChatOption { - id?: string; - title?: string; - iconURL?: string; - onClick?: () => void; -} -``` - ---- - -### searchView - -Custom search bar component in the header. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in search bar | - ---- - -### selectionMode - -Enables single or multi-select checkboxes on list items. - -| | | -| --- | --- | -| Type | `SelectionMode` | -| Default | `SelectionMode.none` | - -```ts lines -enum SelectionMode { - single, // 0 - multiple, // 1 - none, // 2 -} -``` - -Must pair with `onSelect` to capture selections. - ---- - -### showScrollbar - -Shows the scrollbar in the conversation list. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### showSearchBar - -Shows a search bar at the top of the list. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### subtitleView - -Custom renderer for the last message preview text. - -| | | -| --- | --- | -| Type | `(conversation: CometChat.Conversation) => JSX.Element` | -| Default | Built-in subtitle | - ---- - -### textFormatters - -Custom text formatters for the conversation subtitle. - -| | | -| --- | --- | -| Type | `CometChatTextFormatter[]` | -| Default | Default formatters from data source | - -See [CometChatMentionsFormatter](/ui-kit/react/mentions-formatter-guide) for mention formatting. - ---- - -### titleView - -Custom renderer for the name / title text. - -| | | -| --- | --- | -| Type | `(conversation: CometChat.Conversation) => JSX.Element` | -| Default | Built-in title | - ---- - -### trailingView - -Custom renderer for the timestamp / badge / right section. - -| | | -| --- | --- | -| Type | `(conversation: CometChat.Conversation) => JSX.Element` | -| Default | Built-in trailing view | - ---- - -## Events - -| Event | Payload | Fires when | -| --- | --- | --- | -| `CometChatConversationEvents.ccConversationDeleted` | `CometChat.Conversation` | Conversation deleted from list | -| `CometChatConversationEvents.ccUpdateConversation` | `CometChat.Conversation` | Conversation updated | -| `CometChatConversationEvents.ccMarkConversationAsRead` | `CometChat.Conversation` | Conversation marked as read | - -All events are `Subject` from RxJS. Subscribe with `.subscribe()`, unsubscribe with the returned subscription's `.unsubscribe()`. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-conversations` | -| Header title | `.cometchat-conversations .cometchat-list__header-title` | -| List item | `.cometchat-conversations .cometchat-list-item` | -| Body title | `.cometchat-conversations .cometchat-list-item__body-title` | -| Avatar | `.cometchat-conversations .cometchat-avatar` | -| Avatar text | `.cometchat-conversations .cometchat-avatar__text` | -| Unread badge | `.cometchat-conversations .cometchat-badge` | -| Subtitle text | `.cometchat-conversations .cometchat-conversations__subtitle-text` | -| Subtitle sender | `.cometchat-conversations__subtitle-text-sender` | -| Status indicator (online) | `.cometchat-conversations__list-item-online .cometchat-list-item__status` | -| Group type (password) | `.cometchat-conversations__list-item-password .cometchat-list-item__status` | -| Group type (private) | `.cometchat-conversations__list-item-private .cometchat-list-item__status` | -| Read receipts | `.cometchat-conversations__subtitle-receipts-read` | -| Delivered receipts | `.cometchat-conversations__subtitle-receipts-delivered` | -| Sent receipts | `.cometchat-conversations__subtitle-receipts-sent` | -| Error receipts | `.cometchat-conversations__subtitle-receipts-error` | -| Active item | `.cometchat-conversations__list-item-active .cometchat-list-item` | -| Typing indicator | `.cometchat-conversations__subtitle-typing` | -| Trailing view | `.cometchat-conversations__trailing-view` | -| Badge count | `.cometchat-conversations__trailing-view-badge-count` | -| Empty state | `.cometchat-conversations__empty-state-view` | -| Error state | `.cometchat-conversations__error-state-view` | -| Shimmer loading | `.cometchat-conversations__shimmer` | -| Context menu | `.cometchat-conversations__trailing-view-options` | -| Mentions highlight | `.cometchat-conversations__subtitle-text .cometchat-mentions` | -| @you mentions | `.cometchat-conversations__subtitle-text .cometchat-mentions-you` | diff --git a/ui-kit/react/core-features.mdx b/ui-kit/react/core-features.mdx index d6f66ecba..b468b3c66 100644 --- a/ui-kit/react/core-features.mdx +++ b/ui-kit/react/core-features.mdx @@ -8,11 +8,11 @@ description: "Overview of CometChat React UI Kit core features, including messag | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Required setup | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` — must complete before rendering any component | +| Required setup | Wrap app in `CometChatProvider` with valid credentials — must complete before rendering any component | | Core features | Instant Messaging, Media Sharing, Read Receipts, Mark as Unread, Typing Indicator, User Presence, Reactions, Mentions, Quoted Reply, Search, Threaded Conversations, Moderation, Report Message, Group Chat | -| Key components | `CometChatConversations` → [Conversations](/ui-kit/react/conversations), `CometChatMessageList` → [Message List](/ui-kit/react/message-list), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/message-composer), `CometChatMessageHeader` → [Message Header](/ui-kit/react/message-header), `CometChatUsers` → [Users](/ui-kit/react/users), `CometChatGroups` → [Groups](/ui-kit/react/groups), `CometChatGroupMembers` → [Group Members](/ui-kit/react/group-members) | +| Key components | `CometChatConversations` → [Conversations](/ui-kit/react/components/conversations), `CometChatMessageList` → [Message List](/ui-kit/react/components/message-list), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/components/message-composer), `CometChatMessageHeader` → [Message Header](/ui-kit/react/components/message-header), `CometChatUsers` → [Users](/ui-kit/react/components/users), `CometChatGroups` → [Groups](/ui-kit/react/components/groups), `CometChatGroupMembers` → [Group Members](/ui-kit/react/components/group-members) | | CSS class prefix | `.cometchat-` | -| Theming | Override CSS variables on `.cometchat` class. See [Theming](/ui-kit/react/theme) | +| Theming | Override CSS variables on `.cometchat` class. See [Theming](/ui-kit/react/theming) | @@ -28,8 +28,8 @@ At the heart of CometChat's functionality is the ability to support real-time te | Components | Functionality | | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [Message Composer](/ui-kit/react/message-composer) | The [Message Composer](/ui-kit/react/message-composer) is a Component that enables users to write and send a variety of messages. | -| [Message List](/ui-kit/react/message-list) | The [Message List](/ui-kit/react/message-list) is a Component that renders a list of messages sent and messages received using Text Bubble. | +| [Message Composer](/ui-kit/react/components/message-composer) | The [Message Composer](/ui-kit/react/components/message-composer) is a Component that enables users to write and send a variety of messages. | +| [Message List](/ui-kit/react/components/message-list) | The [Message List](/ui-kit/react/components/message-list) is a Component that renders a list of messages sent and messages received using Text Bubble. | ## Media Sharing @@ -41,8 +41,8 @@ CometChat supports sharing images, videos, audio files, and documents within con | Components | Functionality | | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message Composer](/ui-kit/react/message-composer) | The [Message Composer](/ui-kit/react/message-composer) component includes an ActionSheet. This ActionSheet serves as a menu appearing over the app's context, offering various options for sharing media files. | -| [Message List](/ui-kit/react/message-list) | The [Message List](/ui-kit/react/message-list) component is responsible for rendering various Media Message bubbles, such as Image, File, Audio & Video Bubble. | +| [Message Composer](/ui-kit/react/components/message-composer) | The [Message Composer](/ui-kit/react/components/message-composer) component includes an ActionSheet. This ActionSheet serves as a menu appearing over the app's context, offering various options for sharing media files. | +| [Message List](/ui-kit/react/components/message-list) | The [Message List](/ui-kit/react/components/message-list) component is responsible for rendering various Media Message bubbles, such as Image, File, Audio & Video Bubble. | ## Read Receipts @@ -54,8 +54,8 @@ CometChat's Read Receipts feature provides visibility into the message status, l | Components | Functionality | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [Conversations](/ui-kit/react/conversations) | [Conversations](/ui-kit/react/conversations) is a component that renders conversation list item. Conversation item also displays the delivery status of the last message providing users with real-time updates on the status of their messages. | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) is a component that renders different types of message bubbles. Read receipt status is an integral part of all message bubbles, no matter the type and provides real-time updates about the status of the message. | +| [Conversations](/ui-kit/react/components/conversations) | [Conversations](/ui-kit/react/components/conversations) is a component that renders conversation list item. Conversation item also displays the delivery status of the last message providing users with real-time updates on the status of their messages. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) is a component that renders different types of message bubbles. Read receipt status is an integral part of all message bubbles, no matter the type and provides real-time updates about the status of the message. | | Message Information | Message Information component provides transparency into the status of each sent message, giving the sender insights into whether their message has been delivered and read. | ## Mark as Unread @@ -68,8 +68,8 @@ CometChat's Read Receipts feature provides visibility into the message status, l | Components | Functionality | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) provides the "Mark as unread" option in message actions and supports starting from the first unread message when enabled. | -| [Conversations](/ui-kit/react/conversations) | [Conversations](/ui-kit/react/conversations) component listens to conversation updates and reflects the updated unread count in real-time. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) provides the "Mark as unread" option in message actions and supports starting from the first unread message when enabled. | +| [Conversations](/ui-kit/react/components/conversations) | [Conversations](/ui-kit/react/components/conversations) component listens to conversation updates and reflects the updated unread count in real-time. | ## Typing Indicator @@ -81,8 +81,8 @@ The Typing Indicator feature in CometChat shows when a user is typing a response | Components | Functionality | | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Conversations](/ui-kit/react/conversations) | [Conversations](/ui-kit/react/conversations) is a component that renders conversation list item. Conversations item also shows real-time typing status indicators. This means that if a user in a one-on-one chat or a participant in a group chat is currently typing a message. | -| [Message Header](/ui-kit/react/message-header) | [Message Header](/ui-kit/react/message-header) that renders details of User or Groups in ToolBar. The Message Header also handles the typing indicator functionality. When a user or a member in a group is typing, the Message Header dynamically updates to display a `typing...` status in real-time. | +| [Conversations](/ui-kit/react/components/conversations) | [Conversations](/ui-kit/react/components/conversations) is a component that renders conversation list item. Conversations item also shows real-time typing status indicators. This means that if a user in a one-on-one chat or a participant in a group chat is currently typing a message. | +| [Message Header](/ui-kit/react/components/message-header) | [Message Header](/ui-kit/react/components/message-header) that renders details of User or Groups in ToolBar. The Message Header also handles the typing indicator functionality. When a user or a member in a group is typing, the Message Header dynamically updates to display a `typing...` status in real-time. | ## User Presence @@ -94,10 +94,10 @@ CometChat's User Presence feature allows users to see whether their contacts are | Components | Functionality | | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Conversations](/ui-kit/react/conversations) | [Conversations](/ui-kit/react/conversations) is a component that renders conversation list item. Conversations item also shows user presence information. | -| [Message Header](/ui-kit/react/message-header) | [Message Header](/ui-kit/react/message-header) that renders details of user/group. The Message Header also handles user presence information. | -| [Users](/ui-kit/react/users) | [Users](/ui-kit/react/users) renders the list of available users with presence information. | -| [Group Members](/ui-kit/react/group-members) | [Group Members](/ui-kit/react/group-members) renders list of users available in the group. The Group Members component also handles user presence information. | +| [Conversations](/ui-kit/react/components/conversations) | [Conversations](/ui-kit/react/components/conversations) is a component that renders conversation list item. Conversations item also shows user presence information. | +| [Message Header](/ui-kit/react/components/message-header) | [Message Header](/ui-kit/react/components/message-header) that renders details of user/group. The Message Header also handles user presence information. | +| [Users](/ui-kit/react/components/users) | [Users](/ui-kit/react/components/users) renders the list of available users with presence information. | +| [Group Members](/ui-kit/react/components/group-members) | [Group Members](/ui-kit/react/components/group-members) renders list of users available in the group. The Group Members component also handles user presence information. | ## Reactions @@ -109,7 +109,7 @@ CometChat's Reactions feature adds a layer of expressiveness to your chat applic | Components | Functionality | | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) is a component that renders different types of message bubbles. Reactions are an integral part and offer a more engaging, expressive way for users to respond to messages. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) is a component that renders different types of message bubbles. Reactions are an integral part and offer a more engaging, expressive way for users to respond to messages. | ## Mentions @@ -121,9 +121,9 @@ Mentions is a robust feature provided by CometChat that enhances the interactivi | Components | Functionality | | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Conversations](/ui-kit/react/conversations) | [Conversations](/ui-kit/react/conversations) component provides an enhanced user experience by integrating the Mentions feature. This means that from the conversation list itself, users can see where they or someone else have been specifically mentioned. | -| [Message Composer](/ui-kit/react/message-composer) | [Message Composer](/ui-kit/react/message-composer) is a component that allows users to craft and send various types of messages, including the usage of the mentions feature for direct addressing within the conversation. | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) is a component that displays a list of sent and received messages. It also supports the rendering of Mentions, enhancing the readability and interactivity of conversations. | +| [Conversations](/ui-kit/react/components/conversations) | [Conversations](/ui-kit/react/components/conversations) component provides an enhanced user experience by integrating the Mentions feature. This means that from the conversation list itself, users can see where they or someone else have been specifically mentioned. | +| [Message Composer](/ui-kit/react/components/message-composer) | [Message Composer](/ui-kit/react/components/message-composer) is a component that allows users to craft and send various types of messages, including the usage of the mentions feature for direct addressing within the conversation. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) is a component that displays a list of sent and received messages. It also supports the rendering of Mentions, enhancing the readability and interactivity of conversations. | ## Rich Text Formatting @@ -135,8 +135,8 @@ Rich Text Formatting allows users to style their messages with bold, italic, und | Components | Functionality | | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [CompactMessageComposer](/ui-kit/react/compact-message-composer) | [CompactMessageComposer](/ui-kit/react/compact-message-composer) provides a built-in rich text editor with formatting toolbar, floating selection toolbar, and keyboard shortcuts for bold, italic, underline, strikethrough, code, links, lists, and blockquotes. | -| [MessageList](/ui-kit/react/message-list) | [MessageList](/ui-kit/react/message-list) renders formatted messages with the appropriate styling applied, displaying bold, italic, underline, strikethrough, code, links, lists, and blockquote formatting as intended by the sender. | +| [Message Composer](/ui-kit/react/components/message-composer) | [Message Composer](/ui-kit/react/components/message-composer) with `enableRichTextEditor` provides a built-in rich text editor with formatting toolbar, floating selection toolbar, and keyboard shortcuts for bold, italic, underline, strikethrough, code, links, lists, and blockquotes. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) renders formatted messages with the appropriate styling applied, displaying bold, italic, underline, strikethrough, code, links, lists, and blockquote formatting as intended by the sender. | ## Threaded Conversations @@ -160,8 +160,8 @@ Quoted Replies is a robust feature provided by CometChat that enables users to q | Components | Functionality | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) supports replying to messages via the "Reply" option. Users can select "Reply" on a message to open the composer with the quoted reply pre-filled, maintaining context. | -| [Message Composer](/ui-kit/react/message-composer) | [Message Composer](/ui-kit/react/message-composer) shows the quoted reply above the input field, providing context for the response. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) supports replying to messages via the "Reply" option. Users can select "Reply" on a message to open the composer with the quoted reply pre-filled, maintaining context. | +| [Message Composer](/ui-kit/react/components/message-composer) | [Message Composer](/ui-kit/react/components/message-composer) shows the quoted reply above the input field, providing context for the response. | ## Group Chat @@ -171,7 +171,7 @@ CometChat facilitates Group Chats, allowing users to have conversations with mul -See the [Groups](/ui-kit/react/groups) component page for details. +See the [Groups](/ui-kit/react/components/groups) component page for details. ## Moderation @@ -187,7 +187,7 @@ Learn more about setting up moderation rules and managing content in the [Modera | Components | Functionality | | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) automatically handles moderated messages, displaying blocked content based on moderation settings. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) automatically handles moderated messages, displaying blocked content based on moderation settings. | The **[Report Message](#report-message)** feature enables users to flag messages for review by moderators. @@ -205,7 +205,7 @@ Learn more about how flagged messages are handled, reviewed, and moderated in th | Components | Functionality | | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) provides the "Report Message" option in the message actions menu, allowing users to initiate the reporting process for inappropriate messages. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) provides the "Report Message" option in the message actions menu, allowing users to initiate the reporting process for inappropriate messages. | ## Conversation and Advanced Search @@ -217,12 +217,12 @@ Conversation and Advanced Search is a powerful feature provided by CometChat tha | Components | Functionality | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Search](/ui-kit/react/search) | [Search](/ui-kit/react/search) allows users to search across conversations and messages in real time. Users can click on a result to open the conversation or jump directly to a specific message. | -| [Message Header](/ui-kit/react/message-header) | [Message Header](/ui-kit/react/message-header) shows the search button in the chat header, allowing users to search within a conversation. | -| [Message List](/ui-kit/react/message-list) | [Message List](/ui-kit/react/message-list) shows the selected message when clicked from search results and highlights it in the message list. | -| [Conversations](/ui-kit/react/conversations) | [Conversations](/ui-kit/react/conversations) displays the search input. | +| [Search](/ui-kit/react/components/search) | [Search](/ui-kit/react/components/search) allows users to search across conversations and messages in real time. Users can click on a result to open the conversation or jump directly to a specific message. | +| [Message Header](/ui-kit/react/components/message-header) | [Message Header](/ui-kit/react/components/message-header) shows the search button in the chat header, allowing users to search within a conversation. | +| [Message List](/ui-kit/react/components/message-list) | [Message List](/ui-kit/react/components/message-list) shows the selected message when clicked from search results and highlights it in the message list. | +| [Conversations](/ui-kit/react/components/conversations) | [Conversations](/ui-kit/react/components/conversations) displays the search input. | -See the [Groups](/ui-kit/react/groups) component page for details. +See the [Groups](/ui-kit/react/components/groups) component page for details. --- @@ -232,7 +232,7 @@ See the [Groups](/ui-kit/react/groups) component page for details. Browse all available UI Kit components - + Customize the look and feel of your chat UI diff --git a/ui-kit/react/custom-text-formatter-guide.mdx b/ui-kit/react/custom-text-formatter-guide.mdx deleted file mode 100644 index 5411a5ec3..000000000 --- a/ui-kit/react/custom-text-formatter-guide.mdx +++ /dev/null @@ -1,397 +0,0 @@ ---- -title: "Custom Text Formatter" -description: "Extend the CometChatTextFormatter base class to implement custom inline text patterns with regex and callbacks." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Key class | `CometChatTextFormatter` (abstract base class for custom formatters) | -| Required setup | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` | -| Purpose | Extend to create custom inline text patterns with regex, styling, and callbacks | -| Features | Text formatting, customizable styles, dynamic text replacement, input field integration, key event callbacks | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [ShortCut Formatter](/ui-kit/react/shortcut-formatter-guide) \| [Mentions Formatter](/ui-kit/react/mentions-formatter-guide) \| [All Guides](/ui-kit/react/guide-overview) | - - - -`CometChatTextFormatter` is an abstract class for formatting text in the message composer and message bubbles. Extend it to build custom formatters — hashtags, keywords, or any regex-based pattern. - -| Capability | Description | -| --- | --- | -| Text formatting | Auto-format text based on regex patterns and styles | -| Custom styles | Set colors, fonts, and backgrounds for matched text | -| Dynamic replacement | Regex-based find-and-replace in user input | -| Input integration | Real-time monitoring of the composer input field | -| 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. - - ---- - -## Steps - -### 1. Import the base class - -```javascript lines -import { CometChatTextFormatter } from "@cometchat/chat-uikit-react"; -``` - -### 2. Extend it - -```javascript lines -class HashTagTextFormatter extends CometChatTextFormatter { - ... -} -``` - -### 3. Configure tracking character and regex - -Set the character that triggers formatting, the regex to match, and the regex to strip formatting back to plain text. - -```javascript lines -this.setTrackingCharacter("#"); -this.setRegexPatterns([/\B#(\w+)\b/g]); -this.setRegexToReplaceFormatting([ - /#(\w+)<\/span>/g, -]); -``` - -### 4. Set key event callbacks - -```javascript lines -this.setKeyUpCallBack(this.onKeyUp.bind(this)); -this.setKeyDownCallBack(this.onKeyDown.bind(this)); -``` - -### 5. Implement formatting methods - -```typescript lines -getFormattedText(inputText:string) { ... } -getOriginalText(inputText:string) { ... } -customLogicToFormatText(inputText: string) { ... } -``` - ---- - -## Example - -A hashtag formatter used with [CometChatMessageList](/ui-kit/react/message-list) and [CometChatMessageComposer](/ui-kit/react/message-composer). - - - - - - - -```ts lines -import { CometChatTextFormatter } from "@cometchat/chat-uikit-react"; - -class HashTagTextFormatter extends CometChatTextFormatter { - constructor() { - super(); - this.setTrackingCharacter("#"); - this.setRegexPatterns([/\B#(\w+)\b/g]); - this.setRegexToReplaceFormatting([/#(\w+)/g]); - this.setKeyUpCallBack(this.onKeyUp.bind(this)); - this.setKeyDownCallBack(this.onKeyDown.bind(this)); - this.setReRender(() => { - console.log("Re-rendering message composer to update text content."); - }); - this.initializeComposerTracking(); - } - - initializeComposerTracking() { - const composerInput = document.getElementById("yourComposerInputId"); - this.setInputElementReference(composerInput); - } - - getCaretPosition(): number { - if (!this.inputElementReference) return 0; - const selection = window.getSelection(); - if (!selection || selection.rangeCount === 0) return 0; - const range = selection.getRangeAt(0); - const clonedRange = range.cloneRange(); - clonedRange.selectNodeContents(this.inputElementReference); - clonedRange.setEnd(range.endContainer, range.endOffset); - return clonedRange.toString().length; - } - - setCaretPosition(position: number) { - if (!this.inputElementReference) return; - const range = document.createRange(); - const selection = window.getSelection(); - if (!selection) return; - range.setStart( - this.inputElementReference.childNodes[0] || this.inputElementReference, - position - ); - range.collapse(true); - selection.removeAllRanges(); - selection.addRange(range); - } - - onKeyUp(event: KeyboardEvent) { - if (event.key === this.trackCharacter) { - this.startTracking = true; - } - if (this.startTracking && (event.key === " " || event.key === "Enter")) { - const caretPosition = this.getCaretPosition(); - this.formatText(); - this.setCaretPosition(caretPosition); - } - if ( - this.startTracking && - event.key !== " " && - event.key !== "Enter" && - this.getCaretPosition() === this.inputElementReference?.innerText?.length - ) { - this.startTracking = false; - } - } - - formatText() { - const inputValue = - this.inputElementReference?.innerText || - this.inputElementReference?.textContent || - ""; - const formattedText = this.getFormattedText(inputValue); - if (this.inputElementReference) { - this.inputElementReference.innerHTML = formattedText || ""; - this.reRender(); - } - } - - onKeyDown(event: KeyboardEvent) {} - - getFormattedText(inputText: string) { - if (!inputText) return; - return this.customLogicToFormatText(inputText); - } - - customLogicToFormatText(inputText: string) { - return inputText.replace( - /\B#(\w+)\b/g, - '#$1' - ); - } - - getOriginalText(inputText: string) { - if (!inputText) return ""; - for (let i = 0; i < this.regexToReplaceFormatting.length; i++) { - let regexPattern = this.regexToReplaceFormatting[i]; - if (inputText) { - inputText = inputText.replace(regexPattern, "#$1"); - } - } - return inputText; - } -} - -export default HashTagTextFormatter; -``` - - - - - -Pass the formatter via the `textFormatters` prop. - -```tsx lines -import { HashTagTextFormatter } from "./HashTagTextFormatter"; - -export default function MessageListDemo() { - const [chatUser, setChatUser] = React.useState(); - - React.useEffect(() => { - CometChat.getUser("uid").then((user) => { - setChatUser(user); - }) - }, []) - - return ( - - ); -} -``` - - - - ---- - -## Methods Reference - -| Field | Setter | Description | -| --- | --- | --- | -| `trackCharacter` | `setTrackingCharacter(char)` | Character that starts tracking (e.g. `#` for hashtags) | -| `currentCaretPosition` | `setCaretPositionAndRange(selection, range)` | Current selection set by the composer | -| `currentRange` | `setCaretPositionAndRange(selection, range)` | Text range or cursor position set by the composer | -| `inputElementReference` | `setInputElementReference(element)` | DOM reference to the composer input field | -| `regexPatterns` | `setRegexPatterns(patterns)` | Regex patterns to match text for formatting | -| `regexToReplaceFormatting` | `setRegexToReplaceFormatting(patterns)` | Regex patterns to strip formatting back to plain text | -| `keyUpCallBack` | `setKeyUpCallBack(fn)` | Callback for key up events | -| `keyDownCallBack` | `setKeyDownCallBack(fn)` | Callback for key down events | -| `reRender` | `setReRender(fn)` | Triggers a re-render of the composer to update displayed text | -| `loggedInUser` | `setLoggedInUser(user)` | Logged-in user object, set by composer and text bubbles | -| `id` | `setId(id)` | Unique identifier for the formatter instance | - - -Don't modify `textContent` or `innerHTML` of the input element directly. Call `reRender` instead — the composer will invoke `getFormattedText` for all formatters in order. - - ---- - -## Override Methods - - - - -Returns formatted HTML from input text, or edits at cursor position if `inputText` is null. - -```js lines -getFormattedText(inputText: string | null, params: any): string | void { - if (!inputText) { - return; // edit at cursor position - } - return this.customLogicToFromatText(inputText); -} -``` - - - - - -Handles `keyup` events. Start tracking when the track character is typed. - -```js lines -onKeyUp(event: KeyboardEvent) { - if (event.key == this.trackCharacter) { - this.startTracking = true; - } - if (this.startTracking && event.key == " ") { - this.debouncedFormatTextOnKeyUp(); - } -} -``` - - - - - -Handles `keydown` events. - -```js lines -onKeyDown(event: KeyboardEvent) {} -``` - - - - - -Called by the composer and text bubbles for each HTML element in the formatted string. Check for your formatter's CSS class before attaching listeners. - -```js lines -registerEventListeners(element: HTMLElement, domTokenList: DOMTokenList) { - let classList: string[] = Array.from(domTokenList); - for (let i = 0; i < classList.length; i++) { - if (classList[i] in this.mentionsCssClassMapping) { - element.addEventListener("click", (event: Event) => { - clearTimeout(this.timeoutID); - CometChatUIEvents.ccMouseEvent.next({ - body: { - CometChatUserGroupMembersObject: - this.mentionsCssClassMapping[classList[i]], - message: this.messageObject ?? null, - id: this.getId(), - }, - event, - source: MouseEventSource.mentions, - }); - }); - - element.addEventListener("mouseover", (event: Event) => { - this.timeoutID = setTimeout(() => { - this.mouseOverEventDispatched = true; - CometChatUIEvents.ccMouseEvent.next({ - body: { - CometChatUserGroupMembersObject: - this.mentionsCssClassMapping[classList[i]], - message: this.messageObject ?? null, - id: this.getId(), - }, - event, - source: MouseEventSource.mentions, - }); - }, CometChatUtilityConstants.MentionsFormatter.MENTIONS_HOVER_TIMEOUT); - }); - - element.addEventListener("mouseout", (event: Event) => { - clearTimeout(this.timeoutID); - if (this.mouseOverEventDispatched) { - CometChatUIEvents.ccMouseEvent.next({ - body: { - CometChatUserGroupMembersObject: - this.mentionsCssClassMapping[classList[i]], - message: this.messageObject ?? null, - id: this.getId(), - }, - event, - source: MouseEventSource.mentions, - }); - this.mouseOverEventDispatched = false; - } - }); - } - } - return element; -} -``` - - - - - -Strips formatting and returns plain text. - -```js lines -getOriginalText(inputText: string | null | undefined): string { - if (!inputText) return ""; - for (let i = 0; i < this.regexToReplaceFormatting.length; i++) { - let regexPattern = this.regexToReplaceFormatting[i]; - if (inputText) { - inputText = inputText.replace(regexPattern, "$1"); - } - } - return inputText; -} -``` - - - - ---- - -## Next Steps - - - - Add @mentions with styled tokens. - - - Customize the message input component. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - diff --git a/ui-kit/react/v7/event-system.mdx b/ui-kit/react/event-system.mdx similarity index 99% rename from ui-kit/react/v7/event-system.mdx rename to ui-kit/react/event-system.mdx index 3e1d74699..d47424d8e 100644 --- a/ui-kit/react/v7/event-system.mdx +++ b/ui-kit/react/event-system.mdx @@ -222,7 +222,7 @@ These events are published by UI Kit components for local cross-component commun | `ui:group/member-banned` | `{ message, user, group }` | GroupMembers | | `ui:group/member-unbanned` | `{ message?, user, group }` | GroupMembers | | `ui:group/member-scope-changed` | `{ message, user, group, newScope }` | GroupMembers | -| `ui:group/ownership-changed` | `{ group, newOwner }` | GroupMembers | +| `ui:group/ownership-changed` | `{ group, newOwner, previousOwnerUid }` | GroupMembers | ### Thread diff --git a/ui-kit/react/events.mdx b/ui-kit/react/events.mdx deleted file mode 100644 index b00bb4989..000000000 --- a/ui-kit/react/events.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "Events" -description: "Reference for CometChat React UI Kit events including conversation, user, group, message, and call events." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Conversation events | `ccConversationDeleted`, `ccUpdateConversation` | -| User events | `ccUserBlocked`, `ccUserUnblocked` | -| Group events | `ccGroupCreated`, `ccGroupDeleted`, `ccGroupLeft`, `ccGroupMemberScopeChanged`, `ccGroupMemberKicked`, `ccGroupMemberBanned`, `ccGroupMemberUnbanned`, `ccGroupMemberJoined`, `ccGroupMemberAdded`, `ccOwnershipChanged` | -| Message events | `ccMessageSent`, `ccMessageEdited`, `ccReplyToMessage`, `ccMessageDeleted`, `ccMessageRead`, `ccLiveReaction`, plus SDK listener events | -| Call events | `ccOutgoingCall`, `ccCallAccepted`, `ccCallRejected`, `ccCallEnded` | -| UI events | `ccActiveChatChanged` | -| Purpose | Decoupled communication between UI Kit components — subscribe to events to react to changes without direct component references | - - - -Events provide decoupled communication between UI Kit components. Components emit events in response to user interactions or state changes, allowing other parts of the application to react without direct component references. - -### CometChatConversationEvents - -`CometChatConversationEvents` emits events when the logged-in user acts on a conversation object. - -| Name | Description | -| ------------------------- | ------------------------------------------------------------------------------------------------ | -| **ccConversationDeleted** | This event is triggered when the user successfully deletes a conversation. | -| **ccUpdateConversation** | This event is triggered to update a conversation in the conversation list. Takes a Conversation object to update. | - -### CometChatUserEvents - -`CometChatUserEvents` emits events when the logged-in user acts on another user object. - -| Name | Description | -| --------------- | ------------------------------------------------------------------------- | -| **ccUserBlocked** | This event is triggered when the user successfully blocks another user. | -| **ccUserUnblocked** | This event is triggered when the user successfully unblocks another user. | - -### CometChatGroupEvents - -`CometChatGroupEvents` emits events when the logged-in user acts on a group object. - -| Name | Description | -| ------------------------- | ------------------------------------------------------------------------------------ | -| **ccGroupCreated** | This event is triggered when the user creates a group successfully | -| **ccGroupDeleted** | This event is triggered when the group member deletes the group successfully | -| **ccGroupLeft** | This event is triggered when the group member leaves the group successfully | -| **ccGroupMemberScopeChanged** | This event is triggered when the group member's scope is updated successfully | -| **ccGroupMemberKicked** | This event is triggered when the group member is kicked | -| **ccGroupMemberBanned** | This event is triggered when the group member is banned | -| **ccGroupMemberUnbanned** | This event is triggered when the group member is un-banned | -| **ccGroupMemberJoined** | This event is triggered when a user joins the group | -| **ccGroupMemberAdded** | This event is triggered when a user is added to the group | -| **ccOwnershipChanged** | This event is triggered when the group ownership is assigned to another group member | - -### CometChatMessageEvents - -`CometChatMessageEvents` emits events when the logged-in user acts on a message object. - -| Name | Description | -| -------------------------- | --------------------------------------------------------------------------------------------------------- | -| **ccMessageSent** | This event is triggered when the sent message is in transit and also when it is received by the receiver. | -| **ccMessageEdited** | This event is triggered when the user successfully edits the message. | -| **ccReplyToMessage** | This event is triggered when the user successfully replies to a message. | -| **ccMessageDeleted** | This event is triggered when the user successfully deletes the message. | -| **ccMessageRead** | This event is triggered when the sent message is read by the receiver. | -| **ccLiveReaction** | This event is triggered when the user sends a live reaction. | -| **onTextMessageReceived** | This event is emitted when the CometChat SDK listener emits a text message. | -| **onMediaMessageReceived** | This event is emitted when the CometChat SDK listener emits a media message. | -| **onCustomMessageReceived** | This event is emitted when the CometChat SDK listener emits a custom message. | -| **onTypingStarted** | This event is emitted when the CometChat SDK listener indicates that a user has started typing. | -| **onTypingEnded** | This event is emitted when the CometChat SDK listener indicates that a user has stopped typing. | -| **onMessagesDelivered** | This event is emitted when the CometChat SDK listener indicates that messages have been delivered. | -| **onMessagesRead** | This event is emitted when the CometChat SDK listener indicates that messages have been read. | -| **onMessageEdited** | This event is emitted when the CometChat SDK listener indicates that a message has been edited. | -| **onMessageDeleted** | This event is emitted when the CometChat SDK listener indicates that a message has been deleted. | -| **onTransientMessageReceived** | This event is emitted when the CometChat SDK listener emits a transient message. | - -### CometChatCallEvents - -`CometChatCallEvents` emits events when the logged-in user acts on a call object. - -| Name | Description | -| -------------- | ---------------------------------------------------------------------------- | -| **ccOutgoingCall** | This event is triggered when the user initiates a voice/video call. | -| **ccCallAccepted** | This event is triggered when the initiated call is accepted by the receiver. | -| **ccCallRejected** | This event is triggered when the initiated call is rejected by the receiver. | -| **ccCallEnded** | This event is triggered when the initiated call successfully ends. | - -### UI events - -UI events are triggered when a user interacts with UI Kit elements such as buttons, menus, or input fields. - -| Name | Description | -| ------------------- | ---------------------------------------------------------------------------- | -| **ccActiveChatChanged** | This event is triggered when the user navigates to a particular chat window. | diff --git a/ui-kit/react/extensions.mdx b/ui-kit/react/extensions.mdx index ebdf35e8e..e61f0b0f8 100644 --- a/ui-kit/react/extensions.mdx +++ b/ui-kit/react/extensions.mdx @@ -8,19 +8,19 @@ description: "Overview of CometChat extensions for React UI Kit, including engag | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Required setup | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` + Extensions enabled in [CometChat Dashboard](/fundamentals/extensions-overview) | +| Required setup | Wrap app in `CometChatProvider` with valid credentials + Extensions enabled in [CometChat Dashboard](/fundamentals/extensions-overview) | | Extension categories | User Experience, User Engagement, Collaboration, Security, Customer Support, Smart Chat Features | -| Key components | `CometChatMessageComposer` → [Message Composer](/ui-kit/react/message-composer) (Stickers, Polls, Whiteboard, Document), `CometChatMessageList` → [Message List](/ui-kit/react/message-list) (Translation, Link Preview, Thumbnails) | +| Key components | `CometChatMessageComposer` → [Message Composer](/ui-kit/react/components/message-composer) (Stickers, Polls, Whiteboard, Document), `CometChatMessageList` → [Message List](/ui-kit/react/components/message-list) (Translation, Link Preview, Thumbnails) | | Activation | Enable each extension from the CometChat Dashboard — UI Kit auto-integrates them, no additional code required | ## Overview -CometChat UI Kit includes built-in support for extensions that add interactive, secure, and efficient features to chat. Extensions are activated from the [CometChat Dashboard](/fundamentals/extensions-overview) and auto-integrate into UI Kit components on init and login. +CometChat UI Kit includes built-in support for extensions that add interactive, secure, and efficient features to chat. Extensions are activated from the [CometChat Dashboard](https://app.cometchat.com/) and auto-integrate into UI Kit components. -Ensure `CometChatUIKit.init(UIKitSettings)` has completed and the user is logged in via `CometChatUIKit.login("UID")`. Extensions must be activated from the [CometChat Dashboard](/fundamentals/extensions-overview). +Ensure your app is wrapped in `CometChatProvider` with valid credentials. Extensions must be activated from the [CometChat Dashboard](/fundamentals/extensions-overview). ## Built-in Extensions @@ -37,7 +37,7 @@ Shortens long URLs in text messages using Bitly. See [Bitly Extension](/fundamen Displays a summary (title, description, thumbnail) for URLs shared in chat. See [Link Preview Extension](/fundamentals/link-preview). -Auto-integrates into the Message Bubble of [MessageList](/ui-kit/react/message-list) when activated. +Auto-integrates into the Message Bubble of [MessageList](/ui-kit/react/components/message-list) when activated. @@ -63,7 +63,7 @@ Bookmarks messages for later reference. Saved messages are private to the user. Creates smaller preview images for shared images, reducing bandwidth. See [Thumbnail Generation Extension](/fundamentals/thumbnail-generation). -Auto-integrates into the Message Bubble of [MessageList](/ui-kit/react/message-list) when activated. +Auto-integrates into the Message Bubble of [MessageList](/ui-kit/react/components/message-list) when activated. @@ -87,7 +87,7 @@ Search and share GIFs from Giphy. See [Giphy Extension](/fundamentals/giphy). Translates messages into the local locale. See [Message Translation Extension](/fundamentals/message-translation). -Auto-integrates into the Action Sheet of [MessageList](/ui-kit/react/message-list) when activated. +Auto-integrates into the message options menu of [MessageList](/ui-kit/react/components/message-list) when activated. @@ -97,7 +97,7 @@ Auto-integrates into the Action Sheet of [MessageList](/ui-kit/react/message-lis Creates polls in group discussions with predefined answer options. See [Polls Extension](/fundamentals/polls). -Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/message-composer) when activated. +Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/components/message-composer) when activated. @@ -111,7 +111,7 @@ Sets reminders for messages or creates personal reminders. A bot sends a notific Sends pre-designed stickers in chat. See [Sticker Extension](/fundamentals/stickers). -Auto-integrates into [Message Composer](/ui-kit/react/message-composer) when activated. +Auto-integrates into [Message Composer](/ui-kit/react/components/message-composer) when activated. @@ -131,7 +131,7 @@ Search and share GIFs from Tenor. See [Tenor Extension](/fundamentals/tenor). Shared document editing for real-time collaboration. See [Collaborative Document Extension](/fundamentals/collaborative-document). -Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/message-composer) when activated. +Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/components/message-composer) when activated. @@ -141,7 +141,7 @@ Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/messag Real-time shared whiteboard for drawing and brainstorming. See [Collaborative Whiteboard Extension](/fundamentals/collaborative-whiteboard). -Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/message-composer) when activated. +Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/components/message-composer) when activated. @@ -182,10 +182,10 @@ AI-generated recap of long conversations. See [Conversation Summary](/fundamenta ## Next Steps - + Customize the composer where most extensions appear - + Customize the message list for extension-rendered content diff --git a/ui-kit/react/group-members.mdx b/ui-kit/react/group-members.mdx deleted file mode 100644 index d9ef73a8e..000000000 --- a/ui-kit/react/group-members.mdx +++ /dev/null @@ -1,1189 +0,0 @@ ---- -title: "Group Members" -description: "Scrollable, searchable list of members in a specific group with roles, scopes, online status, and member management actions." ---- - -```json -{ - "component": "CometChatGroupMembers", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatGroupMembers } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", - "description": "Scrollable, searchable list of members in a specific group with roles, scopes, online status, and member management actions.", - "cssRootClass": ".cometchat-group-members", - "primaryOutput": { - "prop": "onItemClick", - "type": "(groupMember: CometChat.GroupMember) => void" - }, - "props": { - "data": { - "group": { - "type": "CometChat.Group", - "required": true, - "note": "The group whose members are displayed" - }, - "groupMemberRequestBuilder": { - "type": "CometChat.GroupMembersRequestBuilder", - "default": "SDK default (30 per page)", - "note": "Pass the builder, not the result of .build()" - }, - "searchRequestBuilder": { - "type": "CometChat.GroupMembersRequestBuilder", - "default": "undefined" - }, - "searchKeyword": { - "type": "string", - "default": "\"\"" - } - }, - "callbacks": { - "onItemClick": "(groupMember: CometChat.GroupMember) => void", - "onSelect": "(groupMember: CometChat.GroupMember, selected: boolean) => void", - "onEmpty": "() => void", - "onError": "((error: CometChat.CometChatException) => void) | null" - }, - "visibility": { - "hideSearch": { "type": "boolean", "default": false }, - "hideError": { "type": "boolean", "default": false }, - "hideKickMemberOption": { "type": "boolean", "default": false }, - "hideBanMemberOption": { "type": "boolean", "default": false }, - "hideScopeChangeOption": { "type": "boolean", "default": false }, - "hideUserStatus": { "type": "boolean", "default": false }, - "disableLoadingState": { "type": "boolean", "default": false }, - "showScrollbar": { "type": "boolean", "default": false } - }, - "selection": { - "selectionMode": { - "type": "SelectionMode", - "values": ["SelectionMode.single (0)", "SelectionMode.multiple (1)", "SelectionMode.none (2)"], - "default": "SelectionMode.none" - } - }, - "viewSlots": { - "itemView": "(groupMember: CometChat.GroupMember) => JSX.Element", - "leadingView": "(groupMember: CometChat.GroupMember) => JSX.Element", - "titleView": "(groupMember: CometChat.GroupMember) => JSX.Element", - "subtitleView": "(groupMember: CometChat.GroupMember) => JSX.Element", - "trailingView": "(groupMember: CometChat.GroupMember) => JSX.Element", - "headerView": "JSX.Element", - "loadingView": "JSX.Element", - "emptyView": "JSX.Element", - "errorView": "JSX.Element", - "options": "(group: CometChat.Group, groupMember: CometChat.GroupMember) => CometChatOption[]" - } - }, - "events": [ - { - "name": "CometChatGroupEvents.ccGroupMemberKicked", - "payload": "IGroupMemberKickedBanned", - "description": "Member kicked" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberBanned", - "payload": "IGroupMemberKickedBanned", - "description": "Member banned" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberScopeChanged", - "payload": "IGroupMemberScopeChanged", - "description": "Member scope changed" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberAdded", - "payload": "IGroupMemberAdded", - "description": "Members added" - } - ], - "sdkListeners": [ - "onGroupMemberScopeChanged", - "onGroupMemberKicked", - "onGroupMemberBanned", - "onMemberAddedToGroup", - "onGroupMemberLeft", - "onGroupMemberJoined", - "onUserOnline", - "onUserOffline" - ], - "types": { - "CometChatOption": { - "id": "string | undefined", - "title": "string | undefined", - "iconURL": "string | undefined", - "onClick": "(() => void) | undefined" - }, - "SelectionMode": { - "single": 0, - "multiple": 1, - "none": 2 - } - } -} -``` - - -## Where It Fits - -`CometChatGroupMembers` is a panel component that renders the member list for a specific group. It requires a `group` prop and provides built-in member management actions (kick, ban, scope change) based on the logged-in user's role. Typically rendered alongside the message view in a group chat layout. - -```tsx lines -import { useEffect, useState } from "react"; -import { - CometChatGroupMembers, - CometChatMessageHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function GroupChatWithMembers() { - const [group, setGroup] = useState(); - - useEffect(() => { - CometChat.getGroup("GROUP_GUID").then(setGroup); - }, []); - - if (!group) return null; - - return ( -
-
- -
-
- - - -
-
- ); -} -``` - - - - - ---- - -## Minimal Render - -```tsx lines -import { useEffect, useState } from "react"; -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function GroupMembersDemo() { - const [group, setGroup] = useState(); - - useEffect(() => { - CometChat.getGroup("GROUP_GUID").then(setGroup); - }, []); - - return group ? ( -
- -
- ) : null; -} - -export default GroupMembersDemo; -``` - -Root CSS class: `.cometchat-group-members` - ---- - -## Filtering Group Members - -Pass a `CometChat.GroupMembersRequestBuilder` to `groupMemberRequestBuilder`. Pass the builder instance — not the result of `.build()`. - -```tsx lines -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function FilteredGroupMembers({ group }: { group: CometChat.Group }) { - return ( - - ); -} -``` - -### Filter Recipes - -| Recipe | Code | -| --- | --- | -| Limit to 10 per page | `new CometChat.GroupMembersRequestBuilder("GUID").setLimit(10)` | -| Search by keyword | `new CometChat.GroupMembersRequestBuilder("GUID").setSearchKeyword("john")` | -| Admins and moderators only | `new CometChat.GroupMembersRequestBuilder("GUID").setScopes(["admin", "moderator"])` | - -Default page size is 30. The component uses infinite scroll — the next page loads as the user scrolls to the bottom. - -The `searchRequestBuilder` prop accepts a separate `GroupMembersRequestBuilder` for filtering when the search bar is active. - -Refer to [GroupMembersRequestBuilder](/sdk/javascript/retrieve-group-members) for the full builder API. - ---- - -## Actions and Events - -### Callback Props - -#### onItemClick - -Fires when a member row is tapped. - -```tsx lines -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function GroupMembersWithClick({ group }: { group: CometChat.Group }) { - return ( - { - console.log("Selected member:", member.getName()); - }} - /> - ); -} -``` - -#### onSelect - -Fires when a member is checked/unchecked in multi-select mode. Requires `selectionMode` to be set. - -```tsx lines -import { useState } from "react"; -import { - CometChatGroupMembers, - SelectionMode, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function BatchSelectMembers({ group }: { group: CometChat.Group }) { - const [selected, setSelected] = useState>(new Set()); - - return ( - { - setSelected((prev) => { - const next = new Set(prev); - const uid = member.getUid(); - isSelected ? next.add(uid) : next.delete(uid); - return next; - }); - }} - /> - ); -} -``` - -#### onEmpty - -Fires when the member list has no data to display. - -```tsx lines -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function GroupMembersWithEmpty({ group }: { group: CometChat.Group }) { - return ( - console.log("No members found")} - /> - ); -} -``` - -#### onError - -Fires on internal errors (network failure, auth issue, SDK exception). - -```tsx lines -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function GroupMembersWithError({ group }: { group: CometChat.Group }) { - return ( - { - console.error("CometChatGroupMembers error:", error); - }} - /> - ); -} -``` - -### Global UI Events - -`CometChatGroupEvents` emits events subscribable from anywhere in the application. The component both emits and subscribes to these events. - -Events emitted by this component: - -| Event | Fires when | Payload | -| --- | --- | --- | -| `ccGroupMemberKicked` | A member is kicked | `IGroupMemberKickedBanned` | -| `ccGroupMemberBanned` | A member is banned | `IGroupMemberKickedBanned` | -| `ccGroupMemberScopeChanged` | A member's scope changes | `IGroupMemberScopeChanged` | - -Events subscribed internally: - -| Event | Internal behavior | -| --- | --- | -| `ccGroupMemberKicked` | Removes the kicked member from the list | -| `ccGroupMemberBanned` | Removes the banned member from the list | -| `ccGroupMemberScopeChanged` | Updates the member's scope in the list | -| `ccGroupMemberAdded` | Appends newly added members to the list | - -```tsx lines -import { useEffect } from "react"; -import { CometChatGroupEvents } from "@cometchat/chat-uikit-react"; - -function useGroupMemberEvents() { - useEffect(() => { - const kickedSub = CometChatGroupEvents.ccGroupMemberKicked.subscribe( - (item) => { - console.log("Member kicked:", item.kickedUser.getName()); - } - ); - const scopeSub = CometChatGroupEvents.ccGroupMemberScopeChanged.subscribe( - (item) => { - console.log("Scope changed:", item.updatedUser.getName(), "to", item.scopeChangedTo); - } - ); - - return () => { - kickedSub?.unsubscribe(); - scopeSub?.unsubscribe(); - }; - }, []); -} -``` - -### SDK Events (Real-Time, Automatic) - -The component listens to these SDK events internally. No manual attachment needed unless additional side effects are required. - -| SDK Listener | Internal behavior | -| --- | --- | -| `onGroupMemberScopeChanged` | Updates the member's scope in the list | -| `onGroupMemberKicked` | Removes the kicked member from the list | -| `onGroupMemberBanned` | Removes the banned member from the list | -| `onMemberAddedToGroup` | Appends the new member to the list | -| `onGroupMemberLeft` | Removes the member who left from the list | -| `onGroupMemberJoined` | Appends the joined member to the list | -| `onUserOnline` / `onUserOffline` | Updates the member's online/offline status (disabled when `hideUserStatus={true}`) | - - -In React 18 StrictMode, `useEffect` runs twice on mount in development. The component handles listener cleanup internally, but any additional listeners added alongside the component need cleanup in the `useEffect` return function to avoid duplicate event handling. - - ---- - -## Custom View Slots - -Each slot replaces a section of the default UI. Slots that accept a member parameter receive the `CometChat.GroupMember` object for that row. - -| Slot | Signature | Replaces | -| --- | --- | --- | -| `itemView` | `(groupMember: CometChat.GroupMember) => JSX.Element` | Entire list item row | -| `leadingView` | `(groupMember: CometChat.GroupMember) => JSX.Element` | Avatar / left section | -| `titleView` | `(groupMember: CometChat.GroupMember) => JSX.Element` | Name / title text | -| `subtitleView` | `(groupMember: CometChat.GroupMember) => JSX.Element` | Subtitle text | -| `trailingView` | `(groupMember: CometChat.GroupMember) => JSX.Element` | Right section (scope badge / actions) | -| `headerView` | `JSX.Element` | Entire header bar | -| `loadingView` | `JSX.Element` | Loading spinner | -| `emptyView` | `JSX.Element` | Empty state | -| `errorView` | `JSX.Element` | Error state | -| `options` | `(group: CometChat.Group, groupMember: CometChat.GroupMember) => CometChatOption[]` | Context menu / hover actions | - -### itemView - -Replace the entire list item row. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatAvatar, - CometChatGroupMembers, -} from "@cometchat/chat-uikit-react"; - -function CustomItemViewMembers({ group }: { group: CometChat.Group }) { - const getItemView = (member: CometChat.GroupMember) => { - const scope = member.getScope(); - return ( -
-
- -
-
-
{member.getName()}
-
- {scope} -
-
-
- ); - }; - - return ; -} -``` -
- -```css lines -.group-member-list-item { - display: flex; - min-width: 240px; - padding: 8px 16px; - align-items: center; - gap: 12px; - background: #fff; -} - -.group-member-list-item__content { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; -} - -.group-member-list-item__avatar { - width: 40px; - height: 40px; -} - -.group-member-list-item__content-name { - overflow: hidden; - color: #141414; - text-overflow: ellipsis; - font: 500 16px Roboto; -} - -.group-member-list-item__content-tag { - display: flex; - padding: 4px 12px; - border-radius: 1000px; - background: #edeafa; - color: #6852d6; - font: 400 12px Roboto; -} - -.group-member-list-item__content-tag-owner { - background: #6852d6; - color: #fff; -} - -.group-member-list-item__content-tag-admin { - border: 1px solid #6852d6; -} - -.group-member-list-item__content-tag-participant { - display: none; -} -``` - -
- -### subtitleView - -Replace the subtitle text. Joined date example. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; - -function SubtitleMembers({ group }: { group: CometChat.Group }) { - const getSubtitleView = (member: CometChat.GroupMember) => { - const date = new Date(member.getJoinedAt() * 1000).toLocaleDateString(); - return
Joined: {date}
; - }; - - return ; -} -``` -
- -```css lines -.group-member-subtitle { - overflow: hidden; - color: #727272; - text-overflow: ellipsis; - white-space: nowrap; - font: 400 14px Roboto; -} -``` - -
- -### trailingView - -Replace the right section. Scope tag example. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; - -function TrailingViewMembers({ group }: { group: CometChat.Group }) { - const getTrailingView = (member: CometChat.GroupMember) => { - return ( -
- {member.getScope()} -
- ); - }; - - return ; -} -``` -
- -```css lines -.group-member-scope-tag { - display: flex; - padding: 4px 12px; - border-radius: 1000px; - background: #edeafa; - color: #6852d6; - font: 400 12px Roboto; -} -``` - -
- -### headerView - -Replace the entire header bar. - - - - - - - -```tsx lines -import { - CometChatGroupMembers, - CometChatButton, - getLocalizedString, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function CustomHeaderMembers({ group }: { group: CometChat.Group }) { - return ( - -
- {getLocalizedString("GROUP_MEMBERS")} -
- { /* handle click */ }} /> - - } - /> - ); -} -``` -
- -```css lines -.group-members__header { - display: flex; - width: 100%; - padding: 8px 16px; - align-items: center; - justify-content: space-between; - gap: 12px; - border-radius: 10px; - border: 1px solid #e8e8e8; - background: #edeafa; -} - -.group-members__header__title { - overflow: hidden; - color: #141414; - text-overflow: ellipsis; - font: 700 24px Roboto; -} -``` - -
- -### options - -Replace the context menu / hover actions on each member item. The `options` callback receives both the group and the member. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatGroupMembers, - CometChatOption, -} from "@cometchat/chat-uikit-react"; - -function CustomOptionsMembers({ group }: { group: CometChat.Group }) { - return ( - [ - new CometChatOption({ - id: "kick", - title: "Kick User", - onClick: () => { /* kick logic */ }, - }), - ]} - /> - ); -} -``` - - -```css lines -.cometchat-group-members .cometchat-menu-list__main-menu-item-icon { - background: #f44649; -} - -.cometchat-group-members .cometchat-menu-list__menu { - background: transparent; - box-shadow: none; -} -``` - - - ---- - -## Common Patterns - -### Hide member management actions - -```tsx lines -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function ReadOnlyMembers({ group }: { group: CometChat.Group }) { - return ( - - ); -} -``` - -### Admins and moderators only - -```tsx lines -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function AdminMembers({ group }: { group: CometChat.Group }) { - return ( - - ); -} -``` - -### Minimal chrome - -```tsx lines -import { CometChatGroupMembers } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function MinimalMembers({ group }: { group: CometChat.Group }) { - return ( - - ); -} -``` - ---- - -## CSS Architecture - -The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade: - -1. Global tokens (e.g., `--cometchat-primary-color`, `--cometchat-background-color-01`) are set on the `.cometchat` root wrapper. -2. Component CSS (`.cometchat-group-members`) consumes these tokens via `var()` with fallback values. -3. Overrides target `.cometchat-group-members` descendant selectors in a global stylesheet. - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-group-members` | -| Header title | `.cometchat-group-members .cometchat-list__header-title` | -| List item | `.cometchat-group-members .cometchat-list-item` | -| Body title | `.cometchat-group-members .cometchat-list-item__body-title` | -| Trailing view | `.cometchat-group-members .cometchat-list-item__trailing-view` | -| Scope badge | `.cometchat-group-members__trailing-view-options` | -| Admin scope badge | `.cometchat-group-members__trailing-view-options-admin` | -| Owner scope badge | `.cometchat-group-members__trailing-view-options-owner` | -| Participant scope badge | `.cometchat-group-members__trailing-view-options-participant` | -| Online status | `.cometchat-group-members__list-item-online .cometchat-list-item__status` | -| Scope change dropdown | `.cometchat-group-members .cometchat-menu-list__sub-menu` | -| Empty state | `.cometchat-group-members__empty-state-view` | -| Error state | `.cometchat-group-members__error-state-view` | -| Shimmer loading | `.cometchat-group-members__shimmer` | -| Backdrop (modal) | `.cometchat-group-members__backdrop` | - -### Example: Brand-themed group members - - - - - -```css lines -.cometchat-group-members .cometchat-list__header-title { - background: #feede1; - color: #f76808; - font-family: "Times New Roman"; -} - -.cometchat-group-members .cometchat-list-item__body-title { - font-family: "Times New Roman"; -} - -.cometchat-group-members .cometchat-group-members__trailing-view-options { - font-family: "Times New Roman"; -} -``` - -### Customization Matrix - -| What to change | Where | Property/API | Example | -| --- | --- | --- | --- | -| Override behavior on user interaction | Component props | `on` callbacks | `onItemClick={(m) => openProfile(m)}` | -| Filter which members appear | Component props | `groupMemberRequestBuilder` | `groupMemberRequestBuilder={new CometChat.GroupMembersRequestBuilder("GUID").setScopes(["admin"])}` | -| Toggle visibility of UI elements | Component props | `hide` boolean props | `hideKickMemberOption={true}` | -| Replace a section of the list item | Component props | `View` render props | `subtitleView={(m) =>
{m.getScope()}
}` | -| Change colors, fonts, spacing | Global CSS | Target `.cometchat-group-members` class | `.cometchat-group-members .cometchat-avatar { border-radius: 8px; }` | - ---- - -## Props - -All props are optional unless noted otherwise. - ---- - -### disableLoadingState - -Skips the loading spinner when re-fetching. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### emptyView - -Custom component displayed when there are no members. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in empty state | - ---- - -### errorView - -Custom component displayed when an error occurs. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in error state | - -Hidden when `hideError={true}`. - ---- - -### group - -The group whose members are fetched and displayed. **Required.** - -| | | -| --- | --- | -| Type | `CometChat.Group` | -| Default | — | - ---- - -### groupMemberRequestBuilder - -Controls which members load and in what order. - -| | | -| --- | --- | -| Type | `CometChat.GroupMembersRequestBuilder` | -| Default | SDK default (30 per page) | - -Pass the builder instance, not the result of `.build()`. - ---- - -### headerView - -Custom component rendered as the entire header bar. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in header with title | - ---- - -### hideBanMemberOption - -Hides the option to ban a member from the group. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideError - -Hides the default and custom error views. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideKickMemberOption - -Hides the option to kick a member from the group. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideScopeChangeOption - -Hides the option to change the scope of a group member. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideSearch - -Hides the default search bar. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideUserStatus - -Hides the user's online/offline status indicator. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### itemView - -Custom renderer for the entire list item row. - -| | | -| --- | --- | -| Type | `(groupMember: CometChat.GroupMember) => JSX.Element` | -| Default | Built-in list item | - ---- - -### leadingView - -Custom renderer for the avatar / left section. - -| | | -| --- | --- | -| Type | `(groupMember: CometChat.GroupMember) => JSX.Element` | -| Default | Built-in avatar | - ---- - -### loadingView - -Custom component displayed during the loading state. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in shimmer | - ---- - -### onEmpty - -Callback fired when the member list is empty. - -| | | -| --- | --- | -| Type | `() => void` | -| Default | `undefined` | - ---- - -### onError - -Callback fired when the component encounters an error. - -| | | -| --- | --- | -| Type | `((error: CometChat.CometChatException) => void) \| null` | -| Default | `undefined` | - ---- - -### onItemClick - -Callback fired when a member row is clicked. - -| | | -| --- | --- | -| Type | `(groupMember: CometChat.GroupMember) => void` | -| Default | `undefined` | - ---- - -### onSelect - -Callback fired when a member is selected/deselected. Requires `selectionMode` to be set. - -| | | -| --- | --- | -| Type | `(groupMember: CometChat.GroupMember, selected: boolean) => void` | -| Default | `undefined` | - ---- - -### options - -Custom context menu / hover actions for each member item. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group, groupMember: CometChat.GroupMember) => CometChatOption[]` | -| Default | `undefined` | - ---- - -### searchKeyword - -Pre-fills the search and filters the member list. - -| | | -| --- | --- | -| Type | `string` | -| Default | `""` | - ---- - -### searchRequestBuilder - -Controls filtering when the search bar is active. - -| | | -| --- | --- | -| Type | `CometChat.GroupMembersRequestBuilder` | -| Default | `undefined` | - ---- - -### selectionMode - -Enables single or multi-select checkboxes on list items. - -| | | -| --- | --- | -| Type | `SelectionMode` | -| Default | `SelectionMode.none` | - -```ts lines -enum SelectionMode { - single, // 0 - multiple, // 1 - none, // 2 -} -``` - ---- - -### showScrollbar - -Shows the scrollbar in the member list. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### subtitleView - -Custom renderer for the subtitle text. - -| | | -| --- | --- | -| Type | `(groupMember: CometChat.GroupMember) => JSX.Element` | -| Default | Built-in subtitle | - ---- - -### titleView - -Custom renderer for the name / title text. - -| | | -| --- | --- | -| Type | `(groupMember: CometChat.GroupMember) => JSX.Element` | -| Default | Built-in title | - ---- - -### trailingView - -Custom renderer for the right section (scope badge / actions). - -| | | -| --- | --- | -| Type | `(groupMember: CometChat.GroupMember) => JSX.Element` | -| Default | Built-in trailing view | - ---- - -## Events - -| Event | Payload | Fires when | -| --- | --- | --- | -| `CometChatGroupEvents.ccGroupMemberKicked` | `IGroupMemberKickedBanned` | Member kicked | -| `CometChatGroupEvents.ccGroupMemberBanned` | `IGroupMemberKickedBanned` | Member banned | -| `CometChatGroupEvents.ccGroupMemberScopeChanged` | `IGroupMemberScopeChanged` | Member scope changed | -| `CometChatGroupEvents.ccGroupMemberAdded` | `IGroupMemberAdded` | Members added | - -All events are RxJS `Subject` instances. Subscribe with `.subscribe()`, unsubscribe with the returned subscription's `.unsubscribe()`. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-group-members` | -| Header title | `.cometchat-group-members .cometchat-list__header-title` | -| List item | `.cometchat-group-members .cometchat-list-item` | -| Body title | `.cometchat-group-members .cometchat-list-item__body-title` | -| Trailing view | `.cometchat-group-members .cometchat-list-item__trailing-view` | -| Scope badge | `.cometchat-group-members__trailing-view-options` | -| Admin scope badge | `.cometchat-group-members__trailing-view-options-admin` | -| Owner scope badge | `.cometchat-group-members__trailing-view-options-owner` | -| Participant scope badge | `.cometchat-group-members__trailing-view-options-participant` | -| Online status | `.cometchat-group-members__list-item-online .cometchat-list-item__status` | -| Scope change dropdown | `.cometchat-group-members .cometchat-menu-list__sub-menu` | -| Scope change list | `.cometchat-group-members .cometchat-menu-list__sub-menu-list` | -| Empty state | `.cometchat-group-members__empty-state-view` | -| Empty state title | `.cometchat-group-members__empty-state-view-body-title` | -| Error state | `.cometchat-group-members__error-state-view` | -| Error state title | `.cometchat-group-members__error-state-view-body-title` | -| Shimmer loading | `.cometchat-group-members__shimmer` | -| Backdrop | `.cometchat-group-members__backdrop` | diff --git a/ui-kit/react/groups.mdx b/ui-kit/react/groups.mdx deleted file mode 100644 index 233b7dadf..000000000 --- a/ui-kit/react/groups.mdx +++ /dev/null @@ -1,1337 +0,0 @@ ---- -title: "Groups" -description: "Searchable, scrollable list of all available groups with icon, name, member count, and group type indicator." ---- - -```json -{ - "component": "CometChatGroups", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatGroups } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", - "description": "Searchable, scrollable list of all available groups with icon, name, member count, and group type indicator.", - "cssRootClass": ".cometchat-groups", - "primaryOutput": { - "prop": "onItemClick", - "type": "(group: CometChat.Group) => void" - }, - "props": { - "data": { - "groupsRequestBuilder": { - "type": "CometChat.GroupsRequestBuilder", - "default": "SDK default (30 per page)", - "note": "Pass the builder, not the result of .build()" - }, - "searchRequestBuilder": { - "type": "CometChat.GroupsRequestBuilder", - "default": "undefined" - }, - "activeGroup": { - "type": "CometChat.Group", - "default": "undefined" - } - }, - "callbacks": { - "onItemClick": "(group: CometChat.Group) => void", - "onSelect": "(group: CometChat.Group, selected: boolean) => void", - "onError": "((error: CometChat.CometChatException) => void) | null" - }, - "visibility": { - "hideSearch": { "type": "boolean", "default": false }, - "hideError": { "type": "boolean", "default": false }, - "hideGroupType": { "type": "boolean", "default": false }, - "showScrollbar": { "type": "boolean", "default": false } - }, - "selection": { - "selectionMode": { - "type": "SelectionMode", - "values": ["SelectionMode.single (0)", "SelectionMode.multiple (1)", "SelectionMode.none (2)"], - "default": "SelectionMode.none" - } - }, - "viewSlots": { - "itemView": "(group: CometChat.Group) => JSX.Element", - "leadingView": "(group: CometChat.Group) => JSX.Element", - "titleView": "(group: CometChat.Group) => JSX.Element", - "subtitleView": "(group: CometChat.Group) => JSX.Element", - "trailingView": "(group: CometChat.Group) => JSX.Element", - "headerView": "JSX.Element", - "loadingView": "JSX.Element", - "emptyView": "JSX.Element", - "errorView": "JSX.Element", - "options": "(group: CometChat.Group) => CometChatOption[]" - } - }, - "events": [ - { - "name": "CometChatGroupEvents.ccGroupCreated", - "payload": "CometChat.Group", - "description": "New group created" - }, - { - "name": "CometChatGroupEvents.ccGroupDeleted", - "payload": "CometChat.Group", - "description": "Group deleted" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberJoined", - "payload": "IGroupMemberJoined", - "description": "User joins a group" - }, - { - "name": "CometChatGroupEvents.ccGroupLeft", - "payload": "IGroupLeft", - "description": "User leaves a group" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberAdded", - "payload": "IGroupMemberAdded", - "description": "Members added to a group" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberScopeChanged", - "payload": "IGroupMemberScopeChanged", - "description": "Member scope changed" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberKicked", - "payload": "IGroupMemberKickedBanned", - "description": "Member kicked" - }, - { - "name": "CometChatGroupEvents.ccGroupMemberBanned", - "payload": "IGroupMemberKickedBanned", - "description": "Member banned" - }, - { - "name": "CometChatGroupEvents.ccOwnershipChanged", - "payload": "IOwnershipChanged", - "description": "Ownership transferred" - } - ], - "sdkListeners": [ - "onGroupMemberJoined", - "onGroupMemberLeft", - "onMemberAddedToGroup", - "onGroupMemberKicked", - "onGroupMemberBanned", - "onGroupMemberScopeChanged" - ], - "compositionExample": { - "description": "Group directory wired to message view", - "components": [ - "CometChatGroups", - "CometChatMessageHeader", - "CometChatMessageList", - "CometChatMessageComposer" - ], - "flow": "onItemClick emits CometChat.Group -> pass to MessageHeader, MessageList, MessageComposer" - }, - "types": { - "CometChatOption": { - "id": "string | undefined", - "title": "string | undefined", - "iconURL": "string | undefined", - "onClick": "(() => void) | undefined" - }, - "SelectionMode": { - "single": 0, - "multiple": 1, - "none": 2 - } - } -} -``` - - -## Where It Fits - -`CometChatGroups` is a directory list component. It renders available groups and emits the selected `CometChat.Group` via `onItemClick`. Wire it to `CometChatMessageHeader`, `CometChatMessageList`, and `CometChatMessageComposer` to build a group chat layout. - -```tsx lines -import { useState } from "react"; -import { - CometChatGroups, - CometChatMessageHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function GroupChatApp() { - const [selectedGroup, setSelectedGroup] = useState(); - - return ( -
-
- setSelectedGroup(group)} - /> -
- {selectedGroup ? ( -
- - - -
- ) : ( -
- Select a group -
- )} -
- ); -} -``` - - - - - ---- - -## Minimal Render - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function GroupsDemo() { - return ( -
- -
- ); -} - -export default GroupsDemo; -``` - -Root CSS class: `.cometchat-groups` - ---- - -## Filtering Groups - -Pass a `CometChat.GroupsRequestBuilder` to `groupsRequestBuilder`. Pass the builder instance — not the result of `.build()`. - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function FilteredGroups() { - return ( - - ); -} -``` - -### Filter Recipes - -| Recipe | Code | -| --- | --- | -| Joined groups only | `new CometChat.GroupsRequestBuilder().joinedOnly(true)` | -| Limit to 10 per page | `new CometChat.GroupsRequestBuilder().setLimit(10)` | -| Search by keyword | `new CometChat.GroupsRequestBuilder().setSearchKeyword("design")` | -| Filter by tags | `new CometChat.GroupsRequestBuilder().setTags(["vip"])` | -| With tags data | `new CometChat.GroupsRequestBuilder().withTags(true)` | - -Default page size is 30. The component uses infinite scroll — the next page loads as the user scrolls to the bottom. - -The `searchRequestBuilder` prop accepts a separate `GroupsRequestBuilder` for filtering when the search bar is active. - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function SearchFilteredGroups() { - return ( - - ); -} -``` - -Refer to [GroupsRequestBuilder](/sdk/javascript/retrieve-groups) for the full builder API. - ---- - -## Actions and Events - -### Callback Props - -#### onItemClick - -Fires when a group row is tapped. Primary navigation hook — set the active group and render the message view. - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function GroupsWithClick() { - const handleItemClick = (group: CometChat.Group) => { - console.log("Selected:", group.getGuid()); - }; - - return ; -} -``` - -#### onSelect - -Fires when a group is checked/unchecked in multi-select mode. Requires `selectionMode` to be set. - -```tsx lines -import { useState } from "react"; -import { - CometChatGroups, - SelectionMode, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function BatchSelectGroups() { - const [selected, setSelected] = useState>(new Set()); - - const handleSelect = (group: CometChat.Group, isSelected: boolean) => { - setSelected((prev) => { - const next = new Set(prev); - const id = group.getGuid(); - isSelected ? next.add(id) : next.delete(id); - return next; - }); - }; - - return ( - - ); -} -``` - -#### onError - -Fires on internal errors (network failure, auth issue, SDK exception). - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function GroupsWithErrorHandler() { - return ( - { - console.error("CometChatGroups error:", error); - }} - /> - ); -} -``` - -### Global UI Events - -`CometChatGroupEvents` emits events subscribable from anywhere in the application. Subscribe in a `useEffect` and unsubscribe on cleanup. - -| Event | Fires when | Payload | -| --- | --- | --- | -| `ccGroupCreated` | A new group is created | `CometChat.Group` | -| `ccGroupDeleted` | A group is deleted | `CometChat.Group` | -| `ccGroupMemberJoined` | A user joins a group | `IGroupMemberJoined` | -| `ccGroupLeft` | A user leaves a group | `IGroupLeft` | -| `ccGroupMemberAdded` | Members are added to a group | `IGroupMemberAdded` | -| `ccGroupMemberScopeChanged` | A member's scope changes | `IGroupMemberScopeChanged` | -| `ccGroupMemberKicked` | A member is kicked | `IGroupMemberKickedBanned` | -| `ccGroupMemberBanned` | A member is banned | `IGroupMemberKickedBanned` | -| `ccGroupMemberUnbanned` | A member is unbanned | `IGroupMemberUnBanned` | -| `ccOwnershipChanged` | Group ownership is transferred | `IOwnershipChanged` | - -```tsx lines -import { useEffect } from "react"; -import { CometChatGroupEvents } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function useGroupEvents() { - useEffect(() => { - const createdSub = CometChatGroupEvents.ccGroupCreated.subscribe( - (group: CometChat.Group) => { - console.log("Group created:", group.getName()); - } - ); - const deletedSub = CometChatGroupEvents.ccGroupDeleted.subscribe( - (group: CometChat.Group) => { - console.log("Group deleted:", group.getName()); - } - ); - const memberAddedSub = CometChatGroupEvents.ccGroupMemberAdded.subscribe( - (item) => { - console.log("Members added to:", item.userAddedIn.getName()); - } - ); - const leftSub = CometChatGroupEvents.ccGroupLeft.subscribe( - (item) => { - console.log("User left group:", item.leftGroup.getName()); - } - ); - - return () => { - createdSub?.unsubscribe(); - deletedSub?.unsubscribe(); - memberAddedSub?.unsubscribe(); - leftSub?.unsubscribe(); - }; - }, []); -} -``` - -### SDK Events (Real-Time, Automatic) - -The component listens to these SDK events internally. No manual attachment needed unless additional side effects are required. - -| SDK Listener | Internal behavior | -| --- | --- | -| `onGroupMemberJoined` | Updates member count, sets `hasJoined` if current user joined | -| `onGroupMemberLeft` | Updates member count, sets `hasJoined(false)` if current user left | -| `onMemberAddedToGroup` | Updates member count, adds group to list if current user was added | -| `onGroupMemberKicked` | Updates member count, sets `hasJoined(false)` if current user was kicked | -| `onGroupMemberBanned` | Removes group if current user was banned, otherwise updates member count | -| `onGroupMemberScopeChanged` | Updates scope if current user's scope changed, updates member count | - - -In React 18 StrictMode, `useEffect` runs twice on mount in development. The component handles listener cleanup internally, but any additional listeners added alongside the component need cleanup in the `useEffect` return function to avoid duplicate event handling. - - ---- - -## Custom View Slots - -Each slot replaces a section of the default UI. Slots that accept a group parameter receive the `CometChat.Group` object for that row. - -| Slot | Signature | Replaces | -| --- | --- | --- | -| `itemView` | `(group: CometChat.Group) => JSX.Element` | Entire list item row | -| `leadingView` | `(group: CometChat.Group) => JSX.Element` | Avatar / left section | -| `titleView` | `(group: CometChat.Group) => JSX.Element` | Name / title text | -| `subtitleView` | `(group: CometChat.Group) => JSX.Element` | Member count subtitle | -| `trailingView` | `(group: CometChat.Group) => JSX.Element` | Right section | -| `headerView` | `JSX.Element` | Entire header bar | -| `loadingView` | `JSX.Element` | Loading spinner | -| `emptyView` | `JSX.Element` | Empty state | -| `errorView` | `JSX.Element` | Error state | -| `options` | `(group: CometChat.Group) => CometChatOption[]` | Context menu / hover actions | - -### itemView - -Replace the entire list item row. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatGroups } from "@cometchat/chat-uikit-react"; - -function CustomItemViewGroups() { - const getItemView = (group: CometChat.Group) => { - return ( -
-
-
{group.getName()}
-
JOIN
-
-
- {group.getMembersCount()} Members • {group.getDescription()} -
-
- ); - }; - - return ; -} -``` -
- -```css lines -.group-list-item { - display: flex; - flex-direction: column; - text-align: left; - min-width: 240px; - padding: 8px 16px; - gap: 4px; - flex: 1 0 0; - border-right: 1px solid #f5f5f5; - background: #fff; -} - -.group-list-item:hover { - background-color: #f5f5f5; -} - -.group-list-item__title-wrapper { - display: flex; - justify-content: space-between; - align-items: center; - align-self: stretch; -} - -.group-list-item__title { - overflow: hidden; - color: #141414; - text-overflow: ellipsis; - font: 500 16px Roboto; -} - -.group-list-item__tail { - display: flex; - padding: 4px 12px; - justify-content: center; - align-items: center; - border-radius: 1000px; - background: #edeafa; - overflow: hidden; - color: #6852d6; - text-overflow: ellipsis; - font: 700 12px Roboto; -} - -.group-list-item__subtitle { - overflow: hidden; - color: #727272; - text-overflow: ellipsis; - white-space: nowrap; - font: 400 14px Roboto; -} -``` - -
- -### titleView - -Replace the name / title text. Group type badge inline example. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatGroups } from "@cometchat/chat-uikit-react"; - -function GroupTypeTitleGroups() { - const getTitleView = (group: CometChat.Group) => { - return ( -
- {group.getName()} - {group.getType()} -
- ); - }; - - return ; -} -``` -
- -```css lines -.groups__title-view { - display: flex; - align-items: center; - gap: 4px; - align-self: stretch; -} - -.groups__title-view-name { - overflow: hidden; - color: #141414; - text-overflow: ellipsis; - font: 500 16px Roboto; -} - -.groups__title-view-type { - color: #fff; - font: 600 8px Roboto; - display: flex; - height: 15px; - padding: 1px 3px; - justify-content: center; - align-items: center; - gap: 4px; - border-radius: 7px; - background: #09c26f; -} - -.groups__title-view-public .groups__title-view-type { - background: #0b7bea; -} -``` - -
- -### subtitleView - -Replace the member count subtitle text. - -Default: - - - - - -Customized: - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatGroups } from "@cometchat/chat-uikit-react"; - -function SubtitleGroups() { - const getSubtitleView = (group: CometChat.Group) => { - return ( -
- {group.getMembersCount()} Members • {group.getDescription()} -
- ); - }; - - return ; -} -``` -
- -```css lines -.cometchat .cometchat-groups .group-subtitle { - overflow: hidden; - color: #727272; - text-overflow: ellipsis; - white-space: nowrap; - font: 400 14px Roboto; -} -``` - -
- -### leadingView - -Replace the avatar / left section. Joined status badge example. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatGroups, CometChatAvatar } from "@cometchat/chat-uikit-react"; - -function LeadingViewGroups() { - const getLeadingView = (group: CometChat.Group) => { - return ( - <> - {group.getHasJoined() ? ( -
- - Joined -
- ) : ( -
- - Join -
- )} - - ); - }; - - return ; -} -``` -
- -```css lines -.cometchat-groups .cometchat-list-item .groups__leading-view .cometchat-avatar__image, -.cometchat-groups .cometchat-list-item .groups__leading-view .cometchat-avatar { - border-radius: 8px; - height: 48px; - width: 48px; -} - -.groups__leading-view-info { - display: flex; - width: 48px; - height: 15px; - padding: 1px 3px; - justify-content: center; - align-items: center; - color: #fff; - font: 600 8px/9.6px Roboto; - background: #ffab00; - position: absolute; - bottom: -2px; -} - -.groups__leading-view-joined .groups__leading-view-info { - background: #09c26f; -} - -.groups__leading-view { - position: relative; -} -``` - -
- -### trailingView - -Replace the right section. Join status button example. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatGroups } from "@cometchat/chat-uikit-react"; - -function TrailingViewGroups() { - const getTrailingView = (group: CometChat.Group) => { - return ( -
- {group.getHasJoined() ? "JOINED" : "+ JOIN"} -
- ); - }; - - return ; -} -``` -
- -```css lines -.groups__trailing-view { - display: flex; - padding: 4px 12px; - justify-content: center; - align-items: center; - border-radius: 1000px; - background: #edeafa; - overflow: hidden; - color: #6852d6; - text-overflow: ellipsis; - font: 700 12px Roboto; -} - -.cometchat-groups .cometchat-list-item__trailing-view { - width: fit-content; - height: fit-content; -} -``` - -
- -### headerView - -Replace the entire header bar. - - - - - - - -```tsx lines -import { - CometChatButton, - CometChatGroups, - getLocalizedString, -} from "@cometchat/chat-uikit-react"; - -function CustomHeaderGroups() { - return ( - -
- {getLocalizedString("GROUPS")} -
- { /* handle click */ }} /> - - } - /> - ); -} -``` -
- -```css lines -.groups__header { - display: flex; - width: 100%; - padding: 8px 16px; - align-items: center; - justify-content: space-between; - gap: 12px; - border-radius: 10px; - border: 1px solid #e8e8e8; - background: #edeafa; -} - -.groups__header__title { - overflow: hidden; - color: #141414; - text-overflow: ellipsis; - font: 700 24px Roboto; -} - -.groups__header .cometchat-button .cometchat-button__icon { - background: #141414; -} - -.groups__header .cometchat-button { - width: 24px; - border: none; - background: transparent; - border-radius: 0; -} -``` - -
- -### options - -Replace the context menu / hover actions on each group item. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatOption, - CometChatGroups, -} from "@cometchat/chat-uikit-react"; - -function CustomOptionsGroups() { - const getOptions = (group: CometChat.Group) => [ - new CometChatOption({ - title: "Delete", - id: "delete", - onClick: () => { /* delete logic */ }, - }), - ]; - - return ; -} -``` - - -```css lines -.cometchat .cometchat-groups .cometchat-menu-list__menu { - background: none; -} - -.cometchat .cometchat-groups .cometchat-menu-list__main-menu-item-icon { - background: #f44649; -} -``` - - - -```ts lines -// CometChatOption interface -interface CometChatOption { - id?: string; // Unique identifier - title?: string; // Display text - iconURL?: string; // Icon asset URL - onClick?: () => void; // Click handler -} -``` - ---- - -## Common Patterns - -### Custom empty state with CTA - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; - -function EmptyStateGroups() { - return ( - -

No groups available

- - - } - /> - ); -} -``` - -### Hide all chrome — minimal list - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; - -function MinimalGroups() { - return ( - - ); -} -``` - -### Joined groups only - -```tsx lines -import { CometChatGroups } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function JoinedGroups() { - return ( - - ); -} -``` - ---- - -## CSS Architecture - -The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade: - -1. Global tokens (e.g., `--cometchat-primary-color`, `--cometchat-background-color-01`) are set on the `.cometchat` root wrapper. -2. Component CSS (`.cometchat-groups`) consumes these tokens via `var()` with fallback values. -3. Overrides target `.cometchat-groups` descendant selectors in a global stylesheet. - -To scope overrides to a single instance when multiple `CometChatGroups` exist on the same page, wrap the component in a container and scope selectors: - -```css lines -.sidebar-left .cometchat-groups .cometchat-avatar { - border-radius: 8px; -} -``` - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-groups` | -| Header title | `.cometchat-groups .cometchat-list__header-title` | -| Search bar input | `.cometchat-groups .cometchat-search-bar__input` | -| List item | `.cometchat-groups .cometchat-list-item` | -| Body title | `.cometchat-groups .cometchat-list-item__body-title` | -| Avatar | `.cometchat-groups__list-item .cometchat-avatar` | -| Subtitle | `.cometchat-groups__subtitle` | -| Active item | `.cometchat-groups__list-item-active .cometchat-list-item` | -| Password group icon | `.cometchat-groups__list-item-password .cometchat-list-item__status` | -| Private group icon | `.cometchat-groups__list-item-private .cometchat-list-item__status` | -| Empty state | `.cometchat-groups__empty-state-view` | -| Error state | `.cometchat-groups__error-state-view` | -| Shimmer loading | `.cometchat-groups__shimmer` | - -### Example: Brand-themed groups - - - - - -```css lines -.cometchat-groups .cometchat-list__header-title { - background-color: #edeafa; - color: #6852d6; - border-width: 0px 1px 1px 0px; - border-style: solid; - border-color: #6852d6; - font-family: "Times New Roman"; - font-size: 24px; - font-weight: 700; -} - -.cometchat-groups__list-item .cometchat-avatar { - background-color: #aa9ee8; - border-radius: 6.67px; -} - -.cometchat-groups .cometchat-list-item__body-title { - font-family: "Times New Roman"; - font-size: 16px; - font-weight: 400; -} - -.cometchat-groups .cometchat-groups__subtitle { - font-family: "Times New Roman"; - font-size: 14px; - font-weight: 400; -} -``` - -### Customization Matrix - -| What to change | Where | Property/API | Example | -| --- | --- | --- | --- | -| Override behavior on user interaction | Component props | `on` callbacks | `onItemClick={(g) => setActive(g)}` | -| Filter which groups appear | Component props | `groupsRequestBuilder` | `groupsRequestBuilder={new CometChat.GroupsRequestBuilder().joinedOnly(true)}` | -| Toggle visibility of UI elements | Component props | `hide` boolean props | `hideGroupType={true}` | -| Replace a section of the list item | Component props | `View` render props | `itemView={(group) =>
...
}` | -| Change colors, fonts, spacing | Global CSS | Target `.cometchat-groups` class | `.cometchat-groups .cometchat-avatar { border-radius: 8px; }` | - ---- - -## Props - -All props are optional unless noted otherwise. - ---- - -### activeGroup - -Highlights the specified group in the list. - -| | | -| --- | --- | -| Type | `CometChat.Group` | -| Default | `undefined` | - -Must be a reference-equal object from the SDK; a manually constructed object will not match. - ---- - -### emptyView - -Custom component displayed when there are no groups. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in empty state | - ---- - -### errorView - -Custom component displayed when an error occurs. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in error state | - -Hidden when `hideError={true}`. - ---- - -### groupsRequestBuilder - -Controls which groups load and in what order. - -| | | -| --- | --- | -| Type | `CometChat.GroupsRequestBuilder` | -| Default | SDK default (30 per page) | - -Pass the builder instance, not the result of `.build()`. - ---- - -### headerView - -Custom component rendered as the entire header bar. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in header with title | - ---- - -### hideError - -Hides the default and custom error views. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - -Also suppresses `errorView` if set. - ---- - -### hideGroupType - -Hides the group type icon (public/private/password). - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideSearch - -Hides the default search bar. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### itemView - -Custom renderer for the entire list item row. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group) => JSX.Element` | -| Default | Built-in list item | - ---- - -### leadingView - -Custom renderer for the avatar / left section. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group) => JSX.Element` | -| Default | Built-in avatar | - ---- - -### loadingView - -Custom component displayed during the loading state. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in shimmer | - ---- - -### onError - -Callback fired when the component encounters an error. - -| | | -| --- | --- | -| Type | `((error: CometChat.CometChatException) => void) \| null` | -| Default | `undefined` | - ---- - -### onItemClick - -Callback fired when a group row is clicked. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group) => void` | -| Default | `undefined` | - ---- - -### onSelect - -Callback fired when a group is selected/deselected. Requires `selectionMode` to be set. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group, selected: boolean) => void` | -| Default | `undefined` | - ---- - -### options - -Custom context menu / hover actions for each group item. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group) => CometChatOption[]` | -| Default | `undefined` | - -```ts lines -class CometChatOption { - id?: string; - title?: string; - iconURL?: string; - onClick?: () => void; -} -``` - ---- - -### searchRequestBuilder - -Controls filtering when the search bar is active. - -| | | -| --- | --- | -| Type | `CometChat.GroupsRequestBuilder` | -| Default | `undefined` | - ---- - -### selectionMode - -Enables single or multi-select checkboxes on list items. - -| | | -| --- | --- | -| Type | `SelectionMode` | -| Default | `SelectionMode.none` | - -```ts lines -enum SelectionMode { - single, // 0 - multiple, // 1 - none, // 2 -} -``` - -Must pair with `onSelect` to capture selections. - ---- - -### showScrollbar - -Shows the scrollbar in the group list. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### subtitleView - -Custom renderer for the member count subtitle text. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group) => JSX.Element` | -| Default | Built-in subtitle | - ---- - -### titleView - -Custom renderer for the name / title text. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group) => JSX.Element` | -| Default | Built-in title | - ---- - -### trailingView - -Custom renderer for the right section. - -| | | -| --- | --- | -| Type | `(group: CometChat.Group) => JSX.Element` | -| Default | Built-in trailing view | - ---- - -## Events - -| Event | Payload | Fires when | -| --- | --- | --- | -| `CometChatGroupEvents.ccGroupCreated` | `CometChat.Group` | New group created | -| `CometChatGroupEvents.ccGroupDeleted` | `CometChat.Group` | Group deleted | -| `CometChatGroupEvents.ccGroupMemberJoined` | `IGroupMemberJoined` | User joins a group | -| `CometChatGroupEvents.ccGroupLeft` | `IGroupLeft` | User leaves a group | -| `CometChatGroupEvents.ccGroupMemberAdded` | `IGroupMemberAdded` | Members added to a group | -| `CometChatGroupEvents.ccGroupMemberScopeChanged` | `IGroupMemberScopeChanged` | Member scope changed | -| `CometChatGroupEvents.ccGroupMemberKicked` | `IGroupMemberKickedBanned` | Member kicked | -| `CometChatGroupEvents.ccGroupMemberBanned` | `IGroupMemberKickedBanned` | Member banned | -| `CometChatGroupEvents.ccGroupMemberUnbanned` | `IGroupMemberUnBanned` | Member unbanned | -| `CometChatGroupEvents.ccOwnershipChanged` | `IOwnershipChanged` | Ownership transferred | - -All events are RxJS `Subject` instances. Subscribe with `.subscribe()`, unsubscribe with the returned subscription's `.unsubscribe()`. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-groups` | -| Header title | `.cometchat-groups .cometchat-list__header-title` | -| Search bar input | `.cometchat-groups .cometchat-search-bar__input` | -| List item | `.cometchat-groups .cometchat-list-item` | -| Body title | `.cometchat-groups .cometchat-list-item__body-title` | -| Avatar | `.cometchat-groups__list-item .cometchat-avatar` | -| Leading view | `.cometchat-groups__list-item .cometchat-list-item__leading-view` | -| Subtitle | `.cometchat-groups__subtitle` | -| Active item | `.cometchat-groups__list-item-active .cometchat-list-item` | -| Password group icon | `.cometchat-groups__list-item-password .cometchat-list-item__status` | -| Password group status icon | `.cometchat-groups__list-item-password .cometchat-list-item__status-icon` | -| Private group icon | `.cometchat-groups__list-item-private .cometchat-list-item__status` | -| Private group status icon | `.cometchat-groups__list-item-private .cometchat-list-item__status-icon` | -| Empty state | `.cometchat-groups__empty-state-view` | -| Empty state title | `.cometchat-groups__empty-state-view-body-title` | -| Empty state description | `.cometchat-groups__empty-state-view-body-description` | -| Error state | `.cometchat-groups__error-state-view` | -| Error state title | `.cometchat-groups__error-state-view-body-title` | -| Error state description | `.cometchat-groups__error-state-view-body-description` | -| Shimmer loading | `.cometchat-groups__shimmer` | -| Shimmer item | `.cometchat-groups__shimmer-item` | -| Shimmer avatar | `.cometchat-groups__shimmer-item-avatar` | -| Shimmer title | `.cometchat-groups__shimmer-item-body-title` | -| Shimmer subtitle | `.cometchat-groups__shimmer-item-body-subtitle` | diff --git a/ui-kit/react/guide-block-unblock-user.mdx b/ui-kit/react/guide-block-unblock-user.mdx index 163d7b9c1..95eb9cb06 100644 --- a/ui-kit/react/guide-block-unblock-user.mdx +++ b/ui-kit/react/guide-block-unblock-user.mdx @@ -1,212 +1,304 @@ --- -title: "Block/Unblock Users" -sidebarTitle: "Block/Unblock Users" -description: "Implement block and unblock user functionality in CometChat React UI Kit with composer state management." +title: "Block/Unblock User" +sidebarTitle: "Block/Unblock User" +description: "Let users block and unblock others directly within chat to control unwanted communication." --- - +## Goal -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Key components | `CometChatMessages` — uses `CometChat.blockUsers()` / `CometChat.unblockUsers()` SDK methods | -| Init | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` | -| Events | `CometChatUserEvents.ccUserBlocked`, `CometChatUserEvents.ccUserUnblocked` | -| UI helpers | `CometChatConfirmDialog`, `CometChatToast` | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [All Guides](/ui-kit/react/guide-overview) | +By the end of this guide you will have a chat interface where users can block and unblock other users, with a confirmation dialog before blocking, the composer automatically hidden for blocked users, and an unblock prompt displayed in its place — all coordinated through UI events so every component stays in sync. - +## Prerequisites -Block/Unblock lets users prevent specific users from sending them messages. When blocked, the message composer is hidden and replaced with an unblock prompt. +- Completed the [Integration Guide](/ui-kit/react/integration-react) guide +- A running `CometChatProvider` setup with valid credentials +- An existing one-on-one chat screen using `CometChatMessageList` and `CometChatMessageComposer` -Before starting, complete the [Getting Started](/ui-kit/react/react-js-integration) guide for your framework. +## Components Used ---- +| Component / API | Purpose | +|:----------------|:--------| +| `CometChatConfirmDialog` | Compound dialog for block confirmation | +| `CometChatMessageList` | Displays messages in the conversation | +| `CometChatMessageComposer` | Text input for sending messages | +| `useCometChatEvents` | Subscribe to UI events | +| `usePublishEvent` | Publish UI events | +| `CometChat.blockUsers()` | SDK method to block a user | +| `CometChat.unblockUsers()` | SDK method to unblock a user | +| `ui:user/blocked` | UI event fired after blocking | +| `ui:user/unblocked` | UI event fired after unblocking | -## Components +## Step 1: Block User -| Component / Class | Role | -|:---|:---| -| `CometChat.blockUsers()` | SDK method to block specific users | -| `CometChat.unblockUsers()` | SDK method to unblock previously blocked users | -| `CometChatUserEvents.ccUserBlocked` | Event fired when a user is blocked | -| `CometChatUserEvents.ccUserUnblocked` | Event fired when a user is unblocked | -| `CometChatConfirmDialog` | Confirmation dialog for block/unblock actions | +Call `CometChat.blockUsers()` with the target UID. On success, update the user object and publish the `ui:user/blocked` event so other components (thread panel, details panel) can react. ---- +_File: ChatView.tsx_ -## Integration Steps - -### 1. Block User - -Call `CometChat.blockUsers()` with the target UID. On success, update the local user object with `setBlockedByMe(true)` and emit `ccUserBlocked` so all subscribed components (like the composer) react to the change. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const onBlockUserClicked: () => Promise = () => { - let UID = user.getUid(); - return new Promise(async (resolve, reject) => { - CometChat.blockUsers([UID]).then( - list => { - user.setBlockedByMe(true); - CometChatUserEvents.ccUserBlocked.next(user); - toastTextRef.current = getLocalizedString("blocked_successfully"); - setShowToast(true); - return resolve(); - }, error => { - console.log("Blocking user fails with error", error); - return reject(); - } - ) - }) -} -``` +```tsx +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { usePublishEvent } from "@cometchat/chat-uikit-react"; ---- +const publish = usePublishEvent(); -### 2. Unblock User - -Call `CometChat.unblockUsers()` with the target UID. On success, reset the action items back to "Block" (instead of "Unblock"), update the local user object, and emit `ccUserUnblocked` to restore the composer. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const onUnblockUserClicked = () => { - let UID = user.getUid(); - CometChat.unblockUsers([UID]).then( - list => { - setActionItems([{ - "name": getLocalizedString("user_details_block"), - "icon": blockIcon, - "id": "block_unblock_user" - }, { - "name": getLocalizedString("delete_chat"), - "icon": deleteIcon, - "id": "delete_chat" - }]); - user.setBlockedByMe(false); - CometChatUserEvents.ccUserUnblocked.next(user); - }, error => { - console.log("Unblocking user fails with error", error); - } - ); +async function handleBlock(user: CometChat.User) { + try { + await CometChat.blockUsers([user.getUid()]); + user.setBlockedByMe(true); + setIsBlocked(true); + setShowBlockDialog(false); + publish({ type: "ui:user/blocked", user }); + } catch (error) { + console.error("Error blocking user:", error); + } } ``` ---- - -### 3. Confirmation Dialog +## Step 2: Unblock User -Show a confirmation dialog before blocking. This prevents accidental blocks. The dialog uses `CometChatConfirmDialog` with localized title, message, and button text. +Call `CometChat.unblockUsers()` to reverse the block. Publish `ui:user/unblocked` so all listening components restore their normal state. -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +_File: ChatView.tsx_ -```tsx lines -const getBlockUserConfirmationDialogView = () => { - return <> -
- { - setShowBlockUserDialog(!showBlockUserDialog); - }} - onSubmitClick={onBlockUserClicked} /> -
- +```tsx +async function handleUnblock(user: CometChat.User) { + try { + await CometChat.unblockUsers([user.getUid()]); + user.setBlockedByMe(false); + setIsBlocked(false); + publish({ type: "ui:user/unblocked", user }); + } catch (error) { + console.error("Error unblocking user:", error); + } } ``` ---- +## Step 3: Confirmation Dialog -### 4. Composer Blocked State +Show a `CometChatConfirmDialog` before blocking. Render it conditionally based on a `showBlockDialog` state flag. -_File: [CometChatMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatMessages/CometChatMessages.tsx)_ +_File: ChatView.tsx_ -When a user is blocked, the composer is replaced with an unblock prompt: +```tsx +import { useState } from "react"; +import { CometChatConfirmDialog } from "@cometchat/chat-uikit-react"; -```tsx lines -{showComposerState ? ( -
- -
-) : ( -
{ - if (user) { - CometChat.unblockUsers([user?.getUid()]).then(() => { - user.setBlockedByMe(false); - CometChatUserEvents.ccUserUnblocked.next(user); - }) - } - }}> -
- {getLocalizedString("cannot_send_to_blocked_user")} - {getLocalizedString("click_to_unblock")} -
-
+const [showBlockDialog, setShowBlockDialog] = useState(false); + +// In your JSX: +{showBlockDialog && ( + setShowBlockDialog(false)}> + + + handleBlock(user)} + onCancel={() => setShowBlockDialog(false)} + /> + )} ``` ---- +## Step 4: Listen for Block/Unblock Events -### 5. Event Listeners +Use `useCometChatEvents` to subscribe to block/unblock events. This keeps the composer visibility in sync even when the block action originates from a different component (e.g., a details panel). -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +_File: ChatView.tsx_ -Subscribe to block/unblock events to update the UI in real time: +```tsx +import { useCometChatEvents } from "@cometchat/chat-uikit-react"; +import type { CometChatEvent } from "@cometchat/chat-uikit-react"; -```tsx lines -const ccUserBlocked = CometChatUserEvents.ccUserBlocked.subscribe(user => { - if (user.getBlockedByMe()) { - setShowComposer(false); - } - updateUserAfterBlockUnblock(user); -}); +useCometChatEvents( + (event: CometChatEvent) => { + if (!user) return; -const ccUserUnblocked = CometChatUserEvents.ccUserUnblocked.subscribe(user => { - if (!user.getBlockedByMe()) { - setShowComposer(true); + if (event.type === "ui:user/blocked" && event.user.getUid() === user.getUid()) { + setIsBlocked(true); + } + if (event.type === "ui:user/unblocked" && event.user.getUid() === user.getUid()) { + setIsBlocked(false); } - updateUserAfterBlockUnblock(user); -}); + }, + [user?.getUid()] +); ``` ---- +## Step 5: Blocked Composer State -## Feature Matrix +Conditionally render the composer or a blocked prompt based on the `isBlocked` state. The blocked prompt includes an inline unblock action. -| Feature | Component / Method | File | -|:---|:---|:---| -| Block user | `CometChat.blockUsers([UID])` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Unblock user | `CometChat.unblockUsers([UID])` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Check blocked status | `user.getBlockedByMe()` | [CometChatMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatMessages/CometChatMessages.tsx) | -| Block confirmation | `CometChatConfirmDialog` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Blocked composer state | `message-composer-blocked` | [CometChatMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatMessages/CometChatMessages.tsx) | -| Block events | `ccUserBlocked.subscribe()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Unblock events | `ccUserUnblocked.subscribe()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Update user state | `user.setBlockedByMe(boolean)` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | +_File: ChatView.tsx_ ---- +```tsx +import { CometChatMessageComposer } from "@cometchat/chat-uikit-react"; + +// In your JSX: +{!isBlocked ? ( + +) : ( +
+

Cannot send a message to a blocked user.

+ handleUnblock(user)} + role="button" + tabIndex={0} + style={{ color: "#3399ff", cursor: "pointer" }} + > + Click to unblock. + +
+)} +``` + +## Complete Example + +_File: ChatView.tsx_ + +```tsx +import { useState, useEffect } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatProvider, + CometChatMessageList, + CometChatMessageComposer, + CometChatMessageHeader, + CometChatConfirmDialog, + usePublishEvent, + useCometChatEvents, +} from "@cometchat/chat-uikit-react"; +import type { CometChatEvent } from "@cometchat/chat-uikit-react"; + +function ChatView({ targetUid }: { targetUid: string }) { + const [user, setUser] = useState(null); + const [isBlocked, setIsBlocked] = useState(false); + const [showBlockDialog, setShowBlockDialog] = useState(false); + const publish = usePublishEvent(); + + useEffect(() => { + async function fetchUser() { + try { + const fetchedUser = await CometChat.getUser(targetUid); + setUser(fetchedUser); + setIsBlocked(fetchedUser.getBlockedByMe()); + } catch (error) { + console.error("Error fetching user:", error); + } + } + fetchUser(); + }, [targetUid]); + + useCometChatEvents( + (event: CometChatEvent) => { + if (!user) return; + if (event.type === "ui:user/blocked" && event.user.getUid() === user.getUid()) { + setIsBlocked(true); + } + if (event.type === "ui:user/unblocked" && event.user.getUid() === user.getUid()) { + setIsBlocked(false); + } + }, + [user?.getUid()] + ); + + async function handleBlock() { + if (!user) return; + try { + await CometChat.blockUsers([user.getUid()]); + user.setBlockedByMe(true); + setIsBlocked(true); + setShowBlockDialog(false); + publish({ type: "ui:user/blocked", user }); + } catch (error) { + console.error("Error blocking user:", error); + } + } + + async function handleUnblock() { + if (!user) return; + try { + await CometChat.unblockUsers([user.getUid()]); + user.setBlockedByMe(false); + setIsBlocked(false); + publish({ type: "ui:user/unblocked", user }); + } catch (error) { + console.error("Error unblocking user:", error); + } + } + + if (!user) return
Loading...
; + + return ( +
+ {/* Confirmation dialog */} + {showBlockDialog && ( + setShowBlockDialog(false)}> + + + setShowBlockDialog(false)} + /> + + )} + + {/* Header with block/unblock action */} + setShowBlockDialog(true)} + style={{ background: "none", border: "none", cursor: "pointer", fontSize: "14px", color: isBlocked ? "#3399ff" : "#f44336" }} + > + {isBlocked ? "Unblock" : "Block"} + + } + /> + + {/* Message list */} +
+ +
+ + {/* Composer or blocked prompt */} + {!isBlocked ? ( + + ) : ( +
+

Cannot send a message to a blocked user.

+ + Click to unblock. + +
+ )} +
+ ); +} + +function App() { + return ( + + + + ); +} + +export default App; +``` ## Next Steps - - - Display and manage user lists. - - - Customize the message input component. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - \ No newline at end of file +- [Message Composer](/ui-kit/react/components/message-composer) — learn about composer customization +- [Conversations](/ui-kit/react/components/conversations) — build a full conversations list +- [CometChatProvider](/ui-kit/react/cometchat-provider) — configure the root provider diff --git a/ui-kit/react/guide-call-log-details.mdx b/ui-kit/react/guide-call-log-details.mdx deleted file mode 100644 index 136921cac..000000000 --- a/ui-kit/react/guide-call-log-details.mdx +++ /dev/null @@ -1,214 +0,0 @@ ---- -title: "Call Log Details" -sidebarTitle: "Call Log Details" -description: "Build a detailed call insights screen with metadata, participants, and recordings in CometChat React UI Kit." ---- - - - -| Field | Value | -| --- | --- | -| Packages | `@cometchat/chat-uikit-react` + `@cometchat/calls-sdk-javascript` | -| Key components | `CometChatCallDetails`, `CometChatCallDetailsInfo`, `CometChatCallDetailsParticipants`, `CometChatCallDetailsRecording` | -| Init | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` + Calls SDK installed | -| Purpose | Detailed call insights screen with metadata, participants, and recordings | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [All Guides](/ui-kit/react/guide-overview) | - - - -Call Log Details shows call metadata, participants, duration, recordings, and history when a user selects a call from the Calls tab. - -Before starting, complete the [Getting Started](/ui-kit/react/react-js-integration) guide for your framework and install `@cometchat/calls-sdk-javascript`. - ---- - -## Components - -| Component / Class | Role | -|:---|:---| -| `CometChatCallDetails` | Main container for call details display | -| `CometChatCallDetailsInfo` | Shows call status, duration, and info | -| `CometChatCallDetailsParticipants` | Displays call participants | -| `CometChatCallDetailsRecording` | Shows call recordings if available | -| `CometChatCallDetailsHistory` | Displays call history | -| `CometChatCallLogs` | Calls list component in the calls tab | - ---- - -## Integration Steps - -### 1. Calls Tab Integration - -Render `CometChatCallLogs` when the "Calls" tab is active. When a call is clicked, dispatch it to the app state so the details panel can display it. - -_File: [CometChatSelector.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatSelector/CometChatSelector.tsx)_ - -```tsx lines -{activeTab === "calls" ? ( - { - onSelectorItemClicked(e, "updateSelectedItemCall"); - }} - /> -) : null} -``` - ---- - -### 2. Call Details Component - -Guard-check that the selected item is a `CometChat.Call` instance, then render `CometChatCallDetails`. The `onBack` callback clears the selection and returns to the call list. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const CallDetailsView = () => { - if (!selectedItem || !(selectedItem instanceof CometChat.Call)) return null; - - return ( - { - setSelectedItem(undefined); - setAppState({ type: "updateSelectedItemCall", payload: undefined }); - }} - /> - ); -} -``` - ---- - -### 3. Call Details Implementation - -The main details screen. It shows the caller's avatar and name at the top, call info (status, duration) below, and three tabs: Participants, Recording, and History. Tab selection switches the content panel. - -_File: [CometChatCallLogDetails.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogDetails.tsx)_ - -```tsx lines -export const CometChatCallDetails = (props: { selectedItem: any, onBack?: () => void }) => { - const { selectedItem, onBack } = props; - const callDetailTabItems = [ - getLocalizedString("participants"), - getLocalizedString("recording"), - getLocalizedString("history") - ]; - const [activeTab, setActiveTab] = useState("Participants"); - const [user, setUser] = useState(); - const [subtitleText, setSubtitleText] = useState(); - - return ( -
-
-
- {getLocalizedString("call_details")} -
-
- -
- -
- {callDetailTabItems.map((tabItem) => ( -
setActiveTab(tabItem)} - className={activeTab === tabItem ? "cometchat-call-log-details__tabs-tab-item-active" : "cometchat-call-log-details__tabs-tab-item"} - > - {tabItem} -
- ))} -
- {activeTab === "Participants" ? - : activeTab === "Recording" ? - : activeTab === "History" ? - : null - } -
- ); -} -``` - ---- - -### 4. Call Information Display - -Renders the call status line (incoming/outgoing) based on who initiated the call. Compares the initiator's UID against the logged-in user to determine direction, then maps the SDK call status to a localized label. - -_File: [CometChatCallLogInfo.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogInfo.tsx)_ - -```tsx lines -export const CometChatCallDetailsInfo = (props: { call: any }) => { - const { call } = props; - const [loggedInUser, setLoggedInUser] = useState(null); - - const getCallStatus = (call: CometChat.Call, loggedInUser: CometChat.User): string => { - const isSentByMe = (call: any, loggedInUser: CometChat.User) => { - const senderUid: string = call.initiator?.getUid(); - return !senderUid || senderUid === loggedInUser?.getUid(); - } - const callStatus: string = call.getStatus(); - const isSentByMeFlag: boolean = isSentByMe(call, loggedInUser!); - - switch (callStatus) { - case CometChatUIKitConstants.calls.initiated: { - return isSentByMeFlag ? getLocalizedString("calls_outgoing_call") : getLocalizedString('calls_incoming_call'); - } - case CometChatUIKitConstants.calls.ended: { - return isSentByMeFlag ? getLocalizedString("calls_outgoing_call") : getLocalizedString('calls_incoming_call'); - } - } - } - - return ( -
- -
- ); -} -``` - ---- - -## Feature Matrix - -| Feature | Component / Method | File | -|:---|:---|:---| -| Calls tab integration | `CometChatCallLogs` | [CometChatSelector.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatSelector/CometChatSelector.tsx) | -| Call details display | `CometChatCallDetails` | [CometChatCallLogDetails.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogDetails.tsx) | -| Call information | `CometChatCallDetailsInfo` | [CometChatCallLogInfo.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogInfo.tsx) | -| Call participants | `CometChatCallDetailsParticipants` | [CometChatCallLogParticipants.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogParticipants.tsx) | -| Call recordings | `CometChatCallDetailsRecording` | [CometChatCallLogRecordings.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogRecordings.tsx) | -| Call history | `CometChatCallDetailsHistory` | [CometChatCallLogHistory.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogHistory.tsx) | -| Tab navigation | `activeTab` state | [CometChatCallLogDetails.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogDetails.tsx) | -| User status monitoring | `CometChat.addUserListener()` | [CometChatCallLogDetails.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCallLog/CometChatCallLogDetails.tsx) | - ---- - -## Next Steps - - - - The call logs component reference. - - - Overview of calling capabilities. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - \ No newline at end of file diff --git a/ui-kit/react/v7/guide-group-chat-setup.mdx b/ui-kit/react/guide-group-chat-setup.mdx similarity index 92% rename from ui-kit/react/v7/guide-group-chat-setup.mdx rename to ui-kit/react/guide-group-chat-setup.mdx index d4fa0d9b0..ac2667ad9 100644 --- a/ui-kit/react/v7/guide-group-chat-setup.mdx +++ b/ui-kit/react/guide-group-chat-setup.mdx @@ -10,9 +10,9 @@ By the end of this guide you will have a working group chat interface where user ## Prerequisites -- Completed the [Integration Guide](/ui-kit/react/v7/integration-react) guide +- Completed the [Integration Guide](/ui-kit/react/integration-react) guide - A running `CometChatProvider` setup with valid credentials -- Familiarity with the [Conversations](/ui-kit/react/v7/components/conversations) and [Message List](/ui-kit/react/v7/components/message-list) components +- Familiarity with the [Conversations](/ui-kit/react/components/conversations) and [Message List](/ui-kit/react/components/message-list) components ## Components Used @@ -34,16 +34,11 @@ Wrap your application in `CometChatProvider` and create a layout with a sidebar import { useState } from "react"; import { CometChat } from "@cometchat/chat-sdk-javascript"; import { CometChatProvider } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; import { GroupChat } from "./GroupChat"; function App() { return ( - + ); @@ -234,7 +229,6 @@ import { CometChatMessageComposer, CometChatMessageHeader, } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; function CreateGroupForm({ onCreate }: { onCreate: (group: CometChat.Group) => void }) { const [name, setName] = useState(""); @@ -347,11 +341,7 @@ function GroupChat() { function App() { return ( - + ); @@ -362,7 +352,7 @@ export default App; ## Next Steps -- [Groups](/ui-kit/react/v7/components/groups) — browse and join existing groups -- [Group Members](/ui-kit/react/v7/components/group-members) — manage group membership -- [Message Header](/ui-kit/react/v7/components/message-header) — customize the group header -- [CometChatProvider](/ui-kit/react/v7/cometchat-provider) — configure the root provider +- [Groups](/ui-kit/react/components/groups) — browse and join existing groups +- [Group Members](/ui-kit/react/components/group-members) — manage group membership +- [Message Header](/ui-kit/react/components/message-header) — customize the group header +- [CometChatProvider](/ui-kit/react/cometchat-provider) — configure the root provider diff --git a/ui-kit/react/guide-group-chat.mdx b/ui-kit/react/guide-group-chat.mdx deleted file mode 100644 index aa08c0532..000000000 --- a/ui-kit/react/guide-group-chat.mdx +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: "Group Chat" -sidebarTitle: "Group Chat" -description: "Implement group management including create, join, members, roles, and ownership transfer in CometChat React UI Kit." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Key components | `CometChatGroups`, `CometChatGroupMembers`, `CometChatCreateGroup`, `CometChatJoinGroup`, `CometChatAddMembers`, `CometChatBannedMembers`, `CometChatTransferOwnership` | -| Init | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` | -| Features | Create public/private/password-protected groups, manage members, roles, ownership transfer | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [All Guides](/ui-kit/react/guide-overview) | - - - -This guide covers the full group lifecycle: creating groups, joining them, managing members, changing roles, and transferring ownership. - -Before starting, complete the [Getting Started](/ui-kit/react/react-js-integration) guide for your framework. - ---- - -## Components - -| Component / Class | Role | -|:---|:---| -| `CometChatCreateGroup` | Creates new groups with different types and settings | -| `CometChatJoinGroup` | Handles joining public and password-protected groups | -| `CometChatGroupMembers` | Displays and manages group member lists | -| `CometChatAddMembers` | Adds new members to existing groups | -| `CometChatBannedMembers` | Manages banned members and unban operations | -| `CometChatTransferOwnership` | Transfers group ownership to other members | - ---- - -## Integration Steps - -### 1. Create Group - -Build a form that collects a group name, type (public/private/password), and optional password. On submit, generate a unique GUID, call `CometChat.createGroup()`, and emit `ccGroupCreated` so the rest of the UI updates. - -_File: [CometChatCreateGroup.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCreateGroup/CometChatCreateGroup.tsx)_ - -```tsx lines -export const CometChatCreateGroup = ({ setShowCreateGroup, onGroupCreated }: CreateGroupProps) => { - const [groupType, setGroupType] = useState("public"); - const [groupName, setGroupName] = useState(""); - const [groupPassword, setGroupPassword] = useState(""); - - async function handleSubmit(e: React.FormEvent) { - e.preventDefault(); - const GUID = `group_${new Date().getTime()}`; - const group = new CometChat.Group(GUID, groupName, groupType, groupPassword); - - try { - const createdGroup = await CometChat.createGroup(group); - CometChatGroupEvents.ccGroupCreated.next(createdGroup); - onGroupCreated(createdGroup); - setShowCreateGroup(false); - } catch (error) { - console.error("Group creation failed:", error); - } - } -}; -``` - ---- - -### 2. Join Group - -Handle joining for both public and password-protected groups. Call `CometChat.joinGroup()` with the group's GUID, type, and password (if applicable). On success, emit `ccGroupMemberJoined` to update the member list across the app. - -_File: [CometChatJoinGroup.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatJoinGroup/CometChatJoinGroup.tsx)_ - -```tsx lines -export const CometChatJoinGroup = ({ group, onProtectedGroupJoin }) => { - const [password, setPassword] = useState(""); - const [error, setError] = useState(false); - const loggedInUser = CometChatUIKitLoginListener.getLoggedInUser(); - - const joinGroup = () => { - CometChat.joinGroup(group.getGuid(), group.getType(), password) - .then((res) => { - onProtectedGroupJoin(group); - CometChatGroupEvents.ccGroupMemberJoined.next({ - joinedGroup: res, - joinedUser: loggedInUser - }); - }) - .catch(() => setError(true)); - }; -}; -``` - ---- - -### 3. View Group Members - -Render the member list for a group using `CometChatGroupMembers`. Pass `onItemClick` to handle member selection and `options` to add context-menu actions like "View Profile". - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const GroupMembersView = ({ group }: { group: CometChat.Group }) => { - return ( -
- { - console.log("Selected member:", member); - }} - options={[ - { - id: "view_profile", - title: getLocalizedString("view_profile"), - iconURL: profileIcon, - onClick: (member) => viewMemberProfile(member) - } - ]} - /> -
- ); -}; -``` - - ---- - -### 4. Add Members - -Let admins select users and add them to the group. Collect selected UIDs, call `CometChat.addMembersToGroup()`, and emit `ccGroupMemberAdded` so the member list refreshes. - -_File: [CometChatAddMembers.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatAddMembers/CometChatAddMembers.tsx)_ - -```tsx lines -export const CometChatAddMembers = ({ group, onBack }: IAddMembersProps) => { - const [selectedUsers, setSelectedUsers] = useState([]); - const [isLoading, setIsLoading] = useState(false); - - const addMembersToGroup = async () => { - if (selectedUsers.length === 0) return; - setIsLoading(true); - try { - const uids = selectedUsers.map(user => user.getUid()); - await CometChat.addMembersToGroup(uids, group.getGuid(), group.getType() as CometChat.GroupType); - CometChatGroupEvents.ccGroupMemberAdded.next({ - addedBy: CometChatUIKitLoginListener.getLoggedInUser()!, - addedMembers: selectedUsers, - addedIn: group - }); - onBack(); - } catch (error) { - console.error("Failed to add members:", error); - } finally { - setIsLoading(false); - } - }; -}; -``` - ---- - -### 5. Ban Members - -Fetch the list of banned members using `BannedMembersRequestBuilder`. This component displays banned users and provides unban functionality for group admins. - -_File: [CometChatBannedMembers.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatBannedMembers/CometChatBannedMembers.tsx)_ - -```tsx lines -export const CometChatBannedMembers = ({ group }: bannedMembersProp) => { - const [bannedMembers, setBannedMembers] = useState([]); - const [state, setState] = useState(States.loading); - - useEffect(() => { - const bannedMembersRequest = new CometChat.BannedMembersRequestBuilder(group.getGuid()) - .setLimit(30) - .build(); - - bannedMembersRequest.fetchNext().then( - bannedMembers => { - setBannedMembers(bannedMembers); - setState(States.loaded); - }, - error => { - console.log("Banned members fetch failed:", error); - setState(States.error); - } - ); - }, [group]); -}; -``` - - ---- - -### 6. Change Member Scope - -Promote or demote a member by calling `CometChat.updateGroupMemberScope()`. Pass the member's UID, the new scope (`admin`, `moderator`, or `participant`), and the group GUID. Emit `ccGroupMemberScopeChanged` so the UI reflects the role change. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const changeMemberScope = async (member: CometChat.GroupMember, newScope: string) => { - try { - await CometChat.updateGroupMemberScope(member.getUid(), newScope, group.getGuid()); - const updatedMember = { ...member, scope: newScope }; - CometChatGroupEvents.ccGroupMemberScopeChanged.next({ - changedBy: CometChatUIKitLoginListener.getLoggedInUser()!, - changedUser: updatedMember, - changedIn: group, - newScope: newScope, - oldScope: member.getScope() - }); - } catch (error) { - console.error("Failed to update member scope:", error); - } -}; -``` - ---- - -### 7. Transfer Ownership - -Let the current owner select a member and transfer ownership via `CometChat.transferGroupOwnership()`. The group object is cloned and updated locally, then `ccOwnershipChanged` is emitted to sync the UI. - -_File: [CometChatTransferOwnership.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatTransferOwnership/CometChatTransferOwnership.tsx)_ - -```tsx lines -export const CometChatTransferOwnership = ({ group, onClose }: ITransferOwnershipProps) => { - const [selectedMember, setSelectedMember] = useState(null); - const [isLoading, setIsLoading] = useState(false); - const [isError, setIsError] = useState(false); - - const transferOwnership = async () => { - if (!selectedMember) return; - setIsLoading(true); - setIsError(false); - try { - await CometChat.transferGroupOwnership(group.getGuid(), selectedMember.getUid()); - const groupClone = CometChatUIKitUtility.clone(group); - groupClone.setOwner(selectedMember.getUid()); - CometChatGroupEvents.ccOwnershipChanged.next({ - group: groupClone, - newOwner: CometChatUIKitUtility.clone(selectedMember) - }); - onClose(); - } catch (error) { - setIsError(true); - console.error("Ownership transfer failed:", error); - } finally { - setIsLoading(false); - } - }; -}; -``` - ---- - -## Feature Matrix - -| Feature | Component / Method | File | -|:---|:---|:---| -| Create group | `CometChatCreateGroup` | [CometChatCreateGroup.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatCreateGroup/CometChatCreateGroup.tsx) | -| Join group | `CometChatJoinGroup` | [CometChatJoinGroup.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatJoinGroup/CometChatJoinGroup.tsx) | -| View members | `CometChatGroupMembers` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Add members | `CometChatAddMembers` | [CometChatAddMembers.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatAddMembers/CometChatAddMembers.tsx) | -| Ban members | `CometChatBannedMembers` | [CometChatBannedMembers.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatBannedMembers/CometChatBannedMembers.tsx) | -| Change scope | `updateGroupMemberScope()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Transfer ownership | `CometChatTransferOwnership` | [CometChatTransferOwnership.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatTransferOwnership/CometChatTransferOwnership.tsx) | -| Group events | `CometChatGroupEvents` | Multiple files | - ---- - -## Next Steps - - - - Display and manage group lists. - - - Display and manage group member lists. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - \ No newline at end of file diff --git a/ui-kit/react/guide-message-privately.mdx b/ui-kit/react/guide-message-privately.mdx index 8095db11e..2c3edee72 100644 --- a/ui-kit/react/guide-message-privately.mdx +++ b/ui-kit/react/guide-message-privately.mdx @@ -1,189 +1,266 @@ --- title: "Message Privately" sidebarTitle: "Message Privately" -description: "Start private one-to-one chats from CometChat React UI Kit group conversations with message options, user lookup, and navigation." +description: "Let users send a private one-on-one message to another user directly from within a group chat conversation." --- - +## Goal -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Key components | `CometChatMessages`, `CometChatGroupMembers`, `CometChatMessageComposer`, `CometChatMessageList`, `CometChatMessageHeader` | -| Init | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` | -| Purpose | Launch a direct 1:1 chat from a group member profile | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [All Guides](/ui-kit/react/guide-overview) | +By the end of this guide you will have a group chat interface where users can select a group member and open a private one-on-one conversation with them — without leaving the current screen. This is useful for side conversations, follow-ups, or sensitive messages that shouldn't be shared with the entire group. - +## Prerequisites -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. +- Completed the [Integration Guide](/ui-kit/react/integration-react) guide +- A running `CometChatProvider` setup with valid credentials +- An existing group chat screen using `CometChatMessageList` and `CometChatMessageComposer` -Before starting, complete the [Getting Started](/ui-kit/react/react-js-integration) guide for your framework. +## Components Used ---- +| Component / API | Purpose | +|:----------------|:--------| +| `CometChatMessageList` | Displays group messages (publishes `ui:open-chat` internally via "Message Privately" option) | +| `CometChatMessageComposer` | Text input for the private conversation | +| `CometChatMessageHeader` | Displays user/group info | +| `useCometChatEvents` | Subscribe to `ui:open-chat` event | +| `ui:open-chat` | UI event published when user clicks "Message Privately" | -## Components +## Step 1: Set up the main layout with provider -| Component / Class | Role | -|:---|:---| -| `CometChatGroupMembers` | Displays group members with click handlers for private messaging | -| `CometChatMessageComposer` | Input component for composing private messages | -| `CometChatMessageList` | Displays private conversation messages | -| `CometChatMessageHeader` | Header showing private chat information | +Start with a layout that includes a conversations sidebar and a main chat area wrapped in `CometChatProvider`. ---- +```tsx App.tsx +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatProvider, + CometChatConversations, + CometChatMessageList, + CometChatMessageComposer, + CometChatMessageHeader, +} from "@cometchat/chat-uikit-react"; -## Integration Steps +function App() { + return ( + + + + ); +} -### 1. Group Member Click Handler +export default App; +``` -When a group member is clicked, cast them to a `User` object and initiate a private chat. The current group is saved so the user can return to it later. `CometChat.getConversation()` fetches or creates the 1:1 conversation. +## Step 2: Track group and private chat state -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +Maintain state for the active group conversation and a separate state for the private user when a user initiates a private message. -```tsx lines -const handleGroupMemberClick = (groupMember: CometChat.GroupMember) => { - const user = groupMember as CometChat.User; - startPrivateChatFromGroup(user, currentGroup); -} +```tsx ChatWithPrivateMessaging.tsx +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; + +function ChatWithPrivateMessaging() { + const [user, setUser] = useState(null); + const [group, setGroup] = useState(null); + const [privateUser, setPrivateUser] = useState(null); -const startPrivateChatFromGroup = (user: CometChat.User, group: CometChat.Group) => { - setAppState({ type: "updatePreviousGroup", payload: group }); - - CometChat.getConversation(user.getUid(), CometChatUIKitConstants.MessageReceiverType.user) - .then((conversation) => { - setSelectedItem(conversation); - setAppState({ type: "updateSideComponent", payload: { visible: false, type: "" } }); - setShowPrivateChat(true); - }) - .catch((error) => { - console.error("Failed to start private chat:", error); - }); + // ... continued in next steps } ``` ---- +## Step 3: Handle conversation selection -### 2. Group Members with Private Messaging Option - -Add a "Message Privately" option to the group members list. The `options` prop adds a context-menu action that triggers the private chat flow when clicked. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const GroupMembersWithPrivateMessaging = ({ group }: { group: CometChat.Group }) => { - return ( - { - handleGroupMemberClick(member); - } - } - ]} - selectionMode={SelectionMode.none} - /> - ); +Connect `CometChatConversations` to switch between user and group chats. When switching conversations, close any open private message panel. + +```tsx +function handleConversationClick(conversation: CometChat.Conversation) { + setPrivateUser(null); // close private panel on conversation switch + + const entity = conversation.getConversationWith(); + if (entity instanceof CometChat.User) { + setUser(entity); + setGroup(null); + } else if (entity instanceof CometChat.Group) { + setGroup(entity); + setUser(null); + } } ``` ---- +## Step 4: Initiate a private message from a group member -### 3. Private Chat Interface - -Render a full chat view (header, message list, composer) for the 1:1 conversation. The header includes a back button that returns the user to the original group, and a subtitle showing which group the private chat was initiated from. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const PrivateChatFromGroupView = ({ user, previousGroup }: { - user: CometChat.User, - previousGroup: CometChat.Group -}) => { - const returnToGroup = () => { - setShowPrivateChat(false); - CometChat.getConversation(previousGroup.getGuid(), CometChatUIKitConstants.MessageReceiverType.group) - .then((conversation) => { - setSelectedItem(conversation); - }); - }; - - return ( -
- - {}} /> - -
- ); +Use the message header or a custom action to let users pick a group member for private messaging. You can fetch the user from a member click event or from the message sender's info. + +```tsx +async function handleMessagePrivately(uid: string) { + try { + const targetUser = await CometChat.getUser(uid); + setPrivateUser(targetUser); + } catch (error) { + console.error("Failed to fetch user for private messaging:", error); + } } ``` ---- +## Step 5: Listen for the `ui:open-chat` event + +Use `useCometChatEvents` to subscribe to the `ui:open-chat` event, which is published internally when a user clicks "Message Privately" from the context menu. When the event fires, extract the user and open the private panel. -### 4. State Management +```tsx +import { useCometChatEvents } from "@cometchat/chat-uikit-react"; +import type { CometChatEvent } from "@cometchat/chat-uikit-react"; -Add reducer cases to track the group the user came from, whether the private chat is visible, and which user is being messaged. This lets the app restore the group context when the user navigates back. +useCometChatEvents( + (event: CometChatEvent) => { + if (event.type === "ui:open-chat" && event.user) { + setPrivateUser(event.user); + } + }, + [group?.getGuid()] +); +``` -_File: [appReducer.ts](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/context/appReducer.ts)_ +## Step 6: Render the private message panel -```tsx lines -interface AppState { - previousGroup?: CometChat.Group; - showPrivateChat?: boolean; - privateChatUser?: CometChat.User; -} +When `privateUser` is set, show a side panel with a private one-on-one chat. This panel includes a header, message list, and composer scoped to the private user. -case "updatePreviousGroup": { - return { ...state, ["previousGroup"]: action.payload }; -} -case "updateShowPrivateChat": { - return { ...state, ["showPrivateChat"]: action.payload }; -} -case "updatePrivateChatUser": { - return { ...state, ["privateChatUser"]: action.payload }; -} -``` +```tsx +{privateUser && ( +
+
+ + Private: {privateUser.getName()} + + +
---- +
+ +
-## Feature Matrix + +
+)} +``` -| Feature | Component / Method | File | -|:---|:---|:---| -| Group member selection | `CometChatGroupMembers` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Private chat initiation | `startPrivateChatFromGroup()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Private chat interface | `PrivateChatFromGroupView` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Context preservation | `updatePreviousGroup` | [appReducer.ts](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/context/appReducer.ts) | -| Return to group | `returnToGroup()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Member options | `options` in CometChatGroupMembers | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| State management | `updateShowPrivateChat` | [appReducer.ts](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/context/appReducer.ts) | +## Step 7: Handle edge cases + +Consider these scenarios when implementing private messaging from a group: + +| Scenario | Behavior | +|:---------|:---------| +| User messages themselves | Disable the private message option for the logged-in user's own messages | +| User is blocked | Check `getBlockedByMe()` before opening the private panel and show a prompt | +| Private panel already open | Replace the current private user with the newly selected one | +| Group conversation changes | Close the private panel when switching to a different conversation | + +## Complete Example + +```tsx App.tsx +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatProvider, + CometChatConversations, + CometChatMessageList, + CometChatMessageComposer, + CometChatMessageHeader, + useCometChatEvents, +} from "@cometchat/chat-uikit-react"; +import type { CometChatEvent } from "@cometchat/chat-uikit-react"; + +function ChatWithPrivateMessaging() { + const [user, setUser] = useState(null); + const [group, setGroup] = useState(null); + const [privateUser, setPrivateUser] = useState(null); + + function handleConversationClick(conversation: CometChat.Conversation) { + setPrivateUser(null); + const entity = conversation.getConversationWith(); + if (entity instanceof CometChat.User) { + setUser(entity); + setGroup(null); + } else if (entity instanceof CometChat.Group) { + setGroup(entity); + setUser(null); + } + } + + async function handleMessagePrivately(uid: string) { + try { + const targetUser = await CometChat.getUser(uid); + setPrivateUser(targetUser); + } catch (error) { + console.error("Failed to fetch user for private messaging:", error); + } + } + + useCometChatEvents( + (event: CometChatEvent) => { + if (event.type === "ui:open-chat" && event.user) { + setPrivateUser(event.user); + } + }, + [group?.getGuid()] + ); + + return ( +
+ {/* Conversations sidebar */} +
+ +
+ + {/* Main chat panel */} +
+ {(user || group) && ( + <> + +
+ +
+ + + )} +
+ + {/* Private message panel */} + {privateUser && ( +
+
+ + Private: {privateUser.getName()} + + +
+ +
+ +
+ + +
+ )} +
+ ); +} ---- +function App() { + return ( + + + + ); +} + +export default App; +``` ## Next Steps - - - Display and manage group member lists. - - - Render real-time message threads. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - +- [Message Composer](/ui-kit/react/components/message-composer) — customize the composer for private chats +- [Conversations](/ui-kit/react/components/conversations) — manage the conversations list +- [Users](/ui-kit/react/components/cometchat-users) — browse and select users directly +- [CometChatProvider](/ui-kit/react/cometchat-provider) — learn about provider configuration diff --git a/ui-kit/react/v7/guide-new-chat-creation.mdx b/ui-kit/react/guide-new-chat-creation.mdx similarity index 93% rename from ui-kit/react/v7/guide-new-chat-creation.mdx rename to ui-kit/react/guide-new-chat-creation.mdx index 2e1975d30..2572cbc7f 100644 --- a/ui-kit/react/v7/guide-new-chat-creation.mdx +++ b/ui-kit/react/guide-new-chat-creation.mdx @@ -10,9 +10,9 @@ By the end of this guide you will have a chat interface where users can initiate ## Prerequisites -- Completed the [Integration Guide](/ui-kit/react/v7/integration-react) guide +- Completed the [Integration Guide](/ui-kit/react/integration-react) guide - A running `CometChatProvider` setup with valid credentials -- Familiarity with [CometChatUsers](/ui-kit/react/v7/components/users) and [CometChatGroups](/ui-kit/react/v7/components/groups) components +- Familiarity with [CometChatUsers](/ui-kit/react/components/users) and [CometChatGroups](/ui-kit/react/components/groups) components ## Components Used @@ -34,16 +34,11 @@ Wrap your application in `CometChatProvider` and create a layout that will hold import { useState } from "react"; import { CometChat } from "@cometchat/chat-sdk-javascript"; import { CometChatProvider } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; import { NewChatApp } from "./NewChatApp"; function App() { return ( - + ); @@ -266,7 +261,6 @@ import { CometChatMessageComposer, CometChatMessageHeader, } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; type ChatTarget = | { type: "user"; entity: CometChat.User } @@ -408,11 +402,7 @@ function NewChatApp() { function App() { return ( - + ); @@ -423,7 +413,7 @@ export default App; ## Next Steps -- [CometChatUsers](/ui-kit/react/v7/components/users) — customize the user list appearance and filtering -- [CometChatGroups](/ui-kit/react/v7/components/groups) — browse and manage groups -- [Conversations](/ui-kit/react/v7/components/conversations) — display existing conversations -- [Group Chat Setup](/ui-kit/react/v7/guide-group-chat-setup) — create and configure group conversations +- [CometChatUsers](/ui-kit/react/components/users) — customize the user list appearance and filtering +- [CometChatGroups](/ui-kit/react/components/groups) — browse and manage groups +- [Conversations](/ui-kit/react/components/conversations) — display existing conversations +- [Group Chat Setup](/ui-kit/react/guide-group-chat-setup) — create and configure group conversations diff --git a/ui-kit/react/guide-new-chat.mdx b/ui-kit/react/guide-new-chat.mdx deleted file mode 100644 index 40beee2ac..000000000 --- a/ui-kit/react/guide-new-chat.mdx +++ /dev/null @@ -1,206 +0,0 @@ ---- -title: "New Chat" -sidebarTitle: "New Chat" -description: "Build a unified new chat entry point for starting 1:1 or group conversations in CometChat React UI Kit." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Key components | `CometChatUsers`, `CometChatGroups`, `CometChatJoinGroup`, `CometChatSelector` | -| Init | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` | -| Purpose | Unified new chat entry point for starting 1:1 or group conversations | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [All Guides](/ui-kit/react/guide-overview) | - - - -The New Chat feature lets users start conversations with other users or join group conversations from a single interface. - -Before starting, complete the [Getting Started](/ui-kit/react/react-js-integration) guide for your framework. - ---- - -## Components - -| Component / Class | Role | -|:---|:---| -| `CometChatNewChatView` | Main container for new chat creation interface | -| `CometChatUsers` | Displays list of available users for chat creation | -| `CometChatGroups` | Shows available groups for joining | -| `CometChatJoinGroup` | Handles protected group joining process | -| `CometChatSelector` | Navigation component with new chat button | - ---- - -## Integration Steps - -### 1. New Chat State Management - -Track whether the new chat view is visible and which user/group was selected. When the "New Chat" button is clicked, show the view and hide any open side panels. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const [showNewChat, setShowNewChat] = useState(false); -const [newChat, setNewChat] = useState<{ - user?: CometChat.User, - group?: CometChat.Group -} | undefined>(); - -const onNewChatClicked = () => { - setShowNewChat(true); - setAppState({ type: "updateSideComponent", payload: { type: "", visible: false } }); -} -``` - ---- - -### 2. Conditional Rendering - -Switch between the new chat view, the messages view, or an empty state depending on the current app state. `useCallback` prevents unnecessary re-renders. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const InformationComponent = useCallback(() => { - return ( - <> - {showNewChat ? - : - (selectedItem || newChat?.user || newChat?.group) ? () - : - () - } - - ) -}, [activeTab, showNewChat, selectedItem, newChat, appState.goToMessageId]); -``` - ---- - -### 3. New Chat View - -The main new chat interface with a header, back button, and tabbed navigation between Users and Groups. Selecting a tab switches the list below. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const CometChatNewChatView: React.FC = () => { - const [selectedTab, setSelectedTab] = useState('user'); - const [group, setGroup] = useState(); - const loggedInUser = CometChatUIKitLoginListener.getLoggedInUser(); - - const handleTabClick = (tab: string) => { - setSelectedTab(tab); - }; - - return ( -
-
- { - setShowNewChat(false); - }} /> -
New Chat
-
- -
-
handleTabClick('user')}> {getLocalizedString("user_title")}
-
handleTabClick('group')}> {getLocalizedString("group_title")}
-
- -
- -
-
- ); -}; -``` - ---- - -### 4. User Selection and Chat Creation - -The tab content renders either `CometChatUsers` or `CometChatGroups`. Clicking a user creates a 1:1 chat and closes the new chat view. Clicking a group triggers the join flow. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const TabContent: React.FC = ({ selectedTab }) => { - return selectedTab === 'user' ? { - setNewChat({ user, group: undefined }); - setAppState({ type: "updateSideComponent", payload: { visible: false, type: "" } }); - setShowNewChat(false); - setAppState({ type: "updateSelectedItemUser", payload: user }); - setAppState({ type: "updateSelectedItemGroup", payload: undefined }); - }} - /> - : { - setAppState({ type: "updateSelectedItemUser", payload: undefined }); - setAppState({ type: "updateSelectedItemGroup", payload: e }); - joinGroup(e) - }} />; -}; -``` - ---- - -### 5. Group Joining Logic - -Handle the join flow based on group type. Public groups are joined directly via `CometChat.joinGroup()`. Password-protected groups show a password prompt first. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const joinGroup = (e) => { - if (!e.getHasJoined()) { - if (e.getType() === CometChatUIKitConstants.GroupTypes.public) { - CometChat.joinGroup(...) - .then((response) => { setNewChat({ group: response }); }) - .catch((error) => { console.log(error); }); - } else { - setGroup(e); - showJoinGroupRef.current = true; - } - } -} -``` - ---- - -## Feature Matrix - -| Feature | Component / Method | File | -|:---|:---|:---| -| Open new chat view | `onNewChatClicked()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| New chat interface | `CometChatNewChatView` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| User selection | `CometChatUsers` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Group selection | `CometChatGroups` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Group joining | `joinGroup()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| State management | `showNewChat` state | [appReducer.ts](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/context/appReducer.ts) | -| Chat creation | `setNewChat()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Navigation handling | `setShowNewChat(false)` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | - ---- - -## Next Steps - - - - Display and manage conversation lists. - - - Display and manage group lists. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - diff --git a/ui-kit/react/guide-overview.mdx b/ui-kit/react/guide-overview.mdx deleted file mode 100644 index 765f2e2f0..000000000 --- a/ui-kit/react/guide-overview.mdx +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "Overview" -sidebarTitle: "Overview" -description: "Browse React UI Kit feature guides for blocking users, call details, group chat, private messages, search, and threaded conversations." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Purpose | Index of task-oriented feature guides for the React UI Kit | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Components | [Components Overview](/ui-kit/react/components-overview) | -| Guides | [Block/Unblock](/ui-kit/react/guide-block-unblock-user) · [Call Log Details](/ui-kit/react/guide-call-log-details) · [Group Chat](/ui-kit/react/guide-group-chat) · [Message Privately](/ui-kit/react/guide-message-privately) · [New Chat](/ui-kit/react/guide-new-chat) · [Search Messages](/ui-kit/react/guide-search-messages) · [Threaded Messages](/ui-kit/react/guide-threaded-messages) | - - - -> This page indexes focused, task‑oriented feature guides for the React UI Kit. Each guide shows how to implement a specific capability end‑to‑end using UI components. - -## When to Use These Guides - -Use these guides after completing the base [Getting Started](/ui-kit/react/react-js-integration) (or framework variant: [Next.js](/ui-kit/react/next-js-integration), [React Router](/ui-kit/react/react-router-integration)). They help you layer additional UX without rewriting core chat flows. - -## Guide Directory - -| Guide | Description | -|:------|:------------| -| [Block / Unblock User](/ui-kit/react/guide-block-unblock-user) | Let users block or unblock others in 1:1 chats; hides composer and shows an unblock prompt while preventing message exchange. | -| [Call Log Details](/ui-kit/react/guide-call-log-details) | Detailed call insights screen: metadata, participants, join/leave history, and recordings. | -| [Group Management](/ui-kit/react/guide-group-chat) | Create/join groups, view members, add / ban users, change roles/scopes, transfer ownership. | -| [Message Privately](/ui-kit/react/guide-message-privately) | Launch a direct 1:1 chat from a user profile or list; optionally send a first message to surface conversation. | -| [New Chat](/ui-kit/react/guide-new-chat) | Unified entry for starting new 1:1 or group chats with user & group discovery. | -| [Threaded Messages](/ui-kit/react/guide-threaded-messages) | Threaded replies: open parent context, list replies, compose within focused thread. | -| [Search Messages](/ui-kit/react/guide-search-messages) | Add full‑text message search across conversations with result routing into context. | -| [Custom Text Formatter](/ui-kit/react/custom-text-formatter-guide) | Extend the base formatter to implement custom inline patterns (hashtags, keywords) with regex + callbacks. | -| [Mentions Formatter](/ui-kit/react/mentions-formatter-guide) | Add @mentions with styled tokens, suggestion list, and click handling for users & members. | -| [URL Formatter](/ui-kit/react/url-formatter-guide) | Detect and style plain URLs; render them as clickable links with optional tracking logic. | -| [Shortcut Formatter](/ui-kit/react/shortcut-formatter-guide) | Provide !shortcut style expansions invoking extension APIs or dialogs before inserting content. | - -Need another guide? Open a request via our [Support Portal](https://help.cometchat.com/hc/en-us/requests/new). - ---- - -## Next Steps - - - - Set up the React UI Kit - - - Explore all UI components - - - Customize themes and styling - - - Handle UI Kit events - - diff --git a/ui-kit/react/guide-search-messages.mdx b/ui-kit/react/guide-search-messages.mdx index e510ead5c..b917e2ce8 100644 --- a/ui-kit/react/guide-search-messages.mdx +++ b/ui-kit/react/guide-search-messages.mdx @@ -1,132 +1,182 @@ --- title: "Search Messages" sidebarTitle: "Search Messages" -description: "Add CometChat React UI Kit message search with query input, scoped results, message selection, and navigation to matching chats." +description: "Add message search to your chat so users can find specific messages within a conversation using the built-in CometChatSearch component." --- - +## Goal -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Key components | `CometChatSearchMessages`, `CometChatMessageList`, `CometChatMessageComposer`, `CometChatMessageHeader` | -| Init | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` | -| Purpose | Full-text message search across conversations with result routing and navigation | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [All Guides](/ui-kit/react/guide-overview) | +By the end of this guide you will have a chat interface with a search panel that lets users find messages in a conversation by keyword and scroll to a selected result — using the built-in [`CometChatSearch`](/ui-kit/react/components/search) component instead of building your own search UI. - +`CometChatSearch` already handles the input, debouncing, SDK queries, result rendering, pagination, loading/empty/error states, and keyword highlighting — so you only wire it to your message list. -Search Messages lets users locate specific messages across conversations and groups using keyword search, then navigate directly to the result. +## Prerequisites -Before starting, complete the [Getting Started](/ui-kit/react/react-js-integration) guide for your framework. +- Completed the [Integration Guide](/ui-kit/react/integration-react) +- A running `CometChatProvider` setup with valid credentials +- An existing chat screen using `CometChatMessageList` and `CometChatMessageHeader` ---- - -## Components - -| Component / Class | Role | -|:---|:---| -| `CometChatSearchMessages` | Main container for searching messages | -| `CometChatMessageList` | Displays filtered messages based on search results | -| `CometChatMessageComposer` | Supports navigation after selecting a search result | -| `CometChatMessageHeader` | Displays search context and navigation controls | +## Components Used ---- +| Component | Purpose | +|:----------|:--------| +| `CometChatSearch` | Built-in search panel — input, message queries, result list, and states | +| `CometChatMessageList` | Displays messages and supports `goToMessageId` for scrolling to a result | +| `CometChatMessageHeader` | Header with a search trigger button | +| `CometChatConversations` | Sidebar for switching conversations | -## Integration Steps +## Step 1: Set up the chat layout with search state -### 1. Search State Management +Start with a full chat layout — a conversations sidebar, message panel, and state to control the search panel visibility and the message to jump to. -Track the current search keyword and the message ID to scroll to. When a new search is triggered, reset `goToMessageId` so the list doesn't jump to a stale result. +_File: App.tsx_ -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +```tsx +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatProvider, + CometChatConversations, + CometChatMessageList, + CometChatMessageComposer, + CometChatMessageHeader, + CometChatSearch, + type CometChatSearchMessageClickEvent, +} from "@cometchat/chat-uikit-react"; -```tsx lines -const [searchKeyword, setSearchKeyword] = useState(""); -const [goToMessageId, setGoToMessageId] = useState(undefined); +function ChatWithSearch() { + const [user, setUser] = useState(null); + const [group, setGroup] = useState(null); + const [showSearch, setShowSearch] = useState(false); + const [goToMessageId, setGoToMessageId] = useState(undefined); -const onSearch = (keyword: string) => { - setSearchKeyword(keyword); + function handleConversationClick(conversation: CometChat.Conversation) { + setShowSearch(false); setGoToMessageId(undefined); -}; + const entity = conversation.getConversationWith(); + if (entity instanceof CometChat.User) { + setUser(entity); + setGroup(null); + } else if (entity instanceof CometChat.Group) { + setGroup(entity); + setUser(null); + } + } + + // Fired by CometChatSearch when a message result is clicked + function handleMessageClick(event: CometChatSearchMessageClickEvent) { + setGoToMessageId(event.message.getId()); + } + + return ( +
+ {/* Conversations sidebar */} +
+ +
+ + {/* Main message panel */} +
+ {(user || group) && ( + <> + setShowSearch((prev) => !prev)} + aria-label="Search messages" + style={{ background: "none", border: "none", cursor: "pointer", fontSize: "18px" }} + > + 🔍 + + } + /> +
+ +
+ + + )} +
+ + {/* Built-in search panel, scoped to the open conversation */} + {showSearch && (user || group) && ( +
+ setShowSearch(false)} + /> +
+ )} +
+ ); +} + +function App() { + return ( + + + + ); +} + +export default App; ``` ---- - -### 2. Search Input +## Step 2: Scope CometChatSearch to the conversation -Render the search component and wire its `onSearch` callback to update the keyword state. The placeholder text is localized. +`CometChatSearch` is a complete, self-contained search panel — there's no custom input or result list to build. A few props tailor it to in-conversation message search: -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines - onSearch(keyword)} - placeholder={getLocalizedString("search_messages_placeholder")} +```tsx + setShowSearch(false)} /> ``` ---- +| Prop | What it does | +|:-----|:-------------| +| `searchIn={["messages"]}` | Shows only message results (omit it to also search conversations) | +| `uid` / `guid` | Scopes the search to a single user or group conversation. Pass whichever matches the open chat | +| `onMessageClicked` | Fired when a result is tapped. The event payload is `{ message, searchKeyword }` | +| `onBack` | Fired when the back button is clicked — use it to close the panel | + +The component handles the search input, debouncing, SDK queries, pagination, and the loading/empty/error states internally. For the full prop list and customization (filter chips, custom result item views, request builders), see the [Search component reference](/ui-kit/react/components/search). -### 3. Search Result Integration +## Step 3: Navigate to a selected search result -Pass `searchKeyword` and `goToMessageId` to `CometChatMessageList`. The list filters messages matching the keyword and highlights them. When `goToMessageId` is set, the list scrolls to that message. +When a result is clicked, `onMessageClicked` gives you the selected `message`. Pass its ID to `CometChatMessageList` via the `goToMessageId` prop — the list scrolls to the matching message and highlights it. -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +```tsx +function handleMessageClick(event: CometChatSearchMessageClickEvent) { + setGoToMessageId(event.message.getId()); +} -```tsx lines ``` ---- - -### 4. Navigate to Search Result - -When a user taps a search result, set `goToMessageId` to that message's ID. The message list will scroll to and highlight the target message. - -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ - -```tsx lines -const handleResultClick = (messageId: number) => { - setGoToMessageId(messageId); -}; -``` - -Attach `handleResultClick` to your message search result selection logic. - ---- - -## Feature Matrix - -| Feature | Component / Method | File | -|:---|:---|:---| -| Search input | `CometChatSearchMessages` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Display results | `CometChatMessageList` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Keyword highlighting | `searchKeyword` prop | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Navigate to result | `goToMessageId` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| State management | `onSearch` handler | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | - ---- + +Reset `goToMessageId` to `undefined` when switching conversations (as in `handleConversationClick` above) so the list doesn't try to jump to a message ID from a previous chat. + ## Next Steps - - - The search component reference. - - - Render real-time message threads. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - +- [Search](/ui-kit/react/components/search) — full `CometChatSearch` reference: filters, scopes, custom result views, and request builders +- [Message List](/ui-kit/react/components/message-list) — configure message rendering and scroll behavior +- [Message Header](/ui-kit/react/components/message-header) — customize header actions and auxiliary views +- [Threaded Messages](/ui-kit/react/guide-threaded-messages) — add threaded replies to your chat diff --git a/ui-kit/react/guide-threaded-messages.mdx b/ui-kit/react/guide-threaded-messages.mdx index da08eeb2e..ced528be6 100644 --- a/ui-kit/react/guide-threaded-messages.mdx +++ b/ui-kit/react/guide-threaded-messages.mdx @@ -1,189 +1,214 @@ --- title: "Threaded Messages" sidebarTitle: "Threaded Messages" -description: "Implement threaded message replies with parent context, reply list, and focused thread composer in CometChat React UI Kit." +description: "Add threaded message replies to your chat so users can create focused sub-conversations on any message." --- - +## Goal -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Key components | `CometChatThreadedMessages`, `CometChatThreadHeader`, `CometChatMessageList`, `CometChatMessageComposer` | -| Init | `CometChatUIKit.init(UIKitSettings)` then `CometChatUIKit.login("UID")` | -| Entry point | `CometChatMessages.onThreadRepliesClick` opens thread view from group messages | -| Sample app | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) | -| Related | [All Guides](/ui-kit/react/guide-overview) | +By the end of this guide you will have a chat interface where users can open a thread panel from any message, view the parent message with its reply count, browse threaded replies, and send new replies — all using v7 compound components and a state-based approach (no custom events needed). - +## Prerequisites -Threaded messages let users create sub-conversations by replying to specific messages in group chats. This reduces clutter and keeps discussions focused. +- Completed the [Integration Guide](/ui-kit/react/integration-react) guide +- A running `CometChatProvider` setup with valid credentials +- An existing chat screen using `CometChatMessageList` and `CometChatMessageComposer` -Before starting, complete the [Getting Started](/ui-kit/react/react-js-integration) guide for your framework. +## Components Used ---- - -## Components - -| Component / Class | Role | -|:---|:---| -| `CometChatThreadedMessages` | Main container for threaded messages | -| `CometChatThreadHeader` | Displays parent message and controls | -| `CometChatMessageList` | Shows messages filtered by `parentMessageId` | -| `CometChatMessageComposer` | Input for composing threaded replies | -| `CometChatMessages.onThreadRepliesClick` | Opens thread view from group messages | +| Component | Purpose | +|:----------|:--------| +| `CometChatThreadHeader` | Displays the parent message and reply count at the top of the thread panel | +| `CometChatMessageList` | Renders threaded replies when given a `parentMessageId` | +| `CometChatMessageComposer` | Sends replies into the thread with `parentMessageId`, `layout="compact"`, and `enableRichTextEditor` | ---- - -## Integration Steps +## Step 1: Thread State Management -### 1. Thread State Management +Store the `threadedMessage` in state. When set, the thread panel renders. When cleared, it closes. This mirrors the pattern used in the sample app's `CometChatThreadPanel` component. -Store the parent message that the user clicked "Reply in Thread" on. When set, update the app state to show the threaded messages side panel. +_File: ChatWithThreads.tsx_ -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +```tsx +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; -```tsx lines -const [threadedMessage, setThreadedMsg] = useState(); +function ChatWithThreads() { + const [user, setUser] = useState(null); + const [group, setGroup] = useState(null); + const [threadedMessage, setThreadedMessage] = useState(null); -const updateThreadedMessage = (message: CometChat.BaseMessage) => { - setThreadedMsg(message); - setAppState({ type: "updateSideComponent", payload: { visible: true, type: "threadedMessage" } }); - setAppState({ type: "updateThreadedMessage", payload: message }); -}; + // Thread opens when threadedMessage is set, closes when cleared +} ``` ---- +## Step 2: Wire the Thread Trigger -### 2. Thread Trigger in Group Messages +Use the `onThreadRepliesClick` callback on `CometChatMessageList` to capture when a user clicks "Reply in Thread." This sets the threaded message and opens the panel — no events required. -Wire the `onThreadRepliesClick` callback on `CometChatMessages`. When a user clicks the thread reply icon on any message, this fires with the parent message object. +_File: ChatWithThreads.tsx_ -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +```tsx +import { CometChatMessageList } from "@cometchat/chat-uikit-react"; -```tsx lines - updateThreadedMessage(message)} + setThreadedMessage(message)} /> ``` ---- +## Step 3: Build the Thread Panel -### 3. Threaded Messages Component +When `threadedMessage` is set, render a side panel composing `CometChatThreadHeader` + `CometChatMessageList` (with `parentMessageId`) + `CometChatMessageComposer` (with `parentMessageId`, `layout="compact"`, and `enableRichTextEditor`). The `onClose` callback clears the state to dismiss the panel. -Render the thread panel with the parent message, reply list, and composer. `goToMessageId` and `searchKeyword` support in-thread search navigation. +_File: ChatWithThreads.tsx_ -_File: [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx)_ +```tsx +import { + CometChatThreadHeader, + CometChatMessageList, + CometChatMessageComposer, +} from "@cometchat/chat-uikit-react"; -```tsx lines - -``` - ---- - -### 4. App State Management - -Add reducer cases to store the threaded message and control the side panel visibility. These are dispatched by `updateThreadedMessage` in step 1. +{threadedMessage && ( +
+ setThreadedMessage(null)} + onParentDeleted={() => setThreadedMessage(null)} + /> -_File: [appReducer.ts](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/context/appReducer.ts)_ +
+ +
-```tsx lines -case "updateThreadedMessage": { - return { ...state, ["threadedMessage"]: action.payload }; -} -case "updateSideComponent": { - return { - ...state, - ["sideComponent"]: action.payload, - ["sideComponentTop"]: action.payload?.type || "" - }; -} + +
+)} ``` ---- - -## Implementation Flow +## Step 4: Handle Parent Deleted -Fetch the parent message, load replies, send new replies, and handle live updates: - -```tsx lines -const parentMessage = message; -const group = selectedItem as CometChat.Group; -``` +Use the `onParentDeleted` prop on `CometChatThreadHeader` to automatically close the thread panel when the parent message is deleted by another user or a moderation action. -```tsx lines - -``` +_File: ChatWithThreads.tsx_ -```tsx lines - setThreadedMessage(null)} + onParentDeleted={() => setThreadedMessage(null)} /> ``` -When the composer is blocked (e.g. permissions), show a fallback: - -```tsx lines -{showComposer ? ( - -) : ( -
-
- {getLocalizedString("cannot_send_to_group")} - {getLocalizedString("check_permissions")} +## Complete Example + +_File: App.tsx_ + +```tsx +import { useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatProvider, + CometChatConversations, + CometChatMessageList, + CometChatMessageComposer, + CometChatMessageHeader, + CometChatThreadHeader, +} from "@cometchat/chat-uikit-react"; + +function ChatWithThreads() { + const [user, setUser] = useState(null); + const [group, setGroup] = useState(null); + const [threadedMessage, setThreadedMessage] = useState(null); + + function handleConversationClick(conversation: CometChat.Conversation) { + setThreadedMessage(null); + const entity = conversation.getConversationWith(); + if (entity instanceof CometChat.User) { + setUser(entity); + setGroup(null); + } else if (entity instanceof CometChat.Group) { + setGroup(entity); + setUser(null); + } + } + + return ( +
+ {/* Conversations sidebar */} +
+ +
+ + {/* Main message panel */} +
+ {(user || group) && ( + <> + +
+ setThreadedMessage(message)} + /> +
+ + + )} +
+ + {/* Thread panel */} + {threadedMessage && ( +
+ setThreadedMessage(null)} + onParentDeleted={() => setThreadedMessage(null)} + /> +
+ +
+
+ )}
-)} -``` - ---- - -## Feature Matrix + ); +} -| Feature | Component / Method | File | -|:---|:---|:---| -| Show thread option | `onThreadRepliesClick` | [CometChatMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatMessages/CometChatMessages.tsx) | -| Display thread msgs | `ThreadedMessageList` | [CometChatThreadedMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatDetails/CometChatThreadedMessages.tsx) | -| Compose reply | `MessageComposer` | [CometChatThreadedMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatDetails/CometChatThreadedMessages.tsx) | -| Thread header | `ThreadHeader` | [CometChatThreadedMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatDetails/CometChatThreadedMessages.tsx) | -| Search in threads | `TextHighlightFormatter` | [CometChatThreadedMessages.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatDetails/CometChatThreadedMessages.tsx) | -| Navigate to message | `goToMessageId` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| Thread state | `updateThreadedMessage()` | [CometChatHome.tsx](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/components/CometChatHome/CometChatHome.tsx) | -| App context | `appReducer.ts` | [appReducer.ts](https://github.com/cometchat/cometchat-uikit-react/blob/v6/sample-app/src/context/appReducer.ts) | +function App() { + return ( + + + + ); +} ---- +export default App; +``` ## Next Steps - - - Render real-time message threads. - - - Customize the thread header component. - - - Browse all feature and formatter guides. - - - Full working sample application on GitHub. - - +- [Thread Header](/ui-kit/react/components/thread-header) — customize the thread header appearance +- [Message List](/ui-kit/react/components/message-list) — configure message list rendering and options +- [CometChatProvider](/ui-kit/react/cometchat-provider) — learn about provider configuration diff --git a/ui-kit/react/incoming-call.mdx b/ui-kit/react/incoming-call.mdx deleted file mode 100644 index d8b7d3237..000000000 --- a/ui-kit/react/incoming-call.mdx +++ /dev/null @@ -1,492 +0,0 @@ ---- -title: "Incoming Call" -description: "Handle incoming CometChat React UI Kit voice and video calls with caller details, accept, reject, custom sounds, and view slots." ---- - -```json -{ - "component": "CometChatIncomingCall", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatIncomingCall } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", - "description": "Visual notification for incoming voice/video calls with accept and decline controls.", - "cssRootClass": ".cometchat-incoming-call", - "props": { - "data": { - "call": { "type": "any", "default": "auto-detected" }, - "callSettingsBuilder": { "type": "(call: CometChat.Call) => CallSettingsBuilder", "default": "undefined" } - }, - "callbacks": { - "onAccept": "(call: CometChat.Call) => void", - "onDecline": "(call: CometChat.Call) => void", - "onError": "((error: CometChat.CometChatException) => void) | null" - }, - "sound": { - "disableSoundForCalls": { "type": "boolean", "default": false }, - "customSoundForCalls": { "type": "string", "default": "undefined" } - }, - "viewSlots": { - "itemView": "(call: CometChat.Call) => JSX.Element", - "leadingView": "(call: CometChat.Call) => JSX.Element", - "titleView": "(call: CometChat.Call) => JSX.Element", - "subtitleView": "(call: CometChat.Call) => JSX.Element", - "trailingView": "(call: CometChat.Call) => JSX.Element" - } - }, - "events": [ - { "name": "CometChatCallEvents.ccCallRejected", "payload": "CometChat.Call" }, - { "name": "CometChatCallEvents.ccCallAccepted", "payload": "CometChat.Call" }, - { "name": "CometChatCallEvents.ccCallEnded", "payload": "CometChat.Call" } - ] -} -``` - - -## Where It Fits - -`CometChatIncomingCall` is an overlay component that auto-detects incoming calls and renders a notification with accept/decline buttons. Place it at the app root level so it appears above all other content. - -```tsx lines -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function App() { - return ( -
- - {/* rest of app */} -
- ); -} -``` - - - - - ---- - -## Minimal Render - -```tsx lines -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function IncomingCallDemo() { - return ; -} - -export default IncomingCallDemo; -``` - -Root CSS class: `.cometchat-incoming-call` - ---- - -## Actions and Events - -### Callback Props - -#### onAccept - -Fires when the accept button is clicked. - -```tsx lines -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function IncomingCallWithAccept() { - return ( - { - console.log("Call accepted:", call); - }} - /> - ); -} -``` - -#### onDecline - -Fires when the decline button is clicked. - -```tsx lines -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function IncomingCallWithDecline() { - return ( - { - console.log("Call declined:", call); - }} - /> - ); -} -``` - -#### onError - -Fires on internal errors. - -```tsx lines -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function IncomingCallWithError() { - return ( - { - console.error("IncomingCall error:", error); - }} - /> - ); -} -``` - -### Global UI Events - -`CometChatCallEvents` emits events subscribable from anywhere in the application. - -| Event | Fires when | Payload | -| --- | --- | --- | -| `ccCallRejected` | Incoming call is rejected | `CometChat.Call` | -| `ccCallAccepted` | Incoming call is accepted | `CometChat.Call` | -| `ccCallEnded` | Call ends | `CometChat.Call` | - -```tsx lines -import { useEffect } from "react"; -import { CometChatCallEvents } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function useCallEvents() { - useEffect(() => { - const acceptedSub = CometChatCallEvents.ccCallAccepted.subscribe( - (call: CometChat.Call) => console.log("Accepted:", call) - ); - const rejectedSub = CometChatCallEvents.ccCallRejected.subscribe( - (call: CometChat.Call) => console.log("Rejected:", call) - ); - - return () => { - acceptedSub?.unsubscribe(); - rejectedSub?.unsubscribe(); - }; - }, []); -} -``` - -### SDK Events (Real-Time, Automatic) - -The component listens to SDK call events internally for real-time incoming call detection. No manual attachment needed. - ---- - -## Custom View Slots - -View slots for `CometChatIncomingCall` are functions that receive the `CometChat.Call` object. - -| Slot | Signature | Replaces | -| --- | --- | --- | -| `itemView` | `(call: CometChat.Call) => JSX.Element` | Entire list item | -| `leadingView` | `(call: CometChat.Call) => JSX.Element` | Avatar / left section | -| `titleView` | `(call: CometChat.Call) => JSX.Element` | Name / title text | -| `subtitleView` | `(call: CometChat.Call) => JSX.Element` | Subtitle text | -| `trailingView` | `(call: CometChat.Call) => JSX.Element` | Right section | - -### leadingView - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAvatar, CometChatIncomingCall } from "@cometchat/chat-uikit-react"; - -function CustomLeadingIncoming() { - return ( - ( - - )} - /> - ); -} -``` - -### titleView - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; - -function CustomTitleIncoming() { - return ( - ( -
{call.getCallInitiator()?.getName()}
- )} - /> - ); -} -``` - -### itemView - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatAvatar, CometChatIncomingCall } from "@cometchat/chat-uikit-react"; - -function CustomItemViewIncoming() { - return ( - ( -
- -
{call.getCallInitiator()?.getName()}
-
{"Incoming " + call.getType() + " call"}
-
- )} - /> - ); -} -``` - ---- - -## Common Patterns - -### Disable ringtone - -```tsx lines -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; - -function SilentIncoming() { - return ; -} -``` - -### Custom ringtone - -```tsx lines -import { CometChatIncomingCall } from "@cometchat/chat-uikit-react"; - -function CustomSoundIncoming() { - return ; -} -``` - ---- - -## CSS Architecture - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-incoming-call` | -| List item | `.cometchat-incoming-call .cometchat-list-item` | -| Body title | `.cometchat-incoming-call .cometchat-list-item__body-title` | -| Button group | `.cometchat-incoming-call__button-group` | -| Decline button | `.cometchat-incoming-call__button-decline` | -| Accept button | `.cometchat-incoming-call__button-accept` | - -### Example: Brand-themed incoming call - - - - - -```css lines -.cometchat-incoming-call { - border-radius: 18.5px; - border: 1.542px solid #aa9ee8; - background: #fff; -} - -.cometchat-incoming-call__button-decline .cometchat-button__text { - color: #f44649; -} - -.cometchat-incoming-call__button-accept .cometchat-button { - background-color: #6852d6; -} -``` - ---- - -## Props - -All props are optional. - ---- - -### call - -Sets a specific call object for the incoming call display. - -| | | -| --- | --- | -| Type | `any` | -| Default | Auto-detected | - ---- - -### callSettingsBuilder - -Custom call settings builder for the call session. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => typeof CometChatUIKitCalls.CallSettingsBuilder` | -| Default | `undefined` | - ---- - -### customSoundForCalls - -Custom sound file URL for incoming calls. - -| | | -| --- | --- | -| Type | `string` | -| Default | `undefined` | - ---- - -### disableSoundForCalls - -Disables the incoming call ringtone. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### itemView - -Custom renderer for the entire list item. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => JSX.Element` | -| Default | `undefined` | - ---- - -### leadingView - -Custom renderer for the avatar / left section. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => JSX.Element` | -| Default | `undefined` | - ---- - -### onAccept - -Callback fired when the accept button is clicked. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => void` | -| Default | `undefined` | - ---- - -### onDecline - -Callback fired when the decline button is clicked. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => void` | -| Default | `undefined` | - ---- - -### onError - -Callback fired when the component encounters an error. - -| | | -| --- | --- | -| Type | `((error: CometChat.CometChatException) => void) \| null` | -| Default | `undefined` | - ---- - -### subtitleView - -Custom renderer for the subtitle text. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => JSX.Element` | -| Default | `undefined` | - ---- - -### titleView - -Custom renderer for the name / title text. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => JSX.Element` | -| Default | `undefined` | - ---- - -### trailingView - -Custom renderer for the right section. - -| | | -| --- | --- | -| Type | `(call: CometChat.Call) => JSX.Element` | -| Default | `undefined` | - ---- - -## Events - -| Event | Payload | Fires when | -| --- | --- | --- | -| `CometChatCallEvents.ccCallRejected` | `CometChat.Call` | Call rejected | -| `CometChatCallEvents.ccCallAccepted` | `CometChat.Call` | Call accepted | -| `CometChatCallEvents.ccCallEnded` | `CometChat.Call` | Call ended | - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-incoming-call` | -| List item | `.cometchat-incoming-call .cometchat-list-item` | -| Body title | `.cometchat-incoming-call .cometchat-list-item__body-title` | -| Title container | `.cometchat-incoming-call .cometchat-list-item__title-container` | -| Trailing view | `.cometchat-incoming-call .cometchat-list-item__trailing-view` | -| Button group | `.cometchat-incoming-call__button-group` | -| Decline button | `.cometchat-incoming-call__button-decline` | -| Accept button | `.cometchat-incoming-call__button-accept` | diff --git a/ui-kit/react/v7/integration-astro.mdx b/ui-kit/react/integration-astro.mdx similarity index 72% rename from ui-kit/react/v7/integration-astro.mdx rename to ui-kit/react/integration-astro.mdx index 57bc27c21..0a6fb3764 100644 --- a/ui-kit/react/v7/integration-astro.mdx +++ b/ui-kit/react/integration-astro.mdx @@ -1,7 +1,7 @@ --- title: "Astro Integration" sidebarTitle: "Integration" -description: "Add CometChat to an Astro app in 5 steps: create project, install, init, login, render." +description: "Add CometChat to an Astro app in 5 steps: create project, install, init + login, render island, run." --- @@ -12,12 +12,11 @@ description: "Add CometChat to an Astro app in 5 steps: create project, install, | Peer deps | `react` >=18, `react-dom` >=18, `@cometchat/chat-sdk-javascript` ^4.1.9, `dompurify` ^3.3.1 | | Init | `CometChatUIKit.init(UIKitSettings)` — must resolve before `login()` | | Login | `CometChatUIKit.login("UID")` — must resolve before rendering components | -| Order | `init()` → `login()` → render. Breaking this order = blank screen | +| Order | `init()` → `login()` → render ``. Breaking this order = blank screen | | Auth Key | Dev/testing only. Use Auth Token in production | -| CSS | `import "@cometchat/chat-uikit-react/styles";` | | SSR | Use `client:only="react"` directive — CometChat components cannot be server-rendered | -| Calling | Optional. Install `@cometchat/calls-sdk-javascript` to enable | -| Other frameworks | [React.js](/ui-kit/react/v7/integration-react) · [Next.js](/ui-kit/react/v7/integration-nextjs) · [React Router](/ui-kit/react/v7/integration-react-router) | +| Calling | Optional. Install `@cometchat/calls-sdk-javascript` and call `.setCallingEnabled(true)` on `UIKitSettingsBuilder` | +| Other frameworks | [React.js](/ui-kit/react/integration-react) · [Next.js](/ui-kit/react/integration-nextjs) · [React Router](/ui-kit/react/integration-react-router) | @@ -84,28 +83,46 @@ npm install @cometchat/calls-sdk-javascript ## Step 3 — Create the React Island Component -CometChat components live inside a React island (a `.tsx` file in `src/components/`). Wrap your chat UI in `CometChatProvider` which handles init and login automatically. +CometChat components live inside a React island (a `.tsx` file in `src/components/`). Initialize the SDK, login, then render inside `CometChatProvider`. For development, use one of the pre-created test UIDs: `cometchat-uid-1` · `cometchat-uid-2` · `cometchat-uid-3` · `cometchat-uid-4` · `cometchat-uid-5` ```tsx title="src/components/CometChatApp.tsx" -import { useState } from "react"; +import { useEffect, useState } from "react"; import { CometChat } from "@cometchat/chat-sdk-javascript"; import { + CometChatUIKit, + UIKitSettingsBuilder, CometChatProvider, CometChatConversations, CometChatMessageHeader, CometChatMessageList, CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; export default function CometChatApp() { + const [ready, setReady] = useState(false); const [chatUser, setChatUser] = useState(); const [chatGroup, setChatGroup] = useState(); + useEffect(() => { + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .build(); + + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + setReady(true); + }); + }, []); + + if (!ready) return
Loading chat...
; + const handleConversationClick = (conversation: CometChat.Conversation) => { const entity = conversation.getConversationWith(); if (conversation.getConversationType() === "user") { @@ -118,12 +135,7 @@ export default function CometChatApp() { }; return ( - +
@@ -143,10 +155,10 @@ export default function CometChatApp() { } ``` -`CometChatProvider` handles init, login, and all context setup automatically. For advanced use cases (custom login flows, individual providers), see the [CometChatProvider](/ui-kit/react/v7/cometchat-provider) guide. +`CometChatProvider` supplies theme, locale, plugin registry, and event context to all child components. Init and login happen in `useEffect` and the provider only mounts after login succeeds. See the [CometChatProvider](/ui-kit/react/cometchat-provider) guide for all props. -For production, use the `authToken` prop instead of `authKey` + `uid`. Generate auth tokens server-side via the CometChat REST API. Never ship auth keys in client code. +For production, use `CometChatUIKit.loginWithAuthToken(token)` instead of `login(uid)`. Generate auth tokens server-side via the CometChat REST API. Never ship auth keys in client code. --- @@ -224,19 +236,31 @@ Tabbed navigation — Chat, Call Logs, Users, Settings in separate tabs. --- +## Build Your Own Chat Experience + +Need full control over the UI? Use individual components, customize themes, and wire up your own layouts. + +- [Sample App](https://github.com/cometchat/cometchat-uikit-react/tree/v7/sample-app) — Working reference app to compare against +- [Components](/ui-kit/react/components-overview) — All prebuilt UI elements with props and customization options +- [Core Features](/ui-kit/react/core-features) — Messaging, real-time updates, and other capabilities +- [Theming](/ui-kit/react/theming) — Colors, fonts, dark mode, and custom styling +- [Build Your Own UI](/sdk/javascript/overview) — Skip the UI Kit entirely and build on the raw SDK + +--- + ## Next Steps - + Browse all prebuilt UI components - + Customize colors, fonts, and styles - + Customize message rendering - + Common issues and fixes diff --git a/ui-kit/react/v7/integration-nextjs.mdx b/ui-kit/react/integration-nextjs.mdx similarity index 68% rename from ui-kit/react/v7/integration-nextjs.mdx rename to ui-kit/react/integration-nextjs.mdx index 5662ad03f..ccdb3a670 100644 --- a/ui-kit/react/v7/integration-nextjs.mdx +++ b/ui-kit/react/integration-nextjs.mdx @@ -1,7 +1,7 @@ --- title: "Next.js Integration" sidebarTitle: "Integration" -description: "Add CometChat to a Next.js (App Router) app in 4 steps: create project, install, wrap in CometChatProvider, run." +description: "Add CometChat to a Next.js (App Router) app in 5 steps: create project, install, init + login, render, run." --- @@ -10,12 +10,13 @@ description: "Add CometChat to a Next.js (App Router) app in 4 steps: create pro | --- | --- | | Package | `@cometchat/chat-uikit-react` v7.0.x | | Peer deps | `react` >=18, `react-dom` >=18, `@cometchat/chat-sdk-javascript` ^4.1.9, `dompurify` ^3.3.1 | -| Setup | Wrap app in `` | -| Auth Key | Dev/testing only. Use `authToken` prop in production | -| CSS | `import "@cometchat/chat-uikit-react/styles";` | +| Init | `CometChatUIKit.init(UIKitSettings)` — must resolve before `login()` | +| Login | `CometChatUIKit.login("UID")` — must resolve before rendering components | +| Order | `init()` → `login()` → render ``. Breaking this order = blank screen | +| Auth Key | Dev/testing only. Use `loginWithAuthToken` in production | | SSR | CometChat components must be loaded with `dynamic(() => import(...), { ssr: false })` | -| Calling | Optional. Install `@cometchat/calls-sdk-javascript` and set `callingEnabled` prop | -| Other frameworks | [React.js](/ui-kit/react/v7/integration-react) · [React Router](/ui-kit/react/v7/integration-react-router) · [Astro](/ui-kit/react/v7/integration-astro) | +| Calling | Optional. Install `@cometchat/calls-sdk-javascript` and call `.setCallingEnabled(true)` on `UIKitSettingsBuilder` | +| Other frameworks | [React.js](/ui-kit/react/integration-react) · [React Router](/ui-kit/react/integration-react-router) · [Astro](/ui-kit/react/integration-astro) | @@ -80,7 +81,7 @@ npm install @cometchat/calls-sdk-javascript ## Step 3 — Create the CometChat Client Component -CometChat uses browser APIs and cannot run in Server Components. Create a `'use client'` component that wraps your chat UI in `CometChatProvider`. +CometChat uses browser APIs and cannot run in Server Components. Create a `'use client'` component that initializes the SDK, logs in, and renders your chat UI inside `CometChatProvider`. For development, use one of the pre-created test UIDs: @@ -89,21 +90,39 @@ For development, use one of the pre-created test UIDs: ```tsx title="app/CometChatClient.tsx" 'use client'; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { CometChat } from "@cometchat/chat-sdk-javascript"; import { + CometChatUIKit, + UIKitSettingsBuilder, CometChatProvider, CometChatConversations, CometChatMessageHeader, CometChatMessageList, CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; export default function CometChatClient() { + const [ready, setReady] = useState(false); const [chatUser, setChatUser] = useState(); const [chatGroup, setChatGroup] = useState(); + useEffect(() => { + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .build(); + + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + setReady(true); + }); + }, []); + + if (!ready) return
Loading chat...
; + const handleConversationClick = (conversation: CometChat.Conversation) => { const entity = conversation.getConversationWith(); if (conversation.getConversationType() === "user") { @@ -116,12 +135,7 @@ export default function CometChatClient() { }; return ( - +
@@ -141,10 +155,10 @@ export default function CometChatClient() { } ``` -`'use client'` is required because CometChat components use browser APIs. `CometChatProvider` handles init, login, and all context setup automatically. For advanced use cases (custom login flows, individual providers), see the [CometChatProvider](/ui-kit/react/v7/cometchat-provider) guide. +`'use client'` is required because CometChat components use browser APIs. Init and login happen in a `useEffect`, and the provider only mounts after login succeeds. See the [CometChatProvider](/ui-kit/react/cometchat-provider) guide for all provider props. -For production, use the `authToken` prop instead of `authKey` + `uid`. Generate auth tokens server-side via the CometChat REST API. Never ship auth keys in client code. +For production, use `CometChatUIKit.loginWithAuthToken(token)` instead of `login(uid)`. Generate auth tokens server-side via the CometChat REST API. Never ship auth keys in client code. --- @@ -215,19 +229,31 @@ Tabbed navigation — Chat, Call Logs, Users, Settings in separate tabs. --- +## Build Your Own Chat Experience + +Need full control over the UI? Use individual components, customize themes, and wire up your own layouts. + +- [Sample App](https://github.com/cometchat/cometchat-uikit-react/tree/v7/sample-app) — Working reference app to compare against +- [Components](/ui-kit/react/components-overview) — All prebuilt UI elements with props and customization options +- [Core Features](/ui-kit/react/core-features) — Messaging, real-time updates, and other capabilities +- [Theming](/ui-kit/react/theming) — Colors, fonts, dark mode, and custom styling +- [Build Your Own UI](/sdk/javascript/overview) — Skip the UI Kit entirely and build on the raw SDK + +--- + ## Next Steps - + Browse all prebuilt UI components - + Customize colors, fonts, and styles - + Customize message rendering - + Common issues and fixes diff --git a/ui-kit/react/v7/integration-react-router.mdx b/ui-kit/react/integration-react-router.mdx similarity index 70% rename from ui-kit/react/v7/integration-react-router.mdx rename to ui-kit/react/integration-react-router.mdx index b315077e4..3cc261677 100644 --- a/ui-kit/react/v7/integration-react-router.mdx +++ b/ui-kit/react/integration-react-router.mdx @@ -1,7 +1,7 @@ --- title: "React Router Integration" sidebarTitle: "Integration" -description: "Add CometChat to a React Router app in 5 steps: create project, install, init, login, render." +description: "Add CometChat to a React Router app in 5 steps: create project, install, init + login, render, run." --- @@ -12,12 +12,11 @@ description: "Add CometChat to a React Router app in 5 steps: create project, in | Peer deps | `react` >=18, `react-dom` >=18, `@cometchat/chat-sdk-javascript` ^4.1.9, `dompurify` ^3.3.1 | | Init | `CometChatUIKit.init(UIKitSettings)` — must resolve before `login()` | | Login | `CometChatUIKit.login("UID")` — must resolve before rendering components | -| Order | `init()` → `login()` → render. Breaking this order = blank screen | +| Order | `init()` → `login()` → render ``. Breaking this order = blank screen | | Auth Key | Dev/testing only. Use Auth Token in production | -| CSS | `import "@cometchat/chat-uikit-react/styles";` | | SSR | N/A — client-side SPA by default | -| Calling | Optional. Install `@cometchat/calls-sdk-javascript` to enable | -| Other frameworks | [React.js](/ui-kit/react/v7/integration-react) · [Next.js](/ui-kit/react/v7/integration-nextjs) · [Astro](/ui-kit/react/v7/integration-astro) | +| Calling | Optional. Install `@cometchat/calls-sdk-javascript` and call `.setCallingEnabled(true)` on `UIKitSettingsBuilder` | +| Other frameworks | [React.js](/ui-kit/react/integration-react) · [Next.js](/ui-kit/react/integration-nextjs) · [Astro](/ui-kit/react/integration-astro) | @@ -80,9 +79,9 @@ npm install @cometchat/calls-sdk-javascript --- -## Step 3 — Set Up Routes and Render +## Step 3 — Initialize, Login, and Set Up Routes -Create your route structure with a chat route. `CometChatProvider` handles init and login automatically. +Call `CometChatUIKit.init()` and `CometChatUIKit.login()` before rendering. Then wrap your chat route in `CometChatProvider`. For development, use one of the pre-created test UIDs: @@ -91,14 +90,24 @@ For development, use one of the pre-created test UIDs: ```tsx title="src/main.tsx" import ReactDOM from "react-dom/client"; import { BrowserRouter } from "react-router-dom"; +import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; import App from "./App"; -const root = ReactDOM.createRoot(document.getElementById("root")!); -root.render( - - - -); +const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .build(); + +CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + ReactDOM.createRoot(document.getElementById("root")!).render( + + + + ); +}); ``` ```tsx title="src/App.tsx" @@ -127,7 +136,6 @@ import { CometChatMessageList, CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; export default function ChatPage() { const [chatUser, setChatUser] = useState(); @@ -145,12 +153,7 @@ export default function ChatPage() { }; return ( - +
@@ -170,10 +173,10 @@ export default function ChatPage() { } ``` -`CometChatProvider` handles init, login, and all context setup automatically. For advanced use cases (custom login flows, individual providers), see the [CometChatProvider](/ui-kit/react/v7/cometchat-provider) guide. +Init and login complete before the app renders. `CometChatProvider` then supplies theme, locale, plugin registry, and event context. See the [CometChatProvider](/ui-kit/react/cometchat-provider) guide for all props. -For production, use the `authToken` prop instead of `authKey` + `uid`. Generate auth tokens server-side via the CometChat REST API. Never ship auth keys in client code. +For production, use `CometChatUIKit.loginWithAuthToken(token)` instead of `login(uid)`. Generate auth tokens server-side via the CometChat REST API. Never ship auth keys in client code. --- @@ -224,19 +227,31 @@ Tabbed navigation — Chat, Call Logs, Users, Settings in separate tabs. --- +## Build Your Own Chat Experience + +Need full control over the UI? Use individual components, customize themes, and wire up your own layouts. + +- [Sample App](https://github.com/cometchat/cometchat-uikit-react/tree/v7/sample-app) — Working reference app to compare against +- [Components](/ui-kit/react/components-overview) — All prebuilt UI elements with props and customization options +- [Core Features](/ui-kit/react/core-features) — Messaging, real-time updates, and other capabilities +- [Theming](/ui-kit/react/theming) — Colors, fonts, dark mode, and custom styling +- [Build Your Own UI](/sdk/javascript/overview) — Skip the UI Kit entirely and build on the raw SDK + +--- + ## Next Steps - + Browse all prebuilt UI components - + Customize colors, fonts, and styles - + Customize message rendering - + Common issues and fixes diff --git a/ui-kit/react/v7/integration-react.mdx b/ui-kit/react/integration-react.mdx similarity index 60% rename from ui-kit/react/v7/integration-react.mdx rename to ui-kit/react/integration-react.mdx index 6038b2245..be1b58400 100644 --- a/ui-kit/react/v7/integration-react.mdx +++ b/ui-kit/react/integration-react.mdx @@ -1,7 +1,7 @@ --- title: "React.js Integration" sidebarTitle: "Integration" -description: "Add CometChat to a React.js app in 4 steps: create project, install, wrap in CometChatProvider, run." +description: "Add CometChat to a React.js app in 4 steps: create project, install, init + login, render." --- @@ -10,11 +10,12 @@ description: "Add CometChat to a React.js app in 4 steps: create project, instal | --- | --- | | Package | `@cometchat/chat-uikit-react` v7.0.x | | Peer deps | `react` >=18, `react-dom` >=18, `@cometchat/chat-sdk-javascript` ^4.1.9, `dompurify` ^3.3.1 | -| Setup | Wrap app in `` | -| Auth Key | Dev/testing only. Use `authToken` prop in production | -| CSS | `import "@cometchat/chat-uikit-react/styles";` | -| Calling | Optional. Install `@cometchat/calls-sdk-javascript` and set `callingEnabled` prop | -| Other frameworks | [Next.js](/ui-kit/react/v7/integration-nextjs) · [React Router](/ui-kit/react/v7/integration-react-router) · [Astro](/ui-kit/react/v7/integration-astro) | +| Init | `CometChatUIKit.init(UIKitSettings)` — must resolve before `login()` | +| Login | `CometChatUIKit.login("UID")` — must resolve before rendering components | +| Order | `init()` → `login()` → render ``. Breaking this order = blank screen | +| Auth Key | Dev/testing only. Use Auth Token in production | +| Calling | Optional. Install `@cometchat/calls-sdk-javascript` and call `.setCallingEnabled(true)` on `UIKitSettingsBuilder` | +| Other frameworks | [Next.js](/ui-kit/react/integration-nextjs) · [React Router](/ui-kit/react/integration-react-router) · [Astro](/ui-kit/react/integration-astro) | @@ -86,14 +87,32 @@ npm install @cometchat/calls-sdk-javascript --- -## Step 3 — Render with CometChatProvider +## Step 3 — Initialize, Login, and Render -Wrap your app in `CometChatProvider` with your credentials. It handles SDK initialization, login, and all internal context setup automatically. +Call `CometChatUIKit.init()` and `CometChatUIKit.login()` before rendering your app. Then wrap your components in `CometChatProvider`. For development, use one of the pre-created test UIDs: `cometchat-uid-1` · `cometchat-uid-2` · `cometchat-uid-3` · `cometchat-uid-4` · `cometchat-uid-5` +```tsx title="src/main.tsx" +import ReactDOM from "react-dom/client"; +import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; +import App from "./App"; + +const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .build(); + +CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + ReactDOM.createRoot(document.getElementById("root")!).render(); +}); +``` + ```tsx title="src/App.tsx" import { useState } from "react"; import { CometChat } from "@cometchat/chat-sdk-javascript"; @@ -104,7 +123,6 @@ import { CometChatMessageList, CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; function App() { const [chatUser, setChatUser] = useState(); @@ -122,12 +140,7 @@ function App() { }; return ( - +
@@ -149,10 +162,14 @@ function App() { export default App; ``` -`CometChatProvider` handles init, login, plugin registration, theming, locale, and real-time events — no manual setup needed. For advanced use cases (custom login flows, individual providers), see the [CometChatProvider](/ui-kit/react/v7/cometchat-provider) guide. +`CometChatProvider` supplies theme, locale, plugin registry, and event context to all child components. Init and login must complete before the provider mounts. See the [CometChatProvider](/ui-kit/react/cometchat-provider) guide for all props. + + +For production, use `CometChatUIKit.loginWithAuthToken(token)` instead of `login(uid)`. Generate auth tokens server-side via the [REST API](/rest-api/chat-apis). Never ship auth keys in client code. + -For production, use the `authToken` prop instead of `authKey` + `uid`. Generate auth tokens server-side via the CometChat REST API. Never ship auth keys in client code. +By default, session data is stored in `localStorage`. To use `sessionStorage` instead, see [Setting Session Storage Mode](/ui-kit/react/methods#setting-session-storage-mode). --- @@ -203,19 +220,49 @@ Tabbed navigation — Chat, Call Logs, Users, Settings in separate tabs. --- +## Build Your Own Chat Experience + +Need full control over the UI? Use individual components, customize themes, and wire up your own layouts. + +- [Sample App](https://github.com/cometchat/cometchat-uikit-react/tree/v7/sample-app) — Working reference app to compare against +- [Components](/ui-kit/react/components-overview) — All prebuilt UI elements with props and customization options +- [Core Features](/ui-kit/react/core-features) — Messaging, real-time updates, and other capabilities +- [Theming](/ui-kit/react/theming) — Colors, fonts, dark mode, and custom styling +- [Build Your Own UI](/sdk/javascript/overview) — Skip the UI Kit entirely and build on the raw SDK + +--- + +## iFrame Embedding + +If your React app runs inside an ` - - - -CometChat UI Kit requires browser APIs (`window`, `WebSocket`, `document`). In Next.js, always load CometChat components client-side using dynamic imports with `ssr: false`. - - ---- - -## Integrate with AI Coding Agents - -Skip the manual steps — use [CometChat Skills](https://github.com/cometchat/cometchat-skills) to integrate via your AI coding agent. Your agent has a short conversation with you to understand your project and chat requirements, then writes production-grade integration code tailored to the files you already have. - -```bash -npx @cometchat/skills add -``` - -Use `--ide ` to target a specific IDE (e.g. `--ide cursor`), or `--ide all` for all supported IDEs. - -Then in your IDE: - -``` -/cometchat add chat to my app -``` - -The skill detects your Next.js version and router type (App Router vs Pages Router), env prefix, and existing auth system. It onboards you to CometChat directly in the terminal — signup, login, and app creation all via the CLI. It reads your routes, nav, and components before proposing a placement, shows the plan, and waits for your approval before writing code. - -After the first integration, re-run `/cometchat` to access the iteration menu: theme presets, 40+ features, component customization, floating widget, production auth, user management, and diagnostics. - -Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and [30+ more agents](https://github.com/cometchat/cometchat-skills). - ---- - -## Prerequisites - -You need three things from the [CometChat Dashboard](https://app.cometchat.com/): - -| Credential | Where to find it | -| --- | --- | -| App ID | Dashboard → Your App → Credentials | -| Auth Key | Dashboard → Your App → Credentials | -| Region | Dashboard → Your App → Credentials (e.g. `us`, `eu`, `in`) | - -You also need Node.js (v16+) and npm/yarn installed. - - -Auth Key is for development only. In production, generate Auth Tokens server-side via the [REST API](/rest-api/chat-apis) and use [`loginWithAuthToken()`](/ui-kit/react/methods#login-using-auth-token). Never ship Auth Keys in client code. - - ---- - -## Step 1 — Create a Next.js Project - -```bash lines -npx create-next-app@latest my-app --typescript -cd my-app -``` - ---- - -## Step 2 — Install the UI Kit - - - -```bash lines -npm install @cometchat/chat-uikit-react -``` - - -```bash lines -yarn add @cometchat/chat-uikit-react -``` - - - -This installs the UI Kit and its dependency `@cometchat/chat-sdk-javascript` automatically. - -If you want voice/video calling, also install: - -```bash lines -npm install @cometchat/calls-sdk-javascript -``` - ---- - -## Step 3 — Initialize CometChat - - - - -```ts lines highlight={7-9} -import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; - -/** - * CometChat Constants - Replace with your actual credentials - */ -const COMETCHAT_CONSTANTS = { - APP_ID: "APP_ID", // Replace with your actual App ID from CometChat - REGION: "REGION", // Replace with your App's Region - AUTH_KEY: "AUTH_KEY", // Replace with your Auth Key (leave blank if using Auth Token) -}; - -const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) - .subscribePresenceForAllUsers() - .build(); - -CometChatUIKit.init(UIKitSettings) - ?.then(() => { - console.log("CometChat UI Kit initialized successfully."); - }) - .catch((error) => { - console.error("CometChat UI Kit initialization failed:", error); - }); -``` - - -```js lines highlight={7-9} -import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; - -/** - * CometChat Constants - Replace with your actual credentials - */ -const COMETCHAT_CONSTANTS = { - APP_ID: "APP_ID", // Replace with your actual App ID from CometChat - REGION: "REGION", // Replace with your App's Region - AUTH_KEY: "AUTH_KEY", // Replace with your Auth Key (leave blank if using Auth Token) -}; - -const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) - .subscribePresenceForAllUsers() - .build(); - -CometChatUIKit.init(UIKitSettings) - .then(() => { - console.log("CometChat UI Kit initialized successfully."); - }) - .catch((error) => { - console.error("CometChat UI Kit initialization failed:", error); - }); -``` - - - - -`init()` must resolve before you call `login()`. If you call `login()` before init completes, it will fail silently. Note the `?.then()` — in Next.js, `init()` may return `undefined` if settings are invalid. - - ---- - -## Step 4 — Login - -After init resolves, log the user in. For development, use one of the pre-created test UIDs: - -`cometchat-uid-1` · `cometchat-uid-2` · `cometchat-uid-3` · `cometchat-uid-4` · `cometchat-uid-5` - - - -```ts lines highlight={3} -import { CometChatUIKit } from "@cometchat/chat-uikit-react"; - -const UID = "UID"; // Replace with your actual UID - -CometChatUIKit.getLoggedinUser().then((user: CometChat.User | null) => { - if (!user) { - CometChatUIKit.login(UID) - .then((user: CometChat.User) => { - console.log("Login Successful:", { user }); - // Mount your app - }) - .catch(console.log); - } else { - // Already logged in — mount your app - } -}); -``` - - -```js lines highlight={3} -import { CometChatUIKit } from "@cometchat/chat-uikit-react"; - -const UID = "UID"; // Replace with your actual UID - -CometChatUIKit.getLoggedinUser().then((user) => { - if (!user) { - CometChatUIKit.login(UID) - .then((user) => { - console.log("Login Successful:", { user }); - // Mount your app - }) - .catch(console.log); - } else { - // Already logged in — mount your app - } -}); -``` - - - -Key points: -- `getLoggedinUser()` checks for an existing session so you don't re-login unnecessarily. -- `login(uid)` skips the API call if a session already exists and returns the cached user. -- Components must not render until login resolves — use a state flag to gate rendering. - - -For production, use [`loginWithAuthToken()`](/ui-kit/react/methods#login-using-auth-token) instead of Auth Key. Generate tokens server-side via the REST API. - - ---- - -## Step 5 — Add the CSS Import - -Add this line at the top of your global CSS file (e.g. `globals.css`): - -```css title="globals.css" lines -@import url("@cometchat/chat-uikit-react/css-variables.css"); -``` - -Also ensure your global CSS sets `height: 100%` on the root elements: - -```css title="globals.css" lines -html, -body { - height: 100%; -} - -#__next { - height: 100%; -} -``` - -Without the CSS import, components will render with broken or missing styles. Without the height rules, the chat UI won't fill the viewport. - ---- - -## Step 6 — Choose a Chat Experience - -Integrate a conversation view that suits your app's UX. Each option below includes a live CodeSandbox demo and a step-by-step guide. - -### Conversation List + Message View - -Two-panel layout — conversation list on the left, messages on the right. Think WhatsApp Web or Slack. - -- Two-panel layout with conversation list and active chat window -- Switch between one-to-one and group conversations -- Tap-to-view on mobile — tapping a conversation opens the message view -- Real-time updates and message sync across sessions - - - - - -[](https://link.cometchat.com/next-conversation-list-message) - -> Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. - - - Step-by-step guide to build this layout - - ---- - -### One-to-One / Group Chat - -Single chat window — no sidebar. Good for support chat, embedded widgets, or focused messaging. - -- Dedicated chat window for one-on-one or group messaging -- No conversation list — users go directly into the chat -- Full-screen experience optimized for mobile -- Ideal for support chat or community messaging - - - - - -[](https://link.cometchat.com/next-one-on-one) - -> Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. - - - Step-by-step guide to build this layout - - ---- - -### Tab-Based Chat - -Tabbed navigation — Chat, Call Logs, Users, Settings in separate tabs. Good for full-featured apps. - -- Tab navigation between Chat, Call Logs, Users, and Settings -- Full-screen messaging within each tab -- Unified experience for conversations, call history, and settings -- Scales well for adding future features like notifications or contacts - - - - - -[](https://link.cometchat.com/next-tabs-sidebar-message) - -> Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. - - - Step-by-step guide to build this layout - - ---- - -## Build Your Own Chat Experience - -Need full control over the UI? Use individual components, customize themes, and wire up your own layouts. - -- [Sample App](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) — Working reference app to compare against -- [Components](/ui-kit/react/components-overview) — All prebuilt UI elements with props and customization options -- [Core Features](/ui-kit/react/core-features) — Messaging, real-time updates, and other capabilities -- [Theming](/ui-kit/react/theme) — Colors, fonts, dark mode, and custom styling -- [Build Your Own UI](/sdk/javascript/overview) — Skip the UI Kit entirely and build on the raw SDK - ---- - -## Next Steps - - - - Browse all prebuilt UI components - - - Customize colors, fonts, and styles - - - Chat features included out of the box - - - Common issues and fixes - - diff --git a/ui-kit/react/next-one-to-one-chat.mdx b/ui-kit/react/next-one-to-one-chat.mdx index 9f9878096..8d743a646 100644 --- a/ui-kit/react/next-one-to-one-chat.mdx +++ b/ui-kit/react/next-one-to-one-chat.mdx @@ -1,7 +1,7 @@ --- title: "One-to-One / Group Chat" sidebarTitle: "One-to-One / Group Chat" -description: "Build focused CometChat UI Kit chat screens in Next.js with headers, message lists, composers, users, groups, and direct navigation." +description: "Build a single chat window for one-to-one or group messaging in Next.js (App Router) with CometChat UI Kit." --- @@ -9,26 +9,23 @@ description: "Build focused CometChat UI Kit chat screens in Next.js with header | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Framework | Next.js | +| Framework | Next.js (App Router) | | Components | `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | | Layout | Single chat window — no sidebar, no conversation list | -| Prerequisite | Complete [Next.js Integration](/ui-kit/react/next-js-integration) Steps 1–5 first | -| SSR | Dynamic import with `ssr: false` — CometChat requires browser APIs | +| Prerequisite | Complete [Next.js Integration](/ui-kit/react/integration-nextjs) first | +| SSR | Component loaded with `dynamic(() => import(...), { ssr: false })` | | Pattern | Support chat, embedded widgets, focused messaging | This guide builds a single chat window — no sidebar, no conversation list. Users go directly into a one-to-one or group chat. Good for support chat, embedded widgets, or any focused messaging experience. -This assumes you've already completed [Next.js Integration](/ui-kit/react/next-js-integration) (project created, UI Kit installed, CSS imported). +This assumes you've already completed [Next.js Integration](/ui-kit/react/integration-nextjs) (project created, UI Kit installed, init + login working). - + -[](https://link.cometchat.com/next-one-on-one) - -> Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. --- @@ -42,222 +39,157 @@ Three components stacked vertically: --- -## Step 1 — Create the CometChatNoSSR Component - -This component handles init, login, fetches the target user/group, and renders the chat UI. It runs client-side only. +## Full Code - - - - - - - - - - +Create the client component with the chat UI, then import it dynamically in your page. - - +```tsx title="app/chat/CometChatClient.tsx" +'use client'; -```tsx title="CometChatNoSSR.tsx" lines highlight={13-15, 19} -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; import { - CometChatMessageComposer, - CometChatMessageHeader, - CometChatMessageList, CometChatUIKit, UIKitSettingsBuilder, + CometChatProvider, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import "./CometChatNoSSR.css"; -const COMETCHAT_CONSTANTS = { - APP_ID: "", // Replace with your App ID - REGION: "", // Replace with your Region - AUTH_KEY: "", // Replace with your Auth Key (dev only) -}; +const RECIPIENT_UID = "cometchat-uid-2"; // Replace with the UID you want to chat with -// Fetch the user whose chat you want to load -const UID = "cometchat-uid-1"; - -const CometChatNoSSR: React.FC = () => { - const [user, setUser] = useState(undefined); - const [selectedUser, setSelectedUser] = useState(undefined); - const [selectedGroup, setSelectedGroup] = useState(undefined); +export default function CometChatClient() { + const [ready, setReady] = useState(false); + const [chatUser, setChatUser] = useState(undefined); useEffect(() => { - const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") .subscribePresenceForAllUsers() .build(); - CometChatUIKit.init(UIKitSettings) - ?.then(() => { - console.log("Initialization completed successfully"); - CometChatUIKit.getLoggedinUser().then((loggedInUser) => { - if (!loggedInUser) { - CometChatUIKit.login("cometchat-uid-2") - .then((user) => { - console.log("Login Successful", { user }); - setUser(user); - }) - .catch((error) => console.error("Login failed", error)); - } else { - console.log("Already logged-in", { loggedInUser }); - setUser(loggedInUser); - } - }); - }) - .catch((error) => console.error("Initialization failed", error)); + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + const user = await CometChat.getUser(RECIPIENT_UID); + setChatUser(user); + setReady(true); + }); }, []); - useEffect(() => { - if (user) { - CometChat.getUser(UID).then( - (user) => setSelectedUser(user), - (error) => console.log("User fetching failed with error:", error) - ); - - // To load a group chat instead, uncomment below: - // const GUID = "GUID"; - // CometChat.getGroup(GUID).then( - // (group) => setSelectedGroup(group), - // (error) => console.log("Group fetching failed with error:", error) - // ); - } - }, [user]); - - return user ? ( - <> - {selectedUser || selectedGroup ? ( -
- - - -
- ) : ( -
- Set a user or group UID in CometChatNoSSR.tsx to start chatting -
- )} - - ) : undefined; -}; - -export default CometChatNoSSR; + if (!ready || !chatUser) return
Loading chat...
; + + return ( + +
+ + + +
+
+ ); +} ``` -
- +```tsx title="app/chat/page.tsx" +import dynamic from 'next/dynamic'; -```css title="CometChatNoSSR.css" lines -.messages-wrapper { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; -} +const CometChatClient = dynamic(() => import('./CometChatClient'), { ssr: false }); -.empty-conversation { - height: 100%; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - background: white; - color: var(--cometchat-text-color-secondary, #727272); - font: var(--cometchat-font-body-regular, 400 14px Roboto); -} - -.cometchat .cometchat-message-composer { - border-radius: 0px; +export default function ChatPage() { + return ; } ``` - -
- Key points: -- `CometChat.getUser(UID)` fetches the user object from the SDK — you need a real user object, not a manually constructed one. +- `'use client'` is required — CometChat components use browser APIs (DOM, WebSocket). +- `dynamic(() => import(...), { ssr: false })` prevents server-side rendering of the chat component. +- `CometChat.getUser(UID)` fetches the full user object from the SDK — you need a real user object, not a manually constructed one. - Pass either `user` or `group` to the message components, never both. -- The highlighted lines show where to set your credentials. +- The `RECIPIENT_UID` should be a user that exists in your CometChat app. Use one of the pre-created test UIDs: `cometchat-uid-1` through `cometchat-uid-5`. --- -## Switching Between User and Group Chat +## Switching to Group Chat -To load a group chat instead of one-to-one, replace the `getUser` call with `getGroup`: +To load a group chat instead of one-to-one, fetch a `Group` object and pass it to the message components: -```tsx highlight={1} lines -const GUID = "GUID"; // Replace with your actual Group ID - -CometChat.getGroup(GUID) - .then((group) => setSelectedGroup(group)) - .catch((error) => console.error("Failed to fetch group:", error)); -``` +```tsx title="app/chat/CometChatClient.tsx" +'use client'; ---- +import { useEffect, useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; +import { + CometChatUIKit, + UIKitSettingsBuilder, + CometChatProvider, + CometChatMessageHeader, + CometChatMessageList, + CometChatMessageComposer, +} from "@cometchat/chat-uikit-react"; -## Step 2 — Disable SSR in Your Page +const GROUP_ID = "cometchat-guid-1"; // Replace with your Group ID -Dynamically import `CometChatNoSSR` with `ssr: false` so it only loads client-side. +export default function CometChatClient() { + const [ready, setReady] = useState(false); + const [chatGroup, setChatGroup] = useState(undefined); -```tsx title="index.tsx" lines -import dynamic from "next/dynamic"; -import "@cometchat/chat-uikit-react/css-variables.css"; + useEffect(() => { + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") + .subscribePresenceForAllUsers() + .build(); -const CometChatComponent = dynamic( - () => import("../CometChatNoSSR/CometChatNoSSR"), - { ssr: false } -); + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + const group = await CometChat.getGroup(GROUP_ID); + setChatGroup(group); + setReady(true); + }); + }, []); -export default function Home() { - return ; + if (!ready || !chatGroup) return
Loading chat...
; + + return ( + +
+ + + +
+
+ ); } ``` +The only difference: use `CometChat.getGroup(GUID)` instead of `CometChat.getUser(UID)`, and pass `group` instead of `user`. + --- -## Step 3 — Run the Project +## Run - - -```bash lines +```bash npm run dev ``` - - -```bash lines -pnpm dev -``` - - -```bash lines -yarn dev -``` - - -You should see the chat window load with the conversation for the UID you set. +Open `http://localhost:3000/chat`. You should see the chat window load with the conversation for the UID or GUID you set. --- ## Next Steps - - Customize colors, fonts, and styles to match your brand + + Two-panel layout with a sidebar + + + Tabbed navigation with Chats, Calls, Users Browse all prebuilt UI components - } href="/ui-kit/react/next-js-integration"> - Back to the main setup guide - - - Chat features included out of the box - diff --git a/ui-kit/react/next-tab-based-chat.mdx b/ui-kit/react/next-tab-based-chat.mdx index 06a788584..35b9649ed 100644 --- a/ui-kit/react/next-tab-based-chat.mdx +++ b/ui-kit/react/next-tab-based-chat.mdx @@ -1,7 +1,7 @@ --- title: "Tab-Based Chat" sidebarTitle: "Tab-Based Chat" -description: "Build a tab-based messaging UI with chats, calls, users, and groups in Next.js with CometChat UI Kit." +description: "Build a tab-based chat interface with Chat, Call Logs, and Users tabs in Next.js (App Router)." --- @@ -9,26 +9,23 @@ description: "Build a tab-based messaging UI with chats, calls, users, and group | Field | Value | | --- | --- | | Package | `@cometchat/chat-uikit-react` | -| Framework | Next.js | -| Components | `CometChatConversations`, `CometChatCallLogs`, `CometChatUsers`, `CometChatGroups`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | -| Layout | Tabbed sidebar (Chats, Calls, Users, Groups) + message view | -| Prerequisite | Complete [Next.js Integration](/ui-kit/react/next-js-integration) Steps 1–5 first | -| SSR | Dynamic import with `ssr: false` — CometChat requires browser APIs | +| Framework | Next.js (App Router) | +| Components | `CometChatConversations`, `CometChatCallLogs`, `CometChatUsers`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | +| Layout | Tabbed sidebar (Chat, Calls, Users) + message view | +| Prerequisite | Complete [Next.js Integration](/ui-kit/react/integration-nextjs) first | +| SSR | Component loaded with `dynamic(() => import(...), { ssr: false })` | | Pattern | Full-featured messaging app with multiple sections | -This guide builds a tabbed messaging UI — Chats, Calls, Users, and Groups tabs in the sidebar, with a message view on the right. Good for full-featured apps that need more than just conversations. +This guide builds a tabbed messaging UI — Chat, Calls, and Users tabs in the sidebar, with a message view on the right. Good for full-featured apps that need more than just conversations. -This assumes you've already completed [Next.js Integration](/ui-kit/react/next-js-integration) (project created, UI Kit installed, CSS imported). +This assumes you've already completed [Next.js Integration](/ui-kit/react/integration-nextjs) (project created, UI Kit installed, init + login working). - + -[](https://link.cometchat.com/next-tabs-sidebar-message) - -> Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. --- @@ -36,573 +33,288 @@ This assumes you've already completed [Next.js Integration](/ui-kit/react/next-j Three sections working together: -1. **Tab bar** — switches between Chats, Calls, Users, and Groups +1. **Tab bar** — switches between Chat, Calls, and Users 2. **Sidebar** — renders the list for the active tab 3. **Message view** — header + messages + composer for the selected item --- -## Step 1 — Create the Tab Component - - - - - - - - - - - - -Tab icons need to be placed in `public/assets/`. Download them from the [CometChat UI Kit assets folder on GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app/src/assets). - - - - - - - - - - - - - - - -```tsx title="CometChatTabs.tsx" lines -import { useState } from "react"; -import "./CometChatTabs.css"; - -const chatsIcon = "/assets/chats.svg"; -const callsIcon = "/assets/calls.svg"; -const usersIcon = "/assets/users.svg"; -const groupsIcon = "/assets/groups.svg"; - -export const CometChatTabs = (props: { - onTabClicked?: (tabItem: { name: string; icon?: string }) => void; - activeTab?: string; -}) => { - const { onTabClicked = () => {}, activeTab } = props; - const [hoverTab, setHoverTab] = useState(""); - - const tabItems = [ - { name: "CHATS", icon: chatsIcon }, - { name: "CALLS", icon: callsIcon }, - { name: "USERS", icon: usersIcon }, - { name: "GROUPS", icon: groupsIcon }, - ]; - - return ( -
- {tabItems.map((tabItem) => { - const isActive = - activeTab === tabItem.name.toLowerCase() || - hoverTab === tabItem.name.toLowerCase(); - - return ( -
onTabClicked(tabItem)} - > -
setHoverTab(tabItem.name.toLowerCase())} - onMouseLeave={() => setHoverTab("")} - /> -
setHoverTab(tabItem.name.toLowerCase())} - onMouseLeave={() => setHoverTab("")} - > - {tabItem.name} -
-
- ); - })} -
- ); -}; -``` - - - - -```css title="CometChatTabs.css" lines -.cometchat-tab-component { - display: flex; - width: 100%; - padding: 0px 8px; - align-items: flex-start; - gap: 8px; - border-top: 1px solid var(--cometchat-border-color-light, #F5F5F5); - border-right: 1px solid var(--cometchat-border-color-light, #F5F5F5); - background: var(--cometchat-background-color-01, #FFF); -} - -.cometchat-tab-component__tab { - display: flex; - padding: 12px 0px 10px 0px; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 4px; - flex: 1 0 0; - min-height: 48px; -} - -.cometchat-tab-component__tab-icon { - display: flex; - width: 32px; - height: 32px; - justify-content: center; - align-items: center; - background: var(--cometchat-icon-color-secondary); - -webkit-mask-size: contain; - -webkit-mask-position: center; - -webkit-mask-repeat: no-repeat; - mask-size: contain; - mask-position: center; - mask-repeat: no-repeat; - cursor: pointer; -} - -.cometchat-tab-component__tab-text { - color: var(--cometchat-text-color-secondary, #727272); - text-align: center; - font: var(--cometchat-font-caption1-medium, 500 12px Roboto); - cursor: pointer; -} - -.cometchat-tab-component__tab-icon-active { - background: var(--cometchat-icon-color-highlight); -} - -.cometchat-tab-component__tab-text-active { - color: var(--cometchat-text-color-highlight); -} -``` - - - - ---- +## Full Code -## Step 2 — Create the Sidebar Component +Create the client component with the tabbed UI, then import it dynamically in your page. Init and login happen in a `useEffect` before the provider mounts. -The sidebar renders the list for whichever tab is active, plus the tab bar at the bottom. +```tsx title="app/chat/CometChatClient.tsx" +'use client'; - - - - - - - - - - - - - - -```tsx title="CometChatSelector.tsx" lines import { useEffect, useState } from "react"; +import { CometChat } from "@cometchat/chat-sdk-javascript"; import { - Call, - Conversation, - Group, - User, - CometChat, -} from "@cometchat/chat-sdk-javascript"; -import { - CometChatCallLogs, + CometChatUIKit, + UIKitSettingsBuilder, + CometChatProvider, CometChatConversations, - CometChatGroups, - CometChatUIKitLoginListener, CometChatUsers, -} from "@cometchat/chat-uikit-react"; -import { CometChatTabs } from "../CometChatTabs/CometChatTabs"; - -interface SelectorProps { - onSelectorItemClicked?: ( - input: User | Group | Conversation | Call, - type: string - ) => void; -} - -export const CometChatSelector = (props: SelectorProps) => { - const { onSelectorItemClicked = () => {} } = props; - const [loggedInUser, setLoggedInUser] = useState(); - const [activeItem, setActiveItem] = useState< - Conversation | User | Group | Call | undefined - >(); - const [activeTab, setActiveTab] = useState("chats"); - - useEffect(() => { - const user = CometChatUIKitLoginListener.getLoggedInUser(); - setLoggedInUser(user); - }, []); - - return ( - <> - {loggedInUser && ( - <> - {activeTab === "chats" && ( - { - setActiveItem(item); - onSelectorItemClicked(item, "updateSelectedItem"); - }} - /> - )} - - {activeTab === "calls" && ( - { - setActiveItem(item); - onSelectorItemClicked(item, "updateSelectedItemCall"); - }} - /> - )} - - {activeTab === "users" && ( - { - setActiveItem(item); - onSelectorItemClicked(item, "updateSelectedItemUser"); - }} - /> - )} - - {activeTab === "groups" && ( - { - setActiveItem(item); - onSelectorItemClicked(item, "updateSelectedItemGroup"); - }} - /> - )} - - )} - - setActiveTab(item.name.toLowerCase())} - /> - - ); -}; -``` - - - - -```css title="CometChatSelector.css" lines -.selector-wrapper .cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon { - background: var(--cometchat-icon-color-primary); -} - -.cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon:hover { - background: var(--cometchat-icon-color-highlight); -} - -.cometchat-list__header-search-bar { - border-right: none; -} - -.cometchat .cometchat-menu-list__sub-menu-list-item { - text-align: left; -} - -.cometchat .cometchat-conversations .cometchat-menu-list__sub-menu-list { - width: 212px; - top: 40px !important; - left: 172px !important; -} - -#logged-in-user { - border-bottom: 2px solid var(--cometchat-border-color-default, #E8E8E8); -} - -#logged-in-user .cometchat-menu-list__sub-menu-item-title, -#logged-in-user .cometchat-menu-list__sub-menu-list-item { - cursor: default; -} - -.cometchat-menu-list__sub-menu-list-item-icon-log-out { - background-color: var(--cometchat-error-color, #F44649); -} - -.cometchat-menu-list__sub-menu-item-title-log-out { - color: var(--cometchat-error-color, #F44649); -} - -.chat-menu .cometchat .cometchat-menu-list__sub-menu-item-title { - cursor: pointer; -} - -.chat-menu .cometchat .cometchat-menu-list__sub-menu { - box-shadow: none; -} - -.chat-menu .cometchat .cometchat-menu-list__sub-menu-icon { - background-color: var(--cometchat-icon-color-primary, #141414); - width: 24px; - height: 24px; -} -``` - - - - ---- - -## Step 3 — Create the CometChatNoSSR Component - -This component handles init, login, and renders the full tabbed chat experience. It runs client-side only. - - - - - - - - - - - - - - - -```tsx title="CometChatNoSSR.tsx" highlight={15-17, 20} lines -import React, { useEffect, useState } from "react"; -import { - CometChatMessageComposer, + CometChatCallLogs, CometChatMessageHeader, CometChatMessageList, - CometChatUIKit, - UIKitSettingsBuilder, + CometChatMessageComposer, } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { CometChatSelector } from "../CometChatSelector/CometChatSelector"; -import "./CometChatNoSSR.css"; -// Replace with your actual credentials -const COMETCHAT_CONSTANTS = { - APP_ID: "", // Replace with your App ID - REGION: "", // Replace with your Region - AUTH_KEY: "", // Replace with your Auth Key (dev only) -}; +type Tab = "chat" | "calls" | "users"; -const UID = "cometchat-uid-4"; // Replace with your actual UID - -const CometChatNoSSR: React.FC = () => { - const [user, setUser] = useState(undefined); +export default function CometChatClient() { + const [ready, setReady] = useState(false); + const [activeTab, setActiveTab] = useState("chat"); const [selectedUser, setSelectedUser] = useState(undefined); const [selectedGroup, setSelectedGroup] = useState(undefined); useEffect(() => { - const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) + const settings = new UIKitSettingsBuilder() + .setAppId("YOUR_APP_ID") + .setRegion("YOUR_REGION") + .setAuthKey("YOUR_AUTH_KEY") .subscribePresenceForAllUsers() .build(); - CometChatUIKit.init(UIKitSettings) - ?.then(() => { - console.log("Initialization completed successfully"); - CometChatUIKit.getLoggedinUser().then((loggedInUser) => { - if (!loggedInUser) { - CometChatUIKit.login(UID) - .then((user) => { - console.log("Login Successful", { user }); - setUser(user); - }) - .catch((error) => console.error("Login failed", error)); - } else { - console.log("Already logged-in", { loggedInUser }); - setUser(loggedInUser); - } - }); - }) - .catch((error) => console.error("Initialization failed", error)); + CometChatUIKit.init(settings).then(async () => { + await CometChatUIKit.login("cometchat-uid-1"); + setReady(true); + }); }, []); - return user ? ( -
-
- { - let item = activeItem; - if (activeItem instanceof CometChat.Conversation) { - item = activeItem.getConversationWith(); - } - if (item instanceof CometChat.User) { - setSelectedUser(item as CometChat.User); - setSelectedGroup(undefined); - } else if (item instanceof CometChat.Group) { - setSelectedUser(undefined); - setSelectedGroup(item as CometChat.Group); - } else { - setSelectedUser(undefined); - setSelectedGroup(undefined); - } - }} - /> -
+ if (!ready) return
Loading chat...
; + + const handleConversationClick = (conversation: CometChat.Conversation) => { + const entity = conversation.getConversationWith(); + if (conversation.getConversationType() === "user") { + setSelectedUser(entity as CometChat.User); + setSelectedGroup(undefined); + } else { + setSelectedGroup(entity as CometChat.Group); + setSelectedUser(undefined); + } + }; + + const handleUserClick = (user: CometChat.User) => { + setSelectedUser(user); + setSelectedGroup(undefined); + }; + + const handleCallClick = (call: any) => { + const initiator = call.getInitiator(); + const receiver = call.getReceiver(); + + // Determine the other party in the call + if (receiver instanceof CometChat.User) { + setSelectedUser(receiver); + setSelectedGroup(undefined); + } else if (receiver instanceof CometChat.Group) { + setSelectedUser(undefined); + setSelectedGroup(receiver); + } else if (initiator instanceof CometChat.User) { + setSelectedUser(initiator); + setSelectedGroup(undefined); + } + }; - {selectedUser || selectedGroup ? ( -
- - - + return ( + +
+
+
+ + + +
+ +
+ {activeTab === "chat" && ( + + )} + {activeTab === "calls" && ( + + )} + {activeTab === "users" && ( + + )} +
- ) : ( -
Select a conversation to start chatting
- )} -
- ) : undefined; -}; - -export default CometChatNoSSR; -``` - - + {selectedUser || selectedGroup ? ( +
+ + + +
+ ) : ( +
+ Select a conversation to start chatting +
+ )} +
+ + ); +} +``` -```css title="CometChatNoSSR.css" lines -.conversations-with-messages { +```css title="app/chat/chat.css" +.tabbed-chat { display: flex; - height: 100%; + height: 100vh; width: 100%; } -.conversations-wrapper { +.sidebar { + width: 360px; height: 100%; - width: 480px; - overflow: hidden; display: flex; flex-direction: column; - height: inherit; + border-right: 1px solid #eee; +} + +.tab-bar { + display: flex; + border-bottom: 1px solid #eee; + background: var(--cometchat-background-color-01, #fff); } -.conversations-wrapper > .cometchat { +.tab-button { + flex: 1; + padding: 12px 0; + border: none; + background: none; + cursor: pointer; + font: var(--cometchat-font-body-medium, 500 14px Roboto); + color: var(--cometchat-text-color-secondary, #727272); + border-bottom: 2px solid transparent; + transition: color 0.2s, border-color 0.2s; +} + +.tab-button:hover { + color: var(--cometchat-text-color-primary, #141414); +} + +.tab-button--active { + color: var(--cometchat-text-color-highlight, #6851d6); + border-bottom-color: var(--cometchat-primary-color, #6851d6); +} + +.sidebar-list { + flex: 1; overflow: hidden; + display: flex; + flex-direction: column; } .messages-wrapper { - width: calc(100% - 480px); + flex: 1; height: 100%; display: flex; flex-direction: column; } .empty-conversation { - height: 100%; - width: 100%; + flex: 1; display: flex; justify-content: center; align-items: center; - background: white; + background: var(--cometchat-background-color-03, #f5f5f5); color: var(--cometchat-text-color-secondary, #727272); font: var(--cometchat-font-body-regular, 400 14px Roboto); } - -.cometchat .cometchat-message-composer { - border-radius: 0px; -} ``` - - +```tsx title="app/chat/page.tsx" +import dynamic from 'next/dynamic'; -How it works: -- Selections from any tab (Chats, Calls, Users, Groups) flow through the same `onSelectorItemClicked` callback. -- Conversation items are unwrapped via `getConversationWith()` to extract the underlying `User` or `Group`. -- Only one of `selectedUser` / `selectedGroup` is set at a time — the other is cleared. +const CometChatClient = dynamic(() => import('./CometChatClient'), { ssr: false }); ---- +export default function ChatPage() { + return ; +} +``` -## Step 4 — Disable SSR in Your Page +--- -Dynamically import `CometChatNoSSR` with `ssr: false` so it only loads client-side. +## How It Works -```tsx title="index.tsx" lines -import dynamic from "next/dynamic"; -import "@cometchat/chat-uikit-react/css-variables.css"; +1. **`'use client'`** marks the component as a Client Component — required because CometChat uses browser APIs. +2. **`dynamic(() => import(...), { ssr: false })`** prevents the component from rendering on the server. +3. **Tab state** — `activeTab` controls which list component renders in the sidebar. +4. **Conditional rendering** — only the active tab's component mounts. Switching tabs unmounts the previous list and mounts the new one. +5. **Unified selection** — all three tabs feed into the same `selectedUser` / `selectedGroup` state. Clicking any item (conversation, call log, or user) updates the message panel. +6. **Call log handling** — when a call log is clicked, the receiver (user or group) is extracted and passed to the message components. -const CometChatComponent = dynamic( - () => import("../CometChatNoSSR/CometChatNoSSR"), - { ssr: false } -); +--- -export default function Home() { - return ; -} +## Adding More Tabs + +To add a Groups tab, import `CometChatGroups` and add another tab button + conditional render: + +```tsx +import { CometChatGroups } from "@cometchat/chat-uikit-react"; + +// Add to Tab type: +type Tab = "chat" | "calls" | "users" | "groups"; + +// Add button in tab-bar: + + +// Add in sidebar-list: +{activeTab === "groups" && ( + { + setSelectedGroup(group); + setSelectedUser(undefined); + }} + /> +)} ``` +You can follow the same pattern for any additional tabs (Settings, Contacts, etc.). + --- -## Step 5 — Run the Project +## Run - - -```bash lines +```bash npm run dev ``` - - -```bash lines -pnpm dev -``` - - -```bash lines -yarn dev -``` - - -You should see the tab bar at the bottom of the sidebar. Switch between Chats, Calls, Users, and Groups — tapping any item loads the message view on the right. +Open `http://localhost:3000/chat`. You should see the tab bar at the top of the sidebar. Switch between Chats, Calls, and Users — clicking any item loads the message view on the right. --- ## Next Steps - - Customize colors, fonts, and styles to match your brand + + Two-panel layout without tabs Browse all prebuilt UI components - } href="/ui-kit/react/next-js-integration"> - Back to the main setup guide - - - Chat features included out of the box + + Customize colors, fonts, and styles diff --git a/ui-kit/react/outgoing-call.mdx b/ui-kit/react/outgoing-call.mdx deleted file mode 100644 index ab98f2658..000000000 --- a/ui-kit/react/outgoing-call.mdx +++ /dev/null @@ -1,713 +0,0 @@ ---- -title: "Outgoing Call" -description: "Display CometChat React UI Kit outgoing call screens with recipient details, cancel actions, custom sounds, and outgoing call callbacks." ---- - -```json -{ - "component": "CometChatOutgoingCall", - "package": "@cometchat/chat-uikit-react", - "import": "import { CometChatOutgoingCall } from \"@cometchat/chat-uikit-react\";", - "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";", - "description": "Overlay component displaying an outgoing voice/video call with recipient info and cancel control.", - "cssRootClass": ".cometchat-outgoing-call", - "primaryOutput": { - "prop": "onCallCanceled", - "type": "Function" - }, - "props": { - "data": { - "call": { - "type": "CometChat.Call", - "default": "undefined", - "note": "Must come from CometChat.initiateCall()" - } - }, - "callbacks": { - "onCallCanceled": "Function", - "onError": "((error: CometChat.CometChatException) => void) | null" - }, - "sound": { - "disableSoundForCalls": { "type": "boolean", "default": false }, - "customSoundForCalls": { "type": "string", "default": "built-in" } - }, - "viewSlots": { - "titleView": "JSX.Element", - "subtitleView": "JSX.Element", - "avatarView": "JSX.Element", - "cancelButtonView": "JSX.Element" - } - }, - "events": [ - { - "name": "CometChatCallEvents.ccOutgoingCall", - "payload": "CometChat.Call", - "description": "Call initiated" - }, - { - "name": "CometChatCallEvents.ccCallAccepted", - "payload": "CometChat.Call", - "description": "Recipient accepts" - }, - { - "name": "CometChatCallEvents.ccCallRejected", - "payload": "CometChat.Call", - "description": "Recipient rejects" - }, - { - "name": "CometChatCallEvents.ccCallEnded", - "payload": "CometChat.Call", - "description": "Call session ends" - } - ], - "sdkListeners": [], - "compositionExample": { - "description": "App-level overlay rendered after CometChat.initiateCall()", - "components": ["CometChatOutgoingCall"], - "flow": "CometChat.initiateCall() returns CometChat.Call -> pass to call prop -> onCallCanceled ends session" - } -} -``` - - -## Where It Fits - -`CometChatOutgoingCall` is an overlay component that displays the outgoing call screen with the recipient's name, avatar, and a cancel button. It plays a ringtone while the call is pending. Typically rendered at the app root level after initiating a call via `CometChat.initiateCall()`. - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatOutgoingCall, - CometChatUIKitConstants, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function OutgoingCallDemo() { - const [call, setCall] = useState(); - - useEffect(() => { - const uid = "uid"; - const callObject = new CometChat.Call( - uid, - CometChatUIKitConstants.MessageTypes.audio, - CometChatUIKitConstants.MessageReceiverType.user - ); - CometChat.initiateCall(callObject) - .then((c) => setCall(c)) - .catch(console.log); - }, []); - - return call ? : null; -} - -export default OutgoingCallDemo; -``` - - - - - ---- - -## Minimal Render - -```tsx lines -import { CometChatOutgoingCall } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/css-variables.css"; - -function OutgoingCallMinimal() { - // `call` must be a CometChat.Call object from CometChat.initiateCall() - return call ? : null; -} -``` - -Root CSS class: `.cometchat-outgoing-call` - ---- - -## Actions and Events - -### Callback Props - -#### onCallCanceled - -Fires when the cancel button is clicked. Pauses the ringtone internally before invoking the callback. - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatOutgoingCall, - CometChatUIKitConstants, -} from "@cometchat/chat-uikit-react"; - -function OutgoingCallWithCancel() { - const [call, setCall] = useState(); - - useEffect(() => { - const uid = "uid"; - const callObject = new CometChat.Call( - uid, - CometChatUIKitConstants.MessageTypes.audio, - CometChatUIKitConstants.MessageReceiverType.user - ); - CometChat.initiateCall(callObject) - .then((c) => setCall(c)) - .catch(console.log); - }, []); - - const cancelCall = () => { - CometChat.endCall(call!.getSessionId()).then(() => setCall(undefined)); - }; - - return call ? ( - - ) : null; -} -``` - -#### onError - -Fires on internal errors. - -```tsx lines -import { CometChatOutgoingCall } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function OutgoingCallWithError() { - return ( - { - console.error("OutgoingCall error:", error); - }} - /> - ); -} -``` - -### Global UI Events - -`CometChatCallEvents` emits call lifecycle events subscribable from anywhere. Subscribe in a `useEffect` and unsubscribe on cleanup. - -| Event | Fires when | Payload | -| --- | --- | --- | -| `ccOutgoingCall` | A call is initiated | `CometChat.Call` | -| `ccCallAccepted` | The recipient accepts the call | `CometChat.Call` | -| `ccCallRejected` | The recipient rejects the call | `CometChat.Call` | -| `ccCallEnded` | The call session ends | `CometChat.Call` | - -```tsx lines -import { useEffect } from "react"; -import { CometChatCallEvents } from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function useCallEvents() { - useEffect(() => { - const acceptedSub = CometChatCallEvents.ccCallAccepted.subscribe( - (call: CometChat.Call) => { - console.log("Call accepted:", call.getSessionId()); - } - ); - const rejectedSub = CometChatCallEvents.ccCallRejected.subscribe( - (call: CometChat.Call) => { - console.log("Call rejected:", call.getSessionId()); - } - ); - const endedSub = CometChatCallEvents.ccCallEnded.subscribe( - (call: CometChat.Call) => { - console.log("Call ended:", call.getSessionId()); - } - ); - - return () => { - acceptedSub?.unsubscribe(); - rejectedSub?.unsubscribe(); - endedSub?.unsubscribe(); - }; - }, []); -} -``` - -### SDK Events (Real-Time, Automatic) - -The component internally manages call sound playback. It plays the outgoing call ringtone on mount (unless `disableSoundForCalls={true}`) and pauses it on unmount or cancel. No SDK call listeners are attached by the component itself — call status updates are handled by the parent application. - ---- - -## Custom View Slots - -All view slots on `CometChatOutgoingCall` are `JSX.Element` (not functions). They do not receive parameters — pass call data via closure if needed. - -| Slot | Type | Replaces | -| --- | --- | --- | -| `titleView` | `JSX.Element` | Recipient name | -| `subtitleView` | `JSX.Element` | "Calling..." text | -| `avatarView` | `JSX.Element` | Recipient avatar | -| `cancelButtonView` | `JSX.Element` | Cancel call button | - -### titleView - -Replace the recipient name. - - - - - - - -```tsx lines -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatOutgoingCall, - CometChatUIKitConstants, -} from "@cometchat/chat-uikit-react"; - -function OutgoingCallCustomTitle() { - // assume `call` is a CometChat.Call from CometChat.initiateCall() - const getTitleView = (call: CometChat.Call) => ( -
- {call.getCallInitiator().getName()} {" <> "}{" "} - {call.getCallReceiver().getName()} -
- ); - - return call ? ( - - ) : null; -} -``` -
- -```css lines -.outgoing-call__title { - color: #141414; - text-align: center; - font: 500 24px Roboto; -} -``` - -
- -### subtitleView - -Replace the "Calling..." text. - - - - - - - -```tsx lines -const getSubtitleView = (call: CometChat.Call) => ( -
-
- {"Calling..."} -
-); - -; -``` - - -```css lines -.outgoing-call__subtitle { - display: flex; - justify-content: center; - align-items: flex-start; - gap: 8px; - color: #727272; - text-align: center; - font: 400 16px Roboto; -} - -.outgoing-call__subtitle-icon { - -webkit-mask: url("") center center no-repeat; - background: #a1a1a1; - height: 24px; - width: 24px; -} -``` - - - -### avatarView - -Replace the recipient avatar. - - - - - - - -```tsx lines -import { - CometChatAvatar, - CometChatOutgoingCall, -} from "@cometchat/chat-uikit-react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function OutgoingCallCustomAvatar() { - const getAvatarView = (call: CometChat.Call) => ( -
- -
-
- ); - - return call ? ( - - ) : null; -} -``` - - -```css lines -.outgoing-call__avatar .cometchat-avatar, -.outgoing-call__avatar .cometchat-avatar__image { - width: 160px; - height: 160px; - border-radius: 20px; -} - -.outgoing-call__avatar-status { - background-image: url(""); - height: 44px; - width: 44px; - background-size: contain; - position: relative; - top: -45px; - right: -60px; -} -``` - - - -### cancelButtonView - -Replace the cancel call button. - - - - - - - -```tsx lines -function OutgoingCallCustomCancel() { - const getCancelButtonView = (call: CometChat.Call) => ( -
-
-
- {"End Call"} -
-
- ); - - return call ? ( - - ) : null; -} -``` - - -```css lines -.outgoing-call__cancel-button-wrapper { - height: 64px; - display: flex; - justify-content: center; - cursor: pointer; -} - -.outgoing-call__cancel-button { - display: flex; - width: 330px; - padding: 12px 30px; - justify-content: center; - align-items: center; - gap: 12px; - border-radius: 12px; - background-color: #f44649; - color: #fff; - font: 500 20px Roboto; -} - -.outgoing-call__cancel-button-icon { - -webkit-mask: url("") center center no-repeat; - background: #e8e8e8; - height: 32px; - width: 32px; -} -``` - - - ---- - -## Common Patterns - -### Cancel and end the call session - -```tsx lines -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatOutgoingCall, - CometChatUIKitConstants, -} from "@cometchat/chat-uikit-react"; - -function OutgoingCallWithEndSession() { - const [call, setCall] = useState(); - - useEffect(() => { - const uid = "uid"; - const callObject = new CometChat.Call( - uid, - CometChatUIKitConstants.MessageTypes.audio, - CometChatUIKitConstants.MessageReceiverType.user - ); - CometChat.initiateCall(callObject) - .then((c) => setCall(c)) - .catch(console.log); - }, []); - - const handleCancel = () => { - if (call) { - CometChat.endCall(call.getSessionId()).then(() => setCall(undefined)); - } - }; - - return call ? ( - - ) : null; -} -``` - -### Custom ringtone - -```tsx lines -import { CometChatOutgoingCall } from "@cometchat/chat-uikit-react"; - -function OutgoingCallCustomSound() { - return ( - - ); -} -``` - -### Silent outgoing call (no ringtone) - -```tsx lines -import { CometChatOutgoingCall } from "@cometchat/chat-uikit-react"; - -function SilentOutgoingCall() { - return ( - - ); -} -``` - ---- - -## CSS Architecture - -The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade: - -1. Global tokens (e.g., `--cometchat-primary-color`, `--cometchat-error-color`) set on the `.cometchat` root wrapper. -2. Component CSS (`.cometchat-outgoing-call`) consumes these tokens via `var()` with fallback values. -3. Overrides target `.cometchat-outgoing-call` descendant selectors in a global stylesheet. - -### Key Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-outgoing-call` | -| Title container | `.cometchat-outgoing-call__title-container` | -| Title text | `.cometchat-outgoing-call__title` | -| Subtitle text | `.cometchat-outgoing-call__subtitle` | -| Avatar container | `.cometchat-outgoing-call__avatar` | -| Avatar image | `.cometchat-outgoing-call__avatar .cometchat-avatar` | -| Avatar text | `.cometchat-outgoing-call__avatar .cometchat-avatar__text` | -| Cancel button wrapper | `.cometchat-outgoing-call__button` | -| Cancel button | `.cometchat-outgoing-call__button .cometchat-button` | -| Cancel button icon | `.cometchat-outgoing-call__button .cometchat-button .cometchat-button__icon` | - -### Example: Themed outgoing call - - - - - -```css lines -.cometchat-outgoing-call__avatar .cometchat-avatar { - border-radius: 16px; - background: #fbaa75; -} - -.cometchat-outgoing-call__button .cometchat-button { - border-radius: 8px; - background: #f44649; -} - -.cometchat-outgoing-call .cometchat-outgoing-call__title { - text-align: center; - font: 400 32px/38px "Times New Roman"; -} -``` - -### Customization Matrix - -| What to change | Where | Property/API | Example | -| --- | --- | --- | --- | -| Handle cancel action | Component props | `onCallCanceled` | `onCallCanceled={() => endCall()}` | -| Disable ringtone | Component props | `disableSoundForCalls` | `disableSoundForCalls={true}` | -| Custom ringtone | Component props | `customSoundForCalls` | `customSoundForCalls="/sounds/ring.mp3"` | -| Replace UI sections | Component props | View slot props | `titleView={
Custom
}` | -| Change colors, fonts, spacing | Global CSS | Target `.cometchat-outgoing-call` class | `.cometchat-outgoing-call__title { color: red; }` | - ---- - -## Props - -All props are optional unless noted. Sorted alphabetically. - -### avatarView - -Custom JSX replacing the recipient avatar. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in avatar | - ---- - -### call - -The outgoing call object from `CometChat.initiateCall()`. - -| | | -| --- | --- | -| Type | `CometChat.Call` | -| Default | `undefined` | - -Component renders nothing when `call` is not provided. - ---- - -### cancelButtonView - -Custom JSX replacing the cancel call button. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in cancel button | - ---- - -### customSoundForCalls - -URL to a custom audio file for the outgoing call ringtone. - -| | | -| --- | --- | -| Type | `string` | -| Default | Built-in ringtone | - ---- - -### disableSoundForCalls - -Disables the outgoing call ringtone. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### onCallCanceled - -Callback fired when the cancel button is clicked. - -| | | -| --- | --- | -| Type | `Function` | -| Default | `undefined` | - ---- - -### onError - -Callback fired when the component encounters an error. - -| | | -| --- | --- | -| Type | `((error: CometChat.CometChatException) => void) \| null` | -| Default | `undefined` | - ---- - -### subtitleView - -Custom JSX replacing the "Calling..." subtitle text. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in subtitle | - ---- - -### titleView - -Custom JSX replacing the recipient name. - -| | | -| --- | --- | -| Type | `JSX.Element` | -| Default | Built-in title | - ---- - -## Events - -| Event | Payload | Fires when | -| --- | --- | --- | -| `CometChatCallEvents.ccOutgoingCall` | `CometChat.Call` | Call initiated | -| `CometChatCallEvents.ccCallAccepted` | `CometChat.Call` | Recipient accepts | -| `CometChatCallEvents.ccCallRejected` | `CometChat.Call` | Recipient rejects | -| `CometChatCallEvents.ccCallEnded` | `CometChat.Call` | Call session ends | - -All events are `Subject` from RxJS. Subscribe with `.subscribe()`, unsubscribe with the returned subscription's `.unsubscribe()`. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Root | `.cometchat-outgoing-call` | -| Title container | `.cometchat-outgoing-call__title-container` | -| Title text | `.cometchat-outgoing-call__title` | -| Subtitle text | `.cometchat-outgoing-call__subtitle` | -| Avatar container | `.cometchat-outgoing-call__avatar` | -| Avatar image | `.cometchat-outgoing-call__avatar .cometchat-avatar` | -| Avatar text | `.cometchat-outgoing-call__avatar .cometchat-avatar__text` | -| Cancel button wrapper | `.cometchat-outgoing-call__button` | -| Cancel button | `.cometchat-outgoing-call__button .cometchat-button` | -| Cancel button icon | `.cometchat-outgoing-call__button .cometchat-button .cometchat-button__icon` | diff --git a/ui-kit/react/overview.mdx b/ui-kit/react/overview.mdx index 4245cf963..ae7935a47 100644 --- a/ui-kit/react/overview.mdx +++ b/ui-kit/react/overview.mdx @@ -4,96 +4,27 @@ sidebarTitle: "Overview" description: "Prebuilt React components for chat, voice, and video calling. Supports React.js, Next.js, React Router, and Astro." --- - -🚀 **CometChat React UI Kit v7 (beta) is now available!** It features a revamped component architecture, improved customization, and enhanced performance. [Switch to v7 →](/ui-kit/react/v7/overview) - - | Field | Value | | --- | --- | -| Package | `@cometchat/chat-uikit-react` v6.3.x | -| Peer deps | `react` >=18, `react-dom` >=18, `rxjs` ^7.8.1 | +| Package | `@cometchat/chat-uikit-react` v7.0.x | +| Peer deps | `react` >=18, `react-dom` >=18, `@cometchat/chat-sdk-javascript` ^4.1.9, `dompurify` ^3.3.1 | | Calling | Optional — `@cometchat/calls-sdk-javascript` | -| SSR | Client-side only. Use `ssr: false` or `client:only="react"` | +| SSR | SSR-safe — no browser APIs at module scope. Next.js App Router compatible. | | Localization | 19 languages built-in | -| Source | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v6) | -| AI Skills | `npx @cometchat/skills add` — [GitHub](https://github.com/cometchat/cometchat-skills) | +| Source | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v7) | The CometChat React UI Kit provides prebuilt, customizable components for adding chat, voice, and video calling to any React app. Each component handles its own data fetching, real-time listeners, and state — you just drop them into your layout. - + --- -## Integrate with AI Coding Agents - -Use [CometChat Skills](https://github.com/cometchat/cometchat-skills) to add chat to any React project through your AI coding agent. The skill takes an AI-first approach — your agent has a short conversation with you to understand your project and chat requirements, then writes production-grade integration code tailored to the files you already have. One slash — `/cometchat` — works for React, Next.js, React Router, Astro, Expo, bare React Native, Angular, Android, Flutter, and iOS. - -Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and [30+ more agents](https://github.com/cometchat/cometchat-skills). - -```bash -npx @cometchat/skills add -``` - -Use `--ide ` to target a specific IDE (e.g. `--ide cursor`), or `--ide all` to install for all supported IDEs. - -Then in your IDE: - -``` -/cometchat add chat to my app -``` - -The skill detects your framework, router, env prefix, and existing auth system. It onboards you to CometChat directly in the terminal — signup, login, and app creation all via the CLI with no browser round-trip. It reads your routes, nav, and components before proposing a placement, shows the plan (which files it will create, modify, and leave untouched), and waits for your approval before writing code. - -After the first integration, re-run `/cometchat` anytime to pick from the iteration menu: - -- **Customize look & feel** — theme presets (slack / whatsapp / imessage / discord / notion) or your own brand color -- **Add a feature** — 40+ features including calls, reactions, polls, AI smart replies, file sharing, presence -- **Customize a component** — custom message bubbles, headers, composer actions, empty/loading states -- **Add a floating widget** — overlay chat button + drawer on top of your existing app -- **Set up production auth** — replace the dev Auth Key with a server-side token endpoint -- **Set up user management** — server endpoints for creating/updating/deleting CometChat users -- **Run diagnostics** — verify, drift detection, symptom-to-cause lookup - - - -For deeper component customization (custom views, SDK events, request builders), install the docs MCP: - -**Claude Code:** -```bash -claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp -``` - -**Cursor** (`.cursor/mcp.json`): -```json -{ "mcpServers": { "cometchat-docs": { "url": "https://www.cometchat.com/docs/mcp" } } } -``` - -**Windsurf:** -```json -{ "mcpServers": { "cometchat-docs": { "type": "sse", "serverUrl": "https://www.cometchat.com/docs/mcp" } } } -``` - -No authentication required. Not needed for the initial integration — the skill handles it without the MCP. - - - - - - AI-first integration for any React project - - - Claude Code · Cursor · Kiro · VS Code Copilot · Windsurf · Cline - - - ---- - ## Try It @@ -109,42 +40,79 @@ No authentication required. Not needed for the initial integration — the skill ## Get Started - - - - Pick your framework and follow the step-by-step integration guide: - + Vite or Create React App - } href="/ui-kit/react/next-js-integration"> + App Router with client-side rendering - } href="/ui-kit/react/react-router-integration"> + SPA with React Router v6+ - } href="/ui-kit/react/astro-integration"> + React islands with client:only directive --- +## What's Included + +- **Compound components** — compose only what you need using namespace sub-components (Root, View, EmptyState, etc.) +- **Plugin system** — extensible message rendering via `CometChatMessagePlugin` interface +- **Theming** — CSS custom properties (`--cometchat-*`) with built-in light and dark themes +- **Localization** — 19 supported languages with customizable translation keys +- **Calling** — optional voice and video calling via `@cometchat/calls-sdk-javascript` +- **SSR-safe** — no browser-only APIs at module scope; Next.js App Router compatible +- **Tree-shakeable** — ESM-first build with dual ESM + CJS output + +--- + +## Prerequisites + +Before integrating the UI Kit, ensure you have: + +- **Node.js 18+** installed +- A **CometChat account** with the following credentials: + - `appId` — your CometChat application ID + - `region` — your app region (e.g., `"us"` or `"eu"`) + - `authKey` — your CometChat auth key (for client-side authentication) + +You can find these values in the [CometChat Dashboard](https://app.cometchat.com). + +### Installation + +```bash +npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript react react-dom dompurify +``` + +| Package | Version | +|---------|---------| +| `@cometchat/chat-uikit-react` | `^7.0.0` | +| `@cometchat/chat-sdk-javascript` | `^4.1.9` | +| `react` | `>=18.0.0 <21.0.0` | +| `react-dom` | `>=18.0.0 <21.0.0` | +| `dompurify` | `^3.3.1` | +| `@cometchat/calls-sdk-javascript` | Optional — for voice/video calling | + +--- + ## Explore Browse all prebuilt UI components - - Chat, calling, AI, and extensions - - + Colors, fonts, dark mode, and custom styling - + + Customize message rendering with the plugin system + + Threaded messages, new chat, search, and more @@ -154,10 +122,10 @@ Pick your framework and follow the step-by-step integration guide: ## Resources - + Working reference app - + Full UI Kit source on GitHub @@ -169,7 +137,7 @@ Pick your framework and follow the step-by-step integration guide: Open a support ticket - - Upgrading from v5 + + Upgrading from v6 diff --git a/ui-kit/react/v7/plugins/custom-plugin.mdx b/ui-kit/react/plugins/custom-plugin.mdx similarity index 59% rename from ui-kit/react/v7/plugins/custom-plugin.mdx rename to ui-kit/react/plugins/custom-plugin.mdx index 11c7e10b5..e12959a5f 100644 --- a/ui-kit/react/v7/plugins/custom-plugin.mdx +++ b/ui-kit/react/plugins/custom-plugin.mdx @@ -1,21 +1,14 @@ --- title: "Creating a Custom Plugin" -description: "Step-by-step guide to building a custom message plugin for rendering, context menus, and conversation previews." +sidebarTitle: "Custom Plugin" +description: "Build a custom message plugin for rendering, context menus, and conversation previews, plus the plugin interface and context reference." --- -## Overview - -Custom plugins let you handle any message type with your own rendering logic. This guide walks through building a complete "Location" plugin that: - -1. Renders a map preview bubble -2. Provides context menu options -3. Shows a preview in the conversations list - ---- +Custom plugins let you handle any message type with your own rendering logic. This walkthrough builds a complete "Location" plugin that renders a map preview, provides context menu options, and shows a conversation preview. ## Step 1: Define the Plugin -Create a file for your plugin that implements `CometChatMessagePlugin`: +Create a file that implements `CometChatMessagePlugin`: ```tsx title="src/plugins/LocationPlugin.tsx" import React from "react"; @@ -111,8 +104,6 @@ export const LocationPlugin: CometChatMessagePlugin = { }; ``` ---- - ## Step 2: Register the Plugin Pass your plugin to `CometChatProvider`: @@ -123,13 +114,7 @@ import { LocationPlugin } from "./plugins/LocationPlugin"; function App() { return ( - + ); @@ -138,8 +123,6 @@ function App() { Your plugin is appended after the default plugins. Since resolution is first-match, default plugins handle their types first, and your plugin handles `"location"` messages. ---- - ## Step 3: Send a Location Message Use the CometChat SDK to send a custom message with type `"location"`: @@ -160,12 +143,8 @@ async function sendLocation(receiverUid: string, lat: number, lng: number) { } ``` ---- - ## Step 4: Style the Bubble -Add CSS for your bubble: - ```css title="src/plugins/LocationPlugin.css" .location-bubble { padding: 4px; @@ -178,36 +157,64 @@ Add CSS for your bubble: } ``` ---- - -## Plugin Interface Quick Reference +## Plugin Interface Reference ```typescript interface CometChatMessagePlugin { - id: string; // Unique identifier - messageTypes: string[]; // SDK message types to handle - messageCategories: string[]; // SDK message categories to handle + /** Unique plugin identifier. */ + id: string; + + /** SDK message types this plugin handles (e.g., ["text"], ["image"]). */ + messageTypes: string[]; - // Required - renderBubble(message, context): ReactNode; + /** SDK message categories this plugin handles (e.g., ["message"], ["custom"]). */ + messageCategories: string[]; - // Optional - getOptions?(message, context): MessageOption[]; - getLastMessagePreview?(message, loggedInUser, t?): string; + /** Render the bubble content for a message. */ + renderBubble(message: BaseMessage, context: PluginContext): ReactNode; + + /** Return context menu options for a message. */ + getOptions?(message: BaseMessage, context: PluginContext): MessageOption[]; + + /** Return plain-text preview for the conversation list subtitle. */ + getLastMessagePreview?(message: BaseMessage, loggedInUser: User, t?: (key: string) => string): string; + + /** Return text formatters (only relevant for text plugin). */ getTextFormatters?(): CometChatTextFormatter[]; - // View slot overrides (optional) - renderLeadingView?(message, context): ReactNode; - renderHeaderView?(message, context): ReactNode; - renderFooterView?(message, context): ReactNode; - renderBottomView?(message, context): ReactNode; - renderStatusInfoView?(message, context): ReactNode; - renderReplyView?(message, context): ReactNode; - renderThreadView?(message, context): ReactNode; + // --- View Slot Methods (optional) --- + renderLeadingView?(message: BaseMessage, context: PluginContext): ReactNode; + renderHeaderView?(message: BaseMessage, context: PluginContext): ReactNode; + renderFooterView?(message: BaseMessage, context: PluginContext): ReactNode; + renderBottomView?(message: BaseMessage, context: PluginContext): ReactNode; + renderStatusInfoView?(message: BaseMessage, context: PluginContext): ReactNode; + renderReplyView?(message: BaseMessage, context: PluginContext): ReactNode; + renderThreadView?(message: BaseMessage, context: PluginContext): ReactNode; } ``` ---- +## Plugin Context + +The `context` object passed to every plugin method: + +| Field | Type | Description | +| --- | --- | --- | +| `loggedInUser` | `CometChat.User` | The currently logged-in user | +| `group` | `CometChat.Group \| undefined` | The group (if group chat) | +| `alignment` | `"left" \| "right" \| "center"` | Bubble alignment | +| `theme` | `"light" \| "dark"` | Current theme | +| `getLocalizedString` | `(key: string) => string` | Localization function | +| `onDeleteMessage` | `(msg) => void` | Delete a message | +| `onEditMessage` | `(msg) => void` | Enter edit mode | +| `onReplyMessage` | `(msg) => void` | Set reply-to target | +| `onThreadClick` | `(msg) => void` | Open thread view | +| `onReactToMessage` | `(msg) => void` | Open emoji picker | +| `onMessageInfo` | `(msg) => void` | Open message info panel | +| `onMarkAsUnread` | `(msg) => void` | Mark as unread | +| `onFlagMessage` | `(msg) => void` | Open flag/report dialog | +| `showToast` | `(text) => void` | Show a toast notification | +| `getTextFormatters` | `() => Formatter[]` | Get text formatters for caption rendering | +| `publish` | `(event) => void` | Publish a UI event | ## Tips @@ -215,4 +222,4 @@ interface CometChatMessagePlugin { - **Use `context.getLocalizedString`** — for any user-facing text in options or bubbles - **Return `[]` from `getOptions`** — for system messages that shouldn't have a context menu - **Keep `getLastMessagePreview` short** — max ~100 characters, plain text only (no HTML) -- **Test with `messageTypes` array** — a single plugin can handle multiple types (like the Call Action plugin handles both `audio` and `video` in the `call` category) +- **A single plugin can handle multiple types** — like the Call Action plugin handles both `audio` and `video` in the `call` category diff --git a/ui-kit/react/plugins/overview.mdx b/ui-kit/react/plugins/overview.mdx new file mode 100644 index 000000000..65f3f6f87 --- /dev/null +++ b/ui-kit/react/plugins/overview.mdx @@ -0,0 +1,149 @@ +--- +title: "Plugins" +sidebarTitle: "Overview" +description: "How the plugin system renders messages, the built-in plugins, and the AI plugin." +--- + +## What is a Plugin? + +A plugin owns one or more message types. It tells the UI Kit: + +- **How to render the message** as a bubble in the message list +- **What context menu options** to show when a user hovers/long-presses a message +- **What preview text** to display in the Conversations list subtitle + +Every message that appears in the UI is rendered by a plugin. If no plugin matches a message type, the message is not displayed. + +Plugins are a thin routing layer — they decide which bubble component renders a message and provide context menu options and conversation previews. The **bubble components themselves are standalone** and documented under [Message Bubbles](/ui-kit/react/components/message-bubble); this page links each plugin to its component instead of repeating that detail. + +--- + +## Where Plugins Are Used + +| Location | Plugin Method | What it does | +| --- | --- | --- | +| **Message List** | `renderBubble()` | Routes to the appropriate bubble component (e.g., `CometChatTextBubble`, `CometChatImageBubble`) | +| **Message List** | `getOptions()` | Provides context menu items (reply, edit, delete, copy, react) | +| **Conversations List** | `getLastMessagePreview()` | Returns subtitle text ("📷 Photo", "You: Hello", "🎥 Video") | +| **Message Bubble** | `renderHeaderView()`, `renderFooterView()`, etc. | Customizes bubble regions beyond content | + +--- + +## The Plugin Interface + +Every plugin implements the `CometChatMessagePlugin` interface. Three members are **required**; everything else is optional and lets you override a specific bubble region or behavior. + +| Member | Signature | Required | Purpose | +| --- | --- | --- | --- | +| `id` | `string` | Yes | Unique plugin identifier (e.g. `'text'`, `'polls'`) | +| `messageTypes` | `string[]` | Yes | SDK message types this plugin handles | +| `messageCategories` | `string[]` | Yes | SDK message categories this plugin handles | +| `renderBubble` | `(message, context) => ReactNode` | Yes | Render the inner bubble content (the outer wrapper is handled by `CometChatMessageBubble`) | +| `getOptions` | `(message, context) => CometChatMessageOption[]` | Optional | Context menu options for the message (return `[]` for none) | +| `getLastMessagePreview` | `(message, loggedInUser, t?) => string` | Optional | Plain-text subtitle shown in the Conversations list | +| `getTextFormatters` | `() => CometChatTextFormatter[]` | Optional | Text formatters this plugin provides (only the text plugin uses this) | +| `renderLeadingView` | `(message, context) => ReactNode` | Optional | Override the leading view (avatar area) | +| `renderHeaderView` | `(message, context) => ReactNode` | Optional | Override the header view (sender name area) | +| `renderFooterView` | `(message, context) => ReactNode` | Optional | Override the footer view (reactions area) | +| `renderBottomView` | `(message, context) => ReactNode` | Optional | Override the bottom view (moderation / error footer) | +| `renderStatusInfoView` | `(message, context) => ReactNode` | Optional | Override the status info (timestamp + receipts + "edited") | +| `renderReplyView` | `(message, context) => ReactNode` | Optional | Override the reply view (quoted-message preview) | +| `renderThreadView` | `(message, context) => ReactNode` | Optional | Override the thread view (reply-count indicator) | + +For the view-slot methods (`render*View`), return a `ReactNode` to override the region, `null` to suppress it, or `undefined` to keep the built-in default. The full TypeScript interface and the `context` object reference are documented in [Creating a Custom Plugin](/ui-kit/react/plugins/custom-plugin). + +--- + +## How Plugin Resolution Works + +When the UI Kit needs to render a message, it asks the **Plugin Registry** to find the right plugin: + +1. If the message is deleted (`getDeletedAt() !== null`), the Delete plugin handles it +2. Otherwise, the registry finds the first plugin whose `messageTypes` includes the message's type AND whose `messageCategories` includes the message's category +3. First match wins — plugin order matters + +``` +Message { type: "image", category: "message" } + → Registry scans plugins in order + → CometChatImagePlugin matches (messageTypes: ["image"], messageCategories: ["message"]) + → ImagePlugin.renderBubble() is called +``` + +--- + +## Adding Plugins + +All default plugins are always included. To add your own custom plugins, pass them via the `plugins` prop on `CometChatProvider`. They are appended after the defaults, so default plugins keep priority for their message types: + +```tsx +import { CometChatProvider } from "@cometchat/chat-uikit-react"; +import { MyCustomPlugin } from "./plugins/MyCustomPlugin"; + +function App() { + return ( + + + + ); +} +``` + +--- + +## Built-in Plugins + +These plugins are included automatically — no configuration needed. Each routes its message type to a bubble component; follow the component link for the full rendering behavior, props, and CSS. + +| Plugin | Message type(s) | Category | What it renders | Component | +| --- | --- | --- | --- | --- | +| **Text** | `text` | `message` | Formatted text with @mentions, clickable URLs, and markdown | [Text Bubble](/ui-kit/react/components/text-bubble) | +| **Image** | `image` | `message` | Responsive image grid with captions and a fullscreen viewer | [Image Bubble](/ui-kit/react/components/image-bubble) | +| **Video** | `video` | `message` | Inline player (single) or thumbnail grid with play overlays (multiple) | [Video Bubble](/ui-kit/react/components/video-bubble) | +| **File** | `file` | `message` | File card with name, size, type icon, and download | [File Bubble](/ui-kit/react/components/file-bubble) | +| **Audio** | `audio` | `message` | Audio player with waveform, play/pause, duration, and download | [Audio Bubble](/ui-kit/react/components/audio-bubble) | +| **Polls** | `extension_poll` | `custom` | Interactive poll with voting and live results | [Poll Bubble](/ui-kit/react/components/poll-bubble) | +| **Stickers** | `extension_sticker` | `custom` | Sticker image extracted from the message metadata | [Sticker Bubble](/ui-kit/react/components/sticker-bubble) | +| **Collaborative Document** | `extension_document` | `custom` | Document card with an "Open Document" button | [Collaborative Document Bubble](/ui-kit/react/components/collaborative-document-bubble) | +| **Collaborative Whiteboard** | `extension_whiteboard` | `custom` | Whiteboard card with an "Open Whiteboard" button | [Collaborative Whiteboard Bubble](/ui-kit/react/components/collaborative-whiteboard-bubble) | +| **Group Action** | `groupMember` | `action` | Centered system messages (joined, left, kicked, banned, scope change) | [Group Action Bubble](/ui-kit/react/components/group-action-bubble) | +| **Call Action** | `audio` / `video` | `call` | Centered call status messages (missed, outgoing, incoming, ended) | [Call Action Bubble](/ui-kit/react/components/call-action-bubble) | +| **AI** | `assistant`, `toolArguments`, `toolResults`, `run_started` | `agentic`, `custom` | AI assistant responses, tool call arguments/results, and a streaming bubble | [AI Plugin ↓](#ai-plugin) | +| **Delete** | any (deleted) | any | "This message was deleted" placeholder | [Delete Bubble](/ui-kit/react/components/delete-bubble) | + +--- + +## AI Plugin + +The AI plugin handles messages in the `agentic` category. It renders completed assistant responses (with markdown), tool call arguments and results (as formatted JSON), and a streaming bubble while the AI is generating. It is **included by default** — no installation or `plugins` configuration is required. + + + +### Message Types + +| Type | Category | What it renders | +| --- | --- | --- | +| `assistant` | `agentic` | Completed AI response with markdown | +| `toolArguments` | `agentic` | Tool call arguments as formatted JSON | +| `toolResults` | `agentic` | Tool call results as formatted JSON | +| `run_started` | `custom` | Streaming placeholder while the AI generates | + +Bubble components: `CometChatAIAssistantBubble`, `CometChatStreamMessageBubble`, `CometChatToolCallArgumentBubble`, `CometChatToolCallResultBubble`. AI messages are system-generated and have no context menu. For the full chat experience, see [AI Assistant Chat](/ui-kit/react/components/ai-assistant-chat). + +### Conversation Preview + +| Type | Preview text | +| --- | --- | +| `assistant` | First 80 characters of the response (markdown stripped) | +| `toolArguments` | "Tool call" | +| `toolResults` | "Tool result" | + +### Preloading + +The AI Assistant Chat panel can be preloaded on hover/focus to reduce perceived latency: + +```tsx +import { preloadAIAssistantChat } from "@cometchat/chat-uikit-react"; + +// Call on AI button hover +onMouseEnter={() => preloadAIAssistantChat()} +``` diff --git a/ui-kit/react/v7/plugins/text-formatters.mdx b/ui-kit/react/plugins/text-formatters.mdx similarity index 74% rename from ui-kit/react/v7/plugins/text-formatters.mdx rename to ui-kit/react/plugins/text-formatters.mdx index 285328099..e908319ad 100644 --- a/ui-kit/react/v7/plugins/text-formatters.mdx +++ b/ui-kit/react/plugins/text-formatters.mdx @@ -1,27 +1,10 @@ --- title: "Text Formatters" -description: "Transform plain text into formatted HTML in message bubbles. Built-in formatters handle URLs, mentions, and markdown." +sidebarTitle: "Text Formatters" +description: "Transform plain text into formatted HTML in message bubbles, with built-in URL, mention, and markdown formatters plus custom formatters." --- - - -| Field | Value | -| --- | --- | -| Base Class | `CometChatTextFormatter` | -| Package | `@cometchat/chat-uikit-react` | -| Built-in Formatters | `CometChatMarkdownFormatter`, `CometChatMentionsFormatter`, `CometChatUrlFormatter` | -| Pipeline Order | Sorted by `priority` (lower = first) | -| Used By | Text plugin (`getTextFormatters()`), media plugins (caption rendering) | - - - -## Overview - -Text formatters detect patterns in message text and transform them into formatted HTML for display in bubbles. They run as a pipeline — each formatter receives the output of the previous one, sorted by priority (lower number = runs first). - -The Text plugin provides three built-in formatters. You can add custom formatters to extend the pipeline. - ---- +Text formatters detect patterns in message text and transform them into formatted HTML for display in bubbles. They run as a pipeline — each formatter receives the output of the previous one, sorted by priority (lower number = runs first). The Text plugin provides three built-in formatters, and you can add your own. ## Built-in Formatters @@ -31,8 +14,6 @@ The Text plugin provides three built-in formatters. You can add custom formatter | `CometChatMentionsFormatter` | 50 | `<@uid:xxx>` tokens | Styled `@DisplayName` chips | | `CometChatUrlFormatter` | 100 | `https://...`, `www.` | Clickable `` links | -### Pipeline Flow - ``` Raw text: "Hey **@Alice**, check https://example.com" ↓ MarkdownFormatter (priority 10) @@ -43,8 +24,6 @@ Raw text: "Hey **@Alice**, check https://example.com" "Hey @Alice, check https://example.com" ``` ---- - ## The Formatter Interface All formatters extend the abstract `CometChatTextFormatter` class: @@ -71,8 +50,6 @@ abstract class CometChatTextFormatter { } ``` ---- - ## Creating a Custom Formatter Here's a hashtag formatter that wraps `#word` patterns in a styled span: @@ -122,18 +99,18 @@ export class HashtagFormatter extends CometChatTextFormatter { } ``` ---- - ## Registering Custom Formatters -Custom formatters are registered by creating a custom text plugin that extends the default one: +Custom formatters are registered by creating a custom text plugin that provides them: ```typescript title="src/plugins/CustomTextPlugin.ts" import { CometChatTextPlugin } from "@cometchat/chat-uikit-react"; import type { CometChatTextFormatter } from "@cometchat/chat-uikit-react"; -import { CometChatMarkdownFormatter } from "@cometchat/chat-uikit-react"; -import { CometChatMentionsFormatter } from "@cometchat/chat-uikit-react"; -import { CometChatUrlFormatter } from "@cometchat/chat-uikit-react"; +import { + CometChatMarkdownFormatter, + CometChatMentionsFormatter, + CometChatUrlFormatter, +} from "@cometchat/chat-uikit-react"; import { HashtagFormatter } from "../formatters/HashtagFormatter"; export const CustomTextPlugin = { @@ -151,31 +128,18 @@ export const CustomTextPlugin = { }; ``` -Then use it in your provider with a custom plugin array (replacing the default text plugin): +Then pass it in your provider's `plugins` prop: ```tsx -import { CometChatProvider, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; -import { defaultPlugins } from "@cometchat/chat-uikit-react"; +import { CometChatProvider } from "@cometchat/chat-uikit-react"; import { CustomTextPlugin } from "./plugins/CustomTextPlugin"; -// Replace the default text plugin with our custom one -const plugins = defaultPlugins.map(p => - p.id === "text" ? CustomTextPlugin : p -); - -const settings = new UIKitSettingsBuilder() - .setAppId("YOUR_APP_ID") - .setRegion("us") - .setAuthKey("YOUR_AUTH_KEY") - .setPlugins(plugins) - .build(); - - + ``` ---- +Since user plugins are prepended before the defaults in the registry, your custom text plugin takes precedence over the built-in one (first match wins) ## Formatter Details @@ -183,7 +147,6 @@ const settings = new UIKitSettingsBuilder() Converts markdown syntax to HTML. Runs first (priority 10) so subsequent formatters operate on HTML output. -**Supported syntax:** - `**bold**` → `bold` - `_italic_` → `italic` - `__underline__` or `++underline++` → `underline` @@ -192,23 +155,20 @@ Converts markdown syntax to HTML. Runs first (priority 10) so subsequent formatt - ` ```code block``` ` → `
code block
` - `> blockquote` → `
blockquote
` - `[text](url)` → `text` -- `1. item` → ordered list -- `• item` or `- item` → unordered list +- `1. item` → ordered list; `• item` / `- item` → unordered list ### CometChatMentionsFormatter -Resolves SDK mention tokens (`<@uid:xxx>` and `<@all:label>`) into styled mention chips. Requires the mentioned users list from the message to resolve UIDs to display names. +Resolves SDK mention tokens (`<@uid:xxx>` and `<@all:label>`) into styled mention chips. Requires the mentioned-users list from the message to resolve UIDs to display names. ### CometChatUrlFormatter Detects bare URLs (`https://...` and `www.`) and wraps them in clickable `` tags with `target="_blank"` and `rel="noopener noreferrer"`. Protects existing markdown links and `` tags from double-processing. ---- - ## Tips - **Priority matters** — markdown must run before mentions/URLs so it doesn't break HTML tags - **Protect code blocks** — formatters should skip content inside `` and `
` tags
-- **Keep it fast** — formatters run on every text message render, avoid expensive operations
-- **Use `shouldFormat()`** — override to skip formatting for specific messages (e.g., skip hashtags in system messages)
+- **Keep it fast** — formatters run on every text message render; avoid expensive operations
+- **Use `shouldFormat()`** — override to skip formatting for specific messages
 - **Store metadata** — use `this.metadata` to expose extracted data (URLs, hashtags, mentions) to consumers
diff --git a/ui-kit/react/react-conversation.mdx b/ui-kit/react/react-conversation.mdx
index 7302e81a6..e4f13a2e3 100644
--- a/ui-kit/react/react-conversation.mdx
+++ b/ui-kit/react/react-conversation.mdx
@@ -1,7 +1,7 @@
 ---
 title: "Conversation List + Message View"
 sidebarTitle: "Conversation List + Message View"
-description: "Build CometChat React UI Kit conversation list and message view layouts with navigation, headers, message lists, and composers."
+description: "Build a two-panel conversation list + message view layout in React.js with CometChat UI Kit."
 ---
 
 
@@ -12,22 +12,19 @@ description: "Build CometChat React UI Kit conversation list and message view la
 | Framework | React.js |
 | Components | `CometChatConversations`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` |
 | Layout | Two-panel — conversation list (left) + message view (right) |
-| Prerequisite | Complete [React.js Integration](/ui-kit/react/react-js-integration) Steps 1–5 first |
+| Prerequisite | Complete [React.js Integration](/ui-kit/react/integration-react) first |
 | Pattern | WhatsApp Web, Slack, Microsoft Teams |
 
 
 
-This guide builds a two-panel chat layout — conversation list on the left, messages on the right. Users tap a conversation to open it.
+This guide builds a two-panel chat layout — conversation list on the left, messages on the right. Users click a conversation to open it.
 
-This assumes you've already completed [React.js Integration](/ui-kit/react/react-js-integration) (project created, UI Kit installed, init + login working, CSS imported).
+This assumes you've already completed [React.js Integration](/ui-kit/react/integration-react) (project created, UI Kit installed, init + login working).
 
 
-  
+  
 
 
-[](https://link.cometchat.com/react-conversation-list-message)
-
-> Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time.
 
 ---
 
@@ -41,366 +38,132 @@ Three sections working together:
 
 ---
 
-## Step 1 — Create the Sidebar Component
-
-Create a `CometChatSelector` folder inside `src/`:
-
-
-  
-    
-      
-      
-    
-  
-
-
-
-
-
-```tsx title="CometChatSelector.tsx" lines
-import { useEffect, useState } from "react";
-import {
-  Conversation,
-  Group,
-  User,
-  CometChat,
-} from "@cometchat/chat-sdk-javascript";
-import {
-  CometChatConversations,
-  CometChatUIKitLoginListener,
-} from "@cometchat/chat-uikit-react";
-import "./CometChatSelector.css";
-
-interface SelectorProps {
-  onSelectorItemClicked?: (
-    input: User | Group | Conversation,
-    type: string
-  ) => void;
-}
-
-export const CometChatSelector = (props: SelectorProps) => {
-  const { onSelectorItemClicked = () => {} } = props;
-  const [loggedInUser, setLoggedInUser] = useState();
-  const [activeItem, setActiveItem] = useState<
-    CometChat.Conversation | CometChat.User | CometChat.Group | undefined
-  >();
-
-  useEffect(() => {
-    const user = CometChatUIKitLoginListener.getLoggedInUser();
-    setLoggedInUser(user);
-  }, []);
-
-  return (
-    <>
-      {loggedInUser && (
-         {
-            setActiveItem(e);
-            onSelectorItemClicked(e, "updateSelectedItem");
-          }}
-        />
-      )}
-    
-  );
-};
-```
-
-
-
-
-```css title="CometChatSelector.css" lines
-/* Menu icon in conversation header */
-.selector-wrapper .cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon {
-  background: var(--cometchat-icon-color-primary);
-}
-
-.cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon:hover {
-  background: var(--cometchat-icon-color-highlight);
-}
-
-.cometchat-list__header-search-bar {
-  border-right: none;
-}
-
-.cometchat .cometchat-menu-list__sub-menu-list-item {
-  text-align: left;
-}
-
-.cometchat .cometchat-conversations .cometchat-menu-list__sub-menu-list {
-  width: 212px;
-  top: 40px !important;
-  left: 172px !important;
-}
-
-/* Logged-in user section */
-#logged-in-user {
-  border-bottom: 2px solid var(--cometchat-border-color-default, #E8E8E8);
-}
-
-#logged-in-user .cometchat-menu-list__sub-menu-item-title,
-#logged-in-user .cometchat-menu-list__sub-menu-list-item {
-  cursor: default;
-}
-
-.cometchat-menu-list__sub-menu-list-item-icon-log-out {
-  background-color: var(--cometchat-error-color, #F44649);
-}
-
-.cometchat-menu-list__sub-menu-item-title-log-out {
-  color: var(--cometchat-error-color, #F44649);
-}
-
-.chat-menu .cometchat .cometchat-menu-list__sub-menu-item-title {
-  cursor: pointer;
-}
-
-.chat-menu .cometchat .cometchat-menu-list__sub-menu {
-  box-shadow: none;
-}
-
-.chat-menu .cometchat .cometchat-menu-list__sub-menu-icon {
-  background-color: var(--cometchat-icon-color-primary, #141414);
-  width: 24px;
-  height: 24px;
-}
-
-/* Selector container */
-.cometchat-selector {
-  display: flex;
-  width: 100%;
-  padding: 0px 8px;
-  align-items: flex-start;
-  gap: 8px;
-  border-top: 1px solid var(--cometchat-border-color-light, #F5F5F5);
-  border-right: 1px solid var(--cometchat-border-color-light, #F5F5F5);
-  background: var(--cometchat-background-color-01, #FFF);
-}
-
-.cometchat-selector__tab {
-  display: flex;
-  padding: 12px 0px 10px 0px;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-  gap: 4px;
-  flex: 1 0 0;
-  min-height: 48px;
-}
-
-.cometchat-selector__tab-icon-active {
-  display: flex;
-  width: 32px;
-  height: 32px;
-  justify-content: center;
-  align-items: center;
-  -webkit-mask-size: contain;
-  mask-size: contain;
-  cursor: default;
-  background: var(--cometchat-icon-color-highlight);
-  -webkit-mask: url('./assets/chats.svg') no-repeat center;
-  mask: url('./assets/chats.svg') no-repeat center;
-}
-
-.cometchat-selector__tab-text-active {
-  text-align: center;
-  font: var(--cometchat-font-caption1-medium, 500 12px Roboto);
-  cursor: default;
-  color: var(--cometchat-text-color-highlight);
-}
-```
-
-
-
-
-Key points about the sidebar:
-- `CometChatUIKitLoginListener.getLoggedInUser()` checks for an active session — the component only renders if a user is logged in.
-- `activeConversation` highlights the currently selected conversation in the list.
-- `onItemClick` fires when a user taps a conversation, passing the `Conversation` object to the parent.
-
----
-
-## Step 2 — Update App.tsx and App.css
+## Full Code
 
-Wire the sidebar and message components together in your main app file.
+Replace your `src/App.tsx` with the following. Init and login must complete before the provider mounts — see the [React.js Integration](/ui-kit/react/integration-react) guide for the `src/main.tsx` setup.
 
-
-
-
-```tsx title="App.tsx" lines
+```tsx title="src/App.tsx"
 import { useState } from "react";
+import { CometChat } from "@cometchat/chat-sdk-javascript";
 import {
-  CometChatMessageComposer,
+  CometChatProvider,
+  CometChatConversations,
   CometChatMessageHeader,
   CometChatMessageList,
+  CometChatMessageComposer,
 } from "@cometchat/chat-uikit-react";
-import { CometChat } from "@cometchat/chat-sdk-javascript";
-import { CometChatSelector } from "./CometChatSelector/CometChatSelector";
 import "./App.css";
-import "@cometchat/chat-uikit-react/css-variables.css";
 
 function App() {
-  const [selectedUser, setSelectedUser] = useState<
-    CometChat.User | undefined
-  >(undefined);
-  const [selectedGroup, setSelectedGroup] = useState<
-    CometChat.Group | undefined
-  >(undefined);
+  const [selectedUser, setSelectedUser] = useState(undefined);
+  const [selectedGroup, setSelectedGroup] = useState(undefined);
+
+  const handleConversationClick = (conversation: CometChat.Conversation) => {
+    const entity = conversation.getConversationWith();
+    if (conversation.getConversationType() === "user") {
+      setSelectedUser(entity as CometChat.User);
+      setSelectedGroup(undefined);
+    } else {
+      setSelectedGroup(entity as CometChat.Group);
+      setSelectedUser(undefined);
+    }
+  };
 
   return (
-    
- {/* Sidebar — conversation list */} -
- { - let item = activeItem; - - // Extract user/group from Conversation object - if (activeItem instanceof CometChat.Conversation) { - item = activeItem.getConversationWith(); - } - - if (item instanceof CometChat.User) { - setSelectedUser(item as CometChat.User); - setSelectedGroup(undefined); - } else if (item instanceof CometChat.Group) { - setSelectedUser(undefined); - setSelectedGroup(item as CometChat.Group); - } else { - setSelectedUser(undefined); - setSelectedGroup(undefined); - } - }} - /> -
- - {/* Message view — header + messages + composer */} - {selectedUser || selectedGroup ? ( -
- - - -
- ) : ( -
- Select a conversation to start chatting + +
+
+
- )} -
+ + {selectedUser || selectedGroup ? ( +
+ + + +
+ ) : ( +
+ Select a conversation to start chatting +
+ )} +
+ ); } export default App; ``` - - - -```css title="App.css" lines -@import url("@cometchat/chat-uikit-react/css-variables.css"); - -#root { - text-align: center; - width: 100vw; - height: 100vh; - background-color: #282c34; -} - -/* Two-panel layout */ +```css title="src/App.css" .conversations-with-messages { display: flex; - height: 100%; + height: 100vh; width: 100%; - flex-direction: row; } -/* Left panel — conversation list */ .conversations-wrapper { - height: 100vh; - width: 480px; + width: 360px; + height: 100%; + border-right: 1px solid #eee; overflow: hidden; display: flex; flex-direction: column; } -.conversations-wrapper > .cometchat { - overflow: hidden; -} - -/* Right panel — messages */ .messages-wrapper { - width: 100%; + flex: 1; height: 100%; display: flex; flex-direction: column; } -/* Empty state */ .empty-conversation { - height: 100vh; - width: 100%; + flex: 1; display: flex; justify-content: center; align-items: center; - background: var(--cometchat-background-color-03, #F5F5F5); + background: var(--cometchat-background-color-03, #f5f5f5); color: var(--cometchat-text-color-secondary, #727272); font: var(--cometchat-font-body-regular, 400 14px Roboto); } - -.cometchat .cometchat-message-composer { - border-radius: 0px; -} ``` - - +--- + +## How It Works -How it works: -- When a conversation is tapped, `onSelectorItemClicked` extracts the `User` or `Group` from the `Conversation` object. -- `selectedUser` / `selectedGroup` state drives which chat is displayed — pass either `user` or `group` to the message components, never both. -- The empty state shows until a conversation is selected. +1. **CometChatProvider** wraps the entire tree — it supplies theme, locale, and event context to all CometChat components. +2. **CometChatConversations** renders the sidebar list. When a user clicks a conversation, `onItemClick` fires with the `Conversation` object. +3. **handleConversationClick** extracts the `User` or `Group` from the conversation and stores it in state. +4. **Message components** (`MessageHeader`, `MessageList`, `MessageComposer`) receive either `user` or `group` as a prop — never both at the same time. +5. When the user switches conversations, state updates and the message panel re-renders with the new chat. --- -## Step 3 — Run the Project +## Run - - -```bash lines +```bash npm run dev ``` - - -```bash lines -npm start -``` - - -You should see the conversation list on the left. Tap any conversation to load messages on the right. +Open `http://localhost:5173`. You should see the conversation list on the left. Click any conversation to load messages on the right. --- ## Next Steps - - Customize colors, fonts, and styles to match your brand + + Single chat window without a sidebar + + + Tabbed navigation with Chats, Calls, Users Browse all prebuilt UI components - - Back to the main setup guide - - - Chat features included out of the box + + Customize colors, fonts, and styles diff --git a/ui-kit/react/react-js-integration.mdx b/ui-kit/react/react-js-integration.mdx deleted file mode 100644 index e01ac0648..000000000 --- a/ui-kit/react/react-js-integration.mdx +++ /dev/null @@ -1,391 +0,0 @@ ---- -title: "React.js Integration" -sidebarTitle: "Integration" -description: "Integrate CometChat React UI Kit with React.js using app credentials, package setup, initialization, login, and chat rendering." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Peer deps | `react` >=18, `react-dom` >=18, `rxjs` ^7.8.1 | -| Init | `CometChatUIKit.init(UIKitSettings)` — must resolve before `login()` | -| Login | `CometChatUIKit.login("UID")` — must resolve before rendering components | -| Order | `init()` → `login()` → render. Breaking this order = blank screen | -| Auth Key | Dev/testing only. Use Auth Token in production | -| CSS | `@import url("@cometchat/chat-uikit-react/css-variables.css");` in global CSS | -| Calling | Optional. Install `@cometchat/calls-sdk-javascript` to enable | -| Other frameworks | [Next.js](/ui-kit/react/next-js-integration) · [React Router](/ui-kit/react/react-router-integration) · [Astro](/ui-kit/react/astro-integration) | -| AI Skills | `npx @cometchat/skills add` — [GitHub](https://github.com/cometchat/cometchat-skills) | - - - -This guide walks you through adding CometChat to a React.js app. By the end you'll have a working chat UI. - - - - - ---- - -## Integrate with AI Coding Agents - -Skip the manual steps — use [CometChat Skills](https://github.com/cometchat/cometchat-skills) to integrate via your AI coding agent. Your agent has a short conversation with you to understand your project and chat requirements, then writes production-grade integration code tailored to the files you already have. - -```bash -npx @cometchat/skills add -``` - -Use `--ide ` to target a specific IDE (e.g. `--ide cursor`), or `--ide all` for all supported IDEs. - -Then in your IDE: - -``` -/cometchat add chat to my app -``` - -The skill detects your bundler (Vite or CRA), env prefix (`VITE_` or `REACT_APP_`), router, and existing auth system. It onboards you to CometChat directly in the terminal — signup, login, and app creation all via the CLI. It reads your routes, nav, and components before proposing a placement, shows the plan, and waits for your approval before writing code. - -After the first integration, re-run `/cometchat` to access the iteration menu: theme presets, 40+ features, component customization, floating widget, production auth, user management, and diagnostics. - -Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and [30+ more agents](https://github.com/cometchat/cometchat-skills). - ---- - -## Prerequisites - -You need three things from the [CometChat Dashboard](https://app.cometchat.com/): - -| Credential | Where to find it | -| --- | --- | -| App ID | Dashboard → Your App → Credentials | -| Auth Key | Dashboard → Your App → Credentials | -| Region | Dashboard → Your App → Credentials (e.g. `us`, `eu`, `in`) | - -You also need Node.js (v16+) and npm/yarn installed. - - -Auth Key is for development only. In production, generate Auth Tokens server-side via the [REST API](/rest-api/chat-apis) and use [`loginWithAuthToken()`](/ui-kit/react/methods#login-using-auth-token). Never ship Auth Keys in client code. - - ---- - -## Step 1 — Create a React Project - - - -```bash lines -npm create vite@latest my-app -- --template react-ts -cd my-app -``` - - -```bash lines -npx create-react-app my-app --template typescript -cd my-app -``` - - - ---- - -## Step 2 — Install the UI Kit - - - -```bash lines -npm install @cometchat/chat-uikit-react -``` - - -```bash lines -yarn add @cometchat/chat-uikit-react -``` - - - -This installs the UI Kit and its dependency `@cometchat/chat-sdk-javascript` automatically. - -If you want voice/video calling, also install: - -```bash lines -npm install @cometchat/calls-sdk-javascript -``` - ---- - -## Step 3 — Initialize CometChat - -Create a constants file and initialize the UI Kit before anything else. - -```ts title="src/AppConstants.ts" lines -export const COMETCHAT_CONSTANTS = { - APP_ID: "APP_ID", // Replace with your App ID - REGION: "REGION", // Replace with your Region - AUTH_KEY: "AUTH_KEY", // Replace with your Auth Key (dev only) -}; -``` - - - -```ts lines highlight={7-9} -import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; - -/** - * CometChat Constants - Replace with your actual credentials - */ -const COMETCHAT_CONSTANTS = { - APP_ID: "APP_ID", // Replace with your actual App ID from CometChat - REGION: "REGION", // Replace with your App's Region - AUTH_KEY: "AUTH_KEY", // Replace with your Auth Key (leave blank if using Auth Token) -}; - -const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) - .subscribePresenceForAllUsers() - .build(); - -CometChatUIKit.init(UIKitSettings) - .then(() => { - console.log("CometChat UI Kit initialized successfully."); - }) - .catch((error) => { - console.error("CometChat UI Kit initialization failed:", error); - }); -``` - - -```js lines highlight={7-9} -import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; - -/** - * CometChat Constants - Replace with your actual credentials - */ -const COMETCHAT_CONSTANTS = { - APP_ID: "APP_ID", // Replace with your actual App ID from CometChat - REGION: "REGION", // Replace with your App's Region - AUTH_KEY: "AUTH_KEY", // Replace with your Auth Key (leave blank if using Auth Token) -}; - -const UIKitSettings = new UIKitSettingsBuilder() - .setAppId(COMETCHAT_CONSTANTS.APP_ID) - .setRegion(COMETCHAT_CONSTANTS.REGION) - .setAuthKey(COMETCHAT_CONSTANTS.AUTH_KEY) - .subscribePresenceForAllUsers() - .build(); - -CometChatUIKit.init(UIKitSettings) - .then(() => { - console.log("CometChat UI Kit initialized successfully."); - }) - .catch((error) => { - console.error("CometChat UI Kit initialization failed:", error); - }); -``` - - - - -`init()` must resolve before you call `login()`. If you call `login()` before init completes, it will fail silently. - - - -By default, session data is stored in `localStorage`. To use `sessionStorage` instead, see [Setting Session Storage Mode](/ui-kit/react/methods#setting-session-storage-mode). - - ---- - -## Step 4 — Login - -After init resolves, log the user in. For development, use one of the pre-created test UIDs: - -`cometchat-uid-1` · `cometchat-uid-2` · `cometchat-uid-3` · `cometchat-uid-4` · `cometchat-uid-5` - - - -```ts lines highlight={3} -import { CometChatUIKit } from "@cometchat/chat-uikit-react"; - -const UID = "UID"; // Replace with your actual UID - -CometChatUIKit.getLoggedinUser().then((user: CometChat.User | null) => { - if (!user) { - CometChatUIKit.login(UID) - .then((user: CometChat.User) => { - console.log("Login Successful:", { user }); - // Mount your app - }) - .catch(console.log); - } else { - // Already logged in — mount your app - } -}); -``` - - -```js lines highlight={3} -import { CometChatUIKit } from "@cometchat/chat-uikit-react"; - -const UID = "UID"; // Replace with your actual UID - -CometChatUIKit.getLoggedinUser().then((user) => { - if (!user) { - CometChatUIKit.login(UID) - .then((user) => { - console.log("Login Successful:", { user }); - // Mount your app - }) - .catch(console.log); - } else { - // Already logged in — mount your app - } -}); -``` - - - -Key points: -- `getLoggedinUser()` checks for an existing session so you don't re-login unnecessarily. -- `login(uid)` skips the API call if a session already exists and returns the cached user. -- Components must not render until login resolves — use a state flag to gate rendering. - - -For production, use [`loginWithAuthToken()`](/ui-kit/react/methods#login-using-auth-token) instead of Auth Key. Generate tokens server-side via the REST API. - - ---- - -## Step 5 — Add the CSS Import - -Add this line at the top of your global CSS file (e.g. `src/App.css` or `src/index.css`): - -```css title="src/App.css" lines -@import url("@cometchat/chat-uikit-react/css-variables.css"); -``` - -Without this import, components will render with broken or missing styles. - ---- - -## Step 6 — Choose a Chat Experience - -Integrate a conversation view that suits your app's UX. Each option below includes a live CodeSandbox demo and a step-by-step guide. - -### Conversation List + Message View - -Two-panel layout — conversation list on the left, messages on the right. Think WhatsApp Web or Slack. - -- Two-panel layout with conversation list and active chat window -- Switch between one-to-one and group conversations -- Tap-to-view on mobile — tapping a conversation opens the message view -- Real-time updates and message sync across sessions - - - - - -[](https://link.cometchat.com/react-conversation-list-message) - -> **Tip:** Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. - - - Step-by-step guide to build this layout - - ---- - -### One-to-One / Group Chat - -Single chat window — no sidebar. Good for support chat, embedded widgets, or focused messaging. - -- Dedicated chat window for one-on-one or group messaging -- No conversation list — users go directly into the chat -- Full-screen experience optimized for mobile -- Ideal for support chat or community messaging - - - - - -[](https://link.cometchat.com/react-one-on-one) - -> **Tip:** Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. - - - Step-by-step guide to build this layout - - ---- - -### Tab-Based Chat - -Tabbed navigation — Chat, Call Logs, Users, Settings in separate tabs. Good for full-featured apps. - -- Tab navigation between Chat, Call Logs, Users, and Settings -- Full-screen messaging within each tab -- Unified experience for conversations, call history, and settings -- Scales well for adding future features like notifications or contacts - - - - - -[](https://link.cometchat.com/react-tabs-sidebar-message) - -> **Tip:** Fork the sandbox, insert your CometChat credentials (App ID, Region, Auth Key), and preview the UI in real time. - - - Step-by-step guide to build this layout - - ---- - -## Build Your Own Chat Experience - -Need full control over the UI? Use individual components, customize themes, and wire up your own layouts. - -- [Sample App](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app) — Working reference app to compare against -- [Components](/ui-kit/react/components-overview) — All prebuilt UI elements with props and customization options -- [Core Features](/ui-kit/react/core-features) — Messaging, real-time updates, and other capabilities -- [Theming](/ui-kit/react/theme) — Colors, fonts, dark mode, and custom styling -- [Build Your Own UI](/sdk/javascript/overview) — Skip the UI Kit entirely and build on the raw SDK - ---- - -## iFrame Embedding - -If your React app runs inside an ` - -```tsx lines -import { CometChatMessageBubble } from "@cometchat/chat-uikit-react"; -import { CometChatTextBubble } from "@cometchat/chat-uikit-react/plugins/core/text"; - -function MessageItem({ message, alignment }) { - return ( - - } - /> - ); -} -``` - -## Shared Chrome Elements - -| Element | When Shown | Source | -| --- | --- | --- | -| Avatar | Incoming + group + `!hideAvatar` | `message.getSender().getAvatar()` | -| Sender name | Incoming + group + `!hideSenderName` | `message.getSender().getName()` | -| Bubble background | Always | Type-specific: primary for outgoing, neutral for incoming | -| Timestamp | `!hideTimestamp` | `message.getSentAt()` via `CometChatDate` | -| Receipts | Outgoing + `!hideReceipts` | `message.getReadAt()` / `getDeliveredAt()` | -| Edited indicator | `message.getEditedAt()` truthy | "(edited)" text | -| Thread replies | `message.getReplyCount() > 0` + `!hideThreadView` | Reply count button | -| Context menu | `options.length > 0` + `!disableInteraction` | Hover/click | - -## GlobalConfig Integration - -`hideReceipts` reads from `GlobalConfigContext` when the prop is not explicitly set: - -```tsx lines - - {/* All bubbles hide receipts unless overridden */} - {/* This one shows receipts */} - -``` - -## Props - -### message - -The SDK message object. **Required.** - -| | | -| --- | --- | -| Type | `CometChat.BaseMessage` | - ---- - -### alignment - -Bubble alignment: `'left'` (incoming), `'right'` (outgoing), `'center'` (action). - -| | | -| --- | --- | -| Type | `'left' \| 'right' \| 'center'` | - ---- - -### contentView - -The inner content from the plugin's `renderBubble()`. **Required.** - -| | | -| --- | --- | -| Type | `ReactNode` | - ---- - -### group - -Group context. Enables avatar and sender name display. - -| | | -| --- | --- | -| Type | `CometChat.Group` | -| Default | `undefined` | - ---- - -### hideAvatar / hideSenderName / hideTimestamp / hideThreadView - -Per-bubble display controls. Not in GlobalConfig. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### hideReceipts - -Hide receipt indicators. Reads from GlobalConfig if not set. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `undefined` (falls back to GlobalConfig, then `false`) | - ---- - -### showError - -Show error receipt icon instead of normal receipts. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - ---- - -### disableInteraction - -Disable hover options and keyboard interactions. - -| | | -| --- | --- | -| Type | `boolean` | -| Default | `false` | - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Wrapper | `.cometchat-message-bubble__wrapper` | -| Outgoing wrapper | `.cometchat-message-bubble__wrapper--outgoing` | -| Avatar area | `.cometchat-message-bubble__leading-view` | -| Bubble container | `.cometchat-message-bubble` | -| Incoming | `.cometchat-message-bubble-incoming` | -| Outgoing | `.cometchat-message-bubble-outgoing` | -| Action (center) | `.cometchat-message-bubble-action` | -| Sender name | `.cometchat-message-bubble__sender-name` | -| Body | `.cometchat-message-bubble__body` | -| Content | `.cometchat-message-bubble__body-content-view` | -| Status info | `.cometchat-message-bubble__body-status-info-view` | -| Receipts | `.cometchat-receipts` | -| Thread button | `.cometchat-message-bubble__thread-button` | diff --git a/ui-kit/react/v7/core-features.mdx b/ui-kit/react/v7/core-features.mdx deleted file mode 100644 index 04a67490b..000000000 --- a/ui-kit/react/v7/core-features.mdx +++ /dev/null @@ -1,244 +0,0 @@ ---- -title: "Core" -description: "Overview of CometChat React UI Kit core features, including messaging, media sharing, receipts, presence, reactions, search, and moderation." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Required setup | Wrap app in `CometChatProvider` with valid credentials — must complete before rendering any component | -| Core features | Instant Messaging, Media Sharing, Read Receipts, Mark as Unread, Typing Indicator, User Presence, Reactions, Mentions, Quoted Reply, Search, Threaded Conversations, Moderation, Report Message, Group Chat | -| Key components | `CometChatConversations` → [Conversations](/ui-kit/react/v7/components/conversations), `CometChatMessageList` → [Message List](/ui-kit/react/v7/components/message-list), `CometChatMessageComposer` → [Message Composer](/ui-kit/react/v7/components/message-composer), `CometChatMessageHeader` → [Message Header](/ui-kit/react/v7/components/message-header), `CometChatUsers` → [Users](/ui-kit/react/v7/components/users), `CometChatGroups` → [Groups](/ui-kit/react/v7/components/groups), `CometChatGroupMembers` → [Group Members](/ui-kit/react/v7/components/group-members) | -| CSS class prefix | `.cometchat-` | -| Theming | Override CSS variables on `.cometchat` class. See [Theming](/ui-kit/react/v7/theming) | - - - -The UI Kit components work together to deliver a complete chat experience. The sections below map each core feature to the components that power it. - -## Instant Messaging - -At the heart of CometChat's functionality is the ability to support real-time text messaging. Users can send and receive instant messages, fostering quick and efficient communication. - - - - - -| Components | Functionality | -| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [Message Composer](/ui-kit/react/v7/components/message-composer) | The [Message Composer](/ui-kit/react/v7/components/message-composer) is a Component that enables users to write and send a variety of messages. | -| [Message List](/ui-kit/react/v7/components/message-list) | The [Message List](/ui-kit/react/v7/components/message-list) is a Component that renders a list of messages sent and messages received using Text Bubble. | - -## Media Sharing - -CometChat supports sharing images, videos, audio files, and documents within conversations. - - - - - -| Components | Functionality | -| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message Composer](/ui-kit/react/v7/components/message-composer) | The [Message Composer](/ui-kit/react/v7/components/message-composer) component includes an ActionSheet. This ActionSheet serves as a menu appearing over the app's context, offering various options for sharing media files. | -| [Message List](/ui-kit/react/v7/components/message-list) | The [Message List](/ui-kit/react/v7/components/message-list) component is responsible for rendering various Media Message bubbles, such as Image, File, Audio & Video Bubble. | - -## Read Receipts - -CometChat's Read Receipts feature provides visibility into the message status, letting users know when a message has been delivered and read. This brings clarity to the communication and ensures users are informed about the status of their messages. - - - - - -| Components | Functionality | -| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [Conversations](/ui-kit/react/v7/components/conversations) | [Conversations](/ui-kit/react/v7/components/conversations) is a component that renders conversation list item. Conversation item also displays the delivery status of the last message providing users with real-time updates on the status of their messages. | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) is a component that renders different types of message bubbles. Read receipt status is an integral part of all message bubbles, no matter the type and provides real-time updates about the status of the message. | -| Message Information | Message Information component provides transparency into the status of each sent message, giving the sender insights into whether their message has been delivered and read. | - -## Mark as Unread - - Mark as Unread feature allows users to manually mark messages as unread, helping them keep track of important conversations they want to revisit later. When enabled, the message list can automatically start from the first unread message, making it easier to pick up where you left off. - - - - - -| Components | Functionality | -| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) provides the "Mark as unread" option in message actions and supports starting from the first unread message when enabled. | -| [Conversations](/ui-kit/react/v7/components/conversations) | [Conversations](/ui-kit/react/v7/components/conversations) component listens to conversation updates and reflects the updated unread count in real-time. | - -## Typing Indicator - -The Typing Indicator feature in CometChat shows when a user is typing a response in real-time, fostering a more interactive and engaging chat environment. This feature enhances the real-time communication experience, making conversations feel more natural and fluid. - - - - - -| Components | Functionality | -| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Conversations](/ui-kit/react/v7/components/conversations) | [Conversations](/ui-kit/react/v7/components/conversations) is a component that renders conversation list item. Conversations item also shows real-time typing status indicators. This means that if a user in a one-on-one chat or a participant in a group chat is currently typing a message. | -| [Message Header](/ui-kit/react/v7/components/message-header) | [Message Header](/ui-kit/react/v7/components/message-header) that renders details of User or Groups in ToolBar. The Message Header also handles the typing indicator functionality. When a user or a member in a group is typing, the Message Header dynamically updates to display a `typing...` status in real-time. | - -## User Presence - -CometChat's User Presence feature allows users to see whether their contacts are online, offline. This helps users know the best time to initiate a conversation and sets expectations about response times. - - - - - -| Components | Functionality | -| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Conversations](/ui-kit/react/v7/components/conversations) | [Conversations](/ui-kit/react/v7/components/conversations) is a component that renders conversation list item. Conversations item also shows user presence information. | -| [Message Header](/ui-kit/react/v7/components/message-header) | [Message Header](/ui-kit/react/v7/components/message-header) that renders details of user/group. The Message Header also handles user presence information. | -| [Users](/ui-kit/react/v7/components/users) | [Users](/ui-kit/react/v7/components/users) renders the list of available users with presence information. | -| [Group Members](/ui-kit/react/v7/components/group-members) | [Group Members](/ui-kit/react/v7/components/group-members) renders list of users available in the group. The Group Members component also handles user presence information. | - -## Reactions - -CometChat's Reactions feature adds a layer of expressiveness to your chat application by allowing users to react to messages. With reactions, users can convey a range of emotions or express their thoughts on a particular message without typing out a full response, enhancing their user experience and fostering greater engagement. - - - - - -| Components | Functionality | -| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) is a component that renders different types of message bubbles. Reactions are an integral part and offer a more engaging, expressive way for users to respond to messages. | - -## Mentions - -Mentions is a robust feature provided by CometChat that enhances the interactivity and clarity of group or 1-1 chats by allowing users to directly address or refer to specific individuals in a conversation. The feature also supports group mentions like @all, enabling users to quickly notify all members in a group chat simultaneously. - - - - - -| Components | Functionality | -| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Conversations](/ui-kit/react/v7/components/conversations) | [Conversations](/ui-kit/react/v7/components/conversations) component provides an enhanced user experience by integrating the Mentions feature. This means that from the conversation list itself, users can see where they or someone else have been specifically mentioned. | -| [Message Composer](/ui-kit/react/v7/components/message-composer) | [Message Composer](/ui-kit/react/v7/components/message-composer) is a component that allows users to craft and send various types of messages, including the usage of the mentions feature for direct addressing within the conversation. | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) is a component that displays a list of sent and received messages. It also supports the rendering of Mentions, enhancing the readability and interactivity of conversations. | - -## Rich Text Formatting - -Rich Text Formatting allows users to style their messages with bold, italic, underline, strikethrough, code, links, lists, and blockquotes. This brings richer expression to conversations and helps users emphasize key points, making communication clearer and more engaging. - - - - - -| Components | Functionality | -| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message Composer](/ui-kit/react/v7/components/message-composer) | [Message Composer](/ui-kit/react/v7/components/message-composer) with `enableRichTextEditor` provides a built-in rich text editor with formatting toolbar, floating selection toolbar, and keyboard shortcuts for bold, italic, underline, strikethrough, code, links, lists, and blockquotes. | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) renders formatted messages with the appropriate styling applied, displaying bold, italic, underline, strikethrough, code, links, lists, and blockquote formatting as intended by the sender. | - -## Threaded Conversations - -The Threaded Conversations feature enables users to respond directly to a specific message in a chat. This keeps conversations organized and enhances the user experience by maintaining context, especially in group chats. - - - - - -| Components | Functionality | -| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| [Threaded Message Preview](/ui-kit/react/v7/guide-threaded-messages) | [Threaded Message Preview](/ui-kit/react/v7/guide-threaded-messages) component displays the parent message along with the number of replies. | - -## Quoted Replies - -Quoted Replies is a robust feature provided by CometChat that enables users to quickly reply to specific messages by selecting the "Reply" option from a message's action menu. This enhances context, keeps conversations organized, and improves overall chat experience in both 1-1 and group chats. - - - - - -| Components | Functionality | -| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) supports replying to messages via the "Reply" option. Users can select "Reply" on a message to open the composer with the quoted reply pre-filled, maintaining context. | -| [Message Composer](/ui-kit/react/v7/components/message-composer) | [Message Composer](/ui-kit/react/v7/components/message-composer) shows the quoted reply above the input field, providing context for the response. | - -## Group Chat - -CometChat facilitates Group Chats, allowing users to have conversations with multiple participants simultaneously. This feature is crucial for team collaborations, group discussions, social communities, and more. - - - - - -See the [Groups](/ui-kit/react/v7/components/groups) component page for details. - -## Moderation - -CometChat's Message Moderation feature helps maintain a safe and respectful chat environment by automatically filtering and managing inappropriate content. Messages can be automatically blocked or flagged based on predefined rules, ensuring harmful content is handled before it reaches users. - - - - - - -Learn more about setting up moderation rules and managing content in the [Moderation](/moderation/overview) documentation. - - -| Components | Functionality | -| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) automatically handles moderated messages, displaying blocked content based on moderation settings. | - -The **[Report Message](#report-message)** feature enables users to flag messages for review by moderators. - -## Report Message - -The Report Message feature allows users to report inappropriate or harmful messages within the chat. Users can choose from predefined reasons and provide additional remarks for detailed context. This feature helps maintain a safe and respectful chat environment. - - -Learn more about how flagged messages are handled, reviewed, and moderated in the [Flagged Messages](/moderation/flagged-messages) documentation. - - - - - - -| Components | Functionality | -| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) provides the "Report Message" option in the message actions menu, allowing users to initiate the reporting process for inappropriate messages. | - -## Conversation and Advanced Search - -Conversation and Advanced Search is a powerful feature provided by CometChat that enables users to quickly find conversations, messages, and media across chats in real time. It supports filters, scopes, and custom actions, allowing users to locate content efficiently while keeping the chat experience smooth and intuitive. - - - - - -| Components | Functionality | -| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [Search](/ui-kit/react/v7/components/search) | [Search](/ui-kit/react/v7/components/search) allows users to search across conversations and messages in real time. Users can click on a result to open the conversation or jump directly to a specific message. | -| [Message Header](/ui-kit/react/v7/components/message-header) | [Message Header](/ui-kit/react/v7/components/message-header) shows the search button in the chat header, allowing users to search within a conversation. | -| [Message List](/ui-kit/react/v7/components/message-list) | [Message List](/ui-kit/react/v7/components/message-list) shows the selected message when clicked from search results and highlights it in the message list. | -| [Conversations](/ui-kit/react/v7/components/conversations) | [Conversations](/ui-kit/react/v7/components/conversations) displays the search input. | - -See the [Groups](/ui-kit/react/v7/components/groups) component page for details. - ---- - -## Next Steps - - - - Browse all available UI Kit components - - - Customize the look and feel of your chat UI - - - Add audio and video calling - - - Explore AI-powered chat capabilities - - diff --git a/ui-kit/react/v7/extensions.mdx b/ui-kit/react/v7/extensions.mdx deleted file mode 100644 index f2e9e45d1..000000000 --- a/ui-kit/react/v7/extensions.mdx +++ /dev/null @@ -1,197 +0,0 @@ ---- -title: "Extensions" -description: "Overview of CometChat extensions for React UI Kit, including engagement, collaboration, security, support, and smart chat features." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Required setup | Wrap app in `CometChatProvider` with valid credentials + Extensions enabled in [CometChat Dashboard](/fundamentals/extensions-overview) | -| Extension categories | User Experience, User Engagement, Collaboration, Security, Customer Support, Smart Chat Features | -| Key components | `CometChatMessageComposer` → [Message Composer](/ui-kit/react/v7/components/message-composer) (Stickers, Polls, Whiteboard, Document), `CometChatMessageList` → [Message List](/ui-kit/react/v7/components/message-list) (Translation, Link Preview, Thumbnails) | -| Activation | Enable each extension from the CometChat Dashboard — UI Kit auto-integrates them, no additional code required | - - - -## Overview - -CometChat UI Kit includes built-in support for extensions that add interactive, secure, and efficient features to chat. Extensions are activated from the [CometChat Dashboard](https://app.cometchat.com/) and auto-integrate into UI Kit components. - - -Ensure your app is wrapped in `CometChatProvider` with valid credentials. Extensions must be activated from the [CometChat Dashboard](/fundamentals/extensions-overview). - - -## Built-in Extensions - -The grouping below mirrors the CometChat Dashboard. - -### User Experience - -#### Bitly - -Shortens long URLs in text messages using Bitly. See [Bitly Extension](/fundamentals/bitly). - -#### Link Preview - -Displays a summary (title, description, thumbnail) for URLs shared in chat. See [Link Preview Extension](/fundamentals/link-preview). - -Auto-integrates into the Message Bubble of [MessageList](/ui-kit/react/v7/components/message-list) when activated. - - - - - -#### Message Shortcuts - -Sends predefined messages using short codes (e.g., `!hb` expands to `Happy birthday!`). See [Message Shortcuts Extension](/fundamentals/message-shortcuts). - -#### Pin Message - -Pins important messages in a conversation for easy access. See [Pin Message Extension](/fundamentals/pin-message). - -#### Rich Media Preview - -Generates rich preview panels for URLs using iFramely. See [Rich Media Preview Extension](/fundamentals/rich-media-preview). - -#### Save Message - -Bookmarks messages for later reference. Saved messages are private to the user. See [Save Message Extension](/fundamentals/save-message). - -#### Thumbnail Generation - -Creates smaller preview images for shared images, reducing bandwidth. See [Thumbnail Generation Extension](/fundamentals/thumbnail-generation). - -Auto-integrates into the Message Bubble of [MessageList](/ui-kit/react/v7/components/message-list) when activated. - - - - - -#### TinyURL - -URL shortening using TinyURL. See [TinyURL Extension](/fundamentals/tinyurl). - -#### Voice Transcription - -Converts audio messages to text. See [Voice Transcription Extension](/fundamentals/voice-transcription). - -### User Engagement - -#### Giphy - -Search and share GIFs from Giphy. See [Giphy Extension](/fundamentals/giphy). - -#### Message Translation - -Translates messages into the local locale. See [Message Translation Extension](/fundamentals/message-translation). - -Auto-integrates into the Action Sheet of [MessageList](/ui-kit/react/v7/components/message-list) when activated. - - - - - -#### Polls - -Creates polls in group discussions with predefined answer options. See [Polls Extension](/fundamentals/polls). - -Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/v7/components/message-composer) when activated. - - - - - -#### Reminders - -Sets reminders for messages or creates personal reminders. A bot sends a notification when due. See [Reminders Extension](/fundamentals/reminders). - -#### Stickers - -Sends pre-designed stickers in chat. See [Sticker Extension](/fundamentals/stickers). - -Auto-integrates into [Message Composer](/ui-kit/react/v7/components/message-composer) when activated. - - - - - -#### Stipop - -Integrates Stipop's sticker library. See [Stipop Extension](/fundamentals/stickers-stipop). - -#### Tenor - -Search and share GIFs from Tenor. See [Tenor Extension](/fundamentals/tenor). - -### Collaboration - -#### Collaborative Document - -Shared document editing for real-time collaboration. See [Collaborative Document Extension](/fundamentals/collaborative-document). - -Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/v7/components/message-composer) when activated. - - - - - -#### Collaborative Whiteboard - -Real-time shared whiteboard for drawing and brainstorming. See [Collaborative Whiteboard Extension](/fundamentals/collaborative-whiteboard). - -Auto-integrates into the Action Sheet of [Message Composer](/ui-kit/react/v7/components/message-composer) when activated. - - - - - -### Security - -#### Disappearing Messages - -Messages auto-delete after a specified interval. Works for 1:1 and group messages. See [Disappearing Messages Extension](/fundamentals/disappearing-messages). - -### Customer Support - -#### Chatwoot - -Routes user messages to Chatwoot for customer support. See [Chatwoot Extension](/fundamentals/chatwoot). - -#### Intercom - -Integrates Intercom for in-app customer support. See [Intercom Extension](/fundamentals/intercom). - -### Smart Chat Features - -#### Conversation Starter - -AI-generated opening messages for new chats. See [Conversation Starter](/fundamentals/ai-user-copilot/conversation-starter) and [AI Features](/ui-kit/react/v7/ai-features). - -#### Smart Replies - -AI-generated response suggestions based on conversation context. See [Smart Replies](/fundamentals/ai-user-copilot/smart-replies) and [AI Features](/ui-kit/react/v7/ai-features). - -#### Conversation Summary - -AI-generated recap of long conversations. See [Conversation Summary](/fundamentals/ai-user-copilot/conversation-summary) and [AI Features](/ui-kit/react/v7/ai-features). - ---- - -## Next Steps - - - - Customize the composer where most extensions appear - - - Customize the message list for extension-rendered content - - - Core chat features like messaging and reactions - - - AI-powered chat capabilities - - diff --git a/ui-kit/react/v7/guide-block-unblock-user.mdx b/ui-kit/react/v7/guide-block-unblock-user.mdx deleted file mode 100644 index e978d105e..000000000 --- a/ui-kit/react/v7/guide-block-unblock-user.mdx +++ /dev/null @@ -1,309 +0,0 @@ ---- -title: "Block/Unblock User" -sidebarTitle: "Block/Unblock User" -description: "Let users block and unblock others directly within chat to control unwanted communication." ---- - -## Goal - -By the end of this guide you will have a chat interface where users can block and unblock other users, with a confirmation dialog before blocking, the composer automatically hidden for blocked users, and an unblock prompt displayed in its place — all coordinated through UI events so every component stays in sync. - -## Prerequisites - -- Completed the [Integration Guide](/ui-kit/react/v7/integration-react) guide -- A running `CometChatProvider` setup with valid credentials -- An existing one-on-one chat screen using `CometChatMessageList` and `CometChatMessageComposer` - -## Components Used - -| Component / API | Purpose | -|:----------------|:--------| -| `CometChatConfirmDialog` | Compound dialog for block confirmation | -| `CometChatMessageList` | Displays messages in the conversation | -| `CometChatMessageComposer` | Text input for sending messages | -| `useCometChatEvents` | Subscribe to UI events | -| `usePublishEvent` | Publish UI events | -| `CometChat.blockUsers()` | SDK method to block a user | -| `CometChat.unblockUsers()` | SDK method to unblock a user | -| `ui:user/blocked` | UI event fired after blocking | -| `ui:user/unblocked` | UI event fired after unblocking | - -## Step 1: Block User - -Call `CometChat.blockUsers()` with the target UID. On success, update the user object and publish the `ui:user/blocked` event so other components (thread panel, details panel) can react. - -_File: ChatView.tsx_ - -```tsx -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { usePublishEvent } from "@cometchat/chat-uikit-react"; - -const publish = usePublishEvent(); - -async function handleBlock(user: CometChat.User) { - try { - await CometChat.blockUsers([user.getUid()]); - user.setBlockedByMe(true); - setIsBlocked(true); - setShowBlockDialog(false); - publish({ type: "ui:user/blocked", user }); - } catch (error) { - console.error("Error blocking user:", error); - } -} -``` - -## Step 2: Unblock User - -Call `CometChat.unblockUsers()` to reverse the block. Publish `ui:user/unblocked` so all listening components restore their normal state. - -_File: ChatView.tsx_ - -```tsx -async function handleUnblock(user: CometChat.User) { - try { - await CometChat.unblockUsers([user.getUid()]); - user.setBlockedByMe(false); - setIsBlocked(false); - publish({ type: "ui:user/unblocked", user }); - } catch (error) { - console.error("Error unblocking user:", error); - } -} -``` - -## Step 3: Confirmation Dialog - -Show a `CometChatConfirmDialog` before blocking. Render it conditionally based on a `showBlockDialog` state flag. - -_File: ChatView.tsx_ - -```tsx -import { useState } from "react"; -import { CometChatConfirmDialog } from "@cometchat/chat-uikit-react"; - -const [showBlockDialog, setShowBlockDialog] = useState(false); - -// In your JSX: -{showBlockDialog && ( - setShowBlockDialog(false)}> - - - handleBlock(user)} - onCancel={() => setShowBlockDialog(false)} - /> - -)} -``` - -## Step 4: Listen for Block/Unblock Events - -Use `useCometChatEvents` to subscribe to block/unblock events. This keeps the composer visibility in sync even when the block action originates from a different component (e.g., a details panel). - -_File: ChatView.tsx_ - -```tsx -import { useCometChatEvents } from "@cometchat/chat-uikit-react"; -import type { CometChatEvent } from "@cometchat/chat-uikit-react"; - -useCometChatEvents( - (event: CometChatEvent) => { - if (!user) return; - - if (event.type === "ui:user/blocked" && event.user.getUid() === user.getUid()) { - setIsBlocked(true); - } - if (event.type === "ui:user/unblocked" && event.user.getUid() === user.getUid()) { - setIsBlocked(false); - } - }, - [user?.getUid()] -); -``` - -## Step 5: Blocked Composer State - -Conditionally render the composer or a blocked prompt based on the `isBlocked` state. The blocked prompt includes an inline unblock action. - -_File: ChatView.tsx_ - -```tsx -import { CometChatMessageComposer } from "@cometchat/chat-uikit-react"; - -// In your JSX: -{!isBlocked ? ( - -) : ( -
-

Cannot send a message to a blocked user.

- handleUnblock(user)} - role="button" - tabIndex={0} - style={{ color: "#3399ff", cursor: "pointer" }} - > - Click to unblock. - -
-)} -``` - -## Complete Example - -_File: ChatView.tsx_ - -```tsx -import { useState, useEffect } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatMessageList, - CometChatMessageComposer, - CometChatMessageHeader, - CometChatConfirmDialog, - usePublishEvent, - useCometChatEvents, -} from "@cometchat/chat-uikit-react"; -import type { CometChatEvent } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -function ChatView({ targetUid }: { targetUid: string }) { - const [user, setUser] = useState(null); - const [isBlocked, setIsBlocked] = useState(false); - const [showBlockDialog, setShowBlockDialog] = useState(false); - const publish = usePublishEvent(); - - useEffect(() => { - async function fetchUser() { - try { - const fetchedUser = await CometChat.getUser(targetUid); - setUser(fetchedUser); - setIsBlocked(fetchedUser.getBlockedByMe()); - } catch (error) { - console.error("Error fetching user:", error); - } - } - fetchUser(); - }, [targetUid]); - - useCometChatEvents( - (event: CometChatEvent) => { - if (!user) return; - if (event.type === "ui:user/blocked" && event.user.getUid() === user.getUid()) { - setIsBlocked(true); - } - if (event.type === "ui:user/unblocked" && event.user.getUid() === user.getUid()) { - setIsBlocked(false); - } - }, - [user?.getUid()] - ); - - async function handleBlock() { - if (!user) return; - try { - await CometChat.blockUsers([user.getUid()]); - user.setBlockedByMe(true); - setIsBlocked(true); - setShowBlockDialog(false); - publish({ type: "ui:user/blocked", user }); - } catch (error) { - console.error("Error blocking user:", error); - } - } - - async function handleUnblock() { - if (!user) return; - try { - await CometChat.unblockUsers([user.getUid()]); - user.setBlockedByMe(false); - setIsBlocked(false); - publish({ type: "ui:user/unblocked", user }); - } catch (error) { - console.error("Error unblocking user:", error); - } - } - - if (!user) return
Loading...
; - - return ( -
- {/* Confirmation dialog */} - {showBlockDialog && ( - setShowBlockDialog(false)}> - - - setShowBlockDialog(false)} - /> - - )} - - {/* Header with block/unblock action */} - setShowBlockDialog(true)} - style={{ background: "none", border: "none", cursor: "pointer", fontSize: "14px", color: isBlocked ? "#3399ff" : "#f44336" }} - > - {isBlocked ? "Unblock" : "Block"} - - } - /> - - {/* Message list */} -
- -
- - {/* Composer or blocked prompt */} - {!isBlocked ? ( - - ) : ( -
-

Cannot send a message to a blocked user.

- - Click to unblock. - -
- )} -
- ); -} - -function App() { - return ( - - - - ); -} - -export default App; -``` - -## Next Steps - -- [Message Composer](/ui-kit/react/v7/components/message-composer) — learn about composer customization -- [Conversations](/ui-kit/react/v7/components/conversations) — build a full conversations list -- [CometChatProvider](/ui-kit/react/v7/cometchat-provider) — configure the root provider diff --git a/ui-kit/react/v7/guide-message-privately.mdx b/ui-kit/react/v7/guide-message-privately.mdx deleted file mode 100644 index 3f16d7648..000000000 --- a/ui-kit/react/v7/guide-message-privately.mdx +++ /dev/null @@ -1,276 +0,0 @@ ---- -title: "Message Privately" -sidebarTitle: "Message Privately" -description: "Let users send a private one-on-one message to another user directly from within a group chat conversation." ---- - -## Goal - -By the end of this guide you will have a group chat interface where users can select a group member and open a private one-on-one conversation with them — without leaving the current screen. This is useful for side conversations, follow-ups, or sensitive messages that shouldn't be shared with the entire group. - -## Prerequisites - -- Completed the [Integration Guide](/ui-kit/react/v7/integration-react) guide -- A running `CometChatProvider` setup with valid credentials -- An existing group chat screen using `CometChatMessageList` and `CometChatMessageComposer` - -## Components Used - -| Component / API | Purpose | -|:----------------|:--------| -| `CometChatMessageList` | Displays group messages (publishes `ui:open-chat` internally via "Message Privately" option) | -| `CometChatMessageComposer` | Text input for the private conversation | -| `CometChatMessageHeader` | Displays user/group info | -| `useCometChatEvents` | Subscribe to `ui:open-chat` event | -| `ui:open-chat` | UI event published when user clicks "Message Privately" | - -## Step 1: Set up the main layout with provider - -Start with a layout that includes a conversations sidebar and a main chat area wrapped in `CometChatProvider`. - -```tsx App.tsx -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatConversations, - CometChatMessageList, - CometChatMessageComposer, - CometChatMessageHeader, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -function App() { - return ( - - - - ); -} - -export default App; -``` - -## Step 2: Track group and private chat state - -Maintain state for the active group conversation and a separate state for the private user when a user initiates a private message. - -```tsx ChatWithPrivateMessaging.tsx -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function ChatWithPrivateMessaging() { - const [user, setUser] = useState(null); - const [group, setGroup] = useState(null); - const [privateUser, setPrivateUser] = useState(null); - - // ... continued in next steps -} -``` - -## Step 3: Handle conversation selection - -Connect `CometChatConversations` to switch between user and group chats. When switching conversations, close any open private message panel. - -```tsx -function handleConversationClick(conversation: CometChat.Conversation) { - setPrivateUser(null); // close private panel on conversation switch - - const entity = conversation.getConversationWith(); - if (entity instanceof CometChat.User) { - setUser(entity); - setGroup(null); - } else if (entity instanceof CometChat.Group) { - setGroup(entity); - setUser(null); - } -} -``` - -## Step 4: Initiate a private message from a group member - -Use the message header or a custom action to let users pick a group member for private messaging. You can fetch the user from a member click event or from the message sender's info. - -```tsx -async function handleMessagePrivately(uid: string) { - try { - const targetUser = await CometChat.getUser(uid); - setPrivateUser(targetUser); - } catch (error) { - console.error("Failed to fetch user for private messaging:", error); - } -} -``` - -## Step 5: Listen for the `ui:open-chat` event - -Use `useCometChatEvents` to subscribe to the `ui:open-chat` event, which is published internally when a user clicks "Message Privately" from the context menu. When the event fires, extract the user and open the private panel. - -```tsx -import { useCometChatEvents } from "@cometchat/chat-uikit-react"; -import type { CometChatEvent } from "@cometchat/chat-uikit-react"; - -useCometChatEvents( - (event: CometChatEvent) => { - if (event.type === "ui:open-chat" && event.user) { - setPrivateUser(event.user); - } - }, - [group?.getGuid()] -); -``` - -## Step 6: Render the private message panel - -When `privateUser` is set, show a side panel with a private one-on-one chat. This panel includes a header, message list, and composer scoped to the private user. - -```tsx -{privateUser && ( -
-
- - Private: {privateUser.getName()} - - -
- -
- -
- - -
-)} -``` - -## Step 7: Handle edge cases - -Consider these scenarios when implementing private messaging from a group: - -| Scenario | Behavior | -|:---------|:---------| -| User messages themselves | Disable the private message option for the logged-in user's own messages | -| User is blocked | Check `getBlockedByMe()` before opening the private panel and show a prompt | -| Private panel already open | Replace the current private user with the newly selected one | -| Group conversation changes | Close the private panel when switching to a different conversation | - -## Complete Example - -```tsx App.tsx -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatConversations, - CometChatMessageList, - CometChatMessageComposer, - CometChatMessageHeader, - useCometChatEvents, -} from "@cometchat/chat-uikit-react"; -import type { CometChatEvent } from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -function ChatWithPrivateMessaging() { - const [user, setUser] = useState(null); - const [group, setGroup] = useState(null); - const [privateUser, setPrivateUser] = useState(null); - - function handleConversationClick(conversation: CometChat.Conversation) { - setPrivateUser(null); - const entity = conversation.getConversationWith(); - if (entity instanceof CometChat.User) { - setUser(entity); - setGroup(null); - } else if (entity instanceof CometChat.Group) { - setGroup(entity); - setUser(null); - } - } - - async function handleMessagePrivately(uid: string) { - try { - const targetUser = await CometChat.getUser(uid); - setPrivateUser(targetUser); - } catch (error) { - console.error("Failed to fetch user for private messaging:", error); - } - } - - useCometChatEvents( - (event: CometChatEvent) => { - if (event.type === "ui:open-chat" && event.user) { - setPrivateUser(event.user); - } - }, - [group?.getGuid()] - ); - - return ( -
- {/* Conversations sidebar */} -
- -
- - {/* Main chat panel */} -
- {(user || group) && ( - <> - -
- -
- - - )} -
- - {/* Private message panel */} - {privateUser && ( -
-
- - Private: {privateUser.getName()} - - -
- -
- -
- - -
- )} -
- ); -} - -function App() { - return ( - - - - ); -} - -export default App; -``` - -## Next Steps - -- [Message Composer](/ui-kit/react/v7/components/message-composer) — customize the composer for private chats -- [Conversations](/ui-kit/react/v7/components/conversations) — manage the conversations list -- [Users](/ui-kit/react/v7/components/cometchat-users) — browse and select users directly -- [CometChatProvider](/ui-kit/react/v7/cometchat-provider) — learn about provider configuration diff --git a/ui-kit/react/v7/guide-search-messages.mdx b/ui-kit/react/v7/guide-search-messages.mdx deleted file mode 100644 index 9644a999a..000000000 --- a/ui-kit/react/v7/guide-search-messages.mdx +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: "Search Messages" -sidebarTitle: "Search Messages" -description: "Add message search to your chat so users can find specific messages within a conversation." ---- - -## Goal - -By the end of this guide you will have a chat interface with a search panel that lets users query messages in a conversation by keyword, displays matching results, and scrolls to a selected message — all using v7 compound components and the CometChat SDK's `MessagesRequestBuilder`. - -## Prerequisites - -- Completed the [Integration Guide](/ui-kit/react/v7/integration-react) guide -- A running `CometChatProvider` setup with valid credentials -- An existing chat screen using `CometChatMessageList` and `CometChatMessageHeader` - -## Components Used - -| Component / API | Purpose | -|:----------------|:--------| -| `CometChatSearch` or `CometChat.MessagesRequestBuilder` | SDK builder for querying messages by keyword | -| `CometChatMessageList` | Displays messages and supports `goToMessageId` for scrolling to a result | -| `CometChatMessageHeader` | Header with search trigger button | -| `CometChatConversations` | Sidebar for switching conversations | - -## Step 1: Set up the chat layout with search state - -Start with a full chat layout that includes a conversations sidebar, message panel, and state to control the search panel visibility and the message to jump to. - -_File: App.tsx_ - -```tsx -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatConversations, - CometChatMessageList, - CometChatMessageComposer, - CometChatMessageHeader, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; -import MessageSearchPanel from "./MessageSearchPanel"; - -function ChatWithSearch() { - const [user, setUser] = useState(null); - const [group, setGroup] = useState(null); - const [showSearch, setShowSearch] = useState(false); - const [goToMessageId, setGoToMessageId] = useState(undefined); - - function handleConversationClick(conversation: CometChat.Conversation) { - setShowSearch(false); - setGoToMessageId(undefined); - const entity = conversation.getConversationWith(); - if (entity instanceof CometChat.User) { - setUser(entity); - setGroup(null); - } else if (entity instanceof CometChat.Group) { - setGroup(entity); - setUser(null); - } - } - - function handleMessageSelect(message: CometChat.BaseMessage) { - setGoToMessageId(message.getId()); - setShowSearch(false); - } - - return ( -
- {/* Conversations sidebar */} -
- -
- - {/* Main message panel */} -
- {(user || group) && ( - <> - setShowSearch((prev) => !prev)} - aria-label="Search messages" - style={{ background: "none", border: "none", cursor: "pointer", fontSize: "18px" }} - > - 🔍 - - } - /> -
- -
- - - )} -
- - {/* Search panel */} - {showSearch && (user || group) && ( - setShowSearch(false)} - /> - )} -
- ); -} - -function App() { - return ( - - - - ); -} - -export default App; -``` - -## Step 2: Create the search panel component - -Build a `MessageSearchPanel` component that accepts a `user` or `group`, takes a search keyword, queries messages using `MessagesRequestBuilder`, and displays the results. - -_File: MessageSearchPanel.tsx_ - -```tsx -import { useState, useCallback } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -interface MessageSearchPanelProps { - user?: CometChat.User; - group?: CometChat.Group; - onMessageSelect: (message: CometChat.BaseMessage) => void; - onClose: () => void; -} - -function MessageSearchPanel({ user, group, onMessageSelect, onClose }: MessageSearchPanelProps) { - const [keyword, setKeyword] = useState(""); - const [results, setResults] = useState([]); - const [loading, setLoading] = useState(false); - - const handleSearch = useCallback(async () => { - if (!keyword.trim()) return; - - setLoading(true); - try { - const builder = new CometChat.MessagesRequestBuilder() - .setSearchKeyword(keyword) - .setLimit(50); - - if (user) { - builder.setUID(user.getUid()); - } else if (group) { - builder.setGUID(group.getGuid()); - } - - const request = builder.build(); - const messages = await request.fetchPrevious(); - setResults(messages); - } catch (error) { - console.error("Search failed:", error); - } finally { - setLoading(false); - } - }, [keyword, user, group]); - - return ( -
- {/* Header */} -
-

Search Messages

- -
- - {/* Search input */} -
- setKeyword(e.target.value)} - onKeyDown={(e) => { if (e.key === "Enter") handleSearch(); }} - style={{ width: "100%", padding: "8px 12px", borderRadius: "8px", border: "1px solid #e0e0e0" }} - aria-label="Search keyword" - /> -
- - {/* Results */} -
- {loading &&

Searching...

} - {!loading && results.length === 0 && keyword &&

No messages found.

} - {results.map((message) => ( - - ))} -
-
- ); -} - -export default MessageSearchPanel; -``` - -## Step 3: Navigate to a selected search result - -When the user clicks a search result, pass the message ID to `CometChatMessageList` via the `goToMessageId` prop. This scrolls the message list to the matching message and highlights it. - -_File: ChatWithSearch.tsx_ - -```tsx -const [goToMessageId, setGoToMessageId] = useState(undefined); - -function handleMessageSelect(message: CometChat.BaseMessage) { - setGoToMessageId(message.getId()); - setShowSearch(false); -} - - -``` - -## Next Steps - -- [Message List](/ui-kit/react/v7/components/message-list) — configure message list rendering and scroll behavior -- [Message Header](/ui-kit/react/v7/components/message-header) — customize header actions and auxiliary views -- [CometChatProvider](/ui-kit/react/v7/cometchat-provider) — learn about provider configuration -- [Threaded Messages](/ui-kit/react/v7/guide-threaded-messages) — add threaded replies to your chat diff --git a/ui-kit/react/v7/guide-threaded-messages.mdx b/ui-kit/react/v7/guide-threaded-messages.mdx deleted file mode 100644 index 5eca800ea..000000000 --- a/ui-kit/react/v7/guide-threaded-messages.mdx +++ /dev/null @@ -1,219 +0,0 @@ ---- -title: "Threaded Messages" -sidebarTitle: "Threaded Messages" -description: "Add threaded message replies to your chat so users can create focused sub-conversations on any message." ---- - -## Goal - -By the end of this guide you will have a chat interface where users can open a thread panel from any message, view the parent message with its reply count, browse threaded replies, and send new replies — all using v7 compound components and a state-based approach (no custom events needed). - -## Prerequisites - -- Completed the [Integration Guide](/ui-kit/react/v7/integration-react) guide -- A running `CometChatProvider` setup with valid credentials -- An existing chat screen using `CometChatMessageList` and `CometChatMessageComposer` - -## Components Used - -| Component | Purpose | -|:----------|:--------| -| `CometChatThreadHeader` | Displays the parent message and reply count at the top of the thread panel | -| `CometChatMessageList` | Renders threaded replies when given a `parentMessageId` | -| `CometChatMessageComposer` | Sends replies into the thread with `parentMessageId`, `layout="compact"`, and `enableRichTextEditor` | - -## Step 1: Thread State Management - -Store the `threadedMessage` in state. When set, the thread panel renders. When cleared, it closes. This mirrors the pattern used in the sample app's `CometChatThreadPanel` component. - -_File: ChatWithThreads.tsx_ - -```tsx -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; - -function ChatWithThreads() { - const [user, setUser] = useState(null); - const [group, setGroup] = useState(null); - const [threadedMessage, setThreadedMessage] = useState(null); - - // Thread opens when threadedMessage is set, closes when cleared -} -``` - -## Step 2: Wire the Thread Trigger - -Use the `onThreadRepliesClick` callback on `CometChatMessageList` to capture when a user clicks "Reply in Thread." This sets the threaded message and opens the panel — no events required. - -_File: ChatWithThreads.tsx_ - -```tsx -import { CometChatMessageList } from "@cometchat/chat-uikit-react"; - - setThreadedMessage(message)} -/> -``` - -## Step 3: Build the Thread Panel - -When `threadedMessage` is set, render a side panel composing `CometChatThreadHeader` + `CometChatMessageList` (with `parentMessageId`) + `CometChatMessageComposer` (with `parentMessageId`, `layout="compact"`, and `enableRichTextEditor`). The `onClose` callback clears the state to dismiss the panel. - -_File: ChatWithThreads.tsx_ - -```tsx -import { - CometChatThreadHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; - -{threadedMessage && ( -
- setThreadedMessage(null)} - onParentDeleted={() => setThreadedMessage(null)} - /> - -
- -
- - -
-)} -``` - -## Step 4: Handle Parent Deleted - -Use the `onParentDeleted` prop on `CometChatThreadHeader` to automatically close the thread panel when the parent message is deleted by another user or a moderation action. - -_File: ChatWithThreads.tsx_ - -```tsx - setThreadedMessage(null)} - onParentDeleted={() => setThreadedMessage(null)} -/> -``` - -## Complete Example - -_File: App.tsx_ - -```tsx -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatConversations, - CometChatMessageList, - CometChatMessageComposer, - CometChatMessageHeader, - CometChatThreadHeader, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -function ChatWithThreads() { - const [user, setUser] = useState(null); - const [group, setGroup] = useState(null); - const [threadedMessage, setThreadedMessage] = useState(null); - - function handleConversationClick(conversation: CometChat.Conversation) { - setThreadedMessage(null); - const entity = conversation.getConversationWith(); - if (entity instanceof CometChat.User) { - setUser(entity); - setGroup(null); - } else if (entity instanceof CometChat.Group) { - setGroup(entity); - setUser(null); - } - } - - return ( -
- {/* Conversations sidebar */} -
- -
- - {/* Main message panel */} -
- {(user || group) && ( - <> - -
- setThreadedMessage(message)} - /> -
- - - )} -
- - {/* Thread panel */} - {threadedMessage && ( -
- setThreadedMessage(null)} - onParentDeleted={() => setThreadedMessage(null)} - /> -
- -
- -
- )} -
- ); -} - -function App() { - return ( - - - - ); -} - -export default App; -``` - -## Next Steps - -- [Thread Header](/ui-kit/react/v7/components/thread-header) — customize the thread header appearance -- [Message List](/ui-kit/react/v7/components/message-list) — configure message list rendering and options -- [CometChatProvider](/ui-kit/react/v7/cometchat-provider) — learn about provider configuration diff --git a/ui-kit/react/v7/methods.mdx b/ui-kit/react/v7/methods.mdx deleted file mode 100644 index b67815b5c..000000000 --- a/ui-kit/react/v7/methods.mdx +++ /dev/null @@ -1,200 +0,0 @@ ---- -title: "Methods" -description: "Static methods on CometChatUIKit for initialization, authentication, and message sending." ---- - - - -| Field | Value | -| --- | --- | -| Class | `CometChatUIKit` | -| Package | `@cometchat/chat-uikit-react` | -| Usage | Static methods — no instantiation needed | -| Note | Most users don't need these directly — `CometChatProvider` handles init and login automatically | - - - -## Overview - -`CometChatUIKit` is a static class that provides imperative methods for SDK initialization, authentication, and message sending. Most users won't need these directly — `CometChatProvider` handles init and login automatically. These methods are useful for: - -- The [individual providers approach](/ui-kit/react/v7/cometchat-provider#approach-2%3A-individual-providers-advanced) -- Sending messages programmatically outside the composer -- Checking initialization/login state - ---- - -## Initialization - -### `CometChatUIKit.init(settings)` - -Initialize the CometChat SDK and UIKit. - -```tsx -import { CometChatUIKit, UIKitSettingsBuilder } from "@cometchat/chat-uikit-react"; - -const settings = new UIKitSettingsBuilder() - .setAppId("APP_ID") - .setRegion("us") - .setAuthKey("AUTH_KEY") - .subscribePresenceForAllUsers() - .build(); - -const user = await CometChatUIKit.init(settings); -// user is non-null if an existing session was found -``` - -| Parameter | Type | Description | -| --- | --- | --- | -| `settings` | `UIKitSettings` | Built via `UIKitSettingsBuilder` | - -**Returns:** `Promise` — the logged-in user if a session exists, otherwise null. - -**What it does:** -1. Initializes the CometChat SDK with app settings -2. Sets source metadata for analytics -3. Creates the plugin registry (default + user plugins) -4. Initializes the localization singleton -5. Resumes existing session (if any) -6. Initializes Calls SDK (if enabled) - ---- - -## Authentication - -### `CometChatUIKit.login(uid)` - -Log in a user by UID. Requires `authKey` in UIKitSettings. - -```tsx -const user = await CometChatUIKit.login("superhero1"); -``` - -| Parameter | Type | Description | -| --- | --- | --- | -| `uid` | `string` | The user's UID | - -**Returns:** `Promise` - -### `CometChatUIKit.loginWithAuthToken(authToken)` - -Log in with a server-generated auth token. Preferred for production. - -```tsx -const user = await CometChatUIKit.loginWithAuthToken(token); -``` - -| Parameter | Type | Description | -| --- | --- | --- | -| `authToken` | `string` | Server-generated auth token | - -**Returns:** `Promise` - -### `CometChatUIKit.logout()` - -Log out the current user. - -```tsx -await CometChatUIKit.logout(); -``` - -**Returns:** `Promise` - ---- - -## State Getters - -### `CometChatUIKit.getLoggedInUser()` - -Get the currently logged-in user (synchronous). - -```tsx -const user = CometChatUIKit.getLoggedInUser(); -``` - -**Returns:** `CometChat.User | null` - -### `CometChatUIKit.isInitialized()` - -Check if the SDK has been initialized. - -```tsx -if (CometChatUIKit.isInitialized()) { ... } -``` - -**Returns:** `boolean` - -### `CometChatUIKit.isCallingReady()` - -Check if the Calls SDK is ready. - -**Returns:** `boolean` - -### `CometChatUIKit.getPluginRegistry()` - -Get the plugin registry instance. - -**Returns:** `CometChatPluginRegistry | null` - -### `CometChatUIKit.getSettings()` - -Get the UIKitSettings used during initialization. - -**Returns:** `UIKitSettings | null` - -### `CometChatUIKit.getConversationUpdateSettings()` - -Get conversation update settings fetched from the dashboard. - -**Returns:** `CometChat.ConversationUpdateSettings | null` - ---- - -## Message Sending - - -These methods are low-level utilities. They send messages via the SDK but do **not** publish `ui:message/sent` events. This means: -- The message won't appear in `CometChatMessageList` automatically -- The `CometChatConversations` list won't update - -For messages to appear in the UI, use the `CometChatMessageComposer` component, or manually publish the event after sending: - -```tsx -const publish = usePublishEvent(); -const msg = await CometChatUIKit.sendTextMessage(message); -publish({ type: "ui:message/sent", message: msg, status: CometChatMessageStatus.success }); -``` - - -### `CometChatUIKit.sendTextMessage(message)` - -Send a text message. Sets `muid` and `sentAt` if not already set. - -```tsx -const textMessage = new CometChat.TextMessage("receiverUid", "Hello!", "user"); -const sent = await CometChatUIKit.sendTextMessage(textMessage); -``` - -**Returns:** `Promise` - -### `CometChatUIKit.sendMediaMessage(message)` - -Send a media message (image, video, audio, file). - -```tsx -const mediaMessage = new CometChat.MediaMessage("receiverUid", file, "image", "user"); -const sent = await CometChatUIKit.sendMediaMessage(mediaMessage); -``` - -**Returns:** `Promise` - -### `CometChatUIKit.sendCustomMessage(message)` - -Send a custom message (polls, location, etc.). - -```tsx -const customMessage = new CometChat.CustomMessage("receiverUid", "user", "location", { latitude: 37.7749, longitude: -122.4194 }); -const sent = await CometChatUIKit.sendCustomMessage(customMessage); -``` - -**Returns:** `Promise` diff --git a/ui-kit/react/v7/next-conversation.mdx b/ui-kit/react/v7/next-conversation.mdx deleted file mode 100644 index 2402b5a9d..000000000 --- a/ui-kit/react/v7/next-conversation.mdx +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: "Conversation List + Message View" -sidebarTitle: "Conversation List + Message View" -description: "Build a two-panel conversation list + message view layout in Next.js (App Router) with CometChat UI Kit." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Framework | Next.js (App Router) | -| Components | `CometChatConversations`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | -| Layout | Two-panel — conversation list (left) + message view (right) | -| Prerequisite | Complete [Next.js Integration](/ui-kit/react/v7/integration-nextjs) first | -| SSR | Component loaded with `dynamic(() => import(...), { ssr: false })` | -| Pattern | WhatsApp Web, Slack, Microsoft Teams | - - - -This guide builds a two-panel chat layout — conversation list on the left, messages on the right. Users click a conversation to open it. - -This assumes you've already completed [Next.js Integration](/ui-kit/react/v7/integration-nextjs) (project created, UI Kit installed, init + login working). - - - - - - ---- - -## What You're Building - -Three sections working together: - -1. **Sidebar (conversation list)** — shows all active conversations (users and groups) -2. **Message view** — displays chat messages for the selected conversation in real time -3. **Message composer** — text input with support for media, emojis, and reactions - ---- - -## Full Code - -Create the client component with the chat UI, then import it dynamically in your page. - -```tsx title="app/chat/CometChatClient.tsx" -'use client'; - -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatConversations, - CometChatMessageHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -export default function CometChatClient() { - const [selectedUser, setSelectedUser] = useState(undefined); - const [selectedGroup, setSelectedGroup] = useState(undefined); - - const handleConversationClick = (conversation: CometChat.Conversation) => { - const entity = conversation.getConversationWith(); - if (conversation.getConversationType() === "user") { - setSelectedUser(entity as CometChat.User); - setSelectedGroup(undefined); - } else { - setSelectedGroup(entity as CometChat.Group); - setSelectedUser(undefined); - } - }; - - return ( - -
-
- -
- - {selectedUser || selectedGroup ? ( -
- - - -
- ) : ( -
- Select a conversation to start chatting -
- )} -
-
- ); -} -``` - -```css title="app/chat/chat.module.css" -.conversations-with-messages { - display: flex; - height: 100vh; - width: 100%; -} - -.conversations-wrapper { - width: 360px; - height: 100%; - border-right: 1px solid #eee; - overflow: hidden; - display: flex; - flex-direction: column; -} - -.messages-wrapper { - flex: 1; - height: 100%; - display: flex; - flex-direction: column; -} - -.empty-conversation { - flex: 1; - display: flex; - justify-content: center; - align-items: center; - background: var(--cometchat-background-color-03, #f5f5f5); - color: var(--cometchat-text-color-secondary, #727272); - font: var(--cometchat-font-body-regular, 400 14px Roboto); -} -``` - -```tsx title="app/chat/page.tsx" -import dynamic from 'next/dynamic'; - -const CometChatClient = dynamic(() => import('./CometChatClient'), { ssr: false }); - -export default function ChatPage() { - return ; -} -``` - ---- - -## How It Works - -1. **`'use client'`** marks the component as a Client Component — required because CometChat uses browser APIs. -2. **`dynamic(() => import(...), { ssr: false })`** prevents the component from rendering on the server, avoiding `window is not defined` errors. -3. **CometChatProvider** wraps the entire tree — it supplies theme, locale, and event context to all CometChat components. -4. **CometChatConversations** renders the sidebar list. When a user clicks a conversation, `onItemClick` fires with the `Conversation` object. -5. **handleConversationClick** extracts the `User` or `Group` from the conversation and stores it in state. -6. **Message components** (`MessageHeader`, `MessageList`, `MessageComposer`) receive either `user` or `group` as a prop — never both at the same time. - ---- - -## Run - -```bash -npm run dev -``` - -Open `http://localhost:3000/chat`. You should see the conversation list on the left. Click any conversation to load messages on the right. - ---- - -## Next Steps - - - - Single chat window without a sidebar - - - Tabbed navigation with Chats, Calls, Users - - - Browse all prebuilt UI components - - - Customize colors, fonts, and styles - - diff --git a/ui-kit/react/v7/next-one-to-one-chat.mdx b/ui-kit/react/v7/next-one-to-one-chat.mdx deleted file mode 100644 index 4d7b7b0b2..000000000 --- a/ui-kit/react/v7/next-one-to-one-chat.mdx +++ /dev/null @@ -1,173 +0,0 @@ ---- -title: "One-to-One / Group Chat" -sidebarTitle: "One-to-One / Group Chat" -description: "Build a single chat window for one-to-one or group messaging in Next.js (App Router) with CometChat UI Kit." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Framework | Next.js (App Router) | -| Components | `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | -| Layout | Single chat window — no sidebar, no conversation list | -| Prerequisite | Complete [Next.js Integration](/ui-kit/react/v7/integration-nextjs) first | -| SSR | Component loaded with `dynamic(() => import(...), { ssr: false })` | -| Pattern | Support chat, embedded widgets, focused messaging | - - - -This guide builds a single chat window — no sidebar, no conversation list. Users go directly into a one-to-one or group chat. Good for support chat, embedded widgets, or any focused messaging experience. - -This assumes you've already completed [Next.js Integration](/ui-kit/react/v7/integration-nextjs) (project created, UI Kit installed, init + login working). - - - - - - ---- - -## What You're Building - -Three components stacked vertically: - -1. **Chat header** — displays recipient name, avatar, online status, and optional call buttons -2. **Message list** — real-time chat history with scrolling -3. **Message composer** — text input with media, emojis, and reactions - ---- - -## Full Code - -Create the client component with the chat UI, then import it dynamically in your page. - -```tsx title="app/chat/CometChatClient.tsx" -'use client'; - -import { useEffect, useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatMessageHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -const RECIPIENT_UID = "cometchat-uid-2"; // Replace with the UID you want to chat with - -export default function CometChatClient() { - const [chatUser, setChatUser] = useState(undefined); - - useEffect(() => { - CometChat.getUser(RECIPIENT_UID).then( - (user) => setChatUser(user), - (error) => console.error("User fetch failed:", error) - ); - }, []); - - if (!chatUser) return
Loading chat...
; - - return ( - -
- - - -
-
- ); -} -``` - -```tsx title="app/chat/page.tsx" -import dynamic from 'next/dynamic'; - -const CometChatClient = dynamic(() => import('./CometChatClient'), { ssr: false }); - -export default function ChatPage() { - return ; -} -``` - -Key points: -- `'use client'` is required — CometChat components use browser APIs (DOM, WebSocket). -- `dynamic(() => import(...), { ssr: false })` prevents server-side rendering of the chat component. -- `CometChat.getUser(UID)` fetches the full user object from the SDK — you need a real user object, not a manually constructed one. -- Pass either `user` or `group` to the message components, never both. -- The `RECIPIENT_UID` should be a user that exists in your CometChat app. Use one of the pre-created test UIDs: `cometchat-uid-1` through `cometchat-uid-5`. - ---- - -## Switching to Group Chat - -To load a group chat instead of one-to-one, fetch a `Group` object and pass it to the message components: - -```tsx title="app/chat/CometChatClient.tsx" -'use client'; - -import { useEffect, useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatMessageHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -const GROUP_ID = "cometchat-guid-1"; // Replace with your Group ID - -export default function CometChatClient() { - const [chatGroup, setChatGroup] = useState(undefined); - - useEffect(() => { - CometChat.getGroup(GROUP_ID).then( - (group) => setChatGroup(group), - (error) => console.error("Group fetch failed:", error) - ); - }, []); - - if (!chatGroup) return
Loading chat...
; - - return ( - -
- - - -
-
- ); -} -``` - -The only difference: use `CometChat.getGroup(GUID)` instead of `CometChat.getUser(UID)`, and pass `group` instead of `user`. - ---- - -## Run - -```bash -npm run dev -``` - -Open `http://localhost:3000/chat`. You should see the chat window load with the conversation for the UID or GUID you set. - ---- - -## Next Steps - - - - Two-panel layout with a sidebar - - - Tabbed navigation with Chats, Calls, Users - - - Browse all prebuilt UI components - - diff --git a/ui-kit/react/v7/next-tab-based-chat.mdx b/ui-kit/react/v7/next-tab-based-chat.mdx deleted file mode 100644 index 427a9f30d..000000000 --- a/ui-kit/react/v7/next-tab-based-chat.mdx +++ /dev/null @@ -1,302 +0,0 @@ ---- -title: "Tab-Based Chat" -sidebarTitle: "Tab-Based Chat" -description: "Build a tab-based chat interface with Chat, Call Logs, Users, and Settings tabs in Next.js (App Router)." ---- - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` | -| Framework | Next.js (App Router) | -| Components | `CometChatConversations`, `CometChatCallLogs`, `CometChatUsers`, `CometChatMessageHeader`, `CometChatMessageList`, `CometChatMessageComposer` | -| Layout | Tabbed sidebar (Chat, Calls, Users) + message view | -| Prerequisite | Complete [Next.js Integration](/ui-kit/react/v7/integration-nextjs) first | -| SSR | Component loaded with `dynamic(() => import(...), { ssr: false })` | -| Pattern | Full-featured messaging app with multiple sections | - - - -This guide builds a tabbed messaging UI — Chat, Calls, and Users tabs in the sidebar, with a message view on the right. Good for full-featured apps that need more than just conversations. - -This assumes you've already completed [Next.js Integration](/ui-kit/react/v7/integration-nextjs) (project created, UI Kit installed, init + login working). - - - - - - ---- - -## What You're Building - -Three sections working together: - -1. **Tab bar** — switches between Chat, Calls, and Users -2. **Sidebar** — renders the list for the active tab -3. **Message view** — header + messages + composer for the selected item - ---- - -## Full Code - -Create the client component with the tabbed UI, then import it dynamically in your page. - -```tsx title="app/chat/CometChatClient.tsx" -'use client'; - -import { useState } from "react"; -import { CometChat } from "@cometchat/chat-sdk-javascript"; -import { - CometChatProvider, - CometChatConversations, - CometChatUsers, - CometChatCallLogs, - CometChatMessageHeader, - CometChatMessageList, - CometChatMessageComposer, -} from "@cometchat/chat-uikit-react"; -import "@cometchat/chat-uikit-react/styles"; - -type Tab = "chat" | "calls" | "users"; - -export default function CometChatClient() { - const [activeTab, setActiveTab] = useState("chat"); - const [selectedUser, setSelectedUser] = useState(undefined); - const [selectedGroup, setSelectedGroup] = useState(undefined); - - const handleConversationClick = (conversation: CometChat.Conversation) => { - const entity = conversation.getConversationWith(); - if (conversation.getConversationType() === "user") { - setSelectedUser(entity as CometChat.User); - setSelectedGroup(undefined); - } else { - setSelectedGroup(entity as CometChat.Group); - setSelectedUser(undefined); - } - }; - - const handleUserClick = (user: CometChat.User) => { - setSelectedUser(user); - setSelectedGroup(undefined); - }; - - const handleCallClick = (call: any) => { - const initiator = call.getInitiator(); - const receiver = call.getReceiver(); - - // Determine the other party in the call - if (receiver instanceof CometChat.User) { - setSelectedUser(receiver); - setSelectedGroup(undefined); - } else if (receiver instanceof CometChat.Group) { - setSelectedUser(undefined); - setSelectedGroup(receiver); - } else if (initiator instanceof CometChat.User) { - setSelectedUser(initiator); - setSelectedGroup(undefined); - } - }; - - return ( - -
-
-
- - - -
- -
- {activeTab === "chat" && ( - - )} - {activeTab === "calls" && ( - - )} - {activeTab === "users" && ( - - )} -
-
- - {selectedUser || selectedGroup ? ( -
- - - -
- ) : ( -
- Select a conversation to start chatting -
- )} -
-
- ); -} -``` - -```css title="app/chat/chat.module.css" -.tabbed-chat { - display: flex; - height: 100vh; - width: 100%; -} - -.sidebar { - width: 360px; - height: 100%; - display: flex; - flex-direction: column; - border-right: 1px solid #eee; -} - -.tab-bar { - display: flex; - border-bottom: 1px solid #eee; - background: var(--cometchat-background-color-01, #fff); -} - -.tab-button { - flex: 1; - padding: 12px 0; - border: none; - background: none; - cursor: pointer; - font: var(--cometchat-font-body-medium, 500 14px Roboto); - color: var(--cometchat-text-color-secondary, #727272); - border-bottom: 2px solid transparent; - transition: color 0.2s, border-color 0.2s; -} - -.tab-button:hover { - color: var(--cometchat-text-color-primary, #141414); -} - -.tab-button--active { - color: var(--cometchat-text-color-highlight, #6851d6); - border-bottom-color: var(--cometchat-primary-color, #6851d6); -} - -.sidebar-list { - flex: 1; - overflow: hidden; - display: flex; - flex-direction: column; -} - -.messages-wrapper { - flex: 1; - height: 100%; - display: flex; - flex-direction: column; -} - -.empty-conversation { - flex: 1; - display: flex; - justify-content: center; - align-items: center; - background: var(--cometchat-background-color-03, #f5f5f5); - color: var(--cometchat-text-color-secondary, #727272); - font: var(--cometchat-font-body-regular, 400 14px Roboto); -} -``` - -```tsx title="app/chat/page.tsx" -import dynamic from 'next/dynamic'; - -const CometChatClient = dynamic(() => import('./CometChatClient'), { ssr: false }); - -export default function ChatPage() { - return ; -} -``` - ---- - -## How It Works - -1. **`'use client'`** marks the component as a Client Component — required because CometChat uses browser APIs. -2. **`dynamic(() => import(...), { ssr: false })`** prevents the component from rendering on the server. -3. **Tab state** — `activeTab` controls which list component renders in the sidebar. -4. **Conditional rendering** — only the active tab's component mounts. Switching tabs unmounts the previous list and mounts the new one. -5. **Unified selection** — all three tabs feed into the same `selectedUser` / `selectedGroup` state. Clicking any item (conversation, call log, or user) updates the message panel. -6. **Call log handling** — when a call log is clicked, the receiver (user or group) is extracted and passed to the message components. - ---- - -## Adding More Tabs - -To add a Groups tab, import `CometChatGroups` and add another tab button + conditional render: - -```tsx -import { CometChatGroups } from "@cometchat/chat-uikit-react"; - -// Add to Tab type: -type Tab = "chat" | "calls" | "users" | "groups"; - -// Add button in tab-bar: - - -// Add in sidebar-list: -{activeTab === "groups" && ( - { - setSelectedGroup(group); - setSelectedUser(undefined); - }} - /> -)} -``` - -You can follow the same pattern for any additional tabs (Settings, Contacts, etc.). - ---- - -## Run - -```bash -npm run dev -``` - -Open `http://localhost:3000/chat`. You should see the tab bar at the top of the sidebar. Switch between Chats, Calls, and Users — clicking any item loads the message view on the right. - ---- - -## Next Steps - - - - Two-panel layout without tabs - - - Browse all prebuilt UI components - - - Customize colors, fonts, and styles - - diff --git a/ui-kit/react/v7/overview.mdx b/ui-kit/react/v7/overview.mdx deleted file mode 100644 index 29b7aa29e..000000000 --- a/ui-kit/react/v7/overview.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: "React UI Kit" -sidebarTitle: "Overview" -description: "Prebuilt React components for chat, voice, and video calling. Supports React.js, Next.js, React Router, and Astro." ---- - - -**Beta Release** - React UI Kit v7 is currently in beta. Breaking changes may be introduced before the GA release. - - - - -| Field | Value | -| --- | --- | -| Package | `@cometchat/chat-uikit-react` v7.0.x | -| Peer deps | `react` >=18, `react-dom` >=18, `@cometchat/chat-sdk-javascript` ^4.1.9, `dompurify` ^3.3.1 | -| Calling | Optional — `@cometchat/calls-sdk-javascript` | -| SSR | SSR-safe — no browser APIs at module scope. Next.js App Router compatible. | -| Localization | 19 languages built-in | -| Source | [GitHub](https://github.com/cometchat/cometchat-uikit-react/tree/v7) | - - - -The CometChat React UI Kit provides prebuilt, customizable components for adding chat, voice, and video calling to any React app. Each component handles its own data fetching, real-time listeners, and state — you just drop them into your layout. - - - - - ---- - -## Try It - - - - Try the full chat experience in your browser - - - Fork, add your credentials, and start building - - - ---- - -## Get Started - -Pick your framework and follow the step-by-step integration guide: - - - - Vite or Create React App - - - App Router with client-side rendering - - - SPA with React Router v6+ - - - React islands with client:only directive - - - ---- - -## What's Included - -- **Compound components** — compose only what you need using namespace sub-components (Root, View, EmptyState, etc.) -- **Plugin system** — extensible message rendering via `CometChatMessagePlugin` interface -- **Theming** — CSS custom properties (`--cometchat-*`) with built-in light and dark themes -- **Localization** — 19 supported languages with customizable translation keys -- **Calling** — optional voice and video calling via `@cometchat/calls-sdk-javascript` -- **SSR-safe** — no browser-only APIs at module scope; Next.js App Router compatible -- **Tree-shakeable** — ESM-first build with dual ESM + CJS output - ---- - -## Prerequisites - -Before integrating the UI Kit, ensure you have: - -- **Node.js 18+** installed -- A **CometChat account** with the following credentials: - - `appId` — your CometChat application ID - - `region` — your app region (e.g., `"us"` or `"eu"`) - - `authKey` — your CometChat auth key (for client-side authentication) - -You can find these values in the [CometChat Dashboard](https://app.cometchat.com). - -### Installation - -```bash -npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript react react-dom dompurify -``` - -| Package | Version | -|---------|---------| -| `@cometchat/chat-uikit-react` | `^7.0.0` | -| `@cometchat/chat-sdk-javascript` | `^4.1.9` | -| `react` | `>=18.0.0 <21.0.0` | -| `react-dom` | `>=18.0.0 <21.0.0` | -| `dompurify` | `^3.3.1` | -| `@cometchat/calls-sdk-javascript` | Optional — for voice/video calling | - ---- - -## Explore - - - - Browse all prebuilt UI components - - - Colors, fonts, dark mode, and custom styling - - - Customize message rendering with the plugin system - - - Threaded messages, new chat, search, and more - - - ---- - -## Resources - - - - Working reference app - - - Full UI Kit source on GitHub - - - Design resources and prototyping - - - Common issues and fixes - - - Open a support ticket - - diff --git a/ui-kit/react/v7/plugins/ai.mdx b/ui-kit/react/v7/plugins/ai.mdx deleted file mode 100644 index 4c3aaf582..000000000 --- a/ui-kit/react/v7/plugins/ai.mdx +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: "AI Plugin" -description: "Renders AI assistant messages including streaming responses, tool call arguments, and tool results." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `ai` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `assistant`, `toolArguments`, `toolResults`, `run_started` | -| Message Categories | `agentic`, `custom` | -| Included by Default | No (add via `plugins` prop) | -| Bubble Component | `CometChatAIAssistantBubble`, `CometChatStreamMessageBubble`, `CometChatToolCallArgumentBubble`, `CometChatToolCallResultBubble` | -| Conversation Preview | First 80 chars of response / Tool call / Tool result | -| Context Menu | None | - - - -## Overview - -The AI plugin handles messages in the `agentic` category. It renders three types of AI-generated content: - -- **Assistant messages** — completed AI responses with markdown formatting -- **Tool call arguments** — JSON display of arguments passed to a tool -- **Tool results** — JSON display of results returned by a tool -- **Streaming messages** — real-time streaming bubble while the AI is generating a response - - - ---- - -## Installation - -The AI plugin is NOT included in the default plugins. Add it explicitly: - -```tsx -import { CometChatProvider } from "@cometchat/chat-uikit-react"; -import { CometChatAIPlugin } from "@cometchat/chat-uikit-react/plugins/ai"; - - - - -``` - ---- - -## Message Types - -| Type | Category | What it renders | -| --- | --- | --- | -| `assistant` | `agentic` | Completed AI response with markdown | -| `toolArguments` | `agentic` | Tool call arguments as formatted JSON | -| `toolResults` | `agentic` | Tool call results as formatted JSON | -| `run_started` | `custom` | Streaming placeholder while AI generates | - ---- - -## Bubble Rendering - -### Assistant Bubble -Renders the AI response with full markdown support (headings, lists, code blocks, bold, italic, links). Uses `CometChatAIAssistantBubble`. - -### Streaming Bubble -Shows a real-time streaming animation while the AI is generating. Connects to the streaming service keyed by `chatId`. Uses `CometChatStreamMessageBubble`. - -### Tool Call Bubbles -Display tool invocation details as collapsible JSON blocks. Useful for debugging AI agent workflows. - -All bubble components are **lazy-loaded** — they're not included in the initial bundle until an AI message is actually rendered. - ---- - -## Context Menu Options - -None — AI messages are system-generated and have no context menu options. - ---- - -## Conversation Preview - -| Type | Preview text | -| --- | --- | -| `assistant` | First 80 characters of the response (markdown stripped) | -| `toolArguments` | "Tool call" | -| `toolResults` | "Tool result" | - ---- - -## Preloading - -The AI Assistant Chat panel can be preloaded on hover/focus to reduce perceived latency: - -```tsx -import { preloadAIAssistantChat } from "@cometchat/chat-uikit-react/plugins/ai"; - -// Call on AI button hover -onMouseEnter={() => preloadAIAssistantChat()} -``` - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Assistant bubble | `.cometchat-ai-assistant-bubble` | -| Streaming bubble | `.cometchat-stream-message-bubble` | -| Tool argument bubble | `.cometchat-tool-call-argument-bubble` | -| Tool result bubble | `.cometchat-tool-call-result-bubble` | diff --git a/ui-kit/react/v7/plugins/audio.mdx b/ui-kit/react/v7/plugins/audio.mdx deleted file mode 100644 index 286e4ff76..000000000 --- a/ui-kit/react/v7/plugins/audio.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: "Audio Plugin" -description: "Renders audio messages with waveform visualization, playback controls, and download." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `audio` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `audio` | -| Message Categories | `message` | -| Included by Default | Yes | -| Bubble Component | `CometChatAudioBubble` | -| Conversation Preview | Audio | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Audio plugin handles messages of type `audio` in category `message`. It renders an audio player with waveform visualization (via WaveSurfer.js), play/pause controls, duration display, and a download button. - - -**Live Preview** — interact with the audio message bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-audio--default) - - - - ---- - -## Bubble Rendering - -- **Waveform player** — WaveSurfer.js-powered waveform visualization with play/pause toggle -- **Duration** — displays total duration and current playback position -- **Download button** — download with progress indicator -- **Multiple audio files** — expand/collapse list -- **Caption** — rendered below the player, formatted with text formatters -- **Pending state** — renders from local blob URL while uploading - ---- - -## Context Menu Options - -Same as [Image Plugin](/ui-kit/react/v7/plugins/image) — standard media options (React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately). - ---- - -## Conversation Preview - -Returns: `Audio` (localized via `conversation_subtitle_audio` key) - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-audio-bubble` | -| Waveform container | `.cometchat-audio-bubble__waveform` | -| Play/pause button | `.cometchat-audio-bubble__play-button` | -| Duration text | `.cometchat-audio-bubble__duration` | -| Download button | `.cometchat-audio-bubble__download` | -| Caption | `.cometchat-audio-bubble__caption` | diff --git a/ui-kit/react/v7/plugins/call-action.mdx b/ui-kit/react/v7/plugins/call-action.mdx deleted file mode 100644 index 6e2ef3232..000000000 --- a/ui-kit/react/v7/plugins/call-action.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Call Action Plugin" -description: "Renders call action system messages like 'Missed Call', 'Call Ended', 'Incoming Call'." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `call-action` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `audio`, `video` | -| Message Categories | `call` | -| Included by Default | Yes | -| Bubble Component | `CometChatActionBubble` | -| Conversation Preview | Video call / Voice call | -| Context Menu | None | - - - -## Overview - -The Call Action plugin handles messages of type `audio` and `video` in category `call`. These are system messages generated when calls are initiated, answered, missed, or ended. They render as centered, pill-shaped bubbles with a call status icon. - ---- - -## Bubble Rendering - -- **Centered pill** — same style as action bubbles -- **Status icon** — colored icon indicating call direction and outcome -- **Status text** — localized description (e.g., "Missed Call", "Outgoing Call", "Call Ended") - -### Call Status Icons - -| Status | Sent by me | Received | Icon | -| --- | --- | --- | --- | -| Initiated | Outgoing call icon | Incoming call icon | Phone/video arrow | -| Ended | Call end icon | Call end icon | Red phone | -| Missed/Cancelled/Unanswered | Unanswered icon | Missed call icon (red) | Red phone with X | -| Ongoing/Answered | Outgoing icon | Incoming icon | Green phone | - -### Status Text Mapping - -**Sent by me:** -- `initiated` → "Outgoing Call" -- `cancelled` → "Cancelled Call" -- `rejected` → "Rejected Call" -- `ended` → "Call Ended" -- `unanswered` → "Unanswered Call" - -**Received:** -- `initiated` → "Incoming Call" -- `ended` → "Call Ended" -- `unanswered`/`cancelled` → "Missed Call" -- `busy` → "Busy Call" - ---- - -## Context Menu Options - -None — call action messages have no context menu. - ---- - -## Conversation Preview - -Returns: `Video call` or `Voice call` based on the call type (localized). - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-action-bubble` | -| Icon | `.cometchat-action-bubble__icon` | -| Icon (error) | `.cometchat-action-bubble__icon--error` | -| Text | `.cometchat-action-bubble__text` | -| Text (error) | `.cometchat-action-bubble__text--error` | -| Missed video icon | `.cometchat-action-bubble__icon--missed-video` | -| Missed audio icon | `.cometchat-action-bubble__icon--missed-audio` | -| Outgoing video icon | `.cometchat-action-bubble__icon--outgoing-video` | -| Outgoing audio icon | `.cometchat-action-bubble__icon--outgoing-audio` | -| Incoming video icon | `.cometchat-action-bubble__icon--incoming-video` | -| Incoming audio icon | `.cometchat-action-bubble__icon--incoming-audio` | -| Call ended icon | `.cometchat-action-bubble__icon--call-ended` | - -Icons are rendered via CSS `mask-image`. Override the mask in your own CSS to use custom icons: - -```css -.cometchat-action-bubble__icon--missed-video { - -webkit-mask-image: url('/my-custom-missed-video-icon.svg'); - mask-image: url('/my-custom-missed-video-icon.svg'); -} -``` diff --git a/ui-kit/react/v7/plugins/collaborative-document.mdx b/ui-kit/react/v7/plugins/collaborative-document.mdx deleted file mode 100644 index 754da65b1..000000000 --- a/ui-kit/react/v7/plugins/collaborative-document.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: "Collaborative Document Plugin" -description: "Renders collaborative document messages with a banner and 'Open Document' button." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `collaborative-document` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `extension_document` | -| Message Categories | `custom` | -| Included by Default | Yes | -| Bubble Component | `CometChatCollaborativeBubble` | -| Conversation Preview | Collaborative Document | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Collaborative Document plugin handles messages of type `extension_document` in category `custom`. It renders a card with a document banner image, title, subtitle, and an "Open Document" button that launches the collaborative editor in a new window. - - -**Live Preview** — interact with the collaborative document bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--collaborative-document-message) - - - - ---- - -## Bubble Rendering - -- **Banner image** — themed (light/dark) document illustration -- **Title** — "Collaborative Document" -- **Subtitle** — "Open document to edit content together" -- **Button** — "Open Document" — opens the document URL in a fullscreen popup window -- Lazy-loaded — the bubble component is not included in the initial bundle - -The document URL is extracted from the message's extension metadata at `@injected.extensions.document.document_url`. - ---- - -## Context Menu Options - -Standard media options: React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately. - ---- - -## Conversation Preview - -Returns: `Collaborative Document` (localized via `conversation_subtitle_collaborative_document` key) - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-collaborative-bubble` | -| Banner image | `.cometchat-collaborative-bubble__banner` | -| Title | `.cometchat-collaborative-bubble__title` | -| Subtitle | `.cometchat-collaborative-bubble__subtitle` | -| Open button | `.cometchat-collaborative-bubble__button` | diff --git a/ui-kit/react/v7/plugins/collaborative-whiteboard.mdx b/ui-kit/react/v7/plugins/collaborative-whiteboard.mdx deleted file mode 100644 index a6a9fe615..000000000 --- a/ui-kit/react/v7/plugins/collaborative-whiteboard.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: "Collaborative Whiteboard Plugin" -description: "Renders collaborative whiteboard messages with a banner and 'Open Whiteboard' button." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `collaborative-whiteboard` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `extension_whiteboard` | -| Message Categories | `custom` | -| Included by Default | Yes | -| Bubble Component | `CometChatCollaborativeBubble` | -| Conversation Preview | Collaborative Whiteboard | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Collaborative Whiteboard plugin handles messages of type `extension_whiteboard` in category `custom`. It renders a card with a whiteboard banner image, title, subtitle, and an "Open Whiteboard" button that launches the whiteboard in a new window. - - -**Live Preview** — interact with the collaborative whiteboard bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--collaborative-whiteboard-message) - - - - ---- - -## Bubble Rendering - -- **Banner image** — themed (light/dark) whiteboard illustration -- **Title** — "Collaborative Whiteboard" -- **Subtitle** — "Open whiteboard to draw together" -- **Button** — "Open Whiteboard" — opens the board URL in a fullscreen popup window -- Lazy-loaded — the bubble component is not included in the initial bundle - -The whiteboard URL is extracted from the message's extension metadata at `@injected.extensions.whiteboard.board_url`. - ---- - -## Context Menu Options - -Standard media options: React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately. - ---- - -## Conversation Preview - -Returns: `Collaborative Whiteboard` (localized via `conversation_subtitle_collaborative_whiteboard` key) - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-collaborative-bubble` | -| Banner image | `.cometchat-collaborative-bubble__banner` | -| Title | `.cometchat-collaborative-bubble__title` | -| Subtitle | `.cometchat-collaborative-bubble__subtitle` | -| Open button | `.cometchat-collaborative-bubble__button` | diff --git a/ui-kit/react/v7/plugins/delete.mdx b/ui-kit/react/v7/plugins/delete.mdx deleted file mode 100644 index b2c5267d4..000000000 --- a/ui-kit/react/v7/plugins/delete.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: "Delete Plugin" -description: "Renders deleted messages with a 'This message was deleted' placeholder." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `delete` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | (any deleted message) | -| Message Categories | (any) | -| Included by Default | Yes | -| Bubble Component | `CometChatDeleteBubble` | -| Conversation Preview | This message was deleted | -| Context Menu | None | - - - -## Overview - -The Delete plugin handles any message that has been deleted (where `getDeletedAt()` returns a non-null value). It renders a placeholder bubble indicating the message was removed. - - -**Live Preview** — interact with the delete message bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-delete--default) - - - - ---- - -## Bubble Rendering - -- **Placeholder text** — "This message was deleted" (localized) -- **Styling** — italic, muted text color, no bubble background for incoming -- **Variant** — different styling for sent vs received deleted messages - -### Resolution - -The Delete plugin is special — it's matched by the Plugin Registry's **deleted-message fast path**, not by type+category. When the registry encounters a message with `getDeletedAt() !== null`, it immediately returns the Delete plugin regardless of the message's original type. - -This means a deleted text message, deleted image, deleted poll — all render the same "deleted" placeholder. - ---- - -## Context Menu Options - -None — deleted messages have no context menu options. - ---- - -## Conversation Preview - -Returns: `This message was deleted` (localized via `message_deleted` key) - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-delete-bubble` | -| Placeholder text | `.cometchat-delete-bubble__text` | diff --git a/ui-kit/react/v7/plugins/file.mdx b/ui-kit/react/v7/plugins/file.mdx deleted file mode 100644 index 45c9a5f1d..000000000 --- a/ui-kit/react/v7/plugins/file.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: "File Plugin" -description: "Renders file messages with file icon, name, size, and download button." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `file` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `file` | -| Message Categories | `message` | -| Included by Default | Yes | -| Bubble Component | `CometChatFileBubble` | -| Conversation Preview | File | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The File plugin handles messages of type `file` in category `message`. It renders a file card showing the file name, size, extension icon, and a download button with progress indicator. - - -**Live Preview** — interact with the file message bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-file--default) - - - - ---- - -## Bubble Rendering - -- **File card** — displays file icon (based on extension), file name, and formatted file size -- **Download button** — click to download with progress indicator (uses `downloadWithProgress` utility) -- **Multiple files** — expand/collapse list showing all attachments -- **Caption** — rendered below the file card, formatted with text formatters -- **Pending state** — shows file info from local metadata while uploading (no download button) - ---- - -## Context Menu Options - -Same as [Image Plugin](/ui-kit/react/v7/plugins/image) — standard media options (React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately). - ---- - -## Conversation Preview - -Returns: `File` (localized via `conversation_subtitle_file` key) - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-file-bubble` | -| File card | `.cometchat-file-bubble__card` | -| File icon | `.cometchat-file-bubble__icon` | -| File name | `.cometchat-file-bubble__name` | -| File size | `.cometchat-file-bubble__size` | -| Download button | `.cometchat-file-bubble__download` | -| Caption | `.cometchat-file-bubble__caption` | diff --git a/ui-kit/react/v7/plugins/group-action.mdx b/ui-kit/react/v7/plugins/group-action.mdx deleted file mode 100644 index 92f64c536..000000000 --- a/ui-kit/react/v7/plugins/group-action.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "Group Action Plugin" -description: "Renders group action system messages like 'User joined', 'User left', 'User was kicked'." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `group-action` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `groupMember` | -| Message Categories | `action` | -| Included by Default | Yes | -| Bubble Component | `CometChatActionBubble` | -| Conversation Preview | Action text (e.g., 'Alice joined') | -| Context Menu | None | - - - -## Overview - -The Group Action plugin handles messages of type `groupMember` in category `action`. These are system messages generated by the SDK when group membership changes occur. They render as centered, pill-shaped bubbles with no sender attribution. - ---- - -## Bubble Rendering - -- **Centered pill** — no left/right alignment, no avatar, no timestamp -- **Action text** — localized description of what happened (e.g., "Alice joined", "Bob was kicked by Admin") -- Uses the shared `getActionMessageText()` utility for localized text generation - -### Supported Actions - -| Action | Example text | -| --- | --- | -| Member joined | "Alice joined" | -| Member left | "Bob left" | -| Member kicked | "Admin kicked Bob" | -| Member banned | "Admin banned Charlie" | -| Member unbanned | "Admin unbanned Charlie" | -| Scope changed | "Admin made Bob a moderator" | -| Member added | "Admin added Dave" | - ---- - -## Context Menu Options - -None — group action messages have no context menu. - ---- - -## Conversation Preview - -Returns the action text (truncated to 100 characters). Falls back to `Group action` if text generation fails. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-action-bubble` | -| Icon (when present) | `.cometchat-action-bubble__icon` | -| Action text | `.cometchat-action-bubble__text` | diff --git a/ui-kit/react/v7/plugins/image.mdx b/ui-kit/react/v7/plugins/image.mdx deleted file mode 100644 index 097f4b1b7..000000000 --- a/ui-kit/react/v7/plugins/image.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: "Image Plugin" -description: "Renders image messages with multi-image grid, captions, and fullscreen gallery viewer." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `image` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `image` | -| Message Categories | `message` | -| Included by Default | Yes | -| Bubble Component | `CometChatImageBubble` | -| Conversation Preview | Photo | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Image plugin handles messages of type `image` in category `message`. It renders images in a responsive grid layout with optional captions. Clicking an image opens a fullscreen gallery viewer. - - -**Live Preview** — interact with the image message bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-image--default) - - - - ---- - -## Bubble Rendering - -- **Single image** — full-width image with rounded corners -- **Multiple images** — responsive grid (2 images side-by-side, 3+ in a masonry-style layout) -- **Caption** — rendered below the image grid, formatted with text formatters (mentions, URLs, markdown) -- **Pending state** — shows a placeholder while the image uploads - -Clicking any image opens the `CometChatFullScreenViewer` gallery with swipe navigation between images. - ---- - -## Context Menu Options - -| Option | Condition | Action | -| --- | --- | --- | -| React | Always | Opens emoji picker | -| Reply | Always | Sets reply-to in composer | -| Reply in Thread | Not in thread | Opens thread view | -| Info | Sender only | Opens message info panel | -| Delete | Sender only | Shows delete confirmation | -| Report | Receiver only | Opens flag/report dialog | -| Mark Unread | Receiver only | Marks message as unread | -| Message Privately | Receiver, group only | Opens 1:1 chat with sender | - ---- - -## Conversation Preview - -Returns: `Photo` (localized via `conversation_subtitle_image` key) - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-image-bubble` | -| Image grid | `.cometchat-image-bubble__grid` | -| Single image | `.cometchat-image-bubble__image` | -| Caption | `.cometchat-image-bubble__caption` | diff --git a/ui-kit/react/v7/plugins/message-translation.mdx b/ui-kit/react/v7/plugins/message-translation.mdx deleted file mode 100644 index 6c3639e57..000000000 --- a/ui-kit/react/v7/plugins/message-translation.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "Message Translation Plugin" -description: "Adds a 'Translate' context menu option to text messages using the CometChat translation extension." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `message-translation` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | (none — enhancer) | -| Message Categories | (none — enhancer) | -| Included by Default | No | -| Bubble Component | None (enhancer only) | -| Conversation Preview | N/A | -| Context Menu | Translate (added to text messages) | - - - -## Overview - -The Message Translation plugin is an **enhancer plugin** — it doesn't own a message type or render bubbles. Instead, it adds a "Translate" option to the context menu of text messages. When triggered, it calls the CometChat translation extension API to translate the message into the user's browser language. - - -**Live Preview** — text bubble with translation applied. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-text--with-translation) - - - - ---- - -## How It Works - -1. User hovers/long-presses a text message → context menu appears -2. "Translate" option is shown (for non-deleted text messages only) -3. User clicks "Translate" → plugin calls the translation extension API -4. Translated text is stored in the message's metadata (`translated_message` key) -5. The text bubble re-renders showing the translation below the original - ---- - -## Plugin Details - -| Field | Value | -| --- | --- | -| Plugin ID | `message-translation` | -| Message Types | `[]` (none — enhancer only) | -| Message Categories | `[]` (none — enhancer only) | -| Renders Bubble | No (`renderBubble` returns `null`) | -| Provides Options | Yes — "Translate" for text messages | - ---- - -## Context Menu Option - -| Option | Condition | Action | -| --- | --- | --- | -| Translate | Text messages only, not deleted | Translates to browser language via extension API | - -The translation target language is detected from `navigator.language` (e.g., `en`, `fr`, `de`). - ---- - -## Conversation Preview - -Returns empty string — this plugin doesn't handle conversation previews. - ---- - -## Requirements - -The CometChat **Message Translation** extension must be enabled in your [CometChat Dashboard](https://app.cometchat.com) under Extensions. - ---- - -## Installation - -The Message Translation plugin is NOT included in the default plugins. Add it explicitly: - -```tsx -import { CometChatProvider } from "@cometchat/chat-uikit-react"; -import { CometChatMessageTranslationPlugin } from "@cometchat/chat-uikit-react"; - - - - -``` diff --git a/ui-kit/react/v7/plugins/overview.mdx b/ui-kit/react/v7/plugins/overview.mdx deleted file mode 100644 index 8c2bb2779..000000000 --- a/ui-kit/react/v7/plugins/overview.mdx +++ /dev/null @@ -1,251 +0,0 @@ ---- -title: "Plugins" -sidebarTitle: "Overview" -description: "The plugin system controls how messages are rendered, what options appear in context menus, and what preview text shows in conversations." ---- - -## What is a Plugin? - -A plugin owns one or more message types. It tells the UI Kit: - -- **How to render the message** as a bubble in the message list -- **What context menu options** to show when a user hovers/long-presses a message -- **What preview text** to display in the Conversations list subtitle - -Every message that appears in the UI is rendered by a plugin. If no plugin matches a message type, the message is not displayed. - -{/* TODO:IMAGE - Diagram showing a message bubble with labeled regions: header, content (plugin), footer, status info */} - ---- - -## Where Plugins Are Used - -| Location | Plugin Method | What it does | -| --- | --- | --- | -| **Message List** | `renderBubble()` | Renders the bubble content (text, image grid, poll, etc.) | -| **Message List** | `getOptions()` | Provides context menu items (reply, edit, delete, copy, react) | -| **Conversations List** | `getLastMessagePreview()` | Returns subtitle text ("📷 Photo", "You: Hello", "🎥 Video") | -| **Message Bubble** | `renderHeaderView()`, `renderFooterView()`, etc. | Customizes bubble regions beyond content | - ---- - -## Default Plugins - -These plugins are included automatically — no configuration needed: - -| Plugin | Message Type | What it renders | -| --- | --- | --- | -| [Text](/ui-kit/react/v7/plugins/text) | `text` | Formatted text with mentions, URLs, markdown | -| [Image](/ui-kit/react/v7/plugins/image) | `image` | Image grid with captions, click-to-fullscreen | -| [Video](/ui-kit/react/v7/plugins/video) | `video` | Video player with thumbnail | -| [File](/ui-kit/react/v7/plugins/file) | `file` | File card with download button | -| [Audio](/ui-kit/react/v7/plugins/audio) | `audio` | Waveform audio player | -| [Polls](/ui-kit/react/v7/plugins/polls) | `extension_poll` | Poll creation + voting bubble | -| [Stickers](/ui-kit/react/v7/plugins/stickers) | `extension_sticker` | Sticker image bubble | -| [Collaborative Document](/ui-kit/react/v7/plugins/collaborative-document) | `extension_document` | Document collaboration link | -| [Collaborative Whiteboard](/ui-kit/react/v7/plugins/collaborative-whiteboard) | `extension_whiteboard` | Whiteboard collaboration link | -| [Group Action](/ui-kit/react/v7/plugins/group-action) | `groupMember` | "User joined", "User left" system messages | -| [Call Action](/ui-kit/react/v7/plugins/call-action) | `audio`, `video` (call category) | "Missed call", "Call ended" system messages | -| [Delete](/ui-kit/react/v7/plugins/delete) | Any (deleted) | "This message was deleted" placeholder | - ---- - -## How Plugin Resolution Works - -When the UI Kit needs to render a message, it asks the **Plugin Registry** to find the right plugin: - -1. If the message is deleted (`getDeletedAt() !== null`), the Delete plugin handles it -2. Otherwise, the registry finds the first plugin whose `messageTypes` includes the message's type AND whose `messageCategories` includes the message's category -3. First match wins — plugin order matters - -``` -Message { type: "image", category: "message" } - → Registry scans plugins in order - → CometChatImagePlugin matches (messageTypes: ["image"], messageCategories: ["message"]) - → ImagePlugin.renderBubble() is called -``` - ---- - -## Adding Plugins - -Default plugins are always included. To add extra plugins (like AI), pass them via the `plugins` prop on `CometChatProvider`: - -```tsx -import { CometChatProvider } from "@cometchat/chat-uikit-react"; -import { CometChatAIPlugin } from "@cometchat/chat-uikit-react/plugins/ai"; - -function App() { - return ( - - - - ); -} -``` - -Your custom plugins are appended after the defaults. Since first match wins, default plugins take priority for their message types. To override a default plugin, you'd need to use the manual approach with a custom plugin array. - ---- - -## Creating a Custom Plugin - -Implement the `CometChatMessagePlugin` interface. Here's a minimal "location" message plugin: - -```tsx -import React from "react"; -import type { CometChat } from "@cometchat/chat-sdk-javascript"; -import type { - CometChatMessagePlugin, - CometChatMessagePluginContext, - CometChatMessageOption, -} from "@cometchat/chat-uikit-react"; - -export const LocationPlugin: CometChatMessagePlugin = { - id: "location", - messageTypes: ["location"], - messageCategories: ["custom"], - - renderBubble(message: CometChat.BaseMessage, context: CometChatMessagePluginContext) { - const customMessage = message as CometChat.CustomMessage; - const data = customMessage.getData() as { customData?: { latitude: number; longitude: number } }; - const { latitude, longitude } = data.customData ?? { latitude: 0, longitude: 0 }; - - return React.createElement("div", { className: "location-bubble" }, - React.createElement("img", { - src: `https://maps.googleapis.com/maps/api/staticmap?center=${latitude},${longitude}&zoom=15&size=300x200&key=YOUR_KEY`, - alt: "Location", - style: { borderRadius: 8, width: "100%" }, - }), - React.createElement("p", { style: { margin: "8px 0 0", fontSize: 12 } }, - `${latitude.toFixed(4)}, ${longitude.toFixed(4)}` - ) - ); - }, - - getOptions(message: CometChat.BaseMessage, context: CometChatMessagePluginContext): CometChatMessageOption[] { - // Minimal options — just delete for sender - return [ - { - id: "delete", - title: context.getLocalizedString?.("delete") ?? "Delete", - senderOnly: true, - onClick: (msg) => context.onDeleteMessage?.(msg), - }, - ]; - }, - - getLastMessagePreview(): string { - return "📍 Location"; - }, -}; -``` - -Register it: - -```tsx - - - -``` - -For a complete tutorial with sending, receiving, and styling, see [Creating a Custom Plugin](/ui-kit/react/v7/plugins/custom-plugin). - ---- - -## Plugin Interface Reference - -```typescript -interface CometChatMessagePlugin { - /** Unique plugin identifier. */ - id: string; - - /** SDK message types this plugin handles (e.g., ["text"], ["image"]). */ - messageTypes: string[]; - - /** SDK message categories this plugin handles (e.g., ["message"], ["custom"]). */ - messageCategories: string[]; - - /** Render the bubble content for a message. */ - renderBubble(message: BaseMessage, context: PluginContext): ReactNode; - - /** Return context menu options for a message. */ - getOptions?(message: BaseMessage, context: PluginContext): MessageOption[]; - - /** Return plain-text preview for the conversation list subtitle. */ - getLastMessagePreview?(message: BaseMessage, loggedInUser: User, t?: (key: string) => string): string; - - /** Return text formatters (only relevant for text plugin). */ - getTextFormatters?(): CometChatTextFormatter[]; - - // --- View Slot Methods (optional) --- - /** Custom leading view (avatar area). */ - renderLeadingView?(message: BaseMessage, context: PluginContext): ReactNode; - /** Custom header view (sender name area). */ - renderHeaderView?(message: BaseMessage, context: PluginContext): ReactNode; - /** Custom footer view (reactions area). */ - renderFooterView?(message: BaseMessage, context: PluginContext): ReactNode; - /** Custom bottom view (moderation area). */ - renderBottomView?(message: BaseMessage, context: PluginContext): ReactNode; - /** Custom status info view (timestamp + receipts). */ - renderStatusInfoView?(message: BaseMessage, context: PluginContext): ReactNode; - /** Custom reply view (quoted message preview). */ - renderReplyView?(message: BaseMessage, context: PluginContext): ReactNode; - /** Custom thread view (reply count indicator). */ - renderThreadView?(message: BaseMessage, context: PluginContext): ReactNode; -} -``` - -### Plugin Context - -The `context` object passed to every plugin method: - -| Field | Type | Description | -| --- | --- | --- | -| `loggedInUser` | `CometChat.User` | The currently logged-in user | -| `group` | `CometChat.Group \| undefined` | The group (if group chat) | -| `alignment` | `"left" \| "right" \| "center"` | Bubble alignment | -| `theme` | `"light" \| "dark"` | Current theme | -| `getLocalizedString` | `(key: string) => string` | Localization function | -| `onDeleteMessage` | `(msg) => void` | Delete a message | -| `onEditMessage` | `(msg) => void` | Enter edit mode | -| `onReplyMessage` | `(msg) => void` | Set reply-to target | -| `onThreadClick` | `(msg) => void` | Open thread view | -| `onReactToMessage` | `(msg) => void` | Open emoji picker | -| `onMessageInfo` | `(msg) => void` | Open message info panel | -| `onMarkAsUnread` | `(msg) => void` | Mark as unread | -| `onFlagMessage` | `(msg) => void` | Open flag/report dialog | -| `showToast` | `(text) => void` | Show a toast notification | -| `getTextFormatters` | `() => Formatter[]` | Get text formatters for caption rendering | -| `publish` | `(event) => void` | Publish a UI event | - ---- - -## Next Steps - - - - Text rendering, mentions, markdown, URLs - - - Image grid, captions, fullscreen viewer - - - Build your own plugin from scratch - - - URL, mentions, markdown, and custom formatters - - diff --git a/ui-kit/react/v7/plugins/polls.mdx b/ui-kit/react/v7/plugins/polls.mdx deleted file mode 100644 index 538bebd69..000000000 --- a/ui-kit/react/v7/plugins/polls.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: "Polls Plugin" -description: "Renders poll messages with question, voting options, and real-time vote counts." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `polls` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `extension_poll` | -| Message Categories | `custom` | -| Included by Default | Yes | -| Bubble Component | `CometChatPollBubble` | -| Conversation Preview | Poll question text (truncated) | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Polls plugin handles messages of type `extension_poll` in category `custom`. It renders an interactive poll bubble where users can vote on options and see real-time results. - - -**Live Preview** — interact with the poll bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--poll-message) - - - - ---- - -## Bubble Rendering - -- **Question** — displayed as the poll title -- **Options** — clickable vote buttons with option text -- **Results** — percentage bars showing vote distribution after voting -- **Vote count** — total number of votes -- Lazy-loaded — the bubble component is not included in the initial bundle - -The poll data is extracted from the message's `customData`: -```json -{ - "question": "What's for lunch?", - "options": { "1": "Pizza", "2": "Sushi", "3": "Tacos" }, - "results": { "total": 5, "options": { "1": 3, "2": 1, "3": 1 }, "voters": {} } -} -``` - ---- - -## Context Menu Options - -Standard media options: React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately. - ---- - -## Conversation Preview - -Returns the poll question text (truncated to 80 characters). Falls back to `Poll` if no question is found. - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-poll-bubble` | -| Question | `.cometchat-poll-bubble__question` | -| Option | `.cometchat-poll-bubble__option` | -| Progress bar | `.cometchat-poll-bubble__progress` | -| Vote count | `.cometchat-poll-bubble__vote-count` | diff --git a/ui-kit/react/v7/plugins/stickers.mdx b/ui-kit/react/v7/plugins/stickers.mdx deleted file mode 100644 index c238787c3..000000000 --- a/ui-kit/react/v7/plugins/stickers.mdx +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: "Stickers Plugin" -description: "Renders sticker messages as full-size sticker images." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `stickers` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `extension_sticker` | -| Message Categories | `custom` | -| Included by Default | Yes | -| Bubble Component | `CometChatStickerBubble` | -| Conversation Preview | Sticker | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Stickers plugin handles messages of type `extension_sticker` in category `custom`. It renders a sticker image extracted from the message's custom data. - - -**Live Preview** — interact with the sticker bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble--sticker-message) - - - - ---- - -## Bubble Rendering - -- Renders the sticker as a full-size image (no bubble background) -- Extracts the sticker URL from the message's custom data or extension metadata -- Lazy-loaded — the bubble component is not included in the initial bundle - - -Stickers use a separate keyboard button in the composer (the smiley icon), not the attachment menu. The sticker keyboard is a standalone component (`CometChatStickersKeyboard`) rendered by the composer. - - ---- - -## Context Menu Options - -Standard media options: React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately. - ---- - -## Conversation Preview - -Returns: `Sticker` (localized via `conversation_subtitle_sticker` key) - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-sticker-bubble` | -| Sticker image | `.cometchat-sticker-bubble__image` | diff --git a/ui-kit/react/v7/plugins/text.mdx b/ui-kit/react/v7/plugins/text.mdx deleted file mode 100644 index f8f6eed0c..000000000 --- a/ui-kit/react/v7/plugins/text.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: "Text Plugin" -description: "Renders text messages with mentions, URLs, and markdown formatting." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `text` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `text` | -| Message Categories | `message` | -| Included by Default | Yes | -| Bubble Component | `CometChatTextBubble` | -| Conversation Preview | Message text (markdown stripped, mentions resolved) | -| Context Menu | React, Reply, Reply in Thread, Copy, Edit, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Text plugin handles messages of type `text` in category `message`. It renders formatted text with support for @mentions, clickable URLs, and markdown syntax (bold, italic, strikethrough, code, blockquotes, lists). - - -**Live Preview** — interact with the text message bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-text--default) - - - - ---- - -## Bubble Rendering - -The text bubble displays the message text after running it through the formatter pipeline: - -1. **Markdown** — `**bold**`, `_italic_`, `~~strike~~`, `` `code` ``, `> blockquote`, lists -2. **Mentions** — `<@uid:xxx>` tokens → styled `@DisplayName` chips -3. **URLs** — bare URLs → clickable links with `target="_blank"` - -Long messages are truncated with a "Read more" toggle (configurable via `disableTruncation` in the plugin context). - ---- - -## Context Menu Options - -| Option | Condition | Action | -| --- | --- | --- | -| React | Always | Opens emoji picker | -| Reply | Always | Sets reply-to in composer | -| Reply in Thread | Not in thread | Opens thread view | -| Copy | Always | Copies plain text (markdown stripped, mentions resolved) to clipboard | -| Edit | Sender only | Enters edit mode in composer | -| Info | Sender only | Opens message info panel | -| Delete | Sender only | Shows delete confirmation | -| Report | Receiver only | Opens flag/report dialog | -| Mark Unread | Receiver only | Marks message as unread | -| Message Privately | Receiver, group only | Opens 1:1 chat with sender | - ---- - -## Conversation Preview - -Returns the message text with markdown stripped and mentions resolved to display names. Example: `@John: Check the **docs**` → `@John: Check the docs` - ---- - -## Text Formatters - -The text plugin provides three built-in formatters via `getTextFormatters()`: - -| Formatter | Priority | What it does | -| --- | --- | --- | -| `CometChatMarkdownFormatter` | 10 | Converts markdown syntax to HTML | -| `CometChatMentionsFormatter` | 50 | Resolves `<@uid:xxx>` tokens to styled mention chips | -| `CometChatUrlFormatter` | 100 | Converts bare URLs to clickable `
` tags | - -Formatters run in priority order (lower = first). Each receives the output of the previous formatter. - -For custom formatters, see [Text Formatters](/ui-kit/react/v7/plugins/text-formatters). - ---- - -## CSS Selectors - -| Target | Selector | -| --- | --- | -| Bubble root | `.cometchat-text-bubble` | -| Text content | `.cometchat-text-bubble__text` | -| Mention chip | `.cometchat-text-bubble__mention` | -| Link | `.cometchat-link` | -| Read more toggle | `.cometchat-text-bubble__read-more` | diff --git a/ui-kit/react/v7/plugins/video.mdx b/ui-kit/react/v7/plugins/video.mdx deleted file mode 100644 index a048ee769..000000000 --- a/ui-kit/react/v7/plugins/video.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: "Video Plugin" -description: "Renders video messages with inline player, thumbnail grid, and caption support." ---- - - - -| Field | Value | -| --- | --- | -| Plugin ID | `video` | -| Package | `@cometchat/chat-uikit-react` | -| Message Types | `video` | -| Message Categories | `message` | -| Included by Default | Yes | -| Bubble Component | `CometChatVideoBubble` | -| Conversation Preview | Video | -| Context Menu | React, Reply, Reply in Thread, Info, Delete, Report, Mark Unread, Message Privately | - - - -## Overview - -The Video plugin handles messages of type `video` in category `message`. Single videos render with an inline HTML5 player. Multiple videos display as a thumbnail grid with play overlays. - - -**Live Preview** — interact with the video message bubble. - -[Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-bubbles-message-bubble-video--default) - - - - ---- - -## Bubble Rendering - -- **Single video** — inline `