@ng-forge/dynamic-forms 1.1.0 → 1.2.0-next.1
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.
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-CvjDqYyq.mjs → ng-forge-dynamic-forms-array-field.component-BVnXnaNw.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-CvjDqYyq.mjs.map → ng-forge-dynamic-forms-array-field.component-BVnXnaNw.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CcoUnroD.mjs → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CkqvXXs_.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CcoUnroD.mjs.map → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-CkqvXXs_.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-DZfVWjiM.mjs → ng-forge-dynamic-forms-container-field.component-CM1pY9v5.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-DZfVWjiM.mjs.map → ng-forge-dynamic-forms-container-field.component-CM1pY9v5.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-CPFgu3pM.mjs → ng-forge-dynamic-forms-group-field.component-D4JhDffB.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-CPFgu3pM.mjs.map → ng-forge-dynamic-forms-group-field.component-D4JhDffB.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +6 -2
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs +149 -28
- package/fesm2022/ng-forge-dynamic-forms-internal.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-Du3V5AOb.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-ZiNaCWHl.mjs} +148 -304
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-ZiNaCWHl.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-amWhCdHL.mjs → ng-forge-dynamic-forms-page-field.component-Wbz6S8iH.mjs} +47 -9
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-Wbz6S8iH.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +1 -1
- package/types/ng-forge-dynamic-forms-integration.d.ts +8 -2
- package/types/ng-forge-dynamic-forms-internal.d.ts +63 -11
- package/types/ng-forge-dynamic-forms.d.ts +124 -24
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-Du3V5AOb.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-amWhCdHL.mjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, DestroyRef, Injector, EnvironmentInjector, input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { i as injectFieldRegistry, c as createFieldResolutionPipe, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-
|
|
3
|
+
import { i as injectFieldRegistry, F as FIELD_WINDOWING, j as resolveFieldWindowing, c as createFieldResolutionPipe, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-ZiNaCWHl.mjs';
|
|
4
4
|
import { outputFromObservable } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
6
|
-
import { EventBus, DynamicFormLogger, validatePageNesting, derivedFromDeferred } from '@ng-forge/dynamic-forms/internal';
|
|
6
|
+
import { EventBus, DynamicFormLogger, FORM_OPTIONS, validatePageNesting, derivedFromDeferred, isContainerField, getGridClassString } from '@ng-forge/dynamic-forms/internal';
|
|
7
7
|
import { c as computeContainerHostClasses, s as setupContainerInitEffect } from './ng-forge-dynamic-forms-container-utils-BZFz6ztF.mjs';
|
|
8
8
|
|
|
9
9
|
class PageFieldComponent {
|
|
@@ -13,6 +13,8 @@ class PageFieldComponent {
|
|
|
13
13
|
environmentInjector = inject(EnvironmentInjector);
|
|
14
14
|
eventBus = inject(EventBus);
|
|
15
15
|
logger = inject(DynamicFormLogger);
|
|
16
|
+
formOptions = inject(FORM_OPTIONS, { optional: true });
|
|
17
|
+
globalFieldWindowing = inject(FIELD_WINDOWING);
|
|
16
18
|
field = input.required(/* @ts-ignore */
|
|
17
19
|
...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
|
|
18
20
|
key = input.required(/* @ts-ignore */
|
|
@@ -29,6 +31,8 @@ class PageFieldComponent {
|
|
|
29
31
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
30
32
|
isValid = computed(() => validatePageNesting(this.field()), /* @ts-ignore */
|
|
31
33
|
...(ngDevMode ? [{ debugName: "isValid" }] : /* istanbul ignore next */ []));
|
|
34
|
+
fieldWindowing = computed(() => resolveFieldWindowing(this.globalFieldWindowing, this.formOptions?.()?.fieldWindowing), /* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "fieldWindowing" }] : /* istanbul ignore next */ []));
|
|
32
36
|
rawFieldRegistry = computed(() => this.fieldRegistry.raw, /* @ts-ignore */
|
|
33
37
|
...(ngDevMode ? [{ debugName: "rawFieldRegistry" }] : /* istanbul ignore next */ []));
|
|
34
38
|
nextPage = outputFromObservable(this.eventBus.on('next-page'));
|
|
@@ -54,6 +58,14 @@ class PageFieldComponent {
|
|
|
54
58
|
})), { initialValue: [], injector: this.injector });
|
|
55
59
|
constructor() {
|
|
56
60
|
this.setupEffects();
|
|
61
|
+
}
|
|
62
|
+
windowsField(field, index) {
|
|
63
|
+
const w = this.fieldWindowing();
|
|
64
|
+
return w.enabled && index >= w.eager && !isContainerField(field.fieldDef);
|
|
65
|
+
}
|
|
66
|
+
placeholderGridClass(field) {
|
|
67
|
+
const grid = getGridClassString(field.fieldDef);
|
|
68
|
+
return grid ? `df-field-placeholder ${grid}` : 'df-field-placeholder';
|
|
57
69
|
}
|
|
58
70
|
setupEffects() {
|
|
59
71
|
setupContainerInitEffect(this.resolvedFields, this.eventBus, 'page', () => this.field().key, this.injector);
|
|
@@ -66,19 +78,45 @@ class PageFieldComponent {
|
|
|
66
78
|
}
|
|
67
79
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: PageFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
68
80
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: PageFieldComponent, isStandalone: true, selector: "section[page-field]", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: true, transformFunction: null }, isVisible: { classPropertyName: "isVisible", publicName: "isVisible", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { nextPage: "nextPage", previousPage: "previousPage", pageChange: "pageChange" }, host: { properties: { "class": "hostClasses()", "class.disabled": "disabled()", "class.df-page-visible": "isVisible()", "class.df-page-hidden": "!isVisible()", "attr.aria-hidden": "!isVisible()", "attr.data-page-index": "pageIndex()", "id": "`${key()}`", "attr.data-testid": "key()" } }, ngImport: i0, template: `
|
|
69
|
-
@for (field of resolvedFields(); track field.key) {
|
|
81
|
+
@for (field of resolvedFields(); track field.key; let i = $index) {
|
|
70
82
|
@if (!field.hidden()) {
|
|
71
|
-
|
|
83
|
+
@if (windowsField(field, i)) {
|
|
84
|
+
@defer (on viewport) {
|
|
85
|
+
<ng-container *dfFieldOutlet="field; environmentInjector: environmentInjector" />
|
|
86
|
+
} @placeholder {
|
|
87
|
+
<div
|
|
88
|
+
[class]="placeholderGridClass(field)"
|
|
89
|
+
[style.min-height]="fieldWindowing().placeholderHeight"
|
|
90
|
+
[attr.data-field-key]="field.key"
|
|
91
|
+
aria-hidden="true"
|
|
92
|
+
></div>
|
|
93
|
+
}
|
|
94
|
+
} @else {
|
|
95
|
+
<ng-container *dfFieldOutlet="field; environmentInjector: environmentInjector" />
|
|
96
|
+
}
|
|
72
97
|
}
|
|
73
98
|
}
|
|
74
|
-
`, isInline: true, styles: [".df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap, .5rem);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-sm, .5rem)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns, 12),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-md, .5rem)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-lg, .5rem)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-xl, .5rem)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-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}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;width:100%;gap:var(--df-grid-row-gap, .5rem);transition:opacity .2s ease-in-out}:host.df-page-spacing-custom{--df-grid-row-gap: var(--df-page-custom-spacing, 1.5rem)}:host.df-page-visible{opacity:1}:host.df-page-hidden{display:none;opacity:0;pointer-events:none}:host[aria-hidden=true]{pointer-events:none;visibility:hidden}@media(prefers-reduced-motion:no-preference){:host{transition:opacity var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out),transform var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out)}:host.df-page-visible{transform:translate(0)}:host.df-page-hidden{transform:translate(var(--df-page-slide-offset, -10px))}}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"], dependencies: [{ kind: "directive", type: DfFieldOutlet, selector: "[dfFieldOutlet]", inputs: ["dfFieldOutlet", "dfFieldOutletEnvironmentInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
99
|
+
`, isInline: true, styles: [".df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap, .5rem);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-sm, .5rem)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns, 12),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-md, .5rem)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-lg, .5rem)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-xl, .5rem)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-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}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;width:100%;gap:var(--df-grid-row-gap, .5rem);transition:opacity .2s ease-in-out}:host.df-page-spacing-custom{--df-grid-row-gap: var(--df-page-custom-spacing, 1.5rem)}:host.df-page-visible{opacity:1}:host.df-page-hidden{display:none;opacity:0;pointer-events:none}:host[aria-hidden=true]{pointer-events:none;visibility:hidden}@media(prefers-reduced-motion:no-preference){:host{transition:opacity var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out),transform var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out)}:host.df-page-visible{transform:translate(0)}:host.df-page-hidden{transform:translate(var(--df-page-slide-offset, -10px))}}@media(prefers-reduced-motion:reduce){:host{transition:none}}.df-field-placeholder{display:block}\n"], dependencies: [{ kind: "directive", type: DfFieldOutlet, selector: "[dfFieldOutlet]", inputs: ["dfFieldOutlet", "dfFieldOutletEnvironmentInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [DfFieldOutlet]] });
|
|
75
100
|
}
|
|
76
101
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: PageFieldComponent, decorators: [{
|
|
77
102
|
type: Component,
|
|
78
103
|
args: [{ selector: 'section[page-field]', imports: [DfFieldOutlet], template: `
|
|
79
|
-
@for (field of resolvedFields(); track field.key) {
|
|
104
|
+
@for (field of resolvedFields(); track field.key; let i = $index) {
|
|
80
105
|
@if (!field.hidden()) {
|
|
81
|
-
|
|
106
|
+
@if (windowsField(field, i)) {
|
|
107
|
+
@defer (on viewport) {
|
|
108
|
+
<ng-container *dfFieldOutlet="field; environmentInjector: environmentInjector" />
|
|
109
|
+
} @placeholder {
|
|
110
|
+
<div
|
|
111
|
+
[class]="placeholderGridClass(field)"
|
|
112
|
+
[style.min-height]="fieldWindowing().placeholderHeight"
|
|
113
|
+
[attr.data-field-key]="field.key"
|
|
114
|
+
aria-hidden="true"
|
|
115
|
+
></div>
|
|
116
|
+
}
|
|
117
|
+
} @else {
|
|
118
|
+
<ng-container *dfFieldOutlet="field; environmentInjector: environmentInjector" />
|
|
119
|
+
}
|
|
82
120
|
}
|
|
83
121
|
}
|
|
84
122
|
`, host: {
|
|
@@ -90,8 +128,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
90
128
|
'[attr.data-page-index]': 'pageIndex()',
|
|
91
129
|
'[id]': '`${key()}`',
|
|
92
130
|
'[attr.data-testid]': 'key()',
|
|
93
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap, .5rem);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-sm, .5rem)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns, 12),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-md, .5rem)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-lg, .5rem)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-xl, .5rem)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-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}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;width:100%;gap:var(--df-grid-row-gap, .5rem);transition:opacity .2s ease-in-out}:host.df-page-spacing-custom{--df-grid-row-gap: var(--df-page-custom-spacing, 1.5rem)}:host.df-page-visible{opacity:1}:host.df-page-hidden{display:none;opacity:0;pointer-events:none}:host[aria-hidden=true]{pointer-events:none;visibility:hidden}@media(prefers-reduced-motion:no-preference){:host{transition:opacity var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out),transform var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out)}:host.df-page-visible{transform:translate(0)}:host.df-page-hidden{transform:translate(var(--df-page-slide-offset, -10px))}}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] }]
|
|
131
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap, .5rem);width:100%}.df-form>*{grid-column:1/-1}.df-row{display:grid;grid-template-columns:repeat(var(--df-grid-columns, 12),1fr);gap:var(--df-grid-gap, .5rem);align-items:start;width:100%}.df-row>*:not([class*=df-col-]){grid-column:1/-1}.df-col-1{grid-column:span 1}.df-col-2{grid-column:span 2}.df-col-3{grid-column:span 3}.df-col-4{grid-column:span 4}.df-col-5{grid-column:span 5}.df-col-6{grid-column:span 6}.df-col-7{grid-column:span 7}.df-col-8{grid-column:span 8}.df-col-9{grid-column:span 9}.df-col-10{grid-column:span 10}.df-col-11{grid-column:span 11}.df-col-12{grid-column:span 12}.df-col-auto{grid-column:span auto;width:auto}.df-col-full{grid-column:1/-1}.df-col-start-1{grid-column-start:1}.df-col-start-2{grid-column-start:2}.df-col-start-3{grid-column-start:3}.df-col-start-4{grid-column-start:4}.df-col-start-5{grid-column-start:5}.df-col-start-6{grid-column-start:6}.df-col-start-7{grid-column-start:7}.df-col-start-8{grid-column-start:8}.df-col-start-9{grid-column-start:9}.df-col-start-10{grid-column-start:10}.df-col-start-11{grid-column-start:11}.df-col-start-12{grid-column-start:12}.df-col-end-1{grid-column-end:1}.df-col-end-2{grid-column-end:2}.df-col-end-3{grid-column-end:3}.df-col-end-4{grid-column-end:4}.df-col-end-5{grid-column-end:5}.df-col-end-6{grid-column-end:6}.df-col-end-7{grid-column-end:7}.df-col-end-8{grid-column-end:8}.df-col-end-9{grid-column-end:9}.df-col-end-10{grid-column-end:10}.df-col-end-11{grid-column-end:11}.df-col-end-12{grid-column-end:12}.df-col-end-13{grid-column-end:13}@media(max-width:576px){.df-form{--df-grid-gap: var(--df-grid-gap-sm, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-sm, .5rem)}.df-row{grid-template-columns:1fr}.df-row>*{grid-column:1/-1!important}.df-row.df-row-mobile-keep-cols{grid-template-columns:repeat(var(--df-grid-columns, 12),1fr)}.df-row.df-row-mobile-keep-cols>*{grid-column:revert!important}}@media(min-width:577px)and (max-width:768px){.df-form{--df-grid-gap: var(--df-grid-gap-md, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-md, .5rem)}.df-row{--df-grid-columns: 6}.df-col-sm-1{grid-column:span 1}.df-col-sm-2{grid-column:span 2}.df-col-sm-3{grid-column:span 3}.df-col-sm-4{grid-column:span 4}.df-col-sm-5{grid-column:span 5}.df-col-sm-6{grid-column:span 6}.df-col-sm-full{grid-column:1/-1}}@media(min-width:769px)and (max-width:992px){.df-form{--df-grid-gap: var(--df-grid-gap-lg, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-lg, .5rem)}.df-col-md-1{grid-column:span 1}.df-col-md-2{grid-column:span 2}.df-col-md-3{grid-column:span 3}.df-col-md-4{grid-column:span 4}.df-col-md-5{grid-column:span 5}.df-col-md-6{grid-column:span 6}.df-col-md-7{grid-column:span 7}.df-col-md-8{grid-column:span 8}.df-col-md-9{grid-column:span 9}.df-col-md-10{grid-column:span 10}.df-col-md-11{grid-column:span 11}.df-col-md-12{grid-column:span 12}.df-col-md-full{grid-column:1/-1}}@media(min-width:993px){.df-form{--df-grid-gap: var(--df-grid-gap-xl, .5rem);--df-grid-row-gap: var(--df-grid-row-gap-xl, .5rem)}.df-col-lg-1{grid-column:span 1}.df-col-lg-2{grid-column:span 2}.df-col-lg-3{grid-column:span 3}.df-col-lg-4{grid-column:span 4}.df-col-lg-5{grid-column:span 5}.df-col-lg-6{grid-column:span 6}.df-col-lg-7{grid-column:span 7}.df-col-lg-8{grid-column:span 8}.df-col-lg-9{grid-column:span 9}.df-col-lg-10{grid-column:span 10}.df-col-lg-11{grid-column:span 11}.df-col-lg-12{grid-column:span 12}.df-col-lg-full{grid-column:1/-1}}.df-gap-none{--df-grid-gap: 0}.df-gap-xs{--df-grid-gap: .25rem}.df-gap-sm{--df-grid-gap: .5rem}.df-gap-md{--df-grid-gap: 1rem}.df-gap-lg{--df-grid-gap: 1.5rem}.df-gap-xl{--df-grid-gap: 2rem}.df-row-gap-none{--df-grid-row-gap: 0}.df-row-gap-xs{--df-grid-row-gap: .25rem}.df-row-gap-sm{--df-grid-row-gap: .5rem}.df-row-gap-md{--df-grid-row-gap: 1rem}.df-row-gap-lg{--df-grid-row-gap: 1.5rem}.df-row-gap-xl{--df-grid-row-gap: 2rem}.df-field{display:block;width:100%;min-width:0;overflow:hidden;margin:0}.df-group,.df-page{display:block;width:100%}.df-form.disabled,.df-row.disabled,.df-field.disabled{opacity:.6;pointer-events:none}.df-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}.df-sr-only-focusable:focus,.df-sr-only-focusable:active{position:static;width:auto;height:auto;padding:inherit;margin:inherit;overflow:visible;clip:auto;white-space:normal}.df-live-region{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.df-form :focus-visible{outline:2px solid var(--df-focus-color, #005fcc);outline-offset:2px}.df-group:focus-within{outline:1px dashed var(--df-focus-color, #005fcc);outline-offset:4px}:host{display:grid;grid-template-columns:1fr;width:100%;gap:var(--df-grid-row-gap, .5rem);transition:opacity .2s ease-in-out}:host.df-page-spacing-custom{--df-grid-row-gap: var(--df-page-custom-spacing, 1.5rem)}:host.df-page-visible{opacity:1}:host.df-page-hidden{display:none;opacity:0;pointer-events:none}:host[aria-hidden=true]{pointer-events:none;visibility:hidden}@media(prefers-reduced-motion:no-preference){:host{transition:opacity var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out),transform var(--df-page-transition-duration, .3s) var(--df-page-transition-timing, ease-in-out)}:host.df-page-visible{transform:translate(0)}:host.df-page-hidden{transform:translate(var(--df-page-slide-offset, -10px))}}@media(prefers-reduced-motion:reduce){:host{transition:none}}.df-field-placeholder{display:block}\n"] }]
|
|
94
132
|
}], ctorParameters: () => [], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: true }] }], isVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVisible", required: true }] }], nextPage: [{ type: i0.Output, args: ["nextPage"] }], previousPage: [{ type: i0.Output, args: ["previousPage"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }] } });
|
|
95
133
|
|
|
96
134
|
export { PageFieldComponent as default };
|
|
97
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-page-field.component-
|
|
135
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-page-field.component-Wbz6S8iH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-page-field.component-Wbz6S8iH.mjs","mappings":";;;;;;;;AAwDc;YAKK;;AAEA;AACE;AACF;AACA;;AAEA;;;;;AAQjB;;;;;;YAQS;;AAEA;;AAEA;;AAET,IAKmB;;;;YAUV;AACA;AACA;YAMQ;AACf;AACE;;;;;AAKe;AAGf;AACA;;;AAGA;AACE;;;;AAOH;YAQH;;;AAIA;AAOE;AACA;;IAIQ;;;;;;AAYR;;;;;AAQA;;;AA3HiB;;;;;;;;;;;;;;;;;;;;;;;AAnCT;;;;;;;;;;;;;;;;;;;;AAwBR;AACA;AACA;AACA;AACA;AACA;AACA;AACA","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms/src/lib/fields/page/page-field.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, DestroyRef, EnvironmentInjector, inject, Injector, input } from '@angular/core';\nimport { DfFieldOutlet } from '../../directives/df-field-outlet/df-field-outlet.directive';\nimport { outputFromObservable } from '@angular/core/rxjs-interop';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { derivedFromDeferred } from '@ng-forge/dynamic-forms/internal';\nimport { createFieldResolutionPipe, ResolvedField } from '../../utils/resolve-field/resolve-field';\nimport { computeContainerHostClasses, setupContainerInitEffect } from '../../utils/container-utils/container-utils';\nimport { PageField, validatePageNesting } from '@ng-forge/dynamic-forms/internal';\nimport { injectFieldRegistry } from '../../utils/inject-field-registry/inject-field-registry';\nimport { EventBus } from '@ng-forge/dynamic-forms/internal';\nimport { NextPageEvent, PageChangeEvent, PreviousPageEvent } from '../../events/constants';\nimport { FieldDef } from '@ng-forge/dynamic-forms/internal';\nimport { DynamicFormLogger } from '@ng-forge/dynamic-forms/internal';\nimport { FORM_OPTIONS } from '@ng-forge/dynamic-forms/internal';\nimport { getGridClassString } from '@ng-forge/dynamic-forms/internal';\nimport { isContainerField } from '@ng-forge/dynamic-forms/internal';\nimport { FIELD_WINDOWING } from '../../providers/features/field-windowing/field-windowing.token';\nimport { resolveFieldWindowing } from '../../providers/features/field-windowing/resolve-field-windowing';\n\n/** Renders a single page in multi-page (wizard) forms. */\n@Component({\n selector: 'section[page-field]',\n imports: [DfFieldOutlet],\n template: `\n @for (field of resolvedFields(); track field.key; let i = $index) {\n @if (!field.hidden()) {\n @if (windowsField(field, i)) {\n @defer (on viewport) {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\n } @placeholder {\n <div\n [class]=\"placeholderGridClass(field)\"\n [style.min-height]=\"fieldWindowing().placeholderHeight\"\n [attr.data-field-key]=\"field.key\"\n aria-hidden=\"true\"\n ></div>\n }\n } @else {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\n }\n }\n }\n `,\n styleUrl: './page-field.component.scss',\n host: {\n '[class]': 'hostClasses()',\n '[class.disabled]': 'disabled()',\n '[class.df-page-visible]': 'isVisible()',\n '[class.df-page-hidden]': '!isVisible()',\n '[attr.aria-hidden]': '!isVisible()',\n '[attr.data-page-index]': 'pageIndex()',\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class PageFieldComponent {\n // ─────────────────────────────────────────────────────────────────────────────\n // Dependencies\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly fieldRegistry = injectFieldRegistry();\n private readonly injector = inject(Injector);\n protected readonly environmentInjector = inject(EnvironmentInjector);\n private readonly eventBus = inject(EventBus);\n private readonly logger = inject(DynamicFormLogger);\n private readonly formOptions = inject(FORM_OPTIONS, { optional: true });\n private readonly globalFieldWindowing = inject(FIELD_WINDOWING);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Inputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n field = input.required<PageField>();\n key = input.required<string>();\n className = input<string>();\n pageIndex = input.required<number>();\n isVisible = input.required<boolean>();\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Computed Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly hostClasses = computed(() => computeContainerHostClasses('page-field', this.className()));\n\n readonly disabled = computed(() => this.field().disabled || false);\n\n readonly isValid = computed(() => validatePageNesting(this.field()));\n\n /**\n * Effective field-windowing config for this page. Per-form\n * `FormOptions.fieldWindowing` wins over the global `withFieldWindowing()`\n * default; both fall back to disabled (fully eager).\n */\n protected readonly fieldWindowing = computed(() =>\n resolveFieldWindowing(this.globalFieldWindowing, this.formOptions?.()?.fieldWindowing),\n );\n\n private readonly rawFieldRegistry = computed(() => this.fieldRegistry.raw);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Outputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly nextPage = outputFromObservable(this.eventBus.on<NextPageEvent>('next-page'));\n readonly previousPage = outputFromObservable(this.eventBus.on<PreviousPageEvent>('previous-page'));\n readonly pageChange = outputFromObservable(this.eventBus.on<PageChangeEvent>('page-change'));\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Field Resolution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldsSource = computed(() => {\n if (!this.isValid()) {\n return [];\n }\n return this.field().fields || [];\n });\n\n protected readonly resolvedFields = derivedFromDeferred(\n this.fieldsSource,\n createFieldResolutionPipe(() => ({\n loadTypeComponent: (type: string) => this.fieldRegistry.loadTypeComponent(type),\n registry: this.rawFieldRegistry(),\n injector: this.injector,\n destroyRef: this.destroyRef,\n onError: (fieldDef: FieldDef<unknown>, error: unknown) => {\n const fieldKey = fieldDef.key || '<no key>';\n this.logger.error(\n `Failed to load component for field type '${fieldDef.type}' (key: ${fieldKey}) ` +\n `within page '${this.field().key}'. Ensure the field type is registered in your field registry.`,\n error,\n );\n },\n })),\n { initialValue: [] as ResolvedField[], injector: this.injector },\n );\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Constructor\n // ─────────────────────────────────────────────────────────────────────────────\n\n constructor() {\n this.setupEffects();\n }\n\n /**\n * Whether a field should be deferred by field windowing. Containers are never\n * windowed: they emit `ComponentInitializedEvent`, which the form's init\n * tracker counts, so deferring one would stall `initialized` until it scrolls\n * into view. Leaf fields carry no such count, so they defer freely.\n */\n protected windowsField(field: ResolvedField, index: number): boolean {\n const w = this.fieldWindowing();\n return w.enabled && index >= w.eager && !isContainerField(field.fieldDef);\n }\n\n /** Class string for a windowed field's placeholder — matches the real field's grid column. */\n protected placeholderGridClass(field: ResolvedField): string {\n const grid = getGridClassString(field.fieldDef);\n return grid ? `df-field-placeholder ${grid}` : 'df-field-placeholder';\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Private Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n private setupEffects(): void {\n setupContainerInitEffect(this.resolvedFields, this.eventBus, 'page', () => this.field().key, this.injector);\n\n explicitEffect([this.isValid, this.field], ([valid, pageField]) => {\n if (!valid) {\n this.logger.error(\n `Invalid configuration: Page '${pageField.key}' contains nested page fields. ` +\n `Pages cannot contain other pages. Consider using groups or rows for nested structure.`,\n pageField,\n );\n }\n });\n }\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { q as AppendArrayItemEvent, B as BUILT_IN_FIELDS, s as ComponentAddonComponent, u as ConsoleLogger, v as DfTemplate, w as DynamicForm, E as EventDispatcher, x as FormClearEvent, y as FormResetEvent, z as FormSubmitEvent, I as InsertArrayItemEvent, M as MoveArrayItemEvent, N as NextPageEvent, G as PageChangeEvent, H as PopArrayItemEvent, J as PrependArrayItemEvent, K as PreviousPageEvent, R as RemoveAtIndexEvent, S as ShiftArrayItemEvent, T as TemplateAddonComponent, L as TextAddonComponent, O as arrayEvent, Q as createWrappers, U as isWrappersBundle, V as provideDynamicForm, W as sanitizeFormConfig, X as withAddonActions, Y as withCustomAddon, Z as withEventFormValue, _ as withFieldWindowing, $ as withLegacyStatusClasses, a0 as withLoggerConfig, a1 as withPagePreload, a2 as withValidationExecutionDefaults, a3 as withValueExclusionDefaults, a4 as wrapperProps } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-ZiNaCWHl.mjs';
|
|
2
2
|
export { DF_FIELD_TEMPLATES, DynamicFormError, DynamicFormLogger, NoopLogger, hasFormValue, isArrayField, isContainerField, isDisplayOnlyField, isFieldBoundContext, isFormStateCondition, isGroupField, isHiddenField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isWrapperTypeDefinition, resolveDynamicValue } from '@ng-forge/dynamic-forms/internal';
|
|
3
3
|
//# sourceMappingURL=ng-forge-dynamic-forms.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-forge/dynamic-forms",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-next.1",
|
|
4
4
|
"description": "Type-safe, signal-powered dynamic forms for Angular. Build complex forms from configuration with full TypeScript inference.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -329,7 +329,13 @@ interface ArrayButtonContext {
|
|
|
329
329
|
targetArrayKey: string | undefined;
|
|
330
330
|
/** Computed signal that returns the current array index (-1 if not inside array) */
|
|
331
331
|
indexSignal: Signal<number>;
|
|
332
|
-
/**
|
|
332
|
+
/**
|
|
333
|
+
* Current form value for token resolution. Implemented as a lazy getter so it
|
|
334
|
+
* is read at event-dispatch time, not when the mapper builds its context —
|
|
335
|
+
* reading it eagerly inside the mapper's computed would resnapshot a stale
|
|
336
|
+
* value and subscribe every array button to the whole form entity per
|
|
337
|
+
* keystroke. Keep it a getter on any reimplementation.
|
|
338
|
+
*/
|
|
333
339
|
formValue: Record<string, unknown>;
|
|
334
340
|
/** Whether this button is inside an array context */
|
|
335
341
|
isInsideArray: boolean;
|
|
@@ -342,7 +348,7 @@ interface ArrayButtonEventContext {
|
|
|
342
348
|
index: number;
|
|
343
349
|
/** The target array key */
|
|
344
350
|
arrayKey: string;
|
|
345
|
-
/**
|
|
351
|
+
/** Form value for token resolution — a lazy getter, resolved at dispatch time. See {@link ArrayButtonContext.formValue}. */
|
|
346
352
|
formValue: Record<string, unknown>;
|
|
347
353
|
/**
|
|
348
354
|
* Optional template for add operations.
|
|
@@ -1583,6 +1583,37 @@ interface FormOptions {
|
|
|
1583
1583
|
submitButton?: SubmitButtonOptions;
|
|
1584
1584
|
/** Default disabled behavior for next page buttons. */
|
|
1585
1585
|
nextButton?: NextButtonOptions;
|
|
1586
|
+
/**
|
|
1587
|
+
* For paged forms: how many pages on each side of the current page are eagerly
|
|
1588
|
+
* mounted (the "preload window"). Pages outside the window render a lightweight
|
|
1589
|
+
* placeholder and mount when navigation brings them into range.
|
|
1590
|
+
*
|
|
1591
|
+
* `0` mounts only the current page; `1` mounts ±1 for flicker-free sequential
|
|
1592
|
+
* navigation; higher values pre-warm more pages for jump navigation at the cost
|
|
1593
|
+
* of more initial DOM + change detection.
|
|
1594
|
+
*
|
|
1595
|
+
* Overrides the global `withPagePreload(n)` default for this form.
|
|
1596
|
+
*
|
|
1597
|
+
* @default undefined (uses global setting, which defaults to `1`)
|
|
1598
|
+
*/
|
|
1599
|
+
pagePreloadWindow?: number;
|
|
1600
|
+
/**
|
|
1601
|
+
* For flat (single-page) forms: progressive field mounting ("field
|
|
1602
|
+
* windowing"). Fields beyond the eager count render as a placeholder and
|
|
1603
|
+
* mount only once scrolled near/into view, instead of all mounting eagerly.
|
|
1604
|
+
*
|
|
1605
|
+
* `true` enables windowing using the global `withFieldWindowing()` defaults;
|
|
1606
|
+
* `false` force-disables it even if the global feature is enabled; an object
|
|
1607
|
+
* enables it with per-form `eager` / `placeholderHeight` overrides.
|
|
1608
|
+
*
|
|
1609
|
+
* Overrides the global `withFieldWindowing(...)` default for this form.
|
|
1610
|
+
*
|
|
1611
|
+
* @default undefined (uses global setting, which defaults to disabled)
|
|
1612
|
+
*/
|
|
1613
|
+
fieldWindowing?: boolean | {
|
|
1614
|
+
eager?: number;
|
|
1615
|
+
placeholderHeight?: string;
|
|
1616
|
+
};
|
|
1586
1617
|
/**
|
|
1587
1618
|
* Whether to exclude values of hidden fields from submission output.
|
|
1588
1619
|
*
|
|
@@ -2352,16 +2383,10 @@ declare function isResourceBasedValidator(config: ValidatorConfig): boolean;
|
|
|
2352
2383
|
* @param context Optional context providing function scope lookup
|
|
2353
2384
|
* @returns true if the when condition references other fields
|
|
2354
2385
|
* @deprecated No longer used for validator routing; `when` conditions are applied natively
|
|
2355
|
-
* via Angular's validator `when` config
|
|
2386
|
+
* via Angular's validator `when` config, and validator expressions are applied per-field
|
|
2387
|
+
* with a reactive evaluation context — no validator config ever requires tree validation.
|
|
2356
2388
|
*/
|
|
2357
2389
|
declare function hasCrossFieldWhenCondition(config: ValidatorConfig, context?: CrossFieldDetectionContext): boolean;
|
|
2358
|
-
/**
|
|
2359
|
-
* True only when the validator must be evaluated by the root validateTree:
|
|
2360
|
-
* a cross-field dynamic-value/validation EXPRESSION. A `when` condition alone
|
|
2361
|
-
* never requires tree validation; it is applied natively via Angular's
|
|
2362
|
-
* validator `when` config (built-ins) or whenLogic gating (custom/async/http).
|
|
2363
|
-
*/
|
|
2364
|
-
declare function requiresTreeValidation(config: ValidatorConfig): boolean;
|
|
2365
2390
|
/**
|
|
2366
2391
|
* Detects if a StateLogicConfig has a cross-field condition.
|
|
2367
2392
|
*
|
|
@@ -2665,7 +2690,13 @@ declare class FieldContextRegistryService {
|
|
|
2665
2690
|
/** Builds an evaluation context scoped to a specific array item. */
|
|
2666
2691
|
private buildArrayScopedContext;
|
|
2667
2692
|
/**
|
|
2668
|
-
*
|
|
2693
|
+
* Builds a REACTIVE evaluation context scoped to a specific array item, fine-grained:
|
|
2694
|
+
* `formValue`/`rootFormValue` are proxies over the FieldTree so a condition subscribes
|
|
2695
|
+
* only to the fields it actually reads, instead of the whole-form value.
|
|
2696
|
+
*/
|
|
2697
|
+
private buildReactiveArrayScopedContext;
|
|
2698
|
+
/**
|
|
2699
|
+
* Resolves external data signals as a lazy, read-only view.
|
|
2669
2700
|
*
|
|
2670
2701
|
* Always reads reactively. Unlike the field value and form value (which are
|
|
2671
2702
|
* read untracked to break the validator -> state -> valid -> validator cycle),
|
|
@@ -2674,7 +2705,12 @@ declare class FieldContextRegistryService {
|
|
|
2674
2705
|
* reactively is what lets dynamic values and validators bound to externalData
|
|
2675
2706
|
* update when it changes.
|
|
2676
2707
|
*
|
|
2677
|
-
*
|
|
2708
|
+
* Fine-grained: reading `externalData.foo` subscribes to only that key's
|
|
2709
|
+
* signal (plus the record signal), so an expression referencing one key does
|
|
2710
|
+
* not re-run when other external signals change. Enumeration (spread,
|
|
2711
|
+
* `Object.keys`) resolves every key.
|
|
2712
|
+
*
|
|
2713
|
+
* @returns Lazy record of resolved external data values, or undefined if no external data.
|
|
2678
2714
|
*/
|
|
2679
2715
|
private resolveExternalData;
|
|
2680
2716
|
/** Creates a REACTIVE evaluation context for logic functions. */
|
|
@@ -2697,6 +2733,22 @@ declare class FieldContextRegistryService {
|
|
|
2697
2733
|
static ɵprov: i0.ɵɵInjectableDeclaration<FieldContextRegistryService>;
|
|
2698
2734
|
}
|
|
2699
2735
|
|
|
2736
|
+
/**
|
|
2737
|
+
* A lazy, read-only view over the form value that subscribes fine-grainedly:
|
|
2738
|
+
* reading `formValue.foo` resolves `foo` through the Signal Forms `FieldTree` and
|
|
2739
|
+
* subscribes to only that field's `value()` signal, so a condition/validator that
|
|
2740
|
+
* references one field re-runs only when that field changes (instead of every
|
|
2741
|
+
* field, as reading the whole-form value would cause).
|
|
2742
|
+
*
|
|
2743
|
+
* Whole-object operations (spread, `Object.keys`) fall back to the eager whole-form
|
|
2744
|
+
* value and subscribe to everything — correct for code that needs all keys.
|
|
2745
|
+
*
|
|
2746
|
+
* @param getRootForm - the current root `FieldTree` (structural; changes on rebuild).
|
|
2747
|
+
* @param getRootFormValue - the eager whole-form value; fallback for keys absent
|
|
2748
|
+
* from the tree and for whole-object enumeration.
|
|
2749
|
+
*/
|
|
2750
|
+
declare function createFieldValueProxy(getRootForm: () => FieldTree<unknown> | undefined, getRootFormValue: () => Record<string, unknown>): Record<string, unknown>;
|
|
2751
|
+
|
|
2700
2752
|
/** Registry service for custom functions and validators */
|
|
2701
2753
|
declare class FunctionRegistryService {
|
|
2702
2754
|
private readonly customFunctions;
|
|
@@ -3604,5 +3656,5 @@ declare function assertNever(value: never): never;
|
|
|
3604
3656
|
*/
|
|
3605
3657
|
declare function withPreviousValue<T>(input: Resource<T>): Resource<T>;
|
|
3606
3658
|
|
|
3607
|
-
export { ADDON_ACTION_HANDLERS, ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AsyncConditionFunctionCacheService, ComponentInitializedEvent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DEPRECATION_WARNING_TRACKER, DF_FIELD_TEMPLATES, DfAddonSlot, DynamicFormError, DynamicFormLogger, DynamicTextPipe, DynamicValueFunctionCacheService, EMIT_FORM_VALUE_ON_EVENTS, EXTERNAL_DATA, EventBus, ExpressionParser, ExpressionParserError, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FunctionRegistryService, GROUP_CONTEXT, HTTP_CONDITION_CACHE, HttpConditionCache, HttpConditionFunctionCacheService, INITIALIZATION_TIMEOUT_MS, LogicFunctionCacheService, NoopLogger, READONLY_FIELD_TREE_CACHE, RootFormRegistryService, TokenType, WRAPPER_AUTO_ASSOCIATIONS, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, buildClassName, compareValues, containerFieldMapper, createAddonActionRegistry, createDebouncedLogicFunction, createDefaultDerivationLogConfig, createDynamicValueFunction, createFormFieldStateMap, createFormStateLogicFunction, createInitializationTracker, createLogicFunction, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getFieldValueHandling, getGridClassString, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldSignalContext, injectFieldsSupportingAddons, injectNonFieldEvaluationContext, interpolateParams, isArrayField, isCheckedField, isContainerField, isCrossFieldBuiltInValidator, isCrossFieldExpression, isCrossFieldSchema, isCrossFieldStateLogic, isCrossFieldValidator, isDerivationLogicConfig, isDisplayOnlyField, isEqual, isFieldBoundContext, isFormStateCondition, isFunctionHttpValidator, isGenericContainerField, isGroupField, isHiddenField, isLeafField, isNonPagedForm, isPageField, isPagedForm, isResourceBasedValidator, isRowField, isSimplifiedArrayField, isStateLogicConfig, isValidNonPagedForm, isValidPagedForm, isValueBearingField, isValueField, isWrapperTypeDefinition, keyBy, mapValues, memoize, normalizeFieldsArray, omit, pageFieldMapper, readFieldStateInfo,
|
|
3659
|
+
export { ADDON_ACTION_HANDLERS, ADDON_ACTION_REGISTRY, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, ADDON_TYPE_REGISTRY, ARRAY_CONTEXT, AsyncConditionFunctionCacheService, ComponentInitializedEvent, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, DEFAULT_WRAPPERS, DEPRECATION_WARNING_TRACKER, DF_FIELD_TEMPLATES, DfAddonSlot, DynamicFormError, DynamicFormLogger, DynamicTextPipe, DynamicValueFunctionCacheService, EMIT_FORM_VALUE_ON_EVENTS, EXTERNAL_DATA, EventBus, ExpressionParser, ExpressionParserError, FIELD_REGISTRY, FIELD_SIGNAL_CONTEXT, FORM_ID_PREFIX, FORM_OPTIONS, FieldContextRegistryService, FunctionRegistryService, GROUP_CONTEXT, HTTP_CONDITION_CACHE, HttpConditionCache, HttpConditionFunctionCacheService, INITIALIZATION_TIMEOUT_MS, LogicFunctionCacheService, NoopLogger, READONLY_FIELD_TREE_CACHE, RootFormRegistryService, TokenType, WRAPPER_AUTO_ASSOCIATIONS, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, applyMetaToElement, applyValidator, applyValidators, arrayFieldMapper, assertNever, baseFieldMapper, buildBaseInputs, buildClassName, compareValues, containerFieldMapper, createAddonActionRegistry, createDebouncedLogicFunction, createDefaultDerivationLogConfig, createDynamicValueFunction, createFieldValueProxy, createFormFieldStateMap, createFormStateLogicFunction, createInitializationTracker, createLogicFunction, createWarningTracker, deepMergeDefaults, derivedFromDeferred, detectFormMode, dynamicTextToObservable, evaluateCondition, evaluateNonFieldDisabled, evaluateNonFieldHidden, extractExpressionDependencies, extractStringDependencies, getArrayLength, getChangedKeys, getFieldValueHandling, getGridClassString, getNestedValue, groupFieldMapper, hasChildFields, hasCrossFieldWhenCondition, hasFormValue, hasNestedProperty, hasTargetProperty, injectAddonTypeRegistry, injectFieldSignalContext, injectFieldsSupportingAddons, injectNonFieldEvaluationContext, interpolateParams, isArrayField, isCheckedField, isContainerField, isCrossFieldBuiltInValidator, isCrossFieldExpression, isCrossFieldSchema, isCrossFieldStateLogic, isCrossFieldValidator, isDerivationLogicConfig, isDisplayOnlyField, isEqual, isFieldBoundContext, isFormStateCondition, isFunctionHttpValidator, isGenericContainerField, isGroupField, isHiddenField, isLeafField, isNonPagedForm, isPageField, isPagedForm, isResourceBasedValidator, isRowField, isSimplifiedArrayField, isStateLogicConfig, isValidNonPagedForm, isValidPagedForm, isValueBearingField, isValueField, isWrapperTypeDefinition, keyBy, mapValues, memoize, normalizeFieldsArray, omit, pageFieldMapper, readFieldStateInfo, resolveDynamicValue, resolveHttpRequest, resolveNextButtonDisabled, resolveNonFieldDisabled, resolveNonFieldHidden, resolveSubmitButtonDisabled, resolveTokens, rowFieldMapper, runPresetAction, setupInitializationTracking, shouldLog, textFieldMapper, toReadonlyFieldTree, toReadonlyFieldTreeCached, validatePageNesting, withPreviousValue, writeToFieldValue };
|
|
3608
3660
|
export type { ASTNode, AddonActionContext, AddonActionHandler, AddonActionPreset, AddonShapeValidator, AddonSlot, AddonTypeDefinition, AddonTypeRegistryRef, AddonTypeSchema, AndCondition, AnyAddon, ArrayAllowedChildren, ArrayButtonConfig, ArrayComponent, ArrayContext, ArrayField, ArrayFieldTree, ArrayItemDefinition, ArrayItemTemplate, ArrayLiteralNode, ArrowFunctionNode, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseAddon, BaseCheckedField, BaseValidatorConfig, BaseValueField, BinaryOpNode, BuiltInValidatorConfig, ButtonLogicContext, CallExpressionNode, CheckedFieldComponent, CommonAddonActionPreset, CommonAddonSlot, ComparisonOperator, ComponentAddon, ComputedMemberAccessNode, ConditionalExpression, ConditionalNode, ContainerAllowedChildren, ContainerComponent, ContainerField, ContainerFieldTypes, ContainerLogicConfig, CrossFieldDetectionContext, CssWrapper, CustomCondition, CustomFnConfig, CustomFunction, CustomFunctionOptions, CustomFunctionScope, CustomValidator, CustomValidatorConfig, DeclarativeHttpValidatorConfig, DerivationLogConfig, DerivationLogLevel, DerivationLogicConfig, DerivedFromDeferredOptions, DynamicFormActionRegistry, DynamicFormAddonActionPresetRegistry, DynamicFormAddonRegistry, DynamicFormAddonSlotRegistry, DynamicFormFieldRegistry, DynamicText, DynamicValue, EvaluationContext, ExtractField, FieldAddonSupport, FieldAddonSupportEntry, FieldBoundAddonActionContext, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldScope, FieldSignalContext, FieldStateContext, FieldStateInfo, FieldTreeRecord, FieldTypeDefinition, FieldValueCondition, FieldWithValidation, FieldWrapper, FormConfig, FormEvent, FormEventConstructor, FormFieldStateMap, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, FunctionHttpValidatorConfig, GroupAllowedChildren, GroupComponent, GroupContext, GroupField, HiddenField, HiddenScalar, HiddenValue, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpResourceRequest, HttpValidationResponseMapping, IdentifierNode, InferFormModel, InferFormValue, InitializationTrackingOptions, JavascriptCondition, LazyComponentLoader, LeafFieldTypes, LiteralNode, Logger, LogicConfig, LogicTrigger, MapperFn, MemberAccessNode, MemoizeOptions, NarrowField, NarrowFields, NextButtonOptions, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, ObjectLiteralNode, OrCondition, OrphanAddonActionContext, PageAllowedChildren, PageField, PresetCollaborators, Prettify, ReadonlyFieldTree, RegisteredActionRef, RegisteredFieldTypes, RegisteredWrapperTypes, RenderReadyInput, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowComponent, RowField, RowWrapper, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, StateLogicType, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, Token, TokenContext, UnaryOpNode, ValidationError, ValidationExecutionConfig, ValidationMessage, ValidationMessageResolver, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueHandlingMode, ValueType, WarningTracker, WithInputSignals, WrapperAutoAssociations, WrapperConfig, WrapperFieldInputs, WrapperTypeDefinition };
|
|
@@ -1,32 +1,29 @@
|
|
|
1
1
|
import * as rxjs from 'rxjs';
|
|
2
|
-
import * as _angular_core from '@angular/core';
|
|
3
|
-
import { Type, Injector, Signal, EnvironmentInjector, WritableSignal, Provider, EnvironmentProviders, TemplateRef } from '@angular/core';
|
|
4
|
-
import * as _ng_forge_dynamic_forms_internal from '@ng-forge/dynamic-forms/internal';
|
|
5
|
-
import { FieldDef, FormEvent, RegisteredFieldTypes, InferFormModel, FormConfig, FormOptions, EventBus, LazyComponentLoader, WrapperTypeDefinition, FieldTypeDefinition, InferFormValue as InferFormValue$1, DerivationLogLevel, Logger, ValueExclusionConfig, ValidationExecutionConfig, TextAddon, WrapperFieldInputs, TemplateAddon, ComponentAddon, BaseAddon, AddonTypeDefinition, AddonActionHandler, ArrayItemDefinition } from '@ng-forge/dynamic-forms/internal';
|
|
6
|
-
export { AddonActionContext, AddonActionPreset, AddonSlot, AddonTypeDefinition, AnyAddon, ArrayAllowedChildren, ArrayButtonConfig, ArrayField, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseAddon, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, CheckedFieldComponent, CommonAddonActionPreset, CommonAddonSlot, ComponentAddon, ConditionalExpression, ContainerAllowedChildren, ContainerField, ContainerFieldTypes, CssWrapper, CustomFnConfig, CustomFunction, CustomValidator, CustomValidatorConfig, DF_FIELD_TEMPLATES, DeclarativeHttpValidatorConfig, DynamicFormActionRegistry, DynamicFormAddonActionPresetRegistry, DynamicFormAddonRegistry, DynamicFormAddonSlotRegistry, DynamicFormError, DynamicFormFieldRegistry, DynamicFormLogger, DynamicText, DynamicValue, EvaluationContext, ExtractField, FieldBoundAddonActionContext, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldWithValidation, FieldWrapper, FormConfig, FormEvent, FormEventConstructor, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HiddenField, HiddenScalar, HiddenValue, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpValidationResponseMapping, InferFormValue, LeafFieldTypes, Logger, LogicConfig, NarrowField, NarrowFields, NextButtonOptions, NoopLogger, OrphanAddonActionContext, PageAllowedChildren, PageField, RegisteredActionRef, RegisteredFieldTypes, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationExecutionConfig, ValidationMessage, ValidationMessageResolver, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueType, WithInputSignals, WrapperConfig, WrapperTypeDefinition, hasFormValue, isArrayField, isContainerField, isDisplayOnlyField, isFieldBoundContext, isFormStateCondition, isGroupField, isHiddenField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isWrapperTypeDefinition, resolveDynamicValue } from '@ng-forge/dynamic-forms/internal';
|
|
7
2
|
import * as _angular_forms_signals from '@angular/forms/signals';
|
|
8
3
|
import { FieldTree } from '@angular/forms/signals';
|
|
9
4
|
import * as _angular_forms from '@angular/forms';
|
|
5
|
+
import * as _ng_forge_dynamic_forms_internal from '@ng-forge/dynamic-forms/internal';
|
|
6
|
+
import { FormEvent, FieldDef, RegisteredFieldTypes, InferFormModel, FormConfig, FormOptions, EventBus, LazyComponentLoader, WrapperTypeDefinition, FieldTypeDefinition, InferFormValue as InferFormValue$1, DerivationLogLevel, Logger, ValueExclusionConfig, ValidationExecutionConfig, TextAddon, WrapperFieldInputs, TemplateAddon, ComponentAddon, BaseAddon, AddonTypeDefinition, AddonActionHandler, ArrayItemDefinition } from '@ng-forge/dynamic-forms/internal';
|
|
7
|
+
export { AddonActionContext, AddonActionPreset, AddonSlot, AddonTypeDefinition, AnyAddon, ArrayAllowedChildren, ArrayButtonConfig, ArrayField, ArrayItemTemplate, AsyncCondition, AsyncConditionFunction, AsyncCustomValidator, AsyncDerivationFunction, AsyncValidatorConfig, AvailableFieldTypes, BaseAddon, BaseCheckedField, BaseValidatorConfig, BaseValueField, BuiltInValidatorConfig, CheckedFieldComponent, CommonAddonActionPreset, CommonAddonSlot, ComponentAddon, ConditionalExpression, ContainerAllowedChildren, ContainerField, ContainerFieldTypes, CssWrapper, CustomFnConfig, CustomFunction, CustomValidator, CustomValidatorConfig, DF_FIELD_TEMPLATES, DeclarativeHttpValidatorConfig, DynamicFormActionRegistry, DynamicFormAddonActionPresetRegistry, DynamicFormAddonRegistry, DynamicFormAddonSlotRegistry, DynamicFormError, DynamicFormFieldRegistry, DynamicFormLogger, DynamicText, DynamicValue, EvaluationContext, ExtractField, FieldBoundAddonActionContext, FieldComponent, FieldDef, FieldMeta, FieldOption, FieldPathAccess, FieldRegistryContainers, FieldRegistryLeaves, FieldRegistryWrappers, FieldWithValidation, FieldWrapper, FormConfig, FormEvent, FormEventConstructor, FormMode, FormModeDetectionResult, FormOptions, FormStateCondition, GroupAllowedChildren, GroupField, HiddenField, HiddenScalar, HiddenValue, HttpCondition, HttpCustomValidator, HttpRequestConfig, HttpValidationResponseMapping, InferFormValue, LeafFieldTypes, Logger, LogicConfig, NarrowField, NarrowFields, NextButtonOptions, NoopLogger, OrphanAddonActionContext, PageAllowedChildren, PageField, RegisteredActionRef, RegisteredFieldTypes, ResolvedValidationExecutionConfig, ResolvedValueExclusionConfig, RowAllowedChildren, RowField, SchemaApplicationConfig, SchemaDefinition, SimplifiedArrayField, StateLogicConfig, SubmissionActionResult, SubmissionConfig, SubmitButtonOptions, TemplateAddon, TextAddon, TextElementType, TextField, TextProps, TokenContext, ValidationError, ValidationExecutionConfig, ValidationMessage, ValidationMessageResolver, ValidationMessages, ValidatorConfig, ValueExclusionConfig, ValueFieldComponent, ValueType, WithInputSignals, WrapperConfig, WrapperTypeDefinition, hasFormValue, isArrayField, isContainerField, isDisplayOnlyField, isFieldBoundContext, isFormStateCondition, isGroupField, isHiddenField, isLeafField, isPageField, isRowField, isSimplifiedArrayField, isValueBearingField, isWrapperTypeDefinition, resolveDynamicValue } from '@ng-forge/dynamic-forms/internal';
|
|
8
|
+
import * as _angular_core from '@angular/core';
|
|
9
|
+
import { Type, Injector, Signal, EnvironmentInjector, WritableSignal, Provider, EnvironmentProviders, TemplateRef } from '@angular/core';
|
|
10
10
|
import * as _ng_forge_dynamic_forms from '@ng-forge/dynamic-forms';
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* removed from the DOM — Angular Signal Forms warns (NG01916) otherwise.
|
|
28
|
-
*/
|
|
29
|
-
hidden: Signal<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* Global default configuration for progressive field mounting ("field
|
|
14
|
+
* windowing"): fields beyond `eager` render as `@defer (on viewport)`
|
|
15
|
+
* placeholders instead of mounting immediately, and mount only once scrolled
|
|
16
|
+
* near/into view.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
interface FieldWindowingConfig {
|
|
21
|
+
/** Whether field windowing is active. */
|
|
22
|
+
readonly enabled: boolean;
|
|
23
|
+
/** Number of leading fields mounted eagerly (not windowed). */
|
|
24
|
+
readonly eager: number;
|
|
25
|
+
/** CSS `min-height` reserved for each unmounted field's placeholder. */
|
|
26
|
+
readonly placeholderHeight: string;
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
/** Error from async field component loading. */
|
|
@@ -84,6 +81,26 @@ declare class PageNavigationStateChangeEvent implements FormEvent {
|
|
|
84
81
|
constructor(state: PageOrchestratorState);
|
|
85
82
|
}
|
|
86
83
|
|
|
84
|
+
/** Resolved field ready for rendering with ngComponentOutlet / DfFieldOutlet. */
|
|
85
|
+
interface ResolvedField {
|
|
86
|
+
key: string;
|
|
87
|
+
/** The original field definition (used by DfFieldOutlet to resolve wrappers). */
|
|
88
|
+
fieldDef: FieldDef<unknown>;
|
|
89
|
+
component: Type<unknown>;
|
|
90
|
+
injector: Injector;
|
|
91
|
+
inputs: Signal<Record<string, unknown>>;
|
|
92
|
+
renderReady: Signal<boolean>;
|
|
93
|
+
/**
|
|
94
|
+
* Whether the field is currently hidden. Sourced from the FieldTree's
|
|
95
|
+
* `state.hidden()` for value-bearing fields (set by Angular Signal Forms in
|
|
96
|
+
* response to `hidden(path, …)` calls), or from the mapper's explicit
|
|
97
|
+
* `hidden` input for non-value fields (button, text, container, …). Consumers
|
|
98
|
+
* must `@if (!field.hidden())` around `*dfFieldOutlet` so hidden fields are
|
|
99
|
+
* removed from the DOM — Angular Signal Forms warns (NG01916) otherwise.
|
|
100
|
+
*/
|
|
101
|
+
hidden: Signal<boolean>;
|
|
102
|
+
}
|
|
103
|
+
|
|
87
104
|
/**
|
|
88
105
|
* Renders a form from a {@link FormConfig}. Attribute component on a native
|
|
89
106
|
* `<form>` element (selector `form[dynamic-form]`); state management is
|
|
@@ -135,6 +152,7 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
135
152
|
private logger;
|
|
136
153
|
private dispatcher;
|
|
137
154
|
private templateRegistry;
|
|
155
|
+
private globalFieldWindowing;
|
|
138
156
|
/** All `<ng-template dfTemplate="...">` instances projected into this form. */
|
|
139
157
|
private readonly _projectedTemplates;
|
|
140
158
|
private readonly stateManager;
|
|
@@ -162,6 +180,11 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
162
180
|
maxDerivationIterations?: number;
|
|
163
181
|
submitButton?: _ng_forge_dynamic_forms.SubmitButtonOptions;
|
|
164
182
|
nextButton?: _ng_forge_dynamic_forms.NextButtonOptions;
|
|
183
|
+
pagePreloadWindow?: number;
|
|
184
|
+
fieldWindowing?: boolean | {
|
|
185
|
+
eager?: number;
|
|
186
|
+
placeholderHeight?: string;
|
|
187
|
+
};
|
|
165
188
|
excludeValueIfHidden?: boolean;
|
|
166
189
|
excludeValueIfDisabled?: boolean;
|
|
167
190
|
excludeValueIfReadonly?: boolean;
|
|
@@ -197,6 +220,12 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
197
220
|
shouldRender: Signal<boolean>;
|
|
198
221
|
/** Resolved fields ready for rendering */
|
|
199
222
|
protected resolvedFields: Signal<ResolvedField[]>;
|
|
223
|
+
/**
|
|
224
|
+
* Effective field-windowing config for non-paged forms. Per-form
|
|
225
|
+
* `FormOptions.fieldWindowing` wins over the global `withFieldWindowing()`
|
|
226
|
+
* default; both fall back to disabled (fully eager).
|
|
227
|
+
*/
|
|
228
|
+
protected readonly fieldWindowing: Signal<FieldWindowingConfig>;
|
|
200
229
|
/**
|
|
201
230
|
* Recursively counts container components that will emit ComponentInitializedEvent.
|
|
202
231
|
* Includes the dynamic-form component itself (+1).
|
|
@@ -234,6 +263,15 @@ declare class DynamicForm<TFields extends RegisteredFieldTypes[] = RegisteredFie
|
|
|
234
263
|
* @param event - The native submit event from the form element
|
|
235
264
|
*/
|
|
236
265
|
protected onNativeSubmit(event: Event): void;
|
|
266
|
+
/**
|
|
267
|
+
* Whether a field should be deferred by field windowing. Containers are never
|
|
268
|
+
* windowed: they emit `ComponentInitializedEvent`, which the form's init
|
|
269
|
+
* tracker counts, so deferring one would stall `initialized` until it scrolls
|
|
270
|
+
* into view. Leaf fields carry no such count, so they defer freely.
|
|
271
|
+
*/
|
|
272
|
+
protected windowsField(field: ResolvedField, index: number): boolean;
|
|
273
|
+
/** Class string for a windowed field's placeholder — matches the real field's grid column. */
|
|
274
|
+
protected placeholderGridClass(field: ResolvedField): string;
|
|
237
275
|
private setupEffects;
|
|
238
276
|
/**
|
|
239
277
|
* Populates FORM_STATE_DEPS with this component's input signals, then injects
|
|
@@ -450,6 +488,68 @@ declare function withEventFormValue(): DynamicFormFeature<'event-form-value'>;
|
|
|
450
488
|
*/
|
|
451
489
|
declare function withValueExclusionDefaults(config?: Partial<ValueExclusionConfig>): DynamicFormFeature<'value-exclusion'>;
|
|
452
490
|
|
|
491
|
+
/**
|
|
492
|
+
* Configures the global page preload window for paged forms — how many pages on
|
|
493
|
+
* each side of the current page are eagerly mounted.
|
|
494
|
+
*
|
|
495
|
+
* @remarks
|
|
496
|
+
* Paged forms only ever display one page at a time, so mounting every page (the
|
|
497
|
+
* fields, containers, and change-detection of pages the user may never reach)
|
|
498
|
+
* is wasted work: it inflates initial-render time and makes every keystroke pay
|
|
499
|
+
* change detection for off-screen pages. The preload window bounds how much is
|
|
500
|
+
* mounted around the current page. Pages outside the window render a lightweight
|
|
501
|
+
* placeholder and mount the moment navigation brings them inside it.
|
|
502
|
+
*
|
|
503
|
+
* **Precedence:**
|
|
504
|
+
* 1. Per-form `pagePreloadWindow` on `FormOptions` — wins for that form
|
|
505
|
+
* 2. Global `withPagePreload(n)` — baseline default for all forms
|
|
506
|
+
* 3. No feature — token default (`1`, i.e. current page ±1)
|
|
507
|
+
*
|
|
508
|
+
* @param window - Pages to preload on each side of the current page. `0` mounts
|
|
509
|
+
* only the current page; `1` (default) mounts ±1 for flicker-free sequential
|
|
510
|
+
* navigation; higher values pre-warm more pages for jump navigation. Negative
|
|
511
|
+
* values are clamped to `0`.
|
|
512
|
+
* @returns A DynamicFormFeature that configures the global preload window
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```typescript
|
|
516
|
+
* provideDynamicForm(...withMaterialFields(), withPagePreload(2));
|
|
517
|
+
* ```
|
|
518
|
+
*/
|
|
519
|
+
declare function withPagePreload(window: number): DynamicFormFeature<'page-preload'>;
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Configures global progressive field mounting ("field windowing") for large
|
|
523
|
+
* flat (single-page) forms.
|
|
524
|
+
*
|
|
525
|
+
* @remarks
|
|
526
|
+
* A flat form mounts every field eagerly, so a large form pays the full
|
|
527
|
+
* initial-render cost up front and every keystroke walks all N live views —
|
|
528
|
+
* even for fields far off-screen. Field windowing bounds how much is mounted:
|
|
529
|
+
* the first `eager` fields render immediately, and the rest render as a
|
|
530
|
+
* lightweight placeholder that mounts the moment it scrolls near/into view.
|
|
531
|
+
* Validators, derivations, and values live at the Signal Forms schema level
|
|
532
|
+
* (not the DOM), so unmounted fields keep full form semantics.
|
|
533
|
+
*
|
|
534
|
+
* **Precedence:**
|
|
535
|
+
* 1. Per-form `fieldWindowing` on `FormOptions` — wins for that form
|
|
536
|
+
* 2. Global `withFieldWindowing(...)` — baseline default for all forms
|
|
537
|
+
* 3. No feature — token default (disabled, i.e. fully eager)
|
|
538
|
+
*
|
|
539
|
+
* @param config - `eager` (default `12`) and `placeholderHeight` (default `'4rem'`)
|
|
540
|
+
* overrides. `eager` is clamped to a non-negative integer.
|
|
541
|
+
* @returns A DynamicFormFeature that enables the global field windowing default
|
|
542
|
+
*
|
|
543
|
+
* @example
|
|
544
|
+
* ```typescript
|
|
545
|
+
* provideDynamicForm(...withMaterialFields(), withFieldWindowing({ eager: 20 }));
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
declare function withFieldWindowing(config?: {
|
|
549
|
+
eager?: number;
|
|
550
|
+
placeholderHeight?: string;
|
|
551
|
+
}): DynamicFormFeature<'field-windowing'>;
|
|
552
|
+
|
|
453
553
|
/**
|
|
454
554
|
* Configures global validation execution defaults — when validators should run
|
|
455
555
|
* relative to a field's reactive state.
|
|
@@ -878,5 +978,5 @@ interface ArrayItemContext {
|
|
|
878
978
|
formValue?: unknown;
|
|
879
979
|
}
|
|
880
980
|
|
|
881
|
-
export { AppendArrayItemEvent, BUILT_IN_FIELDS, ComponentAddonComponent, ConsoleLogger, DfTemplate, DynamicForm, EventDispatcher, FormClearEvent, FormResetEvent, FormSubmitEvent, InsertArrayItemEvent, MoveArrayItemEvent, NextPageEvent, PageChangeEvent, PopArrayItemEvent, PrependArrayItemEvent, PreviousPageEvent, RemoveAtIndexEvent, ShiftArrayItemEvent, TemplateAddonComponent, TextAddonComponent, arrayEvent, createWrappers, isWrappersBundle, provideDynamicForm, sanitizeFormConfig, withAddonActions, withCustomAddon, withEventFormValue, withLegacyStatusClasses, withLoggerConfig, withValidationExecutionDefaults, withValueExclusionDefaults, wrapperProps };
|
|
981
|
+
export { AppendArrayItemEvent, BUILT_IN_FIELDS, ComponentAddonComponent, ConsoleLogger, DfTemplate, DynamicForm, EventDispatcher, FormClearEvent, FormResetEvent, FormSubmitEvent, InsertArrayItemEvent, MoveArrayItemEvent, NextPageEvent, PageChangeEvent, PopArrayItemEvent, PrependArrayItemEvent, PreviousPageEvent, RemoveAtIndexEvent, ShiftArrayItemEvent, TemplateAddonComponent, TextAddonComponent, arrayEvent, createWrappers, isWrappersBundle, provideDynamicForm, sanitizeFormConfig, withAddonActions, withCustomAddon, withEventFormValue, withFieldWindowing, withLegacyStatusClasses, withLoggerConfig, withPagePreload, withValidationExecutionDefaults, withValueExclusionDefaults, wrapperProps };
|
|
882
982
|
export type { AddonActionsFeature, AddonWarning, ArrayItemContext, ArrayItemDefinitionTemplate, ExtractFieldDefs, ExtractFormValue, InferWrapperRegistry, SanitizeFormConfigOptions, SanitizedFormConfig, WrapperRegistration, WrappersBundle };
|