@egose/shadcn-theme-ng-tw 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +1 -1
  2. package/form-autocomplete/README.md +20 -19
  3. package/form-autocomplete/fesm2022/form-autocomplete.mjs +47 -14
  4. package/form-autocomplete/types/form-autocomplete.d.ts +22 -1
  5. package/form-checkbox/README.md +20 -19
  6. package/form-checkbox/fesm2022/form-checkbox.mjs +102 -20
  7. package/form-checkbox/types/form-checkbox.d.ts +43 -3
  8. package/form-combobox/README.md +21 -20
  9. package/form-combobox/fesm2022/form-combobox.mjs +47 -14
  10. package/form-combobox/types/form-combobox.d.ts +22 -1
  11. package/form-date-picker/README.md +28 -27
  12. package/form-date-picker/fesm2022/form-date-picker.mjs +48 -20
  13. package/form-date-picker/types/form-date-picker.d.ts +22 -1
  14. package/form-date-picker-multi/README.md +28 -27
  15. package/form-date-picker-multi/fesm2022/form-date-picker-multi.mjs +48 -20
  16. package/form-date-picker-multi/types/form-date-picker-multi.d.ts +22 -1
  17. package/form-date-range-picker/README.md +28 -27
  18. package/form-date-range-picker/fesm2022/form-date-range-picker.mjs +48 -20
  19. package/form-date-range-picker/types/form-date-range-picker.d.ts +22 -1
  20. package/form-field/README.md +9 -0
  21. package/form-field/fesm2022/form-field.mjs +97 -5
  22. package/form-field/types/form-field.d.ts +96 -2
  23. package/form-field-simple/fesm2022/form-field-simple.mjs +15 -1
  24. package/form-field-simple/types/form-field-simple.d.ts +9 -2
  25. package/form-input-otp/README.md +17 -16
  26. package/form-input-otp/fesm2022/form-input-otp.mjs +46 -13
  27. package/form-input-otp/types/form-input-otp.d.ts +22 -1
  28. package/form-month-year-picker/README.md +26 -25
  29. package/form-month-year-picker/fesm2022/form-month-year-picker.mjs +48 -20
  30. package/form-month-year-picker/types/form-month-year-picker.d.ts +22 -1
  31. package/form-native-select/README.md +18 -17
  32. package/form-native-select/fesm2022/form-native-select.mjs +61 -21
  33. package/form-native-select/types/form-native-select.d.ts +22 -1
  34. package/form-phone-input/README.md +23 -22
  35. package/form-phone-input/fesm2022/form-phone-input.mjs +47 -19
  36. package/form-phone-input/types/form-phone-input.d.ts +22 -1
  37. package/form-radio-group/README.md +18 -17
  38. package/form-radio-group/fesm2022/form-radio-group.mjs +47 -19
  39. package/form-radio-group/types/form-radio-group.d.ts +22 -1
  40. package/form-searchable-multiselect/README.md +18 -17
  41. package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +47 -19
  42. package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +22 -1
  43. package/form-select/README.md +20 -19
  44. package/form-select/fesm2022/form-select.mjs +47 -19
  45. package/form-select/types/form-select.d.ts +22 -1
  46. package/form-slider/README.md +19 -18
  47. package/form-slider/fesm2022/form-slider.mjs +46 -13
  48. package/form-slider/types/form-slider.d.ts +22 -1
  49. package/form-switch/README.md +16 -15
  50. package/form-switch/fesm2022/form-switch.mjs +47 -19
  51. package/form-switch/types/form-switch.d.ts +22 -1
  52. package/form-text-input/README.md +27 -26
  53. package/form-text-input/fesm2022/form-text-input.mjs +47 -19
  54. package/form-text-input/types/form-text-input.d.ts +22 -1
  55. package/form-textarea/README.md +23 -22
  56. package/form-textarea/fesm2022/form-textarea.mjs +47 -19
  57. package/form-textarea/types/form-textarea.d.ts +22 -1
  58. package/form-toggle/README.md +17 -16
  59. package/form-toggle/fesm2022/form-toggle.mjs +48 -11
  60. package/form-toggle/types/form-toggle.d.ts +22 -3
  61. package/form-toggle-group/README.md +20 -19
  62. package/form-toggle-group/fesm2022/form-toggle-group.mjs +47 -19
  63. package/form-toggle-group/types/form-toggle-group.d.ts +22 -1
  64. package/package.json +5 -1
  65. package/stepper/README.md +353 -0
  66. package/stepper/fesm2022/stepper.mjs +686 -0
  67. package/stepper/package.json +24 -0
  68. package/stepper/types/stepper.d.ts +116 -0
@@ -2,15 +2,17 @@ import * as i0 from '@angular/core';
2
2
  import { inject, input, computed, Component } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormGroupDirective, ReactiveFormsModule, ControlContainer } from '@angular/forms';
