@decaf-ts/for-angular 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE.md +157 -21
  2. package/README.md +0 -0
  3. package/dist/for-angular/README.md +0 -0
  4. package/dist/for-angular/assets/i18n/en.json +0 -0
  5. package/dist/for-angular/components/decaf-crud-field/decaf-crud-field.component.d.ts +33 -6
  6. package/dist/for-angular/components/decaf-crud-form/constants.d.ts +0 -0
  7. package/dist/for-angular/components/decaf-crud-form/decaf-crud-form.component.d.ts +4 -4
  8. package/dist/for-angular/components/decaf-crud-form/types.d.ts +0 -0
  9. package/dist/for-angular/components/decaf-model-renderer/decaf-model-renderer.component.d.ts +13 -13
  10. package/dist/for-angular/engine/DynamicModule.d.ts +0 -0
  11. package/dist/for-angular/engine/NgxCrudFormField.d.ts +16 -17
  12. package/dist/for-angular/engine/NgxFormService.d.ts +2 -2
  13. package/dist/for-angular/engine/NgxRenderingEngine.d.ts +7 -6
  14. package/dist/for-angular/engine/ValidatorFactory.d.ts +0 -0
  15. package/dist/for-angular/engine/constants.d.ts +3 -0
  16. package/dist/for-angular/engine/decorators.d.ts +0 -0
  17. package/dist/for-angular/engine/index.d.ts +0 -0
  18. package/dist/for-angular/engine/types.d.ts +15 -3
  19. package/dist/for-angular/esm2022/components/decaf-crud-field/decaf-crud-field.component.mjs +84 -21
  20. package/dist/for-angular/esm2022/components/decaf-crud-form/constants.mjs +0 -0
  21. package/dist/for-angular/esm2022/components/decaf-crud-form/decaf-crud-form.component.mjs +15 -19
  22. package/dist/for-angular/esm2022/components/decaf-crud-form/types.mjs +0 -0
  23. package/dist/for-angular/esm2022/components/decaf-model-renderer/decaf-model-renderer.component.mjs +30 -29
  24. package/dist/for-angular/esm2022/decaf-ts-for-angular.mjs +0 -0
  25. package/dist/for-angular/esm2022/engine/DynamicModule.mjs +0 -0
  26. package/dist/for-angular/esm2022/engine/NgxCrudFormField.mjs +6 -9
  27. package/dist/for-angular/esm2022/engine/NgxFormService.mjs +4 -1
  28. package/dist/for-angular/esm2022/engine/NgxRenderingEngine.mjs +52 -3
  29. package/dist/for-angular/esm2022/engine/ValidatorFactory.mjs +0 -0
  30. package/dist/for-angular/esm2022/engine/constants.mjs +4 -1
  31. package/dist/for-angular/esm2022/engine/decorators.mjs +5 -8
  32. package/dist/for-angular/esm2022/engine/index.mjs +0 -0
  33. package/dist/for-angular/esm2022/engine/types.mjs +1 -1
  34. package/dist/for-angular/esm2022/interfaces.mjs +0 -0
  35. package/dist/for-angular/esm2022/public-apis.mjs +2 -1
  36. package/dist/for-angular/fesm2022/decaf-ts-for-angular.mjs +237 -153
  37. package/dist/for-angular/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
  38. package/dist/for-angular/index.d.ts +0 -0
  39. package/dist/for-angular/interfaces.d.ts +0 -0
  40. package/dist/for-angular/public-apis.d.ts +1 -0
  41. package/package.json +3 -1
  42. package/dist/for-angular/directives/decaf-field.directive.d.ts +0 -8
  43. package/dist/for-angular/esm2022/directives/decaf-field.directive.mjs +0 -23
@@ -1,90 +1,166 @@
1
+ import { UIKeys, RenderingEngine, HTML5CheckTypes, escapeHtml, HTML5InputTypes, parseToNumber } from '@decaf-ts/ui-decorators';
1
2
  import * as i0 from '@angular/core';
2
- import { Component, Input, Directive, HostBinding, ElementRef, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, ViewChild, EventEmitter, Output } from '@angular/core';
3
- import { Model, Validation, ValidationKeys, sf } from '@decaf-ts/decorator-validation';
4
- import { IonSkeletonText, IonInput, IonItem, IonCheckbox, IonRadioGroup, IonRadio, IonSelect, IonSelectOption } from '@ionic/angular/standalone';
5
- import { NgComponentOutlet, NgClass } from '@angular/common';
3
+ import { reflectComponentType, TemplateRef, Component, Input, ViewChild, ElementRef, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, EventEmitter, Output } from '@angular/core';
4
+ import { Model, sf, Validation, ValidationKeys } from '@decaf-ts/decorator-validation';
5
+ import { NgComponentOutlet } from '@angular/common';
6
+ import { apply, metadata } from '@decaf-ts/reflection';
7
+ import { InternalError, OperationKeys } from '@decaf-ts/db-decorators';
8
+ import { __decorate } from 'tslib';
6
9
  import * as i1 from '@angular/forms';
7
10
  import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
8
- import { UIKeys, RenderingEngine, HTML5CheckTypes, escapeHtml, HTML5InputTypes, parseToNumber } from '@decaf-ts/ui-decorators';
11
+ import { IonInput, IonItem, IonCheckbox, IonRadioGroup, IonRadio, IonSelect, IonSelectOption, IonTextarea } from '@ionic/angular/standalone';
9
12
  import { TranslatePipe } from '@ngx-translate/core';
10
- import { OperationKeys, InternalError } from '@decaf-ts/db-decorators';
11
13
  import * as i1$1 from '@ionic/angular';
12
14
  import { IonicModule } from '@ionic/angular';
