My suggestion is not to actually "change" the icons, but rather consider hiding or showing them based on certain variables or object states. This approach can provide a smoother user experience (for instance, instant icon changes with no delay). You can take a look at my implementation in this stackblitz demo:
https://stackblitz.com/edit/angular-63sjtx?file=app%2Flist-sections-example.html
Here's an example of how I would structure the HTML:
<mat-list>
<h3 mat-subheader>Folders</h3>
<mat-list-item *ngFor="let folder of folders; let i = index" (click)="toggleArrow(i)" class="list-item">
<mat-icon mat-list-icon [ngClass]="folder.open ? 'hidden' : ''">arrow_right</mat-icon>
<mat-icon mat-list-icon [ngClass]="folder.open ? '' : 'hidden'">arrow_drop_down</mat-icon>
<h4 mat-line>{{folder.name}}</h4>
<p mat-line> {{folder.updated | date}} </p>
</mat-list-item>
</mat-list>
And here's the corresponding TypeScript code:
import {Component} from '@angular/core';
export interface Section {
name: string;
updated: Date;
open: boolean
}
@Component({
selector: 'list-sections-example',
styleUrls: ['list-sections-example.css'],
templateUrl: 'list-sections-example.html',
})
export class ListSectionsExample {
folders: Section[] = [
{
name: 'Photos',
updated: new Date('1/1/16'),
open: false
},
{
name: 'Recipes',
updated: new Date('1/17/16'),
open: false
},
{
name: 'Work',
updated: new Date('1/28/16'),
open: false
}
];
toggleArrow(folderIndex) {
this.folders[folderIndex].open = !this.folders[folderIndex].open;
}
}
Lastly, here's the CSS styling applied:
.mat-list-icon {
color: rgba(0, 0, 0, 0.54);
}
.list-item {
cursor: pointer;
}
.list-item:hover {
background: #eee;
}
.list-item .hidden{
display: none;
}