1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-12-23 01:29:41 +01:00

dark mode tweaks

This commit is contained in:
Matthias Kretschmann 2019-11-09 19:12:58 +01:00
parent 9f7b96656b
commit 7d208934a2
Signed by: m
GPG Key ID: 606EEEF3C479A91F
7 changed files with 63 additions and 54 deletions

View File

@ -72,10 +72,11 @@ module.exports = {
short_name: 'mk', short_name: 'mk',
start_url: '/', start_url: '/',
background_color: '#e7eef4', background_color: '#e7eef4',
theme_color: '#88bec8', theme_color: '#e7eef4',
icon: 'src/images/favicon.png', icon: 'src/images/favicon.png',
display: 'minimal-ui', display: 'standalone',
cache_busting_mode: 'name' cache_busting_mode: 'name',
theme_color_in_head: false // dynamically set in ThemeSwitch
} }
}, },
'gatsby-plugin-react-helmet', 'gatsby-plugin-react-helmet',

View File

@ -1,8 +1,8 @@
import React, { PureComponent } from 'react' import React, { useContext } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Helmet from 'react-helmet' import Helmet from 'react-helmet'
import posed from 'react-pose' import posed from 'react-pose'
import { Consumer } from '../../store/createContext' import Context from '../../store/createContext'
import { fadeIn } from '../atoms/Transitions' import { fadeIn } from '../atoms/Transitions'
import { ReactComponent as Day } from '../../images/day.svg' import { ReactComponent as Day } from '../../images/day.svg'
@ -39,25 +39,23 @@ ThemeToggleInput.propTypes = {
toggleDark: PropTypes.func.isRequired toggleDark: PropTypes.func.isRequired
} }
export default class ThemeSwitch extends PureComponent { export default function ThemeSwitch() {
render() { const { darkMode, toggleDark } = useContext(Context)
const themeColor = darkMode ? '#1d2224' : '#e7eef4'
return ( return (
<Consumer>
{({ dark, toggleDark }) => (
<> <>
<Helmet> <Helmet>
<body className={dark ? 'dark' : null} /> <body className={darkMode ? 'dark' : null} />
<meta content={themeColor} name="theme-color" />
</Helmet> </Helmet>
<Animation className={styles.themeSwitch}> <Animation className={styles.themeSwitch}>
<label className={styles.checkbox}> <label className={styles.checkbox}>
<span className={styles.label}>Toggle Night Mode</span> <span className={styles.label}>Toggle Night Mode</span>
<ThemeToggleInput dark={dark} toggleDark={toggleDark} /> <ThemeToggleInput dark={darkMode} toggleDark={toggleDark} />
<ThemeToggle dark={dark} /> <ThemeToggle dark={darkMode} />
</label> </label>
</Animation> </Animation>
</> </>
)}
</Consumer>
) )
} }
}

