mirror of
https://github.com/unraid/api.git
synced 2025-12-31 21:49:57 -06:00
fix: theme store now uses singular variables object
This commit is contained in:
@@ -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,23 +51,34 @@ 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(
|
||||||
console.log(newVal);
|
[
|
||||||
const themeToSet: Theme = {
|
setDarkMode,
|
||||||
banner: setBanner.value,
|
bgColorToSet,
|
||||||
bannerGradient: setGradient.value,
|
textSecondaryToSet,
|
||||||
descriptionShow: setDescription.value,
|
textPrimaryToSet,
|
||||||
textColor: textPrimaryToSet.value,
|
setDescription,
|
||||||
metaColor: textSecondaryToSet.value,
|
setBanner,
|
||||||
bgColor: bgColorToSet.value,
|
setGradient,
|
||||||
name: setDarkMode.value ? 'black' : 'light',
|
],
|
||||||
};
|
(newVal) => {
|
||||||
themeStore.setTheme(themeToSet);
|
console.log(newVal);
|
||||||
});
|
const themeToSet: Theme = {
|
||||||
|
banner: setBanner.value,
|
||||||
|
bannerGradient: setGradient.value,
|
||||||
|
descriptionShow: setDescription.value,
|
||||||
|
textColor: textPrimaryToSet.value,
|
||||||
|
metaColor: textSecondaryToSet.value,
|
||||||
|
bgColor: bgColorToSet.value,
|
||||||
|
name: setDarkMode.value ? 'black' : 'light',
|
||||||
|
};
|
||||||
|
themeStore.setTheme(themeToSet);
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -18,73 +18,67 @@ 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',
|
'--background': '0 0% 100%',
|
||||||
headerBackgroundColor: '#1c1b1b',
|
'--foreground': '0 0% 3.9%',
|
||||||
headerTextSecondary: '#999999',
|
'--muted': '0 0% 96.1%',
|
||||||
|
'--muted-foreground': '0 0% 45.1%',
|
||||||
|
'--popover': '0 0% 100%',
|
||||||
|
'--popover-foreground': '0 0% 3.9%',
|
||||||
|
'--card': '0 0% 100%',
|
||||||
|
'--card-foreground': '0 0% 3.9%',
|
||||||
|
'--border': '0 0% 89.8%',
|
||||||
|
'--input': '0 0% 89.8%',
|
||||||
|
'--primary': '24 100% 50%',
|
||||||
|
'--primary-foreground': '0 0% 98%',
|
||||||
|
'--secondary': '0 0% 96.1%',
|
||||||
|
'--secondary-foreground': '0 0% 9%',
|
||||||
|
'--accent': '0 0% 96.1%',
|
||||||
|
'--accent-foreground': '0 0% 9%',
|
||||||
|
'--destructive': '0 84.2% 60.2%',
|
||||||
|
'--destructive-foreground': '0 0% 98%',
|
||||||
|
'--ring': '0 0% 3.9%',
|
||||||
|
'--radius': '0.5rem',
|
||||||
|
'--header-text-primary': '#f2f2f2',
|
||||||
|
'--header-text-secondary': '#999999',
|
||||||
|
'--header-background-color': '#1c1b1b',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const lightVariables = {
|
|
||||||
'--background': '0 0% 100%',
|
|
||||||
'--foreground': '0 0% 3.9%',
|
|
||||||
'--muted': '0 0% 96.1%',
|
|
||||||
'--muted-foreground': '0 0% 45.1%',
|
|
||||||
'--popover': '0 0% 100%',
|
|
||||||
'--popover-foreground': '0 0% 3.9%',
|
|
||||||
'--card': '0 0% 100%',
|
|
||||||
'--card-foreground': '0 0% 3.9%',
|
|
||||||
'--border': '0 0% 89.8%',
|
|
||||||
'--input': '0 0% 89.8%',
|
|
||||||
'--primary': '24 100% 50%',
|
|
||||||
'--primary-foreground': '0 0% 98%',
|
|
||||||
'--secondary': '0 0% 96.1%',
|
|
||||||
'--secondary-foreground': '0 0% 9%',
|
|
||||||
'--accent': '0 0% 96.1%',
|
|
||||||
'--accent-foreground': '0 0% 9%',
|
|
||||||
'--destructive': '0 84.2% 60.2%',
|
|
||||||
'--destructive-foreground': '0 0% 98%',
|
|
||||||
'--ring': '0 0% 3.9%',
|
|
||||||
'--radius': '0.5rem',
|
|
||||||
};
|
|
||||||
|
|
||||||
const darkVariables = {
|
|
||||||
'--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(key, value);
|
||||||
body.style.setProperty('--header-background-color', headerBackgroundColor);
|
});
|
||||||
|
|
||||||
if (darkMode.value) {
|
if (darkMode.value) {
|
||||||
Object.entries(darkVariables).forEach(([key, value]) => {
|
|
||||||
body.style.setProperty(key, 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,
|
||||||
|
|||||||
Reference in New Issue
Block a user