13
- import { apply, metadata } from '@decaf-ts/reflection';
15
+
16
+ const AngularEngineKeys = {
17
+ REFLECT: `${UIKeys.REFLECT}.angular.`,
18
+ DYNAMIC: 'dynamic-component',
19
+ ANNOTATIONS: '__annotations__',
20
+ ECMP: 'ecmp',
21
+ NG_REFLECT: 'ng-reflect-',
22
+ RENDERED: 'rendered-as-',
23
+ RENDERED_ID: 'rendered-as-{0}',
24
+ };
25
+ const FormConstants = {
26
+ VALID: 'VALID',
27
+ INVALID: 'INVALID',
28
+ };
29
+
30
+ class NgxRenderingEngine extends RenderingEngine {
31
+ constructor() {
32
+ super('angular');
33
+ }
34
+ fromFieldDefinition(fieldDef, vcr, injector, tpl) {
35
+ const component = NgxRenderingEngine.components(fieldDef.tag)
36
+ .constructor;
37
+ const componentMetadata = reflectComponentType(component);
38
+ if (!componentMetadata) {
39
+ throw new InternalError(`Metadata for component ${fieldDef.tag} not found.`);
40
+ }
41
+ const inputs = fieldDef.props;
42
+ const possibleInputs = componentMetadata.inputs;
43
+ const inputKeys = Object.keys(inputs);
44
+ for (let input of possibleInputs) {
45
+ const index = inputKeys.indexOf(input.propName);
46
+ if (index !== -1) {
47
+ inputKeys.splice(index, 1);
48
+ }
49
+ if (!inputKeys.length)
50
+ break;
51
+ }
52
+ if (inputKeys.length)
53
+ console.warn(`Unmapped input properties for component ${fieldDef.tag}: ${inputKeys.join(', ')}`);
54
+ const result = {
55
+ component: component,
56
+ inputs: inputs || {},
57
+ injector: injector,
58
+ };
59
+ if (fieldDef.rendererId) {
60
+ result.inputs['rendererId'] =
61
+ fieldDef.rendererId;
62
+ }
63
+ if (fieldDef.children && fieldDef.children.length) {
64
+ result.children = fieldDef.children.map((child) => {
65
+ return this.fromFieldDefinition(child, vcr, injector, tpl);
66
+ });
67
+ const template = vcr.createEmbeddedView(tpl, injector).rootNodes;
68
+ result.content = [template];
69
+ }
70
+ return result;
71
+ }
72
+ render(model, globalProps, vcr, injector, tpl) {
73
+ let result;
74
+ try {
75
+ const fieldDef = this.toFieldDefinition(model, globalProps);
76
+ result = this.fromFieldDefinition(fieldDef, vcr, injector, tpl);
77
+ }
78
+ catch (e) {
79
+ throw new InternalError(`Failed to render Model ${model.constructor.name}: ${e}`);
80
+ }
81
+ return result;
82
+ }
83
+ async initialize(...args) {
84
+ if (this.initialized)
85
+ return;
86
+ // ValidatableByType[]
87
+ this.initialized = true;
88
+ }
89
+ static registerComponent(name, constructor) {
90
+ if (!this._components)
91
+ this._components = {};
92
+ if (name in this._components)
93
+ throw new InternalError(`Component already registered under ${name}`);
94
+ this._components[name] = {
95
+ constructor: constructor,
96
+ };
97
+ }
98
+ static components(selector) {
99
+ if (!selector)
100
+ return Object.values(this._components);
101
+ if (!(selector in this._components))
102
+ throw new InternalError(`No Component registered under ${selector}`);
103
+ return this._components[selector];
104
+ }
105
+ static key(key) {
106
+ return `${AngularEngineKeys.REFLECT}${key}`;
107
+ }
108
+ }
109
+
110
+ function Dynamic() {
111
+ return apply((original) => {
112
+ const metadata = reflectComponentType(original);
113
+ if (!metadata)
114
+ throw new InternalError(`Could not find Component metadata. @Dynamic decorator must come above @Component`);
115
+ NgxRenderingEngine.registerComponent(metadata.selector, original);
116
+ }, metadata(NgxRenderingEngine.key(AngularEngineKeys.DYNAMIC), true));
117
+ }
118
+
119
+ class DynamicModule {
120
+ }
14
121
 
15
122
  class DecafModelRendererComponent {
16
- //
17
- // @ViewChild('componentElementContainer', {
18
- // static: true,
19
- // read: ViewContainerRef,
20
- // })
21
- // componentElementContainer!: ViewContainerRef;
22
- constructor(vcr) {
123
+ constructor(vcr, injector) {
23
124
  this.vcr = vcr;
125
+ this.injector = injector;
126
+ this.JSON = JSON;
24
127
  }
25
- ngOnInit() {
26
- this.model =
27
- typeof this.model === 'string'
28
- ? Model.build({}, JSON.parse(this.model))
29
- : this.model;
30
- // this.output = RenderingEngine.render(this.model as unknown as Model);
31
- // this.component = NgxRenderingEngine.components(this.output.tag);
32
- // this.props = this.output.props;
33
- // this.content = this.output.children?.map((child) => {
34
- // return this.vcr.createEmbeddedView();
35
- // });
128
+ refresh(model) {
129
+ model =
130
+ typeof model === 'string'
131
+ ? Model.build({}, JSON.parse(model))
132
+ : model;
133
+ this.output = model.render(this.globals || {}, this.vcr, this.injector, this.inner);
134
+ this.rendererId = sf(AngularEngineKeys.RENDERED_ID, this.output.inputs['rendererId']);
36
135
  }
37
136
  ngOnChanges(changes) {
38
137
  if (changes['model']) {
39
138
  const { currentValue, previousValue, firstChange } = changes['model'];
139
+ this.refresh(currentValue);
40
140
  }
41
- if (changes['details']) {
42
- const { currentValue, previousValue, firstChange } = changes['details'];
43
- }
141
+ // this.refresh();
142
+ }
143
+ ngOnDestroy() {
144
+ this.output = undefined;
44
145
  }
45
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafModelRendererComponent, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
46
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DecafModelRendererComponent, isStandalone: true, selector: "decaf-model-renderer", inputs: { model: "model" }, usesOnChanges: true, ngImport: i0, template: "<!--<div #loadingElement>-->\n<!-- <ion-skeleton-text [animated]=\"true\" style=\"width: 100%;\"></ion-skeleton-text>-->\n<!--</div>-->\n@if (output?.children?.length){\n @for (item of output.children; track item.props.name){\n <ng-template>{{item.props.name}}</ng-template>\n }\n}\n<ng-container *ngComponentOutlet=\"component;\n inputs: props;\n content: content;\">\n</ng-container>\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }] }); }
146
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafModelRendererComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
147
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DecafModelRendererComponent, isStandalone: true, selector: "decaf-model-renderer", inputs: { model: "model", globals: "globals", rendererId: "rendererId" }, viewQueries: [{ propertyName: "inner", first: true, predicate: ["inner"], descendants: true, read: (TemplateRef), static: true }], usesOnChanges: true, ngImport: i0, template: "<div #renderer>\n <ng-container #outer *ngComponentOutlet=\"output?.component;\n inputs: output?.inputs;\n content: output?.content;\">\n </ng-container>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\n @for (child of output?.children; track child.inputs.name) {\n <ng-container *ngComponentOutlet=\"child.component;\n injector: child.injector;\n inputs: child.inputs\n content: child.content\">\n </ng-container>\n }\n </div>\n </ng-template>\n</div>\n\n\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }] }); }
47
148
  }
48
149
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafModelRendererComponent, decorators: [{
49
150
  type: Component,
50
- args: [{ standalone: true, imports: [IonSkeletonText, NgComponentOutlet], selector: 'decaf-model-renderer', template: "<!--<div #loadingElement>-->\n<!-- <ion-skeleton-text [animated]=\"true\" style=\"width: 100%;\"></ion-skeleton-text>-->\n<!--</div>-->\n@if (output?.children?.length){\n @for (item of output.children; track item.props.name){\n <ng-template>{{item.props.name}}</ng-template>\n }\n}\n<ng-container *ngComponentOutlet=\"component;\n inputs: props;\n content: content;\">\n</ng-container>\n" }]
51
- }], ctorParameters: () => [{ type: i0.ViewContainerRef }], propDecorators: { model: [{
151
+ args: [{ standalone: true, imports: [NgComponentOutlet], selector: 'decaf-model-renderer', template: "<div #renderer>\n <ng-container #outer *ngComponentOutlet=\"output?.component;\n inputs: output?.inputs;\n content: output?.content;\">\n </ng-container>\n <ng-template #inner>\n <div [id]=\"rendererId || null\">\n @for (child of output?.children; track child.inputs.name) {\n <ng-container *ngComponentOutlet=\"child.component;\n injector: child.injector;\n inputs: child.inputs\n content: child.content\">\n </ng-container>\n }\n </div>\n </ng-template>\n</div>\n\n\n" }]
152
+ }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.Injector }], propDecorators: { model: [{
52
153
  type: Input,
53
154
  args: [{ required: true }]
155
+ }], globals: [{
156
+ type: Input
157
+ }], inner: [{
158
+ type: ViewChild,
159
+ args: ['inner', { read: (TemplateRef), static: true }]
160
+ }], rendererId: [{
161
+ type: Input
54
162
  }] } });
