An introduction to
Web Components

Soledad Penadés

@supersole

I work at Mozilla

essentially...

I help you build cool stuff on the web

or find out why you can't...

and nag people until you can.

So...

Web Components

huh?

Let's start by going back in time

Web 1.0

Web 1.5

Web 2.0

LOTS of plug-ins!

MASSIVE ecosystem, YAY!

Maintenance pain

Also, cumbersome code

<div class="widget calendar ui theme-winter">
  <div class="component-wrapper">
    <div class="inner-content">
      (ad nauseaum)
    </div>
  </div>
</div>
var componentWrapper 
  = document.createElement('div');
var innerContent
  = document.createElement('div');
componentWrapper.appendChild(innerContent);
// ...
return componentWrapper;

// ...
calendarEl.appendChild(componentWrapper);
$("#datepicker")
  .datepicker($.datepicker.regional["fr"]);
$("#locale").change(function() {
  $("#datepicker").datepicker("option",
    $.datepicker.regional[ $(this).val() ] );
});

Can we do better?

What if browsers made it easier to build modular, more encapsulated code?

What if we could teach new elements to the browser?

<x-calendar></x-calendar>
var calendar =
  document.createElement('x-calendar');
  
var calendar =
  document.querySelector('x-calendar');
  
calendar.nextMonth();
calendar.setLocale('fr');

Each instance of these new elements...

How do we make this happen?

The pillars of Web Components

1. Custom elements

Teach the browser about a new type of element

document.register('web-bell', WebBellPrototype);

A custom element prototype

WebBell Prototype:

var WebBellPrototype =
  Object.create(HTMLElement.prototype);
  
WebBellPrototype.createdCallback = function() {
  this.innerHTML = '🔔';
};

2. HTML Templates

"Inert HTML chunks"

not live until you say so

<template id="row-template">
  <tr>
    <td><input .../></td>
    <td><button .../></td>
  </tr>
</template>

Creating rows on the fly

var tpl =
  document.getElementById('row-template');
var table =
  document.getElementById('form-table');
  
table.appendChild(tpl.content.cloneNode());

3. Shadow DOM

Or: you can see, but not touch this!

var shadow = node.createShadowRoot();
shadow.appendChild(otherNodes);

Shadow DOM in context

Shadow DOM:

Tricky yet powerful

4. HTML imports

Include HTML documents in other HTML documents

or: "require() for the web"

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

my-component.html's <head>

<script src="my-component.js"></script>
<link rel="stylesheet" href="my-component.css">

A tutorial

(Rough) support overview

Are we componentized yet?

Not supported on every browser

but... polyfills!

webcomponents.js

Also webcomponents-lite.js

Custom Elements are pretty safe to use right now!

A note of warning

Polyfills are NOT FREE

What about Polymer? X-Tag?

Syntactic sugar to make vanilla web components less sour

I ❤️ BAD PUNS

X-Tag example

xtag.register('web-bell', {
  extends: 'div',
  lifecycle: {
    created: function() {
      this.innerHTML = 'BELL';
    }
  }
});

Declarative polymer example

<polymer-element name="web-bell" extends="div">
  <template>
    BELL
  </template>
  <script>
    Polymer();
  </script>
</polymer-element>

Imperative Polymer example

Polymer('web-bell', {
  extends: 'div',
  created: function() {
    this.innerHTML = 'BELL';
  }
});

There's also Bosonic

(but I haven't had time to look into it in detail yet)

Which one is better?

for more info

webcomponents.org

is a good starting point!

Thanks!

@supersole

soledadpenades.com