@egose/shadcn-theme-ng 0.6.0 → 0.6.1
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.
- package/README.md +119 -1
- package/autocomplete/fesm2022/autocomplete.mjs +14 -4
- package/autocomplete/types/autocomplete.d.ts +4 -1
- package/checkbox/README.md +6 -2
- package/checkbox/fesm2022/checkbox.mjs +11 -7
- package/checkbox/types/checkbox.d.ts +6 -4
- package/combobox/fesm2022/combobox.mjs +13 -7
- package/combobox/types/combobox.d.ts +8 -2
- package/data-table/README.md +10 -0
- package/data-table/fesm2022/data-table.mjs +48 -12
- package/data-table/types/data-table.d.ts +16 -4
- package/date-picker/README.md +41 -9
- package/date-picker/fesm2022/date-picker.mjs +265 -59
- package/date-picker/types/date-picker.d.ts +58 -27
- package/form-autocomplete/README.md +4 -2
- package/form-autocomplete/fesm2022/form-autocomplete.mjs +19 -6
- package/form-autocomplete/types/form-autocomplete.d.ts +9 -3
- package/form-combobox/README.md +4 -2
- package/form-combobox/fesm2022/form-combobox.mjs +23 -6
- package/form-combobox/types/form-combobox.d.ts +10 -3
- package/form-input-otp/README.md +7 -5
- package/form-input-otp/fesm2022/form-input-otp.mjs +20 -8
- package/form-input-otp/types/form-input-otp.d.ts +9 -3
- package/form-searchable-multiselect/README.md +15 -1
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +15 -3
- package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +9 -1
- package/form-slider/README.md +3 -1
- package/form-slider/fesm2022/form-slider.mjs +19 -6
- package/form-slider/types/form-slider.d.ts +9 -3
- package/form-toggle/README.md +22 -18
- package/form-toggle/fesm2022/form-toggle.mjs +22 -9
- package/form-toggle/types/form-toggle.d.ts +6 -2
- package/input-otp/README.md +33 -9
- package/input-otp/fesm2022/input-otp.mjs +127 -11
- package/input-otp/types/input-otp.d.ts +24 -4
- package/package.json +1 -1
- package/pagination/README.md +21 -12
- package/pagination/fesm2022/pagination.mjs +73 -65
- package/pagination/types/pagination.d.ts +21 -8
- package/phone-input/README.md +16 -0
- package/phone-input/fesm2022/phone-input.mjs +41 -3
- package/phone-input/types/phone-input.d.ts +5 -2
- package/searchable-multiselect/README.md +62 -40
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +59 -32
- package/searchable-multiselect/types/searchable-multiselect.d.ts +23 -6
- package/slider/fesm2022/slider.mjs +9 -5
- package/slider/types/slider.d.ts +6 -2
- package/stepper/README.md +39 -19
- package/stepper/fesm2022/stepper.mjs +64 -12
- package/stepper/types/stepper.d.ts +12 -1
|
@@ -11,7 +11,23 @@ import * as _spartan_ng_brain_popover from '@spartan-ng/brain/popover';
|
|
|
11
11
|
import { BrnPopover } from '@spartan-ng/brain/popover';
|
|
12
12
|
import * as i1$1 from '@spartan-ng/brain/field';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/** Internal input lifecycle shared by the single, range and multi pickers. */
|
|
15
|
+
declare abstract class HlmConstrainedDateInput<V> extends BrnDateInput<V> {
|
|
16
|
+
private readonly _commitState;
|
|
17
|
+
protected abstract readonly: () => boolean;
|
|
18
|
+
protected readonly _inputValue: _angular_core.WritableSignal<string>;
|
|
19
|
+
/** Rejected text stays invalid until a successful commit, clear, or external value write. */
|
|
20
|
+
readonly inputInvalid: _angular_core.WritableSignal<boolean>;
|
|
21
|
+
protected _commitDate(): void;
|
|
22
|
+
protected _handleBlur(): void;
|
|
23
|
+
protected _handleEnter(event: Event): void;
|
|
24
|
+
protected _handleFocus(): void;
|
|
25
|
+
protected _clear(): void;
|
|
26
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HlmConstrainedDateInput<any>, never>;
|
|
27
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HlmConstrainedDateInput<any>, never, never, {}, {}, never, never, true, never>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare class HlmDateMultiInput<T> extends HlmConstrainedDateInput<T[]> implements BrnDatePickerTriggerBase {
|
|
15
31
|
private readonly _config;
|
|
16
32
|
/** Native `name` attribute forwarded to the inner `<input>`. */
|
|
17
33
|
readonly name: _angular_core.InputSignal<string | undefined>;
|
|
@@ -26,9 +42,9 @@ declare class HlmDateMultiInput<T> extends BrnDateInput<T[]> implements BrnDateP
|
|
|
26
42
|
protected readonly $inputClass: _angular_core.Signal<string>;
|
|
27
43
|
constructor();
|
|
28
44
|
/**
|
|
29
|
-
* Parses input text into dates. Return `null` for invalid input
|
|
30
|
-
*
|
|
31
|
-
*
|
|
45
|
+
* Parses input text into dates. Return `null` for invalid input. Rejected
|
|
46
|
+
* text stays editable and aria-invalid; the committed value is preserved.
|
|
47
|
+
* Empty text explicitly clears on blur/Enter.
|
|
32
48
|
*
|
|
33
49
|
* Defaults to `parseDate` from `HlmDatePickerMultiConfig`.
|
|
34
50
|
*/
|
|
@@ -53,6 +69,10 @@ declare const HLM_DATE_PICKER_VALUE_ACCESSOR: {
|
|
|
53
69
|
};
|
|
54
70
|
declare class HlmDatePicker<T> implements BrnDatePickerBase<T>, ControlValueAccessor {
|
|
55
71
|
private readonly _config;
|
|
72
|
+
private readonly _dateAdapter;
|
|
73
|
+
private readonly _commitState;
|
|
74
|
+
private readonly _calendar;
|
|
75
|
+
private _restoringCalendar;
|
|
56
76
|
readonly popover: _angular_core.Signal<BrnPopover>;
|
|
57
77
|
private readonly _trigger;
|
|
58
78
|
/** Show dropdowns to navigate between months or years. */
|
|
@@ -91,13 +111,12 @@ declare class HlmDatePicker<T> implements BrnDatePickerBase<T>, ControlValueAcce
|
|
|
91
111
|
protected _onStateChange(state: BrnOverlayState): void;
|
|
92
112
|
protected _handleChange(value: T | undefined): void;
|
|
93
113
|
/**
|
|
94
|
-
* Commit a
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* is parsing user-entered values while typing.
|
|
114
|
+
* Commit a user value (null clears). Returns false without changing/emitting
|
|
115
|
+
* the model when disabled or when the raw/transformed date is invalid or
|
|
116
|
+
* outside the adapter's inclusive whole-day min/max bounds.
|
|
98
117
|
*/
|
|
99
|
-
updateDate(value: T | null):
|
|
100
|
-
/**
|
|
118
|
+
updateDate(value: T | null): boolean;
|
|
119
|
+
/** Programmatic CVA write: transforms without enforcing user constraints or emitting. Clears rejected text. */
|
|
101
120
|
writeValue(value: T | null): void;
|
|
102
121
|
registerOnChange(fn: ChangeFn<T | null>): void;
|
|
103
122
|
registerOnTouched(fn: TouchFn): void;
|
|
@@ -120,7 +139,7 @@ declare class HlmDatePickerAnchor {
|
|
|
120
139
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HlmDatePickerAnchor, "[hlmDatePickerAnchor]", never, { "hlmDatePickerAnchorForInput": { "alias": "hlmDatePickerAnchorFor"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
121
140
|
}
|
|
122
141
|
|
|
123
|
-
declare class HlmDatePickerInput<T> extends
|
|
142
|
+
declare class HlmDatePickerInput<T> extends HlmConstrainedDateInput<T> implements BrnDatePickerTriggerBase {
|
|
124
143
|
private readonly _config;
|
|
125
144
|
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
126
145
|
readonly ariaDescribedby: _angular_core.InputSignal<string | null>;
|
|
@@ -136,8 +155,8 @@ declare class HlmDatePickerInput<T> extends BrnDateInput<T> implements BrnDatePi
|
|
|
136
155
|
constructor();
|
|
137
156
|
/**
|
|
138
157
|
* Parses input text into a date value. Return `null` for invalid
|
|
139
|
-
* input
|
|
140
|
-
*
|
|
158
|
+
* input. Rejected text stays editable and aria-invalid; the committed value
|
|
159
|
+
* is preserved. Empty text explicitly clears on blur/Enter.
|
|
141
160
|
*
|
|
142
161
|
* Defaults to `parseDate` from `HlmDatePickerConfig`.
|
|
143
162
|
*/
|
|
@@ -162,6 +181,10 @@ declare const HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR: {
|
|
|
162
181
|
};
|
|
163
182
|
declare class HlmDatePickerMulti<T> implements BrnDatePickerBase<T[]>, ControlValueAccessor {
|
|
164
183
|
private readonly _config;
|
|
184
|
+
private readonly _dateAdapter;
|
|
185
|
+
private readonly _commitState;
|
|
186
|
+
private readonly _calendar;
|
|
187
|
+
private _restoringCalendar;
|
|
165
188
|
readonly popover: _angular_core.Signal<BrnPopover>;
|
|
166
189
|
private readonly _trigger;
|
|
167
190
|
/** Show dropdowns to navigate between months or years. */
|
|
@@ -170,7 +193,7 @@ declare class HlmDatePickerMulti<T> implements BrnDatePickerBase<T[]>, ControlVa
|
|
|
170
193
|
readonly min: _angular_core.InputSignal<T | undefined>;
|
|
171
194
|
/** The maximum date that can be selected. */
|
|
172
195
|
readonly max: _angular_core.InputSignal<T | undefined>;
|
|
173
|
-
/**
|
|
196
|
+
/** Deselection floor; selection can grow from empty below this count. Explicit clear is allowed. */
|
|
174
197
|
readonly minSelection: _angular_core.InputSignalWithTransform<number | undefined, NumberInput>;
|
|
175
198
|
/** The maximum selectable dates. */
|
|
176
199
|
readonly maxSelection: _angular_core.InputSignalWithTransform<number | undefined, NumberInput>;
|
|
@@ -201,13 +224,15 @@ declare class HlmDatePickerMulti<T> implements BrnDatePickerBase<T[]>, ControlVa
|
|
|
201
224
|
protected _onStateChange(state: BrnOverlayState): void;
|
|
202
225
|
protected _handleChange(value: T[] | undefined): void;
|
|
203
226
|
/**
|
|
204
|
-
* Commit dates
|
|
205
|
-
*
|
|
206
|
-
*
|
|
227
|
+
* Commit user dates, validating raw and transformed dates/counts. Returns
|
|
228
|
+
* false without changing/emitting on rejection. Min selection prevents
|
|
229
|
+
* reductions below the floor, but permits growth from empty. Null explicitly
|
|
230
|
+
* clears (emits []), bypassing the selection floor and transform.
|
|
207
231
|
*/
|
|
208
|
-
updateDate(value: T[] | null):
|
|
232
|
+
updateDate(value: T[] | null): boolean;
|
|
233
|
+
private _isSelectionAllowed;
|
|
209
234
|
touched(): void;
|
|
210
|
-
/**
|
|
235
|
+
/** Programmatic CVA write: transforms without enforcing user constraints or emitting. Clears rejected text. */
|
|
211
236
|
writeValue(value: T[] | null): void;
|
|
212
237
|
registerOnChange(fn: ChangeFn<T[]>): void;
|
|
213
238
|
registerOnTouched(fn: TouchFn): void;
|
|
@@ -246,7 +271,7 @@ declare class HlmDatePickerTrigger implements BrnDatePickerTriggerBase {
|
|
|
246
271
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<HlmDatePickerTrigger, "hlm-date-picker-trigger", never, { "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "buttonId": { "alias": "buttonId"; "required": false; "isSignal": true; }; "forceInvalid": { "alias": "forceInvalid"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "showTrigger": { "alias": "showTrigger"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
247
272
|
}
|
|
248
273
|
|
|
249
|
-
declare class HlmDateRangeInput<T> extends
|
|
274
|
+
declare class HlmDateRangeInput<T> extends HlmConstrainedDateInput<[T, T]> implements BrnDatePickerTriggerBase {
|
|
250
275
|
private readonly _config;
|
|
251
276
|
/** Native `name` attribute forwarded to the inner `<input>`. */
|
|
252
277
|
readonly name: _angular_core.InputSignal<string | undefined>;
|
|
@@ -262,8 +287,8 @@ declare class HlmDateRangeInput<T> extends BrnDateInput<[T, T]> implements BrnDa
|
|
|
262
287
|
constructor();
|
|
263
288
|
/**
|
|
264
289
|
* Parses input text into a date range. Return `null` for invalid
|
|
265
|
-
* input
|
|
266
|
-
*
|
|
290
|
+
* input. Rejected text stays editable and aria-invalid; the committed value
|
|
291
|
+
* is preserved. Empty text explicitly clears on blur/Enter.
|
|
267
292
|
*
|
|
268
293
|
* Defaults to `parseDate` from `HlmDateRangePickerConfig`.
|
|
269
294
|
*/
|
|
@@ -288,6 +313,10 @@ declare const HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR: {
|
|
|
288
313
|
};
|
|
289
314
|
declare class HlmDateRangePicker<T> implements BrnDatePickerBase<[T, T]>, ControlValueAccessor {
|
|
290
315
|
private readonly _config;
|
|
316
|
+
private readonly _dateAdapter;
|
|
317
|
+
private readonly _commitState;
|
|
318
|
+
private readonly _calendar;
|
|
319
|
+
private _restoringCalendar;
|
|
291
320
|
readonly popover: _angular_core.Signal<BrnPopover>;
|
|
292
321
|
private readonly _trigger;
|
|
293
322
|
/** Show dropdowns to navigate between months or years. */
|
|
@@ -325,14 +354,16 @@ declare class HlmDateRangePicker<T> implements BrnDatePickerBase<[T, T]>, Contro
|
|
|
325
354
|
protected _onStateChange(state: BrnOverlayState): void;
|
|
326
355
|
protected _handleStartDayChange(value: T | undefined): void;
|
|
327
356
|
protected _handleEndDateChange(value: T | undefined): void;
|
|
357
|
+
private _restoreCalendar;
|
|
328
358
|
/**
|
|
329
|
-
* Commit a range
|
|
330
|
-
*
|
|
331
|
-
*
|
|
359
|
+
* Commit a user range (null clears). Both raw/transformed endpoints must
|
|
360
|
+
* satisfy adapter whole-day bounds; the transformed range must be ordered.
|
|
361
|
+
* Returns false without changing/emitting the model on rejection or disabled.
|
|
332
362
|
*/
|
|
333
|
-
updateDate(value: [T, T] | null):
|
|
363
|
+
updateDate(value: [T, T] | null): boolean;
|
|
364
|
+
private _isRangeAllowed;
|
|
334
365
|
touched(): void;
|
|
335
|
-
/**
|
|
366
|
+
/** Programmatic CVA write: transforms without enforcing user constraints or emitting. Clears rejected text. */
|
|
336
367
|
writeValue(value: [T, T] | null): void;
|
|
337
368
|
registerOnChange(fn: ChangeFn<[T, T] | null>): void;
|
|
338
369
|
registerOnTouched(fn: TouchFn): void;
|
|
@@ -151,8 +151,10 @@ export class CityComponent {
|
|
|
151
151
|
## Accessibility notes
|
|
152
152
|
|
|
153
153
|
- Label `for` ↔ input `inputId` wiring is automatic via `effectiveId` — always pass a `label`.
|
|
154
|
-
- The
|
|
155
|
-
-
|
|
154
|
+
- The native input's `aria-describedby` references the displayed error when invalid and touched/dirty/submitted, otherwise the hint. Correction/reset restores the hint; absent messages leave no wrapper-owned reference.
|
|
155
|
+
- Optional `[aria-describedby]` (`string | null`, default `null`) adds consumer-owned IDs before the current message ID, with whitespace normalization and deduplication. Keep those external elements mounted; reserve `<effectiveId>-error` and `<effectiveId>-hint` for the wrapper. Use the input binding, not `[attr.aria-describedby]` on the wrapper host.
|
|
156
|
+
- `required` supplies the visual `*` and native `aria-required`; configure `Validators.required` independently. Native invalid state continues to follow the form control.
|
|
157
|
+
- Verification covers rendered DOM relationships and focus, not screen-reader announcement behavior. `HlmError` itself is not a live region.
|
|
156
158
|
|
|
157
159
|
## Theming / CSS variables
|
|
158
160
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, input, computed, Component } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, ChangeDetectorRef, DestroyRef, input, computed, Component } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { FormGroupDirective, ReactiveFormsModule, ControlContainer } from '@angular/forms';
|
|
5
5
|
import { injectEgFormErrorMessages, HlmFormIdGenerator, injectEgFormSharedConfig, resolveEgFormError, HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
|
|
6
6
|
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
7
7
|
import { HlmAutocomplete, HlmAutocompleteContent, HlmAutocompleteEmpty, HlmAutocompleteGroup, HlmAutocompleteInput, HlmAutocompleteItem, HlmAutocompleteList, HlmAutocompleteLabel } from '@egose/shadcn-theme-ng/autocomplete';
|
|
8
8
|
import { hlm } from '@egose/shadcn-theme-ng/utils';
|
|
9
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
9
10
|
|
|
10
11
|
const EgFormAutocompleteConfigToken = new InjectionToken('EgFormAutocompleteConfig');
|
|
11
12
|
function provideEgFormAutocompleteConfig(config) {
|
|
@@ -21,6 +22,14 @@ class EgFormAutocomplete {
|
|
|
21
22
|
generatedId = inject(HlmFormIdGenerator).generate('eg-form-autocomplete');
|
|
22
23
|
_config = injectEgFormAutocompleteConfig();
|
|
23
24
|
_shared = injectEgFormSharedConfig();
|
|
25
|
+
_cdr = inject(ChangeDetectorRef);
|
|
26
|
+
_destroyRef = inject(DestroyRef);
|
|
27
|
+
ngOnInit() {
|
|
28
|
+
// Submit/reset may change message visibility without changing the field's value or validity.
|
|
29
|
+
this.formGroupDirective.form.events
|
|
30
|
+
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
31
|
+
.subscribe(() => this._cdr.markForCheck());
|
|
32
|
+
}
|
|
24
33
|
label = input(undefined, /* @ts-ignore */
|
|
25
34
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
26
35
|
controlId = input(undefined, /* @ts-ignore */
|
|
@@ -38,6 +47,8 @@ class EgFormAutocomplete {
|
|
|
38
47
|
...(ngDevMode ? [{ debugName: "autoError" }] : /* istanbul ignore next */ []));
|
|
39
48
|
hint = input(undefined, /* @ts-ignore */
|
|
40
49
|
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
50
|
+
/** Consumer-owned description IDs, merged with the current error and hint IDs. */
|
|
51
|
+
ariaDescribedBy = input(null, { ...(ngDevMode ? { debugName: "ariaDescribedBy" } : /* istanbul ignore next */ {}), alias: 'aria-describedby' });
|
|
41
52
|
id = input(undefined, /* @ts-ignore */
|
|
42
53
|
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
43
54
|
placeholder = input('Type to search…', /* @ts-ignore */
|
|
@@ -90,6 +101,10 @@ class EgFormAutocomplete {
|
|
|
90
101
|
effectiveDisabled() {
|
|
91
102
|
return this.disabled() || !!this.formGroupDirective.form.get(this.controlName())?.disabled;
|
|
92
103
|
}
|
|
104
|
+
describedBy() {
|
|
105
|
+
const ids = [this.ariaDescribedBy(), this.showError() ? this.errorId() : this.hint() ? this.hintId() : null];
|
|
106
|
+
return [...new Set(ids.filter(Boolean).join(' ').split(/\s+/).filter(Boolean))].join(' ') || null;
|
|
107
|
+
}
|
|
93
108
|
// Styling
|
|
94
109
|
userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
|
|
95
110
|
labelClass = input('', /* @ts-ignore */
|
|
@@ -103,8 +118,6 @@ class EgFormAutocomplete {
|
|
|
103
118
|
hintClass = input('', /* @ts-ignore */
|
|
104
119
|
...(ngDevMode ? [{ debugName: "hintClass" }] : /* istanbul ignore next */ []));
|
|
105
120
|
// Computed classes (library base < global config < per-instance).
|
|
106
|
-
// NOTE: the autocomplete input exposes no aria-describedby, so error/hint
|
|
107
|
-
// ids render without an input-level describedby link.
|
|
108
121
|
$userClass = computed(() => hlm("w-full", this.userClass()), /* @ts-ignore */
|
|
109
122
|
...(ngDevMode ? [{ debugName: "$userClass" }] : /* istanbul ignore next */ []));
|
|
110
123
|
$labelClass = computed(() => hlm("mb-1", this._shared.labelClass, this._config.labelClass, this.labelClass()), /* @ts-ignore */
|
|
@@ -118,7 +131,7 @@ class EgFormAutocomplete {
|
|
|
118
131
|
$hintClass = computed(() => hlm("mt-0", this._shared.hintClass, this._config.hintClass, this.hintClass()), /* @ts-ignore */
|
|
119
132
|
...(ngDevMode ? [{ debugName: "$hintClass" }] : /* istanbul ignore next */ []));
|
|
120
133
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
121
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormAutocomplete, isStandalone: true, selector: "eg-form-autocomplete", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, controlId: { classPropertyName: "controlId", publicName: "controlId", isSignal: true, isRequired: false, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, autoError: { classPropertyName: "autoError", publicName: "autoError", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, labelClass: { classPropertyName: "labelClass", publicName: "labelClass", isSignal: true, isRequired: false, transformFunction: null }, controlClass: { classPropertyName: "controlClass", publicName: "controlClass", isSignal: true, isRequired: false, transformFunction: null }, inputClass: { classPropertyName: "inputClass", publicName: "inputClass", isSignal: true, isRequired: false, transformFunction: null }, errorClass: { classPropertyName: "errorClass", publicName: "errorClass", isSignal: true, isRequired: false, transformFunction: null }, hintClass: { classPropertyName: "hintClass", publicName: "hintClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "$userClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], ngImport: i0, template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div hlmAutocomplete [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\" [class]=\"$controlClass()\">\n <hlm-autocomplete-input
|
|
134
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormAutocomplete, isStandalone: true, selector: "eg-form-autocomplete", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, controlId: { classPropertyName: "controlId", publicName: "controlId", isSignal: true, isRequired: false, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, autoError: { classPropertyName: "autoError", publicName: "autoError", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, labelClass: { classPropertyName: "labelClass", publicName: "labelClass", isSignal: true, isRequired: false, transformFunction: null }, controlClass: { classPropertyName: "controlClass", publicName: "controlClass", isSignal: true, isRequired: false, transformFunction: null }, inputClass: { classPropertyName: "inputClass", publicName: "inputClass", isSignal: true, isRequired: false, transformFunction: null }, errorClass: { classPropertyName: "errorClass", publicName: "errorClass", isSignal: true, isRequired: false, transformFunction: null }, hintClass: { classPropertyName: "hintClass", publicName: "hintClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "$userClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], ngImport: i0, template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div hlmAutocomplete [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\" [class]=\"$controlClass()\">\n <hlm-autocomplete-input\n [inputId]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [aria-describedby]=\"describedBy()\"\n [required]=\"rqrd\"\n [class]=\"$inputClass()\"\n />\n <hlm-autocomplete-content>\n <div hlmAutocompleteList>\n <div hlmAutocompleteGroup>\n @for (option of options(); track option) {\n <hlm-autocomplete-item [value]=\"option\">{{ option }}</hlm-autocomplete-item>\n }\n </div>\n </div>\n <div hlmAutocompleteEmpty>{{ emptyText() }}</div>\n </hlm-autocomplete-content>\n </div>\n\n @if (showError()) {\n <hlm-error [id]=\"errorId()\" [class]=\"$errorClass()\">\n {{ resolvedError() }}\n </hlm-error>\n }\n\n @if (hnt) {\n <hlm-hint [id]=\"hintId()\" [class]=\"$hintClass()\">\n {{ hnt }}\n </hlm-hint>\n }\n </hlm-form-field>\n ", isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: HlmFormField, selector: "hlm-form-field", inputs: ["class"] }, { kind: "directive", type: HlmError, selector: "hlm-error", inputs: ["class"] }, { kind: "directive", type: HlmHint, selector: "hlm-hint", inputs: ["class"] }, { kind: "directive", type: HlmLabel, selector: "[hlmLabel]", inputs: ["class"] }, { kind: "directive", type: HlmAutocomplete, selector: "[hlmAutocomplete],hlm-autocomplete" }, { kind: "directive", type: HlmAutocompleteContent, selector: "[hlmAutocompleteContent],hlm-autocomplete-content" }, { kind: "directive", type: HlmAutocompleteEmpty, selector: "[hlmAutocompleteEmpty],hlm-autocomplete-empty" }, { kind: "directive", type: HlmAutocompleteGroup, selector: "[hlmAutocompleteGroup]" }, { kind: "component", type: HlmAutocompleteInput, selector: "hlm-autocomplete-input", inputs: ["inputId", "placeholder", "aria-describedby", "required", "showSearch", "showClear", "forceInvalid", "aria-invalid"] }, { kind: "component", type: HlmAutocompleteItem, selector: "hlm-autocomplete-item" }, { kind: "directive", type: HlmAutocompleteList, selector: "[hlmAutocompleteList]" }] });
|
|
122
135
|
}
|
|
123
136
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormAutocomplete, decorators: [{
|
|
124
137
|
type: Component,
|
|
@@ -144,9 +157,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
144
157
|
HlmAutocompleteList,
|
|
145
158
|
],
|
|
146
159
|
providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }],
|
|
147
|
-
template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div hlmAutocomplete [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\" [class]=\"$controlClass()\">\n <hlm-autocomplete-input
|
|
160
|
+
template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <div hlmAutocomplete [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\" [class]=\"$controlClass()\">\n <hlm-autocomplete-input\n [inputId]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [aria-describedby]=\"describedBy()\"\n [required]=\"rqrd\"\n [class]=\"$inputClass()\"\n />\n <hlm-autocomplete-content>\n <div hlmAutocompleteList>\n <div hlmAutocompleteGroup>\n @for (option of options(); track option) {\n <hlm-autocomplete-item [value]=\"option\">{{ option }}</hlm-autocomplete-item>\n }\n </div>\n </div>\n <div hlmAutocompleteEmpty>{{ emptyText() }}</div>\n </hlm-autocomplete-content>\n </div>\n\n @if (showError()) {\n <hlm-error [id]=\"errorId()\" [class]=\"$errorClass()\">\n {{ resolvedError() }}\n </hlm-error>\n }\n\n @if (hnt) {\n <hlm-hint [id]=\"hintId()\" [class]=\"$hintClass()\">\n {{ hnt }}\n </hlm-hint>\n }\n </hlm-form-field>\n ",
|
|
148
161
|
}]
|
|
149
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], controlId: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlId", required: false }] }], controlName: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlName", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], autoError: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoError", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], controlClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlClass", required: false }] }], inputClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputClass", required: false }] }], errorClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorClass", required: false }] }], hintClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hintClass", required: false }] }] } });
|
|
162
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], controlId: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlId", required: false }] }], controlName: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlName", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], autoError: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoError", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], controlClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlClass", required: false }] }], inputClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputClass", required: false }] }], errorClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorClass", required: false }] }], hintClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hintClass", required: false }] }] } });
|
|
150
163
|
|
|
151
164
|
/*
|
|
152
165
|
* Public API Surface of form-autocomplete
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { ValueProvider } from '@angular/core';
|
|
2
|
+
import { OnInit, ValueProvider } from '@angular/core';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
4
|
|
|
5
|
-
declare class EgFormAutocomplete {
|
|
5
|
+
declare class EgFormAutocomplete implements OnInit {
|
|
6
6
|
private readonly formGroupDirective;
|
|
7
7
|
private readonly _errorMessages;
|
|
8
8
|
private readonly generatedId;
|
|
9
9
|
private readonly _config;
|
|
10
10
|
private readonly _shared;
|
|
11
|
+
private readonly _cdr;
|
|
12
|
+
private readonly _destroyRef;
|
|
13
|
+
ngOnInit(): void;
|
|
11
14
|
label: _angular_core.InputSignal<string | undefined>;
|
|
12
15
|
controlId: _angular_core.InputSignal<string | undefined>;
|
|
13
16
|
controlName: _angular_core.InputSignal<string>;
|
|
@@ -19,6 +22,8 @@ declare class EgFormAutocomplete {
|
|
|
19
22
|
*/
|
|
20
23
|
autoError: _angular_core.InputSignal<boolean>;
|
|
21
24
|
hint: _angular_core.InputSignal<string | undefined>;
|
|
25
|
+
/** Consumer-owned description IDs, merged with the current error and hint IDs. */
|
|
26
|
+
ariaDescribedBy: _angular_core.InputSignal<string | null>;
|
|
22
27
|
id: _angular_core.InputSignal<string | undefined>;
|
|
23
28
|
placeholder: _angular_core.InputSignal<string>;
|
|
24
29
|
emptyText: _angular_core.InputSignal<string>;
|
|
@@ -47,6 +52,7 @@ declare class EgFormAutocomplete {
|
|
|
47
52
|
* wrapper-toggle + `control.disable()` cannot clobber CVA state.
|
|
48
53
|
*/
|
|
49
54
|
effectiveDisabled(): boolean;
|
|
55
|
+
protected describedBy(): string | null;
|
|
50
56
|
userClass: _angular_core.InputSignal<ClassValue>;
|
|
51
57
|
labelClass: _angular_core.InputSignal<string>;
|
|
52
58
|
controlClass: _angular_core.InputSignal<string>;
|
|
@@ -60,7 +66,7 @@ declare class EgFormAutocomplete {
|
|
|
60
66
|
$errorClass: _angular_core.Signal<string>;
|
|
61
67
|
$hintClass: _angular_core.Signal<string>;
|
|
62
68
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgFormAutocomplete, never>;
|
|
63
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormAutocomplete, "eg-form-autocomplete", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "controlName": { "alias": "controlName"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "autoError": { "alias": "autoError"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "controlClass": { "alias": "controlClass"; "required": false; "isSignal": true; }; "inputClass": { "alias": "inputClass"; "required": false; "isSignal": true; }; "errorClass": { "alias": "errorClass"; "required": false; "isSignal": true; }; "hintClass": { "alias": "hintClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
69
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormAutocomplete, "eg-form-autocomplete", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "controlName": { "alias": "controlName"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "autoError": { "alias": "autoError"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "controlClass": { "alias": "controlClass"; "required": false; "isSignal": true; }; "inputClass": { "alias": "inputClass"; "required": false; "isSignal": true; }; "errorClass": { "alias": "errorClass"; "required": false; "isSignal": true; }; "hintClass": { "alias": "hintClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
interface EgFormAutocompleteConfig {
|
package/form-combobox/README.md
CHANGED
|
@@ -176,8 +176,10 @@ export class FruitSingleComponent {
|
|
|
176
176
|
## Accessibility notes
|
|
177
177
|
|
|
178
178
|
- Label `for` ↔ chip-search-input `id` wiring is automatic via `effectiveId` — always pass a `label`.
|
|
179
|
-
-
|
|
180
|
-
-
|
|
179
|
+
- Multiple mode connects the native chip input to the displayed error (invalid + touched/dirty/submitted), otherwise the hint. Single mode connects both the native trigger button and portaled search input. Correction/reset restores hint descriptions and obsolete message IDs disappear.
|
|
180
|
+
- Optional `[aria-describedby]` (`string | null`, default `null`) adds consumer-owned IDs before the current message ID, with whitespace normalization and deduplication. Keep external elements mounted and reserve `<effectiveId>-error` / `-hint` for the wrapper. Use the input binding rather than `[attr.aria-describedby]` on the wrapper host.
|
|
181
|
+
- Single mode uses `<effectiveId>` for the labeled trigger and `<effectiveId>-search` for its search input, labeled by `<effectiveId>-label`; this avoids duplicate IDs while open. The search filters options, so required/invalid state belongs to the selected-value trigger. Multiple mode exposes that state on its chip input.
|
|
182
|
+
- `required` supplies the visual `*` and `aria-required` on the selected-value control; configure `Validators.required` independently. `HlmError` is not a live region; rendered DOM/focus tests do not establish screen-reader announcement behavior.
|
|
181
183
|
|
|
182
184
|
## Theming / CSS variables
|
|
183
185
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, viewChild, input, computed, Component } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, viewChild, ChangeDetectorRef, DestroyRef, input, computed, Component } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { FormGroupDirective, ReactiveFormsModule, ControlContainer } from '@angular/forms';
|
|
5
5
|
import { injectEgFormErrorMessages, HlmFormIdGenerator, injectEgFormSharedConfig, resolveEgFormError, HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng/form-field';
|
|
6
6
|
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
7
7
|
import { HlmCombobox, HlmComboboxChip, HlmComboboxChipInput, HlmComboboxChips, HlmComboboxContent, HlmComboboxEmpty, HlmComboboxInput, HlmComboboxItem, HlmComboboxList, HlmComboboxMultiple, HlmComboboxPortal, HlmComboboxTrigger } from '@egose/shadcn-theme-ng/combobox';
|
|
8
8
|
import { BrnComboboxMultiple, BrnCombobox } from '@spartan-ng/brain/combobox';
|
|
9
|
+
import { BrnFieldControlDescribedBy } from '@spartan-ng/brain/field';
|
|
9
10
|
import { hlm } from '@egose/shadcn-theme-ng/utils';
|
|
11
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
10
12
|
|
|
11
13
|
const EgFormComboboxConfigToken = new InjectionToken('EgFormComboboxConfig');
|
|
12
14
|
function provideEgFormComboboxConfig(config) {
|
|
@@ -26,6 +28,14 @@ class EgFormCombobox {
|
|
|
26
28
|
...(ngDevMode ? [{ debugName: "_picker" }] : /* istanbul ignore next */ []));
|
|
27
29
|
_single = viewChild((BrnCombobox), /* @ts-ignore */
|
|
28
30
|
...(ngDevMode ? [{ debugName: "_single" }] : /* istanbul ignore next */ []));
|
|
31
|
+
_cdr = inject(ChangeDetectorRef);
|
|
32
|
+
_destroyRef = inject(DestroyRef);
|
|
33
|
+
ngOnInit() {
|
|
34
|
+
// Submit/reset may change message visibility without changing the field's value or validity.
|
|
35
|
+
this.formGroupDirective.form.events
|
|
36
|
+
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
37
|
+
.subscribe(() => this._cdr.markForCheck());
|
|
38
|
+
}
|
|
29
39
|
label = input(undefined, /* @ts-ignore */
|
|
30
40
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
31
41
|
controlId = input(undefined, /* @ts-ignore */
|
|
@@ -43,6 +53,8 @@ class EgFormCombobox {
|
|
|
43
53
|
...(ngDevMode ? [{ debugName: "autoError" }] : /* istanbul ignore next */ []));
|
|
44
54
|
hint = input(undefined, /* @ts-ignore */
|
|
45
55
|
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
56
|
+
/** Consumer-owned description IDs, merged with the current error and hint IDs in both modes. */
|
|
57
|
+
ariaDescribedBy = input(null, { ...(ngDevMode ? { debugName: "ariaDescribedBy" } : /* istanbul ignore next */ {}), alias: 'aria-describedby' });
|
|
46
58
|
id = input(undefined, /* @ts-ignore */
|
|
47
59
|
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
48
60
|
placeholder = input('Pick…', /* @ts-ignore */
|
|
@@ -64,6 +76,8 @@ class EgFormCombobox {
|
|
|
64
76
|
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
65
77
|
effectiveId = computed(() => this.controlId() || this.id() || this.generatedId, /* @ts-ignore */
|
|
66
78
|
...(ngDevMode ? [{ debugName: "effectiveId" }] : /* istanbul ignore next */ []));
|
|
79
|
+
labelId = computed(() => `${this.effectiveId()}-label`, /* @ts-ignore */
|
|
80
|
+
...(ngDevMode ? [{ debugName: "labelId" }] : /* istanbul ignore next */ []));
|
|
67
81
|
errorId = computed(() => `${this.effectiveId()}-error`, /* @ts-ignore */
|
|
68
82
|
...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
|
|
69
83
|
hintId = computed(() => `${this.effectiveId()}-hint`, /* @ts-ignore */
|
|
@@ -108,6 +122,10 @@ class EgFormCombobox {
|
|
|
108
122
|
effectiveDisabled() {
|
|
109
123
|
return this.disabled() || !!this.formGroupDirective.form.get(this.controlName())?.disabled;
|
|
110
124
|
}
|
|
125
|
+
describedBy() {
|
|
126
|
+
const ids = [this.ariaDescribedBy(), this.showError() ? this.errorId() : this.hint() ? this.hintId() : null];
|
|
127
|
+
return [...new Set(ids.filter(Boolean).join(' ').split(/\s+/).filter(Boolean))].join(' ') || null;
|
|
128
|
+
}
|
|
111
129
|
// Styling
|
|
112
130
|
userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
|
|
113
131
|
labelClass = input('', /* @ts-ignore */
|
|
@@ -121,8 +139,6 @@ class EgFormCombobox {
|
|
|
121
139
|
hintClass = input('', /* @ts-ignore */
|
|
122
140
|
...(ngDevMode ? [{ debugName: "hintClass" }] : /* istanbul ignore next */ []));
|
|
123
141
|
// Computed classes (library base < global config < per-instance).
|
|
124
|
-
// NOTE: the chip search input exposes no aria-describedby, so error/hint
|
|
125
|
-
// ids render without an input-level describedby link.
|
|
126
142
|
$userClass = computed(() => hlm("w-full", this.userClass()), /* @ts-ignore */
|
|
127
143
|
...(ngDevMode ? [{ debugName: "$userClass" }] : /* istanbul ignore next */ []));
|
|
128
144
|
$labelClass = computed(() => hlm("mb-1", this._shared.labelClass, this._config.labelClass, this.labelClass()), /* @ts-ignore */
|
|
@@ -136,7 +152,7 @@ class EgFormCombobox {
|
|
|
136
152
|
$hintClass = computed(() => hlm("mt-0", this._shared.hintClass, this._config.hintClass, this.hintClass()), /* @ts-ignore */
|
|
137
153
|
...(ngDevMode ? [{ debugName: "$hintClass" }] : /* istanbul ignore next */ []));
|
|
138
154
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormCombobox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
139
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormCombobox, isStandalone: true, selector: "eg-form-combobox", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, controlId: { classPropertyName: "controlId", publicName: "controlId", isSignal: true, isRequired: false, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, autoError: { classPropertyName: "autoError", publicName: "autoError", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, labelClass: { classPropertyName: "labelClass", publicName: "labelClass", isSignal: true, isRequired: false, transformFunction: null }, controlClass: { classPropertyName: "controlClass", publicName: "controlClass", isSignal: true, isRequired: false, transformFunction: null }, chipsClass: { classPropertyName: "chipsClass", publicName: "chipsClass", isSignal: true, isRequired: false, transformFunction: null }, errorClass: { classPropertyName: "errorClass", publicName: "errorClass", isSignal: true, isRequired: false, transformFunction: null }, hintClass: { classPropertyName: "hintClass", publicName: "hintClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "$userClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], viewQueries: [{ propertyName: "_picker", first: true, predicate: (BrnComboboxMultiple), descendants: true, isSignal: true }, { propertyName: "_single", first: true, predicate: (BrnCombobox), descendants: true, isSignal: true }], ngImport: i0, template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n @if (mode() === 'single') {\n <hlm-combobox [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\">\n <hlm-combobox-trigger
|
|
155
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormCombobox, isStandalone: true, selector: "eg-form-combobox", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, controlId: { classPropertyName: "controlId", publicName: "controlId", isSignal: true, isRequired: false, transformFunction: null }, controlName: { classPropertyName: "controlName", publicName: "controlName", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, autoError: { classPropertyName: "autoError", publicName: "autoError", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, labelClass: { classPropertyName: "labelClass", publicName: "labelClass", isSignal: true, isRequired: false, transformFunction: null }, controlClass: { classPropertyName: "controlClass", publicName: "controlClass", isSignal: true, isRequired: false, transformFunction: null }, chipsClass: { classPropertyName: "chipsClass", publicName: "chipsClass", isSignal: true, isRequired: false, transformFunction: null }, errorClass: { classPropertyName: "errorClass", publicName: "errorClass", isSignal: true, isRequired: false, transformFunction: null }, hintClass: { classPropertyName: "hintClass", publicName: "hintClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "$userClass()" } }, providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }], viewQueries: [{ propertyName: "_picker", first: true, predicate: (BrnComboboxMultiple), descendants: true, isSignal: true }, { propertyName: "_single", first: true, predicate: (BrnCombobox), descendants: true, isSignal: true }], ngImport: i0, template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [id]=\"labelId()\" [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n @if (mode() === 'single') {\n <hlm-combobox [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\">\n <hlm-combobox-trigger\n [buttonId]=\"effectiveId()\"\n [aria-describedby]=\"describedBy()\"\n [required]=\"rqrd\"\n [class]=\"$controlClass()\"\n >\n {{ singleDisplay() ?? placeholder() }}\n </hlm-combobox-trigger>\n <hlm-combobox-content *hlmComboboxPortal>\n <hlm-combobox-input\n [inputId]=\"effectiveId() + '-search'\"\n [aria-labelledby]=\"lbl ? labelId() : null\"\n [aria-describedby]=\"describedBy()\"\n [placeholder]=\"placeholder()\"\n />\n <div hlmComboboxList>\n @for (option of options(); track option) {\n <hlm-combobox-item [value]=\"option\">{{ option }}</hlm-combobox-item>\n }\n </div>\n <div hlmComboboxEmpty>{{ emptyText() }}</div>\n </hlm-combobox-content>\n </hlm-combobox>\n } @else {\n <hlm-combobox-multiple [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\" [class]=\"$controlClass()\">\n <hlm-combobox-chips [class]=\"$chipsClass()\">\n @for (v of selectedValues(); track v) {\n <hlm-combobox-chip [value]=\"v\">{{ v }}</hlm-combobox-chip>\n }\n <input\n hlmComboboxChipInput\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n brnFieldControlDescribedBy\n [aria-describedby]=\"describedBy()\"\n [attr.aria-required]=\"rqrd || null\"\n />\n </hlm-combobox-chips>\n <hlm-combobox-content *hlmComboboxPortal>\n <div hlmComboboxList>\n @for (option of options(); track option) {\n <hlm-combobox-item [value]=\"option\">{{ option }}</hlm-combobox-item>\n }\n </div>\n <div hlmComboboxEmpty>{{ emptyText() }}</div>\n </hlm-combobox-content>\n </hlm-combobox-multiple>\n }\n\n @if (showError()) {\n <hlm-error [id]=\"errorId()\" [class]=\"$errorClass()\">\n {{ resolvedError() }}\n </hlm-error>\n }\n\n @if (hnt) {\n <hlm-hint [id]=\"hintId()\" [class]=\"$hintClass()\">\n {{ hnt }}\n </hlm-hint>\n }\n </hlm-form-field>\n ", isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: HlmFormField, selector: "hlm-form-field", inputs: ["class"] }, { kind: "directive", type: HlmError, selector: "hlm-error", inputs: ["class"] }, { kind: "directive", type: HlmHint, selector: "hlm-hint", inputs: ["class"] }, { kind: "directive", type: HlmLabel, selector: "[hlmLabel]", inputs: ["class"] }, { kind: "directive", type: HlmCombobox, selector: "[hlmCombobox],hlm-combobox" }, { kind: "component", type: HlmComboboxChip, selector: "hlm-combobox-chip", inputs: ["showRemove"] }, { kind: "directive", type: HlmComboboxChipInput, selector: "input[hlmComboboxChipInput]" }, { kind: "directive", type: HlmComboboxChips, selector: "[hlmComboboxChips],hlm-combobox-chips", inputs: ["forceInvalid"] }, { kind: "directive", type: HlmComboboxContent, selector: "[hlmComboboxContent],hlm-combobox-content" }, { kind: "directive", type: HlmComboboxEmpty, selector: "[hlmComboboxEmpty],hlm-combobox-empty" }, { kind: "component", type: HlmComboboxInput, selector: "hlm-combobox-input", inputs: ["inputId", "placeholder", "aria-describedby", "aria-labelledby", "showTrigger", "showClear", "forceInvalid", "aria-invalid"] }, { kind: "component", type: HlmComboboxItem, selector: "hlm-combobox-item" }, { kind: "directive", type: HlmComboboxList, selector: "[hlmComboboxList]" }, { kind: "directive", type: HlmComboboxMultiple, selector: "[hlmComboboxMultiple],hlm-combobox-multiple" }, { kind: "directive", type: HlmComboboxPortal, selector: "[hlmComboboxPortal]" }, { kind: "component", type: HlmComboboxTrigger, selector: "hlm-combobox-trigger", inputs: ["class", "buttonId", "aria-describedby", "required", "variant", "forceInvalid"] }, { kind: "directive", type: BrnFieldControlDescribedBy, selector: "[brnFieldControlDescribedBy]", inputs: ["aria-describedby"] }] });
|
|
140
156
|
}
|
|
141
157
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormCombobox, decorators: [{
|
|
142
158
|
type: Component,
|
|
@@ -164,11 +180,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
164
180
|
HlmComboboxMultiple,
|
|
165
181
|
HlmComboboxPortal,
|
|
166
182
|
HlmComboboxTrigger,
|
|
183
|
+
BrnFieldControlDescribedBy,
|
|
167
184
|
],
|
|
168
185
|
providers: [{ provide: ControlContainer, useExisting: FormGroupDirective }],
|
|
169
|
-
template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n @if (mode() === 'single') {\n <hlm-combobox [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\">\n <hlm-combobox-trigger
|
|
186
|
+
template: "\n @let lbl = label();\n @let cnm = controlName();\n @let hnt = hint();\n @let rqrd = required();\n\n <hlm-form-field>\n @if (lbl) {\n <label hlmLabel [id]=\"labelId()\" [for]=\"effectiveId()\" [class]=\"$labelClass()\"\n >{{ lbl }}\n @if (rqrd) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n @if (mode() === 'single') {\n <hlm-combobox [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\">\n <hlm-combobox-trigger\n [buttonId]=\"effectiveId()\"\n [aria-describedby]=\"describedBy()\"\n [required]=\"rqrd\"\n [class]=\"$controlClass()\"\n >\n {{ singleDisplay() ?? placeholder() }}\n </hlm-combobox-trigger>\n <hlm-combobox-content *hlmComboboxPortal>\n <hlm-combobox-input\n [inputId]=\"effectiveId() + '-search'\"\n [aria-labelledby]=\"lbl ? labelId() : null\"\n [aria-describedby]=\"describedBy()\"\n [placeholder]=\"placeholder()\"\n />\n <div hlmComboboxList>\n @for (option of options(); track option) {\n <hlm-combobox-item [value]=\"option\">{{ option }}</hlm-combobox-item>\n }\n </div>\n <div hlmComboboxEmpty>{{ emptyText() }}</div>\n </hlm-combobox-content>\n </hlm-combobox>\n } @else {\n <hlm-combobox-multiple [formControlName]=\"cnm\" [disabled]=\"effectiveDisabled()\" [class]=\"$controlClass()\">\n <hlm-combobox-chips [class]=\"$chipsClass()\">\n @for (v of selectedValues(); track v) {\n <hlm-combobox-chip [value]=\"v\">{{ v }}</hlm-combobox-chip>\n }\n <input\n hlmComboboxChipInput\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n brnFieldControlDescribedBy\n [aria-describedby]=\"describedBy()\"\n [attr.aria-required]=\"rqrd || null\"\n />\n </hlm-combobox-chips>\n <hlm-combobox-content *hlmComboboxPortal>\n <div hlmComboboxList>\n @for (option of options(); track option) {\n <hlm-combobox-item [value]=\"option\">{{ option }}</hlm-combobox-item>\n }\n </div>\n <div hlmComboboxEmpty>{{ emptyText() }}</div>\n </hlm-combobox-content>\n </hlm-combobox-multiple>\n }\n\n @if (showError()) {\n <hlm-error [id]=\"errorId()\" [class]=\"$errorClass()\">\n {{ resolvedError() }}\n </hlm-error>\n }\n\n @if (hnt) {\n <hlm-hint [id]=\"hintId()\" [class]=\"$hintClass()\">\n {{ hnt }}\n </hlm-hint>\n }\n </hlm-form-field>\n ",
|
|
170
187
|
}]
|
|
171
|
-
}], propDecorators: { _picker: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnComboboxMultiple), { isSignal: true }] }], _single: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnCombobox), { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], controlId: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlId", required: false }] }], controlName: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlName", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], autoError: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoError", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], controlClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlClass", required: false }] }], chipsClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "chipsClass", required: false }] }], errorClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorClass", required: false }] }], hintClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hintClass", required: false }] }] } });
|
|
188
|
+
}], propDecorators: { _picker: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnComboboxMultiple), { isSignal: true }] }], _single: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnCombobox), { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], controlId: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlId", required: false }] }], controlName: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlName", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], autoError: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoError", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], controlClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlClass", required: false }] }], chipsClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "chipsClass", required: false }] }], errorClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorClass", required: false }] }], hintClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "hintClass", required: false }] }] } });
|
|
172
189
|
|
|
173
190
|
/*
|
|
174
191
|
* Public API Surface of form-combobox
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { ValueProvider } from '@angular/core';
|
|
2
|
+
import { OnInit, ValueProvider } from '@angular/core';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
4
|
|
|
5
|
-
declare class EgFormCombobox {
|
|
5
|
+
declare class EgFormCombobox implements OnInit {
|
|
6
6
|
private readonly formGroupDirective;
|
|
7
7
|
private readonly _errorMessages;
|
|
8
8
|
private readonly generatedId;
|
|
@@ -10,6 +10,9 @@ declare class EgFormCombobox {
|
|
|
10
10
|
private readonly _shared;
|
|
11
11
|
private readonly _picker;
|
|
12
12
|
private readonly _single;
|
|
13
|
+
private readonly _cdr;
|
|
14
|
+
private readonly _destroyRef;
|
|
15
|
+
ngOnInit(): void;
|
|
13
16
|
label: _angular_core.InputSignal<string | undefined>;
|
|
14
17
|
controlId: _angular_core.InputSignal<string | undefined>;
|
|
15
18
|
controlName: _angular_core.InputSignal<string>;
|
|
@@ -21,6 +24,8 @@ declare class EgFormCombobox {
|
|
|
21
24
|
*/
|
|
22
25
|
autoError: _angular_core.InputSignal<boolean>;
|
|
23
26
|
hint: _angular_core.InputSignal<string | undefined>;
|
|
27
|
+
/** Consumer-owned description IDs, merged with the current error and hint IDs in both modes. */
|
|
28
|
+
ariaDescribedBy: _angular_core.InputSignal<string | null>;
|
|
24
29
|
id: _angular_core.InputSignal<string | undefined>;
|
|
25
30
|
placeholder: _angular_core.InputSignal<string>;
|
|
26
31
|
emptyText: _angular_core.InputSignal<string>;
|
|
@@ -34,6 +39,7 @@ declare class EgFormCombobox {
|
|
|
34
39
|
mode: _angular_core.InputSignal<"single" | "multiple">;
|
|
35
40
|
options: _angular_core.InputSignal<string[]>;
|
|
36
41
|
readonly effectiveId: _angular_core.Signal<string>;
|
|
42
|
+
readonly labelId: _angular_core.Signal<string>;
|
|
37
43
|
readonly errorId: _angular_core.Signal<string>;
|
|
38
44
|
readonly hintId: _angular_core.Signal<string>;
|
|
39
45
|
/**
|
|
@@ -59,6 +65,7 @@ declare class EgFormCombobox {
|
|
|
59
65
|
* wrapper-toggle + `control.disable()` cannot clobber CVA state.
|
|
60
66
|
*/
|
|
61
67
|
effectiveDisabled(): boolean;
|
|
68
|
+
protected describedBy(): string | null;
|
|
62
69
|
userClass: _angular_core.InputSignal<ClassValue>;
|
|
63
70
|
labelClass: _angular_core.InputSignal<string>;
|
|
64
71
|
controlClass: _angular_core.InputSignal<string>;
|
|
@@ -72,7 +79,7 @@ declare class EgFormCombobox {
|
|
|
72
79
|
$errorClass: _angular_core.Signal<string>;
|
|
73
80
|
$hintClass: _angular_core.Signal<string>;
|
|
74
81
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgFormCombobox, never>;
|
|
75
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormCombobox, "eg-form-combobox", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "controlName": { "alias": "controlName"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "autoError": { "alias": "autoError"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "controlClass": { "alias": "controlClass"; "required": false; "isSignal": true; }; "chipsClass": { "alias": "chipsClass"; "required": false; "isSignal": true; }; "errorClass": { "alias": "errorClass"; "required": false; "isSignal": true; }; "hintClass": { "alias": "hintClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
82
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormCombobox, "eg-form-combobox", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "controlName": { "alias": "controlName"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "autoError": { "alias": "autoError"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "controlClass": { "alias": "controlClass"; "required": false; "isSignal": true; }; "chipsClass": { "alias": "chipsClass"; "required": false; "isSignal": true; }; "errorClass": { "alias": "errorClass"; "required": false; "isSignal": true; }; "hintClass": { "alias": "hintClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
interface EgFormComboboxConfig {
|