Front-End Insights

A short introduction to Web Components and Polymer

PolymerProgramming

New project, new technologies to learn… My current company has acquired a new customer recently and I was assigned to help in the project. Unfortunately, they don’t use any popular front-end technologies such as Angular or React. Instead, I now have to learn Web Components and Polymer which are completely new to me… The good thing is that this is a good opportunity for me to create several blog posts where I will show you what I’ve learned.

Ok, let’s check what this is all about…

A few words about Web Components

Well… Web Components are not actually a new thing in web development. Basically, it is a concept of reusable widgets (components) which contain an html template and can be imported in different files and used as normal HTML tags. The main intention of its creators is to make Web Components a browser standard so they won’t need any external libraries to work.

Unfortunately they are still not supported by all browsers so there is a need to use a set of polyfills – they are called webcomponentsjs and are available here, on GitHub. Here’s how they are described:

A suite of polyfills supporting the Web Components specs:

  • Custom Elements: allows authors to define their own custom tags.
  • HTML Imports: a way to include and reuse HTML documents via other HTML documents.
  • Shadow DOM: provides encapsulation by hiding DOM subtrees under shadow roots.

This also folds in polyfills for MutationObserver and WeakMap.

The above description shows that thanks to the webcomponentsjs polyfills we can use all of Web Components functionalities even if the browser does not support them yet.

What is Polymer?

Polymer is basically a library which is built on top of the Web Components API. Apart from all the benefits of Web Components, it provides several useful and helpful simplifications to make building custom components easier. For example it gives us a declarative syntax which helps in defining element structure, styling it with CSS and adding behaviours written in JavaScript. It can also provide two-way data binding.

Ok, we know the theory… Let’s take a look at how we can create our first “Hello world” component. First, we just have to create an index.html file and load the polyfill:

<!doctype html>
<html>
<head>
    <!-- import latest release version of all components from polygit -->
    <script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.js"></script>
</head>
<body>
</body>
</html>

As you can see, all we have to do is to load one JavaScript file of the webcomponentjs project.

Now, let’s create a really simple component. To do so, we have to create a file, e.g. hello-world.html – yes, components are just HTML files:

<link rel="import" href="https://polygit.org/components/polymer/polymer.html">

<dom-module id="hello-world">
    <template>
        <p>Hello world!</p>
    </template>

    <script>
        Polymer({
            is: 'hello-world'
        });
    </script>
</dom-module>

In the first line of the file, you can see that we “import” a polymer custom component. You have to do that whenever you create a new custom component. You can also import any other component this way, if you like. And, of course, you can use components inside other components, etc.

Ok, the next important thing: as you can see, the whole component is just a dom-module HTML tag. Its id attribute contains the name of the component which will be used later when we use this component.

Inside the dom-module tag we can see the template tag. It contains the whole template of the component – in our case it’s just a “Hello world!” sentence.

Later in the module we have a script. It contains a registration of our custom component in Polymer by passing an object with the is attribute set to the name of the component.

Ok, now it’s time to use our custom component in the index.html page. Please see below the modified file:

<!doctype html>
<html>
<head>
    <!-- import latest release version of all components from polygit -->
    <script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.js"></script>

    <!-- import custom component -->
    <link rel="import" href="./hello-world.html">
</head>
<body>
    <hello-world></hello-world>
</body>
</html>

As you may have noticed, we import the hello-world component in the header the same way like before when we imported the polymer component at the beginning of our custom component file.

The next thing is the way we use the component. Please see inside the body of the HTML document. We just use the custom HTML tag hello-world. When we open the file in the browser it will render the content of the component’s template tag inside of it – please see below the resulting HTML rendered by the browser:

<!doctype html>
<html>
    <head>
        <!-- Shady DOM styles for custom-style -->
        <!-- Shady DOM styles for dom-template -->
        <!-- Shady DOM styles for dom-repeat -->
        <!-- Shady DOM styles for array-selector -->
        <!-- Shady DOM styles for dom-if -->
        <!-- Shady DOM styles for hello-world -->

        <style>
            body {transition: opacity ease-in 0.2s; } 
            body[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } 
        </style>

        <!-- import latest release version of all components from polygit -->
        <script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.js"></script>

        <!-- import custom component -->
        <link rel="import" href="./hello-world.html">

        <style>.pkt_added {text-decoration:none !important;}</style>
    </head>
    <body>
        <hello-world>
            <p class="style-scope hello-world">Hello world!</p>
        </hello-world>
    </body>
</html>

Of course, Polymer has added some additional classes, styles, etc. but the key is that it works as we expect it to.

Passing properties into the component

Passing some data into the component is easy. Just take a look at the modification of our custom component:

<link rel="import" href="https://polygit.org/components/polymer/polymer.html">

<dom-module id="hello-world">
    <template>
        <p>Hello world and {{andWho}}!</p>
    </template>

    <script>
        Polymer({
            is: 'hello-world',
            properties: {
                andWho: {
                    type: String
                }
            }
        });
    </script>
</dom-module>

Firstly, please look at the script – we have added a second property called properties which contain a declaration of the name of the property (andWho) and its type (String).

Secondly, please see how we use it in the template – just like in many other frameworks ({{andWho}}).

Great, so how can we now pass the value into the component? The answer is below:

<hello-world and-who="Bartek"></hello-world>

That’s right. The property we’ve just declared is a HTML attribute of the component. Of course the name of the variable is camelCase but the attribute uses dash.

Adding styles to a component

Styling a component is also very easy! Just add the style tag inside the template:

<link rel="import" href="https://polygit.org/components/polymer/polymer.html">

<dom-module id="hello-world">
    <template>
        <style>
            p {
                color: red;
            }
        </style>

        <p>Hello world and {{andWho}}!</p>
    </template>

    <script>
        Polymer({
            is: 'hello-world',
            properties: {
                andWho: {
                    type: String
                }
            }
        });
    </script>
</dom-module>

I don’t think this needs any additional explanation 😉

Summary

That’s it for today, but I believe it is not the end of the Web Components/Polymer topic. If I learn something new and interesting I will share it with you, for sure!

P.S. The example I’ve shown today is available for you on my GitHub: https://github.com/burczu/polymer-introduction!

Related Post

I recommend Nozbe

Simply Get Everything Done

Get your tasks and projects done thanks to Nozbe system and apps for the Mac, Windows, Linux, Android, iPad and iPhone.

If you want to know more about Nozbe and its capabilities, please take a look at my article about this great application.