一番お手軽だと思われる、gatsby-plugin-dark-mode を使います。
ちなみに現在のモードは localStrage に保存されます。
プラグインインストール
yarn add gatsby-plugin-dark-mode
gatsby-config.js
module.exports = {
plugins: ['gatsby-plugin-dark-mode'],
}
## コンポーネント作成
スイッチするためのコンポーネントを作ります。
toggleTheme()でスイッチするためだけのものなので、必ず新規でコンポーネントを作る必要はありません。
よきところに
C:/src/components/mode.js
import React from 'react'
import { ThemeToggler } from 'gatsby-plugin-dark-mode'
class mode extends React.Component {
render() {
return (
<ThemeToggler>
{({ theme, toggleTheme }) => {
// Don't render anything at compile time. Deferring rendering until we
// know which theme to use on the client avoids incorrect initial
// state being displayed.
if (theme == null) {
return null
}
return (
<label>
<input
type="checkbox"
onChange={e => toggleTheme(e.target.checked ? 'dark' : 'light')}
checked={theme === 'dark'}
/>{' '}
Dark mode
</label>
)
}}
</ThemeToggler>
)
}
}
テーマをつくる
各種定義はいい感じに修正します。
global.css
body {
--bg: white;
--textNormal: #222;
--textTitle: #222;
--textLink: blue;
--hr: hsla(0, 0%, 0%, 0.2);
background-color: var(--bg);
}
body.dark {
-webkit-font-smoothing: antialiased;
--bg: darkslategray;
--textNormal: rgba(255, 255, 255, 0.88);
--textTitle: white;
--textLink: yellow;
--hr: hsla(0, 0%, 100%, 0.2);
}
テーマを適用する
src/components/layout.js
class Layout extends React.Component {
render() {
return (
<div
style={{
backgroundColor: 'var(--bg)',
color: 'var(--textNormal)',
transition: 'color 0.2s ease-out, background 0.2s ease-out',
}}
>
...
</div>
)
}
}
typography を導入していた場合、そこにダークモードを適用の仕方はこんな感じ。
src/utils/Typography.js
…
theme.overrideThemeStyles = ({ rhythm }, options) => ({
'h2,h3,h4,h5': {
marginBottom: rhythm(1 / 2),
marginTop: rhythm(2),
},
a: { color: 'var(--textLink)', }, // gatsby-remark-autolink-headers - don't underline when hidden 'a.anchor': { boxShadow: 'none', }, // gatsby-remark-autolink-headers - use theme colours for the link icon 'a.anchor svg[aria-hidden="true"]': { stroke: 'var(--textLink)', }, hr: { background: 'var(--hr)', },})
…