DEV Community

Cover image for WebComponents as the standard should be. @github/catalyst
Scipion
Scipion

Posted on

WebComponents as the standard should be. @github/catalyst

⚠️ Don't confuse @github/catalyst with the perl framework Catalyst (also hosted in github).

Good approach, No magic, Production ready.

First of all, don't look for Virtual DOM or Two-way binding in here. But some existing libraries are probably very good to doing this kind of things.

Many developers feel that Web Components still have to improve or the standard should contain those features. IMHO it would be very cool have what React, Vue or Angular already do but with just native custom elements, but the scene is not jet that.

Anyway every day more companies are choosing web components to build/improve their modern web pages. And Github is one of these companies

To make the gap smaller github have just shipped a nice set of helpers using Typescript (mainly the decorators). It's only on the version 1.0.2, but everything shipped is already working in github.com.

Less Boilerplate

Catalyst makes use of decorators to save some repetitive code that every custom element needs. The main one is @controller to decorate the whole class.

@controller
class TodoAppElement extends HTMLElement {

    connectedCallback() {
        //...
    }
}
Enter fullscreen mode Exit fullscreen mode

Automatically the class is register by calling customElement.register with the proper name, in the case above it would be todo-app removing the sufix "Element" from the name.

To make us the live easier @controller also injects a call to bind(this) in the connectedCallback. This makes the actions work in the current scope.

Actions and Targets

The main interaction between the dom and the web component class is made by delegating actions (callbacks), that will be public methods in the current class.

In the data-action we have to specify the dom event, webcomponent name and callback name and the binding will be done.

<div>
    <button data-action="click:todo-item#handleOnRemoved"></button>
</div>
Enter fullscreen mode Exit fullscreen mode

A class field decorated with @target will receive the respective dom element. So the field @target elem; will receive a element marked as data-target="component-name.elem".

The HTMLElemenet can be a target and also the source of actions.

<input
    class="new-todo"
    data-target="todo-input.text"
    data-action="keyup:todo-input#handleInputChange"
    type="text"
    placeholder="What needs to be done?"
    />
Enter fullscreen mode Exit fullscreen mode

Custom Events

Let's don't forget that we are working with just HTMLElments, so in the end we can receive a DOM Event as well as a Custom Event from a nested web coponent. Actions can handle any kind of event and fire any callback defined.

<todo-item
    data-action="
        removed:todo-list#handleOnRemoved
        checked:todo-list#handleOnChecked
    "
    ></todo-item>
Enter fullscreen mode Exit fullscreen mode

Just by adding extra lines in the data-action attribute the callbacks will be binded.

Conclusion

Thanks for reading up to here, this was just a quick summary of what I learned by messing around with @github/catalyst.

You can check the full code of the ToDo List app here.

As I said at the begining, I don't think catalyst is a replacement for modern frameworks but It can be an alternative in the future for other similar tools (today much more matures) like LitElement or Svelte.

It's still a very young package but let's keep an eye on what Github can ship in the future.

Top comments (0)