Angular Material Handbook: Setup and Basics
Tags: angular, javascript, typescript
Published: 2020-05-30 00:30:13

If you're an Angular developer, chances are that you've heard of [Angular Material](https://material.angular.io/). If not, then that's okay, I'm here to guide you. 

Angular Material is a component library that follows the Google [Material Design Spec](https://material.io/design/guidelines-overview). Buttons, tabs, form fields and loading spinners are just a few of the many components in this library and it's super easy to develop applications quickly. 

My goal with this series is to walk through each and every single component and show you how to use it, take advantage of its API and customize them for your own applications. We will need to run through a few foundation concepts before hitting the components but I'll try my best to keep it short and sweet. Let's get started!

**Note that at the time of writing, I'm currently using Angular 9 with its corresponding Angular Material Version. I'll try my best to update these articles as Angular updates.**

_Hint: All the code for this article can be found [here](https://github.com/Qarun-Qadir-Bissoondial/angular-material-tutorial/tree/1-setup-and-basic-concepts)._ 

## Installation and Setup

Create a new project by running `ng new angular-material-tutorial` and `cd` into the root directory of the project. Once inside, we need to run `ng add @angular/material`. 

This will install the necessary npm modules and walks us through some default configuration options. Let's walk through them.

### Themes
The first question we need to answer is what theme we would like to pick. 

```
? Choose a prebuilt theme name, or "custom" for a custom theme: (Use arrow keys)
❯ Indigo/Pink        [ Preview: https://material.angular.io?theme=indigo-pink ] 
  Deep Purple/Amber  [ Preview: https://material.angular.io?theme=deeppurple-amber ] 
  Pink/Blue Grey     [ Preview: https://material.angular.io?theme=pink-bluegrey ] 
  Purple/Green       [ Preview: https://material.angular.io?theme=purple-green ] 
  Custom 
```

Pick any that you like, I'll choose Indigo/Pink as my default. We'll look at custom themes in a later article, I promise! But for now, I'll link the previews below. 

[Indigo/Pink](https://material.angular.io?theme=indigo-pink)
[Deep Purple/Amber](https://material.angular.io?theme=deeppurple-amber)
[Pink/Blue Grey](https://material.angular.io?theme=pink-bluegrey)
[Purple/Green](https://material.angular.io?theme=purple-green)

It's important to pick a theme that matches the feel of your application or a theme that matches the brand of your company. But more importantly, we need to keep accessibility in mind. Angular Material Themes should all conform to the [WCAG Standards](https://www.w3.org/WAI/standards-guidelines/wcag/). These rules are laid out so that people who are differently-abled can still access our applications.

One example is maintaining an acceptable level of contrast between background and foreground to ensure visibility of content. This is also part of WCAG Compliance and should be adhered to. Failure to adhere to these rules can actually result in a lawsuit in some parts of the world!

### Angular Material Typography

```
? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink        [ Preview: https://material.angular.io?theme=indigo-pink ]
? Set up global Angular Material typography styles? (y/N) y
```

Unless you have your own Typography System, you'll want to select yes for this setting. This gives us access to a lot of classes responsible for spacing, shadows, animations, etc. By default, Angular Material does not apply any global CSS but these will be applied within components and to child elements of a parent bearing the `.mat-typography` class. You can find out more [here](https://material.angular.io/guide/typography).

### Browser Animations

```
 Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink        [ Preview: https://material.angular.io?theme=indigo-pink ]
? Set up global Angular Material typography styles? Yes
? Set up browser animations for Angular Material? (Y/n) y
```
You'll want to select yes for this one as well as most of Angular Material UX interactions rely on animations. It follows the [Material Design Guidelines on Motion](https://material.io/design/motion/understanding-motion.html#principles).

### Finishing Installation 

```
UPDATE src/app/app.module.ts (502 bytes)
UPDATE angular.json (3972 bytes)
UPDATE src/index.html (526 bytes)
UPDATE src/styles.scss (181 bytes)
```

At this point, the installation is complete and the above files have been altered. Here's a brief summary:

 - Material Design Icons and the Roboto Font (at font weights 300, 400 and 500) has been added to your `index.html`. You can add more of these weights if needed. Weights are in multiples of 100 and ranges 100-900. `.mat-typography` has also been applied to your body.
 - Default styles have been added to your `styles.scss` file
 - The `.css` theme that we selected earlier has been inserted into `angular.json` under the `styles` section of our application `build` and `test configuration`
 - `package.json` and `package-lock.json` were updated with the installed packages.

Now we can run `ng serve` and open our browser on `localhost:4200` to see our Angular Application. If you've reached this far without any errors, then you've sucessfully added Angular Material to your project :smile:

## Templating Basics

Angular gives us access to the properties of an HTML Element by allowing us to create a Template Reference. This reference can now be accessed directly by our HTML just like a component variable or inside the component itself using the `@ViewChild` decorator.

We won't need to use `@ViewChild` unless necessary but I wanted to illustrate how to use Template Referencing to our advantage. It's also extremely vital knowledge to have when working with Angular Material.

Let's say we have a counter component. This component starts at 0 and shows the number by default. We have the option to show, hide and increment the number. But we want parent components to control these actions. I used inline styles and template as the component was small.

```typescript
import { Component } from '@angular/core';

@Component({
  selector: 'app-counter',
  template: `
  <h2>My Counter - {{showNumber ? "shown" : "hidden"}}</h2>
  <p *ngIf = 'showNumber'>{{num}}</p>`,
  styles: [':host { text-align: center; }']
})
export class CounterComponent {

  num: number = 0;
  showNumber: boolean = true;
  
  constructor() { }

  increment() { this.num++; }
  show() { this.showNumber = true; }
  hide() { this.showNumber = false; } 
  private toggle() { this.showNumber = !this.showNumber; }

}
```

Now let's take a look at our `app.component.ts`. I also used inline styles and template here since there isn't much code.

```typescript
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <h1>Angular-Material-Tutorial</h1>

    <app-counter #counter></app-counter>
    <button (click) = 'counter.increment()'>Add number</button>
    <button (click) = 'counter.show()'>Show Counter</button>
    <button (click) = 'counter.hide()'>Hide Counter</button>
  `,
  styles: [
    `h1 {
      text-align: center;
      padding: 20px;
    }`,
    `button {
      border: 0;
      outline: 0;
      padding: 10px;
      border-radius: 8px;
      display: block;
      margin: 10px auto;
  }`]
})
export class AppComponent {}
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rsdbc87w0orvk4diejfi.png)

Notice how our app component has absolutely no code inside the class. Not even a constructor! Yet, if we click on the Add Number button, it will increment the count, and our Show and Hide Counter buttons will also work as expected. 

**We managed to access the properties and methods of the `CounterComponent` through the `AppComponent` because of Template Referencing**.

When we say `<app-counter #counter></app-counter>`, we are accessing this particular instance of the `CounterComponent` class. And since the properties and methods boil down to plain JavaScript Objects, we can access them as we do with regular objects (`counter.increment()` for example). Any property or instance marked as private cannot be accessed through Template Referencing. 

This simple, but powerful, feature of Angular allows us to accomplish useful tasks without needed to bloat our TypeScript Class. Additionally, this is the very technique that we will use to access many of the properties of the Angular Material Components in order to take full advantage of them.

## Conclusion

In this article, we gained an understanding of what Angular Material is, added Angular Material to our project and learned about Template Referencing and how it relates to Angular Material. 

In the next article, we'll get started on simple components from the [Buttons and Indicators Section](https://material.angular.io/components/categories/buttons). Thanks a lot for reading! :smile: