Skip to content

Instantly share code, notes, and snippets.

@MaximeHeckel
Last active February 14, 2019 02:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaximeHeckel/5acb2fc118c8211c2686e0588a9c036d to your computer and use it in GitHub Desktop.
Save MaximeHeckel/5acb2fc118c8211c2686e0588a9c036d to your computer and use it in GitHub Desktop.
import { ThemeProvider as EmotionThemeProvider } from 'emotion-theming';
import React from 'react';
import themeDark from '../theme_dark';
import themeLight from '../theme_light';
interface InterfaceState {
dark: boolean;
toggleDark: () => void;
}
const defaultState = {
dark: false,
toggleDark: () => {},
};
const ThemeContext = React.createContext(defaultState);
const useTheme = () => React.useContext(ThemeContext);
const supportsDarkMode = () =>
window.matchMedia('(prefers-color-scheme: dark)').matches === true;
class ThemeProvider extends React.Component<{}, InterfaceState> {
state = defaultState;
toggleDark = () => {
const dark = !this.state.dark;
localStorage.setItem('dark', JSON.stringify(dark));
this.setState({ dark });
};
componentDidMount() {
// Getting dark mode value from localStorage!
const lsDark = localStorage.getItem('dark') === 'true';
if (lsDark) {
this.setState({ dark: lsDark });
} else if (supportsDarkMode()) {
this.setState({ dark: true });
}
}
render() {
const { children } = this.props;
const { dark } = this.state;
let theme = themeLight;
if (dark) {
theme = themeDark;
}
return (
<EmotionThemeProvider theme={theme}>
<ThemeContext.Provider
value={{
dark,
toggleDark: this.toggleDark,
}}
>
{children}
</ThemeContext.Provider>
</EmotionThemeProvider>
);
}
}
export default ThemeContext;
export { ThemeProvider, useTheme };
// This is has the original effect where we see the theme switching on load (see video https://twitter.com/MaximeHeckel/status/1095565760326291457?s=20)
import React from 'react';
import ThemeContext from '../context/ThemeContext';
const IndexPage = (props) => (
<ThemeContext.Consumer>
{(theme: { dark: boolean; toggleDark: () => void }) => (
<React.Fragment>
<div>Some Emotion styled components consuming the theme...</div>
</React.Fragment>
)}
</ThemeContext.Consumer>
);
export default IndexPage;
// If the theme in localstorage is dark, it will be immediately set (see video https://twitter.com/MaximeHeckel/status/1095565797789855745?s=20)
import React from 'react';
import { useTheme } from '../context/ThemeContext';
const IndexPage = ({ data }: IndexProps) => {
const theme = useTheme();
return (
<React.Fragment>
<div>Some Emotion styled components consuming the theme...</div>
</React.Fragment>
);
};
export default IndexPage;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment