salvo
salvo

Reputation: 73

StencilJs/Jsx: render HTMLElements in nested component

This is my component:

@Component({
  tag: "my-alert-list",
  styleUrl: "alert-list.scss",
  shadow: true,
})
export class AlertList {
  @State() alertList: object[] = [];

  @Method()
  async appendAlert(
    type: string,
    message: string,
    htmlContent: object,
    canClose: boolean = false,
    closeDelay: number
  ) {
    let alertBoxElement = (
      <my-alert-box
        alert-type={type}
        message={message}
        can-close={canClose}
        close-delay={closeDelay}
        opened
      >
      {htmlContent}
      </my-alert-box>
    );
    this.alertList = [
      ...this.alertList,
      alertBoxElement
    ]
  }


  render() {
    return (
      <Host>
        {this.alertList}
      </Host>
    );
  }
}

The method appendAlert aims to append a new my-alert-box element to the list of alerts. In same case i don't want to pass a simple text to the my-alert-box but some HTML block. (my-alert-box has a receiver slot element and i verified that it works). I tried to achieve this with the htmlContent variable as you can see, but of course it doesn't work if i do:

$('#alertlist')[0].appendAlert(type='info',message='', htmlContent=document.createElement('div'))

I receive the error:

[STENCIL-DEV-MODE] vNode passed as children has unexpected type. Make sure it's using the correct h() function. Empty objects can also be the cause, look for JSX comments that became objects.

Any idea on how can i achieve this?

Upvotes: 1

Views: 2217

Answers (1)

Simon H&#228;nisch
Simon H&#228;nisch

Reputation: 4968

It's not possible like this because JSX works differently. You could pass the htmlContent as a string and use innerHTML on my-alert-box but it's dangerous (XSS).

Ionic's ion-alert has the same limitation with the message prop... see https://ionicframework.com/docs/api/alert#properties which has a link to https://ionicframework.com/docs/techniques/security, and there they explain how they do some basic DOM sanitization (@ionic/core is also built with Stencil).

Upvotes: 2

Related Questions