1 | import React from 'react';
|
2 | import deepmerge from 'deepmerge';
|
3 | import colors from './colors';
|
4 | import darkColors from './colorsDark';
|
5 | export const ThemeContext = React.createContext({
|
6 | theme: {
|
7 | colors,
|
8 | },
|
9 | });
|
10 | export 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 |
|
39 |
|
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 | }
|
62 | ThemeProvider.defaultProps = {
|
63 | theme: {},
|
64 | useDark: false,
|
65 | };
|
66 | export const ThemeConsumer = ThemeContext.Consumer;
|