Polymer &Web Components – Getting Started With Polymer – Existing Approaches



Polymer &Web Components – Getting Started With Polymer – Existing Approaches

0 0


nerdsummit-2015-polymer


On Github petejohanson / nerdsummit-2015-polymer

Polymer &Web Components

Getting Started With Polymer

Pete Johanson / @petejohanson

ApplicationsExisting FrameworksWeb Components (Polymer?)Web Platform
  • Web Components a layer directly above the DOM: fundamental building blocks like standard DOM elements
  • Polymer is syntactic sugar + databinding, eventing on top of Web Components

No Panacea

  • 'Evergreen' browsers only
  • Browser support is still sketchy. Polyfills needed
  • Performance improving with things like Polymer 'shady DOM' polyfill
  • Not suited for high level concepts. Inter-component communication is primitive (events)

Considerations

  • Progressive Enhancement Challenges
  • Server Side Rendering?
  • Browser Support

Existing Approaches

<head>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  <script>
  $(function() {
    $( "#menu" ).menu({ disabled: true });
  });
  </script>
</head>
<body>

<ul id="menu">
	<li>Item 1</li>
	<li>Item 2</li>
</ul>
						
  • Less semantic meaning.
  • CSS is global, so element authors need to be careful
  • Behaviour/config is disjoint from DOM. Not declarative.

Polymer

<head>
	<link rel="import" href="paper-item/paper-item.html">
	<link rel="import" href="paper-menu/paper-menu.html">
<head>

<body>
	<paper-menu selected="1">
		<paper-item>Item 1</paper-item>
		<paper-item>Item 2</paper-item>
	</paper-menu>
</body>
						
  • CSS is scoped to the local DOM
  • Can provide more semantic meaning
  • Declarative customization/configuration with attributes

Features

  • Declared Properties
  • Local/Light DOM
  • Data Binding
  • Events
  • Scoped Styles and Custom CSS Properties

Declared Properties

Polymer({
	is: 'my-gravatar',
	properties: {
		email: String,
		size: {
			type: String,
			value: ''
		},
		/* ... */
	}
});
						

Computed Properties

Polymer({
	is: 'my-gravatar',

	properties: {
		email: String,
		size: String,
		imgsrc: {
			type: String,
			computed: 'computeImageSource(email, size)'
		}
	},

	computeImageSource: function(email, size) {
		return ...;
	}
});
						

Change Notification

Needed for two-way data binding

Polymer({
	is: 'my-chooser',

	properties: {
		choice: {
			type: String,
			notify: true,
		}
	},
});
						

Local (Shadow) DOM

<dom-module id="my-gravatar">
	<template>
		<img src="{{imgsrc}}">
	</template>
	...
</dom-module>
						
  • Shady DOM used for now, until native implementations

Automatic Node Finding

<dom-module id="my-gravatar">
	<template>
		<img id="gravatar">
	</template>
	<script>
		Polymer({
			is: 'my-gravatar',
			ready: function() {
				this.$.gravatar.src = '//gravatar.com/avatar/abcdef';
			}
		});
	</script>

</dom-module>
						
  • Only Static Nodes

DOM Manipulation

Local DOM

var toLocal = document.createElement('div');
var beforeNode = Polymer.dom(this.root).childNodes[0];
Polymer.dom(this.root).insertBefore(toLocal, beforeNode);
						

Light DOM

Polymer.dom(this).appendChild(document.createElement('div'));
var allSpans = Polymer.dom(this).querySelectorAll('span');
							
  • this.root for local DOM
  • Custom API needed to maintain DOM w/ shady DOM

Light DOM

<dom-module id="my-strongbad">
	<template>
		<strong><content></content></strong>
	</template>
	...
</dom-module>
						
<my-strongbad>Deleted!</my-strongbad>
						

Data Binding

<dom-module id="my-gravatar">
	<template>
		<input type="text" value={{email::input}}></input>
		<input type="text" value={{size::input}}></input>
		<img src="{{imgsrc}}">
	</template>
	...
</dom-module>
						

One-Way vs Two-Way Bindings

<template>
	<my-gravatar email="[[email]]"></my-gravatar>
</template>
						
<template>
	<my-chooser choice="{{choice}}"></my-chooser>
</template>

One-Way Binding

Host-To-Child

<template>
	<my-gravatar email="[[email]]"></my-gravatar>
	<input type="text" value="{{email::input}}">
</template>
<script>
	Polymer({
		is: 'my-element',
		properties: {
			email: String,
		},
	});
</script>
						
  • Flow's from host down to child
  • Cannot modify host env value

Two-Way Binding

Bi-directional between child and host

<template>
	<my-chooser choice="{{type}}"></my-chooser>
</template>
<script>
	Polymer({
		is: 'my-element',
		properties: {
			type: String,
		},
	});
</script>

Events

  • Declarative event listeners
  • Annotated event listeners
  • Custom Event Firing

Declarative Event Listeners

Polymer({
	is: 'x-custom',

	listeners: {
		'tap': 'regularTap',
		'special.tap': 'specialTap'
	},

	regularTap: function(e) {
		alert("Thank you for tapping");
	},
	specialTap: function(e) {
		alert("It was special tapping");
	}
});
						
  • can hook up id's element from this.$ map

Annotated Event Listeners

<button on-click="buttonClick">Click Me</button>
						

Event Firing

<dom-module id="x-custom">
	<template>
		<button on-click="handleClick">Kick Me</button>
	</template>

	<script>

		Polymer({
			is: 'x-custom',

			handleClick: function(e, detail) {
				this.fire('kick', {kicked: true});
			}
		});

	</script>
</dom-module>
						

Styling

Scoped Styles

<template>
	<style>
		:host { /* Selector to style the host DOM element */
			display: block;
		}

		.content-wrapper > ::content .warning { /* Light DOM */
			color: red;
		}
	</style>

	<div class="content-wrapper"><content></content></div>
</template>
						
  • Host selector
  • ::content requires selector to the left (shady DOM)

Cross Scope Styles

"Theming"

<template>
	<style>
		:host { /* Selector to style the host DOM element */
			display: block;
		}

		.content-wrapper > ::content .warning { /* Light DOM */
			color: var(--my-element-warning-color, red);
		}
	</style>

	<div class="content-wrapper"><content></content></div>
</template>
						
  • Value defined anywhere in the parent hierarchy
  • like font settings

CSS Mixins

<template>
	<style>
		:host { /* Selector to style the host DOM element */
			display: block;
			@apply(--my-element-theme);
		}
	</style>
</template>
						
<style>
	:host {
		--my-element-theme {
			background-color: green;
		}
	}
</style>
						
  • Allows complete theming not anticipated.

Element Catalog

Polymer Starter Kit

  • Best Practices Baked In
  • Build
  • Offline Support
  • Testing
$ wget https://github.com/PolymerElements/polymer-starter-kit/releases/download/v1.0.3/polymer-starter-kit-1.0.3.zip
$ unzip polymer-starter-kit-1.0.3.zip
$ cd polymer-starter-kit-1.0.3
$ npm install && bower install
$ gulp serve
						

Slides

http://petejohanson.github.io/nerdsummit-2015-polymer
Polymer &Web Components Getting Started With Polymer Pete Johanson / @petejohanson