[Rendering] Add Missing Properties to Default Types
Target Platforms
NodeJS
SDK Version
3.0.5
Application Name
Custom UI
Problem Description
I have an application that renderes AdaptiveCards in my own UI. I have been using some default adaptive card examples from the new designer: https://adaptivecards.microsoft.com/designer
A lot of them use the targetWidth property.
When rendering them using the Microsoft Adaptive Card JS SDK it looks like it doesn't support this property.
So I created my own custom Image Element that simply extends the default Image and overrides the existing default Image element according to the MS Docs
While my own renderer is now being called for images, the new property I added isn't being processed:
static readonly targetWidthProperty = new StringProperty(AdaptiveCards.Versions.v1_0, "targetWidth");
@AdaptiveCards.property(CustomElement.targetWidthProperty)
targetWidth?: string;
If I register my component under a different name (e.g. CustomImage) and rename the Images in the json config to CustomImage by new property is processed properly.
It seems like the schema of default elements is somehow cached. If I try to override the Image type the populateSchema() isn't called, if I use my own CustomImage it's called.
I've tried everything, using my own SerializationContext etc. but can't find a solution.
So how are we supposed to add missing features to the default components?
Screenshots
No response
Card JSON
{
"type": "AdaptiveCard",
"$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"text": "Time off request",
"wrap": true,
"size": "Large",
"weight": "Bolder",
"spacing": "None"
},
{
"type": "Image",
"url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Adaptive-Card-Samples/main/samples/time-off-request/assets/hero-image-default.png",
"style": "RoundedCorners",
"targetWidth": "Standard"
},
{
"type": "Image",
"targetWidth": "Wide",
"url": "https://raw.githubusercontent.com/OfficeDev/Microsoft-Teams-Adaptive-Card-Samples/main/samples/time-off-request/assets/hero-wide.png",
"style": "RoundedCorners"
}
]
}
Sample Code Language
TypeScript
Sample Code
import * as AdaptiveCards from "adaptivecards";
import {Image, SerializableObjectSchema, StringProperty} from "adaptivecards";
import {PropertyBag} from "adaptivecards/src/serialization";
export default class AdaptiveCardApi {
private readonly serializationContext: AdaptiveCards.SerializationContext;
constructor() {
// Create a custom registry for elements
let elementRegistry = new AdaptiveCards.CardObjectRegistry<AdaptiveCards.CardElement>();
// Populate it with the default set of elements
AdaptiveCards.GlobalRegistry.populateWithDefaultElements(elementRegistry);
// Parse a card payload using the custom registry
this.serializationContext = new AdaptiveCards.SerializationContext();
this.serializationContext.setElementRegistry(elementRegistry);
const serializationContext = this.serializationContext;
class CustomElement extends OriginalClass {
//#region Schema
static readonly targetWidthProperty = new StringProperty(AdaptiveCards.Versions.v1_0, "targetWidth");
@AdaptiveCards.property(CustomElement.targetWidthProperty)
targetWidth?: string;
//#endregion
protected populateSchema(schema: SerializableObjectSchema) {
// Never logged as never being called
console.log("populateSchema", this.getJsonTypeName(), 'schema', schema);
super.populateSchema(schema);
}
protected internalRender(): HTMLElement | undefined {
const renderedElement = super.internalRender();
// Add our data attribute if targetWidth is present on the model.
if (renderedElement && this.targetWidth) {
renderedElement.classList.add(`ac-${this.targetWidth}`);
}
return renderedElement;
}
}
elementRegistry.register("Image", CustomElement);
}
public createCard(cardConfig: PropertyBag) {
// Create an AdaptiveCard instance
const adaptiveCard = new AdaptiveCards.AdaptiveCard();
// Parse the card payload
adaptiveCard.parse(cardConfig, this.serializationContext);
// Render the card to an HTML element:
return adaptiveCard.render();
}
}