diff --git a/README.md b/README.md index f1af0e2..2d42e1a 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ The whole [portfolio](https://matthiaskretschmann.com) is a React-based Single P ### Lighthouse score -[![Lighthouse scores](https://lighthouse.now.sh/?perf=99&pwa=100&a11y=100&bp=100&seo=100)](https://travis-ci.com/kremalicious/portfolio) +[![Lighthouse scores](https://lighthouse.now.sh/?perf=100&pwa=100&a11y=100&bp=100&seo=100)](https://travis-ci.com/kremalicious/portfolio) ### One data file to rule all pages diff --git a/gatsby-browser.js b/gatsby-browser.js index 8e155d4..cb8dd92 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -1,3 +1,5 @@ +import React from 'react' +import AppProvider from './src/store/provider' import wrapPageElementWithTransition from './src/helpers/wrapPageElement' import './src/styles/global.scss' @@ -6,5 +8,11 @@ if (typeof window !== 'undefined' && !window.IntersectionObserver) { import('intersection-observer') } +// React Context in Browser +// eslint-disable-next-line +export const wrapRootElement = ({ element }) => { + return {element} +} + // Page Transitions & Layout export const wrapPageElement = wrapPageElementWithTransition diff --git a/gatsby-ssr.js b/gatsby-ssr.js index ba55016..1f8c9ea 100644 --- a/gatsby-ssr.js +++ b/gatsby-ssr.js @@ -1,4 +1,13 @@ +import React from 'react' +import { renderToString } from 'react-dom/server' +import AppProvider from './src/store/provider' import wrapPageElementWithTransition from './src/helpers/wrapPageElement' +export const replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => { + // React Context in SSR/build + const ConnectedBody = () => {bodyComponent} + replaceBodyHTMLString(renderToString()) +} + // Page Transitions & Layout export const wrapPageElement = wrapPageElementWithTransition diff --git a/src/components/molecules/Availability.jsx b/src/components/molecules/Availability.jsx index e081b1c..2765447 100644 --- a/src/components/molecules/Availability.jsx +++ b/src/components/molecules/Availability.jsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import { StaticQuery, graphql } from 'gatsby' -import posed, { PoseGroup } from 'react-pose' +import posed from 'react-pose' import { fadeIn } from '../atoms/Transitions' import styles from './Availability.module.scss' @@ -32,21 +32,19 @@ export default class Availability extends PureComponent { return ( !this.props.hide && ( - - -

- - + +

+ ) ) }} diff --git a/src/components/molecules/LogoUnit.jsx b/src/components/molecules/LogoUnit.jsx index 4ce408d..7816d64 100644 --- a/src/components/molecules/LogoUnit.jsx +++ b/src/components/molecules/LogoUnit.jsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import { StaticQuery, graphql } from 'gatsby' -import posed, { PoseGroup } from 'react-pose' +import posed from 'react-pose' import { moveInBottom } from '../atoms/Transitions' import Logo from '../svg/Logo' @@ -48,19 +48,17 @@ export default class LogoUnit extends PureComponent { const { minimal } = this.state return ( - - -

- -

- {title.toLowerCase()} -

-

- {tagline.toLowerCase()} -

-
-
-
+ +
+ +

+ {title.toLowerCase()} +

+

+ {tagline.toLowerCase()} +

+
+
) }} /> diff --git a/src/components/molecules/Networks.jsx b/src/components/molecules/Networks.jsx index e60e738..1dda022 100644 --- a/src/components/molecules/Networks.jsx +++ b/src/components/molecules/Networks.jsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import { StaticQuery, graphql } from 'gatsby' -import posed, { PoseGroup } from 'react-pose' +import posed from 'react-pose' import { moveInTop } from '../atoms/Transitions' import Email from '../svg/Email' @@ -81,16 +81,14 @@ export default class Network extends PureComponent { return ( !this.props.hide && ( - - - {Object.keys(meta.social).map((key, i) => ( - - - {key} - - ))} - - + + {Object.keys(meta.social).map((key, i) => ( + + + {key} + + ))} + ) ) }} diff --git a/src/components/molecules/ThemeSwitch.jsx b/src/components/molecules/ThemeSwitch.jsx index 79f723f..39fc764 100644 --- a/src/components/molecules/ThemeSwitch.jsx +++ b/src/components/molecules/ThemeSwitch.jsx @@ -1,7 +1,8 @@ import React, { PureComponent, Fragment } from 'react' import PropTypes from 'prop-types' import Helmet from 'react-helmet' -import posed, { PoseGroup } from 'react-pose' +import posed from 'react-pose' +import { Consumer } from '../../store/createContext' import { fadeIn } from '../atoms/Transitions' import Day from '../svg/Day' @@ -22,66 +23,41 @@ ThemeToggle.propTypes = { dark: PropTypes.bool } +const ThemeToggleInput = ({ dark, toggleDark }) => ( + +) + +ThemeToggleInput.propTypes = { + dark: PropTypes.bool, + toggleDark: PropTypes.func +} + export default class ThemeSwitch extends PureComponent { - state = { dark: null } - - isDark = () => this.state.dark === true - - darkLocalStorageMode = darkLocalStorage => { - if (darkLocalStorage === 'true') { - this.setState({ dark: true }) - } else { - this.setState({ dark: false }) - } - } - - darkMode = now => { - if (!this.isDark() && (now >= 19 || now <= 7)) { - this.setState({ dark: true }) - } else { - this.setState({ dark: null }) - } - } - - componentDidMount() { - const now = new Date().getHours() - const darkLocalStorage = localStorage.getItem('dark') - - if (darkLocalStorage) { - this.darkLocalStorageMode(darkLocalStorage) - } else { - this.darkMode(now) - } - } - - handleChange = event => { - this.setState({ dark: event.target.checked }) - localStorage.setItem('dark', event.target.checked) - } - render() { return ( - - - - - - - - - - + + {({ dark, toggleDark }) => ( + + + + + + + + + )} + ) } } diff --git a/src/store/createContext.jsx b/src/store/createContext.jsx new file mode 100644 index 0000000..25bffa4 --- /dev/null +++ b/src/store/createContext.jsx @@ -0,0 +1,5 @@ +import { createContext } from 'react' + +const { Provider, Consumer } = createContext() + +export { Provider, Consumer } diff --git a/src/store/provider.jsx b/src/store/provider.jsx new file mode 100644 index 0000000..f78d06a --- /dev/null +++ b/src/store/provider.jsx @@ -0,0 +1,57 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { Provider } from './createContext' + +export default class AppProvider extends Component { + state = { + dark: false, + toggleDark: () => { + this.setState({ dark: !this.state.dark }) + + if (this.store) { + this.store.setItem('dark', !this.state.dark) + } + } + } + + static propTypes = { + children: PropTypes.any.isRequired + } + + store = typeof localStorage === 'undefined' ? null : localStorage + + darkLocalStorageMode = darkLocalStorage => { + if (darkLocalStorage === 'true') { + this.setState({ dark: true }) + } else { + this.setState({ dark: false }) + } + } + + darkMode = now => { + if (!this.state.dark && (now >= 19 || now <= 7)) { + this.setState({ dark: true }) + } else { + this.setState({ dark: null }) + } + } + + checkDark = () => { + const now = new Date().getHours() + const darkLocalStorage = this.store.getItem('dark') + + if (darkLocalStorage) { + this.darkLocalStorageMode(darkLocalStorage) + } else { + this.darkMode(now) + } + } + + componentDidMount() { + this.checkDark() + } + + render() { + return {this.props.children} + } +}