Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material Snackbar position

I'd like to place material snackbar under my header (height of it is 60px).

The problem is that verticalPosition places snackbar to the top and covers header. I'd tried to add "margin-top: 75px", but the above area was unclickable. (there's an overlay)

enter image description here

I can't change the style of cdk-overlay-pan because i have other dialogs.

like image 398
Alexandre Adereyko Avatar asked Jul 06 '20 14:07

Alexandre Adereyko


2 Answers

You can try this :

  1. Create a global css class to modify style of your Snackbar component.
  2. Set panelClass property in config options.

Add this style declaration in global styles.scss :

.my-custom-snackbar {
  margin: 0 !important;
  position: absolute;
  right: 25px;
  top: 60px;
}

Then when SnackBar is opened :

this.snackbar.open('Hello the world!', '', {
  panelClass: 'my-custom-snackbar'
});
like image 199
Thierry Falvo Avatar answered Sep 19 '22 00:09

Thierry Falvo


From the api documentation (https://material.angular.io/components/snack-bar/api):

Parameters for the "Open" method of MatSnackBar:

message (string) - The message to show in the snackbar.
action (string) - The label for the snackbar action.
config? (MatSnackBarConfig<any>) - Additional configuration options for the snackbar.

MatSnackBarConfig has amongst the following properties:

horizontalPosition: MatSnackBarHorizontalPosition - The horizontal position to place the snack bar.
verticalPosition: MatSnackBarVerticalPosition - The vertical position to place the snack bar.

To see that in action, you could easily create a component, inject the MatSnackBar and write a open method to pass your config.

Here is a little example how my Snackbar component looks like:

import { Component } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';

@Component({
  selector: 'app-mat-snackbar',
  templateUrl: './mat-snackbar.component.html',
  styleUrls: ['./mat-snackbar.component.scss']
})
export class MatSnackbarComponent {

  constructor(public snackBar: MatSnackBar) {}

  openSnackBar(message: string, action: string, className: string) {
    this.snackBar.open(message, action, {
      duration: 9000,
      verticalPosition: 'top',
      horizontalPosition: 'center',
      panelClass: [className],
    });
  }

}

I call it from my http Interceptor like that:

constructor(private SnackbarComponent: MatSnackbarComponent) {}
...
...
// Something wrong happened
this.SnackbarComponent.openSnackBar(errorMessage, 'Close', 'error-snackbar');

In my Style.css file i added a css class for this snackbar, which is also the last parameter for the openSnackBar method. This was just a workaround because some css inside my mat-snackbar.component.css does not work. I found some other solution with ::ng-deep here: MatSnackBar panelClass doesnt read styling class. You have to use it carefully because there is no ViewEncapsulation if you use the style in styles.css. But for me it was much cleaner to do that like this.

my styles.css looks like:

.error-snackbar {
  position: absolute;
  top: 60px;
}
like image 28
Danloc Avatar answered Sep 20 '22 00:09

Danloc