Last active
February 14, 2019 02:37
-
-
Save MaximeHeckel/5acb2fc118c8211c2686e0588a9c036d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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