Web Components: Learnings From ADEO Design System

THOMAS RUMAS
ADEO Tech Blog
Published in
7 min readMay 17, 2022

Introduction

The most known Javascript Frameworks has a concept of ‘Components’. Components are reusable pieces of code inside their ecosystem. For example, in React ecosystem, I can reuse my React Component that I created across my React project(s).

Adding a Design System to the equation, to support three major JavaScript Frameworks (Vue.js, React, Angular), you have to implement your design system three times, in terms of Javascript code.

One question came to us: How to make a component reusable on different frameworks? — W3C provided an answer. The W3C (World Wide Web Consortium) come up with an API to create components only using Javascript — known as Web Components.

Our article describes what we learned at ADEO working with Web Components in the last few months.

Before getting into it, we want to introduce: What are Web Components?

What are Web Components?

The W3C describes that Web Components make it possible to:

…[…] combine several elements to create reusable graphical interface components (widgets) with a level of richness and interactivity beyond what is possible today by limiting oneself to CSS […]”.

Web Components allow developers to create custom and reusable HTML tags. Web Components are based on several W3C programming interfaces (APIs) like:

  • Templates: skeletons for instantiable HTML elements
  • Shadow DOM: what will be public or private in the elements
  • Custom elements: to persist new HTML elements and have them recognised by the browser
  • HTML imports: to package its components (CSS, JavaScript, etc.)
  • Model-driven views: provides a data binding similar with AngularJS’s approach

Shadow DOM behaviour is a important topic inside Web Components W3C specs, so we will add a brief explanation about Shadow DOM. For other Web Component API specs, I invite you to read MSDN documentation.

The Shadow DOM

You can think of the Shadow DOM as a “DOM within a DOM”. Shadow DOM is its own isolated DOM tree. It has his own elements and styles, completely isolated from the original DOM.

Shadow DOM has been used by user agents for years to create and style complex components such as form elements, even it was only recently specified for use by W3C.

Example of Shadow Dom use by Safari browser for input[type=”range”]

Shadow DOM makes sure that the JS instructions and CSS instructions will only scope our Web Components.

Your first Web Component

We will declare our Web Component. In this way, we need to create a new class and extend the HTMLElement class with a constructor:

To summarize, we have:

  • Declared a new JS class inherits from HTMLElement
  • Create a Shadow DOM for our Web Component
  • Create a HTML div element that will contains our HTML structure
  • Insert our HTML structure to our Shadow DOM.

If you have previous experience with JavaScript frameworks, it looks like familiar with component’s lifecycle on JavasScript Frameworks. With no surprise, a Web Component has his own lifecycle too.

Web Component lifecycle’s, from Custom Element API, are composed of defined:

  • Constructor initialize the class
  • connectedCallback will be triggered once when Web Component is added to the DOM
  • attributeChangedCallback will be triggered when a attribute changed
  • adoptedCallback will be triggered when the Web Component moved into a new document
  • disconnectedCallback will be triggered once when the element is removed from the DOM

Now, we can create a method for each lifecycle step:

Now, to register our Web Component to Custom Element Registry, we need to add this instruction:

window.customElements.define('button-wc', ButtonWC);

We declared to the browser a new HTML custom element <button-wc> . It will render our class ButtonWC.

** Important info: Naming of Web Component is standardized by the W3C. It must follow this my-component. The - is mandatory to declare your Web Component to the CustomElement registry. **

Test our Web Component

We can create a HTML file to test our Web Component:

Inside your favorite browser, you can check the web page and play with your Web Component!

If you read with attention the HTML code, you can see that we declared an onclick attribute to our Web Component.

In fact, all event methods known and useable of any native HTML element are available for your custom elements, onclick, onblur, onfocus and others.

Declaring events, for example, like we did an onclick event, all clicked elements inside the Web Component's UI will trigger the method. We just want to interact on a specific event triggered inside a UI component in some cases.

Create Custom Event

A solution is to use simple CustomEvent with JavaScript, you can find more information here about CustomEventdocs page.

For example, if we want to tell that the value has changed, we can implement in our previous Web Component:

How we use Web Component inside ADEO?

