React-native-paper provides a default theme which is used automatically. But if you want to customize that, then you need to provide theme
prop in <provider>
component. This prop holds the custom theme. Use it like this –
import * as React from 'react'; import { DefaultTheme, Provider as PaperProvider } from 'react-native-paper'; import App from './src/App'; const theme = { ...DefaultTheme, }; export default function Main() { return ( <PaperProvider theme={theme}> <App /> </PaperProvider> ); }
In the above code snippet we have used theme
prop in <PaperProvider>
component. This prop holds theme object which we have declared in line 5. For this example we are using the default theme without any customization.
When we need to do the customization, we do that in theme
object. For example, changing colors, fonts, typography etc.
What is PaperProvider
?
PaperProvider is nothing but an alias of Provider component of react-native-paper. We are using this name because if you use Redux then it also has a component with name Provider and same names will clash.
To customize the theme, we change theme
object like this –
const theme = { ...DefaultTheme, roundness: 2, colors: { ...DefaultTheme.colors, primary: '#3498db', accent: '#f1c40f', }, };
You can see that we are including the whole DefaultTheme
first. This is because we need to provide all the theme properties in this object. First we included all of them by spreading DefaultTheme
and then change the properties we need to customize, like roundness
or colors
.
What properties can we customize in the theme?
Here is the list of properties that we can customize –
const theme = { dark: true, // Set dark theme mode: 'adaptive' | 'exact', // adaptive - According to material guidelines // exact - According to your custom theme roundness: 3, // roundness of components like buttons colors: { primary: '#FF0000', accent: '#FFFF00', background: '#FFFFFF', surface: '#EEEEEE', text: '#000000', disabled: '#aaaaaa', placeholder: '#cccccc', backdrop: '#333333', // backdrop means the modal overlay onSurface: '#111111', // background color of snackbars notification: '#aa0000', // background color of badge }, fonts: { regular: 'Open Sans', medium: 'Open Sans', light: 'Open Sans', thin: 'Open Sans', }, animation: { scale: 2, // Scale for animations } }
Can we add a self defined property in theme object?
Yes. We can add a user defined property in theme object. Like this –
const theme = { ...DefaultTheme, // đ A custom property myCustomFlag: true, colors: { ...DefaultTheme.colors, // đ Nested custom property myCustomColor: '#123456', } }
In the above code we are setting two self defined custom properties – theme.myCustomFlag
and theme.colors.myCustomColor
.
How to access theme properties throughout the application code?
React-native-paper provides a hook – useTheme()
. In any component we can get the theme object using this hook. Like this –
import * as React from 'react'; import { useTheme } from 'react-native-paper'; function MyComponent(props) { const { colors } = useTheme(); return <Text style={{ color: colors.primary }}>Yo!</Text>; }
This way, you can access your self defined custom properties too.
Can we apply custom theme to a single component?
Sure we can. Every component holds theme
prop where we can pass the customized theme. Check the below code –
import * as React from 'react'; import { Button } from 'react-native-paper'; export default function FancyButton(props) { return <Button theme={{ roundness: 3, fonts: { medium: 'Open Sans' } }} {...props} />; }
From the above code you can see that we have changed the theme properties in Button
component. This won’t change the other Buttons in the app but only FancyButton
.
Why we didn’t pass complete theme?
If you remember, we said that we need to provide all the theme properties but in above code we only provided roundness
and fonts
properties. This is because react-native-paper merge the application theme and these properties and then pass to the component.