CUB-50: Implement Adaptive Navigation Component
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<!-- ======================================================================== -->
|
||||
<!-- Adaptive Navigation — Desktop sidebar / Mobile header -->
|
||||
<!-- Desktop (≥768px): 72px sidebar with full navigation items -->
|
||||
<!-- Mobile (<768px): 56px compact header with hamburger menu -->
|
||||
<!-- ======================================================================== -->
|
||||
|
||||
<!-- ======================= DESKTOP SIDEBAR (≥768px) ======================= -->
|
||||
<aside class="adaptive-nav__sidebar" aria-label="Navigation sidebar">
|
||||
<!-- Brand / Toggle header -->
|
||||
<div class="adaptive-nav__sidebar-header">
|
||||
<span class="adaptive-nav__brand">OC</span>
|
||||
</div>
|
||||
|
||||
<!-- Navigation destinations -->
|
||||
<nav class="adaptive-nav__sidebar-nav">
|
||||
@for (dest of destinations; track dest.route) {
|
||||
<a
|
||||
class="adaptive-nav__sidebar-item"
|
||||
[routerLink]="dest.route"
|
||||
routerLinkActive="adaptive-nav__sidebar-item--active"
|
||||
[attr.aria-label]="dest.label"
|
||||
>
|
||||
<mat-icon
|
||||
[matBadge]="dest.badge ?? 0"
|
||||
[matBadgeHidden]="!dest.badge"
|
||||
matBadgePosition="above after"
|
||||
matBadgeSize="small"
|
||||
>
|
||||
{{ dest.icon }}
|
||||
</mat-icon>
|
||||
<span class="adaptive-nav__sidebar-label">{{ dest.label }}</span>
|
||||
</a>
|
||||
}
|
||||
</nav>
|
||||
|
||||
<!-- Sidebar footer: LIVE indicator + action buttons -->
|
||||
<div class="adaptive-nav__sidebar-footer">
|
||||
<div class="adaptive-nav__live" [class.adaptive-nav__live--connected]="isConnected()">
|
||||
<span
|
||||
class="adaptive-nav__live-dot"
|
||||
[class.adaptive-nav__live-dot--connected]="isConnected()"
|
||||
></span>
|
||||
<mat-chip
|
||||
class="adaptive-nav__live-chip"
|
||||
[highlighted]="isConnected()"
|
||||
[disabled]="!isConnected()"
|
||||
>
|
||||
{{ isConnected() ? 'LIVE' : 'OFFLINE' }}
|
||||
</mat-chip>
|
||||
</div>
|
||||
|
||||
<!-- Action buttons (placeholder) -->
|
||||
<div class="adaptive-nav__sidebar-actions">
|
||||
<button mat-icon-button aria-label="Notifications">
|
||||
<mat-icon>notifications</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button aria-label="Settings">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- ======================= MOBILE HEADER (<768px) ======================== -->
|
||||
<header class="adaptive-nav__mobile-header" role="banner">
|
||||
<!-- Hamburger menu button -->
|
||||
<button
|
||||
class="adaptive-nav__hamburger"
|
||||
mat-icon-button
|
||||
[attr.aria-label]="mobileMenuOpen() ? 'Close menu' : 'Open menu'"
|
||||
[attr.aria-expanded]="mobileMenuOpen()"
|
||||
(click)="toggleMobileMenu()"
|
||||
>
|
||||
<mat-icon>{{ mobileMenuOpen() ? 'close' : 'menu' }}</mat-icon>
|
||||
</button>
|
||||
|
||||
<!-- Title -->
|
||||
<h1 class="adaptive-nav__mobile-title">Command Hub</h1>
|
||||
|
||||
<!-- LIVE indicator (always visible on mobile) -->
|
||||
<div class="adaptive-nav__live adaptive-nav__live--mobile" [class.adaptive-nav__live--connected]="isConnected()">
|
||||
<span
|
||||
class="adaptive-nav__live-dot"
|
||||
[class.adaptive-nav__live-dot--connected]="isConnected()"
|
||||
></span>
|
||||
<span class="adaptive-nav__live-text">{{ isConnected() ? 'LIVE' : 'OFFLINE' }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Mobile action buttons (placeholder) -->
|
||||
<button class="adaptive-nav__mobile-action" mat-icon-button aria-label="Notifications">
|
||||
<mat-icon>notifications</mat-icon>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<!-- ======================= MOBILE DRAWER OVERLAY ========================= -->
|
||||
@if (mobileMenuOpen()) {
|
||||
<div class="adaptive-nav__overlay" (click)="closeMobileMenu()" role="presentation"></div>
|
||||
<nav class="adaptive-nav__mobile-drawer" aria-label="Mobile navigation menu">
|
||||
@for (dest of destinations; track dest.route) {
|
||||
<a
|
||||
class="adaptive-nav__drawer-item"
|
||||
[routerLink]="dest.route"
|
||||
routerLinkActive="adaptive-nav__drawer-item--active"
|
||||
[attr.aria-label]="dest.label"
|
||||
(click)="closeMobileMenu()"
|
||||
>
|
||||
<mat-icon>{{ dest.icon }}</mat-icon>
|
||||
<span class="adaptive-nav__drawer-label">{{ dest.label }}</span>
|
||||
</a>
|
||||
}
|
||||
</nav>
|
||||
}
|
||||
Reference in New Issue
Block a user