Skip to content

Commit b4ba64c

Browse files
committed
feat: add MessageDeletedBubble to ComponentContext
1 parent 45e41ac commit b4ba64c

4 files changed

Lines changed: 61 additions & 68 deletions

File tree

src/components/Gallery/decisions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,15 @@ The new ModalGallery is a composition component: thumbnail grid + Modal + Galler
122122

123123
- Downstream consumers (`Image.tsx`, `AttachmentPreviewRoot.tsx`, `ComponentContext.tsx`) that use the old `ModalGalleryProps` shape will need updates in Task 8 (Exports & Public API).
124124

125-
## Decision: GalleryContainer and FixedHeightMessage use ModalGallery instead of Gallery
125+
## Decision: GalleryContainer use ModalGallery instead of Gallery
126126

127127
**Date:** 2026-02-09
128128

129129
**Context:**
130-
The old `Gallery` component was a thumbnail grid that accepted `images: Attachment[]` and `innerRefs`. The new `Gallery` is a carousel provider accepting `items: GalleryItem[]`. The `GalleryContainer` (in `AttachmentContainer.tsx`) and `FixedHeightMessage` used the old `Gallery` API.
130+
The old `Gallery` component was a thumbnail grid that accepted `images: Attachment[]` and `innerRefs`. The new `Gallery` is a carousel provider accepting `items: GalleryItem[]`. The `GalleryContainer` (in `AttachmentContainer.tsx`) used the old `Gallery` API.
131131

132132
**Decision:**
133-
Replace `Gallery` usage with `ModalGallery` in both `GalleryContainer` and `FixedHeightMessage`. Pass `attachment.images` cast to `GalleryItem[]` via `as unknown as GalleryItem[]`. The `AttachmentProps.Gallery` prop was renamed to `AttachmentProps.ModalGallery` with `ModalGalleryProps` type.
133+
Replace `Gallery` usage with `ModalGallery` in both `GalleryContainer`. Pass `attachment.images` cast to `GalleryItem[]` via `as unknown as GalleryItem[]`. The `AttachmentProps.Gallery` prop was renamed to `AttachmentProps.ModalGallery` with `ModalGalleryProps` type.
134134

135135
**Reasoning:**
136136
The old `Gallery` rendered a thumbnail grid, which is now `ModalGallery`'s responsibility. The `GalleryContainer`'s `imageAttachmentSizeHandler` and `innerRefs` logic was removed since `ModalGallery` handles its own thumbnail rendering. The type cast is necessary because `Attachment[]` (from stream-chat) is structurally compatible with `GalleryItem` for the properties used by the Gallery UI (image_url, thumb_url, fallback).

src/components/Message/MessageSimple.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import clsx from 'clsx';
33