5
- import { HlmFormIdGenerator, HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng-tw/form-field';
5
+ import { injectEgFormErrorMessages, HlmFormIdGenerator, injectEgFormSharedConfig, resolveEgFormError, HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng-tw/form-field';
6
6
  import { HlmLabel } from '@egose/shadcn-theme-ng-tw/label';
7
7
  import { injectHlmDatePickerConfig, HlmDatePicker, HlmDatePickerInput } from '@egose/shadcn-theme-ng-tw/date-picker';
8
8
  import { hlm } from '@egose/shadcn-theme-ng-tw/utils';
9
9
 
10
10
  class EgFormDatePicker {
11
11
  formGroupDirective = inject(FormGroupDirective);
12
+ _errorMessages = injectEgFormErrorMessages();
12
13
  generatedId = inject(HlmFormIdGenerator).generate('eg-form-date-picker');
13
14
  _config = injectHlmDatePickerConfig();
15
+ _shared = injectEgFormSharedConfig();
14
16
  // Inputs
15
17
  label = input(undefined, /* @ts-ignore */
16
18
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
@@ -20,6 +22,13 @@ class EgFormDatePicker {
20
22
  ...(ngDevMode ? [{ debugName: "controlName" }] : /* istanbul ignore next */ []));
21
23
  error = input(undefined, /* @ts-ignore */
22
24
  ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
25
+ /**
26
+ * Auto-resolve the displayed message from the control's `ValidationErrors`
27
+ * when `error()` is unset. Explicit `error()` always wins. Set to `false`
28
+ * for manual-only messages.
29
+ */
30
+ autoError = input(true, /* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "autoError" }] : /* istanbul ignore next */ []));
23
32
  hint = input(undefined, /* @ts-ignore */
24
33
  ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
25
34
  // HTML attributes
@@ -59,6 +68,32 @@ class EgFormDatePicker {
59
68
  ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
60
69
  hintId = computed(() => `${this.effectiveId()}-hint`, /* @ts-ignore */
61
70
  ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
71
+ /**
72
+ * Displayed message: explicit `error()` wins; otherwise (when `autoError()`)
73
+ * auto-resolved from the control's `ValidationErrors`. Plain method (not a
74
+ * computed): `ValidationErrors` is not a signal, so the control must be read
75
+ * fresh on every change-detection pass.
76
+ */
77
+ resolvedError() {
78
+ const explicit = this.error();
79
+ if (explicit)
80
+ return explicit;
81
+ if (!this.autoError())
82
+ return undefined;
83
+ const control = this.formGroupDirective.form.get(this.controlName());
84
+ return resolveEgFormError(control?.errors ?? null, this.label(), this._errorMessages);
85
+ }
86
+ /**
87
+ * Whether the error is surfaced: message present + control invalid +
88
+ * touched/dirty/submitted. Gates the visual `<hlm-error>` (and
89
+ * `describedBy()`, where present) so sighted and screen-reader output agree.
90
+ */
91
+ showError() {
92
+ const control = this.formGroupDirective.form.get(this.controlName());
93
+ return (!!this.resolvedError() &&
94
+ !!control?.invalid &&
95
+ (control.dirty || control.touched || this.formGroupDirective.submitted));
96
+ }
62
97
  /**
63
98
  * Bounds projected onto the picker's `Date` model. The cast keeps the
64
99
  * template's generic inference on `Date` while passing runtime values
@@ -69,12 +104,7 @@ class EgFormDatePicker {
69
104
  $max = computed(() => this.max(), /* @ts-ignore */
70
105
  ...(ngDevMode ? [{ debugName: "$max" }] : /* istanbul ignore next */ []));
71
106
  describedBy() {
72
- const control = this.formGroupDirective.form.get(this.controlName());
73
- return this.error() && control?.invalid && (control.dirty || control.touched)
74
- ? this.errorId()
75
- : this.hint()
76
- ? this.hintId()
77
- : null;
107
+ return this.showError() ? this.errorId() : this.hint() ? this.hintId() : null;
78
108
  }
79
109
  // Styling
80
110
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
@@ -91,21 +121,20 @@ class EgFormDatePicker {
91
121
  // Computed classes (library base < global config < per-instance)
92
122
  $userClass = computed(() => hlm('tw:w-full', this.userClass()), /* @ts-ignore */
93
123
  ...(ngDevMode ? [{ debugName: "$userClass" }] : /* istanbul ignore next */ []));
94
- $labelClass = computed(() => hlm('tw:mb-1', this._config.labelClass, this.labelClass()), /* @ts-ignore */
124
+ $labelClass = computed(() => hlm('tw:mb-1', this._shared.labelClass, this._config.labelClass, this.labelClass()), /* @ts-ignore */
95
125
  ...(ngDevMode ? [{ debugName: "$labelClass" }] : /* istanbul ignore next */ []));
96
- $pickerClass = computed(() => hlm('tw:mb-1', this._config.pickerClass, this.pickerClass()), /* @ts-ignore */
126
+ $pickerClass = computed(() => hlm('tw:mb-1', this._shared.pickerClass, this._config.pickerClass, this.pickerClass()), /* @ts-ignore */
97
127
  ...(ngDevMode ? [{ debugName: "$pickerClass" }] : /* istanbul ignore next */ []));
98
- $inputClass = computed(() => hlm(this._config.inputClass, this.inputClass()), /* @ts-ignore */
128
+ $inputClass = computed(() => hlm(this._shared.inputClass, this._config.inputClass, this.inputClass()), /* @ts-ignore */
99
129
  ...(ngDevMode ? [{ debugName: "$inputClass" }] : /* istanbul ignore next */ []));
100
- $errorClass = computed(() => hlm('tw:mt-0', this._config.errorClass, this.errorClass()), /* @ts-ignore */
130
+ $errorClass = computed(() => hlm('tw:mt-0', this._shared.errorClass, this._config.errorClass, this.errorClass()), /* @ts-ignore */
101
131
  ...(ngDevMode ? [{ debugName: "$errorClass" }] : /* istanbul ignore next */ []));
102
- $hintClass = computed(() => hlm('tw:mt-0', this._config.hintClass, this.hintClass()), /* @ts-ignore */
132
+ $hintClass = computed(() => hlm('tw:mt-0', this._shared.hintClass, this._config.hintClass, this.hintClass()), /* @ts-ignore */
103
133
  ...(ngDevMode ? [{ debugName: "$hintClass" }] : /* istanbul ignore next */ []));
104
134
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormDatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
105
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormDatePicker, isStandalone: true, selector: "eg-form-date-picker", 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 }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnSelect: { classPropertyName: "autoCloseOnSelect", publicName: "autoCloseOnSelect", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, transformDate: { classPropertyName: "transformDate", publicName: "transformDate", isSignal: true, isRequired: false, transformFunction: null }, parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDate: { classPropertyName: "formatInputDate", publicName: "formatInputDate", 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 }, pickerClass: { classPropertyName: "pickerClass", publicName: "pickerClass", 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: `
135
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormDatePicker, isStandalone: true, selector: "eg-form-date-picker", 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 }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnSelect: { classPropertyName: "autoCloseOnSelect", publicName: "autoCloseOnSelect", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, transformDate: { classPropertyName: "transformDate", publicName: "transformDate", isSignal: true, isRequired: false, transformFunction: null }, parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDate: { classPropertyName: "formatInputDate", publicName: "formatInputDate", 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 }, pickerClass: { classPropertyName: "pickerClass", publicName: "pickerClass", 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: `
106
136
  @let lbl = label();
107
137
  @let cnm = controlName();
108
- @let err = error();
109
138
  @let hnt = hint();
110
139
  @let rqrd = required();
111
140
 
@@ -143,9 +172,9 @@ class EgFormDatePicker {
143
172
  />
144
173
  </hlm-date-picker>
145
174
 
146
- @if (err) {
175
+ @if (showError()) {
147
176
  <hlm-error [id]="errorId()" [class]="$errorClass()">
148
- {{ err }}
177
+ {{ resolvedError() }}
149
178
  </hlm-error>
150
179
  }
151
180
 
@@ -170,7 +199,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
170
199
  template: `
171
200
  @let lbl = label();
172
201
  @let cnm = controlName();
173
- @let err = error();
174
202
  @let hnt = hint();
175
203
  @let rqrd = required();
176
204
 
@@ -208,9 +236,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
208
236
  />
209
237
  </hlm-date-picker>
210
238
 
211
- @if (err) {
239
+ @if (showError()) {
212
240
  <hlm-error [id]="errorId()" [class]="$errorClass()">
213
- {{ err }}
241
+ {{ resolvedError() }}
214
242
  </hlm-error>
215
243
  }
216
244
 
@@ -222,7 +250,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
222
250
  </hlm-form-field>
223
251
  `,
224
252
  }]
225
- }], 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 }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], autoCloseOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnSelect", required: false }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], formatDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDate", required: false }] }], transformDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDate", required: false }] }], parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDate", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], pickerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickerClass", 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 }] }] } });
253
+ }], 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 }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], autoCloseOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnSelect", required: false }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], formatDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDate", required: false }] }], transformDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDate", required: false }] }], parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDate", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], pickerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickerClass", 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 }] }] } });
226
254
 
