Angular Material Theme Generator

As we started covering Angular Material with a few different posts, today, I want to address one of the common objections to Angular Material: Sometimes, people don’t like the look and feel of the library and fear that it won’t match their business requirements.

While it is true that the default themes picked by the Material team aren’t for everyone, with a lot of bright pink, purple or flashy green, I have seen several companies customize Material to make it their own with great success.

Here are a few examples:

Bank of Montreal (BMO)

Air France

You can see that in some cases, it’s actually hard to recognize Material components in those apps. On the Air France website, the tabs and slide toggle are the most recognizable components.

How to generate my own custom theme?

One of the easiest way to see what’s possible is to use the (unofficial – though it comes from a team at Google) Material Theme Generator:

With the theme generator, you can:

  • Generate a theme from an image (such as a company logo!) and the tool will pick the colors and do the rest
  • Tweak all possible variables using color pickers and see the result on every component on the right-hand side.
  • Then export your customization as a CSS file using th “Download CSS” button.

Here I tried uploading a picture of mine from the Canyonlands of Utah last winter, and the resulting auto-generated theme is impressive – I didn’t touch any of the settings:

Migrating Angular Material to v15+

This is a guest post by Duncan Faulkner. You can read his first post on Angular Material here. This is the third and final post in this series.

Note: This post will cover upgrading to Angular Material version 15 from Angular Material 14—all changes affected version 15. Once the migration to Angular Material 15 is complete, migration to Angular Material 16 is straightforward.

The team at Angular Material has created a schema that will do all the heavy lifting when migrating to the new MDC format.

To upgrade your application to version 15

ng update @angular/material@15Code language: CSS (css)

This will automatically run the migration schema and move your project over to use the legacy version, ensuring that your application continues to run with minimal changes.

Once your project has upgraded, you can now run the migration tool. This will migrate from the legacy to the new MDC format.

ng generate @angular/material:mdc-migration

This will update your project, including TypeScript, styles, and templates, as much as possible. Where it cannot update your code, the migration tool will insert comments into your code for a developer to fix.

// TODO(mdc-migration):...Code language: JSON / JSON with Comments (json)

It’s also possible to migrate parts of your application; this can be a single component or a range of components, and the migration script will prompt the directory and components to migrate.

The migration to MDC is a welcoming and positive step. It improves accessibility, adheres to the Material Design Specification, and allows better adoption of future specification versions.

Legacy components

Currently, the Angular Material library includes all the legacy components. If you’re not able to upgrade to the latest version and want to continue to use these legacy components, you need to import the legacy module, for example:

import {
  MatLegacySliderModule,
} from '@angular/material/legacy-slider';

@Component({
  selector: 'slider-formatting-example',
  templateUrl: 'slider-formatting-example.html',
  styleUrls: ['slider-formatting-example.css'],
  standalone: true,
  imports: [MatLegacySliderModule],
})
export class SliderFormattingExample { 
    ...
}Code language: JavaScript (javascript)

Please note: The legacy versions are currently marked as deprecated and will be removed in version 17 of Angular Material.

Using the Angular Material Slider

This is the second guest post by Duncan Faulkner. You can read his first post on Angular Material here. This is the second post in this series.

The mat-slider was recently rewritten in Angular 15 as part of a refactoring towards MDC (Material Design Components for the Web). The most notable change to the mat-slider is the element now requires up to two input elements, instead of just a mat-slider element, this allows us to use the slider as either a single slider (with one input) or a range (with two inputs).

The original mat-slider looked like this in versions prior to Angular Material 15:

<!-- original -->
<mat-slider></mat-slider>Code language: HTML, XML (xml)

And in versions after 15:

<!-- single slider -->
<mat-slider>
  <input matSliderThumb />
</mat-slider>

<!-- range slider -->
<mat-slider>
  <input matSliderStartThumb />
  <input matSliderEndThumb />
</mat-slider>Code language: HTML, XML (xml)

Slider usage options

It’s also possible to set the range slider to have a min/max or both, for example:

<!-- range slider -->
<mat-slider [min]="30" [max]="75">
  <input matSliderStartThumb />
  <input matSliderEndThumb />
</mat-slider>Code language: HTML, XML (xml)

If min is not supplied then zero is assumed, likewise if max is not supplied then one hundred is assumed. If step is supplied then maxis required otherwise the slider will not be able to calculate the step division.

The thumbLabel directive has now been replaced with a new discrete attribute, this controls whether the value indicator tool-tip is shown when the slider is dragged.

<!-- original -->
<mat-slider thumbLabel></mat-slider>

<!-- replaced with -->
<mat-slider discrete>
  <input matSliderThumb />
</mat-slider>Code language: HTML, XML (xml)

To show the tick-marks on the slider add the showTickMarks attribute.

<mat-slider showTickMarks>
  <input matSliderThumb />
</mat-slider>Code language: HTML, XML (xml)

For now the tickInterval property has been removed from the API, though this is being reviewed and could be reintroduced in the future. If we want to define the interval of the tick marks we use the step property and the tick marks will match the step:

<mat-slider discrete showTickMarks step="10">
  <input matSliderThumb />
</mat-slider>Code language: HTML, XML (xml)

The displayValue property has also been removed in favour of the new displayWith this property controls the text value of the indicator, we need to provide a function for this property where we can manipulate the value to be displayed. We use the min property to set the lowest value, the max property to the highest value we want the slider to be an set the step property to what we want the increment to be.

