Skip to content

Instantly share code, notes, and snippets.

@tomastrajan
Last active May 2, 2022 06:02
Show Gist options
  • Save tomastrajan/ee29cd8e180b14ce9bc120e2f7435db7 to your computer and use it in GitHub Desktop.
Save tomastrajan/ee29cd8e180b14ce9bc120e2f7435db7 to your computer and use it in GitHub Desktop.
Angular Material Theming - overlay handling
import { OverlayContainer } from '@angular/cdk/overlay';
export class AppComponent implements OnInit {
// use this to set correct theme class on app holder
// eg: <div [class]="themeClass">...</div>
themeClass: string;
constructor(
private overlayContainer: OverlayContainer
) {}
ngOnInit(): void {
// subscribe to some source of theme change events, then...
this.themeClass = newThemeClass;
// remove old theme class and add new theme class
// we're removing any css class that contains '-theme' string but your theme classes can follow any pattern
const overlayContainerClasses = this.overlayContainer.getContainerElement().classList;
const themeClassesToRemove = Array.from(classList).filter((item: string) => item.includes('-theme'));
if (themeClassesToRemove.length) {
overlayContainerClasses.remove(...themeClassesToRemove);
}
overlayContainerClasses.add(newThemeClass);
}
}
@jaredcasto
Copy link

when I enter the ngOnInit() code in my component, it can't find names - newThemeClass, classList. And for the .remove , it shows the following error - [ts] Argument of type '{}' is not assignable to parameter of type 'string'.

this.themeClass = newThemeClass;
...
const themeClassesToRemove = Array.from(classList).filter((item: string) => item.includes('-theme'));
overlayContainerClasses.remove(...themeClassesToRemove);
overlayContainerClasses.add(newThemeClass);

@stephane-segning
Copy link

Where should the classList be?

@VladislavBaranov
Copy link

VladislavBaranov commented Jun 21, 2018

This should help in Angular 6 and Angular Material 6.x

import { Component, OnInit } from "@angular/core";
import { OverlayContainer } from "@angular/cdk/overlay";

@Component({
  selector: 'ams-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements OnInit {

  theme: string = 'my-dark-theme';

  constructor(
    private overlayContainer: OverlayContainer
  ) { }

  ngOnInit(): void {
    this.overlayContainer.getContainerElement().classList.add(this.theme);
  }

  onThemeChange(theme:string) {
    this.theme = theme;
    //console.log(theme);
    const overlayContainerClasses = this.overlayContainer.getContainerElement().classList;
    const themeClassesToRemove = Array.from(overlayContainerClasses).filter((item: string) => item.includes('-theme'));
    if (themeClassesToRemove.length) {
       overlayContainerClasses.remove(...themeClassesToRemove);
    }
    overlayContainerClasses.add(theme);
  }

}

@edifortcarlos
Copy link

Thanks VladislavBaranov your insight was very helpful

@fireflysemantics
Copy link

I'm attempting to get this working. I created a demo using a mat-select and it looks like the theme class is not being added to the overlay container. I asked about this on both StackOverflow and the material repository. This is the issue link:

angular/components#24858

Anyone have any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment