@i-cell/ids-angular 0.2.16 → 0.2.18

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.
@@ -1,11 +1,19 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, signal, ChangeDetectionStrategy, ViewEncapsulation, Component, InjectionToken, Directive, input, contentChildren, computed, inject, Injector, effect, booleanAttribute, Input, ElementRef, ChangeDetectorRef, viewChild, contentChild, isDevMode, output } from '@angular/core';
3
- import { ComponentBase, IdsSize, ComponentBaseWithDefaults, coerceBooleanAttribute } from '@i-cell/ids-angular/core';
4
- import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
5
- import { NgForm, FormGroupDirective, NgControl, Validators, StatusChangeEvent } from '@angular/forms';
6
- import { Subject, observeOn, asapScheduler, tap, switchMap, of, startWith } from 'rxjs';
2
+ import { Injectable, InjectionToken, inject, input, computed, ChangeDetectionStrategy, ViewEncapsulation, Component, ElementRef, viewChild, signal, output, effect, Directive, Injector, booleanAttribute, Input, contentChildren, ChangeDetectorRef, contentChild, isDevMode, viewChildren, model, untracked, forwardRef } from '@angular/core';
3
+ import { ComponentBase, coerceBooleanAttribute, ComponentBaseWithDefaults, IdsSize, coerceNumberAttribute } from '@i-cell/ids-angular/core';
7
4
  import { IdsIconComponent } from '@i-cell/ids-angular/icon';
8
5
  import { hasModifierKey } from '@angular/cdk/keycodes';
6
+ import { takeUntilDestroyed, toObservable, rxResource } from '@angular/core/rxjs-interop';
7
+ import * as i1 from '@angular/forms';
8
+ import { NgForm, FormGroupDirective, NgControl, Validators, StatusChangeEvent, ValueChangeEvent, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
9
+ import { Subject, observeOn, asapScheduler, tap, switchMap, of, startWith, filter } from 'rxjs';
10
+ import { LiveAnnouncer, ActiveDescendantKeyManager } from '@angular/cdk/a11y';
11
+ import { SelectionModel } from '@angular/cdk/collections';
12
+ import { CdkOverlayOrigin } from '@angular/cdk/overlay';
13
+ import { IdsIconButtonComponent } from '@i-cell/ids-angular/icon-button';
14
+ import { IdsOverlayPanelComponent } from '@i-cell/ids-angular/overlay-panel';
15
+ import { IdsSpinnerComponent } from '@i-cell/ids-angular/spinner';
16
+ import { IdsTooltipDirective } from '@i-cell/ids-angular/tooltip';
9
17
 
10
18
  class AbstractErrorStateMatcher {
11
19
  }
@@ -81,77 +89,228 @@ class SuccessStateTracker {
81
89
  }
82
90
  }
83
91
 
