UNPKG

2.31 kBJavaScriptView Raw
1import React from 'react';
2import deepmerge from 'deepmerge';
3import colors from './colors';
4import darkColors from './colorsDark';
5export const ThemeContext = React.createContext({
6 theme: {
7 colors,
8 },
9});
10export default class ThemeProvider extends React.Component {
11 constructor(props) {
12 super(props);
13 this.updateTheme = (updates) => {
14 this.setState(({ theme }) => ({
15 theme: deepmerge(theme, updates),
16 }));
17 };
18 this.replaceTheme = (theme) => {
19 this.setState(() => ({
20 theme: deepmerge(this.defaultTheme, theme),
21 }));
22 };
23 this.getTheme = () => this.state.theme;
24 const defaultColors = props.useDark ? darkColors : colors;
25 this.defaultTheme = deepmerge({
26 colors: defaultColors,
27 }, props.theme);
28 this.state = {
29 theme: this.defaultTheme,
30 useDark: Boolean(props.useDark),
31 };
32 }
33 static getDerivedStateFromProps(props, state) {
34 const { useDark } = props;
35 const isTheme = (theme) => {
36 return !(Object.keys(theme).length === 0 && theme.constructor === Object);
37 };
38 //isTheme will check if the theme is provided by user and will update the theme only if its provided by user
39 //Not checking if the theme exist or not will always result in if statement getting executed as props.theme !== state.theme if theme is not provided
40 if (useDark !== state.useDark ||
41 (isTheme(props.theme) && props.theme !== state.theme)) {
42 const defaultColors = useDark ? darkColors : colors;
43 return {
44 theme: deepmerge(state.theme, deepmerge({
45 colors: defaultColors,
46 }, props.theme)),
47 useDark,
48 };
49 }
50 return null;
51 }
52 render() {
53 return (<ThemeContext.Provider value={{
54 theme: this.state.theme,
55 updateTheme: this.updateTheme,
56 replaceTheme: this.replaceTheme,
57 }}>
58 {this.props.children}
59 </ThemeContext.Provider>);
60 }
61}
62ThemeProvider.defaultProps = {
63 theme: {},
64 useDark: false,
65};
66export const ThemeConsumer = ThemeContext.Consumer;