Package Exports
- gatsby-plugin-dark-mode
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (gatsby-plugin-dark-mode) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
gatsby-plugin-dark-mode
A Gatsby plugin which handles some of the details of implementing a dark mode theme.
It provides:
- Browser code for toggling and persisting the theme (from Dan Abramov's overreacted.io implementation)
- Automatic use of a dark mode theme (via the
prefers-color-schemeCSS media query) if you've configured your system to use dark colour themes when available. - A React component for implementing theme toggling UI in your site.
Install
npm install gatsby-plugin-dark-mode// gatsby-config.js
module.exports = {
plugins: ['gatsby-plugin-dark-mode'],
}How to use
Implement theme toggling UI
The plugin module exports a ThemeToggler component which takes a children render prop, providing the current theme name and a toggleTheme function to change the theme.
Here's an example of using ThemeToggler with a checkbox to toggle the theme:
import React from 'react'
import { ThemeToggler } from 'gatsby-plugin-dark-mode'
class MyComponent extends React.Component {
render() {
return (
<ThemeToggler>
{({ theme, toggleTheme }) => (
<label>
<input
type="checkbox"
onChange={e => toggleTheme(e.target.checked ? 'dark' : 'light')}
checked={theme === 'dark'}
/>{' '}
Dark mode
</label>
)}
</ThemeToggler>
)
}
}The toggled theme will be persisted across visits in localStorage.theme.
Implement theming
The default theme names are 'light' and 'dark' - the plugin adds the current theme name to the <body> element's className, so you can use global styles to implement theming.
A nice option is to use CSS variables like so:
/* 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);
}You can then use these variables in your site's components...
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>
)
}
}...and in your Typography config if you're using gatsby-plugin-typography, which is included in the Gatsby Starter Blog:
// typography.js
import './global.css'
import Typography from 'typography'
import Wordpress2016 from 'typography-theme-wordpress-2016'
Wordpress2016.overrideThemeStyles = () => ({
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)',
},
})Acknowledgements
The theme detecting/switching/persistence code and the suggested theming implementation are entirely from the implementation of overreacted.io by Dan Abramov - I'm just publishing them as a plugin to make them easier to use in my own blog, and for reuse by others.