diff --git a/docs.json b/docs.json
index ad3c1f53d..28e42a371 100644
--- a/docs.json
+++ b/docs.json
@@ -531,9 +531,14 @@
"ui-kit/react/components/message-bubble",
"ui-kit/react/components/text-bubble",
"ui-kit/react/components/image-bubble",
+ "ui-kit/react/components/images-bubble",
"ui-kit/react/components/video-bubble",
+ "ui-kit/react/components/videos-bubble",
"ui-kit/react/components/audio-bubble",
+ "ui-kit/react/components/audios-bubble",
+ "ui-kit/react/components/voice-note-bubble",
"ui-kit/react/components/file-bubble",
+ "ui-kit/react/components/files-bubble",
"ui-kit/react/components/poll-bubble",
"ui-kit/react/components/sticker-bubble",
"ui-kit/react/components/collaborative-document-bubble",
diff --git a/ui-kit/react/components/audios-bubble.mdx b/ui-kit/react/components/audios-bubble.mdx
new file mode 100644
index 000000000..7eda64398
--- /dev/null
+++ b/ui-kit/react/components/audios-bubble.mdx
@@ -0,0 +1,206 @@
+---
+title: "Audios Bubble"
+sidebarTitle: "Audios Bubble"
+description: "A batch-aware bubble that renders one or more audio file attachments with inline playback cards, seek controls, and download."
+---
+
+
+```json
+{
+ "component": "CometChatAudiosBubble",
+ "package": "@cometchat/chat-uikit-react",
+ "import": "import { CometChatAudiosBubble } from \"@cometchat/chat-uikit-react\";",
+ "description": "Batch-aware audio bubble for attached audio files. Renders stacked audio cards with play/pause, seekable slider, duration, and download. NOT used for voice notes — see CometChatVoiceNoteBubble.",
+ "cssRootClass": ".cometchat-audios-bubble",
+ "selfExtracting": true,
+ "multiAttachment": 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[]" },
+ "batchPosition": { "type": "\"first\" | \"middle\" | \"last\" | \"single\"", "note": "Controls corner-radius styling within a batch group." },
+ "className": { "type": "string" }
+ }
+ }
+}
+```
+
+
+## Overview
+
+`CometChatAudiosBubble` renders audio file attachment(s) as stacked playback cards. It is **self-extracting**: pass the SDK `message` and the bubble derives the audio attachments and caption itself.
+
+This is the **multi-attachment replacement** for `CometChatAudioBubble` when dealing with attached audio files. It renders when `enableMultipleAttachments` is `true` (the default in v7) and the audio message does **not** have `audioType: "voice_note"` in its metadata. When the prop is `false`, the legacy `CometChatAudioBubble` is used for all audio.
+
+
+**Audio files vs Voice notes.** The audio plugin routes messages by the `audioType` metadata key:
+- **No `audioType`** (attached audio files) → `CometChatAudiosBubble` (this component)
+- **`audioType: "voice_note"`** (recorded via voice recorder) → [CometChatVoiceNoteBubble](/ui-kit/react/components/voice-note-bubble)
+
+This distinction is automatic — you don't need to configure it.
+
+
+Key capabilities:
+
+- **Stacked audio cards** — one card per audio attachment with filename, play/pause, seekable slider, elapsed/total time
+- **Inline playback** — plays audio directly in the bubble without a fullscreen viewer
+- **Download button** — download individual audio files
+- **Batch position awareness** — adjusts corner radius based on position within a multi-message batch group
+- **Caption support** — optional caption rendered below the cards
+
+{/* TODO: Add screenshot showing audios bubble with multiple audio cards */}
+
+---
+
+## Usage
+
+```tsx
+import { CometChat } from "@cometchat/chat-sdk-javascript";
+import { CometChatAudiosBubble } from "@cometchat/chat-uikit-react";
+
+function AudioFilesMessage({ message }: { message: CometChat.MediaMessage }) {
+ return ;
+}
+```
+
+---
+
+## Audio Card Layout
+
+Each attachment renders as a card with:
+
+| Element | Description |
+| --- | --- |
+| Play/Pause button | Toggles playback for that audio file |
+| Filename | Display name of the audio file |
+| Seek slider | Seekable progress bar showing current position |
+| Time display | `currentTime / totalDuration` in `m:ss` format |
+| Download button | Downloads the audio file |
+
+When a message has multiple audio attachments, cards stack vertically.
+
+{/* TODO: Add Storybook embed showing single and multi-audio card layouts */}
+
+---
+
+## Batch Position
+
+When multiple media messages are sent together (sharing the same `batchId`), each message receives a `batchPosition` that controls its visual grouping:
+
+| Position | Behavior |
+| --- | --- |
+| `first` | Rounded top corners, flat bottom |
+| `middle` | Flat top and bottom (tight grouping) |
+| `last` | Flat top, rounded bottom corners |
+| `single` | All corners rounded (standalone message) |
+
+The `batchPosition` is computed automatically by the message list. You only need to pass it when using the bubble standalone outside of `CometChatMessageList`.
+
+---
+
+## Props
+
+### message
+
+The audio message. The bubble extracts its 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` |
+
+---
+
+### batchPosition
+
+Position within a multi-attachment batch group. Controls corner-radius styling.
+
+| | |
+| --- | --- |
+| Type | `"first" \| "middle" \| "last" \| "single"` |
+| Default | `undefined` |
+
+---
+
+### className
+
+Additional CSS class applied to the root element.
+
+| | |
+| --- | --- |
+| Type | `string` |
+| Default | `undefined` |
+
+---
+
+## CSS Selectors
+
+| Target | Selector |
+| --- | --- |
+| Root | `.cometchat-audios-bubble` |
+| Incoming variant | `.cometchat-audios-bubble--incoming` |
+| Outgoing variant | `.cometchat-audios-bubble--outgoing` |
+| Container | `.cometchat-audios-bubble__container` |
+| Multi-card container | `.cometchat-audios-bubble__container--multi` |
+| Audio card | `.cometchat-audios-bubble__card` |
+| Play button | `.cometchat-audios-bubble__play-btn` |
+| Play button icon | `.cometchat-audios-bubble__play-btn-icon` |
+| Card body (name + slider + time) | `.cometchat-audios-bubble__body` |
+| Filename | `.cometchat-audios-bubble__name` |
+| Seek slider | `.cometchat-audios-bubble__slider` |
+| Time display | `.cometchat-audios-bubble__time` |
+| Expand/collapse toggle | `.cometchat-audios-bubble__toggle` |
+| Caption | `.cometchat-audios-bubble__caption` |
+
+---
+
+## Relationship to Legacy Audio Bubble
+
+| | `CometChatAudioBubble` (legacy) | `CometChatAudiosBubble` (v7 multi-attachment) |
+| --- | --- | --- |
+| Used when | `enableMultipleAttachments: false` | `enableMultipleAttachments: true` + no `audioType: "voice_note"` |
+| Multiple attachments | No | Yes (stacked cards) |
+| Batch grouping | No | Yes (`batchPosition` prop) |
+| Audio routing | All audio messages | Only attached audio files (not voice notes) |
+
+---
+
+## Next Steps
+
+
+
+ Waveform bubble for recorded voice notes
+
+
+ Single-attachment audio bubble
+
+
+ Multi-attachment file bubble
+
+
+ Enable multi-attachment staging tray
+
+
diff --git a/ui-kit/react/components/files-bubble.mdx b/ui-kit/react/components/files-bubble.mdx
new file mode 100644
index 000000000..9c2e19b08
--- /dev/null
+++ b/ui-kit/react/components/files-bubble.mdx
@@ -0,0 +1,213 @@
+---
+title: "Files Bubble"
+sidebarTitle: "Files Bubble"
+description: "A batch-aware bubble that renders one or more generic file attachments with file-type icons, metadata, download, and a collapsible list."
+---
+
+
+```json
+{
+ "component": "CometChatFilesBubble",
+ "package": "@cometchat/chat-uikit-react",
+ "import": "import { CometChatFilesBubble } from \"@cometchat/chat-uikit-react\";",
+ "description": "Batch-aware file bubble. Extracts file attachments and caption from a MediaMessage; renders stacked file cards with type icons, name, size, extension, and download. Collapses to 3 cards with '+N more' expander.",
+ "cssRootClass": ".cometchat-files-bubble",
+ "selfExtracting": true,
+ "multiAttachment": true,
+ "props": {
+ "data": {
+ "message": { "type": "CometChat.MediaMessage", "required": true, "note": "Drives extraction of file attachments and caption." },
+ "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." },
+ "textFormatters": { "type": "CometChatTextFormatter[]" },
+ "batchPosition": { "type": "\"first\" | \"middle\" | \"last\" | \"single\"", "note": "Controls corner-radius styling within a batch group." },
+ "className": { "type": "string" }
+ }
+ }
+}
+```
+
+
+## Overview
+
+`CometChatFilesBubble` renders generic file attachment(s) as stacked file cards. It is **self-extracting**: pass the SDK `message` and the bubble derives the file attachments and caption itself.
+
+This is the **multi-attachment replacement** for `CometChatFileBubble`. It renders when `enableMultipleAttachments` is `true` (the default in v7). When the prop is `false`, the legacy `CometChatFileBubble` is used instead.
+
+Key capabilities:
+
+- **Stacked file cards** — one card per file with type icon, filename, extension label, and file size
+- **File-type icons** — recognizes PDF, Word, Excel, PowerPoint, text, zip, audio, video, and image extensions
+- **Collapsible list** — shows up to 3 files initially, with a "+N more" toggle to expand
+- **Download button** — download individual files
+- **Batch position awareness** — adjusts corner radius based on position within a multi-message batch group
+- **Caption support** — optional caption rendered below the cards
+
+{/* TODO: Add screenshot showing files bubble with multiple file cards and expand toggle */}
+
+---
+
+## Usage
+
+```tsx
+import { CometChat } from "@cometchat/chat-sdk-javascript";
+import { CometChatFilesBubble } from "@cometchat/chat-uikit-react";
+
+function FileMessage({ message }: { message: CometChat.MediaMessage }) {
+ return ;
+}
+```
+
+---
+
+## File Card Layout
+
+Each attachment renders as a card with:
+
+| Element | Description |
+| --- | --- |
+| File-type icon | Color-coded icon based on file extension |
+| Filename | Display name of the file |
+| Meta label | Extension (uppercase) and human-readable file size |
+| Download button | Downloads the file |
+
+When a message has more than 3 file attachments, the list is initially collapsed with a toggle showing "+N more". Clicking the toggle expands to show all files.
+
+### Supported File-Type Icons
+
+| Icon | Extensions |
+| --- | --- |
+| PDF | `pdf` |
+| Word | `doc`, `docx` |
+| Excel | `xls`, `xlsx`, `csv` |
+| PowerPoint | `ppt`, `pptx` |
+| Text | `txt`, `rtf` |
+| Archive | `zip`, `rar`, `7z`, `gz` |
+| Audio | `mp3`, `wav`, `m4a`, `aac`, `ogg` |
+| Video | `mov`, `mp4`, `avi`, `mkv` |
+| Image | `jpg`, `jpeg`, `png`, `gif`, `webp`, `bmp`, `svg`, `heic`, `heif` |
+| Unsupported | All other extensions |
+
+{/* TODO: Add Storybook embed showing collapsed and expanded file lists */}
+
+---
+
+## Batch Position
+
+When multiple media messages are sent together (sharing the same `batchId`), each message receives a `batchPosition` that controls its visual grouping:
+
+| Position | Behavior |
+| --- | --- |
+| `first` | Rounded top corners, flat bottom |
+| `middle` | Flat top and bottom (tight grouping) |
+| `last` | Flat top, rounded bottom corners |
+| `single` | All corners rounded (standalone message) |
+
+The `batchPosition` is computed automatically by the message list. You only need to pass it when using the bubble standalone outside of `CometChatMessageList`.
+
+---
+
+## Props
+
+### message
+
+The file message. The bubble extracts its 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` |
+
+---
+
+### batchPosition
+
+Position within a multi-attachment batch group. Controls corner-radius styling.
+
+| | |
+| --- | --- |
+| Type | `"first" \| "middle" \| "last" \| "single"` |
+| Default | `undefined` |
+
+---
+
+### className
+
+Additional CSS class applied to the root element.
+
+| | |
+| --- | --- |
+| Type | `string` |
+| Default | `undefined` |
+
+---
+
+## CSS Selectors
+
+| Target | Selector |
+| --- | --- |
+| Root | `.cometchat-files-bubble` |
+| Incoming variant | `.cometchat-files-bubble--incoming` |
+| Outgoing variant | `.cometchat-files-bubble--outgoing` |
+| Container | `.cometchat-files-bubble__container` |
+| Multi-card container | `.cometchat-files-bubble__container--multi` |
+| File card | `.cometchat-files-bubble__card` |
+| File-type icon wrapper | `.cometchat-files-bubble__card-icon` |
+| File-type icon image | `.cometchat-files-bubble__card-icon-img` |
+| Card text area | `.cometchat-files-bubble__card-text` |
+| Filename | `.cometchat-files-bubble__card-name` |
+| Meta (extension + size) | `.cometchat-files-bubble__card-meta` |
+| Expand/collapse toggle | `.cometchat-files-bubble__toggle` |
+| Caption | `.cometchat-files-bubble__caption` |
+
+---
+
+## Relationship to Legacy File Bubble
+
+| | `CometChatFileBubble` (legacy) | `CometChatFilesBubble` (v7 multi-attachment) |
+| --- | --- | --- |
+| Used when | `enableMultipleAttachments: false` | `enableMultipleAttachments: true` (default) |
+| Multiple attachments | No | Yes (stacked cards with collapse) |
+| Batch grouping | No | Yes (`batchPosition` prop) |
+| File-type icons | Basic | Color-coded per extension type |
+| Collapse/expand | No | Yes (3 visible, "+N more" toggle) |
+
+---
+
+## Next Steps
+
+
+
+ Single-attachment file bubble
+
+
+ Multi-attachment image bubble with grid layouts
+
+
+ Configure multi-attachment rendering
+
+
+ Enable multi-attachment staging tray
+
+
diff --git a/ui-kit/react/components/images-bubble.mdx b/ui-kit/react/components/images-bubble.mdx
new file mode 100644
index 000000000..4ac04d151
--- /dev/null
+++ b/ui-kit/react/components/images-bubble.mdx
@@ -0,0 +1,222 @@
+---
+title: "Images Bubble"
+sidebarTitle: "Images Bubble"
+description: "A batch-aware bubble that renders one or more image attachments with adaptive grid layouts, a caption, and a fullscreen gallery viewer."
+---
+
+
+```json
+{
+ "component": "CometChatImagesBubble",
+ "package": "@cometchat/chat-uikit-react",
+ "import": "import { CometChatImagesBubble } from \"@cometchat/chat-uikit-react\";",
+ "description": "Batch-aware image bubble. Extracts image attachments and caption from a MediaMessage; renders adaptive grid layouts (single, 2-col, 2x2, overflow) and opens a fullscreen gallery viewer.",
+ "cssRootClass": ".cometchat-images-bubble",
+ "selfExtracting": true,
+ "multiAttachment": 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[]" },
+ "batchPosition": { "type": "\"first\" | \"middle\" | \"last\" | \"single\"", "note": "Controls corner-radius styling within a batch group." },
+ "placeholderImage": { "type": "string" },
+ "onImageClicked": { "type": "(attachment, index) => void" },
+ "className": { "type": "string" }
+ }
+ }
+}
+```
+
+
+## Overview
+
+`CometChatImagesBubble` renders the image attachment(s) of a media message with batch-aware styling. It is **self-extracting**: pass the SDK `message` and the bubble derives its attachments, caption, and alignment itself.
+
+This is the **multi-attachment replacement** for `CometChatImageBubble`. It renders when `enableMultipleAttachments` is `true` (the default in v7). When the prop is `false`, the legacy `CometChatImageBubble` is used instead.
+
+Key capabilities:
+
+- **Adaptive grid layouts** — single image, 2-column, 2×2 grid, and overflow (+N) based on attachment count
+- **Fullscreen gallery viewer** — click any image to open a paginated fullscreen gallery
+- **Batch position awareness** — adjusts corner radius based on position within a multi-message batch group
+- **Placeholder loading** — shows a configurable placeholder while images load
+
+{/* TODO: Add screenshot showing grid layouts (single, 2-col, 2x2, overflow) */}
+
+---
+
+## Usage
+
+```tsx
+import { CometChat } from "@cometchat/chat-sdk-javascript";
+import { CometChatImagesBubble } from "@cometchat/chat-uikit-react";
+
+function ImageMessage({ message }: { message: CometChat.MediaMessage }) {
+ return ;
+}
+```
+
+---
+
+## Grid Layouts
+
+The bubble automatically selects a layout based on the number of image attachments:
+
+| Attachment Count | Layout | Description |
+| --- | --- | --- |
+| 1 | `single` | Full-width single image |
+| 2 | `grid` (2-col) | Side-by-side images |
+| 3 | `grid` (three) | 2-col grid with one spanning |
+| 4 | `grid-2x2` | 2×2 even grid |
+| 5+ | `overflow` | 2×2 grid with last tile showing "+N" overlay |
+
+{/* TODO: Add Storybook embed or screenshot showing each layout variant */}
+
+---
+
+## Batch Position
+
+When multiple media messages are sent together (sharing the same `batchId`), each message receives a `batchPosition` that controls its visual grouping:
+
+| Position | Behavior |
+| --- | --- |
+| `first` | Rounded top corners, flat bottom |
+| `middle` | Flat top and bottom (tight grouping) |
+| `last` | Flat top, rounded bottom corners |
+| `single` | All corners rounded (standalone message) |
+
+The `batchPosition` is computed automatically by the message list. You only need to pass it when using the bubble standalone outside of `CometChatMessageList`.
+
+---
+
+## Props
+
+### message
+
+The image message. The bubble extracts its 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` |
+
+---
+
+### batchPosition
+
+Position within a multi-attachment batch group. Controls corner-radius styling.
+
+| | |
+| --- | --- |
+| Type | `"first" \| "middle" \| "last" \| "single"` |
+| Default | `undefined` |
+
+---
+
+### placeholderImage
+
+Custom placeholder image URL shown while the image is loading. Falls back to a default photo icon.
+
+| | |
+| --- | --- |
+| Type | `string` |
+| Default | built-in placeholder |
+
+---
+
+### onImageClicked
+
+Callback fired when an image tile is clicked (in addition to opening the fullscreen viewer).
+
+| | |
+| --- | --- |
+| Type | `(attachment: CometChatImagesBubbleAttachment, index: number) => void` |
+| Default | `undefined` |
+
+---
+
+### className
+
+Additional CSS class applied to the root element.
+
+| | |
+| --- | --- |
+| Type | `string` |
+| Default | `undefined` |
+
+---
+
+## CSS Selectors
+
+| Target | Selector |
+| --- | --- |
+| Root | `.cometchat-images-bubble` |
+| Incoming variant | `.cometchat-images-bubble--incoming` |
+| Outgoing variant | `.cometchat-images-bubble--outgoing` |
+| Single layout | `.cometchat-images-bubble--single` |
+| Grid container | `.cometchat-images-bubble__grid` |
+| 2-column grid | `.cometchat-images-bubble__grid--two-col` |
+| 3-image grid | `.cometchat-images-bubble__grid--three` |
+| 2×2 grid | `.cometchat-images-bubble__grid--2x2` |
+| Overflow grid | `.cometchat-images-bubble__grid--overflow` |
+| Image wrapper | `.cometchat-images-bubble__image-wrapper` |
+| Image element | `.cometchat-images-bubble__image` |
+| Placeholder | `.cometchat-images-bubble__placeholder` |
+| Overflow tile | `.cometchat-images-bubble__overflow-tile` |
+| Overflow overlay | `.cometchat-images-bubble__overflow-overlay` |
+| Overflow text (+N) | `.cometchat-images-bubble__overflow-text` |
+| Container | `.cometchat-images-bubble__container` |
+| Caption | `.cometchat-images-bubble__caption` |
+
+---
+
+## Relationship to Legacy Image Bubble
+
+| | `CometChatImageBubble` (legacy) | `CometChatImagesBubble` (v7 multi-attachment) |
+| --- | --- | --- |
+| Used when | `enableMultipleAttachments: false` | `enableMultipleAttachments: true` (default) |
+| Grid layouts | No | Yes (single, 2-col, 2×2, overflow) |
+| Batch grouping | No | Yes (`batchPosition` prop) |
+| Fullscreen viewer | Single image | Gallery with pagination |
+
+---
+
+## Next Steps
+
+
+
+ Multi-attachment video bubble with grid layouts
+
+
+ Single-attachment image bubble
+
+
+ Configure multi-attachment rendering
+
+
+ Enable multi-attachment staging tray
+
+
diff --git a/ui-kit/react/components/message-composer.mdx b/ui-kit/react/components/message-composer.mdx
index 6ec240902..d32cb6a18 100644
--- a/ui-kit/react/components/message-composer.mdx
+++ b/ui-kit/react/components/message-composer.mdx
@@ -51,9 +51,9 @@ description: "Rich text input with attachments, emoji, voice recording, mentions
"attachmentOptions": { "type": "CometChatComposerAttachmentOption[]", "default": "undefined" },
"hideAttachmentOptions": { "type": "CometChatAttachmentHideOptions", "default": "undefined" },
"showAttachmentPreview": { "type": "boolean", "default": true },
- "maxAttachments": { "type": "number", "default": 10 },
- "allowedFileTypes": { "type": "string[]", "default": "undefined" },
- "maxFileSize": { "type": "number", "default": "undefined" }
+ "enableMultipleAttachments": { "type": "boolean", "default": true, "note": "Enable multi-attachment staging tray and batch send. Set false for legacy single-select behavior." },
+ "disableDragAndDrop": { "type": "boolean", "default": false, "note": "Disable drag-and-drop file upload." },
+ "allowedFileTypes": { "type": "string[]", "default": "undefined" }
},
"hideButtons": {
"hideAttachmentButton": { "type": "boolean", "default": false },
@@ -671,36 +671,36 @@ Whether to show attachment preview thumbnails before sending.
---
-#### maxAttachments
+#### enableMultipleAttachments
-Maximum number of attachments allowed.
+Enable multi-attachment staging tray and batch send. When `true` (default), selecting an attachment option stages files in a tray for a single batched send. When `false`, each attachment option reverts to legacy single-select, send-immediately behavior.
| | |
| --- | --- |
-| Type | `number` |
-| Default | `10` |
+| Type | `boolean` |
+| Default | `true` |
---
-#### allowedFileTypes
+#### disableDragAndDrop
-Allowed file MIME types for attachments.
+Disable drag-and-drop file upload on the composer.
| | |
| --- | --- |
-| Type | `string[]` |
-| Default | `undefined` (all types allowed) |
+| Type | `boolean` |
+| Default | `false` |
---
-#### maxFileSize
+#### allowedFileTypes
-Maximum file size in bytes.
+Allowed file MIME types for attachments.
| | |
| --- | --- |
-| Type | `number` |
-| Default | `undefined` (no limit) |
+| Type | `string[]` |
+| Default | `undefined` (all types allowed) |
---
@@ -1116,6 +1116,15 @@ Called when a mention is selected from the suggestions list.
| Send button | `.cometchat-message-composer__send-button-wrapper` |
| Sticker button | `.cometchat-message-composer__sticker-button-wrapper` |
| AI button | `.cometchat-message-composer__ai-button-wrapper` |
+| Staging tray | `.cometchat-message-composer__tray` |
+| Tray overlay (upload status) | `.cometchat-message-composer__tray-overlay` |
+| Tray audio card body | `.cometchat-message-composer__tray-audio-body` |
+| Tray audio name | `.cometchat-message-composer__tray-audio-name` |
+| Tray audio slider | `.cometchat-message-composer__tray-audio-slider` |
+| Tray audio time | `.cometchat-message-composer__tray-audio-time` |
+| Tray retry button | `.cometchat-message-composer__tray-retry-button` |
+| Tray rejected icon | `.cometchat-message-composer__tray-rejected-icon` |
+| Drag-and-drop overlay | `.cometchat-message-composer__drop-zone` |
---
diff --git a/ui-kit/react/components/message-list.mdx b/ui-kit/react/components/message-list.mdx
index 74d698780..68e312e53 100644
--- a/ui-kit/react/components/message-list.mdx
+++ b/ui-kit/react/components/message-list.mdx
@@ -77,7 +77,8 @@ description: "Scrollable message feed with plugin-based bubble rendering, reacti
"showConversationStarters": { "type": "boolean", "default": false },
"showMarkAsUnreadOption": { "type": "boolean", "default": false },
"disableTruncation": { "type": "boolean", "default": false },
- "isAgentChat": { "type": "boolean", "default": false }
+ "isAgentChat": { "type": "boolean", "default": false },
+ "enableMultipleAttachments": { "type": "boolean", "default": true, "note": "Enable batch-aware plural bubbles (ImagesBubble, VideosBubble, AudiosBubble, FilesBubble) and batch chrome. Set false for legacy singular bubbles." }
},
"optionToggles": {
"hideReplyOption": { "type": "boolean", "default": false },
@@ -893,6 +894,17 @@ Whether this is an AI agent chat. Suppresses moderation UI and enables agent-spe
---
+### enableMultipleAttachments
+
+Enable batch-aware rendering for multi-attachment messages. When `true` (default), media messages render using the plural bubble components (`CometChatImagesBubble`, `CometChatVideosBubble`, `CometChatAudiosBubble`, `CometChatFilesBubble`) with batch-group chrome (shared avatar/sender on the first bubble, receipts on the last). When `false`, legacy singular bubbles render.
+
+| | |
+| --- | --- |
+| Type | `boolean` |
+| Default | `true` |
+
+---
+
### Option Toggles
---
diff --git a/ui-kit/react/components/videos-bubble.mdx b/ui-kit/react/components/videos-bubble.mdx
new file mode 100644
index 000000000..3c028eb45
--- /dev/null
+++ b/ui-kit/react/components/videos-bubble.mdx
@@ -0,0 +1,217 @@
+---
+title: "Videos Bubble"
+sidebarTitle: "Videos Bubble"
+description: "A batch-aware bubble that renders one or more video attachments with adaptive grid layouts, poster thumbnails, and a fullscreen viewer."
+---
+
+
+```json
+{
+ "component": "CometChatVideosBubble",
+ "package": "@cometchat/chat-uikit-react",
+ "import": "import { CometChatVideosBubble } from \"@cometchat/chat-uikit-react\";",
+ "description": "Batch-aware video bubble. Extracts video attachments and caption from a MediaMessage; renders adaptive grid layouts with poster thumbnails and opens a fullscreen viewer.",
+ "cssRootClass": ".cometchat-videos-bubble",
+ "selfExtracting": true,
+ "multiAttachment": 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[]" },
+ "batchPosition": { "type": "\"first\" | \"middle\" | \"last\" | \"single\"", "note": "Controls corner-radius styling within a batch group." },
+ "onVideoClicked": { "type": "(attachment, index) => void" },
+ "className": { "type": "string" }
+ }
+ }
+}
+```
+
+
+## Overview
+
+`CometChatVideosBubble` renders the video attachment(s) of a media message with batch-aware styling. It is **self-extracting**: pass the SDK `message` and the bubble derives its attachments, caption, and alignment itself.
+
+This is the **multi-attachment replacement** for `CometChatVideoBubble`. It renders when `enableMultipleAttachments` is `true` (the default in v7). When the prop is `false`, the legacy `CometChatVideoBubble` is used instead.
+
+Key capabilities:
+
+- **Adaptive grid layouts** — single video, 2-column, 2×2 grid, and overflow (+N) based on attachment count
+- **Poster thumbnails** — auto-generated from the `thumbnail-generation` extension or first frame
+- **Duration overlay** — displays video duration on each tile
+- **Play icon overlay** — visual indicator on each video tile
+- **Fullscreen viewer** — click any video to open in fullscreen player
+- **Batch position awareness** — adjusts corner radius based on position within a multi-message batch group
+
+{/* TODO: Add screenshot showing video grid layouts with poster thumbnails */}
+
+---
+
+## Usage
+
+```tsx
+import { CometChat } from "@cometchat/chat-sdk-javascript";
+import { CometChatVideosBubble } from "@cometchat/chat-uikit-react";
+
+function VideoMessage({ message }: { message: CometChat.MediaMessage }) {
+ return ;
+}
+```
+
+---
+
+## Grid Layouts
+
+The bubble automatically selects a layout based on the number of video attachments:
+
+| Attachment Count | Layout | Description |
+| --- | --- | --- |
+| 1 | `single` | Full-width single video with poster |
+| 2 | `grid` (2-col) | Side-by-side video tiles |
+| 3 | `grid` (three) | 2-col grid with one spanning |
+| 4 | `grid-2x2` | 2×2 even grid |
+| 5+ | `overflow` | 2×2 grid with last tile showing "+N" overlay |
+
+Each tile shows a poster thumbnail, play icon, and duration badge.
+
+{/* TODO: Add Storybook embed or screenshot showing each layout variant */}
+
+---
+
+## Batch Position
+
+When multiple media messages are sent together (sharing the same `batchId`), each message receives a `batchPosition` that controls its visual grouping:
+
+| Position | Behavior |
+| --- | --- |
+| `first` | Rounded top corners, flat bottom |
+| `middle` | Flat top and bottom (tight grouping) |
+| `last` | Flat top, rounded bottom corners |
+| `single` | All corners rounded (standalone message) |
+
+The `batchPosition` is computed automatically by the message list. You only need to pass it when using the bubble standalone outside of `CometChatMessageList`.
+
+---
+
+## Props
+
+### message
+
+The video message. The bubble extracts its 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` |
+
+---
+
+### batchPosition
+
+Position within a multi-attachment batch group. Controls corner-radius styling.
+
+| | |
+| --- | --- |
+| Type | `"first" \| "middle" \| "last" \| "single"` |
+| Default | `undefined` |
+
+---
+
+### onVideoClicked
+
+Callback fired when a video tile is clicked.
+
+| | |
+| --- | --- |
+| Type | `(attachment: CometChatVideosBubbleAttachment, index: number) => void` |
+| Default | `undefined` |
+
+---
+
+### className
+
+Additional CSS class applied to the root element.
+
+| | |
+| --- | --- |
+| Type | `string` |
+| Default | `undefined` |
+
+---
+
+## CSS Selectors
+
+| Target | Selector |
+| --- | --- |
+| Root | `.cometchat-videos-bubble` |
+| Incoming variant | `.cometchat-videos-bubble--incoming` |
+| Outgoing variant | `.cometchat-videos-bubble--outgoing` |
+| Single layout | `.cometchat-videos-bubble--single` |
+| Grid container | `.cometchat-videos-bubble__grid` |
+| 2-column grid | `.cometchat-videos-bubble__grid--two-col` |
+| 3-video grid | `.cometchat-videos-bubble__grid--three` |
+| 2×2 grid | `.cometchat-videos-bubble__grid--2x2` |
+| Overflow grid | `.cometchat-videos-bubble__grid--overflow` |
+| Video tile | `.cometchat-videos-bubble__tile` |
+| Poster thumbnail | `.cometchat-videos-bubble__thumbnail` |
+| Play icon | `.cometchat-videos-bubble__play-icon` |
+| Duration badge | `.cometchat-videos-bubble__duration` |
+| Placeholder | `.cometchat-videos-bubble__placeholder` |
+| Overflow tile | `.cometchat-videos-bubble__overflow-tile` |
+| Overflow overlay | `.cometchat-videos-bubble__overflow-overlay` |
+| Overflow text (+N) | `.cometchat-videos-bubble__overflow-text` |
+| Container | `.cometchat-videos-bubble__container` |
+| Caption | `.cometchat-videos-bubble__caption` |
+
+---
+
+## Relationship to Legacy Video Bubble
+
+| | `CometChatVideoBubble` (legacy) | `CometChatVideosBubble` (v7 multi-attachment) |
+| --- | --- | --- |
+| Used when | `enableMultipleAttachments: false` | `enableMultipleAttachments: true` (default) |
+| Grid layouts | No | Yes (single, 2-col, 2×2, overflow) |
+| Batch grouping | No | Yes (`batchPosition` prop) |
+| Poster thumbnails | Single | Per-tile with duration overlay |
+| Fullscreen viewer | Single video | Gallery with pagination |
+
+---
+
+## Next Steps
+
+
+
+ Multi-attachment image bubble with grid layouts
+
+
+ Multi-attachment audio bubble with player cards
+
+
+ Configure multi-attachment rendering
+
+
+ Enable multi-attachment staging tray
+
+
diff --git a/ui-kit/react/components/voice-note-bubble.mdx b/ui-kit/react/components/voice-note-bubble.mdx
new file mode 100644
index 000000000..43a8dbd23
--- /dev/null
+++ b/ui-kit/react/components/voice-note-bubble.mdx
@@ -0,0 +1,174 @@
+---
+title: "Voice Note Bubble"
+sidebarTitle: "Voice Note Bubble"
+description: "A dedicated bubble for recorded voice notes with waveform playback, rendered when audio messages carry the voice_note metadata tag."
+---
+
+
+```json
+{
+ "component": "CometChatVoiceNoteBubble",
+ "package": "@cometchat/chat-uikit-react",
+ "import": "import { CometChatVoiceNoteBubble } from \"@cometchat/chat-uikit-react\";",
+ "description": "Voice note bubble. Renders for audio messages explicitly tagged audioType='voice_note'. Delegates to CometChatAudioBubble internally for waveform playback. Always standalone (no grid).",
+ "cssRootClass": ".cometchat-audio-bubble",
+ "selfExtracting": true,
+ "multiAttachment": true,
+ "props": {
+ "data": {
+ "message": { "type": "CometChat.MediaMessage", "required": true, "note": "Must have metadata audioType='voice_note'." },
+ "alignment": { "type": "\"left\" | \"right\"", "note": "Defaults to sender-vs-logged-in-user." },
+ "textFormatters": { "type": "CometChatTextFormatter[]" },
+ "batchPosition": { "type": "\"first\" | \"middle\" | \"last\" | \"single\"", "note": "Always 'single' for voice notes — they never participate in grid layouts." },
+ "className": { "type": "string" }
+ }
+ }
+}
+```
+
+
+## Overview
+
+`CometChatVoiceNoteBubble` renders audio messages that were recorded via the composer's voice recorder. It is a thin wrapper around `CometChatAudioBubble`, providing the same waveform playback UI.
+
+This bubble renders when `enableMultipleAttachments` is `true` (the default in v7) **and** the audio message carries `audioType: "voice_note"` in its metadata. Voice notes are always standalone — they never participate in batch grid layouts or multi-attachment grouping.
+
+
+**Routing logic.** The audio plugin automatically routes messages based on metadata:
+- `audioType: "voice_note"` → `CometChatVoiceNoteBubble` (this component)
+- No `audioType` (attached audio files) → [CometChatAudiosBubble](/ui-kit/react/components/audios-bubble)
+- `enableMultipleAttachments: false` → legacy [CometChatAudioBubble](/ui-kit/react/components/audio-bubble) for all audio
+
+You don't need to configure this — it's handled automatically by the plugin system.
+
+
+Key characteristics:
+
+- **Waveform playback** — play/pause, seekable progress bar, elapsed/total time
+- **Always standalone** — `batchPosition` is always `'single'`; voice notes are never grouped with other messages
+- **Metadata-driven** — only used when the message has `audioType: "voice_note"` in metadata
+- **Delegates to CometChatAudioBubble** — inherits its styling and CSS selectors
+
+{/* TODO: Add screenshot showing voice note bubble with waveform */}
+
+---
+
+## Usage
+
+```tsx
+import { CometChat } from "@cometchat/chat-sdk-javascript";
+import { CometChatVoiceNoteBubble } from "@cometchat/chat-uikit-react";
+
+function VoiceNoteMessage({ message }: { message: CometChat.MediaMessage }) {
+ return ;
+}
+```
+
+---
+
+## How Voice Notes Are Tagged
+
+When a user records audio via the composer's voice recorder, the UIKit stamps `audioType: "voice_note"` into the message metadata before sending:
+
+```json
+{
+ "metadata": {
+ "audioType": "voice_note"
+ }
+}
+```
+
+Audio files attached via the attachment menu do **not** receive this tag — they render as [CometChatAudiosBubble](/ui-kit/react/components/audios-bubble) instead.
+
+---
+
+## Props
+
+### message
+
+The audio message (voice note). The bubble delegates rendering to `CometChatAudioBubble`. **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 any caption.
+
+| | |
+| --- | --- |
+| Type | `CometChatTextFormatter[]` |
+| Default | `undefined` |
+
+---
+
+### batchPosition
+
+Batch position. Always `'single'` for voice notes — they never participate in grid layouts.
+
+| | |
+| --- | --- |
+| Type | `"first" \| "middle" \| "last" \| "single"` |
+| Default | `undefined` |
+
+---
+
+### className
+
+Additional CSS class applied to the root element.
+
+| | |
+| --- | --- |
+| Type | `string` |
+| Default | `undefined` |
+
+---
+
+## CSS Selectors
+
+`CometChatVoiceNoteBubble` delegates to `CometChatAudioBubble` — it uses the same 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
+
+
+
+ Multi-attachment audio file bubble (non-voice-notes)
+
+
+ Legacy single-attachment audio bubble
+
+
+ Voice recorder and multi-attachment staging
+
+
+ Multi-attachment image bubble
+
+
diff --git a/ui-kit/react/migration-property-changes.mdx b/ui-kit/react/migration-property-changes.mdx
index 794a883f2..556da00c7 100644
--- a/ui-kit/react/migration-property-changes.mdx
+++ b/ui-kit/react/migration-property-changes.mdx
@@ -80,6 +80,7 @@ These 8 patterns apply across all components. You do not need to look them up pe
| `onMessageDeleted` | `(message: CometChat.BaseMessage) => void` | Message deleted callback |
| `onConversationMarkedAsRead` | `(conversation) => void` | Conversation marked as read |
| `onConversationUpdated` | `(conversation) => void` | Conversation updated callback |
+| `enableMultipleAttachments` | `boolean` | Enable batch-aware rendering with plural bubbles (ImagesBubble, VideosBubble, AudiosBubble, FilesBubble) and batch chrome. Default: `true`. Set to `false` for legacy singular bubbles |
---
@@ -107,10 +108,9 @@ These 8 patterns apply across all components. You do not need to look them up pe
| `messageToReply` | `BaseMessage \| null` | Message being replied to |
| `hideAttachmentOptions` | `CometChatAttachmentHideOptions` | Object to hide specific attachment types |
| `showAttachmentPreview` | `boolean` | Show attachment preview before sending |
-| `enableDragDrop` | `boolean` | Enable drag-and-drop file upload |
-| `maxAttachments` | `number` | Max attachments per message |
-| `allowedFileTypes` | `string[]` | Allowed MIME types |
-| `maxFileSize` | `number` | Max file size in bytes |
+| `enableMultipleAttachments` | `boolean` | Enable multi-attachment staging tray and batch send. Default: `true`. Set to `false` for legacy single-select behavior |
+| `disableDragAndDrop` | `boolean` | Disable drag-and-drop file upload. Default: `false` |
+| `allowedFileTypes` | `string[]` | Allowed MIME types for attachments |
| `hideAIButton` | `boolean` | Hide AI assistant button |
| `hideLiveReaction` | `boolean` | Hide live reaction button |
| `hideError` | `boolean` | Hide error state |