Theme
The majority of components used in stream-chat-react-native
can have custom styles applied to them via the theming system.
Setting the theme
To accurately create a theme, we suggest utilizing our exported types to create your own theme. This will allow you to ensure the keys you are using in your theme object are correct.
When you provide a theme as a prop a deep merge of the theme and default theme is performed so only styles designated in the custom theme overwrite the defaults. We provide a helper type DeepPartial
that makes all of the keys at every depth optional, this is to account for the deep merge that is performed.
You can find the default theme object in theme.ts.
Most of the styles are standard React Native styles, but some styles applying to SVG, Markdown, or custom components are numbers, strings, or other specified types.
The TypeScript documentation of Theme
should help you in this regard.
Message text is an instance of an exception as it is rendered using react-native-markdown-package
and the MarkdownStyle
is added to the theme at key messageSimple
-> content
-> markdown
.
import type { DeepPartial, Theme } from 'stream-chat-react-native';
const theme: DeepPartial<Theme> = {
messageSimple: {
file: {
container: {
backgroundColor: 'red',
},
},
},
};
Now you can provide this theme object to the style
key of the value
prop of the OverlayProvider
component.
import { Chat, ChannelList, OverlayProvider } from 'stream-chat-react-native';
const style = { style: theme };
export const App = () => (
<OverlayProvider value={style}>
<Chat client={client}>
<ChannelList />
</Chat>
</OverlayProvider>
);
Using the theme
You can easily access the theme in any custom components you create using the useTheme
hook. To ensure any change to the theme is reflected within the UI it is not advised to pass theme variables through custom memoization checks.
const {
theme: {
colors: { black },
},
} = useTheme();
Dark mode
If you would like to support dark mode in your application, you can create and apply different themes depending on the current colorScheme
provided by React Native. To prevent unnecessary deep merges and re-renders we suggest keeping the current theme in state and only change it when theme colorScheme
changes.
import { useEffect, useState } from 'react';
import { useColorScheme } from 'react-native';
import type { DeepPartial, Theme } from 'stream-chat-react-native';
const getTheme = (): DeepPartial<Theme> => ({
colors: colorScheme === 'dark' ? { black: '#FFFFFF' } : { black: '#000000' },
});
export const App = () => {
const colorScheme = useColorScheme();
const [theme, setTheme] = useState(getTheme());
useEffect(() => {
setTheme(getTheme());
}, [colorScheme]);
return (
<OverlayProvider value={{ style: theme }}>
<Chat client={client}>
<ChannelList />
</Chat>
</OverlayProvider>
);
};