Today I want to talk about how you can support the dark theme in your Adaptive Card Extension’s Quick View while using it on mobile.
I took inspiration from the Microsoft learn article that can be found here.
If you want you can check the code of the sample solution I used for this article here.
You might be wondering: doesn’t the ACE’s already support light and dark theming? And you’d be right, but this is true only for the out of the box controls, what if you want to support a different behavior when using images? Like, per say, a specific image for when the user is using light theme or another image when the user is using a dark theme.
Changing the image based on the current theme is quite an easy thing, but before showing you the code I want to show you the results.
What is it like?
Since we are talking about styling the Quick View of the ACE I will show you the results in the Viva Connections dashboard.
Starting with the Card View here are the results for the light and dark themes:
And those are achieved without any further customization.
iOS
In this section I want to show the results in the Teams app in iOS.
Light mode
Dark mode
Android
In this section I want to show the results for the Teams app in Android
Light mode
Dark mode
Show me the code
The Adaptive Card Extensions support the dark and light themes natively both for the Card Views and Quick Views, while this is true for the native controls this isn’t true for custom images in the Quick View.
To help you set the right image for the light or dark theme you can use the context.sdks.microsoftTeams.teamsJs.app.getContext()
API, this is available from SPFx version 1.18.1 and allows you to retrieve the Teams context with the current theme. Using this API you can set the correct image based on the current theme.
To use this you will have to define a property in the ACE state to allow the current theme to be passed from the main ACE component to the Quick View.
In the sample the state is defined as following:
export interface IAceWithDarkThemeSupportAdaptiveCardExtensionState {
theme: string;
}
In the ACE main component, inside the onInit method, you can set the state specifying the current selected theme. Other than this there’s also the getContext
method which retrieves the current context from the Teams application.
public async onInit(): Promise<void> {
this.state = {
theme: "light"
};
this.context.sdks?.microsoftTeams?.teamsJs.app
.getContext()
.then((context) => {
this.setState({
theme: context.app.appInfo.theme,
});
})
.catch((error) => {
console.error(error);
});
... omitted for brevity ...
return Promise.resolve();
}
The state’s theme
property will be used in the Quick View inside the data
method to select the right image to be displayed in the view:
public get data(): IQuickViewData {
const isDarkTheme = this.state.theme === "dark"
? true : false;
const imageUrl = isDarkTheme ?
require("../assets/darkImage.svg") :
require("../assets/lightImage.svg");
return {
subTitle: strings.SubTitle,
title: strings.Title,
imageUrl
};
}
As you can see if the theme
property is equal to "dark"
then you can set the dark image instead of the light one.
Finally in the Quick View I just displayed the image with some text, just for reference this is the JSON Quick View code:
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"weight": "Bolder",
"text": "${title}",
"horizontalAlignment": "center"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "Image",
"url": "${imageUrl}",
"width": "100px",
"height": "100px",
"horizontalAlignment": "center"
},
{
"type": "TextBlock",
"weight": "Bolder",
"text": "${subTitle}",
"wrap": true,
"horizontalAlignment": "center"
}],
"width": "stretch"
}]
}]
}
Conclusions
Supporting the dark theme is a nice addition for every modern mobile application, the ACEs are already theme aware but what I described in this article is quite an easy step to increase furthermore the personalization of your ACE, I showed you how to use an image but you can do the same also for icons!
Hope this helps!
Top comments (0)