Polytechnic speaker deck oluwadamilare

Preview:

Citation preview

GDG UI Devfest, November 2014

+Ibrahim Oluwadamilare@IODamilare

#itshackademic

@polymer

AgendaOverviewComponentsJoin the revolution

Web Components: Overview

What problems are we solving?

@polymer

#itshackademic

http://drbl.in/esYL

Building UI tabsshould be easy!

@polymer

#itshackademic

@polymer

#itshackademic

@polymer

#itshackademic

@polymer

#itshackademic

@polymer

#itshackademic

<paper-tabs> <paper-tab>KNOWLEDGE</paper-tab> <paper-tab>HISTORY</paper-tab> <paper-tab>FOOD</paper-tab></paper-tabs>

Less Code. Less confusion.

Web Components

What are Web Components?

Custom Elementsdefine new HTML/DOM elements

<paper-tabs selected=“1”> <paper-tab>Tab 1</paper-tab> <paper-tab>Tab 2</paper-tab> <paper-tab>Tab 3</paper-tab></paper-tabs>

declarative, readablemeaningful HTMLcommon way to extend → reusable

Custom Elementsdefine new HTML

@polymer

#itshackademic

declarative, readablemeaningful HTMLcommon way to extend → reusable

Custom Elementsdefine new HTML

var tabs = document.querySelector('paper-tabs');tabs.addEventListener('core-activate', function() { console.log(this.selected);});

@polymer

#itshackademic

Templatesnative client-side templating

<template> <div class=“comment”> <img src=“image.png”> </div> <script>...</script></template>

use DOM to scaffold DOM → no XSS

content is inert until cloned/useddoc fragment → not part of the page

HTML Templatesnative client-side templates

parsed, not rendered

@polymer

#itshackademic

Shadow DOMDOM/CSS scoping

<video src=“foo.webm” controls></video>

@polymer

#itshackademic

<video src=“foo.webm” controls></video>

Actually Shadow DOM

@polymer

#itshackademic

<video src=“foo.webm” controls></video>

HTML Importsloading web components

@polymer

#itshackademic

@polymer

#itshackademic

Custom ElementsCreate new HTML elements and extend existing ones

TemplatesNative templating in the browser

Shadow DOMScoped CSS!!! + encapsulated markup

HTML ImportsLoad custom element definitions and resources

@polymer

#itshackademic

@polymer

#itshackademic

@polymer

#itshackademic

@polymer

#itshackademic

Browser supportSummer 2014

Polyfills Web Componentswith platform.js

Adds syntactic “sugar”with polymer.js

Browser supportSummer 2014 (with Polymer)

Browser supportSummer 2014 (with Polymer)

Sugaring: Custom Elements

vanilla

polymer

<polymer-element name=“paper-tabs”> …</polymer-element>

usage

<paper-tabs>…</paper-tabs>// document.createElement(‘paper-tabs’);

document.registerElement(‘paper-tabs’, { prototype: Object.create(HTMLElement.prototype)});

@polymer

#itshackademic

document.registerElement(‘paper-tabs’, { prototype: Object.create(HTMLElement.prototype)});

vanilla

polymer

<polymer-element name=“paper-tabs”> …</polymer-element>

usage

<paper-tabs>…</paper-tabs>// document.createElement(‘paper-tabs’);

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“paper-tabs”> …</polymer-element>

usage

<paper-tabs>…</paper-tabs>// document.createElement(‘paper-tabs’);

document.registerElement(‘paper-tabs’, { prototype: Object.create(HTMLElement.prototype)});

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“paper-tabs”> …</polymer-element>

usage

<paper-tabs>…</paper-tabs>// document.createElement(‘paper-tabs’);

document.registerElement(‘paper-tabs’, { prototype: Object.create(HTMLElement.prototype)});

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“super-button” extends=“button”> …</polymer-element>

usage

<button is=“super-button”>…</button>// document.createElement(‘button’, ‘super-button’);

document.registerElement(‘super-button’, { prototype: Object.create(HTMLButtonElement.prototype), extends: ‘button’});

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“super-button” extends=“button”> …</polymer-element>

usage

<button is=“super-button”>…</button>// document.createElement(‘button’, ‘super-button’);

document.registerElement(‘super-button’, { prototype: Object.create(HTMLButtonElement.prototype), extends: ‘button’});

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“super-button” extends=“button”> …</polymer-element>

usage

<button is=“super-button”>…</button>// document.createElement(‘button’, ‘super-button’);

document.registerElement(‘super-button’, { prototype: Object.create(HTMLButtonElement.prototype), extends: ‘button’});

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“super-button” extends=“button”> …</polymer-element>

usage

<button is=“super-button”>…</button>// document.createElement(‘button’, ‘super-button’);

