# @callstack/react-theme-provider

> Theme provider for react and react-native applications

Latest version **3.0.9** (published 2023-08-01) · MIT license · 0 weekly downloads

## Install

```sh
npm install @callstack/react-theme-provider
pnpm add @callstack/react-theme-provider
yarn add @callstack/react-theme-provider
bun add @callstack/react-theme-provider
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.0.9 |
| Published | 2023-08-01 |
| First published | 2018-04-12 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 32 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 465 |
| Maintainers | admin-callstack, rafikitiki, jbinda, mdjastrzebski, souhe, thymikee, grabbou, satya164 |
| Keywords | react, react-native, theme, provider |

## Links

- npm: https://www.npmjs.com/package/@callstack/react-theme-provider
- Repository: https://github.com/callstack/react-theme-provider
- Homepage: https://github.com/callstack/react-theme-provider#readme
- Issues: https://github.com/callstack/react-theme-provider/issues
- npm.io page: https://npm.io/package/@callstack/react-theme-provider

## Dependencies (2)

- [deepmerge](https://npm.io/package/deepmerge.md) ^3.2.0
- [hoist-non-react-statics](https://npm.io/package/hoist-non-react-statics.md) ^3.3.0

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 3.0.9 (latest) — 2023-08-01
- 3.0.6 (v3.0.6) — 2021-05-06
- 3.0.8 — 2022-09-05
- 3.0.7 — 2021-10-15
- 2.1.0 — 2020-01-02
- 3.0.5 — 2019-10-16
- 3.0.3 — 2019-07-11
- 3.0.2 — 2019-06-24
- 3.0.1 — 2019-06-24
- 2.0.2 — 2019-06-24
- 3.0.0 — 2019-05-22
- 2.0.1 — 2019-03-29
- 2.0.0 — 2019-03-14
- 1.0.7 — 2018-11-05
- 1.0.6 — 2018-10-08
- … 9 more at https://npm.io/package/@callstack/react-theme-provider/versions

## README

<p align="center">
  <img alt="react-theme-provider" src="./assets/theme-provider-logo.png" width="496">
</p>

---

[![Build Status][build-badge]][build]
[![Version][version-badge]][package]
[![MIT License][license-badge]][license]

## About

`@callstack/react-theme-provider` is a set of utilities that help you create your own theming system in few easy steps.
You can use it to customize colors, fonts, etc.

## Features

- Works in **React** and **React Native**
- `createTheming(defaultTheme)` - factory returns:
  - `ThemeProvider` - component
  - `withTheme` - Higher Order Component
  - `useTheme` - React Hook

## Examples

- built-in example for web react - ['/examples/web'](/examples/web)
- [![Edit v6o562k6l7](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/v6o562k6l7)

## Getting started

### Installation

```sh
npm install --save @callstack/react-theme-provider
```

or using yarn

```sh
yarn add @callstack/react-theme-provider
```

### Usage

Import `createTheming` from the library to create a theming object.

```js
import { createTheming } from '@callstack/react-theme-provider';

const { ThemeProvider, withTheme, useTheme } = createTheming(defaultTheme);
```

Then wrap your code in `ThemeProvider` component to make it available to all components.

```js
<ThemeProvider>
  <App />
</ThemeProvider>
```

You can access the theme data in your components by wrapping it in `withTheme` HOC:

```js
class App extends React.Component {
  render() {
    return <div style={{ color: props.theme.primaryColor }}>Hello</div>;
  }
}

export default withTheme(App);
```

Another usage for functional component:

```js
const App = ({ theme }) => (
  <div style={{ color: theme.primaryColor }}>
    Hello
  </div>
);

export withTheme(App);
```

You can also use the [hooks](https://reactjs.org/docs/hooks-intro.html) based API:

```js
function App() {
  const theme = useTheme();

  return <div style={{ color: theme.primaryColor }}>Hello</div>;
}
```

### Injected props

It will inject the following props to the component:

- `theme` - our theme object.
- `getWrappedInstance` - exposed by some HOCs like react-redux's `connect`.
  Use it to get the ref of the underlying element.

### Injecting theme by a direct prop

You can also override `theme` provided by `ThemeProvider` by setting `theme` prop on the component wrapped in `withTheme` HOC.

Just like this:

```js
const Button = withTheme(({ theme }) => (
  <div style={{ color: theme.primaryColor }}>Click me</div>
));

const App = () => (
  <ThemeProvider theme={{ primaryColor: 'red' }}>
    <Button theme={{ primaryColor: 'green' }} />
  </ThemeProvider>
);
```

In this example Button will have green text.

## `createTheming`

**type:**

```js
<T, S>(defaultTheme: T) => {
  ThemeProvider: ThemeProviderType<T>,
  withTheme: WithThemeType<T, S>,
}
```

This is more advanced replacement to classic importing `ThemeProvider` and `withTheme` directly from the library.
Thanks to it you can create your own ThemeProvider with any default theme.

Returns instance of `ThemeProvider` component and `withTheme` HOC.
You can use this factory to create a singleton with your instances of `ThemeProvider` and `withTheme`.

> **Note:** `ThemeProvider` and `withTheme` generated by `createTheming` always will use different context so make sure you are using matching `withTheme`!
> If you acidentially import `withTheme` from `@callstack/react-theme-provider` instead of your theming instance it won't work.

### Arguments

- `defaultTheme` - default theme object

### Benefits

- Possibility to define `flow` types for your theme
- Possibility to pass default theme
- You can use multiple `ThemeProvider`s in your app without any conflicts.

### Usage

```js
// theming.js
import { createTheming } from '@callstack/react-theme-provider';
const { ThemeProvider, withTheme } = createTheming({
  primaryColor: 'red',
  secondaryColor: 'green',
});
export { ThemeProvider, withTheme };

//App.js
import { ThemeProvider, withTheme } from './theming';
```

### Helpers

#### `ThemeProvider`

**type:**

```js
type ThemeProviderType<Theme> = React.ComponentType<{
  children: React.Node,
  theme?: Theme,
}>;
```

Component you have to use to provide the theme to any component wrapped in `withTheme` HOC.

##### Props

-`theme` - your theme object

#### `withTheme`

**type:**

```js
type WithThemeType<Theme> = React.ComponentType<{ theme: Theme }>
```

Higher Order Component which takes your component as an argument and injects `theme` prop into it.

#### `useTheme`

**type:**

```js
type UseTheme = (overrides?: PartialTheme) => Theme;
```

Hook which takes theme overrides and returns a theme object.

Example:

```js
function App(props) {
  const theme = useTheme(props.theme);

  return <div style={{ color: theme.primaryColor }}>Hello</div>;
}
```

## Applying a custom theme to a component

If you want to change the theme for a certain component, 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 MyButton from './MyButton';

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

## Gotchas

The `ThemeProvider` 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 `ThemeProvider`. 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.

[build-badge]: https://img.shields.io/circleci/project/github/callstack/react-theme-provider/master.svg?style=flat-square
[build]: https://circleci.com/gh/callstack/react-theme-provider
[version-badge]: https://img.shields.io/npm/v/@callstack/react-theme-provider.svg?style=flat-square
[package]: https://www.npmjs.com/package/@callstack/react-theme-provider
[license-badge]: https://img.shields.io/npm/l/react-theme-provider.svg?style=flat-square
[license]: https://opensource.org/licenses/MIT
[chat-badge]: https://img.shields.io/badge/chat-slack-brightgreen.svg?style=flat-square&colorB=E01563
[chat]: https://slack.callstack.com/

---
_Source: https://npm.io/package/@callstack/react-theme-provider · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