55
163
 
56
- class DecafFieldDirective {
57
- constructor() {
58
- this.name = this.fieldName;
59
- }
60
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
61
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: DecafFieldDirective, isStandalone: true, selector: "[appDecafField]", inputs: { fieldName: ["appDecafField", "fieldName"] }, host: { properties: { "#name": "this.name" } }, ngImport: i0 }); }
62
- }
63
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafFieldDirective, decorators: [{
64
- type: Directive,
65
- args: [{
66
- selector: '[appDecafField]',
67
- standalone: true,
68
- }]
69
- }], ctorParameters: () => [], propDecorators: { fieldName: [{
70
- type: Input,
71
- args: [{ alias: 'appDecafField' }]
72
- }], name: [{
73
- type: HostBinding,
74
- args: ['#name']
75
- }] } });
76
-
77
- const AngularEngineKeys = {
78
- REFLECT: `${UIKeys.REFLECT}.angular.`,
79
- DYNAMIC: 'dynamic-component',
80
- ANNOTATIONS: '__annotations__',
81
- NG_REFLECT: 'ng-reflect-',
82
- };
83
- const FormConstants = {
84
- VALID: 'VALID',
85
- INVALID: 'INVALID',
86
- };
87
-
88
164
  class ValidatorFactory {
89
165
  static spawn(key, arg) {
90
166
  if (!Validation.keys().includes(key))
@@ -338,6 +414,9 @@ class NgxFormService {
338
414
  throw new Error(`No parent with the tag ${tag} was found for provided element`);
339
415
  }
340
416
  static register(formId, control, props) {
417
+ if (formId.includes(AngularEngineKeys.RENDERED)) {
418
+ formId = formId.split(AngularEngineKeys.RENDERED)[1];
419
+ }
341
420
  this.controls[formId] = this.controls[formId] || {};
342
421
  this.controls[formId][props.name] = {
343
422
  control: control,
@@ -414,7 +493,7 @@ class NgxCrudFormField {
414
493
  * @param {boolean} isDisabled - Whether the field should be disabled
415
494
  */
416
495
  setDisabledState(isDisabled) {
417
- this.props.disabled = isDisabled;
496
+ this.disabled = isDisabled;
418
497
  }
419
498
  /**
420
499
  * @summary After view initialization logic
@@ -428,12 +507,12 @@ class NgxCrudFormField {
428
507
  case OperationKeys.UPDATE:
429
508
  case OperationKeys.DELETE:
430
509
  try {
431
- parent = NgxFormService.getParentEl(this.component.nativeElement, 'form');
510
+ parent = NgxFormService.getParentEl(this.component.nativeElement, 'div');
432
511
  }
433
512
  catch (e) {
434
513
  throw new Error(`Unable to retrieve parent form element for the ${this.operation}: ${e instanceof Error ? e.message : e}`);
435
514
  }
436
- NgxFormService.register(parent.id, this.formGroup, this.props);
515
+ NgxFormService.register(parent.id, this.formGroup, this);
437
516
  return parent;
438
517
  default:
439
518
  throw new Error(`Invalid operation: ${this.operation}`);
@@ -453,10 +532,7 @@ class NgxCrudFormField {
453
532
  * @param {FieldUpdateMode} updateOn - The update mode for the field
454
533
  */
455
534
  onInit(updateOn) {
456
- if (!this.props || !this.operation)
457
- throw new InternalError(`props and operation are required`);
458
- this.formGroup = NgxFormService.fromProps(this.props, updateOn);
459
- this.name = this.props.name;
535
+ this.formGroup = NgxFormService.fromProps(this, updateOn);
460
536
  }
461
537
  /**
462
538
  * @summary Get field errors
@@ -473,13 +549,18 @@ class NgxCrudFormField {
473
549
  }
474
550
  }
475
551
 
476
- // @Dynamic()
477
- class DecafCrudFieldComponent extends NgxCrudFormField {
552
+ let DecafCrudFieldComponent = class DecafCrudFieldComponent extends NgxCrudFormField {
478
553
  constructor() {
479
554
  super(...arguments);
555
+ this.value = '';
556
+ this.spellcheck = false;
557
+ this.inputmode = 'none';
558
+ this.autocomplete = 'off';
559
+ this.fill = 'outline';
560
+ this.labelPlacement = 'stacked';
561
+ // Component
480
562
  this.updateOn = 'change';
481
563
  this.translatable = true;
482
- this.HTML5InputTypes = Object.values(HTML5InputTypes);
483
564
  }
484
565
  ngAfterViewInit() {
485
566
  super.afterViewInit();
@@ -491,13 +572,15 @@ class DecafCrudFieldComponent extends NgxCrudFormField {
491
572
  super.onInit(this.updateOn);
492
573
  }
493
574
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafCrudFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
494
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DecafCrudFieldComponent, isStandalone: true, selector: "decaf-crud-field", inputs: { updateOn: "updateOn", operation: "operation", props: "props", name: "name", options: "options", formGroup: "formGroup", translatable: "translatable" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "<ng-container #component [formGroup]=\"formGroup\">\n @if(props.type === 'textarea') {\n <ion-item>\n <ion-textarea\n [ngClass]=\"props.className\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [required]=\"props.required !== undefined ? props.required : null\"\n [minlength]=\"props.minlength !== undefined ? props.minlength : null\"\n [maxlength]=\"props.maxlength !== undefined ? props.maxlength : null\"\n [readonly]=\"props.readonly !== undefined ? props.readonly : null\"\n [inputmode]=\"props.inputmode\"\n [spellcheck]=\"props.spellcheck\"\n [rows]=\"props.rows\"\n [labelPlacement]=\"props.labelPlacement\"\n [value]=\"props.value\"\n [fill]=\"props.fill\"\n [placeholder]=\"translatable ? (props.placeholder | translate) : props.placeholder\"\n [formControlName]=\"props.name\"\n [label]=\"translatable ? (props.label | translate) : props.label\">\n </ion-textarea>\n </ion-item>\n }\n @if(props.type === 'checkbox') {\n <ion-item [formControlName]=\"props.name\">\n <ion-checkbox\n #checkboxElement\n [name]=\"props.name\"\n [ngClass]=\"props.className\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [labelPlacement]=\"props.labelPlacement\"\n [alignment]=\"props.alignment\"\n [justify]=\"props.justify\"\n [disabled]=\"props.disabled || props.readonly\"\n [attr.checkedValue]=\"props.value\"\n [value]=\"props.value\"\n [checked]=\"props.checked\"\n (ionChange)=\"props.checked = !props.checked\"\n [formControlName]=\"props.name\">\n <span [innerHTML]=\"props.label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(props.type === 'radio') {\n <ion-radio-group [ngClass]=\"props.className\" [formControlName]=\"props.name\" [name]=\"props.name\" [value]=\"props.value\">\n <label class=\"radio-group-label\">{{props.label | translate}}</label>\n @for(option of options; track option.value) {\n <ion-item>\n <ion-radio\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [disabled]=\"props.readonly || props.disabled\"\n [labelPlacement]=\"props.labelPlacement\"\n [alignment]=\"props.alignment\"\n [justify]=\"props.justify\"\n [value]=\"option.value\"\n >{{ option.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(props.type === 'select') {\n <ion-item>\n <ion-select\n [name]=\"props.name\"\n [ngClass]=\"props.className\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [labelPlacement]=\"props.labelPlacement\"\n [cancelText]=\"props.cancelText | translate\"\n [label]=\"translatable ? (props.label | translate) : props.label\"\n [value]=\"props.value\"\n [fill]=\"props.fill\"\n [disabled]=\"props.readonly || props.disabled\"\n [placeholder]=\"props.placeholder | translate\"\n [formControlName]=\"props.name\"\n [interface]=\"props.interface\">\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ translatable ? (option.text | translate) : option.text }}\n </ion-select-option>\n }\n </ion-select>\n </ion-item>\n }\n @else if(HTML5InputTypes.includes(props.type)) {\n <ion-item>\n <ion-input\n [ngClass]=\"props.className\"\n [type]=\"props.type\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [inputmode]=\"props.inputmode\"\n [autocomplete]=\"props.autocomplete\"\n [spellcheck]=\"props.spellcheck\"\n [labelPlacement]=\"props.labelPlacement\"\n [required]=\"props.required !== undefined ? props.required : false\"\n [minlength]=\"props.minlength !== undefined ? props.minlength : null\"\n [maxlength]=\"props.maxlength !== undefined ? props.maxlength : null\"\n [readonly]=\"props.readonly !== undefined ? props.readonly : null\"\n [max]=\"props.max !== undefined ? props.max : null\"\n [min]=\"props.min !== undefined ? props.min : null\"\n [pattern]=\"props.pattern !== undefined ? props.pattern : null\"\n [step]=\"props.step !== undefined ? props.step : null\"\n [value]=\"props.value\"\n [fill]=\"props.fill\"\n [placeholder]=\"props.placeholder | translate\"\n [formControlName]=\"props.name\"\n [label]=\"props.label | translate\">\n </ion-input>\n </ion-item>\n }\n @else {\n <h1>INVALID FIELD TYPE</h1>\n }\n @if((!formGroup.pristine || formGroup.touched) && !formGroup.valid) {\n <div class=\"error uk-flex uk-flex-top\">\n @for(item of getErrors(); track item.key) {\n <p>\n <span color=\"danger\" class=\"ti ti-alert-triangle\"></span>\n <span>{{item.key}} - {{ sf((\"errors.\" + item.message) | translate, props[item.key]) }}</span>\n </p>\n }\n </div>\n }\n</ng-container>\n", styles: [".disabled{opacity:.7;pointer-events:none;touch-action:none}.disabled *{pointer-events:none;touch-action:none}.proccessing,.proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-item{--border-color: transparent;--padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-hover: var(--ion-color-primary);--background-activated-opacity: .15;--background-focused: var(--ion-color-primary);--background-focused-opacity: .15}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.select-label-placement-floating::part(label){line-height:1.2rem!important}.radio-group-label{margin-left:.5rem}.radio-group-label+ion-item{margin-top:.5rem}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--ion-color-primary);--checkmark-width: 2px}ion-checkbox::part(container){border-radius:50%;border:2px solid var(--ion-color-primary);padding:3px}ion-item+.helper,ion-radio-group+.helper{padding-left:.75rem;position:relative}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "expandedIcon", "fill", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }] }); }
495
- }
575
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DecafCrudFieldComponent, isStandalone: true, selector: "decaf-crud-field", inputs: { operation: "operation", name: "name", type: "type", value: "value", disabled: "disabled", label: "label", placeholder: "placeholder", format: "format", hidden: "hidden", max: "max", maxlength: "maxlength", min: "min", minlength: "minlength", pattern: "pattern", readonly: "readonly", required: "required", step: "step", cols: "cols", rows: "rows", alignment: "alignment", checked: "checked", justify: "justify", cancelText: "cancelText", interface: "interface", options: "options", mode: "mode", spellcheck: "spellcheck", inputmode: "inputmode", autocomplete: "autocomplete", fill: "fill", labelPlacement: "labelPlacement", updateOn: "updateOn", formGroup: "formGroup", translatable: "translatable" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["component"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: "<ng-container #component [formGroup]=\"formGroup\">\n @if(type === 'textarea') {\n <ion-item>\n <ion-textarea\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [required]=\"required !== undefined ? required : null\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [label]=\"translatable ? (label | translate) : label\">\n </ion-textarea>\n </ion-item>\n }\n @if(type === 'checkbox') {\n <ion-item [formControlName]=\"name\">\n <ion-checkbox\n #checkboxElement\n [name]=\"name\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [disabled]=\"disabled || readonly\"\n [value]=\"value\"\n [checked]=\"checked\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\">\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [name]=\"name\" [value]=\"value\">\n <label class=\"radio-group-label\">{{label | translate}}</label>\n @for(option of options; track option.value) {\n <ion-item>\n <ion-radio\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [disabled]=\"readonly || disabled\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n >{{ option.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-item>\n <ion-select\n [name]=\"name\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [cancelText]=\"cancelText | translate\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [disabled]=\"readonly || disabled\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\">\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ translatable ? (option.text | translate) : option.text }}\n </ion-select-option>\n }\n </ion-select>\n </ion-item>\n }\n @else {\n <ion-item>\n <ion-input\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [autocomplete]=\"autocomplete\"\n [spellcheck]=\"spellcheck\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\">\n </ion-input>\n </ion-item>\n }\n @if((!formGroup.pristine || formGroup.touched) && !formGroup.valid) {\n <div class=\"error uk-flex uk-flex-top\">\n @for(item of getErrors(); track item.key) {\n <p>\n <span color=\"danger\" class=\"ti ti-alert-triangle\"></span>\n <span>{{item.key}} - {{ sf((\"errors.\" + item.message) | translate, this[item.key]) }}</span>\n </p>\n }\n </div>\n }\n</ng-container>\n", styles: [".disabled{opacity:.7;pointer-events:none;touch-action:none}.disabled *{pointer-events:none;touch-action:none}.proccessing,.proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-item{--border-color: transparent;--padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-hover: var(--ion-color-primary);--background-activated-opacity: .15;--background-focused: var(--ion-color-primary);--background-focused-opacity: .15}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.select-label-placement-floating::part(label){line-height:1.2rem!important}.radio-group-label{margin-left:.5rem}.radio-group-label+ion-item{margin-top:.5rem}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--ion-color-primary);--checkmark-width: 2px}ion-checkbox::part(container){border-radius:50%;border:2px solid var(--ion-color-primary);padding:3px}ion-item+.helper,ion-radio-group+.helper{padding-left:.75rem;position:relative}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { 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: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "expandedIcon", "fill", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonTextarea, selector: "ion-textarea", inputs: ["autoGrow", "autocapitalize", "autofocus", "clearOnEdit", "color", "cols", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "maxlength", "minlength", "mode", "name", "placeholder", "readonly", "required", "rows", "shape", "spellcheck", "value", "wrap"] }] }); }
576
+ };
577
+ DecafCrudFieldComponent = __decorate([
578
+ Dynamic()
579
+ ], DecafCrudFieldComponent);
496
580
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafCrudFieldComponent, decorators: [{
497
581
  type: Component,
498
582
  args: [{ standalone: true, imports: [
499
583
  ReactiveFormsModule,
500
- NgClass,
501
584
  IonInput,
502
585
  IonItem,
503
586
  IonCheckbox,
@@ -506,23 +589,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
506
589
  IonSelect,
507
590
  TranslatePipe,
508
591
  IonSelectOption,
509
- DecafFieldDirective,
510
- ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], selector: 'decaf-crud-field', template: "<ng-container #component [formGroup]=\"formGroup\">\n @if(props.type === 'textarea') {\n <ion-item>\n <ion-textarea\n [ngClass]=\"props.className\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [required]=\"props.required !== undefined ? props.required : null\"\n [minlength]=\"props.minlength !== undefined ? props.minlength : null\"\n [maxlength]=\"props.maxlength !== undefined ? props.maxlength : null\"\n [readonly]=\"props.readonly !== undefined ? props.readonly : null\"\n [inputmode]=\"props.inputmode\"\n [spellcheck]=\"props.spellcheck\"\n [rows]=\"props.rows\"\n [labelPlacement]=\"props.labelPlacement\"\n [value]=\"props.value\"\n [fill]=\"props.fill\"\n [placeholder]=\"translatable ? (props.placeholder | translate) : props.placeholder\"\n [formControlName]=\"props.name\"\n [label]=\"translatable ? (props.label | translate) : props.label\">\n </ion-textarea>\n </ion-item>\n }\n @if(props.type === 'checkbox') {\n <ion-item [formControlName]=\"props.name\">\n <ion-checkbox\n #checkboxElement\n [name]=\"props.name\"\n [ngClass]=\"props.className\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [labelPlacement]=\"props.labelPlacement\"\n [alignment]=\"props.alignment\"\n [justify]=\"props.justify\"\n [disabled]=\"props.disabled || props.readonly\"\n [attr.checkedValue]=\"props.value\"\n [value]=\"props.value\"\n [checked]=\"props.checked\"\n (ionChange)=\"props.checked = !props.checked\"\n [formControlName]=\"props.name\">\n <span [innerHTML]=\"props.label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(props.type === 'radio') {\n <ion-radio-group [ngClass]=\"props.className\" [formControlName]=\"props.name\" [name]=\"props.name\" [value]=\"props.value\">\n <label class=\"radio-group-label\">{{props.label | translate}}</label>\n @for(option of options; track option.value) {\n <ion-item>\n <ion-radio\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [disabled]=\"props.readonly || props.disabled\"\n [labelPlacement]=\"props.labelPlacement\"\n [alignment]=\"props.alignment\"\n [justify]=\"props.justify\"\n [value]=\"option.value\"\n >{{ option.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(props.type === 'select') {\n <ion-item>\n <ion-select\n [name]=\"props.name\"\n [ngClass]=\"props.className\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [labelPlacement]=\"props.labelPlacement\"\n [cancelText]=\"props.cancelText | translate\"\n [label]=\"translatable ? (props.label | translate) : props.label\"\n [value]=\"props.value\"\n [fill]=\"props.fill\"\n [disabled]=\"props.readonly || props.disabled\"\n [placeholder]=\"props.placeholder | translate\"\n [formControlName]=\"props.name\"\n [interface]=\"props.interface\">\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ translatable ? (option.text | translate) : option.text }}\n </ion-select-option>\n }\n </ion-select>\n </ion-item>\n }\n @else if(HTML5InputTypes.includes(props.type)) {\n <ion-item>\n <ion-input\n [ngClass]=\"props.className\"\n [type]=\"props.type\"\n [mode]=\"props.mode\"\n [hidden]=\"props.hidden\"\n [inputmode]=\"props.inputmode\"\n [autocomplete]=\"props.autocomplete\"\n [spellcheck]=\"props.spellcheck\"\n [labelPlacement]=\"props.labelPlacement\"\n [required]=\"props.required !== undefined ? props.required : false\"\n [minlength]=\"props.minlength !== undefined ? props.minlength : null\"\n [maxlength]=\"props.maxlength !== undefined ? props.maxlength : null\"\n [readonly]=\"props.readonly !== undefined ? props.readonly : null\"\n [max]=\"props.max !== undefined ? props.max : null\"\n [min]=\"props.min !== undefined ? props.min : null\"\n [pattern]=\"props.pattern !== undefined ? props.pattern : null\"\n [step]=\"props.step !== undefined ? props.step : null\"\n [value]=\"props.value\"\n [fill]=\"props.fill\"\n [placeholder]=\"props.placeholder | translate\"\n [formControlName]=\"props.name\"\n [label]=\"props.label | translate\">\n </ion-input>\n </ion-item>\n }\n @else {\n <h1>INVALID FIELD TYPE</h1>\n }\n @if((!formGroup.pristine || formGroup.touched) && !formGroup.valid) {\n <div class=\"error uk-flex uk-flex-top\">\n @for(item of getErrors(); track item.key) {\n <p>\n <span color=\"danger\" class=\"ti ti-alert-triangle\"></span>\n <span>{{item.key}} - {{ sf((\"errors.\" + item.message) | translate, props[item.key]) }}</span>\n </p>\n }\n </div>\n }\n</ng-container>\n", styles: [".disabled{opacity:.7;pointer-events:none;touch-action:none}.disabled *{pointer-events:none;touch-action:none}.proccessing,.proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-item{--border-color: transparent;--padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-hover: var(--ion-color-primary);--background-activated-opacity: .15;--background-focused: var(--ion-color-primary);--background-focused-opacity: .15}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.select-label-placement-floating::part(label){line-height:1.2rem!important}.radio-group-label{margin-left:.5rem}.radio-group-label+ion-item{margin-top:.5rem}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--ion-color-primary);--checkmark-width: 2px}ion-checkbox::part(container){border-radius:50%;border:2px solid var(--ion-color-primary);padding:3px}ion-item+.helper,ion-radio-group+.helper{padding-left:.75rem;position:relative}\n"] }]
511
- }], propDecorators: { updateOn: [{
512
- type: Input
513
- }], component: [{
514
- type: ViewChild,
515
- args: ['component', { read: ElementRef }]
516
- }], operation: [{
592
+ IonTextarea,
593
+ ], schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA], selector: 'decaf-crud-field', template: "<ng-container #component [formGroup]=\"formGroup\">\n @if(type === 'textarea') {\n <ion-item>\n <ion-textarea\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [required]=\"required !== undefined ? required : null\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [inputmode]=\"inputmode\"\n [spellcheck]=\"spellcheck\"\n [rows]=\"rows\"\n [labelPlacement]=\"labelPlacement\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"translatable ? (placeholder | translate) : placeholder\"\n [formControlName]=\"name\"\n [label]=\"translatable ? (label | translate) : label\">\n </ion-textarea>\n </ion-item>\n }\n @if(type === 'checkbox') {\n <ion-item [formControlName]=\"name\">\n <ion-checkbox\n #checkboxElement\n [name]=\"name\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"justify\"\n [disabled]=\"disabled || readonly\"\n [value]=\"value\"\n [checked]=\"checked\"\n (ionChange)=\"checked = !checked\"\n [formControlName]=\"name\">\n <span [innerHTML]=\"label | translate\"></span>\n </ion-checkbox>\n </ion-item>\n }\n @else if(type === 'radio') {\n <ion-radio-group [formControlName]=\"name\" [name]=\"name\" [value]=\"value\">\n <label class=\"radio-group-label\">{{label | translate}}</label>\n @for(option of options; track option.value) {\n <ion-item>\n <ion-radio\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [disabled]=\"readonly || disabled\"\n [labelPlacement]=\"labelPlacement\"\n [alignment]=\"alignment\"\n [justify]=\"justify\"\n [value]=\"option.value\"\n >{{ option.text | translate }}</ion-radio>\n </ion-item>\n }\n </ion-radio-group>\n }\n @else if(type === 'select') {\n <ion-item>\n <ion-select\n [name]=\"name\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [labelPlacement]=\"labelPlacement\"\n [cancelText]=\"cancelText | translate\"\n [label]=\"translatable ? (label | translate) : label\"\n [value]=\"value\"\n [fill]=\"fill\"\n [disabled]=\"readonly || disabled\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [interface]=\"interface\">\n @for(option of options; track option.value) {\n <ion-select-option [value]=\"option.value\">\n {{ translatable ? (option.text | translate) : option.text }}\n </ion-select-option>\n }\n </ion-select>\n </ion-item>\n }\n @else {\n <ion-item>\n <ion-input\n [type]=\"type\"\n [mode]=\"mode\"\n [hidden]=\"hidden\"\n [inputmode]=\"inputmode\"\n [autocomplete]=\"autocomplete\"\n [spellcheck]=\"spellcheck\"\n [labelPlacement]=\"labelPlacement\"\n [required]=\"required !== undefined ? required : false\"\n [minlength]=\"minlength !== undefined ? minlength : null\"\n [maxlength]=\"maxlength !== undefined ? maxlength : null\"\n [readonly]=\"readonly !== undefined ? readonly : null\"\n [max]=\"max !== undefined ? max : null\"\n [min]=\"min !== undefined ? min : null\"\n [pattern]=\"pattern !== undefined ? pattern : null\"\n [step]=\"step !== undefined ? step : null\"\n [value]=\"value\"\n [fill]=\"fill\"\n [placeholder]=\"placeholder | translate\"\n [formControlName]=\"name\"\n [label]=\"label | translate\">\n </ion-input>\n </ion-item>\n }\n @if((!formGroup.pristine || formGroup.touched) && !formGroup.valid) {\n <div class=\"error uk-flex uk-flex-top\">\n @for(item of getErrors(); track item.key) {\n <p>\n <span color=\"danger\" class=\"ti ti-alert-triangle\"></span>\n <span>{{item.key}} - {{ sf((\"errors.\" + item.message) | translate, this[item.key]) }}</span>\n </p>\n }\n </div>\n }\n</ng-container>\n", styles: [".disabled{opacity:.7;pointer-events:none;touch-action:none}.disabled *{pointer-events:none;touch-action:none}.proccessing,.proccessing *{pointer-events:none;touch-action:none;cursor:text}ion-item{--border-color: transparent;--padding-start: .75rem;--background: transparent;--background-hover-opacity: .1;--background-hover: var(--ion-color-primary);--background-activated-opacity: .15;--background-focused: var(--ion-color-primary);--background-focused-opacity: .15}ion-textarea textarea{scrollbar-width:thin!important;margin-bottom:.5rem!important}ion-select.select-label-placement-floating::part(label){line-height:1.2rem!important}.radio-group-label{margin-left:.5rem}.radio-group-label+ion-item{margin-top:.5rem}ion-checkbox{--size: 1.5rem;--checkbox-background-checked: var(--ion-color-primary);--checkmark-width: 2px}ion-checkbox::part(container){border-radius:50%;border:2px solid var(--ion-color-primary);padding:3px}ion-item+.helper,ion-radio-group+.helper{padding-left:.75rem;position:relative}\n"] }]
594
+ }], propDecorators: { operation: [{
517
595
  type: Input,
518
596
  args: [{ required: true }]
519
- }], props: [{
597
+ }], name: [{
520
598
  type: Input,
521
599
  args: [{ required: true }]
522
- }], name: [{
600
+ }], type: [{
601
+ type: Input,
602
+ args: [{ required: true }]
603
+ }], value: [{
604
+ type: Input
605
+ }], disabled: [{
606
+ type: Input
607
+ }], label: [{
608
+ type: Input,
609
+ args: [{ required: true }]
610
+ }], placeholder: [{
611
+ type: Input
612
+ }], format: [{
613
+ type: Input
614
+ }], hidden: [{
615
+ type: Input
616
+ }], max: [{
617
+ type: Input
618
+ }], maxlength: [{
619
+ type: Input
620
+ }], min: [{
621
+ type: Input
622
+ }], minlength: [{
623
+ type: Input
624
+ }], pattern: [{
625
+ type: Input
626
+ }], readonly: [{
627
+ type: Input
628
+ }], required: [{
629
+ type: Input
630
+ }], step: [{
631
+ type: Input
632
+ }], cols: [{
633
+ type: Input
634
+ }], rows: [{
635
+ type: Input
636
+ }], alignment: [{
637
+ type: Input
638
+ }], checked: [{
639
+ type: Input
640
+ }], justify: [{
641
+ type: Input
642
+ }], cancelText: [{
643
+ type: Input
644
+ }], interface: [{
523
645
  type: Input
524
646
  }], options: [{
525
647
  type: Input
648
+ }], mode: [{
649
+ type: Input
650
+ }], spellcheck: [{
651
+ type: Input
652
+ }], inputmode: [{
653
+ type: Input
654
+ }], autocomplete: [{
655
+ type: Input
656
+ }], fill: [{
657
+ type: Input
658
+ }], labelPlacement: [{
659
+ type: Input
660
+ }], updateOn: [{
661
+ type: Input
662
+ }], component: [{
663
+ type: ViewChild,
664
+ args: ['component', { read: ElementRef }]
526
665
  }], formGroup: [{
527
666
  type: Input
528
667
  }], translatable: [{
@@ -543,7 +682,7 @@ const DefaultFormReactiveOptions = {
543
682
  },
544
683
  };
545
684
 
546
- class DecafCrudFormComponent {
685
+ let DecafCrudFormComponent = class DecafCrudFormComponent {
547
686
  constructor() {
548
687
  this.updateOn = 'change';
549
688
  this.target = '_self';
@@ -552,15 +691,13 @@ class DecafCrudFormComponent {
552
691
  this.submitEvent = new EventEmitter();
553
692
  }
554
693
  ngAfterViewInit() {
555
- NgxFormService.formAfterViewInit(this, this.formId);
694
+ NgxFormService.formAfterViewInit(this, this.rendererId);
556
695
  }
557
696
  ngOnInit() {
558
697
  this.options = Object.assign({}, DefaultFormReactiveOptions, this.options || {});
559
- if (!this.formId)
560
- this.formId = Date.now().toString();
561
698
  }
562
699
  ngOnDestroy() {
563
- NgxFormService.forOnDestroy(this, this.formId);
700
+ NgxFormService.forOnDestroy(this, this.rendererId);
564
701
  }
565
702
  /**
566
703
  * @param {Event} event
@@ -573,28 +710,23 @@ class DecafCrudFormComponent {
573
710
  return NgxFormService.validateFields(this.formGroup);
574
711
  console.log('onSubmit');
575
712
  // fix para valores de campos radio e check
576
- const data = NgxFormService.getFormData(this.formId);
713
+ const data = NgxFormService.getFormData(this.rendererId);
577
714
  const submitEvent = {
578
715
  data: data,
579
716
  };
580
717
  if (this.action)
581
718
  return this.component.nativeElement.dispatchEvent(new CustomEvent('submit', data));
582
719
  this.submitEvent.emit(submitEvent);
583
- // self.emitEvent({
584
- // role: button?.role || FORM_BUTTON_ROLES.SUBMIT,
585
- // data,
586
- // reset: button?.reset,
587
- // operation: self.operation,
588
- // eventName: self.eventName,
589
- // event,
590
- // } as FormReactiveSubmitEvent);
591
720
  }
592
721
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafCrudFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
593
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DecafCrudFormComponent, isStandalone: true, selector: "decaf-crud-form", inputs: { updateOn: "updateOn", target: "target", method: "method", options: "options", action: "action", operation: "operation", formGroup: "formGroup", formId: "formId" }, outputs: { submitEvent: "submitEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["reactiveForm"], descendants: true, read: ElementRef }], ngImport: i0, template: "<form #reactiveForm [id]=\"formId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"buttons-container\">\n <ion-button\n type=\"submit\">\n<!-- [shape]=\"buttons?.submit?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.submit?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.submit?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.submit?.fill || 'solid'\"-->\n<!-- [disabled]=\"buttons?.submit?.disabled || false\"-->\n<!-- expand=\"block\"-->\n<!-- [disabled]=\"disableSubmitButtonWhenInvalid ? !form.valid : false\"-->\n @if(options.buttons.submit.icon) {\n <ion-icon [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n @if(options.buttons.clear) {\n <ion-button>\n<!-- type=\"clear\"-->\n<!-- (click)=\"clear($event)\"-->\n<!-- [shape]=\"buttons?.clear?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.clear?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.clear?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.clear?.fill || 'clear'\"-->\n<!-- [disabled]=\"buttons?.clear?.disabled || false\"-->\n<!-- expand=\"block\"-->\n @if(options.buttons.clear?.icon) {\n <ion-icon [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{options.buttons.clear?.text}}\n </ion-button>\n }\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: IonicModule }, { kind: "component", type: i1$1.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: i1$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
594
- }
722
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DecafCrudFormComponent, isStandalone: true, selector: "decaf-crud-form", inputs: { updateOn: "updateOn", target: "target", method: "method", options: "options", action: "action", operation: "operation", formGroup: "formGroup", rendererId: "rendererId" }, outputs: { submitEvent: "submitEvent" }, viewQueries: [{ propertyName: "component", first: true, predicate: ["reactiveForm"], descendants: true, read: ElementRef }], ngImport: i0, template: "<form #reactiveForm [id]=\"rendererId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"buttons-container\">\n <ion-button\n type=\"submit\">\n<!-- [shape]=\"buttons?.submit?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.submit?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.submit?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.submit?.fill || 'solid'\"-->\n<!-- [disabled]=\"buttons?.submit?.disabled || false\"-->\n<!-- expand=\"block\"-->\n<!-- [disabled]=\"disableSubmitButtonWhenInvalid ? !form.valid : false\"-->\n @if(options.buttons.submit.icon) {\n <ion-icon [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n @if(options.buttons.clear) {\n <ion-button>\n<!-- type=\"clear\"-->\n<!-- (click)=\"clear($event)\"-->\n<!-- [shape]=\"buttons?.clear?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.clear?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.clear?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.clear?.fill || 'clear'\"-->\n<!-- [disabled]=\"buttons?.clear?.disabled || false\"-->\n<!-- expand=\"block\"-->\n @if(options.buttons.clear?.icon) {\n <ion-icon [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{options.buttons.clear?.text}}\n </ion-button>\n }\n </div>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: IonicModule }, { kind: "component", type: i1$1.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: i1$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
723
+ };
724
+ DecafCrudFormComponent = __decorate([
725
+ Dynamic()
726
+ ], DecafCrudFormComponent);
595
727
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DecafCrudFormComponent, decorators: [{
596
728
  type: Component,
597
- args: [{ standalone: true, selector: 'decaf-crud-form', imports: [IonicModule, ReactiveFormsModule], template: "<form #reactiveForm [id]=\"formId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"buttons-container\">\n <ion-button\n type=\"submit\">\n<!-- [shape]=\"buttons?.submit?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.submit?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.submit?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.submit?.fill || 'solid'\"-->\n<!-- [disabled]=\"buttons?.submit?.disabled || false\"-->\n<!-- expand=\"block\"-->\n<!-- [disabled]=\"disableSubmitButtonWhenInvalid ? !form.valid : false\"-->\n @if(options.buttons.submit.icon) {\n <ion-icon [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n @if(options.buttons.clear) {\n <ion-button>\n<!-- type=\"clear\"-->\n<!-- (click)=\"clear($event)\"-->\n<!-- [shape]=\"buttons?.clear?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.clear?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.clear?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.clear?.fill || 'clear'\"-->\n<!-- [disabled]=\"buttons?.clear?.disabled || false\"-->\n<!-- expand=\"block\"-->\n @if(options.buttons.clear?.icon) {\n <ion-icon [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{options.buttons.clear?.text}}\n </ion-button>\n }\n </div>\n</form>\n" }]
729
+ args: [{ standalone: true, selector: 'decaf-crud-form', imports: [IonicModule, ReactiveFormsModule], template: "<form #reactiveForm [id]=\"rendererId\" [formGroup]=\"formGroup\" (submit)=\"submit($event)\" [target]=\"target\">\n <ng-content #formContent></ng-content>\n <div class=\"buttons-container\">\n <ion-button\n type=\"submit\">\n<!-- [shape]=\"buttons?.submit?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.submit?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.submit?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.submit?.fill || 'solid'\"-->\n<!-- [disabled]=\"buttons?.submit?.disabled || false\"-->\n<!-- expand=\"block\"-->\n<!-- [disabled]=\"disableSubmitButtonWhenInvalid ? !form.valid : false\"-->\n @if(options.buttons.submit.icon) {\n <ion-icon [slot]=\"options.buttons.submit.iconSlot\" [name]=\"options.buttons.submit.icon\"></ion-icon>\n }\n {{options.buttons.submit.text}}\n </ion-button>\n @if(options.buttons.clear) {\n <ion-button>\n<!-- type=\"clear\"-->\n<!-- (click)=\"clear($event)\"-->\n<!-- [shape]=\"buttons?.clear?.shape || 'round'\"-->\n<!-- [color]=\"buttons?.clear?.color || 'primary'\"-->\n<!-- [size]=\"buttons?.clear?.size || 'default'\"-->\n<!-- [fill]=\"buttons?.clear?.fill || 'clear'\"-->\n<!-- [disabled]=\"buttons?.clear?.disabled || false\"-->\n<!-- expand=\"block\"-->\n @if(options.buttons.clear?.icon) {\n <ion-icon [slot]=\"options.buttons.clear?.iconSlot\" [name]=\"options.buttons.clear?.icon\"></ion-icon>\n }\n {{options.buttons.clear?.text}}\n </ion-button>\n }\n </div>\n</form>\n" }]
598
730
  }], propDecorators: { updateOn: [{
599
731
  type: Input
600
732
  }], component: [{
@@ -613,60 +745,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
613
745
  args: [{ required: true }]
614
746
  }], formGroup: [{
615
747
  type: Input
616
- }], formId: [{
748
+ }], rendererId: [{
617
749
  type: Input
618
750
  }], submitEvent: [{
619
751
  type: Output
620
752
  }] } });
621
753
 
622
- class NgxRenderingEngine extends RenderingEngine {
623
- constructor() {
624
- super('angular');
625
- }
626
- async initialize(...args) {
627
- if (this.initialized)
628
- return;
629
- // ValidatableByType[]
630
- this.initialized = true;
631
- }
632
- static registerComponent(name, constructor, metadata) {
633
- if (!this._components)
634
- this._components = {};
635
- if (name in this._components)
636
- throw new InternalError(`Component already registered under ${name}`);
637
- this._components[name] = {
638
- constructor: constructor,
639
- metadata: metadata,
640
- };
641
- }
642
- static components(selector) {
643
- if (!selector)
644
- return Object.values(this._components);
645
- if (!(selector in this._components))
646
- throw new InternalError(`No Component registered under ${selector}`);
647
- return this._components[selector];
648
- }
649
- static key(key) {
650
- return `${AngularEngineKeys.REFLECT}${key}`;
651
- }
652
- }
653
-
654
- function Dynamic() {
655
- return apply((original) => {
656
- const annotation = Object.getOwnPropertyDescriptor(original, AngularEngineKeys.ANNOTATIONS);
657
- if (!annotation || !annotation.value)
658
- throw new InternalError(`Could not find Component metadata. @Dynamic decorator must come above @Component`);
659
- // console.log(
660
- // `Could not find Component metadata. @Dynamic decorator must come above @Component`,
661
- // );
662
- const decorator = annotation.value[0];
663
- NgxRenderingEngine.registerComponent(decorator.selector, original, decorator);
664
- }, metadata(NgxRenderingEngine.key(AngularEngineKeys.DYNAMIC), true));
665
- }
666
-
667
- class DynamicModule {
668
- }
669
-
670
754
  /**
671
755
  * Generated bundle index. Do not edit.
672
756
  */