How can I customize icons within the <mat-nav-list> using Angular?

Is it possible to change the icons as follows?

  1. If the list is expanded, display icon "arrow1"
  2. Otherwise, show icon named "arrow2".

How can I determine if the list is expanded and implement this in HTML?

<mat-nav-list>
    <mat-list-item>
        <h3>Text1</h3>
        <mat-list-item>
            <a>One</a>
        </mat-list-item>
        <mat-list-item>
            <a>Two</a>
        </mat-list-item>
    </mat-list-item>
</mat-nav-list>

Answer №1

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;
}

Answer №2

If you want to customize the icon displayed in place of the mat-select-arrow class, you will need to navigate deep into the rendered element and make the replacement. This should be done within the ngOnInit method to ensure that the DOM is fully loaded when the changes are made.

Here is the relevant HTML code snippet:

<div #mySelect id="mySelect">
    <mat-form-field>
        <mat-select placeholder="Select">
            <mat-option value="option">Option</mat-option>
            <mat-option value="option">Option</mat-option>
            <mat-option value="option">Option</mat-option>
            <mat-option value="option">Option</mat-option>
        </mat-select>
    </mat-form-field>
</div>

And here is the corresponding TypeScript (TS) code:

import {Component, ElementRef, Renderer2, ViewChild} from '@angular/core';

@Component({
  selector: 'select-form-example',
  templateUrl: 'select-form-example.html',
  styleUrls: ['select-form-example.css'],
})
export class SelectFormExample {
  @ViewChild('mySelect') mySelectElement: ElementRef;

  constructor(private renderer: Renderer2, hostElement: ElementRef) {  }

  ngOnInit(){
    let myElement = this.mySelectElement.nativeElement.childNodes[1].childNodes[0].childNodes[0].childNodes[1].childNodes[1].childNodes[0].childNodes[1].childNodes[0];
    this.renderer.removeClass(myElement, 'mat-select-arrow');
    this.renderer.addClass(myElement, 'fas');
    this.renderer.addClass(myElement, 'fa-cat');
  }
}

For a demo, check out this working StackBlitz link.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dynamically setting properties in a Vue component using Angular

After browsing through this interesting discussion, I decided to create a web component: <my-vue-web-comp [userId]="1"></my-vue-web-comp> Initially, everything was working smoothly in Angular when I assigned a static property. Howeve ...

Obtain text output from an Observable

After retrieving a String from the backend: String value = "{I am here}"; In my service method: getValue(): Observable<String> { return this.http.get<String>(this.myURL); } In my component, I am subscribing to this method: String myM ...

switching the color of a path in an SVG when hovering over a

In the midst of working on SVG, I'm trying to implement a color change effect upon hover. The desired functionality is such that when hovering over the .business div, the color of the SVG business path should also change accordingly as specified in th ...

Troubleshooting a dysfunctional collapsed navbar in React with Bootstrap 5

I am experiencing an issue where the collapsed navbar icon does not expand when clicked on smaller screens. I followed the example provided by bootstrap 5 and made sure to include bootstrap css/js and jquery. class CustomNavBar extends Component { re ...

How come the element is not appearing in the div even though it should be there?

The placement of the image and select menu within the same div element may be causing a display issue where only the first image is shown correctly and the select menu appears outside. Why does this occur? <body> <div style="height: 1080px; ...

The router is unable to direct when an item is clicked

I am encountering an issue with my routing setup - when I click on an item in the list-item component, it does not successfully route to the detail-component. Here is a glimpse of my source code: product-list.component.html: <h1>Product List Compon ...

What is the reason behind the equality comparison between number[][number] and number in TypeScript?

https://i.stack.imgur.com/htnkb.png type Test = number[][]; // The Test type will be inferred as 'number' based on the image above. Can you explain why number[] is considered an index signature type with a signature of 'number'? ...

The RxJS observable fails to initiate the subscribe function following the mergeMap operation

I am attempting to organize my dataset in my Angular application using the RxJS operators and split it into multiple streams. However, I am facing difficulties making this work properly. Inside my SignalRService, I have set up a SignalR trigger in the cons ...

What are some recommended strategies for incorporating nested routes with separate pages in a React application?

In my React (TypeScript) project, I have a basic routing setup. There's a constant display of a Header and a Footer, a home component for the frontpage, and a Projects section for showcasing past projects worked on. However, I'm facing an issue w ...

Derived a key from an enum member to be used as an interface key

I am attempting to configure an object property by selecting its key using a computed key, via an enum, as shown in the code snippet below. Unfortunately, solutions 1 and 2 are not functioning. These are the solutions I need to implement in my code becaus ...

What is the syntax for declaring a boolean or object type?

Is it possible to create a variable in TypeScript that can hold either true/false or an object of booleans? I'm still learning TS and would like some input on this syntax. variableA: { a: boolean, b: boolean } | boolean I found a workaround for now, ...

Restrict the number of rows in a CSS grid

Hello there, I am in the process of creating an image gallery using CSS grid. Specifically, my goal is to initially show just one row of images and then allow users to click a "Show more" button to reveal additional images. You can see my progress here: ...

Layering one canvas on top of another

Here is the code I am working with. With a JavaScript library, I can draw on the first canvas and then merge it onto the second canvas. My question is, how can I make the first canvas stay in place or float, regardless of where I scroll on the second canv ...

Is there a way to fix the noticeable difference in how bold text appears between IE11 and Chrome?

When viewing some of the titles on in Google Chrome, they appear like this: https://i.sstatic.net/bKjNE.png However, when viewed in MSIE11, they look like this: https://i.sstatic.net/SJfKk.png The use of strong/bold/font-weight seems to have no effect ...

Creating CSS rounded corners with pseudo-elements

Take a look at this fiddle: https://jsfiddle.net/xnr7tqm1/ This is the html code I'm working with: <div class="media-container"> <iframe width="365" height="200" src="https://www.youtube.com/embed/JqjIb6FhU_k" frameborder="0" al ...

Can you please explain the purpose of the white space in the HTML code?

Currently, I am working on developing a mobile application, and as I start adding styles, I notice a mysterious blank space that seems to be appearing out of nowhere. Can anyone provide any insights or suggestions to help me troubleshoot this issue? https ...

Performance of Angular4 UI decreases with a large amount of data objects

https://i.sstatic.net/PdmFk.jpg The table above displays an array of objects, typically containing 50-60 items. As the item count increases, elements like transition animations and click events become slower. However, I have observed that when filtering t ...

Applying Validators manually in Angular 2 beta 17

We are currently working on a legacy project that needs to be maintained until the final version with angular-final is deployed. Once we upgrade to the final version, I will be able to easily apply conditional Validators using: this.myForm.controls[&apos ...

Executing a function in the constructor of an Angular4 component

I am currently facing an issue where I am attempting to invoke a modal function within the constructor in Angular 4. However, it seems that the function is not being called properly as it gets highlighted. Upon loading the page, no errors are logged and th ...

Unable to perform action on Angular 4 data table page. The NGX Store and effect are not functioning properly

Every time I click on the "go to page" button, it redirects me back to page 1. I recently switched to Angular 4, which is quite new to me since I started with Angular 1 a while ago. The strange thing is that the console.log in the page component is loggin ...