web-map/src/services/theme.service.ts

53 lines
1.4 KiB
TypeScript
Raw Normal View History

2025-04-20 00:49:14 +08:00
import { theme, type TokenType as AntdTheme } from 'ant-design-vue';
2025-04-28 00:43:33 +08:00
import { chain } from 'lodash-es';
2025-04-20 00:49:14 +08:00
import { ref, watch } from 'vue';
2025-04-28 00:43:33 +08:00
const THEME_FILES = import.meta.glob('asset/themes/*.json', { eager: true, import: 'default' });
const THEME_MAP = chain(THEME_FILES)
.mapKeys((_, k) => k.match(/^.*[\\|\\/](.+?)\.[^\\.]+$/)?.[1])
.mapValues((v) => <Record<string, string>>v)
.value();
2025-04-20 00:49:14 +08:00
enum Theme {
Light = 'light',
Dark = 'dark',
}
export const THEMES = Object.freeze<[string, Theme][]>(Object.entries(Theme));
2025-04-27 00:05:18 +08:00
const THEME_STORAGE_KEY = 'theme';
2025-04-20 00:49:14 +08:00
class ThemeService {
#theme = ref<Theme>(<Theme>localStorage.getItem(THEME_STORAGE_KEY) || Theme.Dark);
public get theme(): Theme {
return this.#theme.value;
}
public set theme(v: Theme) {
this.#theme.value = v;
localStorage.setItem(THEME_STORAGE_KEY, v);
}
public get ant(): AntdTheme {
switch (this.#theme.value) {
case Theme.Dark:
2025-05-05 01:06:09 +08:00
return { algorithm: theme.darkAlgorithm };
2025-04-20 00:49:14 +08:00
case Theme.Light:
return { algorithm: theme.defaultAlgorithm };
2025-05-05 01:06:09 +08:00
default:
return {};
2025-04-20 00:49:14 +08:00
}
}
2025-04-28 00:43:33 +08:00
public get editor(): object {
return THEME_MAP[`editor-${this.#theme.value}`] ?? {};
}
2025-04-20 00:49:14 +08:00
constructor() {
watch(this.#theme, (v) => this.#load(v), { immediate: true });
}
#load(theme: Theme): void {
document.documentElement.setAttribute('theme', theme);
}
}
export default new ThemeService();