Angular + Polymer
npm install @codebakery/origami_Origami is the art of folding paper with angles to form beautiful creations._
Angular + Polymer


Angular and custom elements are BFFs. With Polymer, there are a few gaps that Origami fills. The library is divided into several modules that can be imported individually to address these gaps.
- Angular Form Support
- ShadyCSS Support
- Style Modules
- Polymer Stamping
- Polyfill Utilities
To setup Origami, follow these steps:
1. Install and import OrigamiModule
2. Set up polyfills
3. Prepare dependencies if targeting ES5
4. Read the Usage Summary
> Upgrading from Origami v2? Follow this guide.
``sh`
npm install @codebakery/origami
Import each module as described in the links above, or if you need all of the modules you can simply import OrigamiModule. Include CUSTOM_ELEMENTS_SCHEMA to enable custom elements in Angular templates.
`ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
// If @angular/router is not used, import modules individually
// and use IncludeStylesNoRouterModule instead of IncludeStylesModule.
import { OrigamiModule } from '@codebakery/origami';
import { AppComponent } from './app.component';
@NgModule({
imports: [BrowserModule, FormsModule, RouterModule, OrigamiModule],
declarations: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent]
})
export class AppModule {}
`
Polyfills are needed to support browsers that do not support all webcomponent features. To quickly set up polyfills, use the Origami CLI.
`sh`
npm install @webcomponents/webcomponentsjs
./node_modules/.bin/origami polyfill
Some imports (such as Polymer's TemplateStamp mixin) have side effects that require certain features to be immediately available. For example, TemplateStamp expects HTMLTemplateElement to be defined. These imports should be deferred until after webcomponentsReady() resolves.
`ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { webcomponentsReady } from '@codebakery/origami/polyfills';
webcomponentsReady()
.then(() => {
// requires "module": "esnext" in tsconfig.json "compilerOptions" and
// "angularCompilerOptions": {
// "entryModule": "app/app.module#AppModule"
// }
return import('./app/app.module');
})
.then(({ AppModule }) => {
platformBrowserDynamic().bootstrapModule(AppModule);
});
`
Angular will not transpile node_modules/, and a common pattern among webcomponents is to be distributed as ES2015 classes. Use Origami's CLI to effeciently transpile dependencies to ES5 or back to ES2015 before building.
Example:
`sh
origami prepare es5 node_modules/{@polymer/,@vaadin/,@webcomponents/shadycss}
> Note that
@webcomponents/webcomponentsjs should _not_ be transpiled. However, @webcomponents/shadycss _should_ be if it's used.The CLI can also restore the previous ES2015 files for projects that compile to both targets.
It is recommended to add a script before
ng build and ng serve tasks in package.json.`json
{
"scripts": {
"prepare:es5": "origami prepare es5 node_modules/{@polymer/,@vaadin/,@webcomponents/shadycss}",
"prepare:es2015": "origami prepare es2015 node_modules/{@polymer/,@vaadin/,@webcomponents/shadycss}",
"start": "npm run prepare:es5 && ng serve es5App",
"start:es2015": "npm run prepare:es2015 && ng serve es2015App",
"build": "npm run prepare:es5 && ng build es5App --prod",
"build:es2015": "npm run prepare:es2015 && ng build es2015App --prod"
}
}
`Usage Summary
$3
Add the
origami attribute to any custom element using [ngModel], [formControl] or [formControlName].> Requires the
@angular/forms module.`ts
import { Component } from '@angular/core';
import '@polymer/paper-input/paper-input';@Component({
selector: 'app-component',
template:
})
export class AppComponent {
value: string;
}
`$3
Enables the use of CSS custom properties in Angular styles on browsers that do not support them via ShadyCSS, with some limitations.
`ts
import { Component } from '@angular/core';
import '@polymer/paper-button/paper-button';@Component({
selector: 'app-component',
styles: [
],
template:
})
export class AppComponent {}
`$3
Allows for style modules defined in Polymer to be injected into Angular components.
> Requires the
@angular/router module. Use IncludeStylesNoRouterModule if @angular/router is not used.`ts
import { Component } from '@angular/core';
import { IncludeStyles } from '@codebakery/origami/styles';
import '@polymer/iron-flex-layout/iron-flex-layout-classes';@IncludeStyles('iron-flex')
@Component({
selector: 'app-component',
styles: [':host { display: block; }'], // See Limitations
template:
})
export class AppComponent {}
`$3
Call
polymerHost() and add it to the providers for a component that uses Polymer's data binding syntax in elements. Add ngNonBindable to all elements.`ts
import { Component } from '@angular/core';
import { polymerHost } from '@codebakery/origami/templates';
import '@polymer/iron-list/iron-list';@Component({
selector: 'app-component',
template:
,
providers: [polymerHost(AppComponent)]
})
export class AppComponent {
items = [1, 2, 3]; getLabel(item: number) {
return
# ${item};
} itemClicked(event: Event) {
console.log(event);
}
}
``