mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 17:23:50 +01:00
gatsby v3 updates
This commit is contained in:
parent
3aa87e0e82
commit
2c171a5ee7
@ -42,9 +42,5 @@ module.exports = {
|
|||||||
title: '/Uses',
|
title: '/Uses',
|
||||||
link: '/uses'
|
link: '/uses'
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
darkModeConfig: {
|
|
||||||
classNameDark: 'dark',
|
|
||||||
classNameLight: 'light'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -220,13 +220,6 @@ module.exports = {
|
|||||||
exclude: ['/archive', '/archive/**/*', '/thanks', '/tags']
|
exclude: ['/archive', '/archive/**/*', '/thanks', '/tags']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resolve: 'gatsby-plugin-use-dark-mode',
|
|
||||||
options: {
|
|
||||||
...siteConfig.darkModeConfig,
|
|
||||||
minify: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'gatsby-plugin-react-helmet',
|
'gatsby-plugin-react-helmet',
|
||||||
'gatsby-plugin-catch-links',
|
'gatsby-plugin-catch-links',
|
||||||
'gatsby-redirect-from',
|
'gatsby-redirect-from',
|
||||||
|
36905
package-lock.json
generated
36905
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
40
package.json
40
package.json
@ -29,32 +29,31 @@
|
|||||||
"not op_mini all"
|
"not op_mini all"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ethersproject/providers": "^5.0.23",
|
"@ethersproject/providers": "^5.0.24",
|
||||||
"@ethersproject/units": "^5.0.10",
|
"@ethersproject/units": "^5.0.11",
|
||||||
"@loadable/component": "^5.14.1",
|
"@loadable/component": "^5.14.1",
|
||||||
"@web3-react/core": "^6.1.9",
|
"@web3-react/core": "^6.1.9",
|
||||||
"@web3-react/injected-connector": "^6.0.7",
|
"@web3-react/injected-connector": "^6.0.7",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"date-fns": "^2.17.0",
|
"date-fns": "^2.19.0",
|
||||||
"dms2dec": "^1.1.0",
|
"dms2dec": "^1.1.0",
|
||||||
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
||||||
"fast-exif": "^1.0.1",
|
"fast-exif": "^1.0.1",
|
||||||
"feather-icons": "^4.28.0",
|
"feather-icons": "^4.28.0",
|
||||||
"fraction.js": "^4.0.13",
|
"fraction.js": "^4.0.13",
|
||||||
"gatsby": "^3.0.3",
|
"gatsby": "^3.0.4",
|
||||||
"gatsby-plugin-catch-links": "^3.0.0",
|
"gatsby-plugin-catch-links": "^3.0.0",
|
||||||
"gatsby-plugin-feed": "^3.0.0",
|
"gatsby-plugin-feed": "^3.0.0",
|
||||||
"gatsby-plugin-image": "^1.0.0",
|
"gatsby-plugin-image": "^1.0.1",
|
||||||
"gatsby-plugin-lunr": "^1.5.2",
|
"gatsby-plugin-lunr": "^1.5.2",
|
||||||
"gatsby-plugin-manifest": "^3.0.0",
|
"gatsby-plugin-manifest": "^3.0.0",
|
||||||
"gatsby-plugin-matomo": "^0.9.0",
|
"gatsby-plugin-matomo": "^0.9.0",
|
||||||
"gatsby-plugin-meta-redirect": "^1.1.1",
|
"gatsby-plugin-meta-redirect": "^1.1.1",
|
||||||
"gatsby-plugin-offline": "^4.0.0",
|
"gatsby-plugin-offline": "^4.0.0",
|
||||||
"gatsby-plugin-react-helmet": "^4.0.0",
|
"gatsby-plugin-react-helmet": "^4.0.0",
|
||||||
"gatsby-plugin-sharp": "^3.0.0",
|
"gatsby-plugin-sharp": "^3.0.1",
|
||||||
"gatsby-plugin-sitemap": "^3.0.0",
|
"gatsby-plugin-sitemap": "^3.0.0",
|
||||||
"gatsby-plugin-svgr": "^3.0.0-beta.0",
|
"gatsby-plugin-svgr": "^3.0.0-beta.0",
|
||||||
"gatsby-plugin-use-dark-mode": "^1.3.0",
|
|
||||||
"gatsby-plugin-webpack-size": "^1.0.0",
|
"gatsby-plugin-webpack-size": "^1.0.0",
|
||||||
"gatsby-redirect-from": "^0.3.0",
|
"gatsby-redirect-from": "^0.3.0",
|
||||||
"gatsby-remark-autolink-headers": "^3.0.0",
|
"gatsby-remark-autolink-headers": "^3.0.0",
|
||||||
@ -80,29 +79,28 @@
|
|||||||
"react-transition-group": "^4.4.1",
|
"react-transition-group": "^4.4.1",
|
||||||
"remark": "^13.0.0",
|
"remark": "^13.0.0",
|
||||||
"remark-react": "^8.0.0",
|
"remark-react": "^8.0.0",
|
||||||
"slugify": "^1.4.7",
|
"slugify": "^1.4.7"
|
||||||
"use-dark-mode": "^2.3.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@svgr/webpack": "^5.5.0",
|
"@svgr/webpack": "^5.5.0",
|
||||||
"@testing-library/jest-dom": "^5.11.9",
|
"@testing-library/jest-dom": "^5.11.9",
|
||||||
"@testing-library/react": "^11.2.5",
|
"@testing-library/react": "^11.2.5",
|
||||||
"@types/classnames": "^2.2.11",
|
"@types/classnames": "^2.2.11",
|
||||||
"@types/fs-extra": "^9.0.7",
|
"@types/fs-extra": "^9.0.8",
|
||||||
"@types/jest": "^26.0.20",
|
"@types/jest": "^26.0.20",
|
||||||
"@types/loadable__component": "^5.13.3",
|
"@types/loadable__component": "^5.13.3",
|
||||||
"@types/lunr": "^2.3.3",
|
"@types/lunr": "^2.3.3",
|
||||||
"@types/node": "^14.14.28",
|
"@types/node": "^14.14.34",
|
||||||
"@types/node-fetch": "^2.5.8",
|
"@types/node-fetch": "^2.5.8",
|
||||||
"@types/react": "^17.0.2",
|
"@types/react": "^17.0.3",
|
||||||
"@types/react-dom": "^17.0.1",
|
"@types/react-dom": "^17.0.2",
|
||||||
"@types/react-helmet": "^6.1.0",
|
"@types/react-helmet": "^6.1.0",
|
||||||
"@types/react-transition-group": "^4.4.0",
|
"@types/react-transition-group": "^4.4.0",
|
||||||
"@types/shortid": "^0.0.29",
|
"@types/shortid": "^0.0.29",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.15.2",
|
"@typescript-eslint/eslint-plugin": "^4.17.0",
|
||||||
"@typescript-eslint/parser": "^4.15.2",
|
"@typescript-eslint/parser": "^4.17.0",
|
||||||
"@welldone-software/why-did-you-render": "^6.0.5",
|
"@welldone-software/why-did-you-render": "^6.1.0",
|
||||||
"eslint": "^7.21.0",
|
"eslint": "^7.22.0",
|
||||||
"eslint-config-prettier": "^8.1.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
"eslint-plugin-graphql": "^4.0.0",
|
"eslint-plugin-graphql": "^4.0.0",
|
||||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||||
@ -110,23 +108,23 @@
|
|||||||
"eslint-plugin-react": "^7.22.0",
|
"eslint-plugin-react": "^7.22.0",
|
||||||
"eslint-plugin-testing-library": "^3.10.1",
|
"eslint-plugin-testing-library": "^3.10.1",
|
||||||
"fs-extra": "^9.1.0",
|
"fs-extra": "^9.1.0",
|
||||||
"gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.20",
|
"gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.21",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"markdownlint-cli": "^0.26.0",
|
"markdownlint-cli": "^0.26.0",
|
||||||
"node-iptc": "^1.0.5",
|
"node-iptc": "^1.0.5",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"ora": "^5.3.0",
|
"ora": "^5.3.0",
|
||||||
"postcss": "^8.2.7",
|
"postcss": "^8.2.8",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
"shortid": "^2.2.16",
|
"shortid": "^2.2.16",
|
||||||
"stylelint": "^13.11.0",
|
"stylelint": "^13.12.0",
|
||||||
"stylelint-config-css-modules": "^2.2.0",
|
"stylelint-config-css-modules": "^2.2.0",
|
||||||
"stylelint-config-prettier": "^8.0.2",
|
"stylelint-config-prettier": "^8.0.2",
|
||||||
"stylelint-config-standard": "^20.0.0",
|
"stylelint-config-standard": "^20.0.0",
|
||||||
"stylelint-prettier": "^1.2.0",
|
"stylelint-prettier": "^1.2.0",
|
||||||
"ts-node": "^9.1.1",
|
"ts-node": "^9.1.1",
|
||||||
"typescript": "^4.2.2"
|
"typescript": "^4.2.3"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { ReactElement, useState } from 'react'
|
import React, { ReactElement, useState } from 'react'
|
||||||
import Map from 'pigeon-maps'
|
import Map from 'pigeon-maps'
|
||||||
import Marker from 'pigeon-marker'
|
import Marker from 'pigeon-marker'
|
||||||
import useDarkMode from 'use-dark-mode'
|
import useDarkMode from '../../hooks/useDarkMode'
|
||||||
|
|
||||||
const mapbox = (mapboxId: string) => (
|
const mapbox = (mapboxId: string) => (
|
||||||
x: string,
|
x: string,
|
||||||
@ -23,10 +23,7 @@ export default function ExifMap({
|
|||||||
}: {
|
}: {
|
||||||
gps: { latitude: string; longitude: string }
|
gps: { latitude: string; longitude: string }
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { value } = useDarkMode(false, {
|
const { value } = useDarkMode()
|
||||||
classNameDark: 'dark',
|
|
||||||
classNameLight: 'light'
|
|
||||||
})
|
|
||||||
const isDarkMode = value
|
const isDarkMode = value
|
||||||
const [zoom, setZoom] = useState(12)
|
const [zoom, setZoom] = useState(12)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
|
|||||||
import { graphql } from 'gatsby'
|
import { graphql } from 'gatsby'
|
||||||
import { GatsbyImage } from 'gatsby-plugin-image'
|
import { GatsbyImage } from 'gatsby-plugin-image'
|
||||||
import { ImageProps } from '../../@types/Image'
|
import { ImageProps } from '../../@types/Image'
|
||||||
import * as styles from './Image.module.css'
|
import { image as styleImage, imageTitle } from './Image.module.css'
|
||||||
|
|
||||||
export const Image = ({
|
export const Image = ({
|
||||||
title,
|
title,
|
||||||
@ -12,11 +12,11 @@ export const Image = ({
|
|||||||
className
|
className
|
||||||
}: ImageProps): ReactElement => (
|
}: ImageProps): ReactElement => (
|
||||||
<figure
|
<figure
|
||||||
className={`${styles.image} ${className ? className : ''}`}
|
className={`${styleImage} ${className ? className : ''}`}
|
||||||
data-original={original && original.src}
|
data-original={original?.src}
|
||||||
>
|
>
|
||||||
<GatsbyImage backgroundColor="transparent" image={image} alt={alt} />
|
<GatsbyImage backgroundColor="transparent" image={image} alt={alt} />
|
||||||
{title && <figcaption className={styles.imageTitle}>{title}</figcaption>}
|
{title && <figcaption className={imageTitle}>{title}</figcaption>}
|
||||||
</figure>
|
</figure>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,7 +3,11 @@ import { Link, graphql } from 'gatsby'
|
|||||||
import { Image } from '../atoms/Image'
|
import { Image } from '../atoms/Image'
|
||||||
import { Post } from '../../@types/Post'
|
import { Post } from '../../@types/Post'
|
||||||
import PostTitle from '../templates/Post/Title'
|
import PostTitle from '../templates/Post/Title'
|
||||||
import * as styles from './PostTeaser.module.css'
|
import {
|
||||||
|
post as stylePost,
|
||||||
|
empty,
|
||||||
|
title as styleTitle
|
||||||
|
} from './PostTeaser.module.css'
|
||||||
|
|
||||||
export const postTeaserQuery = graphql`
|
export const postTeaserQuery = graphql`
|
||||||
fragment PostTeaser on MarkdownRemark {
|
fragment PostTeaser on MarkdownRemark {
|
||||||
@ -42,21 +46,24 @@ export default function PostTeaser({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
className={styles.post}
|
className={stylePost}
|
||||||
to={slug}
|
to={slug}
|
||||||
onClick={toggleSearch && toggleSearch}
|
onClick={toggleSearch && toggleSearch}
|
||||||
>
|
>
|
||||||
{image ? (
|
{image ? (
|
||||||
<Image image={image} alt={title} />
|
<Image
|
||||||
|
image={(image as any).childImageSharp.gatsbyImageData}
|
||||||
|
alt={title}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<span className={styles.empty} />
|
<span className={empty} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<PostTitle
|
<PostTitle
|
||||||
title={title}
|
title={title}
|
||||||
date={hideDate ? null : date}
|
date={hideDate ? null : date}
|
||||||
updated={updated}
|
updated={updated}
|
||||||
className={styles.title}
|
className={styleTitle}
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import useDarkMode from 'use-dark-mode'
|
import { themeSwitch, checkbox, label } from './ThemeSwitch.module.css'
|
||||||
import * as styles from './ThemeSwitch.module.css'
|
|
||||||
import Icon from '../atoms/Icon'
|
import Icon from '../atoms/Icon'
|
||||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
import useDarkMode from '../../hooks/useDarkMode'
|
||||||
|
|
||||||
const ThemeToggleInput = ({
|
const ThemeToggleInput = ({
|
||||||
isDark,
|
isDark,
|
||||||
toggleDark
|
toggleDark
|
||||||
}: {
|
}: {
|
||||||
isDark: boolean
|
isDark: boolean
|
||||||
toggleDark(): void
|
toggleDark: () => void
|
||||||
}) => (
|
}) => (
|
||||||
<input
|
<input
|
||||||
onChange={toggleDark}
|
onChange={() => toggleDark()}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="toggle"
|
name="toggle"
|
||||||
value="toggle"
|
value="toggle"
|
||||||
@ -22,8 +21,15 @@ const ThemeToggleInput = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
const HeadMarkup = ({ themeColor }: { themeColor: string }) => (
|
const HeadMarkup = ({
|
||||||
|
bodyClass,
|
||||||
|
themeColor
|
||||||
|
}: {
|
||||||
|
bodyClass: string
|
||||||
|
themeColor: string
|
||||||
|
}) => (
|
||||||
<Helmet>
|
<Helmet>
|
||||||
|
<body className={bodyClass} />
|
||||||
<meta name="theme-color" content={themeColor} />
|
<meta name="theme-color" content={themeColor} />
|
||||||
<meta
|
<meta
|
||||||
name="apple-mobile-web-app-status-bar-style"
|
name="apple-mobile-web-app-status-bar-style"
|
||||||
@ -33,28 +39,30 @@ const HeadMarkup = ({ themeColor }: { themeColor: string }) => (
|
|||||||
)
|
)
|
||||||
|
|
||||||
export default function ThemeSwitch(): ReactElement {
|
export default function ThemeSwitch(): ReactElement {
|
||||||
const { darkModeConfig } = useSiteMetadata()
|
const { value, toggle } = useDarkMode()
|
||||||
const darkMode = useDarkMode(false, darkModeConfig)
|
const [themeColor, setThemeColor] = useState('')
|
||||||
const themeColor = darkMode.value ? '#1d2224' : '#e7eef4'
|
const [bodyClass, setBodyClass] = useState('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setBodyClass(value ? 'dark' : null)
|
||||||
|
setThemeColor(value ? '#1d2224' : '#e7eef4')
|
||||||
|
}, [value])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeadMarkup themeColor={themeColor} />
|
<HeadMarkup themeColor={themeColor} bodyClass={bodyClass} />
|
||||||
<aside className={styles.themeSwitch} title="Toggle Dark Mode">
|
<aside className={themeSwitch} title="Toggle Dark Mode">
|
||||||
<label
|
<label
|
||||||
htmlFor="toggle"
|
htmlFor="toggle"
|
||||||
className={styles.checkbox}
|
className={checkbox}
|
||||||
onClick={darkMode.toggle}
|
onClick={toggle}
|
||||||
onKeyPress={darkMode.toggle}
|
onKeyPress={toggle}
|
||||||
role="presentation"
|
role="presentation"
|
||||||
>
|
>
|
||||||
<span className={styles.label}>Toggle Dark Mode</span>
|
<span className={label}>Toggle Dark Mode</span>
|
||||||
<ThemeToggleInput
|
<ThemeToggleInput isDark={value} toggleDark={toggle} />
|
||||||
isDark={darkMode.value}
|
|
||||||
toggleDark={darkMode.toggle}
|
|
||||||
/>
|
|
||||||
<div aria-live="assertive">
|
<div aria-live="assertive">
|
||||||
{darkMode.value ? <Icon name="Sun" /> : <Icon name="Moon" />}
|
{value ? <Icon name="Sun" /> : <Icon name="Moon" />}
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</aside>
|
</aside>
|
||||||
|
@ -3,19 +3,19 @@ import { graphql, Link, PageProps } from 'gatsby'
|
|||||||
import Page from './Page'
|
import Page from './Page'
|
||||||
import { Post, PageContext } from '../../@types/Post'
|
import { Post, PageContext } from '../../@types/Post'
|
||||||
import { Image } from '../atoms/Image'
|
import { Image } from '../atoms/Image'
|
||||||
import * as styles from './Photos.module.css'
|
import { photo as stylePhoto, photos as stylePhotos } from './Photos.module.css'
|
||||||
import Pagination from '../molecules/Pagination'
|
import Pagination from '../molecules/Pagination'
|
||||||
|
|
||||||
export const PhotoThumb = ({ photo }: { photo: Post }): ReactElement => {
|
export const PhotoThumb = ({ photo }: { photo: Post }): ReactElement => {
|
||||||
const { title, image } = photo.frontmatter
|
const { title, image } = photo.frontmatter
|
||||||
const { slug } = photo.fields
|
const { slug } = photo.fields
|
||||||
const { fluid } = image.childImageSharp
|
const { gatsbyImageData } = (image as any).childImageSharp
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={styles.photo}>
|
<article className={stylePhoto}>
|
||||||
{image && (
|
{image && (
|
||||||
<Link to={slug}>
|
<Link to={slug}>
|
||||||
<Image title={title} fluid={fluid} alt={title} />
|
<Image title={title} image={gatsbyImageData} alt={title} />
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
</article>
|
</article>
|
||||||
@ -55,7 +55,7 @@ export default function Photos(props: PhotosPageProps): ReactElement {
|
|||||||
post={page}
|
post={page}
|
||||||
pathname={props.location.pathname}
|
pathname={props.location.pathname}
|
||||||
>
|
>
|
||||||
<section className={styles.photos}>
|
<section className={stylePhotos}>
|
||||||
{photos.map(({ node }: { node: Post }) => (
|
{photos.map(({ node }: { node: Post }) => (
|
||||||
<PhotoThumb key={node.id} photo={node} />
|
<PhotoThumb key={node.id} photo={node} />
|
||||||
))}
|
))}
|
||||||
|
@ -53,7 +53,7 @@ export default function Post({
|
|||||||
{image && (
|
{image && (
|
||||||
<Image
|
<Image
|
||||||
className={styles.image}
|
className={styles.image}
|
||||||
fluid={image.childImageSharp.fluid}
|
image={(image as any).childImageSharp.gatsbyImageData}
|
||||||
alt={title}
|
alt={title}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -361,4 +361,5 @@ td {
|
|||||||
|
|
||||||
.gatsby-image-wrapper {
|
.gatsby-image-wrapper {
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,6 @@ const query = graphql`
|
|||||||
jsonfeed
|
jsonfeed
|
||||||
itemsPerPage
|
itemsPerPage
|
||||||
repoContentPath
|
repoContentPath
|
||||||
darkModeConfig {
|
|
||||||
classNameDark
|
|
||||||
classNameLight
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
62
src/hooks/useDarkMode.ts
Normal file
62
src/hooks/useDarkMode.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// 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(): {
|
||||||
|
value: boolean
|
||||||
|
toggle?: () => void
|
||||||
|
} {
|
||||||
|
const [darkMode, setDarkMode] = useState(getDarkMode)
|
||||||
|
|
||||||
|
function toggleDarkMode() {
|
||||||
|
setDarkMode(!darkMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle system theme change events
|
||||||
|
//
|
||||||
|
const handleChange = useCallback(() => {
|
||||||
|
setDarkMode(getDarkMode())
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isClient) return
|
||||||
|
|
||||||
|
const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
|
||||||
|
try {
|
||||||
|
darkModeQuery.addEventListener('change', handleChange)
|
||||||
|
} catch (addEventListenerError) {
|
||||||
|
console.error(addEventListenerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
window
|
||||||
|
.matchMedia('(prefers-color-scheme: dark)')
|
||||||
|
.removeEventListener('change', handleChange)
|
||||||
|
}, [handleChange])
|
||||||
|
|
||||||
|
return { value: darkMode, toggle: toggleDarkMode }
|
||||||
|
}
|
@ -5,21 +5,21 @@ import SEO from '../components/atoms/SEO'
|
|||||||
import PostTeaser from '../components/molecules/PostTeaser'
|
import PostTeaser from '../components/molecules/PostTeaser'
|
||||||
import { PhotoThumb } from '../components/templates/Photos'
|
import { PhotoThumb } from '../components/templates/Photos'
|
||||||
import PostMore from '../components/templates/Post/More'
|
import PostMore from '../components/templates/Post/More'
|
||||||
import * as styles from './index.module.css'
|
import { section, articles, articlesLast, photos } from './index.module.css'
|
||||||
|
|
||||||
export default function Home({ data }: PageProps): ReactElement {
|
export default function Home({ data }: PageProps): ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SEO />
|
<SEO />
|
||||||
<section className={styles.section}>
|
<section className={section}>
|
||||||
<div className={styles.articles}>
|
<div className={articles}>
|
||||||
{(data as any).latestArticles.edges
|
{(data as any).latestArticles.edges
|
||||||
.slice(0, 2)
|
.slice(0, 2)
|
||||||
.map(({ node }: { node: Post }) => (
|
.map(({ node }: { node: Post }) => (
|
||||||
<PostTeaser key={node.id} post={node} hideDate />
|
<PostTeaser key={node.id} post={node} hideDate />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className={`${styles.articles} ${styles.articlesLast}`}>
|
<div className={`${articles} ${articlesLast}`}>
|
||||||
{(data as any).latestArticles.edges
|
{(data as any).latestArticles.edges
|
||||||
.slice(2, 8)
|
.slice(2, 8)
|
||||||
.map(({ node }: { node: Post }) => (
|
.map(({ node }: { node: Post }) => (
|
||||||
@ -30,8 +30,8 @@ export default function Home({ data }: PageProps): ReactElement {
|
|||||||
<PostMore to="/archive">All Articles</PostMore>
|
<PostMore to="/archive">All Articles</PostMore>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className={styles.section}>
|
<section className={section}>
|
||||||
<div className={styles.photos}>
|
<div className={photos}>
|
||||||
{(data as any).latestPhotos.edges.map(({ node }: { node: Post }) => (
|
{(data as any).latestPhotos.edges.map(({ node }: { node: Post }) => (
|
||||||
<PhotoThumb key={node.id} photo={node} />
|
<PhotoThumb key={node.id} photo={node} />
|
||||||
))}
|
))}
|
||||||
|
Loading…
Reference in New Issue
Block a user