Building a custom tag input with Skate.js

8,703 reads

Are you lost trying to build and use Web Components? Skate.js uses the platform and sheds some light on it.

What are we going to build?

An input-like tag which looks like a normal text input but splits the content into tags when the users hit space. Take a look at the live demo of the component here and the code here for a better understanding and features:

Autofocus when tags are created.

Natural deletion when pressing DEL.

UI 100% customizable, full control of the elements inside shadowDom.

Allow user to delete tags pressing a button.

Initial value through component attributes.

Input automatically grows as the user types something.

Specify custom delimiter.

Introduction

Web Components are great because they allow us to define custom HTML elements and encapsulate their behavior. But today I want to introduce you a library which I’ve been playing recently and may change the way you see web components.

Skate.js it’s a lightweight library (4k min+gz), which focuses on the usage of web components specs and gives you a functional rendering pipeline.

Skate.js achieves that using the 2 most important web component features:

Ok, but… What does this all mean? All right, lets take a look at the code.

Registering the component 📦

In the first line we are including skatejs-web-components module, which provides all the necessary polyfills Skate.js needs, so you don’t have to worry about browser compatibility.

Later on we are creating the skeleton of our component, we extend the Skate Component, which is like a WebComponent on steroids and we can just pass it to customElements.define ✌.

️We define the layout of the component in the renderCallback, pretty much the same as you will do with React.js in the render method. And finally, we register the props which will cause a re-render when mutated.

That will gives us a component with shadowDom as a result:

Adding behavior: Events + props 🔩

Now we have a fully working tag component 🎉, this is what we have added:

tags prop: Property which contains the state of the tags, every time we modify it Skate.js will re-render your component with the minimum DOM modifications. Nice thing here is we are using the props.array method, this is a built-in and will ensure that any value passed to the property is an array, allowing us to parse the value of the property and set an initial value like: <sk-tags tags="[milk,bread,chocolate]" />

prop: Property which contains the state of the tags, every time we modify it Skate.js will re-render your component with the minimum DOM modifications. Nice thing here is we are using the props.array method, this is a built-in and will ensure that any value passed to the property is an array, allowing us to parse the value of the property and set an initial value like: Input resize: This is a key part of the component and makes it responsive. Method adjustInputSize sets the width of the real input every time the value changes, that way the component breaks the line properly.

sets the width of the real input every time the value changes, that way the component breaks the line properly. Delimiter handling: onIput check whether or not the last character introduced by the users matches the component delimiter (defaults to empty space).

The image above shows how we use the tags element (blue) to add the tags and how the real input element (red) grows dynamically making the component responsive.

Allowing deletion + custom styles 💅

Changes here are pretty straight forward, 2 new props deletion and styles, just concatenate the default styles + the user ones allowing him to do something like this:

<sk-tags styles=".tag{ background-color: red;} .wrapper{ border: 1px solid black; }" />

Or if you prefer something more maintainable you can do this:

Just using a 10 lines styles helper which will convert objects to css content.

Conclusion

It feels quite natural building components with Skate.js. I didn’t have any experience with it before but a lot of things just worked out of the box the way I expected them to work and was enough for me to realize of the benefits that Skate.js provides vs building the component with vanilla js.

Im pretty sure that if you are familiar with web components you might find there are some things missing, like having a high level way of rendering your component without having to mutate the DOM manually or having a mechanism that takes care of the properties and keeps the UI in sync with the actual component state, a robust property api, etc. You might find those issues solved with the Skate.js opinionated way of doing things.

To recap a bit we have covered props and extension from the docs. In the next article I want to show you how to build a more advanced component and cover other interesting parts of the library.

Finally, I’d like to recommend you a good source from the ChromeDevelopers youtube channel, the Supercharged series, in which you can see great live demos of how to build web components today and you can compare 👀.

You can follow me on Twitter or Github @zzarcon

Tags