60 lines
1.2 KiB
TypeScript
60 lines
1.2 KiB
TypeScript
export const useTheme = () => {
|
|
interface ColorSwitcher {
|
|
icon: string;
|
|
next: () => ColorSwitcher;
|
|
}
|
|
|
|
class DefaultTheme implements ColorSwitcher {
|
|
icon = 'i-mdi-theme-light-dark';
|
|
|
|
constructor() {
|
|
colourMode.preference = 'system';
|
|
}
|
|
|
|
next() {
|
|
return new LightTheme();
|
|
}
|
|
}
|
|
|
|
class LightTheme implements ColorSwitcher {
|
|
icon = 'i-mdi-white-balance-sunny';
|
|
|
|
constructor() {
|
|
colourMode.preference = 'light';
|
|
}
|
|
|
|
next() {
|
|
return new DarkTheme();
|
|
}
|
|
}
|
|
|
|
class DarkTheme implements ColorSwitcher {
|
|
icon = 'i-mdi-weather-night';
|
|
|
|
constructor() {
|
|
colourMode.preference = 'dark';
|
|
}
|
|
|
|
next() {
|
|
return new DefaultTheme();
|
|
}
|
|
}
|
|
|
|
type Theme = 'system' | 'dark' | 'light';
|
|
|
|
const colourMode = useColorMode();
|
|
const themeToSwitcher = (theme: Theme): ColorSwitcher => {
|
|
const conversionTable: Record<Theme, () => ColorSwitcher> = {
|
|
system: () => new DefaultTheme(),
|
|
dark: () => new DarkTheme(),
|
|
light: () => new LightTheme(),
|
|
};
|
|
return conversionTable[theme]();
|
|
};
|
|
|
|
let switcher = ref(themeToSwitcher(colourMode.preference as Theme));
|
|
const next = () => (switcher.value = switcher.value.next());
|
|
|
|
return { switcher, next };
|
|
};
|