mirror of
https://github.com/kremalicious/portfolio.git
synced 2024-11-13 16:45:12 +01:00
custom useDarkMode hook
This commit is contained in:
parent
15b5006df4
commit
487461518a
@ -74,11 +74,12 @@ If you want to know how, have a look at the respective components:
|
||||
|
||||
### 💅 Theme switcher
|
||||
|
||||
Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's system preferences. If a visitor has set the theme manually that selection is remembered in `localStorage`, and is restored on next visit. All handled by [use-dark-mode](https://github.com/donavon/use-dark-mode)
|
||||
Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's system preferences.
|
||||
|
||||
If you want to know how, have a look at the respective components:
|
||||
|
||||
- [`src/components/molecules/ThemeSwitch.jsx`](src/components/molecules/ThemeSwitch.jsx)
|
||||
- [`src/hooks/useDarkMode.js`](src/hooks/useDarkMode.js)
|
||||
|
||||
### 🏆 SEO component
|
||||
|
||||
|
@ -73,14 +73,6 @@ module.exports = {
|
||||
theme_color_in_head: false // dynamically set in ThemeSwitch
|
||||
}
|
||||
},
|
||||
{
|
||||
resolve: 'gatsby-plugin-use-dark-mode',
|
||||
options: {
|
||||
classNameDark: 'dark',
|
||||
classNameLight: 'light',
|
||||
minify: true
|
||||
}
|
||||
},
|
||||
'gatsby-plugin-react-helmet',
|
||||
'gatsby-plugin-sitemap',
|
||||
'gatsby-plugin-offline',
|
||||
|
28194
package-lock.json
generated
28194
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,6 @@
|
||||
"gatsby-plugin-sharp": "^3.0.1",
|
||||
"gatsby-plugin-sitemap": "^3.0.0",
|
||||
"gatsby-plugin-svgr": "^3.0.0-beta.0",
|
||||
"gatsby-plugin-use-dark-mode": "^1.3.0",
|
||||
"gatsby-plugin-webpack-size": "^2.0.1",
|
||||
"gatsby-source-filesystem": "^3.0.0",
|
||||
"gatsby-transformer-json": "^3.0.0",
|
||||
@ -51,7 +50,6 @@
|
||||
"remark-parse": "^9.0.0",
|
||||
"remark-react": "^8.0.0",
|
||||
"shortid": "^2.2.16",
|
||||
"use-dark-mode": "^2.3.1",
|
||||
"vcf": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -4,7 +4,7 @@ import posed, { PoseGroup } from 'react-pose'
|
||||
import { fadeIn } from './atoms/Transitions'
|
||||
import Typekit from './atoms/Typekit'
|
||||
import HostnameCheck from './atoms/HostnameCheck'
|
||||
// import ThemeSwitch from './molecules/ThemeSwitch'
|
||||
import ThemeSwitch from './molecules/ThemeSwitch'
|
||||
import Header from './organisms/Header'
|
||||
import Footer from './organisms/Footer'
|
||||
import { screen } from './Layout.module.css'
|
||||
@ -40,7 +40,7 @@ export default function Layout({ children, location }) {
|
||||
<>
|
||||
<Typekit />
|
||||
<HostnameCheck allowedHosts={allowedHosts} />
|
||||
{/* <ThemeSwitch /> */}
|
||||
<ThemeSwitch />
|
||||
|
||||
<PoseGroup animateOnMount={process.env.NODE_ENV !== 'test'}>
|
||||
<RoutesContainer
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React, { memo, useEffect, useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import useDarkMode from 'use-dark-mode'
|
||||
import Icon from '../atoms/Icon'
|
||||
import {
|
||||
checkboxContainer,
|
||||
@ -10,16 +9,15 @@ import {
|
||||
checkbox,
|
||||
label
|
||||
} from './ThemeSwitch.module.css'
|
||||
import useDarkMode from '../../hooks/useDarkMode'
|
||||
|
||||
const ThemeToggle = memo(({ dark }) => (
|
||||
const ThemeToggle = ({ dark }) => (
|
||||
<span id="toggle" className={checkboxContainer} aria-live="assertive">
|
||||
<Icon name="Sun" className={!dark ? null : 'active'} />
|
||||
<span className={checkboxFake} />
|
||||
<Icon name="Moon" className={dark ? 'active' : null} />
|
||||
</span>
|
||||
))
|
||||
|
||||
ThemeToggle.displayName = 'ThemeToggle'
|
||||
)
|
||||
|
||||
ThemeToggle.propTypes = {
|
||||
dark: PropTypes.bool.isRequired
|
||||
@ -27,7 +25,7 @@ ThemeToggle.propTypes = {
|
||||
|
||||
const ThemeToggleInput = ({ dark, toggleDark }) => (
|
||||
<input
|
||||
onChange={() => toggleDark()}
|
||||
onChange={() => toggleDark(!dark)}
|
||||
type="checkbox"
|
||||
name="toggle"
|
||||
value="toggle"
|
||||
@ -36,8 +34,6 @@ const ThemeToggleInput = ({ dark, toggleDark }) => (
|
||||
/>
|
||||
)
|
||||
|
||||
ThemeToggleInput.displayName = 'ThemeToggleInput'
|
||||
|
||||
ThemeToggleInput.propTypes = {
|
||||
dark: PropTypes.bool.isRequired,
|
||||
toggleDark: PropTypes.func.isRequired
|
||||
@ -60,10 +56,7 @@ HeadItems.propTypes = {
|
||||
}
|
||||
|
||||
export default function ThemeSwitch() {
|
||||
const { value, toggle } = useDarkMode(false, {
|
||||
classNameDark: 'dark',
|
||||
classNameLight: 'light'
|
||||
})
|
||||
const { value, toggle } = useDarkMode()
|
||||
const [themeColor, setThemeColor] = useState('')
|
||||
const [bodyClass, setBodyClass] = useState('')
|
||||
|
||||
|
60
src/hooks/useDarkMode.js
Normal file
60
src/hooks/useDarkMode.js
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// adapted from
|
||||
// https://github.com/daveschumaker/react-dark-mode-hook/blob/master/useDarkMode.js
|
||||
//
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
|
||||
const isClient = typeof window === 'object'
|
||||
|
||||
function getDarkMode() {
|
||||
// if (localStorage.getItem('theme') === 'dark') {
|
||||
// return true
|
||||
// } else if (localStorage.getItem('theme') === 'light') {
|
||||
// return false
|
||||
// }
|
||||
|
||||
if (
|
||||
isClient &&
|
||||
window.matchMedia &&
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export default function useDarkMode() {
|
||||
const [darkMode, setDarkMode] = useState(getDarkMode)
|
||||
|
||||
//
|
||||
// Handle system theme change events
|
||||
//
|
||||
const handleChange = useCallback(() => {
|
||||
setDarkMode(getDarkMode())
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isClient) return false
|
||||
|
||||
const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
|
||||
try {
|
||||
// Handle Chrome & Firefox
|
||||
darkModeQuery.addEventListener('change', handleChange)
|
||||
} catch (addEventListenerError) {
|
||||
try {
|
||||
// Handle Safari
|
||||
darkModeQuery.addListener('change', handleChange)
|
||||
} catch (addListenerError) {
|
||||
console.error(addListenerError)
|
||||
}
|
||||
}
|
||||
return () =>
|
||||
window
|
||||
.matchMedia('(prefers-color-scheme: dark)')
|
||||
.removeEventListener('change', handleChange)
|
||||
}, [handleChange])
|
||||
|
||||
return { value: darkMode, toggle: setDarkMode }
|
||||
}
|
Loading…
Reference in New Issue
Block a user