Quentin
Quentin

Reputation: 1933

Angular Material mat-menu-item to be the same size as the mat-menu button

I use mat-menu of Angular Material with different mat-menu-item and I would like the list of menu items to be the same size as the button.

That's what I have:

enter image description here

And what I wish:

enter image description here

I tried to change the size of the menu with the css, but it does not work properly.

CSS:

.cdk-overlay-pane {width: 100%;}
.mat-menu-panel {width: 100%;}

HTML:

<button mat-raised-button [matMenuTriggerFor]="menu" class="btn-block btn-blue">
  <div fxLayout="row" fxLayoutAlign="center center">
    <mat-icon>more_vert</mat-icon>
    <span fxFlex>OPTION</span>
  </div>
</button>

<mat-menu #menu="matMenu">
  <button mat-menu-item>
    <mat-icon>unarchive</mat-icon>
    <span>First</span>
  </button>
  <button mat-menu-item>
    <mat-icon>file_copy</mat-icon>
    <span>Second</span>
  </button>
</mat-menu>

I did a StackBlitz HERE for my mat-menu.

Thank you in advance!

EDIT : I changed my code because I'm using a responsive button with the bootstrap class "btn-block".

Upvotes: 11

Views: 19794

Answers (7)

shhdharmen
shhdharmen

Reputation: 1463

Simply provide your CSS class in class wth mat-menu, like below:

<mat-menu #menu="matMenu" class="custom-wrapper-for-menu">
  <button mat-menu-item>
    <mat-icon>unarchive</mat-icon>
    <span>First</span>
  </button>
  <button mat-menu-item>
    <mat-icon>file_copy</mat-icon>
    <span>Second</span>
  </button>
</mat-menu>

Upvotes: 0

Khuram Niaz
Khuram Niaz

Reputation: 919

Since ::ng-deep is going to be deprecated,

https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep

another trick is to create margin around text span (mx-4 is bootstrap class for margin left and right

  <button mat-menu-item>
    <mat-icon>file_copy</mat-icon>
    <span class="mx-4">Second</span>
  </button>

Upvotes: 1

Steve
Steve

Reputation: 602

In case somebody still needs this. Here is my solution

The idea is to read matMenuTriggerFor clientWidth, pass it to the menu itself as matMenuTriggerData, and bind it to the wrapper width

Upvotes: 1

Mr Guro
Mr Guro

Reputation: 11

For those searching this in the future your can set this in your

.mat-menu-panel {
  min-width: fit-content !important;
  padding: 0px 0px !important;
}

.cdk-overlay-pane {
  min-width: fit-content;
}

To make the mat-menu dynamic then you can apply with and styling in the component css of ts file through [ngClass]="getClassWithWidthandHieght()".Through css set the class of the in side div to the class like this the apply the styling set you styles.

.example-panel{

min-width: 500px; }

Upvotes: 0

TirupathiRao
TirupathiRao

Reputation: 71

Use menuOpened event for matMenuTriggerFor and add width runtime

HTML:

<button mat-raised-button [matMenuTriggerFor]="menu" class="btn-block btn-blue"  (menuOpened)="onMenuOpened()" id="button">
  <div fxLayout="row" fxLayoutAlign="center center">
    <mat-icon>more_vert</mat-icon>
    <span fxFlex>OPTION</span>
  </div>
</button>

TS:

onMenuOpened() {
    const btn = document.getElementById('revisitSection');
    if (btn) {
      const elems = document.getElementsByClassName('button') as any;
      // for (let i = 0; i < elems.length; i++) {
      //   elems[i].style.width = `${btn.offsetWidth}px`;
      // }
      for (const item of elems) {
        item.style.width = `${btn.offsetWidth}px`;
      }
    }
  }

I don't recommend to use ngDoCheck. it has more performance issue.

Upvotes: 0

Quentin
Quentin

Reputation: 1933

I found a solution really not clean, but here it is: StackBlitz HERE

If someone would have a CSS solution, I'm interested.

HTML:

<button mat-raised-button [matMenuTriggerFor]="menu" class="btn-block btn-blue" id="button">
  <div fxLayout="row" fxLayoutAlign="center center">
    <mat-icon>more_vert</mat-icon>
    <span fxFlex>OPTION</span>
  </div>
</button>

TS:

export class AppComponent implements DoCheck{
  ngDoCheck(){
    var widthButton=document.getElementById("button").offsetWidth;

    var elems = document.getElementsByClassName('mat-menu-panel');
    for(var i = 0; i < elems.length; i++) {
      elems[i].style.width = widthButton+"px";
    }
  }
}

CSS:

.cdk-overlay-pane {width: 100%!important;}
.mat-menu-panel {max-width: 100%!important; min-width: 64px!important;}

DEMO:

enter image description here

Upvotes: 5

לבני מלכה
לבני מלכה

Reputation: 16261

Use ::ng-deep to style .mat-menu-panel

::ng-deep .mat-menu-panel {
  padding: 0 10px!important;
  width: 100%!important;
}

See working code

Upvotes: 3

Related Questions