I am using Angular Material 14 with Angular 15 and below is the code to display Menu items with mat-nav-list
<mat-nav-list role="list">
<a mat-list-item role="listitem" class="list-item-setting" matTooltipPosition="right" routerLinkActive="active"
[routerLinkActiveOptions]="{exact:true}" class="admin-link">
<mat-icon class="list-item-setting">user1</mat-icon>
<span>User 1</span>
</a>
<a mat-list-item role="listitem" class="list-item-setting" matTooltipPosition="right" routerLinkActive="active"
[routerLinkActiveOptions]="{exact:true}" class="admin-link">
<mat-icon class="list-item-setting">user2</mat-icon>
<span class="nowrap">User 2</span>
</a>
<a mat-list-item role="listitem" class="list-item-setting" matTooltipPosition="right" routerLinkActive="active"
[routerLinkActiveOptions]="{exact:true}" class="admin-link">
<mat-icon class="list-item-setting">user3</mat-icon>
<span class="nowrap">User 3</span>
</a>
<mat-accordion>
<mat-expansion-panel hideToggle [(expanded)]="panelOpenState" class="mat-elevation-z0">
<mat-expansion-panel-header>
<mat-panel-title style="text-align: left">
<img src="../../../../assets/images/icon_bell.svg">
<span class="add-padding-to-mat-panel-header"><a class="list-item-setting" routerLinkActive="active">Submenu
Accordion</a></span>
</mat-panel-title>
</mat-expansion-panel-header>
<div>
<mat-panel-description mat-list-item role="listitem" id="notificationListId"
class="mat-panel-description-setting"><a class="list-item-setting" routerLinkActive="active"
[routerLinkActiveOptions]="{exact:true}">Submenu 1
</a></mat-panel-description>
<mat-panel-description mat-list-item role="listitem" id="subscriberGroupsId"
class="mat-panel-description-setting"><a class="list-item-setting" routerLinkActive="active"
[routerLinkActiveOptions]="{exact:true}" style="white-space: nowrap;">Submenu 2</a></mat-panel-description>
<mat-panel-description mat-list-item role="listitem" id="allSubscribersId"
class="mat-panel-description-setting"><a class="list-item-setting" routerLinkActive="active">Submenu
3</a></mat-panel-description>
</div>
</mat-expansion-panel>
</mat-accordion>
</mat-nav-list>
And below is the Menu list that appears with this code..
The CSS Code related to the Menu is below...
.mat-panel-description-setting {
color: $white;
padding-top: 10px;
padding-left: 30px;
flex-basis: 100%;
}
.mat-expansion-panel-header {
padding: 0 16px !important;
}
.list-item-setting {
padding: 0!important;
padding-left: 16px;
color: $white;
}
.add-padding-to-mat-panel-header {
color: $white;
padding-left: 16px;
}
How can I make the same effect for the Submenu Accordion
Description items on selection of any one of the Submenu items in the list. I mean to say, if user selects Submenu 2, then it should highlight with Band(Shadow effect) that I have shown in the picture for that Submenu 2 item.
I tried using <mat-nav-list></mat-nav-list>
for the Accordion Submenu
items and it is not accepting there..
EDIT
With the code given in the Answer, I am getting as below screenshot. I have changed your code little bit like - using @HostListener instead of document.addEventListener. The grey background is not going away on click of 2nd Submenu item. And the width is covering only to that text.
Can anyone throw some light on this..
Posting a more "Angular" approach to this problem as the current solution offered, while it certainly solves the problem, it does leverage what I would consider to be Angular anti patterns.
Leverage @ViewChildren
to retrieve ElementRef
from the DOM via the MatListItem
class.
@ViewChildren(MatListItem, { read: ElementRef }) listItems!: QueryList<ElementRef>;
Import Renderer2
for styling of the elements.
Using
Renderer2
ensures vended compilations are compliant with regard to specified targets.
constructor(private renderer: Renderer2) {}
Function to hanleSelectionState
.
// Function to reset the background color of all elements
public handleSelectionState(e: any) {
// loop over all elements to remove any is-active attributes
this.listItems.forEach((listItem) => {
this.renderer.removeAttribute(listItem.nativeElement, 'is-active', '');
});
// use target on click event to set attribute is-active
this.renderer.setAttribute(e.currentTarget, 'is-active', '');
}
Add CSS to styles.scss
for the is-active
attribute
[is-active] {
background-color: lightgray;
}
In the HTML bind the click
event to the hanleSelectionState
function
<mat-list-item (click)="handleSelectionState($event)">
<mat-icon class="list-item-setting">email</mat-icon>
<span class="add-padding">User 1</span>
</mat-list-item>
STACKBLITZ