web components - an introduction
TRANSCRIPT
Web Components
Diwakar Cherukumilli
Oswald Campesato
What are Web Components?
Web Components are a set of emerging standards that change the way web apps are developed by reusing components in a much more efficient way
“A web app is a large collection of web components composed of many subelements, known as custom elements” - Eric Bidelman
Why Web Components?
HTML at the beginning of the web
Small set of tags like:● <select>● <form>● ….
These elements provided:
● Declarative● Encapsulation● Default UI● Events
...<select>
<option>One</option><option disabled>Two</option><option disabled>Three</option><option>Four</option><li>Five</li>
</select>…
● Declarative● Encapsulated● Default UI● NO JS :)
Modern Web apps without Web Components
● Copy & paste chunks of HTML from CSS libraries like Bootstrap
● All sorts of Javascript frameworks and plugins
● Reusing components from different frameworks in the same page is not possible
○ Pages end up with bloated CSS and/or Javascript
● Difficult to maintain
GMail code (in chrome developer tools)
Building a modern chart
Building a modern chart without web components
<head><!-- Load the google JS library to use the google visualization API --><script type=”text/javascript” src=”https://www.google.com/jsapi”></script>
</head>
<body><!-- Add the div tag as a placeholder for the chart --><div id=”char_div” style=”width:400; height: 300”></div>
</body>
Building a modern chart without web components
<!-- Using javascript --><!-- Load the visualization API -->google.load(‘visualization’, ‘1.0’, {‘packages’: [‘corechart’]});
<!-- Set values and options on load callback -->google.setOnLoadCallback(function() {
var data = new google.visualization.arrayToDataTable([[“Day”, “A”, “B”, “C”], [“Mon”, 20, 45, 28], [“Tue”, 31, 66, 38], [“Wed”, 50, 80, 55], [“Thu”, 77, 50, 77], [“Fri”, 68, 15, 66]]);
var options = {“seriesType”: “bars”, “series”: {“2”: {“type”: “line”}}, “width”: 400,“height”: 300
};
<!-- Specify the dom element for the chart and draw it-->var div = document.getElementById(‘chart_div’);var chart = new google.visualization.ComboChart(div);chart.draw(data, options);
});
Building a modern chart with web components<head>
<!-- Load polyfill for cross browser support --><script src=”js/webcomponentjs.js”></script>
<!-- Import the google chart component --><link rel=”import” href=”components/google-chart.html”>
</head>
<body><!-- Add google chart tag and fill in the attributes --><google-chart
type=”combo”height=”300px” width=”400px”options=”{‘seriesType’: ‘bars’, ‘series’: {‘2’: {‘type’: ‘line’}}}”data=”[[‘Day’, ‘A’, ‘B’, ‘C’], [‘Mon’, 20, 45, 28], [‘Tue’, 31, 66, 38], [‘Wed’, 50, 80, 55], [‘Thu’, 77, 50, 77], [‘Fri’, 68, 15, 66]]”>
</google-chart></body>
Declarative approach (with web components)
<google-charttype=”combo”height=”300px” width=”400px”options=”{‘seriesType’: ‘bars’, ‘series’: {‘2’: {‘type’:
‘line’}}}”
data=”[[‘Day’, ‘A’, ‘B’, ‘C’], [‘Mon’, 20, 45, 28], [‘Tue’, 31, 66, 38], [‘Wed’, 50, 80, 55], [‘Thu’, 77, 50, 77], [‘Fri’, 68, 15, 66]]”>
</google-chart>
<!-- Easier to use -->
<!-- No need to know the underlying JS API and CSS -->
Imperative Approach (without web components)
google.load(‘visualization’, ‘1.0’, {‘packages’: [‘corechart’]});
google.setOnLoadCallback(function() {var data = new google.visualization.
arrayToDataTable([[“Day”, “A”, “B”, “C”], [“Mon”, 20, 45, 28], [“Tue”, 31, 66, 38], [“Wed”, 50, 80, 55], [“Thu”, 77, 50, 77], [“Fri”, 68, 15, 66]]);
var options = {“seriesType”: “bars”, “series”: {“2”: {“type”:
“line”}}, “width”: 400,“height”: 300
};
var div = document.getElementById(‘chart_div’);var chart = new google.visualization.ComboChart
(div);chart.draw(data, options);
});
Scoped
Web components
● All mark up and CSS are scoped to the element● Styles scoped to the element will not leak out to the parent● Parent can’t style the web component accidentally● Imported web components will not harm any part of your web page
Non Web Component based libraries
● Existing libraries that have same classes and id can cause styles to leak
Reusable
● Scoped and decoupled with the other parts of your web app
● Use same component in the other parts of your web app
● Use the component in another web app
● Publish your component as open source so that others can use it
Isolation
● Decouple development of web components from the rest of the web app as they are scoped
● Maintenance of the web component is much easier due to isolation
Web Components is an umbrella term for four different W3C specifications
● Custom Elements lets you define your own HTML tags
● HTML Templates enables you to define blocks of markup with the ability to
inject dynamic content into
● Shadow DOM gives you the ability to scope markup and styles in a separate
DOM tree
● HTML Imports provides a way to include and reuse HTML documents in other
HTML documents
Vanilla Web Component (svcc-component.html)<template>
<p>This is svcc-component’s SHADOW DOM</p></template><script> // 1. Register a custom element var XElement = document.registerElement(‘svcc-component’, { prototype: Object.create(HTMLElement.prototype, { createCallback: {
value: function(){// 2. Associate Shadow dom onto itvar root = this.createShadowRoot();
//3. Use templates to provide the contents of the shadow domvar template = thisDoc.querySelector(‘#template’);var content = thisDoc.importNode(template.content, true);root.appendChild(content);
} } } });</script>
index.html
<html> <head> <!-- 4. Use HTML import to import the component--> <link rel=”import” href=”svcc-component.html> </head>
<body> <svcc-component></svcc-component> </body></html>
Polymer for buiding Web Components
Polymer lets you build
● encapsulated, ● re-usable elements ● that work just like HTML elements, ● to use in building web applications.
Polymer in 1 minute
/** * A not-very-useful inline element */
Polymer({ is: 'my-element' });
Add markup to your element
<!-- define the markup that your element will use --><dom-module id="my-simple-namecard"> <template> <div> Hi! My name is <span>Jane</span> </div> </template>
<script> Polymer({ is: 'my-simple-namecard' }); </script></dom-module>
Configure properties on your element
// Create an element that takes a propertyPolymer({ is: 'my-property-namecard', properties: { myName: { type: String } }, ready: function() { this.textContent = 'Hi! My name is ' + this.myName; }});
<!-- using the element --><my-property-namecard my-name="Jim"></my-property-namecard>
Hi! My name is Jim.
Bind data into your element using the familiar mustache-syntax
<!-- define markup with bindings --><dom-module id="my-bound-namecard"> <template> <div> Hi! My name is <span>{{myName}}</span> </div> </template>
<script> Polymer({ is: 'my-bound-namecard', properties: { myName: { type: String } } }); </script></dom-module>
Hi! My name is Josh.
<!-- using the element --><my-bound-namecard my-name="Josh"></my-bound-namecard>
Bind data into your element using the familiar mustache-syntax
<!-- define markup with bindings --><dom-module id="my-bound-namecard"> <template> <div> Hi! My name is <span>{{myName}}</span> </div> </template>
<script> Polymer({ is: 'my-bound-namecard', properties: { myName: { type: String } } }); </script></dom-module>
Hi! My name is Josh.
<!-- using the element --><my-bound-namecard my-name="Josh"></my-bound-namecard>
Style the internals of your element, without the style leaking out
<!-- add style to your element --><dom-module id="my-styled-namecard"> <template> <style> /* This would be crazy in non webcomponents. */ span {font-weight: bold;} </style>
<div>Hi! My name is <span>{{myName}}</span></div> </template>
<script> Polymer({ is: 'my-styled-namecard', properties: { myName: { type: String} } }); </script></dom-module>
Hi! My name is Jesse.
<!-- using the element --><my-styled-namecard my-name="Jesse"></my-styled-namecard>
References...
Polymer - Chrome Dev Summit 2013 (Eric Bidelman)
Why Web Components (Zeno Rocha & Addy Osmani)?
DevBytes: Web Components - Overview (Eiji Katamura)
Polymer Github page (https://github.com/Polymer/polymer)