Search code examples
javascripttypescriptadaptive-cards

How can I override rendering labels when extending Input Elements for Adaptive Cards (JS)


We are using the Adaptive Cards JS SDK for rendering Adaptive Cards in Angular. We want to make the Adaptive Cards render the Elements as Angular Material Design Components. For this I am following the Extensibility guidelines for Custom Inputs.

Here I see that we should override the protected updateInputControlAriaLabelledBy() to correctly set the aria-labelledby attribute, but actually what I want is to rely on the default labels provided by Angular Material Design Inputs.

Is there a way to prevent the SDK from rendering the labels as separate elements in the cards?

Looking in the SDK source: Maybe I am already answering my own question by pointing out that I did find this code, where it seems to always create this label element as a separate element above the actual input.

Work around?: The only work around I found so far, is to add a new property to my custom input: inlineLabel, then when that property is set, and no label is provided, I can use that to render the label inside the Material Input. But ofcourse I don't like this, because actually I would like to stick to the standard, and be able to override the behaviour of label.


Solution

  • There is no explicit support for overriding the rendering of the label, and we should seriously think about adding such support.

    There is a workaround though, although it's a hack and I haven't explicitly tested it. In your custom input:

    • Declare a private _labelCopy?: string field
    • Override the overrideInternalRender() method as shown below
    • In your internalRender implementation, use the value of _labelCopy (because by the time it is called, label will be undefined)
    private _labelCopy?: string;
    
    protected overrideInternalRender(): HTMLElement | undefined {
        this._labelCopy = this.label;
    
        // Reset the label property temporarily so that
        // overrideInternalRender doesn't render a label
        this.label = undefined;
    
        // The base overrideInternalRender implementation will
        // call internalRender, which can then render the label
        // using the value of the _labelCopy field
        let renderedElement = super.overrideInternalRender();
    
        // Restore the label property
        this.label = this._labelCopy;
    
        return renderedElement;
    }
    

    Please let me know if that solved your problem.