1
0
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:
Matthias Kretschmann 2021-03-13 04:11:44 +01:00
parent 3aa87e0e82
commit 2c171a5ee7
Signed by: m
GPG Key ID: 606EEEF3C479A91F
14 changed files with 1119 additions and 36014 deletions

View File

@ -42,9 +42,5 @@ module.exports = {
title: '/Uses',
link: '/uses'
}
],
darkModeConfig: {
classNameDark: 'dark',
classNameLight: 'light'
}
]
}

View File

@ -220,13 +220,6 @@ module.exports = {
exclude: ['/archive', '/archive/**/*', '/thanks', '/tags']
}
},
{
resolve: 'gatsby-plugin-use-dark-mode',
options: {
...siteConfig.darkModeConfig,
minify: true
}
},
'gatsby-plugin-react-helmet',
'gatsby-plugin-catch-links',
'gatsby-redirect-from',

36905
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -29,32 +29,31 @@
"not op_mini all"
],
"dependencies": {
"@ethersproject/providers": "^5.0.23",
"@ethersproject/units": "^5.0.10",
"@ethersproject/providers": "^5.0.24",
"@ethersproject/units": "^5.0.11",
"@loadable/component": "^5.14.1",
"@web3-react/core": "^6.1.9",
"@web3-react/injected-connector": "^6.0.7",
"classnames": "^2.2.6",
"date-fns": "^2.17.0",
"date-fns": "^2.19.0",
"dms2dec": "^1.1.0",
"ethereum-blockies": "github:MyEtherWallet/blockies",
"fast-exif": "^1.0.1",
"feather-icons": "^4.28.0",
"fraction.js": "^4.0.13",
"gatsby": "^3.0.3",
"gatsby": "^3.0.4",
"gatsby-plugin-catch-links": "^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-manifest": "^3.0.0",
"gatsby-plugin-matomo": "^0.9.0",
"gatsby-plugin-meta-redirect": "^1.1.1",
"gatsby-plugin-offline": "^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-svgr": "^3.0.0-beta.0",
"gatsby-plugin-use-dark-mode": "^1.3.0",
"gatsby-plugin-webpack-size": "^1.0.0",
"gatsby-redirect-from": "^0.3.0",
"gatsby-remark-autolink-headers": "^3.0.0",
@ -80,29 +79,28 @@
"react-transition-group": "^4.4.1",
"remark": "^13.0.0",
"remark-react": "^8.0.0",
"slugify": "^1.4.7",
"use-dark-mode": "^2.3.1"
"slugify": "^1.4.7"
},
"devDependencies": {
"@svgr/webpack": "^5.5.0",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@types/classnames": "^2.2.11",
"@types/fs-extra": "^9.0.7",
"@types/fs-extra": "^9.0.8",
"@types/jest": "^26.0.20",
"@types/loadable__component": "^5.13.3",
"@types/lunr": "^2.3.3",
"@types/node": "^14.14.28",
"@types/node": "^14.14.34",
"@types/node-fetch": "^2.5.8",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"@types/react": "^17.0.3",
"@types/react-dom": "^17.0.2",
"@types/react-helmet": "^6.1.0",
"@types/react-transition-group": "^4.4.0",
"@types/shortid": "^0.0.29",
"@typescript-eslint/eslint-plugin": "^4.15.2",
"@typescript-eslint/parser": "^4.15.2",
"@welldone-software/why-did-you-render": "^6.0.5",
"eslint": "^7.21.0",
"@typescript-eslint/eslint-plugin": "^4.17.0",
"@typescript-eslint/parser": "^4.17.0",
"@welldone-software/why-did-you-render": "^6.1.0",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-graphql": "^4.0.0",
"eslint-plugin-jsx-a11y": "^6.4.1",
@ -110,23 +108,23 @@
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-testing-library": "^3.10.1",
"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",
"jest": "^26.6.3",
"markdownlint-cli": "^0.26.0",
"node-iptc": "^1.0.5",
"npm-run-all": "^4.1.5",
"ora": "^5.3.0",
"postcss": "^8.2.7",
"postcss": "^8.2.8",
"prettier": "^2.2.1",
"shortid": "^2.2.16",
"stylelint": "^13.11.0",
"stylelint": "^13.12.0",
"stylelint-config-css-modules": "^2.2.0",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-standard": "^20.0.0",
"stylelint-prettier": "^1.2.0",
"ts-node": "^9.1.1",
"typescript": "^4.2.2"
"typescript": "^4.2.3"
},
"repository": {
"type": "git",

View File

@ -1,7 +1,7 @@
import React, { ReactElement, useState } from 'react'
import Map from 'pigeon-maps'
import Marker from 'pigeon-marker'
import useDarkMode from 'use-dark-mode'
import useDarkMode from '../../hooks/useDarkMode'
const mapbox = (mapboxId: string) => (
x: string,
@ -23,10 +23,7 @@ export default function ExifMap({
}: {
gps: { latitude: string; longitude: string }
}): ReactElement {
const { value } = useDarkMode(false, {
classNameDark: 'dark',
classNameLight: 'light'
})
const { value } = useDarkMode()
const isDarkMode = value
const [zoom, setZoom] = useState(12)

View File

@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
import { graphql } from 'gatsby'
import { GatsbyImage } from 'gatsby-plugin-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 = ({
title,
@ -12,11 +12,11 @@ export const Image = ({
className
}: ImageProps): ReactElement => (
<figure
className={`${styles.image} ${className ? className : ''}`}
data-original={original && original.src}
className={`${styleImage} ${className ? className : ''}`}
data-original={original?.src}
>
<GatsbyImage backgroundColor="transparent" image={image} alt={alt} />
{title && <figcaption className={styles.imageTitle}>{title}</figcaption>}
<GatsbyImage backgroundColor="transparent" image={image} alt={alt} />
{title && <figcaption className={imageTitle}>{title}</figcaption>}
</figure>
)

View File

@ -3,7 +3,11 @@ import { Link, graphql } from 'gatsby'
import { Image } from '../atoms/Image'
import { Post } from '../../@types/Post'
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`
fragment PostTeaser on MarkdownRemark {
@ -42,21 +46,24 @@ export default function PostTeaser({
return (
<Link
className={styles.post}
className={stylePost}
to={slug}
onClick={toggleSearch && toggleSearch}
>
{image ? (
<Image image={image} alt={title} />
<Image
image={(image as any).childImageSharp.gatsbyImageData}
alt={title}
/>
) : (
<span className={styles.empty} />
<span className={empty} />
)}
<PostTitle
title={title}
date={hideDate ? null : date}
updated={updated}
className={styles.title}
className={styleTitle}
/>
</Link>
)

View File

@ -1,19 +1,18 @@
import React, { ReactElement } from 'react'
import React, { ReactElement, useEffect, useState } from 'react'
import { Helmet } from 'react-helmet'
import useDarkMode from 'use-dark-mode'
import * as styles from './ThemeSwitch.module.css'
import { themeSwitch, checkbox, label } from './ThemeSwitch.module.css'
import Icon from '../atoms/Icon'
import { useSiteMetadata } from '../../hooks/use-site-metadata'
import useDarkMode from '../../hooks/useDarkMode'
const ThemeToggleInput = ({
isDark,
toggleDark
}: {
isDark: boolean
toggleDark(): void
toggleDark: () => void
}) => (
<input
onChange={toggleDark}
onChange={() => toggleDark()}
type="checkbox"
name="toggle"
value="toggle"
@ -22,8 +21,15 @@ const ThemeToggleInput = ({
/>
)
const HeadMarkup = ({ themeColor }: { themeColor: string }) => (
const HeadMarkup = ({
bodyClass,
themeColor
}: {
bodyClass: string
themeColor: string
}) => (
<Helmet>
<body className={bodyClass} />
<meta name="theme-color" content={themeColor} />
<meta
name="apple-mobile-web-app-status-bar-style"
@ -33,28 +39,30 @@ const HeadMarkup = ({ themeColor }: { themeColor: string }) => (
)
export default function ThemeSwitch(): ReactElement {
const { darkModeConfig } = useSiteMetadata()
const darkMode = useDarkMode(false, darkModeConfig)
const themeColor = darkMode.value ? '#1d2224' : '#e7eef4'
const { value, toggle } = useDarkMode()
const [themeColor, setThemeColor] = useState('')
const [bodyClass, setBodyClass] = useState('')
useEffect(() => {
setBodyClass(value ? 'dark' : null)
setThemeColor(value ? '#1d2224' : '#e7eef4')
}, [value])
return (
<>
<HeadMarkup themeColor={themeColor} />
<aside className={styles.themeSwitch} title="Toggle Dark Mode">
<HeadMarkup themeColor={themeColor} bodyClass={bodyClass} />
<aside className={themeSwitch} title="Toggle Dark Mode">
<label
htmlFor="toggle"
className={styles.checkbox}
onClick={darkMode.toggle}
onKeyPress={darkMode.toggle}
className={checkbox}
onClick={toggle}
onKeyPress={toggle}
role="presentation"
>
<span className={styles.label}>Toggle Dark Mode</span>
<ThemeToggleInput
isDark={darkMode.value}
toggleDark={darkMode.toggle}
/>
<span className={label}>Toggle Dark Mode</span>
<ThemeToggleInput isDark={value} toggleDark={toggle} />
<div aria-live="assertive">
{darkMode.value ? <Icon name="Sun" /> : <Icon name="Moon" />}
{value ? <Icon name="Sun" /> : <Icon name="Moon" />}
</div>
</label>
</aside>

View File

@ -3,19 +3,19 @@ import { graphql, Link, PageProps } from 'gatsby'
import Page from './Page'
import { Post, PageContext } from '../../@types/Post'
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'
export const PhotoThumb = ({ photo }: { photo: Post }): ReactElement => {
const { title, image } = photo.frontmatter
const { slug } = photo.fields
const { fluid } = image.childImageSharp
const { gatsbyImageData } = (image as any).childImageSharp
return (
<article className={styles.photo}>
<article className={stylePhoto}>
{image && (
<Link to={slug}>
<Image title={title} fluid={fluid} alt={title} />
<Image title={title} image={gatsbyImageData} alt={title} />
</Link>
)}
</article>
@ -55,7 +55,7 @@ export default function Photos(props: PhotosPageProps): ReactElement {
post={page}
pathname={props.location.pathname}
>
<section className={styles.photos}>
<section className={stylePhotos}>
{photos.map(({ node }: { node: Post }) => (
<PhotoThumb key={node.id} photo={node} />
))}

View File

@ -53,7 +53,7 @@ export default function Post({
{image && (
<Image
className={styles.image}
fluid={image.childImageSharp.fluid}
image={(image as any).childImageSharp.gatsbyImageData}
alt={title}
/>
)}

View File

@ -361,4 +361,5 @@ td {
.gatsby-image-wrapper {
max-height: 100vh;
display: block;
}

View File

@ -28,10 +28,6 @@ const query = graphql`
jsonfeed
itemsPerPage
repoContentPath
darkModeConfig {
classNameDark
classNameLight
}
}
}
}

62
src/hooks/useDarkMode.ts Normal file
View 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 }
}

View File

@ -5,21 +5,21 @@ import SEO from '../components/atoms/SEO'
import PostTeaser from '../components/molecules/PostTeaser'
import { PhotoThumb } from '../components/templates/Photos'
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 {
return (
<>
<SEO />
<section className={styles.section}>
<div className={styles.articles}>
<section className={section}>
<div className={articles}>
{(data as any).latestArticles.edges
.slice(0, 2)
.map(({ node }: { node: Post }) => (
<PostTeaser key={node.id} post={node} hideDate />
))}
</div>
<div className={`${styles.articles} ${styles.articlesLast}`}>
<div className={`${articles} ${articlesLast}`}>
{(data as any).latestArticles.edges
.slice(2, 8)
.map(({ node }: { node: Post }) => (
@ -30,8 +30,8 @@ export default function Home({ data }: PageProps): ReactElement {
<PostMore to="/archive">All Articles</PostMore>
</section>
<section className={styles.section}>
<div className={styles.photos}>
<section className={section}>
<div className={photos}>
{(data as any).latestPhotos.edges.map(({ node }: { node: Post }) => (
<PhotoThumb key={node.id} photo={node} />
))}