Applying a theme to the whole app

To support custom themes, paper exports a Provider component. You need to wrap your root component with the provider to be able to support themes.

import * as React from 'react';
import { Provider as PaperProvider } from 'react-native-paper';
import App from './src/App';

export default function Main() {
  return (
    <PaperProvider>
      <App />
    </PaperProvider>
  );
}

If no prop is specified, this will apply the default theme to the components. You can also provide a theme prop with a theme object with same properties as the default theme:

import * as React from 'react';
import { DefaultTheme, Provider as PaperProvider } from 'react-native-paper';
import App from './src/App';

const theme = {
  ...DefaultTheme,
  roundness: 2,
  colors: {
    ...DefaultTheme.colors,
    primary: '#3498db',
    accent: '#f1c40f',
  }
};

export default function Main() {
  return (
    <PaperProvider theme={theme}>
      <App />
    </PaperProvider>
  );
}

You can change the theme prop dynamically and all the components will automatically update to reflect the new theme.

A theme usually contains the following properties:

  • dark (boolean): whether this is a dark theme or light theme.
  • roundness (number): roundness of common elements, such as buttons.
  • colors (object): various colors used throught different elements.
    • primary - primary color for your app, usually your brand color.
    • accent - secondary color for your app which complements the primary color.
    • background - background color for pages, such as lists.
    • paper - background color for elements containing content, such as cards.
    • text - text color for content.
    • disabled - color for disabled elements.
    • placeholder - color for placeholder text, such as input placeholder.
  • fonts (object): various fonts used throught different elements.
    • regular
    • medium
    • light
    • thin

When creating a custom theme, you will need to provide all of these properties.

Applying a theme to a paper component

If you want to change the theme for a certain component from the library, you can directly pass the theme prop to the component. The theme passed as the prop is merged with the theme from the Provider.

import * as React from 'react';
import { Button } from 'react-native-paper';

export default function ButtonExample() {
  return (
    <Button raised theme={{ roundness: 3 }}>
      Press me
    </Button>
  );
}

Using the theme in your own components

To access the theme in your own components, you can use the withTheme HOC exported from the library. If you wrap your component with the HOC, you'll receive the theme as a prop.

import * as React from 'react';
import { withTheme } from 'react-native-paper';

function MyComponent(props) {
  const { colors } = props.theme;
  return <Text style={{ color: colors.primary }}>Yo!</Text>;
}

export default withTheme(MyComponent);

Components wrapped with withTheme support the theme from the Provider as well as from the theme prop.

Customizing all instances of a component

Sometimes you want to style a component in a different way everywhere and don't want to change the properties in the theme so that other components are not affected. For example, say you want to change the font for all your buttons, but don't want to change theme.fonts.medium because it affects other components.

We don't have an API to do this, because you can already do it with components:

import * as React from 'react';
import { Button } from 'react-native-paper';

export default function FancyButton(props) {
  return <Button theme={{ fonts: { medium: 'Open Sans' } }} {...props} />;
}

Now you can use your FancyButton component everywhere instead of using Button from Paper.

Gotchas

The Provider exposes the theme to the components via React's context API, which means that the component must be in the same tree as the Provider. Some React Native components will render a different tree such as a Modal, in which case the components inside the Modal won't be able to access the theme. The work around is to get the theme using the withTheme HOC and pass it down to the components as props, or expose it again with the exported ThemeProvider component.

The Modal component from the library already handles this edge case, so you won't need to do anything.