Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change Material design theme for Angular 2

I am trying to use Angular Material 2 with my Angular 2 application.

I did not found how to change material theme globally (primaryColor, etc). I know that Angular Material 2 is still in alpha, but is there currently a way to do that?

like image 879
quen2404 Avatar asked Apr 29 '16 13:04

quen2404


People also ask

How do I change the theme of angular materials?

add("custom-theme"); With adding class="mat-app-background" to the <body> tag, the correct background color will take effect. As you call @include angular-material-theme($custom-theme); within your custom custom-them-css-class mixin, the mat-app-background css-selector will become a nested selector.

Can we customize angular material?

For any Angular Material component, you can safely define custom CSS for a component's host element that affect the positioning or layout of that component, such as margin , position , top , left , transform , and z-index .

How do you set a material theme?

You can do so by selecting Custom Theme in the theme list, then customize the theme colors in the settings page at Settings → Appearance → Material Custom Theme Settings . Once you set these colors, simply select the Custom Theme in the Material Theme Chooser and see your colors take effect.

What is theming in angular?

Angular Material's theming system lets you customize color and typography styles for components in your application. The theming system is based on Google's Material Design specification. This document describes the concepts and APIs for customizing colors. For typography customization, see Angular Material Typography.


1 Answers

Here's an example of dynamic Angular Material theme implementation as of Angular 5.1 and Angular Material 5.0.

(edit) - Currently tested and working in angular 7+ as well.

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

In theme.scss file, 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, OnInit} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Version } from './classes/version';
import { OverlayContainer} from '@angular/cdk/overlay';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {

  constructor(private http: HttpClient, public overlayContainer: OverlayContainer) {}

  title = 'app';
  version: Version;
  @HostBinding('class') componentCssClass;

  ngOnInit() {
    this.getVersion();
  }

  onSetTheme(theme) {
    this.overlayContainer.getContainerElement().classList.add(theme);
    this.componentCssClass = theme;
  }

  getVersion() {
    this.http.get<Version>('/api/version')
      .subscribe(data => {
        this.version = data;
      });
  }

}

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

<button mat-raised-button color="primary" (click)="onSetTheme('default-theme')">Default</button>
<button mat-raised-button color="primary" (click)="onSetTheme('dark-theme')">Dark</button>
<button mat-raised-button color="primary" (click)="onSetTheme('light-theme')">Light</button>

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

like image 127
K. Waite Avatar answered Oct 05 '22 12:10

K. Waite