Reputation: 1933
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:
And what I wish:
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
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
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
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
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
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
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:
Upvotes: 5
Reputation: 16261
Use ::ng-deep
to style .mat-menu-panel
::ng-deep .mat-menu-panel {
padding: 0 10px!important;
width: 100%!important;
}
Upvotes: 3