Skip to main content
This is a beta version. Features and documentation may change.
Version: v5

Introduction

Overview

Theming in CometChat for React Native allows you to create visually consistent and customizable user interfaces that align with your application's branding. The CometChatThemeProvider acts as a global theme provider, enabling seamless integration of light and dark modes while giving you the flexibility to define custom colors, typography, and component-specific styles.

At the core of theming is the CometChatTheme interface, which defines the structure of the theme supplied to the provider. This interface lets you specify various theme attributes such as colors, fonts, and component-level customizations. By wrapping your application with CometChatThemeProvider and supplying a CometChatTheme, you can maintain a consistent look and feel across all CometChat components while having full control over customizations to match your app’s aesthetic.

Using Theming in Your Project

By default, the theme is automatically selected based on the system settings, ensuring that your app aligns with the user's preferred light or dark mode unless you choose to override it with a custom theme.

The CometChatThemeProvider is used to apply a custom theme to your components. By setting the theme prop with a specific mode, such as { mode: 'dark' }, you can override the default system theme and ensure that the UI is displayed in the desired light or dark mode. This allows you to provide a consistent visual experience based on the selected theme mode.

Here’s an example of how to explicitly set the theme mode to dark:

return (
<SafeAreaView style={{ flex: 1 }}>
<CometChatThemeProvider theme={{ mode: "dark" }}>
{/* Component */}
</CometChatThemeProvider>
</SafeAreaView>
);
Image

Customization

To customize the primary color in your app, you can override the primary color attribute in the theme. Here's how to override the primary color for light theme:

return (
<SafeAreaView style={{ flex: 1 }}>
<CometChatThemeProvider
theme={{
light: {
color: {
primary: "#F76808",
},
},
}}
>
{/* Component */}
</CometChatThemeProvider>
</SafeAreaView>
);
Image

Overriding the Theme for Specific Components by Customizing Style Properties

Following is an example of how the light theme for the CometChatConversations component is overridden directly by setting custom theme properties within the CometChatThemeProvider. This ensures that the CometChatConversations component uses a specific light theme, independent of the global theme applied to the rest of the app. The light theme is customized further by defining specific styles, such as the background color for the conversation container. This approach allows you to customize the theme for specific components while keeping the global theme intact.

import {
CometChatConversations,
CometChatUIKit,
CometChatUiKitConstants,
UIKitSettings,
useTheme,
} from "@cometchat/chat-uikit-react-native";
import { CometChatThemeProvider } from "@cometchat/chat-uikit-react-native/src/theme/provider";
import Messages from "./src/Messages";

//other code

const theme = useTheme();

return (
<SafeAreaView style={{ flex: 1 }}>
<CometChatThemeProvider
theme={{
light: {
conversationStyles: {
containerStyle: {
backgroundColor: theme.color.extendedPrimary500,
},
},
},
}}
>
{loggedIn && (
<>
<CometChatConversations
style={{
containerStyle: {
display: messageUser || messageGroup ? "none" : "flex",
},
}}
onItemPress={(item: CometChat.Conversation) => {
if (
item.getConversationType() ==
CometChatUiKitConstants.ConversationTypeConstants.user
) {
setMessageUser(item.getConversationWith() as CometChat.User);
return;
}
setMessageGroup(item.getConversationWith() as CometChat.Group);
}}
></CometChatConversations>
{(messageUser || messageGroup) && (
<Messages
user={messageUser}
group={messageGroup}
onBack={() => {
setMessageUser(undefined);
setMessageGroup(undefined);
}}
/>
)}
</>
)}
</CometChatThemeProvider>
</SafeAreaView>
);

Supplying Custom Theme to Specific Components by wrapping them in a separate CometChatThemeProvider

Following is an example of how the theme for the CometChatConversations component is specifically overridden by wrapping it in a separate CometChatThemeProvider. This allows the CometChatConversations component to use a dark mode theme, independent of the global theme applied to the rest of the app. Additionally, the dark theme is further customized for the component by defining specific styles, such as the background color for the conversation container. This approach enables you to tailor the theme for specific components while maintaining the overall consistency of the global theme.

import {
CometChatConversations,
CometChatUIKit,
CometChatUiKitConstants,
UIKitSettings,
useTheme,
CometChatThemeProvider,
} from "@cometchat/chat-uikit-react-native";
import Messages from "./src/Messages";

//other code

const theme = useTheme();

return (
<SafeAreaView style={{ flex: 1 }}>
<CometChatThemeProvider>
{loggedIn && (
<>
<CometChatThemeProvider
theme={{
mode: "dark",
dark: {
conversationStyles: {
containerStyle: {
backgroundColor: theme.color.extendedPrimary600,
},
},
},
}}
>
<CometChatConversations
style={{
containerStyle: {
display: messageUser || messageGroup ? "none" : "flex",
},
}}
onItemPress={(item: CometChat.Conversation) => {
if (
item.getConversationType() ==
CometChatUiKitConstants.ConversationTypeConstants.user
) {
setMessageUser(item.getConversationWith() as CometChat.User);
return;
}
setMessageGroup(item.getConversationWith() as CometChat.Group);
}}
></CometChatConversations>
</CometChatThemeProvider>
{(messageUser || messageGroup) && (
<Messages
user={messageUser}
group={messageGroup}
onBack={() => {
setMessageUser(undefined);
setMessageGroup(undefined);
}}
/>
)}
</>
)}
</CometChatThemeProvider>
</SafeAreaView>
);
info

When customizing theme properties, whether by overriding specific properties or supplying a completely custom theme, the provided values will be deeply merged with the default theme. This means that only the specified properties will be overridden, while all other properties will retain their default values. Additionally, if a style is passed through props, it will take priority over the style provided via the theme. The deep merge will occur in the following order of priority:

  1. The style prop (highest priority)
  2. The custom theme
  3. The default theme (lowest priority)

This ensures that customizations are prioritized and applied while preserving the integrity of the default theme.

// The custom theme is merged with the default theme (handled internally)
const mergedTheme = internalDeepMergeImplementation(defaultTheme, customTheme);

// The style prop is applied with higher priority, merging it with the previous result (handled internally)
const finalConversationsStyle = internalDeepMergeImplementation(
mergedTheme,
conversationStyleProp
);