I'm going to get in touch with Angular Elements on Angular 7 to build lightweight web components which can be simply deployed in existing web pages. First tests were promising however I've got a display trouble with dialogs based on Angular Material (MatDialog). If I build the Angular component (FilterComponent) as Angular element and run the generated web component in a simple HTML5 web page the dialog box is displayed directly on the base web page instead of a detached box.

I use the currently stable version of Angular/cli 7.3.8.

app.module.ts:

@NgModule({
  declarations: [
    AppComponent,
    SearchElementComponent,
    FilterDialogComponent,
    FilterComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    MaterialModule,
    ReactiveFormsModule,
  ],
  entryComponents: [SearchElementComponent, FilterComponent, FilterDialogComponent]
})
export class AppModule {
  constructor(private injector: Injector) {
  }

  ngDoBootstrap() {
    // Convert `SearchElementComponent` to a custom element.
    const SearchElementElement = createCustomElement(SearchElementComponent, {injector: this.injector});
    // Register the custom element with the browser.
    customElements.define('search-element', SearchElementElement);

    const FilterComponentElement = createCustomElement(FilterComponent, {injector: this.injector});
    customElements.define('filter-element', FilterComponentElement);
  }
}

filter.component.ts:

@Component({
  selector: 'app-filter',
  template: `
    <button mat-mini-fab class="filer-button" (click)="openFilterDialog()" title="Filter">
      <i class="material-icons filter-icon">filter_list</i>
    </button>
  `,
  styleUrls: ['./filter.component.css'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class FilterComponent {
  topicMedical = true;
  topicPharma = true;
  topicBiotec = true;

  constructor(
    public dialog: MatDialog,
  ) { }

  public openFilterDialog(): void {
    const dialogRef = this.dialog.open(FilterDialogComponent, {
      panelClass: 'filterDialog',
      autoFocus: false,
      minWidth: 350,
      maxWidth: '60%',
      maxHeight: '45%',
      data: {
        topicMedical: this.topicMedical,
        topicPharma: this.topicPharma,
        topicBiotec: this.topicBiotec,
      }
    });
    dialogRef.afterClosed().subscribe(data => {
      console.log('Filter dialog closed. ');
    });
  }
}

filter-dialog.component.ts:

@Component({
  selector: 'app-filter-dialog',
  templateUrl: './filter-dialog.component.html',
  styleUrls: ['./filter-dialog.component.css'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class FilterDialogComponent {


  constructor(
    public dialogRef: MatDialogRef<FilterDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: FilterDialogData) { }

  onNoClick(): void {
    this.dialogRef.close();
  }

}

Does anybody has a hint for me why does the dialog box not work as expected?

Displayed as expected as regular Angular app Display as expected as regular Angular app

However: Displayed as Angular Element / web component in a simple web page - not detached dialog box Display as Angular Element - not detached dialog box

I will appreciate all your comments :-)

0 Answers