Switch themes in angular material 5

前端 未结 4 1373
一整个雨季
一整个雨季 2020-12-08 11:06

I been reading a few articles on this but they seem to be conflicting in several different ways. I am hoping to re-create the same theme switching as the angular material do

4条回答
  •  暖寄归人
    2020-12-08 12:07

    Here's an alternative solution for Angular 5.1+/Angular Material 5.0+.

    *Edit: As noted, this still works in Angular 7+.

    Working editable example - https://stackblitz.com/edit/dynamic-material-theming

    In theme.scss, include a default theme(notice it isn't kept under a class name - this is so Angular will use it as the default), and then a light and dark theme.

    theme.scss

    @import '~@angular/material/theming';
    @include mat-core();
    
    // Typography
    $custom-typography: mat-typography-config(
      $font-family: Raleway,
      $headline: mat-typography-level(24px, 48px, 400),
      $body-1: mat-typography-level(16px, 24px, 400)
    );
    @include angular-material-typography($custom-typography);
    
    // Default colors
    $my-app-primary: mat-palette($mat-teal, 700, 100, 800);
    $my-app-accent:  mat-palette($mat-teal, 700, 100, 800);
    
    $my-app-theme: mat-light-theme($my-app-primary, $my-app-accent);
    @include angular-material-theme($my-app-theme);
    
    // Dark theme
    $dark-primary: mat-palette($mat-blue-grey);
    $dark-accent:  mat-palette($mat-amber, A200, A100, A400);
    $dark-warn:    mat-palette($mat-deep-orange);
    
    $dark-theme:   mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
    
    .dark-theme {
      @include angular-material-theme($dark-theme);
    }
    
    // Light theme
    $light-primary: mat-palette($mat-grey, 200, 500, 300);
    $light-accent: mat-palette($mat-brown, 200);
    $light-warn: mat-palette($mat-deep-orange, 200);
    
    $light-theme: mat-light-theme($light-primary, $light-accent, $light-warn);
    
    .light-theme {
      @include angular-material-theme($light-theme)
    }
    

    In the app.component file, include OverlayContainer from @angular/cdk/overlay. You can find Angular's documentation for this here https://material.angular.io/guide/theming; though their implementation is a little different. Please note, I also had to include OverlayModule as an import in app.module as well.

    In my app.component file, I also declared @HostBinding('class') componentCssClass; as a variable, which will be used to set the theme as a class.

    app.component.ts

    import {Component, HostBinding } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { OverlayContainer} from '@angular/cdk/overlay';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
    })
    export class AppComponent {
    
      constructor(public overlayContainer: OverlayContainer) {}
    
      @HostBinding('class') componentCssClass;
    
      onSetTheme(theme) {
        this.overlayContainer.getContainerElement().classList.add(theme);
        this.componentCssClass = theme;
      }
    
    }
    

    app.module.ts

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    
    import { HttpClientModule } from '@angular/common/http';
    
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { MatCardModule } from '@angular/material/card';
    import { MatButtonModule } from '@angular/material/button';
    
    import { AppComponent } from './app.component';
    
    import { OverlayModule} from '@angular/cdk/overlay';
    
    @NgModule({
      declarations: [
        AppComponent,
      ],
      imports: [
        BrowserModule,
        HttpClientModule,
        BrowserAnimationsModule,
        MatCardModule,
        MatButtonModule,
        OverlayModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    

    Finally, call the onSetTheme function from your view.

    app.component.html

    
    
    
    

    You might consider using an observable so that the functionality would be more dynamic.

提交回复
热议问题