44
import { MessageErrorIcon } from './icons';
55
import { MessageBouncePrompt as DefaultMessageBouncePrompt } from '../MessageBounce';
6-
import { MessageDeletedBubble } from './MessageDeletedBubble';
6+
import { MessageDeletedBubble as DefaultMessageDeletedBubble } from './MessageDeletedBubble';
77
import { MessageBlocked as DefaultMessageBlocked } from './MessageBlocked';
88
import { MessageActions as DefaultMessageActions } from '../MessageActions';
99
import { MessageRepliesCountButton as DefaultMessageRepliesCountButton } from './MessageRepliesCountButton';
@@ -85,6 +85,7 @@ const MessageSimpleWithContext = ({
8585
MessageBlocked = DefaultMessageBlocked,
8686
MessageBouncePrompt = DefaultMessageBouncePrompt,
8787
MessageDeleted,
88+
MessageDeletedBubble = DefaultMessageDeletedBubble,
8889
MessageIsThreadReplyInChannelButtonIndicator = DefaultMessageIsThreadReplyInChannelButtonIndicator,
8990
MessageRepliesCountButton = DefaultMessageRepliesCountButton,
9091
MessageStatus = DefaultMessageStatus,

src/components/MessageList/__tests__/VirtualizedMessageList.test.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,6 @@ jest.mock('../../Loading', () => ({
4040
LoadingIndicator: jest.fn(() => <div>LoadingIndicator</div>),
4141
}));
4242

43-
jest.mock('../../Message', () => ({
44-
FixedHeightMessage: jest.fn(({ groupedByUser }) => (
45-
<div data-testid='msg'>
46-
FixedHeightMessage groupedByUser:
47-
{groupedByUser ? 'true' : 'false'}
48-
</div>
49-
)),
50-
}));
51-
5243
async function createChannel(empty = false) {
5344
const user1 = generateUser();
5445
const user2 = generateUser();

src/context/ComponentContext.tsx

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,58 @@
11
import type { PropsWithChildren } from 'react';
22
import React, { useContext } from 'react';
33

4-
import type {
5-
AttachmentPreviewListProps,
6-
AttachmentProps,
7-
AvatarProps,
8-
AvatarStackProps,
9-
BaseImageProps,
10-
CalloutDialogProps,
11-
ChannelPreviewActionButtonsProps,
12-
DateSeparatorProps,
13-
EmojiSearchIndex,
14-
EmptyStateIndicatorProps,
15-
EventComponentProps,
16-
FileDragAndDropContentProps,
17-
FixedHeightMessageProps,
18-
GalleryProps,
19-
GiphyPreviewMessageProps,
20-
LoadingErrorIndicatorProps,
21-
LoadingIndicatorProps,
22-
MessageBouncePromptProps,
23-
MessageDeletedProps,
24-
MessageInputProps,
25-
MessageListNotificationsProps,
26-
MessageNotificationProps,
27-
MessageProps,
28-
MessageRepliesCountButtonProps,
29-
MessageStatusProps,
30-
MessageTimestampProps,
31-
MessageUIComponentProps,
32-
ModalGalleryProps,
33-
ModalProps,
34-
PinIndicatorProps,
35-
PollCreationDialogProps,
36-
PollOptionSelectorProps,
37-
QuotedMessagePreviewProps,
38-
ReactionOptions,
39-
ReactionSelectorProps,
40-
ReactionsListModalProps,
41-
ReactionsListProps,
42-
RecordingPermissionDeniedNotificationProps,
43-
ReminderNotificationProps,
44-
SendButtonProps,
45-
StartRecordingAudioButtonProps,
46-
StreamedMessageTextProps,
47-
TextareaComposerProps,
48-
ThreadHeaderProps,
49-
ThreadListItemProps,
50-
ThreadListItemUIProps,
51-
TimestampProps,
52-
TranslationIndicatorProps,
53-
TypingIndicatorProps,
54-
UnreadMessagesNotificationProps,
55-
UnreadMessagesSeparatorProps,
56-
VoiceRecordingPreviewSlotProps,
4+
import {
5+
type AttachmentPreviewListProps,
6+
type AttachmentProps,
7+
type AvatarProps,
8+
type AvatarStackProps,
9+
type BaseImageProps,
10+
type CalloutDialogProps,
11+
type ChannelPreviewActionButtonsProps,
12+
type DateSeparatorProps,
13+
type EmojiSearchIndex,
14+
type EmptyStateIndicatorProps,
15+
type EventComponentProps,
16+
type FileDragAndDropContentProps,
17+
type GalleryProps,
18+
type GiphyPreviewMessageProps,
19+
type LoadingErrorIndicatorProps,
20+
type LoadingIndicatorProps,
21+
type MessageBouncePromptProps,
22+
type MessageDeletedProps,
23+
type MessageInputProps,
24+
type MessageListNotificationsProps,
25+
type MessageNotificationProps,
26+
type MessageProps,
27+
type MessageRepliesCountButtonProps,
28+
type MessageStatusProps,
29+
type MessageTimestampProps,
30+
type MessageUIComponentProps,
31+
type ModalGalleryProps,
32+
type ModalProps,
33+
type PinIndicatorProps,
34+
type PollCreationDialogProps,
35+
type PollOptionSelectorProps,
36+
type QuotedMessagePreviewProps,
37+
type ReactionOptions,
38+
type ReactionSelectorProps,
39+
type ReactionsListModalProps,
40+
type ReactionsListProps,
41+
type RecordingPermissionDeniedNotificationProps,
42+
type ReminderNotificationProps,
43+
type SendButtonProps,
44+
type StartRecordingAudioButtonProps,
45+
type StreamedMessageTextProps,
46+
type TextareaComposerProps,
47+
type ThreadHeaderProps,
48+
type ThreadListItemProps,
49+
type ThreadListItemUIProps,
50+
type TimestampProps,
51+
type TranslationIndicatorProps,
52+
type TypingIndicatorProps,
53+
type UnreadMessagesNotificationProps,
54+
type UnreadMessagesSeparatorProps,
55+
type VoiceRecordingPreviewSlotProps,
5756
} from '../components';
5857

5958
import type {
@@ -140,8 +139,10 @@ export type ComponentContextValue = {
140139
MessageBouncePrompt?: React.ComponentType<MessageBouncePromptProps>;
141140
/** Custom UI component for a moderation-blocked message, defaults to and accepts same props as: [MessageBlocked](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageBlocked.tsx) */
142141
MessageBlocked?: React.ComponentType;
143-
/** Custom UI component for a deleted message, defaults to and accepts same props as: [MessageDeleted](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageDeleted.tsx) */
142+
/** Custom UI component for a deleted message. Has no default component */
144143
MessageDeleted?: React.ComponentType<MessageDeletedProps>;
144+
/** Custom UI component for a message bubble of a deleted message, defaults to and accepts same props as: [MessageDeletedBubble](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageDeletedBubble.tsx) */
145+
MessageDeletedBubble?: React.ComponentType;
145146
/** Custom UI component for an indicator that a message is a thread reply sent to channel list: [MessageIsThreadReplyInChannelButtonIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageIsThreadReplyInChannelButtonIndicator.tsx) */
146147
MessageIsThreadReplyInChannelButtonIndicator?: React.ComponentType;
147148
MessageListMainPanel?: React.ComponentType<PropsWithChildrenOnly>;
@@ -249,7 +250,7 @@ export type ComponentContextValue = {
249250
/** Component used to play video. If not provided, ReactPlayer is used as a default video player. */
250251
VideoPlayer?: React.ComponentType<VideoPlayerProps>;
251252
/** Custom UI component to display a message in the `VirtualizedMessageList`, does not have a default implementation */
252-
VirtualMessage?: React.ComponentType<FixedHeightMessageProps>;
253+
VirtualMessage?: React.ComponentType<MessageUIComponentProps>;
253254
/** Custom UI component to wrap MessageList children. Default is the `ul` tag */
254255
MessageListWrapper?: React.ComponentType<PropsWithChildren>;
255256
/** Custom UI component to wrap each element of MessageList. Default is the `li` tag */

0 commit comments

Comments
 (0)