# Channel Preview

> **Info:** This is release candidate documentation for **Stream Chat React SDK v15**. For the latest stable version, see the [latest version (v14)](https://getstream.io/chat/docs/sdk/react/).

Each row of a [`ChannelList`](https://getstream.io/chat/docs/sdk/react/v15/component-reference/channel-list/channellist/) is a `ChannelListItem`. It reads the row's values from the channel's stores, such as the title, the last message and the unread count, and renders `ChannelListItemUI`, the row's look, with them as props. [Channel list UI](https://getstream.io/chat/docs/sdk/react/v15/ui/components/channel-list-ui/#rows) explains what each value is read from.

## Best practices

- To change the look and keep the values, register your own `ChannelListItemUI`. To change the whole row, register a `ListItem`.
- Keep a row light: it renders for every channel in the list.
- Use the props a row gets, such as `displayTitle` and `unread`, rather than reading them from the channel again. They're reactive, and `channel.data` isn't.
- Keep the row's clickable element a `<button>` with `role="option"` inside a `str-chat__channel-list-item-container` element. The list's arrow-key navigation moves between those.
- To change only the avatar or the last-message line, override `Avatar` or `SummarizedMessagePreview` instead of the whole row.

## Basic usage

Register your component as `ChannelListItemUI`. This one renders the default row, and adds a label to frozen channels:

```tsx
import type { PropsWithChildren } from "react";
import type { ChannelStateData } from "stream-chat";
import type { ChannelListItemUIProps } from "stream-chat-react";
import {
  ChannelListItemUI,
  useStateStore,
  WithComponents,
} from "stream-chat-react";

const frozenSelector = ({ data }: ChannelStateData) => ({
  frozen: !!data?.frozen,
});

const RowWithFrozenLabel = (props: ChannelListItemUIProps) => {
  const { frozen } = useStateStore(props.channel.state, frozenSelector);

  return (
    <div className="channel-row">
      <ChannelListItemUI {...props} />
      {frozen && <span className="channel-row__label">Frozen</span>}
    </div>
  );
};

const overrides = { ChannelListItemUI: RowWithFrozenLabel };

export const WithFrozenLabels = ({ children }: PropsWithChildren) => (
  <WithComponents overrides={overrides}>{children}</WithComponents>
);
```

The [Preview UI recipe](https://getstream.io/chat/docs/sdk/react/v15/recipes/channel-list/preview-ui/) builds a row from scratch.

## Default preview behavior

The default `ChannelListItemUI`:

- is a `<button>` with `role="option"`, and `aria-selected` while its channel is open;
- renders the `Avatar` override, `ChannelAvatar` by default, with `displayImage` and the members of a group channel;
- shows `displayTitle`, and a pin icon and a mute icon when the channel is pinned or muted;
- shows the time of the previewed message with `ChannelListItemTimestamp`, and an unread badge when `unread` is above 0;
- renders the `SummarizedMessagePreview` override for the last-message line, with the sender and the delivery status of the user's own message;
- renders the `ChannelListItemActionButtons` override after the button: mute, and a menu with archive, block, pin and leave. See [Channel-list row actions](https://getstream.io/chat/docs/sdk/react/v15/ui/customizing/actions/#channel-list-row-actions);
- calls `onSelect` when clicked, if set. Otherwise it opens the channel with `openChannel(channel, { event })`.

## Props

`ChannelListItem` takes the props in the first table, and passes them on to `ChannelListItemUI`. `ChannelListItemUI` also gets the values in the second table, which `ChannelListItem` computes.

| Prop               | Type                                | Default                      | Description                                                                                                       |
| ------------------ | ----------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `channel`          | `Channel`                           | required                     | The row's channel.                                                                                                |
| `active`           | `boolean`                           | whether the channel is open  | Whether the row is highlighted. `ChannelListItem` sets it from `isChannelActive(channel.cid)` unless you pass it. |
| `activeChannel`    | `Channel`                           | none                         | In the type, but nothing sets or reads it.                                                                        |
| `className`        | `string`                            | none                         | Class name added to the row's button.                                                                             |
| `onSelect`         | `(event: React.MouseEvent) => void` | none                         | Runs when the row is clicked, instead of opening the channel.                                                     |
| `previewedMessage` | `LocalMessage`                      | the channel's latest message | The message the row previews. Search results pass the matched message.                                            |

| Prop                      | Type                         | Description                                                                                                                                                                                 |
| ------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `accessibleLabelConfig`   | `ChannelListItemLabelConfig` | Not set by `ChannelListItem`. Pass it from your own `ChannelListItemUI` to the default one, to change the row's accessible name: its parts, their order, the separator, or the whole label. |
| `displayImage`            | `string`                     | The channel's image. In a channel with two members and no image, the other member's image.                                                                                                  |
| `displayTitle`            | `string`                     | The channel's name. Without one: the other member's name in a channel with two members, or two other members' names in a larger one.                                                        |
| `groupChannelDisplayInfo` | `GroupChannelDisplayInfo`    | The members to show in a group avatar. Its `overflowCount` is in the type, but the SDK leaves it `undefined`.                                                                               |
| `messageDeliveryStatus`   | `MessageDeliveryStatus`      | `sent`, `delivered` or `read`, for the user's own previewed message. `undefined` for someone else's message.                                                                                |
| `muted`                   | `boolean`                    | Whether the user muted the channel.                                                                                                                                                         |
| `pinned`                  | `boolean`                    | Whether the user pinned the channel.                                                                                                                                                        |
| `unread`                  | `number`                     | The user's unread messages in the channel. `0` while the channel is muted.                                                                                                                  |

## Delivery status and summaries

These parts and helpers are exported, to build a row that matches the default one:

| Name                                             | What it does                                                                                                                |
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `ChannelListItemTimestamp`                       | The time of `previewedMessage`, formatted like the default row.                                                             |
| `SummarizedMessagePreview`                       | The last-message line. Takes `latestMessage`, `messageDeliveryStatus` and `participantCount`.                               |
| `useLatestMessagePreview(params)`                | What `SummarizedMessagePreview` renders, as data: `text`, `type`, `senderName` and `deliveryStatus`. Takes the same params. |
| `useChannelPreviewInfo({ channel })`             | `displayTitle`, `displayImage` and `groupChannelDisplayInfo`, reactively.                                                   |
| `useChannelDisplayName(channel)`                 | `displayTitle` alone.                                                                                                       |
| `getChannelDisplayImage(channel, currentUserId)` | `displayImage`, read once, not reactively.                                                                                  |
| `useChannelMembershipState(channel)`             | The user's membership, with `pinned_at` and `archived_at`.                                                                  |
| `useChannelListItemContext()`                    | `{ channel }`, for any component rendered inside a row. Throws outside one.                                                 |

`useLatestMessagePreview` returns a `type` for the kind of message, such as `text`, `image`, `giphy`, `voice`, `poll` or `deleted`. A `/giphy` message has the `giphy` type, not `image`. Its `deliveryStatus` adds `sending` to the three values of `MessageDeliveryStatus`.

## Hooks

- [`useChannelPreviewInfo`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/channel-and-thread-hooks/#usechannelpreviewinfo) and [`useChannelDisplayName`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/channel-and-thread-hooks/#usechanneldisplayname)
- [`useChannelMembershipState`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/channel-and-thread-hooks/#usechannelmembershipstate)

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v15/component-reference/channel-list/channel-preview/](https://getstream.io/chat/docs/sdk/react/v15/component-reference/channel-list/channel-preview/).