Create custom element in angular 6

1) Create Angular Project

ng new <project name> --prefix custom --style=scss --skip-tests

2) Use schematics to add angular element support

ng add @angular/elements

3) Use angular-cli to generate new component and specify encapsulation is ViewEncapsulation.Native
4) Assume the custom element uses Bootstrap 4 for styling. Then, import Bootstrap Sass in scss file of the component.

$icon-font-path: "../../../../node_modules/bootstrap-sass/assets/fonts/bootstrap/";
@import "~bootstrap/scss/bootstrap";

5) app.module.ts does not bootstrap AppComponent

  1. @NgModule({
  2.   declarations: [AppComponent],
  3.   imports: [
  4.     BrowserModule,
  5.     FormsModule,
  6.     HttpClientModule,
  7.     NgbModule.forRoot(),
  8.     TimeZoneModule
  9.   ],
  10.   providers: [],
  11.   bootstrap: []
  12. })
  13. export class AppModule {
  14.   constructor(private injector: Injector) {}
  15.  
  16.   ngDoBootstrap() {
  17.     const timeConverterElement = createCustomElement(InputTimeFormComponent, {
  18.       injector: this.injector
  19.     });
  20.     customElements.define("time-converter", timeConverterElement);
  21.   }
  22. }

6) Build a nodeJS script to concatenate runtime.js, polyfill.js, script.js, main.js into time-converter.js. The time-converter.js can be used in other JS Frameworks and static website.

  1.  
  2. const fs = require("fs-extra");
  3. const concat = require("concat");
  4. (async function build() {
  5.   const files = [
  6.     "./dist/ng-time-converter/runtime.js",
  7.     "./dist/ng-time-converter/polyfills.js",
  8.     "./dist/ng-time-converter/scripts.js",
  9.     "./dist/ng-time-converter/main.js"
  10.   ];
  11.   await fs.ensureDir("elements");
  12.   await fs.emptyDir("elements");
  13.   await concat(files, "elements/time-converter.js");
  14.   await fs.copyFile(
  15.     "./dist/ng-time-converter/styles.css",
  16.     "elements/styles.css"
  17.   );
  18.   await fs.copy("./dist/ng-time-converter/assets/", "elements/assets/");
  19.   await fs.copyFile("./src/demo.html", "elements/index.html");
  20.   await fs.copyFile("CNAME", "elements/CNAME");
  21. })();