You must have seen “Dark Theme” in many apps nowadays some app even support the totally customizable theme, but how theming works and how it changes on the go? Well, it’s pretty simple with styled-components, most of the steps will be same for any library.
Maintain theme at single place
Never refer colours, font-weight and font-size in your app directly always use a central place to keep theme-related info, it can be redux too.
It will look something like
const theme = {
colors: {
primary: '#0043E8',
secondary: '#F45D01',
alert: '#F73F52',
success: '#1BAA53'
}
fontSize: {
body: 14
..
}
}
Half the work is done
Theme Provider
With styled-components, we have an API ThemeProvider
A helper component for theming. Injects the theme into all styled components anywhere beneath it in the component tree, via the context API. Check the section on Theming.
This is how it is used
<ThemeProvider theme={theme}>
<App />
</ThemeProvider
Here theme
is just an object which will be available in each styled-component in props
can be accessed using props.theme
for example
const Alert = styled.p`
color: ${({ props }) => props.theme.colors.alert};
`;
Theming
Just as we created theme
variable above we have to create a darkTheme
, it should be same as theme
structure-wise or if you are using TypeScript then there interface should be same, some values can be optional them we have to merge both before using.
const defaultTheme = {
colors: {
primary: '#0043E8',
secondary: '#F45D01',
alert: '#F73F52',
success: '#1BAA53'
}
fontSize: {
body: 14
..
}
}const darkTheme = {
colors: {
primary: 'black',
secondary: 'white',
alert: '#F73F52',
success: '#1BAA53'
}
fontSize: defaultTheme.fontSize
}
While passing theme to ThemeProvider
<ThemeProvider
theme={this.props.theme.value === "dark" ? darkTheme : defaultTheme}
>
<App />
</ThemeProvider>
In the above example, the component is connected to redux so we can get theme from redux and on change by the user, it will be reflected instantly.