Building Web Components 101 - Part 3
Tags: webdev, webcomponents, javascript
Published: 2022-09-26 02:52:15

In Part 2, I went through the fundamentals of FAST and created a custom component using FAST Element. In this article, I will explain how to create custom attributes in FAST.

I will start with where we left off in Part 2. To access the source code in this article, you can clone the project at [https://github.com/tebinraouf/learning-fast/tree/building-web-components-101-part-3](https://github.com/tebinraouf/learning-fast/tree/building-web-components-101-part-3)


or you can use Stackblitz 
{% embed https://stackblitz.com/github/tebinraouf/learning-fast/tree/building-web-components-101-part-3?file=index.html %}


## How to create a custom attribute?
In Part 2, we create a custom `<tebin-h1>` component where we hard coded the heading colour. In this article, we will create a custom attribute so that we can define the custom attribute value when the component is used.

**Code:**

`<tebin-h1>Albert Einstein</tebin-h1>`

**Result:**

![A custom Albert Einstein title](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a9am78ygeyb27q1gtwkt.png)

By default, the title is brown since we defined it. 

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

export const styles = css`
    :host {
        display: block;
    }
    h1 {
        color: brown
    }
`;
```

We want to create a `color` attribute so that we can set it when the component is used like below:

```html
<tebin-h1 color="yellow">Albert Einstein</tebin-h1>
<tebin-h1 color="#41aea9">Albert Einstein</tebin-h1>
<tebin-h1 color="blue">Albert Einstein</tebin-h1>
```


## How to create custom attributes in FAST?

FAST offers `@attr` decorator to create attributes. Let's go through the steps required to use `@attr` decorator:

- Create a property on the custom component class. In this case, the class for `tebin-h1` component is defined in `h1.ts`.

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


export class H1Component extends FASTElement {
+    @attr color: string = 'brown'
}

export const h1component = H1Component.compose({
    name: "tebin-h1",
    template,
    styles,
});

```

By default the value is set to brown. 

- The next step is to update the template so that the value is set to the `h1` tag. We are going to use inline style for this demo. However, you would normally use the the css tag or scss to style your components. 

`h1.template.ts` now looks like the following:

```diff
import { html } from "@microsoft/fast-element";

export const template = html`
-    <h1>
+    <h1 style="color: ${x => x.color}">
        <slot></slot>
    </h1>
`;
```

FAST uses MVVM - _Model-View-ViewModel_ pattern. Since we defined the `color` property on the class, which is the Model, then we can bind it on the view by using `${x => x.color}`.

- Lastly, we will delete the style that we defined in the `h1.style.ts` file.

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

export const styles = css`
    :host {
        display: block;
    }
-    h1 {
-        color: brown
-    }
`;
```


With only a few changes, our custom element now has a custom attribute. 

**Markup:**
```html
    <tebin-h1 color="yellow">Albert Einstein</tebin-h1>
    <p>Life is like riding a bicycle. To keep your balance, you must keep moving.</p>

    <tebin-h1 color="#41aea9">Albert Einstein</tebin-h1>
    <p>Life is like riding a bicycle. To keep your balance, you must keep moving.</p>

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

**Result:**

![Showing Einstein title in different colours](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fbt11c2xbw31qj563p6.png)


In the next article, we will talk about how to bind events in FAST.