amin mohammadi
amin mohammadi

Reputation: 1053

Angular material; How to change mat-menu background color programmatically?

I have this piece of code for my mega menu:

<button mat-button [matMenuTriggerFor]="objectmenu">Objects</button>
        <mat-menu #objectmenu="matMenu" >
              <div class="menu-content" [style.backgroundColor]="getUnSelectedRandomColor()" style="height: 550px;">
                <div  fxFlex="100" fxFlex.gt-sm="30" fxFlex.sm="45" class="dropdown-menu-items"> 
                  <div class="dropdown-menu-btns" *ngFor="let parent of (objectList$ | async)"
                   (mouseover)="openCategory($event, 
                   parent)"
                   [style.background-color] = "this.selectedColor === (parent.categoryId * 100)  ? getSelectedRandomColor() : getUnSelectedRandomColor()"

                   >{{parent.name}}</div>
              </div>
                    <div class="theme-container">

                    <div class="theme-container" style=" padding-bottom: 0px !important; padding-top: 7px !important;">
                      <div fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="center center" class="content border-lighter">
                        <div fxFlex="100" fxFlex.gt-sm="100" fxLayout="column" fxLayoutAlign="center center"> 
                            <h2 *ngIf="this.selectedCategory" class="uppercase">{{this.selectedCategory.name}}</h2>
                        </div>
                    </div>

                    <div class="content border-lighter" [style.backgroundColor]="getSelectedRandomColor()" style="height: 380px;">

                        <div fxLayout="row wrap" fxLayoutAlign="space-between"> 
                            <div fxFlex="100" fxFlex.gt-sm="70" fxFlex.sm="45" style="column-count: 2;"> 
                              <ul class="ht-dropdown megamenu-two d-flex"
                              *ngFor="let parent of (childCategories$ | async)" style="list-style: none;">

                               <label [routerLink]="['/products']" [queryParams]="{categories: parent.categoryId}"
                               routerLinkActive="router-link-active">{{parent.name}}</label>
                             <li *ngFor="let child of parent.childrenCategories"
                             [routerLink]="['/products']" [queryParams]="{categories: child.categoryId}"
                               routerLinkActive="router-link-active">
                               {{child.name}}

                           </li>
                         </ul>
                            </div>



                            <div fxFlex="100" fxFlex.gt-sm="30" ngClass.lt-md="pt-5" style="background-size: contain !important;"
                            [style.background]="selectedCategoryUrl"> 

                            </div>
                        </div> 

                    </div>


                    </div> 
                    <div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="space-between center" >
                      <img *ngFor="let brand of (relatedBrandsList$ | async)"  [src]=" brand.thumbnail | safeHtml" style="width: 110px; height: 110px; border-radius: 50%;"/>
                    </div>                     
                  </div>                    
                 </div>   


        </mat-menu>

and it gives me the following style: enter image description here

As shown in the picture, the top and the bottom edges of the menu panel are not taking the dynamic background color which I generate in my angular code by getUnSelectedRandomColor() method. The getUnSelectedRandomColor() method is as follow:

openCategory(evt, category: Category) {
    this.selectedCategory = category;
    this.selectedCategoryUrl = `url('../../assets/categories/${category.categoryId}.webp')`;
    this.childCategories$ = this.store.pipe(select(getChildCategories(category.categoryId)));
    this.relatedBrandsList$ = this.store.pipe(select(getRelatedBrands(category.categoryId)));
    this.selectedColor = category.categoryId * 100;
    }

  getSelectedRandomColor() {
    const color = 'hsl(' + this.selectedColor + ', 30%, 75%)';
    return color;
    }
  getUnSelectedRandomColor() {
      const color = 'hsl(' + this.selectedColor + ', 30%, 86%)';
      return color;
    }

How can I do this?

Upvotes: 0

Views: 9114

Answers (2)

Angular 9

What happens is that you are not affecting the menu panel item, you must get the panelId which is a property of MatMenu, with the panel id you get the element and then change the value of the attribute you want, to achieve this you can use property decorator that configures a view query ViewChild and the service Renderer2.

Here I show you an example in which I dynamically change the background of the panel according to the menu item that emits the mouseover stackblitz

import { Component, ViewChild, Renderer2 } from '@angular/core';
import { MatMenu } from '@angular/material/menu/';

@Component({
  selector: 'my-app',
  template: './app.component.html',
})
export class AppComponent {
  @ViewChild('menu', {static: true}) menu: MatMenu

  constructor(private _renderer2: Renderer2) {
  }

  changeBackgroundPanel(colorValue: string) {
    const el = document.getElementById(this.menu.panelId);
    this._renderer2.setStyle(el, 'background', colorValue);
  }
}
<button mat-raised-button [matMenuTriggerFor]="menu" color="primary">Open Menu</button>
<mat-menu #menu="matMenu">
  <button mat-menu-item (mouseover)="changeBackgroundPanel('blue')">Blue</button>
  <button mat-menu-item (mouseover)="changeBackgroundPanel('orange')">Orange</button>
  <button mat-menu-item (mouseover)="changeBackgroundPanel('red')">Red</button>
</mat-menu>

[Solution for Angular 8]

See the example working here: stackblitz

Component:

import { Component, Renderer2 } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.scss' ]
})
export class AppComponent  {
  constructor(private _renderer2: Renderer2) {
  }

  changeBackgroundPanel(colorValue: string) {
    const el = document.getElementById('myPanelId');
    this._renderer2.setStyle(el, 'background', colorValue);
  }
}

Html:

<button mat-raised-button [matMenuTriggerFor]="menu" color="primary">Open Menu</button>
<mat-menu #menu="matMenu">
  <div id="myPanelId" class="menu-panel">
    <button mat-menu-item (mouseover)="changeBackgroundPanel('blue')">Blue</button>
    <button mat-menu-item (mouseover)="changeBackgroundPanel('orange')">Orange</button>
    <button mat-menu-item (mouseover)="changeBackgroundPanel('red')">Red</button>
  </div>
</mat-menu>

CSS:

.menu-panel {
  margin: -8px 0; 
  padding: 8px 0;
}

Upvotes: 2

amin mohammadi
amin mohammadi

Reputation: 1053

Finally I found the answer:

::ng-deep .mat-menu-content{
            padding-top: 0px !important;
            padding-bottom: 0px !important;
          }

I removed the paddings using the above style and then the white gaps were removed

Upvotes: 0

Related Questions