Igor Shvets
Igor Shvets

Reputation: 547

How to use the mat-icon in MatSnackBar?

I want to display an icon when displaying a message from the service message service which uses MatSnackBar. (The Material module is imported in the app's module).

However, the default snackbar doesn't support an icon. How do I implement such a feature?

import { Injectable } from '@angular/core'
import {MatSnackBar} from '@angular/material/snack-bar';
import {MatSnackBarHorizontalPosition, MatSnackBarVerticalPosition} from "@angular/material";


@Injectable()

export class MessagesService {
    horizontalPosition: MatSnackBarHorizontalPosition = 'right';
    verticalPosition: MatSnackBarVerticalPosition = 'top';

    constructor(private snackBar: MatSnackBar) {
    }

    info(message: string) {
        const icon = `<mat-icon>info</mat-icon>`;
        const msg = `${icon} ${message}`;
        this.snackBar.open(msg, 'X', {
            duration: 2000,
            horizontalPosition: this.horizontalPosition,
            verticalPosition: this.verticalPosition,
            panelClass: ['info-message']
        });
    }
}

Upvotes: 5

Views: 9524

Answers (3)

domstic
domstic

Reputation: 21

This can be simply achieved with pure CSS. Add your snackbar-code with action in your component. In this example the text "close" will be rendered as a close image with the X symbol. Other Text like "delete" will render a trash basket.

this._snackBar.open('your snack bar message', 'close');

Add the following CSS. Make sure you have the Google Icon Font properly imported.

.mat-simple-snackbar .mat-button-wrapper {
        font-family: 'Material Icons';
        font-size: 24px;
        line-height: 1;
        letter-spacing: normal;
        text-transform: none;
}

More about icons you find here: enter link description here

Upvotes: 2

Ravi
Ravi

Reputation: 39

Adding to the answer by Edric.

If using flex layout, you dont need additional styles to align your snackbar content. Just wrap content in a div with proper layoutAlign values.

Upvotes: 1

Edric
Edric

Reputation: 26700

You have to use a custom snackbar component in order to show the icon. Thankfully, this should be similar to how you would define a dialog to show content, just that it's a snackbar instead of a dialog.

It's possible to pass in data to a snackbar, the same way as passing data to a dialog.

Note that when declaring a snackbar, you also have to import it in the entryComponents property in the NgModule declaration.

Here's an example:

icon-snack-bar.component.ts

import { MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar';
// ...

@Component({
  selector: '...',
  template: `<mat-icon>{{ data?.icon }}</mat-icon> <span>{{ data?.message }}</span>`
  // Most likely you have to add styles in order to position the icon, although I haven't tested it yet
export class IconSnackBarComponent {
  constructor(@Inject(MAT_SNACK_BAR_DATA) public data: any) { }
}

my-component.component.ts

import { IconSnackBarComponent } from './icon-snack-bar/icon-snack-bar.component';
import { MatSnackBar } from '@angular/material/snack-bar';
// ...

export class MyComponent {
  constructor(private snackBar: MatSnackBar) { }
  openCustomSnackBar() {
    this.snackBar.openFromComponent(IconSnackBarComponent, {
      data: {
        message: 'Hello, snackbar!',
        icon: 'info'
      }
    });
  }
}

app.module.ts

import { NgModule } from '@angular/core';
import { IconSnackBarComponent } from './icon-snack-bar/icon-snack-bar.component';
// ...

@NgModule({
  declarations: [
    // ...
    IconSnackBarComponent
  ],
  entryComponents: [
    IconSnackBarComponent
  ]
})
export class AppModule { }

This is also partially covered in the docs here.

Upvotes: 12

Related Questions