Logo

Introduction to Web Component

What's web component?

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

-- webcomponents.org --

For example:

Switch Web Component

<script type="module" src="node_modules/@spectrum-web-components/switch/sp-switch.js"></script>

---

<sp-switch emphasized value="on" checked>
  Switch Web Component
</sp-switch>

source: spectrum - switch componet

Web Component Spesifications

There are four key specifications that define web components and enable their use in building web applications:

1. Custom Elements
2. Shadow DOM
3. ES Modules
4. HTML Templates

1. Custom Elements

It is a set of API spesification in the browser to create custom tag html.

class BeautifulButton extends HTMLElement {...}

window.customElements.define("beautiful-button", BeautifulButton);

---

<beautiful-button></beautiful-button>

source: web.dev - Custom Elements

2. Shadow DOM

The Shadow DOM is a web platform feature that provides encapsulation for web components. It allows you to create a separate DOM tree and style tree that are attached to a host element, and that are isolated from the main document's DOM and style sheets.

It helps to prevent conflicts with the main document's styles and layout.

How to create Shadow DOM (Element.attachShadow)

source: web.dev - Shadow DOM

Example of Shadow DOM

Screenshot inspect element shadow DOM on Chrome

3. ES Modules

ES Modules enable web components to be developed in a modular way that is in alignment with other industry accepted implementations for JavaScript application development.

<script type="module" src="awesome-explosion.js"></script>

...

<script type="module">
  import 'awesome-explosion.js';
  ...
  import {awesomeExplosion} from '@awesome-things/awesome-explosion';
</script>

source: HTML Living Standard - ES Module

4. HTML Templates

Defines how to declare fragments of markup that go unused at page load, but can be instantiated later on at runtime, that can be cloned and inserted in the document by script

Content between <template></template> tags

  • Will not render until it is activated
  • Has no effect on other parts of the page - scripts won’t run, images won’t load, audio won’t play - until activated
  • Will not appear in the DOM

source: webcomponents.org - Template Elements

Example usage of Template Elements

Declare a template:

<template id="mytemplate">
  <img src="" alt="great image">
  <div class="comment"></div>
</template>

Use the template:

var t = document.querySelector('#mytemplate');
// Populate the src at runtime.
t.content.querySelector('img').src = 'logo.png';

var clone = document.importNode(t.content, true);
document.body.appendChild(clone);

Browser Support

Logo

Use Polyfills

For more detail: webcomponents.org/polyfills

Let's Demonstrate!

We will try to create our arcade button component using web component with property 2 variant only:

purchasing: #EF6000

non-purchasing: #307FE2

The Code

const color = {
  purchasing: '#EF6000',
  'non-purchasing': '#307FE2',
}

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

    // render the element
    const shadowRoot = this.attachShadow({ mode: 'closed' });
    shadowRoot.innerHTML = `
      <!-- styles are scoped to arcade-button! -->
      <style>
        :host([variant='purchasing']) #arcade-button {
          background-color: ${color.purchasing};
        }
        :host([variant='non-purchasing']) #arcade-button {
          background-color: ${color['non-purchasing']};
        }
        #arcade-button {
          border: none;
          padding: 4px 8px;
          font-size: 18px;
          color: white;
          padding: 8px 20px;
          border-radius: 8px;
        }
      </style>
      <button id="arcade-button">
        <slot></slot>
      </button>
    `;
  }
};

window.customElements.define('arcade-button', ArcadeButton);

The Result

<arcade-button variant="purchasing">Purchasing Variant</arcade-button>
<arcade-button variant="non-purchasing">Non-Purchasing Variant</arcade-button>

Purchasing Variant Non-Purchasing Variant

Thankyou