Web Components

 

It's all rainbows and unicorns! Is it?

Sara HARKOUSSE

Human Talks

Paris, 13 Juin 2017

http://vignette2.wikia.nocookie.net/weirdcommunity/images/a/a2/Rainbow-flow-abstract-backgrounds-for-powerpoint.jpg/revision/latest?cb=20130603085532​​

SARA HARKOUSSE

@Sara_harkousse

 

 

Tech Lead, front-end Web developer at Dassault Systèmes

3D design & PLM software

 

"Duchess France" Leader & 3DS Advocate at "Elles Bougent"

 

 

About me

@HumanTalks

Motivation

  • Modular architecture

Filterable Product Table

Search Bar

Product Table

Product Row

Product Category Row

https://facebook.github.io/react/docs/thinking-in-react.html

@HumanTalks #webcomponents @Sara_harkousse

Angular 4.0 Component

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>`
})

export class AppComponent { name = 'Angular'; }
<my-app><h1>Hello Angular</h1></my-app>

https://embed.plnkr.co/?show=preview&show=app%2Fapp.component.ts

@HumanTalks #webcomponents @Sara_harkousse

Ember 3.1.0 Component

<article class="blog-post">
  <h1>{{title}}</h1>
  <p>{{yield}}</p>
  <p>Edit title: {{input type="text" value=title}}</p>
</article>
{{#each model as |post|}}
  {{#blog-post title=post.title}}
    {{post.body}}
  {{/blog-post}}
{{/each}}

https://guides.emberjs.com/v3.0.0/components/defining-a-component/

Polymer 2.0 Element

  // Define the class for a new element called custom-element
  class CustomElement extends Polymer.Element {
    static get is() { return "custom-element"; }
    constructor() {
        super();
        this.textContent = "I'm a custom-element.";
      }
  }
  // Register the new element with the browser
  customElements.define('custom-element', CustomElement);
<custom-element></custom-element>

http://plnkr.co/edit/PaCt2M?p=preview

Frameworks make it hard to get along

@HumanTalks #webcomponents @Sara_harkousse

@HumanTalks #webcomponents @Sara_harkousse

Browser support

https://www.webcomponents.org/

  • use webcomponents.js

Refresher on web components

Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web apps.”

@HumanTalks #webcomponents @Sara_harkousse

https://www.webcomponents.org/

Refresher on web components

  • HTML Template Tag

  • HTML Imports

  • Custom Elements

  • Shadow DOM

@HumanTalks #webcomponents @Sara_harkousse

HTML Template Tag

  <template id="template">
    <div id="container">
      <img class="webcomponents" src="https://webcomponents/imgs/webcomponents-logo.svg">
    </div>
  </template>

https://jsfiddle.net/sara_harkousse/rnu8zc0c/

@HumanTalks #webcomponents @Sara_harkousse

HTML Template Tag Usage

var template = document.querySelector('#template');
var clone = document.importNode(template.content, true);
var host = document.querySelector('#host');
host.appendChild(clone);

https://jsfiddle.net/sara_harkousse/rnu8zc0c/

@HumanTalks #webcomponents @Sara_harkousse

HTML Template Tag

  • A way to add inert DOM elements to your document

  • Not something that's going to revolutionize your apps

  • No two-way data binding, no binding at all

@HumanTalks #webcomponents @Sara_harkousse

HTML Imports

 <link rel="import" href="/imports/productRow.html"> 
 <script src="js/productRow.js"></script> 
 <template> 
    <!-- content-->
 <template> 

@HumanTalks #webcomponents @Sara_harkousse

How to get my component?

var link = document.querySelector('link[rel="import"]');
var content = link.import;

// Grab DOM from productRow.html's document.
var el = content.querySelector('.productRow');
document.body.appendChild(el.cloneNode(true));

@HumanTalks #webcomponents @Sara_harkousse

HTML Import requires a polyfill

  • ES6 module?

https://www.webcomponents.org/

@HumanTalks #webcomponents @Sara_harkousse

Shadow DOM

  • A tiny document

  • exists inside of a host element

@HumanTalks #webcomponents @Sara_harkousse

Key concepts

  • Isolated DOM

  • Scoped CSS

@HumanTalks #webcomponents @Sara_harkousse

Shadow DOM requires a polyfill

  • Hard to polyfill

@HumanTalks #webcomponents @Sara_harkousse

Use/Don't use

Shadow DOM?

callback() {
    // Use it
    this.root = this.attachShadow({mode: 'open'});

    var template = document.querySelector('#template');
    var clone = document.importNode(template.content, true);
    this.root.appendChild(clone);
}

callback() {
    // Don't Use it
    this.root = this;

    var template = document.querySelector('#template');
    var clone = document.importNode(template.content, true);
    this.root.appendChild(clone);
}

@HumanTalks #webcomponents @Sara_harkousse

Use/Don't use

Shadow DOM?

/* Use it */
:host {
    color: red;
}

/* Don't use it */
custom-component {
    color: red;
}

@HumanTalks #webcomponents @Sara_harkousse

Use AND Don't use

Shadow DOM

if (shadowflag){
    this.root = this.attachShadow({mode: 'open'});
} else {
    this.root = this;
}
custom-component, :host {
    color: red;
}

@HumanTalks #webcomponents @Sara_harkousse

Custom Elements

class CustomButton extends HTMLElement {...}
window.customElements.define('custom-button', CustomButton);
<custom-button></custom-button>
  • Acts like a div

@HumanTalks #webcomponents @Sara_harkousse

Custom Elements

class CustomButton extends HTMLButtonElement {...}
window.customElements.define('custom-button', CustomButton, {extends: 'button'});
<button is="custom-button" disabled>My button!</button>
  • Acts like a real button

@HumanTalks #webcomponents @Sara_harkousse

Custom Elements ES6 Class

class custom-component extends HTMLElement {
  constructor() {
    super(); // always call super() first in the ctor.
    ...
  }
  connectedCallback() {
    ...
  }
  disconnectedCallback() {
    ...
  }
  attributeChangedCallback(attrName, oldVal, newVal) {
    ...
  }

}

@HumanTalks #webcomponents @Sara_harkousse

Component example

 Bootstrap Progress Bar

<div class="progress">
  <div class="progress-bar" style="width: 60%;">
    60%
  </div>
</div>

@HumanTalks #webcomponents @Sara_harkousse

Components on a page

<!doctype html>
<html lang="en">

    <head>
        <link rel="import" href="/imports/productRow.html">
    </head>

    <body>
        <custom-navbar style="compact"></custom-navbar>
        <custom-toolbar style="full"></custom-toolbar>
        <custom-pagecontent>
            <custom-item attr="val"></custom-item>
            <custom-input attr="val"></custom-input>
            <progress-bar></progress-bar>
        </custom-pagecontent>

        <script>
            document.querySelector('progress-bar').addEventListener(
                'customevent', function () {
                    // do something
                 }
            });
        </script>
    </body>

</html>

@HumanTalks #webcomponents @Sara_harkousse

Takeaway

You will understand some of the design decisions of major frameworks if you learn about custom elements

@HumanTalks #webcomponents @Sara_harkousse

Takeaway

Who is using web components?

@HumanTalks #webcomponents @Sara_harkousse

Takeaway

GitHub

Mozilla VR

Google

@HumanTalks #webcomponents @Sara_harkousse

Thanks for listening!

Follow for slides

@Sara_harkousse

@HumanTalks #webcomponents

http://slides.com/sara_harkousse/web-components-talk-2#/

Made with Slides.com