Skip to content

Commit

Permalink
feat(elements): add support for creating custom elements (angular#22413)
Browse files Browse the repository at this point in the history
PR Close angular#22413
  • Loading branch information
andrewseguin authored and mhevery committed Mar 16, 2018
1 parent cedc04c commit 22b96b9
Show file tree
Hide file tree
Showing 34 changed files with 1,823 additions and 17 deletions.
11 changes: 11 additions & 0 deletions .pullapprove.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#
# alexeagle - Alex Eagle
# alxhub - Alex Rickabaugh
# andrewseguin - Andrew Seguin
# brocco - Mike Brocchi
# chuckjaz - Chuck Jazdzewski
# filipesilva - Filipe Silva
Expand Down Expand Up @@ -302,6 +303,16 @@ groups:
- IgorMinar #fallback
- mhevery #fallback

elements:
conditions:
files:
- "packages/elements/*"
users:
- andrewseguin #primary
- gkalpak
- IgorMinar #fallback
- mhevery #fallback

benchpress:
conditions:
files:
Expand Down
1 change: 1 addition & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ filegroup(
"reflect-metadata",
"source-map-support",
"minimist",
"@webcomponents/webcomponentsjs",
"tslib",
] for ext in [
"*.js",
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ The following is the list of supported scopes:
* **compiler**
* **compiler-cli**
* **core**
* **elements**
* **forms**
* **http**
* **language-service**
Expand Down
67 changes: 67 additions & 0 deletions aio/content/guide/elements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Elements

## Release Status

**Angular Labs Project** - experimental and unstable. **Breaking Changes Possible**

Targeted to land in the [6.x release cycle](https://github.com/angular/angular/blob/master/docs/RELEASE_SCHEDULE.md) of Angular - subject to change

## Overview

Elements provides an API that allows developers to register Angular Components as Custom Elements
("Web Components"), and bridges the built-in DOM API to Angular's component interface and change
detection APIs.

```ts
//hello-world.ts
import { Component, Input, NgModule } from '@angular/core';
import { createNgElementConstructor, getConfigFromComponentFactory } from '@angular/elements';

@Component({
selector: 'hello-world',
template: `<h1>Hello {{name}}</h1>`
})
export class HelloWorld {
@Input() name: string = 'World!';
}

@NgModule({
declarations: [ HelloWorld ],
entryComponents: [ HelloWorld ]
})
export class HelloWorldModule {}
```

```ts
//app.component.ts
import { Component, NgModuleRef } from '@angular/core';
import { createNgElementConstructor } from '@angular/elements';

import { HelloWorld } from './hello-world.ngfactory';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(ngModuleRef: NgModuleRef) {
const ngElementConfig = getConfigFromComponentFactory(HelloWorld, injector);
const NgElementConstructor = createNgElementConstructor(ngElementConfig);
customElements.register('hello-world', NgElementConstructor);
}
}

```
Once registered, these components can be used just like built-in HTML elements, because they *are*
HTML Elements!

They can be used in any HTML page:

```html
<hello-world name="Angular"></hello-world>
<hello-world name="Typescript"></hello-world>
```

Custom Elements are "self-bootstrapping" - they are automatically started when they are added to the
DOM, and automatically destroyed when removed from the DOM.
5 changes: 5 additions & 0 deletions aio/content/navigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,11 @@
}
]
},
{
"url": "guide/elements",
"title": "Elements",
"tooltip": "Exporting Angular Components as Web Components"
},
{
"title": "Service Workers",
"tooltip": "Angular service workers: Controlling caching of application resources.",
Expand Down
1 change: 1 addition & 0 deletions aio/tools/transforms/angular-api-package/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
'common/testing/index.ts',
'core/index.ts',
'core/testing/index.ts',
'elements/index.ts',
'forms/index.ts',
'http/index.ts',
'http/testing/index.ts',
Expand Down
5 changes: 3 additions & 2 deletions aio/tools/transforms/authors-package/api-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ const { API_SOURCE_PATH } = require('../config');

const packageMap = {
animations: ['animations/index.ts', 'animations/browser/index.ts', 'animations/browser/testing/index.ts'],
common: ['common/index.ts', 'common/testing/index.ts'],
common: ['common/index.ts', 'common/testing/index.ts', 'common/http/index.ts', 'common/http/testing/index.ts'],
core: ['core/index.ts', 'core/testing/index.ts'],
elements: ['elements/index.ts'],
forms: ['forms/index.ts'],
http: ['http/index.ts', 'http/testing/index.ts'],
'platform-browser': ['platform-browser/index.ts', 'platform-browser/animations/index.ts', 'platform-browser/testing/index.ts'],
'platform-browser-dynamic': ['platform-browser-dynamic/index.ts', 'platform-browser-dynamic/testing/index.ts'],
'platform-server': ['platform-server/index.ts', 'platform-server/testing/index.ts'],
'platform-webworker': ['platform-webworker/index.ts'],
'platform-webworker-dynamic': 'platform-webworker-dynamic/index.ts',
'platform-webworker-dynamic': ['platform-webworker-dynamic/index.ts'],
router: ['router/index.ts', 'router/testing/index.ts', 'router/upgrade/index.ts'],
'service-worker': ['service-worker/index.ts'],
upgrade: ['upgrade/index.ts', 'upgrade/static/index.ts']
Expand Down
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ PACKAGES=(core
compiler-cli
language-service
benchpress
service-worker)
service-worker
elements)

TSC_PACKAGES=(compiler-cli
language-service
Expand Down
9 changes: 9 additions & 0 deletions karma-js.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ module.exports = function(config) {
'test-events.js',
'shims_for_IE.js',
'node_modules/systemjs/dist/system.src.js',

// Serve polyfills necessary for testing the `elements` package.
{
pattern: 'node_modules/@webcomponents/custom-elements/**/*.js',
included: false,
watched: false
},
{pattern: 'node_modules/mutation-observer/index.js', included: false, watched: false},

{pattern: 'node_modules/rxjs/**', included: false, watched: false, served: true},
'node_modules/reflect-metadata/Reflect.js',
'tools/build/file2modulename.js',
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
"@types/shelljs": "^0.7.8",
"@types/source-map": "^0.5.1",
"@types/systemjs": "0.19.32",
"@webcomponents/custom-elements": "^1.0.4",
"@webcomponents/webcomponentsjs": "^1.1.0",
"angular": "npm:angular@1.6",
"angular-1.5": "npm:angular@1.5",
"angular-mocks": "npm:angular-mocks@1.6",
Expand Down Expand Up @@ -87,6 +89,7 @@
"karma-sourcemap-loader": "0.3.6",
"madge": "0.5.0",
"minimist": "1.2.0",
"mutation-observer": "^1.0.3",
"node-uuid": "1.4.8",
"protractor": "5.1.2",
"rewire": "2.5.2",
Expand Down
19 changes: 19 additions & 0 deletions packages/elements/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package(default_visibility = ["//visibility:public"])

load("//tools:defaults.bzl", "ng_module")

ng_module(
name = "elements",
srcs = glob(
[
"*.ts",
"src/**/*.ts",
],
),
module_name = "@angular/elements",
deps = [
"//packages/core",
"//packages/platform-browser",
"@rxjs",
],
)
14 changes: 14 additions & 0 deletions packages/elements/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

// This file is not used to build this module. It is only used during editing
// by the TypeScript language service and during build for verification. `ngc`
// replaces this file with production index.ts when it rewrites private symbol
// names.

export * from './public_api';
22 changes: 22 additions & 0 deletions packages/elements/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@angular/elements",
"version": "0.0.0-PLACEHOLDER",
"description": "Angular - library for using Angular Components as Custom Elements",
"main": "./bundles/elements.umd.js",
"module": "./esm5/elements.js",
"es2015": "./esm2015/elements.js",
"typings": "./elements.d.ts",
"author": "angular",
"license": "MIT",
"dependencies": {
"tslib": "^1.7.1"
},
"peerDependencies": {
"@angular/core": "0.0.0-PLACEHOLDER",
"@angular/platform-browser": "0.0.0-PLACEHOLDER"
},
"repository": {
"type": "git",
"url": "https://github.com/angular/angular.git"
}
}
19 changes: 19 additions & 0 deletions packages/elements/public_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

/**
* @module
* @description
* Entry point for all public APIs of the `elements` package.
*/
export {ComponentFactoryNgElementStrategy, ComponentFactoryNgElementStrategyFactory, getConfigFromComponentFactory} from './src/component-factory-strategy';
export {NgElementStrategy, NgElementStrategyEvent, NgElementStrategyFactory} from './src/element-strategy';
export {NgElement, NgElementConfig, NgElementConstructor, createNgElementConstructor} from './src/ng-element-constructor';
export {VERSION} from './src/version';

// This file only reexports content of the `src` folder. Keep it that way.
31 changes: 31 additions & 0 deletions packages/elements/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

const resolve = require('rollup-plugin-node-resolve');
const sourcemaps = require('rollup-plugin-sourcemaps');

const globals = {
'@angular/core': 'ng.core',
'@angular/platform-browser': 'ng.platformBrowser',
'rxjs/Subscription': 'Rx',
'rxjs/Observable': 'Rx',
'rxjs/observable/merge': 'Rx.Observable',
'rxjs/operator/map': 'Rx.Observable.prototype'
};

module.exports = {
entry: '../../dist/packages-dist/elements/esm5/elements.js',
dest: '../../dist/packages-dist/elements/bundles/elements.umd.js',
format: 'umd',
exports: 'named',
amd: {id: '@angular/elements'},
moduleName: 'ng.elements',
plugins: [resolve(), sourcemaps()],
external: Object.keys(globals),
globals: globals
};
Loading

0 comments on commit 22b96b9

Please sign in to comment.