🍔 Building Menus with Angular Material’s MatMenu

Creating intuitive, accessible menus is an essential part of modern UI design. Luckily, Angular Material’s MatMenu component makes it easy to add powerful dropdown and context menus to your application. Whether you’re building a simple list of actions or a nested multi-level menu, MatMenu has you covered.

In this guide, I’ll walk you through how to use MatMenu, from the basics to advanced features like nested menus, icons, event handling, and custom styles.


🛠️ Step 1: Install Angular Material

First, make sure Angular Material is installed in your project:

ng add @angular/material

Follow the prompts to select a theme and enable animations and global typography.


📦 Step 2: Import the Required Modules

To start using MatMenu, import the necessary Material modules in your AppModule:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatMenuModule } from '@angular/material/menu';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';

@NgModule({
declarations: [],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatMenuModule,
MatButtonModule,
MatIconModule
],
bootstrap: []
})
export class AppModule {}

⚙️ Basic Usage of MatMenu

Here’s how to set up a simple dropdown menu:

<button mat-button [matMenuTriggerFor]="menu">Menu</button>

<mat-menu #menu="matMenu">
<button mat-menu-item>Option 1</button>
<button mat-menu-item>Option 2</button>
<button mat-menu-item>Option 3</button>
</mat-menu>

🧠 What’s Happening:

  • matMenuTriggerFor binds the button to a menu instance.
  • Each mat-menu-item represents a selectable item in the menu.

🎨 Enhancing with Icons and Dividers

Make your menus more visual and user-friendly by adding icons and separators:

<mat-menu #menu="matMenu">
<button mat-menu-item>
<mat-icon>home</mat-icon>
Home
</button>
<button mat-menu-item>
<mat-icon>settings</mat-icon>
Settings
</button>
<mat-divider></mat-divider>
<button mat-menu-item>
<mat-icon>logout</mat-icon>
Logout
</button>
</mat-menu>

Tip: Use Material Icons or custom SVG icons for a more polished look.


đź“‚ Creating Nested Menus

Need a submenu? Here’s how to set up a multi-level menu structure:

<button mat-button [matMenuTriggerFor]="mainMenu">Main Menu</button>

<mat-menu #mainMenu="matMenu">
<button mat-menu-item [matMenuTriggerFor]="subMenu">More Options</button>
<button mat-menu-item>Profile</button>
</mat-menu>

<mat-menu #subMenu="matMenu">
<button mat-menu-item>Settings</button>
<button mat-menu-item>Help</button>
</mat-menu>

Nested menus are linked just like triggers on buttons, using matMenuTriggerFor.


🖱️ Handling Menu Item Clicks

Trigger actions or navigate based on user selection:

<mat-menu #menu="matMenu">
<button mat-menu-item (click)="handleClick('Option 1')">Option 1</button>
<button mat-menu-item (click)="handleClick('Option 2')">Option 2</button>
</mat-menu>
handleClick(option: string) {
console.log('Menu selected:', option);
}

You can also integrate router navigation or API calls here.


🎨 Styling the Menu

Customize the look and feel of the menu to match your app’s theme:

::ng-deep .mat-menu-panel {
background-color: #2c3e50;
color: #ecf0f1;
border-radius: 8px;
}

::ng-deep .mat-menu-item:hover {
background-color: #34495e;
}

Note: ::ng-deep allows you to override Angular Material’s encapsulated styles. While it’s deprecated, it’s still the most reliable way to target Material internals for now.


âś… Wrap-Up

Angular Material’s MatMenu is a feature-rich component that helps you create interactive and polished menus without reinventing the wheel. With support for icons, nested submenus, click handling, and styling, it’s flexible enough to meet most use cases.

Whether you’re building a user profile menu, a product actions dropdown, or a sidebar navigation, MatMenu is a reliable tool in your Angular toolkit.

Leave a Comment

Your email address will not be published. Required fields are marked *