@siemens/element-ng 49.8.0 → 49.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/fesm2022/siemens-element-ng-application-header.mjs +2 -2
  2. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -1
  3. package/fesm2022/siemens-element-ng-avatar.mjs +2 -2
  4. package/fesm2022/siemens-element-ng-avatar.mjs.map +1 -1
  5. package/fesm2022/siemens-element-ng-breadcrumb-router.mjs +6 -2
  6. package/fesm2022/siemens-element-ng-breadcrumb-router.mjs.map +1 -1
  7. package/fesm2022/siemens-element-ng-circle-status.mjs +2 -2
  8. package/fesm2022/siemens-element-ng-circle-status.mjs.map +1 -1
  9. package/fesm2022/siemens-element-ng-dashboard.mjs +8 -5
  10. package/fesm2022/siemens-element-ng-dashboard.mjs.map +1 -1
  11. package/fesm2022/siemens-element-ng-datatable.mjs +10 -19
  12. package/fesm2022/siemens-element-ng-datatable.mjs.map +1 -1
  13. package/fesm2022/siemens-element-ng-datepicker.mjs +6 -6
  14. package/fesm2022/siemens-element-ng-datepicker.mjs.map +1 -1
  15. package/fesm2022/siemens-element-ng-file-uploader.mjs +2 -2
  16. package/fesm2022/siemens-element-ng-file-uploader.mjs.map +1 -1
  17. package/fesm2022/siemens-element-ng-form.mjs +8 -10
  18. package/fesm2022/siemens-element-ng-form.mjs.map +1 -1
  19. package/fesm2022/siemens-element-ng-header-dropdown.mjs +19 -55
  20. package/fesm2022/siemens-element-ng-header-dropdown.mjs.map +1 -1
  21. package/fesm2022/siemens-element-ng-menu.mjs +5 -7
  22. package/fesm2022/siemens-element-ng-menu.mjs.map +1 -1
  23. package/fesm2022/siemens-element-ng-navbar-vertical-next.mjs +90 -49
  24. package/fesm2022/siemens-element-ng-navbar-vertical-next.mjs.map +1 -1
  25. package/fesm2022/siemens-element-ng-navbar-vertical.mjs +25 -29
  26. package/fesm2022/siemens-element-ng-navbar-vertical.mjs.map +1 -1
  27. package/fesm2022/siemens-element-ng-select.mjs +455 -48
  28. package/fesm2022/siemens-element-ng-select.mjs.map +1 -1
  29. package/fesm2022/siemens-element-ng-side-panel.mjs +2 -2
  30. package/fesm2022/siemens-element-ng-side-panel.mjs.map +1 -1
  31. package/fesm2022/siemens-element-ng-slider.mjs +2 -2
  32. package/fesm2022/siemens-element-ng-slider.mjs.map +1 -1
  33. package/fesm2022/siemens-element-ng-status-toggle.mjs +2 -2
  34. package/fesm2022/siemens-element-ng-status-toggle.mjs.map +1 -1
  35. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -1
  36. package/fesm2022/siemens-element-ng-tree-view.mjs +52 -30
  37. package/fesm2022/siemens-element-ng-tree-view.mjs.map +1 -1
  38. package/package.json +3 -3
  39. package/template-i18n.json +1 -0
  40. package/types/siemens-element-ng-breadcrumb-router.d.ts +6 -2
  41. package/types/siemens-element-ng-dashboard.d.ts +2 -1
  42. package/types/siemens-element-ng-datatable.d.ts +0 -1
  43. package/types/siemens-element-ng-form.d.ts +1 -1
  44. package/types/siemens-element-ng-header-dropdown.d.ts +0 -8
  45. package/types/siemens-element-ng-navbar-vertical-next.d.ts +29 -8
  46. package/types/siemens-element-ng-navbar-vertical.d.ts +2 -1
  47. package/types/siemens-element-ng-select.d.ts +241 -2
  48. package/types/siemens-element-ng-translate.d.ts +1 -0
  49. package/types/siemens-element-ng-tree-view.d.ts +4 -5
@@ -1,7 +1,7 @@
1
1
  import * as i1$3 from '@angular/cdk/overlay';
2
- import { CdkOverlayOrigin, OverlayModule } from '@angular/cdk/overlay';
2
+ import { CdkOverlayOrigin, OverlayModule, Overlay } from '@angular/cdk/overlay';
3
3
  import * as i0 from '@angular/core';
4
- import { InjectionToken, Directive, input, ChangeDetectionStrategy, Component, booleanAttribute, output, computed, signal, inject, Input, HostListener, ElementRef, HostBinding, viewChild, contentChild, TemplateRef, NgModule } from '@angular/core';
4
+ import { InjectionToken, Directive, input, ChangeDetectionStrategy, Component, booleanAttribute, output, computed, signal, inject, Input, ElementRef, viewChild, contentChild, TemplateRef, NgModule, model, ViewContainerRef, DestroyRef, PLATFORM_ID } from '@angular/core';
5
5
  import { SI_FORM_ITEM_CONTROL } from '@siemens/element-ng/form';
6
6
  import { SiTranslatePipe, t } from '@siemens/element-translate-ng/translate';
7
7
  import { elementDown2, elementOk, elementSearch } from '@siemens/element-icons';
@@ -9,15 +9,17 @@ import * as i1 from '@siemens/element-ng/auto-collapsable-list';
9
9
  import { SiAutoCollapsableListModule } from '@siemens/element-ng/auto-collapsable-list';
10
10
  import { SiIconComponent, addIcons } from '@siemens/element-ng/icon';
11
11
  import * as i1$2 from '@angular/common';
12
- import { NgTemplateOutlet, CommonModule } from '@angular/common';
12
+ import { NgTemplateOutlet, CommonModule, isPlatformBrowser } from '@angular/common';
13
13
  import * as i1$1 from '@siemens/element-ng/autocomplete';
14
14
  import { SiAutocompleteDirective, SiAutocompleteModule } from '@siemens/element-ng/autocomplete';
15
15
  import { SiLoadingSpinnerComponent } from '@siemens/element-ng/loading-spinner';
