# Technical Documentation: callstack/react-native-paper

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/callstack/react-native-paper)

### Overview (`README.md`)

<p align="center">
  <img alt="react-native-paper" src="docs/assets/images/paper-logo.svg?sanitize=true" width="300">
</p>
<p align="center">
  Material design for React Native.<br/>
  <a href="https://reactnativepaper.com">reactnativepaper.com</a>
</p>

---

[](https://greenkeeper.io/)

[![Build Status][build-badge]][build]
[![Version][version-badge]][package]
[![MIT License][license-badge]][license]
[![All Contributors][all-contributors-badge]][all-contributors]
[![PRs Welcome][prs-welcome-badge]][prs-welcome]
[![Chat][chat-badge]][chat]
[![Sponsored by Callstack][callstack-badge]][callstack]

## Features

- Follows [material design guidelines](https://material.io/guidelines/)
- Works on both iOS and Android following [platform adaptation guidelines](https://material.io/design/platform-guidance/cross-platform-adaptation.html)
- Full [theming support](https://callstack.github.io/react-native-paper/theming.html)

Currently supported React Native version: `>= 0.50.3`

## Try it out

Run the [example app](https://snack.expo.io/@react-native-paper/github.com-callstack-react-native-paper:example) with [Expo](https://expo.io/) to see it in action.

The source code for the examples are under the [/example](/example) folder.

## Getting Started

Refer to the [getting started guide](https://callstack.github.io/react-native-paper/getting-started.html) for instructions.

## Documentation

Check the components and their usage in our [documentation](https://callstack.github.io/react-native-paper/index.html).

## Contributing

Read the [contribution guidelines](/CONTRIBUTING.md) before contributing.

## Figma and Sketch component kits

Use official component kits provided by [Material Design](https://material.io/resources). 

## Made with ❤️ at Callstack

`react-native-paper` is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack][callstack-readme-with-love] is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi!



[build-badge]: https://img.shields.io/circleci/project/github/callstack/react-native-paper/master.svg?style=flat-square
[build]: https://circleci.com/gh/callstack/react-native-paper
[version-badge]: https://img.shields.io/npm/v/react-native-paper.svg?style=flat-square
[package]: https://www.npmjs.com/package/react-native-paper
[license-badge]: https://img.shields.io/npm/l/react-native-paper.svg?style=flat-square
[license]: https://opensource.org/licenses/MIT
[all-contributors-badge]: https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square
[all-contributors]: #contributors
[prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[prs-welcome]: http://makeapullrequest.com
[chat-badge]: https://img.shields.io/discord/426714625279524876.svg?style=flat-square&colorB=758ED3
[chat]: https://discord.gg/zwR2Cdh
[callstack-badge]: https://callstack.com/images/callstack-badge.svg
[callstack]: https://callstack.com/open-source/?utm_source=github.com&utm_medium=referral&utm_campaign=react-native-paper&utm_term=readme-badge
[callstack-readme-with-love]: https://callstack.com/?utm_source=github.com&utm_medium=referral&utm_campaign=react-native-paper&utm_term=readme-with-love

## Contributors

Thanks goes to these wonderful people ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key)):



<table>
  <tr>
    <td align="center"><a href="https://twitter.com/@satya164"><img src="https://avatars2.githubusercontent.com/u/1174278?v=4" width="100px;" alt="Satyajit Sahoo"/><br /><sub><b>Satyajit Sahoo</b></sub></a><br /><a href="#ideas-satya164" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/callstack/react-native-paper/commits?author=satya164" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=satya164" title="Documentation">📖</a></td>
    <td align="center"><a href="https://ferrannp.com/"><img src="https://avatars2.githubusercontent.com/u/774577?v=4" width="100px;" alt="Ferran Negre"/><br /><sub><b>Ferran Negre</b></sub></a><br /><a href="#ideas-ferrannp" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/callstack/react-native-paper/commits?author=ferrannp" title="Code">💻</a></td>
    <td align="center"><a href="http://dawidurbaniak.pl"><img src="https://avatars3.githubusercontent.com/u/18584155?v=4" width="100px;" alt="Dawid"/><br /><sub><b>Dawid</b></sub></a><br /><a href="#ideas-Trancever" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/callstack/react-native-paper/commits?author=Trancever" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=Trancever" title="Documentation">📖</a></td>
    <td align="center"><a href="https://twitter.com/esemesek"><img src="https://avatars2.githubusercontent.com/u/9092510?v=4" width="100px;" alt="Kacper Wiszczuk"/><br /><sub><b>Kacper Wiszczuk</b></sub></a><br /><a href="#ideas-Esemesek" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/callstack/react-native-paper/commits?author=Esemesek" title="Code">💻</a></td>
    <td align="center"><a href="https://medium.com/@_happiryu"><img src="https://avatars1.githubusercontent.com/u/22746080?v=4" width="100px;" alt="Luke Walczak"/><br /><sub><b>Luke Walczak</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=lukewalczak" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=lukewalczak" title="Documentation">📖</a></td>
    <td align="center"><a href="https://github.com/ahmedlhanafy"><img src="https://avatars2.githubusercontent.com/u/7052827?v=4" width="100px;" alt="Ahmed Elhanafy"/><br /><sub><b>Ahmed Elhanafy</b></sub></a><br /><a href="#ideas-ahmedlhanafy" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/callstack/react-native-paper/commits?author=ahmedlhanafy" title="Code">💻</a></td>
    <td align="center"><a href="https://github.com/kpsroka"><img src="https://avatars0.githubusercontent.com/u/24893014?v=4" width="100px;" alt="K. P. Sroka"/><br /><sub><b>K. P. Sroka</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=kpsroka" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=kpsroka" title="Documentation">📖</a></td>
  </tr>
  <tr>
    <td align="center"><a href="https://github.com/iyadthayyil"><img src="https://avatars2.githubusercontent.com/u/11161020?v=4" width="100px;" alt="Iyad Thayyil"/><br /><sub><b>Iyad Thayyil</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=iyadthayyil" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=iyadthayyil" title="Documentation">📖</a></td>
    <td align="center"><a href="http://hundeloh-consulting.ch/"><img src="https://avatars1.githubusercontent.com/u/5358638?v=4" width="100px;" alt="Julian Hundeloh"/><br /><sub><b>Julian Hundeloh</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=jaulz" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=jaulz" title="Documentation">📖</a></td>
    <td align="center"><a href="https://www.linkedin.com/in/grzegorzgawrysiak/"><img src="https://avatars3.githubusercontent.com/u/7827311?v=4" width="100px;" alt="Grzegorz Gawrysiak"/><br /><sub><b>Grzegorz Gawrysiak</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=gawrysiak" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=gawrysiak" title="Documentation">📖</a></td>
    <td align="center"><a href="https://github.com/luissmg"><img src="https://avatars2.githubusercontent.com/u/20660551?v=4" width="100px;" alt="Luís"/><br /><sub><b>Luís</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=luissmg" title="Code">💻</a></td>
    <td align="center"><a href="https://raajnadar.in"><img src="https://avatars1.githubusercontent.com/u/17236768?v=4" width="100px;" alt="Rajendran Nadar"/><br /><sub><b>Rajendran Nadar</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=raajnadar" title="Code">💻</a></td>
    <td align="center"><a href="https://github.com/brentvatne"><img src="https://avatars2.githubusercontent.com/u/90494?v=4" width="100px;" alt="Brent Vatne"/><br /><sub><b>Brent Vatne</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=brentvatne" title="Code">💻</a></td>
    <td align="center"><a href="https://jukben.cz"><img src="https://avatars3.githubusercontent.com/u/8135252?v=4" width="100px;" alt="Jakub Beneš"/><br /><sub><b>Jakub Beneš</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=jukben" title="Code">💻</a></td>
  </tr>
  <tr>
    <td align="center"><a href="https://twitter.com/_panpawel"><img src="https://avatars3.githubusercontent.com/u/3886886?v=4" width="100px;" alt="Paweł Szymański"/><br /><sub><b>Paweł Szymański</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=pan-pawel" title="Code">💻</a> <a href="https://github.com/callstack/react-native-paper/commits?author=pan-pawel" title="Documentation">📖</a></td>
    <td align="center"><a href="https://github.com/jaysbytes"><img src="https://avatars1.githubusercontent.com/u/11561585?v=4" width="100px;" alt="Kuba"/><br /><sub><b>Kuba</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=jaysbytes" title="Code">💻</a> <a href="#ideas-jaysbytes" title="Ideas, Planning, & Feedback">🤔</a></td>
    <td align="center"><a href="https://github.com/jbinda"><img src="https://avatars2.githubusercontent.com/u/21242757?v=4" width="100px;" alt="jbinda"/><br /><sub><b>jbinda</b></sub></a><br /><a href="https://github.com/callstack/react-native-paper/commits?author=jbinda" title="Code">💻</a> <a href="#ideas-jbinda" title="Ideas, Planning, & Feedback">🤔</a></td>
  </tr>
</table>



This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

---

### Overview (`example/README.md`)

# Example App for React Native Paper

## React Native App

You can run the React Native app with [this Snack](https://snack.expo.io/@react-native-paper/github.com-callstack-react-native-paper:example). Snack allows you to make changes to the example app directly in the online editor and see changes on your phone instantly using the [Expo](https://expo.io/) app without having to install or setup anything on your computer. You can also "Export" it to download as a standalone Expo app to run locally.

If you want to run the example from the repo,

- Clone the repository and run `yarn` in the root
- Run `yarn example start` to start the packager
- Follow the instructions to open it with the [Expo app](https://expo.io/)

## Web App

You can also run the example app as a web app using [react-native-web](https://github.com/necolas/react-native-web),

- Clone the repository and run `yarn` in the root
- Run `yarn example web` to start the webpack server and open the app in your browser

---

### Pages 1.Getting Started (`docs/pages/1.getting-started.md`)

---
title: Getting Started
---

# Getting Started

## Installation

Open a Terminal in your project's folder and run:

```sh
yarn add react-native-paper
```
or
```sh
npm install react-native-paper
```
If you're on a vanilla React Native project, you also need to install and link [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons).

Specifically `MaterialCommunityIcons` icon pack needs to be included in the project, because some components use those internally (e.g. `AppBar.BackAction` on Android). 

```sh
yarn add react-native-vector-icons
react-native link react-native-vector-icons
```


If you don't want to install vector icons, you can use [babel-plugin-optional-require](https://github.com/satya164/babel-plugin-optional-require) to opt-out.

If you use Expo, you don't need to install vector icons. But if you have a `babel.config.js` or `.babelrc` file, make sure that it includes `babel-preset-expo`.

To get smaller bundle size by excluding modules you don't use, you can use our optional babel plugin. The plugin automatically rewrites the import statements so that only the modules you use are imported instead of the whole library. Add `react-native-paper/babel` to the `plugins` section in your `babel.config.js` for production environment. It should look like this:

```js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  env: {
    production: {
      plugins: ['react-native-paper/babel'],
    },
  },
};
```

If you created your project using Expo, it'll look something like this:

```js
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    env: {
      production: {
        plugins: ['react-native-paper/babel'],
      },
    },
  };
};
```

The plugin only works if you are importing the library using ES2015 import statements and not with `require`.

**Note:** The above examples are for the latest `react-native` using Babel 7. If you have `react-native <= 0.55`, you'll have a `.babelrc` file instead of a `babel.config.js` file and the content of the file will be different.

If you're using Flow for typechecking your code, you need to add the following under the `[options]` section in your `.flowconfig`:

```ini
module.file_ext=.js
module.file_ext=.native.js
module.file_ext=.android.js
module.file_ext=.ios.js
```

## Usage

Wrap your root component in `Provider` from `react-native-paper`. If you have a vanilla React Native project, it's a good idea to add it in the component which is passed to `AppRegistry.registerComponent`. This will usually be in the `index.js` file. If you have an Expo project, you can do this inside the exported component in the `App.js` file.

Example:

```js
import * as React from 'react';
import { AppRegistry } from 'react-native';
import { Provider as PaperProvider } from 'react-native-paper';
import { name as appName } from './app.json';
import App from './src/App';

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

AppRegistry.registerComponent(appName, () => Main);
```

The `PaperProvider` component provides the theme to all the components in the framework. It also acts as a portal to components which need to be rendered at the top level.

If you have another provider (such as `Redux`), wrap it outside `PaperProvider` so that the context is available to components rendered inside a `Modal` from the library:

```js
import * as React from 'react';
import { Provider as PaperProvider } from 'react-native-paper';
import { Provider as StoreProvider } from 'react-redux';
import App from './src/App';
import store from './store';

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

## Customization

You can provide a custom theme to customize the colors, fonts etc. with the `Provider` component. Check the [default theme](https://github.com/callstack/react-native-paper/blob/master/src/styles/DefaultTheme.tsx) to see what customization options are supported.

Example:

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

const theme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    primary: 'tomato',
    accent: 'yellow',
  },
};

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

---

### Package.Json (`docs/package.json`)

{
  "name": "react-native-paper-docs",
  "version": "0.0.1",
  "description": "Documentation for React Native Paper",
  "private": true,
  "author": "",
  "license": "MIT",
  "scripts": {
    "start": "component-docs serve",
    "build": "component-docs build",
    "clean": "del dist/",
    "prestart": "yarn clean"
  },
  "dependencies": {
    "color": "^3.1.2",
    "component-docs": "^0.23.0",
    "linaria": "^1.2.4",
    "react-native-vector-icons": "^6.6.0"
  },
  "devDependencies": {
    "@babel/core": "^7.8.4",
    "@babel/node": "^7.6.3",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/preset-env": "^7.8.4",
    "@babel/preset-flow": "^7.8.3",
    "@babel/preset-react": "^7.8.3",
    "@babel/preset-typescript": "^7.8.3",
    "del-cli": "^3.0.0",
    "file-loader": "^4.2.0",
    "metro-react-native-babel-preset": "^0.56.0",
    "url-loader": "^4.1.0"
  }
}

---

### Pages 2.Theming (`docs/pages/2.theming.md`)

---
title: Theming
---

# Theming

## 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:

```js
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](https://github.com/callstack/react-native-paper/blob/master/src/styles/DefaultTheme.tsx) to the components. You can also provide a `theme` prop with a theme object with same properties as the default theme:

```js
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.
- `mode` (`'adaptive' | 'exact'`): color mode for dark theme (See [Dark Theme](#dark-theme)).
- `roundness` (`number`): roundness of common elements, such as buttons.
- `colors` (`object`): various colors used throughout 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.
  - `surface` - 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.
  - `backdrop` - color for backdrops of various components such as modals.
- `fonts` (`object`): various fonts used throughout different elements.
  - `regular`
  - `medium`
  - `light`
  - `thin`
- `animation` (`object`)
  - `scale` - scale for all animations

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

If you don't use a custom theme, Paper will automatically turn animations on/off, depending on device settings.

Otherwise, your custom theme will need to handle it manually, using React Native's [AccessibilityInfo API](https://reactnative.dev/docs/accessibilityinfo).

## Extending the theme

Keeping your own properties in the theme is fully supported by our library:

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

const theme = {
  ...DefaultTheme,
  // Specify custom property
  myOwnProperty: true,
  // Specify custom property in nested object
  colors: {
    myOwnColor: '#BADA55',
  }
};

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

### TypeScript

By default it won't work well with TypeScript, but we can take advantage of `global augmentations` and specify the new properties that we added to the theme:

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

declare global {
  namespace ReactNativePaper {
    interface ThemeColors {
      myOwnColor: string;
    }

    interface Theme {
      myOwnProperty: boolean;
    }
  }
}

const theme = {
  ...DefaultTheme,
  // Specify custom property
  myOwnProperty: true,
    // Specify custom property in nested object
  colors: {
    myOwnColor: '#BADA55',
  }
};

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

As you can see, custom properties e.g. `myOwnColor` defined in nested object e.g. `colors` needs to be declared in its own interface. You'll find more information in our [example app](https://github.com/callstack/react-native-paper/blob/master/example/src/index.tsx) where we have it implemented.

## 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`:

```js
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:

```js
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.

You can also use the `useTheme` hook:

```js
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>;
}
```

## Customizing all instances of a component

Sometimes you want to style a component in a different way everywhere but 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:

```js
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.

## Dark Theme

Since 3.0 we adapt dark theme to follow [Material design guidelines](https://material.io/design/color/dark-theme.html). </br>
In contrast to light theme, dark theme by default uses `surface` colour instead of `primary` on large components like `AppBar` or `BottomNavigation`.</br>
The dark theme adds a white overlay with opacity depending on elevation of surfaces. It uses it for the better accentuation of surface elevation. Using only shadow is highly imperceptible on dark surfaces.

We are aware that users often use dark theme in their own ways and may not want to use the default dark theme features from the guidelines.</br>
That's why if you are using dark theme you can switch between two dark theme `mode`s:

- `exact` where everything is like it was before. `Appbar` and `BottomNavigation` will still use primary colour by default.</br>
- `adaptive` where we follow [Material design guidelines](https://material.io/design/color/dark-theme.html), the surface will use white overlay with opacity to show elevation, `Appbar` and `BottomNavigation` will use surface colour as a background.

If you don't use a custom theme, Paper will automatically change between the default theme and the default dark theme, depending on device settings.

Otherwise, your custom theme will need to handle it manually, using React Native's [Appearance API](https://reactnative.dev/docs/appearance).

## Gotchas

The `Provider` exposes the theme to the components via [React's context API](https://reactjs.org/docs/context.html), 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.

---

### Pages 3.Icons (`docs/pages/3.icons.mdx`)

export const meta = {
  title: "Icons"
}

import IconsList from './src/components/IconsList.js'

# Icons

## Configuring icons

Many of the components require the [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons) library to render correctly. If you're using Expo, you don't need to do anything extra, but if it's a vanilla React Native project, you need link the library as described in the getting started guide.

If you opted out of vector icons support using [babel-plugin-optional-require](https://github.com/satya164/babel-plugin-optional-require), you won't be able to use icon names for the icon prop. Some components may not look correct without vector icons and might need extra configuration.

## Using the `icon` prop

Many components such as `Button` accept an `icon` prop which is used to display an icon. The `icon` prop supports the following types of values:

### 1. An icon name

You can pass the name of an icon from [`MaterialCommunityIcons`](https://materialdesignicons.com). This will use the [`react-native-vector-icons`](https://github.com/oblador/react-native-vector-icons) library to display the icon.

Example:

```js
<Button icon="camera">
  Press me
</Button>
```

<details><summary>See the list of supported icons</summary>
  <IconsList />
</details>

### 2. An image source

You can pass an image source, such as an object of shape `{ uri: 'https://path.to' }` or a local image: `require('../path/to/image.png')` to use as an icon. The image might be rendered with a different color than the one provided depending on the component. If don't want this behavior, see the next example to pass an `Image` element.

Remote image:

```js
<Button icon={{ uri: 'https://avatars0.githubusercontent.com/u/17571969?v=3&s=400' }}>
  Press me
</Button>
```

Local image:

```js
<Button icon={require('../assets/chameleon.jpg')}>
  Press me
</Button>
```

### 3. A render function

You can pass a function which returns a react element to be used an icon. The function receives an object with `size` and `color` properties as its arguments. The element is used as is without any modification. However, it might get clipped if the provided element's size is bigger than what the component renders. It's up to you to make sure that the size of the element is correct.

Example:

```js
<Button
  icon={({ size, color }) => (
    <Image
      source={require('../assets/chameleon.jpg')}
      style={{ width: size, height: size, tintColor: color }}
    />
  )}
>
  Press me
</Button>
```

### 4. Use custom icons

If you want to use icons other than `MaterialCommunityIcons` you need to import the icons and pass it to the `settings` prop within `PaperProvider`.

Example:

```js
import AwesomeIcon from 'react-native-vector-icons/FontAwesome';
// ...

      <PaperProvider
        settings={{
          icon: props => <AwesomeIcon {...props} />,
        }}
        theme={this.state.theme}
      >
        // ...
      </PaperProvider>
```

## RTL support

If you want your icon to behave properly in a RTL environment, you can pass an object to the `icon` prop with shape: `{ source: { uri: 'https://path.to' }, direction : 'rtl' }`. `source` can be any of the values that the `icon` prop accepts in [option 1](#1.-an-icon-name) and [option 2](#2.-an-image-source). For `direction` you have a few options:

1. `auto` - uses the device language to determine if icon should be displayed from rtl. Uses the `I18nManager` module to get this info.
2. `rtl` - flips the icon so that it is rtl, this is regardless of the device language.
3. `ltr` - displays from ltr, even if in an rtl environment.

Example for using an image source:

```js
<Button icon={{ source: { uri: 'https://avatars0.githubusercontent.com/u/17571969?v=3&s=400' }, direction: 'rtl' }}>
  Press me
</Button>
```

Example for using an icon name:

```js
<Button icon={{ source: "add-a-photo", direction: 'rtl' }}>
  Press me
</Button>
```

You can also use a render function. Along with `size` and `color`, you have access to `direction` which will either be `'rtl'` or `'ltr'`. You can then decide how to render your icon component accordingly.

Example of using a render function:

```js
<Button
  icon={({ size, color, direction }) => (
    <Image
      source={require('../assets/chameleon.jpg')}
      style={[
        {
          transform: [{ scaleX: direction === 'rtl' ? -1 : 1 }],
        },
        {
          width: size,
          height: size,
          tintColor: color
        }
      ]}
    />
  )}
>
  Press me
</Button>
```

---

### Pages 4.Fonts (`docs/pages/4.fonts.md`)

---
title: Fonts
---

# Fonts

## Installing custom fonts

The easiest way to install custom fonts to your RN project is do as follows:

  1. Define path to assets directory with fonts in project:

  Example:

  ```js
    // React Native < 0.60 package.json
    ...
      "rnpm": {
        "assets": [
          "fonts"
        ]
      },
    ...

    // React Native >= 0.60 react-native.config.js
    module.exports = {
    ...
    "assets": [
      "fonts"
    ],
    ...
  ```

  Note: fonts is a folder with .ttf files

  2. Place your font files in your assets folder.
  3. Link font files using '`react-native link`' command.
  4. Restart your project to refresh changes.

Now, you are able to use `fontFamily` from font files.

## Configuring fonts in ThemeProvider

To create a custom font, prepare a `fontConfig` object where fonts are divided by platforms. After that, you have to pass the `fontConfig` into `configureFonts` method in a custom theme. 

The `fontConfig` object accepts `ios`, `android`, `macos`, `windows`, `web`, and `native`. Use these to override fonts on particular platforms.

Note: At a minimum, you need to explicitly pass fonts for `android`, `ios`, and `web`.

Check the [default theme](https://github.com/callstack/react-native-paper/blob/master/src/styles/DefaultTheme.tsx) to see what customization options are supported.

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

const fontConfig = {
  web: {
    regular: {
      fontFamily: 'sans-serif',
      fontWeight: 'normal',
    },
    medium: {
      fontFamily: 'sans-serif-medium',
      fontWeight: 'normal',
    },
    light: {
      fontFamily: 'sans-serif-light',
      fontWeight: 'normal',
    },
    thin: {
      fontFamily: 'sans-serif-thin',
      fontWeight: 'normal',
    },
  },
  ios: {
    regular: {
      fontFamily: 'sans-serif',
      fontWeight: 'normal',
    },
    medium: {
      fontFamily: 'sans-serif-medium',
      fontWeight: 'normal',
    },
    light: {
      fontFamily: 'sans-serif-light',
      fontWeight: 'normal',
    },
    thin: {
      fontFamily: 'sans-serif-thin',
      fontWeight: 'normal',
    },
  },
  android: {
    regular: {
      fontFamily: 'sans-serif',
      fontWeight: 'normal',
    },
    medium: {
      fontFamily: 'sans-serif-medium',
      fontWeight: 'normal',
    },
    light: {
      fontFamily: 'sans-serif-light',
      fontWeight: 'normal',
    },
    thin: {
      fontFamily: 'sans-serif-thin',
      fontWeight: 'normal',
    },
  }
};

const theme = {
  ...DefaultTheme,
  fonts: configureFonts(fontConfig),
};

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

---

### Pages 5.React Native Web (`docs/pages/5.react-native-web.md`)

---
title: Using on the Web
---

# Using on the Web

## Pre-requisites

Make sure that you have followed the getting started guide and have `react-native-paper` installed and configured before following this guide.

We're going to use [react-native-web](https://github.com/necolas/react-native-web) and [webpack](https://webpack.js.org/) to use React Native Paper on the web, so let's install them as well.

To install `react-native-web`, run:

```sh
yarn add react-native-web react-dom react-art
```

### Using CRA ([Create React App](https://github.com/facebook/create-react-app))

Install [`react-app-rewired`](https://github.com/timarney/react-app-rewired) to override `webpack` configuration:

```sh
yarn add --dev react-app-rewired
```

[Configure `babel-loader`](#2-configure-babel-loader) using a new file called `config-overrides.js`:

```js
module.exports = function override(config, env) {
  config.module.rules.push({
    test: /\.js$/,
    exclude: /node_modules[/\\](?!react-native-vector-icons)/,
    use: {
      loader: "babel-loader",
      options: {
        // Disable reading babel configuration
        babelrc: false,
        configFile: false,

        // The configuration for compilation
        presets: [
          ["@babel/preset-env", { useBuiltIns: "usage" }],
          "@babel/preset-react",
          "@babel/preset-flow",
          "@babel/preset-typescript"
        ],
        plugins: [
          "@babel/plugin-proposal-class-properties",
          "@babel/plugin-proposal-object-rest-spread"
        ]
      }
    }
  });

  return config;
};
```

Change your script in `package.json`:

```diff
/* package.json */

  "scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test --env=jsdom",
+   "test": "react-app-rewired test --env=jsdom"
}
```

### Custom webpack setup

To install `webpack`, run:

```sh
yarn add --dev webpack webpack-cli webpack-dev-server
```

If you don't have a webpack config in your project, copy the following to `webpack.config.js` get started:

```js
const path = require('path');

module.exports = {
  mode: 'development',

  // Path to the entry file, change it according to the path you have
  entry: path.join(__dirname, 'App.js'),

  // Path for the output files
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.bundle.js',
  },

  // Enable source map support
  devtool: 'source-map',

  // Loaders and resolver config
  module: {
    rules: [

    ],
  },
  resolve: {

  },

  // Development server config
  devServer: {
    contentBase: [path.join(__dirname, 'public')],
    historyApiFallback: true,
  },
};
```

Also create a folder named `public` and add the following file named `index.html`:

```html
<!doctype html>
<head>
  <meta charSet="utf-8" />
  <meta httpEquiv="X-UA-Compatible" content="IE=edge" />

  <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" />

  <title>App</title>

  <style>
    html, body, #root {
      height: 100%;
    }

    #root {
      display: flex;
      flex-direction: column;
    }
  </style>
</head>
<body>
  <div id="root"></div>
  <script src="app.bundle.js"></script>
</body>
```

Now we're ready to start configuring the project.

## Configure webpack

### 1. Alias `react-native` to `react-native-web`

First, we have to tell webpack to use `react-native-web` instead of `react-native`. Add the following alias in your webpack config under `resolve`:

```js
alias: {
  'react-native$': require.resolve('react-native-web'),
}
```

### 2. Configure `babel-loader`

Next, we want to tell `babel-loader` to compile `react-native-paper` and `react-native-vector-icons`. We would also want to disable reading the babel configuration files to prevent any conflicts.

First install the required dependencies:

```sh
yarn add --dev babel-loader @babel/preset-env @babel/preset-react @babel/preset-flow @babel/preset-typescript @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread
```

Now, add the following in the `module.rules` array in your webpack config:

```js
{
  test: /\.js$/,
  exclude: /node_modules[/\\](?!react-native-vector-icons)/,
  use: {
    loader: 'babel-loader',
    options: {
      // Disable reading babel configuration
      babelrc: false,
      configFile: false,

      // The configuration for compilation
      presets: [
        ['@babel/preset-env', { useBuiltIns: 'usage' }],
        '@babel/preset-react',
        '@babel/preset-flow',
        "@babel/preset-typescript"
      ],
      plugins: [
        '@babel/plugin-proposal-class-properties',
        '@babel/plugin-proposal-object-rest-spread'
      ],
    },
  },
},
```

### 3. Configure `file-loader`

To be able to import images and other assets using `require`, we need to configure `file-loader`. Let's install it:

```sh
yarn add --dev file-loader
```

To configure it, add the following in the `module.rules` array in your webpack config:

```js
{
  test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/,
  loader: 'file-loader',
}
```

## Load the Material Community Icons

If you followed the getting started guide, you should have the following code in your root component:

```js
<PaperProvider>
  <App />
</PaperProvider>
```

Now we need tweak this section to load the Material Community Icons from the [`react-native-vector-icons`](https://github.com/oblador/react-native-vector-icons) library:

```js
<PaperProvider>
  <React.Fragment>
    {Platform.OS === 'web' ? (
      <style type="text/css">{`
        @font-face {
          font-family: 'MaterialCommunityIcons';
          src: url(${require('react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf')}) format('truetype');
        }
      `}</style>
    ) : null}
    <App />
  </React.Fragment>
</PaperProvider>
```

Remember to import `Platform` from `react-native` at the top:

```js
import { Platform } from 'react-native';
```

You can also load these fonts using [`css-loader`](https://github.com/webpack-contrib/css-loader) if you prefer.

## Load the Roboto fonts (optional)

The default theme in React Native Paper uses the Roboto font. You can add them to your project following [the instructions on its Google Fonts page](https://fonts.google.com/specimen/Roboto?selection.family=Roboto:100,300,400,500).

## We're done!

You can run `webpack-dev-server` to run the webpack server and open your project in the browser. You can add the following script in your `package.json` under the `"scripts"` section to make it easier:

```json
"web": "webpack-dev-server --open"
```

Now you can run `yarn web` to run the project on web.

---

### Pages 6.Recommended Libraries (`docs/pages/6.recommended-libraries.md`)

---
title: Recommended Libraries
---

# Recommended Libraries

Our mission is to provide a full suite of well-integrated components built with Material Design in mind. However, many components already have better well maintained implementations.

Here are some of the libraries we recommend:

## Tabs

[react-native-community/react-native-tab-view](https://github.com/react-native-community/react-native-tab-view)

Material Design themed [swipeable tabs](https://material.io/design/components/tabs.html), maintained by [@satya164](https://twitter.com/satya164) and [@mosdnk](https://twitter.com/mosdnk).

## Bottom sheet

[osdnk/reanimated-bottom-sheet](https://github.com/osdnk/react-native-reanimated-bottom-sheet)

An implementation [bottom sheet behaviour](https://material.io/design/components/sheets-bottom.html), maintained by [@mosdnk](https://twitter.com/mosdnk).

## Date Picker
[web-ridge/react-native-paper-dates](https://github.com/web-ridge/react-native-paper-dates)   
[react-native-community/react-native-datetimepicker](https://github.com/react-native-community/react-native-datetimepicker)

## Time Picker
[web-ridge/react-native-paper-dates](https://github.com/web-ridge/react-native-paper-dates)

---

### Pages 7.Contributing (`docs/pages/7.contributing.md`)

---
title: Contributing
---

/../../CONTRIBUTING.md

---

### Pages 8.Theming With React Navigation (`docs/pages/8.theming-with-react-navigation.md`)

---
title: Theming with React Navigation
---

# Theming with React Navigation

In this guide we will look into how to apply theming for an application using React Native Paper and React Navigation at the same time.

Offering different theme options, especially dark/light ones, becomes increasingly a standard requirement of the modern mobile application. Fortunately, both React Navigation and React Native Paper support configurable theming out-of-the-box.
But how to make them work together?

## Combining theme objects

Both libraries require a wrapper to be used at the entry point of the application.
React Navigation exposes `NavigationContainer` which ensures that navigation works correctly, but also accepts `theme` as an optional property. Read more about setting up navigation [here](https://reactnavigation.org/docs/getting-started/).
For React Native Paper theme to work, we need to use `PaperProvider` also at application's entry point.

```js
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { TouchableOpacity } from 'react-native';
import {
  Card,
  Title,
  Paragraph,
  List,
  Provider as PaperProvider,
} from 'react-native-paper';

const Stack = createStackNavigator();

const HomeScreen = ({ navigation }) => (
  <TouchableOpacity
    onPress={() =>
      navigation?.push('Details', {
        title,
        content,
      })
    }
  >
    <Card>
      <Card.Content>
        <Title>{title}</Title>
        <Paragraph>{content}</Paragraph>
      </Card.Content>
    </Card>
  </TouchableOpacity>
);

const DetailsScreen = (props) => {
  const { title, content } = props?.route?.params;
  return (
    <List.Section>
      <List.Subheader>{title}</List.Subheader>
      <List.Item title={content} />
    </List.Section>
  );
};

export default function App() {
  return (
    <PaperProvider>
      <NavigationContainer>
        <Stack.Navigator initialRouteName="Home">
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Details" component={DetailsScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </PaperProvider>
  );
}
```

Fortunately, both React Navigation and React Native Paper offer very similar API when it comes to theming. It's possible to import default themes in light and dark variants from both.

React Navigation and React Native Paper use the same name for default themes - `DefaultTheme` and `DarkTheme`, so we need to alias them at the imports.

Our goal here is to combine those two themes, so that we could control the theme for the entire application from a single place.

To make things easier we can use [deepmerge](https://www.npmjs.com/package/deepmerge) package. With `yarn` we can install it like this

```sh
yarn add deepmerge
```

```js
import {
  NavigationContainer,
  DarkTheme as NavigationDarkTheme,
  DefaultTheme as NavigationDefaultTheme,
} from '@react-navigation/native';
import {
  DarkTheme as PaperDarkTheme,
  DefaultTheme as PaperDefaultTheme,
  Provider as PaperProvider,
} from 'react-native-paper';
import merge from 'deepmerge';

const CombinedDefaultTheme = merge(PaperDefaultTheme, NavigationDefaultTheme);
const CombinedDarkTheme = merge(PaperDarkTheme, NavigationDarkTheme);
```

Alternatively, we could merge those themes using vanilla JavaScript

```js
const CombinedDefaultTheme = {
  ...PaperDefaultTheme,
  ...NavigationDefaultTheme,
  colors: {
    ...PaperDefaultTheme.colors,
    ...NavigationDefaultTheme.colors,
  },
};
const CombinedDarkTheme = {
  ...PaperDarkTheme,
  ...NavigationDarkTheme,
  colors: {
    ...PaperDarkTheme.colors,
    ...NavigationDarkTheme.colors,
  },
};
```

## Passing theme with Providers

After combining the themes, we will be able to control theming in both libraries from a single source, which will come in handy later.

Next, we need to pass merged themes into the Providers. For this part, we use the dark one - `CombinedDarkTheme`.

```js
const CombinedDefaultTheme = merge(PaperDefaultTheme, NavigationDefaultTheme);
const CombinedDarkTheme = merge(PaperDarkTheme, NavigationDarkTheme);

const Stack = createStackNavigator();

export default function App() {
  return (
    <PaperProvider theme={CombinedDarkTheme}>
      <NavigationContainer theme={CombinedDarkTheme}>
        <Stack.Navigator initialRouteName="Home">
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Details" component={DetailsScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </PaperProvider>
  );
}
```

## Customizing theme

We don't need to limit ourselves to the themes offered by the libraries in default. Both packages allow for custom themes to be applied.
You can learn all about it their documentations:

- [Theming in React Navigation](https://reactnavigation.org/docs/themes/)
- [Theming in React Native Paper](https://callstack.github.io/react-native-paper/theming.html)

## React Context for theme customization

Now, we wouldn't want to stay forever with dark theme being on, which is why we need to gain the ability to control theme dynamically. A bit of state management is needed for this purpose.

React Context proves itself very useful in handling cross-cutting concerns like global theme handling, so we will use just that.

## Creating Context

First, we define our Context.

```js
import React from 'react';

export const PreferencesContext = React.createContext({
  toggleTheme: () => {},
  isThemeDark: false,
});
```

## Using Context

Context Provider should be imported also at the entry point, as we want it to wrap the whole app, for the theme values to be accessible at every component that we have.

```js
import React from 'react';
import { PreferencesContext } from './PreferencesContext';

const Stack = createStackNavigator();

const CombinedDefaultTheme = merge(PaperDefaultTheme, NavigationDefaultTheme);
const CombinedDarkTheme = merge(PaperDarkTheme, NavigationDarkTheme);

export default function App() {
  const [isThemeDark, setIsThemeDark] = React.useState(false);

  let theme = isThemeDark ? CombinedDarkTheme : CombinedDefaultTheme;

  const toggleTheme = React.useCallback(() => {
    return setIsThemeDark(!isThemeDark);
  }, [isThemeDark]);

  const preferences = React.useMemo(
    () => ({
      toggleTheme,
      isThemeDark,
    }),
    [toggleTheme, isThemeDark]
  );

  return (
    // Context is wired into the local state of our main component, so that its values could be propagated throughout the entire application
    <PreferencesContext.Provider value={preferences}>
      <PaperProvider theme={theme}>
        <NavigationContainer theme={theme}>
          <Stack.Navigator initialRouteName="Home">
            <Stack.Screen name="Home" component={HomeScreen} />
            <Stack.Screen name="Details" component={DetailsScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      </PaperProvider>
    </PreferencesContext.Provider>
  );
}
```

Now that the Context is available at every component, all we need to do is import it. Next thing is to provide the user with some UI element to control changing the theme. We will use `Paper`'s [Switch](https://callstack.github.io/react-native-paper/switch.html) for this purpose.

```js
import React from 'react';
import { useTheme, Appbar, TouchableRipple, Switch } from 'react-native-paper';
import { PreferencesContext } from './PreferencesContext';

const Header = ({ scene }) => {
  const theme = useTheme();
  const { toggleTheme, isThemeDark } = React.useContext(PreferencesContext);

  return (
    <Appbar.Header
      theme={{
        colors: {
          primary: theme?.colors.surface,
        },
      }}
    >
      <Appbar.Content title={scene.route?.name} />
      <TouchableRipple onPress={() => toggleTheme()}>
        <Switch
          style={[{ backgroundColor: theme.colors.accent }]}
          color={'red'}
          value={isThemeDark}
        />
      </TouchableRipple>
    </Appbar.Header>
  );
};
```

And now you can switch between light and dark theme!



Thanks to the linking of themes that we did earlier, switching themes can be controlled with only one piece of state.

React Native Paper components will automatically use provided theme thanks to the `PaperProvider` that is wrapped around the entry point of our application, but we can also access theme values manually with `useTheme` hook,
exposed by the library. You can see how it's done in the `Header` component code above.

If light/dark themes are not enough for your use case, you can learn more about creating Material Design themes [here](https://material.io/design/material-theming/implementing-your-theme.html#color).
On `master` branch of the example app, you will find implemented [Menu](https://callstack.github.io/react-native-paper/menu.html) component, which allows to choose a few custom themes. Inspecting code in `utils` and `Header` may give you some idea how to use your own themes with `Paper`, in addition to dedicated [docs](https://callstack.github.io/react-native-paper/menu.html).

Read more about integrating `Paper` with `React Navigation` in a brilliant [article](https://reactnavigation.org/blog/2020/01/29/using-react-navigation-5-with-react-native-paper/) by [@trensik](https://twitter.com/trensik)

---

### Pages 9.React Navigation (`docs/pages/9.react-navigation.md`)

---
title: Integrate AppBar with react-navigation
---

# Integrate AppBar with react-navigation

## Prerequisites

 - `react-native-paper`
 - `react-navigation`
 
We assume that you have already installed the mentioned libraries above, otherwise please check out the guides below.
 
 [React Native Paper - Getting Started](https://callstack.github.io/react-native-paper/getting-started.html)
 
 [React Navigation - Getting Started](https://reactnavigation.org/docs/getting-started/)

## Stack Navigator

We will start with `react-navigation` by creating a basic navigation stack. Stack navigator gives us a possibility of transition between screens in our app and manage navigation's history. In a simple scenario where there is only one stack navigator present in the app, it resembles a navigation state in a browser.
Screens are pushed and popped from the stack while the user navigates to a new screen or go back to the previous one.

Let's create two screens. A main screen named `Home` and details screen named `Details`.

```js
import 'react-native-gesture-handler';
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```

At the moment our navigation stack contains two screens and will render `HomeScreen` or `DetailsScreen` components according to the current navigation state. We have not implemented those components yet, so let's do this now:

```js
import React from 'react';
import {View, Text, Button, StyleSheet} from 'react-native';

function HomeScreen() {
  return (
    <View style={style.container}>
      <Text>Home Screen</Text>
    </View>
  );
}

function DetailsScreen() {
  return (
    <View style={style.container}>
      <Text>Details Screen</Text>
    </View>
  );
}

const style = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

Once we have finished implementing the components, we can run the app and check how Stack looks like.



To navigate from `HomeScreen` to `DetailsScreen` we can use the navigation object provided by `Stack.Screen` component. Every component rendered by `Stack.Screen` has an access to the navigation object via props. Let's modify our `HomeScreen` component:

```js
function HomeScreen({ navigation }) {
  return (
    <View style={style.container}>
      <Text>Home Screen</Text>
      <Button
        title="Go to details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}
```

Our result:



As you can see, we can already navigate between two screens. In the next steps, we will show you how to use Paper's `AppBar` instead of the default header.

### Adding AppBar

We can customize Stack's header by passing custom component:

```js
export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{
          header: CustomNavigationBar,
        }}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```

Now we will implement `CustomNavigationBar` using `AppBar` component:

```js
import { Appbar } from 'react-native-paper';

function CustomNavigationBar() {
  return (
    <Appbar.Header>
      <Appbar.Content title="My awesome app" />
    </Appbar.Header>
  );
}
```

Current implementation of the `CustomNavigationBar` is simple - we just render a title inside of it. You may notice there is no way to go back to the previous screen, because the back button is not visible in the header. Let's add it now and let's make sure it's visible on all Stack's screens except `Home` screen.

Firstly, pass navigation props to `CustomNavigationBar`:

```js
export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{
          header: (props) => <CustomNavigationBar {...props} />,
        }}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```

Secondly, we check if navigation has previous state. If it has, it means there is another screen on the stack beneath the current screen and we should render the back arrow button in such a case.

```js
function CustomNavigationBar({ navigation, previous }) {
  return (
    <Appbar.Header>
      {previous ? <Appbar.BackAction onPress={navigation.goBack} /> : null}
      <Appbar.Content title="My awesome app" />
    </Appbar.Header>
  );
}
```




Another interesting pattern that can be implemented with `react-native-paper` and `react-navigation` is a "hamburger menu". Thanks to the `Menu` component we can add a nice looking pop-up to our `Appbar`. To implement this feature we need to make a couple of changes in `CustomNavigationBar`:
- Render a `Menu` component
- Pass `Appbar.Action` to the anchor prop
- Add a state to control `Menu` visibility

We also want the menu to appear only on `HomeScreen`, which means we will render it conditionally based on the `previous` prop.

```js
function CustomNavigationBar({ navigation, previous }) {
  const [visible, setVisible] = React.useState(false);
  const openMenu = () => setVisible(true);
  const closeMenu = () => setVisible(false);

  return (
    <Appbar.Header>
      {previous ? <Appbar.BackAction onPress={navigation.goBack} /> : null}
      <Appbar.Content title="My awesome app" />
      {!previous ? (
        <Menu
          visible={visible}
          onDismiss={closeMenu}
          anchor={
            <Appbar.Action icon="menu" color="white" onPress={openMenu} />
          }>
          <Menu.Item onPress={() => {console.log('Option 1 was pressed')}} title="Option 1" />
          <Menu.Item onPress={() => {console.log('Option 2 was pressed')}} title="Option 2" />
          <Menu.Item onPress={() => {console.log('Option 3 was pressed')}} title="Option 3" disabled />
        </Menu>
      ) : null}
    </Appbar.Header>
  );
}
```

Final result:



That's all we need! We have app bar that contains everything we need to navigate through screens and access an additional menu on the main screen. As you can see, with Material design `Appbar` provided by `react-native-paper` used together with `react-navigation` we can easily create an app that looks and works great.

---

--- METRICS ---
- Files Extracted: 12
- Estimated Token Budget: ~14401 tokens
- Canonical Reference: https://codewiki.google/github.com/callstack/react-native-paper