document.registerElement(‘super-button’, { prototype: Object.create(HTMLButtonElement.prototype), extends: ‘button’});

@polymer

#itshackademic

Sugaring: Templates

vanilla

polymer

<polymer-element name=“user-list” noscript> <template> <ul> <template repeat=“{{user, i in users}}”> <li>{{user.name}}</li> </template> </ul> </template></polymer-element>

<template> …</template>

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“user-list” noscript> <template> <ul> <template repeat=“{{user, i in users}}”> <li>{{user.name}}</li> </template> </ul> </template></polymer-element>

<template> …</template>

@polymer

#itshackademic

vanilla

polymer

<polymer-element name=“user-list” noscript> <template> <ul> <template repeat=“{{user, i in users}}”> <li>{{user.name}}</li> </template> </ul> </template></polymer-element>

<template> …</template>

@polymer

#itshackademic

Sugaring: Shadow DOM

var shadow = el.createShadowRoot();shadow.innerHTML = “<style>h2 { color: red; }</style>” + “<h2>I’m a profile-card</h2>”;

vanilla

<polymer-element name=“profile-card” noscript> <template> <link rel=“stylesheet” href=“styles.css”> <h2>I’m a profile-card</h2> </template></polymer-element>

polymer

@polymer

#itshackademic

var shadow = el.createShadowRoot();shadow.innerHTML = “<style>h2 { color: red; }</style>” + “<h2>I’m a profile-card</h2>”;

vanilla

<polymer-element name=“profile-card” noscript> <template> <link rel=“stylesheet” href=“styles.css”> <h2>I’m a profile-card</h2> </template></polymer-element>

polymer

@polymer

#itshackademic

var shadow = el.createShadowRoot();shadow.innerHTML = “<style>h2 { color: red; }</style>” + “<h2>I’m a profile-card</h2>”;

vanilla

<polymer-element name=“profile-card” noscript> <template> <link rel=“stylesheet” href=“styles.css”> <h2>I’m a profile-card</h2> </template></polymer-element>

polymer

@polymer

#itshackademic

Components

<ul><p>

<h1>

<menu-button><page-scaffold>

<animated-pages>

What if we designed HTMLfor the mobile web?

<core-icon>

<paper-fab>

<core-drawer-panel>

<core-field>

http://bit.ly/1jkTo5c

core-elements

Image: http://bit.ly/1mZjnTu

<core-toolbar>A basic container for controlslike tabs or buttons

MY APP

@polymer

#itshackademic

<link rel=“import” href=“core-toolbar.html”>

<core-toolbar>A basic container for controlslike tabs or buttons

MY APP

@polymer

#itshackademic

<core-toolbar> <div>MY APP</div></core-toolbar>

<link rel=“import” href=“core-toolbar.html”>

<core-toolbar>A basic container for controlslike tabs or buttons

MY APP

@polymer

#itshackademic

<core-toolbar> <core-icon-button icon=“menu”> </core-icon-button> <div>MY APP</div></core-toolbar>

<link rel=“import” href=“core-toolbar.html”>

<core-toolbar>A basic container for controlslike tabs or buttons

MY APP

@polymer

#itshackademic

A simple container with a headersection and a content section

<core-header-panel> MY APP

<core-header-panel flex> <core-toolbar> <core-icon-button icon=“menu"> </core-icon-button> <div>MY APP</div> </core-toolbar> <div class=“content”>…</div></core-header-panel>

A simple container with a headersection and a content section

<core-header-panel> MY APP

<core-header-panel flex> <core-toolbar> <core-icon-button icon=“menu"> </core-icon-button> <div>MY APP</div> </core-toolbar> <div class=“content”>…</div></core-header-panel>

A simple container with a headersection and a content section

<core-header-panel> MY APP

<core-header-panel flex> <core-toolbar> <core-icon-button icon=“menu"> </core-icon-button> <div>MY APP</div> </core-toolbar> <div class=“content”>…</div></core-header-panel>

A simple container with a headersection and a content section

<core-header-panel>

<core-header-panel flex> <core-toolbar> <core-icon-button icon=“menu"> </core-icon-button> <div>MY APP</div> </core-toolbar> <div class=“content”>…</div></core-header-panel>

MY APP

<core-header-panel mode=“scroll" flex> <core-toolbar> <core-icon-button icon=“menu"> </core-icon-button> <div>MY APP</div> </core-toolbar> <div class=“content”>…</div></core-header-panel>

<core-header-panel>

Toolbar will scroll with the page

A responsive container thatcombines a left- or right-side drawerpanel and a main content area.

<core-drawer-panel>

<core-drawer-panel> <div drawer> Drawer panel... </div> <div main> Main panel... </div></core-drawer-panel>

