@ng-forge/dynamic-forms-ionic 0.9.0-next.8 → 0.9.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,9 +1,10 @@
1
- import { FormEvent, NextPageEvent, PreviousPageEvent, AppendArrayItemEvent, ArrayAllowedChildren, PrependArrayItemEvent, InsertArrayItemEvent, RemoveAtIndexEvent, PopArrayItemEvent, ShiftArrayItemEvent, FieldComponent, DynamicText, FormEventConstructor, ArrayItemContext, CheckedFieldComponent, FieldMeta, ValidationMessages, ValueFieldComponent, ValueType, FieldOption, FieldTypeDefinition, NarrowFields, RegisteredFieldTypes, InferFormValue, FormConfig } from '@ng-forge/dynamic-forms';
2
- import * as _ng_forge_dynamic_forms_integration from '@ng-forge/dynamic-forms/integration';
3
- import { ButtonField, EventArgs, CheckboxField, DatepickerField, DatepickerProps, InputMeta, InputField, InputProps, MultiCheckboxField, RadioField, SelectField, SelectProps, SliderField, TextareaField, TextareaProps, TextareaMeta, ToggleField } from '@ng-forge/dynamic-forms/integration';
1
+ import * as _ng_forge_dynamic_forms from '@ng-forge/dynamic-forms';
2
+ import { FormEvent, NextPageEvent, PreviousPageEvent, AppendArrayItemEvent, ArrayAllowedChildren, PrependArrayItemEvent, InsertArrayItemEvent, RemoveAtIndexEvent, PopArrayItemEvent, ShiftArrayItemEvent, DynamicText, CheckedFieldComponent, ValueFieldComponent, BaseAddon, DynamicValue, AddonActionPreset, RegisteredActionRef, AddonActionHandler, TextAddon, TemplateAddon, WrapperFieldInputs, ValueType, FieldOption, FieldTypeDefinition, NarrowFields, RegisteredFieldTypes, InferFormValue, FormConfig } from '@ng-forge/dynamic-forms';
3
+ import * as i1 from '@ng-forge/dynamic-forms/integration';
4
+ import { ButtonField, CheckboxField, DatepickerField, DatepickerProps, InputField, InputProps, MultiCheckboxField, RadioField, SelectField, SelectProps, SliderField, TextareaField, TextareaProps, ToggleField } from '@ng-forge/dynamic-forms/integration';
4
5
  import * as _angular_core from '@angular/core';
5
- import { InjectionToken, Provider } from '@angular/core';
6
- import { FieldTree } from '@angular/forms/signals';
6
+ import { InjectionToken, Provider, WritableSignal } from '@angular/core';
7
+ import * as _ng_forge_dynamic_forms_ionic from '@ng-forge/dynamic-forms-ionic';
7
8
 
8
9
  interface IonicButtonProps {
9
10
  expand?: 'full' | 'block';
@@ -15,7 +16,6 @@ interface IonicButtonProps {
15
16
  type?: 'button' | 'submit' | 'reset';
16
17
  }
17
18
  type IonicButtonField<TEvent extends FormEvent> = ButtonField<IonicButtonProps, TEvent>;
18
- type IonicButtonComponent<TEvent extends FormEvent> = FieldComponent<IonicButtonField<TEvent>>;
19
19
  /**
20
20
  * Specific button field types with preconfigured events
21
21
  */
@@ -112,32 +112,14 @@ type ShiftArrayItemButtonField = Omit<IonicButtonField<ShiftArrayItemEvent>, 'ev
112
112
  arrayKey: string;
113
113
  };
114
114
 
