This story is about my attempt to convert the Angular’s popular Tutorial: Tour of Heroes into a Stencil application. I recommend that you read the introduction part of the Angular tutorial to get a feeling about what kind of app we will build here.

What you will have learned after this tutorial is how to build the Tour of Heros application with Stencil.

The Application Shell

Install the Stencil starter app

Start with cloning down the stencil app starter and install all dependencies.

git clone https://github.com/ionic-team/stencil-app-starter tour-of-heroes

cd tour-of-heroes

git remote rm origin

npm install

Then run npm start and the app should show up in a browser window.

The npm start command builds and start your app in development mode and reloads every time you edit a file.

Stencil components

Stencil apps is built up as web components that is written in JSX and Typescript that then is compiled into standard web components. The components is divided into folders most commonly under src/components /.

Change the application title

Open the project in your editor and navigate to the src/components/my-app/ folder.

The my-app component is the main component of the app since it’s included in the file src/index.html with a custom html tag <my-app></my-app> .

In the my-app component folder you will find 3 files, my-app.css for the components private style sheets, my-app.spec.ts for unit testing and my-app.tsx containing the components logic and JSX markup.

Open the file my-app.tsx and start by adding a private ‘title’ property to the MyApp class:

export class MyApp {

private title: string = ‘Tour of Heroes’;

...

Then edit the h1 tag to contain {this.title} , save the file and you will notice the change in the browser within a few seconds.

Bonus: Update the title tag in the index.html to “Tour of Heroes” as well.

Add application styles

The Stencil starter app have the application wide styling in a style tag inside the index.html file, so let’s replace that with the Tour of Heros sample stylesheet like this (slightly modified to not look like crap):

<style>

/* Application-wide Styles */

h1 {

font-family: Arial, Helvetica, sans-serif;

font-size: 250%;

} h2, h3 {

color: #444;

font-family: Arial, Helvetica, sans-serif;

font-weight: lighter;

} body {

margin: 2em;

margin: 0px;

padding: 0px;

font-family: sans-serif;

} body, input[text], button {

font-family: Cambria, Georgia;

} /* everywhere else */

* {

font-family: Arial, Helvetica, sans-serif;

}

</style>

You can click here to review what we have done so far. (Be kind and give my Github project a star ⭐️😉).

The Hero Editor

Now we will create a stencil component to display information about a hero.

Since Stencil doesn’t have any CLI (Command Line Interface) yet, we will have to create the new component manually.

So create a ‘heroes’ folder in src/components/ and create the 3 files heroes.css, heroes.spec.ts and heroes.tsx inside that folder.

File structure after creating the heroes component.

Add the following initial content to the heroes.spec.ts:

and the heroes.tsx:

You always import the Component symbol from the Stencil core library and annotate the component class with @Component .

The component have two metadata properties,

* tag, the name of the html tag that is used to include this component in any other html page/component.

* styleUrl, the url to the components private styling.

Add a hero property

Add a hero property to the Heroes component for a hero named "Windstorm."

private hero:string = 'Windstorm';

Show the hero

Then print out the hero in the html part inside the div element.

<div>

{this.hero}

</div>

Show the Heroes view

To display the Heroes component, you can add it to the template in app-home.tsx .

Remember that app-heroes is the element selector for the Heroes component. So add an <app-heroes> element to the app-home.tsx JSX template, just below the app-home div.

Create a Hero class

A real hero is more than a name.

Stencil can consume regular Typescript classes just like Angular.

Create a Hero class in its own file in a new src/models folder. Give it id and name properties.

Return to the Heroes component and import the Hero class.

Refactor the component’s hero property to be of type Hero . Initialize it with an id of 1 and the name Windstorm .

The revised Heroes component file should look like this:

Format with an Uppercase function

Since Stencil don’t have anything similar to Angular’s pipes, we will instead use the standard JavaScript function toUpperCase() .

Modify the this.hero.name binding like this:

{ this.hero.name.toUpperCase() }

Before we continue let’s remove the app-home and app-profile components.

Delete the app-home and app-profile component folder.

Remove the app-profile stencil-route from my-app.tsx .

. Change the other stencil route from app-home to app-heroes.

You need to import the stencil router in the my-app.tsx for the routing to continue working:

import { } from '@stencil/router';

Then one last detail, add the following styling to the heroes.css :

.app-heroes {

padding: 10px;

}

and add the class app-heroes to the top div element in heroes.tsx .

If you want to review what we’ve done so far check out the first tag of this project on Github here: https://github.com/nerdic-coder/stencil-tour-of-heroes/tree/v1.0

Edit the hero

Users should be able to edit the hero name in an <input> textbox.

The textbox should both display the hero’s name property and update that property as the user types. That means data flow from the component class out to the screen and from the screen back to the class.

To automate that data flow, setup a two-way data binding between the <input> form element and the this.hero.name property.

Refactor the details area in the Heroes component so it looks like this:

Since Stencil don’t have anything similar to Angular’s ngModel we will have to write the two way binding flow yourself.

So first to make the hero object issue a re-rendering to changes we need to add the State decorator to it.

Then we also need a function to update the heroes name, take a look at the handleChangeName(event) function above how we update the name for the object. The re-rendering would not occur if we would only update the heroes name directly with this.hero.name = event.target.value . The change is only noticed when the whole hero object is reassigned.

The last part is the input field that gets the heroes name as the value and is defining an event ‘onInput’ that is triggering our function every time the input is changed.

If someone knows any other ways to have two-way binding in Stencil, please let me know in the comments below.

Conclusion

We have reached the end of the first part in this tutorial, stay tuned for the second part where we will create a heroes list and making the heroes app more useful.

You can review the code for this tutorial on Github at: https://github.com/nerdic-coder/stencil-tour-of-heroes/tree/v1.1

Continue with part 2 here: https://medium.com/@nerdic.coder/stencil-tutorial-tour-of-heroes-part-2-a6ed0b7b95ac