@ng-forge/dynamic-forms-ionic 1.3.0-next.2 → 1.3.0-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +0 -2
  2. package/fesm2022/ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-bXoq9uY6.mjs +64 -0
  3. package/fesm2022/ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-bXoq9uY6.mjs.map +1 -0
  4. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-button.mjs +129 -34
  5. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-button.mjs.map +1 -1
  6. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-icon.mjs +118 -35
  7. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-icon.mjs.map +1 -1
  8. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-button.mjs +113 -33
  9. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-button.mjs.map +1 -1
  10. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-checkbox.mjs +124 -24
  11. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-checkbox.mjs.map +1 -1
  12. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-datepicker.mjs +374 -90
  13. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-datepicker.mjs.map +1 -1
  14. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-input.mjs +262 -126
  15. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-input.mjs.map +1 -1
  16. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-multi-checkbox.mjs +191 -64
  17. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-multi-checkbox.mjs.map +1 -1
  18. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-radio.mjs +178 -27
  19. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-radio.mjs.map +1 -1
  20. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-select.mjs +163 -27
  21. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-select.mjs.map +1 -1
  22. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-slider.mjs +144 -27
  23. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-slider.mjs.map +1 -1
  24. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-textarea.mjs +157 -45
  25. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-textarea.mjs.map +1 -1
  26. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-toggle.mjs +386 -75
  27. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-toggle.mjs.map +1 -1
  28. package/fesm2022/ng-forge-dynamic-forms-ionic-shared.mjs +139 -62
  29. package/fesm2022/ng-forge-dynamic-forms-ionic-shared.mjs.map +1 -1
  30. package/fesm2022/ng-forge-dynamic-forms-ionic.mjs +238 -251
  31. package/fesm2022/ng-forge-dynamic-forms-ionic.mjs.map +1 -1
  32. package/package.json +2 -3
  33. package/types/ng-forge-dynamic-forms-ionic-lazy-addon-button.d.ts +28 -28
  34. package/types/ng-forge-dynamic-forms-ionic-lazy-addon-icon.d.ts +24 -17
  35. package/types/ng-forge-dynamic-forms-ionic-lazy-button.d.ts +92 -86
  36. package/types/ng-forge-dynamic-forms-ionic-lazy-checkbox.d.ts +24 -18
  37. package/types/ng-forge-dynamic-forms-ionic-lazy-datepicker.d.ts +59 -34
  38. package/types/ng-forge-dynamic-forms-ionic-lazy-input.d.ts +69 -57
  39. package/types/ng-forge-dynamic-forms-ionic-lazy-multi-checkbox.d.ts +34 -23
  40. package/types/ng-forge-dynamic-forms-ionic-lazy-radio.d.ts +31 -20
  41. package/types/ng-forge-dynamic-forms-ionic-lazy-select.d.ts +37 -26
  42. package/types/ng-forge-dynamic-forms-ionic-lazy-slider.d.ts +53 -38
  43. package/types/ng-forge-dynamic-forms-ionic-lazy-textarea.d.ts +29 -23
  44. package/types/ng-forge-dynamic-forms-ionic-lazy-toggle.d.ts +119 -55
  45. package/types/ng-forge-dynamic-forms-ionic-shared.d.ts +78 -83
  46. package/types/ng-forge-dynamic-forms-ionic.d.ts +243 -266
  47. package/fesm2022/ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-CN0CagvT.mjs +0 -26
  48. package/fesm2022/ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-CN0CagvT.mjs.map +0 -1
