Channel Detail Shared Components

The Channel Detail plugin ships a handful of small, reusable building blocks that the default views and nav buttons are composed from. They are exported from stream-chat-react/channel-detail so you can reuse them when building custom sections, nav buttons, or list UIs and keep the look and behavior consistent with the built-ins.

import {
  ChannelDetailNavButton,
  ChannelDetailSearchInput,
  ChannelDetailEmptyList,
  ChannelDetailListLoadingIndicator,
} from "stream-chat-react/channel-detail";

import "stream-chat-react/dist/css/channel-detail.css";

ChannelDetailNavButton

The button every built-in section nav button is built on. It renders a ListItemLayout as a <button> and wires the SectionNavigator selection state into aria-current="page" and the click handler. Use it as the NavButton of a custom section to get a nav entry that matches the defaults:

import { ChannelDetailNavButton } from "stream-chat-react/channel-detail";
import type { SectionNavigatorSection } from "stream-chat-react/channel-detail";

const NotificationsSection: SectionNavigatorSection = {
  id: "notifications",
  NavButton: (props) => (
    <ChannelDetailNavButton
      {...props}
      LeadingIcon={BellIcon}
      title="Notifications"
    />
  ),
  SectionContent: () => <NotificationSettings />,
};

Props

ChannelDetailNavButton extends SectionNavigatorNavButtonProps (sectionId, selected, select, plus native button props), and adds:

NameDescriptionTypeDefault
LeadingIconIcon rendered as the button's leading element.React.ComponentType-
titleLabel displayed for the section.string-

ChannelDetailSearchInput

A memoized search input used by the members, media, and files views. It renders a TextInput with a leading search icon, manages its own value internally, fires onSearchChange on every keystroke, and clears itself whenever resetKey changes (pair it with a counter you bump to reset the field — e.g. the searchInputResetKey returned by useChannelMembersSearch).

import { ChannelDetailSearchInput } from "stream-chat-react/channel-detail";

<ChannelDetailSearchInput
  onSearchChange={(query) => search(query)}
  resetKey={resetKey}
/>;

Props

NameDescriptionTypeDefault
onSearchChangeCalled with the current query on every change. Required.(query: string) => void-
autoFocusWhether the input is focused on mount.boolean-
resetKeyChanging this value clears the input. Use to reset the field programmatically.number-

The placeholder and aria-label are both the translated Search string, so the input is localized through the SDK's i18n.

ChannelDetailEmptyList

The shared empty-state element rendered by list views when there is nothing to show. It renders a search icon above the provided children:

import { ChannelDetailEmptyList } from "stream-chat-react/channel-detail";

<ChannelDetailEmptyList>No results found</ChannelDetailEmptyList>;

The media and files views ship preconfigured wrappers around it — ChannelMediaEmptyList and ChannelFilesEmptyList — with their own translated copy. The pinned-messages view ships its own PinnedMessagesEmptyList (a pin icon with a title and description), which takes no props.

ChannelDetailListLoadingIndicator

An infinite-scroll footer for any stream-chat SearchSource. It subscribes to the source's state and renders a LoadingIndicator only while the source both has a next page and is loading — drop it at the end of a paginated list backed by one of the search hooks:

import { ChannelDetailListLoadingIndicator } from "stream-chat-react/channel-detail";
import { useChannelMediaSearch } from "stream-chat-react/channel-detail";

const CustomMediaList = () => {
  const { mediaItems, channelMediaSearchSource } = useChannelMediaSearch();
  return (
    <>
      <Grid items={mediaItems} />
      <ChannelDetailListLoadingIndicator
        searchSource={channelMediaSearchSource}
      />
    </>
  );
};

Props

NameDescriptionTypeDefault
searchSourceThe stream-chat search source whose paging state to observe.SearchSource<T>-

Its props type is exported as ChannelMembersViewListFooterProps<T>.