Skip to content

Commit a6e0a87

Browse files
fix(emoji-mart): simplify EmojiPicker & emojiSearchIndex (#2117)
Fixes: #2116 Fixes: #2094 BREAKING CHANGE: `EmojiPicker` & `EmojiIndex` signatures changed, `EmojiIndex` has been renamed to `emojiSearchIndex`, both `EmojiPicker` & `emojiSearchIndex` are now optional, see [release guide](https://github.com/GetStream/stream-chat-react/blob/v11.0.0/docusaurus/docs/React/release-guides/upgrade-to-v11.mdx) for more information BREAKING CHANGE: `useImageFlagEmojisOnWindow` flag now requires extra style sheet import, see [release guide](https://github.com/GetStream/stream-chat-react/blob/v11.0.0/docusaurus/docs/React/release-guides/upgrade-to-v11.mdx) for more information
1 parent 14bef23 commit a6e0a87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+811
-998
lines changed

docusaurus/docs/React/basics/getting-started.mdx

+13-1
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,14 @@ const { client } = useChatContext();
124124
The [`Channel`](../components/core-components/channel.mdx) component is a React Context provider that wraps all of the logic, functionality, and UI for an individual chat channel.
125125
It provides five separate contexts to its children:
126126

127+
:::caution
128+
`EmojiContext` has been removed in version `11.0.0`, see related release guides (["Reactions 11.0.0"](../release-guides/reactions-v11.mdx), ["EmojiPicker 11.0.0"](../release-guides/emoji-picker-v11.mdx) and ["emojiSearchIndex 11.0.0"](../release-guides/emoji-search-index-v11.mdx)) to adjust your integration to this new change.
129+
:::
130+
127131
- [`ChannelStateContext`](../components/contexts/channel-state-context.mdx) - stateful data (ex: `messages` or `members`)
128132
- [`ChannelActionContext`](../components/contexts/channel-action-context.mdx) - action handlers (ex: `sendMessage` or `openThread`)
129133
- [`ComponentContext`](../components/contexts/component-context.mdx) - custom component UI overrides (ex: `Avatar` or `Message`)
130-
- [`EmojiContext`](../components/contexts/emoji-context.mdx) - emoji UI components and data (ex: `EmojiPicker` or `emojiConfig`)
134+
- [`EmojiContext`](../components/contexts/emoji-context.mdx) - emoji UI components and data (ex: `EmojiPicker` or `emojiConfig`) - removed in `11.0.0`
131135
- [`TypingContext`](../components/contexts/typing-context.mdx) - object of currently typing users (i.e., `typing`)
132136

133137
### ChannelList
@@ -172,6 +176,14 @@ The [`MessageInput`](../components/message-input-components/message-input.mdx) c
172176

173177
The [`Thread`](../components/core-components/thread.mdx) component renders a list of replies tied to a single parent message in a channel's main message list. A `Thread` maintains its own state and renders its own `MessageList` and `MessageInput` components.
174178

179+
### Emojis (picker & autocomplete)
180+
181+
The SDK is equipped with features designed to facilitate seamless integration, enabling developers to effortlessly incorporate emoji picker and emoji autocomplete (built on top of [`emoji-mart`](https://github.com/missive/emoji-mart)) functionalities for a comprehensive chat experience.
182+
183+
Starting from version `11.0.0`, these features are entirely optional, requiring integrators to opt-in manually. The decision was made in conjunction with enhanced architecture, aiming to reduce the overall size of the final bundles of our integrators.
184+
185+
Make sure to read ["EmojiPicker 11.0.0"](../release-guides/emoji-picker-v11.mdx) and ["emojiSearchIndex 11.0.0"](../release-guides/emoji-search-index-v11.mdx) release guides for more information.
186+
175187
## Summary
176188

177189
In addition to the above referenced UI components, client instantiation, and user connection, you need little other code to get a fully functioning chat application up and running. See below for an example of the complete code.

docusaurus/docs/React/components/contexts/emoji-context.mdx

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ sidebar_position: 5
44
title: EmojiContext
55
---
66

7+
:::caution
8+
`EmojiContext` has been removed in version `11.0.0`, see related release guides (["Reactions 11.0.0"](../release-guides/reactions-v11.mdx), ["EmojiPicker 11.0.0"](../release-guides/emoji-picker-v11.mdx) and ["emojiSearchIndex 11.0.0"](../release-guides/emoji-search-index-v11.mdx)) to adjust your integration to this new change.
9+
:::
10+
711
The `EmojiContext` is established by the `Channel` component and exposes the `useEmojiContext` hook. This context holds
812
the UI components and stateful data necessary to render emoji selector functionality.
913

docusaurus/docs/React/components/core-components/channel.mdx

+57-46
Original file line numberDiff line numberDiff line change
@@ -296,45 +296,54 @@ Custom UI component to override default edit message input.
296296
| --------- | ---------------------------------------------------------------------------------- |
297297
| component | <GHComponentLink text='EditMessageForm' path='/MessageInput/EditMessageForm.tsx'/> |
298298

299-
### Emoji
299+
### Emoji (removed in `11.0.0`)
300300

301301
Custom UI component to override default `NimbleEmoji` from `emoji-mart`.
302302

303303
| Type |
304304
| --------- |
305305
| component |
306306

307-
### emojiData
307+
### emojiData (removed in `11.0.0`)
308308

309309
Custom prop to override default `facebook.json` emoji data set from `emoji-mart`.
310310

311311
| Type |
312312
| ------ |
313313
| object |
314314

315-
### EmojiIcon
315+
### EmojiIcon (removed in `11.0.0`)
316316

317317
Custom UI component for emoji button in input.
318318

319319
| Type | Default |
320320
| --------- | ----------------------------------------------------------------------- |
321321
| component | <GHComponentLink text='EmojiIconSmall' path='/MessageInput/icons.tsx'/> |
322322

323-
### EmojiIndex
323+
### EmojiIndex (removed in `11.0.0`)
324324

325-
Custom UI component to override default `NimbleEmojiIndex` from `emoji-mart`.
325+
Custom search mechanism class to override default `NimbleEmojiIndex` class from `emoji-mart`.
326326

327-
| Type |
328-
| --------- |
329-
| component |
327+
| Type | Default |
328+
| ----- | ----------------------------------------------------------------------------------------------------------------- |
329+
| class | [NimbleEmojiIndex](https://github.com/missive/emoji-mart/blob/v3.0.1/src/utils/emoji-index/nimble-emoji-index.js) |
330330

331-
### EmojiPicker
331+
### emojiSearchIndex (available since `11.0.0`)
332332

333-
Custom UI component to override default `NimblePicker` from `emoji-mart`.
333+
Custom search mechanism instance or object to enable emoji autocomplete. See ["emojiSearchIndex 11.0.0"](../../release-guides/emoji-search-index-v11.mdx) release guide for more information.
334334

335-
| Type |
336-
| --------- |
337-
| component |
335+
| Type | Default |
336+
| ------ | --------- |
337+
| object | undefined |
338+
339+
### EmojiPicker (changed in `11.0.0`)
340+
341+
Custom UI component to override default `NimblePicker` from `emoji-mart`. Markup structure changed in `11.0.0`, see ["EmojiPicker 11.0.0"](../../release-guides/emoji-picker-v11.mdx) release guide for more information.
342+
343+
| Version | Type | Default |
344+
| ------- | --------- | -------------------------------------------------------------------------------------------------------- |
345+
| >=4.0.0 | component | [NimblePicker](https://github.com/missive/emoji-mart/blob/v3.0.1/src/components/picker/nimble-picker.js) |
346+
| ^11.0.0 | component | undefined |
338347

339348
### EmptyPlaceholder
340349

@@ -414,48 +423,50 @@ A custom function to provide size configuration for image attachments
414423
Allows to prevent triggering the `channel.watch()` (triggers channel query HTTP request) call when mounting the `Channel` component (the default behavior) with uninitialized (`channel.initialized`) `Channel` instance. That means that no channel data from the back-end will be received neither channel WS events will be delivered to the client. Preventing to initialize the channel on mount allows us to postpone the channel creation in the Stream's DB to a later point in time, for example, when a first message is sent:
415424

416425
```typescript jsx
417-
import {useCallback} from "react";
426+
import { useCallback } from 'react';
418427
import {
419428
getChannel,
420429
MessageInput as StreamMessageInput,
421-
MessageInputProps, MessageToSend,
430+
MessageInputProps,
431+
MessageToSend,
422432
useChannelActionContext,
423-
useChatContext
424-
} from "stream-chat-react";
425-
import {Message, SendMessageOptions} from "stream-chat";
433+
useChatContext,
434+
} from 'stream-chat-react';
435+
import { Message, SendMessageOptions } from 'stream-chat';
426436

427-
import {useChannelInitContext} from "../../context/ChannelInitProvider";
428-
import type { MyStreamChatGenerics } from "../../types";
437+
import { useChannelInitContext } from '../../context/ChannelInitProvider';
438+
import type { MyStreamChatGenerics } from '../../types';
429439

430440
export const MessageInput = (props: MessageInputProps) => {
431-
const {client} = useChatContext();
432-
const {sendMessage} = useChannelActionContext();
433-
const { setInitializedChannelOnMount} = useChannelInitContext();
434-
435-
const submitHandler: MessageInputProps['overrideSubmitHandler'] = useCallback(async (
436-
message: MessageToSend<MyStreamChatGenerics>,
437-
channelCid: string,
438-
customMessageData?: Partial<Message<MyStreamChatGenerics>>,
439-
options?: SendMessageOptions,
440-
) => {
441-
const [channelType, channelId] = channelCid.split(":");
442-
const channel = client.channel(channelType, channelId);
443-
if (!channel.initialized) {
444-
await getChannel({channel, client});
445-
setInitializedChannelOnMount(true);
446-
}
447-
448-
await sendMessage(message, customMessageData, options);
449-
}, [client, sendMessage, setInitializedChannelOnMount]);
450-
451-
return (
452-
<StreamMessageInput {...props} overrideSubmitHandler={submitHandler} />
441+
const { client } = useChatContext();
442+
const { sendMessage } = useChannelActionContext();
443+
const { setInitializedChannelOnMount } = useChannelInitContext();
444+
445+
const submitHandler: MessageInputProps['overrideSubmitHandler'] = useCallback(
446+
async (
447+
message: MessageToSend<MyStreamChatGenerics>,
448+
channelCid: string,
449+
customMessageData?: Partial<Message<MyStreamChatGenerics>>,
450+
options?: SendMessageOptions,
451+
) => {
452+
const [channelType, channelId] = channelCid.split(':');
453+
const channel = client.channel(channelType, channelId);
454+
if (!channel.initialized) {
455+
await getChannel({ channel, client });
456+
setInitializedChannelOnMount(true);
457+
}
458+
459+
await sendMessage(message, customMessageData, options);
460+
},
461+
[client, sendMessage, setInitializedChannelOnMount],
453462
);
463+
464+
return <StreamMessageInput {...props} overrideSubmitHandler={submitHandler} />;
454465
};
455466
```
456467

457468
| Type | Default |
458-
|---------|---------|
469+
| ------- | ------- |
459470
| boolean | true |
460471

461472
### Input
@@ -662,9 +673,9 @@ Custom UI component for send button.
662673

663674
You can turn on/off thumbnail generation for video attachments
664675

665-
| Type |
666-
| --------- |
667-
| `boolean` |
676+
| Type |
677+
| ------- |
678+
| boolean |
668679

669680
### skipMessageDataMemoization
670681

docusaurus/docs/React/components/core-components/chat.mdx

+6-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ const i18nInstance = new Streami18n({
9393
});
9494

9595
<Chat client={client} i18nInstance={i18nInstance}>
96-
{// children of Chat component}
97-
</Chat>
96+
{/* children of Chat component */}
97+
</Chat>;
9898
```
9999

100100
| Type |
@@ -123,6 +123,10 @@ Windows 10 does not support country flag emojis out of the box. It chooses to re
123123
Stream Chat can override this behavior by loading a custom web font that will render images instead (PNGs or SVGs depending
124124
on the platform). Set this prop to true if you want to use these custom emojis for Windows users.
125125

126+
:::caution
127+
If you're moving from older versions to `11.0.0` then make sure to import related stylesheet from `stream-chat-react/css/v2/emoji-replacement.css` as it has been removed from our main stylesheet to reduce final bundle size for integrators who do not wish to use this feature.
128+
:::
129+
126130
| Type | Default |
127131
| ------- | ------- |
128132
| boolean | false |

docusaurus/docs/React/guides/channel-list-infinite-scroll.mdx

+10-11
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,19 @@ import { ChannelList, InfiniteScroll } from 'stream-chat-react';
2828
If you would like to adjust the configuration parameters like `threshold`, `reverse` (`PaginatorProps`) or `useCapture`, etc. (`InfiniteScrollProps`), you can create a wrapper component where these props can be set:
2929

3030
```tsx
31-
import {
32-
ChannelList,
33-
InfiniteScroll,
34-
InfiniteScrollProps
35-
} from 'stream-chat-react';
36-
31+
import { ChannelList, InfiniteScroll, InfiniteScrollProps } from 'stream-chat-react';
3732

3833
const Paginator = (props: InfiniteScrollProps) => <InfiniteScroll {...props} threshold={50} />;
3934

40-
...
41-
<ChannelList filters={filters} sort={sort} options={options}
42-
Paginator={Paginator}
43-
showChannelSearch
44-
/>
35+
// ...
36+
37+
<ChannelList
38+
filters={filters}
39+
sort={sort}
40+
options={options}
41+
Paginator={Paginator}
42+
showChannelSearch
43+
/>;
4544
```
4645

4746
Especially the `threshold` prop may need to be set as the default is 250px. That may be too soon to load more channels.

docusaurus/docs/React/guides/customization/emoji-picker.mdx

+8-11
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@ title: Emoji Picker
66

77
import CustomEmojiPicker from '../../assets/CustomEmojiPicker.png';
88

9-
In this example, we will demonstrate how to create a custom Emoji Picker component that can be used in the `MessageInput`.
10-
This component will replace the default [`EmojiPicker`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/EmojiPicker.tsx)
11-
with only breakfast food emojis.
9+
:::caution
10+
Note that this guide is for versions lower than `11.0.0`, the new API has slightly changed. See the ["EmojiPicker 11.0.0"](../../release-guides/emoji-picker-v11.mdx) release guide to help you transition smoothly to the new API.
11+
:::
12+
13+
In this example, we will demonstrate how to create a custom Emoji Picker component that can be used in the `MessageInput`. This component will replace the default [`EmojiPicker`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/EmojiPicker.tsx) with only breakfast food emojis.
1214

1315
## Choose Your Emojis
1416

15-
The default `EmojiPicker` renders individual emoji objects using the [`NimbleEmoji`](https://github.com/missive/emoji-mart/blob/master/src/components/emoji/nimble-emoji.js)
16-
component from [emoji-mart](https://www.npmjs.com/package/emoji-mart). Our custom set of emojis will need to follow the same `NimbleEmoji` props.
17-
`NimbleEmoji` accepts an `emoji` prop, which pertains to either an object mapping of the emoji data or simply the ID (for IDs already existing
18-
in `emoji-mart`). The object mapping of the `emoji` prop has the following type:
17+
The default `EmojiPicker` renders individual emoji objects 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). Our custom set of emojis will need to follow the same `NimbleEmoji` props. `NimbleEmoji` accepts an `emoji` prop, which pertains to either an object mapping of the emoji data or simply the ID (for IDs already existing in `emoji-mart`). The object mapping of the `emoji` prop has the following type:
1918

2019
```tsx
2120
export interface BaseEmoji {
@@ -29,8 +28,7 @@ export interface BaseEmoji {
2928
}
3029
```
3130

32-
In this example we will use only the ID and select existing emojis. For a more detailed example of how to construct these emoji objects, please see the
33-
[Reactions Selector and List](../theming/reactions.mdx) section. Below is the array of breakfast emojis we will use:
31+
In this example we will use only the ID and select existing emojis. For a more detailed example of how to construct these emoji objects, please see the [Reactions Selector and List](../theming/reactions.mdx) section. Below is the array of breakfast emojis we will use:
3432

3533
```tsx
3634
const customEmojis = ['fried_egg', 'croissant', 'bacon', 'waffle', 'pancakes', 'doughnut'];
@@ -43,8 +41,7 @@ loaded into the component library.
4341

4442
## Create the Custom Component
4543

46-
To construct our component, we will utilize the `EmojiContext` to get our `emojiConfig` data. This config object contains the `emojiData` we need for the
47-
`data` prop on the `Emoji` component. Using the `onSelectEmoji` method from the `MessageInputContext`, we can add the onClick functionality to our custom picker.
44+
To construct our component, we will utilize the `EmojiContext` to get our `emojiConfig` data. This config object contains the `emojiData` we need for the `data` prop on the `Emoji` component. Using the `onSelectEmoji` method from the `MessageInputContext`, we can add the onClick functionality to our custom picker.
4845

4946
:::note
5047
The `Emoji` component needs to be wrapped in React's `Suspense` component because it is lazy loaded.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
id: emoji-picker-v11
3+
sidebar_position: 3
4+
title: EmojiPicker 11.0.0
5+
keywords: [migration guide, upgrade, emoji picker, breaking changes, v11]
6+
---
7+
8+
import GHComponentLink from '../_docusaurus-components/GHComponentLink';
9+
10+
## Dropping support for built-in `EmojiPicker`
11+
12+
By default - our SDK would ship with `emoji-mart` dependency on top of which our `EmojiPicker` component is built. And since the SDK is using `emoji-mart` for this component - it was also reused for reactions (`ReactionsList` and `ReactionSelector`) and suggestion list (`MessageInput`). This solution proved to be very uncomfortable to work with when it came to replacing either of the mentioned components (or disabling them completely) and the final applications using our SDK would still bundle certain `emoji-mart` parts which weren't needed (or seemingly "disabled") resulting in sub-optimal load times. Maintaining such architecture became a burden so we're switching things a bit.
13+
14+
## Changes to the default component composition (architecture)
15+
16+
SDK's `EmojiPicker` component now comes as two-part "bundle" - a button and an actual picker element. The component now holds its own `open` state which is handled by clicking the button (or anywhere else to close it).
17+
18+
## Switching to opt-in mechanism (BREAKING CHANGE)
19+
20+
We made `emoji-mart` package in our SDK completely optional which means that `EmojiPicker` component is now disabled by default.
21+
22+
### Reinstate the `EmojiPicker` component
23+
24+
To reinstate the previous behavior you'll have to add `emoji-mart` to your packages and make sure the packages come with versions that fit our peer-dependency requirements:
25+
26+
```bash
27+
yarn add emoji-mart @emoji-mart/data @emoji-mart/react
28+
```
29+
30+
Import `EmojiPicker` component from the `stream-chat-react` package:
31+
32+
```tsx
33+
import { Channel } from 'stream-chat-react';
34+
import { EmojiPicker } from 'stream-chat-react/emojis';
35+
36+
// and apply it to the Channel (component context)
37+
38+
const WrappedChannel = ({ children }) => {
39+
return <Channel EmojiPicker={EmojiPicker}>{children}</Channel>;
40+
};
41+
```
42+
43+
### Build your custom `EmojiPicker` (with example)
44+
45+
If `emoji-mart` is too heavy for your use-case and you'd like to build your own you can certainly do so, here's a very simple `EmojiPicker` example built using `emoji-picker-react` package:
46+
47+
```tsx
48+
import EmojiPicker from 'emoji-picker-react';
49+
import { useMessageInputContext } from 'stream-chat-react';
50+
51+
export const CustomEmojiPicker = () => {
52+
const [open, setOpen] = useState(false);
53+
54+
const { insertText, textareaRef } = useMessageInputContext();
55+
56+
return (
57+
<>
58+
<button onClick={() => setOpen((isOpen) => !isOpen)}>Open EmojiPicker</button>
59+
60+
{open && (
61+
<EmojiPicker
62+
onEmojiClick={(emoji, event) => {
63+
insertText(emoji.native);
64+
textareaRef.current?.focus(); // returns focus back to the message input element
65+
}}
66+
/>
67+
)}
68+
</>
69+
);
70+
};
71+
72+
// and pass it down to the `Channel` component
73+
```
74+
75+
You can make the component slightly better using [`FloatingUI`](https://floating-ui.com/) by wrapping the actual picker element to make it float perfectly positioned above the button. See the source of the <GHComponentLink text="EmojiPicker" branch="feat/emoji-picker-delete" as="code" path="/Emojis/EmojiPicker.tsx" /> component which comes with the SDK for inspiration.
76+
77+
## Old `emoji-mart` (v3.0.1)
78+
79+
Even though it's not explicitly provided by our SDK anymore, it's still possible for our integrators to use older version of the `emoji-mart` - specifically version `3.0.1` on top of which our old components were built. We don't recommend using old version of the `emoji-mart` but if you really need to, follow the [`3.0.1` documentation](https://github.com/missive/emoji-mart/tree/v3.0.1#picker) in combination with the previous guide to build your own `EmojiPicker` component with the old `emoji-mart` API. Beware though, if you wish to use slightly modified `emoji-mart` CSS previously supplied by our SDK by default in the main `index.css` file, you'll now have to explicitly import it:
80+
81+
```tsx
82+
import 'stream-chat-react/css/v2/index.css';
83+
import 'stream-chat-react/css/v2/emoji-mart.css';
84+
```

0 commit comments

Comments
 (0)