diff --git a/components/settings/SettingsThemeColors.vue b/components/settings/SettingsThemeColors.vue
new file mode 100644
index 00000000..82091ff0
--- /dev/null
+++ b/components/settings/SettingsThemeColors.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
diff --git a/composables/settings/definition.ts b/composables/settings/definition.ts
index ae7cde93..4c64dba0 100644
--- a/composables/settings/definition.ts
+++ b/composables/settings/definition.ts
@@ -18,6 +18,23 @@ export interface UserSettings {
fontSize: FontSize
language: string
zenMode: boolean
+ themeColors?: ThemeColors
+}
+
+export interface ThemeColors {
+ '--theme-color-name': string
+
+ '--c-primary': string
+ '--c-primary-active': string
+ '--c-primary-light': string
+ '--c-primary-fade': string
+ '--c-dark-primary': string
+ '--c-dark-primary-active': string
+ '--c-dark-primary-light': string
+ '--c-dark-primary-fade': string
+
+ '--rgb-primary': string
+ '--rgb-dark-primary': string
}
export function getDefaultLanguage(languages: string[]) {
diff --git a/constants/themes.json b/constants/themes.json
new file mode 100644
index 00000000..a7875742
--- /dev/null
+++ b/constants/themes.json
@@ -0,0 +1,146 @@
+[
+ [
+ "#cc7d24",
+ {
+ "--theme-color-name": "#cc7d24",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#b16605",
+ "--c-primary-light": "#cc7d2480",
+ "--c-primary-fade": "#c7781f1a",
+ "--rgb-primary": "204, 125, 36",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#b66b0d",
+ "--c-dark-primary-light": "#d1822980",
+ "--c-dark-primary-fade": "#cc7d241a",
+ "--rgb-dark-primary": "204, 125, 36"
+ }
+ ],
+ [
+ "#8d9614",
+ {
+ "--theme-color-name": "#8d9614",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#747f00",
+ "--c-primary-light": "#8d961480",
+ "--c-primary-fade": "#88910c1a",
+ "--rgb-primary": "141, 150, 20",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#798300",
+ "--c-dark-primary-light": "#929b1b80",
+ "--c-dark-primary-fade": "#8d96141a",
+ "--rgb-dark-primary": "141, 150, 20"
+ }
+ ],
+ [
+ "#24a451",
+ {
+ "--theme-color-name": "#24a451",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#008c3b",
+ "--c-primary-light": "#24a45180",
+ "--c-primary-fade": "#1c9f4d1a",
+ "--rgb-primary": "36, 164, 81",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#00903f",
+ "--c-dark-primary-light": "#2ba95580",
+ "--c-dark-primary-fade": "#24a4511a",
+ "--rgb-dark-primary": "36, 164, 81"
+ }
+ ],
+ [
+ "#00a99b",
+ {
+ "--theme-color-name": "#00a99b",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#009184",
+ "--c-primary-light": "#00a99b80",
+ "--c-primary-fade": "#00a4961a",
+ "--rgb-primary": "0, 169, 155",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#009688",
+ "--c-dark-primary-light": "#13aea080",
+ "--c-dark-primary-fade": "#00a99b1a",
+ "--rgb-dark-primary": "0, 169, 155"
+ }
+ ],
+ [
+ "#00a6df",
+ {
+ "--theme-color-name": "#00a6df",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#008ec6",
+ "--c-primary-light": "#00a6df80",
+ "--c-primary-fade": "#00a1da1a",
+ "--rgb-primary": "0, 166, 223",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#0093cb",
+ "--c-dark-primary-light": "#17abe480",
+ "--c-dark-primary-fade": "#00a6df1a",
+ "--rgb-dark-primary": "0, 166, 223"
+ }
+ ],
+ [
+ "#0097fd",
+ {
+ "--theme-color-name": "#0097fd",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#0080e3",
+ "--c-primary-light": "#0097fd80",
+ "--c-primary-fade": "#0092f81a",
+ "--rgb-primary": "0, 151, 253",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#0085e5",
+ "--c-dark-primary-light": "#1a9cff80",
+ "--c-dark-primary-fade": "#0197fa1a",
+ "--rgb-dark-primary": "0, 151, 253"
+ }
+ ],
+ [
+ "#a27be7",
+ {
+ "--theme-color-name": "#a27be7",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#8964cd",
+ "--c-primary-light": "#a27be780",
+ "--c-primary-fade": "#9d76e21a",
+ "--rgb-primary": "162, 123, 231",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#8e69d2",
+ "--c-dark-primary-light": "#a780ec80",
+ "--c-dark-primary-fade": "#a27be71a",
+ "--rgb-dark-primary": "162, 123, 231"
+ }
+ ],
+ [
+ "#e65da9",
+ {
+ "--theme-color-name": "#e65da9",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#cb4391",
+ "--c-primary-light": "#e65da980",
+ "--c-primary-fade": "#e158a41a",
+ "--rgb-primary": "230, 93, 169",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#d14896",
+ "--c-dark-primary-light": "#eb62ae80",
+ "--c-dark-primary-fade": "#e65da91a",
+ "--rgb-dark-primary": "230, 93, 169"
+ }
+ ],
+ [
+ "#ef6061",
+ {
+ "--theme-color-name": "#ef6061",
+ "--c-primary": "rgb(var(--rgb-primary))",
+ "--c-primary-active": "#d3474c",
+ "--c-primary-light": "#ef606180",
+ "--c-primary-fade": "#e95b5d1a",
+ "--rgb-primary": "239, 96, 97",
+ "--c-dark-primary": "rgb(var(--rgb-dark-primary))",
+ "--c-dark-primary-active": "#d94c50",
+ "--c-dark-primary-light": "#f5656580",
+ "--c-dark-primary-fade": "#ef60611a",
+ "--rgb-dark-primary": "239, 96, 97"
+ }
+ ]
+]
diff --git a/locales/en-US.json b/locales/en-US.json
index 985943f5..4065977b 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -291,7 +291,8 @@
"xl": "Extra large",
"xs": "Extra small"
},
- "system_mode": "System"
+ "system_mode": "System",
+ "theme_color": "Theme Color"
},
"language": {
"display_language": "Display Language",
diff --git a/nuxt.config.ts b/nuxt.config.ts
index c50702c7..d0bb12de 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -45,6 +45,7 @@ export default defineNuxtConfig({
css: [
'@unocss/reset/tailwind.css',
'floating-vue/dist/style.css',
+ '~/styles/default-theme.css',
'~/styles/vars.css',
'~/styles/global.css',
'~/styles/tiptap.css',
diff --git a/package.json b/package.json
index 8512083f..c2be291a 100644
--- a/package.json
+++ b/package.json
@@ -80,6 +80,7 @@
"@nuxtjs/color-mode": "^3.2.0",
"@nuxtjs/i18n": "^8.0.0-beta.7",
"@pinia/nuxt": "^0.4.6",
+ "@types/chroma-js": "^2.1.4",
"@types/file-saver": "^2.0.5",
"@types/fnando__sparkline": "^0.3.4",
"@types/fs-extra": "^11.0.0",
@@ -92,6 +93,7 @@
"@vueuse/math": "^9.10.0",
"@vueuse/nuxt": "^9.10.0",
"bumpp": "^8.2.1",
+ "chroma-js": "^2.4.2",
"emoji-mart": "^5.4.0",
"eslint": "^8.31.0",
"esno": "^0.16.3",
diff --git a/pages/settings/interface/index.vue b/pages/settings/interface/index.vue
index 5939bdda..804e7f89 100644
--- a/pages/settings/interface/index.vue
+++ b/pages/settings/interface/index.vue
@@ -24,6 +24,12 @@ useHeadFixed({
+