Skip to content

Commit 5ba0ad8

Browse files
harish-sethuramangaearon
harish-sethuraman
andauthored
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>
1 parent a803dbf commit 5ba0ad8

File tree

2 files changed

+94
-38
lines changed

2 files changed

+94
-38
lines changed

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

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ import {MenuContext} from 'components/useMenu';
1515
import {Logo} from '../../Logo';
1616
import NavLink from './NavLink';
1717

18+
declare global {
19+
interface Window {
20+
__theme: string;
21+
__setPreferredTheme: (theme: string) => void;
22+
}
23+
}
24+
1825
const feedbackIcon = (
1926
<svg
2027
xmlns="http://www.w3.org/2000/svg"
@@ -92,14 +99,6 @@ function inferSection(pathname: string): 'learn' | 'reference' | 'home' {
9299
export default function Nav() {
93100
const {pathname} = useRouter();
94101
const {isOpen, toggleOpen} = React.useContext(MenuContext);
95-
// TODO: persist
96-
// TODO: respect system pref
97-
const [isDark, setIsDark] = React.useState(() => {
98-
if (typeof document === 'undefined') {
99-
return false;
100-
}
101-
return document.documentElement.classList.contains('dark');
102-
});
103102
const section = inferSection(pathname);
104103

105104
function handleFeedback() {
@@ -137,21 +136,28 @@ export default function Nav() {
137136
Beta
138137
</div>
139138
</div>
140-
<button
141-
type="button"
142-
aria-label={isDark ? 'Use Light Mode' : 'Use Dark Mode'}
143-
onClick={() => {
144-
if (isDark) {
145-
document.documentElement.classList.remove('dark');
146-
setIsDark(false);
147-
} else {
148-
document.documentElement.classList.add('dark');
149-
setIsDark(true);
150-
}
151-
}}
152-
className="hidden lg:flex items-center h-full pr-2">
153-
{isDark ? lightIcon : darkIcon}
154-
</button>
139+
<div className="block dark:hidden">
140+
<button
141+
type="button"
142+
aria-label="Use Dark Mode"
143+
onClick={() => {
144+
window.__setPreferredTheme('dark');
145+
}}
146+
className="hidden lg:flex items-center h-full pr-2">
147+
{darkIcon}
148+
</button>
149+
</div>
150+
<div className="hidden dark:block">
151+
<button
152+
type="button"
153+
aria-label="Use Light Mode"
154+
onClick={() => {
155+
window.__setPreferredTheme('light');
156+
}}
157+
className="hidden lg:flex items-center h-full pr-2">
158+
{lightIcon}
159+
</button>
160+
</div>
155161
</div>
156162
<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">
157163
<NavLink href="/" isActive={section === 'home'}>
@@ -172,21 +178,28 @@ export default function Nav() {
172178
onClick={handleFeedback}>
173179
{feedbackIcon}
174180
</button>
175-
<button
176-
type="button"
177-
aria-label={isDark ? 'Use Light Mode' : 'Use Dark Mode'}
178-
onClick={() => {
179-
if (isDark) {
180-
document.documentElement.classList.remove('dark');
181-
setIsDark(false);
182-
} else {
183-
document.documentElement.classList.add('dark');
184-
setIsDark(true);
185-
}
186-
}}
187-
className="flex lg:hidden items-center p-1 h-full ml-4 lg:ml-6">
188-
{isDark ? lightIcon : darkIcon}
189-
</button>
181+
<div className="block dark:hidden">
182+
<button
183+
type="button"
184+
aria-label="Use Dark Mode"
185+
onClick={() => {
186+
window.__setPreferredTheme('dark');
187+
}}
188+
className="flex lg:hidden items-center p-1 h-full ml-4 lg:ml-6">
189+
{darkIcon}
190+
</button>
191+
</div>
192+
<div className="hidden dark:block">
193+
<button
194+
type="button"
195+
aria-label="Use Light Mode"
196+
onClick={() => {
197+
window.__setPreferredTheme('light');
198+
}}
199+
className="flex lg:hidden items-center p-1 h-full ml-4 lg:ml-6">
200+
{lightIcon}
201+
</button>
202+
</div>
190203
</div>
191204
</nav>
192205
);

beta/src/pages/_document.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,49 @@ class MyDocument extends Document {
1212
<Html lang="en">
1313
<Head />
1414
<body className="font-sans antialiased text-lg bg-wash dark:bg-wash-dark text-secondary dark:text-secondary-dark leading-base">
15+
<script
16+
dangerouslySetInnerHTML={{
17+
__html: `
18+
(function () {
19+
function setTheme(newTheme) {
20+
window.__theme = newTheme;
21+
if (newTheme === 'dark') {
22+
document.documentElement.classList.add('dark');
23+
} else if (newTheme === 'light') {
24+
document.documentElement.classList.remove('dark');
25+
}
26+
}
27+
28+
var preferredTheme;
29+
try {
30+
preferredTheme = localStorage.getItem('theme');
31+
} catch (err) { }
32+
33+
window.__setPreferredTheme = function(newTheme) {
34+
preferredTheme = newTheme;
35+
setTheme(newTheme);
36+
try {
37+
localStorage.setItem('theme', newTheme);
38+
} catch (err) { }
39+
};
40+
41+
var initialTheme = preferredTheme;
42+
var darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
43+
44+
if (!initialTheme) {
45+
initialTheme = darkQuery.matches ? 'dark' : 'light';
46+
}
47+
setTheme(initialTheme);
48+
49+
darkQuery.addListener(function (e) {
50+
if (!preferredTheme) {
51+
setTheme(e.matches ? 'dark' : 'light');
52+
}
53+
});
54+
})();
55+
`,
56+
}}
57+
/>
1558
<Main />
1659
<NextScript />
1760
</body>

0 commit comments

Comments
 (0)