@3kles/kles-material-dynamicforms 21.7.5 → 21.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -344,16 +344,16 @@ function isDestroyable(value) {
344
344
  }
345
345
 
346
346
  class KlesDynamicFieldDirective {
347
- constructor(container, injector) {
347
+ constructor(container, injector, applicationRef) {
348
348
  this.container = container;
349
349
  this.injector = injector;
350
+ this.applicationRef = applicationRef;
350
351
  this.context = null;
351
352
  this.subComponents = [];
353
+ this.subComponentViews = new Map();
352
354
  }
353
355
  ngOnDestroy() {
354
- if (this.componentRef) {
355
- this.componentRef.destroy();
356
- }
356
+ this.destroyComponents();
357
357
  }
358
358
  ngOnInit() {
359
359
  this.buildComponent();
@@ -384,11 +384,7 @@ class KlesDynamicFieldDirective {
384
384
  }
385
385
  }
386
386
  buildComponent() {
387
- if (this.componentRef) {
388
- this.subComponents.forEach((c) => c.destroy());
389
- this.subComponents = [];
390
- this.componentRef.destroy();
391
- }
387
+ this.destroyComponents();
392
388
  const options = {
393
389
  providers: [
394
390
  ...(this.field.providers || []),
@@ -481,6 +477,14 @@ class KlesDynamicFieldDirective {
481
477
  createSubComponent(componentType, options) {
482
478
  const injector = Injector.create(options);
483
479
  const component = this.container.createComponent(componentType, { injector });
480
+ // The host element is projected into the field component. Keeping its view
481
+ // in this container would make Angular's logical DOM differ from the real DOM.
482
+ const viewIndex = this.container.indexOf(component.hostView);
483
+ const detachedView = viewIndex !== -1 ? this.container.detach(viewIndex) : null;
484
+ if (detachedView) {
485
+ this.applicationRef.attachView(detachedView);
486
+ this.subComponentViews.set(component, detachedView);
487
+ }
484
488
  component.onDestroy(() => {
485
489
  if (isDestroyable(injector)) {
486
490
  injector.destroy();
@@ -488,7 +492,20 @@ class KlesDynamicFieldDirective {
488
492
  });
489
493
  return component;
490
494
  }
491
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesDynamicFieldDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive }); }
495
+ destroyComponents() {
496
+ this.componentRef?.destroy();
497
+ this.componentRef = undefined;
498
+ this.subComponents.forEach((component) => {
499
+ const view = this.subComponentViews.get(component);
500
+ if (view) {
501
+ this.applicationRef.detachView(view);
502
+ }
503
+ component.destroy();
504
+ });
505
+ this.subComponents = [];
506
+ this.subComponentViews.clear();
507
+ }
508
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesDynamicFieldDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Directive }); }
492
509
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: KlesDynamicFieldDirective, isStandalone: true, selector: "[klesDynamicField]", inputs: { field: "field", group: "group", ui: "ui", siblingFields: "siblingFields", context: "context" }, usesOnChanges: true, ngImport: i0 }); }
493
510
  }
494
511
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesDynamicFieldDirective, decorators: [{
@@ -497,7 +514,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
497
514
  selector: '[klesDynamicField]',
498
515
  standalone: true,
499
516
  }]
