Create Element with Polymer 2

Want to create your first web element with Polymer 2? This post provides a step-by-step tutorial for you: Polymer CLI, useful websites, Polymer element's structure, dependency management, AJAX requ...

Polymer Logo

Today I’d like to share how I created my first element with Polymer 2. This post covers the following topics:

Before getting started, you need to ensure you’ve npm, bower and Polymer CLI installed in your machine. For example, in Mac OS:

brew install node
npm install -g polymer-cli@1.6.0
npm install -g bower@1.8.4

I fixed the version of Polymer and bower to adapt Nuxeo’s requirement. However, you might want to adjust them, or simply take the latest version.

Init Polymer Element

Initialize a Polymer element using Polymer CLI:

$ polymer init

It will ask you “Which starter template would you like to use?”, you can choose:

  • polymer-2-element - A simple Polymer 2.0 element template
  • polymer-2-application - A simple Polymer 2.0 application
  • polymer-2-starter-kit - A Polymer 2.x starter application template, with navigation and “PRPL pattern” loading
  • shop - The “Shop” Progressive Web App demo

I chose polymer-2-element. Once chosen, Polymer CLI will run bower install for you to install the required dependencies. Now, you can start the development using polymer-serve:

polymer-demo $ polymer serve
info:    Files in this directory are available under the following URLs
      applications: http://127.0.0.1:8081
      reusable components: http://127.0.0.1:8081/components/polymer-demo/

Useful Resources

Web components (https://www.webcomponents.org/) are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. Custom components and widgets build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML. You can find the elements you want on this website, see its documentation, demos, dependencies, and its popularity. It helps you to measure how close a component fits your requirement.

  • documentation
  • demos
  • dependencies
  • popularity

MDN Web APIs (https://developer.mozilla.org/en-US/docs/Web/API). When writing code for the Web with JavaScript, there are a great many APIs available. MDN provides a list of all the interfaces (that is, types of objects) that you may be able to use while developing your Web app or site.

  • documentation
  • demos
  • browser supports

Understand Polymer Element

Once you’ve create the structure of a Polymer Element, you will want to understand how it works. This sections describes how to do it using your browser console (I’m taking Chrome as example).

Inspect Elements

You can inspect the elements inside the shadow DOM. The source code is available in browser console:

<polymer-demo>
  #shadow-root (open)
  <style>
    :host {
      display: block;
    }
  </style>
  <h2>Hello polymer-demo!</h2>
</polymer-demo>

Query Shadow DOM

You can test you element by querying its shadow DOM. This is also done in the browser console:

$('polymer-demo').shadowRoot

Query host property prop1:

$('polymer-demo').shadowRoot.root.prop1
// polymer-demo

Query local DOM style sheets:

$('polymer-demo').shadowRoot.styleSheets
// StyleSheetList {0: CSSStyleSheet, length: 1}

More information can be found on MDN: ShadowRoot - Web APIs.

Automatic Node Binding

Polymer automatically builds a map of statically created instance nodes in its local DOM, to provide convenient access to frequently used nodes without the need to query for them manually. Any node specified in the element’s template with an id is stored on the this.$ hash by id.

For example, given the following template:

<template>
  <p id="description">Hello Polymer.</p>
</template>

You can find the description inside the local DOM:

this.$.description.textContent;

Or outside the local DOM, such as in browser console:

$('polymer-demo').$.description.textContent;
// "Hello Polymer."

Events

Elements use events to communicate state changes up the DOM tree to parent elements. Polymer elements can use the standard DOM APIs for creating, dispatching, and listening for events. Polymer also provides annotated event listeners, which allow you to specify even listeners declaratively as part of the element’s DOM template.

To add even listener to local DOM children, user on-<event> annotatons in your template:

<myElement on-myEvent="myFunc">
  ...
</myElement>

Then write a function the handle such event in your element:

class MyElement extends Polymer.Element {
  myFunc(myEvent) { ... }
}

But, which events can I use?

There’re several resources that can help you. Firstly, MDN: Event reference. This article offers a list of events that can be sent; some are standard events defined in official specifications, while others are events used internally by specific browsers. Secondly, check the JSDoc of the target element (or its parent element), all the events are document as @event. For example, the iron-overlay-behavior, it has events iron-overlay-opened, iron-overlay-canceled, and iron-overlay-closed:

/**
 * Fired after the overlay opens.
 * @event iron-overlay-opened
 */

/**
 * Fired when the overlay is canceled, but before it is closed.
 * @event iron-overlay-canceled
 * ...
 */

/**
 * Fired after the overlay closes.
 * @event iron-overlay-closed
 * ...
 */

For more detail, see Polymer 2.0 - Handle and fire events.

Dependency Management

Polymer CLI 1.6 uses Bower for dependency management. You need to declare your dependencies in bower.json. There’re two kinds of dependencies: dependencies and devDependencies.

  • devDependencies are for the development-related scripts, e.g. unit testing, packaging scripts, documentation generation, etc.
  • dependencies are required for production use, and assumed required for dev as well.

The structure of bower.json file, generated by Polymer CLI, is as follows. You can add new dependency to either dependencies or devDependencies based on your need.

{
  "name": "polymer-demo",
  "main": "polymer-demo.html",
  "dependencies": {
    "polymer": "Polymer/polymer#^2.0.0"
  },
  "devDependencies": {
    "iron-demo-helpers": "PolymerElements/iron-demo-helpers#^2.0.0",
    "web-component-tester": "Polymer/web-component-tester#^6.0.0",
    "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0"
  },
  "resolutions": {
    "polymer": "^2.0.0"
  }
}

New developers (like me) might feel difficult to understand the semantic versioning of npm — for example ^2.0.0, or ~2.2. The best way to start is to use npm semver calculator (https://semver.npmjs.com/), which provides concrete examples for you.


The following sections are advanced configurations.

AJAX Request

Proxy in Polymer CLI. When developing AJAX in element with Polymer CLI, you need to provide a proxy to redirect all requests. Use --proxy-path to define the top-level path that should be redirected to the proxy-target. e.g. api/v1 when you want to redirect all requests of https://localhost/api/v1/; use --proxy-target to define host URL to proxy to:

$ polymer serve \
  --proxy-path='api/v1' \
  --proxy-target='https://localhost:8080/api/v1/'

References