26 lines
726 B
TypeScript
26 lines
726 B
TypeScript
import { useCallback, useSyncExternalStore } from 'react';
|
|
|
|
function getTheme(): 'dark' | 'light' {
|
|
return document.documentElement.classList.contains('dark') ? 'dark' : 'light';
|
|
}
|
|
|
|
const listeners = new Set<() => void>();
|
|
|
|
function subscribe(listener: () => void) {
|
|
listeners.add(listener);
|
|
return () => listeners.delete(listener);
|
|
}
|
|
|
|
export function useTheme() {
|
|
const theme = useSyncExternalStore(subscribe, getTheme);
|
|
|
|
const toggleTheme = useCallback(() => {
|
|
const next = getTheme() === 'dark' ? 'light' : 'dark';
|
|
document.documentElement.classList.toggle('dark', next === 'dark');
|
|
localStorage.setItem('theme', next);
|
|
listeners.forEach((l) => l());
|
|
}, []);
|
|
|
|
return { theme, toggleTheme };
|
|
}
|