Info:
This is release candidate documentation for Stream Chat React Native SDK v10. For the latest stable version, see the latest version (v9).

Channel details lists

Channel details has five lists, the member list, the add members form, and the pinned messages, photos and videos, and files lists. ChannelDetails opens each in a modal, and each is exported so a screen of your own can render it. This page lists their parts, override keys and props. ChannelDetails covers the screen that opens them.

Best practices

  • Render a list inside a ChannelDetailsContextProvider for the channel. It reads the channel from there, and renders nothing until the channel has a cid.
  • Give the list a container with a height, such as a screen with flex: 1. The lists scroll inside it.
  • Replace a row through its override key, such as PinnedMessageItem, rather than the whole list. The list keeps its loading, paging, search and empty states.
  • To change what a list loads, pass your own search source as searchSource. Channel details contexts shows the default sources.

How the lists load

Each list loads from a search source of stream-chat, which it creates when it mounts:

List Override key Opened from Loads
ChannelMemberList ChannelMemberList View all in the members section The channel's members, by name, with a ChannelMemberSearchSource
ChannelAddMembersForm ChannelAddMembersForm Add, in the members section and the member list Users, by name, with a UserSearchSource
PinnedMessageList PinnedMessageList Pinned Messages The channel's pinned messages, with a MessageSearchSource, searched by text
MediaList MediaList Photos & Videos The channel's messages with images or videos, newest first, with a MessageSearchSource
FileAttachmentList FileAttachmentList Files The channel's messages with files or audio, newest first, with a MessageSearchSource

Each source loads 25 items a page, and the list loads the next page when it's scrolled near its end, with a spinner at the bottom meanwhile. The member list, the add members form and the pinned messages list have a SearchInput that searches as the user types. The first load shows a skeleton. The pinned messages, photos and videos, and files lists show EmptyList when they have nothing, and the pinned messages list shows EmptySearchResult for a search that matched nothing. The member list and the add members form show EmptySearchResult whenever they're empty.

The sources are a snapshot. They don't change as events arrive, so a message pinned while the list is open shows the next time it opens. The member list is the exception. It loads its first page again when the channel's member count changes, while no search is typed, so members added from it show at once.

When a query fails, the list publishes an error notification, such as api:channel:query-members:failed, to a NotificationList of its own. Each list is its own notification target in the channel-details panel.

Members

ChannelMemberList

The searchable list of the channel's members, each through the ChannelMemberItem key. Pressing a member opens the ChannelMemberActionsSheet key for them.

Prop Type Default Description
searchSource ChannelMemberSearchSource the channel's members, sorted by name The source to load from.
searchInputProps SearchInputProps Passed to the SearchInput, after the list's own props, so onChangeText replaces the search.
additionalFlatListProps Partial<FlatListProps<ChannelMemberResponse>> Passed to the FlatList, after the list's own props.

ChannelMemberItem

A member row shows a UserAvatar, with a presence dot while the user is online, the name, or "You" for the current user, the activity status from useUserActivityStatus, a mute icon while the user is muted, and the RoleList key with the member's roles. With onPress it's a button; without one, a plain row.

Prop Type Default Description
member ChannelMemberResponse required The member. A member without a user renders nothing.
onPress (member: ChannelMemberResponse) => void Makes the row pressable.
size ChannelMemberItemSize 'sm' 'sm', a list row with an md avatar, or 'lg', a header with an lg avatar, as at the top of the member sheet.
getMemberRoles GetMemberRoles the default roles ({ channel, defaultRoleLabels, member, t }) => roles, the roles to show. [] shows none.
testID string Set on the row.

The default roles are Owner for the channel's creator, Admin for a user whose role is admin, and Moderator for a member whose channel_role is channel_moderator. Custom member roles shows others.

RoleList and RoleItem

RoleList renders a RoleItem key for each role, and nothing without roles. RoleItem is a pill with the role's label, in the brand colors for the owner key and in neutral colors otherwise.

Prop Type Default Description
roles RoleLabel[] required The roles, each { key, label }.

RoleItemProps:

Prop Type Default Description
role RoleLabel required The role.
textStyle StyleProp<TextStyle> Applied to the label, after the theme.
viewStyle StyleProp<ViewStyle> Applied to the pill, after the theme.

ChannelMemberActionsSheet

A bottom sheet with the member as a lg ChannelMemberItem and the member's actions as ChannelDetailsActionItem rows. Pressing an action runs it and closes the sheet. The actions come from useChannelMemberActionItems: mute or unmute and block or unblock the user, and remove the member with the update-channel-members capability. The current user's own sheet has no actions.

