├── .gitignore ├── tsconfig.json ├── src ├── index.ts ├── button.module.ts └── button.component.ts ├── README.md ├── index.html ├── webpack.config.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /dist/ -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "sourceMap": true, 5 | "experimentalDecorators": true, 6 | "emitDecoratorMetadata": true, 7 | "moduleResolution": "node", 8 | "target": "es2015", 9 | "lib": ["es2017", "dom"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import 'zone.js/dist/zone'; 2 | 3 | import '@webcomponents/custom-elements/src/native-shim'; 4 | 5 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 6 | import { ButtonModule } from './button.module'; 7 | 8 | platformBrowserDynamic().bootstrapModule(ButtonModule); 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web Components with Angular 6 Elements 2 | 3 | The simplest setup, built from scratch. 4 | 5 | Commands: 6 | - `npm run build` to create a build of a sample component 7 | - `npm run serve` to run a http-server with example usage (click the button, watch the devtools console) 8 | 9 | Read the complete walkthrough in the article: [Wanna create Angular Elements? Here’s how!](https://medium.com/@tomsu/wanna-create-an-angular-element-heres-how-73e2ea85bd28) 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Custom Button Test Page 7 | 8 | 9 | 10 | 11 | 12 | 13 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/button.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, Injector } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { createCustomElement } from '@angular/elements'; 4 | import { ButtonComponent } from './button.component'; 5 | 6 | @NgModule({ 7 | imports: [BrowserModule], 8 | declarations: [ButtonComponent], 9 | entryComponents: [ButtonComponent] 10 | }) 11 | export class ButtonModule { 12 | constructor(private injector: Injector) { 13 | const customButton = createCustomElement(ButtonComponent, { injector }); 14 | customElements.define('custom-button', customButton); 15 | } 16 | 17 | ngDoBootstrap() {} 18 | } 19 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const NgCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin; 3 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 4 | const CompressionPlugin = require('compression-webpack-plugin'); 5 | 6 | module.exports = { 7 | module: { 8 | rules: [ 9 | { 10 | test: /\.ts$/, 11 | loader: '@ngtools/webpack' 12 | } 13 | ] 14 | }, 15 | resolve: { 16 | extensions: ['.ts', '.js'] 17 | }, 18 | plugins: [ 19 | new NgCompilerPlugin({ 20 | tsConfigPath: './tsconfig.json', 21 | mainPath: './src/index.ts' 22 | }), 23 | new UglifyJsPlugin(), 24 | new CompressionPlugin() 25 | ], 26 | mode: 'production', 27 | stats: 'errors-only' 28 | }; 29 | -------------------------------------------------------------------------------- /src/button.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Input, 3 | Component, 4 | ViewEncapsulation, 5 | EventEmitter, 6 | Output 7 | } from '@angular/core'; 8 | 9 | @Component({ 10 | selector: 'custom-button', 11 | template: ``, 12 | styles: [ 13 | ` 14 | button { 15 | border: solid 3px; 16 | padding: 8px 10px; 17 | background: #bada55; 18 | font-size: 20px; 19 | } 20 | ` 21 | ], 22 | encapsulation: ViewEncapsulation.Native 23 | }) 24 | export class ButtonComponent { 25 | @Input() label = 'default label'; 26 | @Output() action = new EventEmitter(); 27 | private clicksCt = 0; 28 | 29 | handleClick() { 30 | this.clicksCt++; 31 | this.action.emit(this.clicksCt); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-elements", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "@angular/common": "^6.0.0-rc.6", 8 | "@angular/compiler": "^6.0.0-rc.6", 9 | "@angular/core": "^6.0.0-rc.6", 10 | "@angular/elements": "^6.0.0-rc.6", 11 | "@angular/platform-browser": "^6.0.0-rc.6", 12 | "@angular/platform-browser-dynamic": "^6.0.0-rc.6", 13 | "@webcomponents/custom-elements": "^1.1.0", 14 | "core-js": "^2.5.5", 15 | "rxjs": "^6.0.0", 16 | "zone.js": "^0.8.26" 17 | }, 18 | "devDependencies": { 19 | "@angular/compiler-cli": "^6.0.0-rc.6", 20 | "@ngtools/webpack": "^6.0.0-beta.6", 21 | "compression-webpack-plugin": "^1.1.11", 22 | "http-server": "^0.11.1", 23 | "typescript": "~2.7.2", 24 | "uglifyjs-webpack-plugin": "^1.2.5", 25 | "webpack": "^4.6.0", 26 | "webpack-cli": "^2.1.2" 27 | }, 28 | "scripts": { 29 | "build": "webpack", 30 | "serve": "http-server --gzip" 31 | }, 32 | "keywords": [], 33 | "author": "", 34 | "license": "ISC" 35 | } 36 | --------------------------------------------------------------------------------