Skip to main content

Overview

The Menu component provides a collapsible sidebar navigation that allows users to navigate between different sections of the application. It features a logo, navigation links with icons, and a user profile section.

Component Definition

selector
string
default:"app-menu"
The CSS selector used to include this component in templates
standalone
boolean
default:true
Standalone component with explicit imports
imports
array
Dependencies: RouterLink, RouterLinkActive

Source Code Location

File: src/app/menu/menu.ts:5
import { Component, signal } from '@angular/core';
import { RouterLink, RouterLinkActive } from '@angular/router';

@Component({
  selector: 'app-menu',
  imports: [RouterLink, RouterLinkActive],
  templateUrl: './menu.html',
  styleUrl: './menu.css',
})
export class Menu {
  protected isCollapsed = signal(false);

  protected toggleMenu() {
    this.isCollapsed.set(!this.isCollapsed());
  }
}

Properties

isCollapsed

isCollapsed
WritableSignal<boolean>
default:false
Controls the collapsed/expanded state of the sidebar menu
The isCollapsed signal determines whether the sidebar shows full navigation labels or only icons. Implementation: src/app/menu/menu.ts:11

Methods

toggleMenu()

toggleMenu
() => void
Toggles the sidebar between collapsed and expanded states
protected toggleMenu() {
  this.isCollapsed.set(!this.isCollapsed());
}
This method is called when the user clicks the menu toggle button. Implementation: src/app/menu/menu.ts:13-15

Template Structure

The menu is organized into three main sections:

Header Section

logo-details
div
Contains the application logo and name
toggle-button
i
Menu icon button that changes between bx-menu and bx-menu-alt-right based on collapse state
The menu includes five navigation items:
Route: /homeIcon: bx-grid-altOverview and statistics

Profile Section

profile
div
Displays user information at the bottom of the sidebar:
  • User icon (bx-user-circle)
  • Name: “Dr. Admin”
  • Role: “Administrador”

Router Integration

The component uses Angular Router directives for navigation:
<li routerLink="/patient">
The routerLink directive enables navigation to specified routes when the list item is clicked.

routerLinkActive

<li routerLink="/patient" routerLinkActive="active">
The routerLinkActive directive automatically adds the “active” class to the menu item when its route matches the current URL.

Usage

The Menu component is included in the main app layout:
import { Component, computed, inject } from '@angular/core';
import { Router, RouterOutlet } from '@angular/router';
import { Menu } from './menu/menu';
import { HeaderComponent } from './header/header';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet, Menu, HeaderComponent],
  templateUrl: './app.html',
  styleUrl: './app.css'
})
export class App {
  protected showMenu = computed(() => {
    // Hide menu on login page
    return !this.router.url.includes('/login');
  });
}

Dynamic Class Binding

The sidebar uses Angular’s class binding to toggle the collapsed state:
<nav class="sidebar" [class.collapsed]="isCollapsed()">
When isCollapsed() returns true, the “collapsed” class is added to the sidebar, triggering CSS transitions.

Toggle Icon

The toggle button icon changes based on the collapsed state:
<i class="icon bx" 
   [class.bx-menu-alt-right]="isCollapsed()" 
   [class.bx-menu]="!isCollapsed()"
   (click)="toggleMenu()"></i>
  • Expanded: Shows bx-menu icon
  • Collapsed: Shows bx-menu-alt-right icon

Styling Behavior

The menu uses CSS transitions for smooth collapse/expand animations:
  • Full width sidebar (typically 250px)
  • Navigation labels visible
  • Profile details displayed

Icon Library

The component uses Boxicons for all icons. The icon classes follow the pattern:
  • bx: Base Boxicons class
  • bx-[icon-name]: Specific icon (e.g., bx-user, bx-calendar)
Documentation: Boxicons

Customization

Add New Menu Item

To add a new navigation link, add a list item to the menu:
<li routerLink="/reports" routerLinkActive="active">
    <i class="icon bx bx-bar-chart"></i>
    <span class="link_name">Reportes</span>
</li>
Replace the logo image source in menu.html:4:
<img src="your-logo.png" alt="Logo" class="logo-img">

Dynamic User Profile

Replace static profile information with dynamic data:
export class Menu {
  private readonly userService = inject(UserService);
  protected readonly currentUser = this.userService.currentUser;

  protected isCollapsed = signal(false);

  protected toggleMenu() {
    this.isCollapsed.set(!this.isCollapsed());
  }
}

Persist Collapsed State

Store the collapsed state in localStorage:
export class Menu implements OnInit {
  protected isCollapsed = signal(false);

  ngOnInit() {
    const stored = localStorage.getItem('menuCollapsed');
    if (stored !== null) {
      this.isCollapsed.set(stored === 'true');
    }
  }

  protected toggleMenu() {
    const newState = !this.isCollapsed();
    this.isCollapsed.set(newState);
    localStorage.setItem('menuCollapsed', String(newState));
  }
}

Accessibility

Consider adding ARIA attributes for better accessibility:
<nav class="sidebar" 
     [class.collapsed]="isCollapsed()"
     role="navigation"
     aria-label="Main navigation">
  <button (click)="toggleMenu()" 
          aria-label="Toggle menu"
          [attr.aria-expanded]="!isCollapsed()">
    <i class="icon bx" ...></i>
  </button>
  <!-- menu items -->
</nav>

Header

Top navigation bar component

Architecture

Main application layout

Build docs developers (and LLMs) love