In this example you will learn how to write Web Components style widgets for adapters.
You can download and install them before starting the tutorial, or can find analogies in your favourite IDE.
The initial code for this exmple is stored in this branch:
ex16-web-components-exercise. You can pull it to go through the lesson.
Web Components - is a way of creating reusable custom HTML-elements while encapsulating their logic and isolating CSS-styles. This method usually presumes the use of the following specifications:
Custom Elements allows the creation of custom HTML-elements with their own tag attribution. Technically, every custom element is a successor of the
HTMLElementclass that's declared in the web-page with the use of the *
window.customElements.define('my-custom-element', MyCustomElement)function. After declaration the element becomes available for reuse in DOM, the same as normal HTML-elements
Shadow DOM provides an isolation of CSS component styles from global styles of the parent web-page. It works in two modes (
HTML Templates are special HTML-elements under the
<template>tag. They provide a convenient opportunity to clone the template's content into a new element, by using the
This approach integrates into the adapter architecture perfectly. It enables the creation of widgets by using any compatible libraries, linters, code formatting and other instruments that facilitate the development process.
- Clone the project template from this branch:
npm idependencies. (this example differs from others by having a library
- Run the project
- Add development servers to the extension with the following addresses:
- On a Google search result activate the dapplet
First let's import to the
./adapter/src/button.ts the necessary elements from the library Lit
LitElement - is a basic class which we will be inheriting from. It expands the native
HTMLElement and hides the extra template rendering, style application, and reactive state change logic.
css - are Tagged Template Literals, which you can use to write HTML and CSS component code. The code inside literals can be highlighted and automatically formatted with the use of the according plugins, which makes the development more convenient.
property - is a decorator. It can be used to make the properties of the component reactive and publically available to change from the outside. These properties will rerender the component when their values are altered.
Read more about other Lit possibilities in its official documentation.
Inherit the widget class from the
LitElement class, and implement the interface with public properties
Most likey, your IDE will not like that unrealized class properties are missing. Do not worry, we will do this below.
Widgets can work in different contexts. The contexts can have various insertion points. The compliance between them must be declared transparently.
Add the properties that will be available to the dapplets developer. Every property is marked with a decorator
@property, this makes them reactive.
Please be aware that there are several required properties that must be realized in your widget. They are system properties, which are defined by the Dynamic Adapter.
All widgets are provided with an
init hook so that dapplets developers can do something the moment a new context appears. This moment needs to be realized transparently.
An overload of the
connectedCallback() method in LitElement allows us to subscribe to the component rendering event. We will use this.
A dapplets developer should have the possibility to subscribe to the button click event. Beforehand, we will add a click handler with a callback from the
Let's begin writing the HTML-template of the component.
render() method is very similar to a method with the same name in a class-based approach to writing
React.js components. Here you can also return
null when it is not necessary to render the component. However, instead of JSX we use Tagged Template Literal -
Learn more about all template possibilities in the official Lit documentation. There you can find information about using conditions in rendering, iterators, events, etc.
You can also look at an example of a complex widget from the Twitter Adapter.
Declaration of CSS-styles is very similar to the approach used in the
styled-components library, famous among React.js developers. Here the Tagged Template Literal -
css function is used again.
Remeber that your Web Components are rendered inside Shadow DOM, which provides an isolation of the styles. This means that global styles of the parent web-page will not be able to redefine internal styles of your component and you will not be able to use them again.
Inside Shadow DOM you can style the shadow root element with the use of a CSS pseudo-class
:host(). Sometimes this is useful for seamless website integration.
:hover are also available here. You can use all of CSS power to style your components.
Together we have realized a button, that will be inserted into search results on the Google search page.
The final solution is available in this branch:
The final initial code of the button is available here.