Skip to content

Commit

Permalink
fix(emoji-mart): new reactions (#1947)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `reactionOptions` signature has changed, see release
guide for more information

### 🎯 Goal

Refactor and fix the way reactions work, introduce new way of
customizing with better DX.

Fixes: #1935
Closes: #1637
Closes: #1437
Closes: #2159
Closes:
GetStream/stream-chat-react-native#2023

### 🛠 Implementation details

- ditch EmojiMart implementation, use native/sprite-sheet solution
  • Loading branch information
arnautov-anton committed Nov 27, 2023
1 parent 28f0676 commit 83f31da
Show file tree
Hide file tree
Showing 24 changed files with 774 additions and 402 deletions.
13 changes: 10 additions & 3 deletions docusaurus/docs/React/_docusaurus-components/GHComponentLink.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import React from 'react';

const GHComponentLink = ({text, path}) => {
return <a target='_blank' href={`https://github.com/GetStream/stream-chat-react/blob/master/src/components${path}`}>{text}</a>
}
const GHComponentLink = ({ text, as: As = React.Fragment, path, branch = 'master' }) => {
return (
<a
target='_blank'
href={`https://github.com/GetStream/stream-chat-react/blob/${branch}/src/components${path}`}
>
<As>{text}</As>
</a>
);
};

export default GHComponentLink;
87 changes: 40 additions & 47 deletions docusaurus/docs/React/components/message-components/reactions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,19 @@ title: Reactions

import GHComponentLink from '../../_docusaurus-components/GHComponentLink';

The Stream Chat API provides built-in support for adding reactions to messages. The component library provides three default
components to enable reaction selection and display:

- [`ReactionSelector`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/ReactionSelector.tsx) - allows
the connected user to select a reaction on a message
:::caution
If you're moving from older versions to `11.0.0` then make sure to read ["Reactions 11.0.0"](../../release-guides/reactions-v11.mdx) release guide to help you transition to the new implementation.
:::

- [`ReactionsList`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/ReactionsList.tsx) - displays
the reactions added to a message
The Stream Chat API provides built-in support for adding reactions to messages. The component library provides three default components to enable reaction selection and display:

- [`SimpleReactionsList`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/SimpleReactionsList.tsx) - displays
a minimal list of the reactions added to a message
- [`ReactionSelector`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/ReactionSelector.tsx) - allows the connected user to select a reaction on a message
- [`ReactionsList`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/ReactionsList.tsx) - displays the reactions added to a message
- [`SimpleReactionsList`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/SimpleReactionsList.tsx) - displays a minimal list of the reactions added to a message

## Basic Usage

By default, the `ReactionSelector` and `ReactionsList` components are included within `MessageSimple`. To render reaction UI within a
custom [Message UI](./message-ui.mdx) component, import both components (or `SimpleReactionsList` for a lightweight view) and render
conditionally.
By default, the `ReactionSelector` and `ReactionsList` components are included within `MessageSimple`. To render reaction UI within a custom [Message UI](./message-ui.mdx) component, import both components (or `SimpleReactionsList` for a lightweight view) and render conditionally.

```jsx
const CustomMessage = () => {
Expand Down Expand Up @@ -55,19 +51,14 @@ Be default, the `ReactionSelector` component provides the following reaction opt
- `haha`
- `wow`
- `sad`
- `angry`
- `angry` - removed in `11.0.0`

The `defaultMinimalEmojis` data set that populates the default reaction options can be found in the
[emojiData](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Channel/emojiData.ts) file in the
component library.
The `defaultMinimalEmojis` data set that populates the default reaction options can be found in the <GHComponentLink as="code" text='emojiData' branch="v10.17.0" path='/Channel/emojiData.ts'/> file in the component library.

To override the default selection set, provide your own array of `MinimalEmoji` type objects and pass into the `reactionOptions`
prop on the `ReactionSelector` component. You can also override the default [handleReaction](./components/contexts/message-context.mdx#handlereaction)
function by adding the `handleReaction` prop.
To override the default selection set, provide your own array of `MinimalEmoji` type objects and pass into the `reactionOptions` prop on the `ReactionSelector` component. You can also override the default [`handleReaction`](../contexts/message-context.mdx#handlereaction) function by adding the `handleReaction` prop.

:::caution
If custom `reactionOptions` are supplied to the `ReactionSelector` component, then the same data set needs to be delivered to the
`ReactionsList` component so the display for processed reactions has the same emoji objects.
If custom `reactionOptions` are supplied to the `ReactionSelector` component, then the same data set needs to be delivered to the `ReactionsList` component so the display for processed reactions has the same emoji objects.
:::

```jsx
Expand Down Expand Up @@ -105,8 +96,7 @@ const CustomMessage = () => {
</Chat>;
```

To completely override the `ReactionSelector` and `ReactionsList` components in `MessageSimple`, pass your own custom components as props
to the [`Channel`](./components/core-components/channel.mdx).
To completely override the `ReactionSelector` and `ReactionsList` components in `MessageSimple`, pass your own custom components as props to the [`Channel`](../core-components/channel.mdx).

```jsx
const CustomReactionSelector = (props) => {
Expand All @@ -131,9 +121,9 @@ const CustomReactionsList = (props) => {

## ReactionSelector Props

### additionalEmojiProps
### additionalEmojiProps (removed in `11.0.0`)

Additional props to be passed to the [NimbleEmoji](https://github.com/missive/emoji-mart/blob/master/src/components/emoji/nimble-emoji.js) component from `emoji-mart`.
Additional props to be passed to the [`NimbleEmoji`](https://github.com/missive/emoji-mart/blob/v3.0.1/src/components/emoji/nimble-emoji.js) component from `emoji-mart`.

| Type |
| ------ |
Expand All @@ -159,9 +149,9 @@ If true, shows the user's avatar with the reaction.

Function that adds/removes a reaction on a message (overrides the function stored in `MessageContext`).

| Type | Default |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| (reactionType: string, event: React.BaseSyntheticEvent) => Promise<void\> | [MessageContextValue['handleReaction']](./components/contexts/message-context.mdx#handlereaction) |
| Type | Default |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| (reactionType: string, event: React.BaseSyntheticEvent) => Promise<void\> | [MessageContextValue['handleReaction']](../contexts/message-context.mdx#handlereaction) |

### latest_reactions

Expand Down Expand Up @@ -191,9 +181,10 @@ An object that keeps track of the count of each type of reaction on a message (o

A list of the currently supported reactions on a message.

| Type | Default |
| ----- | --------------------------------------------------------------------------- |
| array | <GHComponentLink text='defaultMinimalEmojis' path='/Channel/emojiData.ts'/> |
| Version | Type | Default |
| ------- | ----- | -------------------------------------------------------------------------------------------------------------- |
| >=4.0.0 | array | <GHComponentLink text='defaultMinimalEmojis' branch="v10.17.0" path='/Channel/emojiData.ts'/> |
| ^11.0.0 | array | <GHComponentLink text='defaultReactionOptions' branch="feat/reactions" path='/Reactions/reactionOptions.tsx'/> |

### reverse

Expand All @@ -205,9 +196,9 @@ If true, adds a CSS class that reverses the horizontal positioning of the select

## ReactionsList Props

### additionalEmojiProps
### additionalEmojiProps (removed in `11.0.0`)

Additional props to be passed to the [NimbleEmoji](https://github.com/missive/emoji-mart/blob/master/src/components/emoji/nimble-emoji.js) component from `emoji-mart`.
Additional props to be passed to the [`NimbleEmoji`](https://github.com/missive/emoji-mart/blob/v3.0.1/src/components/emoji/nimble-emoji.js) component from `emoji-mart`.

| Type |
| ------ |
Expand All @@ -217,9 +208,9 @@ Additional props to be passed to the [NimbleEmoji](https://github.com/missive/em

Custom on click handler for an individual reaction in the list (overrides the function stored in `MessageContext`).

| Type | Default |
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| (event: React.BaseSyntheticEvent) => Promise<void\> \| void | [MessageContextValue['onReactionListClick']](./components/contexts/message-context.mdx#onreactionlistclick) |
| Type | Default |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| (event: React.BaseSyntheticEvent) => Promise<void\> \| void | [MessageContextValue['onReactionListClick']](../contexts/message-context.mdx#onreactionlistclick) |

### own_reactions

Expand All @@ -241,9 +232,10 @@ An object that keeps track of the count of each type of reaction on a message (o

A list of the currently supported reactions on a message.

| Type | Default |
| ----- | --------------------------------------------------------------------------- |
| array | <GHComponentLink text='defaultMinimalEmojis' path='/Channel/emojiData.ts'/> |
| Version | Type | Default |
| ------- | ----- | -------------------------------------------------------------------------------------------------------------- |
| >=4.0.0 | array | <GHComponentLink text='defaultMinimalEmojis' branch="v10.17.0" path='/Channel/emojiData.ts'/> |
| ^11.0.0 | array | <GHComponentLink text='defaultReactionOptions' branch="feat/reactions" path='/Reactions/reactionOptions.tsx'/> |

### reactions

Expand All @@ -263,9 +255,9 @@ If true, adds a CSS class that reverses the horizontal positioning of the select

## SimpleReactionsList Props

### additionalEmojiProps
### additionalEmojiProps (removed in `11.0.0`)

Additional props to be passed to the [NimbleEmoji](https://github.com/missive/emoji-mart/blob/master/src/components/emoji/nimble-emoji.js) component from `emoji-mart`.
Additional props to be passed to the [`NimbleEmoji`](https://github.com/missive/emoji-mart/blob/v3.0.1/src/components/emoji/nimble-emoji.js) component from `emoji-mart`.

| Type |
| ------ |
Expand All @@ -275,9 +267,9 @@ Additional props to be passed to the [NimbleEmoji](https://github.com/missive/em

Function that adds/removes a reaction on a message (overrides the function stored in `MessageContext`).

| Type | Default |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| (reactionType: string, event: React.BaseSyntheticEvent) => Promise<void\> | [MessageContextValue['handleReaction']](./components/contexts/message-context.mdx#handlereaction) |
| Type | Default |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| (reactionType: string, event: React.BaseSyntheticEvent) => Promise<void\> | [MessageContextValue['handleReaction']](../contexts/message-context.mdx#handlereaction) |

### own_reactions

Expand All @@ -299,9 +291,10 @@ An object that keeps track of the count of each type of reaction on a message (o

A list of the currently supported reactions on a message.

| Type | Default |
| ----- | --------------------------------------------------------------------------- |
| array | <GHComponentLink text='defaultMinimalEmojis' path='/Channel/emojiData.ts'/> |
| Version | Type | Default |
| ------- | ----- | -------------------------------------------------------------------------------------------------------------- |
| >=4.0.0 | array | <GHComponentLink text='defaultMinimalEmojis' branch="v10.17.0" path='/Channel/emojiData.ts'/> |
| ^11.0.0 | array | <GHComponentLink text='defaultReactionOptions' branch="feat/reactions" path='/Reactions/reactionOptions.tsx'/> |

### reactions

Expand Down
19 changes: 9 additions & 10 deletions docusaurus/docs/React/guides/theming/reactions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ title: Reaction Selector and List
import CustomReactionSelector from '../../assets/CustomReactionSelector.png';
import CustomReactionsList from '../../assets/CustomReactionsList.png';

:::caution
If you're moving from older versions to `11.0.0` then make sure to read ["Reactions 11.0.0"](../../release-guides/reactions-v11.mdx) release guide to help you transition to the new implementation.
:::

In this example, we will demonstrate how to override the library's default reaction set, which can be found stored as the
[`defaultMinimalEmojis`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Channel/emojiData.ts)
variable. We will replace the default set with up and down arrows, simulating an up/down voting feature.

### Choose Your Reactions

Under the hood, our `ReactionSelector`, `ReactionsList`, and `SimpleReactionsList` components render individual emoji objects
using the [`NimbleEmoji`](https://github.com/missive/emoji-mart/blob/master/src/components/emoji/nimble-emoji.js) component
from [emoji-mart](https://www.npmjs.com/package/emoji-mart). Therefore, the object type of our custom reactions needs to
using the [`NimbleEmoji`](https://github.com/missive/emoji-mart/blob/v3.0.1/src/components/emoji/nimble-emoji.js) component
from [`emoji-mart`](https://www.npmjs.com/package/emoji-mart). Therefore, the object type of our custom reactions needs to
conform to `NimbleEmoji` props.

`NimbleEmoji` accepts an `emoji` prop, which pertains to the object mapping of your custom reaction. The `emoji` prop has
Expand Down Expand Up @@ -107,15 +111,12 @@ const customReactions = [
```

:::caution
If custom `reactionOptions` are supplied to the selector component, then the same data set needs to be delivered to the
list component so the display for processed reactions has the same emoji objects.
If custom `reactionOptions` are supplied to the selector component, then the same data set needs to be delivered to the list component so the display for processed reactions has the same emoji objects.
:::

### The Final Code

Putting all the pieces together and building upon the [custom message](./message-ui.mdx#how-it-fits-together)
in the General Customization section, we are left with the following code for our [Message UI](../../components/message-components/message-ui.mdx)
component:
Putting all the pieces together and building upon the [custom message](./message-ui.mdx#how-it-fits-together) in the General Customization section, we are left with the following code for our [Message UI](../../components/message-components/message-ui.mdx) component:

```jsx
import React, { useRef } from 'react';
Expand Down Expand Up @@ -186,9 +187,7 @@ export const CustomMessage = () => {
<MessageText />
<MessageStatus />
{message.attachments && <Attachment attachments={message.attachments} />}
{hasReactions && (
<SimpleReactionsList reactionOptions={customReactions} />
)}
{hasReactions && <SimpleReactionsList reactionOptions={customReactions} />}
<MessageRepliesCountButton reply_count={message.reply_count} />
</div>
</div>
Expand Down
Loading

0 comments on commit 83f31da

Please sign in to comment.