@ng-forge/dynamic-forms 0.1.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.
- package/README.md +77 -0
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms--Qgd-rJE.mjs +7359 -0
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms--Qgd-rJE.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-DcZh9mv6.mjs +112 -0
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-DcZh9mv6.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-text-field.component-CnLc464X.mjs +113 -0
- package/fesm2022/ng-forge-dynamic-forms-text-field.component-CnLc464X.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms.mjs +2 -0
- package/fesm2022/ng-forge-dynamic-forms.mjs.map +1 -0
- package/package.json +51 -0
- package/types/ng-forge-dynamic-forms.d.ts +3462 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, DestroyRef, Injector, input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { NgComponentOutlet } from '@angular/common';
|
|
4
|
+
import { outputFromObservable } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { pipe, switchMap, of, forkJoin, map, scan } from 'rxjs';
|
|
6
|
+
import { i as injectFieldRegistry, E as EventBus, v as validatePageNesting, d as derivedFromDeferred, r as resolveField, a as reconcileFields, e as emitComponentInitialized } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms--Qgd-rJE.mjs';
|
|
7
|
+
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Renders a single page in multi-page (wizard) forms.
|
|
11
|
+
*
|
|
12
|
+
* Visibility is controlled by the PageOrchestrator via the isVisible input.
|
|
13
|
+
* Pages cannot be nested within other pages - validation prevents this.
|
|
14
|
+
* Field values are flattened into the parent form (no nesting under page key).
|
|
15
|
+
*/
|
|
16
|
+
class PageFieldComponent {
|
|
17
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
+
// Dependencies
|
|
19
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
destroyRef = inject(DestroyRef);
|
|
21
|
+
fieldRegistry = injectFieldRegistry();
|
|
22
|
+
injector = inject(Injector);
|
|
23
|
+
eventBus = inject(EventBus);
|
|
24
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
25
|
+
// Inputs
|
|
26
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
27
|
+
field = input.required({ ...(ngDevMode ? { debugName: "field" } : {}) });
|
|
28
|
+
key = input.required({ ...(ngDevMode ? { debugName: "key" } : {}) });
|
|
29
|
+
pageIndex = input.required({ ...(ngDevMode ? { debugName: "pageIndex" } : {}) });
|
|
30
|
+
isVisible = input.required({ ...(ngDevMode ? { debugName: "isVisible" } : {}) });
|
|
31
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
+
// Computed Signals
|
|
33
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
34
|
+
disabled = computed(() => this.field().disabled || false, { ...(ngDevMode ? { debugName: "disabled" } : {}) });
|
|
35
|
+
isValid = computed(() => {
|
|
36
|
+
const pageField = this.field();
|
|
37
|
+
const valid = validatePageNesting(pageField);
|
|
38
|
+
if (!valid) {
|
|
39
|
+
console.error(`[Dynamic Forms] Invalid configuration: Page '${pageField.key}' contains nested page fields. ` +
|
|
40
|
+
`Pages cannot contain other pages. Consider using groups or rows for nested structure.`, pageField);
|
|
41
|
+
}
|
|
42
|
+
return valid;
|
|
43
|
+
}, { ...(ngDevMode ? { debugName: "isValid" } : {}) });
|
|
44
|
+
rawFieldRegistry = computed(() => this.fieldRegistry.raw, { ...(ngDevMode ? { debugName: "rawFieldRegistry" } : {}) });
|
|
45
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
46
|
+
// Outputs
|
|
47
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
48
|
+
nextPage = outputFromObservable(this.eventBus.on('next-page'));
|
|
49
|
+
previousPage = outputFromObservable(this.eventBus.on('previous-page'));
|
|
50
|
+
pageChange = outputFromObservable(this.eventBus.on('page-change'));
|
|
51
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
52
|
+
// Field Resolution
|
|
53
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
54
|
+
fieldsSource = computed(() => {
|
|
55
|
+
if (!this.isValid()) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
return this.field().fields || [];
|
|
59
|
+
}, { ...(ngDevMode ? { debugName: "fieldsSource" } : {}) });
|
|
60
|
+
resolvedFields = derivedFromDeferred(this.fieldsSource, pipe(switchMap((fields) => {
|
|
61
|
+
if (!fields || fields.length === 0) {
|
|
62
|
+
return of([]);
|
|
63
|
+
}
|
|
64
|
+
const pageKey = this.field().key;
|
|
65
|
+
const context = {
|
|
66
|
+
loadTypeComponent: (type) => this.fieldRegistry.loadTypeComponent(type),
|
|
67
|
+
registry: this.rawFieldRegistry(),
|
|
68
|
+
injector: this.injector,
|
|
69
|
+
destroyRef: this.destroyRef,
|
|
70
|
+
onError: (fieldDef, error) => {
|
|
71
|
+
const fieldKey = fieldDef.key || '<no key>';
|
|
72
|
+
console.error(`[Dynamic Forms] Failed to load component for field type '${fieldDef.type}' (key: ${fieldKey}) ` +
|
|
73
|
+
`within page '${pageKey}'. Ensure the field type is registered in your field registry.`, error);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
return forkJoin(fields.map((f) => resolveField(f, context)));
|
|
77
|
+
}), map((fields) => fields.filter((f) => f !== undefined)), scan(reconcileFields, [])), { initialValue: [], injector: this.injector });
|
|
78
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
79
|
+
// Effects
|
|
80
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
81
|
+
emitInitializedOnFieldsResolved = explicitEffect([this.resolvedFields], ([fields]) => {
|
|
82
|
+
if (fields.length > 0) {
|
|
83
|
+
emitComponentInitialized(this.eventBus, 'page', this.field().key, this.injector);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: PageFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
87
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.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 }, 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.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()" }, classAttribute: "df-field df-page-field" }, ngImport: i0, template: `
|
|
88
|
+
@for (field of resolvedFields(); track field.key) {
|
|
89
|
+
<ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
|
|
90
|
+
}
|
|
91
|
+
`, isInline: true, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);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);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);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.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),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);--df-grid-row-gap: var(--df-grid-row-gap-md)}.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);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.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);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.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);transition:opacity .2s ease-in-out}:host.df-page-spacing-custom{--df-grid-row-gap: var(--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 .3s ease-in-out,transform .3s ease-in-out}:host.df-page-visible{transform:translate(0)}:host.df-page-hidden{transform:translate(-10px)}}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
92
|
+
}
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: PageFieldComponent, decorators: [{
|
|
94
|
+
type: Component,
|
|
95
|
+
args: [{ selector: 'section[page-field]', imports: [NgComponentOutlet], template: `
|
|
96
|
+
@for (field of resolvedFields(); track field.key) {
|
|
97
|
+
<ng-container *ngComponentOutlet="field.component; injector: field.injector; inputs: field.inputs()" />
|
|
98
|
+
}
|
|
99
|
+
`, host: {
|
|
100
|
+
class: 'df-field df-page-field',
|
|
101
|
+
'[class.disabled]': 'disabled()',
|
|
102
|
+
'[class.df-page-visible]': 'isVisible()',
|
|
103
|
+
'[class.df-page-hidden]': '!isVisible()',
|
|
104
|
+
'[attr.aria-hidden]': '!isVisible()',
|
|
105
|
+
'[attr.data-page-index]': 'pageIndex()',
|
|
106
|
+
'[id]': '`${key()}`',
|
|
107
|
+
'[attr.data-testid]': 'key()',
|
|
108
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host,.df-form{--df-grid-columns: 12;--df-grid-gap: .5rem;--df-grid-row-gap: .5rem;--df-breakpoint-sm: 576px;--df-breakpoint-md: 768px;--df-breakpoint-lg: 992px;--df-breakpoint-xl: 1200px;--df-grid-gap-sm: .5rem;--df-grid-gap-md: .5rem;--df-grid-gap-lg: .5rem;--df-grid-gap-xl: .5rem;--df-grid-row-gap-sm: .5rem;--df-grid-row-gap-md: .5rem;--df-grid-row-gap-lg: .5rem;--df-grid-row-gap-xl: .5rem;--df-group-gap: var(--df-grid-gap);--df-group-padding: var(--df-grid-gap)}.df-form{display:grid;grid-template-columns:1fr;gap:var(--df-grid-row-gap);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);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);--df-grid-row-gap: var(--df-grid-row-gap-sm)}.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),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);--df-grid-row-gap: var(--df-grid-row-gap-md)}.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);--df-grid-row-gap: var(--df-grid-row-gap-lg)}.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);--df-grid-row-gap: var(--df-grid-row-gap-xl)}.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);transition:opacity .2s ease-in-out}:host.df-page-spacing-custom{--df-grid-row-gap: var(--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 .3s ease-in-out,transform .3s ease-in-out}:host.df-page-visible{transform:translate(0)}:host.df-page-hidden{transform:translate(-10px)}}@media(prefers-reduced-motion:reduce){:host{transition:none}}\n"] }]
|
|
109
|
+
}], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], 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"] }] } });
|
|
110
|
+
|
|
111
|
+
export { PageFieldComponent as default };
|
|
112
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-page-field.component-DcZh9mv6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-page-field.component-DcZh9mv6.mjs","sources":["../../../../packages/dynamic-forms/src/lib/fields/page/page-field.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, Injector, input } from '@angular/core';\nimport { NgComponentOutlet } from '@angular/common';\nimport { outputFromObservable } from '@angular/core/rxjs-interop';\nimport { forkJoin, map, of, pipe, scan, switchMap } from 'rxjs';\nimport { derivedFromDeferred } from '../../utils/derived-from-deferred/derived-from-deferred';\nimport { reconcileFields, ResolvedField, resolveField } from '../../utils/resolve-field/resolve-field';\nimport { emitComponentInitialized } from '../../utils/emit-initialization/emit-initialization';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { PageField, validatePageNesting } from '../../definitions/default/page-field';\nimport { injectFieldRegistry } from '../../utils/inject-field-registry/inject-field-registry';\nimport { EventBus } from '../../events/event.bus';\nimport { NextPageEvent, PageChangeEvent, PreviousPageEvent } from '../../events/constants';\nimport { FieldDef } from '../../definitions/base/field-def';\n\n/**\n * Renders a single page in multi-page (wizard) forms.\n *\n * Visibility is controlled by the PageOrchestrator via the isVisible input.\n * Pages cannot be nested within other pages - validation prevents this.\n * Field values are flattened into the parent form (no nesting under page key).\n */\n@Component({\n selector: 'section[page-field]',\n imports: [NgComponentOutlet],\n template: `\n @for (field of resolvedFields(); track field.key) {\n <ng-container *ngComponentOutlet=\"field.component; injector: field.injector; inputs: field.inputs()\" />\n }\n `,\n styleUrl: './page-field.component.scss',\n host: {\n class: 'df-field df-page-field',\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 private readonly eventBus = inject(EventBus);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Inputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n field = input.required<PageField>();\n key = input.required<string>();\n pageIndex = input.required<number>();\n isVisible = input.required<boolean>();\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Computed Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly disabled = computed(() => this.field().disabled || false);\n\n readonly isValid = computed(() => {\n const pageField = this.field();\n const valid = validatePageNesting(pageField);\n\n if (!valid) {\n console.error(\n `[Dynamic Forms] 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 return valid;\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 pipe(\n switchMap((fields) => {\n if (!fields || fields.length === 0) {\n return of([] as (ResolvedField | undefined)[]);\n }\n const pageKey = this.field().key;\n const context = {\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 console.error(\n `[Dynamic Forms] Failed to load component for field type '${fieldDef.type}' (key: ${fieldKey}) ` +\n `within page '${pageKey}'. Ensure the field type is registered in your field registry.`,\n error,\n );\n },\n };\n return forkJoin(fields.map((f) => resolveField(f as FieldDef<unknown>, context)));\n }),\n map((fields) => fields.filter((f): f is ResolvedField => f !== undefined)),\n scan(reconcileFields, [] as ResolvedField[]),\n ),\n { initialValue: [] as ResolvedField[], injector: this.injector },\n );\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Effects\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly emitInitializedOnFieldsResolved = explicitEffect([this.resolvedFields], ([fields]) => {\n if (fields.length > 0) {\n emitComponentInitialized(this.eventBus, 'page', this.field().key, this.injector);\n }\n });\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { AsyncPipe } from '@angular/common';
|
|
4
|
+
import { D as DynamicTextPipe } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms--Qgd-rJE.mjs';
|
|
5
|
+
|
|
6
|
+
class TextFieldComponent {
|
|
7
|
+
key = input.required({ ...(ngDevMode ? { debugName: "key" } : {}) });
|
|
8
|
+
label = input.required({ ...(ngDevMode ? { debugName: "label" } : {}) });
|
|
9
|
+
className = input(undefined, { ...(ngDevMode ? { debugName: "className" } : {}) });
|
|
10
|
+
tabIndex = input(undefined, { ...(ngDevMode ? { debugName: "tabIndex" } : {}) });
|
|
11
|
+
hidden = input(undefined, { ...(ngDevMode ? { debugName: "hidden" } : {}) });
|
|
12
|
+
props = input(undefined, { ...(ngDevMode ? { debugName: "props" } : {}) });
|
|
13
|
+
elementType = computed(() => this.props()?.elementType || 'p', { ...(ngDevMode ? { debugName: "elementType" } : {}) });
|
|
14
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TextFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.1", type: TextFieldComponent, isStandalone: true, selector: "df-text", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "id": "`${key()}`", "attr.data-testid": "key()", "attr.hidden": "hidden() || null" } }, ngImport: i0, template: `
|
|
16
|
+
@switch (elementType()) {
|
|
17
|
+
@case ('p') {
|
|
18
|
+
<p class="df-text df-text-p" [class]="className() || ''">
|
|
19
|
+
{{ label() | dynamicText | async }}
|
|
20
|
+
</p>
|
|
21
|
+
}
|
|
22
|
+
@case ('h1') {
|
|
23
|
+
<h1 class="df-text df-text-h1" [class]="className() || ''">
|
|
24
|
+
{{ label() | dynamicText | async }}
|
|
25
|
+
</h1>
|
|
26
|
+
}
|
|
27
|
+
@case ('h2') {
|
|
28
|
+
<h2 class="df-text df-text-h2" [class]="className() || ''">
|
|
29
|
+
{{ label() | dynamicText | async }}
|
|
30
|
+
</h2>
|
|
31
|
+
}
|
|
32
|
+
@case ('h3') {
|
|
33
|
+
<h3 class="df-text df-text-h3" [class]="className() || ''">
|
|
34
|
+
{{ label() | dynamicText | async }}
|
|
35
|
+
</h3>
|
|
36
|
+
}
|
|
37
|
+
@case ('h4') {
|
|
38
|
+
<h4 class="df-text df-text-h4" [class]="className() || ''">
|
|
39
|
+
{{ label() | dynamicText | async }}
|
|
40
|
+
</h4>
|
|
41
|
+
}
|
|
42
|
+
@case ('h5') {
|
|
43
|
+
<h5 class="df-text df-text-h5" [class]="className() || ''">
|
|
44
|
+
{{ label() | dynamicText | async }}
|
|
45
|
+
</h5>
|
|
46
|
+
}
|
|
47
|
+
@case ('h6') {
|
|
48
|
+
<h6 class="df-text df-text-h6" [class]="className() || ''">
|
|
49
|
+
{{ label() | dynamicText | async }}
|
|
50
|
+
</h6>
|
|
51
|
+
}
|
|
52
|
+
@case ('span') {
|
|
53
|
+
<span class="df-text df-text-span" [class]="className() || ''">
|
|
54
|
+
{{ label() | dynamicText | async }}
|
|
55
|
+
</span>
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`, isInline: true, styles: [":host([hidden]){display:none!important}.df-text{font-size:var(--df-text-font-size, 1rem);font-family:var(--df-text-font-family, inherit);font-weight:var(--df-text-font-weight, normal);color:var(--df-text-color, inherit);line-height:var(--df-text-line-height, 1.5);text-align:var(--df-text-text-align, inherit);letter-spacing:var(--df-text-letter-spacing, normal);text-decoration:var(--df-text-text-decoration, none);text-transform:var(--df-text-text-transform, none);margin:var(--df-text-margin, 0);padding:var(--df-text-padding, 0)}.df-text-h1{font-size:var(--df-text-h1-font-size, 2rem);font-weight:var(--df-text-h1-font-weight, bold);margin:var(--df-text-h1-margin, 0)}.df-text-h2{font-size:var(--df-text-h2-font-size, 1.75rem);font-weight:var(--df-text-h2-font-weight, bold);margin:var(--df-text-h2-margin, 0)}.df-text-h3{font-size:var(--df-text-h3-font-size, 1.5rem);font-weight:var(--df-text-h3-font-weight, bold);margin:var(--df-text-h3-margin, 0)}.df-text-h4{font-size:var(--df-text-h4-font-size, 1.25rem);font-weight:var(--df-text-h4-font-weight, bold);margin:var(--df-text-h4-margin, 0)}.df-text-h5{font-size:var(--df-text-h5-font-size, 1.125rem);font-weight:var(--df-text-h5-font-weight, bold);margin:var(--df-text-h5-margin, 0)}.df-text-h6{font-size:var(--df-text-h6-font-size, 1rem);font-weight:var(--df-text-h6-font-weight, bold);margin:var(--df-text-h6-margin, 0)}.df-text-p{font-size:var(--df-text-p-font-size, 1rem);margin:var(--df-text-p-margin, 0)}.df-text-span{display:var(--df-text-span-display, inline)}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DynamicTextPipe, name: "dynamicText" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
59
|
+
}
|
|
60
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TextFieldComponent, decorators: [{
|
|
61
|
+
type: Component,
|
|
62
|
+
args: [{ selector: 'df-text', template: `
|
|
63
|
+
@switch (elementType()) {
|
|
64
|
+
@case ('p') {
|
|
65
|
+
<p class="df-text df-text-p" [class]="className() || ''">
|
|
66
|
+
{{ label() | dynamicText | async }}
|
|
67
|
+
</p>
|
|
68
|
+
}
|
|
69
|
+
@case ('h1') {
|
|
70
|
+
<h1 class="df-text df-text-h1" [class]="className() || ''">
|
|
71
|
+
{{ label() | dynamicText | async }}
|
|
72
|
+
</h1>
|
|
73
|
+
}
|
|
74
|
+
@case ('h2') {
|
|
75
|
+
<h2 class="df-text df-text-h2" [class]="className() || ''">
|
|
76
|
+
{{ label() | dynamicText | async }}
|
|
77
|
+
</h2>
|
|
78
|
+
}
|
|
79
|
+
@case ('h3') {
|
|
80
|
+
<h3 class="df-text df-text-h3" [class]="className() || ''">
|
|
81
|
+
{{ label() | dynamicText | async }}
|
|
82
|
+
</h3>
|
|
83
|
+
}
|
|
84
|
+
@case ('h4') {
|
|
85
|
+
<h4 class="df-text df-text-h4" [class]="className() || ''">
|
|
86
|
+
{{ label() | dynamicText | async }}
|
|
87
|
+
</h4>
|
|
88
|
+
}
|
|
89
|
+
@case ('h5') {
|
|
90
|
+
<h5 class="df-text df-text-h5" [class]="className() || ''">
|
|
91
|
+
{{ label() | dynamicText | async }}
|
|
92
|
+
</h5>
|
|
93
|
+
}
|
|
94
|
+
@case ('h6') {
|
|
95
|
+
<h6 class="df-text df-text-h6" [class]="className() || ''">
|
|
96
|
+
{{ label() | dynamicText | async }}
|
|
97
|
+
</h6>
|
|
98
|
+
}
|
|
99
|
+
@case ('span') {
|
|
100
|
+
<span class="df-text df-text-span" [class]="className() || ''">
|
|
101
|
+
{{ label() | dynamicText | async }}
|
|
102
|
+
</span>
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
`, imports: [AsyncPipe, DynamicTextPipe], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
106
|
+
'[id]': '`${key()}`',
|
|
107
|
+
'[attr.data-testid]': 'key()',
|
|
108
|
+
'[attr.hidden]': 'hidden() || null',
|
|
109
|
+
}, styles: [":host([hidden]){display:none!important}.df-text{font-size:var(--df-text-font-size, 1rem);font-family:var(--df-text-font-family, inherit);font-weight:var(--df-text-font-weight, normal);color:var(--df-text-color, inherit);line-height:var(--df-text-line-height, 1.5);text-align:var(--df-text-text-align, inherit);letter-spacing:var(--df-text-letter-spacing, normal);text-decoration:var(--df-text-text-decoration, none);text-transform:var(--df-text-text-transform, none);margin:var(--df-text-margin, 0);padding:var(--df-text-padding, 0)}.df-text-h1{font-size:var(--df-text-h1-font-size, 2rem);font-weight:var(--df-text-h1-font-weight, bold);margin:var(--df-text-h1-margin, 0)}.df-text-h2{font-size:var(--df-text-h2-font-size, 1.75rem);font-weight:var(--df-text-h2-font-weight, bold);margin:var(--df-text-h2-margin, 0)}.df-text-h3{font-size:var(--df-text-h3-font-size, 1.5rem);font-weight:var(--df-text-h3-font-weight, bold);margin:var(--df-text-h3-margin, 0)}.df-text-h4{font-size:var(--df-text-h4-font-size, 1.25rem);font-weight:var(--df-text-h4-font-weight, bold);margin:var(--df-text-h4-margin, 0)}.df-text-h5{font-size:var(--df-text-h5-font-size, 1.125rem);font-weight:var(--df-text-h5-font-weight, bold);margin:var(--df-text-h5-margin, 0)}.df-text-h6{font-size:var(--df-text-h6-font-size, 1rem);font-weight:var(--df-text-h6-font-weight, bold);margin:var(--df-text-h6-margin, 0)}.df-text-p{font-size:var(--df-text-p-font-size, 1rem);margin:var(--df-text-p-margin, 0)}.df-text-span{display:var(--df-text-span-display, inline)}\n"] }]
|
|
110
|
+
}], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }], props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }] } });
|
|
111
|
+
|
|
112
|
+
export { TextFieldComponent as default };
|
|
113
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-text-field.component-CnLc464X.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-text-field.component-CnLc464X.mjs","sources":["../../../../packages/dynamic-forms/src/lib/fields/text/text-field.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { AsyncPipe } from '@angular/common';\nimport { DynamicTextPipe } from '../../pipes/dynamic-text/dynamic-text.pipe';\nimport { TextProps } from '../../definitions/default/text-field';\nimport { DynamicText } from '../../models/types/dynamic-text';\n\n@Component({\n selector: 'df-text',\n template: `\n @switch (elementType()) {\n @case ('p') {\n <p class=\"df-text df-text-p\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </p>\n }\n @case ('h1') {\n <h1 class=\"df-text df-text-h1\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </h1>\n }\n @case ('h2') {\n <h2 class=\"df-text df-text-h2\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </h2>\n }\n @case ('h3') {\n <h3 class=\"df-text df-text-h3\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </h3>\n }\n @case ('h4') {\n <h4 class=\"df-text df-text-h4\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </h4>\n }\n @case ('h5') {\n <h5 class=\"df-text df-text-h5\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </h5>\n }\n @case ('h6') {\n <h6 class=\"df-text df-text-h6\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </h6>\n }\n @case ('span') {\n <span class=\"df-text df-text-span\" [class]=\"className() || ''\">\n {{ label() | dynamicText | async }}\n </span>\n }\n }\n `,\n styleUrl: './text-field.component.scss',\n imports: [AsyncPipe, DynamicTextPipe],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n '[attr.hidden]': 'hidden() || null',\n },\n})\nexport default class TextFieldComponent {\n readonly key = input.required<string>();\n readonly label = input.required<DynamicText>();\n readonly className = input<string>();\n readonly tabIndex = input<number>();\n readonly hidden = input<boolean>();\n readonly props = input<TextProps>();\n\n readonly elementType = computed(() => this.props()?.elementType || 'p');\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { O as ARRAY_CONTEXT, A as AddArrayItemEvent, W as ArrayFieldComponent, a0 as BUILT_IN_FIELDS, b as DynamicForm, D as DynamicTextPipe, E as EventBus, L as FIELD_REGISTRY, Q as FIELD_SIGNAL_CONTEXT, F as FormClearEvent, u as FormResetEvent, X as GroupFieldComponent, N as NextPageEvent, P as PageChangeEvent, w as PreviousPageEvent, R as RemoveArrayItemEvent, Y as RowFieldComponent, S as SubmitEvent, Z as applyValidator, _ as applyValidators, x as arrayFieldMapper, y as baseFieldMapper, z as buildBaseInputs, B as checkboxFieldMapper, T as createResolvedErrorsSignal, C as datepickerFieldMapper, V as dynamicTextToObservable, a1 as getChildFieldTree, a2 as getChildrenMap, a3 as getFieldProxy, M as getFieldValueHandling, G as groupFieldMapper, a4 as hasFormStructure, i as injectFieldRegistry, k as isArrayField, h as isCheckedField, l as isContainerField, m as isDisplayOnlyField, c as isFormStateCondition, n as isGroupField, o as isLeafField, q as isPageField, s as isRowField, t as isValueBearingField, j as isValueField, I as optionsFieldMapper, H as pageFieldMapper, p as provideDynamicForm, g as resolveNextButtonDisabled, f as resolveSubmitButtonDisabled, $ as resolveTokens, J as rowFieldMapper, U as shouldShowErrors, K as valueFieldMapper } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms--Qgd-rJE.mjs';
|
|
2
|
+
//# sourceMappingURL=ng-forge-dynamic-forms.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ng-forge/dynamic-forms",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Type-safe, signal-powered dynamic forms for Angular. Build complex forms from configuration with full TypeScript inference.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "ng-forge",
|
|
8
|
+
"homepage": "https://ng-forge.com/dynamic-forms",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/ng-forge/ng-forge.git",
|
|
12
|
+
"directory": "packages/dynamic-forms"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/ng-forge/ng-forge/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"angular",
|
|
19
|
+
"forms",
|
|
20
|
+
"dynamic-forms",
|
|
21
|
+
"reactive-forms",
|
|
22
|
+
"signal-forms",
|
|
23
|
+
"form-builder",
|
|
24
|
+
"form-generator",
|
|
25
|
+
"type-safe",
|
|
26
|
+
"typescript",
|
|
27
|
+
"angular-forms"
|
|
28
|
+
],
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"@angular/common": ">=19.0.0",
|
|
31
|
+
"@angular/core": ">=19.0.0",
|
|
32
|
+
"@angular/forms": ">=19.0.0",
|
|
33
|
+
"ngxtension": ">=4.0.0",
|
|
34
|
+
"rxjs": ">=7.0.0"
|
|
35
|
+
},
|
|
36
|
+
"module": "fesm2022/ng-forge-dynamic-forms.mjs",
|
|
37
|
+
"typings": "types/ng-forge-dynamic-forms.d.ts",
|
|
38
|
+
"exports": {
|
|
39
|
+
"./package.json": {
|
|
40
|
+
"default": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
".": {
|
|
43
|
+
"types": "./types/ng-forge-dynamic-forms.d.ts",
|
|
44
|
+
"default": "./fesm2022/ng-forge-dynamic-forms.mjs"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"sideEffects": false,
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"tslib": "^2.3.0"
|
|
50
|
+
}
|
|
51
|
+
}
|