All files / navbar-vertical si-navbar-vertical-item.component.ts

88.46% Statements 23/26
87.5% Branches 14/16
100% Functions 4/4
88.46% Lines 23/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111                                                                                                1x 51x 51x     51x   51x 51x       51x       51x 51x         51x 101x 101x 63x   38x 18x   20x       51x           9x 9x       9x 9x 3x         1491x                    
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import { NgClass } from '@angular/common';
import {
  ChangeDetectionStrategy,
  Component,
  computed,
  HostListener,
  inject,
  input,
  OnInit
} from '@angular/core';
import { RouterLinkActive } from '@angular/router';
import { MenuItem } from '@siemens/element-ng/common';
import { addIcons, elementDown2, SiIconComponent } from '@siemens/element-ng/icon';
import { SiLinkDirective } from '@siemens/element-ng/link';
 
import { SiNavbarVerticalGroupTriggerDirective } from './si-navbar-vertical-group-trigger.directive';
import {
  NavbarVerticalItemAction,
  NavbarVerticalItemGroup,
  NavbarVerticalItemLink,
  NavbarVerticalItemRouterLink
} from './si-navbar-vertical.model';
import { SI_NAVBAR_VERTICAL } from './si-navbar-vertical.provider';
 
type NavbarVerticalItemInteractive =
  | NavbarVerticalItemGroup
  | NavbarVerticalItemRouterLink
  | NavbarVerticalItemLink
  | NavbarVerticalItemAction;
 
@Component({
  // eslint-disable-next-line @angular-eslint/component-selector
  selector: 'a[si-navbar-vertical-item], button[si-navbar-vertical-item]',
  imports: [NgClass, SiIconComponent],
  templateUrl: './si-navbar-vertical-item.component.html',
  styleUrl: './si-navbar-vertical-item.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: {
    'class': 'focus-inside',
    '[class.dropdown-item]': 'this.parent?.group?.flyout()',
    '[class.navbar-vertical-item]': '!this.parent?.group?.flyout()',
    '[class.active]': 'active'
  }
})
export class SiNavbarVerticalItemComponent implements OnInit {
  protected readonly icons = addIcons({ elementDown2 });
  readonly item = input.required<NavbarVerticalItemInteractive | MenuItem>({
    alias: 'si-navbar-vertical-item'
  });
  readonly activeOverride = input<boolean>();
 
  protected readonly navbar = inject(SI_NAVBAR_VERTICAL);
  protected readonly parent = inject(SiNavbarVerticalItemComponent, {
    skipSelf: true,
    optional: true
  });
  readonly group = inject(SiNavbarVerticalGroupTriggerDirective, {
    optional: true,
    self: true
  });
  private readonly routerLinkActive = inject(RouterLinkActive, { optional: true });
  private readonly siLink = inject(SiLinkDirective, { optional: true });
 
  /**
   * Formats badge value to limit display to "+99" for numbers greater than 99
   */
  protected readonly formattedBadge = computed(() => {
    const badge = this.item().badge;
    if (!badge) {
      return '';
    }
    if (typeof badge === 'number') {
      return badge > 99 ? '+99' : badge.toString();
    }
    return badge.toString();
  });
 
  ngOnInit(): void {
    Iif (this.group && this.active) {
      this.group.expanded.set(true);
    }
  }
 
  @HostListener('click') protected triggered(): void {
    const item = this.item();
    Iif (item.type === 'action') {
      item.action(item);
      return;
    }
    this.parent?.group?.hideFlyout();
    if (!this.group) {
      this.navbar.itemTriggered();
    }
  }
 
  get active(): boolean {
    return (
      this.activeOverride() ||
      this.routerLinkActive?.isActive ||
      this.siLink?.active() ||
      ((!this.group?.expanded() || this.navbar.collapsed()) && this.group?.active()) ||
      false
    );
    /* eslint-disable-enable @typescript-eslint/prefer-nullish-coalescing */
  }
}