Instantly share code, notes, and snippets.

View op2-spfx-webpart-custom-element.ts
// polyfill for ES5 code as doesn't include native implementation for customElements
import '@webcomponents/custom-elements/src/native-shim';
// polyfill for browsers that don't support shadowDom & customElements (IE & Edge)
import '@webcomponents/webcomponentsjs/bundles/webcomponents-sd-ce';
// angular elements application
import './app/ngElementsHelloWorld';
export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
public render(): void {
this.domElement.innerHTML = `<app-hello-world message="${ this.properties.description }"></app-hello-world>`;
View gulpfile.js
// add the following before the existing line: build.initialize(gulp);
const webpack = require('webpack');
const path = require('path');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const bundleAnalyzer = require('webpack-bundle-analyzer');
build.configureWebpack.mergeConfig({
additionalConfiguration: (generatedConfiguration) => {
const lastDirName = path.basename(__dirname);
View package.json
// in addition to the SPFx packages, you need the following
"dependencies": {
"@angular/common": "6.1.3",
"@angular/compiler": "6.1.3",
"@angular/core": "6.1.3",
"@angular/elements": "6.1.3",
"@angular/platform-browser": "6.1.3",
"@angular/platform-browser-dynamic": "6.1.3",
"@webcomponents/custom-elements": "1.2.0",
"@webcomponents/webcomponentsjs": "2.1.1",
View op1-spfx-webpart-custom-element.ts
// polyfill for ES5 code as doesn't include native implementation for customElements
import '@webcomponents/custom-elements/src/native-shim';
// polyfill for browsers that don't support shadowDom & customElements (IE & Edge)
import '@webcomponents/webcomponentsjs/bundles/webcomponents-sd-ce';
// polyfill required when using JIT compilation (not required for AOT)
import 'core-js/es7/reflect';
// required when using JIT compilation (not required for AOT)
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
// angular elements application
View angular-elements-web-part.ts
export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
public render(): void {
this.domElement.innerHTML = `<app-hello-world message="${ this.properties.description }"></app-hello-world>`;
// attach to the custom elements 'elementButtonClick` event
this.domElement.getElementsByTagName('app-hello-world')[0]
.addEventListener('elementButtonClick', (event: any) => {
console.log(`The custom element sent the following message: ${ event.detail }`);
});
}
View app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { AppComponent } from './app.component';
@NgModule({
declarations: [ AppComponent ],
imports: [ BrowserModule ],
entryComponents: [ AppComponent ]
})
View add-angular-elements.sh
# using the Angular CLI
ng add @angular/elements
# using a package manager
yarn add @angular/elements
View app.component.ts
import {
Component,
OnInit,
Input,
Output,
EventEmitter
} from '@angular/core';
@Component({
selector: 'app-hello-world',
View jest.config.json
{
"collectCoverage": true,
"coverageDirectory": "<rootDir>/../temp/test",
"coverageReporters": [
"json",
"lcov",
"text-summary"
],
"coverageThreshold": {
"global": {
View jest.config.json
{
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy",
"^resx-strings/en-us.json": "<rootDir>/node_modules/@microsoft/sp-core-library/lib/resx-strings/en-us.json"