Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 33 additions & 18 deletions components/toggleDarkMode.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
import { useState } from 'react';
import { useCallback, useEffect, useState } from 'react';

import { MoonIcon, SunIcon } from './icons';

export const LIGHTS_OUT = 'lights-out';

export default function ToggleDarkMode({ className }: { className?: string }) {
const [isDarkMode, setDarkMode] = useState(false);

const handleClick = () => {
const hasDarkMode = document.documentElement.hasAttribute(LIGHTS_OUT);

return toggleDarkMode(!hasDarkMode);
};

const toggleDarkMode = (shouldBeDark) => {
document.documentElement.toggleAttribute(LIGHTS_OUT, shouldBeDark);

setDarkMode(shouldBeDark);
const [isDarkMode, setIsDarkMode] = useState(
globalThis.localStorage &&
globalThis.localStorage.getItem(LIGHTS_OUT) === 'true'
);
useEffect(() => {
const mq = window.matchMedia('(prefers-color-scheme: dark)');

writeToStorage(shouldBeDark);
};
if (mq.matches) {
setIsDarkMode(true);
}

const writeToStorage = (prefersDark) => {
localStorage.setItem(LIGHTS_OUT, prefersDark ? 'true' : 'false');
};
// This callback will fire if the preferred color scheme changes without a reload
mq.addEventListener('change', (evt) => setIsDarkMode(evt.matches));
}, []);
useEffect(() => {
console.log('isDarkMode changed!', isDarkMode);
if (isDarkMode) {
globalThis.document.documentElement.dataset.theme = 'dark';
} else {
globalThis.document.documentElement.dataset.theme = null;
}
}, [isDarkMode]);
const handleClick = useCallback(() => {
setIsDarkMode((wasDarkMode) => {
if (wasDarkMode) {
globalThis.localStorage.removeItem(LIGHTS_OUT);
} else {
globalThis.localStorage.setItem(LIGHTS_OUT, 'true');
}
return !wasDarkMode;
});
}, []);
return (
<button
className={className}
Expand Down
6 changes: 6 additions & 0 deletions pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Html, Head, Main, NextScript } from 'next/document';
// eslint-disable-next-line @next/next/no-script-in-document
import Script from 'next/script';

export default function Document() {
return (
<Html lang="uk-UA">
<Head>
<Script
src="../utils/apply-dark-mode.ts"
strategy="beforeInteractive"
/>
<script
dangerouslySetInnerHTML={{
__html:
Expand Down
18 changes: 18 additions & 0 deletions utils/apply-dark-mode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const LIGHTS_OUT = 'lights-out';
const theme =
globalThis.localStorage && globalThis.localStorage.getItem(LIGHTS_OUT);

if (theme === 'true') {
document.documentElement.dataset.theme = 'dark';
} else {
document.documentElement.dataset.theme = null;
}

if (
window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches
) {
document.documentElement.dataset.theme = 'dark';
} else {
document.documentElement.dataset.theme = null;
}