@ng-forge/dynamic-forms-ionic 0.3.0 → 0.4.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
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
|
-
import { EventBus, ARRAY_CONTEXT, resolveTokens, DynamicTextPipe, buildBaseInputs,
|
|
4
|
+
import { EventBus, ARRAY_CONTEXT, resolveTokens, DynamicTextPipe, DEFAULT_PROPS, buildBaseInputs, RootFormRegistryService, FORM_OPTIONS, resolveSubmitButtonDisabled, FIELD_SIGNAL_CONTEXT, resolveNextButtonDisabled, NextPageEvent, PreviousPageEvent, DynamicFormLogger, AddArrayItemEvent, RemoveArrayItemEvent } from '@ng-forge/dynamic-forms';
|
|
5
5
|
import { AsyncPipe } from '@angular/common';
|
|
6
6
|
import { FormField } from '@angular/forms/signals';
|
|
7
|
-
import { createResolvedErrorsSignal, shouldShowErrors, setupMetaTracking, isEqual,
|
|
7
|
+
import { createResolvedErrorsSignal, shouldShowErrors, setupMetaTracking, isEqual, 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,9 +64,12 @@ class IonicButtonFieldComponent {
|
|
|
64
64
|
this.eventBus.dispatch(event);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
68
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0
|
|
67
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
68
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", 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()}`", "class": "className()", "attr.data-testid": "key()", "attr.hidden": "hidden() || null" } }, ngImport: i0, template: `
|
|
69
|
+
@let buttonId = key() + '-button';
|
|
70
|
+
|
|
69
71
|
<ion-button
|
|
72
|
+
[id]="buttonId"
|
|
70
73
|
[type]="buttonType()"
|
|
71
74
|
[expand]="props()?.expand"
|
|
72
75
|
[fill]="props()?.fill || 'solid'"
|
|
@@ -74,26 +77,26 @@ class IonicButtonFieldComponent {
|
|
|
74
77
|
[size]="props()?.size"
|
|
75
78
|
[color]="props()?.color || 'primary'"
|
|
76
79
|
[strong]="props()?.strong"
|
|
77
|
-
[class]="className() || ''"
|
|
78
80
|
[disabled]="disabled()"
|
|
79
81
|
[attr.data-testid]="buttonTestId()"
|
|
80
82
|
(click)="onClick()"
|
|
81
83
|
>
|
|
82
84
|
{{ label() | dynamicText | async }}
|
|
83
85
|
</ion-button>
|
|
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 });
|
|
86
|
+
`, isInline: true, styles: [":host([hidden]){display:none!important}\n"], 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
87
|
}
|
|
86
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
88
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicButtonFieldComponent, decorators: [{
|
|
87
89
|
type: Component,
|
|
88
|
-
args: [{
|
|
89
|
-
selector: 'df-ion-button',
|
|
90
|
-
imports: [IonButton, DynamicTextPipe, AsyncPipe],
|
|
91
|
-
host: {
|
|
90
|
+
args: [{ selector: 'df-ion-button', imports: [IonButton, DynamicTextPipe, AsyncPipe], host: {
|
|
92
91
|
'[id]': '`${key()}`',
|
|
92
|
+
'[class]': 'className()',
|
|
93
93
|
'[attr.data-testid]': 'key()',
|
|
94
|
-
|
|
95
|
-
template: `
|
|
94
|
+
'[attr.hidden]': 'hidden() || null',
|
|
95
|
+
}, template: `
|
|
96
|
+
@let buttonId = key() + '-button';
|
|
97
|
+
|
|
96
98
|
<ion-button
|
|
99
|
+
[id]="buttonId"
|
|
97
100
|
[type]="buttonType()"
|
|
98
101
|
[expand]="props()?.expand"
|
|
99
102
|
[fill]="props()?.fill || 'solid'"
|
|
@@ -101,16 +104,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
101
104
|
[size]="props()?.size"
|
|
102
105
|
[color]="props()?.color || 'primary'"
|
|
103
106
|
[strong]="props()?.strong"
|
|
104
|
-
[class]="className() || ''"
|
|
105
107
|
[disabled]="disabled()"
|
|
106
108
|
[attr.data-testid]="buttonTestId()"
|
|
107
109
|
(click)="onClick()"
|
|
108
110
|
>
|
|
109
111
|
{{ label() | dynamicText | async }}
|
|
110
112
|
</ion-button>
|
|
111
|
-
`,
|
|
112
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
113
|
-
}]
|
|
113
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host([hidden]){display:none!important}\n"] }]
|
|
114
114
|
}], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], event: [{ type: i0.Input, args: [{ isSignal: true, alias: "event", required: false }] }], eventArgs: [{ type: i0.Input, args: [{ isSignal: true, alias: "eventArgs", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], eventContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "eventContext", required: false }] }] } });
|
|
115
115
|
|
|
116
116
|
var ionicButton_component = /*#__PURE__*/Object.freeze({
|
|
@@ -120,6 +120,29 @@ var ionicButton_component = /*#__PURE__*/Object.freeze({
|
|
|
120
120
|
|
|
121
121
|
// Public API - component
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Creates a signal that computes the aria-describedby value based on errors and hint state.
|
|
125
|
+
* Errors take precedence over hints - when errors are displayed, the hint is hidden.
|
|
126
|
+
*
|
|
127
|
+
* @param errorsToDisplay Signal containing the array of errors currently being displayed
|
|
128
|
+
* @param errorId Signal containing the base ID for error elements
|
|
129
|
+
* @param hintId Signal containing the ID for the hint element
|
|
130
|
+
* @param hasHint Function that returns true if a hint is configured
|
|
131
|
+
* @returns Signal containing the aria-describedby value (space-separated IDs) or null
|
|
132
|
+
*/
|
|
133
|
+
function createAriaDescribedBySignal(errorsToDisplay, errorId, hintId, hasHint) {
|
|
134
|
+
return computed(() => {
|
|
135
|
+
const errors = errorsToDisplay();
|
|
136
|
+
if (errors.length > 0) {
|
|
137
|
+
return errors.map((_, i) => `${errorId()}-${i}`).join(' ');
|
|
138
|
+
}
|
|
139
|
+
if (hasHint()) {
|
|
140
|
+
return hintId();
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
123
146
|
class IonicCheckboxFieldComponent {
|
|
124
147
|
elementRef = inject((ElementRef));
|
|
125
148
|
field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
|
|
@@ -147,64 +170,82 @@ class IonicCheckboxFieldComponent {
|
|
|
147
170
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
148
171
|
/** Base ID for error elements */
|
|
149
172
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
173
|
+
/** Unique ID for the helper text element */
|
|
174
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
150
175
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
151
|
-
|
|
176
|
+
ariaInvalid = computed(() => {
|
|
152
177
|
const fieldState = this.field()();
|
|
153
178
|
return fieldState.invalid() && fieldState.touched();
|
|
154
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
179
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
155
180
|
/** Whether the field has a required validator */
|
|
156
|
-
|
|
157
|
-
return this.field()().required?.() === true;
|
|
158
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
159
|
-
|
|
160
|
-
|
|
181
|
+
ariaRequired = computed(() => {
|
|
182
|
+
return this.field()().required?.() === true ? true : null;
|
|
183
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
184
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
185
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
186
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
187
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
161
188
|
@let f = field();
|
|
189
|
+
@let checkboxId = key() + '-checkbox';
|
|
162
190
|
|
|
163
191
|
<ion-checkbox
|
|
192
|
+
[id]="checkboxId"
|
|
164
193
|
[formField]="f"
|
|
165
194
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
166
195
|
[justify]="props()?.justify"
|
|
167
196
|
[color]="props()?.color ?? 'primary'"
|
|
168
197
|
[indeterminate]="props()?.indeterminate ?? false"
|
|
169
198
|
[attr.tabindex]="tabIndex()"
|
|
170
|
-
[attr.aria-invalid]="
|
|
171
|
-
[attr.aria-required]="
|
|
199
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
200
|
+
[attr.aria-required]="ariaRequired()"
|
|
201
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
172
202
|
>
|
|
173
203
|
{{ label() | dynamicText | async }}
|
|
174
204
|
</ion-checkbox>
|
|
175
205
|
|
|
176
206
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
177
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
207
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
208
|
+
} @empty {
|
|
209
|
+
@if (props()?.hint; as hint) {
|
|
210
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
211
|
+
}
|
|
178
212
|
}
|
|
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 });
|
|
213
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
180
214
|
}
|
|
181
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
215
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicCheckboxFieldComponent, decorators: [{
|
|
182
216
|
type: Component,
|
|
183
217
|
args: [{ selector: 'df-ion-checkbox', imports: [IonCheckbox, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
184
218
|
@let f = field();
|
|
219
|
+
@let checkboxId = key() + '-checkbox';
|
|
185
220
|
|
|
186
221
|
<ion-checkbox
|
|
222
|
+
[id]="checkboxId"
|
|
187
223
|
[formField]="f"
|
|
188
224
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
189
225
|
[justify]="props()?.justify"
|
|
190
226
|
[color]="props()?.color ?? 'primary'"
|
|
191
227
|
[indeterminate]="props()?.indeterminate ?? false"
|
|
192
228
|
[attr.tabindex]="tabIndex()"
|
|
193
|
-
[attr.aria-invalid]="
|
|
194
|
-
[attr.aria-required]="
|
|
229
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
230
|
+
[attr.aria-required]="ariaRequired()"
|
|
231
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
195
232
|
>
|
|
196
233
|
{{ label() | dynamicText | async }}
|
|
197
234
|
</ion-checkbox>
|
|
198
235
|
|
|
199
236
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
200
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
237
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
238
|
+
} @empty {
|
|
239
|
+
@if (props()?.hint; as hint) {
|
|
240
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
241
|
+
}
|
|
201
242
|
}
|
|
202
243
|
`, host: {
|
|
203
244
|
'[class]': 'className()',
|
|
204
245
|
'[id]': '`${key()}`',
|
|
205
246
|
'[attr.data-testid]': 'key()',
|
|
206
247
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
248
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
249
|
}], 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 }] }] } });
|
|
209
250
|
|
|
210
251
|
var ionicCheckbox_component = /*#__PURE__*/Object.freeze({
|
|
@@ -242,15 +283,19 @@ class IonicDatepickerFieldComponent {
|
|
|
242
283
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
243
284
|
/** Base ID for error elements */
|
|
244
285
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
286
|
+
/** Unique ID for the helper text element */
|
|
287
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
245
288
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
246
|
-
|
|
289
|
+
ariaInvalid = computed(() => {
|
|
247
290
|
const fieldState = this.field()();
|
|
248
291
|
return fieldState.invalid() && fieldState.touched();
|
|
249
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
292
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
250
293
|
/** Whether the field has a required validator */
|
|
251
|
-
|
|
252
|
-
return this.field()().required?.() === true;
|
|
253
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
294
|
+
ariaRequired = computed(() => {
|
|
295
|
+
return this.field()().required?.() === true ? true : null;
|
|
296
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
297
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
298
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
254
299
|
openModal() {
|
|
255
300
|
this.isModalOpen.set(true);
|
|
256
301
|
}
|
|
@@ -295,13 +340,14 @@ class IonicDatepickerFieldComponent {
|
|
|
295
340
|
return format(date, 'MMM d, yyyy');
|
|
296
341
|
}
|
|
297
342
|
}
|
|
298
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
299
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0
|
|
300
|
-
@let f = field();
|
|
301
|
-
@let
|
|
302
|
-
@let
|
|
343
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
344
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
345
|
+
@let f = field();
|
|
346
|
+
@let dateValue = f().value();
|
|
347
|
+
@let inputId = key() + '-input';
|
|
303
348
|
|
|
304
349
|
<ion-input
|
|
350
|
+
[id]="inputId"
|
|
305
351
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
306
352
|
[labelPlacement]="'stacked'"
|
|
307
353
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
@@ -310,12 +356,17 @@ class IonicDatepickerFieldComponent {
|
|
|
310
356
|
[readonly]="true"
|
|
311
357
|
[fill]="'outline'"
|
|
312
358
|
[attr.tabindex]="tabIndex()"
|
|
313
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
314
|
-
[attr.aria-required]="ariaRequired"
|
|
359
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
360
|
+
[attr.aria-required]="ariaRequired()"
|
|
361
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
315
362
|
(click)="!f().disabled() && openModal()"
|
|
316
363
|
/>
|
|
317
364
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
318
365
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
366
|
+
} @empty {
|
|
367
|
+
@if (props()?.hint; as hint) {
|
|
368
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
369
|
+
}
|
|
319
370
|
}
|
|
320
371
|
|
|
321
372
|
<ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
|
|
@@ -347,9 +398,9 @@ class IonicDatepickerFieldComponent {
|
|
|
347
398
|
</ion-content>
|
|
348
399
|
</ng-template>
|
|
349
400
|
</ion-modal>
|
|
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 });
|
|
401
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
351
402
|
}
|
|
352
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
403
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicDatepickerFieldComponent, decorators: [{
|
|
353
404
|
type: Component,
|
|
354
405
|
args: [{ selector: 'df-ion-datepicker', imports: [
|
|
355
406
|
IonInput,
|
|
@@ -365,11 +416,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
365
416
|
DynamicTextPipe,
|
|
366
417
|
AsyncPipe,
|
|
367
418
|
], template: `
|
|
368
|
-
@let f = field();
|
|
369
|
-
@let
|
|
370
|
-
@let
|
|
419
|
+
@let f = field();
|
|
420
|
+
@let dateValue = f().value();
|
|
421
|
+
@let inputId = key() + '-input';
|
|
371
422
|
|
|
372
423
|
<ion-input
|
|
424
|
+
[id]="inputId"
|
|
373
425
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
374
426
|
[labelPlacement]="'stacked'"
|
|
375
427
|
[placeholder]="(placeholder() | dynamicText | async) ?? ''"
|
|
@@ -378,12 +430,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
378
430
|
[readonly]="true"
|
|
379
431
|
[fill]="'outline'"
|
|
380
432
|
[attr.tabindex]="tabIndex()"
|
|
381
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
382
|
-
[attr.aria-required]="ariaRequired"
|
|
433
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
434
|
+
[attr.aria-required]="ariaRequired()"
|
|
435
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
383
436
|
(click)="!f().disabled() && openModal()"
|
|
384
437
|
/>
|
|
385
438
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
386
439
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
440
|
+
} @empty {
|
|
441
|
+
@if (props()?.hint; as hint) {
|
|
442
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
443
|
+
}
|
|
387
444
|
}
|
|
388
445
|
|
|
389
446
|
<ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
|
|
@@ -420,7 +477,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
420
477
|
'[attr.data-testid]': 'key()',
|
|
421
478
|
'[class]': 'className()',
|
|
422
479
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
480
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
481
|
}], 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 }] }] } });
|
|
425
482
|
|
|
426
483
|
var ionicDatepicker_component = /*#__PURE__*/Object.freeze({
|
|
@@ -476,28 +533,52 @@ class IonicInputFieldComponent {
|
|
|
476
533
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
477
534
|
selector: 'ion-input',
|
|
478
535
|
});
|
|
536
|
+
// Workaround: Ionic's ion-input does NOT automatically propagate aria-describedby changes
|
|
537
|
+
// to the native input element inside its shadow DOM. This effect imperatively syncs the attribute
|
|
538
|
+
// after a microtask to ensure Ionic has processed the attribute change.
|
|
539
|
+
explicitEffect([this.ariaDescribedBy], ([describedBy]) => {
|
|
540
|
+
queueMicrotask(() => {
|
|
541
|
+
const ionInput = this.elementRef.nativeElement.querySelector('ion-input');
|
|
542
|
+
if (ionInput?.getInputElement) {
|
|
543
|
+
ionInput.getInputElement().then((inputEl) => {
|
|
544
|
+
if (inputEl) {
|
|
545
|
+
if (describedBy) {
|
|
546
|
+
inputEl.setAttribute('aria-describedby', describedBy);
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
inputEl.removeAttribute('aria-describedby');
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
});
|
|
479
556
|
}
|
|
480
557
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
481
558
|
// Accessibility
|
|
482
559
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
483
560
|
/** Base ID for error elements */
|
|
484
561
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
562
|
+
/** Unique ID for the helper text element */
|
|
563
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
485
564
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
486
|
-
|
|
565
|
+
ariaInvalid = computed(() => {
|
|
487
566
|
const fieldState = this.field()();
|
|
488
567
|
return fieldState.invalid() && fieldState.touched();
|
|
489
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
568
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
490
569
|
/** Whether the field has a required validator */
|
|
491
|
-
|
|
492
|
-
return this.field()().required?.() === true;
|
|
493
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
494
|
-
|
|
495
|
-
|
|
570
|
+
ariaRequired = computed(() => {
|
|
571
|
+
return this.field()().required?.() === true ? true : null;
|
|
572
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
573
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
574
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
575
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
576
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
496
577
|
@let f = field();
|
|
497
|
-
@let
|
|
498
|
-
@let ariaRequired = isRequired() || null;
|
|
578
|
+
@let inputId = key() + '-input';
|
|
499
579
|
|
|
500
580
|
<ion-input
|
|
581
|
+
[id]="inputId"
|
|
501
582
|
[type]="props()?.type ?? 'text'"
|
|
502
583
|
[formField]="f"
|
|
503
584
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
@@ -509,24 +590,25 @@ class IonicInputFieldComponent {
|
|
|
509
590
|
[fill]="effectiveFill()"
|
|
510
591
|
[shape]="effectiveShape()"
|
|
511
592
|
[readonly]="f().readonly()"
|
|
512
|
-
[helperText]="(props()?.
|
|
593
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
513
594
|
[attr.tabindex]="tabIndex()"
|
|
514
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
515
|
-
[attr.aria-required]="ariaRequired"
|
|
595
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
596
|
+
[attr.aria-required]="ariaRequired()"
|
|
597
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
516
598
|
/>
|
|
517
599
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
518
600
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
519
601
|
}
|
|
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 });
|
|
602
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
521
603
|
}
|
|
522
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicInputFieldComponent, decorators: [{
|
|
523
605
|
type: Component,
|
|
524
606
|
args: [{ selector: 'df-ion-input', imports: [IonInput, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
525
607
|
@let f = field();
|
|
526
|
-
@let
|
|
527
|
-
@let ariaRequired = isRequired() || null;
|
|
608
|
+
@let inputId = key() + '-input';
|
|
528
609
|
|
|
529
610
|
<ion-input
|
|
611
|
+
[id]="inputId"
|
|
530
612
|
[type]="props()?.type ?? 'text'"
|
|
531
613
|
[formField]="f"
|
|
532
614
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
@@ -538,10 +620,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
538
620
|
[fill]="effectiveFill()"
|
|
539
621
|
[shape]="effectiveShape()"
|
|
540
622
|
[readonly]="f().readonly()"
|
|
541
|
-
[helperText]="(props()?.
|
|
623
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
542
624
|
[attr.tabindex]="tabIndex()"
|
|
543
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
544
|
-
[attr.aria-required]="ariaRequired"
|
|
625
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
626
|
+
[attr.aria-required]="ariaRequired()"
|
|
627
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
545
628
|
/>
|
|
546
629
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
547
630
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
@@ -551,7 +634,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
551
634
|
'[attr.data-testid]': 'key()',
|
|
552
635
|
'[class]': 'className()',
|
|
553
636
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
637
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
638
|
}], 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 }] }] } });
|
|
556
639
|
|
|
557
640
|
var ionicInput_component = /*#__PURE__*/Object.freeze({
|
|
@@ -580,19 +663,31 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
580
663
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
581
664
|
/** Base ID for error elements */
|
|
582
665
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
666
|
+
/** Unique ID for the helper text element */
|
|
667
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
583
668
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
584
|
-
|
|
669
|
+
ariaInvalid = computed(() => {
|
|
585
670
|
const fieldState = this.field()();
|
|
586
671
|
return fieldState.invalid() && fieldState.touched();
|
|
587
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
672
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
588
673
|
/** Whether the field has a required validator */
|
|
589
|
-
|
|
590
|
-
return this.field()().required?.() === true;
|
|
591
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
674
|
+
ariaRequired = computed(() => {
|
|
675
|
+
return this.field()().required?.() === true ? true : null;
|
|
676
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
677
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
678
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
592
679
|
valueViewModel = linkedSignal(() => {
|
|
593
680
|
const currentValues = this.field()().value();
|
|
594
681
|
return this.options().filter((option) => currentValues.includes(option.value));
|
|
595
682
|
}, { ...(ngDevMode ? { debugName: "valueViewModel" } : {}), equal: isEqual });
|
|
683
|
+
/** Computed map of checked option values for O(1) lookup in template */
|
|
684
|
+
checkedValuesMap = computed(() => {
|
|
685
|
+
const map = {};
|
|
686
|
+
for (const opt of this.valueViewModel()) {
|
|
687
|
+
map[String(opt.value)] = true;
|
|
688
|
+
}
|
|
689
|
+
return map;
|
|
690
|
+
}, ...(ngDevMode ? [{ debugName: "checkedValuesMap" }] : []));
|
|
596
691
|
constructor() {
|
|
597
692
|
// Shadow DOM - apply meta to ion-checkbox elements, re-apply when options change
|
|
598
693
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
@@ -624,9 +719,10 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
624
719
|
}
|
|
625
720
|
});
|
|
626
721
|
}
|
|
627
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
628
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0
|
|
722
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicMultiCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
723
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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" } }, ngImport: i0, template: `
|
|
629
724
|
@let f = field();
|
|
725
|
+
@let checked = checkedValuesMap();
|
|
630
726
|
@if (label(); as label) {
|
|
631
727
|
<div class="checkbox-group-label">{{ label | dynamicText | async }}</div>
|
|
632
728
|
}
|
|
@@ -634,15 +730,16 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
634
730
|
<div
|
|
635
731
|
class="checkbox-group"
|
|
636
732
|
role="group"
|
|
637
|
-
[attr.aria-invalid]="
|
|
638
|
-
[attr.aria-required]="
|
|
733
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
734
|
+
[attr.aria-required]="ariaRequired()"
|
|
735
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
639
736
|
[class.ion-invalid]="showErrors()"
|
|
640
737
|
[class.ion-touched]="field()().touched()"
|
|
641
738
|
>
|
|
642
739
|
@for (option of options(); track option.value) {
|
|
643
740
|
<ion-item lines="none">
|
|
644
741
|
<ion-checkbox
|
|
645
|
-
[checked]="
|
|
742
|
+
[checked]="checked['' + option.value]"
|
|
646
743
|
[disabled]="f().disabled() || option.disabled"
|
|
647
744
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
648
745
|
[justify]="props()?.justify ?? 'start'"
|
|
@@ -656,14 +753,19 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
656
753
|
</div>
|
|
657
754
|
|
|
658
755
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
659
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
756
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
757
|
+
} @empty {
|
|
758
|
+
@if (props()?.hint; as hint) {
|
|
759
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
760
|
+
}
|
|
660
761
|
}
|
|
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:
|
|
762
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
662
763
|
}
|
|
663
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
764
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicMultiCheckboxFieldComponent, decorators: [{
|
|
664
765
|
type: Component,
|
|
665
|
-
args: [{ selector: 'df-ion-multi-checkbox', imports: [IonCheckbox, IonItem, IonNote,
|
|
766
|
+
args: [{ selector: 'df-ion-multi-checkbox', imports: [IonCheckbox, IonItem, IonNote, DynamicTextPipe, AsyncPipe], template: `
|
|
666
767
|
@let f = field();
|
|
768
|
+
@let checked = checkedValuesMap();
|
|
667
769
|
@if (label(); as label) {
|
|
668
770
|
<div class="checkbox-group-label">{{ label | dynamicText | async }}</div>
|
|
669
771
|
}
|
|
@@ -671,15 +773,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
671
773
|
<div
|
|
672
774
|
class="checkbox-group"
|
|
673
775
|
role="group"
|
|
674
|
-
[attr.aria-invalid]="
|
|
675
|
-
[attr.aria-required]="
|
|
776
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
777
|
+
[attr.aria-required]="ariaRequired()"
|
|
778
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
676
779
|
[class.ion-invalid]="showErrors()"
|
|
677
780
|
[class.ion-touched]="field()().touched()"
|
|
678
781
|
>
|
|
679
782
|
@for (option of options(); track option.value) {
|
|
680
783
|
<ion-item lines="none">
|
|
681
784
|
<ion-checkbox
|
|
682
|
-
[checked]="
|
|
785
|
+
[checked]="checked['' + option.value]"
|
|
683
786
|
[disabled]="f().disabled() || option.disabled"
|
|
684
787
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
685
788
|
[justify]="props()?.justify ?? 'start'"
|
|
@@ -693,14 +796,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
693
796
|
</div>
|
|
694
797
|
|
|
695
798
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
696
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
799
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
800
|
+
} @empty {
|
|
801
|
+
@if (props()?.hint; as hint) {
|
|
802
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
803
|
+
}
|
|
697
804
|
}
|
|
698
805
|
`, host: {
|
|
699
806
|
'[class]': 'className() || ""',
|
|
700
807
|
'[id]': '`${key()}`',
|
|
701
808
|
'[attr.data-testid]': 'key()',
|
|
702
809
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
703
|
-
},
|
|
810
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
811
|
}], 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 }] }] } });
|
|
705
812
|
|
|
706
813
|
var ionicMultiCheckbox_component = /*#__PURE__*/Object.freeze({
|
|
@@ -738,27 +845,34 @@ class IonicRadioFieldComponent {
|
|
|
738
845
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
739
846
|
/** Base ID for error elements */
|
|
740
847
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
848
|
+
/** Unique ID for the helper text element */
|
|
849
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
741
850
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
742
|
-
|
|
851
|
+
ariaInvalid = computed(() => {
|
|
743
852
|
const fieldState = this.field()();
|
|
744
853
|
return fieldState.invalid() && fieldState.touched();
|
|
745
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
854
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
746
855
|
/** Whether the field has a required validator */
|
|
747
|
-
|
|
748
|
-
return this.field()().required?.() === true;
|
|
749
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
750
|
-
|
|
751
|
-
|
|
856
|
+
ariaRequired = computed(() => {
|
|
857
|
+
return this.field()().required?.() === true ? true : null;
|
|
858
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
859
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
860
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
861
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicRadioFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
862
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
752
863
|
@let f = field();
|
|
864
|
+
@let radioGroupId = key() + '-radio-group';
|
|
753
865
|
@if (label(); as label) {
|
|
754
866
|
<div class="radio-label">{{ label | dynamicText | async }}</div>
|
|
755
867
|
}
|
|
756
868
|
|
|
757
869
|
<ion-radio-group
|
|
870
|
+
[id]="radioGroupId"
|
|
758
871
|
[formField]="f"
|
|
759
872
|
[compareWith]="props()?.compareWith || defaultCompare"
|
|
760
|
-
[attr.aria-invalid]="
|
|
761
|
-
[attr.aria-required]="
|
|
873
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
874
|
+
[attr.aria-required]="ariaRequired()"
|
|
875
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
762
876
|
>
|
|
763
877
|
@for (option of options(); track option.value) {
|
|
764
878
|
<ion-item [lines]="'none'">
|
|
@@ -776,23 +890,30 @@ class IonicRadioFieldComponent {
|
|
|
776
890
|
</ion-radio-group>
|
|
777
891
|
|
|
778
892
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
779
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
893
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
894
|
+
} @empty {
|
|
895
|
+
@if (props()?.hint; as hint) {
|
|
896
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
897
|
+
}
|
|
780
898
|
}
|
|
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 });
|
|
899
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
782
900
|
}
|
|
783
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
901
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicRadioFieldComponent, decorators: [{
|
|
784
902
|
type: Component,
|
|
785
903
|
args: [{ selector: 'df-ion-radio', imports: [IonRadioGroup, IonRadio, IonItem, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
786
904
|
@let f = field();
|
|
905
|
+
@let radioGroupId = key() + '-radio-group';
|
|
787
906
|
@if (label(); as label) {
|
|
788
907
|
<div class="radio-label">{{ label | dynamicText | async }}</div>
|
|
789
908
|
}
|
|
790
909
|
|
|
791
910
|
<ion-radio-group
|
|
911
|
+
[id]="radioGroupId"
|
|
792
912
|
[formField]="f"
|
|
793
913
|
[compareWith]="props()?.compareWith || defaultCompare"
|
|
794
|
-
[attr.aria-invalid]="
|
|
795
|
-
[attr.aria-required]="
|
|
914
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
915
|
+
[attr.aria-required]="ariaRequired()"
|
|
916
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
796
917
|
>
|
|
797
918
|
@for (option of options(); track option.value) {
|
|
798
919
|
<ion-item [lines]="'none'">
|
|
@@ -810,14 +931,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
810
931
|
</ion-radio-group>
|
|
811
932
|
|
|
812
933
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
813
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
934
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
935
|
+
} @empty {
|
|
936
|
+
@if (props()?.hint; as hint) {
|
|
937
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
938
|
+
}
|
|
814
939
|
}
|
|
815
940
|
`, host: {
|
|
816
941
|
'[class]': 'className()',
|
|
817
942
|
'[id]': '`${key()}`',
|
|
818
943
|
'[attr.data-testid]': 'key()',
|
|
819
944
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
945
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
946
|
}], 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 }] }] } });
|
|
822
947
|
|
|
823
948
|
var ionicRadio_component = /*#__PURE__*/Object.freeze({
|
|
@@ -850,22 +975,26 @@ class IonicSelectFieldComponent {
|
|
|
850
975
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
851
976
|
/** Base ID for error elements */
|
|
852
977
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
978
|
+
/** Unique ID for the helper text element */
|
|
979
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
853
980
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
854
|
-
|
|
981
|
+
ariaInvalid = computed(() => {
|
|
855
982
|
const fieldState = this.field()();
|
|
856
983
|
return fieldState.invalid() && fieldState.touched();
|
|
857
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
984
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
858
985
|
/** Whether the field has a required validator */
|
|
859
|
-
|
|
860
|
-
return this.field()().required?.() === true;
|
|
861
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
862
|
-
|
|
863
|
-
|
|
986
|
+
ariaRequired = computed(() => {
|
|
987
|
+
return this.field()().required?.() === true ? true : null;
|
|
988
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
989
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
990
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
991
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
992
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
864
993
|
@let f = field();
|
|
865
|
-
@let
|
|
866
|
-
@let ariaRequired = isRequired() || null;
|
|
994
|
+
@let selectId = key() + '-select';
|
|
867
995
|
|
|
868
996
|
<ion-select
|
|
997
|
+
[id]="selectId"
|
|
869
998
|
[formField]="f"
|
|
870
999
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
871
1000
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
@@ -880,8 +1009,9 @@ class IonicSelectFieldComponent {
|
|
|
880
1009
|
[fill]="props()?.fill ?? 'outline'"
|
|
881
1010
|
[shape]="props()?.shape"
|
|
882
1011
|
[attr.tabindex]="tabIndex()"
|
|
883
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
884
|
-
[attr.aria-required]="ariaRequired"
|
|
1012
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1013
|
+
[attr.aria-required]="ariaRequired()"
|
|
1014
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
885
1015
|
>
|
|
886
1016
|
@for (option of options(); track option.value) {
|
|
887
1017
|
<ion-select-option [value]="option.value" [disabled]="option.disabled || false">
|
|
@@ -891,17 +1021,21 @@ class IonicSelectFieldComponent {
|
|
|
891
1021
|
</ion-select>
|
|
892
1022
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
893
1023
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1024
|
+
} @empty {
|
|
1025
|
+
@if (props()?.hint; as hint) {
|
|
1026
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
1027
|
+
}
|
|
894
1028
|
}
|
|
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 });
|
|
1029
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
896
1030
|
}
|
|
897
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1031
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicSelectFieldComponent, decorators: [{
|
|
898
1032
|
type: Component,
|
|
899
1033
|
args: [{ selector: 'df-ion-select', imports: [IonSelect, IonSelectOption, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
900
1034
|
@let f = field();
|
|
901
|
-
@let
|
|
902
|
-
@let ariaRequired = isRequired() || null;
|
|
1035
|
+
@let selectId = key() + '-select';
|
|
903
1036
|
|
|
904
1037
|
<ion-select
|
|
1038
|
+
[id]="selectId"
|
|
905
1039
|
[formField]="f"
|
|
906
1040
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
907
1041
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
@@ -916,8 +1050,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
916
1050
|
[fill]="props()?.fill ?? 'outline'"
|
|
917
1051
|
[shape]="props()?.shape"
|
|
918
1052
|
[attr.tabindex]="tabIndex()"
|
|
919
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
920
|
-
[attr.aria-required]="ariaRequired"
|
|
1053
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1054
|
+
[attr.aria-required]="ariaRequired()"
|
|
1055
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
921
1056
|
>
|
|
922
1057
|
@for (option of options(); track option.value) {
|
|
923
1058
|
<ion-select-option [value]="option.value" [disabled]="option.disabled || false">
|
|
@@ -927,13 +1062,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
927
1062
|
</ion-select>
|
|
928
1063
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
929
1064
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1065
|
+
} @empty {
|
|
1066
|
+
@if (props()?.hint; as hint) {
|
|
1067
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
1068
|
+
}
|
|
930
1069
|
}
|
|
931
1070
|
`, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
932
1071
|
'[id]': '`${key()}`',
|
|
933
1072
|
'[attr.data-testid]': 'key()',
|
|
934
1073
|
'[class]': 'className()',
|
|
935
1074
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
1075
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
1076
|
}], 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 }] }] } });
|
|
938
1077
|
|
|
939
1078
|
var ionicSelect_component = /*#__PURE__*/Object.freeze({
|
|
@@ -965,23 +1104,31 @@ class IonicSliderFieldComponent {
|
|
|
965
1104
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
966
1105
|
/** Base ID for error elements */
|
|
967
1106
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1107
|
+
/** Unique ID for the helper text element */
|
|
1108
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
968
1109
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
969
|
-
|
|
1110
|
+
ariaInvalid = computed(() => {
|
|
970
1111
|
const fieldState = this.field()();
|
|
971
1112
|
return fieldState.invalid() && fieldState.touched();
|
|
972
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
1113
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
973
1114
|
/** Whether the field has a required validator */
|
|
974
|
-
|
|
975
|
-
return this.field()().required?.() === true;
|
|
976
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
977
|
-
|
|
978
|
-
|
|
1115
|
+
ariaRequired = computed(() => {
|
|
1116
|
+
return this.field()().required?.() === true ? true : null;
|
|
1117
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
1118
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
1119
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1120
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicSliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1121
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
979
1122
|
@let f = field();
|
|
1123
|
+
@let inputId = key() + '-input';
|
|
980
1124
|
|
|
981
1125
|
<ion-range
|
|
1126
|
+
[id]="inputId"
|
|
982
1127
|
[formField]="f"
|
|
983
1128
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
984
1129
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
1130
|
+
[min]="props()?.min ?? 0"
|
|
1131
|
+
[max]="props()?.max ?? 100"
|
|
985
1132
|
[step]="props()?.step ?? 1"
|
|
986
1133
|
[dualKnobs]="props()?.dualKnobs ?? false"
|
|
987
1134
|
[pin]="props()?.pin ?? false"
|
|
@@ -990,24 +1137,33 @@ class IonicSliderFieldComponent {
|
|
|
990
1137
|
[snaps]="props()?.snaps ?? false"
|
|
991
1138
|
[color]="props()?.color ?? 'primary'"
|
|
992
1139
|
[attr.tabindex]="tabIndex()"
|
|
993
|
-
[attr.aria-invalid]="
|
|
994
|
-
[attr.aria-required]="
|
|
1140
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1141
|
+
[attr.aria-required]="ariaRequired()"
|
|
1142
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
995
1143
|
/>
|
|
996
1144
|
|
|
997
1145
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
998
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1146
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1147
|
+
} @empty {
|
|
1148
|
+
@if (props()?.hint; as hint) {
|
|
1149
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
1150
|
+
}
|
|
999
1151
|
}
|
|
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 });
|
|
1152
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
1001
1153
|
}
|
|
1002
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1154
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicSliderFieldComponent, decorators: [{
|
|
1003
1155
|
type: Component,
|
|
1004
1156
|
args: [{ selector: 'df-ion-slider', imports: [IonRange, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1005
1157
|
@let f = field();
|
|
1158
|
+
@let inputId = key() + '-input';
|
|
1006
1159
|
|
|
1007
1160
|
<ion-range
|
|
1161
|
+
[id]="inputId"
|
|
1008
1162
|
[formField]="f"
|
|
1009
1163
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
1010
1164
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
1165
|
+
[min]="props()?.min ?? 0"
|
|
1166
|
+
[max]="props()?.max ?? 100"
|
|
1011
1167
|
[step]="props()?.step ?? 1"
|
|
1012
1168
|
[dualKnobs]="props()?.dualKnobs ?? false"
|
|
1013
1169
|
[pin]="props()?.pin ?? false"
|
|
@@ -1016,19 +1172,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1016
1172
|
[snaps]="props()?.snaps ?? false"
|
|
1017
1173
|
[color]="props()?.color ?? 'primary'"
|
|
1018
1174
|
[attr.tabindex]="tabIndex()"
|
|
1019
|
-
[attr.aria-invalid]="
|
|
1020
|
-
[attr.aria-required]="
|
|
1175
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1176
|
+
[attr.aria-required]="ariaRequired()"
|
|
1177
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1021
1178
|
/>
|
|
1022
1179
|
|
|
1023
1180
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1024
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1181
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1182
|
+
} @empty {
|
|
1183
|
+
@if (props()?.hint; as hint) {
|
|
1184
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
1185
|
+
}
|
|
1025
1186
|
}
|
|
1026
1187
|
`, host: {
|
|
1027
1188
|
'[class]': 'className()',
|
|
1028
1189
|
'[id]': '`${key()}`',
|
|
1029
1190
|
'[attr.data-testid]': 'key()',
|
|
1030
1191
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
1192
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
1193
|
}], 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 }] }] } });
|
|
1033
1194
|
|
|
1034
1195
|
var ionicSlider_component = /*#__PURE__*/Object.freeze({
|
|
@@ -1056,28 +1217,52 @@ class IonicTextareaFieldComponent {
|
|
|
1056
1217
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
1057
1218
|
selector: 'ion-textarea',
|
|
1058
1219
|
});
|
|
1220
|
+
// Workaround: Ionic's ion-textarea does NOT automatically propagate aria-describedby changes
|
|
1221
|
+
// to the native textarea element inside its shadow DOM. This effect imperatively syncs the attribute
|
|
1222
|
+
// after a microtask to ensure Ionic has processed the attribute change.
|
|
1223
|
+
explicitEffect([this.ariaDescribedBy], ([describedBy]) => {
|
|
1224
|
+
queueMicrotask(() => {
|
|
1225
|
+
const ionTextarea = this.elementRef.nativeElement.querySelector('ion-textarea');
|
|
1226
|
+
if (ionTextarea?.getInputElement) {
|
|
1227
|
+
ionTextarea.getInputElement().then((textareaEl) => {
|
|
1228
|
+
if (textareaEl) {
|
|
1229
|
+
if (describedBy) {
|
|
1230
|
+
textareaEl.setAttribute('aria-describedby', describedBy);
|
|
1231
|
+
}
|
|
1232
|
+
else {
|
|
1233
|
+
textareaEl.removeAttribute('aria-describedby');
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
});
|
|
1239
|
+
});
|
|
1059
1240
|
}
|
|
1060
1241
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1061
1242
|
// Accessibility
|
|
1062
1243
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1063
1244
|
/** Base ID for error elements */
|
|
1064
1245
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1246
|
+
/** Unique ID for the helper text element */
|
|
1247
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
1065
1248
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
1066
|
-
|
|
1249
|
+
ariaInvalid = computed(() => {
|
|
1067
1250
|
const fieldState = this.field()();
|
|
1068
1251
|
return fieldState.invalid() && fieldState.touched();
|
|
1069
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
1252
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
1070
1253
|
/** Whether the field has a required validator */
|
|
1071
|
-
|
|
1072
|
-
return this.field()().required?.() === true;
|
|
1073
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
1074
|
-
|
|
1075
|
-
|
|
1254
|
+
ariaRequired = computed(() => {
|
|
1255
|
+
return this.field()().required?.() === true ? true : null;
|
|
1256
|
+
}, ...(ngDevMode ? [{ debugName: "ariaRequired" }] : []));
|
|
1257
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
1258
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1259
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicTextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1260
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1076
1261
|
@let f = field();
|
|
1077
|
-
@let
|
|
1078
|
-
@let ariaRequired = isRequired() || null;
|
|
1262
|
+
@let textareaId = key() + '-textarea';
|
|
1079
1263
|
|
|
1080
1264
|
<ion-textarea
|
|
1265
|
+
[id]="textareaId"
|
|
1081
1266
|
[formField]="f"
|
|
1082
1267
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
1083
1268
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
@@ -1089,24 +1274,25 @@ class IonicTextareaFieldComponent {
|
|
|
1089
1274
|
[fill]="props()?.fill ?? 'outline'"
|
|
1090
1275
|
[shape]="props()?.shape"
|
|
1091
1276
|
[readonly]="f().readonly()"
|
|
1092
|
-
[helperText]="(props()?.
|
|
1277
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
1093
1278
|
[attr.tabindex]="tabIndex()"
|
|
1094
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1095
|
-
[attr.aria-required]="ariaRequired"
|
|
1279
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1280
|
+
[attr.aria-required]="ariaRequired()"
|
|
1281
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1096
1282
|
/>
|
|
1097
1283
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1098
1284
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1099
1285
|
}
|
|
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 });
|
|
1286
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
1101
1287
|
}
|
|
1102
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1288
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicTextareaFieldComponent, decorators: [{
|
|
1103
1289
|
type: Component,
|
|
1104
1290
|
args: [{ selector: 'df-ion-textarea', imports: [IonTextarea, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1105
1291
|
@let f = field();
|
|
1106
|
-
@let
|
|
1107
|
-
@let ariaRequired = isRequired() || null;
|
|
1292
|
+
@let textareaId = key() + '-textarea';
|
|
1108
1293
|
|
|
1109
1294
|
<ion-textarea
|
|
1295
|
+
[id]="textareaId"
|
|
1110
1296
|
[formField]="f"
|
|
1111
1297
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
1112
1298
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
@@ -1118,10 +1304,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1118
1304
|
[fill]="props()?.fill ?? 'outline'"
|
|
1119
1305
|
[shape]="props()?.shape"
|
|
1120
1306
|
[readonly]="f().readonly()"
|
|
1121
|
-
[helperText]="(props()?.
|
|
1307
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
1122
1308
|
[attr.tabindex]="tabIndex()"
|
|
1123
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1124
|
-
[attr.aria-required]="ariaRequired"
|
|
1309
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1310
|
+
[attr.aria-required]="ariaRequired()"
|
|
1311
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1125
1312
|
/>
|
|
1126
1313
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1127
1314
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
@@ -1131,7 +1318,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1131
1318
|
'[attr.data-testid]': 'key()',
|
|
1132
1319
|
'[class]': 'className()',
|
|
1133
1320
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
1321
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
1322
|
}], 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 }] }] } });
|
|
1136
1323
|
|
|
1137
1324
|
var ionicTextarea_component = /*#__PURE__*/Object.freeze({
|
|
@@ -1172,6 +1359,7 @@ class IonicToggleControlComponent {
|
|
|
1172
1359
|
enableOnOffLabels = input(false, ...(ngDevMode ? [{ debugName: "enableOnOffLabels" }] : []));
|
|
1173
1360
|
tabIndex = input(undefined, ...(ngDevMode ? [{ debugName: "tabIndex" }] : []));
|
|
1174
1361
|
meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
|
|
1362
|
+
ariaDescribedBy = input(null, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
1175
1363
|
constructor() {
|
|
1176
1364
|
// Shadow DOM - apply meta to ion-toggle element
|
|
1177
1365
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
@@ -1215,8 +1403,8 @@ class IonicToggleControlComponent {
|
|
|
1215
1403
|
onBlur() {
|
|
1216
1404
|
this.touched.set(true);
|
|
1217
1405
|
}
|
|
1218
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
1219
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0
|
|
1406
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicToggleControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1407
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", 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 }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", touched: "touchedChange" }, host: { styleAttribute: "display: block" }, ngImport: i0, template: `
|
|
1220
1408
|
<ion-toggle
|
|
1221
1409
|
[checked]="isChecked()"
|
|
1222
1410
|
(ionChange)="onToggleChange($event)"
|
|
@@ -1230,12 +1418,13 @@ class IonicToggleControlComponent {
|
|
|
1230
1418
|
[attr.aria-invalid]="ariaInvalid()"
|
|
1231
1419
|
[attr.aria-required]="ariaRequired()"
|
|
1232
1420
|
[attr.aria-readonly]="ariaReadonly()"
|
|
1421
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1233
1422
|
>
|
|
1234
1423
|
<ng-content />
|
|
1235
1424
|
</ion-toggle>
|
|
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 });
|
|
1425
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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 });
|
|
1237
1426
|
}
|
|
1238
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1427
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicToggleControlComponent, decorators: [{
|
|
1239
1428
|
type: Component,
|
|
1240
1429
|
args: [{ selector: 'df-ion-toggle-control', imports: [IonToggle], template: `
|
|
1241
1430
|
<ion-toggle
|
|
@@ -1251,11 +1440,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1251
1440
|
[attr.aria-invalid]="ariaInvalid()"
|
|
1252
1441
|
[attr.aria-required]="ariaRequired()"
|
|
1253
1442
|
[attr.aria-readonly]="ariaReadonly()"
|
|
1443
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1254
1444
|
>
|
|
1255
1445
|
<ng-content />
|
|
1256
1446
|
</ion-toggle>
|
|
1257
|
-
`, host: {
|
|
1258
|
-
|
|
1447
|
+
`, host: {
|
|
1448
|
+
style: 'display: block',
|
|
1449
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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"] }]
|
|
1450
|
+
}], 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 }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }] } });
|
|
1259
1451
|
|
|
1260
1452
|
class IonicToggleFieldComponent {
|
|
1261
1453
|
elementRef = inject((ElementRef));
|
|
@@ -1281,11 +1473,17 @@ class IonicToggleFieldComponent {
|
|
|
1281
1473
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1282
1474
|
/** Base ID for error elements */
|
|
1283
1475
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1284
|
-
|
|
1285
|
-
|
|
1476
|
+
/** Unique ID for the helper text element */
|
|
1477
|
+
hintId = computed(() => `${this.key()}-hint`, ...(ngDevMode ? [{ debugName: "hintId" }] : []));
|
|
1478
|
+
/** aria-describedby linking to hint OR error elements (mutually exclusive) */
|
|
1479
|
+
ariaDescribedBy = createAriaDescribedBySignal(this.errorsToDisplay, this.errorId, this.hintId, () => !!this.props()?.hint);
|
|
1480
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicToggleFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1481
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", 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: `
|
|
1286
1482
|
@let f = field();
|
|
1483
|
+
@let toggleId = key() + '-toggle';
|
|
1287
1484
|
|
|
1288
1485
|
<df-ion-toggle-control
|
|
1486
|
+
[id]="toggleId"
|
|
1289
1487
|
[formField]="f"
|
|
1290
1488
|
[meta]="meta()"
|
|
1291
1489
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
@@ -1293,21 +1491,28 @@ class IonicToggleFieldComponent {
|
|
|
1293
1491
|
[color]="props()?.color ?? 'primary'"
|
|
1294
1492
|
[enableOnOffLabels]="props()?.enableOnOffLabels ?? false"
|
|
1295
1493
|
[tabIndex]="tabIndex()"
|
|
1494
|
+
[ariaDescribedBy]="ariaDescribedBy()"
|
|
1296
1495
|
>
|
|
1297
1496
|
{{ label() | dynamicText | async }}
|
|
1298
1497
|
</df-ion-toggle-control>
|
|
1299
1498
|
|
|
1300
1499
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1301
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1500
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1501
|
+
} @empty {
|
|
1502
|
+
@if (props()?.hint; as hint) {
|
|
1503
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
1504
|
+
}
|
|
1302
1505
|
}
|
|
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 });
|
|
1506
|
+
`, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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", "ariaDescribedBy"], 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 });
|
|
1304
1507
|
}
|
|
1305
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0
|
|
1508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: IonicToggleFieldComponent, decorators: [{
|
|
1306
1509
|
type: Component,
|
|
1307
1510
|
args: [{ selector: 'df-ion-toggle', imports: [IonicToggleControlComponent, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1308
1511
|
@let f = field();
|
|
1512
|
+
@let toggleId = key() + '-toggle';
|
|
1309
1513
|
|
|
1310
1514
|
<df-ion-toggle-control
|
|
1515
|
+
[id]="toggleId"
|
|
1311
1516
|
[formField]="f"
|
|
1312
1517
|
[meta]="meta()"
|
|
1313
1518
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
@@ -1315,19 +1520,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1315
1520
|
[color]="props()?.color ?? 'primary'"
|
|
1316
1521
|
[enableOnOffLabels]="props()?.enableOnOffLabels ?? false"
|
|
1317
1522
|
[tabIndex]="tabIndex()"
|
|
1523
|
+
[ariaDescribedBy]="ariaDescribedBy()"
|
|
1318
1524
|
>
|
|
1319
1525
|
{{ label() | dynamicText | async }}
|
|
1320
1526
|
</df-ion-toggle-control>
|
|
1321
1527
|
|
|
1322
1528
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1323
|
-
<ion-note color="danger" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1529
|
+
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1530
|
+
} @empty {
|
|
1531
|
+
@if (props()?.hint; as hint) {
|
|
1532
|
+
<ion-note class="df-ion-hint" [id]="hintId()">{{ hint | dynamicText | async }}</ion-note>
|
|
1533
|
+
}
|
|
1324
1534
|
}
|
|
1325
1535
|
`, host: {
|
|
1326
1536
|
'[class]': 'className()',
|
|
1327
1537
|
'[id]': '`${key()}`',
|
|
1328
1538
|
'[attr.data-testid]': 'key()',
|
|
1329
1539
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
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"] }]
|
|
1540
|
+
}, 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{display:block;color:var(--df-hint-color);font-size:var(--df-hint-font-size)}.df-ion-error{display:block;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
1541
|
}], 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 }] }] } });
|
|
1332
1542
|
|
|
1333
1543
|
var ionicToggle_component = /*#__PURE__*/Object.freeze({
|
|
@@ -1369,9 +1579,9 @@ const IonicField = {
|
|
|
1369
1579
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1370
1580
|
*/
|
|
1371
1581
|
function buttonFieldMapper(fieldDef) {
|
|
1372
|
-
|
|
1373
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1582
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1374
1583
|
return computed(() => {
|
|
1584
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1375
1585
|
const inputs = {
|
|
1376
1586
|
...baseInputs,
|
|
1377
1587
|
};
|
|
@@ -1409,20 +1619,21 @@ function buttonFieldMapper(fieldDef) {
|
|
|
1409
1619
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1410
1620
|
*/
|
|
1411
1621
|
function submitButtonFieldMapper(fieldDef) {
|
|
1412
|
-
|
|
1413
|
-
const
|
|
1414
|
-
|
|
1415
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1416
|
-
// Use button-logic-resolver to compute disabled state
|
|
1622
|
+
const rootFormRegistry = inject(RootFormRegistryService);
|
|
1623
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1624
|
+
const formOptions = inject(FORM_OPTIONS);
|
|
1417
1625
|
const fieldWithLogic = fieldDef;
|
|
1418
|
-
const disabledSignal = resolveSubmitButtonDisabled({
|
|
1419
|
-
form: fieldSignalContext.form,
|
|
1420
|
-
formOptions: fieldSignalContext.formOptions,
|
|
1421
|
-
fieldLogic: fieldWithLogic.logic,
|
|
1422
|
-
explicitlyDisabled: fieldDef.disabled,
|
|
1423
|
-
});
|
|
1424
|
-
// Return computed signal - evaluates disabledSignal inside for reactivity
|
|
1425
1626
|
return computed(() => {
|
|
1627
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1628
|
+
// Use rootFormRegistry instead of fieldSignalContext.form because when the submit button
|
|
1629
|
+
// is inside a group/array, fieldSignalContext.form points to the nested form tree,
|
|
1630
|
+
// not the root form. We need root form validity for submit button disabled state (#157).
|
|
1631
|
+
const disabledSignal = resolveSubmitButtonDisabled({
|
|
1632
|
+
form: rootFormRegistry.getRootForm(),
|
|
1633
|
+
formOptions: formOptions(),
|
|
1634
|
+
fieldLogic: fieldWithLogic.logic,
|
|
1635
|
+
explicitlyDisabled: fieldDef.disabled,
|
|
1636
|
+
});
|
|
1426
1637
|
const inputs = {
|
|
1427
1638
|
...baseInputs,
|
|
1428
1639
|
// No event - native form submit handles it via form's onNativeSubmit
|
|
@@ -1449,21 +1660,19 @@ function submitButtonFieldMapper(fieldDef) {
|
|
|
1449
1660
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1450
1661
|
*/
|
|
1451
1662
|
function nextButtonFieldMapper(fieldDef) {
|
|
1452
|
-
// Inject field signal context to access form state and options
|
|
1453
1663
|
const fieldSignalContext = inject(FIELD_SIGNAL_CONTEXT);
|
|
1454
|
-
|
|
1455
|
-
const
|
|
1456
|
-
// Use button-logic-resolver to compute disabled state
|
|
1664
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1665
|
+
const formOptions = inject(FORM_OPTIONS);
|
|
1457
1666
|
const fieldWithLogic = fieldDef;
|
|
1458
|
-
const disabledSignal = resolveNextButtonDisabled({
|
|
1459
|
-
form: fieldSignalContext.form,
|
|
1460
|
-
formOptions: fieldSignalContext.formOptions,
|
|
1461
|
-
fieldLogic: fieldWithLogic.logic,
|
|
1462
|
-
explicitlyDisabled: fieldDef.disabled,
|
|
1463
|
-
currentPageValid: fieldSignalContext.currentPageValid,
|
|
1464
|
-
});
|
|
1465
|
-
// Return computed signal - evaluates disabledSignal inside for reactivity
|
|
1466
1667
|
return computed(() => {
|
|
1668
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1669
|
+
const disabledSignal = resolveNextButtonDisabled({
|
|
1670
|
+
form: fieldSignalContext.form,
|
|
1671
|
+
formOptions: formOptions(),
|
|
1672
|
+
fieldLogic: fieldWithLogic.logic,
|
|
1673
|
+
explicitlyDisabled: fieldDef.disabled,
|
|
1674
|
+
currentPageValid: fieldSignalContext.currentPageValid,
|
|
1675
|
+
});
|
|
1467
1676
|
const inputs = {
|
|
1468
1677
|
...baseInputs,
|
|
1469
1678
|
event: NextPageEvent,
|
|
@@ -1484,9 +1693,9 @@ function nextButtonFieldMapper(fieldDef) {
|
|
|
1484
1693
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1485
1694
|
*/
|
|
1486
1695
|
function previousButtonFieldMapper(fieldDef) {
|
|
1487
|
-
|
|
1488
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1696
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1489
1697
|
return computed(() => {
|
|
1698
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1490
1699
|
const inputs = {
|
|
1491
1700
|
...baseInputs,
|
|
1492
1701
|
event: PreviousPageEvent,
|
|
@@ -1512,10 +1721,9 @@ function previousButtonFieldMapper(fieldDef) {
|
|
|
1512
1721
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1513
1722
|
*/
|
|
1514
1723
|
function addArrayItemButtonFieldMapper(fieldDef) {
|
|
1515
|
-
// Try to get array context (available when inside an array)
|
|
1516
|
-
// Use optional injection so it doesn't fail when outside an array
|
|
1517
1724
|
const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
|
|
1518
1725
|
const logger = inject(DynamicFormLogger);
|
|
1726
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1519
1727
|
// Determine the target array key
|
|
1520
1728
|
// Priority: explicit arrayKey from fieldDef > arrayKey from context
|
|
1521
1729
|
const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
|
|
@@ -1523,13 +1731,12 @@ function addArrayItemButtonFieldMapper(fieldDef) {
|
|
|
1523
1731
|
logger.warn(`addArrayItem button "${fieldDef.key}" has no array context. ` +
|
|
1524
1732
|
'Either place it inside an array field, or provide an explicit arrayKey property.');
|
|
1525
1733
|
}
|
|
1526
|
-
// Build base inputs (static, from field definition)
|
|
1527
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1528
1734
|
// Set default eventArgs for AddArrayItemEvent (arrayKey)
|
|
1529
1735
|
// User can override by providing eventArgs in field definition
|
|
1530
1736
|
const defaultEventArgs = ['$arrayKey'];
|
|
1531
1737
|
const eventArgs = 'eventArgs' in fieldDef && fieldDef.eventArgs !== undefined ? fieldDef.eventArgs : defaultEventArgs;
|
|
1532
1738
|
return computed(() => {
|
|
1739
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1533
1740
|
// Read signal value if index is a signal (supports differential updates)
|
|
1534
1741
|
const getIndex = () => {
|
|
1535
1742
|
if (!arrayContext)
|
|
@@ -1568,10 +1775,9 @@ function addArrayItemButtonFieldMapper(fieldDef) {
|
|
|
1568
1775
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1569
1776
|
*/
|
|
1570
1777
|
function removeArrayItemButtonFieldMapper(fieldDef) {
|
|
1571
|
-
// Try to get array context (available when inside an array)
|
|
1572
|
-
// Use optional injection so it doesn't fail when outside an array
|
|
1573
1778
|
const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
|
|
1574
1779
|
const logger = inject(DynamicFormLogger);
|
|
1780
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1575
1781
|
// Determine the target array key
|
|
1576
1782
|
// Priority: explicit arrayKey from fieldDef > arrayKey from context
|
|
1577
1783
|
const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
|
|
@@ -1579,14 +1785,13 @@ function removeArrayItemButtonFieldMapper(fieldDef) {
|
|
|
1579
1785
|
logger.warn(`removeArrayItem button "${fieldDef.key}" has no array context. ` +
|
|
1580
1786
|
'Either place it inside an array field, or provide an explicit arrayKey property.');
|
|
1581
1787
|
}
|
|
1582
|
-
// Build base inputs (static, from field definition)
|
|
1583
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1584
1788
|
// Set default eventArgs for RemoveArrayItemEvent (arrayKey, index if inside array)
|
|
1585
1789
|
// When outside array, only pass arrayKey (removes last by default)
|
|
1586
1790
|
// User can override by providing eventArgs in field definition
|
|
1587
1791
|
const defaultEventArgs = arrayContext ? ['$arrayKey', '$index'] : ['$arrayKey'];
|
|
1588
1792
|
const eventArgs = 'eventArgs' in fieldDef && fieldDef.eventArgs !== undefined ? fieldDef.eventArgs : defaultEventArgs;
|
|
1589
1793
|
return computed(() => {
|
|
1794
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1590
1795
|
// Read signal value if index is a signal (supports differential updates)
|
|
1591
1796
|
const getIndex = () => {
|
|
1592
1797
|
if (!arrayContext)
|