3

I'm trying to create a set of Angular Elements using Angular Material. When I run the Angular app everything works just fine. However, once I export my element the things using Angular Material just break.

This is what is in my component

<div fxLayout="row" fxLayoutGap="15px">

  <mat-form-field appearance="outline">
    <mat-label>First Name</mat-label>
    <input matInput type="text" />
  </mat-form-field>

  <mat-form-field appearance="outline">
    <mat-label>Last Name</mat-label>
    <input matInput type="text" />
  </mat-form-field>

</div>

<button mat-raised-button color="primary">Submit</button>

When I run this inside my Angular project it looks as I expected it to (Note: to run this I replaced the body of the index.html in the Angular project with my test-element tag)

Screenshot of Angular element running inside Angular project

So then I try to export it using Angular elements. I ran ng add @angular/elements and added the following to my app.module.ts

@NgModule({
  declarations: [
    AppComponent,Ï
    TestElementComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatButtonModule,
    MatInputModule,
    FlexLayoutModule,
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  providers: [],
  // bootstrap: [AppComponent],
})
export class AppModule {
  constructor(private injector: Injector) {}

  ngDoBootstrap() {
    const elements = [
      { name: 'test-element', component: TestElementComponent },
    ];

    // I plan on adding a bunch of elements which I why I have the for loop
    for (let i = 0; i < elements.length; i++) {
      const element = elements[i];

      const ngElement = createCustomElement(element.component, {
        injector: this.injector,
      });
      customElements.define(element.name, ngElement);
    }
  }
}

I will note, I tried to also move this to the main.ts file in the .then of the platformBrowserDynamic().bootstrapModule(AppModule) and I got the same result.

Then I have the concat script as well

const fs = require("fs-extra");
const concat = require("concat");

(async function () {
  const files = [
    "./dist/elements-demo/runtime.js",
    "./dist/elements-demo/main.js",
    "./dist/elements-demo/polyfills.js",
  ];

  await fs.ensureDir("elements");
  await concat(files, "elements/elements.js");
  await fs.copyFile("./dist/elements-demo/styles.css", "elements/styles.css");
})();

Then I have the build:elements script ng build --output-hashing none && node concat.js

So I create a plain HTML page and try to use the element

<!DOCTYPE html>
<html>
  <title>Elements Demo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link
    href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
    rel="stylesheet"
  />
  <link
    href="https://fonts.googleapis.com/icon?family=Material+Icons"
    rel="stylesheet"
  />

  <body>
    <h1>Customer's Website</h1>

    <test-element></test-element>

    <script src="http://localhost:8080/elements/elements.js"></script>
  </body>
</html>

This basically gives me a completely blank page: Elements not working after being using in a non-angular HTML page

I've also tried including <link href="http://localhost:8080/elements/styles.css" rel="stylesheet" /> as well, but that doesn't work. I've tried using <link href="https://unpkg.com/@angular/material@12.2.12/prebuilt-themes/indigo-pink.css" rel="stylesheet"/> and nothing changes.

Here are the versions of everything I am using

  "dependencies": {
    "@angular/animations": "~12.2.0",
    "@angular/cdk": "^12.2.12",
    "@angular/common": "~12.2.0",
    "@angular/compiler": "~12.2.0",
    "@angular/core": "~12.2.0",
    "@angular/elements": "^12.2.13",
    "@angular/flex-layout": "^12.0.0-beta.35",
    "@angular/forms": "~12.2.0",
    "@angular/material": "^12.2.12",
    "@angular/platform-browser": "~12.2.0",
    "@angular/platform-browser-dynamic": "~12.2.0",
    "@angular/router": "~12.2.0",
    "concat": "^1.0.3",
    "document-register-element": "^1.7.2",
    "rxjs": "~6.6.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
  },

EDIT

I tried using the ShadowDOM for view encapsulation and that KIND OF worked.

Exported using Shadow DOM

I went through all the combinations of things I tried using the Shadow DOM for view encapsulation but the screenshot above is what I got every time.

1 Answers1

0

In Angular 15, icons showed up when encapsulation is set for the component to Viewencapsulation.Emulate with font library included on the parent page.

dreadstar
  • 13
  • 4