84
- class IdsFieldsetRowComponent extends ComponentBase {
85
- constructor() {
86
- super(...arguments);
87
- this._hostClasses = signal(this._getHostClasses([]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
88
- }
89
- get _hostName() {
90
- return 'fieldset-row';
92
+ const IDS_AUTOCOMPLETE_DEFAULT_CONFIG = new InjectionToken('IDS_AUTOCOMPLETE_DEFAULT_CONFIG', {
93
+ providedIn: 'root',
94
+ factory: IDS_AUTOCOMPLETE_DEFAULT_CONFIG_FACTORY,
95
+ });
96
+ function IDS_AUTOCOMPLETE_DEFAULT_CONFIG_FACTORY() {
97
+ return {
98
+ minChars: 1,
99
+ hintLoading: 'Loading...',
100
+ hintNoResults: 'No results found',
101
+ hintMinChars: 'Please provide at least 1 characters',
102
+ hintMaxLength: 'Too many results, please refine your search',
103
+ typeaheadDebounceInterval: 300,
104
+ };
105
+ }
106
+
107
+ const IDS_AUTOCOMPLETE_LOADER = new InjectionToken('IDS_AUTOCOMPLETE_LOADER');
108
+
109
+ const IDS_OPTION_GROUP = new InjectionToken('IdsOptionGroup');
110
+
111
+ const IDS_OPTION_PARENT_COMPONENT = new InjectionToken('IDS_OPTION_PARENT_COMPONENT');
112
+
113
+ class IdsOptionSelectionChange {
114
+ constructor(source, selected, isUserInput = false) {
115
+ this.source = source;
116
+ this.selected = selected;
117
+ this.isUserInput = isUserInput;
91
118
  }
92
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetRowComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
93
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: IdsFieldsetRowComponent, isStandalone: true, selector: "ids-fieldset-row", usesInheritance: true, ngImport: i0, template: "<ng-content />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
94
119
  }
95
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetRowComponent, decorators: [{
96
- type: Component,
97
- args: [{ selector: 'ids-fieldset-row', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n" }]
98
- }] });
99
120
 
100
121
  const IdsFormFieldVariant = {
101
122
  SURFACE: 'surface',
102
123
  LIGHT: 'light',
103
124
  };
104
125
 
105
- const IDS_FIELDSET_DEFAULT_CONFIG = new InjectionToken('IDS_FIELDSET_DEFAULT_CONFIG', {
106
- providedIn: 'root',
107
- factory: IDS_FIELDSET_DEFAULT_CONFIG_FACTORY,
108
- });
109
- function IDS_FIELDSET_DEFAULT_CONFIG_FACTORY() {
110
- return {
111
- size: IdsSize.COMPACT,
112
- variant: IdsFormFieldVariant.SURFACE,
113
- };
114
- }
126
+ const IDS_PSEUDO_CHECKBOX_PARENT = new InjectionToken('IDS_PSEUDO_CHECKBOX_PARENT');
115
127
 
116
- class IdsFieldsetMessageDirective {
117
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetMessageDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
118
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.7", type: IdsFieldsetMessageDirective, isStandalone: true, selector: "[idsFieldsetMessage]", ngImport: i0 }); }
128
+ const IdsPseudoCheckboxState = {
129
+ UNCHECKED: 'unchecked',
130
+ CHECKED: 'checked',
131
+ INDETERMINATE: 'indeterminate',
132
+ };
133
+
134
+ class PseudoCheckboxComponent extends ComponentBase {
135
+ constructor() {
136
+ super(...arguments);
137
+ this._parent = inject(IDS_PSEUDO_CHECKBOX_PARENT, { optional: true });
138
+ this.checkboxState = input(IdsPseudoCheckboxState.UNCHECKED, ...(ngDevMode ? [{ debugName: "checkboxState" }] : []));
139
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: coerceBooleanAttribute }] : [{ transform: coerceBooleanAttribute }]));
140
+ this._isChecked = computed(() => this.checkboxState() === IdsPseudoCheckboxState.CHECKED, ...(ngDevMode ? [{ debugName: "_isChecked" }] : []));
141
+ this._isIndeterminate = computed(() => this.checkboxState() === IdsPseudoCheckboxState.INDETERMINATE, ...(ngDevMode ? [{ debugName: "_isIndeterminate" }] : []));
142
+ this._hostClasses = computed(() => this._getHostClasses([
143
+ this._parent?.embeddedPseudoCheckboxSize(),
144
+ this._parent?.embeddedPseudoCheckboxVariant(),
145
+ this.disabled() ? 'disabled' : null,
146
+ ]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
147
+ }
148
+ get _hostName() {
149
+ return 'pseudo-checkbox';
150
+ }
151
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: PseudoCheckboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
152
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: PseudoCheckboxComponent, isStandalone: true, selector: "ids-pseudo-checkbox", inputs: { checkboxState: { classPropertyName: "checkboxState", publicName: "checkboxState", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div class=\"ids-pseudo-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [disabled]=\"disabled()\"\n [attr.aria-checked]=\"_isIndeterminate() ? 'mixed' : null\"\n [checked]=\"_isChecked()\"\n [indeterminate]=\"_isIndeterminate()\"\n (change)=\"$event.stopPropagation()\"\n />\n <div class=\"ids-pseudo-checkbox__icon\" aria-hidden=\"true\">\n @if (_isIndeterminate()) {\n <ids-icon fontIcon=\"remove\" aria-hidden=\"true\" />\n }\n @if (_isChecked()) {\n <ids-icon fontIcon=\"done\" aria-hidden=\"true\" />\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: IdsIconComponent, selector: "ids-icon", inputs: ["size", "sizeCollection", "variant", "fontIcon", "svgIcon", "aria-hidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
119
153
  }
120
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetMessageDirective, decorators: [{
121
- type: Directive,
122
- args: [{
123
- selector: '[idsFieldsetMessage]',
124
- standalone: true,
125
- }]
154
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: PseudoCheckboxComponent, decorators: [{
155
+ type: Component,
156
+ args: [{ selector: 'ids-pseudo-checkbox', imports: [IdsIconComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ids-pseudo-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [disabled]=\"disabled()\"\n [attr.aria-checked]=\"_isIndeterminate() ? 'mixed' : null\"\n [checked]=\"_isChecked()\"\n [indeterminate]=\"_isIndeterminate()\"\n (change)=\"$event.stopPropagation()\"\n />\n <div class=\"ids-pseudo-checkbox__icon\" aria-hidden=\"true\">\n @if (_isIndeterminate()) {\n <ids-icon fontIcon=\"remove\" aria-hidden=\"true\" />\n }\n @if (_isChecked()) {\n <ids-icon fontIcon=\"done\" aria-hidden=\"true\" />\n }\n </div>\n</div>\n" }]
126
157
  }] });
127
158
 
128
- const defaultConfig$3 = IDS_FIELDSET_DEFAULT_CONFIG_FACTORY();
129
- class IdsFieldsetComponent extends ComponentBaseWithDefaults {
159
+ class IdsOptionComponent extends ComponentBase {
160
+ get _hostName() {
161
+ return 'option';
162
+ }
130
163
  constructor() {
131
- super(...arguments);
132
- this._defaultConfig = this._getDefaultConfig(defaultConfig$3, IDS_FIELDSET_DEFAULT_CONFIG);
133
- this.size = input(this._defaultConfig.size, ...(ngDevMode ? [{ debugName: "size" }] : []));
134
- this.variant = input(this._defaultConfig.variant, ...(ngDevMode ? [{ debugName: "variant" }] : []));
135
- this.legend = input('', ...(ngDevMode ? [{ debugName: "legend" }] : []));
136
- this._fieldsetMessage = contentChildren(IdsFieldsetMessageDirective, ...(ngDevMode ? [{ debugName: "_fieldsetMessage" }] : []));
137
- this._hasMessage = computed(() => this._fieldsetMessage().length > 0, ...(ngDevMode ? [{ debugName: "_hasMessage" }] : []));
164
+ super();
165
+ this._parent = inject(IDS_OPTION_PARENT_COMPONENT);
166
+ this._element = inject(ElementRef);
167
+ this.group = inject(IDS_OPTION_GROUP, { optional: true });
168
+ this._textElement = viewChild.required('text');
169
+ this.selected = signal(false, ...(ngDevMode ? [{ debugName: "selected" }] : []));
170
+ this._active = signal(false, ...(ngDevMode ? [{ debugName: "_active" }] : []));
171
+ this.size = computed(() => this._parent.parentSize(), ...(ngDevMode ? [{ debugName: "size" }] : []));
172
+ this.variant = computed(() => this._parent.parentVariant(), ...(ngDevMode ? [{ debugName: "variant" }] : []));
173
+ this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
174
+ this.explicitViewValue = input(null, ...(ngDevMode ? [{ debugName: "explicitViewValue", alias: 'viewValue' }] : [{ alias: 'viewValue' }]));
175
+ this.disabledInput = input(false, ...(ngDevMode ? [{ debugName: "disabledInput", alias: 'disabled', transform: coerceBooleanAttribute }] : [{ alias: 'disabled', transform: coerceBooleanAttribute }]));
176
+ this.disabled = false; // Do not delete this class member, until ListKeyManagerOption requires: `disabled: boolean`
177
+ this._groupOrOptionIsDisabled = computed(() => this.group?.disabled() || this.disabledInput(), ...(ngDevMode ? [{ debugName: "_groupOrOptionIsDisabled" }] : []));
178
+ this._multiSelect = Boolean(this._parent?.multiSelect());
179
+ // eslint-disable-next-line @angular-eslint/no-output-on-prefix
180
+ this.onSelectionChange = output();
181
+ this.viewValue = computed(() => this._textElement().nativeElement.textContent || this.explicitViewValue() || '', ...(ngDevMode ? [{ debugName: "viewValue" }] : []));
138
182
  this._hostClasses = computed(() => this._getHostClasses([
183
+ this.selected() ? 'selected' : null,
184
+ this._active() ? 'active' : null,
185
+ this._groupOrOptionIsDisabled() ? 'disabled' : null,
186
+ this._multiSelect ? 'multiselect' : null,
139
187
  this.size(),
140
188
  this.variant(),
141
189
  ]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
190
+ this._pseudoCheckboxState = computed(() => (this.selected() ? IdsPseudoCheckboxState.CHECKED : IdsPseudoCheckboxState.UNCHECKED), ...(ngDevMode ? [{ debugName: "_pseudoCheckboxState" }] : []));
191
+ this.embeddedPseudoCheckboxSize = computed(() => this.size(), ...(ngDevMode ? [{ debugName: "embeddedPseudoCheckboxSize" }] : []));
192
+ this.embeddedPseudoCheckboxVariant = signal(IdsFormFieldVariant.SURFACE, ...(ngDevMode ? [{ debugName: "embeddedPseudoCheckboxVariant" }] : []));
193
+ effect(() => {
194
+ this.disabled = this.disabledInput();
195
+ });
142
196
  }
143
- get _hostName() {
144
- return 'fieldset';
197
+ ngOnInit() {
198
+ const parent = this._parent;
199
+ if (parent.isOptionPreSelectedByValue(this.value())) {
200
+ this.selected.set(true);
201
+ }
145
202
  }
146
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
147
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: IdsFieldsetComponent, isStandalone: true, selector: "fieldset[idsFieldset]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "_fieldsetMessage", predicate: IdsFieldsetMessageDirective, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<legend class=\"ids-fieldset-legend\">{{ legend() }}</legend>\n@if (_hasMessage()) {\n <div class=\"ids-fieldset-message\">\n <ng-content select=\"[idsFieldsetMessage]\" />\n </div>\n}\n<ng-content select=\"ids-fieldset-row\" />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
203
+ _handleKeydown(event) {
204
+ if ((event.key === 'ENTER' || event.key === ' ') && !hasModifierKey(event)) {
205
+ this.selectViaInteraction();
206
+ event.preventDefault();
207
+ }
208
+ }
209
+ selectViaInteraction() {
210
+ if (!this._groupOrOptionIsDisabled()) {
211
+ this._emitSelectionChangeEvent(!this.selected(), true);
212
+ }
213
+ }
214
+ getHostElement() {
215
+ return this._element.nativeElement;
216
+ }
217
+ select(emitEvent = true) {
218
+ if (!this.selected()) {
219
+ if (emitEvent) {
220
+ this._emitSelectionChangeEvent(true);
221
+ }
222
+ }
223
+ }
224
+ deselect(emitEvent = true) {
225
+ if (this.selected()) {
226
+ if (emitEvent) {
227
+ this._emitSelectionChangeEvent(false);
228
+ }
229
+ }
230
+ }
231
+ focus(_origin, options) {
232
+ const element = this._element.nativeElement;
233
+ if (typeof element.focus === 'function') {
234
+ element.focus(options);
235
+ }
236
+ }
237
+ setActiveStyles() {
238
+ if (!this._active()) {
239
+ this._active.set(true);
240
+ }
241
+ }
242
+ setInactiveStyles() {
243
+ if (this._active()) {
244
+ this._active.set(false);
245
+ }
246
+ }
247
+ getLabel() {
248
+ return this.viewValue();
249
+ }
250
+ _emitSelectionChangeEvent(selected, isUserInput = false) {
251
+ if (this._multiSelect || !this.selected()) {
252
+ this.onSelectionChange.emit(new IdsOptionSelectionChange(this, selected, isUserInput));
253
+ }
254
+ }
255
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
256
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: IdsOptionComponent, isStandalone: true, selector: "ids-option", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, explicitViewValue: { classPropertyName: "explicitViewValue", publicName: "viewValue", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelectionChange: "onSelectionChange" }, host: { attributes: { "role": "option" }, listeners: { "click": "selectViaInteraction()", "keydown": "_handleKeydown($event)" }, properties: { "attr.aria-selected": "selected()", "attr.aria-disabled": "disabled.toString()" } }, providers: [
257
+ {
258
+ provide: IDS_PSEUDO_CHECKBOX_PARENT,
259
+ useExisting: IdsOptionComponent,
260
+ },
261
+ ], viewQueries: [{ propertyName: "_textElement", first: true, predicate: ["text"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (_multiSelect) {\n <ids-pseudo-checkbox aria-hidden=\"true\" [disabled]=\"_groupOrOptionIsDisabled()\" [checkboxState]=\"_pseudoCheckboxState()\" />\n}\n\n<div #text class=\"ids-option__text\"><ng-content /></div>\n\n@if (!_multiSelect && selected()) {\n <ids-icon fontIcon=\"done\" />\n}\n", dependencies: [{ kind: "component", type: IdsIconComponent, selector: "ids-icon", inputs: ["size", "sizeCollection", "variant", "fontIcon", "svgIcon", "aria-hidden"] }, { kind: "component", type: PseudoCheckboxComponent, selector: "ids-pseudo-checkbox", inputs: ["checkboxState", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
148
262
  }
149
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetComponent, decorators: [{
263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionComponent, decorators: [{
150
264
  type: Component,
151
- args: [{ selector: 'fieldset[idsFieldset]', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<legend class=\"ids-fieldset-legend\">{{ legend() }}</legend>\n@if (_hasMessage()) {\n <div class=\"ids-fieldset-message\">\n <ng-content select=\"[idsFieldsetMessage]\" />\n </div>\n}\n<ng-content select=\"ids-fieldset-row\" />\n" }]
152
- }] });
265
+ args: [{ selector: 'ids-option', imports: [
266
+ IdsIconComponent,
267
+ PseudoCheckboxComponent,
268
+ ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
269
+ {
270
+ provide: IDS_PSEUDO_CHECKBOX_PARENT,
271
+ useExisting: IdsOptionComponent,
272
+ },
273
+ ], host: {
274
+ 'role': 'option',
275
+ '[attr.aria-selected]': 'selected()',
276
+ '[attr.aria-disabled]': 'disabled.toString()',
277
+ '(click)': 'selectViaInteraction()',
278
+ '(keydown)': '_handleKeydown($event)',
279
+ }, template: "@if (_multiSelect) {\n <ids-pseudo-checkbox aria-hidden=\"true\" [disabled]=\"_groupOrOptionIsDisabled()\" [checkboxState]=\"_pseudoCheckboxState()\" />\n}\n\n<div #text class=\"ids-option__text\"><ng-content /></div>\n\n@if (!_multiSelect && selected()) {\n <ids-icon fontIcon=\"done\" />\n}\n" }]
280
+ }], ctorParameters: () => [] });
281
+ function _countGroupLabelsBeforeOption(optionIndex, options, optionGroups) {
282
+ if (optionGroups.length) {
283
+ let groupCounter = 0;
284
+ for (let i = 0; i < optionIndex + 1; i++) {
285
+ if (options[i].group && options[i].group === optionGroups[groupCounter]) {
286
+ groupCounter++;
287
+ }
288
+ }
289
+ return groupCounter;
290
+ }
291
+ return 0;
292
+ }
293
+ function _getOptionScrollPosition(optionOffset, optionHeight, currentScrollPosition, panelHeight) {
294
+ if (optionOffset < currentScrollPosition) {
295
+ return optionOffset;
296
+ }
297
+ if (optionOffset + optionHeight > currentScrollPosition + panelHeight) {
298
+ return Math.max(0, optionOffset - panelHeight + optionHeight);
299
+ }
300
+ return currentScrollPosition;
301
+ }
153
302
 
154
- const IDS_FORM_FIELD_CONTROL = new InjectionToken('IDS_FORM_FIELD_CONTROL');
303
+ class IdsFormFieldActionDirective {
304
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFormFieldActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
305
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.7", type: IdsFormFieldActionDirective, isStandalone: true, selector: "[idsFormFieldAction]", ngImport: i0 }); }
306
+ }
307
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFormFieldActionDirective, decorators: [{
308
+ type: Directive,
309
+ args: [{
310
+ selector: '[idsFormFieldAction]',
311
+ standalone: true,
312
+ }]
313
+ }] });
155
314
 
156
315
  const formFieldControlClass = 'ids-form-field-control';
157
316
  class IdsFormFieldControl extends ComponentBaseWithDefaults {
@@ -236,17 +395,7 @@ function IDS_FORM_FIELD_DEFAULT_CONFIG_FACTORY() {
236
395
  };
237
396
  }
238
397
 
239
- class IdsFormFieldActionDirective {
240
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFormFieldActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
241
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.7", type: IdsFormFieldActionDirective, isStandalone: true, selector: "[idsFormFieldAction]", ngImport: i0 }); }
242
- }
243
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFormFieldActionDirective, decorators: [{
244
- type: Directive,
245
- args: [{
246
- selector: '[idsFormFieldAction]',
247
- standalone: true,
248
- }]
249
- }] });
398
+ const IDS_FORM_FIELD_CONTROL = new InjectionToken('IDS_FORM_FIELD_CONTROL');
250
399
 
251
400
  class IdsPrefixDirective {
252
401
  constructor() {
@@ -314,13 +463,62 @@ function requiredFalseValidator(control) {
314
463
  return control.value === false ? null : { requiredFalse: true };
315
464
  }
316
465
 
317
- /**
318
- * Directive to map an error message to an error code for a form field.
319
- * Mappings must be defined between the directive element's tags ordered by priority (descending from top to bottom).
320
- * The error code is provided as an attribute, while the error message will be this directive's text content.
321
- * The latter can be a plain string literal or even an interpolated string value.
322
- *
323
- * @example
466
+ const IDS_FIELDSET_DEFAULT_CONFIG = new InjectionToken('IDS_FIELDSET_DEFAULT_CONFIG', {
467
+ providedIn: 'root',
468
+ factory: IDS_FIELDSET_DEFAULT_CONFIG_FACTORY,
469
+ });
470
+ function IDS_FIELDSET_DEFAULT_CONFIG_FACTORY() {
471
+ return {
472
+ size: IdsSize.COMPACT,
473
+ variant: IdsFormFieldVariant.SURFACE,
474
+ };
475
+ }
476
+
477
+ class IdsFieldsetMessageDirective {
478
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetMessageDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
479
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.7", type: IdsFieldsetMessageDirective, isStandalone: true, selector: "[idsFieldsetMessage]", ngImport: i0 }); }
480
+ }
481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetMessageDirective, decorators: [{
482
+ type: Directive,
483
+ args: [{
484
+ selector: '[idsFieldsetMessage]',
485
+ standalone: true,
486
+ }]
487
+ }] });
488
+
489
+ const defaultConfig$4 = IDS_FIELDSET_DEFAULT_CONFIG_FACTORY();
490
+ class IdsFieldsetComponent extends ComponentBaseWithDefaults {
491
+ constructor() {
492
+ super(...arguments);
493
+ this._defaultConfig = this._getDefaultConfig(defaultConfig$4, IDS_FIELDSET_DEFAULT_CONFIG);
494
+ this.size = input(this._defaultConfig.size, ...(ngDevMode ? [{ debugName: "size" }] : []));
495
+ this.variant = input(this._defaultConfig.variant, ...(ngDevMode ? [{ debugName: "variant" }] : []));
496
+ this.legend = input('', ...(ngDevMode ? [{ debugName: "legend" }] : []));
497
+ this._fieldsetMessage = contentChildren(IdsFieldsetMessageDirective, ...(ngDevMode ? [{ debugName: "_fieldsetMessage" }] : []));
498
+ this._hasMessage = computed(() => this._fieldsetMessage().length > 0, ...(ngDevMode ? [{ debugName: "_hasMessage" }] : []));
499
+ this._hostClasses = computed(() => this._getHostClasses([
500
+ this.size(),
501
+ this.variant(),
502
+ ]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
503
+ }
504
+ get _hostName() {
505
+ return 'fieldset';
506
+ }
507
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
508
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: IdsFieldsetComponent, isStandalone: true, selector: "fieldset[idsFieldset]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "_fieldsetMessage", predicate: IdsFieldsetMessageDirective, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<legend class=\"ids-fieldset-legend\">{{ legend() }}</legend>\n@if (_hasMessage()) {\n <div class=\"ids-fieldset-message\">\n <ng-content select=\"[idsFieldsetMessage]\" />\n </div>\n}\n<ng-content select=\"ids-fieldset-row\" />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
509
+ }
510
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetComponent, decorators: [{
511
+ type: Component,
512
+ args: [{ selector: 'fieldset[idsFieldset]', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<legend class=\"ids-fieldset-legend\">{{ legend() }}</legend>\n@if (_hasMessage()) {\n <div class=\"ids-fieldset-message\">\n <ng-content select=\"[idsFieldsetMessage]\" />\n </div>\n}\n<ng-content select=\"ids-fieldset-row\" />\n" }]
513
+ }] });
514
+
515
+ /**
516
+ * Directive to map an error message to an error code for a form field.
517
+ * Mappings must be defined between the directive element's tags ordered by priority (descending from top to bottom).
518
+ * The error code is provided as an attribute, while the error message will be this directive's text content.
519
+ * The latter can be a plain string literal or even an interpolated string value.
520
+ *
521
+ * @example
324
522
  * ```html
325
523
  * <ids-form-field>
326
524
  * <ids-label>Input field</ids-label>
@@ -411,12 +609,12 @@ function IDS_MESSAGE_DEFAULT_CONFIG_FACTORY() {
411
609
  // eslint-disable-next-line @typescript-eslint/naming-convention
412
610
  const IDS_MESSAGE_PARENT_FORM_FIELD = new InjectionToken('IDS_MESSAGE_PARENT_FORM_FIELD');
413
611
 
414
- const defaultConfig$2 = IDS_MESSAGE_DEFAULT_CONFIG_FACTORY();
612
+ const defaultConfig$3 = IDS_MESSAGE_DEFAULT_CONFIG_FACTORY();
415
613
  class IdsMessageDirective extends ComponentBaseWithDefaults {
416
614
  constructor() {
417
615
  super(...arguments);
418
616
  this._parent = inject(IDS_MESSAGE_PARENT_FORM_FIELD, { skipSelf: true, optional: true });
419
- this._defaultConfig = this._getDefaultConfig(defaultConfig$2, IDS_MESSAGE_DEFAULT_CONFIG);
617
+ this._defaultConfig = this._getDefaultConfig(defaultConfig$3, IDS_MESSAGE_DEFAULT_CONFIG);
420
618
  this.size = input(this._defaultConfig.size, ...(ngDevMode ? [{ debugName: "size" }] : []));
421
619
  this.variant = input(this._defaultConfig.variant, ...(ngDevMode ? [{ debugName: "variant" }] : []));
422
620
  this._parentOrSelfSize = computed(() => this._parent?.size() ?? this.size(), ...(ngDevMode ? [{ debugName: "_parentOrSelfSize" }] : []));
@@ -523,6 +721,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
523
721
  class IdsSuccessMessageComponent extends ComponentBase {
524
722
  constructor() {
525
723
  super(...arguments);
724
+ this._parent = inject(IDS_MESSAGE_PARENT_FORM_FIELD, { skipSelf: true, optional: true });
725
+ this._isDisabled = computed(() => this._parent?.disabled() ?? false, ...(ngDevMode ? [{ debugName: "_isDisabled" }] : []));
526
726
  this._hostClasses = computed(() => this._getHostClasses([]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
527
727
  this.suffixes = contentChildren(IdsMessageSuffixDirective, ...(ngDevMode ? [{ debugName: "suffixes" }] : []));
528
728
  }
@@ -530,20 +730,20 @@ class IdsSuccessMessageComponent extends ComponentBase {
530
730
  return 'success-message';
531
731
  }
532
732
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsSuccessMessageComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
533
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: IdsSuccessMessageComponent, isStandalone: true, selector: "ids-success-message", queries: [{ propertyName: "suffixes", predicate: IdsMessageSuffixDirective, isSignal: true }], usesInheritance: true, hostDirectives: [{ directive: IdsMessageDirective }], ngImport: i0, template: "<div class=\"ids-message__prefix\">\n <ng-content select=\"[idsMessagePrefix]\">\n <ids-icon aria-hidden=\"true\" fontIcon=\"done\" variant=\"success\" />\n </ng-content>\n</div>\n<div class=\"ids-message__text\">\n <ng-content />\n</div>\n@if (suffixes().length) {\n <div class=\"ids-message__suffix\">\n <ng-content select=\"[idsMessageSuffix]\" />\n </div>\n}\n", dependencies: [{ kind: "component", type: IdsIconComponent, selector: "ids-icon", inputs: ["size", "sizeCollection", "variant", "fontIcon", "svgIcon", "aria-hidden"] }], encapsulation: i0.ViewEncapsulation.None }); }
733
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: IdsSuccessMessageComponent, isStandalone: true, selector: "ids-success-message", queries: [{ propertyName: "suffixes", predicate: IdsMessageSuffixDirective, isSignal: true }], usesInheritance: true, hostDirectives: [{ directive: IdsMessageDirective }], ngImport: i0, template: "<div class=\"ids-message__prefix\">\n <ng-content select=\"[idsMessagePrefix]\">\n @if (_isDisabled()) {\n <ids-icon aria-hidden=\"true\" fontIcon=\"done\" />\n } @else {\n <ids-icon aria-hidden=\"true\" fontIcon=\"done\" variant=\"success\" />\n } </ng-content>\n</div>\n<div class=\"ids-message__text\">\n <ng-content />\n</div>\n@if (suffixes().length) {\n <div class=\"ids-message__suffix\">\n <ng-content select=\"[idsMessageSuffix]\" />\n </div>\n}\n", dependencies: [{ kind: "component", type: IdsIconComponent, selector: "ids-icon", inputs: ["size", "sizeCollection", "variant", "fontIcon", "svgIcon", "aria-hidden"] }], encapsulation: i0.ViewEncapsulation.None }); }
534
734
  }
535
735
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsSuccessMessageComponent, decorators: [{
536
736
  type: Component,
537
- args: [{ selector: 'ids-success-message', imports: [IdsIconComponent], hostDirectives: [IdsMessageDirective], encapsulation: ViewEncapsulation.None, template: "<div class=\"ids-message__prefix\">\n <ng-content select=\"[idsMessagePrefix]\">\n <ids-icon aria-hidden=\"true\" fontIcon=\"done\" variant=\"success\" />\n </ng-content>\n</div>\n<div class=\"ids-message__text\">\n <ng-content />\n</div>\n@if (suffixes().length) {\n <div class=\"ids-message__suffix\">\n <ng-content select=\"[idsMessageSuffix]\" />\n </div>\n}\n" }]
737
+ args: [{ selector: 'ids-success-message', imports: [IdsIconComponent], hostDirectives: [IdsMessageDirective], encapsulation: ViewEncapsulation.None, template: "<div class=\"ids-message__prefix\">\n <ng-content select=\"[idsMessagePrefix]\">\n @if (_isDisabled()) {\n <ids-icon aria-hidden=\"true\" fontIcon=\"done\" />\n } @else {\n <ids-icon aria-hidden=\"true\" fontIcon=\"done\" variant=\"success\" />\n } </ng-content>\n</div>\n<div class=\"ids-message__text\">\n <ng-content />\n</div>\n@if (suffixes().length) {\n <div class=\"ids-message__suffix\">\n <ng-content select=\"[idsMessageSuffix]\" />\n </div>\n}\n" }]
538
738
  }] });
539
739
 
540
- const defaultConfig$1 = IDS_FORM_FIELD_DEFAULT_CONFIG_FACTORY();
740
+ const defaultConfig$2 = IDS_FORM_FIELD_DEFAULT_CONFIG_FACTORY();
541
741
  class IdsFormFieldComponent extends ComponentBaseWithDefaults {
542
742
  constructor() {
543
743
  super(...arguments);
544
744
  this._changeDetectorRef = inject(ChangeDetectorRef);
545
745
  this._parentFieldset = inject(IdsFieldsetComponent, { optional: true });
546
- this._defaultConfig = this._getDefaultConfig(defaultConfig$1, IDS_FORM_FIELD_DEFAULT_CONFIG);
746
+ this._defaultConfig = this._getDefaultConfig(defaultConfig$2, IDS_FORM_FIELD_DEFAULT_CONFIG);
547
747
  this._fieldWrapper = viewChild.required('fieldWrapper');
548
748
  this._child = contentChild.required(IDS_FORM_FIELD_CONTROL);
549
749
  this._hintMessages = contentChildren(IdsHintMessageComponent, ...(ngDevMode ? [{ debugName: "_hintMessages", descendants: true }] : [{ descendants: true }]));
@@ -627,7 +827,7 @@ function IDS_INPUT_DEFAULT_CONFIG_FACTORY() {
627
827
  };
628
828
  }
629
829
 
630
- const defaultConfig = IDS_INPUT_DEFAULT_CONFIG_FACTORY();
830
+ const defaultConfig$1 = IDS_INPUT_DEFAULT_CONFIG_FACTORY();
631
831
  const IDS_INPUT_INVALID_TYPES = [
632
832
  'button',
633
833
  'checkbox',
@@ -643,7 +843,7 @@ class IdsInputDirective extends IdsFormFieldControl {
643
843
  constructor() {
644
844
  super(...arguments);
645
845
  this._elementRef = inject(ElementRef);
646
- this._defaultConfig = this._getDefaultConfig(defaultConfig, IDS_INPUT_DEFAULT_CONFIG);
846
+ this._defaultConfig = this._getDefaultConfig(defaultConfig$1, IDS_INPUT_DEFAULT_CONFIG);
647
847
  this._focused = false;
648
848
  this.name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
649
849
  this.type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
@@ -729,229 +929,579 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
729
929
  }]
730
930
  }] });
731
931
 
732
- const Message = {
733
- HINT: 'hint',
734
- ERROR: 'error',
735
- SUCCESS: 'success',
736
- };
737
-
738
- const IDS_OPTION_GROUP = new InjectionToken('IdsOptionGroup');
739
-
740
- const IDS_OPTION_PARENT_COMPONENT = new InjectionToken('IDS_OPTION_PARENT_COMPONENT');
741
-
742
- class IdsOptionSelectionChange {
743
- constructor(source, selected, isUserInput = false) {
744
- this.source = source;
745
- this.selected = selected;
746
- this.isUserInput = isUserInput;
747
- }
748
- }
749
-
750
- class IdsOptionGroupComponent extends ComponentBase {
751
- constructor() {
752
- super(...arguments);
753
- this._parent = inject(IDS_OPTION_PARENT_COMPONENT);
754
- this._inert = this._parent?.inertGroups ?? false;
755
- this.label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
756
- this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: coerceBooleanAttribute }] : [{ transform: coerceBooleanAttribute }]));
757
- this._labelId = computed(() => `${this.id()}-label`, ...(ngDevMode ? [{ debugName: "_labelId" }] : []));
758
- this._hostClasses = computed(() => this._getHostClasses([
759
- this.disabled() ? 'disabled' : null,
760
- this._parent.parentSize(),
761
- this._parent.parentVariant(),
762
- ]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
763
- }
932
+ const defaultConfig = IDS_AUTOCOMPLETE_DEFAULT_CONFIG_FACTORY();
933
+ const LIVE_ANNOUNCE_DURATION_MS = 10000;
934
+ class IdsAutocompleteComponent extends IdsFormFieldControl {
764
935
  get _hostName() {
765
- return 'option-group';
936
+ return 'autocomplete';
766
937
  }
767
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
768
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.7", type: IdsOptionGroupComponent, isStandalone: true, selector: "ids-option-group", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.role": "_inert ? null : \"group\"", "attr.aria-disabled": "_inert ? null : disabled().toString()", "attr.aria-labelledby": "_inert ? null : _labelId()" } }, providers: [{ provide: IDS_OPTION_GROUP, useExisting: IdsOptionGroupComponent }], usesInheritance: true, ngImport: i0, template: "<div role=\"presentation\" class=\"ids-option-group__label\" [id]=\"_labelId()\">\n <div class=\"ids-option-group__text\">{{ label() }}</div>\n</div>\n<ng-content select=\"ids-option, ng-container\" />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
769
- }
770
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionGroupComponent, decorators: [{
771
- type: Component,
772
- args: [{ selector: 'ids-option-group', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: IDS_OPTION_GROUP, useExisting: IdsOptionGroupComponent }], host: {
773
- '[attr.role]': '_inert ? null : "group"',
774
- '[attr.aria-disabled]': '_inert ? null : disabled().toString()',
775
- '[attr.aria-labelledby]': '_inert ? null : _labelId()',
776
- }, template: "<div role=\"presentation\" class=\"ids-option-group__label\" [id]=\"_labelId()\">\n <div class=\"ids-option-group__text\">{{ label() }}</div>\n</div>\n<ng-content select=\"ids-option, ng-container\" />\n" }]
777
- }] });
778
-
779
- const IDS_PSEUDO_CHECKBOX_PARENT = new InjectionToken('IDS_PSEUDO_CHECKBOX_PARENT');
780
-
781
- const IdsPseudoCheckboxState = {
782
- UNCHECKED: 'unchecked',
783
- CHECKED: 'checked',
784
- INDETERMINATE: 'indeterminate',
785
- };
786
-
787
- class PseudoCheckboxComponent extends ComponentBase {
788
- constructor() {
789
- super(...arguments);
790
- this._parent = inject(IDS_PSEUDO_CHECKBOX_PARENT, { optional: true });
791
- this.checkboxState = input(IdsPseudoCheckboxState.UNCHECKED, ...(ngDevMode ? [{ debugName: "checkboxState" }] : []));
792
- this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: coerceBooleanAttribute }] : [{ transform: coerceBooleanAttribute }]));
793
- this._isChecked = computed(() => this.checkboxState() === IdsPseudoCheckboxState.CHECKED, ...(ngDevMode ? [{ debugName: "_isChecked" }] : []));
794
- this._isIndeterminate = computed(() => this.checkboxState() === IdsPseudoCheckboxState.INDETERMINATE, ...(ngDevMode ? [{ debugName: "_isIndeterminate" }] : []));
795
- this._hostClasses = computed(() => this._getHostClasses([
796
- this._parent?.embeddedPseudoCheckboxSize(),
797
- this._parent?.embeddedPseudoCheckboxVariant(),
798
- this.disabled() ? 'disabled' : null,
799
- ]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
938
+ get _empty() {
939
+ return Boolean(this._selectionModel?.isEmpty());
800
940
  }
801
- get _hostName() {
802
- return 'pseudo-checkbox';
941
+ get selected() {
942
+ return this.multiSelect() ? this._selectionModel?.selected : this._selectionModel?.selected?.[0];
803
943
  }
804
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: PseudoCheckboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
805
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: PseudoCheckboxComponent, isStandalone: true, selector: "ids-pseudo-checkbox", inputs: { checkboxState: { classPropertyName: "checkboxState", publicName: "checkboxState", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<div class=\"ids-pseudo-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [disabled]=\"disabled()\"\n [attr.aria-checked]=\"_isIndeterminate() ? 'mixed' : null\"\n [checked]=\"_isChecked()\"\n [indeterminate]=\"_isIndeterminate()\"\n (change)=\"$event.stopPropagation()\"\n />\n <div class=\"ids-pseudo-checkbox__icon\" aria-hidden=\"true\">\n @if (_isIndeterminate()) {\n <ids-icon fontIcon=\"remove\" aria-hidden=\"true\" />\n }\n @if (_isChecked()) {\n <ids-icon fontIcon=\"done\" aria-hidden=\"true\" />\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: IdsIconComponent, selector: "ids-icon", inputs: ["size", "sizeCollection", "variant", "fontIcon", "svgIcon", "aria-hidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
806
- }
807
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: PseudoCheckboxComponent, decorators: [{
808
- type: Component,
809
- args: [{ selector: 'ids-pseudo-checkbox', imports: [IdsIconComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ids-pseudo-checkbox__input-wrapper\">\n <input\n type=\"checkbox\"\n [disabled]=\"disabled()\"\n [attr.aria-checked]=\"_isIndeterminate() ? 'mixed' : null\"\n [checked]=\"_isChecked()\"\n [indeterminate]=\"_isIndeterminate()\"\n (change)=\"$event.stopPropagation()\"\n />\n <div class=\"ids-pseudo-checkbox__icon\" aria-hidden=\"true\">\n @if (_isIndeterminate()) {\n <ids-icon fontIcon=\"remove\" aria-hidden=\"true\" />\n }\n @if (_isChecked()) {\n <ids-icon fontIcon=\"done\" aria-hidden=\"true\" />\n }\n </div>\n</div>\n" }]
810
- }] });
811
-
812
- class IdsOptionComponent extends ComponentBase {
813
- get _hostName() {
814
- return 'option';
944
+ get _triggerValue() {
945
+ if (this._empty) {
946
+ return '';
947
+ }
948
+ if (this.multiSelect()) {
949
+ const selectedOptions = this._selectionModel?.selected;
950
+ return selectedOptions?.join(', ') || '';
951
+ }
952
+ return this._selectionModel?.selected?.[0] || '';
815
953
  }
816
954
  constructor() {
817
955
  super();
818
- this._parent = inject(IDS_OPTION_PARENT_COMPONENT);
819
- this._element = inject(ElementRef);
820
- this.group = inject(IDS_OPTION_GROUP, { optional: true });
821
- this._textElement = viewChild.required('text');
822
- this.selected = signal(false, ...(ngDevMode ? [{ debugName: "selected" }] : []));
823
- this._active = signal(false, ...(ngDevMode ? [{ debugName: "_active" }] : []));
824
- this.size = computed(() => this._parent.parentSize(), ...(ngDevMode ? [{ debugName: "size" }] : []));
825
- this.variant = computed(() => this._parent.parentVariant(), ...(ngDevMode ? [{ debugName: "variant" }] : []));
826
- this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
827
- this.explicitViewValue = input(null, ...(ngDevMode ? [{ debugName: "explicitViewValue", alias: 'viewValue' }] : [{ alias: 'viewValue' }]));
828
- this.disabledInput = input(false, ...(ngDevMode ? [{ debugName: "disabledInput", alias: 'disabled', transform: coerceBooleanAttribute }] : [{ alias: 'disabled', transform: coerceBooleanAttribute }]));
829
- this.disabled = false; // Do not delete this class member, until ListKeyManagerOption requires: `disabled: boolean`
830
- this._groupOrOptionIsDisabled = computed(() => this.group?.disabled() || this.disabledInput(), ...(ngDevMode ? [{ debugName: "_groupOrOptionIsDisabled" }] : []));
831
- this._multiSelect = Boolean(this._parent?.multiSelect());
832
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix
833
- this.onSelectionChange = output();
834
- this.viewValue = computed(() => this._textElement().nativeElement.textContent || this.explicitViewValue() || '', ...(ngDevMode ? [{ debugName: "viewValue" }] : []));
956
+ this._defaultConfig = this._getDefaultConfig(defaultConfig, IDS_AUTOCOMPLETE_DEFAULT_CONFIG);
957
+ this._elementRef = inject(ElementRef);
958
+ this._changeDetectorRef = inject(ChangeDetectorRef);
959
+ this._liveAnnouncer = inject(LiveAnnouncer);
960
+ this._parentFormField = inject(IdsFormFieldComponent);
961
+ this._overlayWidth = 0;
962
+ /**
963
+ * Minimum number of characters to initiate actual search.
964
+ * Warning is shown when input length is not met.
965
+ * (Resource loader/stream function needs to be adjusted accordingly!)
966
+ */
967
+ this.minChars = input(1, ...(ngDevMode ? [{ debugName: "minChars", transform: coerceNumberAttribute }] : [{ transform: coerceNumberAttribute }]));
968
+ /** Max length of options allowed to show. Warning is shown when available options is higher than this number */
969
+ this.maxLength = input(null, ...(ngDevMode ? [{ debugName: "maxLength", transform: coerceNumberAttribute }] : [{ transform: coerceNumberAttribute }]));
970
+ this.multiSelect = input(false, ...(ngDevMode ? [{ debugName: "multiSelect" }] : []));
971
+ this.ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel", alias: 'aria-label' }] : [{ alias: 'aria-label' }]));
972
+ this.ariaLabelledby = input('', ...(ngDevMode ? [{ debugName: "ariaLabelledby", alias: 'aria-labelledby' }] : [{ alias: 'aria-labelledby' }]));
973
+ this.ariaLabelClearButton = input('Clear', ...(ngDevMode ? [{ debugName: "ariaLabelClearButton" }] : []));
974
+ this.ariaLabelToggleButton = input('Toggle', ...(ngDevMode ? [{ debugName: "ariaLabelToggleButton" }] : []));
975
+ this.valueCompareFn = input((o1, o2) => o1 === o2, ...(ngDevMode ? [{ debugName: "valueCompareFn" }] : []));
976
+ this.sortCompareFn = input(...(ngDevMode ? [undefined, { debugName: "sortCompareFn" }] : []));
977
+ this.tabIndex = input(0, ...(ngDevMode ? [{ debugName: "tabIndex", transform: coerceNumberAttribute }] : [{ transform: coerceNumberAttribute }]));
978
+ this.typeaheadDebounceInterval = input(this._defaultConfig.typeaheadDebounceInterval, ...(ngDevMode ? [{ debugName: "typeaheadDebounceInterval", transform: coerceNumberAttribute }] : [{
979
+ transform: coerceNumberAttribute,
980
+ }]));
981
+ this.hintLoading = input(this._defaultConfig.hintLoading, ...(ngDevMode ? [{ debugName: "hintLoading" }] : []));
982
+ this.hintNoResults = input(this._defaultConfig.hintNoResults, ...(ngDevMode ? [{ debugName: "hintNoResults" }] : []));
983
+ this.hintMinChars = input(this._defaultConfig.hintMinChars, ...(ngDevMode ? [{ debugName: "hintMinChars" }] : []));
984
+ this.hintMaxLength = input(this._defaultConfig.hintMaxLength, ...(ngDevMode ? [{ debugName: "hintMaxLength" }] : []));
985
+ this.panelClasses = input('', ...(ngDevMode ? [{ debugName: "panelClasses" }] : []));
986
+ this.isPanelOpen = signal(false, ...(ngDevMode ? [{ debugName: "isPanelOpen" }] : []));
987
+ this.parentSize = computed(() => this._parentFormField.parentOrSelfSize(), ...(ngDevMode ? [{ debugName: "parentSize" }] : []));
988
+ this.parentVariant = computed(() => this._parentFormField.parentOrSelfVariant(), ...(ngDevMode ? [{ debugName: "parentVariant" }] : []));
989
+ this.errorStateMatcher = signal(inject(ErrorStateMatcher), ...(ngDevMode ? [{ debugName: "errorStateMatcher" }] : []));
990
+ this.successStateMatcher = signal(inject(SuccessStateMatcher), ...(ngDevMode ? [{ debugName: "successStateMatcher" }] : []));
991
+ this.options = viewChildren(IdsOptionComponent, ...(ngDevMode ? [{ debugName: "options" }] : []));
992
+ this.onContainerClick = () => { };
835
993
  this._hostClasses = computed(() => this._getHostClasses([
836
- this.selected() ? 'selected' : null,
837
- this._active() ? 'active' : null,
838
- this._groupOrOptionIsDisabled() ? 'disabled' : null,
839
- this._multiSelect ? 'multiselect' : null,
840
- this.size(),
841
- this.variant(),
842
- ]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
843
- this._pseudoCheckboxState = computed(() => (this.selected() ? IdsPseudoCheckboxState.CHECKED : IdsPseudoCheckboxState.UNCHECKED), ...(ngDevMode ? [{ debugName: "_pseudoCheckboxState" }] : []));
844
- this.embeddedPseudoCheckboxSize = computed(() => this.size(), ...(ngDevMode ? [{ debugName: "embeddedPseudoCheckboxSize" }] : []));
845
- this.embeddedPseudoCheckboxVariant = signal(IdsFormFieldVariant.SURFACE, ...(ngDevMode ? [{ debugName: "embeddedPseudoCheckboxVariant" }] : []));
994
+ this.parentSize(),
995
+ this.parentVariant(),
996
+ this.disabled() ? 'disabled' : null,
997
+ this.readonly() ? 'readonly' : null,
998
+ ], [formFieldControlClass]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
999
+ this._panelClasses = computed(() => [
1000
+ 'ids-overlay-panel__autocomplete-panel',
1001
+ this.panelClasses(),
1002
+ ].join(' '), ...(ngDevMode ? [{ debugName: "_panelClasses" }] : []));
1003
+ this._focused = signal(false, ...(ngDevMode ? [{ debugName: "_focused" }] : []));
1004
+ this._canOpen = computed(() => !this.isPanelOpen() && !this.disabled() && !this.readonly() && this.options().length > 0, ...(ngDevMode ? [{ debugName: "_canOpen" }] : []));
1005
+ this._panel = viewChild('overlayPanel', ...(ngDevMode ? [{ debugName: "_panel", read: (ElementRef) }] : [{ read: (ElementRef) }]));
1006
+ this._inputElemment = viewChild('fallbackOverlayOrigin', ...(ngDevMode ? [{ debugName: "_inputElemment", read: (ElementRef) }] : [{ read: (ElementRef) }]));
1007
+ this._resource = rxResource({
1008
+ defaultValue: [],
1009
+ params: () => ({ search: this._searchText() }),
1010
+ stream: inject(IDS_AUTOCOMPLETE_LOADER),
1011
+ });
1012
+ this._onChange = () => { };
1013
+ this._onTouched = () => { };
1014
+ this._searchText = model('', ...(ngDevMode ? [{ debugName: "_searchText" }] : []));
1015
+ this._skipPredicate = (option) => {
1016
+ if (this.isPanelOpen()) {
1017
+ return false;
1018
+ }
1019
+ return option.disabledInput();
1020
+ };
846
1021
  effect(() => {
847
- this.disabled = this.disabledInput();
1022
+ this._keyManager?.withTypeAhead(this.typeaheadDebounceInterval());
1023
+ });
1024
+ effect(() => {
1025
+ const options = this.options();
1026
+ untracked(() => {
1027
+ if (options.length > 0) {
1028
+ this._initKeyManager();
1029
+ this.options().forEach((option) => {
1030
+ if (this._selectionModel?.selected.includes(option.viewValue())) {
1031
+ option.selected.set(true);
1032
+ }
1033
+ });
1034
+ this._subscribeOptionChanges();
1035
+ }
1036
+ });
1037
+ });
1038
+ effect(() => {
1039
+ const searchText = this._searchText();
1040
+ untracked(() => {
1041
+ const control = this.ngControl();
1042
+ if (control?.value && searchText !== control?.value) {
1043
+ control?.reset();
1044
+ this._clearSelection();
1045
+ }
1046
+ });
848
1047
  });
849
1048
  }
850
1049
  ngOnInit() {
851
- const parent = this._parent;
852
- if (parent.isOptionPreSelectedByValue(this.value())) {
853
- this.selected.set(true);
1050
+ if (!this._parentFormField) {
1051
+ throw this._createHostError('Select must be in a form field');
1052
+ }
1053
+ this._selectionModel = new SelectionModel(this.multiSelect(), undefined, false, this.valueCompareFn());
1054
+ queueMicrotask(() => {
1055
+ const control = this.ngControl()?.control;
1056
+ if (control) {
1057
+ control.events
1058
+ .pipe(filter((event) => event instanceof ValueChangeEvent), takeUntilDestroyed(this._destroyRef))
1059
+ .subscribe(() => this._changeDetectorRef.markForCheck());
1060
+ }
1061
+ });
1062
+ this._initErrorStateTracker();
1063
+ }
1064
+ ngAfterViewInit() {
1065
+ queueMicrotask(() => {
1066
+ const controlDir = this.ngControl();
1067
+ if (controlDir?.control) {
1068
+ controlDir.control.events.pipe(takeUntilDestroyed(this._destroyRef)).subscribe(() => this.updateErrorAndSuccessState());
1069
+ }
1070
+ });
1071
+ }
1072
+ updateErrorAndSuccessState() {
1073
+ this._errorStateTracker?.updateErrorState();
1074
+ this._successStateTracker?.updateSuccessState();
1075
+ }
1076
+ ngOnDestroy() {
1077
+ this._keyManager?.destroy();
1078
+ }
1079
+ _initKeyManager() {
1080
+ this._keyManager = new ActiveDescendantKeyManager(this.options())
1081
+ .withTypeAhead(this.typeaheadDebounceInterval())
1082
+ .withVerticalOrientation()
1083
+ .withHorizontalOrientation('ltr')
1084
+ .withHomeAndEnd()
1085
+ .withPageUpDown()
1086
+ .withAllowedModifierKeys(['shiftKey'])
1087
+ .skipPredicate(this._skipPredicate);
1088
+ this._keyManager.change.subscribe(() => {
1089
+ if (this.isPanelOpen() && this._panel()) {
1090
+ this._scrollOptionIntoView(this._keyManager?.activeItemIndex || 0);
1091
+ }
1092
+ });
1093
+ }
1094
+ _subscribeOptionChanges() {
1095
+ this.options().forEach((option) => {
1096
+ option.onSelectionChange.subscribe((change) => {
1097
+ this._handleOptionChange(change);
1098
+ });
1099
+ });
1100
+ }
1101
+ _handleOptionChange(change) {
1102
+ const { source, selected, isUserInput } = change;
1103
+ if (!this.multiSelect()) {
1104
+ this._clearSelection();
1105
+ }
1106
+ source.selected.set(selected);
1107
+ if (isUserInput) {
1108
+ this._keyManager?.setActiveItem(source);
1109
+ }
1110
+ if (isUserInput && !this.multiSelect() && this.isPanelOpen()) {
1111
+ this.close();
1112
+ }
1113
+ if (this.multiSelect()) {
1114
+ this._sortValues();
854
1115
  }
1116
+ if (selected) {
1117
+ this._selectionModel?.select(source.viewValue());
1118
+ this._searchText.set(source.viewValue());
1119
+ }
1120
+ else {
1121
+ this._selectionModel?.deselect(source.viewValue());
1122
+ }
1123
+ this._handleChange();
1124
+ this._onTouched();
1125
+ this._inputElemment()?.nativeElement.blur();
1126
+ this.isPanelOpen.set(false);
855
1127
  }
856
1128
  _handleKeydown(event) {
857
- if ((event.key === 'ENTER' || event.key === ' ') && !hasModifierKey(event)) {
858
- this.selectViaInteraction();
1129
+ if (!this.disabled() && !this.readonly()) {
1130
+ this.isPanelOpen() ? this._handleOpenedPanelKeydown(event) : this._handleClosedPanelKeydown(event);
1131
+ // announce number of options when a key is pressed
1132
+ this._liveAnnouncer.announce(this.options()
1133
+ .filter((option) => !option.disabled)
1134
+ .length.toString(), LIVE_ANNOUNCE_DURATION_MS);
1135
+ }
1136
+ }
1137
+ _handleClosedPanelKeydown(event) {
1138
+ const key = event.key;
1139
+ const targetElement = event.target;
1140
+ const isButtonTarget = targetElement.localName === 'button';
1141
+ if (isButtonTarget && (key === 'Enter' || key === ' ')) {
859
1142
  event.preventDefault();
1143
+ targetElement.click();
1144
+ targetElement.blur();
1145
+ return;
1146
+ }
1147
+ const manager = this._keyManager;
1148
+ const isArrowKey = key === 'ArrowDown' || key === 'ArrowUp' || key === 'ArrowLeft' || key === 'ArrowRight';
1149
+ const isOpenKey = key === 'Enter' || key === ' ';
1150
+ if ((!manager?.isTyping() && isOpenKey && !hasModifierKey(event)) ||
1151
+ isArrowKey ||
1152
+ this.options().length > 0 ||
1153
+ this._resource.value().length > 0) {
1154
+ if (isArrowKey || isOpenKey) {
1155
+ event.preventDefault();
1156
+ }
1157
+ this.open();
1158
+ }
1159
+ else if (!this.multiSelect()) {
1160
+ const previouslySelectedOption = this.selected;
1161
+ manager?.onKeydown(event);
1162
+ const selectedOption = this.selected;
1163
+ if (selectedOption && previouslySelectedOption !== selectedOption) {
1164
+ this._liveAnnouncer.announce(selectedOption, LIVE_ANNOUNCE_DURATION_MS);
1165
+ }
860
1166
  }
861
1167
  }
862
- selectViaInteraction() {
863
- if (!this._groupOrOptionIsDisabled()) {
864
- this._emitSelectionChangeEvent(!this.selected(), true);
1168
+ _handleOpenedPanelKeydown(event) {
1169
+ const key = event.key;
1170
+ const targetElement = event.target;
1171
+ const isButtonTarget = targetElement.localName === 'button';
1172
+ if (isButtonTarget && (key === 'Enter' || key === ' ')) {
1173
+ event.preventDefault();
1174
+ targetElement.click();
1175
+ targetElement.blur();
1176
+ return;
1177
+ }
1178
+ const manager = this._keyManager;
1179
+ const isArrowKey = key === 'ArrowDown' || key === 'ArrowUp';
1180
+ const isTyping = manager?.isTyping();
1181
+ if (isArrowKey && event.altKey) {
1182
+ event.preventDefault();
1183
+ this.close();
1184
+ }
1185
+ else if (!isTyping && (key === 'Enter' || key === ' ') && manager?.activeItem && !hasModifierKey(event)) {
1186
+ event.preventDefault();
1187
+ manager.activeItem.selectViaInteraction();
1188
+ }
1189
+ else if (!isTyping && this.multiSelect() && key === 'a' && event.ctrlKey) {
1190
+ event.preventDefault();
1191
+ const hasDeselectedOptions = this.options().some((opt) => !opt.disabled && !opt.selected());
1192
+ this.options().forEach((option) => {
1193
+ if (!option.disabled) {
1194
+ hasDeselectedOptions ? option.select() : option.deselect();
1195
+ }
1196
+ });
1197
+ }
1198
+ else {
1199
+ const previouslyFocusedIndex = manager?.activeItemIndex;
1200
+ manager?.onKeydown(event);
1201
+ if (this.multiSelect() &&
1202
+ isArrowKey &&
1203
+ event.shiftKey &&
1204
+ manager?.activeItem &&
1205
+ manager?.activeItemIndex !== previouslyFocusedIndex) {
1206
+ manager?.activeItem.selectViaInteraction();
1207
+ }
865
1208
  }
866
1209
  }
867
- getHostElement() {
868
- return this._element.nativeElement;
1210
+ _scrollOptionIntoView(index) {
1211
+ const option = this.options()[index];
1212
+ if (option) {
1213
+ const panel = this._panel().nativeElement;
1214
+ const element = option.getHostElement();
1215
+ if (index === 0) {
1216
+ panel.scrollTop = 0;
1217
+ }
1218
+ else {
1219
+ panel.scrollTop = _getOptionScrollPosition(element.offsetTop, element.offsetHeight, panel.scrollTop, panel.offsetHeight);
1220
+ }
1221
+ }
869
1222
  }
870
- select(emitEvent = true) {
871
- if (!this.selected()) {
872
- if (emitEvent) {
873
- this._emitSelectionChangeEvent(true);
1223
+ _sortValues() {
1224
+ if (this.multiSelect()) {
1225
+ const options = this.options().map((option) => option.viewValue());
1226
+ const sortComparator = this.sortCompareFn();
1227
+ this._selectionModel?.sort((a, b) => (sortComparator ? sortComparator(a, b, options) : options.indexOf(a) - options.indexOf(b)));
1228
+ }
1229
+ }
1230
+ _getOverlayWidth(preferredOrigin) {
1231
+ const refToMeasure = preferredOrigin instanceof CdkOverlayOrigin ? preferredOrigin.elementRef : preferredOrigin || this._elementRef;
1232
+ return refToMeasure.nativeElement.getBoundingClientRect().width;
1233
+ }
1234
+ toggle() {
1235
+ this.isPanelOpen() ? this.close() : this.open();
1236
+ }
1237
+ open() {
1238
+ if (!this._canOpen()) {
1239
+ return;
1240
+ }
1241
+ if (this._parentFormField) {
1242
+ this._preferredOverlayOrigin = this._parentFormField?.getConnectedOverlayOrigin();
1243
+ }
1244
+ this._overlayWidth = this._getOverlayWidth(this._preferredOverlayOrigin);
1245
+ this.isPanelOpen.set(true);
1246
+ this._keyManager?.withHorizontalOrientation(null);
1247
+ this._highlightCorrectOption();
1248
+ this._changeDetectorRef.markForCheck();
1249
+ }
1250
+ close() {
1251
+ if (this.isPanelOpen()) {
1252
+ this.isPanelOpen.set(false);
1253
+ this._changeDetectorRef.markForCheck();
1254
+ this._onTouched();
1255
+ }
1256
+ }
1257
+ clear() {
1258
+ this.ngControl()?.control?.reset();
1259
+ this._searchText.set('');
1260
+ this._clearSelection();
1261
+ }
1262
+ // #region ControlValueAccessor implementation
1263
+ writeValue(value) {
1264
+ this._setSelectionByValue(value);
1265
+ }
1266
+ registerOnChange(fn) {
1267
+ this._onChange = fn;
1268
+ }
1269
+ registerOnTouched(fn) {
1270
+ this._onTouched = fn;
1271
+ }
1272
+ setDisabledState(isDisabled) {
1273
+ this._disabled.set(isDisabled);
1274
+ this._changeDetectorRef.markForCheck();
1275
+ }
1276
+ // #endregion
1277
+ _setSelectionByValue(value) {
1278
+ this.options().forEach((option) => {
1279
+ option.setInactiveStyles();
1280
+ option.selected.set(false);
1281
+ });
1282
+ this._selectionModel?.clear();
1283
+ this._rawValue = value;
1284
+ if (this.options().length === 0) {
1285
+ return;
1286
+ }
1287
+ if (this.multiSelect() && value) {
1288
+ if (!Array.isArray(value)) {
1289
+ throw this._createHostError('value must be an array in multiple-selection mode');
1290
+ }
1291
+ value.forEach((currentValue) => this._selectValue(currentValue));
1292
+ this._sortValues();
1293
+ }
1294
+ else {
1295
+ const correspondingOption = this._selectValue(value);
1296
+ if (correspondingOption) {
1297
+ this._keyManager?.updateActiveItem(correspondingOption);
1298
+ }
1299
+ else if (!this.isPanelOpen()) {
1300
+ this._keyManager?.updateActiveItem(-1);
874
1301
  }
875
1302
  }
876
1303
  }
877
- deselect(emitEvent = true) {
878
- if (this.selected()) {
879
- if (emitEvent) {
880
- this._emitSelectionChangeEvent(false);
1304
+ _selectValue(value) {
1305
+ const valueCompareFn = this.valueCompareFn();
1306
+ const correspondingOption = this.options().find((option) => {
1307
+ if (this._selectionModel?.isSelected(option.viewValue())) {
1308
+ return false;
1309
+ }
1310
+ try {
1311
+ return valueCompareFn?.(option.value(), value);
881
1312
  }
1313
+ catch (error) {
1314
+ if (isDevMode()) {
1315
+ console.warn(error);
1316
+ }
1317
+ return false;
1318
+ }
1319
+ });
1320
+ if (correspondingOption) {
1321
+ correspondingOption.selected.set(true);
1322
+ this._selectionModel?.select(correspondingOption.viewValue());
882
1323
  }
1324
+ return correspondingOption;
883
1325
  }
884
- focus(_origin, options) {
885
- const element = this._element.nativeElement;
886
- if (typeof element.focus === 'function') {
887
- element.focus(options);
1326
+ _clearSelection() {
1327
+ this._selectionModel?.clear();
1328
+ this.options().forEach((option) => {
1329
+ option.selected.set(false);
1330
+ });
1331
+ }
1332
+ _handleChange() {
1333
+ const selectionModelValues = this._selectionModel?.selected;
1334
+ if (this.multiSelect()) {
1335
+ this._onChange(selectionModelValues);
1336
+ }
1337
+ else {
1338
+ this._onChange(selectionModelValues?.[0]);
1339
+ }
1340
+ this._changeDetectorRef.markForCheck();
1341
+ }
1342
+ _highlightCorrectOption() {
1343
+ if (this._keyManager) {
1344
+ if (this._empty) {
1345
+ let firstEnabledOptionIndex = -1;
1346
+ for (let index = 0; index < this.options().length; index++) {
1347
+ const option = this.options()[index];
1348
+ if (!option.disabled) {
1349
+ firstEnabledOptionIndex = index;
1350
+ break;
1351
+ }
1352
+ }
1353
+ this._keyManager.setActiveItem(firstEnabledOptionIndex);
1354
+ }
1355
+ else {
1356
+ if (this._selectionModel) {
1357
+ const activeItem = this.options().find((option) => this._selectionModel?.isSelected(option.viewValue()));
1358
+ if (activeItem) {
1359
+ this._keyManager.setActiveItem(activeItem);
1360
+ }
1361
+ }
1362
+ }
888
1363
  }
889
1364
  }
890
- setActiveStyles() {
891
- if (!this._active()) {
892
- this._active.set(true);
1365
+ isOptionPreSelectedByValue(optionValue) {
1366
+ if (this._rawValue === undefined) {
1367
+ return false;
893
1368
  }
1369
+ if (this.multiSelect() && Array.isArray(this._rawValue)) {
1370
+ return this._rawValue.some((value) => optionValue != null && value === optionValue);
1371
+ }
1372
+ return optionValue === this._rawValue;
894
1373
  }
895
- setInactiveStyles() {
896
- if (this._active()) {
897
- this._active.set(false);
1374
+ _onFocus() {
1375
+ if (!this.disabled()) {
1376
+ this._focused.set(true);
898
1377
  }
899
1378
  }
900
- getLabel() {
901
- return this.viewValue();
1379
+ _onBlur() {
1380
+ this._focused.set(false);
1381
+ this._keyManager?.cancelTypeahead();
1382
+ if (!this.disabled() && !this.isPanelOpen()) {
1383
+ this._onTouched();
1384
+ this._changeDetectorRef.markForCheck();
1385
+ }
902
1386
  }
903
- _emitSelectionChangeEvent(selected, isUserInput = false) {
904
- if (this._multiSelect || !this.selected()) {
905
- this.onSelectionChange.emit(new IdsOptionSelectionChange(this, selected, isUserInput));
1387
+ _getAriaActiveDescendant() {
1388
+ if (this.isPanelOpen() && this._keyManager?.activeItem) {
1389
+ return this._keyManager.activeItem.id();
906
1390
  }
1391
+ return null;
907
1392
  }
908
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
909
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: IdsOptionComponent, isStandalone: true, selector: "ids-option", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, explicitViewValue: { classPropertyName: "explicitViewValue", publicName: "viewValue", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelectionChange: "onSelectionChange" }, host: { attributes: { "role": "option" }, listeners: { "click": "selectViaInteraction()", "keydown": "_handleKeydown($event)" }, properties: { "attr.aria-selected": "selected()", "attr.aria-disabled": "disabled.toString()" } }, providers: [
1393
+ focus(options) {
1394
+ this._elementRef.nativeElement.focus(options);
1395
+ }
1396
+ _onInputClick() {
1397
+ if (!this._focused() && !this.readonly() && !this.disabled() && this._searchText().length) {
1398
+ this.open();
1399
+ }
1400
+ }
1401
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsAutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1402
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: IdsAutocompleteComponent, isStandalone: true, selector: "ids-autocomplete[ngModel]:not([formControl]):not([formControlName]),\n ids-autocomplete[formControl]:not([ngModel]):not([formControlName]),\n ids-autocomplete[formControlName]:not([ngModel]):not([formControl])", inputs: { minChars: { classPropertyName: "minChars", publicName: "minChars", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, multiSelect: { classPropertyName: "multiSelect", publicName: "multiSelect", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelClearButton: { classPropertyName: "ariaLabelClearButton", publicName: "ariaLabelClearButton", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelToggleButton: { classPropertyName: "ariaLabelToggleButton", publicName: "ariaLabelToggleButton", isSignal: true, isRequired: false, transformFunction: null }, valueCompareFn: { classPropertyName: "valueCompareFn", publicName: "valueCompareFn", isSignal: true, isRequired: false, transformFunction: null }, sortCompareFn: { classPropertyName: "sortCompareFn", publicName: "sortCompareFn", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, typeaheadDebounceInterval: { classPropertyName: "typeaheadDebounceInterval", publicName: "typeaheadDebounceInterval", isSignal: true, isRequired: false, transformFunction: null }, hintLoading: { classPropertyName: "hintLoading", publicName: "hintLoading", isSignal: true, isRequired: false, transformFunction: null }, hintNoResults: { classPropertyName: "hintNoResults", publicName: "hintNoResults", isSignal: true, isRequired: false, transformFunction: null }, hintMinChars: { classPropertyName: "hintMinChars", publicName: "hintMinChars", isSignal: true, isRequired: false, transformFunction: null }, hintMaxLength: { classPropertyName: "hintMaxLength", publicName: "hintMaxLength", isSignal: true, isRequired: false, transformFunction: null }, panelClasses: { classPropertyName: "panelClasses", publicName: "panelClasses", isSignal: true, isRequired: false, transformFunction: null }, _searchText: { classPropertyName: "_searchText", publicName: "_searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { _searchText: "_searchTextChange" }, host: { attributes: { "role": "combobox", "aria-autocomplete": "list", "aria-haspopup": "listbox" }, listeners: { "keydown": "_handleKeydown($event)", "focus": "focus()", "blur": "_onBlur()" }, properties: { "attr.tabindex": "disabled() ? -1 : tabIndex()", "attr.aria-controls": "isPanelOpen() ? id() + \"-panel\" : null", "attr.aria-owns": "isPanelOpen() ? id() + \"-panel\" : null", "attr.aria-expanded": "isPanelOpen()", "attr.aria-label": "ariaLabel() || null", "attr.aria-labelledby": "ariaLabelledby() || null", "attr.aria-required": "required().toString()", "attr.aria-disabled": "disabled().toString()", "attr.aria-invalid": "hasErrorState()", "attr.aria-activedescendant": "_getAriaActiveDescendant()" } }, providers: [
1403
+ { provide: IDS_FORM_FIELD_CONTROL, useExisting: IdsAutocompleteComponent },
1404
+ { provide: IDS_OPTION_PARENT_COMPONENT, useExisting: IdsAutocompleteComponent },
910
1405
  {
911
- provide: IDS_PSEUDO_CHECKBOX_PARENT,
912
- useExisting: IdsOptionComponent,
1406
+ provide: NG_VALUE_ACCESSOR,
1407
+ useExisting: forwardRef(() => IdsAutocompleteComponent),
1408
+ multi: true,
913
1409
  },
914
- ], viewQueries: [{ propertyName: "_textElement", first: true, predicate: ["text"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (_multiSelect) {\n <ids-pseudo-checkbox aria-hidden=\"true\" [disabled]=\"_groupOrOptionIsDisabled()\" [checkboxState]=\"_pseudoCheckboxState()\" />\n}\n\n<div #text class=\"ids-option__text\"><ng-content /></div>\n\n@if (!_multiSelect && selected()) {\n <ids-icon fontIcon=\"done\" />\n}\n", dependencies: [{ kind: "component", type: IdsIconComponent, selector: "ids-icon", inputs: ["size", "sizeCollection", "variant", "fontIcon", "svgIcon", "aria-hidden"] }, { kind: "component", type: PseudoCheckboxComponent, selector: "ids-pseudo-checkbox", inputs: ["checkboxState", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1410
+ ], viewQueries: [{ propertyName: "options", predicate: IdsOptionComponent, descendants: true, isSignal: true }, { propertyName: "_panel", first: true, predicate: ["overlayPanel"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_inputElemment", first: true, predicate: ["fallbackOverlayOrigin"], descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@let isLoading = _resource.isLoading();\n@let optionsLength = _resource.value().length;\n@let maxOptionsLength = maxLength();\n\n<input\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n cdkOverlayOrigin\n idsInput\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"false\"\n [(ngModel)]=\"_searchText\"\n (click)=\"_onInputClick()\"\n/>\n@if (_searchText().length > 0) {\n <div idsFormFieldAction>\n <button\n type=\"button\"\n idsIconButton\n appearance=\"standard\"\n variant=\"surface\"\n size=\"dense\"\n [attr.aria-label]=\"ariaLabelClearButton()\"\n [idsTooltip]=\"ariaLabelClearButton()\"\n [idsTooltipDisabled]=\"!ariaLabelClearButton() || disabled()\"\n [idsTooltipIgnoreClipped]=\"true\"\n [disabled]=\"disabled()\"\n (click)=\"clear()\"\n >\n <ids-icon alt=\"\" aria-hidden=\"true\" fontIcon=\"close\" />\n </button>\n </div>\n}\n@if (!isLoading && optionsLength > 0) {\n <div idsFormFieldAction>\n <button\n type=\"button\"\n idsIconButton\n appearance=\"standard\"\n variant=\"surface\"\n size=\"dense\"\n [attr.aria-label]=\"ariaLabelToggleButton()\"\n [idsTooltip]=\"ariaLabelToggleButton()\"\n [idsTooltipDisabled]=\"!ariaLabelToggleButton() || disabled()\"\n [idsTooltipIgnoreClipped]=\"true\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n >\n <ids-icon alt=\"\" aria-hidden=\"true\" [fontIcon]=\"isPanelOpen() ? 'chevron-up' : 'chevron-down'\" />\n </button>\n </div>\n}\n@if (isLoading) {\n <div idsFormFieldAction>\n <ids-spinner sizeCollection=\"small\" size=\"compact\" variant=\"surface\" [isTrack]=\"true\" [aria-label]=\"hintLoading()\" />\n </div>\n}\n<ids-overlay-panel\n #overlayPanel\n variant=\"light\"\n [id]=\"id() + '-panel'\"\n [origin]=\"_preferredOverlayOrigin || fallbackOverlayOrigin\"\n [open]=\"isPanelOpen()\"\n [size]=\"parentSize()\"\n [width]=\"_overlayWidth\"\n [panelClasses]=\"_panelClasses()\"\n (closed)=\"isPanelOpen.set(false)\"\n>\n @let showHintLoading = isLoading;\n @let showHintMinChars = _searchText().length < minChars();\n @let showHintMaxLength = maxOptionsLength && optionsLength > maxOptionsLength;\n @let showHintNoResults = optionsLength === 0;\n\n @if (showHintLoading || showHintMinChars || showHintMaxLength || showHintNoResults) {\n <div class=\"ids-overlay-panel__autocomplete-message\">\n <ids-option disabled>\n @if (showHintLoading && !showHintMinChars) {\n {{ hintLoading() }}\n } @else if (showHintMinChars) {\n {{ hintMinChars() }}\n } @else if (showHintMaxLength) {\n {{ hintMaxLength() }}\n } @else if (showHintNoResults) {\n {{ hintNoResults() }}\n }\n </ids-option>\n </div>\n } @else {\n @for (option of _resource.value(); track $index) {\n <ids-option [value]=\"option\">{{ option }}</ids-option>\n }\n }\n</ids-overlay-panel>\n", dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IdsFormFieldActionDirective, selector: "[idsFormFieldAction]" }, { kind: "directive", type: IdsInputDirective, selector: "input[idsInput][ngModel]:not([formControl]):not([formControlName]),\n input[idsInput][formControl]:not([ngModel]):not([formControlName]),\n input[idsInput][formControlName]:not([ngModel]):not([formControl]),\n textarea[idsInput][ngModel]:not([formControl]):not([formControlName]),\n textarea[idsInput][formControl]:not([ngModel]):not([formControlName]),\n textarea[idsInput][formControlName]:not([ngModel]):not([formControl])", inputs: ["name", "type", "errorStateMatcher", "successStateMatcher"], exportAs: ["idsInput"] }, { kind: "component", type: IdsIconComponent, selector: "ids-icon", inputs: ["size", "sizeCollection", "variant", "fontIcon", "svgIcon", "aria-hidden"] }, { kind: "component", type: IdsIconButtonComponent, selector: "button[idsIconButton], a[idsIconButton]", inputs: ["appearance", "size", "variant", "disabled"] }, { kind: "component", type: IdsOverlayPanelComponent, selector: "ids-overlay-panel", inputs: ["open", "origin", "positions", "appearance", "size", "variant", "panelClasses", "width"], outputs: ["closed"] }, { kind: "component", type: IdsOptionComponent, selector: "ids-option", inputs: ["value", "viewValue", "disabled"], outputs: ["onSelectionChange"] }, { kind: "component", type: IdsSpinnerComponent, selector: "ids-spinner", inputs: ["size", "sizeCollection", "variant", "isTrack", "aria-label"] }, { kind: "directive", type: IdsTooltipDirective, selector: "[idsTooltip]", inputs: ["idsTooltip", "idsTooltipPosition", "idsTooltipSize", "idsTooltipVariant", "idsTooltipShowDelay", "idsTooltipHideDelay", "idsTooltipDisabled", "idsTooltipTouchGestures", "idsTooltipTextAlign", "idsTooltipClass", "idsTooltipShowPointer", "idsTooltipIgnoreClipped"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
915
1411
  }
916
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionComponent, decorators: [{
1412
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsAutocompleteComponent, decorators: [{
917
1413
  type: Component,
918
- args: [{ selector: 'ids-option', imports: [
1414
+ args: [{ selector: `ids-autocomplete[ngModel]:not([formControl]):not([formControlName]),
1415
+ ids-autocomplete[formControl]:not([ngModel]):not([formControlName]),
1416
+ ids-autocomplete[formControlName]:not([ngModel]):not([formControl])`, imports: [
1417
+ CdkOverlayOrigin,
1418
+ FormsModule,
1419
+ IdsFormFieldActionDirective,
1420
+ IdsInputDirective,
919
1421
  IdsIconComponent,
920
- PseudoCheckboxComponent,
1422
+ IdsIconButtonComponent,
1423
+ IdsOverlayPanelComponent,
1424
+ IdsOptionComponent,
1425
+ IdsSpinnerComponent,
1426
+ IdsTooltipDirective,
921
1427
  ], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
1428
+ { provide: IDS_FORM_FIELD_CONTROL, useExisting: IdsAutocompleteComponent },
1429
+ { provide: IDS_OPTION_PARENT_COMPONENT, useExisting: IdsAutocompleteComponent },
922
1430
  {
923
- provide: IDS_PSEUDO_CHECKBOX_PARENT,
924
- useExisting: IdsOptionComponent,
1431
+ provide: NG_VALUE_ACCESSOR,
1432
+ useExisting: forwardRef(() => IdsAutocompleteComponent),
1433
+ multi: true,
925
1434
  },
926
1435
  ], host: {
927
- 'role': 'option',
928
- '[attr.aria-selected]': 'selected()',
929
- '[attr.aria-disabled]': 'disabled.toString()',
930
- '(click)': 'selectViaInteraction()',
1436
+ role: 'combobox',
1437
+ 'aria-autocomplete': 'list',
1438
+ 'aria-haspopup': 'listbox',
1439
+ '[attr.tabindex]': 'disabled() ? -1 : tabIndex()',
1440
+ '[attr.aria-controls]': 'isPanelOpen() ? id() + "-panel" : null',
1441
+ '[attr.aria-owns]': 'isPanelOpen() ? id() + "-panel" : null',
1442
+ '[attr.aria-expanded]': 'isPanelOpen()',
1443
+ '[attr.aria-label]': 'ariaLabel() || null',
1444
+ '[attr.aria-labelledby]': 'ariaLabelledby() || null',
1445
+ '[attr.aria-required]': 'required().toString()',
1446
+ '[attr.aria-disabled]': 'disabled().toString()',
1447
+ '[attr.aria-invalid]': 'hasErrorState()',
1448
+ '[attr.aria-activedescendant]': '_getAriaActiveDescendant()',
931
1449
  '(keydown)': '_handleKeydown($event)',
932
- }, template: "@if (_multiSelect) {\n <ids-pseudo-checkbox aria-hidden=\"true\" [disabled]=\"_groupOrOptionIsDisabled()\" [checkboxState]=\"_pseudoCheckboxState()\" />\n}\n\n<div #text class=\"ids-option__text\"><ng-content /></div>\n\n@if (!_multiSelect && selected()) {\n <ids-icon fontIcon=\"done\" />\n}\n" }]
1450
+ '(focus)': 'focus()',
1451
+ '(blur)': '_onBlur()',
1452
+ }, template: "@let isLoading = _resource.isLoading();\n@let optionsLength = _resource.value().length;\n@let maxOptionsLength = maxLength();\n\n<input\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n cdkOverlayOrigin\n idsInput\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"false\"\n [(ngModel)]=\"_searchText\"\n (click)=\"_onInputClick()\"\n/>\n@if (_searchText().length > 0) {\n <div idsFormFieldAction>\n <button\n type=\"button\"\n idsIconButton\n appearance=\"standard\"\n variant=\"surface\"\n size=\"dense\"\n [attr.aria-label]=\"ariaLabelClearButton()\"\n [idsTooltip]=\"ariaLabelClearButton()\"\n [idsTooltipDisabled]=\"!ariaLabelClearButton() || disabled()\"\n [idsTooltipIgnoreClipped]=\"true\"\n [disabled]=\"disabled()\"\n (click)=\"clear()\"\n >\n <ids-icon alt=\"\" aria-hidden=\"true\" fontIcon=\"close\" />\n </button>\n </div>\n}\n@if (!isLoading && optionsLength > 0) {\n <div idsFormFieldAction>\n <button\n type=\"button\"\n idsIconButton\n appearance=\"standard\"\n variant=\"surface\"\n size=\"dense\"\n [attr.aria-label]=\"ariaLabelToggleButton()\"\n [idsTooltip]=\"ariaLabelToggleButton()\"\n [idsTooltipDisabled]=\"!ariaLabelToggleButton() || disabled()\"\n [idsTooltipIgnoreClipped]=\"true\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n >\n <ids-icon alt=\"\" aria-hidden=\"true\" [fontIcon]=\"isPanelOpen() ? 'chevron-up' : 'chevron-down'\" />\n </button>\n </div>\n}\n@if (isLoading) {\n <div idsFormFieldAction>\n <ids-spinner sizeCollection=\"small\" size=\"compact\" variant=\"surface\" [isTrack]=\"true\" [aria-label]=\"hintLoading()\" />\n </div>\n}\n<ids-overlay-panel\n #overlayPanel\n variant=\"light\"\n [id]=\"id() + '-panel'\"\n [origin]=\"_preferredOverlayOrigin || fallbackOverlayOrigin\"\n [open]=\"isPanelOpen()\"\n [size]=\"parentSize()\"\n [width]=\"_overlayWidth\"\n [panelClasses]=\"_panelClasses()\"\n (closed)=\"isPanelOpen.set(false)\"\n>\n @let showHintLoading = isLoading;\n @let showHintMinChars = _searchText().length < minChars();\n @let showHintMaxLength = maxOptionsLength && optionsLength > maxOptionsLength;\n @let showHintNoResults = optionsLength === 0;\n\n @if (showHintLoading || showHintMinChars || showHintMaxLength || showHintNoResults) {\n <div class=\"ids-overlay-panel__autocomplete-message\">\n <ids-option disabled>\n @if (showHintLoading && !showHintMinChars) {\n {{ hintLoading() }}\n } @else if (showHintMinChars) {\n {{ hintMinChars() }}\n } @else if (showHintMaxLength) {\n {{ hintMaxLength() }}\n } @else if (showHintNoResults) {\n {{ hintNoResults() }}\n }\n </ids-option>\n </div>\n } @else {\n @for (option of _resource.value(); track $index) {\n <ids-option [value]=\"option\">{{ option }}</ids-option>\n }\n }\n</ids-overlay-panel>\n" }]
933
1453
  }], ctorParameters: () => [] });
934
- function _countGroupLabelsBeforeOption(optionIndex, options, optionGroups) {
935
- if (optionGroups.length) {
936
- let groupCounter = 0;
937
- for (let i = 0; i < optionIndex + 1; i++) {
938
- if (options[i].group && options[i].group === optionGroups[groupCounter]) {
939
- groupCounter++;
940
- }
941
- }
942
- return groupCounter;
1454
+
1455
+ class IdsFieldsetRowComponent extends ComponentBase {
1456
+ constructor() {
1457
+ super(...arguments);
1458
+ this._hostClasses = signal(this._getHostClasses([]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
943
1459
  }
944
- return 0;
1460
+ get _hostName() {
1461
+ return 'fieldset-row';
1462
+ }
1463
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetRowComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1464
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: IdsFieldsetRowComponent, isStandalone: true, selector: "ids-fieldset-row", usesInheritance: true, ngImport: i0, template: "<ng-content />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
945
1465
  }
946
- function _getOptionScrollPosition(optionOffset, optionHeight, currentScrollPosition, panelHeight) {
947
- if (optionOffset < currentScrollPosition) {
948
- return optionOffset;
1466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsFieldsetRowComponent, decorators: [{
1467
+ type: Component,
1468
+ args: [{ selector: 'ids-fieldset-row', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n" }]
1469
+ }] });
1470
+
1471
+ const Message = {
1472
+ HINT: 'hint',
1473
+ ERROR: 'error',
1474
+ SUCCESS: 'success',
1475
+ };
1476
+
1477
+ class IdsOptionGroupComponent extends ComponentBase {
1478
+ constructor() {
1479
+ super(...arguments);
1480
+ this._parent = inject(IDS_OPTION_PARENT_COMPONENT);
1481
+ this._inert = this._parent?.inertGroups ?? false;
1482
+ this.label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
1483
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: coerceBooleanAttribute }] : [{ transform: coerceBooleanAttribute }]));
1484
+ this._labelId = computed(() => `${this.id()}-label`, ...(ngDevMode ? [{ debugName: "_labelId" }] : []));
1485
+ this._hostClasses = computed(() => this._getHostClasses([
1486
+ this.disabled() ? 'disabled' : null,
1487
+ this._parent.parentSize(),
1488
+ this._parent.parentVariant(),
1489
+ ]), ...(ngDevMode ? [{ debugName: "_hostClasses" }] : []));
949
1490
  }
950
- if (optionOffset + optionHeight > currentScrollPosition + panelHeight) {
951
- return Math.max(0, optionOffset - panelHeight + optionHeight);
1491
+ get _hostName() {
1492
+ return 'option-group';
952
1493
  }
953
- return currentScrollPosition;
1494
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1495
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.7", type: IdsOptionGroupComponent, isStandalone: true, selector: "ids-option-group", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.role": "_inert ? null : \"group\"", "attr.aria-disabled": "_inert ? null : disabled().toString()", "attr.aria-labelledby": "_inert ? null : _labelId()" } }, providers: [{ provide: IDS_OPTION_GROUP, useExisting: IdsOptionGroupComponent }], usesInheritance: true, ngImport: i0, template: "<div role=\"presentation\" class=\"ids-option-group__label\" [id]=\"_labelId()\">\n <div class=\"ids-option-group__text\">{{ label() }}</div>\n</div>\n<ng-content select=\"ids-option, ng-container\" />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
954
1496
  }
1497
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsOptionGroupComponent, decorators: [{
1498
+ type: Component,
1499
+ args: [{ selector: 'ids-option-group', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: IDS_OPTION_GROUP, useExisting: IdsOptionGroupComponent }], host: {
1500
+ '[attr.role]': '_inert ? null : "group"',
1501
+ '[attr.aria-disabled]': '_inert ? null : disabled().toString()',
1502
+ '[attr.aria-labelledby]': '_inert ? null : _labelId()',
1503
+ }, template: "<div role=\"presentation\" class=\"ids-option-group__label\" [id]=\"_labelId()\">\n <div class=\"ids-option-group__text\">{{ label() }}</div>\n</div>\n<ng-content select=\"ids-option, ng-container\" />\n" }]
1504
+ }] });
955
1505
 
956
1506
  class IdsLabelDirective {
957
1507
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: IdsLabelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
@@ -969,5 +1519,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImpor
969
1519
  * Generated bundle index. Do not edit.
970
1520
  */
971
1521
 
972
- export { AbstractErrorStateMatcher, AbstractSuccessStateMatcher, ErrorStateMatcher, ErrorStateTracker, IDS_FIELDSET_DEFAULT_CONFIG, IDS_FIELDSET_DEFAULT_CONFIG_FACTORY, IDS_FORM_FIELD_CONTROL, IDS_FORM_FIELD_DEFAULT_CONFIG, IDS_FORM_FIELD_DEFAULT_CONFIG_FACTORY, IDS_INPUT_DEFAULT_CONFIG, IDS_INPUT_DEFAULT_CONFIG_FACTORY, IDS_MESSAGE_DEFAULT_CONFIG, IDS_MESSAGE_DEFAULT_CONFIG_FACTORY, IDS_OPTION_GROUP, IDS_OPTION_PARENT_COMPONENT, IDS_PSEUDO_CHECKBOX_PARENT, IdsErrorDefinitionDirective, IdsErrorMessageComponent, IdsFieldsetComponent, IdsFieldsetMessageDirective, IdsFieldsetRowComponent, IdsFormFieldActionDirective, IdsFormFieldComponent, IdsFormFieldControl, IdsFormFieldVariant, IdsHintMessageComponent, IdsInputDirective, IdsLabelDirective, IdsMessageDirective, IdsMessagePrefixDirective, IdsMessageSuffixDirective, IdsMessageVariant, IdsOptionComponent, IdsOptionGroupComponent, IdsOptionSelectionChange, IdsPrefixDirective, IdsPseudoCheckboxState, IdsSuccessMessageComponent, IdsSuffixDirective, IdsValidators, Message, PseudoCheckboxComponent, SuccessStateMatcher, SuccessStateTracker, _countGroupLabelsBeforeOption, _getOptionScrollPosition, formFieldControlClass, requiredFalseValidator, requiredTrueValidator, requiredValidator };
1522
+ export { AbstractErrorStateMatcher, AbstractSuccessStateMatcher, ErrorStateMatcher, ErrorStateTracker, IDS_AUTOCOMPLETE_DEFAULT_CONFIG, IDS_AUTOCOMPLETE_DEFAULT_CONFIG_FACTORY, IDS_AUTOCOMPLETE_LOADER, IDS_FIELDSET_DEFAULT_CONFIG, IDS_FIELDSET_DEFAULT_CONFIG_FACTORY, IDS_FORM_FIELD_CONTROL, IDS_FORM_FIELD_DEFAULT_CONFIG, IDS_FORM_FIELD_DEFAULT_CONFIG_FACTORY, IDS_INPUT_DEFAULT_CONFIG, IDS_INPUT_DEFAULT_CONFIG_FACTORY, IDS_MESSAGE_DEFAULT_CONFIG, IDS_MESSAGE_DEFAULT_CONFIG_FACTORY, IDS_OPTION_GROUP, IDS_OPTION_PARENT_COMPONENT, IDS_PSEUDO_CHECKBOX_PARENT, IdsAutocompleteComponent, IdsErrorDefinitionDirective, IdsErrorMessageComponent, IdsFieldsetComponent, IdsFieldsetMessageDirective, IdsFieldsetRowComponent, IdsFormFieldActionDirective, IdsFormFieldComponent, IdsFormFieldControl, IdsFormFieldVariant, IdsHintMessageComponent, IdsInputDirective, IdsLabelDirective, IdsMessageDirective, IdsMessagePrefixDirective, IdsMessageSuffixDirective, IdsMessageVariant, IdsOptionComponent, IdsOptionGroupComponent, IdsOptionSelectionChange, IdsPrefixDirective, IdsPseudoCheckboxState, IdsSuccessMessageComponent, IdsSuffixDirective, IdsValidators, Message, PseudoCheckboxComponent, SuccessStateMatcher, SuccessStateTracker, _countGroupLabelsBeforeOption, _getOptionScrollPosition, formFieldControlClass, requiredFalseValidator, requiredTrueValidator, requiredValidator };
973
1523
  //# sourceMappingURL=i-cell-ids-angular-forms.mjs.map