Stateful dark mode
parent
b4f2c00dce
commit
65c6403acc
42
app.vue
42
app.vue
|
@ -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 });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 });
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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);
|
||||||
},
|
},
|
||||||
|
|
|
@ -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'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue