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

Badges

Badges are the small marks the SDK puts on top of or next to other UI: unread counts, the "+3" of an avatar group, presence dots, the mark of a failed message, and the label of a GIF provider. Every component on this page is exported from stream-chat-react-native and stream-chat-expo, and none has an override key: the SDK renders them directly, so you replace a badge by replacing the component around it.

Best practices

  • Use BadgeNotification for a count that needs attention, such as unread messages, and BadgeCount for a neutral count, such as how many more avatars there are.
  • Give BadgeNotification an accessibilityLabel that says what the number counts. Without one, a screen reader reads the bare number.
  • Pass OnlineIndicator the presence you read, such as user.online. It doesn't read presence itself.
  • Every badge reads the theme, which OverlayProvider and Chat provide.

Available components

Component What it shows Where the SDK renders it
BadgeCount A count in a neutral pill AvatarGroup and AvatarStack, for the items left out
BadgeNotification A count in a colored pill with a border The unread count of channel list rows, thread list items and the scroll-to-bottom button, and the order of selected media in the attachment picker
OnlineIndicator A presence dot UserAvatar and UserAvatarGroup
ErrorBadge An exclamation mark in a circle of the error color A failed message, and the latest message of a channel list row when it failed to send
GiphyBadge The Giphy logo and "GIPHY" Giphy attachments
ImgurBadge The Imgur logo and "IMGUR" Nowhere. Render it yourself.

BadgeCount

BadgeCount renders count as it is, so pass "+3" for a plus sign. The pill is at least as wide as it's tall: 20, 24, 32 or 40 points for sm, md, lg and xl. It's drawn with semantics.badgeBgDefault, semantics.badgeText and a border in semantics.borderCoreSubtle.

Prop Type Default Description
count string | number required What the badge says.
size 'sm' | 'md' | 'lg' | 'xl' required The height.

BadgeNotification

BadgeNotification renders count on semantics.badgeBgPrimary, badgeBgError or badgeBgNeutral, inside a 2-point border in semantics.badgeBorder that separates it from what it sits on. sm is 20 points tall and xs 16.

Prop Type Default Description
count number required The number.
size 'sm' | 'xs' required The height.
type 'primary' | 'error' | 'neutral' 'primary' The background color.
accessibilityLabel string Announced in place of the number, such as "3 unread messages".
testID string Set on the text.

It shows count as it is, so cap large numbers yourself, for example at 99.

OnlineIndicator

OnlineIndicator is a dot in semantics.presenceBgOnline or semantics.presenceBgOffline, with a border in semantics.presenceBorder. The avatars place it on their edge and pick the size to match.

Prop Type Default Description
online boolean required Picks the online or the offline color.
size 'xl' | 'lg' | 'sm' | 'md' required 16, 14, 12 or 8 points for xl, lg, md and sm, with a 1-point border at sm and 2 points otherwise.

ErrorBadge

ErrorBadge draws the Exclamation icon of ComponentsContext in a circle of semantics.badgeBgError. ErrorBadgeProps are the props of a React Native View, which go to the circle, plus:

Prop Type Default Description
size 'xs' | 'sm' | 'md' required 16, 20 or 24 points.
style StyleProp<ViewStyle> Applied to the circle after the default style.

GiphyBadge and ImgurBadge

GiphyBadge and ImgurBadge take no props. Each draws the provider's icon from ComponentsContext, Giphy or Imgur, and its name, on semantics.badgeBgOverlay. The Giphy attachment shows GiphyBadge on the image.

Example

A tab label with an unread count, and a status line with a presence dot:

src/badges.tsx
import { Text, View } from "react-native";
import { BadgeNotification, OnlineIndicator } from "stream-chat-react-native";

export const ChatsTabLabel = ({ unreadCount }: { unreadCount: number }) => (
  <View style={{ alignItems: "center", flexDirection: "row", gap: 6 }}>
    <Text>Chats</Text>
    {unreadCount > 0 ? (
      <BadgeNotification
        accessibilityLabel={`${unreadCount} unread`}
        count={Math.min(unreadCount, 99)}
        size="sm"
      />
    ) : null}
  </View>
);

export const PresenceLine = ({ online }: { online: boolean }) => (
  <View style={{ alignItems: "center", flexDirection: "row", gap: 6 }}>
    <OnlineIndicator online={online} size="sm" />
    <Text>{online ? "Online" : "Offline"}</Text>
  </View>
);