ng-form-foundry 0.4.1 → 0.5.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/fesm2022/ng-form-foundry.mjs +272 -17
- package/fesm2022/ng-form-foundry.mjs.map +1 -1
- package/index.d.ts +122 -9
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FormControl, FormArray, FormGroup } from '@angular/forms';
|
|
1
|
+
import { FormControl, FormArray, FormGroup, ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
|
|
2
2
|
import * as _angular_core from '@angular/core';
|
|
3
|
-
import { OnInit, OnDestroy, AfterViewInit, ElementRef, EventEmitter, QueryList, ChangeDetectorRef,
|
|
3
|
+
import { OnInit, OnDestroy, AfterViewInit, ElementRef, EventEmitter, OnChanges, QueryList, ChangeDetectorRef, SimpleChanges } from '@angular/core';
|
|
4
4
|
import { MatDialog } from '@angular/material/dialog';
|
|
5
5
|
|
|
6
6
|
type LeafRuntimeType<T> = T extends 'string' ? string : T extends 'number' ? number : T extends 'boolean' ? boolean : T extends 'enum' ? string | number : never;
|
|
@@ -51,6 +51,13 @@ type LeafString = LeafBase & {
|
|
|
51
51
|
maxLength?: number;
|
|
52
52
|
/** Semantic string format (JSON Schema `format`); adds a matching validator. */
|
|
53
53
|
format?: 'email' | 'uri' | 'url';
|
|
54
|
+
/**
|
|
55
|
+
* Present the value in this base — for the string leaves that carry an
|
|
56
|
+
* integer beyond ±2^53 as its exact decimal digits. The control value stays
|
|
57
|
+
* that decimal-digit string (`pattern` keeps validating it); only the
|
|
58
|
+
* rendered text is based. See {@link LeafNumber.radix}.
|
|
59
|
+
*/
|
|
60
|
+
radix?: 2 | 8 | 16;
|
|
54
61
|
};
|
|
55
62
|
type LeafNumber = LeafBase & {
|
|
56
63
|
type: 'number';
|
|
@@ -63,6 +70,14 @@ type LeafNumber = LeafBase & {
|
|
|
63
70
|
max?: number;
|
|
64
71
|
/** Require the value to be an integer multiple of this number (JSON Schema `multipleOf`). */
|
|
65
72
|
multipleOf?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Present the value in this base (16 hex, 8 octal, 2 binary) instead of
|
|
75
|
+
* decimal — a display hint set by transformers when the source document
|
|
76
|
+
* wrote the literal that way (`0x1A`, `0o17`, `0b101`). The control value
|
|
77
|
+
* stays a plain number, so every numeric validator applies unchanged; only
|
|
78
|
+
* the rendered text is based. See `RadixInputDirective`.
|
|
79
|
+
*/
|
|
80
|
+
radix?: 2 | 8 | 16;
|
|
66
81
|
};
|
|
67
82
|
type LeafBoolean = LeafBase & {
|
|
68
83
|
type: 'boolean';
|
|
@@ -135,6 +150,8 @@ type LeafList<TKind extends Leaf['type'] = Leaf['type']> = {
|
|
|
135
150
|
type: TKind;
|
|
136
151
|
minItems?: number;
|
|
137
152
|
maxItems?: number;
|
|
153
|
+
/** Present every item in this base — see {@link LeafNumber.radix}. */
|
|
154
|
+
radix?: 2 | 8 | 16;
|
|
138
155
|
};
|
|
139
156
|
type NodeGroupList = {
|
|
140
157
|
kind: 'nodeGroupList';
|
|
@@ -409,6 +426,17 @@ declare class DynamicRecursiveFormComponent implements OnInit {
|
|
|
409
426
|
readonly title: _angular_core.InputSignal<string | undefined>;
|
|
410
427
|
/** Whether fields accept input. Two-way: also toggled by the built-in edit control. */
|
|
411
428
|
readonly editable: _angular_core.ModelSignal<boolean>;
|
|
429
|
+
/**
|
|
430
|
+
* Preview absent optional (presence) leaves as **ghost fields**: the field
|
|
431
|
+
* renders read-only and empty — its schema `default`, if any, shown as the
|
|
432
|
+
* placeholder — with a (+) button that incorporates it into the form, so the
|
|
433
|
+
* user sees the complete form surface. A ghost holds **no control in the
|
|
434
|
+
* form**: it never appears in `value`/`getRawValue()`/`serializeForm` output
|
|
435
|
+
* and never affects validity until incorporated. Replaces the default
|
|
436
|
+
* "Add <field>" button affordance; ignored while the form is not editable
|
|
437
|
+
* (read-only mode hides structural affordances, ghosts included).
|
|
438
|
+
*/
|
|
439
|
+
readonly showAbsentOptionals: _angular_core.InputSignal<boolean>;
|
|
412
440
|
/** Invoked with {@link index} to append a new sibling form to a parent list. */
|
|
413
441
|
readonly addButtonCallback: _angular_core.InputSignal<((index: number) => void) | null>;
|
|
414
442
|
/**
|
|
@@ -493,6 +521,22 @@ declare class DynamicRecursiveFormComponent implements OnInit {
|
|
|
493
521
|
* children start absent).
|
|
494
522
|
*/
|
|
495
523
|
toggleNodePresence(key: string, schema: NodeType, present: boolean): void;
|
|
524
|
+
/**
|
|
525
|
+
* The detached stand-in control a ghost field renders against. Never added
|
|
526
|
+
* to {@link formGroup} — that detachment is the whole guarantee: a ghost
|
|
527
|
+
* cannot reach `value`, `getRawValue()`, or validity. Always `null`-valued
|
|
528
|
+
* (the schema default shows as a placeholder instead, see
|
|
529
|
+
* {@link ghostPlaceholder}); cached per key so change detection re-reads a
|
|
530
|
+
* stable instance.
|
|
531
|
+
*/
|
|
532
|
+
protected ghostControl(key: string): FormControl;
|
|
533
|
+
private readonly ghostControls;
|
|
534
|
+
/**
|
|
535
|
+
* A ghost field's placeholder: the leaf's `default`, or empty — spelled in
|
|
536
|
+
* the leaf's `radix` when it has one, matching how the incorporated field
|
|
537
|
+
* will display it.
|
|
538
|
+
*/
|
|
539
|
+
protected ghostPlaceholder(schema: Leaf): string;
|
|
496
540
|
/**
|
|
497
541
|
* {@link toggleNodePresence} for a presence leaf, additionally focusing the
|
|
498
542
|
* rendered field when the toggle just created it.
|
|
@@ -525,7 +569,7 @@ declare class DynamicRecursiveFormComponent implements OnInit {
|
|
|
525
569
|
protected readonly asFormArray: typeof asFormArray;
|
|
526
570
|
protected readonly asFormControl: typeof asFormControl;
|
|
527
571
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DynamicRecursiveFormComponent, never>;
|
|
528
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DynamicRecursiveFormComponent, "nff-dynamic-recursive-form", never, { "schema": { "alias": "schema"; "required": true; "isSignal": true; }; "initialValue": { "alias": "initialValue"; "required": false; "isSignal": true; }; "formGroup": { "alias": "formGroup"; "required": false; "isSignal": true; }; "index": { "alias": "index"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "addButtonCallback": { "alias": "addButtonCallback"; "required": false; "isSignal": true; }; "focusLeaf": { "alias": "focusLeaf"; "required": false; "isSignal": true; }; "inheritedAppearance": { "alias": "inheritedAppearance"; "required": false; "isSignal": true; }; }, { "remove": "remove"; "editable": "editableChange"; }, never, never, true, never>;
|
|
572
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DynamicRecursiveFormComponent, "nff-dynamic-recursive-form", never, { "schema": { "alias": "schema"; "required": true; "isSignal": true; }; "initialValue": { "alias": "initialValue"; "required": false; "isSignal": true; }; "formGroup": { "alias": "formGroup"; "required": false; "isSignal": true; }; "index": { "alias": "index"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "showAbsentOptionals": { "alias": "showAbsentOptionals"; "required": false; "isSignal": true; }; "addButtonCallback": { "alias": "addButtonCallback"; "required": false; "isSignal": true; }; "focusLeaf": { "alias": "focusLeaf"; "required": false; "isSignal": true; }; "inheritedAppearance": { "alias": "inheritedAppearance"; "required": false; "isSignal": true; }; }, { "remove": "remove"; "editable": "editableChange"; }, never, never, true, never>;
|
|
529
573
|
}
|
|
530
574
|
|
|
531
575
|
/** Metadata on a list-container node that lets the tree add items to its FormArray. */
|
|
@@ -849,6 +893,8 @@ declare class LeafRendererComponent implements AfterViewInit {
|
|
|
849
893
|
editable: boolean;
|
|
850
894
|
/** Focus the field once rendered — for fields the user just added (e.g. an enabled presence leaf). */
|
|
851
895
|
autofocus: boolean;
|
|
896
|
+
/** Placeholder for the empty field — e.g. a ghost preview showing the schema default. */
|
|
897
|
+
placeholder: string;
|
|
852
898
|
/** Emitted when the user removes this field (e.g. an optional presence leaf). */
|
|
853
899
|
readonly remove: _angular_core.OutputEmitterRef<void>;
|
|
854
900
|
constructor(elementRef: ElementRef<HTMLElement>);
|
|
@@ -862,7 +908,7 @@ declare class LeafRendererComponent implements AfterViewInit {
|
|
|
862
908
|
*/
|
|
863
909
|
get errorText(): string;
|
|
864
910
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<LeafRendererComponent, never>;
|
|
865
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LeafRendererComponent, "nff-leaf-renderer", never, { "leaf_": { "alias": "leaf_"; "required": false; }; "control": { "alias": "control"; "required": false; }; "removable": { "alias": "removable"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "autofocus": { "alias": "autofocus"; "required": false; }; }, { "remove": "remove"; }, never, never, true, never>;
|
|
911
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LeafRendererComponent, "nff-leaf-renderer", never, { "leaf_": { "alias": "leaf_"; "required": false; }; "control": { "alias": "control"; "required": false; }; "removable": { "alias": "removable"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "autofocus": { "alias": "autofocus"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; }, { "remove": "remove"; }, never, never, true, never>;
|
|
866
912
|
}
|
|
867
913
|
|
|
868
914
|
declare class LeafListRendererComponent implements OnInit {
|
|
@@ -905,8 +951,71 @@ declare class LeafEnumRendererComponent {
|
|
|
905
951
|
removable: boolean;
|
|
906
952
|
remove: any;
|
|
907
953
|
editable: boolean;
|
|
954
|
+
/** Placeholder for the empty select — e.g. a ghost preview showing the schema default. */
|
|
955
|
+
placeholder: string;
|
|
908
956
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<LeafEnumRendererComponent, never>;
|
|
909
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LeafEnumRendererComponent, "nff-leaf-enum-renderer", never, { "leafEnum": { "alias": "leafEnum"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "control": { "alias": "control"; "required": false; }; "removable": { "alias": "removable"; "required": false; }; "remove": { "alias": "remove"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; }, {}, never, never, true, never>;
|
|
957
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LeafEnumRendererComponent, "nff-leaf-enum-renderer", never, { "leafEnum": { "alias": "leafEnum"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "control": { "alias": "control"; "required": false; }; "removable": { "alias": "removable"; "required": false; }; "remove": { "alias": "remove"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; }, {}, never, never, true, never>;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
type Radix = 2 | 8 | 16;
|
|
961
|
+
/**
|
|
962
|
+
* An integer as a prefixed literal in the given base: `0x1A`, `0o17`, `0b101`,
|
|
963
|
+
* hex digits uppercase, a leading `-` for negatives. Accepts a number or a
|
|
964
|
+
* decimal-digit string (the beyond-safe-range carry).
|
|
965
|
+
*/
|
|
966
|
+
declare function formatRadix(value: number | string, radix: Radix): string;
|
|
967
|
+
/**
|
|
968
|
+
* Presents an integer control in hex/octal/binary while the control value
|
|
969
|
+
* stays what the schema and validators expect: a plain `number`, or — with
|
|
970
|
+
* `nffRadixValueType="string"` — the exact decimal-digit string that carries
|
|
971
|
+
* integers beyond the safe range (±(2^53 − 1)). Only the visible text is
|
|
972
|
+
* based (`0x1A`, `0o17`, `0b101`); `min`/`max`/`integer`/`pattern` validators
|
|
973
|
+
* therefore apply unchanged.
|
|
974
|
+
*
|
|
975
|
+
* Typing accepts the base's digits with or without prefix, case-insensitive
|
|
976
|
+
* (`0q` is also accepted for octal, as in libconfig); the text normalizes to
|
|
977
|
+
* the prefixed spelling on blur. Unparseable text sets the control to `null`
|
|
978
|
+
* with a `radixFormat` error — never the raw text, so an invalid entry can
|
|
979
|
+
* reach neither the wire value nor a typed write-back; the text itself stays
|
|
980
|
+
* in the input for the user to correct. In number mode a magnitude beyond the
|
|
981
|
+
* safe range likewise yields `null` with `radixRange` instead of a silently
|
|
982
|
+
* rounded number.
|
|
983
|
+
*/
|
|
984
|
+
declare class RadixInputDirective implements ControlValueAccessor, Validator, OnChanges {
|
|
985
|
+
protected readonly el: ElementRef<HTMLInputElement>;
|
|
986
|
+
/** The display base. */
|
|
987
|
+
radix: Radix;
|
|
988
|
+
/**
|
|
989
|
+
* What the control carries: `'number'` (default), or `'string'` for the
|
|
990
|
+
* decimal-digit bigint carry of a string leaf.
|
|
991
|
+
*/
|
|
992
|
+
valueType: 'number' | 'string';
|
|
993
|
+
private modelValue;
|
|
994
|
+
private parseError;
|
|
995
|
+
private onChange;
|
|
996
|
+
private onTouched;
|
|
997
|
+
private onValidatorChange;
|
|
998
|
+
constructor(el: ElementRef<HTMLInputElement>);
|
|
999
|
+
/** A changed base (or carry mode) re-renders the model and re-validates. */
|
|
1000
|
+
ngOnChanges(): void;
|
|
1001
|
+
writeValue(value: unknown): void;
|
|
1002
|
+
registerOnChange(fn: (value: unknown) => void): void;
|
|
1003
|
+
registerOnTouched(fn: () => void): void;
|
|
1004
|
+
registerOnValidatorChange(fn: () => void): void;
|
|
1005
|
+
setDisabledState(isDisabled: boolean): void;
|
|
1006
|
+
validate(_control: AbstractControl): ValidationErrors | null;
|
|
1007
|
+
protected onInput(text: string): void;
|
|
1008
|
+
protected onBlur(): void;
|
|
1009
|
+
/** Show the model in its base; unrepresentable models pass through as text. */
|
|
1010
|
+
private render;
|
|
1011
|
+
/**
|
|
1012
|
+
* `[-+]?` + this base's optional prefix + this base's digits, or null. The
|
|
1013
|
+
* prefix is base-specific so hex digit runs that merely *look* like another
|
|
1014
|
+
* base's prefix (`0b11` as hex 0x0B11) parse as digits, not as a rejection.
|
|
1015
|
+
*/
|
|
1016
|
+
private parse;
|
|
1017
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RadixInputDirective, never>;
|
|
1018
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RadixInputDirective, "input[nffRadixInput]", never, { "radix": { "alias": "nffRadixInput"; "required": true; }; "valueType": { "alias": "nffRadixValueType"; "required": false; }; }, {}, never, never, true, never>;
|
|
910
1019
|
}
|
|
911
1020
|
|
|
912
1021
|
declare class NodeGroupListRendererComponent implements OnInit, AfterViewInit {
|
|
@@ -914,6 +1023,8 @@ declare class NodeGroupListRendererComponent implements OnInit, AfterViewInit {
|
|
|
914
1023
|
initialValue: number[] | string[] | boolean[];
|
|
915
1024
|
formArray: FormArray<any>;
|
|
916
1025
|
editable: boolean;
|
|
1026
|
+
/** Forwarded to each entry's embedded form — see the form's input of the same name. */
|
|
1027
|
+
showAbsentOptionals: boolean;
|
|
917
1028
|
minItems: number;
|
|
918
1029
|
maxItems: number;
|
|
919
1030
|
/** Field-layout appearance from the enclosing group, forwarded to every item form. */
|
|
@@ -929,7 +1040,7 @@ declare class NodeGroupListRendererComponent implements OnInit, AfterViewInit {
|
|
|
929
1040
|
asFormGroup(group: any): FormGroup;
|
|
930
1041
|
getTitle($index: number): string;
|
|
931
1042
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NodeGroupListRendererComponent, never>;
|
|
932
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NodeGroupListRendererComponent, "nff-node-group-list-renderer", never, { "nodeGroupList": { "alias": "nodeGroupList"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "formArray": { "alias": "formArray"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "minItems": { "alias": "minItems"; "required": false; }; "maxItems": { "alias": "maxItems"; "required": false; }; "inheritedAppearance": { "alias": "inheritedAppearance"; "required": false; }; }, { "message": "message"; }, never, never, true, never>;
|
|
1043
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NodeGroupListRendererComponent, "nff-node-group-list-renderer", never, { "nodeGroupList": { "alias": "nodeGroupList"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "formArray": { "alias": "formArray"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "showAbsentOptionals": { "alias": "showAbsentOptionals"; "required": false; }; "minItems": { "alias": "minItems"; "required": false; }; "maxItems": { "alias": "maxItems"; "required": false; }; "inheritedAppearance": { "alias": "inheritedAppearance"; "required": false; }; }, { "message": "message"; }, never, never, true, never>;
|
|
933
1044
|
}
|
|
934
1045
|
|
|
935
1046
|
/**
|
|
@@ -943,6 +1054,8 @@ declare class NodeMapRendererComponent implements OnChanges {
|
|
|
943
1054
|
nodeMap: NodeMap;
|
|
944
1055
|
formGroup: FormGroup<any>;
|
|
945
1056
|
editable: boolean;
|
|
1057
|
+
/** Forwarded to each entry's embedded form — see the form's input of the same name. */
|
|
1058
|
+
showAbsentOptionals: boolean;
|
|
946
1059
|
/** Field-layout appearance from the enclosing group, forwarded to group-valued entry forms. */
|
|
947
1060
|
inheritedAppearance: Appearance | null;
|
|
948
1061
|
/** Ordered view of entry keys, kept stable across renames (`addControl` appends). */
|
|
@@ -973,8 +1086,8 @@ declare class NodeMapRendererComponent implements OnChanges {
|
|
|
973
1086
|
protected readonly asFormControl: typeof asFormControl;
|
|
974
1087
|
protected readonly asFormGroup: typeof asFormGroup;
|
|
975
1088
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NodeMapRendererComponent, never>;
|
|
976
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NodeMapRendererComponent, "nff-node-map-renderer", never, { "nodeMap": { "alias": "nodeMap"; "required": false; }; "formGroup": { "alias": "formGroup"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "inheritedAppearance": { "alias": "inheritedAppearance"; "required": false; }; }, {}, never, never, true, never>;
|
|
1089
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NodeMapRendererComponent, "nff-node-map-renderer", never, { "nodeMap": { "alias": "nodeMap"; "required": false; }; "formGroup": { "alias": "formGroup"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "showAbsentOptionals": { "alias": "showAbsentOptionals"; "required": false; }; "inheritedAppearance": { "alias": "inheritedAppearance"; "required": false; }; }, {}, never, never, true, never>;
|
|
977
1090
|
}
|
|
978
1091
|
|
|
979
|
-
export { CASE_KEY, ConfigEditorComponent, DynamicRecursiveFormComponent, LeafEnumRendererComponent, LeafListRendererComponent, LeafRendererComponent, NodeGroupListRendererComponent, NodeMapRendererComponent, addMapEntry, buildControl, buildFormFromSchema, caseDisplayLabels, caseFields, defineSchema, removeMapEntry, renameMapEntry, resolveChoiceCase, serializeForm, switchChoiceCase, toWireValue };
|
|
980
|
-
export type { AnonLeaf, Appearance, ChoiceCase, DFormControl, DFormGroup, FormGroupType, Leaf, LeafBase, LeafBoolean, LeafEnum, LeafList, LeafNumber, LeafRuntimeType, LeafString, NodeChoice, NodeGroup, NodeGroupList, NodeMap, NodeType };
|
|
1092
|
+
export { CASE_KEY, ConfigEditorComponent, DynamicRecursiveFormComponent, LeafEnumRendererComponent, LeafListRendererComponent, LeafRendererComponent, NodeGroupListRendererComponent, NodeMapRendererComponent, RadixInputDirective, addMapEntry, buildControl, buildFormFromSchema, caseDisplayLabels, caseFields, defineSchema, formatRadix, removeMapEntry, renameMapEntry, resolveChoiceCase, serializeForm, switchChoiceCase, toWireValue };
|
|
1093
|
+
export type { AnonLeaf, Appearance, ChoiceCase, DFormControl, DFormGroup, FormGroupType, Leaf, LeafBase, LeafBoolean, LeafEnum, LeafList, LeafNumber, LeafRuntimeType, LeafString, NodeChoice, NodeGroup, NodeGroupList, NodeMap, NodeType, Radix };
|
package/package.json
CHANGED