Skip to content

Commit 5b191c9

Browse files
authored
feat: expose optional remark plugin to keep all line breaks and keep HTML in message text (#2170)
1 parent 8dcb1ac commit 5b191c9

File tree

11 files changed

+935
-55
lines changed

11 files changed

+935
-55
lines changed

docusaurus/docs/React/components/core-components/message-list.mdx

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -122,42 +122,6 @@ const App = () => (
122122
);
123123
```
124124

125-
#### Custom element rendering
126-
127-
If you feel like the default output is sufficient, but you'd like to adjust how certain [ReactMarkdown components](https://github.com/remarkjs/react-markdown#appendix-b-components) look like (like `strong` element generated by typing \*\*strong\*\*) you can do so by passing down options to a third argument of the default `renderText` function:
128-
129-
:::note
130-
Types `mention` and `emoji` are special case component types generated by our SDK's custom rehype plugins.
131-
:::
132-
133-
```tsx
134-
import { renderText } from 'stream-chat-react';
135-
136-
const StrongComponent = ({ children }) => <b className='custom-strong-class-name'>{children}</b>;
137-
138-
const MentionComponent = ({ children, node: { mentionedUser } }) => (
139-
<a data-user-id={mentionedUser.id} href={`/user-profile/${mentionedUser.id}`}>
140-
{children}
141-
</a>
142-
);
143-
144-
const App = () => (
145-
<Chat client={client}>
146-
<Channel>
147-
<Window>
148-
<MessageList
149-
renderText={(text, mentionedUsers) =>
150-
renderText(text, mentionedUsers, {
151-
customMarkDownRenderers: { strong: StrongComponent, mention: MentionComponent },
152-
})
153-
}
154-
/>
155-
</Window>
156-
</Channel>
157-
</Chat>
158-
);
159-
```
160-
161125
#### Custom remark and rehype plugins
162126

163127
If you would like to extend the array of plugins used to parse the markdown, you can provide your own lists of remark resp. rehype plugins. The logic that determines what plugins are used and in which order can be specified in custom `getRehypePlugins` and `getRemarkPlugins` functions. These receive the default array of rehype and remark plugins for further customization. Both custom functions ought to be passed to the third `renderText()` parameter. An example follows:
@@ -218,6 +182,79 @@ const CustomMessageList = () => (
218182
);
219183
```
220184

185+
#### Optional remark and rehype plugins
186+
187+
The SDK provides the following plugins that are not applied to the text parsing by the default `renderText()` implementation. However, these can be included by simply overriding the defaults with `getRemarkPlugins` and `getRehypePlugins` parameters as described in [the section about custom plugins](#custom-remark-and-rehype-plugins).
188+
189+
Currently, there are the following optional remark plugins available in the SDK:
190+
191+
- `htmlToTextPlugin` - keeps the HTML tags in the resulting text string.
192+
- `keepLineBreaksPlugin` - replaces empty lines in text with line breaks ([according to the CommonMark Markdown specification](https://spec.commonmark.org/0.30/#hard-line-breaks), the empty lines - meaning newline characters `\n` - are not transformed to `<br/>` elements).
193+
194+
These can be plugged in as follows:
195+
196+
```tsx
197+
import { UserResponse } from 'stream-chat';
198+
import {
199+
htmlToTextPlugin,
200+
keepLineBreaksPlugin,
201+
MessageList,
202+
MessageListProps,
203+
renderText,
204+
RenderTextPluginConfigurator,
205+
} from 'stream-chat-react';
206+
207+
const getRemarkPlugins: RenderTextPluginConfigurator = (plugins) => [
208+
htmlToTextPlugin,
209+
keepLineBreaksPlugin,
210+
...plugins,
211+
];
212+
213+
function customRenderText(text?: string, mentionedUsers?: UserResponse[]) {
214+
return renderText(text, mentionedUsers, { getRemarkPlugins });
215+
}
216+
217+
export const CustomMessageList = (props: MessageListProps) => (
218+
<MessageList {...props} renderText={customRenderText} />
219+
);
220+
```
221+
222+
#### Custom element rendering
223+
224+
If you feel like the default output is sufficient, but you'd like to adjust how certain [ReactMarkdown components](https://github.com/remarkjs/react-markdown#appendix-b-components) look like (like `strong` element generated by typing \*\*strong\*\*) you can do so by passing down options to a third argument of the default `renderText` function:
225+
226+
:::note
227+
Types `mention` and `emoji` are special case component types generated by our SDK's custom rehype plugins.
228+
:::
229+
230+
```tsx
231+
import { renderText } from 'stream-chat-react';
232+
233+
const StrongComponent = ({ children }) => <b className='custom-strong-class-name'>{children}</b>;
234+
235+
const MentionComponent = ({ children, node: { mentionedUser } }) => (
236+
<a data-user-id={mentionedUser.id} href={`/user-profile/${mentionedUser.id}`}>
237+
{children}
238+
</a>
239+
);
240+
241+
const App = () => (
242+
<Chat client={client}>
243+
<Channel>
244+
<Window>
245+
<MessageList
246+
renderText={(text, mentionedUsers) =>
247+
renderText(text, mentionedUsers, {
248+
customMarkDownRenderers: { strong: StrongComponent, mention: MentionComponent },
249+
})
250+
}
251+
/>
252+
</Window>
253+
</Channel>
254+
</Chat>
255+
);
256+
```
257+
221258
## Props
222259

223260
### additionalMessageInputProps

0 commit comments

Comments
 (0)