@ng-forge/dynamic-forms-ionic 0.2.0 → 0.3.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.
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, input, computed, ChangeDetectionStrategy, Component, signal, InjectionToken, linkedSignal, model, isSignal } from '@angular/core';
2
+ import { inject, input, computed, ChangeDetectionStrategy, Component, ElementRef, signal, InjectionToken, linkedSignal, model, isSignal } from '@angular/core';
3
3
  import { IonButton, IonCheckbox, IonNote, IonInput, IonModal, IonDatetime, IonButtons, IonHeader, IonContent, IonToolbar, IonTitle, IonItem, IonRadioGroup, IonRadio, IonSelect, IonSelectOption, IonRange, IonTextarea, IonToggle } from '@ionic/angular/standalone';
4
4
  import { EventBus, ARRAY_CONTEXT, resolveTokens, DynamicTextPipe, buildBaseInputs, FIELD_SIGNAL_CONTEXT, resolveSubmitButtonDisabled, resolveNextButtonDisabled, NextPageEvent, PreviousPageEvent, DynamicFormLogger, AddArrayItemEvent, RemoveArrayItemEvent } from '@ng-forge/dynamic-forms';
5
5
  import { AsyncPipe } from '@angular/common';
6
- import { Field } from '@angular/forms/signals';
7
- import { createResolvedErrorsSignal, shouldShowErrors, isEqual, ValueInArrayPipe, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, datepickerFieldMapper } from '@ng-forge/dynamic-forms/integration';
6
+ import { FormField } from '@angular/forms/signals';
7
+ import { createResolvedErrorsSignal, shouldShowErrors, setupMetaTracking, isEqual, ValueInArrayPipe, valueFieldMapper, optionsFieldMapper, checkboxFieldMapper, datepickerFieldMapper } from '@ng-forge/dynamic-forms/integration';
8
8
  import { format } from 'date-fns';
9
9
  import { explicitEffect } from 'ngxtension/explicit-effect';
10
10
 
@@ -64,8 +64,8 @@ class IonicButtonFieldComponent {
64
64
  this.eventBus.dispatch(event);
65
65
  }
66
66
  }
