Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose optional remark plugin to keep all line breaks and keep HTML in message text #2170

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 73 additions & 36 deletions docusaurus/docs/React/components/core-components/message-list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,42 +122,6 @@ const App = () => (
);
```

#### Custom element rendering

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:

:::note
Types `mention` and `emoji` are special case component types generated by our SDK's custom rehype plugins.
:::

```tsx
import { renderText } from 'stream-chat-react';

const StrongComponent = ({ children }) => <b className='custom-strong-class-name'>{children}</b>;

const MentionComponent = ({ children, node: { mentionedUser } }) => (
<a data-user-id={mentionedUser.id} href={`/user-profile/${mentionedUser.id}`}>
{children}
</a>
);

const App = () => (
<Chat client={client}>
<Channel>
<Window>
<MessageList
renderText={(text, mentionedUsers) =>
renderText(text, mentionedUsers, {
customMarkDownRenderers: { strong: StrongComponent, mention: MentionComponent },
})
}
/>
</Window>
</Channel>
</Chat>
);
```

#### Custom remark and rehype plugins

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:
Expand Down Expand Up @@ -218,6 +182,79 @@ const CustomMessageList = () => (
);
```

#### Optional remark and rehype plugins

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).

Currently, there are the following optional remark plugins available in the SDK:

- `htmlToTextPlugin` - keeps the HTML tags in the resulting text string.
- `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).

These can be plugged in as follows:

```tsx
import { UserResponse } from 'stream-chat';
import {
htmlToTextPlugin,
keepLineBreaksPlugin,
MessageList,
MessageListProps,
renderText,
RenderTextPluginConfigurator,
} from 'stream-chat-react';

const getRemarkPlugins: RenderTextPluginConfigurator = (plugins) => [
htmlToTextPlugin,
keepLineBreaksPlugin,
...plugins,
];

function customRenderText(text?: string, mentionedUsers?: UserResponse[]) {
return renderText(text, mentionedUsers, { getRemarkPlugins });
}

export const CustomMessageList = (props: MessageListProps) => (
<MessageList {...props} renderText={customRenderText} />
);
```

#### Custom element rendering

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:

:::note
Types `mention` and `emoji` are special case component types generated by our SDK's custom rehype plugins.
:::

```tsx
import { renderText } from 'stream-chat-react';

const StrongComponent = ({ children }) => <b className='custom-strong-class-name'>{children}</b>;

const MentionComponent = ({ children, node: { mentionedUser } }) => (
<a data-user-id={mentionedUser.id} href={`/user-profile/${mentionedUser.id}`}>
{children}
</a>
);

const App = () => (
<Chat client={client}>
<Channel>
<Window>
<MessageList
renderText={(text, mentionedUsers) =>
renderText(text, mentionedUsers, {
customMarkDownRenderers: { strong: StrongComponent, mention: MentionComponent },
})
}
/>
</Window>
</Channel>
</Chat>
);
```

## Props

### additionalMessageInputProps
Expand Down
Loading
Loading