Building a Dynamic Sidebar Menu in Angular with Nested Items

Creating a dynamic sidebar menu in Angular can greatly enhance the navigation experience on your website or application. When your menu includes nested items or submenus, it becomes even more important to implement a flexible and maintainable solution. This guide will walk you through building a sidebar with nested items using Angular.

Understanding the Structure

Before diving into the code, it’s essential to understand the structure of a nested menu. Typically, a menu consists of an array of objects, each representing a menu item. Items can have properties like label, icon, and children for nested items.

Creating the Menu Data

Start by defining your menu data in the component:

menuItems = [
  {
    label: 'Home',
    icon: 'home',
    route: '/home'
  },
  {
    label: 'Products',
    icon: 'shopping_cart',
    children: [
      { label: 'Electronics', route: '/products/electronics' },
      { label: 'Clothing', route: '/products/clothing' }
    ]
  },
  {
    label: 'About Us',
    icon: 'info',
    route: '/about'
  }
];

Building the Sidebar Template

Use Angular’s *ngFor directive to iterate over menu items. For nested items, implement recursive templates or use nested *ngFor blocks.

<nav class="sidebar">
  <ul>
    <li *ngFor="let item of menuItems">
      <div class="menu-item">
        <mat-icon>{{item.icon}}</mat-icon>
        <a [routerLink]="item.route" *ngIf="!item.children">{{item.label}}</a>
        <span *ngIf="item.children">{{item.label}}</span>
      </div>
      <ul *ngIf="item.children">
        <li *ngFor="let child of item.children">
          <mat-icon>subdirectory_arrow_right</mat-icon>
          <a [routerLink]="child.route">{{child.label}}</a>
        </li>
      </ul>
    </li>
  </ul>
</nav>

Styling the Sidebar

Apply CSS to style the sidebar for better usability. Consider collapsing and expanding nested menus for a cleaner interface.

.sidebar {
  width: 250px;
  background-color: #f4f4f4;
  padding: 10px;
}

.menu-item {
  display: flex;
  align-items: center;
  padding: 8px;
  cursor: pointer;
}

.menu-item:hover {
  background-color: #ddd;
}

ul {
  list-style: none;
  padding-left: 20px;
}

Adding Interactivity

Implement toggle functionality for nested menus using Angular’s component state. Use a boolean variable to track open/close states and bind it to the menu items.

isOpen = {};

toggle(index) {
  this.isOpen[index] = !this.isOpen[index];
}

Update your template to toggle nested menus:

<li *ngFor="let item of menuItems; let i = index">
  <div class="menu-item" (click)="toggle(i)">
    <mat-icon>{{item.icon}}</mat-icon>
    <span>{{item.label}}</span>
  </div>
  <ul *ngIf="item.children && isOpen[i]">
    <li *ngFor="let child of item.children">
      <mat-icon>subdirectory_arrow_right</mat-icon>
      <a [routerLink]="child.route">{{child.label}}</a>
    </li>
  </ul>
</li>

Conclusion

Building a dynamic, nested sidebar menu in Angular involves managing data structures and user interactions. By following this approach, you can create a flexible navigation system that improves the user experience on your website or application.