Angular 2/4 How to style angular material design snackbar

半世苍凉 提交于 2021-02-05 20:56:16

问题


I am new to Angular2/4 and angular typescript. I want to style the angular material design snackbar for example change the background color from black and font color to something else.
How do i go about styleing the "snackbar" ?

I have the material design snackbar in the service/core and to make it available i call it in every component as needed.

How can I style the Angular 2 material design "snackbar"in Angular 2/4? I have included the code snippet below:

service/core

import { Injectable, Inject } from '@angular/core';
import { Observable } from 'rxjs/Observable'
import { DOCUMENT } from'@angular/platform-browser'; 
import { MdDialog, MdDialogRef } from '@angular/material'; 
import { MdDialogConfig, ComponentType } from '@angular/material'; 
import {MdSnackBar} from '@angular/material';

constructor(
    public dialog: MdDialog,
    public snackBar: MdSnackBar,
    @Inject(DOCUMENT) public doc: any   ) {
      dialog.afterOpen.subscribe((ref: MdDialogRef<any>) => {
        if (!doc.body.classList.contains('no-scroll')) {
        doc.body.classList.add('no-scroll');
        }
      });
      dialog.afterAllClosed.subscribe(() => {
        doc.body.classList.remove('no-scroll');
      });        }

   openSnackBar(message: string, action?: string) {
    this.snackBar.open(message, action, {
      duration: 4000,
    });   }

wiz.components.ts ....

 saveData(): void {
    this.advisorClientModel.currentStep = this.currentStep;
    this.advisorClientModel.clientId = this.faService.getClientId();
    this.advisorClientModel.isMaxAmount = this.isMaximumAmount;
    this.advisorClientModel.desiredLoanAmount = this.loanAmount;
    this.advisorClientModel.maxLoanAmount = this.eligibleSelected.advanceAmount;
    this.advisorClientModel.pledgedAccounts = this.getPledgedAccountsArray();
    this.advisorClientModel.pledgedMarketValue = this.getPledgedMarkeValue();

    this.faService.updateAdvisorClient( this.advisorClientModel )
      .subscribe(
        successModel => {
          this.coreService.openSnackBar("Your Data Has been Saved");
          this.navigateTo("fa/wiz" + (this.currentStep + 1));
        },
        error => {
          this.onError(error);
        }
      );
  }

回答1:


md-snackbar provides a service to provide custom config. One the properties of config is extraClasses that allows to add CSS classes to the snack bar container (doc).

extraClasses can be used with ::ng-deep to override the default CSS classes. Here's an example:

component.ts:

Requires following import in the component:

import {MdSnackBar, MdSnackBarConfig} from '@angular/material';

(providing custom configuration)

openSnackBar(message: string, action?: string) {
  let config = new MdSnackBarConfig();
  config.extraClasses = ['custom-class'];
  this.snackBar.open(message, action ? 'Action Label' : undefined, config);
}

component.css:

::ng-deep snack-bar-container.custom-class {
  background: yellow;
}

::ng-deep .custom-class .mat-simple-snackbar {
  color: green;
}

Here's a Plunker demo if you would like to try.

NOV 2018 UPDATE: Angular 6+

The syntax has changed a bit, with the md- prefix being replaced mat- and extraClasses was replaced with panelClass. The function is overall the same though:

const config = new MatSnackBarConfig();
config.panelClass = ['custom-class'];
...

and the imports too:

import { MatSnackBar, MatSnackBarConfig } from '@angular/material';



回答2:


I made the following code to work with Angular 6 and Angular Material 6.

The service that contain the snackBar calls:

@Injectable()
export class MessageService {
   constructor(private snackBar: MatSnackBar) {}

   showError(message: string) {
      const config = new MatSnackBarConfig();
      config.panelClass = ['background-red'];
      config.duration = 5000;
      this.snackBar.open(message, null, config);
   }
}

Add the css class in the styles.css file:

.background-red{
   background-color: rgb(153, 50, 50);
}



回答3:


From mat SnackBarConfig Class you can add

panelClass: string | string[]

"Extra CSS classes to be added to the snack bar container".

