@ng-forge/dynamic-forms-ionic 0.3.1 → 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,8 +64,8 @@ class IonicButtonFieldComponent {
|
|
|
64
64
|
this.eventBus.dispatch(event);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
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
69
|
@let buttonId = key() + '-button';
|
|
70
70
|
|
|
71
71
|
<ion-button
|
|
@@ -83,19 +83,16 @@ class IonicButtonFieldComponent {
|
|
|
83
83
|
>
|
|
84
84
|
{{ label() | dynamicText | async }}
|
|
85
85
|
</ion-button>
|
|
86
|
-
`, 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 });
|
|
87
87
|
}
|
|
88
|
-
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: [{
|
|
89
89
|
type: Component,
|
|
90
|
-
args: [{
|
|
91
|
-
selector: 'df-ion-button',
|
|
92
|
-
imports: [IonButton, DynamicTextPipe, AsyncPipe],
|
|
93
|
-
host: {
|
|
90
|
+
args: [{ selector: 'df-ion-button', imports: [IonButton, DynamicTextPipe, AsyncPipe], host: {
|
|
94
91
|
'[id]': '`${key()}`',
|
|
95
92
|
'[class]': 'className()',
|
|
96
93
|
'[attr.data-testid]': 'key()',
|
|
97
|
-
|
|
98
|
-
template: `
|
|
94
|
+
'[attr.hidden]': 'hidden() || null',
|
|
95
|
+
}, template: `
|
|
99
96
|
@let buttonId = key() + '-button';
|
|
100
97
|
|
|
101
98
|
<ion-button
|
|
@@ -113,9 +110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
113
110
|
>
|
|
114
111
|
{{ label() | dynamicText | async }}
|
|
115
112
|
</ion-button>
|
|
116
|
-
`,
|
|
117
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
118
|
-
}]
|
|
113
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host([hidden]){display:none!important}\n"] }]
|
|
119
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 }] }] } });
|
|
120
115
|
|
|
121
116
|
var ionicButton_component = /*#__PURE__*/Object.freeze({
|
|
@@ -125,6 +120,29 @@ var ionicButton_component = /*#__PURE__*/Object.freeze({
|
|
|
125
120
|
|
|
126
121
|
// Public API - component
|
|
127
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
|
+
|
|
128
146
|
class IonicCheckboxFieldComponent {
|
|
129
147
|
elementRef = inject((ElementRef));
|
|
130
148
|
field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
|
|
@@ -152,17 +170,21 @@ class IonicCheckboxFieldComponent {
|
|
|
152
170
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
153
171
|
/** Base ID for error elements */
|
|
154
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" }] : []));
|
|
155
175
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
156
|
-
|
|
176
|
+
ariaInvalid = computed(() => {
|
|
157
177
|
const fieldState = this.field()();
|
|
158
178
|
return fieldState.invalid() && fieldState.touched();
|
|
159
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
179
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
160
180
|
/** Whether the field has a required validator */
|
|
161
|
-
|
|
162
|
-
return this.field()().required?.() === true;
|
|
163
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
164
|
-
|
|
165
|
-
|
|
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: `
|
|
166
188
|
@let f = field();
|
|
167
189
|
@let checkboxId = key() + '-checkbox';
|
|
168
190
|
|
|
@@ -174,18 +196,23 @@ class IonicCheckboxFieldComponent {
|
|
|
174
196
|
[color]="props()?.color ?? 'primary'"
|
|
175
197
|
[indeterminate]="props()?.indeterminate ?? false"
|
|
176
198
|
[attr.tabindex]="tabIndex()"
|
|
177
|
-
[attr.aria-invalid]="
|
|
178
|
-
[attr.aria-required]="
|
|
199
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
200
|
+
[attr.aria-required]="ariaRequired()"
|
|
201
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
179
202
|
>
|
|
180
203
|
{{ label() | dynamicText | async }}
|
|
181
204
|
</ion-checkbox>
|
|
182
205
|
|
|
183
206
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
184
|
-
<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
|
+
}
|
|
185
212
|
}
|
|
186
|
-
`, 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 });
|
|
187
214
|
}
|
|
188
|
-
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: [{
|
|
189
216
|
type: Component,
|
|
190
217
|
args: [{ selector: 'df-ion-checkbox', imports: [IonCheckbox, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
191
218
|
@let f = field();
|
|
@@ -199,21 +226,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
199
226
|
[color]="props()?.color ?? 'primary'"
|
|
200
227
|
[indeterminate]="props()?.indeterminate ?? false"
|
|
201
228
|
[attr.tabindex]="tabIndex()"
|
|
202
|
-
[attr.aria-invalid]="
|
|
203
|
-
[attr.aria-required]="
|
|
229
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
230
|
+
[attr.aria-required]="ariaRequired()"
|
|
231
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
204
232
|
>
|
|
205
233
|
{{ label() | dynamicText | async }}
|
|
206
234
|
</ion-checkbox>
|
|
207
235
|
|
|
208
236
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
209
|
-
<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
|
+
}
|
|
210
242
|
}
|
|
211
243
|
`, host: {
|
|
212
244
|
'[class]': 'className()',
|
|
213
245
|
'[id]': '`${key()}`',
|
|
214
246
|
'[attr.data-testid]': 'key()',
|
|
215
247
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
216
|
-
}, 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"] }]
|
|
217
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 }] }] } });
|
|
218
250
|
|
|
219
251
|
var ionicCheckbox_component = /*#__PURE__*/Object.freeze({
|
|
@@ -251,15 +283,19 @@ class IonicDatepickerFieldComponent {
|
|
|
251
283
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
252
284
|
/** Base ID for error elements */
|
|
253
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" }] : []));
|
|
254
288
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
255
|
-
|
|
289
|
+
ariaInvalid = computed(() => {
|
|
256
290
|
const fieldState = this.field()();
|
|
257
291
|
return fieldState.invalid() && fieldState.touched();
|
|
258
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
292
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
259
293
|
/** Whether the field has a required validator */
|
|
260
|
-
|
|
261
|
-
return this.field()().required?.() === true;
|
|
262
|
-
}, ...(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);
|
|
263
299
|
openModal() {
|
|
264
300
|
this.isModalOpen.set(true);
|
|
265
301
|
}
|
|
@@ -304,11 +340,10 @@ class IonicDatepickerFieldComponent {
|
|
|
304
340
|
return format(date, 'MMM d, yyyy');
|
|
305
341
|
}
|
|
306
342
|
}
|
|
307
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
308
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0
|
|
309
|
-
@let f = field();
|
|
310
|
-
@let
|
|
311
|
-
@let ariaRequired = isRequired() || null;
|
|
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();
|
|
312
347
|
@let inputId = key() + '-input';
|
|
313
348
|
|
|
314
349
|
<ion-input
|
|
@@ -321,12 +356,17 @@ class IonicDatepickerFieldComponent {
|
|
|
321
356
|
[readonly]="true"
|
|
322
357
|
[fill]="'outline'"
|
|
323
358
|
[attr.tabindex]="tabIndex()"
|
|
324
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
325
|
-
[attr.aria-required]="ariaRequired"
|
|
359
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
360
|
+
[attr.aria-required]="ariaRequired()"
|
|
361
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
326
362
|
(click)="!f().disabled() && openModal()"
|
|
327
363
|
/>
|
|
328
364
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
329
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
|
+
}
|
|
330
370
|
}
|
|
331
371
|
|
|
332
372
|
<ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
|
|
@@ -358,9 +398,9 @@ class IonicDatepickerFieldComponent {
|
|
|
358
398
|
</ion-content>
|
|
359
399
|
</ng-template>
|
|
360
400
|
</ion-modal>
|
|
361
|
-
`, 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 });
|
|
362
402
|
}
|
|
363
|
-
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: [{
|
|
364
404
|
type: Component,
|
|
365
405
|
args: [{ selector: 'df-ion-datepicker', imports: [
|
|
366
406
|
IonInput,
|
|
@@ -376,9 +416,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
376
416
|
DynamicTextPipe,
|
|
377
417
|
AsyncPipe,
|
|
378
418
|
], template: `
|
|
379
|
-
@let f = field();
|
|
380
|
-
@let
|
|
381
|
-
@let ariaRequired = isRequired() || null;
|
|
419
|
+
@let f = field();
|
|
420
|
+
@let dateValue = f().value();
|
|
382
421
|
@let inputId = key() + '-input';
|
|
383
422
|
|
|
384
423
|
<ion-input
|
|
@@ -391,12 +430,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
391
430
|
[readonly]="true"
|
|
392
431
|
[fill]="'outline'"
|
|
393
432
|
[attr.tabindex]="tabIndex()"
|
|
394
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
395
|
-
[attr.aria-required]="ariaRequired"
|
|
433
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
434
|
+
[attr.aria-required]="ariaRequired()"
|
|
435
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
396
436
|
(click)="!f().disabled() && openModal()"
|
|
397
437
|
/>
|
|
398
438
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
399
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
|
+
}
|
|
400
444
|
}
|
|
401
445
|
|
|
402
446
|
<ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
|
|
@@ -433,7 +477,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
433
477
|
'[attr.data-testid]': 'key()',
|
|
434
478
|
'[class]': 'className()',
|
|
435
479
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
436
|
-
}, 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"] }]
|
|
437
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 }] }] } });
|
|
438
482
|
|
|
439
483
|
var ionicDatepicker_component = /*#__PURE__*/Object.freeze({
|
|
@@ -489,26 +533,48 @@ class IonicInputFieldComponent {
|
|
|
489
533
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
490
534
|
selector: 'ion-input',
|
|
491
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
|
+
});
|
|
492
556
|
}
|
|
493
557
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
494
558
|
// Accessibility
|
|
495
559
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
496
560
|
/** Base ID for error elements */
|
|
497
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" }] : []));
|
|
498
564
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
499
|
-
|
|
565
|
+
ariaInvalid = computed(() => {
|
|
500
566
|
const fieldState = this.field()();
|
|
501
567
|
return fieldState.invalid() && fieldState.touched();
|
|
502
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
568
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
503
569
|
/** Whether the field has a required validator */
|
|
504
|
-
|
|
505
|
-
return this.field()().required?.() === true;
|
|
506
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
507
|
-
|
|
508
|
-
|
|
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: `
|
|
509
577
|
@let f = field();
|
|
510
|
-
@let ariaInvalid = isAriaInvalid();
|
|
511
|
-
@let ariaRequired = isRequired() || null;
|
|
512
578
|
@let inputId = key() + '-input';
|
|
513
579
|
|
|
514
580
|
<ion-input
|
|
@@ -524,22 +590,21 @@ class IonicInputFieldComponent {
|
|
|
524
590
|
[fill]="effectiveFill()"
|
|
525
591
|
[shape]="effectiveShape()"
|
|
526
592
|
[readonly]="f().readonly()"
|
|
527
|
-
[helperText]="(props()?.
|
|
593
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
528
594
|
[attr.tabindex]="tabIndex()"
|
|
529
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
530
|
-
[attr.aria-required]="ariaRequired"
|
|
595
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
596
|
+
[attr.aria-required]="ariaRequired()"
|
|
597
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
531
598
|
/>
|
|
532
599
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
533
600
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
534
601
|
}
|
|
535
|
-
`, 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 });
|
|
536
603
|
}
|
|
537
|
-
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: [{
|
|
538
605
|
type: Component,
|
|
539
606
|
args: [{ selector: 'df-ion-input', imports: [IonInput, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
540
607
|
@let f = field();
|
|
541
|
-
@let ariaInvalid = isAriaInvalid();
|
|
542
|
-
@let ariaRequired = isRequired() || null;
|
|
543
608
|
@let inputId = key() + '-input';
|
|
544
609
|
|
|
545
610
|
<ion-input
|
|
@@ -555,10 +620,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
555
620
|
[fill]="effectiveFill()"
|
|
556
621
|
[shape]="effectiveShape()"
|
|
557
622
|
[readonly]="f().readonly()"
|
|
558
|
-
[helperText]="(props()?.
|
|
623
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
559
624
|
[attr.tabindex]="tabIndex()"
|
|
560
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
561
|
-
[attr.aria-required]="ariaRequired"
|
|
625
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
626
|
+
[attr.aria-required]="ariaRequired()"
|
|
627
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
562
628
|
/>
|
|
563
629
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
564
630
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
@@ -568,7 +634,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
568
634
|
'[attr.data-testid]': 'key()',
|
|
569
635
|
'[class]': 'className()',
|
|
570
636
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
571
|
-
}, 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"] }]
|
|
572
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 }] }] } });
|
|
573
639
|
|
|
574
640
|
var ionicInput_component = /*#__PURE__*/Object.freeze({
|
|
@@ -597,19 +663,31 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
597
663
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
598
664
|
/** Base ID for error elements */
|
|
599
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" }] : []));
|
|
600
668
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
601
|
-
|
|
669
|
+
ariaInvalid = computed(() => {
|
|
602
670
|
const fieldState = this.field()();
|
|
603
671
|
return fieldState.invalid() && fieldState.touched();
|
|
604
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
672
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
605
673
|
/** Whether the field has a required validator */
|
|
606
|
-
|
|
607
|
-
return this.field()().required?.() === true;
|
|
608
|
-
}, ...(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);
|
|
609
679
|
valueViewModel = linkedSignal(() => {
|
|
610
680
|
const currentValues = this.field()().value();
|
|
611
681
|
return this.options().filter((option) => currentValues.includes(option.value));
|
|
612
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" }] : []));
|
|
613
691
|
constructor() {
|
|
614
692
|
// Shadow DOM - apply meta to ion-checkbox elements, re-apply when options change
|
|
615
693
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
@@ -641,9 +719,10 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
641
719
|
}
|
|
642
720
|
});
|
|
643
721
|
}
|
|
644
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
645
|
-
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: `
|
|
646
724
|
@let f = field();
|
|
725
|
+
@let checked = checkedValuesMap();
|
|
647
726
|
@if (label(); as label) {
|
|
648
727
|
<div class="checkbox-group-label">{{ label | dynamicText | async }}</div>
|
|
649
728
|
}
|
|
@@ -651,15 +730,16 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
651
730
|
<div
|
|
652
731
|
class="checkbox-group"
|
|
653
732
|
role="group"
|
|
654
|
-
[attr.aria-invalid]="
|
|
655
|
-
[attr.aria-required]="
|
|
733
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
734
|
+
[attr.aria-required]="ariaRequired()"
|
|
735
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
656
736
|
[class.ion-invalid]="showErrors()"
|
|
657
737
|
[class.ion-touched]="field()().touched()"
|
|
658
738
|
>
|
|
659
739
|
@for (option of options(); track option.value) {
|
|
660
740
|
<ion-item lines="none">
|
|
661
741
|
<ion-checkbox
|
|
662
|
-
[checked]="
|
|
742
|
+
[checked]="checked['' + option.value]"
|
|
663
743
|
[disabled]="f().disabled() || option.disabled"
|
|
664
744
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
665
745
|
[justify]="props()?.justify ?? 'start'"
|
|
@@ -673,14 +753,19 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
673
753
|
</div>
|
|
674
754
|
|
|
675
755
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
676
|
-
<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
|
+
}
|
|
677
761
|
}
|
|
678
|
-
`, 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 });
|
|
679
763
|
}
|
|
680
|
-
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: [{
|
|
681
765
|
type: Component,
|
|
682
|
-
args: [{ selector: 'df-ion-multi-checkbox', imports: [IonCheckbox, IonItem, IonNote,
|
|
766
|
+
args: [{ selector: 'df-ion-multi-checkbox', imports: [IonCheckbox, IonItem, IonNote, DynamicTextPipe, AsyncPipe], template: `
|
|
683
767
|
@let f = field();
|
|
768
|
+
@let checked = checkedValuesMap();
|
|
684
769
|
@if (label(); as label) {
|
|
685
770
|
<div class="checkbox-group-label">{{ label | dynamicText | async }}</div>
|
|
686
771
|
}
|
|
@@ -688,15 +773,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
688
773
|
<div
|
|
689
774
|
class="checkbox-group"
|
|
690
775
|
role="group"
|
|
691
|
-
[attr.aria-invalid]="
|
|
692
|
-
[attr.aria-required]="
|
|
776
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
777
|
+
[attr.aria-required]="ariaRequired()"
|
|
778
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
693
779
|
[class.ion-invalid]="showErrors()"
|
|
694
780
|
[class.ion-touched]="field()().touched()"
|
|
695
781
|
>
|
|
696
782
|
@for (option of options(); track option.value) {
|
|
697
783
|
<ion-item lines="none">
|
|
698
784
|
<ion-checkbox
|
|
699
|
-
[checked]="
|
|
785
|
+
[checked]="checked['' + option.value]"
|
|
700
786
|
[disabled]="f().disabled() || option.disabled"
|
|
701
787
|
[labelPlacement]="props()?.labelPlacement ?? 'end'"
|
|
702
788
|
[justify]="props()?.justify ?? 'start'"
|
|
@@ -710,14 +796,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
710
796
|
</div>
|
|
711
797
|
|
|
712
798
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
713
|
-
<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
|
+
}
|
|
714
804
|
}
|
|
715
805
|
`, host: {
|
|
716
806
|
'[class]': 'className() || ""',
|
|
717
807
|
'[id]': '`${key()}`',
|
|
718
808
|
'[attr.data-testid]': 'key()',
|
|
719
809
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
720
|
-
},
|
|
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"] }]
|
|
721
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 }] }] } });
|
|
722
812
|
|
|
723
813
|
var ionicMultiCheckbox_component = /*#__PURE__*/Object.freeze({
|
|
@@ -755,17 +845,21 @@ class IonicRadioFieldComponent {
|
|
|
755
845
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
756
846
|
/** Base ID for error elements */
|
|
757
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" }] : []));
|
|
758
850
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
759
|
-
|
|
851
|
+
ariaInvalid = computed(() => {
|
|
760
852
|
const fieldState = this.field()();
|
|
761
853
|
return fieldState.invalid() && fieldState.touched();
|
|
762
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
854
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
763
855
|
/** Whether the field has a required validator */
|
|
764
|
-
|
|
765
|
-
return this.field()().required?.() === true;
|
|
766
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
767
|
-
|
|
768
|
-
|
|
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: `
|
|
769
863
|
@let f = field();
|
|
770
864
|
@let radioGroupId = key() + '-radio-group';
|
|
771
865
|
@if (label(); as label) {
|
|
@@ -776,8 +870,9 @@ class IonicRadioFieldComponent {
|
|
|
776
870
|
[id]="radioGroupId"
|
|
777
871
|
[formField]="f"
|
|
778
872
|
[compareWith]="props()?.compareWith || defaultCompare"
|
|
779
|
-
[attr.aria-invalid]="
|
|
780
|
-
[attr.aria-required]="
|
|
873
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
874
|
+
[attr.aria-required]="ariaRequired()"
|
|
875
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
781
876
|
>
|
|
782
877
|
@for (option of options(); track option.value) {
|
|
783
878
|
<ion-item [lines]="'none'">
|
|
@@ -795,11 +890,15 @@ class IonicRadioFieldComponent {
|
|
|
795
890
|
</ion-radio-group>
|
|
796
891
|
|
|
797
892
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
798
|
-
<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
|
+
}
|
|
799
898
|
}
|
|
800
|
-
`, 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 });
|
|
801
900
|
}
|
|
802
|
-
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: [{
|
|
803
902
|
type: Component,
|
|
804
903
|
args: [{ selector: 'df-ion-radio', imports: [IonRadioGroup, IonRadio, IonItem, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
805
904
|
@let f = field();
|
|
@@ -812,8 +911,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
812
911
|
[id]="radioGroupId"
|
|
813
912
|
[formField]="f"
|
|
814
913
|
[compareWith]="props()?.compareWith || defaultCompare"
|
|
815
|
-
[attr.aria-invalid]="
|
|
816
|
-
[attr.aria-required]="
|
|
914
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
915
|
+
[attr.aria-required]="ariaRequired()"
|
|
916
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
817
917
|
>
|
|
818
918
|
@for (option of options(); track option.value) {
|
|
819
919
|
<ion-item [lines]="'none'">
|
|
@@ -831,14 +931,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
831
931
|
</ion-radio-group>
|
|
832
932
|
|
|
833
933
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
834
|
-
<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
|
+
}
|
|
835
939
|
}
|
|
836
940
|
`, host: {
|
|
837
941
|
'[class]': 'className()',
|
|
838
942
|
'[id]': '`${key()}`',
|
|
839
943
|
'[attr.data-testid]': 'key()',
|
|
840
944
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
841
|
-
}, 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"] }]
|
|
842
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 }] }] } });
|
|
843
947
|
|
|
844
948
|
var ionicRadio_component = /*#__PURE__*/Object.freeze({
|
|
@@ -871,20 +975,22 @@ class IonicSelectFieldComponent {
|
|
|
871
975
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
872
976
|
/** Base ID for error elements */
|
|
873
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" }] : []));
|
|
874
980
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
875
|
-
|
|
981
|
+
ariaInvalid = computed(() => {
|
|
876
982
|
const fieldState = this.field()();
|
|
877
983
|
return fieldState.invalid() && fieldState.touched();
|
|
878
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
984
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
879
985
|
/** Whether the field has a required validator */
|
|
880
|
-
|
|
881
|
-
return this.field()().required?.() === true;
|
|
882
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
883
|
-
|
|
884
|
-
|
|
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: `
|
|
885
993
|
@let f = field();
|
|
886
|
-
@let ariaInvalid = isAriaInvalid();
|
|
887
|
-
@let ariaRequired = isRequired() || null;
|
|
888
994
|
@let selectId = key() + '-select';
|
|
889
995
|
|
|
890
996
|
<ion-select
|
|
@@ -903,8 +1009,9 @@ class IonicSelectFieldComponent {
|
|
|
903
1009
|
[fill]="props()?.fill ?? 'outline'"
|
|
904
1010
|
[shape]="props()?.shape"
|
|
905
1011
|
[attr.tabindex]="tabIndex()"
|
|
906
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
907
|
-
[attr.aria-required]="ariaRequired"
|
|
1012
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1013
|
+
[attr.aria-required]="ariaRequired()"
|
|
1014
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
908
1015
|
>
|
|
909
1016
|
@for (option of options(); track option.value) {
|
|
910
1017
|
<ion-select-option [value]="option.value" [disabled]="option.disabled || false">
|
|
@@ -914,15 +1021,17 @@ class IonicSelectFieldComponent {
|
|
|
914
1021
|
</ion-select>
|
|
915
1022
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
916
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
|
+
}
|
|
917
1028
|
}
|
|
918
|
-
`, 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 });
|
|
919
1030
|
}
|
|
920
|
-
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: [{
|
|
921
1032
|
type: Component,
|
|
922
1033
|
args: [{ selector: 'df-ion-select', imports: [IonSelect, IonSelectOption, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
923
1034
|
@let f = field();
|
|
924
|
-
@let ariaInvalid = isAriaInvalid();
|
|
925
|
-
@let ariaRequired = isRequired() || null;
|
|
926
1035
|
@let selectId = key() + '-select';
|
|
927
1036
|
|
|
928
1037
|
<ion-select
|
|
@@ -941,8 +1050,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
941
1050
|
[fill]="props()?.fill ?? 'outline'"
|
|
942
1051
|
[shape]="props()?.shape"
|
|
943
1052
|
[attr.tabindex]="tabIndex()"
|
|
944
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
945
|
-
[attr.aria-required]="ariaRequired"
|
|
1053
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1054
|
+
[attr.aria-required]="ariaRequired()"
|
|
1055
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
946
1056
|
>
|
|
947
1057
|
@for (option of options(); track option.value) {
|
|
948
1058
|
<ion-select-option [value]="option.value" [disabled]="option.disabled || false">
|
|
@@ -952,13 +1062,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
952
1062
|
</ion-select>
|
|
953
1063
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
954
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
|
+
}
|
|
955
1069
|
}
|
|
956
1070
|
`, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
957
1071
|
'[id]': '`${key()}`',
|
|
958
1072
|
'[attr.data-testid]': 'key()',
|
|
959
1073
|
'[class]': 'className()',
|
|
960
1074
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
961
|
-
}, 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"] }]
|
|
962
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 }] }] } });
|
|
963
1077
|
|
|
964
1078
|
var ionicSelect_component = /*#__PURE__*/Object.freeze({
|
|
@@ -990,17 +1104,21 @@ class IonicSliderFieldComponent {
|
|
|
990
1104
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
991
1105
|
/** Base ID for error elements */
|
|
992
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" }] : []));
|
|
993
1109
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
994
|
-
|
|
1110
|
+
ariaInvalid = computed(() => {
|
|
995
1111
|
const fieldState = this.field()();
|
|
996
1112
|
return fieldState.invalid() && fieldState.touched();
|
|
997
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
1113
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
998
1114
|
/** Whether the field has a required validator */
|
|
999
|
-
|
|
1000
|
-
return this.field()().required?.() === true;
|
|
1001
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
1002
|
-
|
|
1003
|
-
|
|
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: `
|
|
1004
1122
|
@let f = field();
|
|
1005
1123
|
@let inputId = key() + '-input';
|
|
1006
1124
|
|
|
@@ -1009,6 +1127,8 @@ class IonicSliderFieldComponent {
|
|
|
1009
1127
|
[formField]="f"
|
|
1010
1128
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
1011
1129
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
1130
|
+
[min]="props()?.min ?? 0"
|
|
1131
|
+
[max]="props()?.max ?? 100"
|
|
1012
1132
|
[step]="props()?.step ?? 1"
|
|
1013
1133
|
[dualKnobs]="props()?.dualKnobs ?? false"
|
|
1014
1134
|
[pin]="props()?.pin ?? false"
|
|
@@ -1017,16 +1137,21 @@ class IonicSliderFieldComponent {
|
|
|
1017
1137
|
[snaps]="props()?.snaps ?? false"
|
|
1018
1138
|
[color]="props()?.color ?? 'primary'"
|
|
1019
1139
|
[attr.tabindex]="tabIndex()"
|
|
1020
|
-
[attr.aria-invalid]="
|
|
1021
|
-
[attr.aria-required]="
|
|
1140
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1141
|
+
[attr.aria-required]="ariaRequired()"
|
|
1142
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1022
1143
|
/>
|
|
1023
1144
|
|
|
1024
1145
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1025
|
-
<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
|
+
}
|
|
1026
1151
|
}
|
|
1027
|
-
`, 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 });
|
|
1028
1153
|
}
|
|
1029
|
-
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: [{
|
|
1030
1155
|
type: Component,
|
|
1031
1156
|
args: [{ selector: 'df-ion-slider', imports: [IonRange, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1032
1157
|
@let f = field();
|
|
@@ -1037,6 +1162,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1037
1162
|
[formField]="f"
|
|
1038
1163
|
[label]="(label() | dynamicText | async) ?? undefined"
|
|
1039
1164
|
[labelPlacement]="props()?.labelPlacement ?? 'stacked'"
|
|
1165
|
+
[min]="props()?.min ?? 0"
|
|
1166
|
+
[max]="props()?.max ?? 100"
|
|
1040
1167
|
[step]="props()?.step ?? 1"
|
|
1041
1168
|
[dualKnobs]="props()?.dualKnobs ?? false"
|
|
1042
1169
|
[pin]="props()?.pin ?? false"
|
|
@@ -1045,19 +1172,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1045
1172
|
[snaps]="props()?.snaps ?? false"
|
|
1046
1173
|
[color]="props()?.color ?? 'primary'"
|
|
1047
1174
|
[attr.tabindex]="tabIndex()"
|
|
1048
|
-
[attr.aria-invalid]="
|
|
1049
|
-
[attr.aria-required]="
|
|
1175
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1176
|
+
[attr.aria-required]="ariaRequired()"
|
|
1177
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1050
1178
|
/>
|
|
1051
1179
|
|
|
1052
1180
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1053
|
-
<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
|
+
}
|
|
1054
1186
|
}
|
|
1055
1187
|
`, host: {
|
|
1056
1188
|
'[class]': 'className()',
|
|
1057
1189
|
'[id]': '`${key()}`',
|
|
1058
1190
|
'[attr.data-testid]': 'key()',
|
|
1059
1191
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
1060
|
-
}, 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"] }]
|
|
1061
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 }] }] } });
|
|
1062
1194
|
|
|
1063
1195
|
var ionicSlider_component = /*#__PURE__*/Object.freeze({
|
|
@@ -1085,26 +1217,48 @@ class IonicTextareaFieldComponent {
|
|
|
1085
1217
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
1086
1218
|
selector: 'ion-textarea',
|
|
1087
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
|
+
});
|
|
1088
1240
|
}
|
|
1089
1241
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1090
1242
|
// Accessibility
|
|
1091
1243
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1092
1244
|
/** Base ID for error elements */
|
|
1093
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" }] : []));
|
|
1094
1248
|
/** Whether the field is currently in an invalid state (invalid AND touched) */
|
|
1095
|
-
|
|
1249
|
+
ariaInvalid = computed(() => {
|
|
1096
1250
|
const fieldState = this.field()();
|
|
1097
1251
|
return fieldState.invalid() && fieldState.touched();
|
|
1098
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
1252
|
+
}, ...(ngDevMode ? [{ debugName: "ariaInvalid" }] : []));
|
|
1099
1253
|
/** Whether the field has a required validator */
|
|
1100
|
-
|
|
1101
|
-
return this.field()().required?.() === true;
|
|
1102
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
1103
|
-
|
|
1104
|
-
|
|
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: `
|
|
1105
1261
|
@let f = field();
|
|
1106
|
-
@let ariaInvalid = isAriaInvalid();
|
|
1107
|
-
@let ariaRequired = isRequired() || null;
|
|
1108
1262
|
@let textareaId = key() + '-textarea';
|
|
1109
1263
|
|
|
1110
1264
|
<ion-textarea
|
|
@@ -1120,22 +1274,21 @@ class IonicTextareaFieldComponent {
|
|
|
1120
1274
|
[fill]="props()?.fill ?? 'outline'"
|
|
1121
1275
|
[shape]="props()?.shape"
|
|
1122
1276
|
[readonly]="f().readonly()"
|
|
1123
|
-
[helperText]="(props()?.
|
|
1277
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
1124
1278
|
[attr.tabindex]="tabIndex()"
|
|
1125
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1126
|
-
[attr.aria-required]="ariaRequired"
|
|
1279
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1280
|
+
[attr.aria-required]="ariaRequired()"
|
|
1281
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1127
1282
|
/>
|
|
1128
1283
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1129
1284
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
1130
1285
|
}
|
|
1131
|
-
`, 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 });
|
|
1132
1287
|
}
|
|
1133
|
-
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: [{
|
|
1134
1289
|
type: Component,
|
|
1135
1290
|
args: [{ selector: 'df-ion-textarea', imports: [IonTextarea, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1136
1291
|
@let f = field();
|
|
1137
|
-
@let ariaInvalid = isAriaInvalid();
|
|
1138
|
-
@let ariaRequired = isRequired() || null;
|
|
1139
1292
|
@let textareaId = key() + '-textarea';
|
|
1140
1293
|
|
|
1141
1294
|
<ion-textarea
|
|
@@ -1151,10 +1304,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1151
1304
|
[fill]="props()?.fill ?? 'outline'"
|
|
1152
1305
|
[shape]="props()?.shape"
|
|
1153
1306
|
[readonly]="f().readonly()"
|
|
1154
|
-
[helperText]="(props()?.
|
|
1307
|
+
[helperText]="errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined"
|
|
1155
1308
|
[attr.tabindex]="tabIndex()"
|
|
1156
|
-
[attr.aria-invalid]="ariaInvalid"
|
|
1157
|
-
[attr.aria-required]="ariaRequired"
|
|
1309
|
+
[attr.aria-invalid]="ariaInvalid()"
|
|
1310
|
+
[attr.aria-required]="ariaRequired()"
|
|
1311
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1158
1312
|
/>
|
|
1159
1313
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1160
1314
|
<ion-note color="danger" class="df-ion-error" [id]="errorId() + '-' + i" role="alert">{{ error.message }}</ion-note>
|
|
@@ -1164,7 +1318,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1164
1318
|
'[attr.data-testid]': 'key()',
|
|
1165
1319
|
'[class]': 'className()',
|
|
1166
1320
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
1167
|
-
}, 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"] }]
|
|
1168
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 }] }] } });
|
|
1169
1323
|
|
|
1170
1324
|
var ionicTextarea_component = /*#__PURE__*/Object.freeze({
|
|
@@ -1205,6 +1359,7 @@ class IonicToggleControlComponent {
|
|
|
1205
1359
|
enableOnOffLabels = input(false, ...(ngDevMode ? [{ debugName: "enableOnOffLabels" }] : []));
|
|
1206
1360
|
tabIndex = input(undefined, ...(ngDevMode ? [{ debugName: "tabIndex" }] : []));
|
|
1207
1361
|
meta = input(...(ngDevMode ? [undefined, { debugName: "meta" }] : []));
|
|
1362
|
+
ariaDescribedBy = input(null, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
1208
1363
|
constructor() {
|
|
1209
1364
|
// Shadow DOM - apply meta to ion-toggle element
|
|
1210
1365
|
setupMetaTracking(this.elementRef, this.meta, {
|
|
@@ -1248,8 +1403,8 @@ class IonicToggleControlComponent {
|
|
|
1248
1403
|
onBlur() {
|
|
1249
1404
|
this.touched.set(true);
|
|
1250
1405
|
}
|
|
1251
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0
|
|
1252
|
-
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: `
|
|
1253
1408
|
<ion-toggle
|
|
1254
1409
|
[checked]="isChecked()"
|
|
1255
1410
|
(ionChange)="onToggleChange($event)"
|
|
@@ -1263,12 +1418,13 @@ class IonicToggleControlComponent {
|
|
|
1263
1418
|
[attr.aria-invalid]="ariaInvalid()"
|
|
1264
1419
|
[attr.aria-required]="ariaRequired()"
|
|
1265
1420
|
[attr.aria-readonly]="ariaReadonly()"
|
|
1421
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1266
1422
|
>
|
|
1267
1423
|
<ng-content />
|
|
1268
1424
|
</ion-toggle>
|
|
1269
|
-
`, 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 });
|
|
1270
1426
|
}
|
|
1271
|
-
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: [{
|
|
1272
1428
|
type: Component,
|
|
1273
1429
|
args: [{ selector: 'df-ion-toggle-control', imports: [IonToggle], template: `
|
|
1274
1430
|
<ion-toggle
|
|
@@ -1284,11 +1440,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1284
1440
|
[attr.aria-invalid]="ariaInvalid()"
|
|
1285
1441
|
[attr.aria-required]="ariaRequired()"
|
|
1286
1442
|
[attr.aria-readonly]="ariaReadonly()"
|
|
1443
|
+
[attr.aria-describedby]="ariaDescribedBy()"
|
|
1287
1444
|
>
|
|
1288
1445
|
<ng-content />
|
|
1289
1446
|
</ion-toggle>
|
|
1290
|
-
`, host: {
|
|
1291
|
-
|
|
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 }] }] } });
|
|
1292
1451
|
|
|
1293
1452
|
class IonicToggleFieldComponent {
|
|
1294
1453
|
elementRef = inject((ElementRef));
|
|
@@ -1314,8 +1473,12 @@ class IonicToggleFieldComponent {
|
|
|
1314
1473
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1315
1474
|
/** Base ID for error elements */
|
|
1316
1475
|
errorId = computed(() => `${this.key()}-error`, ...(ngDevMode ? [{ debugName: "errorId" }] : []));
|
|
1317
|
-
|
|
1318
|
-
|
|
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: `
|
|
1319
1482
|
@let f = field();
|
|
1320
1483
|
@let toggleId = key() + '-toggle';
|
|
1321
1484
|
|
|
@@ -1328,16 +1491,21 @@ class IonicToggleFieldComponent {
|
|
|
1328
1491
|
[color]="props()?.color ?? 'primary'"
|
|
1329
1492
|
[enableOnOffLabels]="props()?.enableOnOffLabels ?? false"
|
|
1330
1493
|
[tabIndex]="tabIndex()"
|
|
1494
|
+
[ariaDescribedBy]="ariaDescribedBy()"
|
|
1331
1495
|
>
|
|
1332
1496
|
{{ label() | dynamicText | async }}
|
|
1333
1497
|
</df-ion-toggle-control>
|
|
1334
1498
|
|
|
1335
1499
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1336
|
-
<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
|
+
}
|
|
1337
1505
|
}
|
|
1338
|
-
`, 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 });
|
|
1339
1507
|
}
|
|
1340
|
-
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: [{
|
|
1341
1509
|
type: Component,
|
|
1342
1510
|
args: [{ selector: 'df-ion-toggle', imports: [IonicToggleControlComponent, IonNote, FormField, DynamicTextPipe, AsyncPipe], template: `
|
|
1343
1511
|
@let f = field();
|
|
@@ -1352,19 +1520,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
|
|
|
1352
1520
|
[color]="props()?.color ?? 'primary'"
|
|
1353
1521
|
[enableOnOffLabels]="props()?.enableOnOffLabels ?? false"
|
|
1354
1522
|
[tabIndex]="tabIndex()"
|
|
1523
|
+
[ariaDescribedBy]="ariaDescribedBy()"
|
|
1355
1524
|
>
|
|
1356
1525
|
{{ label() | dynamicText | async }}
|
|
1357
1526
|
</df-ion-toggle-control>
|
|
1358
1527
|
|
|
1359
1528
|
@for (error of errorsToDisplay(); track error.kind; let i = $index) {
|
|
1360
|
-
<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
|
+
}
|
|
1361
1534
|
}
|
|
1362
1535
|
`, host: {
|
|
1363
1536
|
'[class]': 'className()',
|
|
1364
1537
|
'[id]': '`${key()}`',
|
|
1365
1538
|
'[attr.data-testid]': 'key()',
|
|
1366
1539
|
'[attr.hidden]': 'field()().hidden() || null',
|
|
1367
|
-
}, 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"] }]
|
|
1368
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 }] }] } });
|
|
1369
1542
|
|
|
1370
1543
|
var ionicToggle_component = /*#__PURE__*/Object.freeze({
|
|
@@ -1406,9 +1579,9 @@ const IonicField = {
|
|
|
1406
1579
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1407
1580
|
*/
|
|
1408
1581
|
function buttonFieldMapper(fieldDef) {
|
|
1409
|
-
|
|
1410
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1582
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1411
1583
|
return computed(() => {
|
|
1584
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1412
1585
|
const inputs = {
|
|
1413
1586
|
...baseInputs,
|
|
1414
1587
|
};
|
|
@@ -1446,20 +1619,21 @@ function buttonFieldMapper(fieldDef) {
|
|
|
1446
1619
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1447
1620
|
*/
|
|
1448
1621
|
function submitButtonFieldMapper(fieldDef) {
|
|
1449
|
-
|
|
1450
|
-
const
|
|
1451
|
-
|
|
1452
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1453
|
-
// 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);
|
|
1454
1625
|
const fieldWithLogic = fieldDef;
|
|
1455
|
-
const disabledSignal = resolveSubmitButtonDisabled({
|
|
1456
|
-
form: fieldSignalContext.form,
|
|
1457
|
-
formOptions: fieldSignalContext.formOptions,
|
|
1458
|
-
fieldLogic: fieldWithLogic.logic,
|
|
1459
|
-
explicitlyDisabled: fieldDef.disabled,
|
|
1460
|
-
});
|
|
1461
|
-
// Return computed signal - evaluates disabledSignal inside for reactivity
|
|
1462
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
|
+
});
|
|
1463
1637
|
const inputs = {
|
|
1464
1638
|
...baseInputs,
|
|
1465
1639
|
// No event - native form submit handles it via form's onNativeSubmit
|
|
@@ -1486,21 +1660,19 @@ function submitButtonFieldMapper(fieldDef) {
|
|
|
1486
1660
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1487
1661
|
*/
|
|
1488
1662
|
function nextButtonFieldMapper(fieldDef) {
|
|
1489
|
-
// Inject field signal context to access form state and options
|
|
1490
1663
|
const fieldSignalContext = inject(FIELD_SIGNAL_CONTEXT);
|
|
1491
|
-
|
|
1492
|
-
const
|
|
1493
|
-
// Use button-logic-resolver to compute disabled state
|
|
1664
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1665
|
+
const formOptions = inject(FORM_OPTIONS);
|
|
1494
1666
|
const fieldWithLogic = fieldDef;
|
|
1495
|
-
const disabledSignal = resolveNextButtonDisabled({
|
|
1496
|
-
form: fieldSignalContext.form,
|
|
1497
|
-
formOptions: fieldSignalContext.formOptions,
|
|
1498
|
-
fieldLogic: fieldWithLogic.logic,
|
|
1499
|
-
explicitlyDisabled: fieldDef.disabled,
|
|
1500
|
-
currentPageValid: fieldSignalContext.currentPageValid,
|
|
1501
|
-
});
|
|
1502
|
-
// Return computed signal - evaluates disabledSignal inside for reactivity
|
|
1503
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
|
+
});
|
|
1504
1676
|
const inputs = {
|
|
1505
1677
|
...baseInputs,
|
|
1506
1678
|
event: NextPageEvent,
|
|
@@ -1521,9 +1693,9 @@ function nextButtonFieldMapper(fieldDef) {
|
|
|
1521
1693
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1522
1694
|
*/
|
|
1523
1695
|
function previousButtonFieldMapper(fieldDef) {
|
|
1524
|
-
|
|
1525
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1696
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1526
1697
|
return computed(() => {
|
|
1698
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1527
1699
|
const inputs = {
|
|
1528
1700
|
...baseInputs,
|
|
1529
1701
|
event: PreviousPageEvent,
|
|
@@ -1549,10 +1721,9 @@ function previousButtonFieldMapper(fieldDef) {
|
|
|
1549
1721
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1550
1722
|
*/
|
|
1551
1723
|
function addArrayItemButtonFieldMapper(fieldDef) {
|
|
1552
|
-
// Try to get array context (available when inside an array)
|
|
1553
|
-
// Use optional injection so it doesn't fail when outside an array
|
|
1554
1724
|
const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
|
|
1555
1725
|
const logger = inject(DynamicFormLogger);
|
|
1726
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1556
1727
|
// Determine the target array key
|
|
1557
1728
|
// Priority: explicit arrayKey from fieldDef > arrayKey from context
|
|
1558
1729
|
const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
|
|
@@ -1560,13 +1731,12 @@ function addArrayItemButtonFieldMapper(fieldDef) {
|
|
|
1560
1731
|
logger.warn(`addArrayItem button "${fieldDef.key}" has no array context. ` +
|
|
1561
1732
|
'Either place it inside an array field, or provide an explicit arrayKey property.');
|
|
1562
1733
|
}
|
|
1563
|
-
// Build base inputs (static, from field definition)
|
|
1564
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1565
1734
|
// Set default eventArgs for AddArrayItemEvent (arrayKey)
|
|
1566
1735
|
// User can override by providing eventArgs in field definition
|
|
1567
1736
|
const defaultEventArgs = ['$arrayKey'];
|
|
1568
1737
|
const eventArgs = 'eventArgs' in fieldDef && fieldDef.eventArgs !== undefined ? fieldDef.eventArgs : defaultEventArgs;
|
|
1569
1738
|
return computed(() => {
|
|
1739
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1570
1740
|
// Read signal value if index is a signal (supports differential updates)
|
|
1571
1741
|
const getIndex = () => {
|
|
1572
1742
|
if (!arrayContext)
|
|
@@ -1605,10 +1775,9 @@ function addArrayItemButtonFieldMapper(fieldDef) {
|
|
|
1605
1775
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1606
1776
|
*/
|
|
1607
1777
|
function removeArrayItemButtonFieldMapper(fieldDef) {
|
|
1608
|
-
// Try to get array context (available when inside an array)
|
|
1609
|
-
// Use optional injection so it doesn't fail when outside an array
|
|
1610
1778
|
const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
|
|
1611
1779
|
const logger = inject(DynamicFormLogger);
|
|
1780
|
+
const defaultProps = inject(DEFAULT_PROPS);
|
|
1612
1781
|
// Determine the target array key
|
|
1613
1782
|
// Priority: explicit arrayKey from fieldDef > arrayKey from context
|
|
1614
1783
|
const targetArrayKey = fieldDef.arrayKey ?? arrayContext?.arrayKey;
|
|
@@ -1616,14 +1785,13 @@ function removeArrayItemButtonFieldMapper(fieldDef) {
|
|
|
1616
1785
|
logger.warn(`removeArrayItem button "${fieldDef.key}" has no array context. ` +
|
|
1617
1786
|
'Either place it inside an array field, or provide an explicit arrayKey property.');
|
|
1618
1787
|
}
|
|
1619
|
-
// Build base inputs (static, from field definition)
|
|
1620
|
-
const baseInputs = buildBaseInputs(fieldDef);
|
|
1621
1788
|
// Set default eventArgs for RemoveArrayItemEvent (arrayKey, index if inside array)
|
|
1622
1789
|
// When outside array, only pass arrayKey (removes last by default)
|
|
1623
1790
|
// User can override by providing eventArgs in field definition
|
|
1624
1791
|
const defaultEventArgs = arrayContext ? ['$arrayKey', '$index'] : ['$arrayKey'];
|
|
1625
1792
|
const eventArgs = 'eventArgs' in fieldDef && fieldDef.eventArgs !== undefined ? fieldDef.eventArgs : defaultEventArgs;
|
|
1626
1793
|
return computed(() => {
|
|
1794
|
+
const baseInputs = buildBaseInputs(fieldDef, defaultProps());
|
|
1627
1795
|
// Read signal value if index is a signal (supports differential updates)
|
|
1628
1796
|
const getIndex = () => {
|
|
1629
1797
|
if (!arrayContext)
|