Files
fotospiel-app/resources/js/hooks/use-appearance.ts

69 lines
2.1 KiB
TypeScript

import { useEffect, useState } from 'react';
export type Appearance = 'light' | 'dark' | 'system';
export function useAppearance(): { appearance: Appearance; updateAppearance: (mode: Appearance) => void } {
const [appearance, setAppearance] = useState<Appearance>('system');
useEffect(() => {
const stored = localStorage.getItem('theme') as Appearance | null;
if (stored) {
setAppearance(stored);
} else {
setAppearance('system');
}
}, []);
const updateAppearance = (mode: Appearance) => {
setAppearance(mode);
localStorage.setItem('theme', mode);
if (mode === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
};
useEffect(() => {
if (appearance === 'system') {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
if (mediaQuery.matches) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
const listener = (e: MediaQueryListEvent) => {
if (e.matches) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
};
mediaQuery.addEventListener('change', listener);
return () => mediaQuery.removeEventListener('change', listener);
} else if (appearance === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}, [appearance]);
return { appearance, updateAppearance };
}
export function initializeTheme() {
const stored = localStorage.getItem('theme') as Appearance | null;
if (stored) {
if (stored === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
} else {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
if (mediaQuery.matches) {
document.documentElement.classList.add('dark');
}
}
}