this.snackBar.open("Your custom Message", '', {
      panelClass:"custom_sneak_bar"
}



回答4:


Angular 5 and above you dont need to use custom config service just pass extraClasses array after duration on method openFromComponent.

Here's how

app.module.ts:

  import { MatSnackBarModule } from '@angular/material';

Add to import

@NgModule({ declarations: [ .. ], imports: [ MatSnackBarModule ].... 

component.ts:

Requires following import in the component:

import { MatSnackBar } from '@angular/material';

Example method that calls SnackBar

openSnackBar(message, type) {
   let extraClasses;
   if (type == 'error') {
     extraClasses = ['background-red'];
   } else {
     extraClasses = ['background-green'];
 }

 this.snackBar.openFromComponent(SnackBarTemplateComponent, {
   duration: 30000,
   extraClasses: extraClasses,
   data: {
     message: message,
     type:type
   }
 });
}

Add respective classes to global style.css style.css:

.background-red{
  background-color: rgb(153, 50, 50);
}
.background-green{
  background-color: rgb(29, 102, 29);
}



回答5:


For angular 6 to 9 works with (In your global scss style for material)

Explaination: Customize your snackBar with an @mixin function, in this case is called "@mixin snack-theme($theme)", then you add all classes declared in this function to your templace like this

@include snack-theme($my-app-theme);

Global scss file (styles.scss):

@import '../node_modules/@angular/material/_theming.scss';
@include mat-core();

$background-primary: #232323;
$background-accent: #353535;
$background-warn: #c1640c;
$font-color-default: silver;

$my-app-primary: mat-palette($mat-light-green, 700);
$my-app-accent: mat-palette($mat-cyan, 800 );
$my-app-warn: mat-palette($mat-red, 400);


$my-app-theme: mat-dark-theme($my-app-primary, $my-app-accent, $my-app-warn);


@mixin snack-theme($theme) {
    // Extract whichever individual palettes you need from the theme.
    $primary: map-get($theme, primary);
    $accent: map-get($theme, accent);
    $warn: map-get($theme, warn);


    .mat-snack-bar-container {
        background-color: $background-accent !important;
        color: $font-color-default;
    }
    //Added with panelClass property
    .snack-error {
        button {
            color: mat-color($warn)
        }
    }
    //Added with panelClass property
    .snack-success {
        button {
            color: mat-color($primary)
        }
    }
}

@include snack-theme($my-app-theme);

...

And calling snack like (In your component)

        this.snackBar.open("your message", 
           "your action",
          {
            duration: 3000,
            panelClass: (isSuccess ? ["snack-success"] : ["snack-error"])
          })

snack-success and snack-error class are defined in @mixed function (@mixin snack-theme)

NOTE: Doesn't forget to include your global scss file in your scss component. For example:




回答6:


::ng-deep support will be dropped, as announced any time soon. Set encapsulation: ViewEncapsulation.None on your message bar component, and you are good to go:

import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_SNACK_BAR_DATA } from '@angular/material';
import { MessageBarType } from './message-bar.model';

@Component({
  selector: 'app-message-bar',
  templateUrl: 'message-bar.component.html',
  styleUrls: ['message-bar.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class MessageBarComponent implements OnInit {

  public MessageBarType: typeof MessageBarType = MessageBarType;

  constructor(@Inject(MAT_SNACK_BAR_DATA) public data: { text: String, type: MessageBarType }) { }

  ngOnInit() {
  }
}

Then in your scss file:

@import '~@angular/material/theming';
@import '~app/theme-defs';

snack-bar-container {
  &.error {
    background-color: mat-color($warn);
  }

  &.warning {
    background-color: mat-color($dark-warn);
  }

  &.info {
    background-color: mat-color($accent);
  }
}



回答7:


(Angular 9 at the moment) Hi, here is a summary of the two links at the bottom. You get here the call function with css class and variables passed and the way to get their values in the snackBar component. Hope this helps

In the component where you wish to rise a snackBar, the "father component" :

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


@Component({
  selector: 'app-father-component',
  templateUrl: './father-.component.html',
  styleUrls: ['./father-editor.component.scss'],
})
export class FatherComponent implements OnInit {

  private _durationInSeconds = 5;

  get durationInSeconds(): number {
    return this._durationInSeconds;
  }

  set durationInSeconds(value: number) {
    this._durationInSeconds = value;
  }

  private _className: string;

  get className(): string {
    return this._className;
  }

  set className(value: string) {
    this._className = value;
  }

  private _mMessage: string;

  get mMessage(): string {
    return this._mMessage;
  }

  set mMessage(value: string) {
    this._mMessage = value;
  }

  constructor(
    private snackBar: MatSnackBar
  ) {}

  ngOnInit(): void {

    // your onInit code
  }

// Calling that function rises the snackBar, from .ts this.openSnackBar()
// From template event <button (click)="openSnackBar()"></button> etc...
// No needs to insert the <app-snack-bar> tag in the template.

  openSnackBar() {
    this.snackBar.openFromComponent(SnackBarComponent, {
      duration: this.durationInSeconds * 1000,
      data: {
        myMessage: this.mMessage,
        antoherVar: 'antoher message'
      },
      // here this.className is a string which value is a Bulma class 'has-text-info', snackbar automatically uses the value from panelClass
      panelClass: this.className
    });
  }

Then the component which is the snackBar itSelf, the "child component" :

import {
  Component,
  Inject,
  OnInit
} from '@angular/core';
import {
  MAT_SNACK_BAR_DATA
} from '@angular/material/snack-bar';

@Component({
  selector: 'app-snack-bar',
  templateUrl: './snack-bar.component.html',
  styleUrls: ['./snack-bar.component.scss'],
})
export class SnackBarComponent implements OnInit {

  myMessage: string;
  antoherVar: string;

  constructor(
    @Inject(MAT_SNACK_BAR_DATA) public data: any
  ) {
  // there you get the datas you have passed to the snackbar through the openSnackBar function in the father-component, setting up local properties to their values
    this.myMessage = data.myMessage;
    this.antoherVar = data.antoherVar;
  }

  ngOnInit(): void {}

}
<!--Here we use the local variable set with the datas passed through the data object -->
<!--No needs to setup a class to use the panelClass value passed, it is automatic -->
<span>{{ myMessage }}</span>


来源:https://stackoverflow.com/questions/45439313/angular-2-4-how-to-style-angular-material-design-snackbar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!