Switch UI5 Themes on the fly depending on user setting
Introduction
This is a follow-on post from my blog post "Switching themes on the fly in our standalone SAP UI5 application" from a question that I was asked:
"How can I have the theme switch automatically depending on the user machine settings?"
How to detect theme preferences in JavaScript
Detecting theme preferences is a simple one liner which makes this entire thing possible:
window.matchMedia('(prefers-color-scheme: dark)').matches;
This will return a boolean for true
if dark mode is preferred, we need to therefore take advantage of this inside of our initTheme
function from our themeHelper file.
Our initTheme changes
Just as a quick reminder our previous initTheme function is as follows:
initTheme: function () {
const sTheme = this.getTheme();
if (sTheme) {
this.setTheme(sTheme)
}
}
So we want to incorporate our new theme detector line and set our theme to the dark theme:
initTheme: function () {
const sTheme = this.getTheme();
if (sTheme) {
this.setTheme(sTheme)
}else{
let bDarkModePreferred = window.matchMedia('(prefers-color-scheme: dark)').matches;
if(bDarkModePreferred){
this.setTheme("sap_fiori_3_dark");
}
}
},
That's it! If you simply wanted to just detect for a dark theme preference we've already achieved this, note that any pre-selected themes will instead be used so not to constantly overwrite the users choice.
However, what if the user was actively changing their theme on their device? We haven't got any way to account for that in our current implementation which I think could be useful.
Detecting changes in our theme
Inside of our themeHelper.js file we need to create a new function called "watchForThemeChanges" which we'll add an event listener to a preference change. If we detect a change to a "dark" theme we'll set to the 'sap_fiori_3_dark' theme else we'll set to the 'light' theme which is 'sap_fiori_3'.
watchForThemeChanges: function ( ) {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
const sNewColorScheme = event.matches ? "dark" : "light";
if(sNewColorScheme === "dark"){
this.setTheme("sap_fiori_3_dark");
}else if(sNewColorScheme === "light"){
this.setTheme("sap_fiori_3");
}
});
}
That's it, our new function will now once called watch-out for theme changes on the fly, I suggest simply calling the function call inside of our "initTheme" function at the end.
Conclusion
That concludes our very quick follow-on blog post for automatically switching themes based on the user settings. I think adds that little extra polish to your application that most people wouldn't neccessarily even think of but will easily impress people.
This was tested on MacOS Monterey 12.3 only.
···