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

ThreadListItem

ThreadListItem renders one row of ThreadList. It has two parts:

  • ThreadListItem gives the row its thread, which useThreadListItemContext() returns, and renders ThreadListItemUI.
  • ThreadListItemUI is the row's look: a button that opens the thread.

Thread UI describes what a row shows and which stores it reads.

Best practices

  • Replace ThreadListItemUI to change how a row looks, and keep ThreadListItem. Replace ThreadListItem only to change what a row receives.
  • Read the row's thread with useThreadListItemContext() and its state with useStateStore(thread.state, selector). The row already has the thread, so don't query it again.
  • Open the thread with openThread(thread) from useWorkspaceNavigation(), and mark the open one with isThreadActive(thread.id), as the default row does.
  • Keep the row light: the list is virtualized, so rows mount and unmount as the user scrolls.
  • To change what screen readers announce for a row, wrap the default ThreadListItemUI and pass accessibleLabelConfig.

What the default row shows

ThreadListItemUI renders a button with the option role. It shows the avatar of the latest reply's author, the channel's name, a preview of the parent message, the avatars of up to three participants, the reply count, the time of the latest reply and the user's unread count.

Clicking it opens the thread; ⌘/ctrl-click asks the layout to open it beside the open one. An unseen thread, one that got replies while it wasn't in the list, is highlighted for two seconds when a reload brings it in.

UI customization

This row keeps the default look and adds the number of participants to its accessible name:

import type {
  ThreadListItemLabelConfig,
  ThreadListItemUIProps,
} from "stream-chat-react";
import {
  DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER,
  ThreadList,
  ThreadListItemUI,
  WithComponents,
} from "stream-chat-react";

const accessibleLabelConfig: ThreadListItemLabelConfig = {
  order: [...DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER, "participants"],
  parts: {
    participants: ({ participantCount }) =>
      participantCount ? `${participantCount} participants` : undefined,
  },
};

const LabelledThreadListItemUI = (props: ThreadListItemUIProps) => (
  <ThreadListItemUI {...props} accessibleLabelConfig={accessibleLabelConfig} />
);

const overrides = { ThreadListItemUI: LabelledThreadListItemUI };

export const ThreadsSidebar = () => (
  <WithComponents overrides={overrides}>
    <ThreadList />
  </WithComponents>
);

A part that isn't listed in order never renders. defaultThreadListItemLabelParts holds the default parts, and composeThreadListItemAccessibleLabel(data, config) builds the label for a row of your own. For a row with a different look, see Thread UI.

Props

ThreadListItem

Prop Type Default Description
thread Thread required The row's thread. ThreadList passes each thread of client.threads.paginator.
threadListItemUIProps ThreadListItemUIProps none Props passed to ThreadListItemUI. ThreadList passes resetHighlighting for a thread that just arrived.

ThreadListItemUI

ThreadListItemUI also takes every button prop. They're applied after the SDK's own, so they replace them. onClick is the exception: it runs after the SDK's handler, which opens the thread.

Prop Type Default Description
accessibleLabelConfig ThreadListItemLabelConfig the default parts, in DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER How the row's aria-label is composed: parts to add or replace, their order, the separator, or build for the whole label.
resetHighlighting () => void none Set for a row that just arrived. The row is highlighted while it's set, and calls it after two seconds.
Hook Returns
useThreadListItemContext() the row's thread, or undefined outside a ThreadListItem
useWorkspaceNavigation() openThread and isThreadActive
useStateStore(thread.state, selector) a selection of the thread's state: parent message, reply count, participants, read state

See useThreadListItemContext and, for the fields of thread.state, Thread and thread manager.