Building Web Components 101 - Part 2
Tags: fastdesign, webcomponents, javascript, webdev
Published: 2022-09-14 05:53:37

In [Part 1](https://dev.to/tebin/building-web-components-101-part-1-5p5), I went through the basics of Web Components and the problem it solves. In this article, I will explore [FAST](https://www.fast.design/) to create Web Components or custom elements. 

As I stated in Part 1, there is no need for abstraction layers, however, abstraction layers provide patterns and best practices for engineers to follow. Patterns and best practices take time to learn but they will speed up developments and they will help to make our code more readable by ourselves in the future or by anyone else. 


## What is FAST?
According to [https://www.fast.design/](https://www.fast.design/), FAST is

> The adaptive interface system for modern web experiences

Let's clarify that. FAST is a system to build web experiences which include custom elements, design systems, single page applications, or any other front end sites. With FAST, we get to follow some basic patterns to build components and sites that scale easily. 


## FAST as a system includes the following:

1. **FAST Element:** an extension of HTMLElement to create custom elements. This is a thin layer of abstraction to make it easier to create custom elements.
2. **FAST Foundations:** a set of style-less web components such as Modal, button, badge, etc.
3. **FAST Toolings:** a set of tools/CLI help scaffold component creations and design system creations.
4. **FAST Integrations and Utilities:** additional and optional libraries to add even more functionalities to the FAST system such as Routing, SSR, Animations, Colors, React wrapper, Blazer wrapper, and more.




## How to build a component with FAST?

In [Part 1](https://dev.to/tebin/building-web-components-101-part-1-5p5), we built a custom brown `<h1>` tag and we named it `<tebin-h1>`. Let's build the same component with FAST. 

To create a custom element, we will be using `fast-element@v2.0.0-beta.4` package. 

To go through how to build with FAST, I've setup a basic project with Webpack. In the spirit of using as much as possible from FAST, I used FAST's [ToDo's example](https://github.com/microsoft/fast/tree/master/examples/todo-app) to start with. Kudos to **_FAST team_** for providing these examples.


You can find the repository here ([https://github.com/tebinraouf/learning-fast/tree/building-web-components-101-part-2](https://github.com/tebinraouf/learning-fast/tree/building-web-components-101-part-2)) to follow up with the rest of this article.
 
```sh 
git clone https://github.com/tebinraouf/learning-fast.git
cd learning-fast
yarn or npm install
yarn build
yarn dev
```

or use [Stackblitz](https://stackblitz.com/github/tebinraouf/learning-fast/tree/building-web-components-101-part-2?file=index.html) for the project.

The project structure is as follows: 
```sh
.
├── README.md
├── index.html
├── package.json
├── src
│   ├── components
│   │   └── h1
│   │       ├── h1.style.ts
│   │       ├── h1.template.ts
│   │       ├── h1.ts
│   │       └── index.ts
│   └── index.ts
├── tsconfig.json
└── webpack.config.cjs
```

Let's focus on the component directory. FAST breaks down component creation into 4 pieces: 

1. Component styles, which are defined in `*.style.ts` file. In this case, `h1.style.ts` file.
2. Component template, which is defined in `*.template.ts` file. In this case, `h1.template.ts` file.
3. Component composition, which is defined in `*.ts` file. In this case, `h1.ts` file.
4. Component definition or registration, which is defined in index.ts file. In this case, `h1/index.ts` file.

_Note: these 4 separate files are not required. You can combine all four into one single file, which could be difficult to maintain in a large project. These 4 different files provide clear separation of concern._


### Let's dive deep into each part of the component:
- `h1.style.ts` holds all the styles for your component. Out of the box, we can provide CSS as string or CSS through FAST's `css` tag like below:

```ts
import { css } from "@microsoft/fast-element";

export const styles = css`
    :host {
        display: block;
    }
    h1 {
        color: brown;
    }
`;
```
Or CSS as string
```ts
export const styles = `
    :host {
        display: block;
    }
    h1 {
        color: brown;
    }
`;
```
or with some configurations, you could use SASS. For future articles, 

_I will write about how to configure SASS for FAST. However, the idea is to convert SASS to CSS string, which can then be used by the FAST component directly._

![A flow diagram to show converting SASS to CSS for FAST component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emvdkn6oi9bhc7qy2j4p.png)


- `h1.template.ts` holds the template for the custom component. Out of the box, FAST provides `html` tag build templates like below:
```html
import { html } from "@microsoft/fast-element";

export const template = html`
    <h1>
            <slot></slot>
    </h1>
`;
```
`slot` is an HTML element. It allows us to provide dynamic content or markup to our custom element. We can think of `slot` as placeholder. 


![A diagram to show slot as a placeholder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cc7lpr6m0sbiujlm6j6w.png)

If there is one slot in the template, this is considered as the default slot. Text or mark up can be used in place of a slot. 

If there are more than one slot, we would need to name them to identify the slot. To get more details, you can navigate to [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).

- `h1.ts` is used to compose or combine the template and the style. We also define the custom component name, which will be used when the web component is used.  

`*.compose({})` returns the custom element definition, which we will use to register the component. 

```ts
import { FASTElement } from "@microsoft/fast-element";
import { styles } from "./h1.style.js";
import { template } from "./h1.template.js";


export class H1Component extends FASTElement {

}

export const h1component = H1Component.compose({
    name: "tebin-h1", //the component will be used like <tebin-h1></tebin-h1>
    template,
    styles,
});
```

- `components/index.ts` is used to define/register the component based on the component definition that we get from `*.compose()`. 

```ts
import { h1component } from './h1.js';

h1component.define();
```

Lastly, to use the custom component, we will add the custom element to `index.html`

```html
<tebin-h1>Albert Einstein</tebin-h1>
<p>Life is like riding a bicycle. To keep your balance, you must keep moving.</p>

<tebin-h1>Pablo Picasso</tebin-h1>
<p>Everything you can imagine is real.</p>
```

**DOM Element:**

![DOM Element for tebin-h1 custom element](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufzh1qv7s6jn4qmhn7mz.png)

**Result:**

![A quote from Albert Einstein and Pablo Picasso](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3goskn0th1eblzwwmxh.png)


To learn more, FAST provides excellent documentations on their official site at [https://www.fast.design/](https://www.fast.design/). I will encourage you to check it out.

Lastly, by following a few simple patterns and structure, we were able to create a FAST custom element with ease. This article allows us to talk about more advance topics in the future such as directives, observables, and states. In future articles, I will talk about these and other FAST offerings.