web Components

- kalon frontend meetup -

Andrei Antal

pentru ca de ce nu?

Contents

  • web components - so what?

 

  • Polymer 1.0 - sweet sugar candy components

 

  • anyone else?

WEB COMPONENTS

  • Set of standards that allow us to bundle  markup, styles and scripts into custom HTML elements

 

  • We've been using them but now ca can also create our own

 

  • Google as the main engine

 

WEB COMPONENTS

Main ideas behind web components:

 

  • Custom elements

 

  • Shadow DOM

 

  • HTML Templates

 

  • HTML Imports

WEB COMPONENTS - CUSTOM ELEMENTS

Defining and using new types of DOM elements


//custom element instantiation
var KalonElement = document.registerElement('kalon-element', {
  prototype: Object.create(HTMLElement.prototype, {
    awesomeness: {
      get: function() { return 'over 9000'; }
    },
    createdCallback : function() {
        console.log("Gata boss, m-am creat");
    }
  })
});

// add to document
document.body.appendChild(KalonElement);
<!-- custom element declaration in markup-->
<kalon-element></kalon-element>

or

WEB COMPONENTS - CUSTOM ELEMENTS

Element lyfecycle

Callback name Called when
createdCallback an instance of the element is created
attachedCallback an instance was inserted into the document
detachedCallback an instance was removed from the document
attributeChangedCallback(attrName, oldVal, newVal) an attribute was added, removed, or updated

WEB COMPONENTS - SHADOW DOM

var KalonElementProto = Object.create(HTMLElement.prototype);

KalonElementProto.createdCallback = function() {
  this.innerHTML = "<b>This is my markup!</b>";
};

var KalonElement = document.registerElement('kalon-element',
         {prototype: KalonElementProto});
var KalonElementProto = Object.create(HTMLElement.prototype);

KalonElementProto.createdCallback = function() {
  // 1. Attach a shadow root on the element.
  var shadow = this.createShadowRoot();

  // 2. Fill it with markup goodness.
  shadow.innerHTML = "<b>This is my markup!</b>";
};

var KalonElement = document.registerElement('kalon-element', 
        {prototype: KalonElementProto});




<kalon-element>
  <b>This is my markup!</b>
</kalon-element>




<kalon-element>
  #shadow-root
    <b>This is my markup!</b>
</kalon-element>

WEB COMPONENTS - HTML TEMPLATES

<template id="KalonElementTemplate">
  <style>
    p { color: pink; }
  </style>
  <p>Kalon element Shadow DOM with scoped styling</p>
</template>

<script>

    var KalonElementProto = Object.create(HTMLElement.prototype, {
      createdCallback: {
        value: function() {
          var template = document.querySelector('#KalonElementTemplate');
          var clone = document.importNode(t.content, true);
          this.createShadowRoot().appendChild(clone);
        }
      }
    });
    document.registerElement('x-foo-from-template', 
        {prototype: KalonElementProto});

</script>

WEB COMPONENTS - HTML IMPORTS

<link rel="import" href="kalon-component.html" >

....

<kalon-component></kalon-component>

WEB COMPONENTS

 

Browser compatibility

POLYMER

- WEB COMPONENTS MADE SWEET - 

  • build on top of web components - by GOOGLE
  • offers syntactic sugar for fast creation of reusable components 
  • adds a few tricks to components (eg. data binding)
  • EXTENSIVE POLYMER ELEMENT CATALOG

POLYMER - element starter

<link rel="import" href="../bower_components/polymer/polymer.html">

<dom-module id="hello-folks">
  <style>
    h1 { color: red; }
    h3 { color: blue; }
  </style>
  <template>
    <h1>Hello</h1>
    <h3>folks</h3>
  </template>
</dom-module>

<script>
  Polymer({
    is: "hello-folks",
  })
</script>
    .....
    <link rel="import" href="comp/hello-folks.html">
  </head>
    <body>
      <hello-folks></hello-folks>
    ....

POLYMER - CUSTOM Properties

<script>
  Polymer({
    is: "hello-folks",
    properties : {
      aSimpleProp : String,
      aComputedProp : {
        type: String,
        computed: 'comp(aSimpleProp)'
      }
    },
    comp(prop){
      return "computed: " + prop
    }
  });
</script>
    .....
    
    <hello-folks a-simple-prop="a prop"></hello-folks>

    ....



<dom-module id="hello-folks">
  <style>
    h1 { color: red; }
    h3 { color: blue; }
  </style>
  <template>
    <h1>Hello</h1>
    <h3>folks <span>{{aComputedProp}}</span></h3>
  </template>
</dom-module>

POLYMER - DATA BINDING

<dom-module id="hello-folks">
  <style>
    h1 { color: red; }
    h3 { color: blue; }
  </style>
  <template>
    Name: <input value={{nameValue::input}}>
    <h1>Hello</h1>
    <h3> <span>[[nameValue]]</span></h3>
  </template>
</dom-module>

<!-- Attribute binding -->
  <my-element selected$="{{value}}"></my-element>
<!-- results in <my-element>.setAttribute('selected', this.value); -->

<!-- Property binding -->
  <my-element selected="{{value}}"></my-element>
<!-- results in <my-element>.selected = this.value; -->
  • [[ property]]  one way data binding
  • {{ property }} - automatic (one/two way) data binding

POLYMER - Iterating over data

.......
<template>
  <h1>A list of things</h1>
  <ul>
    <template is="dom-repeat" items={{things}} as="thing" index-as="thing_no">
      <li>thing <i>[[thing_no+1]]</i> - <b>[[thing.name]]</b></li>
    </template>
  </ul>
</template>
........

<script>
  Polymer({
    is: "hello-folks",
    ready: function(){
      this.things = [
        {name: "a thing"},
        {name: "some other thing"},
        {name: "the last thing"}]
    }
  });
</script>

POLYMER - ELEMENT COMPOSITION

<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="components/entry-detail.html">

<dom-module id="entry-list">
  <style>
  </style>
  <template>
    <h1>ELEMENT LIST</h1>
    <template is="dom-repeat" items="{{entries}}">
        <h3> Element #<span>[[index]]</span></h3>
        <entry-detail id="{{item.id}}">
    </template>
  </template>
</dom-module>

<script>
  Polymer({
    is: "hello-folks",
    ready:  function(){
        this.entries = [...]
    }
  })
</script>

POLYMER - Routing

other options

THANKS

webComponents

By Andrei Antal

webComponents

  • 1,221