How to use the new Mat-Slider
In this post, I’m going to talk about one of Angular Material’s components, which was rewritten to be more in line with Google’s Material Design Specification for Web Components (MDC).
Installing Angular Material
Angular Material is a component library for Angular projects, this library comprises a number of User Interface components (UI) and a Component Development Kit (CDK), we’ll cover the CDK in a future post. In this series of posts, we’ll use Angular Material version 16, there haven’t been 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 straightforward, navigate to your Angular project in a terminal window and type:
ng add @angular/material
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
CSSclass
to thebody
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 will be added to the
package.json
file.
"dependencies" : {
"@angular/cdk": "¹⁶.2.1"
"@angular/material" : "¹⁶:2.1"
}
- The
Roboto
font will be added to theindex.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 will 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.
- Removes the margins from the
body
tag - Changes the
height : 100%
onhtml
andbody
tag. - Makes the
Roboto
font as the application's 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 {}
And in the app.component.html
file add the following line.
<mat-slider>
<input matSliderThumb />
</mat-slider>
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 post we’ll dig deeper into the mat-slider
and the recent changes from Angular Material 15.
Note: Angular Material 16 was mainly minor changes and bug fixes.
The Mat-Slider was recently rewritten [in Angular 15] as part of a refactoring towards the Material Design Components for the Web (MDC). The most notable change to the mat-slider
is the element now requiring 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>
And in versions after Angular 15:
<!-- single slider -->
<mat-slider>
<input matSliderThumb />
</mat-slider>
<!-- range slider -->
<mat-slider>
<input matSliderStartThumb />
<input matSliderEndThumb />
</mat-slider>
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>
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 max
is 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>
To show the tick-marks on the slider add the showTickMarks
attribute.
<mat-slider showTickMarks>
<input matSliderThumb />
</mat-slider>
For now the tickInterval
property has been removed from the API for now, (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>
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 set to 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>
export class MySliderComponent {
updateLabelWithFn(value: number): string {
return value >= 1000 ? Math.round(value / 1000) + 'k' : `${value}`;
}
}
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 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>
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<number>
- @Output() dragEnd: EventEmitter<MatSliderDragEvent>
- @Output() dragStart: EventEmitter<MatSliderDragEvent>
- 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 colour of a slider
Like all Angular Material components, we can change the colour of a mat-slider
using the color
properties (primary
, accent
, warn
).
<mat-slider [color]="primary">
<input matThumbSlider>
</mat-slider>
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 {
...
}
Please note: The legacy versions are currently marked as deprecated and will be removed in version 17 of Angular Material.
Migrate to version 15
The team at Angular Material have created a schema that will do all the heavy lifting when migrating to the new MDC format.
- Upgrade your application to version 15
ng update @angular/material@15
This will automatically run the migration schema and move your project over to use the legacy version, this makes sure 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 it can. Where it cannot update your code the migration tool will insert comments into your code for a developer to fix.
// TODO(mdc-migration):...
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 for 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 versions of the specification.