227
255
  /*
228
256
  * Public API Surface of form-date-picker
@@ -4,12 +4,20 @@ import { ClassValue } from 'clsx';
4
4
  type DatePickerCaptionLayout = 'dropdown' | 'label' | 'dropdown-months' | 'dropdown-years';
5
5
  declare class EgFormDatePicker {
6
6
  private readonly formGroupDirective;
7
+ private readonly _errorMessages;
7
8
  private readonly generatedId;
8
9
  private readonly _config;
10
+ private readonly _shared;
9
11
  label: _angular_core.InputSignal<string | undefined>;
10
12
  controlId: _angular_core.InputSignal<string | undefined>;
11
13
  controlName: _angular_core.InputSignal<string>;
12
14
  error: _angular_core.InputSignal<string | undefined>;
15
+ /**
16
+ * Auto-resolve the displayed message from the control's `ValidationErrors`
17
+ * when `error()` is unset. Explicit `error()` always wins. Set to `false`
18
+ * for manual-only messages.
19
+ */
20
+ autoError: _angular_core.InputSignal<boolean>;
13
21
  hint: _angular_core.InputSignal<string | undefined>;
14
22
  id: _angular_core.InputSignal<string | undefined>;
15
23
  name: _angular_core.InputSignal<string | undefined>;
