-
Notifications
You must be signed in to change notification settings - Fork 274
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(emoji-mart): simplify EmojiPicker & EmojiIndex integration (#2117)
BREAKING CHANGE: `EmojiPicker` and `EmojiIndex` have changed, see release guides in #2117 for more information
- Loading branch information
1 parent
b829605
commit 60c24b8
Showing
54 changed files
with
578 additions
and
828 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
--- | ||
id: new-emoji-picker-integration-v11 | ||
sidebar_position: 3 | ||
title: EmojiPicker Integration (11.0.0) | ||
keywords: [migration guide, upgrade, emoji picker, breaking changes, v11] | ||
--- | ||
|
||
import GHComponentLink from '../_docusaurus-components/GHComponentLink'; | ||
|
||
## Dropping support for built-in `EmojiPicker` | ||
|
||
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. | ||
|
||
## Changes to the default component composition (architecture) | ||
|
||
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). | ||
|
||
{/_ TODO: extend once the component is fully ready _/} | ||
|
||
## Switching to opt-in mechanism (BREAKING CHANGE) | ||
|
||
We made `emoji-mart` package in our SDK completely optional which means that `EmojiPicker` component is now disabled by default. | ||
|
||
### Reinstate the `EmojiPicker` component | ||
|
||
To reinstate the previous behavior you'll have to add `emoji-mart` to your packages and make sure the package versions fit our peer-dependency requirements: | ||
|
||
```bash | ||
yarn add emoji-mart@^5.5.2 @emoji-mart/data@^1.1.2 @emoji-mart/react@^1.1.1 | ||
``` | ||
|
||
\\Import `EmojiPicker` component from the `stream-chat-react` package: | ||
|
||
```tsx | ||
import { Channel } from 'stream-chat-react'; | ||
import { EmojiPicker } from 'stream-chat-react/emojis'; | ||
|
||
// and apply it to the Channel (component context) | ||
|
||
const WrappedChannel = ({ children }) => { | ||
return <Channel EmojiPicker={EmojiPicker}>{children}</Channel>; | ||
}; | ||
``` | ||
|
||
### Build your custom `EmojiPicker` (example) | ||
|
||
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 simple `EmojiPicker` built using `emoji-picker-react` package: | ||
|
||
```tsx | ||
import EmojiPicker from 'emoji-picker-react'; | ||
import { useMessageInputContext } from 'stream-chat-react'; | ||
|
||
export const CustomEmojiPicker = () => { | ||
const [open, setOpen] = useState(false); | ||
|
||
const { insertText, textareaRef } = useMessageInputContext(); | ||
|
||
return ( | ||
<> | ||
<button onClick={() => setOpen((cv) => !cv)}>Open EmojiPicker</button> | ||
|
||
{open && ( | ||
<EmojiPicker | ||
onEmojiClick={(emoji, event) => { | ||
insertText(e.native); | ||
textareaRef.current?.focus(); // returns focus back to the message input element | ||
}} | ||
/> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
// and pass it down to the `Channel` component | ||
``` | ||
|
||
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 component (`EmojiPicker`)]() which comes with the SDK for inspiration. | ||
|
||
{/_ TODO: mention EmojiContext removal _/} |
133 changes: 133 additions & 0 deletions
133
docusaurus/docs/React/release-guides/emoji-search-index-v11.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
--- | ||
id: emoji-search-index-integration-v11 | ||
sidebar_position: 4 | ||
title: Emoji Search Index Integration (11.0.0) | ||
keywords: [migration guide, upgrade, emoji search index, breaking changes, v11] | ||
--- | ||
|
||
## Dropping support for built-in `EmojiIndex` | ||
|
||
By default, our SDK comes bundled with the `emoji-mart`'s (`emojiIndex`)[https://github.com/missive/emoji-mart/tree/v3.0.1#headless-search]. This index serves as a tool for efficiently searching through the emoji list and returning a subset that matches the search criteria (query). Within our SDK, this functionality is utilized by our autocomplete component, triggered by entering `:<query>` to the meessage input. This functionality will continue to be integrated within our SDK. However, due to our decision to discontinue the use of `emoji-mart` within the SDK, this feature will now be available on an opt-in basis. With the updated types and interface this will also allow integrators to supply their own `emojiSearchIndex` instead of relying exclusively on the one supplied by `emoji-mart`. | ||
|
||
### Reinstate emoji autocomplete behavior (search for emojis with `:`) | ||
|
||
Add `emoji-mart` to your packages and make sure the package versions fit our peer-dependency requirements: | ||
|
||
```bash | ||
yarn add emoji-mart@^5.5.2 @emoji-mart/data@^1.1.2 | ||
``` | ||
|
||
\Import `SearchIndex` and `data` from `emoji-mart`, initiate these data and then and pass `SearchIndex` to our `MessageInput` component: | ||
|
||
```tsx | ||
import { MessageInput } from 'stream-chat-react'; | ||
import { init, SearchIndex } from 'emoji-mart'; | ||
import data from '@emoji-mart/data'; | ||
|
||
init({ data }); | ||
|
||
export const WrappedMessageInput = () => { | ||
return <MessageInput emojiSearchIndex={SearchIndex} focus />; | ||
}; | ||
``` | ||
|
||
### Build your custom `emojiSearchIndex` | ||
|
||
## Prerequisities | ||
|
||
Your data returned from the `search` method should have _at least_ these three properies which our SDK relies on: | ||
|
||
- name - display name for the emoji, ie: `"Smile"` | ||
- id - unique emoji identificator | ||
- skins - an array of emojis with different skins (our SDK uses only the first one in this array), ie: `[{ native: "😄" }]` | ||
|
||
Optional properties: | ||
|
||
- emoticons - an array of strings to match substitutions with, ie: `[":D", ":-D", ":d"]` | ||
- native - native emoji string (old `emoji-mart` API), ie: `"😄"` - will be prioritized if specified | ||
|
||
## Example | ||
|
||
```tsx | ||
import search from '@jukben/emoji-search'; | ||
|
||
const emoticonMap: Record<string, string[]> = { | ||
'😃': [':D', ':-D'], | ||
'😑': ['-_-'], | ||
'😢': [":'("], | ||
}; | ||
|
||
const emojiSearchIndex: EmojiSearchIndex = { | ||
search: (query) => { | ||
const results = search(query); | ||
|
||
return results.slice(0, 15).map((data) => ({ | ||
emoticons: emoticonMap[data.name], | ||
id: data.name, | ||
name: data.keywords.slice(1, data.keywords.length).join(', '), | ||
native: data.name, | ||
skins: [], | ||
})); | ||
}, | ||
}; | ||
|
||
export const WrappedChannel = ({ children }) => ( | ||
<Channel emojiSearchIndex={emojiSearchIndex}>{children}</Channel> | ||
); | ||
``` | ||
|
||
### Migrate from `v10` to `v11` (`EmojiIndex` becomes `emojiSearchIndex`) | ||
|
||
`EmojiIndex` has previously lived in the `EmojiContext` passed to through `Channel` component. But since `EmojiContext` no longer exists in our SDK, the property has been moved to our `ComponentContext` (still passed through `Channel`) and changed its name to `emojiSearchIndex` to properly repesent its funtionality. If your custom `EmojiIndex` worked with our default components in `v10` then it should still work in `v11` without any changes to its `search` method output: | ||
|
||
Your old code: | ||
|
||
```tsx | ||
import { Channel, MessageInput } from 'stream-chat-react'; | ||
// arbitrary import | ||
import { CustomEmojiIndex } from './CustomEmojiIndex'; | ||
|
||
const App = () => { | ||
return ( | ||
<Channel EmojiIndex={CustomEmojiIndex}> | ||
{/* other components */} | ||
<MessageInput /> | ||
</Channel> | ||
); | ||
}; | ||
``` | ||
|
||
Should newly look like this: | ||
|
||
```tsx | ||
import { Channel, MessageInput } from 'stream-chat-react'; | ||
// arbitrary import | ||
import { CustomEmojiIndex } from './CustomEmojiIndex'; | ||
|
||
const App = () => { | ||
return ( | ||
<Channel emojiSearchIndex={CustomEmojiIndex}> | ||
{/* other components */} | ||
<MessageInput /> | ||
</Channel> | ||
); | ||
}; | ||
``` | ||
|
||
Or enable it in either of the `MessageInput` components individually: | ||
|
||
```tsx | ||
import { Channel, MessageInput } from 'stream-chat-react'; | ||
// arbitrary import | ||
import { CustomEmojiIndex } from './CustomEmojiIndex'; | ||
|
||
const App = () => { | ||
return ( | ||
<Channel> | ||
{/* other components */} | ||
<MessageInput emojiSearchIndex={CustomEmojiIndex} /> | ||
<Thread additionalMessageInputProps={{ emojiSearchIndex: CustomEmojiIndex }} /> | ||
</Channel> | ||
); | ||
}; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.