@@ -1,93 +1,100 @@
1
- import { AsyncPipe } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { inject, ElementRef, input, computed, DestroyRef, signal, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
4
- import { FormField } from '@angular/forms/signals';
5
- import { IonInput, IonNote } from '@ionic/angular/standalone';
6
- import { DynamicFormLogger } from '@ng-forge/dynamic-forms';
7
- import * as i1 from '@ng-forge/dynamic-forms/integration';
8
- import { injectNgForgeField, injectNgForgeAddons, NgForgeControl, DfAddonSlot, DynamicTextPipe, ADDON_PRESET_HANDLER, FIELD_SIGNAL_CONTEXT, NgForgeFieldHost, NgForgeAddons } from '@ng-forge/dynamic-forms/integration';
9
- import { explicitEffect } from 'ngxtension/explicit-effect';
10
- import { IONIC_CONFIG, IONIC_INPUT_TYPE_OVERRIDE, IonicInlineButtonAddonComponent, runIonicPresetAction } from '@ng-forge/dynamic-forms-ionic/shared';
11
-
12
- class IonicInputFieldComponent {
13
- elementRef = inject((ElementRef));
14
- ionicConfig = inject(IONIC_CONFIG, { optional: true });
15
- ngf = injectNgForgeField();
16
- ngfa = injectNgForgeAddons();
17
- props = input(/* @ts-ignore */
18
- ...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
19
- fieldInputs = input(/* @ts-ignore */
20
- ...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
21
- typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
22
- fill = computed(() => this.props()?.fill ?? this.ionicConfig?.fill ?? 'solid', /* @ts-ignore */
23
- ...(ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []));
24
- shape = computed(() => this.props()?.shape ?? this.ionicConfig?.shape, /* @ts-ignore */
25
- ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
26
- labelPlacement = computed(() => this.props()?.labelPlacement ?? this.ionicConfig?.labelPlacement ?? 'stacked', /* @ts-ignore */
27
- ...(ngDevMode ? [{ debugName: "labelPlacement" }] : /* istanbul ignore next */ []));
28
- color = computed(() => this.props()?.color ?? this.ionicConfig?.color, /* @ts-ignore */
29
- ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
30
- type = computed(() => this.typeOverride() ?? this.props()?.type ?? 'text', /* @ts-ignore */
31
- ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
32
- buttonPrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type === 'ion-button'), /* @ts-ignore */
33
- ...(ngDevMode ? [{ debugName: "buttonPrefixAddons" }] : /* istanbul ignore next */ []));
34
- buttonSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type === 'ion-button'), /* @ts-ignore */
35
- ...(ngDevMode ? [{ debugName: "buttonSuffixAddons" }] : /* istanbul ignore next */ []));
36
- decorativePrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type !== 'ion-button'), /* @ts-ignore */
37
- ...(ngDevMode ? [{ debugName: "decorativePrefixAddons" }] : /* istanbul ignore next */ []));
38
- decorativeSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type !== 'ion-button'), /* @ts-ignore */
39
- ...(ngDevMode ? [{ debugName: "decorativeSuffixAddons" }] : /* istanbul ignore next */ []));
40
- destroyed = false;
41
- constructor() {
42
- inject(DestroyRef).onDestroy(() => (this.destroyed = true));
43
- explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {
44
- queueMicrotask(() => {
45
- if (this.destroyed)
46
- return;
47
- const ionInput = this.elementRef.nativeElement.querySelector('ion-input');
48
- if (ionInput?.getInputElement) {
49
- ionInput.getInputElement().then((inputEl) => {
50
- if (this.destroyed || !inputEl)
51
- return;
52
- if (describedBy) {
53
- inputEl.setAttribute('aria-describedby', describedBy);
54
- }
55
- else {
56
- inputEl.removeAttribute('aria-describedby');
57
- }
58
- });
59
- }
60
- });
61
- });
62
- }
63
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
64
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: IonicInputFieldComponent, isStandalone: true, selector: "df-ion-input", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, fieldInputs: { classPropertyName: "fieldInputs", publicName: "fieldInputs", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
65
- {
66
- provide: IONIC_INPUT_TYPE_OVERRIDE,
67
- useFactory: () => signal(undefined),
68
- },
69
- {
70
- provide: ADDON_PRESET_HANDLER,
71
- useFactory: () => {
72
- const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
73
- const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
74
- const logger = inject(DynamicFormLogger);
75
- const host = inject(forwardRef(() => IonicInputFieldComponent));
76
- return {
77
- run: (preset, ctx) => {
78
- const fieldKey = ctx.field.key;
79
- return runIonicPresetAction(preset, ctx, {
80
- typeOverride,
81
- fieldValueSetter: ctx.setValue,
82
- fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : undefined,
83
- baselineType: () => host.props()?.type,
84
- logger,
85
- });
86
- },
87
- };
88
- },
89
- },
90
- ], hostDirectives: [{ directive: i1.NgForgeFieldHost }, { directive: i1.NgForgeAddons }], ngImport: i0, template: `
1
+ import { AsyncPipe } from "@angular/common";
2
+ import * as i0 from "@angular/core";
3
+ import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, computed, forwardRef, inject, input, signal } from "@angular/core";
4
+ import { FormField } from "@angular/forms/signals";
5
+ import { IonInput, IonNote } from "@ionic/angular/standalone";
6
+ import { DynamicFormLogger } from "@ng-forge/dynamic-forms";
7
+ import * as i1 from "@ng-forge/dynamic-forms/integration";
8
+ import { ADDON_PRESET_HANDLER, DfAddonSlot, DynamicTextPipe, FIELD_SIGNAL_CONTEXT, NgForgeAddons, NgForgeControl, NgForgeFieldHost, injectNgForgeAddons, injectNgForgeField } from "@ng-forge/dynamic-forms/integration";
9
+ import { explicitEffect } from "ngxtension/explicit-effect";
10
+ import { IONIC_CONFIG, IONIC_INPUT_TYPE_OVERRIDE, IonicInlineButtonAddonComponent, runIonicPresetAction } from "@ng-forge/dynamic-forms-ionic/shared";
11
+ var IonicInputFieldComponent = class IonicInputFieldComponent {
12
+ elementRef = inject(ElementRef);
13
+ ionicConfig = inject(IONIC_CONFIG, { optional: true });
14
+ ngf = injectNgForgeField();
15
+ ngfa = injectNgForgeAddons();
16
+ props = input(...ngDevMode ? [void 0, { debugName: "props" }] : /* istanbul ignore next */ []);
17
+ fieldInputs = input(...ngDevMode ? [void 0, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []);
18
+ typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
19
+ fill = computed(() => this.props()?.fill ?? this.ionicConfig?.fill ?? "solid", ...ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []);
20
+ shape = computed(() => this.props()?.shape ?? this.ionicConfig?.shape, ...ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []);
21
+ labelPlacement = computed(() => this.props()?.labelPlacement ?? this.ionicConfig?.labelPlacement ?? "stacked", ...ngDevMode ? [{ debugName: "labelPlacement" }] : /* istanbul ignore next */ []);
22
+ color = computed(() => this.props()?.color ?? this.ionicConfig?.color, ...ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []);
23
+ type = computed(() => this.typeOverride() ?? this.props()?.type ?? "text", ...ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []);
24
+ buttonPrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type === "ion-button"), ...ngDevMode ? [{ debugName: "buttonPrefixAddons" }] : /* istanbul ignore next */ []);
25
+ buttonSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type === "ion-button"), ...ngDevMode ? [{ debugName: "buttonSuffixAddons" }] : /* istanbul ignore next */ []);
26
+ decorativePrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type !== "ion-button"), ...ngDevMode ? [{ debugName: "decorativePrefixAddons" }] : /* istanbul ignore next */ []);
27
+ decorativeSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type !== "ion-button"), ...ngDevMode ? [{ debugName: "decorativeSuffixAddons" }] : /* istanbul ignore next */ []);
28
+ destroyed = false;
29
+ constructor() {
30
+ inject(DestroyRef).onDestroy(() => this.destroyed = true);
31
+ explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {
32
+ queueMicrotask(() => {
33
+ if (this.destroyed) return;
34
+ const ionInput = this.elementRef.nativeElement.querySelector("ion-input");
35
+ if (ionInput?.getInputElement) ionInput.getInputElement().then((inputEl) => {
36
+ if (this.destroyed || !inputEl) return;
37
+ if (describedBy) inputEl.setAttribute("aria-describedby", describedBy);
38
+ else inputEl.removeAttribute("aria-describedby");
39
+ });
40
+ });
41
+ });
42
+ }
43
+ static ɵfac = i0.ɵɵngDeclareFactory({
44
+ minVersion: "12.0.0",
45
+ version: "22.2.5",
46
+ ngImport: i0,
47
+ type: IonicInputFieldComponent,
48
+ deps: [],
49
+ target: i0.ɵɵFactoryTarget.Component
50
+ });
51
+ static ɵcmp = i0.ɵɵngDeclareComponent({
52
+ minVersion: "17.0.0",
53
+ version: "22.2.5",
54
+ type: IonicInputFieldComponent,
55
+ isStandalone: true,
56
+ selector: "df-ion-input",
57
+ inputs: {
58
+ props: {
59
+ classPropertyName: "props",
60
+ publicName: "props",
61
+ isSignal: true,
62
+ isRequired: false,
63
+ transformFunction: null
64
+ },
65
+ fieldInputs: {
66
+ classPropertyName: "fieldInputs",
67
+ publicName: "fieldInputs",
68
+ isSignal: true,
69
+ isRequired: false,
70
+ transformFunction: null
71
+ }
72
+ },
73
+ providers: [{
74
+ provide: IONIC_INPUT_TYPE_OVERRIDE,
75
+ useFactory: () => signal(void 0)
76
+ }, {
77
+ provide: ADDON_PRESET_HANDLER,
78
+ useFactory: () => {
79
+ const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
80
+ const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
81
+ const logger = inject(DynamicFormLogger);
82
+ const host = inject(forwardRef(() => IonicInputFieldComponent));
83
+ return { run: (preset, ctx) => {
84
+ const fieldKey = ctx.field.key;
85
+ return runIonicPresetAction(preset, ctx, {
86
+ typeOverride,
87
+ fieldValueSetter: ctx.setValue,
88
+ fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : void 0,
89
+ baselineType: () => host.props()?.type,
90
+ logger
91
+ });
92
+ } };
93
+ }
94
+ }],
95
+ hostDirectives: [{ directive: i1.NgForgeFieldHost }, { directive: i1.NgForgeAddons }],
96
+ ngImport: i0,
97
+ template: `
91
98
  @let f = ngf.field();
