feature/ui-upgrade-dark-mode-preview #6

Merged
jason merged 6 commits from feature/ui-upgrade-dark-mode-preview into main 2026-03-08 16:43:16 -05:00
Showing only changes of commit cdac0b0cd9 - Show all commits

60
frontend/src/lib/theme.ts Normal file
View File

@@ -0,0 +1,60 @@
import { writable } from 'svelte/store';
export type Theme = 'light' | 'dark';
// Get initial theme from localStorage or system preference
function getInitialTheme(): Theme {
if (typeof window === 'undefined') return 'light';
const stored = localStorage.getItem('theme') as Theme;
if (stored === 'light' || stored === 'dark') {
return stored;
}
// Check system preference
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
}
// Create the theme store
function createThemeStore() {
const { subscribe, set, update } = writable<Theme>(getInitialTheme());
return {
subscribe,
set: (theme: Theme) => {
if (typeof window !== 'undefined') {
localStorage.setItem('theme', theme);
document.documentElement.setAttribute('data-theme', theme);
}
set(theme);
},
toggle: () => {
update(current => {
const newTheme = current === 'light' ? 'dark' : 'light';
if (typeof window !== 'undefined') {
localStorage.setItem('theme', newTheme);
document.documentElement.setAttribute('data-theme', newTheme);
}
return newTheme;
});
},
init: () => {
const theme = getInitialTheme();
if (typeof window !== 'undefined') {
document.documentElement.setAttribute('data-theme', theme);
}
set(theme);
}
};
}
export const theme = createThemeStore();
// Initialize theme on module load
if (typeof window !== 'undefined') {
theme.init();
}