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'; import EventBus from '@/layouts/AppEventBus';
export default { export default {
themeChangeListener: null,
newsActivate: null,
newsService: null,
watch: { watch: {
$route: { $route: {
handler(to) { handler(to) {
@ -20,16 +17,29 @@ export default {
} }
} }
}, },
mounted() { created() {
this.themeChangeListener = (event) => { useServerHead({
if (!document.startViewTransition) { link: [
this.applyTheme(event); {
id: 'theme-link',
return; 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() {
const preferredColorScheme = localStorage.getItem(this.$appState.colorSchemeKey);
const prefersDarkColorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
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); EventBus.on('theme-change', this.themeChangeListener);
}, },
@ -37,10 +47,20 @@ export default {
EventBus.off('theme-change', this.themeChangeListener); EventBus.off('theme-change', this.themeChangeListener);
}, },
methods: { methods: {
themeChangeListener(event) {
if (!document.startViewTransition) {
this.applyTheme(event);
return;
}
document.startViewTransition(() => this.applyTheme(event));
},
applyTheme(event) { applyTheme(event) {
this.$primevue.changeTheme(this.$appState.theme, event.theme, 'theme-link', () => { this.$primevue.changeTheme(this.$appState.theme, event.theme, 'theme-link', () => {
this.$appState.theme = event.theme; this.$appState.theme = event.theme;
this.$appState.darkTheme = event.dark; this.$appState.darkTheme = event.dark;
EventBus.emit('theme-change-complete', { theme: event.theme, dark: 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) { if (this.$appState.darkTheme) {
newTheme = currentTheme.replace('dark', 'light'); newTheme = currentTheme.replace('dark', 'light');
localStorage.setItem(this.$appState.colorSchemeKey, 'light');
} else { } else {
if (currentTheme.includes('light') && currentTheme !== 'fluent-light') newTheme = currentTheme.replace('light', 'dark'); if (currentTheme.includes('light') && currentTheme !== 'fluent-light') newTheme = currentTheme.replace('light', 'dark');
else newTheme = 'lara-dark-green'; //fallback else newTheme = 'lara-dark-green'; //fallback
localStorage.setItem(this.$appState.colorSchemeKey, 'dark');
} }
EventBus.emit('theme-change', { theme: newTheme, dark: !this.$appState.darkTheme }); 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:image', content: 'https://www.primefaces.org/static/social/primevue-preview.jpg' },
{ property: 'og:ttl', content: '604800' } { property: 'og:ttl', content: '604800' }
], ],
link: [ link: [{ rel: 'icon', href: baseUrl + 'favicon.ico' }],
{
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' }
],
script: [ script: [
{ {
src: baseUrl + 'scripts/prism.js', src: baseUrl + 'scripts/prism.js',

View File

@ -53,13 +53,21 @@ export default {
document.cookie = 'primeaffiliateid=' + afId + ';expires=' + expire.toUTCString() + ';path=/; domain:primefaces.org'; 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: { methods: {
onDarkModeToggle() { onDarkModeToggle() {
const newTheme = this.$appState.darkTheme ? 'lara-light-green' : 'lara-dark-green'; 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'); 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 }); EventBus.emit('theme-change', { theme: newTheme, dark: !this.$appState.darkTheme });
this.replaceTableTheme(newTableTheme); this.replaceTableTheme(newTableTheme);
}, },

View File

@ -1,6 +1,15 @@
const $appState = { const $appState = {
install: (Vue, options) => { 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'
});
} }
}; };