@ng-forge/dynamic-forms-ionic 0.10.0-next.1 → 0.10.0-next.3

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.
@@ -16,9 +16,7 @@ interface IonicButtonProps {
16
16
  type?: 'button' | 'submit' | 'reset';
17
17
  }
18
18
  type IonicButtonField<TEvent extends FormEvent> = ButtonField<IonicButtonProps, TEvent>;
19
- /**
20
- * Specific button field types with preconfigured events
21
- */
19
+ /** Specific button field types with preconfigured events */
22
20
  /** Submit button field - automatically disabled when form is invalid */
23
21
  type IonicSubmitButtonField = Omit<IonicButtonField<SubmitEvent>, 'event' | 'type' | 'eventArgs'> & {
24
22
  type: 'submit';
@@ -72,9 +70,7 @@ type InsertArrayItemButtonField = Omit<IonicButtonField<InsertArrayItemEvent>, '
72
70
  * When inside an array, this is automatically determined from context.
73
71
  */
74
72
  arrayKey?: string;
75
- /**
76
- * The index at which to insert the new item.
77
- */
73
+ /** The index at which to insert the new item. */
78
74
  index: number;
79
75
  /**
80
76
  * Template for the new array item. REQUIRED.
@@ -174,16 +170,7 @@ declare class IonicDatepickerFieldComponent {
174
170
  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
171
  }
176
172
 
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
- */
173
+ /** Decorative icon addon for Ion fields. */
187
174
  interface IonIconAddon extends BaseAddon {
188
175
  readonly kind: 'ion-icon';
189
176
  /** Ionons name (e.g., `'search-outline'`, `'close-outline'`). */
@@ -191,13 +178,9 @@ interface IonIconAddon extends BaseAddon {
191
178
  /** Accessible label for icons that convey meaning. */
192
179
  readonly ariaLabel?: DynamicText;
193
180
  }
194
- /**
195
- * Ionic-supported button colour palette.
196
- */
181
+ /** Ionic-supported button colour palette. */
197
182
  type IonButtonColor = 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'danger' | 'light' | 'medium' | 'dark';
198
- /**
199
- * Ionic-supported button fill variants.
200
- */
183
+ /** Ionic-supported button fill variants. */
201
184
  type IonButtonFill = 'clear' | 'outline' | 'solid' | 'default';
202
185
  /**
203
186
  * Common shape of every `ion-button` addon — properties that don't
@@ -216,14 +199,6 @@ interface IonButtonBase extends BaseAddon {
216
199
  * Click axis — XOR enforced at type level so configurations that combine
217
200
  * two click handlers (e.g., `preset` AND `actionRef`) are rejected by
218
201
  * 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
202
  */
228
203
  type IonButtonClickPreset = {
229
204
  /** Built-in preset action (e.g., `'clear'`, `'toggle-password-visibility'`). JSON-safe. */
@@ -261,13 +236,6 @@ type IonButtonClick = IonButtonClickPreset | IonButtonClickActionRef | IonButton
261
236
  /**
262
237
  * Content axis — XOR enforced at type level so an icon-only button is
263
238
  * 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
239
  */
272
240
  type IonButtonContentIconOnly = {
273
241
  readonly icon: string;
@@ -286,23 +254,7 @@ type IonButtonContentDecorative = {
286
254
  readonly ariaLabel?: DynamicText;
287
255
  };
288
256
  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
- */
257
+ /** Interactive button addon for Ion fields. */
306
258
  type IonButtonAddon = IonButtonBase & IonButtonContent & IonButtonClick;
307
259
  /** Union of all Ion-shipped addon kinds. */
308
260
  type IonAddon = IonIconAddon | IonButtonAddon;
@@ -326,31 +278,11 @@ interface IonicInputProps extends InputProps {
326
278
  /**
327
279
  * Module-augmentable seam for adding custom addon kinds to `ion-input` at
328
280
  * 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
281
  */
341
282
  interface IonAddonExtensions {
342
283
  }
343
284
  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
- */
285
+ /** Addon kinds accepted by `ion-input`. */
354
286
  type IonInputAddon = IonIconAddon | IonButtonAddon | TextAddon | TemplateAddon | IonAddonExtension;
355
287
  type IonicInputField = InputField<IonicInputProps> & {
356
288
  addons?: ReadonlyArray<IonInputAddon>;
@@ -374,9 +306,7 @@ declare class IonicInputFieldComponent {
374
306
  private readonly typeOverride;
375
307
  protected readonly fill: _angular_core.Signal<"outline" | "solid">;
376
308
  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. */
309
+ /** Bootstrap / PrimeNG. Consumers can opt into Ionic's native inline 'start' */
380
310
  protected readonly labelPlacement: _angular_core.Signal<"start" | "end" | "fixed" | "stacked" | "floating">;
381
311
  protected readonly color: _angular_core.Signal<"primary" | "secondary" | "tertiary" | "success" | "warning" | "danger" | "light" | "medium" | "dark" | undefined>;
382
312
  /** Override (set by `toggle-password-visibility` preset) wins over `props().type`. */
@@ -551,65 +481,53 @@ declare class IonicToggleFieldComponent {
551
481
  */
552
482
  declare const IONIC_FIELD_TYPES: FieldTypeDefinition[];
553
483
 
554
- /**
555
- * Configuration options for Ionic form fields.
556
- *
557
- * These settings can be applied at two levels:
558
- * - **Library-level**: Via `withIonicFields({ ... })` - applies to all forms
559
- * - **Form-level**: Via `defaultProps` in form config - applies to a specific form
560
- *
561
- * The cascade hierarchy is: Library-level → Form-level → Field-level
562
- *
563
- * @example
564
- * ```typescript
565
- * // Library-level (in app config)
566
- * provideDynamicForms(withIonicFields({ fill: 'outline', labelPlacement: 'floating' }))
567
- *
568
- * // Form-level (in form config)
569
- * const config: IonicFormConfig = {
570
- * defaultProps: { color: 'tertiary' },
571
- * fields: [...]
572
- * };
573
- * ```
574
- */
484
+ /** Configuration options for Ionic form fields. */
575
485
  interface IonicConfig {
576
486
  /**
577
487
  * Default fill style for form inputs
488
+ *
578
489
  * @default 'solid'
579
490
  */
580
491
  fill?: 'solid' | 'outline';
581
492
  /**
582
493
  * Default shape for form controls
494
+ *
583
495
  * @default undefined
584
496
  */
585
497
  shape?: 'round';
586
498
  /**
587
499
  * Default label placement for form inputs
500
+ *
588
501
  * @default 'start'
589
502
  */
590
503
  labelPlacement?: 'start' | 'end' | 'fixed' | 'stacked' | 'floating';
591
504
  /**
592
505
  * Default color theme for form controls
506
+ *
593
507
  * @default 'primary'
594
508
  */
595
509
  color?: 'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'danger' | 'light' | 'medium' | 'dark';
596
510
  /**
597
511
  * Default size for buttons
512
+ *
598
513
  * @default 'default'
599
514
  */
600
515
  size?: 'small' | 'default' | 'large';
601
516
  /**
602
517
  * Default expand behavior for buttons
518
+ *
603
519
  * @default undefined
604
520
  */
605
521
  expand?: 'full' | 'block';
606
522
  /**
607
523
  * Default fill style for buttons (overrides general fill if set)
524
+ *
608
525
  * @default 'solid'
609
526
  */
610
527
  buttonFill?: 'clear' | 'outline' | 'solid' | 'default';
611
528
  /**
612
529
  * Whether buttons should be strong (bold) by default
530
+ *
613
531
  * @default false
614
532
  */
615
533
  strong?: boolean;
@@ -618,23 +536,6 @@ interface IonicConfig {
618
536
  /**
619
537
  * Injection token for Ionic form configuration.
620
538
  * Use this to provide global configuration for Ionic form fields.
621
- *
622
- * @example
623
- * ```typescript
624
- * import { provideDynamicForm } from '@ng-forge/dynamic-forms';
625
- * import { withIonicFields } from '@ng-forge/dynamic-forms-ionic';
626
- *
627
- * export const appConfig: ApplicationConfig = {
628
- * providers: [
629
- * provideDynamicForm(
630
- * ...withIonicFields({
631
- * fill: 'outline',
632
- * labelPlacement: 'floating'
633
- * })
634
- * )
635
- * ]
636
- * };
637
- * ```
638
539
  */
639
540
  declare const IONIC_CONFIG: InjectionToken<IonicConfig>;
640
541
 
@@ -665,50 +566,9 @@ declare const IonicField: {
665
566
  };
666
567
  type IonicFieldType = (typeof IonicField)[keyof typeof IonicField];
667
568
 
668
- /**
669
- * Ionic-specific props that can be set at form level and cascade to all fields.
670
- *
671
- * This is the same type as `IonicConfig` used in `withIonicFields()`.
672
- * Using a single type ensures consistency between library-level and form-level configuration.
673
- *
674
- * The cascade hierarchy is: Library-level → Form-level → Field-level
675
- *
676
- * @example
677
- * ```typescript
678
- * const config: IonicFormConfig = {
679
- * defaultProps: {
680
- * fill: 'outline',
681
- * labelPlacement: 'floating',
682
- * color: 'tertiary',
683
- * },
684
- * fields: [
685
- * { type: 'ionic-input', key: 'name', label: 'Name' },
686
- * ],
687
- * };
688
- * ```
689
- */
569
+ /** Ionic-specific props that can be set at form level and cascade to all fields. */
690
570
  type IonicFormProps = IonicConfig;
691
- /**
692
- * Ionic-specific FormConfig with type-safe defaultProps.
693
- *
694
- * Use this type alias when defining form configurations with Ionic components
695
- * to get IDE autocomplete and type checking for `defaultProps`.
696
- *
697
- * @example
698
- * ```typescript
699
- * const formConfig: IonicFormConfig = {
700
- * defaultProps: {
701
- * fill: 'outline',
702
- * labelPlacement: 'floating',
703
- * color: 'primary',
704
- * },
705
- * fields: [
706
- * { type: 'ionic-input', key: 'name', label: 'Name' }, // Uses form defaultProps
707
- * { type: 'ionic-input', key: 'email', props: { fill: 'solid' } }, // Override
708
- * ],
709
- * };
710
- * ```
711
- */
571
+ /** Ionic-specific FormConfig with type-safe defaultProps. */
712
572
  type IonicFormConfig<TFields extends NarrowFields | RegisteredFieldTypes[] = RegisteredFieldTypes[], TValue = InferFormValue<TFields extends readonly RegisteredFieldTypes[] ? TFields : RegisteredFieldTypes[]>> = FormConfig<TFields, TValue, IonicFormProps>;
713
573
 
714
574
  /**
@@ -741,9 +601,7 @@ declare module '@ng-forge/dynamic-forms' {
741
601
  }
742
602
  }
743
603
 
744
- /**
745
- * Field type definitions for Ionic components.
746
- */
604
+ /** Field type definitions for Ionic components. */
747
605
  type IonicFieldTypes = FieldTypeDefinition[];
748
606
  type IonicConfigFeature = {
749
607
  ɵkind: 'ionic-config';
@@ -760,42 +618,7 @@ type IonicFieldsWithConfig = [...IonicFieldTypes, IonicAddonsFeature, IonicConfi
760
618
  * with Ionic-shipped addon kinds (`ion-icon`, `ion-button`) auto-included
761
619
  * so addons work out of the box.
762
620
  *
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.
767
- *
768
621
  * @param config - Optional global configuration for Ionic form fields
769
- *
770
- * @example
771
- * ```typescript
772
- * // Application-level setup — addons (ion-icon, ion-button) ship in automatically
773
- * import { ApplicationConfig } from '@angular/core';
774
- * import { provideDynamicForm } from '@ng-forge/dynamic-forms';
775
- * import { withIonicFields } from '@ng-forge/dynamic-forms-ionic';
776
- *
777
- * export const appConfig: ApplicationConfig = {
778
- * providers: [
779
- * provideDynamicForm(...withIonicFields())
780
- * ]
781
- * };
782
- * ```
783
- *
784
- * @example
785
- * ```typescript
786
- * // With global configuration
787
- * export const appConfig: ApplicationConfig = {
788
- * providers: [
789
- * provideDynamicForm(
790
- * ...withIonicFields({
791
- * fill: 'outline',
792
- * labelPlacement: 'floating'
793
- * })
794
- * )
795
- * ]
796
- * };
797
- * ```
798
- *
799
622
  * @returns Tuple of field type definitions, the addons feature, and
800
623
  * optionally a config feature.
801
624
  */
@@ -811,38 +634,10 @@ type IonicAddonsFeature = {
811
634
  ɵkind: 'addons';
812
635
  ɵproviders: Provider[];
813
636
  };
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
- */
637
+ /** Register Ionic-shipped addon kinds (`ion-icon`, `ion-button`) standalone. */
835
638
  declare function withIonicAddons(): IonicAddonsFeature;
836
639
 
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
- */
640
+ /** Renderer for the `ion-button` addon kind. */
846
641
  declare class IonButtonAddonComponent {
847
642
  protected readonly action: i1.TypedNgForgeAddonAction<IonButtonAddon>;
848
643
  /** Re-exposed for template binding — same signal stored on the directive. */
@@ -865,13 +660,7 @@ declare class IonButtonAddonComponent {
865
660
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<IonButtonAddonComponent, "df-ion-button-addon", never, {}, {}, never, never, true, [{ directive: typeof i1.NgForgeAddonAction; inputs: {}; outputs: {}; }]>;
866
661
  }
867
662
 
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
- */
663
+ /** Renderer for the `ion-icon` addon kind. */
875
664
  declare class IonIconAddonComponent {
876
665
  readonly addon: _angular_core.InputSignal<IonIconAddon>;
877
666
  /** Accepted for contract uniformity — `NgComponentOutlet` setInput is strict; every kind must declare it. */
@@ -883,17 +672,7 @@ declare class IonIconAddonComponent {
883
672
  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
673
  }
885
674
 
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
- */
675
+ /** Per-field writable signal that overrides the input's `type` attribute. */
897
676
  declare const IONIC_INPUT_TYPE_OVERRIDE: InjectionToken<WritableSignal<string | undefined>>;
898
677
 
899
678
  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 };