<mat-slider min="0" max="100000" step="1000" [displayWith]="updateLabelWithFn">
    <input matSliderThumb />
</mat-slider>Code language: HTML, XML (xml)
export class MySliderComponent {
  updateLabelWithFn(value: number): string {
    return value >= 1000 ? Math.round(value / 1000) + 'k' : `${value}`;
  }
}Code language: JavaScript (javascript)

The updateLabelWithFn function takes the value from the slider and [in this instance] if the value is greater than or equal to 1000 then it will round the number and divide it by 1000 and concatenate the letter k to the end, this helps to keep the text small and in the thumbLabel.

The valueText property has also been removed, we now have two options we can use the input’s aria-label-valueText or use the displayWith property.

<!--before Angular 15 -->
<mat-slider [valueText]="someTextValue"></mat-slider>

<!--after Angular 15 -->
<mat-slider>
  <input [attr.aria-valueText]="someTextValue" matSliderThumb />
</mat-slider>

<!--after Angular 15 -->
<mat-slider [displayWith]="displaySomeTextWithFn">
  <input matSliderThumb />
</mat-slider>Code language: HTML, XML (xml)

With the rewrite the API of the slider has also changed and has introduced two new components the MatSliderThumb and MatSliderRangeThumb and provide the following properties:

  • @Input() value: number
  • @Output() valueChange: EventEmitter
  • @Output() dragEnd: EventEmitter
  • @Output() dragStart: EventEmitter
  • @Input() percentage: number

And the following methods:

  • blur
  • focus

There are two notable absences from the mat-slider and these are:

  • invert – this reversed the start and end of the slider
  • vertical – this rotated the slider 90°, you could also invert a vertical slider

These have been removed as they are not part of the Material Design Specification for the Web (MDC).

Changing the color of a slider

Like all Angular Material components we can change the color of a mat-slider using the color property.

<mat-slider [color]="primary">
    <input matThumbSlider>
</mat-slider>Code language: HTML, XML (xml)

In our next post, we’ll see how to migrate from Angular Material 14 to 15+.

Getting Started with Angular Material

This is a guest post by Duncan Faulkner. He is an Angular developer for a fintech company based in the UK. A software engineer with over twenty years of experience, Duncan has been working with Angular since the early betas, written blog posts for ng-conf and several short books on Angular Material. He’s also the maintainer for the @ngbracket/ngx-layout (formerly @angular/flex-layout) open-source project.

You can follow him on Twitter, LinkedIn, Medium and YouTube by using this bio link.

Angular Material is a component library for Angular projects, this library comprises of a number of User Interface components (UI) and a Component Development Kit (CDK). In this series of posts we’ll use Angular Material version 16, there haven’t any major changes to this version of the library.

Some of the components in this library are:

  • buttons
  • inputs
  • cards
  • date picker
  • progress bar
  • grids
  • toolbar
  • and many more:

Adding Angular Material to an existing Angular application is quite straight forward, navigate to your Angular project in a terminal window and type:

ng add @angular/material
Code language: CSS (css)

This will install Angular Material, the CDK and the Angular Animations, during this installation process we are asked to make a few choices.

  • The first one will show the version of Angular Material that will be installed and whether to proceed or not.
  • Next, choose either one of the pre-built themes or create a custom theme.
    • The available pre-built themes are:
      • deeppurple-amber, Palette (Primary, Accent, Warn) – deep-purple, amber, red.
      • indigo-pink, Palette (Primary, Accent, Warn) – indigo, pink, red.
      • pink-bluegrey, Palette (Primary, Accent, Warn) – pink, blue-grey, red.
      • purple-green, Palette (Primary, Accent, Warn) – purple, green, red.
    • Custom – I will discuss this in a future post.
  • Next, include Angular Material typography styles in our project.
    • This will add the mat-typography CSS class to the body tag: <body class="mat-typography"> <app-root></app-root> </body>
  • Finally, include browser animations in our project.
    • Declining this will disable most of the animations of Angular Material.

Now the installation is complete, there have been a few changes made to our project.

  • The following two dependencies were added to the package.json file."dependencies" : { "@angular/cdk": "^16.2.1" "@angular/material" : "^16.2.1" }
  • The Roboto font was added to the index.html file: <link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
  • The Material Design Icon font was also be added to the index.html file. <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

There are also some changes to global CSS styles:

  • Removed the margins from the body tag
  • Changed the height : 100% on html and body tag.
  • Made the Roboto font as the applications default.

Now we have Angular Material installed, let’s try out an Angular Material component in our application. In the app.component.ts file add the following.

import { Component } from '@angular/core';
import { MatSliderModule } from '@angular/material/slider';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
  standalone: true,
  imports: [MatSliderModule],
})
export class AppComponent {}
Code language: JavaScript (javascript)

And in the app.component.html file add the following line.

<mat-slider>
  <input matSliderThumb />
</mat-slider>
Code language: HTML, XML (xml)

Here we’ll just add a simple mat-slider to the page to test everything is working.

If we now run the application in the browser, we should now see a mat-slider on the page.

Coming up in part two of this series we’ll dig deeper into the mat-slider and the recent changes from Angular Material 15 as Angular Material 16 was mainly minor changes and bug fixes.