ng-form-foundry 0.5.4 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -327,6 +327,24 @@ declare function addMapEntry(group: FormGroup, map: NodeMap, key?: string): stri
327
327
  declare function renameMapEntry(group: FormGroup, map: NodeMap, oldKey: string, newKey: string): boolean;
328
328
  /** Remove entry `key` unless the map is at `minEntries`. Returns whether it was removed. */
329
329
  declare function removeMapEntry(group: FormGroup, map: NodeMap, key: string): boolean;
330
+ /**
331
+ * Materialize or de-materialize an optional (presence) child of `group`,
332
+ * mirroring the presence toggle the form UI offers — but callable by any host
333
+ * holding the {@link FormGroup}, for a key at any depth. `present: true` builds
334
+ * the child fresh from `schema` (seeded with `initial` if given; nested
335
+ * presence descendants start absent, as {@link buildControl}); `present: false`
336
+ * removes it, dropping the key from the form value.
337
+ *
338
+ * The materialize direction is why the coupling exists: a materialized
339
+ * non-nullable presence leaf carries `Validators.required`, because an
340
+ * enabled-but-empty key would serialize as `null` and fail a typed schema. A
341
+ * host that materializes fields for editing therefore drops the ones left
342
+ * empty on cancel by de-materializing them — this API is that primitive.
343
+ *
344
+ * `schema` must be the presence node for `key`; a non-presence `schema` is a
345
+ * no-op. Returns whether the form changed.
346
+ */
347
+ declare function setNodePresence(group: FormGroup, schema: NodeType, key: string, present: boolean, initial?: unknown): boolean;
330
348
  /**
331
349
  * Build the `AbstractControl` for a single schema node.
332
350
  *
@@ -525,7 +543,8 @@ declare class DynamicRecursiveFormComponent implements OnInit {
525
543
  * Add or remove a presence node's control on this form — any presence kind:
526
544
  * group, leaf, map, or choice. Removing it drops the key from `form.value`;
527
545
  * adding it builds the control fresh from its schema (nested presence
528
- * children start absent).
546
+ * children start absent). Delegates to {@link setNodePresence}, the
547
+ * host-callable primitive.
529
548
  */
530
549
  toggleNodePresence(key: string, schema: NodeType, present: boolean): void;
531
550
  /**
@@ -638,6 +657,7 @@ interface TreeNode {
638
657
  /** Present on a present optional child node: drives the row's remove control. */
639
658
  presenceRemovable?: {
640
659
  key: string;
660
+ schema: NodeType;
641
661
  };
642
662
  /** Field-layout appearance inherited from ancestor groups, for the node's detail-section form. */
643
663
  inherited?: Appearance | null;
