diff --git a/src/app.js b/src/app.js
index d09e90e..0921b89 100644
--- a/src/app.js
+++ b/src/app.js
@@ -2,9 +2,6 @@ import './assets/css/app.css';
import './assets/css/tailwind.css';
import 'nprogress/nprogress.css';
-import { useColorMode } from '@vueuse/core';
-import customThemePreset from './theme/noir-preset';
-
import { createApp } from 'vue';
import { createPinia } from 'pinia';
@@ -17,16 +14,25 @@ import ToastService from 'primevue/toastservice';
import Container from '@/components/Container.vue';
import PageTitleSection from '@/components/PageTitleSection.vue';
+import { useColorMode } from '@vueuse/core';
+import { useThemePreset } from '@/composables/useThemePreset';
+
+// Site light/dark mode
+const colorMode = useColorMode({ emitAuto: true });
+
+// Site theme preset
+const { getCurrentPreset } = useThemePreset();
+const themePreset = getCurrentPreset();
+
const app = createApp(App);
const pinia = createPinia();
-const colorMode = useColorMode({ emitAuto: true });
app.provide('colorMode', colorMode)
.use(pinia)
.use(router)
.use(PrimeVue, {
theme: {
- preset: customThemePreset,
+ preset: themePreset,
options: {
darkModeSelector: '.dark',
cssLayer: {
diff --git a/src/components/ThemePresetSelector.vue b/src/components/ThemePresetSelector.vue
new file mode 100644
index 0000000..ed6a460
--- /dev/null
+++ b/src/components/ThemePresetSelector.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/src/composables/useThemePreset.ts b/src/composables/useThemePreset.ts
new file mode 100644
index 0000000..1e81df9
--- /dev/null
+++ b/src/composables/useThemePreset.ts
@@ -0,0 +1,50 @@
+import { ref, Ref } from 'vue';
+import { usePreset } from '@primeuix/themes';
+import { Preset } from '@primeuix/themes/types';
+import { useStorage } from '@vueuse/core';
+import bootstrap from '@/theme/bootstrap-preset';
+import breeze from '@/theme/breeze-preset';
+import enterprise from '@/theme/enterprise-preset';
+import noir from '@/theme/noir-preset';
+import warm from '@/theme/warm-preset';
+
+interface ThemePreset {
+ label: string,
+ value: string,
+ preset: Preset,
+}
+
+const presets = ref([
+ { label: 'Bootstrap', value: 'bootstrap', preset: bootstrap },
+ { label: 'Breeze', value: 'breeze', preset: breeze },
+ { label: 'Enterprise', value: 'enterprise', preset: enterprise },
+ { label: 'Noir', value: 'noir', preset: noir },
+ { label: 'Warm', value: 'warm', preset: warm },
+]);
+
+const selectedPreset: Ref = useStorage('theme-preset', 'noir');
+
+function getCurrentPreset(): Preset {
+ return (
+ presets.value.find((p) => p.value === selectedPreset.value)?.preset ||
+ presets.value[3].preset
+ );
+}
+
+function setPreset(presetValue: string): void {
+ const themePreset = presets.value.find((p) => p.value === presetValue);
+ if (themePreset) {
+ usePreset(themePreset.preset);
+ }
+}
+
+setPreset(selectedPreset.value);
+
+export function useThemePreset() {
+ return {
+ presets,
+ selectedPreset,
+ getCurrentPreset,
+ setPreset,
+ };
+}
\ No newline at end of file
diff --git a/src/layouts/app/HeaderLayout.vue b/src/layouts/app/HeaderLayout.vue
index 535d447..726a903 100644
--- a/src/layouts/app/HeaderLayout.vue
+++ b/src/layouts/app/HeaderLayout.vue
@@ -46,7 +46,7 @@ const toggleMobileUserMenu = (event) => {
diff --git a/src/layouts/app/SidebarLayout.vue b/src/layouts/app/SidebarLayout.vue
index d2e9acf..a92b4fc 100644
--- a/src/layouts/app/SidebarLayout.vue
+++ b/src/layouts/app/SidebarLayout.vue
@@ -44,7 +44,7 @@ const toggleMobileUserMenu = (event) => {
@@ -117,7 +117,7 @@ const toggleMobileUserMenu = (event) => {
diff --git a/src/views/settings/Appearance.vue b/src/views/settings/Appearance.vue
index 0000c95..3ea776c 100644
--- a/src/views/settings/Appearance.vue
+++ b/src/views/settings/Appearance.vue
@@ -2,6 +2,7 @@
import AppLayout from '@/layouts/AppLayout.vue';
import SettingsLayout from '@/layouts/UserSettingsLayout.vue';
import SelectColorModeButton from '@/components/SelectColorModeButton.vue';
+import ThemePresetSelector from '@/components/ThemePresetSelector.vue';
@@ -18,7 +19,16 @@ import SelectColorModeButton from '@/components/SelectColorModeButton.vue';
Update your account's appearance settings
-
+
+
+
+
+
+
+
+
+
+