You can't put a <mat-checkbox>
in a <mat-menu>
normally. If so, dark themes don't apply to the text-part of your <mat-checkbox>
(see the image at the end).
About <mat-label>
s there is a similar issue. But the solution is simple:
<label mat-menu-item>
instead of <mat-label>
.
Similarly about button
s.
But I couldn't find a similar solution for <mat-checkbox>
es! These are all states that I tested:
<mat-menu #menu="matMenu">
<mat-label>Bad label</mat-label>
<label mat-menu-item>OK label</label>
<mat-checkbox>Problem here</mat-checkbox>
<!-- ERROR:
<mat-checkbox mat-menu-item>
Template parse errors:
More than one component matched on this element.
</mat-checkbox>
-->
<br><mat-checkbox></mat-checkbox>
<label mat-menu-item style="display:inline">Not good workaround</label>
</mat-menu>
stackblitz
And the result:
There appears to be a way to assign menuitemcheckbox
to the role
input, on the mat-menu-item
directive... unfortunately, I am not clear on how it should work...
<!-- https://github.com/angular/material2/commit/3f1588f562a4abd85d6add87a4f6ed969ba56898#diff-4cc67949abfd84b09e8b7178ac357febR2134 -->
<button mat-menu-item role="menuitemcheckbox" aria-checked="true">Checked</button>
<button mat-menu-item role="menuitemcheckbox" aria-checked="false">Not </button>
With that being said, assigning the mat-menu-item
class rather than the directive may be a viable workaround.
<mat-checkbox class="mat-menu-item">Problem here</mat-checkbox>
Stackblitz
https://stackblitz.com/edit/angular-j4ftuc-5s5k3t?embed=1&file=app/menu-overview-example.html
Since Angular Material 11 the class="mat-menu-item"
Workaround introduced by Marshal seems to be broken. You can fix it by applying the mat-menu-item
directive on a div
wrapping your mat-checkbox
.
<div mat-menu-item>
<mat-checkbox>Problem here</mat-checkbox>
</div>
Be aware that the checkbox is now only triggered when you click exactly on the checkbox, not when you press any other spot of the menu-item. This causes only a click animation. To workaround this you can register a (click)="..."
listener on the wrapping div.
Elaborating on Aki's answer:
<div mat-menu-item (click)="$event.stopPropagation(); cb.toggle()" (keydown.enter)="$event.stopPropagation(); cb.toggle()">
<mat-checkbox class="mat-menu__checkbox" (click)="$event.stopPropagation()" #cb>Problem No Longer Here</mat-checkbox>
</div>
The wrapper div needs (keydown.enter)
so the keyboard controls for the mat menu will still work correctly. We also register a click event so if the user clicks on the right or left edges of the menu item it will toggle the checkbox. $event.stopPropagation()
is here to prevent the menu from closing while the user is interacting with the checkboxes.
Then add the following to your style sheet:
.mat-menu__checkbox {
height: 100%;
&::ng-deep .mat-checkbox-layout {
height: 100%;
&::ng-deep .mat-checkbox-label {
margin: auto;
vertical-align: middle;
position: relative;
}
}
}
This style will make the label of your mat checkbox the full height of the menu item and keep it vertically centered. This makes it so the checkbox can be clicked anywhere and it will trigger.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With