@@ -724,6 +744,7 @@ declare class ConfigEditorComponent implements OnDestroy {
724
744
  private shape;
725
745
  private changes?;
726
746
  private readonly host;
747
+ private readonly cdr;
727
748
  /** Stable per-instance ids for the shape signature, so replacing a control (setControl) reads as a structural change. */
728
749
  private readonly controlIds;
729
750
  private controlIdSeq;
@@ -731,6 +752,15 @@ declare class ConfigEditorComponent implements OnDestroy {
731
752
  ngOnDestroy(): void;
732
753
  /** Bind the editor to a schema/form pair: fresh tree, root selection, and shape-sync subscription. */
733
754
  private attach;
755
+ /**
756
+ * Force the editor to re-read the bound form. Call this when the form was
757
+ * mutated in a way the editor's own `valueChanges` subscription could not
758
+ * observe — a structural change made with `{ emitEvent: false }`, or a
759
+ * mutation while a detached change detector left the view unchecked. It
760
+ * re-syncs the tree structure, rebuilds the current selection's sections
761
+ * from the live controls, and renders them.
762
+ */
763
+ refresh(): void;
734
764
  select(node: TreeNode, reveal?: boolean): void;
735
765
  /**
736
766
  * Root-to-`target` path for the detail-pane breadcrumb (inclusive of both ends),
@@ -940,6 +970,7 @@ declare class LeafListRendererComponent implements OnInit {
940
970
  formArray: any;
941
971
  editable: boolean;
942
972
  minItems: number;
973
+ maxItems: number;
943
974
  /**
944
975
  * The parent group's grid layout (its `fieldsLayout` styles). A stacked list
945
976
  * spans the parent's full row, so its entries repeat the same tracks and
@@ -961,10 +992,14 @@ declare class LeafListRendererComponent implements OnInit {
961
992
  /** Applies {@link layout} to the host (the entries' container) while stacked. */
962
993
  get hostLayout(): LayoutStyles | null;
963
994
  ngOnInit(): void;
995
+ get effectiveMin(): number;
996
+ get effectiveMax(): number;
997
+ /** Whether another item may be appended (below the effective maximum). */
998
+ get canAdd(): boolean;
964
999
  removeItem($index: number): void;
965
1000
  addItem(): void;
966
1001
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<LeafListRendererComponent, never>;
967
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<LeafListRendererComponent, "nff-leaf-list-renderer", never, { "leaf_": { "alias": "leaf_"; "required": false; }; "initialValue": { "alias": "initialValue"; "required": false; }; "formArray": { "alias": "formArray"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "minItems": { "alias": "minItems"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; }, { "message": "message"; }, never, never, true, never>;
1002
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<LeafListRendererComponent, "nff-leaf-list-renderer", never, { "leaf_": { "alias": "leaf_"; "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; }; "layout": { "alias": "layout"; "required": false; }; }, { "message": "message"; }, never, never, true, never>;
968
1003
  }
969
1004
 
970
1005
  declare class LeafEnumRendererComponent {
@@ -1056,9 +1091,13 @@ declare class NodeGroupListRendererComponent implements OnInit, AfterViewInit {
1056
1091
  items: QueryList<DynamicRecursiveFormComponent>;
1057
1092
  cdr: ChangeDetectorRef;
1058
1093
  ngOnInit(): void;
1094
+ get effectiveMin(): number;
1095
+ get effectiveMax(): number;
1096
+ /** Whether another item may be appended (below the effective maximum). */
1097
+ get canAdd(): boolean;
1059
1098
  ngAfterViewInit(): void;
1060
1099
  removeItem($index: number): void;
1061
- addItem: (index: number) => void;
1100
+ addItem: (index?: number) => void;
1062
1101
  setLastEditable(): void;
1063
1102
  asFormGroup(group: any): FormGroup;
1064
1103
  getTitle($index: number): string;
@@ -1094,6 +1133,10 @@ declare class NodeMapRendererComponent implements OnChanges {
1094
1133
  get valueLeaf(): Leaf;
1095
1134
  /** The value schema as a group (used when `value.kind === 'nodeGroup'`). */
1096
1135
  get valueGroup(): NodeGroup;
1136
+ /** Narrowing casts for the complex value kinds the template renders. */
1137
+ protected asLeafList(v: unknown): LeafList;
1138
+ protected asNodeGroupList(v: unknown): NodeGroupList;
1139
+ protected asNodeMap(v: unknown): NodeMap;
1097
1140
  get atMax(): boolean;
1098
1141
  get atMin(): boolean;
1099
1142
  /** Append a new entry under a unique placeholder key. Delegates to {@link addMapEntry}. */
@@ -1108,9 +1151,10 @@ declare class NodeMapRendererComponent implements OnChanges {
1108
1151
  renameEntry(oldKey: string, rawKey: string): void;
1109
1152
  protected readonly asFormControl: typeof asFormControl;
1110
1153
  protected readonly asFormGroup: typeof asFormGroup;
1154
+ protected readonly asFormArray: typeof asFormArray;
1111
1155
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<NodeMapRendererComponent, never>;
1112
1156
  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>;
1113
1157
  }
1114
1158
 
1115
- export { CASE_KEY, ConfigEditorComponent, DynamicRecursiveFormComponent, LeafEnumRendererComponent, LeafListRendererComponent, LeafRendererComponent, NodeGroupListRendererComponent, NodeMapRendererComponent, RadixInputDirective, addMapEntry, buildControl, buildFormFromSchema, caseDisplayLabels, caseFields, defineSchema, formatRadix, removeMapEntry, renameMapEntry, resolveChoiceCase, serializeForm, switchChoiceCase, toWireValue };
1159
+ export { CASE_KEY, ConfigEditorComponent, DynamicRecursiveFormComponent, LeafEnumRendererComponent, LeafListRendererComponent, LeafRendererComponent, NodeGroupListRendererComponent, NodeMapRendererComponent, RadixInputDirective, addMapEntry, buildControl, buildFormFromSchema, caseDisplayLabels, caseFields, defineSchema, formatRadix, removeMapEntry, renameMapEntry, resolveChoiceCase, serializeForm, setNodePresence, switchChoiceCase, toWireValue };
1116
1160
  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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-form-foundry",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Build fully-typed Angular Reactive Forms and Angular Material UI from a declarative, recursive form-description schema.",
5
5
  "keywords": [
6
6
  "angular",