Typing Indicator

In this example, we will demonstrate how to build a custom TypingIndicator using the default component as a guide.

Create the Component

Using the typing object provided by the TypingContext, we can access the name and role of users currently typing in a channel. The threadList prop will allow us to conditionally render the typing indicator in the main message list, or at the bottom of a thread.

export const CustomTypingIndicator = (props: TypingIndicatorProps) => {
  const { threadList } = props;

  const { channelConfig, thread } = useChannelStateContext();
  const { client } = useChatContext();
  const { typing = {} } = useTypingContext();

  if (channelConfig?.typing_events === false) {
    return null;
  }

  const typingInChannel = !threadList
    ? Object.values(typing).filter(
        ({ parent_id, user }) => user?.id !== client.user?.id && !parent_id,
      )
    : [];

  const typingInThread = threadList
    ? Object.values(typing).filter(
        ({ parent_id, user }) =>
          user?.id !== client.user?.id && parent_id === thread?.id,
      )
    : [];

  return (
    <div
      className={`str-chat__typing-indicator ${
        (threadList && typingInThread.length) ||
        (!threadList && typingInChannel.length)
          ? "str-chat__typing-indicator--typing"
          : ""
      }`}
    >
      <div className="str-chat__typing-indicator__avatars">
        {(threadList ? typingInThread : typingInChannel).map(({ user }, i) => (
          <div className="username">
            <div className="typing-indicator-name">{user?.name}</div>
            <div className="typing-indicator-role ">{user?.role}</div>
          </div>
        ))}
      </div>
      <div className="str-chat__typing-indicator__dots">
        <div className="str-chat__typing-indicator__dot" />
        <div className="str-chat__typing-indicator__dot" />
        <div className="str-chat__typing-indicator__dot" />
      </div>
    </div>
  );
};
.str-chat__typing-indicator__dots {
  border: none;
  display: flex;
  margin-left: 0;
  width: fit-content;
}

.str-chat__typing-indicator__dot {
  background: var(--grey);
  opacity: 1;
  height: 4px;
  width: 4px;
  border-radius: var(--border-radius-round);
  display: flex;
}

.str-chat__typing-indicator__dot:nth-child(3) {
  opacity: 1;
}

.str-chat__typing-indicator__dot:nth-child(2) {
  opacity: 1;
}

.typing-indicator-name {
  font-weight: var(--font-weight-bold);
  color: var(--grey);
}
.typing-indicator-role {
  font-weight: var(--font-weight-regular);
  color: var(--grey-whisper);
  margin-left: var(--xxs-m);
}

.username {
  display: flex;
}

From here, all we need to do is override the default component in Channel:

<Channel TypingIndicator={CustomTypingIndicator}>
  {/* children of Channel component */}
</Channel>

The Result

Custom Typing Indicator UI Component for Chat

© Getstream.io, Inc. All Rights Reserved.