@ng-forge/dynamic-forms-ionic 1.1.0 → 1.2.0-next.10

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 (46) hide show
  1. package/README.md +5 -5
  2. package/fesm2022/ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-CN0CagvT.mjs +26 -0
  3. package/fesm2022/ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-CN0CagvT.mjs.map +1 -0
  4. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-button.mjs +75 -0
  5. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-button.mjs.map +1 -0
  6. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-icon.mjs +36 -0
  7. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-addon-icon.mjs.map +1 -0
  8. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-button.mjs +70 -0
  9. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-button.mjs.map +1 -0
  10. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-checkbox.mjs +67 -0
  11. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-checkbox.mjs.map +1 -0
  12. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-datepicker.mjs +195 -0
  13. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-datepicker.mjs.map +1 -0
  14. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-input.mjs +211 -0
  15. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-input.mjs.map +1 -0
  16. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-multi-checkbox.mjs +139 -0
  17. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-multi-checkbox.mjs.map +1 -0
  18. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-radio.mjs +98 -0
  19. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-radio.mjs.map +1 -0
  20. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-select.mjs +92 -0
  21. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-select.mjs.map +1 -0
  22. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-slider.mjs +76 -0
  23. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-slider.mjs.map +1 -0
  24. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-textarea.mjs +96 -0
  25. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-textarea.mjs.map +1 -0
  26. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-toggle.mjs +146 -0
  27. package/fesm2022/ng-forge-dynamic-forms-ionic-lazy-toggle.mjs.map +1 -0
  28. package/fesm2022/ng-forge-dynamic-forms-ionic-shared.mjs +83 -0
  29. package/fesm2022/ng-forge-dynamic-forms-ionic-shared.mjs.map +1 -0
  30. package/fesm2022/ng-forge-dynamic-forms-ionic.mjs +85 -198
  31. package/fesm2022/ng-forge-dynamic-forms-ionic.mjs.map +1 -1
  32. package/package.json +56 -4
  33. package/types/ng-forge-dynamic-forms-ionic-lazy-addon-button.d.ts +29 -0
  34. package/types/ng-forge-dynamic-forms-ionic-lazy-addon-icon.d.ts +18 -0
  35. package/types/ng-forge-dynamic-forms-ionic-lazy-button.d.ts +119 -0
  36. package/types/ng-forge-dynamic-forms-ionic-lazy-checkbox.d.ts +23 -0
  37. package/types/ng-forge-dynamic-forms-ionic-lazy-datepicker.d.ts +39 -0
  38. package/types/ng-forge-dynamic-forms-ionic-lazy-input.d.ts +70 -0
  39. package/types/ng-forge-dynamic-forms-ionic-lazy-multi-checkbox.d.ts +28 -0
  40. package/types/ng-forge-dynamic-forms-ionic-lazy-radio.d.ts +25 -0
  41. package/types/ng-forge-dynamic-forms-ionic-lazy-select.d.ts +31 -0
  42. package/types/ng-forge-dynamic-forms-ionic-lazy-slider.d.ts +43 -0
  43. package/types/ng-forge-dynamic-forms-ionic-lazy-textarea.d.ts +28 -0
  44. package/types/ng-forge-dynamic-forms-ionic-lazy-toggle.d.ts +66 -0
  45. package/types/ng-forge-dynamic-forms-ionic-shared.d.ts +116 -0
  46. package/types/ng-forge-dynamic-forms-ionic.d.ts +10 -164
package/README.md CHANGED
@@ -106,11 +106,11 @@ Input, Textarea, Select, Checkbox, Radio, Toggle, Datepicker, Slider, Multi-Chec
106
106
 
107
107
  ## Documentation
108
108
 
