From ec6af3ef160d5b072a4a9a88abbe86d60b6d7e33 Mon Sep 17 00:00:00 2001 From: Anton Arnautov Date: Wed, 7 Jan 2026 15:45:28 +0100 Subject: [PATCH 1/2] Initial commit --- examples/vite/src/App.tsx | 63 ++++---- src/components/Channel/Channel.tsx | 250 ++--------------------------- src/context/ComponentContext.tsx | 3 + 3 files changed, 50 insertions(+), 266 deletions(-) diff --git a/examples/vite/src/App.tsx b/examples/vite/src/App.tsx index bf3674560..9c9d6dc48 100644 --- a/examples/vite/src/App.tsx +++ b/examples/vite/src/App.tsx @@ -20,6 +20,7 @@ import { useCreateChatClient, VirtualizedMessageList as MessageList, Window, + WithComponents, } from 'stream-chat-react'; import { createTextComposerEmojiMiddleware, EmojiPicker } from 'stream-chat-react/emojis'; import { init, SearchIndex } from 'emoji-mart'; @@ -103,36 +104,38 @@ const App = () => { if (!chatClient) return <>Loading...; return ( - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + ); }; diff --git a/src/components/Channel/Channel.tsx b/src/components/Channel/Channel.tsx index 32fc8fe0f..c7311fe53 100644 --- a/src/components/Channel/Channel.tsx +++ b/src/components/Channel/Channel.tsx @@ -41,7 +41,6 @@ import { useIsMounted } from './hooks/useIsMounted'; import type { OnMentionAction } from './hooks/useMentionsHandlers'; import { useMentionsHandlers } from './hooks/useMentionsHandlers'; -import type { LoadingErrorIndicatorProps } from '../Loading'; import { LoadingErrorIndicator as DefaultLoadingErrorIndicator, LoadingChannel as DefaultLoadingIndicator, @@ -50,7 +49,6 @@ import { import type { ChannelActionContextValue, ChannelNotifications, - ComponentContextValue, MarkReadWrapperOptions, } from '../../context'; import { @@ -58,8 +56,8 @@ import { ChannelStateProvider, TypingProvider, useChatContext, + useComponentContext, useTranslationContext, - WithComponents, } from '../../context'; import { CHANNEL_CONTAINER_ID } from './constants'; @@ -93,79 +91,7 @@ import { import { useSearchFocusedMessage } from '../../experimental/Search/hooks'; import { WithAudioPlayback } from '../AudioPlayback'; -type ChannelPropsForwardedToComponentContext = Pick< - ComponentContextValue, - | 'Attachment' - | 'AttachmentPreviewList' - | 'AttachmentSelector' - | 'AttachmentSelectorInitiationButtonContents' - | 'AudioRecorder' - | 'AutocompleteSuggestionItem' - | 'AutocompleteSuggestionList' - | 'Avatar' - | 'BaseImage' - | 'CooldownTimer' - | 'CustomMessageActionsList' - | 'DateSeparator' - | 'EditMessageInput' - | 'EditMessageModal' - | 'EmojiPicker' - | 'emojiSearchIndex' - | 'EmptyStateIndicator' - | 'FileUploadIcon' - | 'GiphyPreviewMessage' - | 'HeaderComponent' - | 'Input' - | 'LinkPreviewList' - | 'LoadingIndicator' - | 'ShareLocationDialog' - | 'Message' - | 'MessageActions' - | 'MessageBouncePrompt' - | 'MessageBlocked' - | 'MessageDeleted' - | 'MessageIsThreadReplyInChannelButtonIndicator' - | 'MessageListNotifications' - | 'MessageListMainPanel' - | 'MessageNotification' - | 'MessageOptions' - | 'MessageRepliesCountButton' - | 'MessageStatus' - | 'MessageSystem' - | 'MessageTimestamp' - | 'Modal' - | 'ModalGallery' - | 'PinIndicator' - | 'PollActions' - | 'PollContent' - | 'PollCreationDialog' - | 'PollHeader' - | 'PollOptionSelector' - | 'QuotedMessage' - | 'QuotedMessagePreview' - | 'QuotedPoll' - | 'reactionOptions' - | 'ReactionSelector' - | 'ReactionsList' - | 'ReactionsListModal' - | 'ReminderNotification' - | 'SendButton' - | 'SendToChannelCheckbox' - | 'StartRecordingAudioButton' - | 'TextareaComposer' - | 'ThreadHead' - | 'ThreadHeader' - | 'ThreadStart' - | 'Timestamp' - | 'TypingIndicator' - | 'UnreadMessagesNotification' - | 'UnreadMessagesSeparator' - | 'VirtualMessage' - | 'StopAIGenerationButton' - | 'StreamedMessageText' ->; - -export type ChannelProps = ChannelPropsForwardedToComponentContext & { +export type ChannelProps = { /** Custom handler function that runs when the active channel has unread messages and the app is running on a separate browser tab */ activeUnreadHandler?: (unread: number, documentTitle: string) => void; /** Allows multiple audio players to play the audio at the same time. Disabled by default. */ @@ -213,8 +139,6 @@ export type ChannelProps = ChannelPropsForwardedToComponentContext & { * Preventing to initialize the channel on mount allows us to postpone the channel creation to a later point in time. */ initializeOnMount?: boolean; - /** Custom UI component to be shown if the channel query fails, defaults to and accepts same props as: [LoadingErrorIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Loading/LoadingErrorIndicator.tsx) */ - LoadingErrorIndicator?: React.ComponentType; /** Configuration parameter to mark the active channel as read when mounted (opened). By default, the channel is marked read on mount. */ markReadOnMount?: boolean; /** Custom action handler function to run on click of an @mention in a message */ @@ -247,12 +171,9 @@ const ChannelContainer = ({ }; const UnMemoizedChannel = (props: PropsWithChildren) => { - const { - channel: propsChannel, - EmptyPlaceholder = null, - LoadingErrorIndicator, - LoadingIndicator = DefaultLoadingIndicator, - } = props; + const { channel: propsChannel, EmptyPlaceholder = null } = props; + const { LoadingErrorIndicator, LoadingIndicator = DefaultLoadingIndicator } = + useComponentContext(); const { channel: contextChannel, channelsQueryState } = useChatContext('Channel'); @@ -300,13 +221,15 @@ const ChannelInner = ( doSendMessageRequest, doUpdateMessageRequest, initializeOnMount = true, - LoadingErrorIndicator = DefaultLoadingErrorIndicator, - LoadingIndicator = DefaultLoadingIndicator, markReadOnMount = true, onMentionsClick, onMentionsHover, skipMessageDataMemoization, } = props; + const { + LoadingErrorIndicator = DefaultLoadingErrorIndicator, + LoadingIndicator = DefaultLoadingIndicator, + } = useComponentContext(); const channelQueryOptions: ChannelQueryOptions & { messages: { limit: number }; @@ -1203,149 +1126,6 @@ const ChannelInner = ( ], ); - const componentContextValue: Partial = useMemo( - () => ({ - Attachment: props.Attachment, - AttachmentPreviewList: props.AttachmentPreviewList, - AttachmentSelector: props.AttachmentSelector, - AttachmentSelectorInitiationButtonContents: - props.AttachmentSelectorInitiationButtonContents, - AudioRecorder: props.AudioRecorder, - AutocompleteSuggestionItem: props.AutocompleteSuggestionItem, - AutocompleteSuggestionList: props.AutocompleteSuggestionList, - Avatar: props.Avatar, - BaseImage: props.BaseImage, - CooldownTimer: props.CooldownTimer, - CustomMessageActionsList: props.CustomMessageActionsList, - DateSeparator: props.DateSeparator, - EditMessageInput: props.EditMessageInput, - EditMessageModal: props.EditMessageModal, - EmojiPicker: props.EmojiPicker, - emojiSearchIndex: props.emojiSearchIndex, - EmptyStateIndicator: props.EmptyStateIndicator, - FileUploadIcon: props.FileUploadIcon, - GiphyPreviewMessage: props.GiphyPreviewMessage, - HeaderComponent: props.HeaderComponent, - Input: props.Input, - LinkPreviewList: props.LinkPreviewList, - LoadingIndicator: props.LoadingIndicator, - Message: props.Message, - MessageActions: props.MessageActions, - MessageBlocked: props.MessageBlocked, - MessageBouncePrompt: props.MessageBouncePrompt, - MessageDeleted: props.MessageDeleted, - MessageIsThreadReplyInChannelButtonIndicator: - props.MessageIsThreadReplyInChannelButtonIndicator, - MessageListNotifications: props.MessageListNotifications, - MessageNotification: props.MessageNotification, - MessageOptions: props.MessageOptions, - MessageRepliesCountButton: props.MessageRepliesCountButton, - MessageStatus: props.MessageStatus, - MessageSystem: props.MessageSystem, - MessageTimestamp: props.MessageTimestamp, - Modal: props.Modal, - ModalGallery: props.ModalGallery, - PinIndicator: props.PinIndicator, - PollActions: props.PollActions, - PollContent: props.PollContent, - PollCreationDialog: props.PollCreationDialog, - PollHeader: props.PollHeader, - PollOptionSelector: props.PollOptionSelector, - QuotedMessage: props.QuotedMessage, - QuotedMessagePreview: props.QuotedMessagePreview, - QuotedPoll: props.QuotedPoll, - reactionOptions: props.reactionOptions, - ReactionSelector: props.ReactionSelector, - ReactionsList: props.ReactionsList, - ReactionsListModal: props.ReactionsListModal, - ReminderNotification: props.ReminderNotification, - SendButton: props.SendButton, - SendToChannelCheckbox: props.SendToChannelCheckbox, - ShareLocationDialog: props.ShareLocationDialog, - StartRecordingAudioButton: props.StartRecordingAudioButton, - StopAIGenerationButton: props.StopAIGenerationButton, - StreamedMessageText: props.StreamedMessageText, - TextareaComposer: props.TextareaComposer, - ThreadHead: props.ThreadHead, - ThreadHeader: props.ThreadHeader, - ThreadStart: props.ThreadStart, - Timestamp: props.Timestamp, - TypingIndicator: props.TypingIndicator, - UnreadMessagesNotification: props.UnreadMessagesNotification, - UnreadMessagesSeparator: props.UnreadMessagesSeparator, - VirtualMessage: props.VirtualMessage, - }), - [ - props.Attachment, - props.AttachmentPreviewList, - props.AttachmentSelector, - props.AttachmentSelectorInitiationButtonContents, - props.AudioRecorder, - props.AutocompleteSuggestionItem, - props.AutocompleteSuggestionList, - props.Avatar, - props.BaseImage, - props.CooldownTimer, - props.CustomMessageActionsList, - props.DateSeparator, - props.EditMessageInput, - props.EditMessageModal, - props.EmojiPicker, - props.emojiSearchIndex, - props.EmptyStateIndicator, - props.FileUploadIcon, - props.GiphyPreviewMessage, - props.HeaderComponent, - props.Input, - props.LinkPreviewList, - props.LoadingIndicator, - props.Message, - props.MessageActions, - props.MessageBlocked, - props.MessageBouncePrompt, - props.MessageDeleted, - props.MessageIsThreadReplyInChannelButtonIndicator, - props.MessageListNotifications, - props.MessageNotification, - props.MessageOptions, - props.MessageRepliesCountButton, - props.MessageStatus, - props.MessageSystem, - props.MessageTimestamp, - props.Modal, - props.ModalGallery, - props.PinIndicator, - props.PollActions, - props.PollContent, - props.PollCreationDialog, - props.PollHeader, - props.PollOptionSelector, - props.QuotedMessage, - props.QuotedMessagePreview, - props.QuotedPoll, - props.reactionOptions, - props.ReactionSelector, - props.ReactionsList, - props.ReactionsListModal, - props.ReminderNotification, - props.SendButton, - props.SendToChannelCheckbox, - props.ShareLocationDialog, - props.StartRecordingAudioButton, - props.StopAIGenerationButton, - props.StreamedMessageText, - props.TextareaComposer, - props.ThreadHead, - props.ThreadHeader, - props.ThreadStart, - props.Timestamp, - props.TypingIndicator, - props.UnreadMessagesNotification, - props.UnreadMessagesSeparator, - props.VirtualMessage, - ], - ); - const typingContextValue = useCreateTypingContext({ typing, }); @@ -1378,13 +1158,11 @@ const ChannelInner = ( - - - -
{children}
-
-
-
+ + +
{children}
+
+
diff --git a/src/context/ComponentContext.tsx b/src/context/ComponentContext.tsx index 40f9a7845..2214bfbc4 100644 --- a/src/context/ComponentContext.tsx +++ b/src/context/ComponentContext.tsx @@ -16,6 +16,7 @@ import type { EventComponentProps, FixedHeightMessageProps, GiphyPreviewMessageProps, + LoadingErrorIndicatorProps, LoadingIndicatorProps, MessageBouncePromptProps, MessageDeletedProps, @@ -118,6 +119,8 @@ export type ComponentContextValue = { Input?: React.ComponentType; /** Custom component to render link previews in message input **/ LinkPreviewList?: React.ComponentType; + /** Custom UI component to be shown if the channel query fails, defaults to and accepts same props as: [LoadingErrorIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Loading/LoadingErrorIndicator.tsx) */ + LoadingErrorIndicator?: React.ComponentType; /** Custom UI component to render while the `MessageList` is loading new messages, defaults to and accepts same props as: [LoadingIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Loading/LoadingIndicator.tsx) */ LoadingIndicator?: React.ComponentType; /** Custom UI component to display a message in the standard `MessageList`, defaults to and accepts the same props as: [MessageSimple](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageSimple.tsx) */ From 3e3a1a2786701da8677ba158b942d8b1ded21ae1 Mon Sep 17 00:00:00 2001 From: Anton Arnautov Date: Thu, 8 Jan 2026 14:05:25 +0100 Subject: [PATCH 2/2] Adjust tests --- .../Channel/__tests__/Channel.test.js | 52 ++++++++++++------ .../Gallery/__tests__/Gallery.test.js | 17 +++--- .../Gallery/__tests__/Image.test.js | 26 ++++----- .../__snapshots__/Gallery.test.js.snap | 1 - .../__tests__/AttachmentPreviewList.test.js | 48 +++++++++-------- .../__tests__/EditMessageForm.test.js | 54 ++++++++++--------- .../__tests__/MessageInput.test.js | 50 +++++++++-------- .../MessageList/__tests__/MessageList.test.js | 27 +++++++--- 8 files changed, 160 insertions(+), 115 deletions(-) diff --git a/src/components/Channel/__tests__/Channel.test.js b/src/components/Channel/__tests__/Channel.test.js index db59877d0..7eae03b58 100644 --- a/src/components/Channel/__tests__/Channel.test.js +++ b/src/components/Channel/__tests__/Channel.test.js @@ -29,7 +29,7 @@ import { } from '../../../mock-builders'; import { MessageList } from '../../MessageList'; import { Thread } from '../../Thread'; -import { MessageProvider } from '../../../context'; +import { MessageProvider, WithComponents } from '../../../context'; import { MessageActionsBox } from '../../MessageActions'; import { DEFAULT_THREAD_PAGE_SIZE } from '../../../constants/limits'; import { generateMessageDraft } from '../../../mock-builders/generator/messageDraft'; @@ -94,18 +94,22 @@ const renderComponent = async (props = {}, callback = () => {}) => { const { channel: channelFromProps, chatClient: chatClientFromProps, + children, + components, ...channelProps } = props; let result; await act(() => { result = render( - - - - {channelProps.children} - - - , + + + + + {children} + + + + , ); }); return result; @@ -301,9 +305,13 @@ describe('Channel', () => { }, }} > -
{loadingText}
}> - {childrenContent} -
+
{loadingText}
, + }} + > + {childrenContent} +
, ); await waitFor(() => expect(screen.getByText(loadingText)).toBeInTheDocument()); @@ -323,9 +331,13 @@ describe('Channel', () => { }, }} > -
{error.message}
}> - {childrenContent} -
+
{error.message}
, + }} + > + {childrenContent} +
, ); await waitFor(() => expect(screen.getByText(errMsg)).toBeInTheDocument()); @@ -2141,10 +2153,12 @@ describe('Channel', () => { ); await renderComponent( { - Avatar: MockAvatar, channel, chatClient, children: , + components: { + Avatar: MockAvatar, + }, }, callback?.(threadMessage), ); @@ -2176,10 +2190,12 @@ describe('Channel', () => { ); await renderComponent( { - Avatar: MockAvatar, channel, chatClient, children: , + components: { + Avatar: MockAvatar, + }, }, callback?.(threadMessage), ); @@ -2293,7 +2309,9 @@ describe('Channel', () => { [])} /> ), - CustomMessageActionsList, + components: { + CustomMessageActionsList, + }, }); await waitFor(() => { diff --git a/src/components/Gallery/__tests__/Gallery.test.js b/src/components/Gallery/__tests__/Gallery.test.js index 2e70659ad..8ec432986 100644 --- a/src/components/Gallery/__tests__/Gallery.test.js +++ b/src/components/Gallery/__tests__/Gallery.test.js @@ -11,7 +11,7 @@ import { Chat } from '../../Chat'; import { Gallery } from '../Gallery'; import { ComponentProvider } from '../../../context/ComponentContext'; -import { useChatContext } from '../../../context'; +import { useChatContext, WithComponents } from '../../../context'; let chatClient; @@ -172,13 +172,14 @@ describe('Gallery', () => { let result; await act(() => { result = render( - - - - - - , - , + + + + + + + + , ); }); expect(result.container).toMatchSnapshot(); diff --git a/src/components/Gallery/__tests__/Image.test.js b/src/components/Gallery/__tests__/Image.test.js index 4f0421c4b..868deba41 100644 --- a/src/components/Gallery/__tests__/Image.test.js +++ b/src/components/Gallery/__tests__/Image.test.js @@ -8,7 +8,7 @@ import { ImageComponent } from '../Image'; import { Chat } from '../../Chat'; import { Channel } from '../../Channel'; -import { useChatContext } from '../../../context'; +import { useChatContext, WithComponents } from '../../../context'; import { ComponentProvider } from '../../../context/ComponentContext'; import { initClientWithChannels } from '../../../mock-builders'; @@ -101,17 +101,18 @@ describe('Image', () => { let result; await act(() => { result = render( - - - - - - , - , + + + + + + + + , ); }); expect(result.container).toMatchInlineSnapshot(` @@ -133,7 +134,6 @@ describe('Image', () => { /> - , `); }); diff --git a/src/components/Gallery/__tests__/__snapshots__/Gallery.test.js.snap b/src/components/Gallery/__tests__/__snapshots__/Gallery.test.js.snap index 33562fa1c..1e16dba9f 100644 --- a/src/components/Gallery/__tests__/__snapshots__/Gallery.test.js.snap +++ b/src/components/Gallery/__tests__/__snapshots__/Gallery.test.js.snap @@ -226,6 +226,5 @@ exports[`Gallery should render custom BaseImage component 1`] = ` - , `; diff --git a/src/components/MessageInput/__tests__/AttachmentPreviewList.test.js b/src/components/MessageInput/__tests__/AttachmentPreviewList.test.js index 27ed1f76a..7c8301bf9 100644 --- a/src/components/MessageInput/__tests__/AttachmentPreviewList.test.js +++ b/src/components/MessageInput/__tests__/AttachmentPreviewList.test.js @@ -16,7 +16,7 @@ import { generateVoiceRecordingAttachment, initClientWithChannels, } from '../../../mock-builders'; -import { MessageProvider } from '../../../context'; +import { MessageProvider, WithComponents } from '../../../context'; jest.spyOn(window.HTMLMediaElement.prototype, 'pause').mockImplementation(); @@ -30,7 +30,7 @@ const renderComponent = async ({ attachments, channel: customChannel, client: customClient, - componentCtx, + components, coords, editedMessage, props, @@ -47,27 +47,29 @@ const renderComponent = async ({ let result; await act(() => { result = render( - - - {editedMessage ? ( - + + + + {editedMessage ? ( + + + + ) : ( - - ) : ( - - )} - - , + )} + + + , ); }); return { channel, ...result }; @@ -297,7 +299,7 @@ describe('AttachmentPreviewList', () => { { fallback: id }, ), ), - componentCtx: { BaseImage }, + components: { BaseImage }, }); expect(container).toMatchSnapshot(); }); diff --git a/src/components/MessageInput/__tests__/EditMessageForm.test.js b/src/components/MessageInput/__tests__/EditMessageForm.test.js index e2c2daeb8..de1a4918a 100644 --- a/src/components/MessageInput/__tests__/EditMessageForm.test.js +++ b/src/components/MessageInput/__tests__/EditMessageForm.test.js @@ -27,6 +27,7 @@ import { import { generatePoll } from '../../../mock-builders/generator/poll'; import { QuotedMessagePreview } from '../QuotedMessagePreview'; import { useMessageComposer as useMessageComposerMock } from '../hooks'; +import { WithComponents } from '../../../context'; jest.mock('../../Channel/utils', () => ({ ...jest.requireActual('../../Channel/utils'), @@ -119,6 +120,7 @@ const renderComponent = async ({ channelData = [], channelProps = {}, chatContextOverrides = {}, + components = {}, customChannel, customClient, CustomStateSetter = null, @@ -140,26 +142,28 @@ const renderComponent = async ({ await act(() => { renderResult = render( - - + - - {CustomStateSetter && } - - - - , + + {CustomStateSetter && } + + + + + , ); }); @@ -249,7 +253,7 @@ describe(`EditMessageForm`, () => { const CustomEmojiPicker = () =>
; const { customChannel, customClient } = await setup(); await renderComponent({ - channelProps: { EmojiPicker: CustomEmojiPicker }, + components: { EmojiPicker: CustomEmojiPicker }, customChannel, customClient, }); @@ -366,7 +370,7 @@ describe(`EditMessageForm`, () => { ); const { customChannel, customClient } = await setup(); const { container } = await renderComponent({ - channelProps: { FileUploadIcon }, + components: { FileUploadIcon }, customChannel, customClient, }); @@ -394,7 +398,7 @@ describe(`EditMessageForm`, () => { ); const { customChannel, customClient } = await setup(); const { container } = await renderComponent({ - channelProps: { AttachmentSelectorInitiationButtonContents, FileUploadIcon }, + components: { AttachmentSelectorInitiationButtonContents, FileUploadIcon }, customChannel, customClient, }); @@ -1208,7 +1212,7 @@ describe(`EditMessageForm`, () => { ); const { customChannel, customClient } = await setup(); const { container } = await renderComponent({ - channelProps: { AutocompleteSuggestionList }, + components: { AutocompleteSuggestionList }, customChannel, customClient, }); @@ -1324,7 +1328,7 @@ describe(`EditMessageForm`, () => { composition: messageWithQuotedMessage, }); await renderComponent({ - channelProps: { + components: { QuotedMessagePreview: (props) => ( ), @@ -1417,7 +1421,9 @@ describe(`EditMessageForm`, () => { const QuotedPoll = () =>
{pollText}
; await renderComponent({ - channelProps: { QuotedPoll }, + components: { + QuotedPoll, + }, customChannel, customClient, }); diff --git a/src/components/MessageInput/__tests__/MessageInput.test.js b/src/components/MessageInput/__tests__/MessageInput.test.js index 0ce72535e..be4d7e440 100644 --- a/src/components/MessageInput/__tests__/MessageInput.test.js +++ b/src/components/MessageInput/__tests__/MessageInput.test.js @@ -25,6 +25,7 @@ import { } from '../../../mock-builders'; import { generatePoll } from '../../../mock-builders/generator/poll'; import { QuotedMessagePreview } from '../QuotedMessagePreview'; +import { WithComponents } from '../../../context'; expect.extend(toHaveNoViolations); @@ -134,6 +135,7 @@ const renderComponent = async ({ channelData = [], channelProps = {}, chatContextOverrides = {}, + components = {}, customChannel, customClient, customUser, @@ -155,21 +157,23 @@ const renderComponent = async ({ await act(() => { renderResult = render( - - - - - - - - , + + + + + + + + + + , ); }); @@ -257,7 +261,7 @@ describe(`MessageInputFlat`, () => { it('should render custom EmojiPicker', async () => { const CustomEmojiPicker = () =>
; - await renderComponent({ channelProps: { EmojiPicker: CustomEmojiPicker } }); + await renderComponent({ components: { EmojiPicker: CustomEmojiPicker } }); await waitFor(() => { const c = screen.getByTestId('custom-emoji-picker'); @@ -319,7 +323,7 @@ describe(`MessageInputFlat`, () => { ); - const { container } = await renderComponent({ channelProps: { FileUploadIcon } }); + const { container } = await renderComponent({ components: { FileUploadIcon } }); const fileUploadIcon = await screen.findByTitle('NotFileUploadIcon'); @@ -344,7 +348,7 @@ describe(`MessageInputFlat`, () => { ); const { container } = await renderComponent({ - channelProps: { AttachmentSelectorInitiationButtonContents, FileUploadIcon }, + components: { AttachmentSelectorInitiationButtonContents, FileUploadIcon }, }); const fileUploadIcon = await screen.queryByTitle('NotFileUploadIcon'); @@ -368,7 +372,7 @@ describe(`MessageInputFlat`, () => { const customTestId = 'custom-link-preview'; const CustomLinkPreviewList = () =>
; await renderComponent({ - channelProps: { LinkPreviewList: CustomLinkPreviewList }, + components: { LinkPreviewList: CustomLinkPreviewList }, }); await act(async () => { fireEvent.change(await screen.findByPlaceholderText(inputPlaceholder), { @@ -1114,7 +1118,9 @@ describe(`MessageInputFlat`, () => { ); const { customChannel, customClient } = await setup(); const { container } = await renderComponent({ - channelProps: { AutocompleteSuggestionList }, + components: { + AutocompleteSuggestionList, + }, customChannel, customClient, }); @@ -1163,7 +1169,7 @@ describe(`MessageInputFlat`, () => { }); const fn = jest.fn().mockReturnValue(
{m.text}
); await renderComponent({ - channelProps: { + components: { QuotedMessagePreview: (props) => ( ), @@ -1232,7 +1238,7 @@ describe(`MessageInputFlat`, () => { const QuotedPoll = () =>
{pollText}
; await renderComponent({ - channelProps: { QuotedPoll }, + components: { QuotedPoll }, customChannel: channel, customClient: client, messageContextOverrides: { diff --git a/src/components/MessageList/__tests__/MessageList.test.js b/src/components/MessageList/__tests__/MessageList.test.js index efe309095..d4dba3293 100644 --- a/src/components/MessageList/__tests__/MessageList.test.js +++ b/src/components/MessageList/__tests__/MessageList.test.js @@ -171,10 +171,12 @@ describe('MessageList', () => { it('Message UI components should render `Avatar` when the custom prop is provided', async () => { const renderResult = renderComponent({ channelProps: { - Avatar, channel, }, chatClient, + components: { + Avatar, + }, }); await waitFor(() => { @@ -253,8 +255,9 @@ describe('MessageList', () => { const Header = () =>
{headerText}
; renderComponent({ - channelProps: { channel, HeaderComponent: Header }, + channelProps: { channel }, chatClient, + components: { HeaderComponent: Header }, msgListProps: { messages: [intro], }, @@ -580,8 +583,9 @@ describe('MessageList', () => { await act(() => { renderComponent({ - channelProps: { channel, UnreadMessagesSeparator }, + channelProps: { channel }, chatClient: client, + components: { UnreadMessagesSeparator }, msgListProps: { messages }, }); }); @@ -608,8 +612,9 @@ describe('MessageList', () => { await act(() => { renderComponent({ - channelProps: { channel, UnreadMessagesSeparator }, + channelProps: { channel }, chatClient: client, + components: { UnreadMessagesSeparator }, msgListProps: { messages }, }); }); @@ -643,6 +648,7 @@ describe('MessageList', () => { const setupTest = async ({ channelProps = {}, + components = {}, dispatchMarkUnreadPayload = {}, entries, msgListProps = {}, @@ -656,6 +662,7 @@ describe('MessageList', () => { renderComponent({ channelProps: { channel, ...channelProps }, chatClient: client, + components, msgListProps: { messages, ...msgListProps }, }); }); @@ -746,7 +753,9 @@ describe('MessageList', () => {
aaa
); await setupTest({ - channelProps: { UnreadMessagesNotification }, + components: { + UnreadMessagesNotification, + }, entries: observerEntriesScrolledBelowSeparator, }); @@ -803,10 +812,12 @@ describe('MessageList', () => { renderComponent({ channelProps: { channel, + }, + chatClient: client, + components: { MessageListNotifications: MockMessageListNotifications, MessageNotification: ScrollToBottomButton, }, - chatClient: client, msgListProps: { messages }, }); }); @@ -831,10 +842,12 @@ describe('MessageList', () => { renderComponent({ channelProps: { channel, + }, + chatClient: client, + components: { MessageListNotifications: MockMessageListNotifications, MessageNotification: ScrollToBottomButton, }, - chatClient: client, msgListProps: { messages, threadList: true }, }); });