<core-drawer-panel> <div drawer> Drawer panel... </div> <div main> Main panel... </div></core-drawer-panel>

A responsive container thatcombines a left- or right-side drawerpanel and a main content area.

<core-drawer-panel>

<core-drawer-panel> <div drawer> Drawer panel... </div> <div main> Main panel... </div></core-drawer-panel>

A responsive container thatcombines a left- or right-side drawerpanel and a main content area.

<core-drawer-panel>

paper-elements

<paper-input floatinglabel label="Type only numbers... (floating)" validate="^[0-9]*$" error="Input is not a number!"></paper-input>

@polymer

#itshackademic

<paper-checkbox></paper-checkbox>

<div class=“card”> <img src=“science.svg”> <paper-ripple fit></paper-ripple></div>

A reactive ink effect for indicating touchand mouse actions

<paper-ripple>

<div class=“card”> <paper-shadow z=“5” animated> </paper-shadow></div>

A dynamic shadow for conveyingz-depth and spatial relationships

<paper-shadow>

@polymer

#itshackademic

Styling

<paper-slider min=“0” max=“100”></paper-slider>

allows you to style nodesinternal to an element’sshadow dom

::shadow

@polymer

#itshackademic

allows you to style nodesinternal to an element’sshadow dom

::shadow

paper-slider::shadow #sliderKnobInner { background-color: #f4b400;}

<paper-slider min=“0” max=“100”></paper-slider>

@polymer

#itshackademic

html /deep/ paper-ripple { background-color: #E91E63;}

styles will pierce allshadow boundaries

/deep/

@polymer

#itshackademic

With ::shadow and /deep/ youcan apply sitewide themes

source: ebidel.github.io/material-playground

polymer-project.org/apps/topeka/

polymer-project.org

We’re not alone

Mozilla Brick

<brick-appbar>

<brick-deck>

<brick-tabbar>

<core-icon>

<x-instagram>(not shown)

Web Componentscan work together

Not just browser makers

<app-router>github.com/erikringsmuth/app-

router

my-site.com/order/:id

<app-router> <!-- matches an exact path --> <app-route path="/home" import="/pages/home-page.html"></app-route>

<!-- matches using a path variable --> <app-route path="/order/:id" import=“/pages/order-page.html"></app-route></app-router>

<page-er>github.com/addyosmani/page-er

<page-er perpage="5" previous=“<< Previous" next=“Next >>"></page-er>

var pager = document.querySelector("page-er");document.addEventListener("polymer-ready", function() { pager.data = model.items;});

<ajax-form>github.com/garstasio/ajax-

form

Full Name

Country

City

Join newsletter

<form is="ajax-form" action="my/form/handler"> <label>Full Name <input type="text" name=“full_name"> </label> …</form>

Apps

polymer-project.org

chromestatus.com

polymer-project.org/tools/designer/

github.com/ForceDotComLabs/mobile-ui-elementsgithub.com/ForceDotComLabs

APIs

APIs (as elements)

I want to add a markerto a Google map.

@polymer

#itshackademic

<style> #map { height: 400px; }</style>

<div id="map"></div>

<script src=“http://maps.googleapis.com/maps/api/js?callback=mapReady"></script><script> var marker = null; function getCurrentLocation(callback) { navigator.geolocation.watchPosition(callback); }

function addMarker(opts, info) { var marker = new google.maps.Marker(opts);

var infoWindow = new google.maps.InfoWindow({content: info});

google.maps.event.addListener(marker, 'click', function() { infoWindow.open(opts.map, marker); });

return marker; }

function mapReady() { var container = document.querySelector('#map'); var map = new google.maps.Map(container, { zoom: 14, disableDefaultUI: true }); getCurrentLocation(function(pos) { var current = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude); map.setCenter(current);

// Re-position marker or create new one. if (marker) { marker.setPosition(map.getCenter()); } else { marker = addMarker({ position: current, map: map, title: 'Your location' }, '<b>Your location</b>'); } }); }</script>

So much code for one map marker!

@polymer

#itshackademic

@polymer

#itshackademic

googlewebcomponents.github.iogithub.com/GoogleWebComponents

youtube.com/watch?v=eORqFaf_QzM

Join the revolution

Learn

polymer-project.org

Build

Start with <seed-element>github.com/PolymerLabs/seed-element

youtube.com/watch?v=2toYLLcoY14

http://goo.gl/UjLvb2

Chrome Dev Editor

Share!

customelements.io

{ "name": "my-element", "version": "0.0.0", "description": "My awesome Custom Element", "license": "MIT", "keywords": [ "web-components" ], "ignore": [ "**/.*", "node_modules", "bower_components" ]}

bower.json

@polymer

#itshackademic

EXPLORE

<thank-you>

+Ibrahim Oluwadamilare@IODamilare

Recommended