Browse Source

Take system's theme for the beta site (#4022)

* Take system's theme for the site

* Add IIFE for dark mode in document load and preserve in localStorage

* Add types

* Fix SSR and respect override

Co-authored-by: Dan Abramov <dan.abramov@me.com>
main
harish-sethuraman 3 years ago
committed by GitHub
parent
commit
5ba0ad88b8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 89
      beta/src/components/Layout/Nav/Nav.tsx
  2. 43
      beta/src/pages/_document.tsx

89
beta/src/components/Layout/Nav/Nav.tsx

@ -15,6 +15,13 @@ import {MenuContext} from 'components/useMenu';
import {Logo} from '../../Logo';
import NavLink from './NavLink';
declare global {
interface Window {
__theme: string;
__setPreferredTheme: (theme: string) => void;
}
}
const feedbackIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
@ -92,14 +99,6 @@ function inferSection(pathname: string): 'learn' | 'reference' | 'home' {
export default function Nav() {
const {pathname} = useRouter();
const {isOpen, toggleOpen} = React.useContext(MenuContext);
// TODO: persist
// TODO: respect system pref
const [isDark, setIsDark] = React.useState(() => {
if (typeof document === 'undefined') {
return false;
}
return document.documentElement.classList.contains('dark');
});
const section = inferSection(pathname);
function handleFeedback() {
@ -137,21 +136,28 @@ export default function Nav() {
Beta
</div>
</div>
<button
type="button"
aria-label={isDark ? 'Use Light Mode' : 'Use Dark Mode'}
onClick={() => {
if (isDark) {
document.documentElement.classList.remove('dark');
setIsDark(false);
} else {
document.documentElement.classList.add('dark');
setIsDark(true);
}
}}
className="hidden lg:flex items-center h-full pr-2">
{isDark ? lightIcon : darkIcon}
</button>
<div className="block dark:hidden">
<button
type="button"
aria-label="Use Dark Mode"
onClick={() => {
window.__setPreferredTheme('dark');
}}
className="hidden lg:flex items-center h-full pr-2">
{darkIcon}
</button>
</div>
<div className="hidden dark:block">
<button
type="button"
aria-label="Use Light Mode"
onClick={() => {
window.__setPreferredTheme('light');
}}
className="hidden lg:flex items-center h-full pr-2">
{lightIcon}
</button>
</div>
</div>
<div className="px-0 pt-2 w-full 2xl:max-w-xs hidden lg:flex items-center self-center border-b-0 lg:border-b border-border dark:border-border-dark">
<NavLink href="/" isActive={section === 'home'}>
@ -172,21 +178,28 @@ export default function Nav() {
onClick={handleFeedback}>
{feedbackIcon}
</button>
<button
type="button"
aria-label={isDark ? 'Use Light Mode' : 'Use Dark Mode'}
onClick={() => {
if (isDark) {
document.documentElement.classList.remove('dark');
setIsDark(false);
} else {
document.documentElement.classList.add('dark');
setIsDark(true);
}
}}
className="flex lg:hidden items-center p-1 h-full ml-4 lg:ml-6">
{isDark ? lightIcon : darkIcon}
</button>
<div className="block dark:hidden">
<button
type="button"
aria-label="Use Dark Mode"
onClick={() => {
window.__setPreferredTheme('dark');
}}
className="flex lg:hidden items-center p-1 h-full ml-4 lg:ml-6">
{darkIcon}
</button>
</div>
<div className="hidden dark:block">
<button
type="button"
aria-label="Use Light Mode"
onClick={() => {
window.__setPreferredTheme('light');
}}
className="flex lg:hidden items-center p-1 h-full ml-4 lg:ml-6">
{lightIcon}
</button>
</div>
</div>
</nav>
);

43
beta/src/pages/_document.tsx

@ -12,6 +12,49 @@ class MyDocument extends Document {
<Html lang="en">
<Head />
<body className="font-sans antialiased text-lg bg-wash dark:bg-wash-dark text-secondary dark:text-secondary-dark leading-base">
<script
dangerouslySetInnerHTML={{
__html: `
(function () {
function setTheme(newTheme) {
window.__theme = newTheme;
if (newTheme === 'dark') {
document.documentElement.classList.add('dark');
} else if (newTheme === 'light') {
document.documentElement.classList.remove('dark');
}
}
var preferredTheme;
try {
preferredTheme = localStorage.getItem('theme');
} catch (err) { }
window.__setPreferredTheme = function(newTheme) {
preferredTheme = newTheme;
setTheme(newTheme);
try {
localStorage.setItem('theme', newTheme);
} catch (err) { }
};
var initialTheme = preferredTheme;
var darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
if (!initialTheme) {
initialTheme = darkQuery.matches ? 'dark' : 'light';
}
setTheme(initialTheme);
darkQuery.addListener(function (e) {
if (!preferredTheme) {
setTheme(e.matches ? 'dark' : 'light');
}
});
})();
`,
}}
/>
<Main />
<NextScript />
</body>

Loading…
Cancel
Save