92
99
  @let inputId = ngf.key() + '-input';
93
100
 
@@ -130,11 +137,122 @@ class IonicInputFieldComponent {
130
137
  @if (ngf.errorsToDisplay()[0]; as error) {
131
138
  <ion-note color="danger" class="df-ion-error" [id]="ngf.errorId()" role="alert">{{ error.message }}</ion-note>
132
139
  }
133
- `, isInline: true, styles: [".df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-ion-hint{display:block;color:var(--df-hint-color, var(--ion-color-medium, #92949c));font-size:var(--df-hint-font-size, .875rem)}.df-ion-error{display:block;color:var(--df-error-color, var(--ion-color-danger, #eb445a));font-size:var(--df-error-font-size, .875rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}:host{--df-ion-addon-prefix-outer-padding: 0;--df-ion-addon-prefix-inner-padding: .5rem;--df-ion-addon-suffix-inner-padding: .5rem;--df-ion-addon-suffix-outer-padding: 0}:host ::ng-deep ion-input [slot=start],:host ::ng-deep ion-input [slot=end]{display:inline-flex;align-items:center;align-self:center;line-height:1}:host ::ng-deep ion-input [slot=start] df-addon-slot,:host ::ng-deep ion-input [slot=end] df-addon-slot,:host ::ng-deep ion-input [slot=start] df-ion-icon-addon,:host ::ng-deep ion-input [slot=end] df-ion-icon-addon{display:inline-flex;align-items:center;line-height:1}:host ::ng-deep ion-input [slot=start]{padding-inline-start:var(--df-ion-addon-prefix-outer-padding);padding-inline-end:var(--df-ion-addon-prefix-inner-padding)}:host ::ng-deep ion-input [slot=end]{padding-inline-start:var(--df-ion-addon-suffix-inner-padding);padding-inline-end:var(--df-ion-addon-suffix-outer-padding)}:host ::ng-deep ion-input ion-icon{color:inherit}\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"], exportAs: ["formField"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "component", type: DfAddonSlot, selector: "df-addon-slot", inputs: ["addon", "fieldInputs", "hidden"] }, { kind: "component", type: IonicInlineButtonAddonComponent, selector: "ion-button[df-ion-button-addon]" }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
134
- }
135
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicInputFieldComponent, decorators: [{
136
- type: Component,
137
- args: [{ selector: 'df-ion-input', imports: [IonInput, IonNote, FormField, DynamicTextPipe, AsyncPipe, NgForgeControl, DfAddonSlot, IonicInlineButtonAddonComponent], hostDirectives: [NgForgeFieldHost, NgForgeAddons], template: `
140
+ `,
141
+ isInline: true,
142
+ styles: [".df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-ion-hint{display:block;color:var(--df-hint-color, var(--ion-color-medium, #92949c));font-size:var(--df-hint-font-size, .875rem)}.df-ion-error{display:block;color:var(--df-error-color, var(--ion-color-danger, #eb445a));font-size:var(--df-error-font-size, .875rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}:host{--df-ion-addon-prefix-outer-padding: 0;--df-ion-addon-prefix-inner-padding: .5rem;--df-ion-addon-suffix-inner-padding: .5rem;--df-ion-addon-suffix-outer-padding: 0}:host ::ng-deep ion-input [slot=start],:host ::ng-deep ion-input [slot=end]{display:inline-flex;align-items:center;align-self:center;line-height:1}:host ::ng-deep ion-input [slot=start] df-addon-slot,:host ::ng-deep ion-input [slot=end] df-addon-slot,:host ::ng-deep ion-input [slot=start] df-ion-icon-addon,:host ::ng-deep ion-input [slot=end] df-ion-icon-addon{display:inline-flex;align-items:center;line-height:1}:host ::ng-deep ion-input [slot=start]{padding-inline-start:var(--df-ion-addon-prefix-outer-padding);padding-inline-end:var(--df-ion-addon-prefix-inner-padding)}:host ::ng-deep ion-input [slot=end]{padding-inline-start:var(--df-ion-addon-suffix-inner-padding);padding-inline-end:var(--df-ion-addon-suffix-outer-padding)}:host ::ng-deep ion-input ion-icon{color:inherit}\n"],
143
+ dependencies: [
144
+ {
145
+ kind: "component",
146
+ type: IonInput,
147
+ selector: "ion-input",
148
+ inputs: [
149
+ "accept",
150
+ "autocapitalize",
151
+ "autocomplete",
152
+ "autocorrect",
153
+ "autofocus",
154
+ "clearInput",
155
+ "clearOnEdit",
156
+ "color",
157
+ "counter",
158
+ "counterFormatter",
159
+ "debounce",
160
+ "disabled",
161
+ "enterkeyhint",
162
+ "errorText",
163
+ "fill",
164
+ "helperText",
165
+ "inputmode",
166
+ "label",
167
+ "labelPlacement",
168
+ "max",
169
+ "maxlength",
170
+ "min",
171
+ "minlength",
172
+ "mode",
173
+ "multiple",
174
+ "name",
175
+ "pattern",
176
+ "placeholder",
177
+ "readonly",
178
+ "required",
179
+ "shape",
180
+ "size",
181
+ "spellcheck",
182
+ "step",
183
+ "type",
184
+ "value"
185
+ ]
186
+ },
187
+ {
188
+ kind: "component",
189
+ type: IonNote,
190
+ selector: "ion-note",
191
+ inputs: ["color", "mode"]
192
+ },
193
+ {
194
+ kind: "directive",
195
+ type: FormField,
196
+ selector: "[formField]",
197
+ inputs: ["formField"],
198
+ exportAs: ["formField"]
199
+ },
200
+ {
201
+ kind: "directive",
202
+ type: NgForgeControl,
203
+ selector: "[ngForgeControl]",
204
+ inputs: ["ngForgeControl"]
205
+ },
206
+ {
207
+ kind: "component",
208
+ type: DfAddonSlot,
209
+ selector: "df-addon-slot",
210
+ inputs: [
211
+ "addon",
212
+ "fieldInputs",
213
+ "hidden"
214
+ ]
215
+ },
216
+ {
217
+ kind: "component",
218
+ type: IonicInlineButtonAddonComponent,
219
+ selector: "ion-button[df-ion-button-addon]"
220
+ },
221
+ {
222
+ kind: "pipe",
223
+ type: DynamicTextPipe,
224
+ name: "dynamicText"
225
+ },
226
+ {
227
+ kind: "pipe",
228
+ type: AsyncPipe,
229
+ name: "async"
230
+ }
231
+ ],
232
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
233
+ });
234
+ };
235
+ i0.ɵɵngDeclareClassMetadata({
236
+ minVersion: "12.0.0",
237
+ version: "22.2.5",
238
+ ngImport: i0,
239
+ type: IonicInputFieldComponent,
240
+ decorators: [{
241
+ type: Component,
242
+ args: [{
243
+ selector: "df-ion-input",
244
+ imports: [
245
+ IonInput,
246
+ IonNote,
247
+ FormField,
248
+ DynamicTextPipe,
249
+ AsyncPipe,
250
+ NgForgeControl,
251
+ DfAddonSlot,
252
+ IonicInlineButtonAddonComponent
253
+ ],
254
+ hostDirectives: [NgForgeFieldHost, NgForgeAddons],
255
+ template: `
138
256
  @let f = ngf.field();
139
257
  @let inputId = ngf.key() + '-input';
140
258
 
@@ -177,35 +295,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
177
295
  @if (ngf.errorsToDisplay()[0]; as error) {
178
296
  <ion-note color="danger" class="df-ion-error" [id]="ngf.errorId()" role="alert">{{ error.message }}</ion-note>
179
297
  }
180
- `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
181
- {
182
- provide: IONIC_INPUT_TYPE_OVERRIDE,
183
- useFactory: () => signal(undefined),
184
- },
185
- {
186
- provide: ADDON_PRESET_HANDLER,
187
- useFactory: () => {
188
- const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
189
- const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
190
- const logger = inject(DynamicFormLogger);
191
- const host = inject(forwardRef(() => IonicInputFieldComponent));
192
- return {
193
- run: (preset, ctx) => {
194
- const fieldKey = ctx.field.key;
195
- return runIonicPresetAction(preset, ctx, {
196
- typeOverride,
197
- fieldValueSetter: ctx.setValue,
198
- fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : undefined,
199
- baselineType: () => host.props()?.type,
200
- logger,
201
- });
202
- },
203
- };
204
- },
205
- },
206
- ], styles: [".df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-ion-hint{display:block;color:var(--df-hint-color, var(--ion-color-medium, #92949c));font-size:var(--df-hint-font-size, .875rem)}.df-ion-error{display:block;color:var(--df-error-color, var(--ion-color-danger, #eb445a));font-size:var(--df-error-font-size, .875rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}:host{--df-ion-addon-prefix-outer-padding: 0;--df-ion-addon-prefix-inner-padding: .5rem;--df-ion-addon-suffix-inner-padding: .5rem;--df-ion-addon-suffix-outer-padding: 0}:host ::ng-deep ion-input [slot=start],:host ::ng-deep ion-input [slot=end]{display:inline-flex;align-items:center;align-self:center;line-height:1}:host ::ng-deep ion-input [slot=start] df-addon-slot,:host ::ng-deep ion-input [slot=end] df-addon-slot,:host ::ng-deep ion-input [slot=start] df-ion-icon-addon,:host ::ng-deep ion-input [slot=end] df-ion-icon-addon{display:inline-flex;align-items:center;line-height:1}:host ::ng-deep ion-input [slot=start]{padding-inline-start:var(--df-ion-addon-prefix-outer-padding);padding-inline-end:var(--df-ion-addon-prefix-inner-padding)}:host ::ng-deep ion-input [slot=end]{padding-inline-start:var(--df-ion-addon-suffix-inner-padding);padding-inline-end:var(--df-ion-addon-suffix-outer-padding)}:host ::ng-deep ion-input ion-icon{color:inherit}\n"] }]
207
- }], ctorParameters: () => [], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
208
-
209
-
298
+ `,
299
+ changeDetection: ChangeDetectionStrategy.OnPush,
300
+ providers: [{
301
+ provide: IONIC_INPUT_TYPE_OVERRIDE,
302
+ useFactory: () => signal(void 0)
303
+ }, {
304
+ provide: ADDON_PRESET_HANDLER,
305
+ useFactory: () => {
306
+ const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
307
+ const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
308
+ const logger = inject(DynamicFormLogger);
309
+ const host = inject(forwardRef(() => IonicInputFieldComponent));
310
+ return { run: (preset, ctx) => {
311
+ const fieldKey = ctx.field.key;
312
+ return runIonicPresetAction(preset, ctx, {
313
+ typeOverride,
314
+ fieldValueSetter: ctx.setValue,
315
+ fieldDefaultValueGetter: fsc && fieldKey ? () => fsc.defaultValues()?.[fieldKey] : void 0,
316
+ baselineType: () => host.props()?.type,
317
+ logger
318
+ });
319
+ } };
320
+ }
321
+ }],
322
+ styles: [".df-ion-field{display:flex;flex-direction:column;gap:var(--df-field-gap, .5rem);width:100%}.df-ion-label{font-weight:var(--df-label-font-weight, 500);color:var(--df-label-color, inherit)}.df-ion-hint{display:block;color:var(--df-hint-color, var(--ion-color-medium, #92949c));font-size:var(--df-hint-font-size, .875rem)}.df-ion-error{display:block;color:var(--df-error-color, var(--ion-color-danger, #eb445a));font-size:var(--df-error-font-size, .875rem)}:host([hidden]){display:none!important}\n", ":host([hidden]){display:none!important}:host{--df-ion-addon-prefix-outer-padding: 0;--df-ion-addon-prefix-inner-padding: .5rem;--df-ion-addon-suffix-inner-padding: .5rem;--df-ion-addon-suffix-outer-padding: 0}:host ::ng-deep ion-input [slot=start],:host ::ng-deep ion-input [slot=end]{display:inline-flex;align-items:center;align-self:center;line-height:1}:host ::ng-deep ion-input [slot=start] df-addon-slot,:host ::ng-deep ion-input [slot=end] df-addon-slot,:host ::ng-deep ion-input [slot=start] df-ion-icon-addon,:host ::ng-deep ion-input [slot=end] df-ion-icon-addon{display:inline-flex;align-items:center;line-height:1}:host ::ng-deep ion-input [slot=start]{padding-inline-start:var(--df-ion-addon-prefix-outer-padding);padding-inline-end:var(--df-ion-addon-prefix-inner-padding)}:host ::ng-deep ion-input [slot=end]{padding-inline-start:var(--df-ion-addon-suffix-inner-padding);padding-inline-end:var(--df-ion-addon-suffix-outer-padding)}:host ::ng-deep ion-input ion-icon{color:inherit}\n"]
323
+ }]
324
+ }],
325
+ ctorParameters: () => [],
326
+ propDecorators: {
327
+ props: [{
328
+ type: i0.Input,
329
+ args: [{
330
+ isSignal: true,
331
+ alias: "props",
332
+ required: false
333
+ }]
334
+ }],
335
+ fieldInputs: [{
336
+ type: i0.Input,
337
+ args: [{
338
+ isSignal: true,
339
+ alias: "fieldInputs",
340
+ required: false
341
+ }]
342
+ }]
343
+ }
344
+ });
210
345
  export { IonicInputFieldComponent };
