All files / select/select-list si-select-list.base.ts

90% Statements 18/20
50% Branches 1/2
80% Functions 4/5
90% Lines 18/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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86                                                            1x 38x 38x         38x           38x 38x   38x     38x 38x 38x 38x 38x       38x     38x       38x                       9x       18x 9x        
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';
import {
  Directive,
  ElementRef,
  HostBinding,
  HostListener,
  inject,
  input,
  OnDestroy,
  OnInit,
  output,
  TemplateRef
} from '@angular/core';
 
import {
  SI_SELECT_OPTIONS_STRATEGY,
  SiSelectOptionsStrategy
} from '../options/si-select-options-strategy';
import { SiSelectSelectionStrategy } from '../selection/si-select-selection-strategy';
import { SelectGroup, SelectOption } from '../si-select.types';
 
@Directive({
  host: {
    class: 'dropdown-menu position-static w-100 py-4 d-flex flex-column'
  }
})
export abstract class SiSelectListBase<T> implements OnInit, OnDestroy {
  readonly baseId = input.required<string>();
  readonly optionTemplate = input<
    TemplateRef<{
      $implicit: SelectOption<T>;
    }>
  >();
  readonly groupTemplate = input<
    TemplateRef<{
      $implicit: SelectGroup<T>;
    }>
  >();
  /** @defaultValue null */
  readonly labelledby = input<string | null>(null);
  readonly actionsTemplate = input<TemplateRef<any>>();
 
  readonly closeOverlay = output<void>();
 
  protected readonly selectionStrategy =
    inject<SiSelectSelectionStrategy<T>>(SiSelectSelectionStrategy);
  protected readonly selectOptions = inject<SiSelectOptionsStrategy<T>>(SI_SELECT_OPTIONS_STRATEGY);
  protected readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);
  protected readonly elementRef = inject(ElementRef);
  protected rows = this.selectOptions.rows;
  protected focusTrap!: ConfigurableFocusTrap;
 
  @HostBinding('class.si-multi-select')
  protected multiSelect = this.selectionStrategy.allowMultiple;
 
  ngOnInit(): void {
    this.focusTrap = this.focusTrapFactory.create(this.elementRef.nativeElement);
  }
 
  ngOnDestroy(): void {
    this.focusTrap.destroy();
  }
 
  @HostListener('keydown.tab')
  protected keydownTab(): void {
    // Ignore tab key if actions are displayed.
    Iif (!this.actionsTemplate()) {
      this.closeOverlayAlways();
    }
  }
 
  protected closeOverlayAlways(): void {
    this.closeOverlay.emit();
  }
 
  protected closeOverlayIfSingle(): void {
    if (!this.selectionStrategy.allowMultiple) {
      this.closeOverlayAlways();
    }
  }
}