16
16
  import { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';
17
17
  import { CdkListbox, CdkOption } from '@angular/cdk/listbox';
18
- import { Subject, switchMap, of } from 'rxjs';
18
+ import { Subject, switchMap, of, merge, filter, takeUntil as takeUntil$1 } from 'rxjs';
19
19
  import { debounceTime, takeUntil } from 'rxjs/operators';
20
20
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
21
+ import { TemplatePortal } from '@angular/cdk/portal';
22
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
21
23
 
22
24
  /**
23
25
  * Copyright (c) Siemens 2016 - 2026
@@ -190,7 +192,7 @@ class SiSelectInputComponent {
190
192
  this.openListbox.emit();
191
193
  }
192
194
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
193
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSelectInputComponent, isStandalone: true, selector: "si-select-input", inputs: { baseId: { classPropertyName: "baseId", publicName: "baseId", isSignal: true, isRequired: true, transformFunction: null }, labelledby: { classPropertyName: "labelledby", publicName: "labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: true, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openListbox: "openListbox" }, host: { attributes: { "aria-autocomplete": "none" }, listeners: { "blur": "blur()", "click": "click()", "keydown.arrowDown": "click($event)", "keydown.alt.arrowDown": "click($event)", "keydown.arrowUp": "click($event)", "keydown.enter": "click()", "keydown.space": "click()" }, properties: { "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()" }, classAttribute: "select focus-none dropdown-toggle d-flex align-items-center ps-4" }, ngImport: i0, template: "@if (ariaLabel()) {\n <span class=\"visually-hidden\" [id]=\"baseId() + '-aria-label'\">{{ ariaLabel() }}</span>\n}\n<div\n class=\"d-flex align-items-center flex-fill overflow-hidden\"\n [id]=\"baseId() + '-content'\"\n [siAutoCollapsableList]=\"selectionStrategy.allowMultiple && selectedRows().length > 1\"\n>\n @for (activeOption of selectedRows(); track activeOption) {\n @if (activeOption) {\n <si-select-option\n siAutoCollapsableListItem\n [option]=\"activeOption\"\n [optionTemplate]=\"optionTemplate()\"\n [class.overflow-hidden]=\"!selectionStrategy.allowMultiple || $count === 1\"\n />\n }\n } @empty {\n <div class=\"text-secondary\">{{ placeholder() | translate }}</div>\n }\n @if (selectionStrategy.allowMultiple) {\n <div #overflowItem=\"siAutoCollapsableListOverflowItem\" siAutoCollapsableListOverflowItem>\n <div class=\"overflow-item\"> {{ overflowItem.hiddenItemCount }}+</div>\n </div>\n }\n</div>\n<div class=\"form-control-actions\">\n <si-icon\n class=\"dropdown-caret icon flip-rtl ps-0 m-0\"\n [class.text-muted]=\"readonly()\"\n [icon]=\"icons.elementDown2\"\n />\n</div>\n", styles: ["@charset \"UTF-8\";:host{cursor:pointer;font-weight:600;min-inline-size:72px;block-size:100%;color:var(--element-text-primary);padding-block:7px;padding-inline-end:calc(3px + var(--si-feedback-icon-offset, 0px))}:host.disabled{color:var(--element-text-disabled)}:host-context(.form-control) :host{font-weight:400;padding-block:3px;padding-inline-end:var(--si-input-padding-inline-end)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled):hover{background:var(--element-base-1-hover)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled).active{background:var(--element-base-1-selected)}si-select-option+si-select-option:before{content:\",\\a0\"}.overflow-item{border-radius:var(--element-radius-3);background:var(--element-base-0);margin-inline-start:4px;padding-inline:8px}\n"], dependencies: [{ kind: "ngmodule", type: SiAutoCollapsableListModule }, { kind: "directive", type: i1.SiAutoCollapsableListDirective, selector: "[siAutoCollapsableList]", inputs: ["siAutoCollapsableList", "gap", "siAutoCollapsableListContainerElement"], exportAs: ["siAutoCollapsableList"] }, { kind: "directive", type: i1.SiAutoCollapsableListItemDirective, selector: "[siAutoCollapsableListItem]", inputs: ["forceHide"], exportAs: ["siAutoCollapsableListItem"] }, { kind: "directive", type: i1.SiAutoCollapsableListOverflowItemDirective, selector: "[siAutoCollapsableListOverflowItem]", exportAs: ["siAutoCollapsableListOverflowItem"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiSelectOptionComponent, selector: "si-select-option", inputs: ["option", "optionTemplate"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
195
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSelectInputComponent, isStandalone: true, selector: "si-select-input", inputs: { baseId: { classPropertyName: "baseId", publicName: "baseId", isSignal: true, isRequired: true, transformFunction: null }, labelledby: { classPropertyName: "labelledby", publicName: "labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: true, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openListbox: "openListbox" }, host: { attributes: { "aria-autocomplete": "none" }, listeners: { "blur": "blur()", "click": "click($event)", "keydown.arrowDown": "click($event)", "keydown.alt.arrowDown": "click($event)", "keydown.arrowUp": "click($event)", "keydown.enter": "click($event)", "keydown.space": "click($event)" }, properties: { "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()" }, classAttribute: "select focus-none dropdown-toggle d-flex align-items-center ps-4" }, ngImport: i0, template: "@if (ariaLabel()) {\n <span class=\"visually-hidden\" [id]=\"baseId() + '-aria-label'\">{{ ariaLabel() }}</span>\n}\n<div\n class=\"d-flex align-items-center flex-fill overflow-hidden\"\n [id]=\"baseId() + '-content'\"\n [siAutoCollapsableList]=\"selectionStrategy.allowMultiple && selectedRows().length > 1\"\n>\n @for (activeOption of selectedRows(); track activeOption) {\n @if (activeOption) {\n <si-select-option\n siAutoCollapsableListItem\n [option]=\"activeOption\"\n [optionTemplate]=\"optionTemplate()\"\n [class.overflow-hidden]=\"!selectionStrategy.allowMultiple || $count === 1\"\n />\n }\n } @empty {\n <div class=\"text-secondary\">{{ placeholder() | translate }}</div>\n }\n @if (selectionStrategy.allowMultiple) {\n <div #overflowItem=\"siAutoCollapsableListOverflowItem\" siAutoCollapsableListOverflowItem>\n <div class=\"pill py-0 ms-2\"> {{ overflowItem.hiddenItemCount }}+</div>\n </div>\n }\n</div>\n<div class=\"form-control-actions\">\n <si-icon\n class=\"dropdown-caret icon flip-rtl ps-0 m-0\"\n [class.text-muted]=\"readonly()\"\n [icon]=\"icons.elementDown2\"\n />\n</div>\n", styles: ["@charset \"UTF-8\";:host{cursor:pointer;font-weight:600;min-inline-size:72px;block-size:100%;color:var(--element-text-primary);padding-block:7px;padding-inline-end:calc(3px + var(--si-feedback-icon-offset, 0px))}:host.disabled{color:var(--element-text-disabled)}:host-context(.form-control) :host{font-weight:400;padding-block:3px;padding-inline-end:var(--si-input-padding-inline-end)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled):hover{background:var(--element-base-1-hover)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled).active{background:var(--element-base-1-selected)}si-select-option+si-select-option:before{content:\",\\a0\"}\n"], dependencies: [{ kind: "ngmodule", type: SiAutoCollapsableListModule }, { kind: "directive", type: i1.SiAutoCollapsableListDirective, selector: "[siAutoCollapsableList]", inputs: ["siAutoCollapsableList", "gap", "siAutoCollapsableListContainerElement"], exportAs: ["siAutoCollapsableList"] }, { kind: "directive", type: i1.SiAutoCollapsableListItemDirective, selector: "[siAutoCollapsableListItem]", inputs: ["forceHide"], exportAs: ["siAutoCollapsableListItem"] }, { kind: "directive", type: i1.SiAutoCollapsableListOverflowItemDirective, selector: "[siAutoCollapsableListOverflowItem]", exportAs: ["siAutoCollapsableListOverflowItem"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiSelectOptionComponent, selector: "si-select-option", inputs: ["option", "optionTemplate"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
194
196
  }
195
197
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectInputComponent, decorators: [{
196
198
  type: Component,
@@ -208,30 +210,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
208
210
  '[attr.aria-disabled]': 'selectionStrategy.disabled()',
209
211
  '[attr.tabindex]': 'selectionStrategy.disabled() ? "-1" : "0"',
210
212
  '[class.disabled]': 'selectionStrategy.disabled()',
211
- '[class.active]': 'open()'
212
- }, template: "@if (ariaLabel()) {\n <span class=\"visually-hidden\" [id]=\"baseId() + '-aria-label'\">{{ ariaLabel() }}</span>\n}\n<div\n class=\"d-flex align-items-center flex-fill overflow-hidden\"\n [id]=\"baseId() + '-content'\"\n [siAutoCollapsableList]=\"selectionStrategy.allowMultiple && selectedRows().length > 1\"\n>\n @for (activeOption of selectedRows(); track activeOption) {\n @if (activeOption) {\n <si-select-option\n siAutoCollapsableListItem\n [option]=\"activeOption\"\n [optionTemplate]=\"optionTemplate()\"\n [class.overflow-hidden]=\"!selectionStrategy.allowMultiple || $count === 1\"\n />\n }\n } @empty {\n <div class=\"text-secondary\">{{ placeholder() | translate }}</div>\n }\n @if (selectionStrategy.allowMultiple) {\n <div #overflowItem=\"siAutoCollapsableListOverflowItem\" siAutoCollapsableListOverflowItem>\n <div class=\"overflow-item\"> {{ overflowItem.hiddenItemCount }}+</div>\n </div>\n }\n</div>\n<div class=\"form-control-actions\">\n <si-icon\n class=\"dropdown-caret icon flip-rtl ps-0 m-0\"\n [class.text-muted]=\"readonly()\"\n [icon]=\"icons.elementDown2\"\n />\n</div>\n", styles: ["@charset \"UTF-8\";:host{cursor:pointer;font-weight:600;min-inline-size:72px;block-size:100%;color:var(--element-text-primary);padding-block:7px;padding-inline-end:calc(3px + var(--si-feedback-icon-offset, 0px))}:host.disabled{color:var(--element-text-disabled)}:host-context(.form-control) :host{font-weight:400;padding-block:3px;padding-inline-end:var(--si-input-padding-inline-end)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled):hover{background:var(--element-base-1-hover)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled).active{background:var(--element-base-1-selected)}si-select-option+si-select-option:before{content:\",\\a0\"}.overflow-item{border-radius:var(--element-radius-3);background:var(--element-base-0);margin-inline-start:4px;padding-inline:8px}\n"] }]
213
- }], propDecorators: { baseId: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseId", required: true }] }], labelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelledby", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: true }] }], optionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionTemplate", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], openListbox: [{ type: i0.Output, args: ["openListbox"] }], blur: [{
214
- type: HostListener,
215
- args: ['blur']
216
- }], click: [{
217
- type: HostListener,
218
- args: ['click']
219
- }, {
220
- type: HostListener,
221
- args: ['keydown.arrowDown', ['$event']]
222
- }, {
223
- type: HostListener,
224
- args: ['keydown.alt.arrowDown', ['$event']]
225
- }, {
226
- type: HostListener,
227
- args: ['keydown.arrowUp', ['$event']]
228
- }, {
229
- type: HostListener,
230
- args: ['keydown.enter']
231
- }, {
232
- type: HostListener,
233
- args: ['keydown.space']
234
- }] } });
213
+ '[class.active]': 'open()',
214
+ '(blur)': 'blur()',
215
+ '(click)': 'click($event)',
216
+ '(keydown.arrowDown)': 'click($event)',
217
+ '(keydown.alt.arrowDown)': 'click($event)',
218
+ '(keydown.arrowUp)': 'click($event)',
219
+ '(keydown.enter)': 'click($event)',
220
+ '(keydown.space)': 'click($event)'
221
+ }, template: "@if (ariaLabel()) {\n <span class=\"visually-hidden\" [id]=\"baseId() + '-aria-label'\">{{ ariaLabel() }}</span>\n}\n<div\n class=\"d-flex align-items-center flex-fill overflow-hidden\"\n [id]=\"baseId() + '-content'\"\n [siAutoCollapsableList]=\"selectionStrategy.allowMultiple && selectedRows().length > 1\"\n>\n @for (activeOption of selectedRows(); track activeOption) {\n @if (activeOption) {\n <si-select-option\n siAutoCollapsableListItem\n [option]=\"activeOption\"\n [optionTemplate]=\"optionTemplate()\"\n [class.overflow-hidden]=\"!selectionStrategy.allowMultiple || $count === 1\"\n />\n }\n } @empty {\n <div class=\"text-secondary\">{{ placeholder() | translate }}</div>\n }\n @if (selectionStrategy.allowMultiple) {\n <div #overflowItem=\"siAutoCollapsableListOverflowItem\" siAutoCollapsableListOverflowItem>\n <div class=\"pill py-0 ms-2\"> {{ overflowItem.hiddenItemCount }}+</div>\n </div>\n }\n</div>\n<div class=\"form-control-actions\">\n <si-icon\n class=\"dropdown-caret icon flip-rtl ps-0 m-0\"\n [class.text-muted]=\"readonly()\"\n [icon]=\"icons.elementDown2\"\n />\n</div>\n", styles: ["@charset \"UTF-8\";:host{cursor:pointer;font-weight:600;min-inline-size:72px;block-size:100%;color:var(--element-text-primary);padding-block:7px;padding-inline-end:calc(3px + var(--si-feedback-icon-offset, 0px))}:host.disabled{color:var(--element-text-disabled)}:host-context(.form-control) :host{font-weight:400;padding-block:3px;padding-inline-end:var(--si-input-padding-inline-end)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled):hover{background:var(--element-base-1-hover)}:host-context(.dropdown:not(.form-control)) :host:not(.disabled).active{background:var(--element-base-1-selected)}si-select-option+si-select-option:before{content:\",\\a0\"}\n"] }]
222
+ }], propDecorators: { baseId: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseId", required: true }] }], labelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelledby", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: true }] }], optionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionTemplate", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], openListbox: [{ type: i0.Output, args: ["openListbox"] }] } });
235
223
 
236
224
  /**
237
225
  * Copyright (c) Siemens 2016 - 2026
@@ -351,22 +339,18 @@ class SiSelectListBase {
351
339
  }
352
340
  }
353
341
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectListBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
354
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.8", type: SiSelectListBase, isStandalone: true, inputs: { baseId: { classPropertyName: "baseId", publicName: "baseId", isSignal: true, isRequired: true, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupTemplate: { classPropertyName: "groupTemplate", publicName: "groupTemplate", isSignal: true, isRequired: false, transformFunction: null }, labelledby: { classPropertyName: "labelledby", publicName: "labelledby", isSignal: true, isRequired: false, transformFunction: null }, actionsTemplate: { classPropertyName: "actionsTemplate", publicName: "actionsTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeOverlay: "closeOverlay" }, host: { listeners: { "keydown.tab": "keydownTab()" }, properties: { "class.si-multi-select": "this.multiSelect" }, classAttribute: "dropdown-menu position-static w-100 py-4 d-flex flex-column" }, ngImport: i0 });
342
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.8", type: SiSelectListBase, isStandalone: true, inputs: { baseId: { classPropertyName: "baseId", publicName: "baseId", isSignal: true, isRequired: true, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, groupTemplate: { classPropertyName: "groupTemplate", publicName: "groupTemplate", isSignal: true, isRequired: false, transformFunction: null }, labelledby: { classPropertyName: "labelledby", publicName: "labelledby", isSignal: true, isRequired: false, transformFunction: null }, actionsTemplate: { classPropertyName: "actionsTemplate", publicName: "actionsTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeOverlay: "closeOverlay" }, host: { listeners: { "keydown.tab": "keydownTab()" }, properties: { "class.si-multi-select": "multiSelect" }, classAttribute: "dropdown-menu position-static w-100 py-4 d-flex flex-column" }, ngImport: i0 });
355
343
  }
356
344
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectListBase, decorators: [{
357
345
  type: Directive,
358
346
  args: [{
359
347
  host: {
360
- class: 'dropdown-menu position-static w-100 py-4 d-flex flex-column'
348
+ class: 'dropdown-menu position-static w-100 py-4 d-flex flex-column',
349
+ '[class.si-multi-select]': 'multiSelect',
350
+ '(keydown.tab)': 'keydownTab()'
361
351
  }
362
352
  }]
363
- }], propDecorators: { baseId: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseId", required: true }] }], optionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionTemplate", required: false }] }], groupTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupTemplate", required: false }] }], labelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelledby", required: false }] }], actionsTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsTemplate", required: false }] }], closeOverlay: [{ type: i0.Output, args: ["closeOverlay"] }], multiSelect: [{
364
- type: HostBinding,
365
- args: ['class.si-multi-select']
366
- }], keydownTab: [{
367
- type: HostListener,
368
- args: ['keydown.tab']
369
- }] } });
353
+ }], propDecorators: { baseId: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseId", required: true }] }], optionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionTemplate", required: false }] }], groupTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupTemplate", required: false }] }], labelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelledby", required: false }] }], actionsTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsTemplate", required: false }] }], closeOverlay: [{ type: i0.Output, args: ["closeOverlay"] }] } });
370
354
 
371
355
  /**
372
356
  * Copyright (c) Siemens 2016 - 2026
@@ -417,7 +401,7 @@ class SiSelectListHasFilterComponent extends SiSelectListBase {
417
401
  this.closeOverlayIfSingle();
418
402
  }
419
403
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectListHasFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
420
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSelectListHasFilterComponent, isStandalone: true, selector: "si-select-list-has-filter", inputs: { filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: true, transformFunction: null }, noResultsFoundLabel: { classPropertyName: "noResultsFoundLabel", publicName: "noResultsFoundLabel", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.id": "id()" }, classAttribute: "pt-0" }, viewQueries: [{ propertyName: "filterInput", first: true, predicate: ["filter"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"pt-5 pb-5 px-5 top-0\">\n <div class=\"position-relative\">\n <input\n #filter\n #siAutocomplete=\"siAutocomplete\"\n siAutocomplete\n class=\"form-control ps-9 border-0 rounded-2 bg-base-0\"\n [placeholder]=\"filterPlaceholder() | translate\"\n [id]=\"baseId() + 'filter-input'\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (input)=\"input()\"\n />\n <si-icon\n class=\"icon text-secondary position-absolute top-0 bottom-0 d-flex align-items-center ps-2\"\n [icon]=\"icons.elementSearch\"\n />\n @if (selectOptions.loading?.()) {\n <si-loading-spinner class=\"position-absolute end-0 bottom-0 d-flex align-items-center p-2\" />\n }\n </div>\n</div>\n<div\n class=\"si-select-filtered-items\"\n tabindex=\"-1\"\n [siAutocompleteListboxFor]=\"siAutocomplete\"\n [siAutocompleteDefaultIndex]=\"initIndex()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (siAutocompleteOptionSubmitted)=\"select($event)\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <div class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n } @empty {\n <div\n role=\"option\"\n aria-disabled=\"true\"\n aria-selected=\"false\"\n class=\"dropdown-item disabled text-secondary justify-content-center mb-2\"\n >\n <span>{{ noResultsFoundLabel() | translate }}</span>\n </div>\n }\n\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [siAutocompleteOption]=\"option.value\"\n [disabled]=\"option.disabled\"\n [selected]=\"selectionStrategy.arrayValue().includes(option.value)\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container\n [ngTemplateOutlet]=\"actionsTemplate()!\"\n [ngTemplateOutletContext]=\"{\n searchText: filter.value,\n visibleOptionsCount: rows().length\n }\"\n />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n", styles: [".si-select-filtered-items{max-block-size:min(100vh - 56px,266px);overflow-y:auto}si-loading-spinner{--loading-spinner-size: 1.25rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: SiAutocompleteDirective, selector: "input[siAutocomplete]", exportAs: ["siAutocomplete"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "directive", type: SiSelectGroupTemplateDirective, selector: "[siSelectGroupTemplate]" }, { kind: "component", type: SiSelectOptionRowComponent, selector: "si-select-option-row", inputs: ["option", "optionTemplate", "selected"] }, { kind: "directive", type: SiSelectOptionRowTemplateDirective, selector: "[siSelectOptionRowTemplate]" }, { kind: "ngmodule", type: SiAutocompleteModule }, { kind: "directive", type: i1$1.SiAutocompleteListboxDirective, selector: "[siAutocompleteListboxFor]", inputs: ["id", "siAutocompleteListboxFor", "siAutocompleteDefaultIndex"], outputs: ["siAutocompleteOptionSubmitted"], exportAs: ["siAutocompleteListbox"] }, { kind: "directive", type: i1$1.SiAutocompleteOptionDirective, selector: "[siAutocompleteOption]", inputs: ["id", "disabled", "siAutocompleteOption"], exportAs: ["siAutocompleteOption"] }, { kind: "component", type: SiLoadingSpinnerComponent, selector: "si-loading-spinner", inputs: ["isBlockingSpinner", "isSpinnerOverlay", "ariaLabel"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
404
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSelectListHasFilterComponent, isStandalone: true, selector: "si-select-list-has-filter", inputs: { filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: true, transformFunction: null }, noResultsFoundLabel: { classPropertyName: "noResultsFoundLabel", publicName: "noResultsFoundLabel", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.id": "id()" }, classAttribute: "pt-0" }, viewQueries: [{ propertyName: "filterInput", first: true, predicate: ["filter"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"pt-5 pb-5 px-5 top-0\">\n <div class=\"position-relative\">\n <input\n #filter\n #siAutocomplete=\"siAutocomplete\"\n siAutocomplete\n class=\"form-control icon-start border-0 rounded-2 bg-base-0\"\n [placeholder]=\"filterPlaceholder() | translate\"\n [id]=\"baseId() + 'filter-input'\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (input)=\"input()\"\n />\n <si-icon\n class=\"icon text-secondary position-absolute top-0 bottom-0 d-flex align-items-center ps-2\"\n [icon]=\"icons.elementSearch\"\n />\n @if (selectOptions.loading?.()) {\n <si-loading-spinner class=\"position-absolute end-0 bottom-0 d-flex align-items-center p-2\" />\n }\n </div>\n</div>\n<div\n class=\"si-select-filtered-items\"\n tabindex=\"-1\"\n [siAutocompleteListboxFor]=\"siAutocomplete\"\n [siAutocompleteDefaultIndex]=\"initIndex()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (siAutocompleteOptionSubmitted)=\"select($event)\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <div class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n } @empty {\n <div\n role=\"option\"\n aria-disabled=\"true\"\n aria-selected=\"false\"\n class=\"dropdown-item disabled text-secondary justify-content-center mb-2\"\n >\n <span>{{ noResultsFoundLabel() | translate }}</span>\n </div>\n }\n\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [siAutocompleteOption]=\"option.value\"\n [disabled]=\"option.disabled\"\n [selected]=\"selectionStrategy.arrayValue().includes(option.value)\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container\n [ngTemplateOutlet]=\"actionsTemplate()!\"\n [ngTemplateOutletContext]=\"{\n searchText: filter.value,\n visibleOptionsCount: rows().length\n }\"\n />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n", styles: [".si-select-filtered-items{max-block-size:min(100vh - 56px,266px);overflow-y:auto}si-loading-spinner{--loading-spinner-size: 1.25rem}.icon-start{padding-inline-start:calc(1.25rem + 12px)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: SiAutocompleteDirective, selector: "input[siAutocomplete]", exportAs: ["siAutocomplete"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "directive", type: SiSelectGroupTemplateDirective, selector: "[siSelectGroupTemplate]" }, { kind: "component", type: SiSelectOptionRowComponent, selector: "si-select-option-row", inputs: ["option", "optionTemplate", "selected"] }, { kind: "directive", type: SiSelectOptionRowTemplateDirective, selector: "[siSelectOptionRowTemplate]" }, { kind: "ngmodule", type: SiAutocompleteModule }, { kind: "directive", type: i1$1.SiAutocompleteListboxDirective, selector: "[siAutocompleteListboxFor]", inputs: ["id", "siAutocompleteListboxFor", "siAutocompleteDefaultIndex"], outputs: ["siAutocompleteOptionSubmitted"], exportAs: ["siAutocompleteListbox"] }, { kind: "directive", type: i1$1.SiAutocompleteOptionDirective, selector: "[siAutocompleteOption]", inputs: ["id", "disabled", "siAutocompleteOption"], exportAs: ["siAutocompleteOption"] }, { kind: "component", type: SiLoadingSpinnerComponent, selector: "si-loading-spinner", inputs: ["isBlockingSpinner", "isSpinnerOverlay", "ariaLabel"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
421
405
  }
422
406
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectListHasFilterComponent, decorators: [{
423
407
  type: Component,
@@ -434,7 +418,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
434
418
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
435
419
  class: 'pt-0',
436
420
  '[attr.id]': 'id()'
437
- }, template: "<div class=\"pt-5 pb-5 px-5 top-0\">\n <div class=\"position-relative\">\n <input\n #filter\n #siAutocomplete=\"siAutocomplete\"\n siAutocomplete\n class=\"form-control ps-9 border-0 rounded-2 bg-base-0\"\n [placeholder]=\"filterPlaceholder() | translate\"\n [id]=\"baseId() + 'filter-input'\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (input)=\"input()\"\n />\n <si-icon\n class=\"icon text-secondary position-absolute top-0 bottom-0 d-flex align-items-center ps-2\"\n [icon]=\"icons.elementSearch\"\n />\n @if (selectOptions.loading?.()) {\n <si-loading-spinner class=\"position-absolute end-0 bottom-0 d-flex align-items-center p-2\" />\n }\n </div>\n</div>\n<div\n class=\"si-select-filtered-items\"\n tabindex=\"-1\"\n [siAutocompleteListboxFor]=\"siAutocomplete\"\n [siAutocompleteDefaultIndex]=\"initIndex()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (siAutocompleteOptionSubmitted)=\"select($event)\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <div class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n } @empty {\n <div\n role=\"option\"\n aria-disabled=\"true\"\n aria-selected=\"false\"\n class=\"dropdown-item disabled text-secondary justify-content-center mb-2\"\n >\n <span>{{ noResultsFoundLabel() | translate }}</span>\n </div>\n }\n\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [siAutocompleteOption]=\"option.value\"\n [disabled]=\"option.disabled\"\n [selected]=\"selectionStrategy.arrayValue().includes(option.value)\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container\n [ngTemplateOutlet]=\"actionsTemplate()!\"\n [ngTemplateOutletContext]=\"{\n searchText: filter.value,\n visibleOptionsCount: rows().length\n }\"\n />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n", styles: [".si-select-filtered-items{max-block-size:min(100vh - 56px,266px);overflow-y:auto}si-loading-spinner{--loading-spinner-size: 1.25rem}\n"] }]
421
+ }, template: "<div class=\"pt-5 pb-5 px-5 top-0\">\n <div class=\"position-relative\">\n <input\n #filter\n #siAutocomplete=\"siAutocomplete\"\n siAutocomplete\n class=\"form-control icon-start border-0 rounded-2 bg-base-0\"\n [placeholder]=\"filterPlaceholder() | translate\"\n [id]=\"baseId() + 'filter-input'\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (input)=\"input()\"\n />\n <si-icon\n class=\"icon text-secondary position-absolute top-0 bottom-0 d-flex align-items-center ps-2\"\n [icon]=\"icons.elementSearch\"\n />\n @if (selectOptions.loading?.()) {\n <si-loading-spinner class=\"position-absolute end-0 bottom-0 d-flex align-items-center p-2\" />\n }\n </div>\n</div>\n<div\n class=\"si-select-filtered-items\"\n tabindex=\"-1\"\n [siAutocompleteListboxFor]=\"siAutocomplete\"\n [siAutocompleteDefaultIndex]=\"initIndex()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (siAutocompleteOptionSubmitted)=\"select($event)\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <div class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </div>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n } @empty {\n <div\n role=\"option\"\n aria-disabled=\"true\"\n aria-selected=\"false\"\n class=\"dropdown-item disabled text-secondary justify-content-center mb-2\"\n >\n <span>{{ noResultsFoundLabel() | translate }}</span>\n </div>\n }\n\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [siAutocompleteOption]=\"option.value\"\n [disabled]=\"option.disabled\"\n [selected]=\"selectionStrategy.arrayValue().includes(option.value)\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container\n [ngTemplateOutlet]=\"actionsTemplate()!\"\n [ngTemplateOutletContext]=\"{\n searchText: filter.value,\n visibleOptionsCount: rows().length\n }\"\n />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n", styles: [".si-select-filtered-items{max-block-size:min(100vh - 56px,266px);overflow-y:auto}si-loading-spinner{--loading-spinner-size: 1.25rem}.icon-start{padding-inline-start:calc(1.25rem + 12px)}\n"] }]
438
422
  }], ctorParameters: () => [], propDecorators: { filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: true }] }], noResultsFoundLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "noResultsFoundLabel", required: true }] }], filterInput: [{ type: i0.ViewChild, args: ['filter', { isSignal: true }] }] } });
439
423
 
440
424
  /**
@@ -453,7 +437,7 @@ class SiSelectListComponent extends SiSelectListBase {
453
437
  this.selectionStrategy.updateFromUser(changeEvent.value.slice());
454
438
  }
455
439
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
456
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSelectListComponent, isStandalone: true, selector: "si-select-list", viewQueries: [{ propertyName: "listbox", first: true, predicate: CdkListbox, descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n cdkListbox\n class=\"si-select-filtered-items focus-none\"\n [id]=\"baseId() + '-listbox'\"\n [cdkListboxMultiple]=\"selectionStrategy.allowMultiple\"\n [cdkListboxValue]=\"selectionStrategy.arrayValue()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (cdkListboxValueChange)=\"listBoxValueChange($event)\"\n (click)=\"closeOverlayIfSingle()\"\n (keydown.enter)=\"closeOverlayIfSingle()\"\n (keydown.space)=\"closeOverlayIfSingle()\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <span class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </span>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n }\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n #cdkOption=\"cdkOption\"\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [cdkOption]=\"option.value\"\n [cdkOptionDisabled]=\"!!option.disabled\"\n [cdkOptionTypeaheadLabel]=\"(option.typeaheadLabel | translate)!\"\n [class.active]=\"cdkOption.isActive()\"\n [selected]=\"cdkOption.isSelected()\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container [ngTemplateOutlet]=\"actionsTemplate()!\" />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n", styles: [".si-select-filtered-items{max-block-size:min(100vh,266px);overflow-y:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkListbox, selector: "[cdkListbox]", inputs: ["id", "tabindex", "cdkListboxValue", "cdkListboxMultiple", "cdkListboxDisabled", "cdkListboxUseActiveDescendant", "cdkListboxOrientation", "cdkListboxCompareWith", "cdkListboxNavigationWrapDisabled", "cdkListboxNavigatesDisabledOptions"], outputs: ["cdkListboxValueChange"], exportAs: ["cdkListbox"] }, { kind: "directive", type: CdkOption, selector: "[cdkOption]", inputs: ["id", "cdkOption", "cdkOptionTypeaheadLabel", "cdkOptionDisabled", "tabindex"], exportAs: ["cdkOption"] }, { kind: "directive", type: SiSelectOptionRowTemplateDirective, selector: "[siSelectOptionRowTemplate]" }, { kind: "directive", type: SiSelectGroupTemplateDirective, selector: "[siSelectGroupTemplate]" }, { kind: "component", type: SiSelectOptionRowComponent, selector: "si-select-option-row", inputs: ["option", "optionTemplate", "selected"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
440
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSelectListComponent, isStandalone: true, selector: "si-select-list", viewQueries: [{ propertyName: "listbox", first: true, predicate: CdkListbox, descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n cdkListbox\n class=\"dropdown-menu-scroller focus-none\"\n [id]=\"baseId() + '-listbox'\"\n [cdkListboxMultiple]=\"selectionStrategy.allowMultiple\"\n [cdkListboxValue]=\"selectionStrategy.arrayValue()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (cdkListboxValueChange)=\"listBoxValueChange($event)\"\n (click)=\"closeOverlayIfSingle()\"\n (keydown.enter)=\"closeOverlayIfSingle()\"\n (keydown.space)=\"closeOverlayIfSingle()\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <span class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </span>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n }\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n #cdkOption=\"cdkOption\"\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [cdkOption]=\"option.value\"\n [cdkOptionDisabled]=\"!!option.disabled\"\n [cdkOptionTypeaheadLabel]=\"(option.typeaheadLabel | translate)!\"\n [class.active]=\"cdkOption.isActive()\"\n [selected]=\"cdkOption.isSelected()\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container [ngTemplateOutlet]=\"actionsTemplate()!\" />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkListbox, selector: "[cdkListbox]", inputs: ["id", "tabindex", "cdkListboxValue", "cdkListboxMultiple", "cdkListboxDisabled", "cdkListboxUseActiveDescendant", "cdkListboxOrientation", "cdkListboxCompareWith", "cdkListboxNavigationWrapDisabled", "cdkListboxNavigatesDisabledOptions"], outputs: ["cdkListboxValueChange"], exportAs: ["cdkListbox"] }, { kind: "directive", type: CdkOption, selector: "[cdkOption]", inputs: ["id", "cdkOption", "cdkOptionTypeaheadLabel", "cdkOptionDisabled", "tabindex"], exportAs: ["cdkOption"] }, { kind: "directive", type: SiSelectOptionRowTemplateDirective, selector: "[siSelectOptionRowTemplate]" }, { kind: "directive", type: SiSelectGroupTemplateDirective, selector: "[siSelectGroupTemplate]" }, { kind: "component", type: SiSelectOptionRowComponent, selector: "si-select-option-row", inputs: ["option", "optionTemplate", "selected"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
457
441
  }
458
442
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectListComponent, decorators: [{
459
443
  type: Component,
@@ -465,7 +449,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
465
449
  SiSelectOptionRowTemplateDirective,
466
450
  SiSelectGroupTemplateDirective,
467
451
  SiSelectOptionRowComponent
468
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n cdkListbox\n class=\"si-select-filtered-items focus-none\"\n [id]=\"baseId() + '-listbox'\"\n [cdkListboxMultiple]=\"selectionStrategy.allowMultiple\"\n [cdkListboxValue]=\"selectionStrategy.arrayValue()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (cdkListboxValueChange)=\"listBoxValueChange($event)\"\n (click)=\"closeOverlayIfSingle()\"\n (keydown.enter)=\"closeOverlayIfSingle()\"\n (keydown.space)=\"closeOverlayIfSingle()\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <span class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </span>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n }\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n #cdkOption=\"cdkOption\"\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [cdkOption]=\"option.value\"\n [cdkOptionDisabled]=\"!!option.disabled\"\n [cdkOptionTypeaheadLabel]=\"(option.typeaheadLabel | translate)!\"\n [class.active]=\"cdkOption.isActive()\"\n [selected]=\"cdkOption.isSelected()\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container [ngTemplateOutlet]=\"actionsTemplate()!\" />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n", styles: [".si-select-filtered-items{max-block-size:min(100vh,266px);overflow-y:auto}\n"] }]
452
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n cdkListbox\n class=\"dropdown-menu-scroller focus-none\"\n [id]=\"baseId() + '-listbox'\"\n [cdkListboxMultiple]=\"selectionStrategy.allowMultiple\"\n [cdkListboxValue]=\"selectionStrategy.arrayValue()\"\n [attr.aria-labelledby]=\"baseId() + '-aria-label' + ' ' + labelledby()\"\n (cdkListboxValueChange)=\"listBoxValueChange($event)\"\n (click)=\"closeOverlayIfSingle()\"\n (keydown.enter)=\"closeOverlayIfSingle()\"\n (keydown.space)=\"closeOverlayIfSingle()\"\n>\n @for (item of rows(); track item; let index = $index) {\n @if (item.type === 'group') {\n <div\n role=\"group\"\n class=\"ps-0\"\n aria-disabled=\"false\"\n [attr.aria-labelledby]=\"baseId() + '-' + index + '-group-header'\"\n >\n <span class=\"dropdown-header\" [id]=\"baseId() + '-' + index + '-group-header'\">\n <ng-container\n [ngTemplateOutlet]=\"groupTemplate() ?? defaultGroupTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n </span>\n @for (optionRow of item.options; track optionRow) {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: optionRow }\"\n />\n }\n </div>\n }\n @if (item.type === 'option') {\n <ng-container\n [ngTemplateOutlet]=\"optionRowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n />\n }\n }\n <ng-template #optionRowTemplate let-option siSelectOptionRowTemplate>\n <si-select-option-row\n #cdkOption=\"cdkOption\"\n [option]=\"option\"\n [optionTemplate]=\"optionTemplate()\"\n [cdkOption]=\"option.value\"\n [cdkOptionDisabled]=\"!!option.disabled\"\n [cdkOptionTypeaheadLabel]=\"(option.typeaheadLabel | translate)!\"\n [class.active]=\"cdkOption.isActive()\"\n [selected]=\"cdkOption.isSelected()\"\n />\n </ng-template>\n</div>\n@if (actionsTemplate()) {\n <div class=\"dropdown-divider\"></div>\n <div class=\"d-flex flex-column align-items-start\">\n <ng-container [ngTemplateOutlet]=\"actionsTemplate()!\" />\n </div>\n}\n\n<ng-template #defaultGroupTemplate let-group siSelectGroupTemplate>\n {{ group.label | translate }}\n</ng-template>\n" }]
469
453
  }], propDecorators: { listbox: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkListbox), { ...{
470
454
  read: ElementRef
471
455
  }, isSignal: true }] }] } });
@@ -959,14 +943,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
959
943
  args: [{
960
944
  selector: '[siSelectAction]',
961
945
  host: {
962
- class: 'mx-5 my-4'
946
+ class: 'mx-5 my-4',
947
+ '(click)': 'close()'
963
948
  },
964
949
  exportAs: 'si-select-action'
965
950
  }]
966
- }], propDecorators: { selectActionAutoClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectActionAutoClose", required: false }] }], close: [{
967
- type: HostListener,
968
- args: ['click']
969
- }] } });
951
+ }], propDecorators: { selectActionAutoClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectActionAutoClose", required: false }] }] } });
970
952
 
971
953
  /**
972
954
  * Copyright (c) Siemens 2016 - 2026
@@ -1017,6 +999,431 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
1017
999
  }]
1018
1000
  }] });
1019
1001
 
1002
+ /**
1003
+ * Copyright (c) Siemens 2016 - 2026
1004
+ * SPDX-License-Identifier: MIT
1005
+ */
1006
+ /**
1007
+ * Host directive for building custom selects.
1008
+ *
1009
+ * Add this as a `hostDirective` on your component and expose the inputs/outputs you need.
1010
+ * The directive handles:
1011
+ * - {@link ControlValueAccessor} integration (`formControl`, `ngModel`, `[(value)]`)
1012
+ * - Disabled / readonly state management
1013
+ * - Overlay lifecycle for the dropdown (open/close)
1014
+ * - Focus management and focus trapping in the dropdown
1015
+ * - Opening the dropdown on click, Enter, Space, ArrowDown, ArrowUp
1016
+ * - {@link SiFormItemControl} integration
1017
+ *
1018
+ * Use {@link SiSelectDropdownDirective} to mark the dropdown template in your component,
1019
+ * and call {@link open}, {@link close}, {@link updateValue} from your component logic.
1020
+ *
1021
+ * @example
1022
+ * ```ts
1023
+ * @Component({
1024
+ * selector: 'app-my-select',
1025
+ * hostDirectives: [{
1026
+ * directive: SiCustomSelectDirective,
1027
+ * inputs: ['disabled', 'readonly', 'value'],
1028
+ * outputs: ['valueChange']
1029
+ * }],
1030
+ * template: `
1031
+ * <si-select-combobox>
1032
+ * {{ select.value() }}
1033
+ * </si-select-combobox>
1034
+ * <ng-template si-select-dropdown contentType="listbox">
1035
+ * <button (click)="select.updateValue('new'); select.close()">Pick</button>
1036
+ * </ng-template>
1037
+ * `
1038
+ * })
1039
+ * export class MySelectComponent {
1040
+ * readonly select = inject(SiCustomSelectDirective);
1041
+ * }
1042
+ * ```
1043
+ *
1044
+ * @experimental
1045
+ */
1046
+ class SiCustomSelectDirective {
1047
+ static idCounter = 0;
1048
+ /**
1049
+ * Unique identifier.
1050
+ *
1051
+ * @defaultValue
1052
+ * ```
1053
+ * `__si-custom-select-${SiCustomSelectDirective.idCounter++}`
1054
+ * ```
1055
+ */
1056
+ id = input(`__si-custom-select-${SiCustomSelectDirective.idCounter++}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
1057
+ /**
1058
+ * Whether the select input is disabled.
1059
+ *
1060
+ * @defaultValue false
1061
+ */
1062
+ // eslint-disable-next-line @angular-eslint/no-input-rename
1063
+ disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : {}), alias: 'disabled', transform: booleanAttribute });
1064
+ /**
1065
+ * Readonly state. Similar to disabled but with higher contrast.
1066
+ *
1067
+ * @defaultValue false
1068
+ */
1069
+ readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : {}), transform: booleanAttribute });
1070
+ /** Emits when the dropdown open state changes. */
1071
+ openChange = output();
1072
+ /**
1073
+ * The current value, supports two-way binding via `[(value)]`.
1074
+ *
1075
+ * @defaultValue undefined
1076
+ */
1077
+ value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
1078
+ /**
1079
+ * Whether the dropdown is currently open.
1080
+ *
1081
+ * @defaultValue false
1082
+ */
1083
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1084
+ /** @internal */
1085
+ labelledby = computed(() => `${this.id()}-label ${this.id()}-combobox`, ...(ngDevMode ? [{ debugName: "labelledby" }] : []));
1086
+ /** @internal */
1087
+ comboboxLabelId = computed(() => `${this.id()}-combobox`, ...(ngDevMode ? [{ debugName: "comboboxLabelId" }] : []));
1088
+ /** @internal */
1089
+ dropdownId = computed(() => this.id() + '-dropdown', ...(ngDevMode ? [{ debugName: "dropdownId" }] : []));
1090
+ /**
1091
+ * Value forwarded to the `aria-haspopup` attribute. Reflects the
1092
+ * `contentType` input of the registered {@link SiSelectDropdownDirective},
1093
+ * defaulting to `'listbox'` until a dropdown template is registered.
1094
+ * @internal
1095
+ */
1096
+ haspopup = computed(() => this.dropdownDirective()?.contentType() ?? 'listbox', ...(ngDevMode ? [{ debugName: "haspopup" }] : []));
1097
+ /**
1098
+ * This ID will be bound to the `aria-describedby` attribute of the select.
1099
+ *
1100
+ * @defaultValue
1101
+ * ```
1102
+ * `${this.id()}-errormessage`
1103
+ * ```
1104
+ */
1105
+ errormessageId = input(`${this.id()}-errormessage`, ...(ngDevMode ? [{ debugName: "errormessageId" }] : []));
1106
+ /** Combined disabled state from input and form control. */
1107
+ disabled = computed(() => this.disabledInput() || this.disabledByForm(), ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1108
+ onTouched = () => { };
1109
+ onChange = () => { };
1110
+ disabledByForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledByForm" }] : []));
1111
+ overlay = inject(Overlay);
1112
+ focusTrapFactory = inject(ConfigurableFocusTrapFactory);
1113
+ elementRef = inject(ElementRef);
1114
+ viewContainerRef = inject(ViewContainerRef);
1115
+ destroyRef = inject(DestroyRef);
1116
+ isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
1117
+ overlayRef;
1118
+ focusTrap;
1119
+ closeOverlay$ = new Subject();
1120
+ dropdownDirective = signal(undefined, ...(ngDevMode ? [{ debugName: "dropdownDirective" }] : []));
1121
+ constructor() {
1122
+ this.destroyRef.onDestroy(() => {
1123
+ this.disposeOverlay();
1124
+ this.closeOverlay$.complete();
1125
+ });
1126
+ }
1127
+ /**
1128
+ * Registers the dropdown directive. Called by
1129
+ * {@link SiSelectDropdownDirective} when it is initialized.
1130
+ * @internal
1131
+ */
1132
+ registerDropdown(directive) {
1133
+ this.dropdownDirective.set(directive);
1134
+ }
1135
+ /**
1136
+ * Updates the value programmatically.
1137
+ * Call this from your dropdown template to set the new value.
1138
+ */
1139
+ updateValue(value) {
1140
+ this.value.set(value);
1141
+ this.onChange(value);
1142
+ }
1143
+ /** Opens the dropdown overlay. */
1144
+ open(event) {
1145
+ if (this.disabled() || this.readonly() || this.isOpen() || !this.isBrowser) {
1146
+ return;
1147
+ }
1148
+ if (!this.dropdownDirective()) {
1149
+ return;
1150
+ }
1151
+ // Prevent default scrolling behavior for Space / ArrowUp / ArrowDown.
1152
+ event?.preventDefault();
1153
+ const width = this.elementRef.nativeElement.getBoundingClientRect().width;
1154
+ this.overlayRef = this.overlay.create({
1155
+ positionStrategy: this.overlay
1156
+ .position()
1157
+ .flexibleConnectedTo(this.elementRef)
1158
+ .withPositions([
1159
+ // Preferred: below, aligned to the start edge of the trigger.
1160
+ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },
1161
+ // Below, aligned to the end edge (trigger near the end of the viewport).
1162
+ { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top' },
1163
+ // Above, aligned to the start edge (no space below).
1164
+ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' },
1165
+ // Above, aligned to the end edge (no space below, trigger near the end).
1166
+ { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom' },
1167
+ // Below, centered (small screens, trigger in the middle).
1168
+ { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top' },
1169
+ // Above, centered.
1170
+ { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom' }
1171
+ ])
1172
+ .withFlexibleDimensions(true)
1173
+ .withPush(true),
1174
+ hasBackdrop: true,
1175
+ backdropClass: 'cdk-overlay-transparent-backdrop',
1176
+ panelClass: ['dropdown-menu', 'show'],
1177
+ minWidth: width + 2
1178
+ });
1179
+ const portal = new TemplatePortal(this.dropdownDirective().templateRef, this.viewContainerRef);
1180
+ this.overlayRef.attach(portal);
1181
+ this.overlayRef.overlayElement.id = this.dropdownId();
1182
+ this.focusTrap = this.focusTrapFactory.create(this.overlayRef.overlayElement);
1183
+ this.focusTrap.focusFirstTabbableElementWhenReady();
1184
+ this.isOpen.set(true);
1185
+ this.openChange.emit(true);
1186
+ merge(this.overlayRef.backdropClick(), this.overlayRef.keydownEvents().pipe(filter(e => e.key === 'Escape')))
1187
+ .pipe(takeUntil$1(this.closeOverlay$), takeUntilDestroyed(this.destroyRef))
1188
+ .subscribe(() => this.close());
1189
+ }
1190
+ /** Closes the dropdown overlay and restores focus. */
1191
+ close() {
1192
+ if (!this.isOpen()) {
1193
+ return;
1194
+ }
1195
+ this.isOpen.set(false);
1196
+ this.disposeOverlay();
1197
+ this.openChange.emit(false);
1198
+ this.onTouched();
1199
+ if (this.isBrowser) {
1200
+ this.elementRef.nativeElement.focus();
1201
+ }
1202
+ }
1203
+ /** @internal */
1204
+ writeValue(obj) {
1205
+ this.value.set(obj ?? undefined);
1206
+ }
1207
+ /** @internal */
1208
+ registerOnChange(fn) {
1209
+ this.onChange = fn;
1210
+ }
1211
+ /** @internal */
1212
+ registerOnTouched(fn) {
1213
+ this.onTouched = fn;
1214
+ }
1215
+ /** @internal */
1216
+ setDisabledState(isDisabled) {
1217
+ this.disabledByForm.set(isDisabled);
1218
+ }
1219
+ disposeOverlay() {
1220
+ if (this.overlayRef) {
1221
+ this.closeOverlay$.next();
1222
+ this.focusTrap?.destroy();
1223
+ this.focusTrap = undefined;
1224
+ this.overlayRef.detach();
1225
+ this.overlayRef.dispose();
1226
+ this.overlayRef = undefined;
1227
+ }
1228
+ }
1229
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiCustomSelectDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1230
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.8", type: SiCustomSelectDirective, isStandalone: true, selector: "[siCustomSelect]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, errormessageId: { classPropertyName: "errormessageId", publicName: "errormessageId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openChange: "openChange", value: "valueChange" }, host: { attributes: { "role": "combobox", "aria-autocomplete": "none" }, listeners: { "click": "open()", "keydown.enter": "open()", "keydown.space": "open($event)", "keydown.arrowDown": "open($event)", "keydown.arrowUp": "open($event)" }, properties: { "style.--si-action-icon-offset.rem": "1.5", "attr.aria-haspopup": "haspopup()", "attr.aria-labelledby": "labelledby()", "attr.aria-describedby": "errormessageId()", "attr.aria-controls": "isOpen() ? dropdownId() : null", "attr.aria-expanded": "isOpen()", "attr.aria-disabled": "disabled()", "attr.id": "id()", "attr.tabindex": "disabled() ? \"-1\" : \"0\"", "class.disabled": "disabled()", "class.pe-none": "disabled()", "class.readonly": "readonly()", "class.open": "isOpen()", "class.show": "isOpen()" }, classAttribute: "dropdown" }, providers: [
1231
+ { provide: NG_VALUE_ACCESSOR, useExisting: SiCustomSelectDirective, multi: true },
1232
+ { provide: SI_FORM_ITEM_CONTROL, useExisting: SiCustomSelectDirective }
1233
+ ], ngImport: i0 });
1234
+ }
1235
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiCustomSelectDirective, decorators: [{
1236
+ type: Directive,
1237
+ args: [{
1238
+ selector: '[siCustomSelect]',
1239
+ providers: [
1240
+ { provide: NG_VALUE_ACCESSOR, useExisting: SiCustomSelectDirective, multi: true },
1241
+ { provide: SI_FORM_ITEM_CONTROL, useExisting: SiCustomSelectDirective }
1242
+ ],
1243
+ host: {
1244
+ class: 'dropdown',
1245
+ '[style.--si-action-icon-offset.rem]': '1.5',
1246
+ role: 'combobox',
1247
+ 'aria-autocomplete': 'none',
1248
+ '[attr.aria-haspopup]': 'haspopup()',
1249
+ '[attr.aria-labelledby]': 'labelledby()',
1250
+ '[attr.aria-describedby]': 'errormessageId()',
1251
+ '[attr.aria-controls]': 'isOpen() ? dropdownId() : null',
1252
+ '[attr.aria-expanded]': 'isOpen()',
1253
+ '[attr.aria-disabled]': 'disabled()',
1254
+ '[attr.id]': 'id()',
1255
+ '[attr.tabindex]': 'disabled() ? "-1" : "0"',
1256
+ '[class.disabled]': 'disabled()',
1257
+ '[class.pe-none]': 'disabled()',
1258
+ '[class.readonly]': 'readonly()',
1259
+ '[class.open]': 'isOpen()',
1260
+ '[class.show]': 'isOpen()',
1261
+ '(click)': 'open()',
1262
+ '(keydown.enter)': 'open()',
1263
+ '(keydown.space)': 'open($event)',
1264
+ '(keydown.arrowDown)': 'open($event)',
1265
+ '(keydown.arrowUp)': 'open($event)'
1266
+ }
1267
+ }]
1268
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], openChange: [{ type: i0.Output, args: ["openChange"] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], errormessageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "errormessageId", required: false }] }] } });
1269
+
1270
+ /**
1271
+ * Copyright (c) Siemens 2016 - 2026
1272
+ * SPDX-License-Identifier: MIT
1273
+ */
1274
+ /**
1275
+ * Visual trigger element for custom selects built with {@link SiCustomSelectDirective}.
1276
+ * Renders the projected content and a dropdown caret icon.
1277
+ *
1278
+ * The ARIA role, focus handling, and state attributes live on the host component
1279
+ * via {@link SiCustomSelectDirective} — this component is purely visual.
1280
+ *
1281
+ * @example
1282
+ * ```html
1283
+ * <si-select-combobox>
1284
+ * {{ select.value() }}
1285
+ * </si-select-combobox>
1286
+ * ```
1287
+ *
1288
+ * @experimental
1289
+ */
1290
+ class SiSelectComboboxComponent {
1291
+ icons = addIcons({ elementDown2 });
1292
+ customSelect = inject(SiCustomSelectDirective);
1293
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectComboboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1294
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.8", type: SiSelectComboboxComponent, isStandalone: true, selector: "si-select-combobox", host: { properties: { "attr.id": "customSelect.comboboxLabelId()", "class.show": "customSelect.isOpen()" }, classAttribute: "select focus-none dropdown-toggle d-flex align-items-center w-100" }, ngImport: i0, template: `
1295
+ <ng-content />
1296
+ <div class="form-control-actions ms-auto my-n4">
1297
+ <si-icon class="dropdown-caret icon flip-rtl p-0 m-0" [icon]="icons.elementDown2" />
1298
+ </div>
1299
+ `, isInline: true, styles: [":host-context(.form-control.dropdown) .dropdown-caret{margin-inline-end:calc((var(--si-feedback-icon-offset, 0px) + var(--si-action-icon-offset)) * -1)}.dropdown-caret{transform-origin:center}\n"], dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1300
+ }
1301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectComboboxComponent, decorators: [{
1302
+ type: Component,
1303
+ args: [{ selector: 'si-select-combobox', imports: [SiIconComponent], template: `
1304
+ <ng-content />
1305
+ <div class="form-control-actions ms-auto my-n4">
1306
+ <si-icon class="dropdown-caret icon flip-rtl p-0 m-0" [icon]="icons.elementDown2" />
1307
+ </div>
1308
+ `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1309
+ class: 'select focus-none dropdown-toggle d-flex align-items-center w-100',
1310
+ '[attr.id]': 'customSelect.comboboxLabelId()',
1311
+ '[class.show]': 'customSelect.isOpen()'
1312
+ }, styles: [":host-context(.form-control.dropdown) .dropdown-caret{margin-inline-end:calc((var(--si-feedback-icon-offset, 0px) + var(--si-action-icon-offset)) * -1)}.dropdown-caret{transform-origin:center}\n"] }]
1313
+ }] });
1314
+
1315
+ /**
1316
+ * Copyright (c) Siemens 2016 - 2026
1317
+ * SPDX-License-Identifier: MIT
1318
+ */
1319
+ /**
1320
+ * Represents a single selected value inside an {@link SiSelectComboboxComponent}.
1321
+ *
1322
+ * Project one `<si-select-combobox-value>` per selected entry. Optional
1323
+ * `icon`, `iconColor`, `stackedIcon` and `stackedIconColor` inputs mirror the
1324
+ * icon API of {@link SelectOption} and render an icon (with optional stacked
1325
+ * overlay) before the projected content.
1326
+ *
1327
+ * Add the `comma-separated` CSS class to render a comma between adjacent
1328
+ * values. Omit it when using chips, custom separators, or a single value.
1329
+ *
1330
+ * @example
1331
+ * ```html
1332
+ * <si-select-combobox>
1333
+ * <si-select-combobox-value
1334
+ * icon="element-face-happy"
1335
+ * iconColor="status-success"
1336
+ * >
1337
+ * {{ select.value() }}
1338
+ * </si-select-combobox-value>
1339
+ * </si-select-combobox>
1340
+ * ```
1341
+ *
1342
+ * @experimental
1343
+ */
1344
+ class SiSelectComboboxValueComponent {
1345
+ /** An optional icon rendered before the projected content. */
1346
+ icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
1347
+ /** Optional CSS color class applied to {@link icon}. */
1348
+ iconColor = input(...(ngDevMode ? [undefined, { debugName: "iconColor" }] : []));
1349
+ /** Optional secondary icon stacked on top of {@link icon}. */
1350
+ stackedIcon = input(...(ngDevMode ? [undefined, { debugName: "stackedIcon" }] : []));
1351
+ /** Optional CSS color class applied to {@link stackedIcon}. */
1352
+ stackedIconColor = input(...(ngDevMode ? [undefined, { debugName: "stackedIconColor" }] : []));
1353
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectComboboxValueComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1354
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiSelectComboboxValueComponent, isStandalone: true, selector: "si-select-combobox-value", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconColor: { classPropertyName: "iconColor", publicName: "iconColor", isSignal: true, isRequired: false, transformFunction: null }, stackedIcon: { classPropertyName: "stackedIcon", publicName: "stackedIcon", isSignal: true, isRequired: false, transformFunction: null }, stackedIconColor: { classPropertyName: "stackedIconColor", publicName: "stackedIconColor", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "text-nowrap" }, ngImport: i0, template: `
1355
+ @if (icon(); as iconName) {
1356
+ <div class="icon-stack icon me-2 my-n4">
1357
+ <si-icon [icon]="iconName" [class]="iconColor() ?? ''" />
1358
+ @if (stackedIcon(); as stackedIconName) {
1359
+ <si-icon [icon]="stackedIconName" [class]="stackedIconColor() ?? ''" />
1360
+ }
1361
+ </div>
1362
+ }
1363
+ <ng-content />
1364
+ `, isInline: true, styles: ["@charset \"UTF-8\";:host{display:inline-block;max-inline-size:100%}:host(.comma-separated:not(:first-of-type)):before{content:\",\\a0\"}\n"], dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1365
+ }
1366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectComboboxValueComponent, decorators: [{
1367
+ type: Component,
1368
+ args: [{ selector: 'si-select-combobox-value', imports: [SiIconComponent], template: `
1369
+ @if (icon(); as iconName) {
1370
+ <div class="icon-stack icon me-2 my-n4">
1371
+ <si-icon [icon]="iconName" [class]="iconColor() ?? ''" />
1372
+ @if (stackedIcon(); as stackedIconName) {
1373
+ <si-icon [icon]="stackedIconName" [class]="stackedIconColor() ?? ''" />
1374
+ }
1375
+ </div>
1376
+ }
1377
+ <ng-content />
1378
+ `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1379
+ class: 'text-nowrap'
1380
+ }, styles: ["@charset \"UTF-8\";:host{display:inline-block;max-inline-size:100%}:host(.comma-separated:not(:first-of-type)):before{content:\",\\a0\"}\n"] }]
1381
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconColor", required: false }] }], stackedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "stackedIcon", required: false }] }], stackedIconColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "stackedIconColor", required: false }] }] } });
1382
+
1383
+ /**
1384
+ * Copyright (c) Siemens 2016 - 2026
1385
+ * SPDX-License-Identifier: MIT
1386
+ */
1387
+ /**
1388
+ * Structural directive marking the dropdown template for custom selects
1389
+ * built with {@link SiCustomSelectDirective}.
1390
+ *
1391
+ * When placed on an `<ng-template>`, it automatically registers the template
1392
+ * with the parent {@link SiCustomSelectDirective}.
1393
+ *
1394
+ * @example
1395
+ * ```html
1396
+ * <ng-template si-select-dropdown contentType="listbox">
1397
+ * <!-- custom dropdown content -->
1398
+ * </ng-template>
1399
+ * ```
1400
+ *
1401
+ * @experimental
1402
+ */
1403
+ class SiSelectDropdownDirective {
1404
+ /**
1405
+ * Describes the kind of content rendered by the dropdown. The value is
1406
+ * forwarded to the `aria-haspopup` attribute of the combobox host of
1407
+ * the parent {@link SiCustomSelectDirective}.
1408
+ */
1409
+ contentType = input.required(...(ngDevMode ? [{ debugName: "contentType" }] : []));
1410
+ /** @internal */
1411
+ templateRef = inject(TemplateRef);
1412
+ constructor() {
1413
+ const customSelect = inject(SiCustomSelectDirective, { optional: true });
1414
+ customSelect?.registerDropdown(this);
1415
+ }
1416
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectDropdownDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1417
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.8", type: SiSelectDropdownDirective, isStandalone: true, selector: "[si-select-dropdown]", inputs: { contentType: { classPropertyName: "contentType", publicName: "contentType", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
1418
+ }
1419
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiSelectDropdownDirective, decorators: [{
1420
+ type: Directive,
1421
+ args: [{
1422
+ // eslint-disable-next-line @angular-eslint/directive-selector
1423
+ selector: '[si-select-dropdown]'
1424
+ }]
1425
+ }], ctorParameters: () => [], propDecorators: { contentType: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentType", required: true }] }] } });
1426
+
1020
1427
  /**
1021
1428
  * Copyright (c) Siemens 2016 - 2026
1022
1429
  * SPDX-License-Identifier: MIT
@@ -1026,5 +1433,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
1026
1433
  * Generated bundle index. Do not edit.
1027
1434
  */
1028
1435
 
1029
- export { SiSelectActionDirective, SiSelectActionsDirective, SiSelectComponent, SiSelectGroupTemplateDirective, SiSelectLazyOptionsDirective, SiSelectListHasFilterComponent, SiSelectModule, SiSelectMultiValueDirective, SiSelectOptionTemplateDirective, SiSelectSimpleOptionsDirective, SiSelectSingleValueDirective };
1436
+ export { SiCustomSelectDirective, SiSelectActionDirective, SiSelectActionsDirective, SiSelectComboboxComponent, SiSelectComboboxValueComponent, SiSelectComponent, SiSelectDropdownDirective, SiSelectGroupTemplateDirective, SiSelectLazyOptionsDirective, SiSelectListHasFilterComponent, SiSelectModule, SiSelectMultiValueDirective, SiSelectOptionTemplateDirective, SiSelectSimpleOptionsDirective, SiSelectSingleValueDirective };
1030
1437
  //# sourceMappingURL=siemens-element-ng-select.mjs.map