diff --git a/docusaurus/docs/React/basics/getting-started.mdx b/docusaurus/docs/React/basics/getting-started.mdx index b8b2c73c6..1d41a75b2 100644 --- a/docusaurus/docs/React/basics/getting-started.mdx +++ b/docusaurus/docs/React/basics/getting-started.mdx @@ -125,7 +125,7 @@ The [`Channel`](../components/core-components/channel.mdx) component is a React It provides five separate contexts to its children: :::caution -`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. +`EmojiContext` has been removed in version `11.0.0`, see related release guides ([Introducing new reactions](../release-guides/upgrade-to-v11.mdx#introducing-new-reactions), [Dropping support for built-in `EmojiPicker`](../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojipicker) and [Dropping support for built-in `EmojiIndex`](../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojiindex)) to adjust your integration to this new change. ::: - [`ChannelStateContext`](../components/contexts/channel-state-context.mdx) - stateful data (ex: `messages` or `members`) @@ -182,7 +182,7 @@ The SDK is equipped with features designed to facilitate seamless integration, e 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. -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. +Make sure to read ["Dropping support for built-in `EmojiPicker`"](../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojipicker) and ["Dropping support for built-in `EmojiIndex`"](../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojiindex) release guides for more information. ## Summary diff --git a/docusaurus/docs/React/components/contexts/emoji-context.mdx b/docusaurus/docs/React/components/contexts/emoji-context.mdx index 9dfd88b86..9ae1d435f 100644 --- a/docusaurus/docs/React/components/contexts/emoji-context.mdx +++ b/docusaurus/docs/React/components/contexts/emoji-context.mdx @@ -5,7 +5,7 @@ title: EmojiContext --- :::caution -`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. +`EmojiContext` has been removed in version `11.0.0`, see related release guides ([Introducing new reactions](../../release-guides/upgrade-to-v11.mdx#introducing-new-reactions), [Dropping support for built-in `EmojiPicker`](../../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojipicker) and [Dropping support for built-in `EmojiIndex`](../../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojiindex)) to adjust your integration to this new change. ::: The `EmojiContext` is established by the `Channel` component and exposes the `useEmojiContext` hook. This context holds diff --git a/docusaurus/docs/React/components/core-components/channel.mdx b/docusaurus/docs/React/components/core-components/channel.mdx index a3e07fc95..d7bd987ed 100644 --- a/docusaurus/docs/React/components/core-components/channel.mdx +++ b/docusaurus/docs/React/components/core-components/channel.mdx @@ -183,30 +183,30 @@ Optional configuration parameters used for the initial channel query. Applied on In the example below, we specify, that the first page of messages when a channel is queried should have 20 messages (the default is 100). Note that the `channel` prop has to be passed along `channelQueryOptions`. ```tsx -import {ChannelQueryOptions} from "stream-chat"; -import {Channel, useChatContext} from "stream-chat-react"; +import { ChannelQueryOptions } from 'stream-chat'; +import { Channel, useChatContext } from 'stream-chat-react'; const channelQueryOptions: ChannelQueryOptions = { messages: { limit: 20 }, }; type ChannelRendererProps = { - id: string; - type: string; + id: string; + type: string; }; -const ChannelRenderer = ({id, type}: ChannelRendererProps) => { +const ChannelRenderer = ({ id, type }: ChannelRendererProps) => { const { client } = useChatContext(); return ( {/* Channel children */} ); -} +}; ``` | Type | -|-----------------------| +| --------------------- | | `ChannelQueryOptions` | ### CooldownTimer @@ -229,8 +229,8 @@ Custom UI component for date separators. Custom action handler to override the default `client.deleteMessage(message.id)` function. -| Type | -|---------------------------------------------------------------------------------------------------------------------------| +| Type | +| ---------------------------------------------------------------------------------------------- | | `(message: StreamMessage) => Promise>` | The function can execute different logic for message replies compared to messages in the main message list based on the `parent_id` property of `StreamMessage` object: @@ -330,7 +330,7 @@ Custom search mechanism class to override default `NimbleEmojiIndex` class from ### emojiSearchIndex (available since `11.0.0`) -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. +Custom search mechanism instance or object to enable emoji autocomplete. See ["Dropping support for built-in `EmojiIndex`"](../../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojiindex) release guide for more information. | Type | Default | | ------ | --------- | @@ -338,7 +338,7 @@ Custom search mechanism instance or object to enable emoji autocomplete. See ["e ### EmojiPicker (changed in `11.0.0`) -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. +Custom UI component to override default `NimblePicker` from `emoji-mart`. Markup structure changed in `11.0.0`, see ["Dropping support for built-in `EmojiPicker`"](../../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojipicker) release guide for more information. | Version | Type | Default | | ------- | --------- | -------------------------------------------------------------------------------------------------------- | diff --git a/docusaurus/docs/React/components/message-components/reactions.mdx b/docusaurus/docs/React/components/message-components/reactions.mdx index 68189c27d..d9ddd99ff 100644 --- a/docusaurus/docs/React/components/message-components/reactions.mdx +++ b/docusaurus/docs/React/components/message-components/reactions.mdx @@ -7,7 +7,7 @@ title: Reactions import GHComponentLink from '../../_docusaurus-components/GHComponentLink'; :::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. +If you're moving from older versions to `11.0.0` then make sure to read ["Introducing new reactions"](../../release-guides/upgrade-to-v11.mdx#introducing-new-reactions) release guide to help you transition to the new implementation. ::: 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: diff --git a/docusaurus/docs/React/guides/customization/emoji-picker.mdx b/docusaurus/docs/React/guides/customization/emoji-picker.mdx index 37fb310d0..dc7ae5e74 100644 --- a/docusaurus/docs/React/guides/customization/emoji-picker.mdx +++ b/docusaurus/docs/React/guides/customization/emoji-picker.mdx @@ -7,7 +7,7 @@ title: Emoji Picker import CustomEmojiPicker from '../../assets/CustomEmojiPicker.png'; :::caution -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. +Note that this guide is for versions lower than `11.0.0`, the new API has slightly changed. See the ["Dropping support for built-in `EmojiPicker`"](../../release-guides/upgrade-to-v11.mdx#dropping-support-for-built-in-emojipicker) release guide to help you transition smoothly to the new API. ::: 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. diff --git a/docusaurus/docs/React/guides/theming/reactions.mdx b/docusaurus/docs/React/guides/theming/reactions.mdx index f49474a86..7cf289e3c 100644 --- a/docusaurus/docs/React/guides/theming/reactions.mdx +++ b/docusaurus/docs/React/guides/theming/reactions.mdx @@ -8,7 +8,7 @@ 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. +If you're moving from older versions to `11.0.0` then make sure to read ["Introducing new reactions"](../../release-guides/upgrade-to-v11.mdx#introducing-new-reactions) 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 diff --git a/docusaurus/docs/React/release-guides/emoji-picker-v11.mdx b/docusaurus/docs/React/release-guides/emoji-picker-v11.mdx deleted file mode 100644 index 8d7a10a3f..000000000 --- a/docusaurus/docs/React/release-guides/emoji-picker-v11.mdx +++ /dev/null @@ -1,84 +0,0 @@ ---- -id: emoji-picker-v11 -sidebar_position: 3 -title: EmojiPicker 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). - -## 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 packages come with versions that fit our peer-dependency requirements: - -```bash -yarn add emoji-mart @emoji-mart/data @emoji-mart/react -``` - -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 {children}; -}; -``` - -### Build your custom `EmojiPicker` (with 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 very simple `EmojiPicker` example 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 ( - <> - - - {open && ( - { - insertText(emoji.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 which comes with the SDK for inspiration. - -## Old `emoji-mart` (v3.0.1) - -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: - -```tsx -import 'stream-chat-react/css/v2/index.css'; -import 'stream-chat-react/css/v2/emoji-mart.css'; -``` diff --git a/docusaurus/docs/React/release-guides/emoji-search-index-v11.mdx b/docusaurus/docs/React/release-guides/emoji-search-index-v11.mdx deleted file mode 100644 index 4d5ee460c..000000000 --- a/docusaurus/docs/React/release-guides/emoji-search-index-v11.mdx +++ /dev/null @@ -1,138 +0,0 @@ ---- -id: emoji-search-index-v11 -sidebar_position: 4 -title: emojiSearchIndex 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), more specifically - `NimbleEmojiIndex` class which is then instantiated with custom `emojiData` by our SDK. 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 `:` 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 @emoji-mart/data -``` - -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 ; -}; -``` - -## 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 { type EmojiSearchIndex } from 'stream-chat-react'; -import search from '@jukben/emoji-search'; - -const emoticonMap: Record = { - '😃': [':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 }) => ( - {children} -); -``` - -## 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, customData } from './CustomEmojiIndex'; - -const App = () => { - return ( - - {/* other components */} - - - ); -}; -``` - -Should newly look like this: - -```tsx -import { Channel, MessageInput } from 'stream-chat-react'; -// arbitrary import -import { CustomEmojiIndex, customData } from './CustomEmojiIndex'; -// instantiate the search index -const customEmojiSearchIndex = new CustomEmojiIndex(customData); - -const App = () => { - return ( - - {/* other components */} - - - ); -}; -``` - -Or enable it in either of the `MessageInput` components individually: - -```tsx -import { Channel, MessageInput } from 'stream-chat-react'; -// arbitrary import -import { CustomEmojiIndex, customData } from './CustomEmojiIndex'; -// instantiate the search index -const customEmojiSearchIndex = new CustomEmojiIndex(customData); - -const App = () => { - return ( - - {/* other components */} - - - - ); -}; -``` diff --git a/docusaurus/docs/React/release-guides/reactions-v11.mdx b/docusaurus/docs/React/release-guides/reactions-v11.mdx deleted file mode 100644 index 3f6462cef..000000000 --- a/docusaurus/docs/React/release-guides/reactions-v11.mdx +++ /dev/null @@ -1,252 +0,0 @@ ---- -id: reactions-v11 -sidebar_position: 2 -title: Reactions 11.0.0 -keywords: [migration guide, upgrade, reactions, breaking changes, v11] ---- - -import GHComponentLink from '../_docusaurus-components/GHComponentLink'; - -## Introducing new reactions (with breaking changes) - -When it came to developer experience regarding customization of the reaction components our team noticed that our integrators generally strugled to make more advanced adjustments to reactions without having to rebuild the whole [component set](../components/message-components/reactions.mdx). The whole process has been quite unintuitive and that's why this update aims at making adjusting your reactions much easier. - -### Main reasons for a revamp - -- inability to reuse default (Stream supplied reactions) with your custom ones -- strong reliance on [`emoji-mart`](https://github.com/missive/emoji-mart) and inability to use completely custom reactions out of the box -- certain `additionalEmojiProps` did not work with Stream-supplied reactions - -```tsx -// not exported directly (hidden, leading to poor DX) -import { defaultMinimalEmojis } from 'stream-chat-react/dist/components/Channel/emojiData'; - -export const customReactions = [ - { - // relies on EmojiMart-supplied sprite sheet, "native" option does not work for Stream-supplied reactions - // you'd need to look up supported id's in stream-emoji.json under "emojis" key - id: 'bulb', - }, - // unsupported - { - id: 'rick_roll', - }, - // this wouldn't work - ...defaultMinimalEmojis, -]; -``` - -## New default setup and how it works - -SDK by default comes with five pre-defined reaction types (`haha`, `like`, `love`, `sad` and `wow`) which are newly rendered by component which utilises sprite sheet system and renders images for each reaction to make sure it works flawlessly on every system. Default reaction options are defined in and these options are reused for both [`ReactionSelector`](../components/message-components/reactions.mdx#reactionselector-props) and [`ReactionsList`](../components/message-components/reactions.mdx#reactionslist-props) (as well as [`SimpleReactionsList`](../components/message-components/reactions.mdx#simplereactionslist-props)). These options come by default from the ComponentContext but local component property will be prioritised if defined. This is how it works under the hood: - -```ts -contextReactionOptions = defaultReactionOptions; -// ... -const reactionOptions = propsReactionOptions ?? contextReactionOptions; -``` - -:::note -Beware that sixth reaction type `angry` has been removed in this update, if you need to re-enable it, follow [this guide](#re-enabling-angry-reaction). -::: - -## Custom reaction types and components - -It's possible to supply your own reaction types and components to represent such reactions - let's implement reaction of type `rick_roll` to render a Rick Roll GIF and define override for default type `love`: - -```tsx -import { Channel } from 'stream-chat-react'; - -const RickRollReaction = () => ( - -); - -const customReactionOptions = [ - { - Component: RickRollReaction, - type: 'rick_roll', - name: 'Rick Roll', - }, - { - Component: () => <>❤️ - type: 'love', - name: "Heart" - } -]; -``` - -And then you can pass these newly created options to [`Channel`](../components/core-components/channel.mdx) component which will be then propagated to `ReactionSelector` and `ReactionsList`: - -```tsx -{/*...*/} -``` - -## Emoji Mart integration - -If you're used to work with [EmojiMart emojis](https://github.com/missive/emoji-mart#-emoji-component) then integrating with new reaction system shouldn't be a big trouble as you can define how your components look and reach for context if you need to: - -```tsx -// arbitrary EmojiMartContext (does not come with the SDK) -import { useEmojiMartContext } from '../contexts'; - -const CustomLikeComponent = () => { - const { selectedSkinTones, selectedSet } = useEmojiMartContext(); - - // to use EmojiMart web components you'll need to go through initiation steps, see EmojiMart documentation - return ; -}; - -const reactionOptions = [ - { - type: 'like', - component: CustomLikeComponent, - name: 'EmojiMart like', - }, -]; - -// pass reaction options to component context (Channel) or to ReactionSelector and ReactionsList -``` - -## Use of different reaction components for the same reaction types for `ReactionSelector` and `ReactionsList` components - -If you need more fine-grain tuning and want to - for example - enable only a certain subset of clickable reactions but want to display the full set then you'd do something like this: - -```tsx -const JoyReaction = () => <>😂; -const CatReaction = () => <>🐈; -const ThumbsUpReaction = () => <>👍; -const SmileReaction = () => <>🙂; - -// subset of clickable options available to the user -const selectedReactionOptions = [ - { type: 'haha', Component: JoyReaction }, - { type: 'cat', Component: CatReaction }, -]; - -// set of all available options to be rendered -const completeReactionOptions = [ - { type: 'haha', Component: JoyReaction }, - { type: 'cat', Component: CatReaction }, - { type: '+1', Component: ThumbsUpReaction }, - { type: 'smile', Component: SmileReaction }, -]; -``` - -Or if you just want bigger icons for `ReactionsList` while `ReactionSelector` uses regular: - -```tsx -// arbitrary import (does not come with the SDK) -import { ReactionComponent } from './CustomReactions'; - -const selectorReactionOptions = [ - { - type: 'like', - component: ReactionComponent.Like, - name: 'Like', - }, -]; - -const listReactionOptions = [ - { - type: 'like', - // in this example it's just different size of the emoji - component: ReactionComponent.LikeMedium, - name: 'Like medium', - }, -]; -``` - -You can then apply these new options to `ReactionSelector` and `ReactionsList` directly: - -```tsx -import { ReactionSelector, ReactionsList, Channel } from 'stream-chat-react'; - -// ReactionSelector component requires forwarded reference -const CustomReactionSelector = forwardRef((props, ref) => ( - -)); - -const CustomReactionsList = (props) => ( - -); -``` - -And then pass them down to component context (`Channel`) component: - -```tsx - - {/*...*/} - -``` - -## Use of `SpriteImage` component - -:::note -We suggest using individual images per reaction type as multiple smaller requests is more bandwidth-friendly. Use this component only if you have no other choice. -::: - -If you have a sprite sheet of emojis and there's no other way for you to implement your reactions, you can utilise utility component which comes with the SDK: - -```tsx -import { SpriteImage } from 'stream-chat-react'; - -const SPRITE_URL = 'https://getstream.imgix.net/images/emoji-sprite.png'; - -const reactionOptions = [ - { - type: 'joy', - component: () => ( - // renders fallback initially and then image when it successfully loads - - ), - name: 'ROFL', - }, -]; - -// pass reaction options to component context (Channel) or to ReactionSelector and ReactionsList -``` - -## Transition from previous version of custom reactions - -### Default setup - -The transition is super easy: - -```tsx -import { defaultReactionOptions } from 'stream-chat-react'; - -// old custom options -const reactionOptions = [{ id: 'bulb' /* ...extra properties... */ }, { id: '+1' }, { id: 'joy' }]; - -// would newly become -const newReactionOptions = [ - { type: 'bulb', Component: () => <>💡, name: 'Bulb reaction' }, - { type: '+1', Component: () => <>👍 }, - { type: 'joy', Component: () => <>🤣, name: 'ROFL' }, - // reuse default ones if you want to - ...defaultReactionOptions, -]; -``` - -All of the extra options previously applied to `EmojiMart` emojis can now be directly applied to your custom components either manually or through your custom context. For more information see [EmojiMart integration](#emoji-mart-integration). - -### Re-enabling `angry` reaction - -For better compatibility with other SDKs we decided to consolidate default available types and remove `angry` type which was previously available only in the React SDK. Here's how you'd go about re-enabling it: - -```tsx -import { StreamEmoji, defaultReactionOptions } from 'stream-chat-react'; - -const reactionOptions = [ - ...defaultReactionOptions, - { type: 'angry', Component: () => , name: 'Angry' }, -]; - -// pass reaction options to component context (Channel) or to ReactionSelector and ReactionsList -``` diff --git a/docusaurus/docs/React/release-guides/upgrade-to-v11.mdx b/docusaurus/docs/React/release-guides/upgrade-to-v11.mdx new file mode 100644 index 000000000..8932d6785 --- /dev/null +++ b/docusaurus/docs/React/release-guides/upgrade-to-v11.mdx @@ -0,0 +1,527 @@ +--- +id: upgrade-to-v11 +sidebar_position: 2 +title: Upgrade to v11 +keywords: [migration guide, upgrade, v11, breaking changes, emojis, reactions] +--- + +import GHComponentLink from '../_docusaurus-components/GHComponentLink'; + +## Introducing new reactions + +When it came to developer experience regarding customization of the reaction components our team noticed that our integrators generally strugled to make more advanced adjustments to reactions without having to rebuild the whole [component set](../components/message-components/reactions.mdx). The whole process has been quite unintuitive and that's why this update aims at making adjusting your reactions much easier. + +### Main reasons for a revamp + +- inability to reuse default (Stream supplied reactions) with your custom ones +- strong reliance on [`emoji-mart`](https://github.com/missive/emoji-mart) and inability to use completely custom reactions out of the box +- certain `additionalEmojiProps` did not work with Stream-supplied reactions + +```tsx +// not exported directly (hidden, leading to poor DX) +import { defaultMinimalEmojis } from 'stream-chat-react/dist/components/Channel/emojiData'; + +export const customReactions = [ + { + // relies on EmojiMart-supplied sprite sheet, "native" option does not work for Stream-supplied reactions + // you'd need to look up supported id's in stream-emoji.json under "emojis" key + id: 'bulb', + }, + // unsupported + { + id: 'rick_roll', + }, + // this wouldn't work + ...defaultMinimalEmojis, +]; +``` + +### New default setup and how it works + +SDK by default comes with five pre-defined reaction types (`haha`, `like`, `love`, `sad` and `wow`) which are newly rendered by component which utilises sprite sheet system and renders images for each reaction to make sure it works flawlessly on every system. Default reaction options are defined in and these options are reused for both [`ReactionSelector`](../components/message-components/reactions.mdx#reactionselector-props) and [`ReactionsList`](../components/message-components/reactions.mdx#reactionslist-props) (as well as [`SimpleReactionsList`](../components/message-components/reactions.mdx#simplereactionslist-props)). These options come by default from the ComponentContext but local component property will be prioritised if defined. This is how it works under the hood: + +```ts +contextReactionOptions = defaultReactionOptions; +// ... +const reactionOptions = propsReactionOptions ?? contextReactionOptions; +``` + +:::note +Beware that sixth reaction type `angry` has been removed in this update, if you need to re-enable it, follow [this guide](#re-enabling-angry-reaction). +::: + +### Custom reaction types and components + +It's possible to supply your own reaction types and components to represent such reactions - let's implement reaction of type `rick_roll` to render a Rick Roll GIF and define override for default type `love`: + +```tsx +import { Channel } from 'stream-chat-react'; + +const RickRollReaction = () => ( + +); + +const customReactionOptions = [ + { + Component: RickRollReaction, + type: 'rick_roll', + name: 'Rick Roll', + }, + { + Component: () => <>❤️ + type: 'love', + name: "Heart" + } +]; +``` + +And then you can pass these newly created options to [`Channel`](../components/core-components/channel.mdx) component which will be then propagated to `ReactionSelector` and `ReactionsList`: + +```tsx +{/*...*/} +``` + +### Emoji Mart integration + +If you're used to work with [EmojiMart emojis](https://github.com/missive/emoji-mart#-emoji-component) then integrating with new reaction system shouldn't be a big trouble as you can define how your components look and reach for context if you need to: + +```tsx +// arbitrary EmojiMartContext (does not come with the SDK) +import { useEmojiMartContext } from '../contexts'; + +const CustomLikeComponent = () => { + const { selectedSkinTones, selectedSet } = useEmojiMartContext(); + + // to use EmojiMart web components you'll need to go through initiation steps, see EmojiMart documentation + return ; +}; + +const reactionOptions = [ + { + type: 'like', + component: CustomLikeComponent, + name: 'EmojiMart like', + }, +]; + +// pass reaction options to component context (Channel) or to ReactionSelector and ReactionsList +``` + +### Use of different reaction components for the same reaction types for `ReactionSelector` and `ReactionsList` components + +If you need more fine-grain tuning and want to - for example - enable only a certain subset of clickable reactions but want to display the full set then you'd do something like this: + +```tsx +const JoyReaction = () => <>😂; +const CatReaction = () => <>🐈; +const ThumbsUpReaction = () => <>👍; +const SmileReaction = () => <>🙂; + +// subset of clickable options available to the user +const selectedReactionOptions = [ + { type: 'haha', Component: JoyReaction }, + { type: 'cat', Component: CatReaction }, +]; + +// set of all available options to be rendered +const completeReactionOptions = [ + { type: 'haha', Component: JoyReaction }, + { type: 'cat', Component: CatReaction }, + { type: '+1', Component: ThumbsUpReaction }, + { type: 'smile', Component: SmileReaction }, +]; +``` + +Or if you just want bigger icons for `ReactionsList` while `ReactionSelector` uses regular: + +```tsx +// arbitrary import (does not come with the SDK) +import { ReactionComponent } from './CustomReactions'; + +const selectorReactionOptions = [ + { + type: 'like', + component: ReactionComponent.Like, + name: 'Like', + }, +]; + +const listReactionOptions = [ + { + type: 'like', + // in this example it's just different size of the emoji + component: ReactionComponent.LikeMedium, + name: 'Like medium', + }, +]; +``` + +You can then apply these new options to `ReactionSelector` and `ReactionsList` directly: + +```tsx +import { ReactionSelector, ReactionsList, Channel } from 'stream-chat-react'; + +// ReactionSelector component requires forwarded reference +const CustomReactionSelector = forwardRef((props, ref) => ( + +)); + +const CustomReactionsList = (props) => ( + +); +``` + +And then pass them down to component context (`Channel`) component: + +```tsx + + {/*...*/} + +``` + +### Use of `SpriteImage` component + +:::note +We suggest using individual images per reaction type as multiple smaller requests is more bandwidth-friendly. Use this component only if you have no other choice. +::: + +If you have a sprite sheet of emojis and there's no other way for you to implement your reactions, you can utilise utility component which comes with the SDK: + +```tsx +import { SpriteImage } from 'stream-chat-react'; + +const SPRITE_URL = 'https://getstream.imgix.net/images/emoji-sprite.png'; + +const reactionOptions = [ + { + type: 'joy', + component: () => ( + // renders fallback initially and then image when it successfully loads + + ), + name: 'ROFL', + }, +]; + +// pass reaction options to component context (Channel) or to ReactionSelector and ReactionsList +``` + +### Transition from previous version of custom reactions + +#### Default setup + +The transition is super easy: + +```tsx +import { defaultReactionOptions } from 'stream-chat-react'; + +// old custom options +const reactionOptions = [{ id: 'bulb' /* ...extra properties... */ }, { id: '+1' }, { id: 'joy' }]; + +// would newly become +const newReactionOptions = [ + { type: 'bulb', Component: () => <>💡, name: 'Bulb reaction' }, + { type: '+1', Component: () => <>👍 }, + { type: 'joy', Component: () => <>🤣, name: 'ROFL' }, + // reuse default ones if you want to + ...defaultReactionOptions, +]; +``` + +All of the extra options previously applied to `EmojiMart` emojis can now be directly applied to your custom components either manually or through your custom context. For more information see [EmojiMart integration](#emoji-mart-integration). + +#### Re-enabling `angry` reaction + +For better compatibility with other SDKs we decided to consolidate default available types and remove `angry` type which was previously available only in the React SDK. Here's how you'd go about re-enabling it: + +```tsx +import { StreamEmoji, defaultReactionOptions } from 'stream-chat-react'; + +const reactionOptions = [ + ...defaultReactionOptions, + { type: 'angry', Component: () => , name: 'Angry' }, +]; + +// pass reaction options to component context (Channel) or to ReactionSelector and ReactionsList +``` + +## 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), more specifically - `NimbleEmojiIndex` class which is then instantiated with custom `emojiData` by our SDK. 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 `:` 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 @emoji-mart/data +``` + +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 ; +}; +``` + +### 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 { type EmojiSearchIndex } from 'stream-chat-react'; +import search from '@jukben/emoji-search'; + +const emoticonMap: Record = { + '😃': [':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 }) => ( + {children} +); +``` + +### 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, customData } from './CustomEmojiIndex'; + +const App = () => { + return ( + + {/* other components */} + + + ); +}; +``` + +Should newly look like this: + +```tsx +import { Channel, MessageInput } from 'stream-chat-react'; +// arbitrary import +import { CustomEmojiIndex, customData } from './CustomEmojiIndex'; +// instantiate the search index +const customEmojiSearchIndex = new CustomEmojiIndex(customData); + +const App = () => { + return ( + + {/* other components */} + + + ); +}; +``` + +Or enable it in either of the `MessageInput` components individually: + +```tsx +import { Channel, MessageInput } from 'stream-chat-react'; +// arbitrary import +import { CustomEmojiIndex, customData } from './CustomEmojiIndex'; +// instantiate the search index +const customEmojiSearchIndex = new CustomEmojiIndex(customData); + +const App = () => { + return ( + + {/* other components */} + + + + ); +}; +``` + +## 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). + +### 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 packages come with versions that fit our peer-dependency requirements: + +```bash +yarn add emoji-mart @emoji-mart/data @emoji-mart/react +``` + +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 {children}; +}; +``` + +#### Build your custom `EmojiPicker` (with 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 very simple `EmojiPicker` example 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 ( + <> + + + {open && ( + { + insertText(emoji.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 which comes with the SDK for inspiration. + +### Old `emoji-mart` (v3.0.1) + +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: + +```tsx +import 'stream-chat-react/css/v2/index.css'; +import 'stream-chat-react/css/v2/emoji-mart.css'; +``` + +## Channel instance as a first argument to `doSendMessageRequest` + +The `doSendMessageRequest` will from now on be passed the `Channel` instance instead of its CID to avoid forcing the developers to recreate a reference to the `Channel` instance inside the `doSendMessageRequest` function. The developers should adjust their implementation of `doSendMessageRequest` to call directly `await channel.sendMessage(messageData, options)`: + +```ts +import { ChannelProps } from 'stream-chat-react'; + +const doSendMessageRequest: ChannelProps['doSendMessageRequest'] = async ( + channel, + messageData, + options, +) => { + // optional custom logic + await channel.sendMessage(messageData, options); + // optional custom logic +}; +``` + +## Message text rendering + +Optional remark plugins `htmlToTextPlugin`, `keepLineBreaksPlugin` introduced with [stream-chat-react@v10.19.0](https://github.com/GetStream/stream-chat-react/releases/tag/v10.19.0) are now included among the default remark plugins. That means that in the messages that originally contained a sequence of multiple newline characters `\n`, these will be replaced with line break elements `
`. The number of line breaks equals count of newline characters minus 1. +The dependencies used to parse the markdown with [`renderText()` function](../components/core-components/message-list.mdx#rendering-message-text-with-rendertext-function) have been upgraded as a result of that, the following changes had to be performed in stream-chat-react library: + +### `ReactMarkdownProps` dropped from `customMarkDownRenderers` + +`RenderTextOptions.customMarkDownRenderers`- a mapping of element name and corresponding React component to be rendered. The components are no longer accepting `ReactMarkdownProps` + +### User mention renderer props change + +The `RenderTextOptions.customMarkDownRenderers.mention` props have been reduced. From now on, only `children` and `node` are passed to the component. And so now `mention` renderer props look as follows: + +```ts +import { PropsWithChildren } from 'react'; +import type { UserResponse } from 'stream-chat'; +import type { DefaultStreamChatGenerics } from 'stream-chat-react'; + +type MentionProps< + StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics +> = PropsWithChildren<{ + node: { + mentionedUser: UserResponse; + }; +}>; +``` + +### Adjust custom rehype or remark plugins + +If you have implemented your own rehype or remark plugin using `visit` function from the library `unist-util-visit` beware that the `index` and `parent` arguments of the `Visitor` function cannot be `null` but `undefined` instead. You should be notified by Typescript about this and should adjust the type checks accordingly. + +If you would like to prevent applying plugins `htmlToTextPlugin`, `keepLineBreaksPlugin`, you can customize your `renderText()` by overriding the remark plugins. The example below will keep the plugin `remarkGfm` and exclude the rest: + +```tsx +import remarkGfm from 'remark-gfm'; +import { renderText, RenderTextPluginConfigurator } from 'stream-chat-react'; + +const getRemarkPlugins: RenderTextPluginConfigurator = () => { + return [[remarkGfm, { singleTilde: false }]]; +}; + +const customRenderText = (text, mentionedUsers) => + renderText(text, mentionedUsers, { + getRemarkPlugins, + }); + +const CustomMessageList = () => ; +``` diff --git a/docusaurus/docs/React/release-guides/v11/doSendMessageRequest-signature.mdx b/docusaurus/docs/React/release-guides/v11/doSendMessageRequest-signature.mdx deleted file mode 100644 index 865bd9b64..000000000 --- a/docusaurus/docs/React/release-guides/v11/doSendMessageRequest-signature.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -id: minor-breaking-changes-v11 -sidebar_position: 4 -title: Minor breaking changes 11.0.0 -keywords: [migration guide, upgrade, breaking changes, v11] ---- - -### Channel instance as a first argument to doSendMessageRequest - -The `doSendMessageRequest` will from now on be passed the `Channel` instance instead of its CID to avoid forcing the developers to recreate a reference to the `Channel` instance inside the `doSendMessageRequest` function. The developers should adjust their implementation of `doSendMessageRequest` to call directly `await channel.sendMessage(messageData, options)`: - -```ts -import { ChannelProps } from 'stream-chat-react'; - -const doSendMessageRequest: ChannelProps['doSendMessageRequest'] = async (channel, messageData, options) => { - // optional custom logic - await channel.sendMessage(messageData, options); - // optional custom logic -} -``` diff --git a/docusaurus/docs/React/release-guides/v11/message-text-rendering-v11.mdx b/docusaurus/docs/React/release-guides/v11/message-text-rendering-v11.mdx deleted file mode 100644 index a74d5055f..000000000 --- a/docusaurus/docs/React/release-guides/v11/message-text-rendering-v11.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -id: message-text-rendering-v11 -sidebar_position: 3 -title: Message text rendering 11.0.0 -keywords: [migration guide, upgrade, message, text rendering, breaking changes, v11] ---- - -Optional remark plugins `htmlToTextPlugin`, `keepLineBreaksPlugin` introduced with [stream-chat-react@v10.19.0](https://github.com/GetStream/stream-chat-react/releases/tag/v10.19.0) are now included among the default remark plugins. That means that in the messages that originally contained a sequence of multiple newline characters `\n`, these will be replaced with line break elements `
`. The number of line breaks equals count of newline characters minus 1. -The dependencies used to parse the markdown with [`renderText()` function](../../components/core-components/message_list/#rendering-message-text-with-rendertext-function) have been upgraded as a result of that, the following changes had to be performed in stream-chat-react library: - -### `ReactMarkdownProps` dropped from `customMarkDownRenderers` - -`RenderTextOptions.customMarkDownRenderers`- a mapping of element name and corresponding React component to be rendered. The components are no longer accepting `ReactMarkdownProps` - -### User mention renderer props change - -The `RenderTextOptions.customMarkDownRenderers.mention` props have been reduced. From now on, only `children` and `node` are passed to the component. And so now `mention` renderer props look as follows: - -```ts -import { PropsWithChildren } from 'react'; -import type { UserResponse } from 'stream-chat'; -import type { DefaultStreamChatGenerics } from 'stream-chat-react'; - -type MentionProps< - StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics -> = PropsWithChildren<{ - node: { - mentionedUser: UserResponse; - }; -}>; -``` - -### Adjust custom rehype or remark plugins - -If you have implemented your own rehype or remark plugin using `visit` function from the library `unist-util-visit` beware that the `index` and `parent` arguments of the `Visitor` function cannot be `null` but `undefined` instead. You should be notified by Typescript about this and should adjust the type checks accordingly. - -If you would like to prevent applying plugins `htmlToTextPlugin`, `keepLineBreaksPlugin`, you can customize your `renderText()` by overriding the remark plugins. The example below will keep the plugin `remarkGfm` and exclude the rest: - -```tsx -import remarkGfm from 'remark-gfm'; -import { renderText, RenderTextPluginConfigurator } from 'stream-chat-react'; - - -const getRemarkPlugins: RenderTextPluginConfigurator = () => { - return [[remarkGfm, { singleTilde: false }]]; -}; - -const customRenderText = (text, mentionedUsers) => - renderText(text, mentionedUsers, { - getRemarkPlugins - }); -const CustomMessageList = () => ( - -); -```