Skip to content

Commit d4a1ce6

Browse files
committed
Theme preset selector
1 parent 3cc1ad5 commit d4a1ce6

File tree

5 files changed

+80
-6
lines changed

5 files changed

+80
-6
lines changed

src/app.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import './assets/css/tailwind.css';
33
import 'nprogress/nprogress.css';
44

55
import { useColorMode } from '@vueuse/core';
6-
import customThemePreset from './theme/noir-preset';
6+
import { useThemePreset } from '@/composables/useThemePreset';
77

88
import { createApp } from 'vue';
99
import { createPinia } from 'pinia';
@@ -19,14 +19,20 @@ import PageTitleSection from '@/components/PageTitleSection.vue';
1919

2020
const app = createApp(App);
2121
const pinia = createPinia();
22+
23+
// Site light/dark mode
2224
const colorMode = useColorMode({ emitAuto: true });
2325

26+
// Site theme preset
27+
const { getCurrentPreset } = useThemePreset();
28+
const themePreset = getCurrentPreset();
29+
2430
app.provide('colorMode', colorMode)
2531
.use(pinia)
2632
.use(router)
2733
.use(PrimeVue, {
2834
theme: {
29-
preset: customThemePreset,
35+
preset: themePreset,
3036
options: {
3137
darkModeSelector: '.dark',
3238
cssLayer: {

src/composables/useThemePreset.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { ref, Ref } from 'vue';
2+
import { usePreset } from '@primeuix/themes';
3+
import { Preset } from '@primeuix/themes/types';
4+
import { useStorage } from '@vueuse/core';
5+
import bootstrap from '@/theme/bootstrap-preset';
6+
import breeze from '@/theme/breeze-preset';
7+
import enterprise from '@/theme/enterprise-preset';
8+
import noir from '@/theme/noir-preset';
9+
import warm from '@/theme/warm-preset';
10+
11+
interface ThemePreset {
12+
label: string,
13+
value: string,
14+
preset: Preset,
15+
}
16+
17+
const presets = ref<ThemePreset[]>([
18+
{ label: 'Bootstrap', value: 'bootstrap', preset: bootstrap },
19+
{ label: 'Breeze', value: 'breeze', preset: breeze },
20+
{ label: 'Enterprise', value: 'enterprise', preset: enterprise },
21+
{ label: 'Noir', value: 'noir', preset: noir },
22+
{ label: 'Warm', value: 'warm', preset: warm },
23+
]);
24+
25+
const selectedPreset: Ref<string> = useStorage('theme-preset', 'noir');
26+
27+
function getCurrentPreset(): Preset {
28+
return (
29+
presets.value.find((p) => p.value === selectedPreset.value)?.preset ||
30+
presets.value[3].preset
31+
);
32+
}
33+
34+
function setPreset(presetValue: string): void {
35+
const themePreset = presets.value.find((p) => p.value === presetValue);
36+
if (themePreset) {
37+
usePreset(themePreset.preset);
38+
}
39+
}
40+
41+
setPreset(selectedPreset.value);
42+
43+
export function useThemePreset() {
44+
return {
45+
presets,
46+
selectedPreset,
47+
getCurrentPreset,
48+
setPreset,
49+
};
50+
}

src/layouts/app/HeaderLayout.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const toggleMobileUserMenu = (event) => {
4646
<div>
4747
<PanelMenu
4848
:model="menuItems"
49-
class="w-full"
49+
class="mt-1 w-full"
5050
/>
5151
</div>
5252
<template #footer>

src/layouts/app/SidebarLayout.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const toggleMobileUserMenu = (event) => {
4444
<div>
4545
<PanelMenu
4646
:model="menuItems"
47-
class="w-full"
47+
class="mt-1 w-full"
4848
/>
4949
</div>
5050
<template #footer>
@@ -117,7 +117,7 @@ const toggleMobileUserMenu = (event) => {
117117
<div>
118118
<PanelMenu
119119
:model="menuItems"
120-
class="w-full"
120+
class="mt-1 w-full"
121121
/>
122122
</div>
123123
</div>

src/views/settings/Appearance.vue

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import AppLayout from '@/layouts/AppLayout.vue';
33
import SettingsLayout from '@/layouts/UserSettingsLayout.vue';
44
import SelectColorModeButton from '@/components/SelectColorModeButton.vue';
5+
import { useThemePreset } from '@/composables/useThemePreset';
6+
7+
const { presets, selectedPreset, setPreset } = useThemePreset();
58
</script>
69

710
<template>
@@ -18,7 +21,22 @@ import SelectColorModeButton from '@/components/SelectColorModeButton.vue';
1821
Update your account's appearance settings
1922
</template>
2023
<template #content>
21-
<SelectColorModeButton />
24+
<div class="space-y-6">
25+
<div class="flex flex-col gap-2">
26+
<label for="color-mode-selector">Color Mode</label>
27+
<SelectColorModeButton id="color-mode-selector" />
28+
</div>
29+
<div class="flex flex-col gap-2">
30+
<label for="theme-preset-selector">Theme</label>
31+
<Select
32+
v-model="selectedPreset"
33+
:options="presets"
34+
optionLabel="label"
35+
optionValue="value"
36+
@change="setPreset(selectedPreset)"
37+
/>
38+
</div>
39+
</div>
2240
</template>
2341
</Card>
2442
</SettingsLayout>

0 commit comments

Comments
 (0)