500
- }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.Injector }], propDecorators: { field: [{
517
+ }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.Injector }, { type: i0.ApplicationRef }], propDecorators: { field: [{
501
518
  type: Input
502
519
  }], group: [{
503
520
  type: Input
@@ -681,6 +698,7 @@ class KlesDynamicFormComponent {
681
698
  this.submit = new EventEmitter();
682
699
  this._onLoaded = new EventEmitter();
683
700
  this.direction = 'column';
701
+ this.wrap = true;
684
702
  this.orientationClass = 'dynamic-form-column';
685
703
  }
686
704
  ngOnInit() {
@@ -834,8 +852,8 @@ class KlesDynamicFormComponent {
834
852
  return uiGroup;
835
853
  }
836
854
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesDynamicFormComponent, deps: [{ token: i2.UntypedFormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
837
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: KlesDynamicFormComponent, isStandalone: true, selector: "app-kles-dynamic-form", inputs: { context: "context", fields: "fields", validators: "validators", asyncValidators: "asyncValidators", direction: "direction", formClass: "formClass" }, outputs: { submit: "submit", _onLoaded: "_onLoaded" }, providers: [{ provide: ErrorStateMatcher, useClass: KlesFormErrorStateMatcher }], exportAs: ["klesDynamicForm"], usesOnChanges: true, ngImport: i0, template: `
838
- <form class="{{ orientationClass }}" [ngClass]="formClass" [formGroup]="form" (submit)="onSubmit($event)">
855
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: KlesDynamicFormComponent, isStandalone: true, selector: "app-kles-dynamic-form", inputs: { context: "context", fields: "fields", validators: "validators", asyncValidators: "asyncValidators", direction: "direction", wrap: "wrap", formClass: "formClass" }, outputs: { submit: "submit", _onLoaded: "_onLoaded" }, providers: [{ provide: ErrorStateMatcher, useClass: KlesFormErrorStateMatcher }], exportAs: ["klesDynamicForm"], usesOnChanges: true, ngImport: i0, template: `
856
+ <form class="{{ orientationClass }}" [class.dynamic-form-nowrap]="direction === 'row' && wrap === false" [ngClass]="formClass" [formGroup]="form" (submit)="onSubmit($event)">
839
857
  @for (field of fields; track field.name) {
840
858
  @if (field.visible !== false) {
841
859
  <ng-container klesDynamicField [field]="field" [group]="form" [ui]="ui" [siblingFields]="fields" [context]="context"> </ng-container>
@@ -845,12 +863,12 @@ class KlesDynamicFormComponent {
845
863
  <mat-error matErrorForm [form]="form" [validations]="validators" [asyncValidations]="asyncValidators"></mat-error>
846
864
  }
847
865
  </form>
848
- `, isInline: true, styles: [".dynamic-form-column{display:flex;flex-direction:column}\n", ".dynamic-form-column>*{width:100%}\n", ".dynamic-form-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline}\n", ".dynamic-form-row>*{width:100%}\n", ".dynamic-form-grid{display:grid}\n", ".dynamic-form-inline-grid{display:inline-grid}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatErrorFormDirective, selector: "[matErrorForm]", inputs: ["form", "validations", "asyncValidations"] }, { kind: "directive", type: KlesDynamicFieldDirective, selector: "[klesDynamicField]", inputs: ["field", "group", "ui", "siblingFields", "context"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }] }); }
866
+ `, isInline: true, styles: [".dynamic-form-column{display:flex;flex-direction:column}\n", ".dynamic-form-column>*{width:100%}\n", ".dynamic-form-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline}\n", ".dynamic-form-row.dynamic-form-nowrap{flex-wrap:nowrap}\n", ".dynamic-form-row>*{width:100%}\n", ".dynamic-form-grid{display:grid}\n", ".dynamic-form-inline-grid{display:inline-grid}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatErrorFormDirective, selector: "[matErrorForm]", inputs: ["form", "validations", "asyncValidations"] }, { kind: "directive", type: KlesDynamicFieldDirective, selector: "[klesDynamicField]", inputs: ["field", "group", "ui", "siblingFields", "context"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }] }); }
849
867
  }
850
868
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KlesDynamicFormComponent, decorators: [{
851
869
  type: Component,
852
870
  args: [{ exportAs: 'klesDynamicForm', selector: 'app-kles-dynamic-form', standalone: true, template: `
853
- <form class="{{ orientationClass }}" [ngClass]="formClass" [formGroup]="form" (submit)="onSubmit($event)">
871
+ <form class="{{ orientationClass }}" [class.dynamic-form-nowrap]="direction === 'row' && wrap === false" [ngClass]="formClass" [formGroup]="form" (submit)="onSubmit($event)">
854
872
  @for (field of fields; track field.name) {
855
873
  @if (field.visible !== false) {
856
874
  <ng-container klesDynamicField [field]="field" [group]="form" [ui]="ui" [siblingFields]="fields" [context]="context"> </ng-container>
@@ -860,7 +878,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
860
878
  <mat-error matErrorForm [form]="form" [validations]="validators" [asyncValidations]="asyncValidators"></mat-error>
861
879
  }
862
880
  </form>
863
- `, providers: [{ provide: ErrorStateMatcher, useClass: KlesFormErrorStateMatcher }], imports: [CommonModule, MatErrorFormDirective, KlesDynamicFieldDirective, FormsModule, ReactiveFormsModule, MatError], styles: [".dynamic-form-column{display:flex;flex-direction:column}\n", ".dynamic-form-column>*{width:100%}\n", ".dynamic-form-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline}\n", ".dynamic-form-row>*{width:100%}\n", ".dynamic-form-grid{display:grid}\n", ".dynamic-form-inline-grid{display:inline-grid}\n"] }]
881
+ `, providers: [{ provide: ErrorStateMatcher, useClass: KlesFormErrorStateMatcher }], imports: [CommonModule, MatErrorFormDirective, KlesDynamicFieldDirective, FormsModule, ReactiveFormsModule, MatError], styles: [".dynamic-form-column{display:flex;flex-direction:column}\n", ".dynamic-form-column>*{width:100%}\n", ".dynamic-form-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline}\n", ".dynamic-form-row.dynamic-form-nowrap{flex-wrap:nowrap}\n", ".dynamic-form-row>*{width:100%}\n", ".dynamic-form-grid{display:grid}\n", ".dynamic-form-inline-grid{display:inline-grid}\n"] }]
864
882
  }], ctorParameters: () => [{ type: i2.UntypedFormBuilder }, { type: i0.ChangeDetectorRef }], propDecorators: { context: [{
865
883
  type: Input
866
884
  }], fields: [{
@@ -875,6 +893,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
875
893
  type: Output
876
894
  }], direction: [{
877
895
  type: Input
896
+ }], wrap: [{
897
+ type: Input
878
898
  }], formClass: [{
879
899
  type: Input
880
900
  }] } });
@@ -2828,7 +2848,7 @@ let KlesFormGroupComponent = class KlesFormGroupComponent extends KlesFieldAbstr
2828
2848
  this.orientationClass = 'group-container';
2829
2849
  }
2830
2850
  get className() {
2831
- return this.orientationClass;
2851
+ return this.orientationClass === 'group-container-row' && this.field.wrap === false ? `${this.orientationClass} group-container-nowrap` : this.orientationClass;
2832
2852
  }
2833
2853
  ngOnInit() {
2834
2854
  this.subGroup = this.group.controls[this.field.name];
@@ -2874,7 +2894,7 @@ let KlesFormGroupComponent = class KlesFormGroupComponent extends KlesFieldAbstr
2874
2894
  }
2875
2895
  </ng-container>
2876
2896
  </ng-container>
2877
- `, isInline: true, styles: ["mat-form-field{width:100%}\n", ":host.group-container{display:flex;flex-direction:inherit;width:inherit;justify-content:inherit}\n", ":host.group-container-column{display:flex;flex-direction:column;justify-content:inherit}\n", ":host.group-container-column>*{width:100%}\n", ":host.group-container-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline;justify-content:inherit}\n", ":host.group-container-row>*{width:100%}\n", ":host.group-container-grid{display:grid}\n", ":host.group-container-inline-grid{display:inline-grid}\n"], dependencies: [{ kind: "directive", type: KlesDynamicFieldDirective, selector: "[klesDynamicField]", inputs: ["field", "group", "ui", "siblingFields", "context"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }] }); }
2897
+ `, isInline: true, styles: ["mat-form-field{width:100%}\n", ":host.group-container{display:flex;flex-direction:inherit;width:inherit;justify-content:inherit}\n", ":host.group-container-column{display:flex;flex-direction:column;justify-content:inherit}\n", ":host.group-container-column>*{width:100%}\n", ":host.group-container-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline;justify-content:inherit}\n", ":host.group-container-row.group-container-nowrap{flex-wrap:nowrap}\n", ":host.group-container-row>*{width:100%}\n", ":host.group-container-grid{display:grid}\n", ":host.group-container-inline-grid{display:inline-grid}\n"], dependencies: [{ kind: "directive", type: KlesDynamicFieldDirective, selector: "[klesDynamicField]", inputs: ["field", "group", "ui", "siblingFields", "context"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }] }); }
2878
2898
  };
2879
2899
  KlesFormGroupComponent = __decorate([
2880
2900
  FieldMapper({ type: EnumType.group, factory: (field) => new KlesFormGroup(field).create(), ui: (field) => new KlesFormUiGroup(field).create() })
@@ -2897,7 +2917,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImpo
2897
2917
  }
2898
2918
  </ng-container>
2899
2919
  </ng-container>
2900
- `, standalone: true, imports: [KlesDynamicFieldDirective, MatTooltip, ReactiveFormsModule], styles: ["mat-form-field{width:100%}\n", ":host.group-container{display:flex;flex-direction:inherit;width:inherit;justify-content:inherit}\n", ":host.group-container-column{display:flex;flex-direction:column;justify-content:inherit}\n", ":host.group-container-column>*{width:100%}\n", ":host.group-container-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline;justify-content:inherit}\n", ":host.group-container-row>*{width:100%}\n", ":host.group-container-grid{display:grid}\n", ":host.group-container-inline-grid{display:inline-grid}\n"] }]
2920
+ `, standalone: true, imports: [KlesDynamicFieldDirective, MatTooltip, ReactiveFormsModule], styles: ["mat-form-field{width:100%}\n", ":host.group-container{display:flex;flex-direction:inherit;width:inherit;justify-content:inherit}\n", ":host.group-container-column{display:flex;flex-direction:column;justify-content:inherit}\n", ":host.group-container-column>*{width:100%}\n", ":host.group-container-row{display:inline-flex;flex-wrap:wrap;gap:10px;align-items:baseline;justify-content:inherit}\n", ":host.group-container-row.group-container-nowrap{flex-wrap:nowrap}\n", ":host.group-container-row>*{width:100%}\n", ":host.group-container-grid{display:grid}\n", ":host.group-container-inline-grid{display:inline-grid}\n"] }]
2901
2921
  }], propDecorators: { className: [{
2902
2922
  type: HostBinding,
2903
2923
  args: ['class']