Upload
oluwadamilare-ibrahim
View
122
Download
0
Embed Size (px)
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
@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