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 | 1x 114x 114x 114x 114x 114x 114x 114x 114x 114x 114x 114x 114x 114x 114x 4x 1x 40x 40x | /**
* Copyright (c) Siemens 2016 - 2025
* SPDX-License-Identifier: MIT
*/
import {
booleanAttribute,
ChangeDetectionStrategy,
Component,
computed,
HostListener,
inject,
input,
output,
TemplateRef
} from '@angular/core';
import { SiAutoCollapsableListModule } from '@siemens/element-ng/auto-collapsable-list';
import { addIcons, elementDown2, SiIconComponent } from '@siemens/element-ng/icon';
import { SiTranslatePipe, TranslatableString } from '@siemens/element-translate-ng/translate';
import {
SI_SELECT_OPTIONS_STRATEGY,
SiSelectOptionsStrategy
} from '../options/si-select-options-strategy';
import { SiSelectOptionComponent } from '../select-option/si-select-option.component';
import { SiSelectSelectionStrategy } from '../selection/si-select-selection-strategy';
import { SelectOption } from '../si-select.types';
@Component({
selector: 'si-select-input',
imports: [SiAutoCollapsableListModule, SiIconComponent, SiSelectOptionComponent, SiTranslatePipe],
templateUrl: './si-select-input.component.html',
styleUrl: './si-select-input.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
// In readonly mode, the select needs to be announced as a textbox.
// Otherwise, screen-reader won't announce the readonly state.
class: 'select focus-none dropdown-toggle d-flex align-items-center ps-4',
'aria-autocomplete': 'none',
'[attr.role]': 'readonly() ? "textbox": "combobox"',
'[attr.aria-haspopup]': 'readonly() ? undefined : "listbox"',
'[attr.aria-expanded]': 'readonly() ? undefined : open()',
'[attr.aria-controls]': 'readonly() ? undefined : controls()',
'[attr.aria-readonly]': 'readonly()',
'[attr.aria-labelledby]': 'labeledBy()',
'[attr.aria-disabled]': 'selectionStrategy.disabled()',
'[attr.tabindex]': 'selectionStrategy.disabled() ? "-1" : "0"',
'[class.disabled]': 'selectionStrategy.disabled()',
'[class.active]': 'open()'
}
})
export class SiSelectInputComponent<T> {
readonly baseId = input.required<string>();
/**
* Aria labelledby of the select.
*
* @defaultValue null
*/
readonly labelledby = input<string | null>(null);
/**
* Aria label of the select.
*
* @defaultValue null
*/
readonly ariaLabel = input<string | null>(null);
/** @defaultValue false */
readonly open = input(false, { transform: booleanAttribute });
readonly placeholder = input<TranslatableString>();
readonly controls = input.required<string>();
readonly optionTemplate = input<
TemplateRef<{
$implicit: SelectOption<T>;
}>
>();
/** @defaultValue false */
readonly readonly = input(false, { transform: booleanAttribute });
readonly openListbox = output<void>();
protected readonly selectionStrategy = inject<SiSelectSelectionStrategy<T>>(
SiSelectSelectionStrategy<T>
);
private readonly selectOptions = inject<SiSelectOptionsStrategy<T>>(SI_SELECT_OPTIONS_STRATEGY);
protected readonly selectedRows = this.selectOptions.selectedRows;
protected readonly labeledBy = computed(() => `${this.baseId()}-aria-label ${this.labelledby()}`);
protected readonly icons = addIcons({ elementDown2 });
@HostListener('blur')
protected blur(): void {
if (!this.open()) {
this.selectionStrategy.onTouched();
}
}
@HostListener('click')
@HostListener('keydown.arrowDown', ['$event'])
@HostListener('keydown.alt.arrowDown', ['$event'])
@HostListener('keydown.arrowUp', ['$event'])
@HostListener('keydown.enter')
@HostListener('keydown.space')
protected click(event?: Event): void {
event?.preventDefault();
this.openListbox.emit();
}
}
|