Reputation: 6532
Recommend way of including themes is by import in main.js
file at root of the app:
import 'primevue/resources/themes/arya-orange/theme.css';
But I'm look for a way to switch CSS file based on user system theme and on user selection so i moved this in my main App.vue
:
export default {
name: "App",
components: {
HelloWorld,
toDo,
},
mounted() {
//window.matchMedia('(prefers-color-scheme: dark)').matches ? do dark : do light
},
};
<style>
@media (prefers-color-scheme: dark) {
@import url("primevue/resources/themes/bootstrap4-dark-blue/theme.css");
}
@media (prefers-color-scheme: light) {
@import url("primevue/resources/themes/bootstrap4-light-blue/theme.css");
}
</style>
I can not import anything inside mounted and in styles tag I can not import inside media also, both are not correct way of usage.
I can not find any other way online or guidance to solve this. All solutions are based on scoping components, using classes etc.
I could wrap all rules in one theme to
@media (prefers-color-scheme: dark) {
and another for light. But then again how could I switch on user selection?
EDIT:
I find a way to make it work on load:
(async () => {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
await import('primevue/resources/themes/bootstrap4-dark-blue/theme.css');
}else {
await import('primevue/resources/themes/bootstrap4-light-blue/theme.css');
}
})();
And on click overrides the first import:
methods: {
theme() {
(async () => {
await import("primevue/resources/themes/bootstrap4-light-blue/theme.css");
})();
},
},
BUT when I try to toggle it back using click it does nothing, my guess is its because if system was dark it loaded dark theme on load as first import, then on click it loaded light theme, but after that it wont switch back to dark on click, my guess is because dark was all ready loaded on load and it does not take effect on toggle.
Please advise.
Upvotes: 2
Views: 5769
Reputation: 76
One solution is to implement as it is done in the PrimeVue site. In summary, the css theme is imported using a link in the index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
...
<link id="theme-link" rel="stylesheet" href="<%= BASE_URL %>themes/saga-blue/theme.css">
</head>
<body>
...
</body>
</html>
See this link for an example.
Then to switch theme, you can implement it in a function like this:
changeTheme(event) {
let themeElement = document.getElementById('theme-link');
themeElement.setAttribute('href', themeElement.getAttribute('href').replace(this.theme, event.theme));
this.theme = event.theme;
this.activeMenuIndex = null;
EventBus.emit('change-theme', event);
this.$appState.darkTheme = event.dark;
if (event.theme.startsWith('md')) {
this.$primevue.config.ripple = true;
}
localStorage.setItem('theme', this.theme);
}
This is how it is implemented in PrimeVue documentation. See here
Upvotes: 2