All files / status-bar/si-status-bar-item si-status-bar-item.component.ts

85% Statements 17/20
53.84% Branches 7/13
60% Functions 3/5
85% Lines 17/20

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                                                      1x 92x 92x 92x 92x 92x   92x   92x   92x   92x   92x 92x   92x 92x 92x   92x 92x                      
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import { NgClass } from '@angular/common';
import {
  booleanAttribute,
  Component,
  computed,
  ElementRef,
  inject,
  input,
  viewChild
} from '@angular/core';
import { ExtendedStatusType } from '@siemens/element-ng/common';
import { SiIconComponent, STATUS_ICON_CONFIG } from '@siemens/element-ng/icon';
import { SiTranslatePipe, TranslatableString } from '@siemens/element-translate-ng/translate';
 
@Component({
  selector: 'si-status-bar-item',
  imports: [NgClass, SiIconComponent, SiTranslatePipe],
  templateUrl: './si-status-bar-item.component.html',
  styleUrl: './si-status-bar-item.component.scss',
  host: {
    '[class.clickable]': 'clickable()'
  }
})
export class SiStatusBarItemComponent {
  private readonly statusIcons = inject(STATUS_ICON_CONFIG);
  readonly status = input<ExtendedStatusType>();
  readonly value = input.required<TranslatableString | number>();
  readonly heading = input.required<TranslatableString>();
  readonly color = input<string>();
  /** @defaultValue false */
  readonly blink = input(false, { transform: booleanAttribute });
  /** @defaultValue false */
  readonly valueOnly = input<boolean | undefined, unknown>(false, { transform: booleanAttribute });
  /** @defaultValue false */
  readonly clickable = input(false, { transform: booleanAttribute });
 
  private readonly bg = viewChild.required<ElementRef>('bg');
 
  protected readonly contrastFix = computed(() => {
    return !!this.color() && this.blink() && this.calculateContrastFix();
  });
  protected readonly statusIcon = computed(() => {
    const status = this.status();
    return status ? this.statusIcons[status] : undefined;
  });
  protected readonly background = computed(() =>
    this.blink() && this.status() !== 'success' ? (this.statusIcon()?.background ?? '') : ''
  );
 
  private calculateContrastFix(): boolean {
    // see https://www.w3.org/TR/AERT/#color-contrast
    const rgb = getComputedStyle(this.bg().nativeElement)
      .backgroundColor?.match(/\d+/g)
      ?.map(v => +v);
    return !!rgb && Math.round((rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000) <= 128;
  }
}