fix: theme store now uses singular variables object

This commit is contained in:
Eli Bosley
2024-12-17 09:35:02 -05:00
parent 8e0962adba
commit 116efe6f72
2 changed files with 102 additions and 98 deletions

View File

@@ -4,7 +4,7 @@ import Label from '~/components/shadcn/label/Label.vue';
import { defaultColors, useThemeStore, type Theme } from '~/store/theme'; import { defaultColors, useThemeStore, type Theme } from '~/store/theme';
const themeStore = useThemeStore(); const themeStore = useThemeStore();
const { darkMode, theme } = toRefs(themeStore); const { darkMode } = toRefs(themeStore);
const setDarkMode = ref<boolean>(false); const setDarkMode = ref<boolean>(false);
const setGradient = ref<boolean>(false); const setGradient = ref<boolean>(false);
@@ -32,7 +32,9 @@ const textPrimaryToSet = computed(() => {
if (textPrimary.value) { if (textPrimary.value) {
return textPrimary.value; return textPrimary.value;
} }
return darkMode.value ? defaultColors.dark.headerTextPrimary : defaultColors.light.headerTextPrimary; return darkMode.value
? defaultColors.dark['--headerTextPrimary']
: defaultColors.light['--headerTextPrimary'];
}); });
const textSecondaryToSet = computed(() => { const textSecondaryToSet = computed(() => {
@@ -40,8 +42,8 @@ const textSecondaryToSet = computed(() => {
return textSecondary.value; return textSecondary.value;
} }
return darkMode.value return darkMode.value
? defaultColors.dark.headerTextSecondary ? defaultColors.dark['--header-text-secondary']
: defaultColors.light.headerTextSecondary; : defaultColors.light['--header-text-secondary'];
}); });
const bgColorToSet = computed(() => { const bgColorToSet = computed(() => {
@@ -49,11 +51,21 @@ const bgColorToSet = computed(() => {
return bgColor.value; return bgColor.value;
} }
return darkMode.value return darkMode.value
? defaultColors.dark.headerBackgroundColor ? defaultColors.dark['--header-background']
: defaultColors.light.headerBackgroundColor; : defaultColors.light['--header-background'];
}); });
watch([setDarkMode, bgColorToSet, textSecondaryToSet, textPrimaryToSet], (newVal) => { watch(
[
setDarkMode,
bgColorToSet,
textSecondaryToSet,
textPrimaryToSet,
setDescription,
setBanner,
setGradient,
],
(newVal) => {
console.log(newVal); console.log(newVal);
const themeToSet: Theme = { const themeToSet: Theme = {
banner: setBanner.value, banner: setBanner.value,
@@ -65,7 +77,8 @@ watch([setDarkMode, bgColorToSet, textSecondaryToSet, textPrimaryToSet], (newVal
name: setDarkMode.value ? 'black' : 'light', name: setDarkMode.value ? 'black' : 'light',
}; };
themeStore.setTheme(themeToSet); themeStore.setTheme(themeToSet);
}); }
);
</script> </script>
<template> <template>

View File

@@ -18,26 +18,36 @@ export interface Theme {
textColor: string; textColor: string;
} }
interface ColorMode { interface ThemeVariables {
headerTextPrimary: string; [key: string]: string;
headerTextSecondary: string;
headerBackgroundColor: string;
} }
export const defaultColors: Record<string, ColorMode> = { export const defaultColors: Record<string, ThemeVariables> = {
dark: { dark: {
headerTextPrimary: '#1c1c1c', '--background': '0 0% 3.9%',
headerBackgroundColor: '#f2f2f2', '--foreground': '0 0% 98%',
headerTextSecondary: '#999999', '--muted': '0 0% 14.9%',
'--muted-foreground': '0 0% 63.9%',
'--popover': '0 0% 3.9%',
'--popover-foreground': '0 0% 98%',
'--card': '0 0% 14.9%',
'--card-foreground': '0 0% 98%',
'--border': '0 0% 14.9%',
'--input': '0 0% 14.9%',
'--primary': '24 100% 50%',
'--primary-foreground': '0 0% 98%',
'--secondary': '0 0% 14.9%',
'--secondary-foreground': '0 0% 98%',
'--accent': '0 0% 14.9%',
'--accent-foreground': '0 0% 98%',
'--destructive': '0 62.8% 30.6%',
'--destructive-foreground': '0 0% 98%',
'--ring': '0 0% 83.1%',
'--header-text-primary': '#1c1c1c',
'--header-text-secondary': '#999999',
'--header-background-color': '#f2f2f2',
}, },
light: { light: {
headerTextPrimary: '#f2f2f2',
headerBackgroundColor: '#1c1b1b',
headerTextSecondary: '#999999',
},
};
const lightVariables = {
'--background': '0 0% 100%', '--background': '0 0% 100%',
'--foreground': '0 0% 3.9%', '--foreground': '0 0% 3.9%',
'--muted': '0 0% 96.1%', '--muted': '0 0% 96.1%',
@@ -58,33 +68,17 @@ const lightVariables = {
'--destructive-foreground': '0 0% 98%', '--destructive-foreground': '0 0% 98%',
'--ring': '0 0% 3.9%', '--ring': '0 0% 3.9%',
'--radius': '0.5rem', '--radius': '0.5rem',
}; '--header-text-primary': '#f2f2f2',
'--header-text-secondary': '#999999',
const darkVariables = { '--header-background-color': '#1c1b1b',
'--background': '0 0% 3.9%', },
'--foreground': '0 0% 98%',
'--muted': '0 0% 14.9%',
'--muted-foreground': '0 0% 63.9%',
'--popover': '0 0% 3.9%',
'--popover-foreground': '0 0% 98%',
'--card': '0 0% 14.9%',
'--card-foreground': '0 0% 98%',
'--border': '0 0% 14.9%',
'--input': '0 0% 14.9%',
'--primary': '24 100% 50%',
'--primary-foreground': '0 0% 98%',
'--secondary': '0 0% 14.9%',
'--secondary-foreground': '0 0% 98%',
'--accent': '0 0% 14.9%',
'--accent-foreground': '0 0% 98%',
'--destructive': '0 62.8% 30.6%',
'--destructive-foreground': '0 0% 98%',
'--ring': '0 0% 83.1%',
}; };
export const useThemeStore = defineStore('theme', () => { export const useThemeStore = defineStore('theme', () => {
// State // State
const theme = ref<Theme | undefined>(); const theme = ref<Theme | undefined>();
const activeColorVariables = ref<ThemeVariables>(defaultColors.light);
// Getters // Getters
const darkMode = computed( const darkMode = computed(
() => (theme.value?.name === 'black' || theme.value?.name === 'azure') ?? false () => (theme.value?.name === 'black' || theme.value?.name === 'azure') ?? false
@@ -102,40 +96,36 @@ export const useThemeStore = defineStore('theme', () => {
const setTheme = (data: Theme) => { const setTheme = (data: Theme) => {
theme.value = data; theme.value = data;
}; };
const setCssVars = () => {
const body = document.body;
let { headerTextPrimary, headerTextSecondary, headerBackgroundColor } = darkMode.value const setCssVars = () => {
? defaultColors.dark const customColorVariables = structuredClone(defaultColors);
: defaultColors.light; const body = document.body;
const selectedMode = darkMode.value ? 'dark' : 'light';
// overwrite with hex colors set in webGUI @ /Settings/DisplaySettings // overwrite with hex colors set in webGUI @ /Settings/DisplaySettings
if (theme.value?.textColor) { if (theme.value?.textColor) {
headerTextPrimary = theme.value?.textColor; customColorVariables[selectedMode]['--header-text-primary'] = theme.value.textColor;
}
if (theme.value?.bgColor) {
headerBackgroundColor = theme.value.bgColor;
body.style.setProperty('--color-customgradient-start', hexToRgba(headerBackgroundColor, 0));
body.style.setProperty('--color-customgradient-end', hexToRgba(headerBackgroundColor, 0.7));
} }
if (theme.value?.metaColor) { if (theme.value?.metaColor) {
headerTextSecondary = theme.value?.metaColor; customColorVariables[selectedMode]['--header-text-secondary'] = theme.value.metaColor;
}
if (theme.value?.bgColor) {
customColorVariables[selectedMode]['--header-background-color'] = theme.value.bgColor;
body.style.setProperty('--color-customgradient-start', hexToRgba(theme.value.bgColor, 0));
body.style.setProperty('--color-customgradient-end', hexToRgba(theme.value.bgColor, 0.7));
} }
body.style.setProperty('--header-text-primary', headerTextPrimary); Object.entries(customColorVariables[selectedMode]).forEach(([key, value]) => {
body.style.setProperty('--header-text-secondary', headerTextSecondary);
body.style.setProperty('--header-background-color', headerBackgroundColor);
if (darkMode.value) {
Object.entries(darkVariables).forEach(([key, value]) => {
body.style.setProperty(key, value); body.style.setProperty(key, value);
}); });
if (darkMode.value) {
document.body.classList.add('dark'); document.body.classList.add('dark');
} else { } else {
Object.entries(lightVariables).forEach(([key, value]) => {
body.style.setProperty(key, value);
});
document.body.classList.remove('dark'); document.body.classList.remove('dark');
} }
activeColorVariables.value = customColorVariables[selectedMode];
}; };
watch(theme, () => { watch(theme, () => {
@@ -144,6 +134,7 @@ export const useThemeStore = defineStore('theme', () => {
return { return {
// state // state
activeColorVariables,
bannerGradient, bannerGradient,
darkMode, darkMode,
theme, theme,