Skip to content

Instantly share code, notes, and snippets.

@brycedorn
Last active July 23, 2022 10:35
Show Gist options
  • Save brycedorn/8bab2f480ebbbf6d21d5999db4e78dba to your computer and use it in GitHub Desktop.
Save brycedorn/8bab2f480ebbbf6d21d5999db4e78dba to your computer and use it in GitHub Desktop.
deno/fresh useDarkMode hook with inter-island sync
import { IS_BROWSER } from '$fresh/runtime.ts';
import { useState, useEffect } from 'preact/hooks';
export default function useDarkMode() {
const [dark, setDark] = useState(IS_BROWSER && document.body.classList.contains('dark'));
// Explicit toggle action
function toggleDarkMode(save: boolean) {
const prefersDark = document.body.classList.toggle('dark');
setDark(prefersDark);
if (save) {
localStorage.setItem('prefers-dark', prefersDark);
window.dispatchEvent(new Event('dark-mode-preference-updated'));
}
}
// Triggered externally
function respondToEvent() {
const prefersDark = document.body.classList.contains('dark');
setDark(prefersDark);
}
// On load
useEffect(() => {
const prefersDark = localStorage.getItem('prefers-dark') === 'true';
if ((prefersDark === null || prefersDark) && window.matchMedia('(prefers-color-scheme: dark)').matches) {
if (!document.body.classList.contains('dark')) {
toggleDarkMode();
} else if (!dark) {
setDark(true);
}
}
window.addEventListener('dark-mode-preference-updated', respondToEvent);
return () => {
window.removeEventListener('dark-mode-preference-updated');
};
}, []);
return [dark, toggleDarkMode];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment