# Channel Detail Shared Components

The Channel Detail plugin ships a handful of small, reusable building blocks that the default [views](/chat/docs/sdk/react/components/channel-detail/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.

```tsx
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`](/chat/docs/sdk/react/components/channel-detail/section-navigator/) selection state into `aria-current="page"` and the click handler. Use it as the `NavButton` of a [custom section](/chat/docs/sdk/react/components/channel-detail/channel-detail/#add-a-custom-section) to get a nav entry that matches the defaults:

```tsx
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`](/chat/docs/sdk/react/components/channel-detail/section-navigator/#sectionnavigatorsection) (`sectionId`, `selected`, `select`, plus native `button` props), and adds:

| Name          | Description                                    | Type                  | Default |
| ------------- | ---------------------------------------------- | --------------------- | ------- |
| `LeadingIcon` | Icon rendered as the button's leading element. | `React.ComponentType` | -       |
| `title`       | Label 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`](/chat/docs/sdk/react/components/channel-detail/views/#search--pagination-hooks)).

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

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

### Props

| Name             | Description                                                                    | Type                      | Default |
| ---------------- | ------------------------------------------------------------------------------ | ------------------------- | ------- |
| `onSearchChange` | Called with the current query on every change. **Required.**                   | `(query: string) => void` | -       |
| `autoFocus`      | Whether the input is focused on mount.                                         | `boolean`                 | -       |
| `resetKey`       | Changing 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:

```tsx
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:

```tsx
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

| Name           | Description                                                  | Type              | Default |
| -------------- | ------------------------------------------------------------ | ----------------- | ------- |
| `searchSource` | The stream-chat search source whose paging state to observe. | `SearchSource<T>` | -       |

> Its props type is exported as `ChannelMembersViewListFooterProps<T>`.


---

This page was last updated at 2026-06-25T10:44:12.718Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/components/channel-detail/shared-components/](https://getstream.io/chat/docs/sdk/react/components/channel-detail/shared-components/).