Skip to main content

Overview

SidenavComponent renders the side navigation menu containing the application logo and a list of navigation items. It highlights the active route and emits events when navigation items are clicked.

Selector

'jet-sidenav'

Usage

<mat-sidenav>
  <jet-sidenav
    [activeNavigationMenuItemPath]="currentPath"
    (clickNavigationMenuItem)="handleNavigationClick()"
  ></jet-sidenav>
</mat-sidenav>

Inputs

activeNavigationMenuItemPath
string | undefined
required
The current active navigation path. Used to highlight the active menu item in the navigation list.Example: "/dashboard", "/settings", "/profile"

Outputs

clickNavigationMenuItem
EventEmitter<void>
Emitted when any navigation item is clicked. Typically used to close the sidenav on mobile when in ‘over’ mode.Usage: (clickNavigationMenuItem)="sidenav.close()"

Properties

Protected Properties

navigationMenuItems
NavigationMenuItem[]
Array of navigation menu items loaded from NAVIGATION_MENU_ITEMS constant. Each item includes:
  • path: Route path
  • icon: Material icon name
  • nameKey: Translation key for the item name

Template Structure

The sidenav consists of two main sections:
<mat-toolbar class="jet-sidenav-toolbar">
  <a matIconButton [routerLink]="['/']" (click)="clickNavigationMenuItem.emit()">
    <mat-icon svgIcon="logo"></mat-icon>
  </a>
</mat-toolbar>
<div class="jet-sidenav-nav-list">
  <mat-nav-list>
    @for (navigationMenuItem of navigationMenuItems; track navigationMenuItem.path) {
      <a
        mat-list-item
        [activated]="activeNavigationMenuItemPath === navigationMenuItem.path"
        [routerLink]="[navigationMenuItem.path]"
        (click)="clickNavigationMenuItem.emit()"
      >
        <mat-icon matListItemIcon>{{ navigationMenuItem.icon }}</mat-icon>
        <span>{{ navigationMenuItem.nameKey | transloco }}</span>
      </a>
    }
  </mat-nav-list>
</div>
Navigation items are defined in the NAVIGATION_MENU_ITEMS constant. Each item has this structure:
interface NavigationMenuItem {
  path: string;           // Route path (e.g., '/home')
  icon: string;           // Material icon name (e.g., 'home')
  nameKey: string;        // Translation key (e.g., 'nav.home')
}

Features

Active Route Highlighting

The active navigation item is automatically highlighted using the activated property:
[activated]="activeNavigationMenuItemPath === navigationMenuItem.path"
This applies Material Design’s active state styling to the selected item.

Internationalization

All navigation item labels are internationalized using Transloco:
<span>{{ navigationMenuItem.nameKey | transloco }}</span>

Analytics Tracking

The home logo button includes analytics tracking:
[jetAnalyticsEvent]="{ name: 'open_home' }"

Responsive Behavior

While the component itself doesn’t handle responsive behavior, it’s typically used with Material’s <mat-sidenav> which provides:
  • Desktop (‘side’ mode): Sidenav stays open alongside content
  • Mobile (‘over’ mode): Sidenav overlays content and closes on navigation

Dependencies

The component uses:
  • MatButtonModule - Icon button for logo
  • MatIconModule - Material icons
  • MatListModule - Navigation list items
  • MatToolbarModule - Header toolbar
  • MatTooltipModule - Hover tooltips
  • RouterLink - Angular routing
  • AnalyticsDirective - Click tracking
  • TranslocoModule - Internationalization
  • LoggerService - Initialization logging

Example: Full Integration with AppComponent

import { Component, signal } from '@angular/core';
import { MatSidenavModule } from '@angular/material/sidenav';
import { Router } from '@angular/router';
import { SidenavComponent } from '@jet/components/sidenav/sidenav.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [MatSidenavModule, SidenavComponent],
  template: `
    <mat-sidenav-container>
      <mat-sidenav 
        #sidenav
        [mode]="sidenavMode()"
        [(opened)]="isSidenavOpen"
      >
        <jet-sidenav
          [activeNavigationMenuItemPath]="activeRoute()"
          (clickNavigationMenuItem)="onNavigationClick()"
        ></jet-sidenav>
      </mat-sidenav>
      
      <mat-sidenav-content>
        <router-outlet></router-outlet>
      </mat-sidenav-content>
    </mat-sidenav-container>
  `
})
export class AppComponent {
  activeRoute = signal<string | undefined>('/home');
  isSidenavOpen = signal(true);
  sidenavMode = signal<'side' | 'over'>('side');
  
  onNavigationClick() {
    // Close sidenav on mobile after navigation
    if (this.sidenavMode() === 'over') {
      this.isSidenavOpen.set(false);
    }
  }
}

Customizing Navigation Items

To add or modify navigation items, update the NAVIGATION_MENU_ITEMS constant:
// constants/navigation-menu-items.constant.ts
export const NAVIGATION_MENU_ITEMS: NavigationMenuItem[] = [
  {
    path: '/home',
    icon: 'home',
    nameKey: 'jet-sidenav.home'
  },
  {
    path: '/dashboard',
    icon: 'dashboard',
    nameKey: 'jet-sidenav.dashboard'
  },
  {
    path: '/settings',
    icon: 'settings',
    nameKey: 'jet-sidenav.settings'
  }
];
Then add translations:
{
  "jet-sidenav": {
    "home": "Home",
    "dashboard": "Dashboard",
    "settings": "Settings"
  }
}

Styling

Customize the sidenav appearance in sidenav.component.scss:
.jet-sidenav-toolbar {
  display: flex;
  justify-content: center;
  padding: 1rem;
}

.jet-sidenav-nav-list {
  padding: 1rem 0;
  
  mat-nav-list {
    padding: 0;
  }
  
  a[mat-list-item] {
    border-radius: 8px;
    margin: 0.25rem 0.5rem;
    
    &.mdc-list-item--activated {
      background-color: var(--mat-sys-primary-container);
      color: var(--mat-sys-on-primary-container);
    }
  }
}

Accessibility

  • Semantic navigation elements
  • Proper aria-label attributes on buttons
  • Keyboard navigation support via Material components
  • Screen reader friendly with descriptive labels
  • Focus indicators on interactive elements

Source

Location: src/app/components/sidenav/sidenav.component.ts

Build docs developers (and LLMs) love