@@ -28,6 +36,19 @@ declare class EgFormDatePicker {
28
36
  readonly effectiveId: _angular_core.Signal<string>;
29
37
  readonly errorId: _angular_core.Signal<string>;
30
38
  readonly hintId: _angular_core.Signal<string>;
39
+ /**
40
+ * Displayed message: explicit `error()` wins; otherwise (when `autoError()`)
41
+ * auto-resolved from the control's `ValidationErrors`. Plain method (not a
42
+ * computed): `ValidationErrors` is not a signal, so the control must be read
43
+ * fresh on every change-detection pass.
44
+ */
45
+ protected resolvedError(): string | undefined;
46
+ /**
47
+ * Whether the error is surfaced: message present + control invalid +
48
+ * touched/dirty/submitted. Gates the visual `<hlm-error>` (and
49
+ * `describedBy()`, where present) so sighted and screen-reader output agree.
50
+ */
51
+ protected showError(): boolean;
31
52
  /**
32
53
  * Bounds projected onto the picker's `Date` model. The cast keeps the
33
54
  * template's generic inference on `Date` while passing runtime values
@@ -49,7 +70,7 @@ declare class EgFormDatePicker {
49
70
  $errorClass: _angular_core.Signal<string>;
50
71
  $hintClass: _angular_core.Signal<string>;
51
72
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgFormDatePicker, never>;
52
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormDatePicker, "eg-form-date-picker", 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; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "autoCloseOnSelect": { "alias": "autoCloseOnSelect"; "required": false; "isSignal": true; }; "captionLayout": { "alias": "captionLayout"; "required": false; "isSignal": true; }; "formatDate": { "alias": "formatDate"; "required": false; "isSignal": true; }; "transformDate": { "alias": "transformDate"; "required": false; "isSignal": true; }; "parseDate": { "alias": "parseDate"; "required": false; "isSignal": true; }; "formatInputDate": { "alias": "formatInputDate"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "pickerClass": { "alias": "pickerClass"; "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>;
73
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormDatePicker, "eg-form-date-picker", 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; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "autoCloseOnSelect": { "alias": "autoCloseOnSelect"; "required": false; "isSignal": true; }; "captionLayout": { "alias": "captionLayout"; "required": false; "isSignal": true; }; "formatDate": { "alias": "formatDate"; "required": false; "isSignal": true; }; "transformDate": { "alias": "transformDate"; "required": false; "isSignal": true; }; "parseDate": { "alias": "parseDate"; "required": false; "isSignal": true; }; "formatInputDate": { "alias": "formatInputDate"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "pickerClass": { "alias": "pickerClass"; "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>;
53
74
  }
54
75
 
55
76
  export { EgFormDatePicker };
@@ -62,33 +62,34 @@ Selector (from source): `eg-form-date-picker-multi` (standalone component, host
62
62
 
63
63
  ### `EgFormDatePickerMulti` — `eg-form-date-picker-multi`
64
64
 
65
- | Input | Type | Default | Description |
66
- | ------------------------------- | ----------------------------------- | -------------- | ------------------------------------------------------------------------------------------- |
67
- | `controlName` | `string` | `''` | `formControlName` key inside the parent `FormGroup`. **Required.** |
68
- | `label` | `string \| undefined` | — | Label text (hidden when omitted). |
69
- | `error` | `string \| undefined` | — | Error text shown when invalid. |
70
- | `hint` | `string \| undefined` | — | Hint text shown otherwise. |
71
- | `controlId` | `string \| undefined` | — | Explicit id (first priority for `effectiveId`). |
72
- | `id` | `string \| undefined` | — | Fallback id (second priority). |
73
- | `name` | `string \| undefined` | — | Native `name` forwarded to the inner input (`controlName` wins). |
74
- | `placeholder` | `string` | `'Pick dates'` | Input placeholder. |
75
- | `readonly` | `boolean` | `false` | Native `readonly` forwarded to the inner input. |
76
- | `disabled` | `boolean` | `false` | Locks interaction (form control stays enabled). |
77
- | `required` | `boolean` | `false` | Shows a red `*` next to the label. |
78
- | `min` / `max` | `Date \| string \| null` | `null` | Date bounds forwarded to the picker. |
79
- | `minSelection` / `maxSelection` | `number \| undefined` | — | Selection-count bounds forwarded to the picker. |
80
- | `autoCloseOnMaxSelection` | `boolean` | config default | Forwarded to the picker (falls back to `provideHlmDatePickerMultiConfig`, default `false`). |
81
- | `captionLayout` | union | `'label'` | Forwarded to the picker (`'dropdown' \| 'label' \| 'dropdown-months' \| 'dropdown-years'`). |
82
- | `formatDates` | `(dates: Date[]) => string` | config default | Display format (falls back to `provideHlmDatePickerMultiConfig`). |
83
- | `transformDates` | `(dates: Date[]) => Date[]` | config default | Model transform (falls back to `provideHlmDatePickerMultiConfig`). |
84
- | `parseDate` | `(value: string) => Date[] \| null` | config default | Input parsing, forwarded to the input (falls back to `provideHlmDatePickerMultiConfig`). |
85
- | `formatInputDates` | `(dates: Date[]) => string` | config default | Edit format while focused (falls back to `provideHlmDatePickerMultiConfig`). |
86
- | `class` | `ClassValue` | `''` | Extra host classes (base `tw:w-full`). |
87
- | `labelClass` | `string` | `''` | Extra label classes (base `tw:mb-1`). |
88
- | `pickerClass` | `string` | `''` | Extra picker-container classes (base `tw:mb-1`). |
89
- | `inputClass` | `string` | `''` | Extra inner-input classes (e.g. `tw:text-lg`). |
90
- | `errorClass` | `string` | `''` | Extra error classes (base `tw:mt-0`). |
91
- | `hintClass` | `string` | `''` | Extra hint classes (base `tw:mt-0`). |
65
+ | Input | Type | Default | Description |
66
+ | ------------------------------- | ----------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
67
+ | `controlName` | `string` | `''` | `formControlName` key inside the parent `FormGroup`. **Required.** |
68
+ | `label` | `string \| undefined` | — | Label text (hidden when omitted). |
69
+ | `error` | `string \| undefined` | — | Error text shown when invalid. |
70
+ | `autoError` | `boolean` | `true` | Auto-resolve the message from the control's `ValidationErrors` when `error` is unset. Explicit `error` always wins; `error=""` counts as unset. Global wording via `provideEgFormErrorMessages`. |
71
+ | `hint` | `string \| undefined` | — | Hint text shown otherwise. |
72
+ | `controlId` | `string \| undefined` | — | Explicit id (first priority for `effectiveId`). |
73
+ | `id` | `string \| undefined` | — | Fallback id (second priority). |
74
+ | `name` | `string \| undefined` | — | Native `name` forwarded to the inner input (`controlName` wins). |
75
+ | `placeholder` | `string` | `'Pick dates'` | Input placeholder. |
76
+ | `readonly` | `boolean` | `false` | Native `readonly` forwarded to the inner input. |
77
+ | `disabled` | `boolean` | `false` | Locks interaction (form control stays enabled). |
78
+ | `required` | `boolean` | `false` | Shows a red `*` next to the label. |
79
+ | `min` / `max` | `Date \| string \| null` | `null` | Date bounds forwarded to the picker. |
80
+ | `minSelection` / `maxSelection` | `number \| undefined` | — | Selection-count bounds forwarded to the picker. |
81
+ | `autoCloseOnMaxSelection` | `boolean` | config default | Forwarded to the picker (falls back to `provideHlmDatePickerMultiConfig`, default `false`). |
82
+ | `captionLayout` | union | `'label'` | Forwarded to the picker (`'dropdown' \| 'label' \| 'dropdown-months' \| 'dropdown-years'`). |
83
+ | `formatDates` | `(dates: Date[]) => string` | config default | Display format (falls back to `provideHlmDatePickerMultiConfig`). |
84
+ | `transformDates` | `(dates: Date[]) => Date[]` | config default | Model transform (falls back to `provideHlmDatePickerMultiConfig`). |
85
+ | `parseDate` | `(value: string) => Date[] \| null` | config default | Input parsing, forwarded to the input (falls back to `provideHlmDatePickerMultiConfig`). |
86
+ | `formatInputDates` | `(dates: Date[]) => string` | config default | Edit format while focused (falls back to `provideHlmDatePickerMultiConfig`). |
87
+ | `class` | `ClassValue` | `''` | Extra host classes (base `tw:w-full`). |
88
+ | `labelClass` | `string` | `''` | Extra label classes (base `tw:mb-1`). |
89
+ | `pickerClass` | `string` | `''` | Extra picker-container classes (base `tw:mb-1`). |
90
+ | `inputClass` | `string` | `''` | Extra inner-input classes (e.g. `tw:text-lg`). |
91
+ | `errorClass` | `string` | `''` | Extra error classes (base `tw:mt-0`). |
92
+ | `hintClass` | `string` | `''` | Extra hint classes (base `tw:mt-0`). |
92
93
 
93
94
  | Member | Description |
94
95
  | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -2,15 +2,17 @@ import * as i0 from '@angular/core';
2
2
  import { inject, input, numberAttribute, computed, Component } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormGroupDirective, ReactiveFormsModule, ControlContainer } from '@angular/forms';
5
- import { HlmFormIdGenerator, HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng-tw/form-field';
5
+ import { injectEgFormErrorMessages, HlmFormIdGenerator, injectEgFormSharedConfig, resolveEgFormError, HlmFormField, HlmError, HlmHint } from '@egose/shadcn-theme-ng-tw/form-field';
6
6
  import { HlmLabel } from '@egose/shadcn-theme-ng-tw/label';
7
7
  import { injectHlmDatePickerMultiConfig, HlmDatePickerMulti, HlmDateMultiInput } from '@egose/shadcn-theme-ng-tw/date-picker';
8
8
  import { hlm } from '@egose/shadcn-theme-ng-tw/utils';
9
9
 
10
10
  class EgFormDatePickerMulti {
11
11
  formGroupDirective = inject(FormGroupDirective);
12
+ _errorMessages = injectEgFormErrorMessages();
12
13
  generatedId = inject(HlmFormIdGenerator).generate('eg-form-date-picker-multi');
13
14
  _config = injectHlmDatePickerMultiConfig();
15
+ _shared = injectEgFormSharedConfig();
14
16
  label = input(undefined, /* @ts-ignore */
15
17
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
16
18
  controlId = input(undefined, /* @ts-ignore */
@@ -19,6 +21,13 @@ class EgFormDatePickerMulti {
19
21
  ...(ngDevMode ? [{ debugName: "controlName" }] : /* istanbul ignore next */ []));
20
22
  error = input(undefined, /* @ts-ignore */
21
23
  ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
24
+ /**
25
+ * Auto-resolve the displayed message from the control's `ValidationErrors`
26
+ * when `error()` is unset. Explicit `error()` always wins. Set to `false`
27
+ * for manual-only messages.
28
+ */
29
+ autoError = input(true, /* @ts-ignore */
30
+ ...(ngDevMode ? [{ debugName: "autoError" }] : /* istanbul ignore next */ []));
22
31
  hint = input(undefined, /* @ts-ignore */
23
32
  ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
24
33
  id = input(undefined, /* @ts-ignore */
@@ -58,6 +67,32 @@ class EgFormDatePickerMulti {
58
67
  ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
59
68
  hintId = computed(() => `${this.effectiveId()}-hint`, /* @ts-ignore */
60
69
  ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
70
+ /**
71
+ * Displayed message: explicit `error()` wins; otherwise (when `autoError()`)
72
+ * auto-resolved from the control's `ValidationErrors`. Plain method (not a
73
+ * computed): `ValidationErrors` is not a signal, so the control must be read
74
+ * fresh on every change-detection pass.
75
+ */
76
+ resolvedError() {
77
+ const explicit = this.error();
78
+ if (explicit)
79
+ return explicit;
80
+ if (!this.autoError())
81
+ return undefined;
82
+ const control = this.formGroupDirective.form.get(this.controlName());
83
+ return resolveEgFormError(control?.errors ?? null, this.label(), this._errorMessages);
84
+ }
85
+ /**
86
+ * Whether the error is surfaced: message present + control invalid +
87
+ * touched/dirty/submitted. Gates the visual `<hlm-error>` (and
88
+ * `describedBy()`, where present) so sighted and screen-reader output agree.
89
+ */
90
+ showError() {
91
+ const control = this.formGroupDirective.form.get(this.controlName());
92
+ return (!!this.resolvedError() &&
93
+ !!control?.invalid &&
94
+ (control.dirty || control.touched || this.formGroupDirective.submitted));
95
+ }
61
96
  /**
62
97
  * Bounds projected onto the picker's `Date` model. The cast keeps the
63
98
  * template's generic inference on `Date` while passing runtime values
@@ -68,12 +103,7 @@ class EgFormDatePickerMulti {
68
103
  $max = computed(() => this.max(), /* @ts-ignore */
69
104
  ...(ngDevMode ? [{ debugName: "$max" }] : /* istanbul ignore next */ []));
70
105
  describedBy() {
71
- const control = this.formGroupDirective.form.get(this.controlName());
72
- return this.error() && control?.invalid && (control.dirty || control.touched)
73
- ? this.errorId()
74
- : this.hint()
75
- ? this.hintId()
76
- : null;
106
+ return this.showError() ? this.errorId() : this.hint() ? this.hintId() : null;
77
107
  }
78
108
  // Styling
79
109
  userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
@@ -90,21 +120,20 @@ class EgFormDatePickerMulti {
90
120
  // Computed classes (library base < global config < per-instance)
91
121
  $userClass = computed(() => hlm('tw:w-full', this.userClass()), /* @ts-ignore */
92
122
  ...(ngDevMode ? [{ debugName: "$userClass" }] : /* istanbul ignore next */ []));
93
- $labelClass = computed(() => hlm('tw:mb-1', this._config.labelClass, this.labelClass()), /* @ts-ignore */
123
+ $labelClass = computed(() => hlm('tw:mb-1', this._shared.labelClass, this._config.labelClass, this.labelClass()), /* @ts-ignore */
94
124
  ...(ngDevMode ? [{ debugName: "$labelClass" }] : /* istanbul ignore next */ []));
95
- $pickerClass = computed(() => hlm('tw:mb-1', this._config.pickerClass, this.pickerClass()), /* @ts-ignore */
125
+ $pickerClass = computed(() => hlm('tw:mb-1', this._shared.pickerClass, this._config.pickerClass, this.pickerClass()), /* @ts-ignore */
96
126
  ...(ngDevMode ? [{ debugName: "$pickerClass" }] : /* istanbul ignore next */ []));
97
- $inputClass = computed(() => hlm(this._config.inputClass, this.inputClass()), /* @ts-ignore */
127
+ $inputClass = computed(() => hlm(this._shared.inputClass, this._config.inputClass, this.inputClass()), /* @ts-ignore */
98
128
  ...(ngDevMode ? [{ debugName: "$inputClass" }] : /* istanbul ignore next */ []));
99
- $errorClass = computed(() => hlm('tw:mt-0', this._config.errorClass, this.errorClass()), /* @ts-ignore */
129
+ $errorClass = computed(() => hlm('tw:mt-0', this._shared.errorClass, this._config.errorClass, this.errorClass()), /* @ts-ignore */
100
130
  ...(ngDevMode ? [{ debugName: "$errorClass" }] : /* istanbul ignore next */ []));
101
- $hintClass = computed(() => hlm('tw:mt-0', this._config.hintClass, this.hintClass()), /* @ts-ignore */
131
+ $hintClass = computed(() => hlm('tw:mt-0', this._shared.hintClass, this._config.hintClass, this.hintClass()), /* @ts-ignore */
102
132
  ...(ngDevMode ? [{ debugName: "$hintClass" }] : /* istanbul ignore next */ []));
103
133
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgFormDatePickerMulti, deps: [], target: i0.ɵɵFactoryTarget.Component });
104
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormDatePickerMulti, isStandalone: true, selector: "eg-form-date-picker-multi", 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 }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, minSelection: { classPropertyName: "minSelection", publicName: "minSelection", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnMaxSelection: { classPropertyName: "autoCloseOnMaxSelection", publicName: "autoCloseOnMaxSelection", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, formatDates: { classPropertyName: "formatDates", publicName: "formatDates", isSignal: true, isRequired: false, transformFunction: null }, transformDates: { classPropertyName: "transformDates", publicName: "transformDates", isSignal: true, isRequired: false, transformFunction: null }, parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDates: { classPropertyName: "formatInputDates", publicName: "formatInputDates", 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 }, pickerClass: { classPropertyName: "pickerClass", publicName: "pickerClass", 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: `
134
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgFormDatePickerMulti, isStandalone: true, selector: "eg-form-date-picker-multi", 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 }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", 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 }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, minSelection: { classPropertyName: "minSelection", publicName: "minSelection", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnMaxSelection: { classPropertyName: "autoCloseOnMaxSelection", publicName: "autoCloseOnMaxSelection", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, formatDates: { classPropertyName: "formatDates", publicName: "formatDates", isSignal: true, isRequired: false, transformFunction: null }, transformDates: { classPropertyName: "transformDates", publicName: "transformDates", isSignal: true, isRequired: false, transformFunction: null }, parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDates: { classPropertyName: "formatInputDates", publicName: "formatInputDates", 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 }, pickerClass: { classPropertyName: "pickerClass", publicName: "pickerClass", 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: `
105
135
  @let lbl = label();
106
136
  @let cnm = controlName();
107
- @let err = error();
108
137
  @let hnt = hint();
109
138
  @let rqrd = required();
110
139
 
@@ -144,9 +173,9 @@ class EgFormDatePickerMulti {
144
173
  />
145
174
  </hlm-date-picker-multi>
146
175
 
147
- @if (err) {
176
+ @if (showError()) {
148
177
  <hlm-error [id]="errorId()" [class]="$errorClass()">
149
- {{ err }}
178
+ {{ resolvedError() }}
150
179
  </hlm-error>
151
180
  }
152
181
 
@@ -171,7 +200,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
171
200
  template: `
172
201
  @let lbl = label();
173
202
  @let cnm = controlName();
174
- @let err = error();
175
203
  @let hnt = hint();
176
204
  @let rqrd = required();
177
205
 
@@ -211,9 +239,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
211
239
  />
212
240
  </hlm-date-picker-multi>
213
241
 
214
- @if (err) {
242
+ @if (showError()) {
215
243
  <hlm-error [id]="errorId()" [class]="$errorClass()">
216
- {{ err }}
244
+ {{ resolvedError() }}
217
245
  </hlm-error>
218
246
  }
219
247
 
@@ -225,7 +253,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
225
253
  </hlm-form-field>
226
254
  `,
227
255
  }]
228
- }], 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 }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], minSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSelection", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], autoCloseOnMaxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnMaxSelection", required: false }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDates", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], pickerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickerClass", 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 }] }] } });
256
+ }], 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 }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], minSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSelection", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], autoCloseOnMaxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnMaxSelection", required: false }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDates", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], labelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelClass", required: false }] }], pickerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickerClass", 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 }] }] } });
229
257
 