Prop Type Default Description
member ChannelMemberResponse required The member.
visible boolean required Whether the sheet is open.
onClose () => void required Called when the sheet closes, and after an action.
getChannelMemberActionItems GetChannelMemberActionItems ({ context, defaultItems }) => items, the actions to show. See Member actions.

Adding members

ChannelAddMembersButton

Renders Add, or a user-plus icon, when the user has the update-channel-members capability, and nothing otherwise. Pressing it opens the ChannelAddMembersForm key in a modal.

Prop Type Default Description
variant 'icon' | 'text' 'text' An outlined Add button, or an icon-only button.
onPress () => void Called in place of opening the form. The button then renders no modal.
style ButtonProps['style'] Passed to the Button.
testID string Passed to the Button.

The members section renders it with variant="text", and the header of the member list with variant="icon".

ChannelAddMembersForm

Wraps its parts in a ChannelAddMembersProvider, and renders the ChannelAddMembersFormHeader key, the ChannelAddMembersFormContent key and a NotificationList.

Prop Type Default Description
onClose () => void required Called by the close button, and after members are added.
searchSource UserSearchSource users, sorted by name The source to load from. It's used as it is, so activate it and set its sort yourself.

ChannelAddMembersFormHeader

Close, "Add Members", and a confirm button. The confirm button is enabled while at least one user is selected. It calls submit() of the add members context, which adds the selected users with Channel.addMembers({ members }), and closes the form when it succeeds.

Prop Type Default Description
onClose () => void required Called by the close button, and after members are added.

ChannelAddMembersFormContent

The SearchInput and the list of users, each an AddMemberSearchResultItem. It searches with an empty query when it mounts, so the list starts with every user the source returns.

Prop Type Default Description
additionalFlatListProps Partial<FlatListProps<UserResponse>> Passed to the FlatList, after the list's own props.

AddMemberSearchResultItem

A user row with a UserAvatar, the name and a SelectionCircle. Pressing it calls onPress, which the form uses to toggle the user in its selection. A user who is already a member shows "Already a member" and can't be pressed. It has no override key, because ChannelAddMembersFormContent renders it directly.

Prop Type Default Description
user UserResponse required The user.
onPress (user: UserResponse) => void required Called when the row is pressed.

It reads the selection from useChannelAddMembersContext(), so it renders inside a ChannelAddMembersProvider.

Pinned messages

PinnedMessageList

The searchable list of the channel's pinned messages, each through the PinnedMessageItem key. While the channel has no pinned messages, it shows an EmptyList and no search field.

Prop Type Default Description
searchSource MessageSearchSource the channel's pinned messages The source to load from.
searchInputProps SearchInputProps Passed to the SearchInput, after the list's own props.
additionalFlatListProps Partial<FlatListProps<MessageResponse>> Passed to the FlatList, after the list's own props.

PinnedMessageItem

A row with the sender's UserAvatar, the sender's name, and the message's preview and time through the ChannelPreviewLastMessage and ChannelPreviewStatus keys. It shows the message's translation in the user's language when there is one. It isn't pressable. To jump to the message, override the key with a row that navigates, as Pinned messages shows.

Prop Type Default Description
channel Channel required The channel.
message MessageResponse required The pinned message.
formatMessageDate ChannelPreviewStatusProps['formatLatestMessageDate'] the channel preview's format (date: Date) => string, formats the time.

The list passes channel and message.

Photos and videos

MediaList

A grid of three columns, one MediaItem key per image or video attachment, from useMediaList. Pressing an image or a video opens the image gallery on it, with every loaded message to swipe through. Without a video player installed, pressing a video opens its URL instead.

Prop Type Default Description
searchSource MessageSearchSource the channel's messages with images or videos, newest first The source to load from.
additionalFlatListProps Partial<FlatListProps<MediaTile>> Passed to the FlatList, after the list's own props.

It opens the gallery through ImageGalleryContext and OverlayContext, so it renders inside OverlayProvider. On a screen of your own, OverlayProvider's gallery shows over it.

MediaItem

A square tile with the attachment's thumbnail, resized through the CDN to the tile's size, the sender's sm UserAvatar, and, for a video, its duration.

Prop Type Default Description
attachment Attachment required The image or video attachment.
message MessageResponse required Its message.
size number required The side of the tile, in points.
onPress (params: MediaItemPressParams) => void Called when the tile is pressed. Without it, the tile does nothing.

MediaItemPressParams is { attachment, message, requesterNode }. requesterNode is the tile's native handle, for the gallery's openImageGallery().

Files

FileAttachmentList

