@ng-forge/dynamic-forms 0.9.0-next.9 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-array-field.component-us7mQtVQ.mjs → ng-forge-dynamic-forms-array-field.component-Tw49K5kz.mjs} +171 -73
- package/fesm2022/ng-forge-dynamic-forms-array-field.component-Tw49K5kz.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-container-field.component-BCIQ6_Mm.mjs → ng-forge-dynamic-forms-container-field.component-CrOIZEL_.mjs} +12 -8
- package/fesm2022/ng-forge-dynamic-forms-container-field.component-CrOIZEL_.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-container-utils-CzZlFNA0.mjs → ng-forge-dynamic-forms-container-utils-Bx1A5tg-.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-container-utils-CzZlFNA0.mjs.map → ng-forge-dynamic-forms-container-utils-Bx1A5tg-.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-css-wrapper.component-Dhlf6UxN.mjs → ng-forge-dynamic-forms-css-wrapper.component-Q2g56KUM.mjs} +5 -5
- package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-Q2g56KUM.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-DqQ8BA4W.mjs → ng-forge-dynamic-forms-emit-initialization-9l5gPNQc.mjs} +2 -2
- package/fesm2022/{ng-forge-dynamic-forms-emit-initialization-DqQ8BA4W.mjs.map → ng-forge-dynamic-forms-emit-initialization-9l5gPNQc.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-group-field.component-DKcoco0G.mjs → ng-forge-dynamic-forms-group-field.component-DqnhddRH.mjs} +36 -12
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-DqnhddRH.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +936 -54
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-CfbmSRM_.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-Be1Lk0qR.mjs} +2230 -445
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-Be1Lk0qR.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-n4KTMOTm.mjs +114 -0
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-n4KTMOTm.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-CFtnatYj.mjs +34 -0
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-CFtnatYj.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-8C1-oyU_.mjs → ng-forge-dynamic-forms-text-field.component-C14mlROS.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-8C1-oyU_.mjs.map → ng-forge-dynamic-forms-text-field.component-C14mlROS.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 +587 -11
- package/types/ng-forge-dynamic-forms.d.ts +3841 -2428
- package/fesm2022/ng-forge-dynamic-forms-array-field.component-us7mQtVQ.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-container-field.component-BCIQ6_Mm.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-css-wrapper.component-Dhlf6UxN.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-group-field.component-DKcoco0G.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CfbmSRM_.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-DqWAcwhG.mjs +0 -110
- package/fesm2022/ng-forge-dynamic-forms-page-field.component-DqWAcwhG.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs +0 -34
- package/fesm2022/ng-forge-dynamic-forms-row-wrapper.component-BIvEUoia.mjs.map +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { FormEvent, FieldDef, FormEventConstructor, StateLogicConfig, BaseCheckedField,
|
|
2
|
-
export { NonFieldLogicConfig, NonFieldLogicContext, NonFieldLogicType, isEqual, resolveNonFieldDisabled, resolveNonFieldHidden } from '@ng-forge/dynamic-forms';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import { FormEvent, FieldDef, FormEventConstructor, StateLogicConfig, BaseCheckedField, FieldMeta, BaseValueField, FieldOption, ArrayAllowedChildren, NonFieldLogicConfig, NextPageEvent, PreviousPageEvent, FieldWithValidation, ValidationMessages, DynamicText, ArrayItemContext, AnyAddon, BaseAddon, AddonActionHandler, DynamicValue, WrapperFieldInputs, AddonActionContext, 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 i0 from '@angular/core';
|
|
4
|
+
import { Signal, Injector, ElementRef, InjectionToken, 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.
|
|
@@ -38,7 +40,7 @@ interface ButtonField<TProps, TEvent extends FormEvent> extends FieldDef<TProps>
|
|
|
38
40
|
logic?: StateLogicConfig[];
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
interface CheckboxField<TProps> extends BaseCheckedField<TProps> {
|
|
43
|
+
interface CheckboxField<TProps, TNullable extends boolean = boolean> extends BaseCheckedField<TProps, FieldMeta, TNullable> {
|
|
42
44
|
type: 'checkbox';
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -390,7 +392,7 @@ interface TextareaField<TProps = TextareaProps, TNullable extends boolean = bool
|
|
|
390
392
|
maxLength?: number | undefined;
|
|
391
393
|
}
|
|
392
394
|
|
|
393
|
-
interface ToggleField<TProps> extends BaseCheckedField<TProps> {
|
|
395
|
+
interface ToggleField<TProps, TNullable extends boolean = boolean> extends BaseCheckedField<TProps, FieldMeta, TNullable> {
|
|
394
396
|
type: 'toggle';
|
|
395
397
|
}
|
|
396
398
|
|
|
@@ -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
|
*
|
|
@@ -470,7 +471,7 @@ declare function valueFieldMapper<TProps = unknown, TValue = unknown>(fieldDef:
|
|
|
470
471
|
* @param fieldDef The checkbox field definition
|
|
471
472
|
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
472
473
|
*/
|
|
473
|
-
declare function checkboxFieldMapper(fieldDef: BaseCheckedField<unknown>): Signal<Record<string, unknown>>;
|
|
474
|
+
declare function checkboxFieldMapper(fieldDef: BaseCheckedField<unknown, FieldMeta, boolean>): Signal<Record<string, unknown>>;
|
|
474
475
|
|
|
475
476
|
/**
|
|
476
477
|
* Maps a datepicker field to component inputs.
|
|
@@ -789,5 +790,580 @@ 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: i0.InputSignal<string>;
|
|
824
|
+
readonly className: i0.InputSignal<string>;
|
|
825
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeFieldShell, never>;
|
|
826
|
+
static ɵdir: i0.ɵɵ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: i0.InputSignal<FieldTree<unknown>>;
|
|
871
|
+
readonly label: i0.InputSignal<DynamicText | undefined>;
|
|
872
|
+
readonly placeholder: i0.InputSignal<DynamicText | undefined>;
|
|
873
|
+
readonly tabIndex: i0.InputSignal<number | undefined>;
|
|
874
|
+
readonly props: i0.InputSignal<unknown>;
|
|
875
|
+
readonly meta: i0.InputSignal<FieldMeta | undefined>;
|
|
876
|
+
readonly validationMessages: i0.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: i0.ɵɵFactoryDeclaration<NgForgeField, never>;
|
|
892
|
+
static ɵdir: i0.ɵɵ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: i0.InputSignal<DynamicText>;
|
|
954
|
+
readonly disabled: i0.InputSignal<boolean>;
|
|
955
|
+
readonly hidden: i0.InputSignal<boolean>;
|
|
956
|
+
readonly tabIndex: i0.InputSignal<number | undefined>;
|
|
957
|
+
readonly event: i0.InputSignal<FormEventConstructor<TEvent> | undefined>;
|
|
958
|
+
readonly eventArgs: i0.InputSignal<EventArgs | undefined>;
|
|
959
|
+
readonly eventContext: i0.InputSignal<ArrayItemContext | undefined>;
|
|
960
|
+
readonly props: i0.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: i0.ɵɵFactoryDeclaration<NgForgeAction<any>, never>;
|
|
972
|
+
static ɵdir: i0.ɵɵ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
|
+
* Universal addon-array plumbing: signal-cached `hidden` resolution and
|
|
994
|
+
* slot bucketing. Used internally by the `NgForgeAddons` host wrapper —
|
|
995
|
+
* consumers should compose `NgForgeAddons` directly and inject the
|
|
996
|
+
* directive instance via `injectNgForgeAddons<TAddon>()`.
|
|
997
|
+
*/
|
|
998
|
+
declare class NgForgeAddonsBase {
|
|
999
|
+
/** Capture the host's injector so `toSignal` (inside `resolveDynamicValue`) ties to the host's `DestroyRef`. */
|
|
1000
|
+
private readonly hostInjector;
|
|
1001
|
+
/** Addon array mapped from `FieldDef.addons` by `buildBaseInputs`. */
|
|
1002
|
+
readonly addons: i0.InputSignal<readonly AnyAddon[] | undefined>;
|
|
1003
|
+
/**
|
|
1004
|
+
* Per-addon `hidden` signal cache. Built via `explicitEffect` rather
|
|
1005
|
+
* than `computed` because `toSignal` (inside `resolveDynamicValue` for
|
|
1006
|
+
* Observable inputs) is disallowed in reactive contexts (NG0602).
|
|
1007
|
+
*/
|
|
1008
|
+
private readonly _hiddenSignalCache;
|
|
1009
|
+
readonly hiddenSignalCache: Signal<ReadonlyMap<AnyAddon, Signal<boolean>>>;
|
|
1010
|
+
readonly visibleAddons: Signal<ReadonlyArray<AnyAddon>>;
|
|
1011
|
+
readonly hasAddons: Signal<boolean>;
|
|
1012
|
+
readonly prefixAddons: Signal<ReadonlyArray<AnyAddon>>;
|
|
1013
|
+
readonly suffixAddons: Signal<ReadonlyArray<AnyAddon>>;
|
|
1014
|
+
/**
|
|
1015
|
+
* Visible addons grouped by their `slot` string. Convenience view for
|
|
1016
|
+
* adapters with non-universal slots (e.g., Ionic `start` / `end`).
|
|
1017
|
+
*/
|
|
1018
|
+
readonly addonsBySlot: Signal<ReadonlyMap<string, ReadonlyArray<AnyAddon>>>;
|
|
1019
|
+
/** Secondary index keyed by `hidden` value identity. Catches the common case
|
|
1020
|
+
* where a FormConfig re-emit produces structurally-different-but-content-
|
|
1021
|
+
* identical addon objects — without this, every re-emit would spawn a new
|
|
1022
|
+
* `toSignal` subscription for each addon's hidden axis. */
|
|
1023
|
+
private readonly _hiddenByValue;
|
|
1024
|
+
constructor();
|
|
1025
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeAddonsBase, never>;
|
|
1026
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgForgeAddonsBase, never, never, { "addons": { "alias": "addons"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1027
|
+
}
|
|
1028
|
+
/** Forwarded onto `NgForgeAddonsBase` via the `NgForgeAddons` wrapper. */
|
|
1029
|
+
declare const NG_FORGE_ADDONS_INPUTS: readonly ["addons"];
|
|
1030
|
+
/**
|
|
1031
|
+
* Host wrapper for `NgForgeAddonsBase`. Consumers compose this directly:
|
|
1032
|
+
*
|
|
1033
|
+
* ```ts
|
|
1034
|
+
* \@Component({
|
|
1035
|
+
* hostDirectives: [NgForgeFieldHost, NgForgeAddons],
|
|
1036
|
+
* template: `
|
|
1037
|
+
* @if (ngfa.hasAddons()) {
|
|
1038
|
+
* <p-inputgroup>
|
|
1039
|
+
* @for (a of ngfa.prefixAddons(); track $index) {
|
|
1040
|
+
* <df-addon-slot [addon]="a" [hidden]="ngfa.hiddenSignalCache().get(a)" />
|
|
1041
|
+
* }
|
|
1042
|
+
* <input ngForgeControl ... />
|
|
1043
|
+
* </p-inputgroup>
|
|
1044
|
+
* }
|
|
1045
|
+
* `,
|
|
1046
|
+
* })
|
|
1047
|
+
* export class MyInputField {
|
|
1048
|
+
* protected readonly ngfa = injectNgForgeAddons<MyInputAddon>();
|
|
1049
|
+
* }
|
|
1050
|
+
* ```
|
|
1051
|
+
*
|
|
1052
|
+
* The wrapper exists so `hostDirectives: [NgForgeAddons]` resolves
|
|
1053
|
+
* cross-package — same constraint that drives `NgForgeFieldHost`.
|
|
1054
|
+
*/
|
|
1055
|
+
declare class NgForgeAddons {
|
|
1056
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeAddons, never>;
|
|
1057
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgForgeAddons, never, never, {}, {}, never, never, true, [{ directive: typeof NgForgeAddonsBase; inputs: { "addons": "addons"; }; outputs: {}; }]>;
|
|
1058
|
+
}
|
|
1059
|
+
/** Narrowed view of `NgForgeAddonsBase` returned by `injectNgForgeAddons<TAddon>()`. */
|
|
1060
|
+
type TypedNgForgeAddons<TAddon extends AnyAddon = AnyAddon> = Omit<NgForgeAddonsBase, 'addons' | 'visibleAddons' | 'prefixAddons' | 'suffixAddons'> & {
|
|
1061
|
+
readonly addons: Signal<ReadonlyArray<TAddon> | undefined>;
|
|
1062
|
+
readonly visibleAddons: Signal<ReadonlyArray<TAddon>>;
|
|
1063
|
+
readonly prefixAddons: Signal<ReadonlyArray<TAddon>>;
|
|
1064
|
+
readonly suffixAddons: Signal<ReadonlyArray<TAddon>>;
|
|
1065
|
+
};
|
|
1066
|
+
/**
|
|
1067
|
+
* Typed inject helper. Always resolves to the underlying
|
|
1068
|
+
* `NgForgeAddonsBase` instance — the wrapper class has no instance
|
|
1069
|
+
* fields of its own.
|
|
1070
|
+
*/
|
|
1071
|
+
declare function injectNgForgeAddons<TAddon extends AnyAddon = AnyAddon>(): TypedNgForgeAddons<TAddon>;
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* Permissive shape the directive reads from `addon()`. Adapter-specific
|
|
1075
|
+
* addon types (e.g., `PrimeButtonAddon`) narrow this at the inject site via
|
|
1076
|
+
* `injectNgForgeAddonAction<T>()`.
|
|
1077
|
+
*/
|
|
1078
|
+
interface ActionAddonShape extends BaseAddon {
|
|
1079
|
+
readonly preset?: string;
|
|
1080
|
+
readonly actionRef?: string;
|
|
1081
|
+
readonly action?: AddonActionHandler;
|
|
1082
|
+
readonly disabled?: DynamicValue<boolean>;
|
|
1083
|
+
readonly loading?: DynamicValue<boolean>;
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Universal click-dispatch plumbing for action-style addons (icon buttons,
|
|
1087
|
+
* labelled buttons, etc.): `disabled` / `loading` resolution from
|
|
1088
|
+
* `DynamicValue<boolean>`, action context construction, and the
|
|
1089
|
+
* `preset / actionRef / action` precedence dispatcher.
|
|
1090
|
+
*
|
|
1091
|
+
* Adapter button kinds (e.g., `prime-button`) compose `NgForgeAddonAction`
|
|
1092
|
+
* and read state via `injectNgForgeAddonAction<TAddon>()`. Preset semantics
|
|
1093
|
+
* are adapter-specific — register an `ADDON_PRESET_HANDLER` at the host
|
|
1094
|
+
* field scope to receive preset dispatches.
|
|
1095
|
+
*/
|
|
1096
|
+
declare class NgForgeAddonActionBase {
|
|
1097
|
+
private readonly actionRegistry;
|
|
1098
|
+
private readonly presetHandler;
|
|
1099
|
+
private readonly logger;
|
|
1100
|
+
private readonly hostInjector;
|
|
1101
|
+
readonly addon: i0.InputSignal<ActionAddonShape>;
|
|
1102
|
+
readonly fieldInputs: i0.InputSignal<WrapperFieldInputs | undefined>;
|
|
1103
|
+
/**
|
|
1104
|
+
* Per-value caches for `disabled` / `loading` signal resolution. Keyed by
|
|
1105
|
+
* the `DynamicValue` identity so a single `toSignal` subscription is
|
|
1106
|
+
* shared across addon-reference swaps that pass the same Observable.
|
|
1107
|
+
* Mirrors `NgForgeAddonsBase._hiddenByValue` — `resolveDynamicValue`
|
|
1108
|
+
* cannot run inside `computed`/`linkedSignal.computation` because
|
|
1109
|
+
* `toSignal` throws in reactive contexts (NG0602), and re-running it on
|
|
1110
|
+
* every recomputation would leak subscriptions on each cycle.
|
|
1111
|
+
*/
|
|
1112
|
+
private readonly _disabledByValue;
|
|
1113
|
+
private readonly _loadingByValue;
|
|
1114
|
+
private readonly _resolvedDisabled;
|
|
1115
|
+
private readonly _resolvedLoading;
|
|
1116
|
+
readonly disabled: Signal<boolean>;
|
|
1117
|
+
readonly loading: Signal<boolean>;
|
|
1118
|
+
constructor();
|
|
1119
|
+
private _resolveAxis;
|
|
1120
|
+
/**
|
|
1121
|
+
* Resolve the click handler from the addon's three-axis click variant and
|
|
1122
|
+
* invoke it. Precedence on multi-set: `preset > actionRef > action`. The
|
|
1123
|
+
* validator drops multi-set configs at config-init time; this is
|
|
1124
|
+
* defence-in-depth + a logged warning so the misconfiguration is loud.
|
|
1125
|
+
*/
|
|
1126
|
+
dispatch(): void;
|
|
1127
|
+
/**
|
|
1128
|
+
* Build an `AddonActionContext` for handlers from the wrapper-style
|
|
1129
|
+
* `fieldInputs` bag. Returns the field-bound variant when a host field
|
|
1130
|
+
* is reachable, or the orphan variant otherwise.
|
|
1131
|
+
*
|
|
1132
|
+
* Resolution order for `setValue`:
|
|
1133
|
+
* 1. `inputs.setValue` from the forwarded bag (preferred — populated by
|
|
1134
|
+
* `buildFieldInputs` in `DfFieldOutlet`).
|
|
1135
|
+
* 2. Fallback reconstructed from `inputs.field` itself: although
|
|
1136
|
+
* `ReadonlyFieldTree.value` is type-narrowed to `Signal<T>`, the
|
|
1137
|
+
* underlying runtime object is the same `WritableSignal<T>` created
|
|
1138
|
+
* by Signal Forms (the read-only wrapping is type-level only, see
|
|
1139
|
+
* `toReadonlyFieldTree`). Casting back at the writer boundary
|
|
1140
|
+
* produces a working setValue for ANY field depth — top-level OR
|
|
1141
|
+
* nested under groups. This avoids the previous FSC-key navigation
|
|
1142
|
+
* that broke for grouped fields, where `inputs.key` is DOM-mangled
|
|
1143
|
+
* (`'user_address_street'`) and `fsc.form[key]` returns undefined.
|
|
1144
|
+
*
|
|
1145
|
+
* The orphan variant fires only when the bag carries no field tree at
|
|
1146
|
+
* all — genuine "rendered outside a field" scenario.
|
|
1147
|
+
*/
|
|
1148
|
+
buildActionContext(): AddonActionContext;
|
|
1149
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeAddonActionBase, never>;
|
|
1150
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgForgeAddonActionBase, never, never, { "addon": { "alias": "addon"; "required": true; "isSignal": true; }; "fieldInputs": { "alias": "fieldInputs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1151
|
+
}
|
|
1152
|
+
/** Forwarded onto `NgForgeAddonActionBase` via the `NgForgeAddonAction` wrapper. */
|
|
1153
|
+
declare const NG_FORGE_ADDON_ACTION_INPUTS: readonly ["addon", "fieldInputs"];
|
|
1154
|
+
/**
|
|
1155
|
+
* Host wrapper for `NgForgeAddonActionBase`. Consumers compose this directly:
|
|
1156
|
+
*
|
|
1157
|
+
* ```ts
|
|
1158
|
+
* \@Component({
|
|
1159
|
+
* hostDirectives: [NgForgeAddonAction],
|
|
1160
|
+
* template: `
|
|
1161
|
+
* <p-button [loading]="action.loading()" [disabled]="action.disabled()"
|
|
1162
|
+
* (onClick)="action.dispatch()" />
|
|
1163
|
+
* `,
|
|
1164
|
+
* })
|
|
1165
|
+
* export class MyButtonAddon {
|
|
1166
|
+
* protected readonly action = injectNgForgeAddonAction<MyButtonAddon>();
|
|
1167
|
+
* }
|
|
1168
|
+
* ```
|
|
1169
|
+
*/
|
|
1170
|
+
declare class NgForgeAddonAction {
|
|
1171
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeAddonAction, never>;
|
|
1172
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgForgeAddonAction, never, never, {}, {}, never, never, true, [{ directive: typeof NgForgeAddonActionBase; inputs: { "addon": "addon"; "fieldInputs": "fieldInputs"; }; outputs: {}; }]>;
|
|
1173
|
+
}
|
|
1174
|
+
/** Narrowed view of `NgForgeAddonActionBase` returned by `injectNgForgeAddonAction<T>()`. */
|
|
1175
|
+
type TypedNgForgeAddonAction<TAddon extends ActionAddonShape = ActionAddonShape> = Omit<NgForgeAddonActionBase, 'addon'> & {
|
|
1176
|
+
readonly addon: Signal<TAddon>;
|
|
1177
|
+
};
|
|
1178
|
+
declare function injectNgForgeAddonAction<TAddon extends ActionAddonShape = ActionAddonShape>(): TypedNgForgeAddonAction<TAddon>;
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Adapter-supplied resolver for `preset` addon actions (e.g., `'clear'`,
|
|
1182
|
+
* `'toggle-password-visibility'`). The universal click-dispatch directive
|
|
1183
|
+
* (`NgForgeAddonAction`) delegates to this when an addon configures a
|
|
1184
|
+
* `preset`; the adapter wires concrete preset semantics in its own
|
|
1185
|
+
* provider scope.
|
|
1186
|
+
*
|
|
1187
|
+
* `NgForgeAddonAction` injects this with `{ optional: true }`. Addons that
|
|
1188
|
+
* configure a preset on an adapter that hasn't registered a handler get a
|
|
1189
|
+
* lenient warning at click time.
|
|
1190
|
+
*/
|
|
1191
|
+
interface AddonPresetHandler {
|
|
1192
|
+
run(preset: string, ctx: AddonActionContext): void | Promise<void>;
|
|
1193
|
+
}
|
|
1194
|
+
declare const ADDON_PRESET_HANDLER: InjectionToken<AddonPresetHandler>;
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Marker directive applied to the canonical control element of an
|
|
1198
|
+
* `NgForgeField`-using component. Forwards the field's `meta` AND
|
|
1199
|
+
* parent-derived aria signals (`aria-invalid`, `aria-required`,
|
|
1200
|
+
* `aria-describedby`) onto a target element.
|
|
1201
|
+
*
|
|
1202
|
+
* By default attributes land on the directive's own host. For wrapped
|
|
1203
|
+
* controls (e.g. `<mat-checkbox>`, `<p-toggleSwitch>`) where the canonical
|
|
1204
|
+
* native input is rendered as a descendant inside the wrapper, pass a CSS
|
|
1205
|
+
* selector through the input alias — the directive caches the resolved
|
|
1206
|
+
* descendant set and re-resolves only when the selector changes.
|
|
1207
|
+
*
|
|
1208
|
+
* @example Bare native control
|
|
1209
|
+
* ```html
|
|
1210
|
+
* <input ngForgeControl [formField]="ngf.field()" />
|
|
1211
|
+
* ```
|
|
1212
|
+
*
|
|
1213
|
+
* @example Wrapped control with inner native input
|
|
1214
|
+
* ```html
|
|
1215
|
+
* <mat-checkbox ngForgeControl="input[type='checkbox']" [formField]="ngf.field()">
|
|
1216
|
+
* {{ ngf.label() }}
|
|
1217
|
+
* </mat-checkbox>
|
|
1218
|
+
* ```
|
|
1219
|
+
*
|
|
1220
|
+
* @example Dynamic option list (radios rendered in @for)
|
|
1221
|
+
* ```html
|
|
1222
|
+
* @for (option of options(); track option.value) {
|
|
1223
|
+
* <input type="radio" ngForgeControl [value]="option.value" />
|
|
1224
|
+
* }
|
|
1225
|
+
* ```
|
|
1226
|
+
*
|
|
1227
|
+
* Each `@for` iteration creates its own directive instance; Angular's
|
|
1228
|
+
* structural lifecycle handles add/remove naturally.
|
|
1229
|
+
*/
|
|
1230
|
+
declare class NgForgeControl {
|
|
1231
|
+
readonly target: i0.InputSignal<string | undefined>;
|
|
1232
|
+
constructor();
|
|
1233
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeControl, never>;
|
|
1234
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgForgeControl, "[ngForgeControl]", never, { "target": { "alias": "ngForgeControl"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Selectorless companion directive for shadow-DOM-encapsulated components
|
|
1238
|
+
* (PrimeNG `p-select`, Ionic web components, etc.) where no light-DOM child
|
|
1239
|
+
* is the canonical control. Added to the component's `hostDirectives` so the
|
|
1240
|
+
* field's `meta` + parent aria land on the component's own host element.
|
|
1241
|
+
*
|
|
1242
|
+
* For split parent/control components (e.g. `df-prime-select` rendering
|
|
1243
|
+
* `df-prime-select-control` internally), place `NgForgeHostControl` on the
|
|
1244
|
+
* INNER control component's `hostDirectives` — the inner element is the
|
|
1245
|
+
* canonical control, and the marker's `inject(NgForgeField)` walks up the
|
|
1246
|
+
* element-injector tree to find the parent's directive instance.
|
|
1247
|
+
*
|
|
1248
|
+
* @example
|
|
1249
|
+
* ```ts
|
|
1250
|
+
* \@Component({
|
|
1251
|
+
* hostDirectives: [
|
|
1252
|
+
* { directive: NgForgeField, inputs: [...NG_FORGE_FIELD_INPUTS] },
|
|
1253
|
+
* NgForgeHostControl,
|
|
1254
|
+
* ],
|
|
1255
|
+
* template: `...`,
|
|
1256
|
+
* })
|
|
1257
|
+
* export class IonicInputField { ... }
|
|
1258
|
+
* ```
|
|
1259
|
+
*/
|
|
1260
|
+
declare class NgForgeHostControl {
|
|
1261
|
+
constructor();
|
|
1262
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeHostControl, never>;
|
|
1263
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<NgForgeHostControl, never, never, {}, {}, never, never, true, never>;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/**
|
|
1267
|
+
* Value-bearing field host wrapper. Composes `NgForgeFieldShell` (universal
|
|
1268
|
+
* identity) with `NgForgeField` (value + validation + aria + meta-tracking)
|
|
1269
|
+
* in a single host-directive entry, so consumer components compose just one
|
|
1270
|
+
* directive instead of two.
|
|
1271
|
+
*
|
|
1272
|
+
* Why a directive instead of a `const` preset: cross-package partial
|
|
1273
|
+
* compilation can't resolve a const reference inside `hostDirectives:`, so
|
|
1274
|
+
* an exported const array doesn't work for library consumers. A wrapper
|
|
1275
|
+
* directive's own `hostDirectives` IS a literal at compile time (in this
|
|
1276
|
+
* file), so it works everywhere.
|
|
1277
|
+
*
|
|
1278
|
+
* Authoring shape for adapter components:
|
|
1279
|
+
* ```ts
|
|
1280
|
+
* \@Component({
|
|
1281
|
+
* hostDirectives: [NgForgeFieldHost],
|
|
1282
|
+
* ...
|
|
1283
|
+
* })
|
|
1284
|
+
* export class MyInputField {
|
|
1285
|
+
* protected readonly ngf = injectNgForgeField<string>();
|
|
1286
|
+
* }
|
|
1287
|
+
* ```
|
|
1288
|
+
*
|
|
1289
|
+
* Pattern reference: Taiga UI uses the same wrapper-directive technique
|
|
1290
|
+
* for the same reason. See https://www.angularspace.com/host-directives-decomposition-unleashed/
|
|
1291
|
+
*/
|
|
1292
|
+
declare class NgForgeFieldHost {
|
|
1293
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeFieldHost, never>;
|
|
1294
|
+
static ɵdir: i0.ɵɵ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: {}; }]>;
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Action / button host wrapper. Composes `NgForgeFieldShell` with
|
|
1298
|
+
* `NgForgeAction` (event dispatch + aria-disabled) for button-shaped
|
|
1299
|
+
* components.
|
|
1300
|
+
*
|
|
1301
|
+
* Authoring shape:
|
|
1302
|
+
* ```ts
|
|
1303
|
+
* \@Component({
|
|
1304
|
+
* hostDirectives: [NgForgeActionHost],
|
|
1305
|
+
* ...
|
|
1306
|
+
* })
|
|
1307
|
+
* export class MyButton {
|
|
1308
|
+
* protected readonly action = injectNgForgeAction();
|
|
1309
|
+
* }
|
|
1310
|
+
* ```
|
|
1311
|
+
*/
|
|
1312
|
+
declare class NgForgeActionHost {
|
|
1313
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgForgeActionHost, never>;
|
|
1314
|
+
static ɵdir: i0.ɵɵ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: {}; }]>;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
interface CreateNgForgeFieldFixtureOptions<TValue = unknown> {
|
|
1318
|
+
/** Field key. Becomes the only property on the wrapping form. */
|
|
1319
|
+
readonly key: string;
|
|
1320
|
+
/** Initial value for the field. */
|
|
1321
|
+
readonly value?: TValue;
|
|
1322
|
+
/** Optional schema callback that receives the field's `SchemaPath`. Use it to attach validators (`required`, `minLength`, etc.). */
|
|
1323
|
+
readonly schema?: (fieldPath: SchemaPath<TValue>) => void;
|
|
1324
|
+
/** Mark the field as touched after creation (useful for invalid-state assertions). */
|
|
1325
|
+
readonly touched?: boolean;
|
|
1326
|
+
/** Extra inputs to set on the component before `detectChanges()`. */
|
|
1327
|
+
readonly inputs?: Record<string, unknown>;
|
|
1328
|
+
/** Extra TestBed providers. */
|
|
1329
|
+
readonly providers?: readonly Provider[];
|
|
1330
|
+
}
|
|
1331
|
+
interface NgForgeFieldFixture<C, TValue = unknown> {
|
|
1332
|
+
readonly fixture: ComponentFixture<C>;
|
|
1333
|
+
readonly field: FieldTree<TValue>;
|
|
1334
|
+
readonly rootValue: WritableSignal<Record<string, TValue>>;
|
|
1335
|
+
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Builds a `ComponentFixture` for an `NgForgeField`-composing component with
|
|
1338
|
+
* `field` + `key` bound BEFORE `detectChanges()` — sidesteps the NG0950 that
|
|
1339
|
+
* Shell's required `key` and Field's required `field` would otherwise throw.
|
|
1340
|
+
*
|
|
1341
|
+
* The caller drives `detectChanges()` themselves (so they can `setInput`
|
|
1342
|
+
* additional component-specific props in between).
|
|
1343
|
+
*/
|
|
1344
|
+
declare function createNgForgeFieldFixture<C, TValue = unknown>(component: Type<C>, options: CreateNgForgeFieldFixtureOptions<TValue>): NgForgeFieldFixture<C, TValue>;
|
|
1345
|
+
interface CreateNgForgeActionFixtureOptions<TEvent extends FormEvent = FormEvent> {
|
|
1346
|
+
readonly key: string;
|
|
1347
|
+
readonly label: DynamicText;
|
|
1348
|
+
readonly event?: FormEventConstructor<TEvent>;
|
|
1349
|
+
readonly eventArgs?: EventArgs;
|
|
1350
|
+
readonly disabled?: boolean;
|
|
1351
|
+
readonly hidden?: boolean;
|
|
1352
|
+
readonly inputs?: Record<string, unknown>;
|
|
1353
|
+
readonly providers?: readonly Provider[];
|
|
1354
|
+
}
|
|
1355
|
+
interface NgForgeActionFixture<C> {
|
|
1356
|
+
readonly fixture: ComponentFixture<C>;
|
|
1357
|
+
readonly eventBus: EventBus;
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Builds a `ComponentFixture` for an `NgForgeAction`-composing component with
|
|
1361
|
+
* `key` + `label` bound and `EventBus` provided. The caller calls
|
|
1362
|
+
* `detectChanges()`; the harness handles the NG0950-avoidance bindings.
|
|
1363
|
+
*/
|
|
1364
|
+
declare function createNgForgeActionFixture<C, TEvent extends FormEvent = FormEvent>(component: Type<C>, options: CreateNgForgeActionFixtureOptions<TEvent>): NgForgeActionFixture<C>;
|
|
1365
|
+
/** Provider for `DEFAULT_VALIDATION_MESSAGES` in field tests — supply the default-messages map and the directive resolves it from DI. */
|
|
1366
|
+
declare function provideTestValidationMessages(messages: ValidationMessages): Provider;
|
|
1367
|
+
|
|
1368
|
+
export { ADDON_PRESET_HANDLER, NG_FORGE_ACTION_INPUTS, NG_FORGE_ADDONS_INPUTS, NG_FORGE_ADDON_ACTION_INPUTS, NG_FORGE_FIELD_SHELL_INPUTS, NG_FORGE_VALUE_FIELD_INPUTS, NgForgeAction, NgForgeActionHost, NgForgeAddonAction, NgForgeAddonActionBase, NgForgeAddons, NgForgeAddonsBase, NgForgeControl, NgForgeField, NgForgeFieldHost, NgForgeFieldShell, NgForgeHostControl, addArrayItemButtonMapper, buildArrayButtonEventContext, buildValueFieldInputs, buttonFieldMapper, checkboxFieldMapper, createAriaDescribedBySignal, createNgForgeActionFixture, createNgForgeFieldFixture, createResolvedErrorsSignal, datepickerFieldMapper, injectNgForgeAction, injectNgForgeAddonAction, injectNgForgeAddons, injectNgForgeField, insertArrayItemButtonMapper, nextButtonFieldMapper, optionsFieldMapper, popArrayItemButtonMapper, prependArrayItemButtonMapper, previousButtonFieldMapper, provideTestValidationMessages, removeArrayItemButtonMapper, resolveArrayButtonContext, resolveArrayButtonEventArgs, resolveValueFieldContext, setupMetaTracking, shiftArrayItemButtonMapper, shouldShowErrors, submitButtonFieldMapper, valueFieldMapper };
|
|
1369
|
+
export type { AddonPresetHandler, 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, TypedNgForgeAddonAction, TypedNgForgeAddons, TypedNgForgeField, ValueFieldContext };
|