230
258
  /*
231
259
  * Public API Surface of form-date-picker-multi
@@ -5,12 +5,20 @@ import { NumberInput } from '@angular/cdk/coercion';
5
5
  type DatePickerCaptionLayout = 'dropdown' | 'label' | 'dropdown-months' | 'dropdown-years';
6
6
  declare class EgFormDatePickerMulti {
7
7
  private readonly formGroupDirective;
8
+ private readonly _errorMessages;
8
9
  private readonly generatedId;
9
10
  private readonly _config;
11
+ private readonly _shared;
10
12
  label: _angular_core.InputSignal<string | undefined>;
11
13
  controlId: _angular_core.InputSignal<string | undefined>;
12
14
  controlName: _angular_core.InputSignal<string>;
13
15
  error: _angular_core.InputSignal<string | undefined>;
16
+ /**
17
+ * Auto-resolve the displayed message from the control's `ValidationErrors`
18
+ * when `error()` is unset. Explicit `error()` always wins. Set to `false`
19
+ * for manual-only messages.
20
+ */
21
+ autoError: _angular_core.InputSignal<boolean>;
14
22
  hint: _angular_core.InputSignal<string | undefined>;
15
23
  id: _angular_core.InputSignal<string | undefined>;
16
24
  name: _angular_core.InputSignal<string | undefined>;
