type overrideSubmitHandler = (params: {
cid: string;
localMessage: LocalMessage;
message: Message;
sendOptions: SendMessageOptions;
}) => Promise<void> | void;Upgrade to v13
Removal of StreamChatGenerics
See the release guide of stream-chat and TypeScript & Custom Data Types article.
Changes in Message Types
Introduction of LocalMessage type
MessageToSend, StreamMessage, and UpdatedMessage were removed and replaced by LocalMessage. LocalMessage represents the message stored in local state. Server responses (MessageResponse) are converted to LocalMessage immediately.
Introduction of RenderedMessage type
RenderedMessage includes LocalMessage plus client-side ephemeral messages like DateSeparatorMessage and IntroMessage.
Change in Message Composition
Message composition is now managed by MessageComposer instances. Each composition context has its own composer:
channel- for main channel list message compositionthread- for message composition in Thread viewlegacy_thread- for the legacy side-by-side thread layout next to the channel listmessage- for editing a message in any message list
Get the current composer with useMessageComposer.
Introduction of MessageComposer leads to breaking changes described in the following sections.
Replaced Text Autocomplete Components
The following components were removed and replaced:
| Removed | Replaced by |
|---|---|
| AutoCompleteTextarea | TextAreaComposer |
| ChatAutoComplete | TextAreaComposer |
| DefaultSuggestionList | SuggestionList |
| DefaultSuggestionListItem | SuggestionListItem |
ChatAutoComplete (which rendered AutoCompleteTextarea) was replaced by TextAreaComposer.
Removed MessageInput, ChatAutoComplete, and AutoCompleteTextarea Props
The following props previously exposed on ChatAutoComplete and AutoCompleteTextarea are no longer available.
AutoCompleteTextarea
| Prop | Replacement |
|---|---|
containerStyle | Apply custom styles using CSS |
defaultValue | Set via MessageComposer configuration (text.defaultValue) (see the composer configuration guide) or via the TextComposer.defaultValue setter. |
disabled | Set via MessageComposer configuration (text.enabled) (see the composer configuration guide) |
disableMentions | Remove mentions middleware from the TextComposer.middlewareExecutor (see the composer middleware guide) |
dropdownClassName | Override prop containerClassName directly on SuggestionList and pass the list component as AutocompleteSuggestionList to Channel |
dropdownStyle | Apply custom styles using CSS |
itemClassName | Override prop className directly on SuggestionListItem and pass the item component as AutocompleteSuggestionItem to Channel |
itemStyle | Apply custom styles using CSS |
listClassName | Override prop className directly on SuggestionList and pass the list component as AutocompleteSuggestionList to Channel |
listStyle | Apply custom styles using CSS |
loaderClassName | The prop was not used. No replacement provided. |
loaderStyle | The prop was not used. No replacement provided. |
loadingComponent | The prop was not used. No replacement provided. |
grow | Redundant prop. Use prop maxRows to indicate up to what number of rows the textarea can grow. |
onCaretPositionChange | Subscribe to TextComposer.state and observe selection (see the state store guide) |
onSelect | Add custom middleware to TextComposer.middlewareExecutor to handle onSuggestionItemSelect event (see the composer middleware guide) |
style | Apply custom styles using CSS |
trigger | The current trigger value is signaled via TextComposer.state.suggestions |
value | The current (text) value is signaled via TextComposer.state.text |
ChatAutoComplete
The component used to forward props to AutoCompleteTextarea. As those are already described in the previous section, we will omit them in the below table.
| Prop | Replacement |
|---|---|
handleSubmit | Customize composition via MessageComposer.compositionMiddlewareExecutor and draft composition via MessageComposer.draftCompositionMiddlewareExecutor (see the composer middleware guide). Sending can be customized via the Channel prop doSendMessageRequest. |
wordReplace | Emoji replacement now happens in TextComposer middleware via onChange. The built-in emoji middleware covers this (see the composer middleware guide). |
MessageInput
| Prop | Replacement |
|---|---|
doFileUploadRequest | Custom upload function can be configured via MessageComposer configuration (attachments.doUploadRequest) or MessageComposer.attachmentManager.setCustomUploadFn method. |
doImageUploadRequest | Custom upload function can be configured via MessageComposer configuration (attachments.doUploadRequest) or MessageComposer.attachmentManager.setCustomUploadFn method. |
errorHandler | To handle errors thrown during the file upload, subscribe to client.notifications.state and react to notification.message 'Error uploading attachment'. |
getDefaultValue | The default value is set via MessageComposer configuration (text.defaultValue) (see the composer configuration guide) or set reactively via TextComposer.defaultValue setter |
mentionAllAppUsers | Mentions configuration can be done via TextComposer mentions middleware ( createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {mentionAllAppUsers: true}) }) |
mentionQueryParams | Override methods MentionsSearchSource.prepareQueryUsersParams or MentionsSearchSource.prepareQueryMembersParams respectively to generate filter, sort and options objects to perform user and member requests based on search text. |
message | MessageComposer is automatically provided with the edited message. No replacement. |
noFiles | Custom logic to filter files can be specified via MessageComposer configuration (attachments.fileUploadFilter) or MessageComposer.attachmentManager.fileUploadFilter setter. |
parent | The parent message is automatically provided to the MessageComposer. No replacement. |
publishTypingEvent | Configure with MessageComposer.textComposer.publishTypingEvents |
urlEnrichmentConfig | The link preview config can be specified via MessageComposer.linkPreviews configuration or MessageComposer.linkPreviewsManager setters |
useMentionsTransliteration | Mentions configuration can be done via TextComposer mentions middleware ( createMentionsMiddleware(channel, {searchSource: new MentionsSearchSource(channel, {transliterate: (textToTransliterate: string) => string}) }) |
Further, the signature of function passed to overrideSubmitHandler has changed. It now accepts a single object parameter:
Removed Channel Props
| Prop | Replacement |
|---|---|
acceptedFiles | The array of strings can be specified via MessageComposer configuration (attachments.acceptedFiles) or MessageComposer.attachmentManager.acceptedFiles setter. |
enrichURLForPreview, enrichURLForPreviewConfig | The link preview config can be specified via MessageComposer.linkPreviews configuration or MessageComposer.linkPreviewsManager setters. |
maxNumberOfFiles | Can be specified via MessageComposer configuration (attachments.maxNumberOfFilesPerMessage) or MessageComposer.attachmentManager.maxNumberOfFilesPerMessage setter. |
multipleUploads | Does not have replacement. Multiple uploads are inferred from configuration parameter maxNumberOfFilesPerMessage value greater than 1. |
TriggerProvider | Triggers are characters in composed message text that cause suggestions to be rendered (emoji, mentions, commands). This component served to propagate potentially custom trigger logic. This is however now done via TextComposer.middlewareExecutor by providing custom middleware functions (see the composer middleware guide). |
Autocomplete trigger logic migration
Autocomplete triggers are now handled by TextComposer middleware in stream-chat. The following types were removed from stream-chat-react:
SuggestionHeaderPropsChatAutoCompletePropsAutocompleteMinimalDataCommandTriggerSettingEmojiTriggerSettingUserTriggerSettingTriggerSettingTriggerSettings
This migration also led to removal of the trigger generic parameter from stream-chat-react components. Typed text now flows through middleware before it is committed to MessageComposer state.
ChannelActionContext Changes
Besides the LocalMessage change for editMessage, openThread, removeMessage, and updateMessage, the following changes apply:
The sendMessage function signature has changed. Now it accepts a single object parameter:
type sendMessage = (params: {
localMessage: LocalMessage;
message: Message;
options?: SendMessageOptions;
}) => Promise<void>;setQuotedMessage was removed. Quoted message state is now handled by MessageComposer, via MessageComposer.setQuotedMessage(quotedMessage: LocalMessage | null).
ChannelStateContext Changes
Removed Channel props are now absent from ChannelStateContext too: acceptedFiles, enrichURLForPreview, parts of enrichURLForPreviewConfig (debounceURLEnrichmentMs, findURLFn, onLinkPreviewDismissed), and multipleUploads.
| Prop | Replacement |
|---|---|
quotedMessage | Value changes can now be observed by subscribing to MessageComposer.state changes. |
const messageComposerStateSelector = (state: MessageComposerState) => ({
quotedMessage: state.quotedMessage,
});
const messageComposer = useMessageComposer();
const { quotedMessage } = useStateStore(
messageComposer.state,
messageComposerStateSelector,
);useMessageInputState → useMessageInputControls
Message composition state moved from stream-chat-react to stream-chat and MessageComposer. As a result, useMessageInputState was renamed to useMessageInputControls and now exposes only the following API via MessageInputContext:
handleSubmit- Also received an overhaul resulting in signature change (see below).onPasterecordingControllertextareaRef
Message input state and most of the API now live in MessageComposer, not MessageInputContext.
MessageInputContext Changes
With the useMessageInputState refactor:
1. Context Values Removed
| Prop | Replacement |
|---|---|
insertText | Use MessageComposer.textComposer.insertText method |
handleChange | Use MessageComposer.textComposer.handleChange method |
isUploadEnabled | Use useAttachmentManagerState hook to subscribe to isUploadEnabled value changes |
maxFilesLeft | Use useAttachmentManagerState hook to subscribe to availableUploadSlots value changes |
numberOfUploads | Use useAttachmentManagerState hook to subscribe to successfulUploadsCount and uploadsInProgressCount value changes |
onSelectUser | Use MessageComposer.textComposer.handleSelect method to announce a suggestion item has been selected. It is possible to register custom TextComposer middleware (see the middleware guide). |
removeAttachments | Use MessageComposer.attachmentManager.removeAttachments method |
uploadAttachment | Use MessageComposer.attachmentManager.uploadAttachment method |
uploadNewFiles | Use MessageComposer.attachmentManager.uploadFiles method |
upsertAttachments | Use MessageComposer.attachmentManager.upsertAttachments method |
closeCommandsList | Use MessageComposer.textComposer.closeSuggestions method |
openCommandsList | Done automatically upon trigger identification. You can register custom TextComposer onChange middleware or override trigger characters (see the middleware guide). |
showCommandsList | Check whether the command list is open via TextComposer.suggestions?.trigger === commandTrigger |
closeMentionsList | Use MessageComposer.textComposer.closeSuggestions method |
openMentionsList | Done automatically upon trigger identification. We can register a custom TextComposer middleware for onChange event to introduce custom logic, or override the mentions trigger character(s) (see the middleware guide). |
showMentionsList | Check whether the mentions list is open via TextComposer.suggestions?.trigger === mentionTrigger |
The removed values forwarded from MessageInputProps to MessageInputContext have been documented above.
2. handleSubmit Signature Change
handleSubmit now accepts only an optional event object. The customMessageData and options parameters were removed.
Before:
type handleSubmit = (
event?: React.BaseSyntheticEvent,
customMessageData?: Partial<Message<StreamChatGenerics>>,
options?: SendMessageOptions,
) => Promise<void>;Now:
type handleSubmit = (event?: React.BaseSyntheticEvent) => Promise<void>;Custom message data can be injected via middleware (see the middleware guide) or by setting it directly:
messageComposer.customDataManager.setMessageData({ a: "b" });Attachment Identity Functions Moved to stream-chat
The following identity functions were moved to stream-chat:
| Original Name | New Name |
|---|---|
isLocalAttachment | isLocalAttachment |
isScrapedContent | isScrapedContent |
| none | isLocalUploadAttachment |
isFileAttachment | isFileAttachment |
isLocalFileAttachment | isLocalFileAttachment |
isUploadedImage | isImageAttachment |
| none | isLocalImageAttachment |
isAudioAttachment | isAudioAttachment |
isLocalAudioAttachment | isLocalAudioAttachment |
isVoiceRecordingAttachment | isVoiceRecordingAttachment |
isLocalVoiceRecordingAttachment | isLocalVoiceRecordingAttachment |
isMediaAttachment | isVideoAttachment |
isLocalMediaAttachment | isLocalVideoAttachment |
| none | isUploadedAttachment |
isGalleryAttachmentType remains in stream-chat-react because it’s SDK-specific.
Message Composition Changes Summary
Message composition is now handled by the MessageComposer class. Use useMessageComposer to get the correct instance for the current context.
APIs moved to MessageComposer were removed from the relevant React contexts and component props in stream-chat-react.
Removal of Channel.dragAndDropWindow Prop
The Channel prop dragAndDropWindow and associated optionalMessageInputProps were removed. Use WithDragAndDropUpload instead.
- Removal of StreamChatGenerics
- Changes in Message Types
- Change in Message Composition
- Replaced Text Autocomplete Components
- Removed MessageInput, ChatAutoComplete, and AutoCompleteTextarea Props
- Removed Channel Props
- Autocomplete trigger logic migration
- ChannelActionContext Changes
- ChannelStateContext Changes
- useMessageInputState → useMessageInputControls
- MessageInputContext Changes
- Attachment Identity Functions Moved to stream-chat
- Message Composition Changes Summary
- Removal of Channel.dragAndDropWindow Prop