At ADEO we have 2 main elements in your Front end Stack:

  • KOBI: Our Fragment Service, that allows us to mix JavaScript framework inside a same web page
  • ADEO Design System: is a product designed to help set up a coherent human experience, reinforce the team’s delivery time and improve the quality of deliverables. It allows us to distribute a unique component reusable for each Javascript usage; vanilla or with JavaScript framework.

ADEO Design System (ADS)

At the beginning of ADS project, the ADS delivered only SCSS and HTML structure. By the time the ADS team created, after developer’s feedback, a Vue.js implementation of the Adeo Design System.

It wasn’t enough. Other developers wanted a version of ADS for Angular, then React and so on.

Before ADS Web Component, each framework has its own Design System implementation

So we aimed to create a ADS Web Component Library that will be usable for each project inside each technology.

For Component creation, we decided to use Svelte framework to create our Web Component library. We choose Svelte for many reasons:

  • Simple to understand so we can target more developers to contribute
  • Lightweight: Svelte runtime will only charge the JS file of Web Component with 2KB when Gzipped.
  • Easy to declare Web Component with a proper syntax

Here, you can find our NPM package.

After ADS Web Component, one project to rule them all!

Main challenges with Web Components

Based on our experience, we discover some pain points you should look deeper dealing with Web Components. Therefore if you’re working with micro-front:

1. You can only register one custom element with the same name

2. You need to have attention about the versioning of your Web Component.

1. How to verify if a Web Component exists before you register it

if(!customElements.get('button-wc')) {
console.log('custom element not defined');
}
else {
console.log('custom element is defined');
}

This solution has the advantage of declaring the Web Component only one time, but will restrict the version to every Web Component you can have inside your web pages.

A better way is to declare Web Component globally and fixed the version used by everybody. Still, if an update of the Web Component is needed, you need to tell all of your customers to update to the new Web Component simultaneously.

2. Let people register the Web Component by themselves

Delegate the registering responsibility of your Web Component to your Developers. Do not automatically register your Web Component by itself.

For example, if you have 10 consumers using your Web Component, you delegate the decision where is the good place in their application to instantiate your Web Component.

Automatically registering inside your component, will bring name collision and performance issues, depending your Web Component logic and size.

What is coming by W3C about it?

W3C has a proposal to update CustomElementRegistry to be able to scoped Web Component to a custom registry. At this time, the PR is still open inside W3C repository, you can have all the information here.

Should we use a JavaScript framework to create Web Component?

The answer is yes!

With many JavaScript frameworks, you can easily create Web Components. Still, you should know that creating a Web Component using a JavaScript framework is undoubtedly more exciting. Nevertheless, you still need to compile the framework’s runtime to create your Web Components.

For example, with Vue.js, to make work your web component, we need to import the Vue.js runtime into our application or compile the runtime in each of our components, which can quickly increase its weight. A comparison of the same Web Component created with several frameworks, I invite you to see this website.

What about sharing CSS?

Previously, we said that Shadow DOM is closed and sharing CSS needs some adjustments to work. Some of CSS properties are inheritable to the Shadow DOM like font properties. https://www.w3.org/TR/CSS21/propidx.html.

The best solution to share CSS inside your Web Component is to use CSS3 import. You declare your common CSS inside your root HTML Document makes a CSS3 import like this @import 'common.css'; inside your Web Component.

If you declare a <slot> inside your Web Component, all the HTML content from this slot will be able to use CSS properties declared inside root HTML document. Your Web Component is attach to the DOM and not the Shadow DOM of your Web Component.

Conclusion

Web Component is a useful technology for Front-End development from conception to its usage.

ADEO Design System (ADS) is getting more flexible when we’ve thought about using Web Components. We are still in a learning and testing phase but confident of this approach for the future.

New javascript frameworks are often released, ADEO strategy is to focus on a short list of Frameworks (VueJS, React, Angular). Having the Web Component available will make it easy to test any new framework on the market.

Meanwhile, thanks to InnerSource, we are developing and maintaining Vue, React and Angular libraries.

We gather a lot of learnings from this experience, ADS team will provide fully detailed feedback on the road to a stable version with Web components.

We would like to warmly thank all early adopters and contributors that help us with topics like accessibility and UX/UI.

Thanks for reading this article!

I wish for a good adventure with Web Components! 👋

--

--

THOMAS RUMAS
ADEO Tech Blog

Software Engineer for Leroy Merlin France. I’m in love with Front-End development