@ng-forge/dynamic-forms 1.2.0-next.4 → 1.2.0-next.5
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 +11 -11
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-BLPWSurR.mjs → ng-forge-dynamic-forms-array-field.component-D-VWBM-t.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-BLPWSurR.mjs.map → ng-forge-dynamic-forms-array-field.component-D-VWBM-t.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-jHiY95pr.mjs → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-OBDy6qd9.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-jHiY95pr.mjs.map → ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-OBDy6qd9.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-ug5tp6kt.mjs → ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-ug5tp6kt.mjs.map → ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-DyD00a1U.mjs → ng-forge-dynamic-forms-group-field.component-BNjYMTqT.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-DyD00a1U.mjs.map → ng-forge-dynamic-forms-group-field.component-BNjYMTqT.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-BGRxIQ2V.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-DSXZJHcu.mjs} +45 -15
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-DSXZJHcu.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-B7A2v1vN.mjs → ng-forge-dynamic-forms-page-field.component-B92kLZkH.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-B7A2v1vN.mjs.map → ng-forge-dynamic-forms-page-field.component-B92kLZkH.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +1 -1
- package/types/ng-forge-dynamic-forms-internal.d.ts +30 -1
- package/types/ng-forge-dynamic-forms.d.ts +26 -8
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-BGRxIQ2V.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, DestroyRef, Injector, EnvironmentInjector, viewChild, TemplateRef, ViewContainerRef, input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { i as injectFieldRegistry, c as createFieldResolutionPipe, r as resolveWrappers, a as isSameWrapperChain, b as createWrapperChainController, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-
|
|
3
|
+
import { i as injectFieldRegistry, c as createFieldResolutionPipe, r as resolveWrappers, a as isSameWrapperChain, b as createWrapperChainController, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-DSXZJHcu.mjs';
|
|
4
4
|
import { EventBus, DynamicFormLogger, WRAPPER_AUTO_ASSOCIATIONS, DEFAULT_WRAPPERS, derivedFromDeferred } from '@ng-forge/dynamic-forms/internal';
|
|
5
5
|
import { c as computeContainerHostClasses, s as setupContainerInitEffect } from './ng-forge-dynamic-forms-container-utils-BZFz6ztF.mjs';
|
|
6
6
|
|
|
@@ -86,4 +86,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
86
86
|
}], ctorParameters: () => [], propDecorators: { childrenTpl: [{ type: i0.ViewChild, args: ['childrenTpl', { ...{ read: TemplateRef }, isSignal: true }] }], wrapperContainer: [{ type: i0.ViewChild, args: ['wrapperContainer', { ...{ read: ViewContainerRef }, isSignal: true }] }], 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 }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }] } });
|
|
87
87
|
|
|
88
88
|
export { ContainerFieldComponent, ContainerFieldComponent as default };
|
|
89
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-container-field.component-
|
|
89
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-forge-dynamic-forms-container-field.component-
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs","mappings":";;;;;;AAoDc;AACK;;AAEA;AACE;AACF;AACA;AACA;;AAGA;AACA;;;;;AAIjB;;;;AAGS;;AACA;;;;AAGQ;;AAEE;AAGf;AACA;;;AAGA;AACE;;;AAKI;;AAIP;AAIc;AAIjB;;AAGE;;;AAGE;AACD;;;AAxDgB;;;;;;;;;AAZlB;;;;AAXS;;;;;;;;;;AAcR;AACA;AACA;AACA;AACA;AACA;;AAcgD","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms/src/lib/fields/container/container-field.component.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n EnvironmentInjector,\n inject,\n Injector,\n input,\n TemplateRef,\n viewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport { DfFieldOutlet } from '../../directives/df-field-outlet/df-field-outlet.directive';\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 { ContainerField } 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 { FieldDef } from '@ng-forge/dynamic-forms/internal';\nimport { DynamicFormLogger } from '@ng-forge/dynamic-forms/internal';\nimport { WRAPPER_AUTO_ASSOCIATIONS } from '@ng-forge/dynamic-forms/internal';\nimport { DEFAULT_WRAPPERS } from '@ng-forge/dynamic-forms/internal';\nimport { isSameWrapperChain, resolveWrappers } from '../../utils/resolve-wrappers/resolve-wrappers';\nimport { createWrapperChainController } from '../../utils/wrapper-chain/wrapper-chain-controller';\n\n/** Layout container that wraps child fields with UI chrome. */\n@Component({\n selector: 'div[container-field]',\n imports: [DfFieldOutlet],\n template: `\n <ng-template #childrenTpl>\n @for (field of resolvedFields(); track field.key) {\n @if (!field.hidden()) {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\n }\n }\n </ng-template>\n <ng-container #wrapperContainer></ng-container>\n `,\n styleUrl: './container-field.component.scss',\n host: {\n '[class]': 'hostClasses()',\n '[class.disabled]': 'disabled()',\n '[class.df-container-hidden]': 'hidden()',\n '[attr.aria-hidden]': 'hidden() || null',\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class ContainerFieldComponent {\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 wrapperAutoAssociations = inject(WRAPPER_AUTO_ASSOCIATIONS);\n private readonly defaultWrappersSignal = inject(DEFAULT_WRAPPERS, { optional: true });\n\n private readonly childrenTpl = viewChild.required('childrenTpl', { read: TemplateRef });\n private readonly wrapperContainer = viewChild.required('wrapperContainer', { read: ViewContainerRef });\n\n field = input.required<ContainerField>();\n key = input.required<string>();\n className = input<string>();\n hidden = input(false);\n\n readonly hostClasses = computed(() => computeContainerHostClasses('container', this.className()));\n readonly disabled = computed(() => this.field().disabled || false);\n\n private readonly rawFieldRegistry = computed(() => this.fieldRegistry.raw);\n private readonly fieldsSource = computed(() => (this.field().fields || []) as FieldDef<unknown>[]);\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\n const containerKey = this.field().key || '<no key>';\n this.logger.error(\n `Failed to load component for field type '${fieldDef.type}' (key: ${fieldKey}) ` +\n `within container '${containerKey}'. 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 private readonly wrappers = computed(() => resolveWrappers(this.field(), this.defaultWrappersSignal?.(), this.wrapperAutoAssociations), {\n equal: isSameWrapperChain,\n });\n\n constructor() {\n setupContainerInitEffect(this.resolvedFields, this.eventBus, 'container', () => this.field().key, this.injector);\n\n createWrapperChainController({\n vcr: this.wrapperContainer,\n wrappers: this.wrappers,\n renderInnermost: (slot) => slot.createEmbeddedView(this.childrenTpl()),\n });\n }\n}\n\nexport { ContainerFieldComponent };\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, DestroyRef, Injector, EnvironmentInjector, input, computed, linkedSignal, runInInjectionContext, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { i as injectFieldRegistry, C as CONTAINER_FIELD_PROCESSORS, d as createSchemaFromFields, c as createFieldResolutionPipe, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-
|
|
3
|
+
import { i as injectFieldRegistry, C as CONTAINER_FIELD_PROCESSORS, d as createSchemaFromFields, c as createFieldResolutionPipe, D as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-DSXZJHcu.mjs';
|
|
4
4
|
import { outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
6
6
|
import { injectFieldSignalContext, GROUP_CONTEXT, EventBus, DynamicFormLogger, isEqual, FIELD_SIGNAL_CONTEXT, derivedFromDeferred } from '@ng-forge/dynamic-forms/internal';
|
|
@@ -178,4 +178,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
|
|
|
178
178
|
}], 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 }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }], validityChange: [{ type: i0.Output, args: ["validityChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], submitted: [{ type: i0.Output, args: ["submitted"] }] } });
|
|
179
179
|
|
|
180
180
|
export { GroupFieldComponent, GroupFieldComponent as default };
|
|
181
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-group-field.component-
|
|
181
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-group-field.component-BNjYMTqT.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-forge-dynamic-forms-group-field.component-DyD00a1U.mjs","mappings":";;;;;;;;;AA0Dc;YAKK;;;;AAIA;AACE;AACF;AACA;YAMA;;;;;AAQjB;;;;YAOS;;;;AAIQ;AACf;AACA;AAEA;AACE;AACA;;AAEA;;AAGE;AACA;;;;;;;AAQF;AACA;AACA;AACA;;;;;;;AAOJ,IAKiB;;;AAIb;;AAEA;AACF;AAEE;AACA;AACD;AAGc;AACf;AACE;;AAGE;AACA;;AAGF;AACF;;;;;AAQO;;AACA;;AACA;;AACA;;AACA;;AACA;;AAEQ;AACf;;AAEA;;;;AAIA;;;AAGE;;AAEA;AACE;;;;AAKN,IAMiB;AACf;;;AAGE;AACF;;AAGe;;AAEf;;;AAGC;AACF;;;AAQQ;;;AAQU;AAGf;AACA;;;AAGA;AACE;;;;AAOH;YAQH;;;;;AAWE;;AAIM;;AAIJ;;;AA/Me;;;;;;AAhBlB;;;;AARS;;;;;;;AAWR;AACA;AACA;AACA;AACA;wEAIA;AACA","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms/src/lib/fields/group/group-field.component.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n EnvironmentInjector,\n inject,\n Injector,\n input,\n linkedSignal,\n runInInjectionContext,\n untracked,\n} from '@angular/core';\nimport { DfFieldOutlet } from '../../directives/df-field-outlet/df-field-outlet.directive';\nimport { outputFromObservable, toObservable } 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 { CONTAINER_FIELD_PROCESSORS } from '../../utils/container-utils/container-field-processors';\nimport { isEqual } from '@ng-forge/dynamic-forms/internal';\nimport { DynamicFormLogger } from '@ng-forge/dynamic-forms/internal';\nimport { GroupField } from '@ng-forge/dynamic-forms/internal';\nimport { injectFieldRegistry } from '../../utils/inject-field-registry/inject-field-registry';\nimport { FieldTree, form } from '@angular/forms/signals';\nimport { FieldDef } from '@ng-forge/dynamic-forms/internal';\nimport { FieldSignalContext, GroupContext } from '@ng-forge/dynamic-forms/internal';\nimport { FIELD_SIGNAL_CONTEXT, GROUP_CONTEXT, injectFieldSignalContext } from '@ng-forge/dynamic-forms/internal';\nimport { createSchemaFromFields } from '../../core/schema-builder';\nimport { EventBus } from '@ng-forge/dynamic-forms/internal';\nimport { FormSubmitEvent } from '../../events/constants/submit.event';\n\n/** Container component for rendering nested form groups. */\n@Component({\n selector: 'fieldset[group-field]',\n imports: [DfFieldOutlet],\n template: `\n @for (field of resolvedFields(); track field.key) {\n @if (!field.hidden()) {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\n }\n }\n `,\n styleUrl: './group-field.component.scss',\n host: {\n '[class]': 'hostClasses()',\n role: 'group',\n '[class.disabled]': 'disabled()',\n '[class.df-container-hidden]': 'hidden()',\n '[attr.aria-hidden]': 'hidden() || null',\n // The group element's own id is the plain `key()` — only its DESCENDANTS\n // compose scoped ids via GROUP_CONTEXT (e.g. children of an `address`\n // group render as `address_street`). The group selector is `#address`.\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class GroupFieldComponent<TModel extends Record<string, unknown> = Record<string, unknown>> {\n // ─────────────────────────────────────────────────────────────────────────────\n // Dependencies\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly fieldRegistry = injectFieldRegistry();\n private readonly parentFieldSignalContext = injectFieldSignalContext<TModel>();\n private readonly parentGroupContext = inject(GROUP_CONTEXT, { optional: true });\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\n // ─────────────────────────────────────────────────────────────────────────────\n // Memoized Functions\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldProcessors = inject(CONTAINER_FIELD_PROCESSORS);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Inputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n field = input.required<GroupField>();\n key = input.required<string>();\n className = input<string>();\n hidden = input(false);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Computed Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly hostClasses = computed(() => computeContainerHostClasses('group', this.className()));\n\n private readonly rawFieldRegistry = computed(() => this.fieldRegistry.raw);\n\n private readonly formSetup = computed(() => {\n const groupField = this.field();\n const registry = this.rawFieldRegistry();\n\n if (groupField.fields && groupField.fields.length > 0) {\n const flattenedFields = this.fieldProcessors.memoizedFlattenFields(groupField.fields, registry);\n const flattenedFieldsForRendering = this.fieldProcessors.memoizedFlattenFieldsForRendering(groupField.fields, registry);\n const fieldsById = this.fieldProcessors.memoizedKeyBy(flattenedFields);\n const defaultValues = this.fieldProcessors.memoizedDefaultValues(fieldsById, registry);\n\n return {\n fields: flattenedFieldsForRendering,\n schemaFields: flattenedFields,\n originalFields: groupField.fields,\n defaultValues,\n registry,\n };\n }\n\n return {\n fields: [],\n schemaFields: [],\n originalFields: [],\n defaultValues: {},\n registry,\n };\n });\n\n readonly defaultValues = linkedSignal(() => this.formSetup().defaultValues);\n\n /**\n * Entity computed from parent value, group key, and defaults.\n * Uses deep equality check to prevent unnecessary updates when\n * object spread creates new references with identical values.\n */\n private readonly entity = linkedSignal(\n () => {\n const parentValue = this.parentFieldSignalContext.value();\n const groupKey = this.field().key;\n const defaults = this.defaultValues();\n const groupValue = (parentValue as Record<string, unknown>)?.[groupKey] || {};\n return { ...defaults, ...groupValue };\n },\n {\n debugName: 'GroupFieldComponent.entity',\n equal: isEqual,\n },\n );\n\n private readonly form = computed(() => {\n return runInInjectionContext(this.injector, () => {\n const setup = this.formSetup();\n\n if (setup.schemaFields.length > 0) {\n const schema = createSchemaFromFields(setup.schemaFields, setup.registry);\n return untracked(() => form(this.entity, schema));\n }\n\n return untracked(() => form(this.entity));\n });\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Public State Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly formValue = computed(() => this.entity());\n readonly valid = computed(() => this.form()().valid());\n readonly invalid = computed(() => this.form()().invalid());\n readonly dirty = computed(() => this.form()().dirty());\n readonly touched = computed(() => this.form()().touched());\n readonly errors = computed(() => this.form()().errors());\n readonly disabled = computed(() => this.form()().disabled());\n\n private readonly nestedFieldTree = computed((): FieldTree<Record<string, unknown>> | undefined => {\n const parentForm = this.parentFieldSignalContext.form as Record<string, FieldTree<Record<string, unknown>>>;\n const groupKey = this.field().key;\n return parentForm[groupKey];\n });\n\n private readonly groupFieldSignalContext: FieldSignalContext<Record<string, unknown>> = (() => {\n const nestedFieldTree = this.nestedFieldTree;\n return {\n injector: this.injector,\n value: this.parentFieldSignalContext.value,\n defaultValues: this.defaultValues,\n get form() {\n return nestedFieldTree() ?? ({} as FieldTree<Record<string, unknown>>);\n },\n };\n })();\n\n /**\n * Group context propagated to descendants — carries the dot-separated path of\n * group ancestors so child fields can scope their DOM IDs (issue #401).\n * Reactive via `computed()`: a nested group composes its path from the parent\n * context signal + its own key, so the chain stays consistent if either changes.\n */\n private readonly groupContext: GroupContext = {\n groupPath: computed(() => {\n const ownKey = this.field().key;\n const parentPath = this.parentGroupContext?.groupPath();\n return parentPath ? `${parentPath}.${ownKey}` : ownKey;\n }),\n };\n\n private readonly groupInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: FIELD_SIGNAL_CONTEXT, useValue: this.groupFieldSignalContext },\n { provide: GROUP_CONTEXT, useValue: this.groupContext },\n ],\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Outputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly validityChange = outputFromObservable(toObservable(this.valid));\n readonly dirtyChange = outputFromObservable(toObservable(this.dirty));\n readonly submitted = outputFromObservable(this.eventBus.on<FormSubmitEvent>('submit'));\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Field Resolution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldsSource = computed(() => this.formSetup().fields);\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.groupInjector,\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 group '${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 // Private Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n private setupEffects(): void {\n setupContainerInitEffect(this.resolvedFields, this.eventBus, 'group', () => this.field().key, this.injector);\n\n explicitEffect(\n [this.nestedFieldTree, this.field],\n ([tree, field]) => {\n if (!tree) {\n this.logger.warn(\n `Group field \"${field.key}\" not found in parent form. ` + `Ensure the parent form schema includes this group field.`,\n );\n }\n },\n { defer: true },\n );\n }\n}\n\nexport { GroupFieldComponent };\n"]}
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-group-field.component-BNjYMTqT.mjs","mappings":";;;;;;;;;AA0Dc;YAKK;;;;AAIA;AACE;AACF;AACA;YAMA;;;;;AAQjB;;;;YAOS;;;;AAIQ;AACf;AACA;AAEA;AACE;AACA;;AAEA;;AAGE;AACA;;;;;;;AAQF;AACA;AACA;AACA;;;;;;;AAOJ,IAKiB;;;AAIb;;AAEA;AACF;AAEE;AACA;AACD;AAGc;AACf;AACE;;AAGE;AACA;;AAGF;AACF;;;;;AAQO;;AACA;;AACA;;AACA;;AACA;;AACA;;AAEQ;AACf;;AAEA;;;;AAIA;;;AAGE;;AAEA;AACE;;;;AAKN,IAMiB;AACf;;;AAGE;AACF;;AAGe;;AAEf;;;AAGC;AACF;;;AAQQ;;;AAQU;AAGf;AACA;;;AAGA;AACE;;;;AAOH;YAQH;;;;;AAWE;;AAIM;;AAIJ;;;AA/Me;;;;;;AAhBlB;;;;AARS;;;;;;;AAWR;AACA;AACA;AACA;AACA;wEAIA;AACA","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms/src/lib/fields/group/group-field.component.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n EnvironmentInjector,\n inject,\n Injector,\n input,\n linkedSignal,\n runInInjectionContext,\n untracked,\n} from '@angular/core';\nimport { DfFieldOutlet } from '../../directives/df-field-outlet/df-field-outlet.directive';\nimport { outputFromObservable, toObservable } 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 { CONTAINER_FIELD_PROCESSORS } from '../../utils/container-utils/container-field-processors';\nimport { isEqual } from '@ng-forge/dynamic-forms/internal';\nimport { DynamicFormLogger } from '@ng-forge/dynamic-forms/internal';\nimport { GroupField } from '@ng-forge/dynamic-forms/internal';\nimport { injectFieldRegistry } from '../../utils/inject-field-registry/inject-field-registry';\nimport { FieldTree, form } from '@angular/forms/signals';\nimport { FieldDef } from '@ng-forge/dynamic-forms/internal';\nimport { FieldSignalContext, GroupContext } from '@ng-forge/dynamic-forms/internal';\nimport { FIELD_SIGNAL_CONTEXT, GROUP_CONTEXT, injectFieldSignalContext } from '@ng-forge/dynamic-forms/internal';\nimport { createSchemaFromFields } from '../../core/schema-builder';\nimport { EventBus } from '@ng-forge/dynamic-forms/internal';\nimport { FormSubmitEvent } from '../../events/constants/submit.event';\n\n/** Container component for rendering nested form groups. */\n@Component({\n selector: 'fieldset[group-field]',\n imports: [DfFieldOutlet],\n template: `\n @for (field of resolvedFields(); track field.key) {\n @if (!field.hidden()) {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\n }\n }\n `,\n styleUrl: './group-field.component.scss',\n host: {\n '[class]': 'hostClasses()',\n role: 'group',\n '[class.disabled]': 'disabled()',\n '[class.df-container-hidden]': 'hidden()',\n '[attr.aria-hidden]': 'hidden() || null',\n // The group element's own id is the plain `key()` — only its DESCENDANTS\n // compose scoped ids via GROUP_CONTEXT (e.g. children of an `address`\n // group render as `address_street`). The group selector is `#address`.\n '[id]': '`${key()}`',\n '[attr.data-testid]': 'key()',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class GroupFieldComponent<TModel extends Record<string, unknown> = Record<string, unknown>> {\n // ─────────────────────────────────────────────────────────────────────────────\n // Dependencies\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly fieldRegistry = injectFieldRegistry();\n private readonly parentFieldSignalContext = injectFieldSignalContext<TModel>();\n private readonly parentGroupContext = inject(GROUP_CONTEXT, { optional: true });\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\n // ─────────────────────────────────────────────────────────────────────────────\n // Memoized Functions\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldProcessors = inject(CONTAINER_FIELD_PROCESSORS);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Inputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n field = input.required<GroupField>();\n key = input.required<string>();\n className = input<string>();\n hidden = input(false);\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Computed Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly hostClasses = computed(() => computeContainerHostClasses('group', this.className()));\n\n private readonly rawFieldRegistry = computed(() => this.fieldRegistry.raw);\n\n private readonly formSetup = computed(() => {\n const groupField = this.field();\n const registry = this.rawFieldRegistry();\n\n if (groupField.fields && groupField.fields.length > 0) {\n const flattenedFields = this.fieldProcessors.memoizedFlattenFields(groupField.fields, registry);\n const flattenedFieldsForRendering = this.fieldProcessors.memoizedFlattenFieldsForRendering(groupField.fields, registry);\n const fieldsById = this.fieldProcessors.memoizedKeyBy(flattenedFields);\n const defaultValues = this.fieldProcessors.memoizedDefaultValues(fieldsById, registry);\n\n return {\n fields: flattenedFieldsForRendering,\n schemaFields: flattenedFields,\n originalFields: groupField.fields,\n defaultValues,\n registry,\n };\n }\n\n return {\n fields: [],\n schemaFields: [],\n originalFields: [],\n defaultValues: {},\n registry,\n };\n });\n\n readonly defaultValues = linkedSignal(() => this.formSetup().defaultValues);\n\n /**\n * Entity computed from parent value, group key, and defaults.\n * Uses deep equality check to prevent unnecessary updates when\n * object spread creates new references with identical values.\n */\n private readonly entity = linkedSignal(\n () => {\n const parentValue = this.parentFieldSignalContext.value();\n const groupKey = this.field().key;\n const defaults = this.defaultValues();\n const groupValue = (parentValue as Record<string, unknown>)?.[groupKey] || {};\n return { ...defaults, ...groupValue };\n },\n {\n debugName: 'GroupFieldComponent.entity',\n equal: isEqual,\n },\n );\n\n private readonly form = computed(() => {\n return runInInjectionContext(this.injector, () => {\n const setup = this.formSetup();\n\n if (setup.schemaFields.length > 0) {\n const schema = createSchemaFromFields(setup.schemaFields, setup.registry);\n return untracked(() => form(this.entity, schema));\n }\n\n return untracked(() => form(this.entity));\n });\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Public State Signals\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly formValue = computed(() => this.entity());\n readonly valid = computed(() => this.form()().valid());\n readonly invalid = computed(() => this.form()().invalid());\n readonly dirty = computed(() => this.form()().dirty());\n readonly touched = computed(() => this.form()().touched());\n readonly errors = computed(() => this.form()().errors());\n readonly disabled = computed(() => this.form()().disabled());\n\n private readonly nestedFieldTree = computed((): FieldTree<Record<string, unknown>> | undefined => {\n const parentForm = this.parentFieldSignalContext.form as Record<string, FieldTree<Record<string, unknown>>>;\n const groupKey = this.field().key;\n return parentForm[groupKey];\n });\n\n private readonly groupFieldSignalContext: FieldSignalContext<Record<string, unknown>> = (() => {\n const nestedFieldTree = this.nestedFieldTree;\n return {\n injector: this.injector,\n value: this.parentFieldSignalContext.value,\n defaultValues: this.defaultValues,\n get form() {\n return nestedFieldTree() ?? ({} as FieldTree<Record<string, unknown>>);\n },\n };\n })();\n\n /**\n * Group context propagated to descendants — carries the dot-separated path of\n * group ancestors so child fields can scope their DOM IDs (issue #401).\n * Reactive via `computed()`: a nested group composes its path from the parent\n * context signal + its own key, so the chain stays consistent if either changes.\n */\n private readonly groupContext: GroupContext = {\n groupPath: computed(() => {\n const ownKey = this.field().key;\n const parentPath = this.parentGroupContext?.groupPath();\n return parentPath ? `${parentPath}.${ownKey}` : ownKey;\n }),\n };\n\n private readonly groupInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: FIELD_SIGNAL_CONTEXT, useValue: this.groupFieldSignalContext },\n { provide: GROUP_CONTEXT, useValue: this.groupContext },\n ],\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Outputs\n // ─────────────────────────────────────────────────────────────────────────────\n\n readonly validityChange = outputFromObservable(toObservable(this.valid));\n readonly dirtyChange = outputFromObservable(toObservable(this.dirty));\n readonly submitted = outputFromObservable(this.eventBus.on<FormSubmitEvent>('submit'));\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Field Resolution\n // ─────────────────────────────────────────────────────────────────────────────\n\n private readonly fieldsSource = computed(() => this.formSetup().fields);\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.groupInjector,\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 group '${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 // Private Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n private setupEffects(): void {\n setupContainerInitEffect(this.resolvedFields, this.eventBus, 'group', () => this.field().key, this.injector);\n\n explicitEffect(\n [this.nestedFieldTree, this.field],\n ([tree, field]) => {\n if (!tree) {\n this.logger.warn(\n `Group field \"${field.key}\" not found in parent form. ` + `Ensure the parent form schema includes this group field.`,\n );\n }\n },\n { defer: true },\n );\n }\n}\n\nexport { GroupFieldComponent };\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { reflectComponentType, Injector, inject, EnvironmentInjector, DestroyRef, computed, signal, input, ViewContainerRef, Directive, InjectionToken, linkedSignal, ChangeDetectionStrategy, Component, Injectable, isSignal, runInInjectionContext, afterNextRender,
|
|
2
|
+
import { reflectComponentType, Injector, inject, EnvironmentInjector, DestroyRef, computed, signal, input, ViewContainerRef, Directive, InjectionToken, linkedSignal, untracked, ChangeDetectionStrategy, Component, Injectable, isSignal, runInInjectionContext, afterNextRender, PendingTasks, ElementRef, PLATFORM_ID, isDevMode, TemplateRef, model, contentChildren, makeEnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
4
4
|
import { DynamicFormLogger, WRAPPER_COMPONENT_CACHE, WRAPPER_REGISTRY, toReadonlyFieldTreeCached, writeToFieldValue, WRAPPER_AUTO_ASSOCIATIONS, DEFAULT_WRAPPERS, READONLY_FIELD_TREE_CACHE, getGridClassString, EventBus, FieldContextRegistryService, FunctionRegistryService, FORM_OPTIONS, evaluateCondition, FIELD_SIGNAL_CONTEXT, isRowField, isGenericContainerField, isContainerField, isArrayField, hasChildFields, isSimplifiedArrayField, DynamicFormError, isStateLogicConfig, isDerivationLogicConfig, isFormStateCondition, createFormStateLogicFunction, createDebouncedLogicFunction, createLogicFunction, ExpressionParser, applyValidator, isPageField, isGroupField, getFieldValueHandling, normalizeFieldsArray, keyBy, mapValues, isEqual, hasTargetProperty, ARRAY_CONTEXT, GROUP_CONTEXT, FORM_ID_PREFIX, baseFieldMapper, detectFormMode, validatePageNesting, FIELD_REGISTRY, assertNever, ADDON_TYPE_REGISTRY, deepMergeDefaults, derivedFromDeferred, createWarningTracker, RootFormRegistryService, DEFAULT_PROPS, DEFAULT_VALIDATION_MESSAGES, EXTERNAL_DATA, DEPRECATION_WARNING_TRACKER, createAddonActionRegistry, ADDON_ACTION_REGISTRY, HttpConditionCache, HTTP_CONDITION_CACHE, HttpConditionFunctionCacheService, AsyncConditionFunctionCacheService, DynamicValueFunctionCacheService, LogicFunctionCacheService, setupInitializationTracking, ComponentInitializedEvent, DF_FIELD_TEMPLATES, rowFieldMapper, groupFieldMapper, arrayFieldMapper, pageFieldMapper, textFieldMapper, containerFieldMapper, isWrapperTypeDefinition, ADDON_TYPE_COMPONENT_CACHE, ADDON_TYPE_DEFINITIONS, createDefaultDerivationLogConfig, NoopLogger, EMIT_FORM_VALUE_ON_EVENTS, DynamicTextPipe, ADDON_ACTION_HANDLERS } from '@ng-forge/dynamic-forms/internal';
|
|
5
5
|
import { takeUntilDestroyed, toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
@@ -500,9 +500,33 @@ class PageOrchestratorComponent {
|
|
|
500
500
|
const totalPages = this.pageFields().length;
|
|
501
501
|
if (totalPages === 0)
|
|
502
502
|
return 0;
|
|
503
|
-
return
|
|
503
|
+
return untracked(() => this.resolveInitialLanding());
|
|
504
504
|
}, /* @ts-ignore */
|
|
505
505
|
...(ngDevMode ? [{ debugName: "currentPageIndex" }] : /* istanbul ignore next */ []));
|
|
506
|
+
resolveInitialLanding() {
|
|
507
|
+
const { index, validate } = this.initialPage();
|
|
508
|
+
const visible = this.visiblePageIndices();
|
|
509
|
+
if (index === 0 || visible.length === 0)
|
|
510
|
+
return 0;
|
|
511
|
+
const target = visible.includes(index) ? index : this.findNearestVisiblePage(index, visible);
|
|
512
|
+
if (target <= 0)
|
|
513
|
+
return Math.max(target, 0);
|
|
514
|
+
if (!validate)
|
|
515
|
+
return target;
|
|
516
|
+
const firstInvalid = visible.filter((i) => i < target).find((i) => !this.isPageValid(i));
|
|
517
|
+
return firstInvalid ?? target;
|
|
518
|
+
}
|
|
519
|
+
initialPage = computed(() => {
|
|
520
|
+
const raw = this.formOptions?.()?.initialPage;
|
|
521
|
+
const totalPages = this.pageFields().length;
|
|
522
|
+
const requested = typeof raw === 'number' ? raw : raw?.index;
|
|
523
|
+
const validate = typeof raw === 'number' ? false : (raw?.validate ?? false);
|
|
524
|
+
if (typeof requested !== 'number' || !Number.isFinite(requested) || requested < 0 || totalPages === 0) {
|
|
525
|
+
return { index: 0, validate: false };
|
|
526
|
+
}
|
|
527
|
+
return { index: Math.min(Math.trunc(requested), totalPages - 1), validate };
|
|
528
|
+
}, /* @ts-ignore */
|
|
529
|
+
...(ngDevMode ? [{ debugName: "initialPage" }] : /* istanbul ignore next */ []));
|
|
506
530
|
state = computed(() => {
|
|
507
531
|
const currentIndex = this.currentPageIndex();
|
|
508
532
|
const totalPages = this.pageFields().length;
|
|
@@ -553,7 +577,7 @@ class PageOrchestratorComponent {
|
|
|
553
577
|
}
|
|
554
578
|
constructor() {
|
|
555
579
|
this.setupEventListeners();
|
|
556
|
-
|
|
580
|
+
explicitEffect([this.state, this.visiblePageIndices], ([state, visibleIndices]) => {
|
|
557
581
|
const currentVisiblePosition = visibleIndices.indexOf(state.currentPageIndex);
|
|
558
582
|
if (currentVisiblePosition === -1 && visibleIndices.length > 0) {
|
|
559
583
|
const nearest = this.findNearestVisiblePage(state.currentPageIndex, visibleIndices);
|
|
@@ -613,11 +637,14 @@ class PageOrchestratorComponent {
|
|
|
613
637
|
const prevVisiblePageIndex = visibleIndices[currentVisiblePosition - 1];
|
|
614
638
|
return this.executePageChange(prevVisiblePageIndex);
|
|
615
639
|
}
|
|
616
|
-
navigateToPage(pageIndex) {
|
|
640
|
+
navigateToPage(pageIndex, options) {
|
|
617
641
|
const currentIndex = this.state().currentPageIndex;
|
|
618
642
|
const visibleIndices = this.visiblePageIndices();
|
|
619
643
|
if (pageIndex <= currentIndex || !visibleIndices.includes(pageIndex)) {
|
|
620
644
|
return this.executePageChange(pageIndex);
|
|
645
|
+
}
|
|
646
|
+
if (options?.validate === false) {
|
|
647
|
+
return this.executePageChange(pageIndex);
|
|
621
648
|
}
|
|
622
649
|
const disableWhenPageInvalid = this.formOptions?.()?.nextButton?.disableWhenPageInvalid ?? true;
|
|
623
650
|
if (!disableWhenPageInvalid) {
|
|
@@ -696,7 +723,7 @@ class PageOrchestratorComponent {
|
|
|
696
723
|
.on('go-to-page')
|
|
697
724
|
.pipe(takeUntilDestroyed())
|
|
698
725
|
.subscribe((event) => {
|
|
699
|
-
this.navigateToPage(event.pageIndex);
|
|
726
|
+
this.navigateToPage(event.pageIndex, event.options);
|
|
700
727
|
});
|
|
701
728
|
explicitEffect([this.state], ([state]) => this.eventBus.dispatch(PagerStateEvent, state));
|
|
702
729
|
}
|
|
@@ -774,10 +801,10 @@ class PageOrchestratorComponent {
|
|
|
774
801
|
}
|
|
775
802
|
}
|
|
776
803
|
`, isInline: true, styles: [":host{display:block;position:relative;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
|
|
777
|
-
import('./ng-forge-dynamic-forms-page-field.component-
|
|
804
|
+
import('./ng-forge-dynamic-forms-page-field.component-B92kLZkH.mjs').then(m => m.default)]] });
|
|
778
805
|
}
|
|
779
806
|
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.0.1", ngImport: i0, type: PageOrchestratorComponent, resolveDeferredDeps: () => [/* @ts-ignore */
|
|
780
|
-
import('./ng-forge-dynamic-forms-page-field.component-
|
|
807
|
+
import('./ng-forge-dynamic-forms-page-field.component-B92kLZkH.mjs').then(m => m.default)], resolveMetadata: PageFieldComponent => ({ decorators: [{
|
|
781
808
|
type: Component,
|
|
782
809
|
args: [{ selector: 'div[page-orchestrator]', imports: [PageFieldComponent], template: `
|
|
783
810
|
@for (pageField of pageFields(); track pageField.key; let i = $index) {
|
|
@@ -3791,7 +3818,7 @@ function createDerivationRenderGate() {
|
|
|
3791
3818
|
if (!has || engine() !== 'idle')
|
|
3792
3819
|
return;
|
|
3793
3820
|
engine.set('loading');
|
|
3794
|
-
pendingTasks.run(() => import('./ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-
|
|
3821
|
+
pendingTasks.run(() => import('./ng-forge-dynamic-forms-bootstrap-derivation-orchestrator-OBDy6qd9.mjs')
|
|
3795
3822
|
.then(({ bootstrapDerivationOrchestrator }) => {
|
|
3796
3823
|
runInInjectionContext(injector, () => bootstrapDerivationOrchestrator());
|
|
3797
3824
|
engine.set('wired');
|
|
@@ -4346,28 +4373,28 @@ const DISPLAY_FIELD_TYPES_BASE = {
|
|
|
4346
4373
|
const BUILT_IN_FIELDS = [
|
|
4347
4374
|
{
|
|
4348
4375
|
name: 'row',
|
|
4349
|
-
loadComponent: () => import('./ng-forge-dynamic-forms-container-field.component-
|
|
4376
|
+
loadComponent: () => import('./ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs'),
|
|
4350
4377
|
mapper: rowFieldMapper,
|
|
4351
4378
|
valueHandling: 'flatten',
|
|
4352
4379
|
...CONTAINER_FIELD_TYPES_BASE,
|
|
4353
4380
|
},
|
|
4354
4381
|
{
|
|
4355
4382
|
name: 'group',
|
|
4356
|
-
loadComponent: () => import('./ng-forge-dynamic-forms-group-field.component-
|
|
4383
|
+
loadComponent: () => import('./ng-forge-dynamic-forms-group-field.component-BNjYMTqT.mjs'),
|
|
4357
4384
|
mapper: groupFieldMapper,
|
|
4358
4385
|
valueHandling: 'include',
|
|
4359
4386
|
...CONTAINER_FIELD_TYPES_BASE,
|
|
4360
4387
|
},
|
|
4361
4388
|
{
|
|
4362
4389
|
name: 'array',
|
|
4363
|
-
loadComponent: () => import('./ng-forge-dynamic-forms-array-field.component-
|
|
4390
|
+
loadComponent: () => import('./ng-forge-dynamic-forms-array-field.component-D-VWBM-t.mjs'),
|
|
4364
4391
|
mapper: arrayFieldMapper,
|
|
4365
4392
|
valueHandling: 'include',
|
|
4366
4393
|
...CONTAINER_FIELD_TYPES_BASE,
|
|
4367
4394
|
},
|
|
4368
4395
|
{
|
|
4369
4396
|
name: 'page',
|
|
4370
|
-
loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-
|
|
4397
|
+
loadComponent: () => import('./ng-forge-dynamic-forms-page-field.component-B92kLZkH.mjs'),
|
|
4371
4398
|
mapper: pageFieldMapper,
|
|
4372
4399
|
valueHandling: 'flatten',
|
|
4373
4400
|
...CONTAINER_FIELD_TYPES_BASE,
|
|
@@ -4385,7 +4412,7 @@ const BUILT_IN_FIELDS = [
|
|
|
4385
4412
|
},
|
|
4386
4413
|
{
|
|
4387
4414
|
name: 'container',
|
|
4388
|
-
loadComponent: () => import('./ng-forge-dynamic-forms-container-field.component-
|
|
4415
|
+
loadComponent: () => import('./ng-forge-dynamic-forms-container-field.component-BpeFyhAt.mjs'),
|
|
4389
4416
|
mapper: containerFieldMapper,
|
|
4390
4417
|
valueHandling: 'flatten',
|
|
4391
4418
|
...CONTAINER_FIELD_TYPES_BASE,
|
|
@@ -4789,10 +4816,13 @@ function sanitizeFormConfigPure(config, fieldRegistry, typeRegistry, options = {
|
|
|
4789
4816
|
|
|
4790
4817
|
class GoToPageEvent {
|
|
4791
4818
|
pageIndex;
|
|
4819
|
+
options;
|
|
4792
4820
|
type = 'go-to-page';
|
|
4793
4821
|
constructor(
|
|
4794
|
-
pageIndex
|
|
4822
|
+
pageIndex,
|
|
4823
|
+
options) {
|
|
4795
4824
|
this.pageIndex = pageIndex;
|
|
4825
|
+
this.options = options;
|
|
4796
4826
|
}
|
|
4797
4827
|
}
|
|
4798
4828
|
|
|
@@ -4912,4 +4942,4 @@ function arrayEvent(arrayKey) {
|
|
|
4912
4942
|
|
|
4913
4943
|
|
|
4914
4944
|
export { withEventFormValue as $, ArrayItemRegistryService as A, BUILT_IN_FIELDS as B, CONTAINER_FIELD_PROCESSORS as C, DfFieldOutlet as D, EventDispatcher as E, FIELD_WINDOWING as F, GoToPageEvent as G, PageChangeEvent as H, InsertArrayItemEvent as I, PagerStateEvent as J, PopArrayItemEvent as K, PrependArrayItemEvent as L, MoveArrayItemEvent as M, NextPageEvent as N, PreviousPageEvent as O, PROPERTY_OVERRIDE_STORE as P, TextAddonComponent as Q, RemoveAtIndexEvent as R, ShiftArrayItemEvent as S, TemplateAddonComponent as T, arrayEvent as U, createWrappers as V, isWrappersBundle as W, provideDynamicForm as X, sanitizeFormConfig as Y, withAddonActions as Z, withCustomAddon as _, isSameWrapperChain as a, withFieldWindowing as a0, withLegacyStatusClasses as a1, withLoggerConfig as a2, withPagePreload as a3, withValidationExecutionDefaults as a4, withValueExclusionDefaults as a5, wrapperProps as a6, createWrapperChainController as b, createFieldResolutionPipe as c, createSchemaFromFields as d, createHiddenSignal as e, createRenderReadySignal as f, getNormalizedArrayMetadata as g, getFieldDefaultValue as h, injectFieldRegistry as i, resolveFieldWindowing as j, DEV_MODE as k, DEFAULT_DEBOUNCE_MS as l, mapFieldToInputs as m, DERIVATION_WARNING_TRACKER as n, FormStateManager as o, DERIVATION_LOG_CONFIG as p, AppendArrayItemEvent as q, resolveWrappers as r, ComponentAddonComponent as s, traverseFieldsWithContext as t, ConsoleLogger as u, DfTemplate as v, DynamicForm as w, FormClearEvent as x, FormResetEvent as y, FormSubmitEvent as z };
|
|
4915
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-
|
|
4945
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-ng-forge-dynamic-forms-DSXZJHcu.mjs.map
|