61 lines
1.8 KiB
JavaScript
61 lines
1.8 KiB
JavaScript
import { useEffect, useState } from 'react';
|
|
|
|
export function useTheme() {
|
|
const [theme, setTheme] = useState('system');
|
|
const [isDark, setIsDark] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// Get theme from session storage or default to system
|
|
const savedTheme = sessionStorage.getItem('theme') || 'system';
|
|
setTheme(savedTheme);
|
|
|
|
const updateTheme = (themeValue) => {
|
|
const root = document.documentElement;
|
|
|
|
if (themeValue === 'system') {
|
|
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
setIsDark(systemPrefersDark);
|
|
root.classList.toggle('dark', systemPrefersDark);
|
|
} else {
|
|
const shouldBeDark = themeValue === 'dark';
|
|
setIsDark(shouldBeDark);
|
|
root.classList.toggle('dark', shouldBeDark);
|
|
}
|
|
};
|
|
|
|
// Apply initial theme
|
|
updateTheme(savedTheme);
|
|
|
|
// Listen for system theme changes when using system theme
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
const handleSystemThemeChange = () => {
|
|
if (theme === 'system') {
|
|
updateTheme('system');
|
|
}
|
|
};
|
|
|
|
mediaQuery.addEventListener('change', handleSystemThemeChange);
|
|
|
|
return () => {
|
|
mediaQuery.removeEventListener('change', handleSystemThemeChange);
|
|
};
|
|
}, [theme]);
|
|
|
|
const toggleTheme = () => {
|
|
const newTheme = isDark ? 'light' : 'dark';
|
|
setTheme(newTheme);
|
|
sessionStorage.setItem('theme', newTheme);
|
|
};
|
|
|
|
const resetToSystem = () => {
|
|
setTheme('system');
|
|
sessionStorage.removeItem('theme');
|
|
};
|
|
|
|
return {
|
|
theme,
|
|
isDark,
|
|
toggleTheme,
|
|
resetToSystem,
|
|
};
|
|
} |