color pref persistence
This commit is contained in:
@@ -26,16 +26,39 @@ export function useDarkMode() {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const STORAGE_KEY = "theme-override";
|
||||||
|
|
||||||
|
const getSystemPreference = () => {
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInitialTheme = () => {
|
||||||
|
if (typeof window === "undefined") return false;
|
||||||
|
|
||||||
|
const storedOverride = localStorage.getItem(STORAGE_KEY);
|
||||||
|
if (storedOverride !== null) {
|
||||||
|
return storedOverride === "dark";
|
||||||
|
}
|
||||||
|
return getSystemPreference();
|
||||||
|
};
|
||||||
|
|
||||||
export const DarkModeProvider: ParentComponent = (props) => {
|
export const DarkModeProvider: ParentComponent = (props) => {
|
||||||
const [isDark, setIsDark] = createSignal(false);
|
// Initialize with correct theme synchronously
|
||||||
|
const [isDark, setIsDark] = createSignal(getInitialTheme());
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
setIsDark(mediaQuery.matches);
|
|
||||||
|
|
||||||
// Listen for system theme changes
|
// Listen for system theme changes
|
||||||
const handleChange = (e: MediaQueryListEvent) => {
|
const handleChange = (e: MediaQueryListEvent) => {
|
||||||
|
// Only update if there's no explicit override
|
||||||
|
const storedOverride = localStorage.getItem(STORAGE_KEY);
|
||||||
|
if (storedOverride === null) {
|
||||||
setIsDark(e.matches);
|
setIsDark(e.matches);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mediaQuery.addEventListener("change", handleChange);
|
mediaQuery.addEventListener("change", handleChange);
|
||||||
@@ -57,11 +80,30 @@ export const DarkModeProvider: ParentComponent = (props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const toggleDarkMode = () => {
|
const toggleDarkMode = () => {
|
||||||
setIsDark(!isDark());
|
const newValue = !isDark();
|
||||||
|
setIsDark(newValue);
|
||||||
|
|
||||||
|
// Only persist if different from system preference
|
||||||
|
const systemPreference = getSystemPreference();
|
||||||
|
if (newValue !== systemPreference) {
|
||||||
|
localStorage.setItem(STORAGE_KEY, newValue ? "dark" : "light");
|
||||||
|
} else {
|
||||||
|
// If matching system preference, remove override
|
||||||
|
localStorage.removeItem(STORAGE_KEY);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setDarkMode = (dark: boolean) => {
|
const setDarkMode = (dark: boolean) => {
|
||||||
setIsDark(dark);
|
setIsDark(dark);
|
||||||
|
|
||||||
|
// Only persist if different from system preference
|
||||||
|
const systemPreference = getSystemPreference();
|
||||||
|
if (dark !== systemPreference) {
|
||||||
|
localStorage.setItem(STORAGE_KEY, dark ? "dark" : "light");
|
||||||
|
} else {
|
||||||
|
// If matching system preference, remove override
|
||||||
|
localStorage.removeItem(STORAGE_KEY);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -12,6 +12,17 @@ export default createHandler(() => (
|
|||||||
content="width=device-width, initial-scale=1, maximum-scale=1"
|
content="width=device-width, initial-scale=1, maximum-scale=1"
|
||||||
/>
|
/>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<script>
|
||||||
|
{`
|
||||||
|
(function() {
|
||||||
|
const STORAGE_KEY = 'theme-override';
|
||||||
|
const stored = localStorage.getItem(STORAGE_KEY);
|
||||||
|
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
const isDark = stored !== null ? stored === 'dark' : systemDark;
|
||||||
|
document.documentElement.classList.add(isDark ? 'dark' : 'light');
|
||||||
|
})();
|
||||||
|
`}
|
||||||
|
</script>
|
||||||
{assets}
|
{assets}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user