initial commit
This commit is contained in:
83
frontend/src/theme.ts
Normal file
83
frontend/src/theme.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
export const AETHERA_THEME_KEY = 'aethera-theme';
|
||||
|
||||
export type ThemeMode = 'light' | 'dark' | 'system';
|
||||
|
||||
export interface ThemeState {
|
||||
mode: ThemeMode;
|
||||
}
|
||||
|
||||
export function getSystemTheme(): 'light' | 'dark' {
|
||||
if (typeof window !== 'undefined') {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
? 'dark'
|
||||
: 'light';
|
||||
}
|
||||
return 'light';
|
||||
}
|
||||
|
||||
export function getEffectiveTheme(themeMode: ThemeMode): 'light' | 'dark' {
|
||||
if (themeMode === 'system') {
|
||||
return getSystemTheme();
|
||||
}
|
||||
return themeMode;
|
||||
}
|
||||
|
||||
export function loadTheme(): ThemeState {
|
||||
if (typeof localStorage === 'undefined') {
|
||||
return { mode: 'system' };
|
||||
}
|
||||
|
||||
const stored = localStorage.getItem(AETHERA_THEME_KEY);
|
||||
if (stored === 'light' || stored === 'dark' || stored === 'system') {
|
||||
return { mode: stored };
|
||||
}
|
||||
|
||||
return { mode: 'system' };
|
||||
}
|
||||
|
||||
export function saveThemeMode(mode: ThemeMode): void {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.setItem(AETHERA_THEME_KEY, mode);
|
||||
}
|
||||
}
|
||||
|
||||
export function applyTheme(mode: ThemeMode): void {
|
||||
const effectiveTheme = getEffectiveTheme(mode);
|
||||
if (typeof document !== 'undefined') {
|
||||
if (effectiveTheme === 'dark') {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
}
|
||||
applySyntaxTheme(effectiveTheme);
|
||||
}
|
||||
|
||||
export function applySyntaxTheme(theme: 'light' | 'dark'): void {
|
||||
if (typeof document === 'undefined') return;
|
||||
|
||||
const linkId = 'hljs-theme';
|
||||
let link = document.getElementById(linkId) as HTMLLinkElement;
|
||||
|
||||
const cssFile =
|
||||
theme === 'dark'
|
||||
? 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/stackoverflow-dark.css'
|
||||
: 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.css';
|
||||
|
||||
if (!link) {
|
||||
link = document.createElement('link');
|
||||
link.id = linkId;
|
||||
link.rel = 'stylesheet';
|
||||
link.href = cssFile;
|
||||
document.head.appendChild(link);
|
||||
} else if (link.href !== cssFile) {
|
||||
link.href = cssFile;
|
||||
}
|
||||
}
|
||||
|
||||
export function getNextThemeMode(currentMode: ThemeMode): ThemeMode {
|
||||
const cycle: ThemeMode[] = ['light', 'dark', 'system'];
|
||||
const currentIndex = cycle.indexOf(currentMode);
|
||||
const nextIndex = (currentIndex + 1) % cycle.length;
|
||||
return cycle[nextIndex];
|
||||
}
|
||||
Reference in New Issue
Block a user