All files / lib/dynamic-heading dynamic-heading.component.ts

100% Statements 81/81
100% Branches 14/14
100% Functions 5/5
100% Lines 81/81

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 821x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 13398x 13131x 267x 267x 13398x 13398x 1x 1x 1x 1x 1x 1115x 1115x 1115x 1115x 1x 1x 3x 3x 3x 3x 3x 3x 3x 1x 1x 1x 2x 2x 2x 2x 1x  
/*******************************************************************************
 * Copyright bei
 * Entwicklungs- und Pflegeverbund für das gemeinsame Fachverfahren gefa
 *
 *******************************************************************************/
import {
  Component,
  ElementRef,
  Input,
  Optional,
  ViewChild,
} from '@angular/core';
 
import { FocusableElementOwner } from '../utils/util.types';
 
import { DynamicHeadingLevelService } from './dynamic-heading-level.service';
 
/**
 * Inserts a heading element (`h1` to `h6`), the level is automatically calculated based on the context.
 * The context is controlled by adding the accompanying directive to parents and containers.
 */
@Component({
  selector: 'gc-dynamic-heading',
  templateUrl: './dynamic-heading.component.html',
  styleUrls: ['./dynamic-heading.component.css'],
})
export class DynamicHeadingComponent implements FocusableElementOwner {
  /**
   * Set the level of the heading within it's context. `same` puts the heading
   * at the level determined from the context, `child` creates a subheading within
   * the context. The latter is intended as quick shortcut for single subheadings, for multiple
   * headings or more complex structures use the related directive.
   *
   * Note that one heading at level `same` should be present in each context,
   * i.e. before using the related directive or this property to add deeper levels, to ensure
   * a semantically valid heading structure.
   */
  @Input()
  public level: 'same' | 'child' = 'same';
 
  /** @ignore */
  @ViewChild('element')
  private element?: ElementRef<HTMLElement>;
 
  /**
   * Get the effective heading level based on the component's input and context.
   * @ignore
   */
  public get headingLevel(): number {
    if (this.level === 'same') {
      return this.currentHeadingLevel;
    } else {
      return this.currentHeadingLevel + 1;
    }
  }
 
  /** @ignore */
  private currentHeadingLevel: number;
 
  constructor(
    @Optional() private parentLevel: DynamicHeadingLevelService | null,
  ) {
    this.currentHeadingLevel = parentLevel?.headingLevel ?? 1;
  }
 
  focusChild(): boolean {
    if (this.element?.nativeElement) {
      this.element.nativeElement.setAttribute('tabindex', '-1');
      this.element.nativeElement.focus();
      return true;
    }
    return false;
  }
 
  /** @ignore */
  protected onBlur(): void {
    if (this.element?.nativeElement) {
      this.element.nativeElement.removeAttribute('tabindex');
    }
  }
}