Skip to content

Custom Elements ​

Quantum is part of the DNA project and its design is largely connected to Custom Elements.

Quantum interface is similar to the Shadow DOM, in that it aims to offer the same developer experience but with a different technology.

Define an element ​

In the example below, we define a custom element that uses a realm to render its internal template. We are going to use µhtml to render the template, but you can use any other view library.

ts
import { attachRealm } from '@chialab/quantum';
import { html, render } from 'uhtml';

export class MyElement extends HTMLComponent {
    readonly realm = attachRealm(this);

    connectedCallback() {
        this.realm.observe(() => {
            // render internal template
            render(this.realm.root, html`<div class="my-element__wrapper"> ${this.realm.childNodes} </div>`);
        });
    }
}

customElements.define('my-element', MyElement);

TIP

Shadow DOM encapsulates styles, but Quantum does not. This is because Quantum render nodes in the light DOM, so you need a good styling strategy like CSS-in-JS or BEM to avoid collisions.

Customized built-in elements ​

Differently from Shadow DOM, we can use Quantum with built-in elements such as <button>, <a> and <ul>:

ts
import { render, html } from 'uhtml';
import { attachRealm } from '@chialab/quantum';

export class MyButton extends HTMLButtonElement {
    readonly realm = attachRealm(this);
    icon = 'home';

    connectedCallback() {
        this.realm.observe(() => {
            // render internal template
            render(this.realm.root, html`
                <i class="button__icon">${this.icon}</i>
                <span class="button__label">${this.realm.childNodes}</span>
            `));
        });
    }
}

customElements.define('my-button', MyButton, {
    extends: 'button',
});

Released under the MIT License.