Stateful dark mode

pull/5015/head
Cagatay Civici 2023-12-31 01:26:14 +03:00
parent b4f2c00dce
commit 65c6403acc
5 changed files with 54 additions and 26 deletions

42
app.vue
View File

@ -8,9 +8,6 @@
import EventBus from '@/layouts/AppEventBus';
export default {
themeChangeListener: null,
newsActivate: null,
newsService: null,
watch: {
$route: {
handler(to) {
@ -20,16 +17,29 @@ export default {
}
}
},
created() {
useServerHead({
link: [
{
id: 'theme-link',
rel: 'stylesheet',
href: '/themes/lara-light-green/theme.css'
},
{
id: 'home-table-link',
rel: 'stylesheet',
href: '/styles/landing/themes/lara-light-green/theme.css'
}
]
});
},
mounted() {
this.themeChangeListener = (event) => {
if (!document.startViewTransition) {
this.applyTheme(event);
const preferredColorScheme = localStorage.getItem(this.$appState.colorSchemeKey);
const prefersDarkColorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
return;
}
document.startViewTransition(() => this.applyTheme(event));
};
if ((preferredColorScheme === null && prefersDarkColorScheme) || preferredColorScheme === 'dark') {
this.applyTheme({ theme: 'lara-dark-green', dark: true });
}
EventBus.on('theme-change', this.themeChangeListener);
},
@ -37,10 +47,20 @@ export default {
EventBus.off('theme-change', this.themeChangeListener);
},
methods: {
themeChangeListener(event) {
if (!document.startViewTransition) {
this.applyTheme(event);
return;
}
document.startViewTransition(() => this.applyTheme(event));
},
applyTheme(event) {
this.$primevue.changeTheme(this.$appState.theme, event.theme, 'theme-link', () => {
this.$appState.theme = event.theme;
this.$appState.darkTheme = event.dark;
EventBus.emit('theme-change-complete', { theme: event.theme, dark: event.dark });
});
}

View File

@ -92,9 +92,12 @@ export default {
if (this.$appState.darkTheme) {
newTheme = currentTheme.replace('dark', 'light');
localStorage.setItem(this.$appState.colorSchemeKey, 'light');
} else {
if (currentTheme.includes('light') && currentTheme !== 'fluent-light') newTheme = currentTheme.replace('light', 'dark');
else newTheme = 'lara-dark-green'; //fallback
localStorage.setItem(this.$appState.colorSchemeKey, 'dark');
}
EventBus.emit('theme-change', { theme: newTheme, dark: !this.$appState.darkTheme });

View File

@ -52,19 +52,7 @@ export default defineNuxtConfig({
{ property: 'og:image', content: 'https://www.primefaces.org/static/social/primevue-preview.jpg' },
{ property: 'og:ttl', content: '604800' }
],
link: [
{
id: 'home-table-link',
rel: 'stylesheet',
href: baseUrl + 'styles/landing/themes/lara-light-green/theme.css'
},
{
id: 'theme-link',
rel: 'stylesheet',
href: baseUrl + 'themes/lara-light-green/theme.css'
},
{ rel: 'icon', href: baseUrl + 'favicon.ico' }
],
link: [{ rel: 'icon', href: baseUrl + 'favicon.ico' }],
script: [
{
src: baseUrl + 'scripts/prism.js',

View File

@ -53,13 +53,21 @@ export default {
document.cookie = 'primeaffiliateid=' + afId + ';expires=' + expire.toUTCString() + ';path=/; domain:primefaces.org';
}
this.replaceTableTheme(this.$appState.darkTheme ? 'lara-dark-green' : 'lara-light-green');
const preferredColorScheme = localStorage.getItem(this.$appState.colorSchemeKey);
const prefersDarkColorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
if ((preferredColorScheme === null && prefersDarkColorScheme) || preferredColorScheme === 'dark') {
this.replaceTableTheme('lara-dark-green');
} else {
this.replaceTableTheme('lara-light-green');
}
},
methods: {
onDarkModeToggle() {
const newTheme = this.$appState.darkTheme ? 'lara-light-green' : 'lara-dark-green';
const newTableTheme = this.$appState.darkTheme ? this.tableTheme.replace('dark', 'light') : this.tableTheme.replace('light', 'dark');
localStorage.setItem(this.$appState.colorSchemeKey, this.$appState.darkTheme ? 'light' : 'dark');
EventBus.emit('theme-change', { theme: newTheme, dark: !this.$appState.darkTheme });
this.replaceTableTheme(newTableTheme);
},

View File

@ -1,6 +1,15 @@
const $appState = {
install: (Vue, options) => {
Vue.config.globalProperties.$appState = reactive({ theme: 'lara-light-green', darkTheme: false, codeSandbox: false, sourceType: 'options-api', newsActive: false, announcement: null, storageKey: 'primevue' });
Vue.config.globalProperties.$appState = reactive({
theme: 'lara-light-green',
darkTheme: false,
codeSandbox: false,
sourceType: 'options-api',
newsActive: false,
announcement: null,
storageKey: 'primevue',
colorSchemeKey: 'primevue-color-scheme'
});
}
};