ElementBuilder

The builder is bundled in the NPM package @tmorin/ceb-elements-core.

The class ElementBuilder provides services to define and register a Custom Element.

Challenge yourself

Will you be able to ...

  1. change the tag name to <my-greeting></my-greeting> without changing the class name?
  2. transform SimpleGreeting as an extension of h1, so that can be created with <h1 is="my-greeting"></h1>? the class of h1 is HTMLHeadingElement

See the Pen <ceb/> ~ challenge/ElementBuilder by Thibault Morin (@tmorin) on CodePen.

Define a regular Custom Element

import { ElementBuilder } from "@tmorin/ceb-elements-core"

// defines and register the custom element class
@ElementBuilder.get().decorate()
class SimpleGreeting extends HTMLElement {
  constructor(public name = "World") {
    super()
  }

  connectedCallback() {
    this.textContent = `Hello, ${this.name}!`
  }
}

Once registered, the Custom Element can be created with three different styles: markup, Object-Oriented and, hybrid.

The first one relies on the tag name of the Custom Element within the markup of an HTML document.

document.body.innerHTML = `<simple-greeting></simple-greeting>`

The second one relies on the Object-Oriented nature of the Custom Element. Basically, the class can be instantiated, and the created object can be then append to the DOM.

const helloJohn: SimpleGreeting = new SimpleGreeting("John")
document.body.appendChild(helloJohn)

The last one lies between the markup and OO style.

const helloDoe: SimpleGreeting = document.createElement("simple-greeting")
helloDoe.name = "Doe"
document.body.appendChild(helloDoe)

Define an extension of a native Element

import { ElementBuilder } from "@tmorin/ceb-elements-core"

// defines and register the custom element class
@ElementBuilder.get().extends("p").decorate()
class SimpleGreetingParagraph extends HTMLParagraphElement {
  constructor(public name = "World") {
    super()
  }

  connectedCallback() {
    this.textContent = `Hello, ${this.name}!`
  }
}

Once registered, the Custom Element can be created like the regular one. However, because of the extension of a native Element, the creation expects additional information.

The creation with the markup style:

document.body.innerHTML = `<p is="simple-greeting-paragraph"></p>`

The creation with the Object-Oriented style:

const helloJohn: SimpleGreetingParagraph = new SimpleGreeting("John")
document.body.appendChild(helloJohn)

The creation with the hybrid style:

const helloDoe: SimpleGreetingParagraph = document.createElement("p", {
    extends: "is"
})
helloDoe.name = "Doe"
document.body.appendChild(helloDoe)