UNPKG

5.96 kBMarkdownView Raw
1<p align="center">
2 <img alt="react-theme-provider" src="./assets/theme-provider-logo.png" width="496">
3</p>
4
5---
6
7[![Build Status][build-badge]][build]
8[![Version][version-badge]][package]
9[![MIT License][license-badge]][license]
10
11## About
12`@callstack/react-theme-provider` is a set of utilities that help you create your own theming system in few easy steps.
13You can use it to customize colors, fonts, etc.
14
15## Features
16 - works in **React** and **React Native**
17 - `ThemeProvider` - component
18 - `withTheme` - Higher Order Component
19 - `createTheming(defaultTheme)` - factory returns `ThemeProvider` component and `withTheme` HOC with default theme injected.
20
21## Examples
22 - buildin example for web react - ['/examples/web'](/examples/web)
23 - [![Edit v6o562k6l7](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/v6o562k6l7)
24
25## Getting started
26### Instalation
27```
28npm install --save @callstack/react-theme-provider
29```
30or using yarn
31```
32yarn add @callstack/react-theme-provider
33```
34
35### Usage
36To use, simply wrap your code into `ThemeProvider` component and pass your theme as a `theme` prop.
37
38```js
39<ThemeProvider theme={{ primaryColor: 'red', background: 'gray'}}>
40 <App />
41</ThemeProvider>
42```
43
44You could access theme data inside every component by wraping it into `withTheme` HOC. Just like this:
45
46```js
47class App extends React.Component {
48 render() {
49 return (
50 <div style={{ color: props.theme.primaryColor }}>
51 Hello
52 </div>
53 );
54 }
55}
56
57export default withTheme(App);
58```
59
60## `ThemeProvider`
61**type:**
62```js
63type ThemeProviderType<T> = React.ComponentType<{
64 children?: any,
65 theme: T,
66}>
67```
68
69Component you have to use to provide the theme to any component wrapped in `withTheme` HOC.
70
71### props
72 -`theme` - your theme object
73
74## `withTheme`
75**type:**
76```js
77type WithThemeType<T, S> = <C: React.ComponentType<*>>(
78 Comp: C
79) => C &
80 React.ComponentType<
81 $Diff<React.ElementConfig<C>, { theme: T }> & { theme?: S }
82 >;
83```
84
85Classic Higher Order Component which takes your component as an argument and injects `theme` prop into it.
86
87### Example of usage
88```js
89const App = ({ theme }) => (
90 <div style={{ color: theme.primaryColor }}>
91 Hello
92 </div>
93);
94
95export withTheme(App);
96```
97
98### Injected props
99It will inject the following props to the component:
100 - `theme` - our theme object.
101 - `getWrappedInstance` - exposed by some HOCs like react-redux's `connect`.
102 Use it to get the ref of the underlying element.
103
104### Injecting theme by a direct prop
105You can also override `theme` provided by `ThemeProvider` by setting `theme` prop on the component wrapped in `withTheme` HOC.
106
107Just like this:
108```js
109const Button = withTheme(({ theme }) => (
110 <div style={{ color: theme.primaryColor }}>
111 Click me
112 </div>
113));
114
115const App = () => (
116 <ThemeProvider theme={{ primaryColor: 'red' }}>
117 <Button theme= {{ primaryColor: 'green' }}/>
118 </ThemeProvider>
119)
120```
121In this example Button will have green text.
122
123## `createTheming`
124**type:**
125```js
126<T, S>(defaultTheme: T) => {
127 ThemeProvider: ThemeProviderType<T>,
128 withTheme: WithThemeType<T, S>,
129}
130```
131
132This is more advanced replacement to classic importing `ThemeProvider` and `withTheme` directly from the library.
133Thanks to it you can create your own ThemeProvider with any default theme.
134
135Returns instance of `ThemeProvider` component and `withTheme` HOC.
136You can use this factory to create a singleton with your instances of `ThemeProvider` and `withTheme`.
137
138>**Note:** `ThemeProvider` and `withTheme` generated by `createTheming` always will use different context so make sure you are using matching `withTheme`!
139If you acidentially import `withTheme` from `@callstack/react-theme-provider` instead of your theming instance it won't work.
140
141### Arguments
142 - `defaultTheme` - default theme object
143
144### Benefits
145 - Possibility to define `flow` types for your theme
146 - Possibility to pass default theme
147 - You can use multiple `ThemeProvider`s in your app without any conflicts.
148
149### Example of usage
150```js
151// theming.js
152import { createTheming } from '@callstack/react-theme-provider';
153const { ThemeProvider, withTheme } = createTheming({
154 primaryColor: 'red',
155 secondaryColor: 'green',
156});
157export { ThemeProvider, withTheme };
158
159//App.js
160import { ThemeProvider, withTheme } from './theming';
161```
162
163## Applying a custom theme to a component
164If 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.
165
166```js
167import * as React from 'react';
168import MyButton from './MyButton';
169
170export default function ButtonExample() {
171 return (
172 <MyButton theme={{ roundness: 3 }}>
173 Press me
174 </MyButton>
175 );
176}
177```
178
179## Gotchas
180The `ThemeProvider` exposes the theme to the components via [React's context API](https://reactjs.org/docs/context.html),
181which means that the component must be in the same tree as the `ThemeProvider`. Some React Native components will render a
182different tree such as a `Modal`, in which case the components inside the `Modal` won't be able to access the theme. The work
183around is to get the theme using the `withTheme` HOC and pass it down to the components as props, or expose it again with the
184exported `ThemeProvider` component.
185
186
187[build-badge]: https://img.shields.io/circleci/project/github/callstack/react-theme-provider/master.svg?style=flat-square
188[build]: https://circleci.com/gh/callstack/react-theme-provider
189[version-badge]: https://img.shields.io/npm/v/@callstack/react-theme-provider.svg?style=flat-square
190[package]: https://www.npmjs.com/package/@callstack/react-theme-provider
191[license-badge]: https://img.shields.io/npm/l/react-theme-provider.svg?style=flat-square
192[license]: https://opensource.org/licenses/MIT
193[chat-badge]: https://img.shields.io/badge/chat-slack-brightgreen.svg?style=flat-square&colorB=E01563
194[chat]: https://slack.callstack.com/
\No newline at end of file