Web Components

From Zero to hero


by Salvatore Laisa @ BolognaJS - 18/04/2018

About me

  • Lead Frontend Engineer @ Bitrock
    • we are hiring ;-)
  • Kung fu & Tai Chi practitioner
  • Hero of the storm (Abathur FTW!)
  • Doctor who fan
  • from Milano(JS)

Mantra

Agenda:

  1. Web Components 101
  2. Libraries
  3. Interoperability
  4. Mythbusting
  5. Really nice use case

Web Components 101

--- basic concepts ---

Definition

"You can think of Web Components as reusable user interface widgets that are created using open Web technology. They are part of the browser, and so they do not need external libraries like jQuery or Dojo."

from Mozilla MDN

Current specification

After a Chrome-only implementation, referred as "v0", browser vendor worked together for a common specification now called "Web Components v1".

Make your own

  • Custom Elements API (living standard)
  • Shadow DOM API (living standard, editor's draft)
    • <slot> element
  • (optional) polyfills

Shadow DOM and...

CSS-in-CSS

CSS-in-CSS (aka: CSS)


  this.shadow.innerHTML = `
    <style>
      section{
        color: red;
      }
    </style>
    <section>
      My awesome scoped style!
    </section>
   `
        

Browser support - Custom Elements

Can I Use custom-elementsv1? Data on support for the custom-elementsv1 feature across the major browsers from caniuse.com.

Browser support - Shadow DOM

Can I Use shadowdomv1? Data on support for the shadowdomv1 feature across the major browsers from caniuse.com.

Syntax (definition)


  class MyComponent extends HTMLElement {
    constructor(){
      super();
      console.log('<my-componennt> created');
    }

    connectedCallback(){
      console.log('<my-componennt> added to DOM');
    }
  }

  customElements.define('my-component', MyComponent);
        

Syntax (usage)


          <my-element></my-element>
        

it works as a regular HTML element.

With some template & Shadow DOM


  class UsefulElement extends HTMLElement {
    constructor(){
      super();

      this.shadow = this.attachShadow({mode: 'open'});
      this.text = "I'm a super useful element!";
    }

    connectedCallback(){
      this.shadow.innerHTML = `<p>${this.text}</p>$`;
    }
  }

  customElements.define('useful-element', UsefulElement);
        

Libraries

--- with a little help from my friends ---

Polymer

The great (Google) herald of Web Components

  • syntactic sugar, data biding, template utils...
  • extends native syntax
  • just moved from Bower to Yarn (v3)
  • from v3 the templating in "pluggable"

HyperHTML

Not strictly related to Web Components... but what about having pure Javascript competing with Virtual DOM?

  • really lighweight
  • active development
  • with a Custom Element companion
  • "isomorphic" and NativeScript (experimental) implementations

HyperHTML


      	
  function tick(render) {
    render`
      <div>
        <h2>It is ${new Date().toLocaleTimeString()}.</h2>
      </div>
    `;
  }

  setInterval(tick, 1000,
    hyperHTML.bind(document.body)
  );

        

... and many examples and comparisons out there!

hyperHTML vs litHTML

In a quite funny twist Google developed a similar library a few months ago...

SkateJS

Started as a React inspired library but based on Web Components..

  • easier for React folks?
  • trying a functional approach
  • renderer for various libraries

Interoperability

--- aka: reversing the polarity of the neutron flow ---

Can I use Web Components in [name a library]?

yes

(most of the times)

How can I do that?

basically just import che component in your page and add it in your application template

but not always it's so easy 😡

Luckily there is...

Custom Elements Everywhere

Mythbusting

--- who you gonna call? ---

Myth #1: "the spec changed so many times..."


WRONG: just one time

Myth #2: "you can't use Redux with Web Components"


WRONG: Redux is a vanilla library

Myth #3: "there are no related developer tools"


TRUE: you just need the... developer tools!

Myth #4: "you must use Bower to work with Web Components"


FALSE: spec says nothing about package managers

Really nice use case

--- not average, not overwhelming... but nice! ---

Wrapping "weird" APIs

AKA: did you noticed my gamepad remote?

Wrapping "weird" APIs



  Reveal.initialize();
  
  // Listening to custom events from gamepad-api element
  const gamepad = document.querySelector('gamepad-api');

  gamepad.addEventListener('button', evt => {
    evt.detail.button === 'prev' ? 
      Reveal.prev() : Reveal.next();
  });

        

Wrapping "weird" APIs

keep on playin!

Design systems/Pattern libraries

Keep consistency across frameworks

To be continued...