115
- declare class IonicButtonFieldComponent<TEvent extends FormEvent> implements IonicButtonComponent<TEvent> {
116
- private readonly eventBus;
117
- private readonly arrayContext;
118
- readonly key: _angular_core.InputSignal<string>;
119
- readonly label: _angular_core.InputSignal<DynamicText>;
120
- readonly disabled: _angular_core.InputSignal<boolean>;
121
- readonly hidden: _angular_core.InputSignal<boolean>;
122
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
123
- readonly className: _angular_core.InputSignal<string>;
124
- /** Event to dispatch on click. Optional for submit buttons (native form submit handles it). */
125
- readonly event: _angular_core.InputSignal<FormEventConstructor<TEvent> | undefined>;
126
- readonly eventArgs: _angular_core.InputSignal<EventArgs | undefined>;
115
+ declare class IonicButtonFieldComponent<TEvent extends FormEvent> {
116
+ protected readonly action: i1.NgForgeAction<TEvent>;
127
117
  readonly props: _angular_core.InputSignal<IonicButtonProps | undefined>;
128
- readonly eventContext: _angular_core.InputSignal<ArrayItemContext | undefined>;
129
- /** Resolved button type - defaults to 'button' if not specified in props */
130
118
  readonly buttonType: _angular_core.Signal<"button" | "submit" | "reset">;
131
119
  readonly buttonTestId: _angular_core.Signal<string>;
132
- /**
133
- * Handle button click.
134
- * - For submit buttons (type="submit"): do nothing, native form submit handles it
135
- * - For other buttons: dispatch the configured event via EventBus
136
- */
137
120
  onClick(): void;
138
- private dispatchEvent;
139
121
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicButtonFieldComponent<any>, never>;
140
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicButtonFieldComponent<any>, "df-ion-button", never, { "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hidden": { "alias": "hidden"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "event": { "alias": "event"; "required": false; "isSignal": true; }; "eventArgs": { "alias": "eventArgs"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "eventContext": { "alias": "eventContext"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
122
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicButtonFieldComponent<any>, "df-ion-button", never, { "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeActionHost; inputs: {}; outputs: {}; }]>;
141
123
  }
142
124
 
143
125
  interface IonicCheckboxProps {
@@ -148,36 +130,14 @@ interface IonicCheckboxProps {
148
130
  hint?: DynamicText;
149
131
  }
150
132
  type IonicCheckboxField = CheckboxField<IonicCheckboxProps>;
133
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
151
134
  type IonicCheckboxComponent = CheckedFieldComponent<IonicCheckboxField>;
152
135
 
153
- declare class IonicCheckboxFieldComponent implements IonicCheckboxComponent {
154
- private readonly elementRef;
155
- readonly field: _angular_core.InputSignal<FieldTree<boolean>>;
156
- readonly key: _angular_core.InputSignal<string>;
157
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
158
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
159
- readonly className: _angular_core.InputSignal<string>;
160
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
136
+ declare class IonicCheckboxFieldComponent {
137
+ protected readonly ngf: i1.TypedNgForgeField<boolean>;
161
138
  readonly props: _angular_core.InputSignal<IonicCheckboxProps | undefined>;
162
- readonly meta: _angular_core.InputSignal<FieldMeta | undefined>;
163
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
164
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
165
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
166
- readonly showErrors: _angular_core.Signal<boolean>;
167
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
168
- constructor();
169
- /** Base ID for error elements */
170
- protected readonly errorId: _angular_core.Signal<string>;
171
- /** Unique ID for the helper text element */
172
- protected readonly hintId: _angular_core.Signal<string>;
173
- /** Whether the field is currently in an invalid state (invalid AND touched) */
174
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
175
- /** Whether the field has a required validator */
176
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
177
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
178
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
179
139
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicCheckboxFieldComponent, never>;
180
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicCheckboxFieldComponent, "df-ion-checkbox", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
140
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicCheckboxFieldComponent, "df-ion-checkbox", never, { "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }]>;
181
141
  }
182
142
 
183
143
  interface IonicDatepickerProps extends DatepickerProps {
@@ -195,45 +155,162 @@ interface IonicDatepickerProps extends DatepickerProps {
195
155
  hint?: DynamicText;
196
156
  }
197
157
  type IonicDatepickerField = DatepickerField<IonicDatepickerProps>;
158
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
198
159
  type IonicDatepickerComponent = ValueFieldComponent<IonicDatepickerField>;
199
160
 
200
- declare class IonicDatepickerFieldComponent implements IonicDatepickerComponent {
201
- private readonly elementRef;
202
- readonly field: _angular_core.InputSignal<FieldTree<Date | null>>;
203
- readonly key: _angular_core.InputSignal<string>;
204
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
205
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
206
- readonly className: _angular_core.InputSignal<string>;
207
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
161
+ declare class IonicDatepickerFieldComponent {
162
+ protected readonly ngf: i1.TypedNgForgeField<Date | null>;
208
163
  readonly minDate: _angular_core.InputSignal<Date | null>;
209
164
  readonly maxDate: _angular_core.InputSignal<Date | null>;
210
165
  readonly startAt: _angular_core.InputSignal<Date | null>;
211
166
  readonly props: _angular_core.InputSignal<IonicDatepickerProps | undefined>;
212
- readonly meta: _angular_core.InputSignal<InputMeta | undefined>;
213
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
214
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
215
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
216
- readonly showErrors: _angular_core.Signal<boolean>;
217
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
218
167
  readonly isModalOpen: _angular_core.WritableSignal<boolean>;
219
- constructor();
220
- /** Base ID for error elements */
221
- protected readonly errorId: _angular_core.Signal<string>;
222
- /** Unique ID for the helper text element */
223
- protected readonly hintId: _angular_core.Signal<string>;
224
- /** Whether the field is currently in an invalid state (invalid AND touched) */
225
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
226
- /** Whether the field has a required validator */
227
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
228
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
229
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
230
168
  openModal(): void;
231
169
  closeModal(): void;
232
170
  onDateChange(event: CustomEvent): void;
233
171
  dateToIsoString(date: Date | null | undefined): string | undefined;
234
172
  formatDisplayDate(date: Date | null | undefined): string;
235
173
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicDatepickerFieldComponent, never>;
236
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicDatepickerFieldComponent, "df-ion-datepicker", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "startAt": { "alias": "startAt"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
174
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicDatepickerFieldComponent, "df-ion-datepicker", never, { "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "startAt": { "alias": "startAt"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }]>;
175
+ }
176
+
177
+ /**
178
+ * Decorative icon addon for Ion fields.
179
+ *
180
+ * Renders `<ion-icon name="{icon}">` (Ionons). The `icon` string is the
181
+ * Ionons name — e.g., `'search-outline'` produces
182
+ * `<ion-icon name="search-outline">`.
183
+ *
184
+ * Add `ariaLabel` for icons that convey meaning; leave it omitted for
185
+ * purely decorative icons (will be `aria-hidden="true"`).
186
+ */
187
+ interface IonIconAddon extends BaseAddon {
188
+ readonly kind: 'ion-icon';
189
+ /** Ionons name (e.g., `'search-outline'`, `'close-outline'`). */
190
+ readonly icon: string;
191
+ /** Accessible label for icons that convey meaning. */
192
+ readonly ariaLabel?: DynamicText;
193
+ }
194
+ /**
195
+ * Ionic-supported button colour palette.
196
+ */
197
+ type IonButtonColor = 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'danger' | 'light' | 'medium' | 'dark';
198
+ /**
199
+ * Ionic-supported button fill variants.
200
+ */
201
+ type IonButtonFill = 'clear' | 'outline' | 'solid' | 'default';
202
+ /**
203
+ * Common shape of every `ion-button` addon — properties that don't
204
+ * participate in either XOR axis.
205
+ */
206
+ interface IonButtonBase extends BaseAddon {
207
+ readonly kind: 'ion-button';
208
+ /** Ion button colour. */
209
+ readonly color?: IonButtonColor;
210
+ /** Ion button fill style. */
211
+ readonly fill?: IonButtonFill;
212
+ /** Reactive loading state — renders an `<ion-spinner>` when truthy. */
213
+ readonly loading?: DynamicValue<boolean>;
214
+ }
215
+ /**
216
+ * Click axis — XOR enforced at type level so configurations that combine
217
+ * two click handlers (e.g., `preset` AND `actionRef`) are rejected by
218
+ * TypeScript. The four shapes:
219
+ *
220
+ * - `Preset` — built-in preset action.
221
+ * - `ActionRef` — typed reference to a handler registered via `provideAddonActions(...)`.
222
+ * - `Action` — inline handler (code-only; dropped from JSON-derived configs).
223
+ * - `None` — decorative button with no handler.
224
+ *
225
+ * Runtime XOR validation stays as defence-in-depth for JSON-source configs
226
+ * that bypass the type checker.
227
+ */
228
+ type IonButtonClickPreset = {
229
+ /** Built-in preset action (e.g., `'clear'`, `'toggle-password-visibility'`). JSON-safe. */
230
+ readonly preset: AddonActionPreset;
231
+ readonly actionRef?: never;
232
+ readonly action?: never;
233
+ };
234
+ /**
235
+ * Value type for the `actionRef` slot. When no actions have been registered
236
+ * via `provideAddonActions(...)`, `RegisteredActionRef` resolves to `never` —
237
+ * which would make this variant uninhabitable and break `addon.actionRef`
238
+ * narrowing in the renderer. Fall back to `string` so the variant stays
239
+ * usable; once the user augments `DynamicFormActionRegistry`, autocomplete
240
+ * tightens to the registered keys.
241
+ */
242
+ type IonButtonActionRef = [RegisteredActionRef] extends [never] ? string : RegisteredActionRef;
243
+ type IonButtonClickActionRef = {
244
+ readonly preset?: never;
245
+ /** Reference to a handler registered via `provideAddonActions(...)`. JSON-safe. */
246
+ readonly actionRef: IonButtonActionRef;
247
+ readonly action?: never;
248
+ };
249
+ type IonButtonClickAction = {
250
+ readonly preset?: never;
251
+ readonly actionRef?: never;
252
+ /** Inline handler — code-only; dropped from JSON-derived configs. Matches the generic `AddonActionHandler` shape used by `provideAddonActions(...)`. */
253
+ readonly action: AddonActionHandler;
254
+ };
255
+ type IonButtonClickNone = {
256
+ readonly preset?: never;
257
+ readonly actionRef?: never;
258
+ readonly action?: never;
259
+ };
260
+ type IonButtonClick = IonButtonClickPreset | IonButtonClickActionRef | IonButtonClickAction | IonButtonClickNone;
261
+ /**
262
+ * Content axis — XOR enforced at type level so an icon-only button is
263
+ * forced to declare `ariaLabel`. The three shapes:
264
+ *
265
+ * - `IconOnly` — just `icon`; `ariaLabel` is REQUIRED
266
+ * - `Labeled` — `label` set; `icon` and `ariaLabel` optional
267
+ * - `Decorative` — neither icon nor label (e.g., custom-rendered child)
268
+ *
269
+ * Combining keys is rejected by TypeScript — `icon: 'x'` without either
270
+ * `label` or `ariaLabel` doesn't satisfy any branch.
271
+ */
272
+ type IonButtonContentIconOnly = {
273
+ readonly icon: string;
274
+ readonly label?: never;
275
+ /** REQUIRED: icon-only buttons must carry an accessible label. */
276
+ readonly ariaLabel: DynamicText;
277
+ };
278
+ type IonButtonContentLabeled = {
279
+ readonly icon?: string;
280
+ readonly label: DynamicText;
281
+ readonly ariaLabel?: DynamicText;
282
+ };
283
+ type IonButtonContentDecorative = {
284
+ readonly icon?: never;
285
+ readonly label?: never;
286
+ readonly ariaLabel?: DynamicText;
287
+ };
288
+ type IonButtonContent = IonButtonContentIconOnly | IonButtonContentLabeled | IonButtonContentDecorative;
289
+ /**
290
+ * Interactive button addon for Ion fields.
291
+ *
292
+ * Renders `<ion-button>` with optional icon (via `<ion-icon>`), label,
293
+ * colour / fill variants, and a reactive loading state (rendered as
294
+ * `<ion-spinner>`).
295
+ *
296
+ * Type-level guarantees:
297
+ *
298
+ * - **Content axis (XOR):** `IconOnly` (icon + required ariaLabel) |
299
+ * `Labeled` (label, icon optional) | `Decorative` (neither). The IDE
300
+ * rejects icon-only configs that omit `ariaLabel`.
301
+ * - **Click axis (XOR):** exactly one of `preset` / `actionRef` / `action`,
302
+ * or none. Combining two is rejected by TypeScript at the call site;
303
+ * the runtime validator still drops the addon with a clear warning when
304
+ * JSON-source configs slip a multi-set past the type checker.
305
+ */
306
+ type IonButtonAddon = IonButtonBase & IonButtonContent & IonButtonClick;
307
+ /** Union of all Ion-shipped addon kinds. */
308
+ type IonAddon = IonIconAddon | IonButtonAddon;
309
+ declare module '@ng-forge/dynamic-forms' {
310
+ interface DynamicFormAddonRegistry {
311
+ 'ion-icon': IonIconAddon;
312
+ 'ion-button': IonButtonAddon;
313
+ }
237
314
  }
238
315
 
239
316
  interface IonicInputProps extends InputProps {
@@ -246,42 +323,78 @@ interface IonicInputProps extends InputProps {
246
323
  counter?: boolean;
247
324
  clearInput?: boolean;
248
325
  }
249
- type IonicInputField = InputField<IonicInputProps>;
326
+ /**
327
+ * Module-augmentable seam for adding custom addon kinds to `ion-input` at
328
+ * the type level. Pair with `withCustomAddon(...)` for the runtime side:
329
+ *
330
+ * ```ts
331
+ * declare module '@ng-forge/dynamic-forms-ionic' {
332
+ * interface IonAddonExtensions {
333
+ * 'my-rating': MyRatingAddon;
334
+ * }
335
+ * }
336
+ * ```
337
+ *
338
+ * Empty by default — the extension lookup resolves to `never` and contributes
339
+ * nothing to the union.
340
+ */
341
+ interface IonAddonExtensions {
342
+ }
343
+ type IonAddonExtension = IonAddonExtensions[keyof IonAddonExtensions];
344
+ /**
345
+ * Addon kinds accepted by `ion-input`.
346
+ *
347
+ * Ionic-specific kinds (`ion-icon`, `ion-button`) plus the universal `text`
348
+ * and `template` kinds. `component` is permitted at runtime via the broader
349
+ * `BaseAddon` union (and dropped in JSON-derived configs by the validator)
350
+ * but excluded here so the IDE narrows tightly to declarative shapes.
351
+ *
352
+ * To extend with custom kinds, augment `IonAddonExtensions`.
353
+ */
354
+ type IonInputAddon = IonIconAddon | IonButtonAddon | TextAddon | TemplateAddon | IonAddonExtension;
355
+ type IonicInputField = InputField<IonicInputProps> & {
356
+ addons?: ReadonlyArray<IonInputAddon>;
357
+ };
358
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
250
359
  type IonicInputComponent = ValueFieldComponent<IonicInputField>;
251
360
 
252
- declare class IonicInputFieldComponent implements IonicInputComponent {
361
+ declare class IonicInputFieldComponent {
253
362
  private readonly elementRef;
254
363
  private ionicConfig;
255
- readonly field: _angular_core.InputSignal<FieldTree<string>>;
256
- readonly key: _angular_core.InputSignal<string>;
257
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
258
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
259
- readonly className: _angular_core.InputSignal<string>;
260
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
364
+ protected readonly ngf: i1.TypedNgForgeField<string>;
365
+ protected readonly ngfa: i1.TypedNgForgeAddons<IonInputAddon>;
261
366
  readonly props: _angular_core.InputSignal<IonicInputProps | undefined>;
262
- readonly meta: _angular_core.InputSignal<InputMeta | undefined>;
263
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
264
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
265
- readonly effectiveFill: _angular_core.Signal<"outline" | "solid">;
266
- readonly effectiveShape: _angular_core.Signal<"round" | undefined>;
267
- readonly effectiveLabelPlacement: _angular_core.Signal<"start" | "end" | "fixed" | "stacked" | "floating">;
268
- readonly effectiveColor: _angular_core.Signal<"primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "light" | "medium" | "dark" | undefined>;
269
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
270
- readonly showErrors: _angular_core.Signal<boolean>;
271
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
367
+ /**
368
+ * Wrapper-style host bag pushed by `DfFieldOutlet`. Declared at the
369
+ * component level so `setInputIfDeclared` (which uses
370
+ * `reflectComponentType`) can write it.
371
+ */
372
+ readonly fieldInputs: _angular_core.InputSignal<WrapperFieldInputs | undefined>;
373
+ /** Per-instance type override populated by `toggle-password-visibility` preset. */
374
+ private readonly typeOverride;
375
+ protected readonly fill: _angular_core.Signal<"outline" | "solid">;
376
+ protected readonly shape: _angular_core.Signal<"round" | undefined>;
377
+ /** Default 'stacked' (label above the input) for adapter parity with Material /
378
+ * Bootstrap / PrimeNG. Consumers can opt into Ionic's native inline 'start'
379
+ * or 'fixed' via props.labelPlacement or the IONIC_CONFIG token. */
380
+ protected readonly labelPlacement: _angular_core.Signal<"start" | "end" | "fixed" | "stacked" | "floating">;
381
+ protected readonly color: _angular_core.Signal<"primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "light" | "medium" | "dark" | undefined>;
382
+ /** Override (set by `toggle-password-visibility` preset) wins over `props().type`. */
383
+ protected readonly type: _angular_core.Signal<string>;
384
+ /** Per-kind split: ion-button addons render inline via the attribute-
385
+ * selector inline component (so the slotted element is a native
386
+ * <ion-button> Ionic can style); everything else (icon/text/template/
387
+ * component kinds) goes through the universal <df-addon-slot> dispatcher
388
+ * wrapped in <span slot="start|end"> for safe shadow-DOM projection. */
389
+ protected readonly buttonPrefixAddons: _angular_core.Signal<_ng_forge_dynamic_forms_ionic.IonButtonAddon[]>;
390
+ protected readonly buttonSuffixAddons: _angular_core.Signal<_ng_forge_dynamic_forms_ionic.IonButtonAddon[]>;
391
+ protected readonly decorativePrefixAddons: _angular_core.Signal<(_ng_forge_dynamic_forms.TextAddon | _ng_forge_dynamic_forms.TemplateAddon | _ng_forge_dynamic_forms_ionic.IonIconAddon)[]>;
392
+ protected readonly decorativeSuffixAddons: _angular_core.Signal<(_ng_forge_dynamic_forms.TextAddon | _ng_forge_dynamic_forms.TemplateAddon | _ng_forge_dynamic_forms_ionic.IonIconAddon)[]>;
393
+ /** Set when the component is destroyed — guards async aria-describedby sync against teardown. */
394
+ private destroyed;
272
395
  constructor();
273
- /** Base ID for error elements */
274
- protected readonly errorId: _angular_core.Signal<string>;
275
- /** Unique ID for the helper text element */
276
- protected readonly hintId: _angular_core.Signal<string>;
277
- /** Whether the field is currently in an invalid state (invalid AND touched) */
278
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
279
- /** Whether the field has a required validator */
280
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
281
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
282
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
283
396
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicInputFieldComponent, never>;
284
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicInputFieldComponent, "df-ion-input", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
397
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicInputFieldComponent, "df-ion-input", never, { "props": { "alias": "props"; "required": false; "isSignal": true; }; "fieldInputs": { "alias": "fieldInputs"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }, { directive: typeof i1.NgForgeAddons; inputs: {}; outputs: {}; }]>;
285
398
  }
286
399
 
287
400
  interface IonicMultiCheckboxProps {
@@ -291,41 +404,20 @@ interface IonicMultiCheckboxProps {
291
404
  hint?: DynamicText;
292
405
  }
293
406
  type IonicMultiCheckboxField<T> = MultiCheckboxField<T, IonicMultiCheckboxProps>;
407
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
294
408
  type IonicMultiCheckboxComponent = ValueFieldComponent<IonicMultiCheckboxField<ValueType>>;
295
409
 
296
- declare class IonicMultiCheckboxFieldComponent implements IonicMultiCheckboxComponent {
297
- private readonly elementRef;
298
- readonly field: _angular_core.InputSignal<FieldTree<ValueType[]>>;
299
- readonly key: _angular_core.InputSignal<string>;
300
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
301
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
302
- readonly className: _angular_core.InputSignal<string>;
303
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
410
+ declare class IonicMultiCheckboxFieldComponent {
411
+ protected readonly ngf: i1.TypedNgForgeField<ValueType[]>;
304
412
  readonly options: _angular_core.InputSignal<FieldOption<ValueType>[]>;
305
413
  readonly props: _angular_core.InputSignal<IonicMultiCheckboxProps | undefined>;
306
- readonly meta: _angular_core.InputSignal<FieldMeta | undefined>;
307
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
308
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
309
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
310
- readonly showErrors: _angular_core.Signal<boolean>;
311
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
312
- /** Base ID for error elements */
313
- protected readonly errorId: _angular_core.Signal<string>;
314
- /** Unique ID for the helper text element */
315
- protected readonly hintId: _angular_core.Signal<string>;
316
- /** Whether the field is currently in an invalid state (invalid AND touched) */
317
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
318
- /** Whether the field has a required validator */
319
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
320
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
321
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
322
414
  valueViewModel: _angular_core.WritableSignal<FieldOption<ValueType>[]>;
323
415
  /** Computed map of checked option values for O(1) lookup in template */
324
416
  readonly checkedValuesMap: _angular_core.Signal<Record<string, boolean>>;
325
417
  constructor();
326
418
  onCheckboxChange(option: FieldOption<ValueType>, checked: boolean): void;
327
419
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicMultiCheckboxFieldComponent, never>;
328
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicMultiCheckboxFieldComponent, "df-ion-multi-checkbox", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
420
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicMultiCheckboxFieldComponent, "df-ion-multi-checkbox", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }]>;
329
421
  }
330
422
 
331
423
  interface IonicRadioProps {
@@ -336,38 +428,16 @@ interface IonicRadioProps {
336
428
  hint?: DynamicText;
337
429
  }
338
430
  type IonicRadioField<T> = RadioField<T, IonicRadioProps>;
431
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
339
432
  type IonicRadioComponent = ValueFieldComponent<IonicRadioField<ValueType>>;
340
433
 
341
- declare class IonicRadioFieldComponent implements IonicRadioComponent {
342
- private readonly elementRef;
343
- readonly field: _angular_core.InputSignal<FieldTree<ValueType>>;
344
- readonly key: _angular_core.InputSignal<string>;
345
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
346
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
347
- readonly className: _angular_core.InputSignal<string>;
348
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
434
+ declare class IonicRadioFieldComponent {
435
+ protected readonly ngf: i1.TypedNgForgeField<ValueType>;
349
436
  readonly options: _angular_core.InputSignal<FieldOption<ValueType>[]>;
350
437
  readonly props: _angular_core.InputSignal<IonicRadioProps | undefined>;
351
- readonly meta: _angular_core.InputSignal<FieldMeta | undefined>;
352
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
353
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
354
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
355
- readonly showErrors: _angular_core.Signal<boolean>;
356
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
357
438
  defaultCompare: (value1: any, value2: any) => boolean;
358
- constructor();
359
- /** Base ID for error elements */
360
- protected readonly errorId: _angular_core.Signal<string>;
361
- /** Unique ID for the helper text element */
362
- protected readonly hintId: _angular_core.Signal<string>;
363
- /** Whether the field is currently in an invalid state (invalid AND touched) */
364
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
365
- /** Whether the field has a required validator */
366
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
367
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
368
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
369
439
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicRadioFieldComponent, never>;
370
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicRadioFieldComponent, "df-ion-radio", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
440
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicRadioFieldComponent, "df-ion-radio", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }]>;
371
441
  }
372
442
 
373
443
  interface IonicSelectProps extends SelectProps {
@@ -384,38 +454,16 @@ interface IonicSelectProps extends SelectProps {
384
454
  hint?: DynamicText;
385
455
  }
386
456
  type IonicSelectField<T> = SelectField<T, IonicSelectProps>;
457
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
387
458
  type IonicSelectComponent = ValueFieldComponent<IonicSelectField<ValueType>>;
388
459
 
389
- declare class IonicSelectFieldComponent implements IonicSelectComponent {
390
- private readonly elementRef;
391
- readonly field: _angular_core.InputSignal<FieldTree<ValueType>>;
392
- readonly key: _angular_core.InputSignal<string>;
393
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
394
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
395
- readonly className: _angular_core.InputSignal<string>;
396
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
460
+ declare class IonicSelectFieldComponent {
461
+ protected readonly ngf: i1.TypedNgForgeField<ValueType>;
397
462
  readonly options: _angular_core.InputSignal<FieldOption<ValueType>[]>;
398
463
  readonly props: _angular_core.InputSignal<IonicSelectProps | undefined>;
399
- readonly meta: _angular_core.InputSignal<FieldMeta | undefined>;
400
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
401
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
402
- constructor();
403
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
404
- readonly showErrors: _angular_core.Signal<boolean>;
405
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
406
464
  defaultCompare: (value1: any, value2: any) => boolean;
407
- /** Base ID for error elements */
408
- protected readonly errorId: _angular_core.Signal<string>;
409
- /** Unique ID for the helper text element */
410
- protected readonly hintId: _angular_core.Signal<string>;
411
- /** Whether the field is currently in an invalid state (invalid AND touched) */
412
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
413
- /** Whether the field has a required validator */
414
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
415
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
416
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
417
465
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicSelectFieldComponent, never>;
418
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicSelectFieldComponent, "df-ion-select", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
466
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicSelectFieldComponent, "df-ion-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }]>;
419
467
  }
420
468
 
421
469
  interface IonicSliderProps {
@@ -444,38 +492,16 @@ interface IonicSliderProps {
444
492
  hint?: DynamicText;
445
493
  }
446
494
  type IonicSliderField = SliderField<IonicSliderProps>;
495
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
447
496
  type IonicSliderComponent = ValueFieldComponent<IonicSliderField>;
448
497
 
449
- declare class IonicSliderFieldComponent implements IonicSliderComponent {
450
- private readonly elementRef;
451
- readonly field: _angular_core.InputSignal<FieldTree<number>>;
452
- readonly key: _angular_core.InputSignal<string>;
453
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
454
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
455
- readonly className: _angular_core.InputSignal<string>;
456
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
498
+ declare class IonicSliderFieldComponent {
499
+ protected readonly ngf: i1.TypedNgForgeField<number>;
457
500
  readonly step: _angular_core.InputSignal<number | undefined>;
458
501
  readonly props: _angular_core.InputSignal<IonicSliderProps | undefined>;
459
- readonly meta: _angular_core.InputSignal<FieldMeta | undefined>;
460
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
461
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
462
- constructor();
463
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
464
- readonly showErrors: _angular_core.Signal<boolean>;
465
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
466
502
  protected defaultPinFormatter: (value: number) => string;
467
- /** Base ID for error elements */
468
- protected readonly errorId: _angular_core.Signal<string>;
469
- /** Unique ID for the helper text element */
470
- protected readonly hintId: _angular_core.Signal<string>;
471
- /** Whether the field is currently in an invalid state (invalid AND touched) */
472
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
473
- /** Whether the field has a required validator */
474
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
475
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
476
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
477
503
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicSliderFieldComponent, never>;
478
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicSliderFieldComponent, "df-ion-slider", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
504
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicSliderFieldComponent, "df-ion-slider", never, { "step": { "alias": "step"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }, { directive: typeof i1.NgForgeHostControl; inputs: {}; outputs: {}; }]>;
479
505
  }
480
506
 
481
507
  interface IonicTextareaProps extends TextareaProps {
@@ -489,36 +515,16 @@ interface IonicTextareaProps extends TextareaProps {
489
515
  color?: 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'danger' | 'light' | 'medium' | 'dark';
490
516
  }
491
517
  type IonicTextareaField = TextareaField<IonicTextareaProps>;
518
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
492
519
  type IonicTextareaComponent = ValueFieldComponent<IonicTextareaField>;
493
520
 
494
- declare class IonicTextareaFieldComponent implements IonicTextareaComponent {
521
+ declare class IonicTextareaFieldComponent {
495
522
  private readonly elementRef;
496
- readonly field: _angular_core.InputSignal<FieldTree<string>>;
497
- readonly key: _angular_core.InputSignal<string>;
498
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
499
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
500
- readonly className: _angular_core.InputSignal<string>;
501
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
523
+ protected readonly ngf: i1.TypedNgForgeField<string>;
502
524
  readonly props: _angular_core.InputSignal<IonicTextareaProps | undefined>;
503
- readonly meta: _angular_core.InputSignal<TextareaMeta | undefined>;
504
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
505
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
506
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
507
- readonly showErrors: _angular_core.Signal<boolean>;
508
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
509
525
  constructor();
510
- /** Base ID for error elements */
511
- protected readonly errorId: _angular_core.Signal<string>;
512
- /** Unique ID for the helper text element */
513
- protected readonly hintId: _angular_core.Signal<string>;
514
- /** Whether the field is currently in an invalid state (invalid AND touched) */
515
- protected readonly ariaInvalid: _angular_core.Signal<boolean>;
516
- /** Whether the field has a required validator */
517
- protected readonly ariaRequired: _angular_core.Signal<true | null>;
518
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
519
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
520
526
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicTextareaFieldComponent, never>;
521
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicTextareaFieldComponent, "df-ion-textarea", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
527
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicTextareaFieldComponent, "df-ion-textarea", never, { "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }]>;
522
528
  }
523
529
 
524
530
  interface IonicToggleProps {
@@ -529,32 +535,14 @@ interface IonicToggleProps {
529
535
  hint?: DynamicText;
530
536
  }
531
537
  type IonicToggleField = ToggleField<IonicToggleProps>;
538
+ /** @deprecated Scheduled for removal in v1. Use `injectNgForgeField<T>()` for typed access to a field component's directive instance. */
532
539
  type IonicToggleComponent = CheckedFieldComponent<IonicToggleField>;
533
540
 
534
- declare class IonicToggleFieldComponent implements IonicToggleComponent {
535
- private readonly elementRef;
536
- readonly field: _angular_core.InputSignal<FieldTree<boolean>>;
537
- readonly key: _angular_core.InputSignal<string>;
538
- readonly label: _angular_core.InputSignal<DynamicText | undefined>;
539
- readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
540
- readonly className: _angular_core.InputSignal<string>;
541
- readonly tabIndex: _angular_core.InputSignal<number | undefined>;
541
+ declare class IonicToggleFieldComponent {
542
+ protected readonly ngf: i1.TypedNgForgeField<boolean>;
542
543
  readonly props: _angular_core.InputSignal<IonicToggleProps | undefined>;
543
- readonly meta: _angular_core.InputSignal<FieldMeta | undefined>;
544
- readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
545
- readonly defaultValidationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
546
- constructor();
547
- readonly resolvedErrors: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
548
- readonly showErrors: _angular_core.Signal<boolean>;
549
- readonly errorsToDisplay: _angular_core.Signal<_ng_forge_dynamic_forms_integration.ResolvedError[]>;
550
- /** Base ID for error elements */
551
- protected readonly errorId: _angular_core.Signal<string>;
552
- /** Unique ID for the helper text element */
553
- protected readonly hintId: _angular_core.Signal<string>;
554
- /** aria-describedby linking to hint OR error elements (mutually exclusive) */
555
- protected readonly ariaDescribedBy: _angular_core.Signal<string | null>;
556
544
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonicToggleFieldComponent, never>;
557
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicToggleFieldComponent, "df-ion-toggle", never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; "defaultValidationMessages": { "alias": "defaultValidationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
545
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonicToggleFieldComponent, "df-ion-toggle", never, { "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgForgeFieldHost; inputs: {}; outputs: {}; }]>;
558
546
  }
559
547
 
560
548
  /**
@@ -761,19 +749,30 @@ type IonicConfigFeature = {
761
749
  ɵkind: 'ionic-config';
762
750
  ɵproviders: Provider[];
763
751
  };
764
- type IonicFieldsWithConfig = [...IonicFieldTypes, IonicConfigFeature];
765
752
  /**
766
- * Configure dynamic forms with Ionic field types.
767
- * Provides all Ionic field types for use with provideDynamicForm.
753
+ * Default `withIonicFields()` shape — field defs + the auto-included
754
+ * addons feature so `ion-icon` / `ion-button` work out of the box.
755
+ */
756
+ type IonicFieldsWithAddons = [...IonicFieldTypes, IonicAddonsFeature];
757
+ type IonicFieldsWithConfig = [...IonicFieldTypes, IonicAddonsFeature, IonicConfigFeature];
758
+ /**
759
+ * Provides Ionic field type definitions for the dynamic form system,
760
+ * with Ionic-shipped addon kinds (`ion-icon`, `ion-button`) auto-included
761
+ * so addons work out of the box.
762
+ *
763
+ * If you want field types WITHOUT addons (rare), pass them through
764
+ * `provideDynamicForm` directly and skip this helper. If you want addons
765
+ * WITHOUT the field types (also rare — e.g., adding addons to a form that
766
+ * uses custom fields), call `withIonicAddons()` standalone.
768
767
  *
769
768
  * @param config - Optional global configuration for Ionic form fields
770
769
  *
771
770
  * @example
772
771
  * ```typescript
773
- * // Application-level setup
772
+ * // Application-level setup — addons (ion-icon, ion-button) ship in automatically
774
773
  * import { ApplicationConfig } from '@angular/core';
775
- * import { provideDynamicForm } from '@ng-forge/dynamic-form';
776
- * import { withIonicFields } from '@ng-forge/dynamic-form-ionic';
774
+ * import { provideDynamicForm } from '@ng-forge/dynamic-forms';
775
+ * import { withIonicFields } from '@ng-forge/dynamic-forms-ionic';
777
776
  *
778
777
  * export const appConfig: ApplicationConfig = {
779
778
  * providers: [
@@ -797,11 +796,105 @@ type IonicFieldsWithConfig = [...IonicFieldTypes, IonicConfigFeature];
797
796
  * };
798
797
  * ```
799
798
  *
800
- * @returns Array of field type definitions and optionally a config feature
799
+ * @returns Tuple of field type definitions, the addons feature, and
800
+ * optionally a config feature.
801
801
  */
802
- declare function withIonicFields(): IonicFieldTypes;
802
+ declare function withIonicFields(): IonicFieldsWithAddons;
803
803
  declare function withIonicFields(config: IonicConfig): IonicFieldsWithConfig;
804
- declare function withIonicFields(config: IonicConfig | undefined): IonicFieldTypes | IonicFieldsWithConfig;
804
+ declare function withIonicFields(config: IonicConfig | undefined): IonicFieldsWithAddons | IonicFieldsWithConfig;
805
+ /**
806
+ * Feature kind discriminant for the Ionic addons feature. Matches core's
807
+ * `'addons'` kind so providers flow through the standard addon-kind pipeline
808
+ * in `provideDynamicForm`.
809
+ */
810
+ type IonicAddonsFeature = {
811
+ ɵkind: 'addons';
812
+ ɵproviders: Provider[];
813
+ };
814
+ /**
815
+ * Register Ionic-shipped addon kinds (`ion-icon`, `ion-button`) standalone.
816
+ *
817
+ * **Most users don't need this** — `withIonicFields()` auto-includes
818
+ * these kinds. Call `withIonicAddons()` directly only when you want
819
+ * Ionic addon kinds without the Ionic field types (e.g., a custom
820
+ * field set that wants to render `ion-icon` prefixes), or when you're
821
+ * stitching addons through a different DI scope.
822
+ *
823
+ * @example
824
+ * ```typescript
825
+ * // Custom field types + Ionic addon kinds.
826
+ * provideDynamicForm(
827
+ * ...myCustomFields(),
828
+ * withIonicAddons(),
829
+ * );
830
+ * ```
831
+ *
832
+ * Adapter authors who need to override a kind with a customised renderer
833
+ * should call `withCustomAddon(...)` directly instead.
834
+ */
835
+ declare function withIonicAddons(): IonicAddonsFeature;
836
+
837
+ /**
838
+ * Renderer for the `ion-button` addon kind.
839
+ *
840
+ * Wraps Ionic's `<ion-button>`. Click dispatch (preset / actionRef /
841
+ * action precedence, multi-set warning, `disabled` / `loading`
842
+ * resolution) lives on `NgForgeAddonAction`; this component focuses on
843
+ * the visual layer. While `action.loading()`, an `<ion-spinner>` is
844
+ * rendered in place of the icon and the button is disabled.
845
+ */
846
+ declare class IonButtonAddonComponent {
847
+ protected readonly action: i1.TypedNgForgeAddonAction<IonButtonAddon>;
848
+ /** Re-exposed for template binding — same signal stored on the directive. */
849
+ protected readonly addon: _angular_core.Signal<IonButtonAddon>;
850
+ protected readonly label: _angular_core.Signal<_ng_forge_dynamic_forms.DynamicText | undefined>;
851
+ protected readonly ariaLabel: _angular_core.Signal<_ng_forge_dynamic_forms.DynamicText | undefined>;
852
+ protected readonly icon: _angular_core.Signal<string | undefined>;
853
+ /** Default color is undefined so the button inherits the theme's text color
854
+ * (Ionic's `medium` would force low-contrast grey, which fails WCAG on dark
855
+ * surfaces). Consumers can still set `color: 'primary' | 'success' | ...`
856
+ * explicitly when they want adapter-styled coloring. */
857
+ protected readonly color: _angular_core.Signal<("primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "light" | "medium" | "dark") | undefined>;
858
+ protected readonly fill: _angular_core.Signal<"clear" | "outline" | "solid" | "default">;
859
+ /** Icon-only when there is an icon but no label — drives the `slot` choice.
860
+ * Truthy check on `label` mirrors Material's heuristic; empty-string label
861
+ * is treated as "no label" so the button doesn't render an invisible text
862
+ * slot beside the icon. */
863
+ protected readonly iconOnly: _angular_core.Signal<boolean>;
864
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonButtonAddonComponent, never>;
865
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonButtonAddonComponent, "df-ion-button-addon", never, {}, {}, never, never, true, [{ directive: typeof i1.NgForgeAddonAction; inputs: {}; outputs: {}; }]>;
866
+ }
867
+
868
+ /**
869
+ * Renderer for the `ion-icon` addon kind.
870
+ *
871
+ * Outputs `<ion-icon [name]="icon">`. The host is set `aria-hidden="true"`
872
+ * by default; if the addon supplies an `ariaLabel`, it is applied so the
873
+ * icon is announced by screen readers.
874
+ */
875
+ declare class IonIconAddonComponent {
876
+ readonly addon: _angular_core.InputSignal<IonIconAddon>;
877
+ /** Accepted for contract uniformity — `NgComponentOutlet` setInput is strict; every kind must declare it. */
878
+ readonly fieldInputs: _angular_core.InputSignal<WrapperFieldInputs | undefined>;
879
+ protected readonly iconName: _angular_core.Signal<string>;
880
+ protected readonly ariaLabel: _angular_core.Signal<_ng_forge_dynamic_forms.DynamicText | undefined>;
881
+ protected readonly hasAriaLabel: _angular_core.Signal<boolean>;
882
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<IonIconAddonComponent, never>;
883
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonIconAddonComponent, "df-ion-icon-addon", never, { "addon": { "alias": "addon"; "required": true; "isSignal": true; }; "fieldInputs": { "alias": "fieldInputs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
884
+ }
885
+
886
+ /**
887
+ * Per-field writable signal that overrides the input's `type` attribute.
888
+ *
889
+ * Provided at the `ion-input` field component level. The button addon's
890
+ * `'toggle-password-visibility'` preset writes to it; the field component
891
+ * reads it to compute its effective `type`.
892
+ *
893
+ * Optional from a button's perspective — when the button is hosted inside a
894
+ * field that doesn't provide this token (e.g., textarea or a future
895
+ * non-input field), the toggle preset is a no-op.
896
+ */
897
+ declare const IONIC_INPUT_TYPE_OVERRIDE: InjectionToken<WritableSignal<string | undefined>>;
805
898
 
806
- export { IONIC_CONFIG, IONIC_FIELD_TYPES, IonicButtonFieldComponent, IonicCheckboxFieldComponent, IonicDatepickerFieldComponent, IonicField, IonicInputFieldComponent, IonicMultiCheckboxFieldComponent, IonicRadioFieldComponent, IonicSelectFieldComponent, IonicSliderFieldComponent, IonicTextareaFieldComponent, IonicToggleFieldComponent, withIonicFields };
807
- export type { AddArrayItemButtonField, InsertArrayItemButtonField, IonicButtonField, IonicButtonProps, IonicCheckboxComponent, IonicCheckboxField, IonicCheckboxProps, IonicConfig, IonicDatepickerComponent, IonicDatepickerField, IonicDatepickerProps, IonicFieldType, IonicFormConfig, IonicFormProps, IonicInputComponent, IonicInputField, IonicInputProps, IonicMultiCheckboxComponent, IonicMultiCheckboxField, IonicMultiCheckboxProps, IonicNextButtonField, IonicPreviousButtonField, IonicRadioComponent, IonicRadioField, IonicRadioProps, IonicSelectComponent, IonicSelectField, IonicSelectProps, IonicSliderComponent, IonicSliderField, IonicSliderProps, IonicSubmitButtonField, IonicTextareaComponent, IonicTextareaField, IonicTextareaProps, IonicToggleComponent, IonicToggleField, IonicToggleProps, PopArrayItemButtonField, PrependArrayItemButtonField, RemoveArrayItemButtonField, ShiftArrayItemButtonField };
899
+ export { IONIC_CONFIG, IONIC_FIELD_TYPES, IONIC_INPUT_TYPE_OVERRIDE, IonButtonAddonComponent, IonIconAddonComponent, IonicButtonFieldComponent, IonicCheckboxFieldComponent, IonicDatepickerFieldComponent, IonicField, IonicInputFieldComponent, IonicMultiCheckboxFieldComponent, IonicRadioFieldComponent, IonicSelectFieldComponent, IonicSliderFieldComponent, IonicTextareaFieldComponent, IonicToggleFieldComponent, withIonicAddons, withIonicFields };
900
+ export type { AddArrayItemButtonField, InsertArrayItemButtonField, IonAddon, IonAddonExtensions, IonButtonAddon, IonIconAddon, IonInputAddon, IonicButtonField, IonicButtonProps, IonicCheckboxComponent, IonicCheckboxField, IonicCheckboxProps, IonicConfig, IonicDatepickerComponent, IonicDatepickerField, IonicDatepickerProps, IonicFieldType, IonicFormConfig, IonicFormProps, IonicInputComponent, IonicInputField, IonicInputProps, IonicMultiCheckboxComponent, IonicMultiCheckboxField, IonicMultiCheckboxProps, IonicNextButtonField, IonicPreviousButtonField, IonicRadioComponent, IonicRadioField, IonicRadioProps, IonicSelectComponent, IonicSelectField, IonicSelectProps, IonicSliderComponent, IonicSliderField, IonicSliderProps, IonicSubmitButtonField, IonicTextareaComponent, IonicTextareaField, IonicTextareaProps, IonicToggleComponent, IonicToggleField, IonicToggleProps, PopArrayItemButtonField, PrependArrayItemButtonField, RemoveArrayItemButtonField, ShiftArrayItemButtonField };