View File

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import { render, fireEvent, cleanup } from '@testing-library/react' import { render, fireEvent, cleanup } from '@testing-library/react'
import { Provider } from '../../store/createContext' import Context from '../../store/createContext'
import ThemeSwitch from './ThemeSwitch' import ThemeSwitch from './ThemeSwitch'
describe('ThemeSwitch', () => { describe('ThemeSwitch', () => {
@ -9,9 +9,11 @@ describe('ThemeSwitch', () => {
it('renders correctly', () => { it('renders correctly', () => {
const { container } = render( const { container } = render(
<Provider value={{ dark: false, toggleDark: () => toggleDark }}> <Context.Provider
value={{ darkMode: false, toggleDark: () => toggleDark }}
>
<ThemeSwitch /> <ThemeSwitch />
</Provider> </Context.Provider>
) )
const switchContainer = container.querySelector('aside') const switchContainer = container.querySelector('aside')
@ -21,9 +23,11 @@ describe('ThemeSwitch', () => {
it('switches when it is dark', () => { it('switches when it is dark', () => {
const { container } = render( const { container } = render(
<Provider value={{ dark: true, toggleDark: () => toggleDark }}> <Context.Provider
value={{ darkMode: true, toggleDark: () => toggleDark }}
>
<ThemeSwitch /> <ThemeSwitch />
</Provider> </Context.Provider>
) )
const toggle = container.querySelector('input') const toggle = container.querySelector('input')
@ -32,9 +36,11 @@ describe('ThemeSwitch', () => {
it('checkbox can be changed', () => { it('checkbox can be changed', () => {
const { container } = render( const { container } = render(
<Provider value={{ dark: false, toggleDark: () => toggleDark }}> <Context.Provider
value={{ darkMode: false, toggleDark: () => toggleDark }}
>
<ThemeSwitch /> <ThemeSwitch />
</Provider> </Context.Provider>
) )
const toggle = container.querySelector('input') const toggle = container.querySelector('input')

View File

@ -2,7 +2,7 @@ import React from 'react'
import { render } from '@testing-library/react' import { render } from '@testing-library/react'
import { StaticQuery, useStaticQuery } from 'gatsby' import { StaticQuery, useStaticQuery } from 'gatsby'
import Header from './Header' import Header from './Header'
import { Provider } from '../../store/createContext' import Context from '../../store/createContext'
import data from '../../../jest/__fixtures__/meta.json' import data from '../../../jest/__fixtures__/meta.json'
describe('Header', () => { describe('Header', () => {
@ -13,18 +13,18 @@ describe('Header', () => {
it('renders correctly', () => { it('renders correctly', () => {
const { container } = render( const { container } = render(
<Provider value={{ dark: false, toggleDark: () => null }}> <Context.Provider value={{ dark: false, toggleDark: () => null }}>
<Header /> <Header />
</Provider> </Context.Provider>
) )
expect(container.firstChild).toBeInTheDocument() expect(container.firstChild).toBeInTheDocument()
}) })
it('Availability can be hidden', () => { it('Availability can be hidden', () => {
const { container } = render( const { container } = render(
<Provider value={{ dark: false, toggleDark: () => null }}> <Context.Provider value={{ dark: false, toggleDark: () => null }}>
<Header minimal={true} /> <Header minimal={true} />
</Provider> </Context.Provider>
) )
expect(container.querySelector('.availability')).not.toBeInTheDocument() expect(container.querySelector('.availability')).not.toBeInTheDocument()
}) })

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Provider } from './createContext' import Context from './createContext'
import { getLocationTimes } from '../utils/getLocationTimes' import { getLocationTimes } from '../utils/getLocationTimes'
import { getCountry } from '../utils/getCountry' import { getCountry } from '../utils/getCountry'
@ -10,7 +10,7 @@ export default class AppProvider extends PureComponent {
} }
state = { state = {
dark: false, darkMode: false,
toggleDark: () => this.toggleDark(), toggleDark: () => this.toggleDark(),
geolocation: null geolocation: null
} }
@ -31,8 +31,8 @@ export default class AppProvider extends PureComponent {
this.mounted = false this.mounted = false
} }
setDark(dark) { setDark(darkMode) {
this.mounted && this.setState({ dark }) this.mounted && this.setState({ darkMode })
} }
darkLocalStorageMode(darkLocalStorage) { darkLocalStorageMode(darkLocalStorage) {
@ -43,16 +43,16 @@ export default class AppProvider extends PureComponent {
// All the checks to see if we should go dark or light // All the checks to see if we should go dark or light
// //
async checkTimes() { async checkTimes() {
const { geolocation, dark } = this.state const { geolocation, darkMode } = this.state
const { sunset, sunrise } = await getLocationTimes(geolocation) const { sunset, sunrise } = getLocationTimes(geolocation)
const now = new Date().getHours() const now = new Date().getHours()
const weWantItDarkTimes = now >= sunset || now <= sunrise const weWantItDarkTimes = now >= sunset || now <= sunrise
!dark && weWantItDarkTimes ? this.setDark(true) : this.setDark(false) !darkMode && weWantItDarkTimes ? this.setDark(true) : this.setDark(false)
} }
async checkDark() { async checkDark() {
const darkLocalStorage = await this.store.getItem('dark') const darkLocalStorage = await this.store.getItem('darkMode')
darkLocalStorage darkLocalStorage
? this.darkLocalStorageMode(darkLocalStorage) ? this.darkLocalStorageMode(darkLocalStorage)
@ -60,11 +60,15 @@ export default class AppProvider extends PureComponent {
} }
toggleDark = () => { toggleDark = () => {
this.setState({ dark: !this.state.dark }) this.setState({ darkMode: !this.state.darkMode })
this.store && this.store.setItem('dark', !this.state.dark) this.store && this.store.setItem('darkMode', !this.state.darkMode)
} }
render() { render() {
return <Provider value={this.state}>{this.props.children}</Provider> return (
<Context.Provider value={this.state}>
{this.props.children}
</Context.Provider>
)
} }
} }

View File

@ -2,7 +2,7 @@ import React from 'react'
import { render, fireEvent } from '@testing-library/react' import { render, fireEvent } from '@testing-library/react'
import { LocalStorageMock } from '@react-mock/localstorage' import { LocalStorageMock } from '@react-mock/localstorage'
import AppProvider from './AppProvider.jsx' import AppProvider from './AppProvider.jsx'
import { Consumer } from './createContext.jsx' import Context from './createContext.jsx'
describe('AppProvider', () => { describe('AppProvider', () => {
it('renders correctly', () => { it('renders correctly', () => {
@ -15,13 +15,13 @@ describe('AppProvider', () => {
const { getByTestId } = render( const { getByTestId } = render(
<LocalStorageMock items={{ dark: 'true' }}> <LocalStorageMock items={{ dark: 'true' }}>
<AppProvider> <AppProvider>
<Consumer> <Context.Consumer>
{state => ( {state => (
<button data-testid="toggle" onClick={() => state.toggleDark()}> <button data-testid="toggle" onClick={() => state.toggleDark()}>
Toggle Toggle
</button> </button>
)} )}
</Consumer> </Context.Consumer>
</AppProvider> </AppProvider>
</LocalStorageMock> </LocalStorageMock>
) )

View File

@ -1,5 +1,5 @@
import { createContext } from 'react' import { createContext } from 'react'
const { Provider, Consumer } = createContext() const Context = createContext()
export { Provider, Consumer } export default Context