How to create a simple UI library using TypeScript decorators

Vijaya Anand
3 min readNov 28, 2021

Lately I’ve been looking for a light-weight library that helps to develop UI components using native browser technologies like Web Components, Shadow DOM etc. I see most of them surviving out there like Angular, React are not completely based on native technologies and not only that they have quite some learning curve. Also, there is always this fear that, am I doing this in the right way?. I found libraries like LitElement compelling but finally I ended up creating something simple, light-weight that focuses only on solving the component building business and nothing else.

I created a small library called tiny that utilizes decorators and a simple base class to create components using native technologies. I’m pleased by the outcome. Though it doesn’t support fancy data bindings and other cool features (for now) it turned out to be good!. In this article, I would like to share some of the learnings I got in the process of building that library and hopefully someone can use them to build their own library in future and why not please share your thoughts and ideas to transform the tiny into something bigger.

Concept

The below code reveals the concept I had in my mind. It represents a simple web component that displays different emojis in different sizes based on inputs.

@element('my-smiley, `<span></span>`)

class SmileyElement extends BaseElement {

@input()

type: string = 'happy';

@input()

size = 'small' | 'medium' | 'large' = 'medium';

@query('span')

spanEl;

onChanges(changes) {

// TODO: perform DOM operations

}

First of all, I love decorators! I hope you do too. I want to leverage them as much as possible to do the reusable business. You can see in the above snippet that we’ve applied a few decorators like element, input and query.

The element decorator transforms the class into a web component. The input decorator as the name is used to mark the properties as inputs. The query decorator is used to automatically query and return the child element on accessing the applied property. We can have more fun with decorators, how about one to auto bind events to a function? Yes, we can! Let’s keep things simple for now. Please check out the tiny github repo to refer to more decorators.

The other important thing to notice is, the SmileyElement extends from a base class BaseElement. To make the decorators work we got to do some plumbing and not only that we have other works too.. like rendering the passed template, helper methods to work with DOM etc. Most importantly, to register a class as a web component it should extend from HTMLElement or one of the built-in elements and the BaseElement extends from HTMLElement.

The base class also provides some life-cycle hooks for the component to intercept and act. As you see there is an onChanges method that’ll be invoked every time there is a change in inputs and it is the place you need to perform the DOM operations. Since we don’t have those cool data bindings we need to do the DOM updates manually. Don’t worry, the base class provides a bunch of helper methods to make that process easier, effective and with absolute control.

Alright, let’s set up the project and see how we can build those decorators first and then the base class.

To continue read please visit http://prideparrot.com/blog/archive/2021/11/how_to_create_simple_ui_library

--

--