A list of the file and audio attachments, under a header for each month, from useFileAttachmentListSections. Each attachment renders through the FileAttachmentItem key, and each header through FileAttachmentListSectionHeader, which has no override key. The headers stick to the top while their month scrolls.

Prop Type Default Description
searchSource MessageSearchSource the channel's messages with files or audio, newest first The source to load from.
additionalSectionListProps Partial<SectionListProps<FileAttachmentTile, FileAttachmentSection>> Passed to the SectionList, after the list's own props.

FileAttachmentItem

A row with the file's icon, name and size. Pressing it opens the attachment's asset_url.

Prop Type Default Description
attachment Attachment required The file or audio attachment.
message MessageResponse required Its message.
onPress (params: FileAttachmentItemPressParams) => void opens asset_url Called in place of opening the URL, with { attachment, message }.

FileAttachmentListSectionHeader

Prop Type Default Description
title string required The section's title, such as "March 2026".

Loading skeletons

The lists show these while their first page loads. They take no props, have no override key, and are styled by the theme key in brackets: MemberListLoadingSkeleton (memberListSkeleton), UserListLoadingSkeleton (userListSkeleton), PinnedMessageListLoadingSkeleton (pinnedMessageListSkeleton), FileAttachmentListLoadingSkeleton (fileAttachmentListSkeleton) and MediaListLoadingSkeleton.

Theming

The theme's channelDetails key styles the lists and rows: memberList, memberItem, roleList, roleItem, memberActionsSheet, addMembers, pinnedMessageList, pinnedMessageItem, mediaList, mediaItem, fileAttachmentList and fileAttachmentItem. See Theme object.

Example

A files screen of your own, which opens files in your viewer:

src/ChannelFilesScreen.tsx
import { View } from "react-native";
import type { Channel as StreamChannel } from "stream-chat";
import {
  ChannelDetailsContextProvider,
  FileAttachmentItem,
  FileAttachmentList,
  WithComponents,
} from "stream-chat-react-native";
import type {
  ComponentOverrides,
  FileAttachmentItemProps,
} from "stream-chat-react-native";

type Props = {
  channel: StreamChannel;
  openFile: (url: string) => void;
};

export const ChannelFilesScreen = ({ channel, openFile }: Props) => {
  const FileRow = (props: FileAttachmentItemProps) => (
    <FileAttachmentItem
      {...props}
      onPress={({ attachment }) => {
        if (attachment.asset_url) openFile(attachment.asset_url);
      }}
    />
  );
  const overrides: ComponentOverrides = { FileAttachmentItem: FileRow };

  return (
    <ChannelDetailsContextProvider channel={channel}>
      <WithComponents overrides={overrides}>
        <View style={{ flex: 1 }}>
          <FileAttachmentList />
        </View>
      </WithComponents>
    </ChannelDetailsContextProvider>
  );
};

WithComponents reads overrides when it mounts, so the row keeps the openFile of the first render. Pass a function that stays the same, such as one from useCallback or your navigator.

Exports

Export What it is
ChannelMemberList, ChannelMemberItem, ChannelMemberActionsSheet, RoleList, RoleItem The members
ChannelAddMembersButton, ChannelAddMembersForm, ChannelAddMembersFormHeader, ChannelAddMembersFormContent, AddMemberSearchResultItem Adding members
PinnedMessageList, PinnedMessageItem Pinned messages
MediaList, MediaItem Photos and videos
FileAttachmentList, FileAttachmentItem, FileAttachmentListSectionHeader Files
MemberListLoadingSkeleton, UserListLoadingSkeleton, PinnedMessageListLoadingSkeleton, MediaListLoadingSkeleton, FileAttachmentListLoadingSkeleton Loading states

The props types are exported with the components' names plus Props, as ChannelMemberListProps, except for the skeletons. ChannelMemberItemSize, RoleLabel, GetMemberRoles, MediaItemPressParams, FileAttachmentItemPressParams, MediaTile, FileAttachmentTile and FileAttachmentSection are exported too.

Hook Returns
useMemberRoles(member, getMemberRoles?) the roles of a member row
useChannelMemberActionItems({ channel, member }) the actions of the member sheet
useUserActivityStatus(user) "Online", when the user was last active, or "Offline"
useMediaList(messages) one tile per image or video attachment
useFileAttachmentListSections(messages) the file and audio attachments, by month
useChannelMemberListContext(), useChannelAddMembersContext(), useChannelPinnedMessageListContext(), useChannelMediaListContext(), useChannelFileAttachmentListContext() the search source of each list, and the add members selection

They're on Channel details hooks. The contexts are on Channel details contexts.