@ng-forge/dynamic-forms 0.8.0 → 0.9.0-next.10
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-CWxCWVdz.mjs → ng-forge-dynamic-forms-array-field.component-DbWes42V.mjs} +3 -3
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-CWxCWVdz.mjs.map → ng-forge-dynamic-forms-array-field.component-DbWes42V.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-PozYj2JC.mjs → ng-forge-dynamic-forms-container-field.component-CMhqFGJZ.mjs} +3 -3
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-PozYj2JC.mjs.map → ng-forge-dynamic-forms-container-field.component-CMhqFGJZ.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-container-utils-DW_P7w-b.mjs → ng-forge-dynamic-forms-container-utils-D_nNzKo1.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-container-utils-DW_P7w-b.mjs.map → ng-forge-dynamic-forms-container-utils-D_nNzKo1.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-css-wrapper.component-DrtHSaVV.mjs → ng-forge-dynamic-forms-css-wrapper.component-htvP_o95.mjs} +2 -2
- package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-htvP_o95.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-CSx0gwFc.mjs → ng-forge-dynamic-forms-emit-initialization-DtkxP7pE.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-CSx0gwFc.mjs.map → ng-forge-dynamic-forms-emit-initialization-DtkxP7pE.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-2yRmHAUp.mjs → ng-forge-dynamic-forms-group-field.component-BhYFIDA1.mjs} +3 -3
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-2yRmHAUp.mjs.map → ng-forge-dynamic-forms-group-field.component-BhYFIDA1.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +629 -54
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-Ll4W2Z_n.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-DWPPLOrV.mjs} +662 -110
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-DWPPLOrV.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-B_CxX0T-.mjs → ng-forge-dynamic-forms-page-field.component-B9v_1shD.mjs} +3 -3
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-B_CxX0T-.mjs.map → ng-forge-dynamic-forms-page-field.component-B9v_1shD.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-rJMtKX2X.mjs → ng-forge-dynamic-forms-text-field.component-B4LnTnIA.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-rJMtKX2X.mjs.map → ng-forge-dynamic-forms-text-field.component-B4LnTnIA.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +2 -2
- package/types/ng-forge-dynamic-forms-integration.d.ts +380 -8
- package/types/ng-forge-dynamic-forms.d.ts +106 -8
- package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-DrtHSaVV.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-Ll4W2Z_n.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, E as EventBus, D as DynamicFormLogger, v as validatePageNesting, d as derivedFromDeferred, c as createFieldResolutionPipe, f as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-
|
|
3
|
+
import { i as injectFieldRegistry, E as EventBus, D as DynamicFormLogger, v as validatePageNesting, d as derivedFromDeferred, c as createFieldResolutionPipe, f as DfFieldOutlet } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-DWPPLOrV.mjs';
|
|
4
4
|
import { outputFromObservable } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { explicitEffect } from 'ngxtension/explicit-effect';
|
|
6
|
-
import { c as computeContainerHostClasses, s as setupContainerInitEffect } from './ng-forge-dynamic-forms-container-utils-
|
|
6
|
+
import { c as computeContainerHostClasses, s as setupContainerInitEffect } from './ng-forge-dynamic-forms-container-utils-D_nNzKo1.mjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Renders a single page in multi-page (wizard) forms.
|
|
@@ -107,4 +107,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
107
107
|
}], 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"] }] } });
|
|
108
108
|
|
|
109
109
|
export { PageFieldComponent as default };
|
|
110
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-page-field.component-
|
|
110
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-page-field.component-B9v_1shD.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-forge-dynamic-forms-page-field.component-B_CxX0T-.mjs","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.directive';\nimport { outputFromObservable } from '@angular/core/rxjs-interop';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { derivedFromDeferred } from '../../utils/derived-from-deferred/derived-from-deferred';\nimport { createFieldResolutionPipe, ResolvedField } from '../../utils/resolve-field/resolve-field';\nimport { computeContainerHostClasses, setupContainerInitEffect } from '../../utils/container-utils/container-utils';\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';\nimport { DynamicFormLogger } from '../../providers/features/logger/logger.token';\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: [DfFieldOutlet],\n template: `\n @for (field of resolvedFields(); track field.key) {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\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\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 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 // 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"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-page-field.component-B9v_1shD.mjs","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.directive';\nimport { outputFromObservable } from '@angular/core/rxjs-interop';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { derivedFromDeferred } from '../../utils/derived-from-deferred/derived-from-deferred';\nimport { createFieldResolutionPipe, ResolvedField } from '../../utils/resolve-field/resolve-field';\nimport { computeContainerHostClasses, setupContainerInitEffect } from '../../utils/container-utils/container-utils';\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';\nimport { DynamicFormLogger } from '../../providers/features/logger/logger.token';\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: [DfFieldOutlet],\n template: `\n @for (field of resolvedFields(); track field.key) {\n <ng-container *dfFieldOutlet=\"field; environmentInjector: environmentInjector\" />\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\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 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 // 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"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs","sources":["../../../../packages/dynamic-forms/src/lib/wrappers/row/row-wrapper.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, ViewContainerRef, viewChild } from '@angular/core';\nimport {
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs","sources":["../../../../packages/dynamic-forms/src/lib/wrappers/row/row-wrapper.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, ViewContainerRef, viewChild } from '@angular/core';\nimport { FieldWrapper } from '../../models/wrapper-type';\nimport { WrapperFieldInputs } from '../wrapper-field-inputs';\n\n/**\n * Built-in row wrapper component.\n *\n * Applies the grid/flex layout that `{ type: 'row' }` fields historically rendered.\n * The `rowFieldMapper` synthesizes a `{ type: 'row' }` wrapper into the container\n * field so the user-facing config stays `{ type: 'row', fields: [...] }` while the\n * runtime uses the container + wrapper pipeline.\n *\n * Children use the shared `df-col-1`..`df-col-12` utilities on their own `col`\n * property to size within the flex row.\n */\n@Component({\n selector: 'df-row-wrapper',\n template: `<ng-container #fieldComponent></ng-container>`,\n styleUrl: './row-wrapper.component.scss',\n host: {\n class: 'df-field df-row',\n },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class RowWrapperComponent implements FieldWrapper {\n readonly fieldComponent = viewChild.required('fieldComponent', { read: ViewContainerRef });\n\n /**\n * Mapper outputs for the wrapped field.\n * The row wrapper itself does not consume these — the input is accepted\n * for contract consistency so the outlet can set it on any wrapper.\n */\n readonly fieldInputs = input<WrapperFieldInputs>();\n}\n\nexport { RowWrapperComponent };\n"],"names":[],"mappings":";;;AAIA;;;;;;;;;;AAUG;AAUW,MAAO,mBAAmB,CAAA;AAC7B,IAAA,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;AAE1F;;;;AAIG;IACM,WAAW,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAsB;uGAR/B,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAA,EACiC,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAR7E,CAAA,6CAAA,CAA+C,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,2iPAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAOtC,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBATvC,SAAS;+BACE,gBAAgB,EAAA,QAAA,EAChB,+CAA+C,EAAA,IAAA,EAEnD;AACJ,wBAAA,KAAK,EAAE,iBAAiB;qBACzB,EAAA,eAAA,EACgB,uBAAuB,CAAC,MAAM,EAAA,MAAA,EAAA,CAAA,2iPAAA,CAAA,EAAA;AAGF,SAAA,CAAA,EAAA,cAAA,EAAA,EAAA,cAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,IAAA,EAAA,CAAA,gBAAgB,EAAA,EAAA,GAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { AsyncPipe } from '@angular/common';
|
|
4
|
-
import { u as DynamicTextPipe } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-
|
|
4
|
+
import { u as DynamicTextPipe } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-DWPPLOrV.mjs';
|
|
5
5
|
|
|
6
6
|
class TextFieldComponent {
|
|
7
7
|
key = input.required(...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
|
|
@@ -116,4 +116,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
116
116
|
}], 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 }] }] } });
|
|
117
117
|
|
|
118
118
|
export { TextFieldComponent as default };
|
|
119
|
-
//# sourceMappingURL=ng-forge-dynamic-forms-text-field.component-
|
|
119
|
+
//# sourceMappingURL=ng-forge-dynamic-forms-text-field.component-B4LnTnIA.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-forge-dynamic-forms-text-field.component-
|
|
1
|
+
{"version":3,"file":"ng-forge-dynamic-forms-text-field.component-B4LnTnIA.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 @default {\n never;\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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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { A as ARRAY_CONTEXT, x as AppendArrayItemEvent, B as BUILT_IN_FIELDS, y as ConsoleLogger, z as DEFAULT_PROPS, G as DEFAULT_VALIDATION_MESSAGES, a as DEFAULT_WRAPPERS, H as DynamicForm, I as DynamicFormError, D as DynamicFormLogger, u as DynamicTextPipe, E as EventBus, J as EventDispatcher, K as FIELD_REGISTRY, F as FIELD_SIGNAL_CONTEXT, L as FORM_OPTIONS, M as FormClearEvent, N as FormResetEvent, O as INITIALIZATION_TIMEOUT_MS, P as InsertArrayItemEvent, Q as MoveArrayItemEvent, S as NextPageEvent, T as NoopLogger, U as PageChangeEvent, V as PopArrayItemEvent, X as PrependArrayItemEvent, Y as PreviousPageEvent, Z as RemoveAtIndexEvent, R as RootFormRegistryService, _ as ShiftArrayItemEvent, $ as SubmitEvent, a0 as WRAPPER_REGISTRY, a1 as applyMetaToElement, a2 as applyValidator, a3 as applyValidators, a4 as arrayEvent, a5 as arrayFieldMapper, a6 as baseFieldMapper, a7 as buildBaseInputs, a8 as containerFieldMapper, a9 as createField, aa as createWrappers, w as dynamicTextToObservable, ab as evaluateNonFieldDisabled, ac as evaluateNonFieldHidden, ad as field, ae as formConfig, af as getArrayLength, ag as groupFieldMapper, ah as hasFormValue, ai as interpolateParams, aj as isArrayField, ak as isCheckedField, al as isContainerField, am as isContainerTypedField, an as isDisplayOnlyField, g as isEqual, ao as isFormStateCondition, q as isGroupField, ap as isLeafField, aq as isPageField, ar as isRowField, as as isSimplifiedArrayField, at as isValueBearingField, au as isValueField, av as isWrapperTypeDefinition, aw as isWrappersBundle, ax as omit, ay as pageFieldMapper, az as provideDynamicForm, aA as resolveNextButtonDisabled, aB as resolveNonFieldDisabled, aC as resolveNonFieldHidden, aD as resolveSubmitButtonDisabled, aE as resolveTokens, aF as rowFieldMapper, aG as textFieldMapper, aH as toReadonlyFieldTree, aI as withEventFormValue, aJ as withLoggerConfig, aK as withPreviousValue, aL as
|
|
1
|
+
export { A as ARRAY_CONTEXT, x as AppendArrayItemEvent, B as BUILT_IN_FIELDS, y as ConsoleLogger, z as DEFAULT_PROPS, G as DEFAULT_VALIDATION_MESSAGES, a as DEFAULT_WRAPPERS, H as DynamicForm, I as DynamicFormError, D as DynamicFormLogger, u as DynamicTextPipe, E as EventBus, J as EventDispatcher, K as FIELD_REGISTRY, F as FIELD_SIGNAL_CONTEXT, L as FORM_OPTIONS, M as FormClearEvent, N as FormResetEvent, O as INITIALIZATION_TIMEOUT_MS, P as InsertArrayItemEvent, Q as MoveArrayItemEvent, S as NextPageEvent, T as NoopLogger, U as PageChangeEvent, V as PopArrayItemEvent, X as PrependArrayItemEvent, Y as PreviousPageEvent, Z as RemoveAtIndexEvent, R as RootFormRegistryService, _ as ShiftArrayItemEvent, $ as SubmitEvent, a0 as WRAPPER_REGISTRY, a1 as applyMetaToElement, a2 as applyValidator, a3 as applyValidators, a4 as arrayEvent, a5 as arrayFieldMapper, a6 as baseFieldMapper, a7 as buildBaseInputs, a8 as containerFieldMapper, a9 as createField, aa as createWrappers, w as dynamicTextToObservable, ab as evaluateNonFieldDisabled, ac as evaluateNonFieldHidden, ad as field, ae as formConfig, af as getArrayLength, ag as groupFieldMapper, ah as hasFormValue, ai as interpolateParams, aj as isArrayField, ak as isCheckedField, al as isContainerField, am as isContainerTypedField, an as isDisplayOnlyField, g as isEqual, ao as isFormStateCondition, q as isGroupField, ap as isLeafField, aq as isPageField, ar as isRowField, as as isSimplifiedArrayField, at as isValueBearingField, au as isValueField, av as isWrapperTypeDefinition, aw as isWrappersBundle, ax as omit, ay as pageFieldMapper, az as provideDynamicForm, aA as resolveNextButtonDisabled, aB as resolveNonFieldDisabled, aC as resolveNonFieldHidden, aD as resolveSubmitButtonDisabled, aE as resolveTokens, aF as rowFieldMapper, aG as textFieldMapper, aH as toReadonlyFieldTree, aI as withEventFormValue, aJ as withLoggerConfig, aK as withPreviousValue, aL as withValidationExecutionDefaults, aM as withValueExclusionDefaults, aN as wrapperProps } from './ng-forge-dynamic-forms-ng-forge-dynamic-forms-DWPPLOrV.mjs';
|
|
2
2
|
//# 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": "0.
|
|
3
|
+
"version": "0.9.0-next.10",
|
|
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",
|
|
@@ -63,4 +63,4 @@
|
|
|
63
63
|
"default": "./fesm2022/ng-forge-dynamic-forms-schema.mjs"
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
}
|
|
66
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { FormEvent, FieldDef, FormEventConstructor, StateLogicConfig, BaseCheckedField, BaseValueField, FieldMeta, FieldOption,
|
|
2
|
-
export { NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, isEqual, resolveNonFieldDisabled, resolveNonFieldHidden } from '@ng-forge/dynamic-forms';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import { FormEvent, FieldDef, FormEventConstructor, StateLogicConfig, BaseCheckedField, BaseValueField, FieldMeta, FieldOption, ArrayAllowedChildren, NonFieldLogicConfig, NextPageEvent, PreviousPageEvent, FieldWithValidation, ValidationMessages, DynamicText, ArrayItemContext, EventBus } from '@ng-forge/dynamic-forms';
|
|
2
|
+
export { FieldWrapper, InferWrapperRegistry, NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, WrapperFieldInputs, WrapperRegistration, WrapperTypeDefinition, WrappersBundle, createWrappers, isEqual, isWrappersBundle, resolveNonFieldDisabled, resolveNonFieldHidden, wrapperProps } from '@ng-forge/dynamic-forms';
|
|
3
|
+
import * as _angular_core from '@angular/core';
|
|
4
|
+
import { Signal, Injector, ElementRef, Provider, WritableSignal, Type } from '@angular/core';
|
|
5
|
+
import { FieldTree, SchemaPath } from '@angular/forms/signals';
|
|
6
|
+
import { ComponentFixture } from '@angular/core/testing';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Event arguments that can contain static values or tokens to be resolved at runtime.
|
|
@@ -435,10 +437,9 @@ declare function resolveValueFieldContext(): ValueFieldContext;
|
|
|
435
437
|
* @param fieldDef The value field definition
|
|
436
438
|
* @param ctx The resolved value field context
|
|
437
439
|
* @param defaultProps Default props from the form configuration (may be undefined if not configured)
|
|
438
|
-
* @param defaultValidationMessages Default validation messages from the form configuration (may be undefined if not configured)
|
|
439
440
|
* @returns Record of input names to values
|
|
440
441
|
*/
|
|
441
|
-
declare function buildValueFieldInputs<TProps, TValue = unknown>(fieldDef: BaseValueField<TProps, TValue, FieldMeta, boolean>, ctx: ValueFieldContext, defaultProps?: Record<string, unknown
|
|
442
|
+
declare function buildValueFieldInputs<TProps, TValue = unknown>(fieldDef: BaseValueField<TProps, TValue, FieldMeta, boolean>, ctx: ValueFieldContext, defaultProps?: Record<string, unknown>): Record<string, unknown>;
|
|
442
443
|
/**
|
|
443
444
|
* Maps a value field definition to component inputs.
|
|
444
445
|
*
|
|
@@ -789,5 +790,376 @@ interface MetaTrackingOptions {
|
|
|
789
790
|
*/
|
|
790
791
|
declare function setupMetaTracking(elementRef: ElementRef<HTMLElement>, meta: Signal<FieldMeta | undefined>, options?: MetaTrackingOptions): void;
|
|
791
792
|
|
|
792
|
-
|
|
793
|
-
|
|
793
|
+
/**
|
|
794
|
+
* Creates a signal that computes the aria-describedby value based on errors and hint state.
|
|
795
|
+
* Errors take precedence over hints - when errors are displayed, the hint is hidden.
|
|
796
|
+
* Only the first error is displayed (single error ID, not indexed).
|
|
797
|
+
*
|
|
798
|
+
* @param errorsToDisplay Signal containing the array of errors currently being displayed
|
|
799
|
+
* @param errorId Signal containing the ID for the error element (single error only)
|
|
800
|
+
* @param hintId Signal containing the ID for the hint element
|
|
801
|
+
* @param hasHint Function that returns true if a hint is configured
|
|
802
|
+
* @returns Signal containing the aria-describedby value or null
|
|
803
|
+
*/
|
|
804
|
+
declare function createAriaDescribedBySignal(errorsToDisplay: Signal<ResolvedError[]>, errorId: Signal<string>, hintId: Signal<string>, hasHint: () => boolean): Signal<string | null>;
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Base directive composed into every ng-forge component via `hostDirectives`.
|
|
808
|
+
* Owns the universal identity inputs (`key`, `className`) and the host
|
|
809
|
+
* bindings that every field shape — value-bearing, action, future container —
|
|
810
|
+
* shares: `[id]`, `[attr.data-testid]`, `[class]`.
|
|
811
|
+
*
|
|
812
|
+
* Shape-specific add-ons (`NgForgeField` for value fields, `NgForgeAction`
|
|
813
|
+
* for actions) inject this directive and read `key()` / `className()` from
|
|
814
|
+
* it. Source-of-truth concerns like `hidden` / `disabled` live on the add-on
|
|
815
|
+
* because they vary by shape (value fields derive from `field()()`; actions
|
|
816
|
+
* receive direct inputs).
|
|
817
|
+
*
|
|
818
|
+
* Selectorless — usage is exclusively via `hostDirectives`. Prefer the
|
|
819
|
+
* `NG_FORGE_FIELD` / `NG_FORGE_ACTION` presets rather than composing Shell
|
|
820
|
+
* directly.
|
|
821
|
+
*/
|
|
822
|
+
declare class NgForgeFieldShell {
|
|
823
|
+
readonly key: _angular_core.InputSignal<string>;
|
|
824
|
+
readonly className: _angular_core.InputSignal<string>;
|
|
825
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgForgeFieldShell, never>;
|
|
826
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgForgeFieldShell, never, never, { "key": { "alias": "key"; "required": true; "isSignal": true; }; "className": { "alias": "className"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
827
|
+
}
|
|
828
|
+
/** Input names forwarded onto `NgForgeFieldShell` via `hostDirectives`. */
|
|
829
|
+
declare const NG_FORGE_FIELD_SHELL_INPUTS: readonly ["key", "className"];
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* Value-bearing add-on directive — composed alongside `NgForgeFieldShell` via
|
|
833
|
+
* the `NG_FORGE_FIELD` preset. Owns the value/validation/aria plumbing every
|
|
834
|
+
* value-bearing field needs.
|
|
835
|
+
*
|
|
836
|
+
* The Shell owns universal identity (`key`, `className`, `[id]`,
|
|
837
|
+
* `[attr.data-testid]`, `[class]`); this directive injects Shell and adds
|
|
838
|
+
* field-driven bindings (`[attr.hidden]`, `[attr.aria-disabled]`), the
|
|
839
|
+
* standard value-field inputs (`field`, `label`, `placeholder`, `tabIndex`,
|
|
840
|
+
* `props`, `meta`, `validationMessages`), the derived error/aria signals,
|
|
841
|
+
* and the meta-tracking claim contract.
|
|
842
|
+
*
|
|
843
|
+
* @example
|
|
844
|
+
* ```ts
|
|
845
|
+
* \@Component({
|
|
846
|
+
* hostDirectives: NG_FORGE_FIELD,
|
|
847
|
+
* imports: [NgForgeControl, FormField],
|
|
848
|
+
* template: `
|
|
849
|
+
* <label [for]="ngf.key() + '-input'">{{ ngf.label() | dynamicText | async }}</label>
|
|
850
|
+
* <input ngForgeControl [id]="ngf.key() + '-input'" [formField]="ngf.field()" />
|
|
851
|
+
* @if (ngf.errorsToDisplay()[0]; as e) {
|
|
852
|
+
* <span [id]="ngf.errorId()">{{ e.message }}</span>
|
|
853
|
+
* }
|
|
854
|
+
* `,
|
|
855
|
+
* })
|
|
856
|
+
* export class MyInputField {
|
|
857
|
+
* protected readonly ngf = injectNgForgeField<string>();
|
|
858
|
+
* }
|
|
859
|
+
* ```
|
|
860
|
+
*
|
|
861
|
+
* Selectorless — usage is exclusively via `hostDirectives`. Prefer the
|
|
862
|
+
* `NG_FORGE_FIELD` preset over composing this directive manually.
|
|
863
|
+
*/
|
|
864
|
+
declare class NgForgeField {
|
|
865
|
+
private readonly shell;
|
|
866
|
+
/** Shell-owned key, re-exported as plain `Signal<string>` so it doesn't get flagged by the host-directive input-lockstep assertion. */
|
|
867
|
+
readonly key: Signal<string>;
|
|
868
|
+
/** Shell-owned className, re-exported as plain `Signal<string>` for the same reason. */
|
|
869
|
+
readonly className: Signal<string>;
|
|
870
|
+
readonly field: _angular_core.InputSignal<FieldTree<unknown>>;
|
|
871
|
+
readonly label: _angular_core.InputSignal<DynamicText | undefined>;
|
|
872
|
+
readonly placeholder: _angular_core.InputSignal<DynamicText | undefined>;
|
|
873
|
+
readonly tabIndex: _angular_core.InputSignal<number | undefined>;
|
|
874
|
+
readonly props: _angular_core.InputSignal<unknown>;
|
|
875
|
+
readonly meta: _angular_core.InputSignal<FieldMeta | undefined>;
|
|
876
|
+
readonly validationMessages: _angular_core.InputSignal<ValidationMessages | undefined>;
|
|
877
|
+
private readonly defaultValidationMessages;
|
|
878
|
+
readonly errors: Signal<ResolvedError[]>;
|
|
879
|
+
readonly showErrors: Signal<boolean>;
|
|
880
|
+
readonly errorsToDisplay: Signal<ResolvedError[]>;
|
|
881
|
+
readonly errorId: Signal<string>;
|
|
882
|
+
readonly hintId: Signal<string>;
|
|
883
|
+
readonly ariaInvalid: Signal<boolean>;
|
|
884
|
+
readonly ariaRequired: Signal<true | null>;
|
|
885
|
+
readonly ariaDescribedBy: Signal<string | null>;
|
|
886
|
+
private readonly _claimed;
|
|
887
|
+
/** @internal Marker directives + ambient sub-components call this on construction. */
|
|
888
|
+
markClaimed(): void;
|
|
889
|
+
private readonly logger;
|
|
890
|
+
constructor();
|
|
891
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgForgeField, never>;
|
|
892
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgForgeField, never, never, { "field": { "alias": "field"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "validationMessages": { "alias": "validationMessages"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Inputs forwarded onto `NgForgeField` via `hostDirectives`. Excludes
|
|
896
|
+
* `key` / `className` (forwarded to `NgForgeFieldShell` separately via
|
|
897
|
+
* `NG_FORGE_FIELD_SHELL_INPUTS`). Most consumers shouldn't reference this
|
|
898
|
+
* directly — use the `NG_FORGE_FIELD` preset.
|
|
899
|
+
*/
|
|
900
|
+
declare const NG_FORGE_VALUE_FIELD_INPUTS: readonly ["field", "label", "placeholder", "tabIndex", "props", "meta", "validationMessages"];
|
|
901
|
+
/**
|
|
902
|
+
* `NgForgeField` typed for a specific value type. The directive itself stores
|
|
903
|
+
* `field` as `Signal<FieldTree<unknown>>` because Angular's `hostDirectives`
|
|
904
|
+
* doesn't propagate generics — `injectNgForgeField<T>()` narrows it at the
|
|
905
|
+
* inject site so consumers don't have to declare a separate cast computed.
|
|
906
|
+
*/
|
|
907
|
+
type TypedNgForgeField<T> = Omit<NgForgeField, 'field'> & {
|
|
908
|
+
readonly field: Signal<FieldTree<T>>;
|
|
909
|
+
};
|
|
910
|
+
/**
|
|
911
|
+
* Typed wrapper around `inject(NgForgeField)`. The generic narrows the
|
|
912
|
+
* `field` signal to `Signal<FieldTree<T>>` for the calling component's value
|
|
913
|
+
* type. The cast is unchecked — the runtime contract is that mappers only
|
|
914
|
+
* forward a `field` whose value type matches the field-type definition.
|
|
915
|
+
*
|
|
916
|
+
* @example
|
|
917
|
+
* ```ts
|
|
918
|
+
* protected readonly ngf = injectNgForgeField<string>();
|
|
919
|
+
* // ngf.field() is Signal<FieldTree<string>>; ngf.errors() etc. unchanged
|
|
920
|
+
* ```
|
|
921
|
+
*/
|
|
922
|
+
declare function injectNgForgeField<T = unknown>(): TypedNgForgeField<T>;
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Action add-on directive — composed alongside `NgForgeFieldShell` via the
|
|
926
|
+
* `NG_FORGE_ACTION` preset. Owns the inputs + dispatch logic every button /
|
|
927
|
+
* action component needs (label, disabled, event, eventArgs, …) plus the
|
|
928
|
+
* `[attr.hidden]` / `[attr.aria-disabled]` host bindings driven by its own
|
|
929
|
+
* inputs (no field tree).
|
|
930
|
+
*
|
|
931
|
+
* Components call `action.dispatch()` from their click handler; this
|
|
932
|
+
* directive resolves any `eventArgs` tokens via the optional `ARRAY_CONTEXT`
|
|
933
|
+
* and dispatches the configured `event` through the `EventBus`.
|
|
934
|
+
*
|
|
935
|
+
* @example
|
|
936
|
+
* ```ts
|
|
937
|
+
* \@Component({
|
|
938
|
+
* hostDirectives: NG_FORGE_ACTION,
|
|
939
|
+
* template: `<button (click)="action.dispatch()" [disabled]="action.disabled()">{{ action.label() }}</button>`,
|
|
940
|
+
* })
|
|
941
|
+
* export class MyButton {
|
|
942
|
+
* protected readonly action = inject(NgForgeAction);
|
|
943
|
+
* }
|
|
944
|
+
* ```
|
|
945
|
+
*
|
|
946
|
+
* Selectorless — usage is exclusively via `hostDirectives`. Prefer the
|
|
947
|
+
* `NG_FORGE_ACTION` preset over composing this directive manually.
|
|
948
|
+
*/
|
|
949
|
+
declare class NgForgeAction<TEvent extends FormEvent = FormEvent> {
|
|
950
|
+
private readonly shell;
|
|
951
|
+
readonly key: Signal<string>;
|
|
952
|
+
readonly className: Signal<string>;
|
|
953
|
+
readonly label: _angular_core.InputSignal<DynamicText>;
|
|
954
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
955
|
+
readonly hidden: _angular_core.InputSignal<boolean>;
|
|
956
|
+
readonly tabIndex: _angular_core.InputSignal<number | undefined>;
|
|
957
|
+
readonly event: _angular_core.InputSignal<FormEventConstructor<TEvent> | undefined>;
|
|
958
|
+
readonly eventArgs: _angular_core.InputSignal<EventArgs | undefined>;
|
|
959
|
+
readonly eventContext: _angular_core.InputSignal<ArrayItemContext | undefined>;
|
|
960
|
+
readonly props: _angular_core.InputSignal<unknown>;
|
|
961
|
+
private readonly eventBus;
|
|
962
|
+
private readonly arrayContext;
|
|
963
|
+
/**
|
|
964
|
+
* Dispatch the configured event through the EventBus. Resolves `eventArgs`
|
|
965
|
+
* tokens (`$key`, `$index`, `$arrayKey`, `formValue`, …) against the
|
|
966
|
+
* ambient array context if present, falling back to a static `eventContext`
|
|
967
|
+
* input or the field's own `key` otherwise. No-op when `event` is unset
|
|
968
|
+
* (e.g. submit buttons handled by the native form lifecycle).
|
|
969
|
+
*/
|
|
970
|
+
dispatch(): void;
|
|
971
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgForgeAction<any>, never>;
|
|
972
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgForgeAction<any>, never, never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hidden": { "alias": "hidden"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "event": { "alias": "event"; "required": false; "isSignal": true; }; "eventArgs": { "alias": "eventArgs"; "required": false; "isSignal": true; }; "eventContext": { "alias": "eventContext"; "required": false; "isSignal": true; }; "props": { "alias": "props"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Inputs forwarded onto `NgForgeAction` via `hostDirectives`. Excludes
|
|
976
|
+
* `key` / `className` (forwarded to `NgForgeFieldShell` separately via
|
|
977
|
+
* `NG_FORGE_FIELD_SHELL_INPUTS`). Most consumers shouldn't reference this
|
|
978
|
+
* directly — use the `NG_FORGE_ACTION` preset.
|
|
979
|
+
*/
|
|
980
|
+
declare const NG_FORGE_ACTION_INPUTS: readonly ["label", "disabled", "hidden", "tabIndex", "event", "eventArgs", "eventContext", "props"];
|
|
981
|
+
/**
|
|
982
|
+
* Typed wrapper around `inject(NgForgeAction)`. The generic narrows the
|
|
983
|
+
* `event` input to a specific FormEvent subclass.
|
|
984
|
+
*
|
|
985
|
+
* @example
|
|
986
|
+
* ```ts
|
|
987
|
+
* protected readonly action = injectNgForgeAction<SubmitEvent>();
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
declare function injectNgForgeAction<TEvent extends FormEvent = FormEvent>(): NgForgeAction<TEvent>;
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Marker directive applied to the canonical control element of an
|
|
994
|
+
* `NgForgeField`-using component. Forwards the field's `meta` AND
|
|
995
|
+
* parent-derived aria signals (`aria-invalid`, `aria-required`,
|
|
996
|
+
* `aria-describedby`) onto a target element.
|
|
997
|
+
*
|
|
998
|
+
* By default attributes land on the directive's own host. For wrapped
|
|
999
|
+
* controls (e.g. `<mat-checkbox>`, `<p-toggleSwitch>`) where the canonical
|
|
1000
|
+
* native input is rendered as a descendant inside the wrapper, pass a CSS
|
|
1001
|
+
* selector through the input alias — the directive caches the resolved
|
|
1002
|
+
* descendant set and re-resolves only when the selector changes.
|
|
1003
|
+
*
|
|
1004
|
+
* @example Bare native control
|
|
1005
|
+
* ```html
|
|
1006
|
+
* <input ngForgeControl [formField]="ngf.field()" />
|
|
1007
|
+
* ```
|
|
1008
|
+
*
|
|
1009
|
+
* @example Wrapped control with inner native input
|
|
1010
|
+
* ```html
|
|
1011
|
+
* <mat-checkbox ngForgeControl="input[type='checkbox']" [formField]="ngf.field()">
|
|
1012
|
+
* {{ ngf.label() }}
|
|
1013
|
+
* </mat-checkbox>
|
|
1014
|
+
* ```
|
|
1015
|
+
*
|
|
1016
|
+
* @example Dynamic option list (radios rendered in @for)
|
|
1017
|
+
* ```html
|
|
1018
|
+
* @for (option of options(); track option.value) {
|
|
1019
|
+
* <input type="radio" ngForgeControl [value]="option.value" />
|
|
1020
|
+
* }
|
|
1021
|
+
* ```
|
|
1022
|
+
*
|
|
1023
|
+
* Each `@for` iteration creates its own directive instance; Angular's
|
|
1024
|
+
* structural lifecycle handles add/remove naturally.
|
|
1025
|
+
*/
|
|
1026
|
+
declare class NgForgeControl {
|
|
1027
|
+
readonly target: _angular_core.InputSignal<string | undefined>;
|
|
1028
|
+
constructor();
|
|
1029
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgForgeControl, never>;
|
|
1030
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgForgeControl, "[ngForgeControl]", never, { "target": { "alias": "ngForgeControl"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Selectorless companion directive for shadow-DOM-encapsulated components
|
|
1034
|
+
* (PrimeNG `p-select`, Ionic web components, etc.) where no light-DOM child
|
|
1035
|
+
* is the canonical control. Added to the component's `hostDirectives` so the
|
|
1036
|
+
* field's `meta` + parent aria land on the component's own host element.
|
|
1037
|
+
*
|
|
1038
|
+
* For split parent/control components (e.g. `df-prime-select` rendering
|
|
1039
|
+
* `df-prime-select-control` internally), place `NgForgeHostControl` on the
|
|
1040
|
+
* INNER control component's `hostDirectives` — the inner element is the
|
|
1041
|
+
* canonical control, and the marker's `inject(NgForgeField)` walks up the
|
|
1042
|
+
* element-injector tree to find the parent's directive instance.
|
|
1043
|
+
*
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```ts
|
|
1046
|
+
* \@Component({
|
|
1047
|
+
* hostDirectives: [
|
|
1048
|
+
* { directive: NgForgeField, inputs: [...NG_FORGE_FIELD_INPUTS] },
|
|
1049
|
+
* NgForgeHostControl,
|
|
1050
|
+
* ],
|
|
1051
|
+
* template: `...`,
|
|
1052
|
+
* })
|
|
1053
|
+
* export class IonicInputField { ... }
|
|
1054
|
+
* ```
|
|
1055
|
+
*/
|
|
1056
|
+
declare class NgForgeHostControl {
|
|
1057
|
+
constructor();
|
|
1058
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgForgeHostControl, never>;
|
|
1059
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgForgeHostControl, never, never, {}, {}, never, never, true, never>;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* Value-bearing field host wrapper. Composes `NgForgeFieldShell` (universal
|
|
1064
|
+
* identity) with `NgForgeField` (value + validation + aria + meta-tracking)
|
|
1065
|
+
* in a single host-directive entry, so consumer components compose just one
|
|
1066
|
+
* directive instead of two.
|
|
1067
|
+
*
|
|
1068
|
+
* Why a directive instead of a `const` preset: cross-package partial
|
|
1069
|
+
* compilation can't resolve a const reference inside `hostDirectives:`, so
|
|
1070
|
+
* an exported const array doesn't work for library consumers. A wrapper
|
|
1071
|
+
* directive's own `hostDirectives` IS a literal at compile time (in this
|
|
1072
|
+
* file), so it works everywhere.
|
|
1073
|
+
*
|
|
1074
|
+
* Authoring shape for adapter components:
|
|
1075
|
+
* ```ts
|
|
1076
|
+
* \@Component({
|
|
1077
|
+
* hostDirectives: [NgForgeFieldHost],
|
|
1078
|
+
* ...
|
|
1079
|
+
* })
|
|
1080
|
+
* export class MyInputField {
|
|
1081
|
+
* protected readonly ngf = injectNgForgeField<string>();
|
|
1082
|
+
* }
|
|
1083
|
+
* ```
|
|
1084
|
+
*
|
|
1085
|
+
* Pattern reference: Taiga UI uses the same wrapper-directive technique
|
|
1086
|
+
* for the same reason. See https://www.angularspace.com/host-directives-decomposition-unleashed/
|
|
1087
|
+
*/
|
|
1088
|
+
declare class NgForgeFieldHost {
|
|
1089
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgForgeFieldHost, never>;
|
|
1090
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgForgeFieldHost, never, never, {}, {}, never, never, true, [{ directive: typeof NgForgeFieldShell; inputs: { "key": "key"; "className": "className"; }; outputs: {}; }, { directive: typeof NgForgeField; inputs: { "field": "field"; "label": "label"; "placeholder": "placeholder"; "tabIndex": "tabIndex"; "props": "props"; "meta": "meta"; "validationMessages": "validationMessages"; }; outputs: {}; }]>;
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Action / button host wrapper. Composes `NgForgeFieldShell` with
|
|
1094
|
+
* `NgForgeAction` (event dispatch + aria-disabled) for button-shaped
|
|
1095
|
+
* components.
|
|
1096
|
+
*
|
|
1097
|
+
* Authoring shape:
|
|
1098
|
+
* ```ts
|
|
1099
|
+
* \@Component({
|
|
1100
|
+
* hostDirectives: [NgForgeActionHost],
|
|
1101
|
+
* ...
|
|
1102
|
+
* })
|
|
1103
|
+
* export class MyButton {
|
|
1104
|
+
* protected readonly action = injectNgForgeAction();
|
|
1105
|
+
* }
|
|
1106
|
+
* ```
|
|
1107
|
+
*/
|
|
1108
|
+
declare class NgForgeActionHost {
|
|
1109
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NgForgeActionHost, never>;
|
|
1110
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<NgForgeActionHost, never, never, {}, {}, never, never, true, [{ directive: typeof NgForgeFieldShell; inputs: { "key": "key"; "className": "className"; }; outputs: {}; }, { directive: typeof NgForgeAction; inputs: { "label": "label"; "disabled": "disabled"; "hidden": "hidden"; "tabIndex": "tabIndex"; "event": "event"; "eventArgs": "eventArgs"; "eventContext": "eventContext"; "props": "props"; }; outputs: {}; }]>;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
interface CreateNgForgeFieldFixtureOptions<TValue = unknown> {
|
|
1114
|
+
/** Field key. Becomes the only property on the wrapping form. */
|
|
1115
|
+
readonly key: string;
|
|
1116
|
+
/** Initial value for the field. */
|
|
1117
|
+
readonly value?: TValue;
|
|
1118
|
+
/** Optional schema callback that receives the field's `SchemaPath`. Use it to attach validators (`required`, `minLength`, etc.). */
|
|
1119
|
+
readonly schema?: (fieldPath: SchemaPath<TValue>) => void;
|
|
1120
|
+
/** Mark the field as touched after creation (useful for invalid-state assertions). */
|
|
1121
|
+
readonly touched?: boolean;
|
|
1122
|
+
/** Extra inputs to set on the component before `detectChanges()`. */
|
|
1123
|
+
readonly inputs?: Record<string, unknown>;
|
|
1124
|
+
/** Extra TestBed providers. */
|
|
1125
|
+
readonly providers?: readonly Provider[];
|
|
1126
|
+
}
|
|
1127
|
+
interface NgForgeFieldFixture<C, TValue = unknown> {
|
|
1128
|
+
readonly fixture: ComponentFixture<C>;
|
|
1129
|
+
readonly field: FieldTree<TValue>;
|
|
1130
|
+
readonly rootValue: WritableSignal<Record<string, TValue>>;
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Builds a `ComponentFixture` for an `NgForgeField`-composing component with
|
|
1134
|
+
* `field` + `key` bound BEFORE `detectChanges()` — sidesteps the NG0950 that
|
|
1135
|
+
* Shell's required `key` and Field's required `field` would otherwise throw.
|
|
1136
|
+
*
|
|
1137
|
+
* The caller drives `detectChanges()` themselves (so they can `setInput`
|
|
1138
|
+
* additional component-specific props in between).
|
|
1139
|
+
*/
|
|
1140
|
+
declare function createNgForgeFieldFixture<C, TValue = unknown>(component: Type<C>, options: CreateNgForgeFieldFixtureOptions<TValue>): NgForgeFieldFixture<C, TValue>;
|
|
1141
|
+
interface CreateNgForgeActionFixtureOptions<TEvent extends FormEvent = FormEvent> {
|
|
1142
|
+
readonly key: string;
|
|
1143
|
+
readonly label: DynamicText;
|
|
1144
|
+
readonly event?: FormEventConstructor<TEvent>;
|
|
1145
|
+
readonly eventArgs?: EventArgs;
|
|
1146
|
+
readonly disabled?: boolean;
|
|
1147
|
+
readonly hidden?: boolean;
|
|
1148
|
+
readonly inputs?: Record<string, unknown>;
|
|
1149
|
+
readonly providers?: readonly Provider[];
|
|
1150
|
+
}
|
|
1151
|
+
interface NgForgeActionFixture<C> {
|
|
1152
|
+
readonly fixture: ComponentFixture<C>;
|
|
1153
|
+
readonly eventBus: EventBus;
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Builds a `ComponentFixture` for an `NgForgeAction`-composing component with
|
|
1157
|
+
* `key` + `label` bound and `EventBus` provided. The caller calls
|
|
1158
|
+
* `detectChanges()`; the harness handles the NG0950-avoidance bindings.
|
|
1159
|
+
*/
|
|
1160
|
+
declare function createNgForgeActionFixture<C, TEvent extends FormEvent = FormEvent>(component: Type<C>, options: CreateNgForgeActionFixtureOptions<TEvent>): NgForgeActionFixture<C>;
|
|
1161
|
+
/** Provider for `DEFAULT_VALIDATION_MESSAGES` in field tests — supply the default-messages map and the directive resolves it from DI. */
|
|
1162
|
+
declare function provideTestValidationMessages(messages: ValidationMessages): Provider;
|
|
1163
|
+
|
|
1164
|
+
export { NG_FORGE_ACTION_INPUTS, NG_FORGE_FIELD_SHELL_INPUTS, NG_FORGE_VALUE_FIELD_INPUTS, NgForgeAction, NgForgeActionHost, NgForgeControl, NgForgeField, NgForgeFieldHost, NgForgeFieldShell, NgForgeHostControl, addArrayItemButtonMapper, buildArrayButtonEventContext, buildValueFieldInputs, buttonFieldMapper, checkboxFieldMapper, createAriaDescribedBySignal, createNgForgeActionFixture, createNgForgeFieldFixture, createResolvedErrorsSignal, datepickerFieldMapper, injectNgForgeAction, injectNgForgeField, insertArrayItemButtonMapper, nextButtonFieldMapper, optionsFieldMapper, popArrayItemButtonMapper, prependArrayItemButtonMapper, previousButtonFieldMapper, provideTestValidationMessages, removeArrayItemButtonMapper, resolveArrayButtonContext, resolveArrayButtonEventArgs, resolveValueFieldContext, setupMetaTracking, shiftArrayItemButtonMapper, shouldShowErrors, submitButtonFieldMapper, valueFieldMapper };
|
|
1165
|
+
export type { ArrayButtonContext, ArrayButtonEventContext, Autocapitalize, AutocompleteValue, BaseArrayAddButtonField, BaseArrayRemoveButtonField, BaseInsertArrayItemButtonField, BaseNavigationButtonField, ButtonField, CheckboxField, CreateNgForgeActionFixtureOptions, CreateNgForgeFieldFixtureOptions, DatepickerField, DatepickerProps, EnterKeyHint, EventArg, EventArgs, FieldWithOptions, HtmlInputType, InferInputValue, InputField, InputMeta, InputMode, InputProps, InputType, InputTypeToValueType, MetaTrackingOptions, MultiCheckboxField, NgForgeActionFixture, NgForgeFieldFixture, NumericInputType, RadioField, ResolvedError, SelectField, SelectProps, SliderField, StringInputType, TextareaField, TextareaMeta, TextareaProps, TextareaWrap, ToggleField, TypedNgForgeField, ValueFieldContext };
|