Files
bio/src/composables/useTheme.ts
T
2026-04-22 12:20:58 -07:00

49 lines
1.1 KiB
TypeScript

import { ref } from "vue";
const STORAGE_KEY = "bio-theme";
const isDark = ref(false);
function applyDarkClass(value: boolean) {
if (typeof document === "undefined") return;
const root = document.documentElement;
if (value) root.classList.add("dark");
else root.classList.remove("dark");
}
function readInitial(): boolean {
if (typeof window === "undefined") return false;
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored === "dark") return true;
if (stored === "light") return false;
} catch {
/* ignore */
}
return window.matchMedia?.("(prefers-color-scheme: dark)")?.matches ?? false;
}
/** Call once before mounting the app to avoid a flash of wrong theme. */
export function initTheme() {
const dark = readInitial();
isDark.value = dark;
applyDarkClass(dark);
}
export function useTheme() {
function setTheme(dark: boolean) {
isDark.value = dark;
applyDarkClass(dark);
try {
localStorage.setItem(STORAGE_KEY, dark ? "dark" : "light");
} catch {
/* ignore */
}
}
function toggleTheme() {
setTheme(!isDark.value);
}
return { isDark, setTheme, toggleTheme };
}