@@ -31,6 +39,19 @@ declare class EgFormDatePickerMulti {
31
39
  readonly effectiveId: _angular_core.Signal<string>;
32
40
  readonly errorId: _angular_core.Signal<string>;
33
41
  readonly hintId: _angular_core.Signal<string>;
42
+ /**
43
+ * Displayed message: explicit `error()` wins; otherwise (when `autoError()`)
44
+ * auto-resolved from the control's `ValidationErrors`. Plain method (not a
45
+ * computed): `ValidationErrors` is not a signal, so the control must be read
46
+ * fresh on every change-detection pass.
47
+ */
48
+ protected resolvedError(): string | undefined;
49
+ /**
50
+ * Whether the error is surfaced: message present + control invalid +
51
+ * touched/dirty/submitted. Gates the visual `<hlm-error>` (and
52
+ * `describedBy()`, where present) so sighted and screen-reader output agree.
53
+ */
54
+ protected showError(): boolean;
34
55
  /**
35
56
  * Bounds projected onto the picker's `Date` model. The cast keeps the
36
57
  * template's generic inference on `Date` while passing runtime values
@@ -52,7 +73,7 @@ declare class EgFormDatePickerMulti {
52
73
  $errorClass: _angular_core.Signal<string>;
53
74
  $hintClass: _angular_core.Signal<string>;
54
75
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgFormDatePickerMulti, never>;
55
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormDatePickerMulti, "eg-form-date-picker-multi", 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; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "minSelection": { "alias": "minSelection"; "required": false; "isSignal": true; }; "maxSelection": { "alias": "maxSelection"; "required": false; "isSignal": true; }; "autoCloseOnMaxSelection": { "alias": "autoCloseOnMaxSelection"; "required": false; "isSignal": true; }; "captionLayout": { "alias": "captionLayout"; "required": false; "isSignal": true; }; "formatDates": { "alias": "formatDates"; "required": false; "isSignal": true; }; "transformDates": { "alias": "transformDates"; "required": false; "isSignal": true; }; "parseDate": { "alias": "parseDate"; "required": false; "isSignal": true; }; "formatInputDates": { "alias": "formatInputDates"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "pickerClass": { "alias": "pickerClass"; "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>;
76
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgFormDatePickerMulti, "eg-form-date-picker-multi", 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; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "minSelection": { "alias": "minSelection"; "required": false; "isSignal": true; }; "maxSelection": { "alias": "maxSelection"; "required": false; "isSignal": true; }; "autoCloseOnMaxSelection": { "alias": "autoCloseOnMaxSelection"; "required": false; "isSignal": true; }; "captionLayout": { "alias": "captionLayout"; "required": false; "isSignal": true; }; "formatDates": { "alias": "formatDates"; "required": false; "isSignal": true; }; "transformDates": { "alias": "transformDates"; "required": false; "isSignal": true; }; "parseDate": { "alias": "parseDate"; "required": false; "isSignal": true; }; "formatInputDates": { "alias": "formatInputDates"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "labelClass": { "alias": "labelClass"; "required": false; "isSignal": true; }; "pickerClass": { "alias": "pickerClass"; "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>;
56
77
  }
57
78
 
58
79
  export { EgFormDatePickerMulti };