GithubHelp home page GithubHelp logo

bboyzplatform / origami Goto Github PK

View Code? Open in Web Editor NEW

This project forked from hotforfeature/origami

0.0 1.0 0.0 987 KB

Angular + Polymer

License: MIT License

JavaScript 19.11% TypeScript 80.89%

origami's Introduction

NPM Package Commitizen friendly

Build Status

Origami

Origami is the art of folding paper with sharp angles to form beautiful creations.

Angular + Polymer

Intro

Origami bridges the gap between the Angular platform and Polymer-built web components. This opens up a huge ecosystem of high quality custom elements that can be used in Angular!

"The Gap"

Angular and custom elements are BFFs. There are only a few areas specific to Polymer that Origami can help out with.

  • Angular Template/Reactive Form Support ([(ngModel)])
  • Native <template> elements
  • Seamless production-ready build process

Setup

1. Install Dependencies

npm i --save @codebakery/origami
npm i --save-dev babel-loader babel-core babel-preset-es2015 polymer-webpack-loader script-loader

Origami needs to patch the Angular CLI to insert the webpack loaders that we installed. Modify your package.json and add a postinstall script to create the patch.

package.json

{
  "scripts": {
    "postinstall": "node ./node_modules/@codebakery/origami/patch-cli.js"
  }
}
npm run postinstall

Now anytime you install or update the Angular CLI, Origami will check and apply the patch if needed.

2. Use Bower to add elements

Bower is a flat dependency package manager for web modules. Polymer 2 and many elements are hosted with it.

npm i -g bower
bower init

3. Load polyfills

We're going to use a dynamic loader to only add polyfills if the browser needs them. In order to do this, Angular needs to include all the polyfill scripts at runtime as part of its assets.

Since we'll be referencing these assets in our index.html, they must be part of the app's root directory. A typical Angular CLI-generated project will have a src/ directory that is the app root.

We can move where bower dependencies are installed with a .bowerrc file in the project directory.

.bowerrc

{
  "directory": "src/bower_components/"
}

Now all bower dependencies are available for .angular-cli.json and our index.html. This example is using src/bower_components/ as the directory to install to, but this may be any folder name that exists in the app root directory.

Like node_modules/ you should add src/bower_components/ to your .gitignore file to prevent checking them in.

Now that bower is installing where the project files can see it, install the webcomponents polyfill.

bower install --save webcomponentsjs

Modify .angular-cli.json and add the following to your app's assets.

.angular-cli.json

{
  "apps": [
    {
      "root": "src",
      "assets": [
        "assets",
        "favicon.ico",
        "manifest.json",
        "bower_components/webcomponentsjs/custom*.js",
        "bower_components/webcomponentsjs/web*.js"
      ],
      /* remaining app config */
    }
  ],
  /* remaining CLI config */
}

Next, modify the index.html shell to include the polyfills.

index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Origami</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- This div is needed when targeting ES5. 
  It will add the adapter to browsers that support customElements, which 
  require ES6 classes -->
  <div id="ce-es5-shim">
    <script type="text/javascript">
      if (!window.customElements) {
        var ceShimContainer = document.querySelector('#ce-es5-shim');
        ceShimContainer.parentElement.removeChild(ceShimContainer);
      }
    </script>
    <script type="text/javascript" src="bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
  </div>
  <script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
</head>
<body>
  <app-root>Loading...</app-root>
</body>
</html>

Custom elements must be defined as ES6 classes. The custom-elements-es5-adapter.js script will allow our transpiled elements to work in ES6-ready browsers. webcomponents-loader.js will check the browser's abilities and load the correct polyfill from the bower_components/webcomponentsjs/ folder.

The last piece is to wait to bootstrap Angular until the polyfills are loaded. Modify your main.ts and wait for the polyfills.

main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { webcomponentsReady } from '@codebakery/origami';

import { AppModule } from './app/app.module';

webcomponentsReady().then(() => {
  platformBrowserDynamic().bootstrapModule(AppModule);
});

Angular 4 templates

Angular 4 consumes native <template> tags, which are commonly used in web components. Add the following configuration to the app's bootstrap to prevent this.

main.ts

webcomponentsReady().then(() => {
  platformBrowserDynamic().bootstrapModule(AppModule, {
    enableLegacyTemplate: false // Required for Angular 4 to use native <template>s
  });
});

enableLegacyTemplate: false will prevent Angular 4 from turning native <template> elements into <ng-template>s. Bootstrap options must also be specified in your tsconfig.json for Ahead-of-Time compilation.

tsconfig.app.json

{
  "compilerOptions": {
    ...
  },
  "angularCompilerOptions": {
    "enableLegacyTemplate": false
  }
}

Angular 5+ defaults this value to false. You do not need to include it in your bootstrap function or tsconfig.json.

4. Import Origami

Import Origami into your topmost root NgModule. In any modules where you use custom elements, add CUSTOM_ELEMENTS_SCHEMA to the module. This prevents the Angular compiler from emitting errors on unknown element tags.

app.module.ts

import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { PolymerModule } from '@codebakery/origami';

import { AppComponent } from './app.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule, // Origami requires the Angular Forms module
    PolymerModule.forRoot() // Do not call .forRoot() when importing in child modules
  ],
  declarations: [
    AppComponent
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA], // Add to every @NgModule() that uses custom elements
  bootstrap: [AppComponent]
})
export class AppModule { }

5. Import and use custom elements

Install elements! Persist them to bower.json with the --save flag.

bower install --save PolymerElements/paper-checkbox
bower install --save PolymerElements/paper-input

Next, import the element in the Angular component that you want to use it in. Add the [ironControl] directive to elements that use Angular form directives.

app.component.ts

import { Component } from '@angular/core';

import 'paper-checkbox/paper-checkbox.html';
import 'paper-input/paper-input.html';

@Component({
  selector: 'app-root',
  template: `
    <div>
      <label>Hello from Angular</label>
      <input [(ngModel)]="value">
    </div>
    <paper-input label="Hello from Polymer" ironControl [(ngModel)]="value"></paper-input>

    <div>
      <label>Non-form two-way bindings!</label>
      <input type="checkbox" [(value)]="checked">
    </div>
    <paper-checkbox [checked]="checked" (checked-changed)="checked = $event.detail.value"></paper-checkbox>
  `
})
export class AppComponent {
  value: string;
  checked: boolean;
}

Support

  • Angular 4.2.0 +
  • Polymer 2.0 +

Origami does not support Polymer 1. Check out angular-polymer if you need Polymer 1 support.

Browsers

  • Chrome
  • Safari 9+
  • Firefox
  • Edge
  • Internet Explorer 11

Polymer and Angular support different browsers. Using Polymer means that you will lose support for IE 9 and 10 as well as Safari/iOS 7 and 8.

origami's People

Contributors

borntraegermarc avatar hotforfeature avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.