211
- //# sourceMappingURL=ng-forge-dynamic-forms-ionic-lazy-input.mjs.map
346
+
347
+ //# sourceMappingURL=ng-forge-dynamic-forms-ionic-lazy-input.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ng-forge-dynamic-forms-ionic-lazy-input.mjs","mappings":";;;;;;;;;;;AAgKc;AACK;;;;AAMR;;AAET,IAKS;;IAGQ;AAEE;;AACA;;IAEA;;AACA;;IAGA;;AAEnB;;;;;;;;;AAaA;AACE;wBAIA;;;;AAGI;AACA;;AAEI;;;AAEE;;;AAEA;;AAEJ;;AAEJ;AACF;;;AA7DiB;AA7EjB;AACE;AACA;AACD;AACD;gFAME;;AAEE;AACA;AACA;oBAEA;;AAEE;AACE;AACA;;;;;;AAOC;;;;AAIR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAnCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIC;AACE;AACA;AACD;AACD;4IAME;;AAEE;AACA;AACA;;;AAIE;AACE;AACA;;;;;;AAOC;;;;AAIR;AACF","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/fields/input/ionic-input.component.ts"],"sourcesContent":["import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, DestroyRef, ElementRef, forwardRef, inject, input, signal } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { IonInput, IonNote } from '@ionic/angular/standalone';\nimport { AddonActionContext, AddonActionPreset, DynamicFormLogger } from '@ng-forge/dynamic-forms';\nimport { DfAddonSlot } from '@ng-forge/dynamic-forms/integration';\nimport { WrapperFieldInputs } from '@ng-forge/dynamic-forms/integration';\nimport { DynamicTextPipe, FIELD_SIGNAL_CONTEXT } from '@ng-forge/dynamic-forms/integration';\nimport {\n ADDON_PRESET_HANDLER,\n AddonPresetHandler,\n injectNgForgeAddons,\n injectNgForgeField,\n NgForgeAddons,\n NgForgeControl,\n NgForgeFieldHost,\n} from '@ng-forge/dynamic-forms/integration';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport {\n IONIC_CONFIG,\n IONIC_INPUT_TYPE_OVERRIDE,\n IonicInlineButtonAddonComponent,\n runIonicPresetAction,\n} from '@ng-forge/dynamic-forms-ionic/shared';\nimport { IonicInputAddon, IonicInputProps } from './ionic-input.type';\n\n// minlength/maxlength bindings: Signal Forms auto-syncs these on NATIVE\n// inputs; <ion-input> is a Stencil web component so we bind directly from\n// FieldState (`f().maxLength?.()` — the signal itself is missing when no\n// validator is configured).\n@Component({\n selector: 'df-ion-input',\n // IonButton intentionally NOT imported — it would collide with\n // IonicInlineButtonAddonComponent on `<ion-button>` (NG0300).\n imports: [IonInput, IonNote, FormField, DynamicTextPipe, AsyncPipe, NgForgeControl, DfAddonSlot, IonicInlineButtonAddonComponent],\n hostDirectives: [NgForgeFieldHost, NgForgeAddons],\n template: `\n @let f = ngf.field();\n @let inputId = ngf.key() + '-input';\n\n <ion-input\n ngForgeControl\n [id]=\"inputId\"\n [type]=\"type()\"\n [formField]=\"f\"\n [label]=\"(ngf.label() | dynamicText | async) ?? undefined\"\n [labelPlacement]=\"labelPlacement()\"\n [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n [clearInput]=\"props()?.clearInput ?? false\"\n [counter]=\"props()?.counter ?? false\"\n [minlength]=\"f().minLength?.()\"\n [maxlength]=\"f().maxLength?.()\"\n [color]=\"color()\"\n [fill]=\"fill()\"\n [shape]=\"shape()\"\n [readonly]=\"f().readonly()\"\n [helperText]=\"ngf.errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined\"\n [attr.tabindex]=\"ngf.tabIndex()\"\n >\n @for (a of decorativePrefixAddons(); track $index) {\n <span slot=\"start\">\n <df-addon-slot [addon]=\"a\" [fieldInputs]=\"fieldInputs()\" [hidden]=\"ngfa.hiddenSignalCache().get(a)\" />\n </span>\n }\n @for (a of buttonPrefixAddons(); track $index) {\n <ion-button df-ion-button-addon slot=\"start\" [addon]=\"a\" [fieldInputs]=\"fieldInputs()\"></ion-button>\n }\n @for (a of buttonSuffixAddons(); track $index) {\n <ion-button df-ion-button-addon slot=\"end\" [addon]=\"a\" [fieldInputs]=\"fieldInputs()\"></ion-button>\n }\n @for (a of decorativeSuffixAddons(); track $index) {\n <span slot=\"end\">\n <df-addon-slot [addon]=\"a\" [fieldInputs]=\"fieldInputs()\" [hidden]=\"ngfa.hiddenSignalCache().get(a)\" />\n </span>\n }\n </ion-input>\n @if (ngf.errorsToDisplay()[0]; as error) {\n <ion-note color=\"danger\" class=\"df-ion-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</ion-note>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: '../../styles/_form-field.scss',\n providers: [\n {\n provide: IONIC_INPUT_TYPE_OVERRIDE,\n useFactory: () => signal<string | undefined>(undefined),\n },\n {\n // Adapter-specific preset semantics for `ion-button` addons (clear /\n // reset / paste / copy / toggle-password-visibility). The directive\n // (`NgForgeAddonAction`) delegates here when an addon configures a\n // `preset`. Per-ion-input-instance so the `typeOverride` signal is\n // scoped to one field.\n provide: ADDON_PRESET_HANDLER,\n useFactory: (): AddonPresetHandler => {\n const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);\n const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });\n const logger = inject(DynamicFormLogger);\n // forwardRef for baselineType only — host.props()?.type gates toggle-password-visibility.\n const host = inject(forwardRef(() => IonicInputFieldComponent));\n return {\n run: (preset: string, ctx: AddonActionContext) => {\n const fieldKey = ctx.field.key;\n return runIonicPresetAction(preset as AddonActionPreset, ctx, {\n typeOverride,\n fieldValueSetter: ctx.setValue,\n fieldDefaultValueGetter:\n fsc && fieldKey ? () => (fsc.defaultValues() as Record<string, unknown> | undefined)?.[fieldKey] : undefined,\n baselineType: () => host.props()?.type,\n logger,\n });\n },\n };\n },\n },\n ],\n styles: [\n `\n :host([hidden]) {\n display: none !important;\n }\n /* Per-side padding knobs on each slot wrapper (independent prefix/suffix). */\n :host {\n --df-ion-addon-prefix-outer-padding: 0;\n --df-ion-addon-prefix-inner-padding: 0.5rem;\n --df-ion-addon-suffix-inner-padding: 0.5rem;\n --df-ion-addon-suffix-outer-padding: 0;\n }\n /* inline-flex on slot wrappers prevents baseline-pinning of decorative addon glyphs. */\n :host ::ng-deep ion-input [slot='start'],\n :host ::ng-deep ion-input [slot='end'] {\n display: inline-flex;\n align-items: center;\n align-self: center;\n line-height: 1;\n }\n :host ::ng-deep ion-input [slot='start'] df-addon-slot,\n :host ::ng-deep ion-input [slot='end'] df-addon-slot,\n :host ::ng-deep ion-input [slot='start'] df-ion-icon-addon,\n :host ::ng-deep ion-input [slot='end'] df-ion-icon-addon {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n }\n :host ::ng-deep ion-input [slot='start'] {\n padding-inline-start: var(--df-ion-addon-prefix-outer-padding);\n padding-inline-end: var(--df-ion-addon-prefix-inner-padding);\n }\n :host ::ng-deep ion-input [slot='end'] {\n padding-inline-start: var(--df-ion-addon-suffix-inner-padding);\n padding-inline-end: var(--df-ion-addon-suffix-outer-padding);\n }\n /* Inherit input text color so icons stay readable on dark themes\n (Ionic's default \"medium\" greys out and fails WCAG on dark inputs). */\n :host ::ng-deep ion-input ion-icon {\n color: inherit;\n }\n `,\n ],\n})\nexport default class IonicInputFieldComponent {\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private ionicConfig = inject(IONIC_CONFIG, { optional: true });\n\n protected readonly ngf = injectNgForgeField<string>();\n protected readonly ngfa = injectNgForgeAddons<IonicInputAddon>();\n\n readonly props = input<IonicInputProps>();\n\n /**\n * Wrapper-style host bag pushed by `DfFieldOutlet`. Declared at the\n * component level so `setInputIfDeclared` (which uses\n * `reflectComponentType`) can write it.\n */\n readonly fieldInputs = input<WrapperFieldInputs | undefined>();\n\n /** Per-instance type override populated by `toggle-password-visibility` preset. */\n private readonly typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);\n\n protected readonly fill = computed(() => this.props()?.fill ?? this.ionicConfig?.fill ?? 'solid');\n protected readonly shape = computed(() => this.props()?.shape ?? this.ionicConfig?.shape);\n /** Bootstrap / PrimeNG. Consumers can opt into Ionic's native inline 'start' */\n protected readonly labelPlacement = computed(() => this.props()?.labelPlacement ?? this.ionicConfig?.labelPlacement ?? 'stacked');\n protected readonly color = computed(() => this.props()?.color ?? this.ionicConfig?.color);\n\n /** Override (set by `toggle-password-visibility` preset) wins over `props().type`. */\n protected readonly type = computed(() => this.typeOverride() ?? this.props()?.type ?? 'text');\n\n /** Per-type split: ion-button addons render inline via the attribute-\n * selector inline component (so the slotted element is a native\n * <ion-button> Ionic can style); everything else (icon/text/template/\n * component types) goes through the universal <df-addon-slot> dispatcher\n * wrapped in <span slot=\"start|end\"> for safe shadow-DOM projection. */\n protected readonly buttonPrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type === 'ion-button'));\n protected readonly buttonSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type === 'ion-button'));\n protected readonly decorativePrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type !== 'ion-button'));\n protected readonly decorativeSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type !== 'ion-button'));\n\n /** Set when the component is destroyed — guards async aria-describedby sync against teardown. */\n private destroyed = false;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => (this.destroyed = true));\n // ion-input encapsulates a native <input> in shadow DOM and does not automatically\n // propagate aria-describedby to it. This effect imperatively syncs the attribute\n // after a microtask to ensure Ionic has resolved the internal element.\n explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {\n queueMicrotask(() => {\n if (this.destroyed) return;\n const ionInput = this.elementRef.nativeElement.querySelector('ion-input') as HTMLIonInputElement | null;\n if (ionInput?.getInputElement) {\n ionInput.getInputElement().then((inputEl) => {\n if (this.destroyed || !inputEl) return;\n if (describedBy) {\n inputEl.setAttribute('aria-describedby', describedBy);\n } else {\n inputEl.removeAttribute('aria-describedby');\n }\n });\n }\n });\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ng-forge-dynamic-forms-ionic-lazy-input.mjs","names":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/fields/input/ionic-input.component.ts"],"sourcesContent":["import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, DestroyRef, ElementRef, forwardRef, inject, input, signal } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { IonInput, IonNote } from '@ionic/angular/standalone';\nimport { AddonActionContext, AddonActionPreset, DynamicFormLogger } from '@ng-forge/dynamic-forms';\nimport { DfAddonSlot } from '@ng-forge/dynamic-forms/integration';\nimport { WrapperFieldInputs } from '@ng-forge/dynamic-forms/integration';\nimport { DynamicTextPipe, FIELD_SIGNAL_CONTEXT } from '@ng-forge/dynamic-forms/integration';\nimport {\n ADDON_PRESET_HANDLER,\n AddonPresetHandler,\n injectNgForgeAddons,\n injectNgForgeField,\n NgForgeAddons,\n NgForgeControl,\n NgForgeFieldHost,\n} from '@ng-forge/dynamic-forms/integration';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport {\n IONIC_CONFIG,\n IONIC_INPUT_TYPE_OVERRIDE,\n IonicInlineButtonAddonComponent,\n runIonicPresetAction,\n} from '@ng-forge/dynamic-forms-ionic/shared';\nimport { IonicInputAddon, IonicInputProps } from './ionic-input.type';\n\n// minlength/maxlength bindings: Signal Forms auto-syncs these on NATIVE\n// inputs; <ion-input> is a Stencil web component so we bind directly from\n// FieldState (`f().maxLength?.()` — the signal itself is missing when no\n// validator is configured).\n@Component({\n selector: 'df-ion-input',\n // IonButton intentionally NOT imported — it would collide with\n // IonicInlineButtonAddonComponent on `<ion-button>` (NG0300).\n imports: [IonInput, IonNote, FormField, DynamicTextPipe, AsyncPipe, NgForgeControl, DfAddonSlot, IonicInlineButtonAddonComponent],\n hostDirectives: [NgForgeFieldHost, NgForgeAddons],\n template: `\n @let f = ngf.field();\n @let inputId = ngf.key() + '-input';\n\n <ion-input\n ngForgeControl\n [id]=\"inputId\"\n [type]=\"type()\"\n [formField]=\"f\"\n [label]=\"(ngf.label() | dynamicText | async) ?? undefined\"\n [labelPlacement]=\"labelPlacement()\"\n [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n [clearInput]=\"props()?.clearInput ?? false\"\n [counter]=\"props()?.counter ?? false\"\n [minlength]=\"f().minLength?.()\"\n [maxlength]=\"f().maxLength?.()\"\n [color]=\"color()\"\n [fill]=\"fill()\"\n [shape]=\"shape()\"\n [readonly]=\"f().readonly()\"\n [helperText]=\"ngf.errorsToDisplay().length === 0 ? ((props()?.hint | dynamicText | async) ?? undefined) : undefined\"\n [attr.tabindex]=\"ngf.tabIndex()\"\n >\n @for (a of decorativePrefixAddons(); track $index) {\n <span slot=\"start\">\n <df-addon-slot [addon]=\"a\" [fieldInputs]=\"fieldInputs()\" [hidden]=\"ngfa.hiddenSignalCache().get(a)\" />\n </span>\n }\n @for (a of buttonPrefixAddons(); track $index) {\n <ion-button df-ion-button-addon slot=\"start\" [addon]=\"a\" [fieldInputs]=\"fieldInputs()\"></ion-button>\n }\n @for (a of buttonSuffixAddons(); track $index) {\n <ion-button df-ion-button-addon slot=\"end\" [addon]=\"a\" [fieldInputs]=\"fieldInputs()\"></ion-button>\n }\n @for (a of decorativeSuffixAddons(); track $index) {\n <span slot=\"end\">\n <df-addon-slot [addon]=\"a\" [fieldInputs]=\"fieldInputs()\" [hidden]=\"ngfa.hiddenSignalCache().get(a)\" />\n </span>\n }\n </ion-input>\n @if (ngf.errorsToDisplay()[0]; as error) {\n <ion-note color=\"danger\" class=\"df-ion-error\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</ion-note>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: '../../styles/_form-field.scss',\n providers: [\n {\n provide: IONIC_INPUT_TYPE_OVERRIDE,\n useFactory: () => signal<string | undefined>(undefined),\n },\n {\n // Adapter-specific preset semantics for `ion-button` addons (clear /\n // reset / paste / copy / toggle-password-visibility). The directive\n // (`NgForgeAddonAction`) delegates here when an addon configures a\n // `preset`. Per-ion-input-instance so the `typeOverride` signal is\n // scoped to one field.\n provide: ADDON_PRESET_HANDLER,\n useFactory: (): AddonPresetHandler => {\n const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);\n const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });\n const logger = inject(DynamicFormLogger);\n // forwardRef for baselineType only — host.props()?.type gates toggle-password-visibility.\n const host = inject(forwardRef(() => IonicInputFieldComponent));\n return {\n run: (preset: string, ctx: AddonActionContext) => {\n const fieldKey = ctx.field.key;\n return runIonicPresetAction(preset as AddonActionPreset, ctx, {\n typeOverride,\n fieldValueSetter: ctx.setValue,\n fieldDefaultValueGetter:\n fsc && fieldKey ? () => (fsc.defaultValues() as Record<string, unknown> | undefined)?.[fieldKey] : undefined,\n baselineType: () => host.props()?.type,\n logger,\n });\n },\n };\n },\n },\n ],\n styles: [\n `\n :host([hidden]) {\n display: none !important;\n }\n /* Per-side padding knobs on each slot wrapper (independent prefix/suffix). */\n :host {\n --df-ion-addon-prefix-outer-padding: 0;\n --df-ion-addon-prefix-inner-padding: 0.5rem;\n --df-ion-addon-suffix-inner-padding: 0.5rem;\n --df-ion-addon-suffix-outer-padding: 0;\n }\n /* inline-flex on slot wrappers prevents baseline-pinning of decorative addon glyphs. */\n :host ::ng-deep ion-input [slot='start'],\n :host ::ng-deep ion-input [slot='end'] {\n display: inline-flex;\n align-items: center;\n align-self: center;\n line-height: 1;\n }\n :host ::ng-deep ion-input [slot='start'] df-addon-slot,\n :host ::ng-deep ion-input [slot='end'] df-addon-slot,\n :host ::ng-deep ion-input [slot='start'] df-ion-icon-addon,\n :host ::ng-deep ion-input [slot='end'] df-ion-icon-addon {\n display: inline-flex;\n align-items: center;\n line-height: 1;\n }\n :host ::ng-deep ion-input [slot='start'] {\n padding-inline-start: var(--df-ion-addon-prefix-outer-padding);\n padding-inline-end: var(--df-ion-addon-prefix-inner-padding);\n }\n :host ::ng-deep ion-input [slot='end'] {\n padding-inline-start: var(--df-ion-addon-suffix-inner-padding);\n padding-inline-end: var(--df-ion-addon-suffix-outer-padding);\n }\n /* Inherit input text color so icons stay readable on dark themes\n (Ionic's default \"medium\" greys out and fails WCAG on dark inputs). */\n :host ::ng-deep ion-input ion-icon {\n color: inherit;\n }\n `,\n ],\n})\nexport default class IonicInputFieldComponent {\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private ionicConfig = inject(IONIC_CONFIG, { optional: true });\n\n protected readonly ngf = injectNgForgeField<string>();\n protected readonly ngfa = injectNgForgeAddons<IonicInputAddon>();\n\n readonly props = input<IonicInputProps>();\n\n /**\n * Wrapper-style host bag pushed by `DfFieldOutlet`. Declared at the\n * component level so `setInputIfDeclared` (which uses\n * `reflectComponentType`) can write it.\n */\n readonly fieldInputs = input<WrapperFieldInputs | undefined>();\n\n /** Per-instance type override populated by `toggle-password-visibility` preset. */\n private readonly typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);\n\n protected readonly fill = computed(() => this.props()?.fill ?? this.ionicConfig?.fill ?? 'solid');\n protected readonly shape = computed(() => this.props()?.shape ?? this.ionicConfig?.shape);\n /** Bootstrap / PrimeNG. Consumers can opt into Ionic's native inline 'start' */\n protected readonly labelPlacement = computed(() => this.props()?.labelPlacement ?? this.ionicConfig?.labelPlacement ?? 'stacked');\n protected readonly color = computed(() => this.props()?.color ?? this.ionicConfig?.color);\n\n /** Override (set by `toggle-password-visibility` preset) wins over `props().type`. */\n protected readonly type = computed(() => this.typeOverride() ?? this.props()?.type ?? 'text');\n\n /** Per-type split: ion-button addons render inline via the attribute-\n * selector inline component (so the slotted element is a native\n * <ion-button> Ionic can style); everything else (icon/text/template/\n * component types) goes through the universal <df-addon-slot> dispatcher\n * wrapped in <span slot=\"start|end\"> for safe shadow-DOM projection. */\n protected readonly buttonPrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type === 'ion-button'));\n protected readonly buttonSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type === 'ion-button'));\n protected readonly decorativePrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.type !== 'ion-button'));\n protected readonly decorativeSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.type !== 'ion-button'));\n\n /** Set when the component is destroyed — guards async aria-describedby sync against teardown. */\n private destroyed = false;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => (this.destroyed = true));\n // ion-input encapsulates a native <input> in shadow DOM and does not automatically\n // propagate aria-describedby to it. This effect imperatively syncs the attribute\n // after a microtask to ensure Ionic has resolved the internal element.\n explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {\n queueMicrotask(() => {\n if (this.destroyed) return;\n const ionInput = this.elementRef.nativeElement.querySelector('ion-input') as HTMLIonInputElement | null;\n if (ionInput?.getInputElement) {\n ionInput.getInputElement().then((inputEl) => {\n if (this.destroyed || !inputEl) return;\n if (describedBy) {\n inputEl.setAttribute('aria-describedby', describedBy);\n } else {\n inputEl.removeAttribute('aria-describedby');\n }\n });\n }\n });\n });\n }\n}\n"],"mappings":"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"}