109
- - [Feature overview](https://ng-forge.com/ionic/feature-overview)
110
- - [Ionic Integration](https://ng-forge.com/ionic)
111
- - [Field Types](https://ng-forge.com/ionic/field-types/text-inputs)
112
- - [Validation](https://ng-forge.com/ionic/validation/basics)
113
- - [Conditional Logic](https://ng-forge.com/ionic/dynamic-behavior/conditional-logic)
109
+ - [Feature overview](https://ng-forge.com/dynamic-forms/ionic/feature-overview)
110
+ - [Getting Started](https://ng-forge.com/dynamic-forms/ionic/getting-started)
111
+ - [Field Types](https://ng-forge.com/dynamic-forms/ionic/field-types/text-inputs)
112
+ - [Validation](https://ng-forge.com/dynamic-forms/ionic/validation/basics)
113
+ - [Conditional Logic](https://ng-forge.com/dynamic-forms/ionic/dynamic-behavior/conditional-logic)
114
114
 
115
115
  ## Changelog
116
116
 
@@ -0,0 +1,26 @@
1
+ import * as i0 from '@angular/core';
2
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { IonNote } from '@ionic/angular/standalone';
4
+ import { FieldErrorsWrapperBase, provideFieldErrorDisplay } from '@ng-forge/dynamic-forms/integration';
5
+
6
+ class IonicFieldErrorsWrapperComponent extends FieldErrorsWrapperBase {
7
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicFieldErrorsWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
8
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: IonicFieldErrorsWrapperComponent, isStandalone: true, selector: "df-ion-field-errors", providers: [provideFieldErrorDisplay(() => IonicFieldErrorsWrapperComponent)], usesInheritance: true, ngImport: i0, template: `
9
+ <ng-container #fieldComponent></ng-container>
10
+ @if (ngf.errorsToDisplay()[0]; as error) {
11
+ <ion-note color="danger" class="df-ion-error" role="alert" [id]="ngf.errorId()">{{ error.message }}</ion-note>
12
+ }
13
+ `, isInline: true, styles: [".df-ion-error{display:block;color:var(--df-error-color, var(--ion-color-danger, #eb445a));font-size:var(--df-error-font-size, .875rem)}\n"], dependencies: [{ kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
14
+ }
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicFieldErrorsWrapperComponent, decorators: [{
16
+ type: Component,
17
+ args: [{ selector: 'df-ion-field-errors', imports: [IonNote], template: `
18
+ <ng-container #fieldComponent></ng-container>
19
+ @if (ngf.errorsToDisplay()[0]; as error) {
20
+ <ion-note color="danger" class="df-ion-error" role="alert" [id]="ngf.errorId()">{{ error.message }}</ion-note>
21
+ }
22
+ `, changeDetection: ChangeDetectionStrategy.OnPush, providers: [provideFieldErrorDisplay(() => IonicFieldErrorsWrapperComponent)], styles: [".df-ion-error{display:block;color:var(--df-error-color, var(--ion-color-danger, #eb445a));font-size:var(--df-error-font-size, .875rem)}\n"] }]
23
+ }] });
24
+
25
+ export { IonicFieldErrorsWrapperComponent, IonicFieldErrorsWrapperComponent as default };
26
+ //# sourceMappingURL=ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-CN0CagvT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-ionic-ionic-field-errors-wrapper.component-CN0CagvT.mjs","mappings":";;;;;AAkBc;;;;;;;AALX;;;;AAPS","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/wrappers/field-errors/ionic-field-errors-wrapper.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { IonNote } from '@ionic/angular/standalone';\nimport { FieldErrorsWrapperBase, provideFieldErrorDisplay } from '@ng-forge/dynamic-forms/integration';\n\n/** Ionic rendering of a validation message for the wrapped field. Replaces the core default. */\n@Component({\n selector: 'df-ion-field-errors',\n imports: [IonNote],\n template: `\n <ng-container #fieldComponent></ng-container>\n @if (ngf.errorsToDisplay()[0]; as error) {\n <ion-note color=\"danger\" class=\"df-ion-error\" role=\"alert\" [id]=\"ngf.errorId()\">{{ error.message }}</ion-note>\n }\n `,\n styleUrl: './ionic-field-errors-wrapper.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [provideFieldErrorDisplay(() => IonicFieldErrorsWrapperComponent)],\n})\nexport default class IonicFieldErrorsWrapperComponent extends FieldErrorsWrapperBase {}\n\nexport { IonicFieldErrorsWrapperComponent };\n"]}
@@ -0,0 +1,75 @@
1
+ import { AsyncPipe } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { computed, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { IonButton, IonIcon, IonSpinner } from '@ionic/angular/standalone';
5
+ import * as i1 from '@ng-forge/dynamic-forms/integration';
6
+ import { injectNgForgeAddonAction, DynamicTextPipe, NgForgeAddonAction } from '@ng-forge/dynamic-forms/integration';
7
+
8
+ class IonicButtonAddonComponent {
9
+ action = injectNgForgeAddonAction();
10
+ addon = this.action.addon;
11
+ label = computed(() => this.addon().label, /* @ts-ignore */
12
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
13
+ ariaLabel = computed(() => this.addon().ariaLabel, /* @ts-ignore */
14
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
15
+ icon = computed(() => this.addon().icon, /* @ts-ignore */
16
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
17
+ color = computed(() => this.addon().color, /* @ts-ignore */
18
+ ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
19
+ fill = computed(() => this.addon().fill ?? 'clear', /* @ts-ignore */
20
+ ...(ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []));
21
+ iconOnly = computed(() => !!this.icon() && !this.label(), /* @ts-ignore */
22
+ ...(ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []));
23
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicButtonAddonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
24
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: IonicButtonAddonComponent, isStandalone: true, selector: "df-ion-button-addon", hostDirectives: [{ directive: i1.NgForgeAddonAction }], ngImport: i0, template: `
25
+ <ion-button
26
+ [attr.color]="color() ?? null"
27
+ [fill]="fill()"
28
+ [disabled]="action.disabled() || action.loading()"
29
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
30
+ [attr.aria-busy]="action.loading() || null"
31
+ (click)="action.dispatch()"
32
+ >
33
+ @if (action.loading()) {
34
+ <ion-spinner [slot]="iconOnly() ? 'icon-only' : 'start'" name="dots"></ion-spinner>
35
+ } @else if (icon(); as ic) {
36
+ <ion-icon [name]="ic" [slot]="iconOnly() ? 'icon-only' : 'start'"></ion-icon>
37
+ }
38
+ @if (label(); as lbl) {
39
+ {{ lbl | dynamicText | async }}
40
+ }
41
+ </ion-button>
42
+ @if (action.loading()) {
43
+ <span class="df-ion-sr-only" role="status">Loading…</span>
44
+ }
45
+ `, isInline: true, styles: [".df-ion-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicButtonAddonComponent, decorators: [{
48
+ type: Component,
49
+ args: [{ selector: 'df-ion-button-addon', imports: [IonButton, IonIcon, IonSpinner, DynamicTextPipe, AsyncPipe], hostDirectives: [NgForgeAddonAction], template: `
50
+ <ion-button
51
+ [attr.color]="color() ?? null"
52
+ [fill]="fill()"
53
+ [disabled]="action.disabled() || action.loading()"
54
+ [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"
55
+ [attr.aria-busy]="action.loading() || null"
56
+ (click)="action.dispatch()"
57
+ >
58
+ @if (action.loading()) {
59
+ <ion-spinner [slot]="iconOnly() ? 'icon-only' : 'start'" name="dots"></ion-spinner>
60
+ } @else if (icon(); as ic) {
61
+ <ion-icon [name]="ic" [slot]="iconOnly() ? 'icon-only' : 'start'"></ion-icon>
62
+ }
63
+ @if (label(); as lbl) {
64
+ {{ lbl | dynamicText | async }}
65
+ }
66
+ </ion-button>
67
+ @if (action.loading()) {
68
+ <span class="df-ion-sr-only" role="status">Loading…</span>
69
+ }
70
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-ion-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
71
+ }] });
72
+
73
+
74
+ export { IonicButtonAddonComponent };
75
+ //# sourceMappingURL=ng-forge-dynamic-forms-ionic-lazy-addon-button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-ionic-lazy-addon-button.mjs","mappings":";;;;;;;;;IAuDqB;;;;;;;AAKnB;;AAKmB;;AACnB,IAImB;;;AAnBR;;;;;;;;;;;;;;;;;;;;;;;;;AA1CD","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/addons/ion-button-addon.component.ts"],"sourcesContent":["import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed } from '@angular/core';\nimport { IonButton, IonIcon, IonSpinner } from '@ionic/angular/standalone';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeAddonAction, NgForgeAddonAction } from '@ng-forge/dynamic-forms/integration';\nimport type { IonicButtonAddon } from '@ng-forge/dynamic-forms-ionic/shared';\n\n/** Renderer for the `ion-button` addon type. */\n@Component({\n selector: 'df-ion-button-addon',\n imports: [IonButton, IonIcon, IonSpinner, DynamicTextPipe, AsyncPipe],\n hostDirectives: [NgForgeAddonAction],\n template: `\n <ion-button\n [attr.color]=\"color() ?? null\"\n [fill]=\"fill()\"\n [disabled]=\"action.disabled() || action.loading()\"\n [attr.aria-label]=\"(ariaLabel() | dynamicText | async) ?? null\"\n [attr.aria-busy]=\"action.loading() || null\"\n (click)=\"action.dispatch()\"\n >\n @if (action.loading()) {\n <ion-spinner [slot]=\"iconOnly() ? 'icon-only' : 'start'\" name=\"dots\"></ion-spinner>\n } @else if (icon(); as ic) {\n <ion-icon [name]=\"ic\" [slot]=\"iconOnly() ? 'icon-only' : 'start'\"></ion-icon>\n }\n @if (label(); as lbl) {\n {{ lbl | dynamicText | async }}\n }\n </ion-button>\n @if (action.loading()) {\n <span class=\"df-ion-sr-only\" role=\"status\">Loading…</span>\n }\n `,\n styles: [\n `\n .df-ion-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class IonicButtonAddonComponent {\n protected readonly action = injectNgForgeAddonAction<IonicButtonAddon>();\n\n /** Re-exposed for template binding — same signal stored on the directive. */\n protected readonly addon = this.action.addon;\n\n protected readonly label = computed(() => this.addon().label);\n protected readonly ariaLabel = computed(() => this.addon().ariaLabel);\n protected readonly icon = computed(() => this.addon().icon);\n /** Default color is undefined so the button inherits the theme's text color\n * (Ionic's `medium` would force low-contrast grey, which fails WCAG on dark\n * surfaces). Consumers can still set `color: 'primary' | 'success' | ...`\n * explicitly when they want adapter-styled coloring. */\n protected readonly color = computed(() => this.addon().color);\n protected readonly fill = computed(() => this.addon().fill ?? 'clear');\n /** Icon-only when there is an icon but no label — drives the `slot` choice.\n * Truthy check on `label` mirrors Material's heuristic; empty-string label\n * is treated as \"no label\" so the button doesn't render an invisible text\n * slot beside the icon. */\n protected readonly iconOnly = computed(() => !!this.icon() && !this.label());\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { AsyncPipe } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { IonIcon } from '@ionic/angular/standalone';
5
+ import { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';
6
+
7
+ class IonicIconAddonComponent {
8
+ addon = input.required(/* @ts-ignore */
9
+ ...(ngDevMode ? [{ debugName: "addon" }] : /* istanbul ignore next */ []));
10
+ fieldInputs = input(/* @ts-ignore */
11
+ ...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
12
+ iconName = computed(() => this.addon().icon, /* @ts-ignore */
13
+ ...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
14
+ ariaLabel = computed(() => this.addon().ariaLabel, /* @ts-ignore */
15
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
16
+ hasAriaLabel = computed(() => this.addon().ariaLabel !== undefined, /* @ts-ignore */
17
+ ...(ngDevMode ? [{ debugName: "hasAriaLabel" }] : /* istanbul ignore next */ []));
18
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicIconAddonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: IonicIconAddonComponent, isStandalone: true, selector: "df-ion-icon-addon", inputs: { addon: { classPropertyName: "addon", publicName: "addon", isSignal: true, isRequired: true, transformFunction: null }, fieldInputs: { classPropertyName: "fieldInputs", publicName: "fieldInputs", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-hidden": "hasAriaLabel() ? null : \"true\"" } }, ngImport: i0, template: `<ion-icon [name]="iconName()" [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"></ion-icon>`, isInline: true, dependencies: [{ kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
20
+ }
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicIconAddonComponent, decorators: [{
22
+ type: Component,
23
+ args: [{
24
+ selector: 'df-ion-icon-addon',
25
+ imports: [IonIcon, AsyncPipe, DynamicTextPipe],
26
+ template: `<ion-icon [name]="iconName()" [attr.aria-label]="(ariaLabel() | dynamicText | async) ?? null"></ion-icon>`,
27
+ host: {
28
+ '[attr.aria-hidden]': 'hasAriaLabel() ? null : "true"',
29
+ },
30
+ changeDetection: ChangeDetectionStrategy.OnPush,
31
+ }]
32
+ }], propDecorators: { addon: [{ type: i0.Input, args: [{ isSignal: true, alias: "addon", required: true }] }], fieldInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldInputs", required: false }] }] } });
33
+
34
+
35
+ export { IonicIconAddonComponent };
36
+ //# sourceMappingURL=ng-forge-dynamic-forms-ionic-lazy-addon-icon.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-ionic-lazy-addon-icon.mjs","mappings":";;;;;;;;;IAoBW;;;;;;AAIU;;;AAPR;;;;AATF;AACT;AACA;AACA;AACA;AACE;AACD;;AAEF","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/addons/ion-icon-addon.component.ts"],"sourcesContent":["import { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { IonIcon } from '@ionic/angular/standalone';\nimport { WrapperFieldInputs } from '@ng-forge/dynamic-forms/integration';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport type { IonicIconAddon } from '@ng-forge/dynamic-forms-ionic/shared';\n\n/** Renderer for the `ion-icon` addon type. */\n@Component({\n selector: 'df-ion-icon-addon',\n imports: [IonIcon, AsyncPipe, DynamicTextPipe],\n template: `<ion-icon [name]=\"iconName()\" [attr.aria-label]=\"(ariaLabel() | dynamicText | async) ?? null\"></ion-icon>`,\n host: {\n '[attr.aria-hidden]': 'hasAriaLabel() ? null : \"true\"',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class IonicIconAddonComponent {\n readonly addon = input.required<IonicIconAddon>();\n /** Accepted for contract uniformity — `NgComponentOutlet` setInput is strict; every type must declare it. */\n readonly fieldInputs = input<WrapperFieldInputs | undefined>();\n\n protected readonly iconName = computed(() => this.addon().icon);\n protected readonly ariaLabel = computed(() => this.addon().ariaLabel);\n protected readonly hasAriaLabel = computed(() => this.addon().ariaLabel !== undefined);\n}\n"]}
@@ -0,0 +1,70 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { IonButton } from '@ionic/angular/standalone';
4
+ import { AsyncPipe } from '@angular/common';
5
+ import * as i1 from '@ng-forge/dynamic-forms/integration';
6
+ import { injectNgForgeAction, DynamicTextPipe, NgForgeActionHost } from '@ng-forge/dynamic-forms/integration';
7
+
8
+ class IonicButtonFieldComponent {
9
+ action = injectNgForgeAction();
10
+ props = input(/* @ts-ignore */
11
+ ...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
12
+ buttonType = computed(() => this.props()?.type ?? 'button', /* @ts-ignore */
13
+ ...(ngDevMode ? [{ debugName: "buttonType" }] : /* istanbul ignore next */ []));
14
+ buttonTestId = computed(() => `${this.buttonType()}-${this.action.key()}`, /* @ts-ignore */
15
+ ...(ngDevMode ? [{ debugName: "buttonTestId" }] : /* istanbul ignore next */ []));
16
+ onClick() {
17
+ if (this.buttonType() === 'submit')
18
+ return;
19
+ this.action.dispatch();
20
+ }
21
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicButtonFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: IonicButtonFieldComponent, isStandalone: true, selector: "df-ion-button", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeActionHost }], ngImport: i0, template: `
23
+ @let buttonId = action.key() + '-button';
24
+
25
+ <ion-button
26
+ [id]="buttonId"
27
+ [type]="buttonType()"
28
+ [expand]="props()?.expand"
29
+ [fill]="props()?.fill || 'solid'"
30
+ [shape]="props()?.shape"
31
+ [size]="props()?.size"
32
+ [color]="props()?.color || 'primary'"
33
+ [strong]="props()?.strong"
34
+ [disabled]="action.disabled()"
35
+ [attr.tabindex]="action.tabIndex()"
36
+ [attr.data-testid]="buttonTestId()"
37
+ (click)="onClick()"
38
+ >
39
+ {{ action.label() | dynamicText | async }}
40
+ </ion-button>
41
+ `, isInline: true, styles: [":host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
42
+ }
43
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicButtonFieldComponent, decorators: [{
44
+ type: Component,
45
+ args: [{ selector: 'df-ion-button', imports: [IonButton, DynamicTextPipe, AsyncPipe], hostDirectives: [NgForgeActionHost], template: `
46
+ @let buttonId = action.key() + '-button';
47
+
48
+ <ion-button
49
+ [id]="buttonId"
50
+ [type]="buttonType()"
51
+ [expand]="props()?.expand"
52
+ [fill]="props()?.fill || 'solid'"
53
+ [shape]="props()?.shape"
54
+ [size]="props()?.size"
55
+ [color]="props()?.color || 'primary'"
56
+ [strong]="props()?.strong"
57
+ [disabled]="action.disabled()"
58
+ [attr.tabindex]="action.tabIndex()"
59
+ [attr.data-testid]="buttonTestId()"
60
+ (click)="onClick()"
61
+ >
62
+ {{ action.label() | dynamicText | async }}
63
+ </ion-button>
64
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host([hidden]){display:none!important}\n"] }]
65
+ }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
66
+
67
+
68
+
69
+ export { IonicButtonFieldComponent };
70
+ //# sourceMappingURL=ng-forge-dynamic-forms-ionic-lazy-button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-ionic-lazy-button.mjs","mappings":";;;;;;;AAyCc;;AAGH;;AAEA;;AAEA;;;AAGP;;AACA;;;AAXiB;;;;;;;;;;;;;;;;;;;AAHlB;;;;AA7BS","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/fields/button/ionic-button.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { IonButton } from '@ionic/angular/standalone';\nimport { AsyncPipe } from '@angular/common';\nimport { FormEvent } from '@ng-forge/dynamic-forms';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeAction, NgForgeActionHost } from '@ng-forge/dynamic-forms/integration';\nimport { IonicButtonProps } from './ionic-button.type';\n\n@Component({\n selector: 'df-ion-button',\n imports: [IonButton, DynamicTextPipe, AsyncPipe],\n hostDirectives: [NgForgeActionHost],\n styles: [\n `\n :host([hidden]) {\n display: none !important;\n }\n `,\n ],\n template: `\n @let buttonId = action.key() + '-button';\n\n <ion-button\n [id]=\"buttonId\"\n [type]=\"buttonType()\"\n [expand]=\"props()?.expand\"\n [fill]=\"props()?.fill || 'solid'\"\n [shape]=\"props()?.shape\"\n [size]=\"props()?.size\"\n [color]=\"props()?.color || 'primary'\"\n [strong]=\"props()?.strong\"\n [disabled]=\"action.disabled()\"\n [attr.tabindex]=\"action.tabIndex()\"\n [attr.data-testid]=\"buttonTestId()\"\n (click)=\"onClick()\"\n >\n {{ action.label() | dynamicText | async }}\n </ion-button>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class IonicButtonFieldComponent<TEvent extends FormEvent> {\n protected readonly action = injectNgForgeAction<TEvent>();\n\n readonly props = input<IonicButtonProps>();\n\n readonly buttonType = computed(() => this.props()?.type ?? 'button');\n\n readonly buttonTestId = computed(() => `${this.buttonType()}-${this.action.key()}`);\n\n onClick(): void {\n if (this.buttonType() === 'submit') return;\n this.action.dispatch();\n }\n}\n"]}
@@ -0,0 +1,67 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { FormField } from '@angular/forms/signals';
4
+ import { IonCheckbox, IonNote } from '@ionic/angular/standalone';
5
+ import * as i1 from '@ng-forge/dynamic-forms/integration';
6
+ import { injectNgForgeField, NgForgeControl, DynamicTextPipe, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';
7
+ import { AsyncPipe } from '@angular/common';
8
+
9
+ class IonicCheckboxFieldComponent {
10
+ ngf = injectNgForgeField();
11
+ props = input(/* @ts-ignore */
12
+ ...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
13
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicCheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: IonicCheckboxFieldComponent, isStandalone: true, selector: "df-ion-checkbox", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
15
+ @let f = ngf.field();
16
+ @let checkboxId = ngf.key() + '-checkbox';
17
+
18
+ <ion-checkbox
19
+ ngForgeControl
20
+ [id]="checkboxId"
21
+ [formField]="f"
22
+ [labelPlacement]="props()?.labelPlacement ?? 'end'"
23
+ [justify]="props()?.justify"
24
+ [color]="props()?.color ?? 'primary'"
25
+ [indeterminate]="props()?.indeterminate ?? false"
26
+ [attr.tabindex]="ngf.tabIndex()"
27
+ >
28
+ {{ ngf.label() | dynamicText | async }}
29
+ </ion-checkbox>
30
+
31
+ @if (ngf.errorsToDisplay()[0]; as error) {
32
+ <ion-note color="danger" class="df-ion-error" [id]="ngf.errorId()" role="alert">{{ error.message }}</ion-note>
33
+ } @else if (props()?.hint; as hint) {
34
+ <ion-note class="df-ion-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</ion-note>
35
+ }
36
+ `, 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{display:block}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
37
+ }
38
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicCheckboxFieldComponent, decorators: [{
39
+ type: Component,
40
+ args: [{ selector: 'df-ion-checkbox', imports: [IonCheckbox, IonNote, FormField, DynamicTextPipe, AsyncPipe, NgForgeControl], hostDirectives: [NgForgeFieldHost], template: `
41
+ @let f = ngf.field();
42
+ @let checkboxId = ngf.key() + '-checkbox';
43
+
44
+ <ion-checkbox
45
+ ngForgeControl
46
+ [id]="checkboxId"
47
+ [formField]="f"
48
+ [labelPlacement]="props()?.labelPlacement ?? 'end'"
49
+ [justify]="props()?.justify"
50
+ [color]="props()?.color ?? 'primary'"
51
+ [indeterminate]="props()?.indeterminate ?? false"
52
+ [attr.tabindex]="ngf.tabIndex()"
53
+ >
54
+ {{ ngf.label() | dynamicText | async }}
55
+ </ion-checkbox>
56
+
57
+ @if (ngf.errorsToDisplay()[0]; as error) {
58
+ <ion-note color="danger" class="df-ion-error" [id]="ngf.errorId()" role="alert">{{ error.message }}</ion-note>
59
+ } @else if (props()?.hint; as hint) {
60
+ <ion-note class="df-ion-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</ion-note>
61
+ }
62
+ `, changeDetection: ChangeDetectionStrategy.OnPush, 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{display:block}:host([hidden]){display:none!important}\n"] }]
63
+ }], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
64
+
65
+
66
+ export { IonicCheckboxFieldComponent };
67
+ //# sourceMappingURL=ng-forge-dynamic-forms-ionic-lazy-checkbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-ionic-lazy-checkbox.mjs","mappings":";;;;;;;;AAiDc;;AAGH;;;AAHU;;;;;;;;;;;;;;;;;;;;;;;;;;AAxCT","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/fields/checkbox/ionic-checkbox.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { IonCheckbox, IonNote } from '@ionic/angular/standalone';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { NgForgeControl, injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { IonicCheckboxProps } from './ionic-checkbox.type';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n selector: 'df-ion-checkbox',\n imports: [IonCheckbox, IonNote, FormField, DynamicTextPipe, AsyncPipe, NgForgeControl],\n hostDirectives: [NgForgeFieldHost],\n template: `\n @let f = ngf.field();\n @let checkboxId = ngf.key() + '-checkbox';\n\n <ion-checkbox\n ngForgeControl\n [id]=\"checkboxId\"\n [formField]=\"f\"\n [labelPlacement]=\"props()?.labelPlacement ?? 'end'\"\n [justify]=\"props()?.justify\"\n [color]=\"props()?.color ?? 'primary'\"\n [indeterminate]=\"props()?.indeterminate ?? false\"\n [attr.tabindex]=\"ngf.tabIndex()\"\n >\n {{ ngf.label() | dynamicText | async }}\n </ion-checkbox>\n\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 } @else if (props()?.hint; as hint) {\n <ion-note class=\"df-ion-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</ion-note>\n }\n `,\n styleUrl: '../../styles/_form-field.scss',\n styles: [\n `\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class IonicCheckboxFieldComponent {\n protected readonly ngf = injectNgForgeField<boolean>();\n\n readonly props = input<IonicCheckboxProps>();\n}\n"]}
@@ -0,0 +1,195 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, signal, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { IonInput, IonModal, IonDatetime, IonNote, IonButtons, IonHeader, IonContent, IonToolbar, IonTitle, IonButton } from '@ionic/angular/standalone';
4
+ import * as i1 from '@ng-forge/dynamic-forms/integration';
5
+ import { injectNgForgeField, NgForgeControl, DynamicTextPipe, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';
6
+ import { AsyncPipe } from '@angular/common';
7
+ import { format } from 'date-fns';
8
+
9
+ class IonicDatepickerFieldComponent {
10
+ ngf = injectNgForgeField();
11
+ minDate = input(null, /* @ts-ignore */
12
+ ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
13
+ maxDate = input(null, /* @ts-ignore */
14
+ ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
15
+ startAt = input(null, /* @ts-ignore */
16
+ ...(ngDevMode ? [{ debugName: "startAt" }] : /* istanbul ignore next */ []));
17
+ props = input(/* @ts-ignore */
18
+ ...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
19
+ isModalOpen = signal(false, /* @ts-ignore */
20
+ ...(ngDevMode ? [{ debugName: "isModalOpen" }] : /* istanbul ignore next */ []));
21
+ openModal() {
22
+ this.isModalOpen.set(true);
23
+ }
24
+ closeModal() {
25
+ this.isModalOpen.set(false);
26
+ }
27
+ onDateChange(event) {
28
+ const value = event.detail.value;
29
+ if (value && typeof value === 'string' && value.length > 0) {
30
+ const date = new Date(value);
31
+ this.ngf.field()().value.set(date);
32
+ }
33
+ else {
34
+ this.ngf.field()().value.set(null);
35
+ }
36
+ this.closeModal();
37
+ }
38
+ dateToIsoString(date) {
39
+ if (!date)
40
+ return undefined;
41
+ return date.toISOString();
42
+ }
43
+ formatDisplayDate(date) {
44
+ if (!date)
45
+ return '';
46
+ const presentation = this.props()?.presentation ?? 'date';
47
+ switch (presentation) {
48
+ case 'date':
49
+ return format(date, 'MMM d, yyyy');
50
+ case 'date-time':
51
+ case 'time-date':
52
+ return format(date, 'MMM d, yyyy, h:mm a');
53
+ case 'time':
54
+ return format(date, 'h:mm a');
55
+ case 'month':
56
+ return format(date, 'MMMM yyyy');
57
+ case 'month-year':
58
+ return format(date, 'MMM yyyy');
59
+ case 'year':
60
+ return format(date, 'yyyy');
61
+ default:
62
+ return format(date, 'MMM d, yyyy');
63
+ }
64
+ }
65
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicDatepickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
66
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: IonicDatepickerFieldComponent, isStandalone: true, selector: "df-ion-datepicker", inputs: { minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, startAt: { classPropertyName: "startAt", publicName: "startAt", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1.NgForgeFieldHost }], ngImport: i0, template: `
67
+ @let f = ngf.field();
68
+ @let dateValue = f().value();
69
+ @let inputId = ngf.key() + '-input';
70
+
71
+ <ion-input
72
+ ngForgeControl
73
+ [id]="inputId"
74
+ [label]="(ngf.label() | dynamicText | async) ?? undefined"
75
+ [labelPlacement]="'stacked'"
76
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
77
+ [disabled]="f().disabled()"
78
+ [value]="formatDisplayDate(dateValue)"
79
+ [readonly]="true"
80
+ [fill]="'outline'"
81
+ [attr.tabindex]="ngf.tabIndex()"
82
+ (click)="!f().disabled() && openModal()"
83
+ />
84
+ @if (ngf.errorsToDisplay()[0]; as error) {
85
+ <ion-note color="danger" class="df-ion-error" [id]="ngf.errorId()" role="alert">{{ error.message }}</ion-note>
86
+ } @else if (props()?.hint; as hint) {
87
+ <ion-note class="df-ion-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</ion-note>
88
+ }
89
+
90
+ <ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
91
+ <ng-template>
92
+ <ion-header>
93
+ <ion-toolbar>
94
+ <ion-title>{{ ngf.label() | dynamicText | async }}</ion-title>
95
+ <ion-buttons slot="end">
96
+ <ion-button (click)="closeModal()">Close</ion-button>
97
+ </ion-buttons>
98
+ </ion-toolbar>
99
+ </ion-header>
100
+ <ion-content>
101
+ <ion-datetime
102
+ [presentation]="props()?.presentation ?? 'date'"
103
+ [value]="dateToIsoString(dateValue)"
104
+ [multiple]="props()?.multiple ?? false"
105
+ [preferWheel]="props()?.preferWheel ?? false"
106
+ [showDefaultButtons]="props()?.showDefaultButtons ?? false"
107
+ [showDefaultTitle]="props()?.showDefaultTitle ?? false"
108
+ [showDefaultTimeLabel]="props()?.showDefaultTimeLabel ?? true"
109
+ [showClearButton]="props()?.showClearButton ?? false"
110
+ [color]="props()?.color"
111
+ [min]="dateToIsoString(minDate())"
112
+ [max]="dateToIsoString(maxDate())"
113
+ (ionChange)="onDateChange($event)"
114
+ >
115
+ </ion-datetime>
116
+ </ion-content>
117
+ </ng-template>
118
+ </ion-modal>
119
+ `, 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", "ion-input{cursor:pointer}:host([hidden]){display:none!important}\n"], dependencies: [{ kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonModal, selector: "ion-modal" }, { kind: "component", type: IonDatetime, selector: "ion-datetime", inputs: ["cancelText", "clearText", "color", "dayValues", "disabled", "doneText", "firstDayOfWeek", "formatOptions", "highlightedDates", "hourCycle", "hourValues", "isDateEnabled", "locale", "max", "min", "minuteValues", "mode", "monthValues", "multiple", "name", "preferWheel", "presentation", "readonly", "showAdjacentDays", "showClearButton", "showDefaultButtons", "showDefaultTimeLabel", "showDefaultTitle", "size", "titleSelectedDatesFormatter", "value", "yearValues"] }, { kind: "component", type: IonNote, selector: "ion-note", inputs: ["color", "mode"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "directive", type: NgForgeControl, selector: "[ngForgeControl]", inputs: ["ngForgeControl"] }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
120
+ }
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: IonicDatepickerFieldComponent, decorators: [{
122
+ type: Component,
123
+ args: [{ selector: 'df-ion-datepicker', imports: [
124
+ IonInput,
125
+ IonModal,
126
+ IonDatetime,
127
+ IonNote,
128
+ IonButtons,
129
+ IonHeader,
130
+ IonContent,
131
+ IonToolbar,
132
+ IonTitle,
133
+ IonButton,
134
+ DynamicTextPipe,
135
+ AsyncPipe,
136
+ NgForgeControl,
137
+ ], hostDirectives: [NgForgeFieldHost], template: `
138
+ @let f = ngf.field();
139
+ @let dateValue = f().value();
140
+ @let inputId = ngf.key() + '-input';
141
+
142
+ <ion-input
143
+ ngForgeControl
144
+ [id]="inputId"
145
+ [label]="(ngf.label() | dynamicText | async) ?? undefined"
146
+ [labelPlacement]="'stacked'"
147
+ [placeholder]="(ngf.placeholder() | dynamicText | async) ?? ''"
148
+ [disabled]="f().disabled()"
149
+ [value]="formatDisplayDate(dateValue)"
150
+ [readonly]="true"
151
+ [fill]="'outline'"
152
+ [attr.tabindex]="ngf.tabIndex()"
153
+ (click)="!f().disabled() && openModal()"
154
+ />
155
+ @if (ngf.errorsToDisplay()[0]; as error) {
156
+ <ion-note color="danger" class="df-ion-error" [id]="ngf.errorId()" role="alert">{{ error.message }}</ion-note>
157
+ } @else if (props()?.hint; as hint) {
158
+ <ion-note class="df-ion-hint" [id]="ngf.hintId()">{{ hint | dynamicText | async }}</ion-note>
159
+ }
160
+
161
+ <ion-modal [isOpen]="isModalOpen()" (didDismiss)="closeModal()">
162
+ <ng-template>
163
+ <ion-header>
164
+ <ion-toolbar>
165
+ <ion-title>{{ ngf.label() | dynamicText | async }}</ion-title>
166
+ <ion-buttons slot="end">
167
+ <ion-button (click)="closeModal()">Close</ion-button>
168
+ </ion-buttons>
169
+ </ion-toolbar>
170
+ </ion-header>
171
+ <ion-content>
172
+ <ion-datetime
173
+ [presentation]="props()?.presentation ?? 'date'"
174
+ [value]="dateToIsoString(dateValue)"
175
+ [multiple]="props()?.multiple ?? false"
176
+ [preferWheel]="props()?.preferWheel ?? false"
177
+ [showDefaultButtons]="props()?.showDefaultButtons ?? false"
178
+ [showDefaultTitle]="props()?.showDefaultTitle ?? false"
179
+ [showDefaultTimeLabel]="props()?.showDefaultTimeLabel ?? true"
180
+ [showClearButton]="props()?.showClearButton ?? false"
181
+ [color]="props()?.color"
182
+ [min]="dateToIsoString(minDate())"
183
+ [max]="dateToIsoString(maxDate())"
184
+ (ionChange)="onDateChange($event)"
185
+ >
186
+ </ion-datetime>
187
+ </ion-content>
188
+ </ng-template>
189
+ </ion-modal>
190
+ `, changeDetection: ChangeDetectionStrategy.OnPush, 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", "ion-input{cursor:pointer}:host([hidden]){display:none!important}\n"] }]
191
+ }], propDecorators: { minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], startAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAt", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
192
+
193
+
194
+ export { IonicDatepickerFieldComponent };
195
+ //# sourceMappingURL=ng-forge-dynamic-forms-ionic-lazy-datepicker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-forge-dynamic-forms-ionic-lazy-datepicker.mjs","mappings":";;;;;;;;AAyGc;;;;;;;;AAMH;;;;;AAKP;;;AAIA;;AAGF;AACE;gBAGA;AACE;AACA;;;AAEA;;;;AAKJ;AACE;AAAW;AACX;;AAGF;AACE;AAAW;;;AAKT;AACE;AACF;AACA;AACE;AACF;AACE;AACF;AACE;AACF;AACE;AACF;AACE;AACF;AACE;;;;AAxDa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AArFT","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-ionic/src/lib/fields/datepicker/ionic-datepicker.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, signal } from '@angular/core';\nimport {\n IonButton,\n IonButtons,\n IonContent,\n IonDatetime,\n IonHeader,\n IonInput,\n IonModal,\n IonNote,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { NgForgeControl, injectNgForgeField, NgForgeFieldHost } from '@ng-forge/dynamic-forms/integration';\nimport { IonicDatepickerProps } from './ionic-datepicker.type';\nimport { AsyncPipe } from '@angular/common';\nimport { format } from 'date-fns';\n\n@Component({\n selector: 'df-ion-datepicker',\n imports: [\n IonInput,\n IonModal,\n IonDatetime,\n IonNote,\n IonButtons,\n IonHeader,\n IonContent,\n IonToolbar,\n IonTitle,\n IonButton,\n DynamicTextPipe,\n AsyncPipe,\n NgForgeControl,\n ],\n hostDirectives: [NgForgeFieldHost],\n template: `\n @let f = ngf.field();\n @let dateValue = f().value();\n @let inputId = ngf.key() + '-input';\n\n <ion-input\n ngForgeControl\n [id]=\"inputId\"\n [label]=\"(ngf.label() | dynamicText | async) ?? undefined\"\n [labelPlacement]=\"'stacked'\"\n [placeholder]=\"(ngf.placeholder() | dynamicText | async) ?? ''\"\n [disabled]=\"f().disabled()\"\n [value]=\"formatDisplayDate(dateValue)\"\n [readonly]=\"true\"\n [fill]=\"'outline'\"\n [attr.tabindex]=\"ngf.tabIndex()\"\n (click)=\"!f().disabled() && openModal()\"\n />\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 } @else if (props()?.hint; as hint) {\n <ion-note class=\"df-ion-hint\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</ion-note>\n }\n\n <ion-modal [isOpen]=\"isModalOpen()\" (didDismiss)=\"closeModal()\">\n <ng-template>\n <ion-header>\n <ion-toolbar>\n <ion-title>{{ ngf.label() | dynamicText | async }}</ion-title>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"closeModal()\">Close</ion-button>\n </ion-buttons>\n </ion-toolbar>\n </ion-header>\n <ion-content>\n <ion-datetime\n [presentation]=\"props()?.presentation ?? 'date'\"\n [value]=\"dateToIsoString(dateValue)\"\n [multiple]=\"props()?.multiple ?? false\"\n [preferWheel]=\"props()?.preferWheel ?? false\"\n [showDefaultButtons]=\"props()?.showDefaultButtons ?? false\"\n [showDefaultTitle]=\"props()?.showDefaultTitle ?? false\"\n [showDefaultTimeLabel]=\"props()?.showDefaultTimeLabel ?? true\"\n [showClearButton]=\"props()?.showClearButton ?? false\"\n [color]=\"props()?.color\"\n [min]=\"dateToIsoString(minDate())\"\n [max]=\"dateToIsoString(maxDate())\"\n (ionChange)=\"onDateChange($event)\"\n >\n </ion-datetime>\n </ion-content>\n </ng-template>\n </ion-modal>\n `,\n styleUrl: '../../styles/_form-field.scss',\n styles: [\n `\n ion-input {\n cursor: pointer;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class IonicDatepickerFieldComponent {\n protected readonly ngf = injectNgForgeField<Date | null>();\n\n readonly minDate = input<Date | null>(null);\n readonly maxDate = input<Date | null>(null);\n readonly startAt = input<Date | null>(null);\n readonly props = input<IonicDatepickerProps>();\n\n readonly isModalOpen = signal(false);\n\n openModal() {\n this.isModalOpen.set(true);\n }\n\n closeModal() {\n this.isModalOpen.set(false);\n }\n\n onDateChange(event: CustomEvent) {\n const value = event.detail.value;\n // ion-datetime emits ISO 8601 strings internally; convert to Date | null\n // to match the field tree's value type.\n if (value && typeof value === 'string' && value.length > 0) {\n const date = new Date(value);\n this.ngf.field()().value.set(date);\n } else {\n this.ngf.field()().value.set(null);\n }\n this.closeModal();\n }\n\n dateToIsoString(date: Date | null | undefined): string | undefined {\n if (!date) return undefined;\n return date.toISOString();\n }\n\n formatDisplayDate(date: Date | null | undefined): string {\n if (!date) return '';\n\n const presentation = this.props()?.presentation ?? 'date';\n\n switch (presentation) {\n case 'date':\n return format(date, 'MMM d, yyyy');\n case 'date-time':\n case 'time-date':\n return format(date, 'MMM d, yyyy, h:mm a');\n case 'time':\n return format(date, 'h:mm a');\n case 'month':\n return format(date, 'MMMM yyyy');\n case 'month-year':\n return format(date, 'MMM yyyy');\n case 'year':\n return format(date, 'yyyy');\n default:\n return format(date, 'MMM d, yyyy');\n }\n }\n}\n"]}