LitElement: using web components
Tags: litelement, webcomponents, html, css
Published: 2019-02-06 13:15:04

On February the 5th Google announced LitHTML was, finally, at version 1 and LitElement had reached version 2. To celebrate I'm going to have a look at web components and, using [the guide](https://lit-element.polymer-project.org/try), convert my [material design switches](https://dev.to/link2twenty/accessibility-first-toggle-switches-3obj) into elements.

{% link https://dev.to/link2twenty/accessibility-first-toggle-switches-3obj %}

The aim is to be able to just write some simple HTML and get a simple, nice and accessible toggle switch back. I'll be using JSFiddle to show the various steps.

```html
<md-switch>Toggle switch</md-switch>
```
![example](https://thepracticaldev.s3.amazonaws.com/i/tb83a5m5g4eyckyb7kg3.png)

## Create
This part has 3 steps that we'll need to work through in order to register our element. We do these steps in Javascript.

 - Import the LitElement base class and html helper function.
 - Create a class for your element that extends the LitElement base class.
 - Register the new element with the browser.

With importing the project I don't have it locally but know that I can see it hosted here `https://unpkg.com/lit-element/lit-element.js?module` which is why my import line says to get `LitElement` and `html` from there.

The most important, and hardest, part of any project is naming. When making a web component the name must contain a hyphen, like `foo-bar`, following general convention we should name our class the same as our element but with hyphens removed and each new word having a capital letter, like `FooBar`. Our project is called `md-switch`.

>The render function defines your component’s template. You must implement render for every LitElement component.

Our render is a simple paragraph containing "Hello world!".

Finally, we need to register the element. This is where we let the browser know `md-switch` elements are associated with the MdSwitch class.

{% jsfiddle https://jsfiddle.net/link2twenty/khw21yxb/ html result %}

### Customising

Now let's get the HTML for our switches. If you want to read about the logic behind the markup and the styles I suggest you read my older post linked above.

```html
<label class="md_switch">
  <input type="checkbox" />
  <span class="md_switch__toggle"></span>
  Toggle switch
</label>
```
You'll notice the label text for the switch is static. This is where `slots` come in handy. They allow you to take the data/text between that tags in the html and 'slot' it into your template.

{% jsfiddle https://jsfiddle.net/link2twenty/53xqruo9/ html result %}

## Properties

Now we'll look at properties. In reality, our switch is a stylised checkbox so needs all of the same properties/attributes. I'm only going to include checked and disabled for this example as they're the most important and will give you a good enough idea of how to implement more.

To add a property we need to add an object to contain them. The litElement way of doing this is with a static get called Properties.

Our object should contain `checked` and `disabled` these are both `Boolean` values and are both attributes of our element.

```javascript
{checked:  { type: Boolean, attribute: true }}
```

{% jsfiddle https://jsfiddle.net/link2twenty/9kmyrvpL/ html result %}

This is good but now we need to pass these properties to our template. Because our properties are boolean we can use the `?` operator, which looks like this:

```html
?checked="${this.checked}"
```

{% jsfiddle https://jsfiddle.net/link2twenty/y53ehtbp/ html result %}

## Events
We don't have to do much with events on this project but we do want to keep our input's checked state and our elements checked state in sync. The easiest way to achieve this is to have an `onchange` event that updates `md-switch`'s checked state when the input's changes.

The way we do this is with the `@` operator. In our template we say `@eventname="{this.functionName}"` we want the change event so we'll use `@change` we'll also need a new function.

{% jsfiddle https://jsfiddle.net/link2twenty/w2tveadj/ html result %}

## Style

To add our styles we need to add `css` to our initial import. Then we need a static get called styles that returns some CSS and that's it.

{% jsfiddle https://jsfiddle.net/link2twenty/yrm1e2wh/ html result %}

## Fin

And that's all there is to it. Web components make reusing elements super easy but you don't have to make all your elements your self. There is a site called https://www.webcomponents.org/ which has thousands of elements you can use in your projects, some elements are better than others so be careful.

I hope this made sense to you and would love to see any elements you have made yourselves. Thanks for reading!

🦄🧠💕🦄🦄💕❤🧠💕❤