67
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
68
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: IonicButtonFieldComponent, isStandalone: true, selector: "df-ionic-button", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, event: { classPropertyName: "event", publicName: "event", isSignal: true, isRequired: false, transformFunction: null }, eventArgs: { classPropertyName: "eventArgs", publicName: "eventArgs", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, eventContext: { classPropertyName: "eventContext", publicName: "eventContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
67
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
68
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.8", type: IonicButtonFieldComponent, isStandalone: true, selector: "df-ion-button", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, event: { classPropertyName: "event", publicName: "event", isSignal: true, isRequired: false, transformFunction: null }, eventArgs: { classPropertyName: "eventArgs", publicName: "eventArgs", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, eventContext: { classPropertyName: "eventContext", publicName: "eventContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
69
69
  <ion-button
70
70
  [type]="buttonType()"
71
71
  [expand]="props()?.expand"
@@ -83,10 +83,10 @@ class IonicButtonFieldComponent {
83
83
  </ion-button>
84
84
  `, isInline: true, dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
85
85
  }
86
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicButtonFieldComponent, decorators: [{
86
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicButtonFieldComponent, decorators: [{
87
87
  type: Component,
88
88
  args: [{
89
- selector: 'df-ionic-button',
89
+ selector: 'df-ion-button',
90
90
  imports: [IonButton, DynamicTextPipe, AsyncPipe],
91
91
  host: {
92
92
  '[id]': '`${key()}`',
@@ -121,6 +121,7 @@ var ionicButton_component = /*#__PURE__*/Object.freeze({
121
121
  // Public API - component
122
122
 
123
123
  class IonicCheckboxFieldComponent {
124
+ elementRef = inject((ElementRef));
124
125
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
125
126
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
126
127
  // Properties
@@ -129,11 +130,18 @@ class IonicCheckboxFieldComponent {
129
130
  className = input('', ...(ngDevMode ? [{ debugName: "className" }] : []));
130
131
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
131
132
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
133
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
132
134
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
133
135
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
134
136
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
135
137
  showErrors = shouldShowErrors(this.field);
136
138
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
139
+ constructor() {
140
+ // Shadow DOM - apply meta to ion-checkbox element
141
+ setupMetaTracking(this.elementRef, this.meta, {
142
+ selector: 'ion-checkbox',
143
+ });
144
+ }
137
145
  // ─────────────────────────────────────────────────────────────────────────────
138
146
  // Accessibility
139
147
  // ─────────────────────────────────────────────────────────────────────────────
@@ -148,12 +156,12 @@ class IonicCheckboxFieldComponent {
148
156
  isRequired = computed(() => {
149
157
  return this.field()().required?.() === true;
150
158
  }, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
151
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
152
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicCheckboxFieldComponent, isStandalone: true, selector: "df-ionic-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
159
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
160
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicCheckboxFieldComponent, isStandalone: true, selector: "df-ion-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
153
161
  @let f = field();
154
162
 
155
163
  <ion-checkbox
156
- [field]="f"
164
+ [formField]="f"
157
165
  [labelPlacement]="props()?.labelPlacement ?? 'end'"
158
166
  [justify]="props()?.justify"
159
167
  [color]="props()?.color ?? 'primary'"
@@ -168,15 +176,15 @@ class IonicCheckboxFieldComponent {
168
176
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
169
177
  <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
170
178
  }
171
- `, isInline: true, styles: [":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
179
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
172
180
  }
173
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicCheckboxFieldComponent, decorators: [{
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicCheckboxFieldComponent, decorators: [{
174
182
  type: Component,
175
- args: [{ selector: 'df-ionic-checkbox', imports: [IonCheckbox, IonNote, Field, DynamicTextPipe, AsyncPipe], template: `
183
+ args: [{ selector: 'df-ion-checkbox', imports: [IonCheckbox, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
176
184
  @let f = field();
177
185
 
178
186
  <ion-checkbox
179
- [field]="f"
187
+ [formField]="f"
180
188
  [labelPlacement]="props()?.labelPlacement ?? 'end'"
181
189
  [justify]="props()?.justify"
182
190
  [color]="props()?.color ?? 'primary'"
@@ -196,8 +204,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
196
204
  '[id]': '`${key()}`',
197
205
  '[attr.data-testid]': 'key()',
198
206
  '[attr.hidden]': 'field()().hidden() || null',
199
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}:host([hidden]){display:none!important}\n"] }]
200
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
207
+ }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
208
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
201
209
 
202
210
  var ionicCheckbox_component = /*#__PURE__*/Object.freeze({
203
211
  __proto__: null,
@@ -205,6 +213,7 @@ var ionicCheckbox_component = /*#__PURE__*/Object.freeze({
205
213
  });
206
214
 
207
215
  class IonicDatepickerFieldComponent {
216
+ elementRef = inject((ElementRef));
208
217
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
209
218
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
210
219
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -215,12 +224,19 @@ class IonicDatepickerFieldComponent {
215
224
  maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
216
225
  startAt = input(null, ...(ngDevMode ? [{ debugName: "startAt" }] : []));
217
226
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
227
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
218
228
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
219
229
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
220
230
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
221
231
  showErrors = shouldShowErrors(this.field);
222
232
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
223
233
  isModalOpen = signal(false, ...(ngDevMode ? [{ debugName: "isModalOpen" }] : []));
234
+ constructor() {
235
+ // Shadow DOM - apply meta to ion-input element
236
+ setupMetaTracking(this.elementRef, this.meta, {
237
+ selector: 'ion-input',
238
+ });
239
+ }
224
240
  // ─────────────────────────────────────────────────────────────────────────────
225
241
  // Accessibility
226
242
  // ─────────────────────────────────────────────────────────────────────────────
@@ -279,9 +295,11 @@ class IonicDatepickerFieldComponent {
279
295
  return format(date, 'MMM d, yyyy');
280
296
  }
281
297
  }
282
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
283
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicDatepickerFieldComponent, isStandalone: true, selector: "df-ionic-datepicker", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, startAt: { classPropertyName: "startAt", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
298
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
299
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicDatepickerFieldComponent, isStandalone: true, selector: "df-ion-datepicker", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, startAt: { classPropertyName: "startAt", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
284
300
  @let f = field(); @let dateValue = f().value();
301
+ @let ariaInvalid = isAriaInvalid();
302
+ @let ariaRequired = isRequired() || null;
285
303
 
286
304
  <ion-input
287
305
  [label]="(label() | dynamicText | async) ?? undefined"
@@ -292,18 +310,13 @@ class IonicDatepickerFieldComponent {
292
310
  [readonly]="true"
293
311
  [fill]="'outline'"
294
312
  [attr.tabindex]="tabIndex()"
295
- [attr.aria-invalid]="isAriaInvalid()"
296
- [attr.aria-required]="isRequired() || null"
297
- [class.ion-invalid]="f().invalid()"
298
- [class.ion-touched]="f().touched()"
313
+ [attr.aria-invalid]="ariaInvalid"
314
+ [attr.aria-required]="ariaRequired"
299
315
  (click)="!f().disabled() && openModal()"
300
- >
301
- <div slot="error">
302
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
303
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
304
- }
305
- </div>
306
- </ion-input>
316
+ />
317
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
318
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
319
+ }
307
320
 
308
321
  <ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
309
322
  <ng-template>
@@ -334,11 +347,11 @@ class IonicDatepickerFieldComponent {
334
347
  </ion-content>
335
348
  </ng-template>
336
349
  </ion-modal>
337
- `, isInline: true, styles: ["ion-input{cursor:pointer}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: IonDatetime, selector: "ion-datetime", inputs: ["cancelText", "clearText", "color", "dayValues", "disabled", "doneText", "firstDayOfWeek", "formatOptions", "highlightedDates", "hourCycle", "hourValues", "isDateEnabled", "locale", "max", "min", "minuteValues", "mode", "monthValues", "multiple", "name", "preferWheel", "presentation", "readonly", "showAdjacentDays", "showClearButton", "showDefaultButtons", "showDefaultTimeLabel", "showDefaultTitle", "size", "titleSelectedDatesFormatter", "value", "yearValues"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
350
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", "ion-input{cursor:pointer}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: IonDatetime, selector: "ion-datetime", inputs: ["cancelText", "clearText", "color", "dayValues", "disabled", "doneText", "firstDayOfWeek", "formatOptions", "highlightedDates", "hourCycle", "hourValues", "isDateEnabled", "locale", "max", "min", "minuteValues", "mode", "monthValues", "multiple", "name", "preferWheel", "presentation", "readonly", "showAdjacentDays", "showClearButton", "showDefaultButtons", "showDefaultTimeLabel", "showDefaultTitle", "size", "titleSelectedDatesFormatter", "value", "yearValues"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
338
351
  }
339
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicDatepickerFieldComponent, decorators: [{
352
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicDatepickerFieldComponent, decorators: [{
340
353
  type: Component,
341
- args: [{ selector: 'df-ionic-datepicker', imports: [
354
+ args: [{ selector: 'df-ion-datepicker', imports: [
342
355
  IonInput,
343
356
  IonModal,
344
357
  IonDatetime,
@@ -353,6 +366,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
353
366
  AsyncPipe,
354
367
  ], template: `
355
368
  @let f = field(); @let dateValue = f().value();
369
+ @let ariaInvalid = isAriaInvalid();
370
+ @let ariaRequired = isRequired() || null;
356
371
 
357
372
  <ion-input
358
373
  [label]="(label() | dynamicText | async) ?? undefined"
@@ -363,18 +378,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
363
378
  [readonly]="true"
364
379
  [fill]="'outline'"
365
380
  [attr.tabindex]="tabIndex()"
366
- [attr.aria-invalid]="isAriaInvalid()"
367
- [attr.aria-required]="isRequired() || null"
368
- [class.ion-invalid]="f().invalid()"
369
- [class.ion-touched]="f().touched()"
381
+ [attr.aria-invalid]="ariaInvalid"
382
+ [attr.aria-required]="ariaRequired"
370
383
  (click)="!f().disabled() && openModal()"
371
- >
372
- <div slot="error">
373
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
374
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
375
- }
376
- </div>
377
- </ion-input>
384
+ />
385
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
386
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
387
+ }
378
388
 
379
389
  <ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
380
390
  <ng-template>
@@ -410,8 +420,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
410
420
  '[attr.data-testid]': 'key()',
411
421
  '[class]': 'className()',
412
422
  '[attr.hidden]': 'field()().hidden() || null',
413
- }, styles: ["ion-input{cursor:pointer}:host([hidden]){display:none!important}\n"] }]
414
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], startAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAt", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
423
+ }, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", "ion-input{cursor:pointer}:host([hidden]){display:none!important}\n"] }]
424
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], startAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAt", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
415
425
 
416
426
  var ionicDatepicker_component = /*#__PURE__*/Object.freeze({
417
427
  __proto__: null,
@@ -442,6 +452,7 @@ var ionicDatepicker_component = /*#__PURE__*/Object.freeze({
442
452
  const IONIC_CONFIG = new InjectionToken('IONIC_CONFIG');
443
453
 
444
454
  class IonicInputFieldComponent {
455
+ elementRef = inject((ElementRef));
445
456
  ionicConfig = inject(IONIC_CONFIG, { optional: true });
446
457
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
447
458
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
@@ -450,6 +461,7 @@ class IonicInputFieldComponent {
450
461
  className = input('', ...(ngDevMode ? [{ debugName: "className" }] : []));
451
462
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
452
463
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
464
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
453
465
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
454
466
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
455
467
  effectiveFill = computed(() => this.props()?.fill ?? this.ionicConfig?.fill ?? 'solid', ...(ngDevMode ? [{ debugName: "effectiveFill" }] : []));
@@ -459,6 +471,12 @@ class IonicInputFieldComponent {
459
471
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
460
472
  showErrors = shouldShowErrors(this.field);
461
473
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
474
+ constructor() {
475
+ // Shadow DOM - apply meta to ion-input element
476
+ setupMetaTracking(this.elementRef, this.meta, {
477
+ selector: 'ion-input',
478
+ });
479
+ }
462
480
  // ─────────────────────────────────────────────────────────────────────────────
463
481
  // Accessibility
464
482
  // ─────────────────────────────────────────────────────────────────────────────
@@ -473,15 +491,15 @@ class IonicInputFieldComponent {
473
491
  isRequired = computed(() => {
474
492
  return this.field()().required?.() === true;
475
493
  }, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
476
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
477
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicInputFieldComponent, isStandalone: true, selector: "df-ionic-input", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
494
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
495
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicInputFieldComponent, isStandalone: true, selector: "df-ion-input", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
478
496
  @let f = field();
479
497
  @let ariaInvalid = isAriaInvalid();
480
498
  @let ariaRequired = isRequired() || null;
481
499
 
482
500
  <ion-input
483
501
  [type]="props()?.type ?? 'text'"
484
- [field]="f"
502
+ [formField]="f"
485
503
  [label]="(label() | dynamicText | async) ?? undefined"
486
504
  [labelPlacement]="effectiveLabelPlacement()"
487
505
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -492,31 +510,25 @@ class IonicInputFieldComponent {
492
510
  [shape]="effectiveShape()"
493
511
  [readonly]="f().readonly()"
494
512
  [helperText]="(props()?.helperText | dynamicText | async) ?? undefined"
495
- [errorText]="f().invalid() && f().touched() ? ((props()?.errorText | dynamicText | async) ?? undefined) : undefined"
496
513
  [attr.tabindex]="tabIndex()"
497
514
  [attr.aria-invalid]="ariaInvalid"
498
515
  [attr.aria-required]="ariaRequired"
499
- [class.ion-invalid]="f().invalid()"
500
- [class.ion-touched]="f().touched()"
501
- >
502
- <div slot="error">
503
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
504
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
505
- }
506
- </div>
507
- </ion-input>
508
- `, isInline: true, styles: [":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
516
+ />
517
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
518
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
519
+ }
520
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
509
521
  }
510
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicInputFieldComponent, decorators: [{
522
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicInputFieldComponent, decorators: [{
511
523
  type: Component,
512
- args: [{ selector: 'df-ionic-input', imports: [IonInput, IonNote, Field, DynamicTextPipe, AsyncPipe], template: `
524
+ args: [{ selector: 'df-ion-input', imports: [IonInput, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
513
525
  @let f = field();
514
526
  @let ariaInvalid = isAriaInvalid();
515
527
  @let ariaRequired = isRequired() || null;
516
528
 
517
529
  <ion-input
518
530
  [type]="props()?.type ?? 'text'"
519
- [field]="f"
531
+ [formField]="f"
520
532
  [label]="(label() | dynamicText | async) ?? undefined"
521
533
  [labelPlacement]="effectiveLabelPlacement()"
522
534
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -527,26 +539,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
527
539
  [shape]="effectiveShape()"
528
540
  [readonly]="f().readonly()"
529
541
  [helperText]="(props()?.helperText | dynamicText | async) ?? undefined"
530
- [errorText]="f().invalid() && f().touched() ? ((props()?.errorText | dynamicText | async) ?? undefined) : undefined"
531
542
  [attr.tabindex]="tabIndex()"
532
543
  [attr.aria-invalid]="ariaInvalid"
533
544
  [attr.aria-required]="ariaRequired"
534
- [class.ion-invalid]="f().invalid()"
535
- [class.ion-touched]="f().touched()"
536
- >
537
- <div slot="error">
538
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
539
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
540
- }
541
- </div>
542
- </ion-input>
545
+ />
546
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
547
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
548
+ }
543
549
  `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
544
550
  '[id]': '`${key()}`',
545
551
  '[attr.data-testid]': 'key()',
546
552
  '[class]': 'className()',
547
553
  '[attr.hidden]': 'field()().hidden() || null',
548
- }, styles: [":host([hidden]){display:none!important}\n"] }]
549
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
554
+ }, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host([hidden]){display:none!important}\n"] }]
555
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
550
556
 
551
557
  var ionicInput_component = /*#__PURE__*/Object.freeze({
552
558
  __proto__: null,
@@ -554,6 +560,7 @@ var ionicInput_component = /*#__PURE__*/Object.freeze({
554
560
  });
555
561
 
556
562
  class IonicMultiCheckboxFieldComponent {
563
+ elementRef = inject((ElementRef));
557
564
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
558
565
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
559
566
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -562,6 +569,7 @@ class IonicMultiCheckboxFieldComponent {
562
569
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
563
570
  options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
564
571
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
572
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
565
573
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
566
574
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
567
575
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
@@ -586,6 +594,11 @@ class IonicMultiCheckboxFieldComponent {
586
594
  return this.options().filter((option) => currentValues.includes(option.value));
587
595
  }, { ...(ngDevMode ? { debugName: "valueViewModel" } : {}), equal: isEqual });
588
596
  constructor() {
597
+ // Shadow DOM - apply meta to ion-checkbox elements, re-apply when options change
598
+ setupMetaTracking(this.elementRef, this.meta, {
599
+ selector: 'ion-checkbox',
600
+ dependents: [this.options],
601
+ });
589
602
  explicitEffect([this.valueViewModel], ([selectedOptions]) => {
590
603
  const selectedValues = selectedOptions.map((option) => option.value);
591
604
  if (!isEqual(selectedValues, this.field()().value())) {
@@ -611,14 +624,21 @@ class IonicMultiCheckboxFieldComponent {
611
624
  }
612
625
  });
613
626
  }
614
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
615
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicMultiCheckboxFieldComponent, isStandalone: true, selector: "df-ionic-multi-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className() || \"\"", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, providers: [ValueInArrayPipe], ngImport: i0, template: `
627
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
628
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicMultiCheckboxFieldComponent, isStandalone: true, selector: "df-ion-multi-checkbox", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className() || \"\"", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, providers: [ValueInArrayPipe], ngImport: i0, template: `
616
629
  @let f = field();
617
630
  @if (label(); as label) {
618
631
  <div class="checkbox-group-label">{{ label | dynamicText | async }}</div>
619
632
  }
620
633
 
621
- <div class="checkbox-group" role="group" [attr.aria-invalid]="isAriaInvalid()" [attr.aria-required]="isRequired() || null">
634
+ <div
635
+ class="checkbox-group"
636
+ role="group"
637
+ [attr.aria-invalid]="isAriaInvalid()"
638
+ [attr.aria-required]="isRequired() || null"
639
+ [class.ion-invalid]="showErrors()"
640
+ [class.ion-touched]="field()().touched()"
641
+ >
622
642
  @for (option of options(); track option.value) {
623
643
  <ion-item lines="none">
624
644
  <ion-checkbox
@@ -638,17 +658,24 @@ class IonicMultiCheckboxFieldComponent {
638
658
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
639
659
  <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
640
660
  }
641
- `, isInline: true, styles: [":host{display:block}:host([hidden]){display:none!important}.checkbox-group-label{margin-bottom:8px;font-weight:500}.checkbox-group{display:flex;flex-direction:column;gap:4px}ion-item{--padding-start: 0;--inner-padding-end: 0}\n"], dependencies: [{ kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "pipe", type: ValueInArrayPipe, name: "inArray" }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
661
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}.checkbox-group-label{margin-bottom:8px;font-weight:500}.checkbox-group{display:flex;flex-direction:column;gap:4px}ion-item{--padding-start: 0;--inner-padding-end: 0}\n"], dependencies: [{ kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "pipe", type: ValueInArrayPipe, name: "inArray" }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
642
662
  }
643
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicMultiCheckboxFieldComponent, decorators: [{
663
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicMultiCheckboxFieldComponent, decorators: [{
644
664
  type: Component,
645
- args: [{ selector: 'df-ionic-multi-checkbox', imports: [IonCheckbox, IonItem, IonNote, ValueInArrayPipe, DynamicTextPipe, AsyncPipe], template: `
665
+ args: [{ selector: 'df-ion-multi-checkbox', imports: [IonCheckbox, IonItem, IonNote, ValueInArrayPipe, DynamicTextPipe, AsyncPipe], template: `
646
666
  @let f = field();
647
667
  @if (label(); as label) {
648
668
  <div class="checkbox-group-label">{{ label | dynamicText | async }}</div>
649
669
  }
650
670
 
651
- <div class="checkbox-group" role="group" [attr.aria-invalid]="isAriaInvalid()" [attr.aria-required]="isRequired() || null">
671
+ <div
672
+ class="checkbox-group"
673
+ role="group"
674
+ [attr.aria-invalid]="isAriaInvalid()"
675
+ [attr.aria-required]="isRequired() || null"
676
+ [class.ion-invalid]="showErrors()"
677
+ [class.ion-touched]="field()().touched()"
678
+ >
652
679
  @for (option of options(); track option.value) {
653
680
  <ion-item lines="none">
654
681
  <ion-checkbox
@@ -673,8 +700,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
673
700
  '[id]': '`${key()}`',
674
701
  '[attr.data-testid]': 'key()',
675
702
  '[attr.hidden]': 'field()().hidden() || null',
676
- }, providers: [ValueInArrayPipe], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}:host([hidden]){display:none!important}.checkbox-group-label{margin-bottom:8px;font-weight:500}.checkbox-group{display:flex;flex-direction:column;gap:4px}ion-item{--padding-start: 0;--inner-padding-end: 0}\n"] }]
677
- }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
703
+ }, providers: [ValueInArrayPipe], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}.checkbox-group-label{margin-bottom:8px;font-weight:500}.checkbox-group{display:flex;flex-direction:column;gap:4px}ion-item{--padding-start: 0;--inner-padding-end: 0}\n"] }]
704
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
678
705
 
679
706
  var ionicMultiCheckbox_component = /*#__PURE__*/Object.freeze({
680
707
  __proto__: null,
@@ -682,6 +709,7 @@ var ionicMultiCheckbox_component = /*#__PURE__*/Object.freeze({
682
709
  });
683
710
 
684
711
  class IonicRadioFieldComponent {
712
+ elementRef = inject((ElementRef));
685
713
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
686
714
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
687
715
  // Properties
@@ -691,12 +719,20 @@ class IonicRadioFieldComponent {
691
719
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
692
720
  options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
693
721
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
722
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
694
723
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
695
724
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
696
725
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
697
726
  showErrors = shouldShowErrors(this.field);
698
727
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
699
728
  defaultCompare = Object.is;
729
+ constructor() {
730
+ // Shadow DOM - apply meta to ion-radio elements, re-apply when options change
731
+ setupMetaTracking(this.elementRef, this.meta, {
732
+ selector: 'ion-radio',
733
+ dependents: [this.options],
734
+ });
735
+ }
700
736
  // ─────────────────────────────────────────────────────────────────────────────
701
737
  // Accessibility
702
738
  // ─────────────────────────────────────────────────────────────────────────────
@@ -711,15 +747,15 @@ class IonicRadioFieldComponent {
711
747
  isRequired = computed(() => {
712
748
  return this.field()().required?.() === true;
713
749
  }, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
714
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
715
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicRadioFieldComponent, isStandalone: true, selector: "df-ionic-radio", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
750
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
751
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicRadioFieldComponent, isStandalone: true, selector: "df-ion-radio", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
716
752
  @let f = field();
717
753
  @if (label(); as label) {
718
754
  <div class="radio-label">{{ label | dynamicText | async }}</div>
719
755
  }
720
756
 
721
757
  <ion-radio-group
722
- [field]="f"
758
+ [formField]="f"
723
759
  [compareWith]="props()?.compareWith || defaultCompare"
724
760
  [attr.aria-invalid]="isAriaInvalid()"
725
761
  [attr.aria-required]="isRequired() || null"
@@ -742,18 +778,18 @@ class IonicRadioFieldComponent {
742
778
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
743
779
  <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
744
780
  }
745
- `, isInline: true, styles: [":host{display:block}:host([hidden]){display:none!important}.radio-label{font-size:.875rem;font-weight:500;margin-bottom:.5rem;color:var(--ion-text-color)}\n"], dependencies: [{ kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "errorText", "helperText", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
781
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}.radio-label{font-size:.875rem;font-weight:500;margin-bottom:.5rem;color:var(--ion-text-color)}\n"], dependencies: [{ kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "errorText", "helperText", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
746
782
  }
747
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicRadioFieldComponent, decorators: [{
783
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicRadioFieldComponent, decorators: [{
748
784
  type: Component,
749
- args: [{ selector: 'df-ionic-radio', imports: [IonRadioGroup, IonRadio, IonItem, IonNote, Field, DynamicTextPipe, AsyncPipe], template: `
785
+ args: [{ selector: 'df-ion-radio', imports: [IonRadioGroup, IonRadio, IonItem, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
750
786
  @let f = field();
751
787
  @if (label(); as label) {
752
788
  <div class="radio-label">{{ label | dynamicText | async }}</div>
753
789
  }
754
790
 
755
791
  <ion-radio-group
756
- [field]="f"
792
+ [formField]="f"
757
793
  [compareWith]="props()?.compareWith || defaultCompare"
758
794
  [attr.aria-invalid]="isAriaInvalid()"
759
795
  [attr.aria-required]="isRequired() || null"
@@ -781,8 +817,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
781
817
  '[id]': '`${key()}`',
782
818
  '[attr.data-testid]': 'key()',
783
819
  '[attr.hidden]': 'field()().hidden() || null',
784
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}:host([hidden]){display:none!important}.radio-label{font-size:.875rem;font-weight:500;margin-bottom:.5rem;color:var(--ion-text-color)}\n"] }]
785
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
820
+ }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}.radio-label{font-size:.875rem;font-weight:500;margin-bottom:.5rem;color:var(--ion-text-color)}\n"] }]
821
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
786
822
 
787
823
  var ionicRadio_component = /*#__PURE__*/Object.freeze({
788
824
  __proto__: null,
@@ -790,6 +826,7 @@ var ionicRadio_component = /*#__PURE__*/Object.freeze({
790
826
  });
791
827
 
792
828
  class IonicSelectFieldComponent {
829
+ elementRef = inject((ElementRef));
793
830
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
794
831
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
795
832
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -798,8 +835,12 @@ class IonicSelectFieldComponent {
798
835
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
799
836
  options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
800
837
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
838
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
801
839
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
802
840
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
841
+ constructor() {
842
+ setupMetaTracking(this.elementRef, this.meta);
843
+ }
803
844
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
804
845
  showErrors = shouldShowErrors(this.field);
805
846
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
@@ -818,12 +859,14 @@ class IonicSelectFieldComponent {
818
859
  isRequired = computed(() => {
819
860
  return this.field()().required?.() === true;
820
861
  }, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
821
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
822
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicSelectFieldComponent, isStandalone: true, selector: "df-ionic-select", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
862
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
863
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicSelectFieldComponent, isStandalone: true, selector: "df-ion-select", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
823
864
  @let f = field();
865
+ @let ariaInvalid = isAriaInvalid();
866
+ @let ariaRequired = isRequired() || null;
824
867
 
825
868
  <ion-select
826
- [field]="f"
869
+ [formField]="f"
827
870
  [label]="(label() | dynamicText | async) ?? undefined"
828
871
  [labelPlacement]="props()?.labelPlacement ?? 'stacked'"
829
872
  [placeholder]="(placeholder() ?? props()?.placeholder | dynamicText | async) ?? ''"
@@ -837,31 +880,29 @@ class IonicSelectFieldComponent {
837
880
  [fill]="props()?.fill ?? 'outline'"
838
881
  [shape]="props()?.shape"
839
882
  [attr.tabindex]="tabIndex()"
840
- [attr.aria-invalid]="isAriaInvalid()"
841
- [attr.aria-required]="isRequired() || null"
842
- [class.ion-invalid]="f().invalid()"
843
- [class.ion-touched]="f().touched()"
883
+ [attr.aria-invalid]="ariaInvalid"
884
+ [attr.aria-required]="ariaRequired"
844
885
  >
845
886
  @for (option of options(); track option.value) {
846
887
  <ion-select-option [value]="option.value" [disabled]="option.disabled || false">
847
888
  {{ option.label | dynamicText | async }}
848
889
  </ion-select-option>
849
890
  }
850
- <div slot="error">
851
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
852
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
853
- }
854
- </div>
855
891
  </ion-select>
856
- `, isInline: true, styles: [":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
892
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
893
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
894
+ }
895
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
857
896
  }
858
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicSelectFieldComponent, decorators: [{
897
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicSelectFieldComponent, decorators: [{
859
898
  type: Component,
860
- args: [{ selector: 'df-ionic-select', imports: [IonSelect, IonSelectOption, IonNote, Field, DynamicTextPipe, AsyncPipe], template: `
899
+ args: [{ selector: 'df-ion-select', imports: [IonSelect, IonSelectOption, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
861
900
  @let f = field();
901
+ @let ariaInvalid = isAriaInvalid();
902
+ @let ariaRequired = isRequired() || null;
862
903
 
863
904
  <ion-select
864
- [field]="f"
905
+ [formField]="f"
865
906
  [label]="(label() | dynamicText | async) ?? undefined"
866
907
  [labelPlacement]="props()?.labelPlacement ?? 'stacked'"
867
908
  [placeholder]="(placeholder() ?? props()?.placeholder | dynamicText | async) ?? ''"
@@ -875,29 +916,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
875
916
  [fill]="props()?.fill ?? 'outline'"
876
917
  [shape]="props()?.shape"
877
918
  [attr.tabindex]="tabIndex()"
878
- [attr.aria-invalid]="isAriaInvalid()"
879
- [attr.aria-required]="isRequired() || null"
880
- [class.ion-invalid]="f().invalid()"
881
- [class.ion-touched]="f().touched()"
919
+ [attr.aria-invalid]="ariaInvalid"
920
+ [attr.aria-required]="ariaRequired"
882
921
  >
883
922
  @for (option of options(); track option.value) {
884
923
  <ion-select-option [value]="option.value" [disabled]="option.disabled || false">
885
924
  {{ option.label | dynamicText | async }}
886
925
  </ion-select-option>
887
926
  }
888
- <div slot="error">
889
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
890
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
891
- }
892
- </div>
893
927
  </ion-select>
928
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
929
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
930
+ }
894
931
  `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
895
932
  '[id]': '`${key()}`',
896
933
  '[attr.data-testid]': 'key()',
897
934
  '[class]': 'className()',
898
935
  '[attr.hidden]': 'field()().hidden() || null',
899
- }, styles: [":host([hidden]){display:none!important}\n"] }]
900
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
936
+ }, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host([hidden]){display:none!important}\n"] }]
937
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
901
938
 
902
939
  var ionicSelect_component = /*#__PURE__*/Object.freeze({
903
940
  __proto__: null,
@@ -905,6 +942,7 @@ var ionicSelect_component = /*#__PURE__*/Object.freeze({
905
942
  });
906
943
 
907
944
  class IonicSliderFieldComponent {
945
+ elementRef = inject((ElementRef));
908
946
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
909
947
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
910
948
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -912,8 +950,12 @@ class IonicSliderFieldComponent {
912
950
  className = input('', ...(ngDevMode ? [{ debugName: "className" }] : []));
913
951
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
914
952
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
953
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
915
954
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
916
955
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
956
+ constructor() {
957
+ setupMetaTracking(this.elementRef, this.meta);
958
+ }
917
959
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
918
960
  showErrors = shouldShowErrors(this.field);
919
961
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
@@ -932,12 +974,12 @@ class IonicSliderFieldComponent {
932
974
  isRequired = computed(() => {
933
975
  return this.field()().required?.() === true;
934
976
  }, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
935
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
936
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicSliderFieldComponent, isStandalone: true, selector: "df-ionic-slider", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
977
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
978
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicSliderFieldComponent, isStandalone: true, selector: "df-ion-slider", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
937
979
  @let f = field();
938
980
 
939
981
  <ion-range
940
- [field]="f"
982
+ [formField]="f"
941
983
  [label]="(label() | dynamicText | async) ?? undefined"
942
984
  [labelPlacement]="props()?.labelPlacement ?? 'stacked'"
943
985
  [step]="props()?.step ?? 1"
@@ -955,15 +997,15 @@ class IonicSliderFieldComponent {
955
997
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
956
998
  <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
957
999
  }
958
- `, isInline: true, styles: [":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonRange, selector: "ion-range", inputs: ["activeBarStart", "color", "debounce", "disabled", "dualKnobs", "label", "labelPlacement", "max", "min", "mode", "name", "pin", "pinFormatter", "snaps", "step", "ticks", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1000
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonRange, selector: "ion-range", inputs: ["activeBarStart", "color", "debounce", "disabled", "dualKnobs", "label", "labelPlacement", "max", "min", "mode", "name", "pin", "pinFormatter", "snaps", "step", "ticks", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
959
1001
  }
960
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicSliderFieldComponent, decorators: [{
1002
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicSliderFieldComponent, decorators: [{
961
1003
  type: Component,
962
- args: [{ selector: 'df-ionic-slider', imports: [IonRange, IonNote, Field, DynamicTextPipe, AsyncPipe], template: `
1004
+ args: [{ selector: 'df-ion-slider', imports: [IonRange, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
963
1005
  @let f = field();
964
1006
 
965
1007
  <ion-range
966
- [field]="f"
1008
+ [formField]="f"
967
1009
  [label]="(label() | dynamicText | async) ?? undefined"
968
1010
  [labelPlacement]="props()?.labelPlacement ?? 'stacked'"
969
1011
  [step]="props()?.step ?? 1"
@@ -986,8 +1028,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
986
1028
  '[id]': '`${key()}`',
987
1029
  '[attr.data-testid]': 'key()',
988
1030
  '[attr.hidden]': 'field()().hidden() || null',
989
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}:host([hidden]){display:none!important}\n"] }]
990
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1031
+ }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
1032
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
991
1033
 
992
1034
  var ionicSlider_component = /*#__PURE__*/Object.freeze({
993
1035
  __proto__: null,
@@ -995,6 +1037,7 @@ var ionicSlider_component = /*#__PURE__*/Object.freeze({
995
1037
  });
996
1038
 
997
1039
  class IonicTextareaFieldComponent {
1040
+ elementRef = inject((ElementRef));
998
1041
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
999
1042
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
1000
1043
  label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
@@ -1002,11 +1045,18 @@ class IonicTextareaFieldComponent {
1002
1045
  className = input('', ...(ngDevMode ? [{ debugName: "className" }] : []));
1003
1046
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
1004
1047
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
1048
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1005
1049
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
1006
1050
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
1007
1051
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
1008
1052
  showErrors = shouldShowErrors(this.field);
1009
1053
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
1054
+ constructor() {
1055
+ // Shadow DOM - apply meta to ion-textarea element
1056
+ setupMetaTracking(this.elementRef, this.meta, {
1057
+ selector: 'ion-textarea',
1058
+ });
1059
+ }
1010
1060
  // ─────────────────────────────────────────────────────────────────────────────
1011
1061
  // Accessibility
1012
1062
  // ─────────────────────────────────────────────────────────────────────────────
@@ -1021,12 +1071,14 @@ class IonicTextareaFieldComponent {
1021
1071
  isRequired = computed(() => {
1022
1072
  return this.field()().required?.() === true;
1023
1073
  }, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
1024
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1025
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicTextareaFieldComponent, isStandalone: true, selector: "df-ionic-textarea", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1074
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1075
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicTextareaFieldComponent, isStandalone: true, selector: "df-ion-textarea", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "class": "className()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1026
1076
  @let f = field();
1077
+ @let ariaInvalid = isAriaInvalid();
1078
+ @let ariaRequired = isRequired() || null;
1027
1079
 
1028
1080
  <ion-textarea
1029
- [field]="f"
1081
+ [formField]="f"
1030
1082
  [label]="(label() | dynamicText | async) ?? undefined"
1031
1083
  [labelPlacement]="props()?.labelPlacement ?? 'stacked'"
1032
1084
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -1038,28 +1090,24 @@ class IonicTextareaFieldComponent {
1038
1090
  [shape]="props()?.shape"
1039
1091
  [readonly]="f().readonly()"
1040
1092
  [helperText]="(props()?.helperText | dynamicText | async) ?? undefined"
1041
- [errorText]="f().invalid() && f().touched() ? ((props()?.errorText | dynamicText | async) ?? undefined) : undefined"
1042
1093
  [attr.tabindex]="tabIndex()"
1043
- [attr.aria-invalid]="isAriaInvalid()"
1044
- [attr.aria-required]="isRequired() || null"
1045
- [class.ion-invalid]="f().invalid()"
1046
- [class.ion-touched]="f().touched()"
1047
- >
1048
- <div slot="error">
1049
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
1050
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
1051
- }
1052
- </div>
1053
- </ion-textarea>
1054
- `, isInline: true, styles: [":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1094
+ [attr.aria-invalid]="ariaInvalid"
1095
+ [attr.aria-required]="ariaRequired"
1096
+ />
1097
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
1098
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
1099
+ }
1100
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1055
1101
  }
1056
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicTextareaFieldComponent, decorators: [{
1102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicTextareaFieldComponent, decorators: [{
1057
1103
  type: Component,
1058
- args: [{ selector: 'df-ionic-textarea', imports: [IonTextarea, IonNote, Field, DynamicTextPipe, AsyncPipe], template: `
1104
+ args: [{ selector: 'df-ion-textarea', imports: [IonTextarea, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
1059
1105
  @let f = field();
1106
+ @let ariaInvalid = isAriaInvalid();
1107
+ @let ariaRequired = isRequired() || null;
1060
1108
 
1061
1109
  <ion-textarea
1062
- [field]="f"
1110
+ [formField]="f"
1063
1111
  [label]="(label() | dynamicText | async) ?? undefined"
1064
1112
  [labelPlacement]="props()?.labelPlacement ?? 'stacked'"
1065
1113
  [placeholder]="(placeholder() | dynamicText | async) ?? ''"
@@ -1071,26 +1119,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
1071
1119
  [shape]="props()?.shape"
1072
1120
  [readonly]="f().readonly()"
1073
1121
  [helperText]="(props()?.helperText | dynamicText | async) ?? undefined"
1074
- [errorText]="f().invalid() && f().touched() ? ((props()?.errorText | dynamicText | async) ?? undefined) : undefined"
1075
1122
  [attr.tabindex]="tabIndex()"
1076
- [attr.aria-invalid]="isAriaInvalid()"
1077
- [attr.aria-required]="isRequired() || null"
1078
- [class.ion-invalid]="f().invalid()"
1079
- [class.ion-touched]="f().touched()"
1080
- >
1081
- <div slot="error">
1082
- @for (error of errorsToDisplay(); track error.kind; let i = $index) {
1083
- <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
1084
- }
1085
- </div>
1086
- </ion-textarea>
1123
+ [attr.aria-invalid]="ariaInvalid"
1124
+ [attr.aria-required]="ariaRequired"
1125
+ />
1126
+ @for (error of errorsToDisplay(); track error.kind; let i = $index) {
1127
+ <ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
1128
+ }
1087
1129
  `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1088
1130
  '[id]': '`${key()}`',
1089
1131
  '[attr.data-testid]': 'key()',
1090
1132
  '[class]': 'className()',
1091
1133
  '[attr.hidden]': 'field()().hidden() || null',
1092
- }, styles: [":host([hidden]){display:none!important}\n"] }]
1093
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1134
+ }, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host([hidden]){display:none!important}\n"] }]
1135
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1094
1136
 
1095
1137
  var ionicTextarea_component = /*#__PURE__*/Object.freeze({
1096
1138
  __proto__: null,
@@ -1105,6 +1147,7 @@ var ionicTextarea_component = /*#__PURE__*/Object.freeze({
1105
1147
  * The Field directive binds to the `checked` model for checkbox controls.
1106
1148
  */
1107
1149
  class IonicToggleControlComponent {
1150
+ elementRef = inject((ElementRef));
1108
1151
  // ─────────────────────────────────────────────────────────────────────────────
1109
1152
  // FormCheckboxControl implementation
1110
1153
  // ─────────────────────────────────────────────────────────────────────────────
@@ -1128,6 +1171,13 @@ class IonicToggleControlComponent {
1128
1171
  color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
1129
1172
  enableOnOffLabels = input(false, ...(ngDevMode ? [{ debugName: "enableOnOffLabels" }] : []));
1130
1173
  tabIndex = input(undefined, ...(ngDevMode ? [{ debugName: "tabIndex" }] : []));
1174
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1175
+ constructor() {
1176
+ // Shadow DOM - apply meta to ion-toggle element
1177
+ setupMetaTracking(this.elementRef, this.meta, {
1178
+ selector: 'ion-toggle',
1179
+ });
1180
+ }
1131
1181
  // ─────────────────────────────────────────────────────────────────────────────
1132
1182
  // Computed ARIA attributes
1133
1183
  // ─────────────────────────────────────────────────────────────────────────────
@@ -1165,8 +1215,8 @@ class IonicToggleControlComponent {
1165
1215
  onBlur() {
1166
1216
  this.touched.set(true);
1167
1217
  }
1168
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicToggleControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1169
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: IonicToggleControlComponent, isStandalone: true, selector: "df-ionic-toggle-control", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, labelPlacement: { classPropertyName: "labelPlacement", publicName: "labelPlacement", isSignal: true, isRequired: false, transformFunction: null }, justify: { classPropertyName: "justify", publicName: "justify", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, enableOnOffLabels: { classPropertyName: "enableOnOffLabels", publicName: "enableOnOffLabels", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", touched: "touchedChange" }, ngImport: i0, template: `
1218
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicToggleControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1219
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.8", type: IonicToggleControlComponent, isStandalone: true, selector: "df-ion-toggle-control", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, labelPlacement: { classPropertyName: "labelPlacement", publicName: "labelPlacement", isSignal: true, isRequired: false, transformFunction: null }, justify: { classPropertyName: "justify", publicName: "justify", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, enableOnOffLabels: { classPropertyName: "enableOnOffLabels", publicName: "enableOnOffLabels", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", touched: "touchedChange" }, ngImport: i0, template: `
1170
1220
  <ion-toggle
1171
1221
  [checked]="isChecked()"
1172
1222
  (ionChange)="onToggleChange($event)"
@@ -1183,14 +1233,11 @@ class IonicToggleControlComponent {
1183
1233
  >
1184
1234
  <ng-content />
1185
1235
  </ion-toggle>
1186
- `, isInline: true, dependencies: [{ kind: "component", type: IonToggle, selector: "ion-toggle", inputs: ["checked", "color", "disabled", "enableOnOffLabels", "errorText", "helperText", "justify", "labelPlacement", "mode", "name", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1236
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n"], dependencies: [{ kind: "component", type: IonToggle, selector: "ion-toggle", inputs: ["checked", "color", "disabled", "enableOnOffLabels", "errorText", "helperText", "justify", "labelPlacement", "mode", "name", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1187
1237
  }
1188
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicToggleControlComponent, decorators: [{
1238
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicToggleControlComponent, decorators: [{
1189
1239
  type: Component,
1190
- args: [{
1191
- selector: 'df-ionic-toggle-control',
1192
- imports: [IonToggle],
1193
- template: `
1240
+ args: [{ selector: 'df-ion-toggle-control', imports: [IonToggle], template: `
1194
1241
  <ion-toggle
1195
1242
  [checked]="isChecked()"
1196
1243
  (ionChange)="onToggleChange($event)"
@@ -1207,12 +1254,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
1207
1254
  >
1208
1255
  <ng-content />
1209
1256
  </ion-toggle>
1210
- `,
1211
- changeDetection: ChangeDetectionStrategy.OnPush,
1212
- }]
1213
- }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], labelPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPlacement", required: false }] }], justify: [{ type: i0.Input, args: [{ isSignal: true, alias: "justify", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], enableOnOffLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableOnOffLabels", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }] } });
1257
+ `, host: {}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n"] }]
1258
+ }], ctorParameters: () => [], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], labelPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPlacement", required: false }] }], justify: [{ type: i0.Input, args: [{ isSignal: true, alias: "justify", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], enableOnOffLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableOnOffLabels", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }] } });
1214
1259
 
1215
1260
  class IonicToggleFieldComponent {
1261
+ elementRef = inject((ElementRef));
1216
1262
  field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
1217
1263
  key = input.required(...(ngDevMode ? [{ debugName: "key" }] : []));
1218
1264
  // Properties
@@ -1221,8 +1267,12 @@ class IonicToggleFieldComponent {
1221
1267
  className = input('', ...(ngDevMode ? [{ debugName: "className" }] : []));
1222
1268
  tabIndex = input(...(ngDevMode ? [undefined, { debugName: "tabIndex" }] : []));
1223
1269
  props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : []));
1270
+ meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
1224
1271
  validationMessages = input(...(ngDevMode ? [undefined, { debugName: "validationMessages" }] : []));
1225
1272
  defaultValidationMessages = input(...(ngDevMode ? [undefined, { debugName: "defaultValidationMessages" }] : []));
1273
+ constructor() {
1274
+ setupMetaTracking(this.elementRef, this.meta);
1275
+ }
1226
1276
  resolvedErrors = createResolvedErrorsSignal(this.field, this.validationMessages, this.defaultValidationMessages);
1227
1277
  showErrors = shouldShowErrors(this.field);
1228
1278
  errorsToDisplay = computed(() => (this.showErrors() ? this.resolvedErrors() : []), ...(ngDevMode ? [{ debugName: "errorsToDisplay" }] : []));
@@ -1231,12 +1281,13 @@ class IonicToggleFieldComponent {
1231
1281
  // ─────────────────────────────────────────────────────────────────────────────
1232
1282
  /** Base ID for error elements */
1233
1283
  errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
1234
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1235
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: IonicToggleFieldComponent, isStandalone: true, selector: "df-ionic-toggle", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1284
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1285
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: IonicToggleFieldComponent, isStandalone: true, selector: "df-ion-toggle", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, meta: { classPropertyName: "meta", publicName: "meta", isSignal: true, isRequired: false, transformFunction: null }, validationMessages: { classPropertyName: "validationMessages", publicName: "validationMessages", isSignal: true, isRequired: false, transformFunction: null }, defaultValidationMessages: { classPropertyName: "defaultValidationMessages", publicName: "defaultValidationMessages", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "className()", "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "field()().hidden() || null" } }, ngImport: i0, template: `
1236
1286
  @let f = field();
1237
1287
 
1238
- <df-ionic-toggle-control
1239
- [field]="f"
1288
+ <df-ion-toggle-control
1289
+ [formField]="f"
1290
+ [meta]="meta()"
1240
1291
  [labelPlacement]="props()?.labelPlacement ?? 'end'"
1241
1292
  [justify]="props()?.justify"
1242
1293
  [color]="props()?.color ?? 'primary'"
@@ -1244,20 +1295,21 @@ class IonicToggleFieldComponent {
1244
1295
  [tabIndex]="tabIndex()"
1245
1296
  >
1246
1297
  {{ label() | dynamicText | async }}
1247
- </df-ionic-toggle-control>
1298
+ </df-ion-toggle-control>
1248
1299
 
1249
1300
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
1250
1301
  <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
1251
1302
  }
1252
- `, isInline: true, styles: [":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonicToggleControlComponent, selector: "df-ionic-toggle-control", inputs: ["checked", "touched", "disabled", "readonly", "invalid", "required", "labelPlacement", "justify", "color", "enableOnOffLabels", "tabIndex"], outputs: ["checkedChange", "touchedChange"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: Field, selector: "[field]", inputs: ["field"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1303
+ `, isInline: true, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonicToggleControlComponent, selector: "df-ion-toggle-control", inputs: ["checked", "touched", "disabled", "readonly", "invalid", "required", "labelPlacement", "justify", "color", "enableOnOffLabels", "tabIndex", "meta"], outputs: ["checkedChange", "touchedChange"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1253
1304
  }
1254
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IonicToggleFieldComponent, decorators: [{
1305
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: IonicToggleFieldComponent, decorators: [{
1255
1306
  type: Component,
1256
- args: [{ selector: 'df-ionic-toggle', imports: [IonicToggleControlComponent, IonNote, Field, DynamicTextPipe, AsyncPipe], template: `
1307
+ args: [{ selector: 'df-ion-toggle', imports: [IonicToggleControlComponent, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
1257
1308
  @let f = field();
1258
1309
 
1259
- <df-ionic-toggle-control
1260
- [field]="f"
1310
+ <df-ion-toggle-control
1311
+ [formField]="f"
1312
+ [meta]="meta()"
1261
1313
  [labelPlacement]="props()?.labelPlacement ?? 'end'"
1262
1314
  [justify]="props()?.justify"
1263
1315
  [color]="props()?.color ?? 'primary'"
@@ -1265,7 +1317,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
1265
1317
  [tabIndex]="tabIndex()"
1266
1318
  >
1267
1319
  {{ label() | dynamicText | async }}
1268
- </df-ionic-toggle-control>
1320
+ </df-ion-toggle-control>
1269
1321
 
1270
1322
  @for (error of errorsToDisplay(); track error.kind; let i = $index) {
1271
1323
  <ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
@@ -1275,8 +1327,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
1275
1327
  '[id]': '`${key()}`',
1276
1328
  '[attr.data-testid]': 'key()',
1277
1329
  '[attr.hidden]': 'field()().hidden() || null',
1278
- }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}:host([hidden]){display:none!important}\n"] }]
1279
- }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1330
+ }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--df-field-gap: .5rem;--df-label-font-weight: 500;--df-label-color: inherit;--df-hint-color: var(--ion-color-medium, #92949c);--df-hint-font-size: .875rem;--df-error-color: var(--ion-color-danger, #eb445a);--df-error-font-size: .875rem}.df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight);color:var(--df-label-color)}.df-ion-hint{color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{color:var(--df-error-color);font-size:var(--df-error-font-size)}:host([hidden]){display:none!important}ion-input.ng-invalid.ng-touched,ion-textarea.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-select.ng-invalid.ng-touched{--highlight-color: var(--ion-color-danger);--border-color: var(--ion-color-danger)}ion-checkbox.ng-invalid.ng-touched{--checkbox-background-checked: var(--ion-color-danger);--border-color: var(--ion-color-danger);--border-color-checked: var(--ion-color-danger)}ion-radio.ng-invalid.ng-touched{--color: var(--ion-color-danger);--color-checked: var(--ion-color-danger)}ion-range.ng-invalid.ng-touched{--bar-background: var(--ion-color-danger);--knob-background: var(--ion-color-danger)}ion-toggle.ng-invalid.ng-touched{--track-background: var(--ion-color-danger-tint);--track-background-checked: var(--ion-color-danger);--handle-background-checked: var(--ion-color-danger-contrast)}\n", ":host{display:block}:host([hidden]){display:none!important}\n"] }]
1331
+ }], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], meta: [{ type: i0.Input, args: [{ isSignal: true, alias: "meta", required: false }] }], validationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMessages", required: false }] }], defaultValidationMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValidationMessages", required: false }] }] } });
1280
1332
 
1281
1333
  var ionicToggle_component = /*#__PURE__*/Object.freeze({
1282
1334
  __proto__: null,
@@ -1572,6 +1624,7 @@ const IONIC_FIELD_TYPES = [
1572
1624
  name: IonicField.Input,
1573
1625
  loadComponent: () => Promise.resolve().then(function () { return ionicInput_component; }),
1574
1626
  mapper: valueFieldMapper,
1627
+ propsToMeta: ['type'],
1575
1628
  },
1576
1629
  {
1577
1630
  name: IonicField.Select,
@@ -1623,6 +1676,7 @@ const IONIC_FIELD_TYPES = [
1623
1676
  name: IonicField.Textarea,
1624
1677
  loadComponent: () => Promise.resolve().then(function () { return ionicTextarea_component; }),
1625
1678
  mapper: valueFieldMapper,
1679
+ propsToMeta: ['rows'],
1626
1680
  },
1627
1681
  {
1628
1682
  name: IonicField.Radio,