ng-form-foundry 0.6.1 → 0.7.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.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-form-foundry.mjs","sources":["../../../projects/ng-form-foundry/src/lib/types/dynamic-recursive.types.ts","../../../projects/ng-form-foundry/src/lib/core/dynamic-recursive-forms-builder.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-enum-renderer/leaf-enum-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-enum-renderer/leaf-enum-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/radix-input/radix-input.directive.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-renderer/leaf-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-renderer/leaf-renderer.component.html","../../../projects/ng-form-foundry/src/lib/core/appearance.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-group-list-renderer/node-group-list-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-group-list-renderer/node-group-list-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/anon-leaf-renderer/anon-leaf-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/anon-leaf-renderer/anon-leaf-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-list-renderer/leaf-list-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-list-renderer/leaf-list-renderer.component.html","../../../projects/ng-form-foundry/src/lib/core/utils.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-map-renderer/node-map-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-map-renderer/node-map-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/dynamic-recursive-form.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/dynamic-recursive-form.component.html","../../../projects/ng-form-foundry/src/lib/config-editor/config-editor.component.ts","../../../projects/ng-form-foundry/src/lib/config-editor/config-editor.component.html","../../../projects/ng-form-foundry/src/public-api.ts","../../../projects/ng-form-foundry/src/ng-form-foundry.ts"],"sourcesContent":["import { FormArray, FormControl, FormGroup } from '@angular/forms';\n\nexport type LeafRuntimeType<T> = T extends 'string'\n ? string\n : T extends 'number'\n ? number\n : T extends 'boolean'\n ? boolean\n : T extends 'enum'\n ? string | number\n : never;\n\nexport type LeafBase = {\n kind: 'leaf';\n name: string;\n required?: true | undefined;\n label?: string;\n description?: string;\n /**\n * The value may be `null` (JSON Schema `type: [T, 'null']`). Builds a nullable\n * control (drops `nonNullable`), so `null` is a first-class value the\n * constraint validators accept and that survives the round-trip. Distinct from\n * {@link presence}: `nullable` is an explicit `null`, `presence` is an absent key.\n */\n nullable?: boolean;\n /**\n * Optional scalar whose *presence itself* is data (mirrors {@link NodeGroup.presence}).\n * Rendered with an on/off toggle; the control is removed from the parent group\n * when absent (so it drops from `form.value`) and re-added when toggled on. The\n * builder omits it unless an initial value is supplied.\n */\n presence?: boolean;\n /**\n * Render the field read-only even when the surrounding form is editable.\n * Combine with `default` to express a JSON Schema `const` (a fixed,\n * display-only value); single-element `enum` is the alternative for a constant.\n */\n readOnly?: boolean;\n};\n\nexport type AnonLeaf = {\n [K in Leaf['type']]: { type: K };\n}[Leaf['type']];\n\nexport type LeafString = LeafBase & {\n type: 'string';\n default?: LeafRuntimeType<'string'>;\n /**\n * Reject values that don't match this regular expression. Follows JSON Schema\n * `pattern` semantics — an *unanchored* `RegExp.test`, so it matches anywhere\n * in the value unless the pattern itself anchors with `^`/`$`.\n */\n pattern?: string;\n /** Minimum string length (JSON Schema `minLength`). */\n minLength?: number;\n /** Maximum string length (JSON Schema `maxLength`). */\n maxLength?: number;\n /** Semantic string format (JSON Schema `format`); adds a matching validator. */\n format?: 'email' | 'uri' | 'url';\n /**\n * Present the value in this base — for the string leaves that carry an\n * integer beyond ±2^53 as its exact decimal digits. The control value stays\n * that decimal-digit string (`pattern` keeps validating it); only the\n * rendered text is based. See {@link LeafNumber.radix}.\n */\n radix?: 2 | 8 | 16;\n};\nexport type LeafNumber = LeafBase & {\n type: 'number';\n default?: LeafRuntimeType<'number'>;\n /** Require a whole-number value (JSON Schema `type: 'integer'`). */\n integer?: boolean;\n /** Inclusive lower bound (JSON Schema `minimum`). */\n min?: number;\n /** Inclusive upper bound (JSON Schema `maximum`). */\n max?: number;\n /** Require the value to be an integer multiple of this number (JSON Schema `multipleOf`). */\n multipleOf?: number;\n /**\n * Present the value in this base (16 hex, 8 octal, 2 binary) instead of\n * decimal — a display hint set by transformers when the source document\n * wrote the literal that way (`0x1A`, `0o17`, `0b101`). The control value\n * stays a plain number, so every numeric validator applies unchanged; only\n * the rendered text is based. See `RadixInputDirective`.\n */\n radix?: 2 | 8 | 16;\n};\nexport type LeafBoolean = LeafBase & {\n type: 'boolean';\n default?: LeafRuntimeType<'boolean'>;\n};\nexport type LeafEnum = LeafBase & {\n type: 'enum';\n default?: LeafRuntimeType<'enum'>;\n enumLabel?: string[];\n enum: LeafRuntimeType<'enum'>[];\n};\n\nexport type Appearance = {\n flatten?: boolean;\n noBorder?: boolean;\n /** Start this node's section panel collapsed. Ignored when `flatten` is set. */\n collapsed?: boolean;\n /**\n * Fixed grid for the node's scalar fields: `cols` fields per row, filling\n * left-to-right; `rows` alone fills top-to-bottom into that many rows,\n * adding columns as needed. Overrides {@link minFieldWidth}.\n */\n grid?: { rows?: number; cols?: number };\n /**\n * Narrowest a scalar field may get (a CSS length, e.g. `'12rem'`): each row\n * fits as many equal-width fields as stay at least this wide and wraps the\n * rest. Ignored when {@link grid} is set. With neither option the fields\n * share one wrapping row, shrinking down to 10% of it.\n */\n minFieldWidth?: string;\n /**\n * Where boolean (checkbox-rendered) fields go. A checkbox doesn't need a\n * field-sized slot — in a {@link grid} it would claim a whole track —\n * so `'beginning'`/`'end'` gathers them into a compact wrapping row of\n * natural-width items before/after the node's other fields. `'default'`\n * (or unset) keeps them in declaration order within the field flow.\n */\n booleanFields?: 'beginning' | 'end' | 'default';\n /**\n * Narrowest a **text (string) field** may get in the flex flow (a CSS\n * length): the row wraps rather than shrink such a field further. Enum\n * fields (rendered as a select) are text-like and follow it too, as do a\n * string/enum leaf-list's entries. No effect under {@link grid} /\n * {@link minFieldWidth}, whose tracks size every field alike.\n */\n minTextFieldWidth?: string;\n /**\n * Narrowest a **number field** may get in the flex flow (a CSS length) —\n * the numeric counterpart of {@link minTextFieldWidth}, typically smaller.\n * Also bounds a number leaf-list's entries.\n */\n minNumberFieldWidth?: string;\n /**\n * Widest a **number field** may grow in the flex flow (a CSS length):\n * numbers are short, so capping them keeps a lone number from stretching\n * across space a text field could use. Also caps a number leaf-list's\n * entries. No effect under {@link grid} / {@link minFieldWidth}.\n */\n maxNumberFieldWidth?: string;\n}\n\nexport type Leaf = LeafString | LeafNumber | LeafBoolean | LeafEnum;\n\nexport type LeafList<TKind extends Leaf['type'] = Leaf['type']> = {\n kind: 'leafList';\n label?: string;\n name: string;\n description?: string;\n default?: Exclude<Leaf['default'], undefined>[];\n type: TKind;\n minItems?: number;\n maxItems?: number;\n /** Present every item in this base — see {@link LeafNumber.radix}. */\n radix?: 2 | 8 | 16;\n /**\n * Optional scalar list whose *presence itself* is data — an absent key,\n * distinct from a present-but-empty list. Off means no control and no key in\n * the value; on means the (possibly empty) list is materialized. Mirrors\n * {@link NodeGroup.presence}; lets a round-trip distinguish `x = ( )` (present,\n * empty) from an absent `x`.\n */\n presence?: boolean;\n};\n\nexport type NodeGroupList = {\n kind: 'nodeGroupList';\n name: string;\n label?: string;\n description?: string;\n type: NodeGroup;\n minItems?: number;\n maxItems?: number;\n /** Optional list whose presence is itself data — see {@link LeafList.presence}. */\n presence?: boolean;\n};\n\nexport type NodeGroup = {\n kind: 'nodeGroup';\n name: string;\n subType?: string;\n label?: string;\n root?: boolean;\n /**\n * When true, the group is optional: rendered with an on/off toggle and present\n * in the form only while enabled. Its control is removed from the parent\n * FormGroup when absent (so it drops from `form.value`) and re-added when the\n * user toggles it on. The builder omits it unless an initial value is supplied.\n */\n presence?: boolean;\n description?: string;\n /**\n * Minimum / maximum number of keys present in the group's value (JSON Schema\n * `minProperties`/`maxProperties` on a closed object). Meaningful when\n * children are presence-optional: the group carries a `minPresent` /\n * `maxPresent` error while the count of enabled children is out of range.\n */\n minPresent?: number;\n maxPresent?: number;\n children: Record<string, NodeType>;\n appearance?: Appearance;\n};\n\n/**\n * One case of a {@link NodeChoice}: either a record of named fields (an object\n * branch), or a single node (a *leaf-bodied* case — e.g. an `anyOf` branch that\n * is a bare scalar). A single node is normalized to a one-field record keyed by\n * its `name` when the form is built.\n */\nexport type ChoiceCase = Record<string, NodeType> | NodeType;\n\n/**\n * A discriminated selection: the user picks one `case`, and only that case's\n * fields are present. In the form it is a FormGroup holding a `__case` control\n * (the active case name) plus that case's field controls; switching the case\n * swaps the field controls.\n *\n * Cases may be **anonymous / auto-named** (any string key) — for JSON Schema\n * `anyOf`/`oneOf` branches with no name. When a built form is seeded from inline\n * data that carries no `__case`, the builder **infers** the active case from the\n * data shape (the case whose fields best match), so a choice round-trips from\n * real instance data. See the schema reference for the required-set / `const`\n * discriminator recipe.\n */\nexport type NodeChoice = {\n kind: 'choice';\n name: string;\n label?: string;\n cases: Record<string, ChoiceCase>;\n /**\n * Display labels for cases, keyed by case name — for anonymous/auto-named\n * branches whose keys are not human-friendly. Falls back to the case name.\n * Selectors render these through `caseDisplayLabels`, which disambiguates\n * colliding entries by each case's distinguishing fields.\n */\n caseLabels?: Record<string, string>;\n default?: string;\n mandatory?: boolean;\n /** Optional choice: rendered with an on/off toggle, omitted from the value when absent. */\n presence?: boolean;\n appearance?: Appearance;\n};\n\n/**\n * The control name that records which case of a {@link NodeChoice} is active.\n * The name is reserved: it cannot be used as a case field name (the builder\n * throws) or as a map entry key (the entry helpers reject it).\n */\nexport const CASE_KEY = '__case';\n\n/**\n * An open, arbitrary-keyed record: unlike {@link NodeGroup} (a fixed, declared\n * key set), a map's keys are runtime data and every value conforms to one shared\n * `value` schema. Maps JSON Schema `additionalProperties: <schema>` /\n * `patternProperties`. In the form it is a `FormGroup` whose control *names* are\n * the entry keys, so `getRawValue()` is the map object directly; the renderer\n * lets the user add, remove, and rename entries.\n */\nexport type NodeMap = {\n kind: 'map';\n name: string;\n label?: string;\n description?: string;\n /** The schema every entry's value conforms to. */\n value: NodeType;\n /** Label for the key column in the editor. Defaults to \"Key\". */\n keyLabel?: string;\n /** `patternProperties`: entry keys must match this regular expression. */\n keyPattern?: string;\n /** Minimum number of entries (JSON Schema `minProperties`). */\n minEntries?: number;\n /** Maximum number of entries (JSON Schema `maxProperties`). */\n maxEntries?: number;\n /** Optional map: rendered with an on/off toggle, omitted from the value when absent. */\n presence?: boolean;\n appearance?: Appearance;\n};\n\nexport type NodeType = Leaf | LeafList | NodeGroup | NodeGroupList | NodeChoice | NodeMap;\nexport type DFormControl<T extends NodeType> = T extends Leaf\n ? FormControl<LeafRuntimeType<T['type']>>\n : T extends LeafList\n ? FormArray<FormControl<LeafRuntimeType<T['type']>>>\n : T extends NodeGroup\n ? DFormGroup<T>\n : T extends NodeGroupList\n ? FormArray<DFormGroup<T['type']>>\n : T extends NodeChoice\n ? FormGroup<any>\n : T extends NodeMap\n ? FormGroup<any>\n : never;\n\nexport type FormGroupType<T extends NodeGroup> = {\n [TChild in keyof T['children']]: DFormControl<T['children'][TChild]>;\n};\nexport type DFormGroup<T extends NodeGroup> = FormGroup<FormGroupType<T>>;\n","import {\n FormArray,\n FormControl,\n FormGroup,\n ValidatorFn,\n Validators,\n} from '@angular/forms';\nimport {\n CASE_KEY,\n ChoiceCase,\n DFormControl,\n DFormGroup,\n FormGroupType,\n Leaf,\n LeafBase,\n LeafEnum,\n LeafList,\n LeafNumber,\n LeafRuntimeType,\n LeafString,\n NodeChoice,\n NodeGroup,\n NodeGroupList,\n NodeMap,\n NodeType,\n} from '../types/dynamic-recursive.types';\n\n// --- type guards\nfunction isLeaf(node: NodeType): node is Leaf {\n return node.kind === 'leaf';\n}\n\nfunction isLeafList(node: NodeType): node is LeafList {\n return node.kind === 'leafList';\n}\nfunction isNodeGroup(node: NodeType): node is NodeGroup {\n return node.kind === 'nodeGroup';\n}\nfunction isNodeGroupList(node: NodeType): node is NodeGroupList {\n return node.kind === 'nodeGroupList';\n}\nfunction isChoice(node: NodeType): node is NodeChoice {\n return node.kind === 'choice';\n}\nfunction isMap(node: NodeType): node is NodeMap {\n return node.kind === 'map';\n}\n\n/** Whether the node is an optional (presence) node: its key is data, absent until enabled. */\nfunction hasPresence(node: NodeType): boolean {\n return (\n (node.kind === 'leaf' ||\n node.kind === 'nodeGroup' ||\n node.kind === 'map' ||\n node.kind === 'choice' ||\n node.kind === 'leafList' ||\n node.kind === 'nodeGroupList') &&\n node.presence === true\n );\n}\n\n/**\n * Whether a presence child should start absent: there is no initial data\n * object (a scalar seed counts as none), or its key is missing from it. A key\n * that is present with an explicit `null` value keeps its control — `null` is\n * a value (a nullable leaf's), while presence is about the *absent key*.\n */\nfunction presenceAbsent(initial: Record<string, unknown> | null | undefined, key: string): boolean {\n return initial == null || typeof initial !== 'object' || !(key in initial);\n}\n\nfunction enumValidator(choices: readonly (string | number)[]): ValidatorFn {\n const set = new Set(choices);\n return (ctrl) =>\n ctrl.value == null || set.has(ctrl.value) ? null : { enum: true };\n}\n\n/**\n * JSON Schema `pattern`: an *unanchored* `RegExp.test`, unlike Angular's built-in\n * `Validators.pattern` which anchors the expression. An invalid regex disables\n * the check rather than throwing. Empty/absent values pass (use `required`).\n */\nfunction patternValidator(pattern: string): ValidatorFn {\n let re: RegExp;\n try {\n re = new RegExp(pattern);\n } catch {\n return () => null;\n }\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n return re.test(String(v)) ? null : { pattern: { requiredPattern: pattern, actualValue: v } };\n };\n}\n\n/** JSON Schema `type: 'integer'`: reject a value that is not a whole number. */\nfunction integerValidator(): ValidatorFn {\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n const num = typeof v === 'number' ? v : Number(v);\n return Number.isInteger(num) ? null : { integer: true };\n };\n}\n\n/** JSON Schema `multipleOf`: reject a value that is not an integer multiple of `step`. */\nfunction multipleOfValidator(step: number): ValidatorFn {\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n const num = typeof v === 'number' ? v : Number(v);\n if (Number.isNaN(num)) return null;\n const ratio = num / step;\n // A small tolerance absorbs binary float drift (e.g. 0.3 / 0.1).\n return Math.abs(ratio - Math.round(ratio)) < 1e-9\n ? null\n : { multipleOf: { multipleOf: step, actual: num } };\n };\n}\n\n/** JSON Schema `format: uri`: reject a string that is not a parseable absolute URI. */\nfunction uriValidator(): ValidatorFn {\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n try {\n new URL(String(v));\n return null;\n } catch {\n return { uri: true };\n }\n };\n}\n\nfunction buildLeafControl<L extends Leaf>(\n leaf: L,\n initial?: unknown,\n): FormControl<LeafRuntimeType<L['type']>> {\n const validators: ValidatorFn[] = [];\n if ('required' in leaf && leaf.required) validators.push(Validators.required);\n // A presence leaf only ever has a control while enabled, and enabled means\n // the key goes on the wire — an empty materialized value would serialize as\n // null and fail typed-schema validation. So materialized ⇒ must hold a\n // value; disable the field to omit it. A nullable presence leaf is exempt:\n // explicit null is one of its legal values.\n else if ((leaf as LeafBase).presence === true && (leaf as LeafBase).nullable !== true) {\n validators.push(Validators.required);\n }\n if ('type' in leaf && leaf.type === 'enum') {\n const choices = (leaf as LeafEnum).enum as (string | number)[];\n validators.push(enumValidator(choices));\n }\n if (leaf.type === 'string') {\n const s = leaf as LeafString;\n if (s.pattern != null) validators.push(patternValidator(s.pattern));\n if (s.minLength != null) validators.push(Validators.minLength(s.minLength));\n if (s.maxLength != null) validators.push(Validators.maxLength(s.maxLength));\n if (s.format === 'email') validators.push(Validators.email);\n else if (s.format === 'uri' || s.format === 'url') validators.push(uriValidator());\n } else if (leaf.type === 'number') {\n const n = leaf as LeafNumber;\n if (n.integer) validators.push(integerValidator());\n if (n.min != null) validators.push(Validators.min(n.min));\n if (n.max != null) validators.push(Validators.max(n.max));\n if (n.multipleOf != null) validators.push(multipleOfValidator(n.multipleOf));\n }\n const defaultValue =\n initial ?? ('default' in leaf ? (leaf as any).default : undefined) ?? null;\n // A nullable leaf drops `nonNullable`, so `null` is a first-class value that\n // `reset()` restores and that survives the round-trip (JSON Schema `null`).\n // The typed model still treats a leaf value as non-null, so the runtime\n // nullable control is cast back to the declared type.\n const nullable = 'nullable' in leaf && (leaf as LeafBase).nullable === true;\n return new FormControl<LeafRuntimeType<L['type']>>(defaultValue, {\n nonNullable: !nullable,\n validators,\n }) as FormControl<LeafRuntimeType<L['type']>>;\n}\n\n// The list value with no seed data is the empty array: a phantom null entry\n// would fail validation of the serialized value against typed item schemas,\n// and an empty list is the honest wire shape (renderers offer the add row).\nfunction buildLeafListControl<L extends LeafList>(\n list: L,\n initial: LeafRuntimeType<L['type']>[] | null,\n): FormArray<FormControl<LeafRuntimeType<LeafList['type']> | null>> {\n const values = (Array.isArray(initial) ? initial : undefined) ?? list.default ?? [];\n return new FormArray(values.map((v) => new FormControl(v)));\n}\n\n/**\n * Group error while the number of present (enabled) children is outside the\n * group's `minPresent`/`maxPresent` range — JSON Schema `minProperties` /\n * `maxProperties` on a closed object whose properties are presence-optional.\n * Counted from the live controls, so presence toggles re-evaluate it.\n */\nfunction presentChildrenValidator(group: NodeGroup): ValidatorFn {\n return (control) => {\n const actual = Object.keys((control as FormGroup).controls).length;\n if (group.minPresent != null && actual < group.minPresent) {\n return { minPresent: { required: group.minPresent, actual } };\n }\n if (group.maxPresent != null && actual > group.maxPresent) {\n return { maxPresent: { allowed: group.maxPresent, actual } };\n }\n return null;\n };\n}\n\nfunction buildNodeGroupControl<G extends NodeGroup>(\n group: G,\n initial?: Record<string, unknown> | null,\n): DFormGroup<G> {\n const controls: any = {} as Partial<FormGroupType<G>>;\n for (const key in group.children) {\n const child = group.children[key];\n // An absent presence child gets no control at all, so it is absent from the\n // form value until enabled. Because every nested group is built through this\n // function — plain children, list items, map values, choice case fields —\n // presence is honored at any depth.\n if (hasPresence(child) && presenceAbsent(initial, key)) continue;\n // Forward only this child's slice of the initial data, keyed by the child's\n // record key. Passing the whole `initial` object seeds every leaf with the\n // parent record and prevents list builders from sizing to the real data.\n controls[key] = buildControl(\n child,\n initial?.[key],\n ) as FormGroupType<G>[typeof key];\n }\n const constrained = group.minPresent != null || group.maxPresent != null;\n return new FormGroup(\n controls as FormGroupType<G>,\n constrained ? { validators: presentChildrenValidator(group) } : undefined,\n ) as DFormGroup<G>;\n}\n\nfunction buildNodeGroupListControl<GL extends NodeGroupList>(\n list: GL,\n initial: unknown[] | null = null,\n): FormArray<DFormGroup<GL['type']>> {\n // `initial` is the runtime data array — one group per element. With no data\n // the list is empty: seeding a phantom all-null group would put an invalid\n // member on the wire (see buildLeafListControl).\n const values = Array.isArray(initial) ? initial : [];\n return new FormArray(\n values.map((v) =>\n buildNodeGroupControl(list.type, v as Record<string, unknown> | null),\n ),\n );\n}\n\n/**\n * Normalize a {@link ChoiceCase} to a field record. A field record is returned\n * as-is; a single node (a leaf-bodied case, e.g. a scalar `anyOf` branch) becomes\n * a one-field record keyed by the node's `name`. The discriminant is a top-level\n * `kind` string, which a field record never has (its keys are field names).\n *\n * Throws when a case field is keyed `__case`: that name is reserved for the\n * choice discriminator ({@link CASE_KEY}) and a field under it would silently\n * clobber the active-case control.\n */\nexport function caseFields(body: ChoiceCase): Record<string, NodeType> {\n const fields =\n typeof (body as { kind?: unknown }).kind === 'string'\n ? { [(body as NodeType).name]: body as NodeType }\n : (body as Record<string, NodeType>);\n if (CASE_KEY in fields) {\n throw new Error(`\"${CASE_KEY}\" is reserved for the choice discriminator and cannot name a case field`);\n }\n return fields;\n}\n\n/**\n * Display labels for a choice's cases, keyed by case name, with colliding\n * labels made unique. Schema-supplied `caseLabels` can repeat (e.g. two\n * O-RAN A1 scope branches labeled from the same discriminating field), which\n * makes the case selector ambiguous. Unique labels pass through untouched;\n * each colliding case first gains the fields that set it apart from its\n * same-labeled peers — \"UE ID (Group ID)\" vs \"UE ID (Slice ID)\" — and any\n * cases the field suffix cannot separate (no distinguishing fields, peers\n * with identical field sets among a larger clash group, or distinguishing\n * fields that share one display label) fall back to their case name, which\n * is unique by construction.\n */\nexport function caseDisplayLabels(choice: NodeChoice): Record<string, string> {\n const names = Object.keys(choice.cases);\n const base: Record<string, string> = {};\n const out: Record<string, string> = {};\n const byLabel = new Map<string, string[]>();\n for (const name of names) {\n base[name] = choice.caseLabels?.[name] ?? name;\n out[name] = base[name];\n byLabel.set(base[name], [...(byLabel.get(base[name]) ?? []), name]);\n }\n for (const clashing of byLabel.values()) {\n if (clashing.length < 2) continue;\n for (const name of clashing) {\n const fields = caseFields(choice.cases[name]);\n const others = clashing.filter((o) => o !== name).map((o) => caseFields(choice.cases[o]));\n const distinct = Object.keys(fields).filter((key) => !others.every((o) => key in o));\n const suffix = distinct.length\n ? distinct.map((key) => (fields[key] as { label?: string }).label ?? key).join(', ')\n : name;\n out[name] = `${out[name]} (${suffix})`;\n }\n }\n // Uniqueness guarantee: whatever the collision topology, labels still equal\n // after field-suffixing take the case name instead.\n const byFinal = new Map<string, string[]>();\n for (const name of names) byFinal.set(out[name], [...(byFinal.get(out[name]) ?? []), name]);\n for (const clashing of byFinal.values()) {\n if (clashing.length < 2) continue;\n for (const name of clashing) out[name] = `${base[name]} (${name})`;\n }\n return out;\n}\n\n/**\n * The active case of a choice: an explicit `__case` in the initial value, else\n * the case {@link inferChoiceCase} ranks best against the initial data (inline\n * wire data carries no `__case`), else the schema `default`. This lets a choice\n * seed from real instance data whose branch is discriminated by which fields\n * are present and required.\n */\nexport function resolveChoiceCase(\n choice: NodeChoice,\n initial?: Record<string, unknown> | null,\n): string | undefined {\n const explicit = initial?.[CASE_KEY];\n if (typeof explicit === 'string') return explicit;\n return inferChoiceCase(choice, initial) ?? choice.default;\n}\n\n/**\n * Pick the active case from inline wire data (which carries no `__case`).\n *\n * Candidates are the cases sharing at least one field name with the data; when\n * none does, the caller falls back to the schema `default`. Candidates are\n * ranked by, in order: fewest data keys the case has no field for (the case\n * must be able to hold the data), fewest non-presence fields absent from the\n * data (fields the form would have to materialize empty — this is how\n * required-set-discriminated `oneOf` branches differ, e.g. a branch requiring\n * `{ueId, qosId}` vs one requiring only `{qosId}`), most matched fields, and\n * finally declaration order. Presence fields are exempt from the absence count\n * because their absence is itself a legal state of the data.\n */\nfunction inferChoiceCase(choice: NodeChoice, initial?: Record<string, unknown> | null): string | undefined {\n if (initial == null || typeof initial !== 'object' || Array.isArray(initial)) return undefined;\n const dataKeys = new Set(Object.keys(initial).filter((k) => k !== CASE_KEY));\n let best: string | undefined;\n let bestRank: number[] | undefined;\n for (const name of Object.keys(choice.cases)) {\n const fields = caseFields(choice.cases[name]);\n let matched = 0;\n for (const key of dataKeys) if (key in fields) matched++;\n if (matched === 0) continue;\n const missing = Object.keys(fields).filter(\n (f) => !hasPresence(fields[f]) && !dataKeys.has(f),\n ).length;\n const rank = [dataKeys.size - matched, missing, -matched];\n if (bestRank === undefined || lexLess(rank, bestRank)) {\n bestRank = rank;\n best = name;\n }\n }\n return best;\n}\n\n/** Strictly-less comparison of two equal-length rank vectors, first difference wins. */\nfunction lexLess(a: readonly number[], b: readonly number[]): boolean {\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return a[i] < b[i];\n }\n return false;\n}\n\n/**\n * Group error while a choice that must resolve to a case has none selected.\n * Attached to `mandatory` choices (a case is always due) and `presence` choices\n * (enabled means the key serializes, and `{}` satisfies no case) — a plain\n * optional choice stays validator-free, `{ __case: null }` and all.\n */\nfunction caseRequiredValidator(): ValidatorFn {\n return (group) =>\n (group as FormGroup).get(CASE_KEY)?.value == null ? { caseRequired: true } : null;\n}\n\n/**\n * Build the FormGroup for a choice: a `__case` control holding the active case\n * name plus that case's field controls. Only the active case's fields are built,\n * matching the inline YANG encoding; switching the case swaps them. Mandatory\n * and presence choices carry {@link caseRequiredValidator}.\n */\nfunction buildChoiceControl(\n choice: NodeChoice,\n initial?: Record<string, unknown> | null,\n): FormGroup {\n const active = resolveChoiceCase(choice, initial);\n const controls: any = { [CASE_KEY]: new FormControl(active ?? null) };\n if (active && choice.cases[active]) {\n const caseChildren = caseFields(choice.cases[active]);\n for (const key in caseChildren) {\n // Case fields honor presence like any group's children: an absent\n // presence field gets no control.\n if (hasPresence(caseChildren[key]) && presenceAbsent(initial, key)) continue;\n controls[key] = buildControl(caseChildren[key], initial?.[key]);\n }\n }\n const needsCase = choice.mandatory === true || choice.presence === true;\n return new FormGroup(controls, needsCase ? { validators: caseRequiredValidator() } : undefined);\n}\n\n/**\n * Switch a choice's FormGroup to `caseName`: sets `__case`, removes every other\n * control, and builds `caseName`'s fields (normalized via {@link caseFields})\n * with their defaults. Presence fields of the new case start absent — the\n * switch carries no data that could make them present. An unknown case name\n * leaves only `__case`. The swap is atomic: one value change fires, and every\n * observable snapshot has fields matching its discriminator.\n */\nexport function switchChoiceCase(group: FormGroup, choice: NodeChoice, caseName: string): void {\n group.get(CASE_KEY)?.setValue(caseName, { emitEvent: false });\n for (const name of Object.keys(group.controls)) {\n if (name !== CASE_KEY) group.removeControl(name, { emitEvent: false });\n }\n const caseChildren = choice.cases[caseName] ? caseFields(choice.cases[caseName]) : {};\n for (const name in caseChildren) {\n if (hasPresence(caseChildren[name])) continue;\n group.addControl(name, buildControl(caseChildren[name]) as any, { emitEvent: false });\n }\n group.updateValueAndValidity();\n}\n\n/**\n * Append a map entry built from `map.value` and return its committed key, or\n * `null` when nothing was added. With no `key`, the first free `keyN`\n * placeholder is generated (not checked against `keyPattern` — placeholders are\n * meant to be renamed). An explicit `key` is rejected when it duplicates an\n * existing entry or violates `keyPattern`. Rejects when `maxEntries` is reached.\n */\nexport function addMapEntry(group: FormGroup, map: NodeMap, key?: string): string | null {\n if (map.maxEntries != null && Object.keys(group.controls).length >= map.maxEntries) return null;\n let committed: string;\n if (key != null) {\n const trimmed = key.trim();\n // `__case` is reserved for the choice discriminator; as an entry key it\n // would make the map group indistinguishable from a choice group.\n if (!trimmed || trimmed === CASE_KEY || group.contains(trimmed)) return null;\n if (map.keyPattern && !new RegExp(map.keyPattern).test(trimmed)) return null;\n committed = trimmed;\n } else {\n let n = Object.keys(group.controls).length + 1;\n committed = `key${n}`;\n while (group.contains(committed)) committed = `key${++n}`;\n }\n group.addControl(committed, buildControl(map.value) as any);\n return committed;\n}\n\n/**\n * Rename entry `oldKey` to `newKey.trim()`, preserving the control instance\n * (so the value survives) and the entry's position in the group's key order —\n * the order `getRawValue()` serializes and the tree editor renders. Returns\n * whether the rename was committed: an empty, reserved (`__case`), unchanged,\n * duplicate, or `keyPattern`-violating key is a no-op, leaving the entry under\n * its current name. Entry keys are looked up verbatim — never via\n * `AbstractControl.get`, which would split keys like `10.0.0.1` into\n * dot-delimited paths. Emits a single value change.\n */\nexport function renameMapEntry(group: FormGroup, map: NodeMap, oldKey: string, newKey: string): boolean {\n const committed = newKey.trim();\n if (!committed || committed === CASE_KEY || committed === oldKey || group.contains(committed)) return false;\n if (map.keyPattern && !new RegExp(map.keyPattern).test(committed)) return false;\n const control = group.controls[oldKey];\n if (!control) return false;\n // Re-key in place: swap the name, then re-append every key that followed so\n // the renamed entry does not jump to the end of the key order.\n const following = Object.keys(group.controls);\n following.splice(0, following.indexOf(oldKey) + 1);\n group.removeControl(oldKey, { emitEvent: false });\n group.addControl(committed, control, { emitEvent: false });\n for (const key of following) {\n const sibling = group.controls[key];\n group.removeControl(key, { emitEvent: false });\n group.addControl(key, sibling, { emitEvent: false });\n }\n group.updateValueAndValidity();\n return true;\n}\n\n/** Remove entry `key` unless the map is at `minEntries`. Returns whether it was removed. */\nexport function removeMapEntry(group: FormGroup, map: NodeMap, key: string): boolean {\n if (!group.contains(key)) return false;\n if (map.minEntries != null && Object.keys(group.controls).length <= map.minEntries) return false;\n group.removeControl(key);\n return true;\n}\n\n/**\n * Materialize or de-materialize an optional (presence) child of `group`,\n * mirroring the presence toggle the form UI offers — but callable by any host\n * holding the {@link FormGroup}, for a key at any depth. `present: true` builds\n * the child fresh from `schema` (seeded with `initial` if given; nested\n * presence descendants start absent, as {@link buildControl}); `present: false`\n * removes it, dropping the key from the form value.\n *\n * The materialize direction is why the coupling exists: a materialized\n * non-nullable presence leaf carries `Validators.required`, because an\n * enabled-but-empty key would serialize as `null` and fail a typed schema. A\n * host that materializes fields for editing therefore drops the ones left\n * empty on cancel by de-materializing them — this API is that primitive.\n *\n * `schema` must be the presence node for `key`; a non-presence `schema` is a\n * no-op. Returns whether the form changed.\n */\nexport function setNodePresence(group: FormGroup, schema: NodeType, key: string, present: boolean, initial?: unknown): boolean {\n if (!hasPresence(schema)) return false;\n if (present) {\n if (group.contains(key)) return false;\n group.addControl(key, buildControl(schema, initial) as never);\n return true;\n }\n if (!group.contains(key)) return false;\n group.removeControl(key);\n return true;\n}\n\n/**\n * The map's own constraints as a group validator: entry count against\n * `minEntries`/`maxEntries` and every entry key against `keyPattern`. The UI\n * gates prevent most violations; the validator reports the ones that slip\n * through (seeded wire data, generated `keyN` placeholders awaiting a rename).\n */\nfunction mapValidator(map: NodeMap): ValidatorFn {\n let re: RegExp | null = null;\n if (map.keyPattern) {\n try {\n re = new RegExp(map.keyPattern);\n } catch {\n re = null;\n }\n }\n return (ctrl) => {\n const keys = Object.keys((ctrl as FormGroup).controls);\n const errors: Record<string, unknown> = {};\n if (map.minEntries != null && keys.length < map.minEntries) {\n errors['minEntries'] = { required: map.minEntries, actual: keys.length };\n }\n if (map.maxEntries != null && keys.length > map.maxEntries) {\n errors['maxEntries'] = { allowed: map.maxEntries, actual: keys.length };\n }\n if (re) {\n const invalidKeys = keys.filter((k) => !re!.test(k));\n if (invalidKeys.length) errors['keyPattern'] = { pattern: map.keyPattern, keys: invalidKeys };\n }\n return Object.keys(errors).length ? errors : null;\n };\n}\n\n/**\n * Build the FormGroup for a map: one control per entry, keyed by the entry key,\n * each built from the map's shared `value` schema. Because the entry keys are the\n * control names, `getRawValue()` is the map object directly. Empty when no\n * initial object is supplied; the renderer adds/removes/renames entries. The\n * group carries {@link mapValidator}, so `keyPattern`/`minEntries`/`maxEntries`\n * violations surface as validation errors.\n */\nfunction buildMapControl(\n map: NodeMap,\n initial?: Record<string, unknown> | null,\n): FormGroup {\n const controls: any = {};\n const source = initial && typeof initial === 'object' && !Array.isArray(initial) ? initial : {};\n for (const key of Object.keys(source)) {\n controls[key] = buildControl(map.value, source[key]);\n }\n return new FormGroup(controls, { validators: mapValidator(map) });\n}\n\n/**\n * Build the `AbstractControl` for a single schema node.\n *\n * Dispatches on `node.kind`: a `leaf` becomes a `FormControl`, a `leafList` a\n * `FormArray` of controls, a `nodeGroup` a nested `FormGroup`, and a\n * `nodeGroupList` a `FormArray` of groups. `initial` is the runtime value for\n * this node — a scalar for a leaf, an array for a list, an object for a group —\n * and seeds the control's value (falling back to the node's `default`).\n *\n * Most callers use {@link buildFormFromSchema}; this is exposed for building a\n * control from a single non-root node.\n */\nexport function buildControl<T extends NodeType>(\n node: T,\n initial?: unknown | null,\n): DFormControl<T> | FormControl<LeafRuntimeType<any>> | FormArray<any> {\n if (isLeaf(node)) {\n return buildLeafControl(node, initial);\n }\n if (isChoice(node)) {\n return buildChoiceControl(\n node,\n initial ? (initial as Record<string, unknown>) : null,\n ) as DFormControl<T>;\n }\n if (isMap(node)) {\n return buildMapControl(\n node,\n initial ? (initial as Record<string, unknown>) : null,\n ) as DFormControl<T>;\n }\n if (isLeafList(node)) {\n return buildLeafListControl(\n node,\n initial !== null\n ? (initial as LeafRuntimeType<(T & LeafList)['type']>[])\n : initial,\n ) as DFormControl<T>;\n }\n if (isNodeGroup(node)) {\n return buildNodeGroupControl(\n node,\n initial ? (initial as Record<string, unknown>) : null,\n ) as DFormControl<T>;\n }\n if (isNodeGroupList(node)) {\n return buildNodeGroupListControl(\n node,\n initial ? (initial as unknown[]) : null,\n ) as DFormControl<T>;\n }\n return new FormControl(initial ?? '') as DFormControl<T>;\n}\n\n/**\n * Build a typed `FormGroup` from a root `NodeGroup` schema.\n *\n * The returned group's control structure, keys, and value types are inferred\n * from the schema literal — a `leaf` of `type: 'number'` yields a\n * `FormControl<number>`, a `nodeGroup` a nested `FormGroup`, and so on. `initial`\n * is an optional value object keyed by the schema's `children` keys; each child\n * control is seeded from its matching slice (falling back to the node `default`).\n *\n * Presence nodes whose key is absent from `initial` get no control, at any depth\n * — plain children, list items, map values, and choice case fields alike — so\n * they are absent from the form value until enabled. A key present with an\n * explicit `null` keeps its control: `null` is a value, absence is the missing\n * key.\n *\n * Inference only holds when `schema`'s literal type is preserved. Author schemas\n * with {@link defineSchema} or a `satisfies NodeGroup` annotation — never\n * `const schema: NodeGroup = ...`, which widens `children` and erases the field\n * names and value types.\n */\nexport function buildFormFromSchema<S extends NodeGroup>(\n schema: S,\n initial: Record<string, unknown> | null = null,\n): DFormGroup<S> {\n return buildNodeGroupControl<S>(schema, initial);\n}\n\n/**\n * The wire value at `node`: `value` rebuilt with every choice discriminator\n * removed.\n *\n * A choice's form value is `{ __case, ...fields }` ({@link CASE_KEY}); its wire\n * encoding is the active case's fields inline, with no discriminator — the case\n * is recovered from the field shape when the data is seeded back in\n * ({@link resolveChoiceCase}). The walk is schema-driven: only positions the\n * schema declares as choices are stripped, so a group child or map entry that\n * happens to be named `__case` passes through untouched. Values at positions\n * the schema does not describe pass through unchanged.\n */\nexport function toWireValue(node: NodeType, value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value;\n if (isChoice(node)) {\n const { [CASE_KEY]: active, ...rest } = value as Record<string, unknown>;\n const fields =\n typeof active === 'string' && node.cases[active] ? caseFields(node.cases[active]) : {};\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(rest)) {\n out[key] = key in fields ? toWireValue(fields[key], rest[key]) : rest[key];\n }\n return out;\n }\n if (isNodeGroup(node)) {\n const source = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(source)) {\n out[key] = key in node.children ? toWireValue(node.children[key], source[key]) : source[key];\n }\n return out;\n }\n if (isNodeGroupList(node)) {\n return Array.isArray(value) ? value.map((item) => toWireValue(node.type, item)) : value;\n }\n if (isMap(node)) {\n const source = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(source)) out[key] = toWireValue(node.value, source[key]);\n return out;\n }\n return value;\n}\n\n/**\n * Serialize a form built by {@link buildFormFromSchema} to its wire value:\n * `form.getRawValue()` with every choice's {@link CASE_KEY} discriminator\n * stripped (see {@link toWireValue}). The result is the inline encoding that\n * `buildFormFromSchema` accepts back as `initial`, so serialize → rebuild\n * round-trips the value.\n */\nexport function serializeForm(schema: NodeGroup, form: FormGroup): Record<string, unknown> {\n return toWireValue(schema, form.getRawValue()) as Record<string, unknown>;\n}\n\n/**\n * Capture a schema literal with its exact type while checking it against\n * `NodeGroup`.\n *\n * This is an identity function whose only job is the `const` type parameter,\n * which keeps the narrow literal type of `schema` (field names, each node's\n * `type`) instead of widening it to `NodeGroup`. Assigning a schema to a\n * `: NodeGroup`-annotated constant widens `children` to\n * `Record<string, NodeType>` and erases that information, so\n * {@link buildFormFromSchema} can no longer infer a typed `FormGroup`. Passing\n * the schema through `defineSchema` (or annotating it `satisfies NodeGroup`)\n * preserves the schema-to-`FormGroup` inference.\n */\nexport function defineSchema<const S extends NodeGroup>(schema: S): S {\n return schema;\n}\n","import { Component, Input } from '@angular/core';\nimport { LeafEnum } from '../../types/dynamic-recursive.types';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatSelectModule } from '@angular/material/select';\n\n@Component({\n selector: 'nff-leaf-enum-renderer',\n standalone: true,\n imports: [ReactiveFormsModule, MatFormFieldModule, MatSelectModule],\n templateUrl: './leaf-enum-renderer.component.html',\n styleUrl: './leaf-enum-renderer.component.scss',\n})\nexport class LeafEnumRendererComponent {\n @Input() leafEnum!: LeafEnum;\n @Input() initialValue!: string;\n @Input() control = new FormControl();\n @Input() removable: boolean = false;\n @Input() remove: any;\n @Input() editable: boolean = true;\n /** Placeholder for the empty select — e.g. a ghost preview showing the schema default. */\n @Input() placeholder = '';\n}\n","<mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ leafEnum.label ?? leafEnum.name }}</mat-label>\n @if (editable) {\n <mat-select [formControl]=\"control\" [placeholder]=\"placeholder\">\n @for (option of leafEnum.enum; track $index) {\n <mat-option [value]=\"option\">{{ leafEnum.enumLabel?.[$index] ?? option }}</mat-option>\n }\n </mat-select>\n } @else {\n <!-- Display-only: no formControl binding, so the wire value cannot change. -->\n <mat-select [value]=\"control.value\" disabled [placeholder]=\"placeholder\">\n @for (option of leafEnum.enum; track $index) {\n <mat-option [value]=\"option\">{{ leafEnum.enumLabel?.[$index] ?? option }}</mat-option>\n }\n </mat-select>\n }\n</mat-form-field>\n","import { Directive, ElementRef, Input, OnChanges, forwardRef } from '@angular/core';\nimport {\n AbstractControl,\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator,\n} from '@angular/forms';\n\nexport type Radix = 2 | 8 | 16;\n\nconst PREFIX: Record<Radix, string> = { 16: '0x', 8: '0o', 2: '0b' };\nconst MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);\nconst MIN_SAFE = BigInt(Number.MIN_SAFE_INTEGER);\n\n/**\n * An integer as a prefixed literal in the given base: `0x1A`, `0o17`, `0b101`,\n * hex digits uppercase, a leading `-` for negatives. Accepts a number or a\n * decimal-digit string (the beyond-safe-range carry).\n */\nexport function formatRadix(value: number | string, radix: Radix): string {\n const big = BigInt(value);\n const negative = big < 0n;\n const digits = (negative ? -big : big).toString(radix);\n return (negative ? '-' : '') + PREFIX[radix] + (radix === 16 ? digits.toUpperCase() : digits);\n}\n\n/**\n * Presents an integer control in hex/octal/binary while the control value\n * stays what the schema and validators expect: a plain `number`, or — with\n * `nffRadixValueType=\"string\"` — the exact decimal-digit string that carries\n * integers beyond the safe range (±(2^53 − 1)). Only the visible text is\n * based (`0x1A`, `0o17`, `0b101`); `min`/`max`/`integer`/`pattern` validators\n * therefore apply unchanged.\n *\n * Typing accepts the base's digits with or without prefix, case-insensitive\n * (`0q` is also accepted for octal, as in libconfig); the text normalizes to\n * the prefixed spelling on blur. Unparseable text sets the control to `null`\n * with a `radixFormat` error — never the raw text, so an invalid entry can\n * reach neither the wire value nor a typed write-back; the text itself stays\n * in the input for the user to correct. In number mode a magnitude beyond the\n * safe range likewise yields `null` with `radixRange` instead of a silently\n * rounded number.\n */\n@Directive({\n selector: 'input[nffRadixInput]',\n standalone: true,\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RadixInputDirective), multi: true },\n { provide: NG_VALIDATORS, useExisting: forwardRef(() => RadixInputDirective), multi: true },\n ],\n host: {\n '(input)': 'onInput(el.nativeElement.value)',\n '(blur)': 'onBlur()',\n autocomplete: 'off',\n spellcheck: 'false',\n },\n})\nexport class RadixInputDirective implements ControlValueAccessor, Validator, OnChanges {\n /** The display base. */\n @Input({ required: true, alias: 'nffRadixInput' }) radix!: Radix;\n /**\n * What the control carries: `'number'` (default), or `'string'` for the\n * decimal-digit bigint carry of a string leaf.\n */\n @Input({ alias: 'nffRadixValueType' }) valueType: 'number' | 'string' = 'number';\n\n private modelValue: unknown = null;\n private parseError: 'format' | 'range' | null = null;\n private onChange: (value: unknown) => void = () => {};\n private onTouched: () => void = () => {};\n private onValidatorChange: () => void = () => {};\n\n constructor(protected readonly el: ElementRef<HTMLInputElement>) {}\n\n /** A changed base (or carry mode) re-renders the model and re-validates. */\n ngOnChanges(): void {\n this.render();\n this.onValidatorChange();\n }\n\n writeValue(value: unknown): void {\n this.modelValue = value;\n this.parseError = null;\n this.render();\n }\n\n registerOnChange(fn: (value: unknown) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n registerOnValidatorChange(fn: () => void): void {\n this.onValidatorChange = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.el.nativeElement.disabled = isDisabled;\n }\n\n validate(_control: AbstractControl): ValidationErrors | null {\n if (this.parseError === 'format') return { radixFormat: { radix: this.radix } };\n if (this.parseError === 'range') return { radixRange: { radix: this.radix } };\n return null;\n }\n\n protected onInput(text: string): void {\n const trimmed = text.trim();\n if (trimmed === '') {\n this.parseError = null;\n this.modelValue = null;\n this.onChange(null);\n return;\n }\n const big = this.parse(trimmed);\n if (big === null) {\n // Invalid entry: the control gets null (never the raw text), the error\n // marks it, and the element keeps the text for the user to correct.\n this.parseError = 'format';\n this.modelValue = null;\n this.onChange(null);\n return;\n }\n if (this.valueType === 'string') {\n this.parseError = null;\n this.modelValue = big.toString();\n this.onChange(this.modelValue);\n return;\n }\n if (big > MAX_SAFE || big < MIN_SAFE) {\n // A number control cannot hold this exactly: null it, flag it.\n this.parseError = 'range';\n this.modelValue = null;\n this.onChange(null);\n return;\n }\n this.parseError = null;\n this.modelValue = Number(big);\n this.onChange(this.modelValue);\n }\n\n protected onBlur(): void {\n this.onTouched();\n if (this.parseError === null) this.render(); // normalize e.g. `1a` → `0x1A`\n }\n\n /** Show the model in its base; unrepresentable models pass through as text. */\n private render(): void {\n if (!this.radix) return; // before the first input binding — rendered once bound\n const v = this.modelValue;\n let text: string;\n if (v == null || v === '') text = '';\n else if (typeof v === 'number' && Number.isInteger(v)) text = formatRadix(v, this.radix);\n else if (typeof v === 'string' && /^[-+]?[0-9]+$/.test(v)) text = formatRadix(v, this.radix);\n else text = String(v);\n this.el.nativeElement.value = text;\n }\n\n /**\n * `[-+]?` + this base's optional prefix + this base's digits, or null. The\n * prefix is base-specific so hex digit runs that merely *look* like another\n * base's prefix (`0b11` as hex 0x0B11) parse as digits, not as a rejection.\n */\n private parse(text: string): bigint | null {\n const re =\n this.radix === 16\n ? /^([-+]?)(?:0[xX])?([0-9a-fA-F]+)$/\n : this.radix === 8\n ? /^([-+]?)(?:0[oOqQ])?([0-7]+)$/\n : /^([-+]?)(?:0[bB])?([01]+)$/;\n const m = re.exec(text);\n if (!m) return null;\n const big = BigInt(PREFIX[this.radix] + m[2]!.toLowerCase());\n return m[1] === '-' ? -big : big;\n }\n}\n","import { AfterViewInit, Component, ElementRef, Input, output } from '@angular/core';\nimport { AnonLeaf, Leaf } from '../../types/dynamic-recursive.types';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { LeafEnumRendererComponent } from '../leaf-enum-renderer/leaf-enum-renderer.component';\nimport { RadixInputDirective } from '../radix-input/radix-input.directive';\n\n@Component({\n selector: 'nff-leaf-renderer',\n standalone: true,\n imports: [\n MatFormFieldModule,\n ReactiveFormsModule,\n MatInputModule,\n MatCheckboxModule,\n MatSelectModule,\n MatIconModule,\n MatButtonModule,\n MatTooltip,\n LeafEnumRendererComponent,\n RadixInputDirective,\n ],\n templateUrl: './leaf-renderer.component.html',\n styleUrl: './leaf-renderer.component.scss',\n // The leaf's value type as a host class, so the type-scoped flex minimums\n // (`--nff-min-text-field-width` / `--nff-min-number-field-width`) can size\n // string and number fields differently — see the :host rules in the styles.\n host: { '[class]': '\"leaf-type-\" + (leaf_?.type ?? \"unknown\")' },\n})\nexport class LeafRendererComponent implements AfterViewInit {\n @Input() leaf_!: Leaf | AnonLeaf;\n @Input() control: FormControl = new FormControl();\n @Input() removable: boolean = false;\n @Input() editable = true;\n /** Focus the field once rendered — for fields the user just added (e.g. an enabled presence leaf). */\n @Input() autofocus = false;\n /** Placeholder for the empty field — e.g. a ghost preview showing the schema default. */\n @Input() placeholder = '';\n /** Emitted when the user removes this field (e.g. an optional presence leaf). */\n readonly remove = output<void>();\n\n constructor(private readonly elementRef: ElementRef<HTMLElement>) {}\n\n ngAfterViewInit(): void {\n if (this.autofocus) {\n // Deferred out of the change-detection pass: focusing flips the form\n // field's label-float state, which would otherwise trip NG0100.\n setTimeout(() => this.elementRef.nativeElement.querySelector<HTMLElement>('input, mat-select')?.focus());\n }\n }\n\n /** Whether this field accepts input: the form is editable and the leaf is not `readOnly`. */\n get fieldEditable(): boolean {\n return this.editable && !('name' in this.leaf_ && this.leaf_.readOnly);\n }\n\n /**\n * A human-readable message for the control's active validation error, or `''`\n * when valid. `mat-form-field` only shows it once the field is in an error\n * state (invalid and touched), so it can be bound unconditionally.\n */\n get errorText(): string {\n const e = this.control.errors;\n if (!e) return '';\n const label = 'name' in this.leaf_ ? this.leaf_.label ?? this.leaf_.name : 'Value';\n if (e['required']) return `${label} is required`;\n if (e['radixFormat']) {\n const names: Record<number, string> = { 16: 'hexadecimal (0x…)', 8: 'octal (0o…)', 2: 'binary (0b…)' };\n return `Must be a ${names[e['radixFormat'].radix] ?? 'based'} number`;\n }\n if (e['radixRange']) return 'Too large to edit exactly (beyond ±2^53)';\n if (e['minlength']) return `Must be at least ${e['minlength'].requiredLength} characters`;\n if (e['maxlength']) return `Must be at most ${e['maxlength'].requiredLength} characters`;\n if (e['pattern']) return `Must match ${e['pattern'].requiredPattern ?? 'the required pattern'}`;\n if (e['email']) return 'Must be a valid email address';\n if (e['uri']) return 'Must be a valid URI';\n if (e['min']) return `Must be ≥ ${e['min'].min}`;\n if (e['max']) return `Must be ≤ ${e['max'].max}`;\n if (e['multipleOf']) return `Must be a multiple of ${e['multipleOf'].multipleOf}`;\n if (e['enum']) return 'Not an allowed value';\n return 'Invalid value';\n }\n}\n","@if ('name' in leaf_) {\n @if (leaf_.type === 'string') {\n <mat-form-field [appearance]=\"fieldEditable ? 'fill' : 'outline'\">\n <mat-label>{{ leaf_.label ?? leaf_.name }}</mat-label>\n @if (leaf_.radix) {\n <!-- The bigint decimal-string carry, presented in its source base. -->\n <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [nffRadixInput]=\"leaf_.radix\" nffRadixValueType=\"string\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n } @else {\n <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n }\n <mat-error>{{ errorText }}</mat-error>\n </mat-form-field>\n } @else if (leaf_.type === 'number') {\n <mat-form-field [appearance]=\"fieldEditable ? 'fill' : 'outline'\">\n <mat-label>{{ leaf_.label ?? leaf_.name }}</mat-label>\n @if (leaf_.radix) {\n <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [nffRadixInput]=\"leaf_.radix\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n } @else {\n <input [readonly]=\"!fieldEditable\" matInput type=\"number\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n }\n <mat-error>{{ errorText }}</mat-error>\n </mat-form-field>\n } @else if (leaf_.type === 'boolean') {\n @if (fieldEditable) {\n <mat-checkbox [formControl]=\"control\">{{ leaf_.label ?? leaf_.name }}</mat-checkbox>\n } @else {\n <!-- Display-only: no formControl binding, so the wire value cannot change.\n The control itself is never disable()d — a disabled control would\n still appear in the form value with different semantics. -->\n <mat-checkbox [checked]=\"control.value === true\" disabled>{{ leaf_.label ?? leaf_.name }}</mat-checkbox>\n }\n } @else if (leaf_.type === 'enum') {\n <nff-leaf-enum-renderer [editable]=\"fieldEditable\" [leafEnum]=\"leaf_\" [control]=\"control\" [placeholder]=\"placeholder\"></nff-leaf-enum-renderer>\n }\n @if (removable && editable) {\n <button matIconButton class=\"remove-button small-icon-button\" [matTooltip]=\"'Remove ' + ('label' in leaf_ && leaf_.label ? leaf_.label : 'name' in leaf_ ? leaf_.name : 'field')\" [attr.aria-label]=\"'Remove ' + ('label' in leaf_ && leaf_.label ? leaf_.label : 'name' in leaf_ ? leaf_.name : 'field')\" (click)=\"remove.emit()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n}\n","import { Appearance } from '../types/dynamic-recursive.types';\n\n/**\n * Inline CSS declarations (property → value) for a node's `.fields` area,\n * derived from its {@link Appearance} (see the form component's\n * `fieldsLayout`) and bound via `[style]`. Also handed to a stacked\n * leaf-list's `layout` input so its entries repeat the same grid tracks.\n */\nexport type LayoutStyles = Record<string, string>;\n\n/**\n * The field-layout subset of an {@link Appearance} — the properties\n * descendants inherit, in output order. Chrome flags — `flatten`, `noBorder`,\n * `collapsed` — describe the node's own frame and never cascade.\n */\nconst INHERITED_LAYOUT_KEYS = [\n 'grid',\n 'minFieldWidth',\n 'booleanFields',\n 'minTextFieldWidth',\n 'minNumberFieldWidth',\n 'maxNumberFieldWidth',\n] as const satisfies readonly (keyof Appearance)[];\n\n/**\n * `grid` and `minFieldWidth` form one field-sizing decision: a node that sets\n * either has chosen its sizing, so neither is inherited (otherwise an\n * inherited `grid` would override the node's own `minFieldWidth` by the\n * grid-wins precedence). See {@link mergeAppearance}.\n */\nconst FIELD_SIZING_KEYS: ReadonlySet<keyof Appearance> = new Set(['grid', 'minFieldWidth']);\n\n/** `to[key] = value` keyed generically — the key–value correlation TypeScript cannot track for a union-typed key. */\nfunction assign<K extends keyof Appearance>(to: Appearance, key: K, value: Appearance[K]): void {\n to[key] = value;\n}\n\n/**\n * The subset of an `Appearance` that descendants inherit\n * ({@link INHERITED_LAYOUT_KEYS}). Null when nothing is inheritable.\n * Counterpart of {@link mergeAppearance}.\n */\nexport function inheritableAppearance(appearance: Appearance | null | undefined): Appearance | null {\n if (!appearance) return null;\n const out: Appearance = {};\n for (const key of INHERITED_LAYOUT_KEYS) {\n if (appearance[key] != null) assign(out, key, appearance[key]);\n }\n return Object.keys(out).length ? out : null;\n}\n\n/**\n * A node's effective appearance: its own settings win, layout gaps fall back\n * to `inherited` per property — except the {@link FIELD_SIZING_KEYS} pair,\n * which is only inherited as a whole when the node sets neither.\n */\nexport function mergeAppearance(\n inherited: Appearance | null | undefined,\n own: Appearance | undefined,\n): Appearance | undefined {\n if (!inherited) return own;\n const merged: Appearance = { ...own };\n const ownFieldSizing = own?.grid != null || own?.minFieldWidth != null;\n for (const key of INHERITED_LAYOUT_KEYS) {\n if (ownFieldSizing && FIELD_SIZING_KEYS.has(key)) continue;\n if (merged[key] == null && inherited[key] != null) assign(merged, key, inherited[key]);\n }\n return merged;\n}\n\n/**\n * The layout a node's descendants inherit: the layout cascading down from its\n * ancestors with the node's own `appearance` merged over it\n * ({@link mergeAppearance}), reduced to the inheritable subset\n * ({@link inheritableAppearance}).\n */\nexport function descendantLayout(\n inherited: Appearance | null | undefined,\n own: Appearance | undefined,\n): Appearance | null {\n return inheritableAppearance(mergeAppearance(inherited, own));\n}\n","import {\n AfterViewInit,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n forwardRef,\n inject,\n Input,\n OnInit,\n Output,\n QueryList,\n ViewChildren\n} from '@angular/core';\nimport { Appearance, NodeGroupList } from '../../types/dynamic-recursive.types';\nimport { FormArray, FormGroup } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { DynamicRecursiveFormComponent } from '../dynamic-recursive-form.component';\nimport { buildFormFromSchema } from '../../core/dynamic-recursive-forms-builder';\nimport { MatTooltipModule } from '@angular/material/tooltip';\n\n@Component({\n selector: 'nff-node-group-list-renderer',\n standalone: true,\n imports: [\n forwardRef(() => DynamicRecursiveFormComponent),\n MatButtonModule,\n MatIconModule,\n MatTooltipModule,\n ],\n templateUrl: './node-group-list-renderer.component.html',\n styleUrl: './node-group-list-renderer.component.scss',\n})\nexport class NodeGroupListRendererComponent implements OnInit, AfterViewInit {\n @Input() nodeGroupList!: NodeGroupList;\n @Input() initialValue!: number[] | string[] | boolean[];\n @Input() formArray = new FormArray<any>([]);\n @Input() editable: boolean = true;\n /** Forwarded to each entry's embedded form — see the form's input of the same name. */\n @Input() showAbsentOptionals = false;\n // Schema-driven bounds, matching the config editor: absent minItems floors\n // at 0 (an unbounded list can be emptied), absent maxItems is unbounded.\n @Input() minItems: number = 0;\n @Input() maxItems: number = Number.POSITIVE_INFINITY;\n /** Field-layout appearance from the enclosing group, forwarded to every item form. */\n @Input() inheritedAppearance: Appearance | null = null;\n @Output() message = new EventEmitter();\n /**\n * Emitted when the last entry of a presence (optional / advisoryRequired) list\n * is removed — the host de-materializes the whole list (→ absent). An optional\n * list has no present-empty state; a required list never routes here.\n */\n @Output() removeList = new EventEmitter<void>();\n // forwardRef: DynamicRecursiveFormComponent and this component import each\n // other, so the class reference is undefined when this query is evaluated at\n // decoration time. forwardRef defers the lookup and keeps the selector valid.\n @ViewChildren(forwardRef(() => DynamicRecursiveFormComponent))\n items!: QueryList<DynamicRecursiveFormComponent>;\n\n cdr = inject(ChangeDetectorRef);\n\n ngOnInit() {\n if (this.initialValue) {\n this.formArray.patchValue(this.initialValue);\n }\n }\n\n // Effective bounds: the schema wins when it declares them (an explicit\n // `minItems: 0` included), else the `@Input` fallback for a host that binds\n // the renderer directly. Getters, so a schema rebind is reflected live.\n get effectiveMin(): number {\n return this.nodeGroupList?.minItems ?? this.minItems;\n }\n get effectiveMax(): number {\n return this.nodeGroupList?.maxItems ?? this.maxItems;\n }\n\n /** Whether another item may be appended (below the effective maximum). */\n get canAdd(): boolean {\n return this.formArray.length < this.effectiveMax;\n }\n\n ngAfterViewInit() {\n this.items.changes.subscribe(() => {\n this.setLastEditable();\n });\n }\n\n removeItem($index: number) {\n // A presence (optional / advisoryRequired) list has no present-empty state:\n // removing its last entry de-materializes the whole list (→ absent). A\n // required (non-presence) list instead stops at its minimum, staying `[]`.\n if (this.nodeGroupList?.presence && this.formArray.length === 1) {\n this.removeList.emit();\n return;\n }\n if (this.formArray.length <= this.effectiveMin) {\n this.message.emit({\n message: `You cannot remove the last ${this.nodeGroupList.type.name} configuration!`,\n type: 'error',\n })\n return;\n }\n this.formArray.removeAt($index);\n }\n\n addItem = (index?: number) => {\n if (this.formArray.length >= this.effectiveMax) return;\n this.formArray.push(buildFormFromSchema(this.nodeGroupList.type, null));\n }\n\n setLastEditable() {\n const lastItem = this.items.last;\n if (lastItem) {\n lastItem.editable.set(true);\n }\n this.cdr.detectChanges();\n }\n\n asFormGroup(group: any) {\n return group as FormGroup;\n }\n\n getTitle($index: number) {\n let title = `${this.nodeGroupList.type.label ?? this.nodeGroupList.type.name}`;\n if (this.formArray.length > 1) {\n return `${title} #${$index + 1}`;\n }\n else {\n return title;\n }\n\n }\n}\n","@if (formArray && nodeGroupList) {\n <div class=\"fields-container\">\n @for (group of formArray.controls; track $index) {\n <div class=\"field-item\">\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"inheritedAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [schema]=\"nodeGroupList.type\"\n [formGroup]=\"asFormGroup(group)\"\n [title]=\"getTitle($index)\"\n [index]=\"0\"\n [removable]=\"formArray.length > effectiveMin\"\n (remove)=\"removeItem($index)\"\n [editable]=\"editable\"\n [addButtonCallback]=\"canAdd ? addItem : null\"\n [addButtonLabel]=\"'Add ' + (nodeGroupList.type.label ?? nodeGroupList.type.name) + ' #' + (formArray.length + 1)\"\n />\n </div>\n }\n @if (editable && formArray.length === 0 && canAdd) {\n <!-- An empty list has no per-item header to host the add button, so it\n would otherwise be an unrecoverable dead end. This footer add\n creates the first item (mirrors the config editor's \"Add … #1\"). -->\n <button\n matButton=\"outlined\"\n class=\"empty-add-button\"\n [matTooltip]=\"'Add ' + (nodeGroupList.type.label ?? nodeGroupList.type.name)\"\n (click)=\"addItem()\"\n >\n <mat-icon>add</mat-icon> Add {{ nodeGroupList.type.label ?? nodeGroupList.type.name }} #1\n </button>\n }\n </div>\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { AnonLeaf, LeafList } from '../../types/dynamic-recursive.types';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatButtonModule } from '@angular/material/button';\nimport { RadixInputDirective } from '../radix-input/radix-input.directive';\n\n@Component({\n selector: 'nff-anon-leaf-renderer',\n standalone: true,\n imports: [\n ReactiveFormsModule,\n MatFormFieldModule,\n MatSelectModule,\n MatIconModule,\n MatCheckboxModule,\n MatInputModule,\n MatButtonModule,\n RadixInputDirective,\n ],\n templateUrl: './anon-leaf-renderer.component.html',\n styleUrl: './anon-leaf-renderer.component.scss',\n})\nexport class AnonLeafRendererComponent {\n /** The item's shape: a bare `{ type }`, or the whole leafList for its items. */\n @Input() AnonLeaf!: AnonLeaf | LeafList;\n @Input() initialValue!: string;\n @Input() control = new FormControl();\n @Input() removable: boolean = false;\n @Input() editable: boolean = true;\n @Input() index!: number;\n @Output() remove = new EventEmitter();\n @Input() label!: string;\n\n emitRemoveEvent() {\n this.remove.emit();\n }\n\n /** The items' display base, when the leafList carries one. */\n get radix(): 2 | 8 | 16 | undefined {\n return 'radix' in this.AnonLeaf ? this.AnonLeaf.radix : undefined;\n }\n}\n","<div class=\"anon-leaf-container\">\n@if (AnonLeaf.type === 'string') {\n <mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ label }} #{{ index + 1}}</mat-label>\n @if (radix) {\n <!-- The bigint decimal-string carry, presented in its source base. -->\n <input [readonly]=\"!editable\"\n [nffRadixInput]=\"radix\" nffRadixValueType=\"string\"\n [formControl]=\"control\"\n matInput type=\"text\" >\n } @else {\n <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"text\" >\n }\n </mat-form-field>\n} @else if (AnonLeaf.type === 'number') {\n <mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ label }} #{{ index + 1}}</mat-label>\n @if (radix) {\n <input [readonly]=\"!editable\"\n [nffRadixInput]=\"radix\"\n [formControl]=\"control\"\n matInput type=\"text\">\n } @else {\n <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"number\">\n }\n </mat-form-field>\n} @else if (AnonLeaf.type === 'boolean') {\n @if (editable) {\n <mat-checkbox [formControl]=\"control\">value</mat-checkbox>\n } @else {\n <!-- Display-only: no formControl binding, so the wire value cannot change. -->\n <mat-checkbox [checked]=\"control.value === true\" disabled>value</mat-checkbox>\n }\n}\n @else if (AnonLeaf.type === 'enum' && 'enum' in AnonLeaf) {\n <mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ label }} #{{ index + 1}}</mat-label>\n @if (editable) {\n <mat-select [formControl]=\"control\">\n @for (option of (AnonLeaf.type === 'enum' ? AnonLeaf.enum : []); track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-select>\n } @else {\n <mat-select [value]=\"control.value\" disabled>\n @for (option of (AnonLeaf.type === 'enum' ? AnonLeaf.enum : []); track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-select>\n }\n </mat-form-field>\n}\n</div>\n","import { Component, EventEmitter, HostBinding, inject, Input, OnInit, Output } from '@angular/core';\nimport { LayoutStyles } from '../../core/appearance';\nimport { LeafList } from '../../types/dynamic-recursive.types';\nimport { FormControl } from '@angular/forms';\nimport { MatIconModule } from '@angular/material/icon';\nimport { AnonLeafRendererComponent } from '../anon-leaf-renderer/anon-leaf-renderer.component';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatPrefix } from '@angular/material/input';\nimport { MatTooltip } from '@angular/material/tooltip';\n\n@Component({\n selector: 'nff-leaf-list-renderer',\n standalone: true,\n imports: [\n MatIconModule,\n AnonLeafRendererComponent,\n MatButtonModule,\n MatPrefix,\n MatTooltip,\n ],\n templateUrl: './leaf-list-renderer.component.html',\n styleUrl: './leaf-list-renderer.component.scss',\n})\nexport class LeafListRendererComponent implements OnInit {\n @Input() leaf_!: LeafList;\n @Input() initialValue!: number[] | string[] | boolean[];\n @Input() formArray!: any;\n @Input() editable: boolean = true;\n // Schema-driven bounds: absent `minItems` floors at 0 (an unbounded list can\n // be emptied), absent `maxItems` is unbounded. Read from the schema in\n // ngOnInit so a bare `[leaf_]` binding honors them without extra wiring.\n @Input() minItems: number = 0;\n @Input() maxItems: number = Number.POSITIVE_INFINITY;\n /**\n * The parent group's grid layout (its `fieldsLayout` styles). A stacked list\n * spans the parent's full row, so its entries repeat the same tracks and\n * stay aligned with the columns above; an inline (single-entry) list sits in\n * one track and ignores it.\n */\n @Input() layout: LayoutStyles | null = null;\n @Output() message = new EventEmitter();\n /**\n * Emitted from the empty-list remove button when the list is a presence list —\n * the host removes the whole list (de-materializes it, → absent). Only wired\n * for a `presence` `leafList`; the parent maps it to `setNodePresence`.\n */\n @Output() removeList = new EventEmitter<void>();\n\n matDialog = inject(MatDialog);\n\n /**\n * Take a full-width row of its own once the array holds more than one entry.\n * A multi-entry array grows vertically as its items wrap; sitting inline next\n * to a regular leaf that would stretch the leaf to match. On its own line it\n * cannot. Consumed by the `:host(.stacked)` rule.\n */\n @HostBinding('class.stacked')\n get stacked(): boolean {\n return (this.formArray?.length ?? 0) > 1;\n }\n\n /** The entries' value type as a host class, so type-scoped min-widths (`--nff-min-*-field-width`) can target them. */\n @HostBinding('class')\n get typeClass(): string {\n return `list-type-${this.leaf_?.type ?? 'unknown'}`;\n }\n\n /** Applies {@link layout} to the host (the entries' container) while stacked. */\n @HostBinding('style')\n get hostLayout(): LayoutStyles | null {\n return this.stacked ? this.layout : null;\n }\n\n ngOnInit() {\n if (this.initialValue) {\n this.formArray.patchValue(this.initialValue);\n }\n }\n\n // Effective bounds: the schema wins when it declares them (an explicit\n // `minItems: 0` included), else the `@Input` fallback for a host that binds\n // the renderer directly. Getters, so a schema rebind is reflected live.\n get effectiveMin(): number {\n return this.leaf_?.minItems ?? this.minItems;\n }\n get effectiveMax(): number {\n return this.leaf_?.maxItems ?? this.maxItems;\n }\n\n /** Whether another item may be appended (below the effective maximum). */\n get canAdd(): boolean {\n return (this.formArray?.length ?? 0) < this.effectiveMax;\n }\n\n removeItem($index: number) {\n // A presence (optional / advisoryRequired) list has no present-empty state:\n // removing its last entry de-materializes the whole list (→ absent). A\n // required (non-presence) list instead stops at its minimum, staying `[]`.\n if (this.leaf_?.presence && this.formArray.length === 1) {\n this.removeList.emit();\n return;\n }\n if (this.formArray.length <= this.effectiveMin) {\n this.message.emit({\n message: 'You cannot remove the last item!',\n type: 'error',\n })\n return;\n }\n this.formArray.removeAt($index);\n }\n\n addItem() {\n if (this.formArray.length >= this.effectiveMax) return;\n this.formArray.push(new FormControl());\n }\n}\n","@if (formArray && leaf_) {\n @for (control of formArray.controls; track $index) {\n <div class=\"field-item\">\n <nff-anon-leaf-renderer\n [AnonLeaf]=\"leaf_\" [control]=\"control\"\n [removable]=\"formArray.length > effectiveMin\"\n [index]=\"$index\"\n [editable]=\"editable\"\n [label]=\"leaf_.label ?? leaf_.name\"\n (remove)=\"removeItem($index)\"\n />\n @if (editable) {\n <div class=\"actions\">\n @if (formArray.length > effectiveMin) {\n <button class=\"remove-button small-icon-button\" matIconButton [matTooltip]=\"'Remove ' + (leaf_.label ?? leaf_.name) + ' item'\" [attr.aria-label]=\"'Remove ' + (leaf_.label ?? leaf_.name) + ' item'\" (click)=\"removeItem($index)\">\n <mat-icon matPrefix>delete</mat-icon>\n </button>\n }\n @if ($last && canAdd) {\n <button class=\"add-button small-icon-button\" matIconButton [matTooltip]=\"'Add ' + (leaf_.label ?? leaf_.name) + ' item'\" [attr.aria-label]=\"'Add ' + (leaf_.label ?? leaf_.name) + ' item'\" (click)=\"addItem()\">\n <mat-icon matPrefix>add</mat-icon>\n </button>\n }\n <div class=\"actions-spacer\"></div>\n </div>\n }\n </div>\n }\n @if (editable && formArray.length === 0 && canAdd) {\n <!-- A required (non-presence) list can be present-but-empty; this labeled\n affordance adds the first entry so an empty list is not a dead end\n (mirrors the node-group list's \"Add … #1\"). A presence list never\n renders empty here — its first entry appears on materialize, and\n removing the last entry de-materializes it. -->\n <button\n matButton=\"outlined\"\n class=\"empty-add-button\"\n [attr.aria-label]=\"'Add ' + (leaf_.label ?? leaf_.name) + ' item'\"\n (click)=\"addItem()\"\n >\n <mat-icon>add</mat-icon> Add {{ leaf_.label ?? leaf_.name }} item\n </button>\n }\n}\n","import { FormArray, FormControl, FormGroup } from '@angular/forms';\n\nexport function asFormControl(control: any) {\n return control as FormControl;\n}\n\nexport function asFormArray(control: any) {\n return control as FormArray;\n}\n\nexport function asFormGroup(control: any) {\n return control as FormGroup;\n}\n\n","import { Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { Appearance, Leaf, LeafList, NodeGroup, NodeGroupList, NodeMap } from '../../types/dynamic-recursive.types';\nimport { descendantLayout } from '../../core/appearance';\nimport { addMapEntry, removeMapEntry, renameMapEntry } from '../../core/dynamic-recursive-forms-builder';\nimport { asFormArray, asFormControl, asFormGroup } from '../../core/utils';\nimport { LeafRendererComponent } from '../leaf-renderer/leaf-renderer.component';\nimport { LeafListRendererComponent } from '../leaf-list-renderer/leaf-list-renderer.component';\nimport { NodeGroupListRendererComponent } from '../node-group-list-renderer/node-group-list-renderer.component';\nimport { DynamicRecursiveFormComponent } from '../dynamic-recursive-form.component';\n\n/**\n * Renders a {@link NodeMap}: an open, arbitrary-keyed record. Each entry is a row\n * with an editable key and the shared value schema's control; the user can add,\n * remove, and rename entries. The map's control is a `FormGroup` whose control\n * names are the entry keys, so the key is edited as a *rename* (remove + re-add\n * the same control) committed on blur — see {@link renameEntry}.\n */\n@Component({\n selector: 'nff-node-map-renderer',\n standalone: true,\n imports: [\n MatButtonModule,\n MatIconModule,\n MatFormFieldModule,\n MatInputModule,\n MatTooltip,\n LeafRendererComponent,\n LeafListRendererComponent,\n NodeGroupListRendererComponent,\n // node-map-renderer references itself (a map-valued map) and the form (a\n // group-valued map), which import each other; forwardRef breaks the cycles.\n forwardRef(() => NodeMapRendererComponent),\n forwardRef(() => DynamicRecursiveFormComponent),\n ],\n templateUrl: './node-map-renderer.component.html',\n styleUrl: './node-map-renderer.component.scss',\n})\nexport class NodeMapRendererComponent implements OnChanges {\n @Input() nodeMap!: NodeMap;\n @Input() formGroup = new FormGroup<any>({});\n @Input() editable = true;\n /** Forwarded to each entry's embedded form — see the form's input of the same name. */\n @Input() showAbsentOptionals = false;\n /** Field-layout appearance from the enclosing group, forwarded to group-valued entry forms. */\n @Input() inheritedAppearance: Appearance | null = null;\n\n /** Ordered view of entry keys, kept stable across renames (`addControl` appends). */\n entryKeys: string[] = [];\n\n ngOnChanges(changes: SimpleChanges): void {\n // Re-sync whenever the bound group changes: a host may rebind the renderer\n // to another map (e.g. the tree editor swapping documents) while this\n // component instance survives.\n if (changes['formGroup']) this.entryKeys = Object.keys(this.formGroup.controls);\n }\n\n /**\n * What entry forms inherit: the enclosing group's layout with the map's own\n * `appearance` merged over it. Counterpart of the config editor's map-entry\n * threading in `buildChildNode`.\n */\n get entryAppearance(): Appearance | null {\n return descendantLayout(this.inheritedAppearance, this.nodeMap?.appearance);\n }\n\n /** The value schema as a leaf (used when `value.kind === 'leaf'`). */\n get valueLeaf(): Leaf {\n return this.nodeMap.value as Leaf;\n }\n /** The value schema as a group (used when `value.kind === 'nodeGroup'`). */\n get valueGroup(): NodeGroup {\n return this.nodeMap.value as NodeGroup;\n }\n /** Narrowing casts for the complex value kinds the template renders. */\n protected asLeafList(v: unknown): LeafList {\n return v as LeafList;\n }\n protected asNodeGroupList(v: unknown): NodeGroupList {\n return v as NodeGroupList;\n }\n protected asNodeMap(v: unknown): NodeMap {\n return v as NodeMap;\n }\n\n get atMax(): boolean {\n return this.nodeMap.maxEntries != null && this.entryKeys.length >= this.nodeMap.maxEntries;\n }\n get atMin(): boolean {\n return this.nodeMap.minEntries != null && this.entryKeys.length <= this.nodeMap.minEntries;\n }\n\n /** Append a new entry under a unique placeholder key. Delegates to {@link addMapEntry}. */\n addEntry(): void {\n const key = addMapEntry(this.formGroup, this.nodeMap);\n if (key != null) this.entryKeys = [...this.entryKeys, key];\n }\n\n /** Drop an entry (its control leaves the group, so it drops from the value). Delegates to {@link removeMapEntry}. */\n removeEntry(key: string): void {\n if (removeMapEntry(this.formGroup, this.nodeMap, key)) {\n this.entryKeys = this.entryKeys.filter((k) => k !== key);\n }\n }\n\n /**\n * Commit an edited key by renaming its control once (the value is preserved).\n * An empty, unchanged, duplicate, or `keyPattern`-violating key is a no-op,\n * leaving the entry under its current name. Delegates to {@link renameMapEntry}.\n */\n renameEntry(oldKey: string, rawKey: string): void {\n if (renameMapEntry(this.formGroup, this.nodeMap, oldKey, rawKey)) {\n const newKey = rawKey.trim();\n this.entryKeys = this.entryKeys.map((k) => (k === oldKey ? newKey : k));\n }\n }\n\n protected readonly asFormControl = asFormControl;\n protected readonly asFormGroup = asFormGroup;\n protected readonly asFormArray = asFormArray;\n}\n","@if (formGroup && nodeMap) {\n <div class=\"map-node\">\n @for (key of entryKeys; track key) {\n <div class=\"map-entry\">\n <mat-form-field class=\"key-field\" [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ nodeMap.keyLabel ?? 'Key' }}</mat-label>\n <!-- On a rejected rename (empty, duplicate, keyPattern violation) the\n input snaps back to the committed key, so the display never\n disagrees with the key getRawValue() will emit. -->\n <input\n matInput\n #keyInput\n [readonly]=\"!editable\"\n [value]=\"key\"\n (change)=\"renameEntry(key, keyInput.value); keyInput.value = key\"\n >\n </mat-form-field>\n\n <!-- Index access, not .get(): entry keys are arbitrary runtime data and\n .get() would split a key like 'web.example.com' into a dotted path. -->\n <div class=\"value-field\">\n @if (nodeMap.value.kind === 'leaf') {\n <nff-leaf-renderer\n [leaf_]=\"valueLeaf\"\n [control]=\"asFormControl(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'nodeGroup') {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"entryAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [schema]=\"valueGroup\"\n [formGroup]=\"asFormGroup(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'leafList') {\n <nff-leaf-list-renderer\n [leaf_]=\"asLeafList(nodeMap.value)\"\n [formArray]=\"formGroup.controls[key]\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'nodeGroupList') {\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"entryAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [nodeGroupList]=\"asNodeGroupList(nodeMap.value)\"\n [formArray]=\"asFormArray(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'map') {\n <nff-node-map-renderer\n [inheritedAppearance]=\"entryAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [nodeMap]=\"asNodeMap(nodeMap.value)\"\n [formGroup]=\"asFormGroup(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n }\n <!-- A choice-valued map (additionalProperties: anyOf/oneOf) has no\n standalone bare-choice renderer; use the config editor for it. -->\n </div>\n\n @if (editable && !atMin) {\n <button class=\"remove-button small-icon-button\" matIconButton [matTooltip]=\"'Remove ' + key + ' entry'\" [attr.aria-label]=\"'Remove ' + key + ' entry'\" (click)=\"removeEntry(key)\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\n @if (editable && !atMax) {\n <button class=\"add-button small-icon-button\" matIconButton [matTooltip]=\"'Add ' + (nodeMap.label ?? nodeMap.name) + ' entry'\" [attr.aria-label]=\"'Add ' + (nodeMap.label ?? nodeMap.name) + ' entry'\" (click)=\"addEntry()\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n}\n","import { Component, computed, forwardRef, input, model, OnInit, output } from '@angular/core';\nimport { LeafRendererComponent } from './leaf-renderer/leaf-renderer.component';\nimport { Appearance, CASE_KEY, Leaf, NodeChoice, NodeGroup, NodeType } from '../types/dynamic-recursive.types';\nimport { inheritableAppearance, LayoutStyles, mergeAppearance } from '../core/appearance';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { NodeGroupListRendererComponent } from './node-group-list-renderer/node-group-list-renderer.component';\nimport { LeafListRendererComponent } from './leaf-list-renderer/leaf-list-renderer.component';\nimport { NodeMapRendererComponent } from './node-map-renderer/node-map-renderer.component';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { asFormArray, asFormControl, asFormGroup } from '../core/utils';\nimport { formatRadix } from './radix-input/radix-input.directive';\nimport {\n caseDisplayLabels, buildControl, caseFields, setNodePresence, switchChoiceCase } from '../core/dynamic-recursive-forms-builder';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatSelectModule } from '@angular/material/select';\n\n/**\n * A grid track count from `appearance.grid`: positive finite counts floored,\n * anything else (absent, zero, negative, non-finite) is 0 — so a bogus `cols`\n * cannot half-enter grid mode (e.g. suppress the rows-only column flow).\n */\nfunction gridTrackCount(count: number | undefined): number {\n return Number.isFinite(count) && count! > 0 ? Math.floor(count!) : 0;\n}\n\n@Component({\n imports: [\n LeafRendererComponent,\n LeafListRendererComponent,\n // node-group-list-renderer and node-map-renderer import this component back\n // (list items and map values may be groups); forwardRef tolerates either\n // module-evaluation order for the cycle.\n forwardRef(() => NodeGroupListRendererComponent),\n forwardRef(() => NodeMapRendererComponent),\n ReactiveFormsModule,\n MatExpansionModule,\n MatIconModule,\n MatButtonModule,\n NgTemplateOutlet,\n MatCheckboxModule,\n MatFormFieldModule,\n MatSelectModule,\n MatTooltip,\n ],\n selector: 'nff-dynamic-recursive-form',\n standalone: true,\n styleUrl: './dynamic-recursive-form.component.scss',\n templateUrl: './dynamic-recursive-form.component.html',\n})\nexport class DynamicRecursiveFormComponent implements OnInit {\n /** The form-description schema to render (a root or nested `NodeGroup`). */\n readonly schema = input.required<NodeGroup>();\n /** Optional value object to seed the form; keyed by the schema's `children` keys. */\n readonly initialValue = input<Record<string, unknown> | null>(null);\n /** The reactive group this form binds to. Defaults to an empty group. */\n readonly formGroup = input<FormGroup>(new FormGroup({}));\n /** Index of this form within a parent list, used by `addButtonCallback`. */\n readonly index = input<number | null>(null);\n /** Whether this form may be removed from a parent list (shows a remove control). */\n readonly removable = input<boolean>(false);\n /** Emitted when the user removes this form from a parent list. */\n readonly remove = output<void>();\n /** Card/section title; falls back to the schema label or name. */\n readonly title = input<string>();\n /** Whether fields accept input. Two-way: also toggled by the built-in edit control. */\n readonly editable = model<boolean>(false);\n /**\n * Preview absent optional (presence) leaves as **ghost fields**: the field\n * renders read-only and empty — its schema `default`, if any, shown as the\n * placeholder — with a (+) button that incorporates it into the form, so the\n * user sees the complete form surface. A ghost holds **no control in the\n * form**: it never appears in `value`/`getRawValue()`/`serializeForm` output\n * and never affects validity until incorporated. Replaces the default\n * \"Add <field>\" button affordance; ignored while the form is not editable\n * (read-only mode hides structural affordances, ghosts included).\n */\n readonly showAbsentOptionals = input<boolean>(false);\n /** Invoked with {@link index} to append a new sibling form to a parent list. */\n readonly addButtonCallback = input<((index: number) => void) | null>(null);\n /**\n * Label for the add-sibling button — the parent list names the appended\n * entry (\"Add Cell #3\"), which this form cannot derive itself (it knows\n * neither the list's label nor its length). Falls back to\n * \"Add new <own label>\".\n */\n readonly addButtonLabel = input<string | null>(null);\n /**\n * Key of a presence leaf whose field should grab focus when it renders — lets\n * a host that added the control itself (e.g. the tree editor's optionals\n * menu) hand focus to the new field, like the form's own add button does.\n */\n readonly focusLeaf = input<string | null>(null);\n /**\n * Field-layout appearance cascading down from the parent group. The node's\n * own `appearance` wins per property — see {@link mergeAppearance}.\n */\n readonly inheritedAppearance = input<Appearance | null>(null);\n\n /** True when the schema is a root group (rendered flat, without a wrapping card). */\n readonly root = computed(() => this.schema().root ?? false);\n\n /** The node's own `appearance` with inherited layout gaps filled in. */\n protected readonly effectiveAppearance = computed<Appearance | undefined>(() =>\n mergeAppearance(this.inheritedAppearance(), this.schema().appearance),\n );\n\n /** The layout subset this node's children inherit. */\n protected readonly childAppearance = computed<Appearance | null>(() =>\n inheritableAppearance(this.effectiveAppearance()),\n );\n\n /**\n * The per-type width bounds are flex-flow-only, and their CSS custom\n * properties inherit into leaf-list internals that the grid-mode resets\n * cannot reach across the encapsulation boundary — so under a grid layout\n * the variables are simply not set at all.\n */\n private flexOnly<T>(value: T | undefined): T | null {\n return this.fieldsLayout() ? null : (value ?? null);\n }\n\n /** `minTextFieldWidth` for the `.fields` CSS custom property, or null. */\n protected readonly textFieldMin = computed(() => this.flexOnly(this.effectiveAppearance()?.minTextFieldWidth));\n /** `minNumberFieldWidth` for the `.fields` CSS custom property, or null. */\n protected readonly numberFieldMin = computed(() => this.flexOnly(this.effectiveAppearance()?.minNumberFieldWidth));\n /** `maxNumberFieldWidth` for the `.fields` CSS custom property, or null. */\n protected readonly numberFieldMax = computed(() => this.flexOnly(this.effectiveAppearance()?.maxNumberFieldWidth));\n\n /**\n * True when the active grid defines explicit column tracks. Only then can a\n * stacked leaf-list meaningfully span the row (`grid-column: 1 / -1`\n * resolves `-1` to line 1 without an explicit column template) and repeat\n * the tracks for its entries; in a rows-only grid the list stays a normal\n * auto-flowed item.\n */\n protected readonly gridHasCols = computed(() => !!this.fieldsLayout()?.['grid-template-columns']);\n\n /**\n * Inline grid styles for the `.fields` area, from `appearance`: `grid`\n * becomes explicit tracks (`cols` fields per row; `rows` alone fills\n * top-to-bottom, adding columns as needed) and `minFieldWidth` becomes\n * as-many-as-fit equal columns of at least that width. `grid` wins over\n * `minFieldWidth`; with neither, `null` keeps the stylesheet's wrapping\n * flex flow. Non-positive `rows`/`cols` are ignored.\n */\n protected readonly fieldsLayout = computed<LayoutStyles | null>(() => {\n const appearance = this.effectiveAppearance();\n const cols = gridTrackCount(appearance?.grid?.cols);\n const rows = gridTrackCount(appearance?.grid?.rows);\n if (cols > 0 || rows > 0) {\n const layout: LayoutStyles = { display: 'grid' };\n if (cols > 0) layout['grid-template-columns'] = `repeat(${cols}, minmax(0, 1fr))`;\n if (rows > 0) layout['grid-template-rows'] = `repeat(${rows}, auto)`;\n if (rows > 0 && cols === 0) {\n layout['grid-auto-flow'] = 'column';\n // The columns this flow creates are implicit; without a bound they\n // size to content and can overflow — match the cols-mode tracks.\n layout['grid-auto-columns'] = 'minmax(0, 1fr)';\n }\n return layout;\n }\n if (appearance?.minFieldWidth) {\n // min(…, 100%) keeps a narrow container to one column instead of overflowing.\n return {\n display: 'grid',\n 'grid-template-columns': `repeat(auto-fit, minmax(min(${appearance.minFieldWidth}, 100%), 1fr))`,\n };\n }\n return null;\n });\n\n /**\n * Whether the gathered boolean row would show anything: a plain boolean, an\n * enabled presence boolean, or (while editable) an absent one's add button.\n * Keeps a read-only form from rendering an empty `.boolean-fields` div,\n * which would add a stray container gap.\n */\n protected booleanAreaVisible(): boolean {\n return Object.entries(this.schema().children ?? {}).some(\n ([key, child]) =>\n child.kind === 'leaf' &&\n child.type === 'boolean' &&\n (!child.presence || !!this.formGroup().get(key) || this.editable()),\n );\n }\n\n /**\n * Whether a leaf renders in the regular `.fields` flow: always, unless it is\n * a boolean that {@link booleanPlacement} gathers into the `.boolean-fields`\n * row instead.\n */\n protected inFieldFlow(child: Leaf): boolean {\n return this.booleanPlacement() === 'default' || child.type !== 'boolean';\n }\n\n /**\n * Where `appearance.booleanFields` places the checkbox fields: `'beginning'`\n * or `'end'` renders them grouped in the `.boolean-fields` row and excludes\n * them from the regular field flow; `'default'` (also when the group has no\n * boolean leaf to move) leaves the flow untouched.\n */\n protected readonly booleanPlacement = computed<'beginning' | 'end' | 'default'>(() => {\n const placement = this.effectiveAppearance()?.booleanFields ?? 'default';\n if (placement === 'default') return 'default';\n const hasBooleans = Object.values(this.schema().children ?? {}).some(\n (child) => child.kind === 'leaf' && child.type === 'boolean',\n );\n return hasBooleans ? placement : 'default';\n });\n\n ngOnInit() {\n const initial = this.initialValue();\n if (initial) {\n const group = this.formGroup();\n // Presence keys carried by the initial value need controls first:\n // patchValue silently skips keys that have none, dropping the data.\n for (const [key, child] of Object.entries(this.schema().children ?? {})) {\n if ('presence' in child && child.presence && key in initial && !group.get(key)) {\n group.addControl(key, buildControl(child, initial[key]) as never);\n }\n }\n group.patchValue(initial);\n }\n }\n\n protected get nodeGroupChildrenList(): Array<{ key: string; value: NodeType }> {\n const children = this.schema().children ?? {};\n return Object.entries(children).map(([key, value]) => ({\n key,\n value: value as NodeType,\n }));\n }\n\n protected emitRemoveEvent() {\n this.remove.emit();\n }\n\n /** The key of the presence leaf the user just enabled; its field grabs focus when rendered. */\n protected presenceFocusKey: string | null = null;\n\n /**\n * Add or remove a presence node's control on this form — any presence kind:\n * group, leaf, map, or choice. Removing it drops the key from `form.value`;\n * adding it builds the control fresh from its schema (nested presence\n * children start absent). Delegates to {@link setNodePresence}, the\n * host-callable primitive.\n */\n toggleNodePresence(key: string, schema: NodeType, present: boolean) {\n setNodePresence(this.formGroup(), schema, key, present);\n // Either way the key's ghost stand-in is stale: drop it, so a later\n // re-ghosting renders a pristine one even if the old instance was mutated.\n this.ghostControls.delete(key);\n }\n\n /**\n * The detached stand-in control a ghost field renders against. Never added\n * to {@link formGroup} — that detachment is the whole guarantee: a ghost\n * cannot reach `value`, `getRawValue()`, or validity. Always `null`-valued\n * (the schema default shows as a placeholder instead, see\n * {@link ghostPlaceholder}); cached per key so change detection re-reads a\n * stable instance.\n */\n protected ghostControl(key: string): FormControl {\n let control = this.ghostControls.get(key);\n if (!control) {\n control = new FormControl(null);\n this.ghostControls.set(key, control);\n }\n return control;\n }\n private readonly ghostControls = new Map<string, FormControl>();\n\n /**\n * A ghost field's placeholder: the leaf's `default`, or empty — spelled in\n * the leaf's `radix` when it has one, matching how the incorporated field\n * will display it.\n */\n protected ghostPlaceholder(schema: Leaf): string {\n if (!('default' in schema) || schema.default == null) return '';\n const radix = 'radix' in schema ? schema.radix : undefined;\n const integral =\n typeof schema.default === 'number'\n ? Number.isInteger(schema.default)\n : typeof schema.default === 'string' && /^[-+]?[0-9]+$/.test(schema.default);\n if (radix && integral) return formatRadix(schema.default as number | string, radix);\n return String(schema.default);\n }\n\n /**\n * {@link toggleNodePresence} for a presence leaf, additionally focusing the\n * rendered field when the toggle just created it.\n */\n toggleLeafPresence(key: string, schema: Leaf, present: boolean) {\n const had = !!this.formGroup().get(key);\n this.toggleNodePresence(key, schema, present);\n if (present && !had) {\n this.presenceFocusKey = key;\n // Retire the request once the field has rendered and taken focus, so a\n // later re-creation of the same renderer cannot steal focus again.\n setTimeout(() => {\n if (this.presenceFocusKey === key) this.presenceFocusKey = null;\n });\n }\n if (!present && this.presenceFocusKey === key) this.presenceFocusKey = null;\n }\n\n /**\n * Materialize an absent presence (optional / `advisoryRequired`) list *with\n * its first entry* — clicking \"Add <list>\" makes the first entry appear at\n * once. An optional list has no present-empty state: removing the last entry\n * de-materializes it (→ absent). A required list is always present instead and\n * uses the renderer's own \"Add item\" affordance, so it never routes here.\n */\n addPresenceList(key: string, schema: NodeType) {\n setNodePresence(this.formGroup(), schema, key, true, [null]);\n this.ghostControls.delete(key);\n }\n\n protected objectKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj);\n }\n\n /** The active case name of a choice control, or null if none is selected. */\n protected activeCase(key: string): string | null {\n return (this.formGroup().get(key) as FormGroup | null)?.get(CASE_KEY)?.value ?? null;\n }\n\n /**\n * A synthetic flattened NodeGroup used to render the active case's fields\n * against the choice's FormGroup. Carries the choice's own `appearance`\n * (grid / field-width layout) onto the case fields.\n */\n protected caseAsGroup(choice: NodeChoice, caseName: string): NodeGroup {\n return {\n kind: 'nodeGroup',\n name: choice.name,\n children: choice.cases[caseName] ? caseFields(choice.cases[caseName]) : {},\n appearance: { ...choice.appearance, flatten: true },\n };\n }\n\n /**\n * The display label for a case: the schema's `caseLabels` entry (colliding\n * labels disambiguated by their distinguishing fields — see\n * {@link caseDisplayLabels}), else the case name.\n */\n caseLabel(choice: NodeChoice, caseName: string): string {\n return caseDisplayLabels(choice)[caseName] ?? caseName;\n }\n\n /**\n * A copy of a group flagged to render its fields inline (no inner panel). Used\n * for a presence group's body, whose container is the presence panel itself, so\n * the group's own section panel would be a redundant second box.\n */\n protected flatGroup(group: NodeGroup): NodeGroup {\n return { ...group, appearance: { ...group.appearance, flatten: true } };\n }\n\n /** Swap a choice's field controls when the selected case changes. Delegates to {@link switchChoiceCase}. */\n switchCase(key: string, choice: NodeChoice, caseName: string) {\n switchChoiceCase(this.formGroup().get(key) as FormGroup, choice, caseName);\n }\n\n protected readonly asFormGroup = asFormGroup;\n protected readonly asFormArray = asFormArray;\n protected readonly asFormControl = asFormControl;\n}\n","<!-- Checkbox fields grouped by appearance.booleanFields: a compact wrapping\n row of natural-width items, rendered before or after the field flow. -->\n<ng-template #booleanArea>\n @if (booleanAreaVisible()) {\n <div class=\"boolean-fields\">\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && child.type == 'boolean') {\n @if (!child.presence) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=false\n [editable]=\"editable()\"\n />\n } @else if (formGroup().get(childItem.key)) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=true\n [editable]=\"editable()\"\n [autofocus]=\"presenceFocusKey === childItem.key || focusLeaf() === childItem.key\"\n (remove)=\"toggleLeafPresence(childItem.key, child, false)\"\n />\n } @else if (editable()) {\n @if (showAbsentOptionals()) {\n <!-- Ghost preview of an absent boolean: unchecked, display-only,\n no control in the form; (+) incorporates it. -->\n <div class=\"ghost-field\">\n <nff-leaf-renderer\n [leaf_]=child\n [control]=\"ghostControl(childItem.key)\"\n [removable]=false\n [editable]=false\n />\n <button\n matIconButton\n class=\"ghost-add small-icon-button\"\n [matTooltip]=\"'Add ' + (child.label ?? child.name)\"\n [attr.aria-label]=\"'Add ' + (child.label ?? child.name)\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n } @else {\n <button\n matButton=\"outlined\"\n class=\"presence-leaf-add\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n }\n }\n </div>\n }\n</ng-template>\n<!-- The node's scalar-field area — gathered booleans (beginning), the .fields\n flow, gathered booleans (end) — shared by the root and non-root branches. -->\n<ng-template #fieldFlow>\n @if (booleanPlacement() === 'beginning') {\n <ng-container *ngTemplateOutlet=\"booleanArea\"></ng-container>\n }\n <div class=\"fields\" [class.grid-fields]=\"!!fieldsLayout()\" [class.grid-cols]=\"gridHasCols()\" [style]=\"fieldsLayout()\" [style.--nff-min-text-field-width]=\"textFieldMin()\" [style.--nff-min-number-field-width]=\"numberFieldMin()\" [style.--nff-max-number-field-width]=\"numberFieldMax()\">\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && !child.presence && inFieldFlow(child)) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=false\n [editable]=\"editable()\"\n />\n }\n }\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leafList' && !child.presence) {\n <nff-leaf-list-renderer\n [layout]=\"gridHasCols() ? fieldsLayout() : null\"\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n />\n }\n @else if (child.kind == 'leafList' && child.presence) {\n <!-- Optional (advisoryRequired) list: an \"Add <list>\" button while\n absent; clicking it materializes the list with its first entry (no\n empty state). Removing the last entry de-materializes it (the\n renderer's `removeList` → absent). -->\n @let leafListArray = asFormArray(formGroup().get(childItem.key));\n @if (leafListArray) {\n <div class=\"presence-list\">\n <nff-leaf-list-renderer\n [layout]=\"gridHasCols() ? fieldsLayout() : null\"\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"leafListArray\"\n (removeList)=\"toggleNodePresence(childItem.key, child, false)\"\n />\n </div>\n } @else if (editable()) {\n <button\n matButton=\"outlined\"\n class=\"presence-list-add\"\n (click)=\"addPresenceList(childItem.key, child)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n }\n <!-- Presence leaves trail the regular fields so their add buttons don't\n interrupt the field flow; an enabled one keeps its trailing spot. -->\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && child.presence && inFieldFlow(child)) {\n @if (formGroup().get(childItem.key)) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=true\n [editable]=\"editable()\"\n [autofocus]=\"presenceFocusKey === childItem.key || focusLeaf() === childItem.key\"\n (remove)=\"toggleLeafPresence(childItem.key, child, false)\"\n />\n } @else if (editable()) {\n <!-- Read-only mode renders nothing for an absent presence leaf:\n the key is simply absent, and add affordances are hidden\n like every other structural control. -->\n @if (showAbsentOptionals()) {\n <!-- Ghost preview: the field itself, read-only against a detached\n null control (never part of the form value), default as\n placeholder; (+) incorporates it. -->\n <div class=\"ghost-field\">\n <nff-leaf-renderer\n [leaf_]=child\n [control]=\"ghostControl(childItem.key)\"\n [removable]=false\n [editable]=false\n [placeholder]=\"ghostPlaceholder(child)\"\n />\n <button\n matIconButton\n class=\"ghost-add small-icon-button\"\n [matTooltip]=\"'Add ' + (child.label ?? child.name)\"\n [attr.aria-label]=\"'Add ' + (child.label ?? child.name)\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n } @else {\n <button\n matButton=\"outlined\"\n class=\"presence-leaf-add\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n }\n }\n </div>\n @if (booleanPlacement() === 'end') {\n <ng-container *ngTemplateOutlet=\"booleanArea\"></ng-container>\n }\n</ng-template>\n@if (!root()) {\n <ng-template #formRender>\n <div class=\"form-content\" [formGroup]=\"formGroup()\">\n <div class=\"leafs-container\">\n <ng-container *ngTemplateOutlet=\"fieldFlow\"></ng-container>\n </div>\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'nodeGroup' && child.presence) {\n <div class=\"presence-group\">\n <mat-checkbox\n [checked]=\"!!formGroup().get(childItem.key)\"\n [disabled]=\"!editable()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n @if (formGroup().get(childItem.key)) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"flatGroup(child)\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [editable]=\"editable()\"\n />\n }\n </div>\n }\n @else if (child.kind == 'nodeGroup') {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"child\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n }\n @else if (child.kind == 'choice') {\n @let choiceGroup = asFormGroup(formGroup().get(childItem.key));\n @let selectedCase = activeCase(childItem.key);\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!choiceGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!choiceGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (choiceGroup) {\n <div class=\"choice-group\">\n <mat-form-field [appearance]=\"editable() ? 'fill' : 'outline'\">\n <mat-label>Selected option</mat-label>\n <mat-select\n [value]=\"activeCase(childItem.key)\"\n (selectionChange)=\"switchCase(childItem.key, child, $event.value)\"\n >\n @for (caseName of objectKeys(child.cases); track caseName) {\n <mat-option [value]=\"caseName\">{{ caseLabel(child, caseName) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (selectedCase) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"caseAsGroup(child, selectedCase)\"\n [formGroup]=\"choiceGroup\"\n [editable]=\"editable()\"\n />\n }\n </div>\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList' && !child.presence) {\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n }\n @else if (child.kind == 'nodeGroupList' && child.presence) {\n <!-- Optional (advisoryRequired) list: an \"Add <list>\" button while\n absent; clicking it materializes the list with its first entry.\n Removing the last entry de-materializes it (`removeList` → absent). -->\n @let presenceListArray = asFormArray(formGroup().get(childItem.key));\n @if (presenceListArray) {\n <div class=\"presence-list\">\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"presenceListArray\"\n [editable]=\"editable()\"\n (removeList)=\"toggleNodePresence(childItem.key, child, false)\"\n />\n </div>\n } @else if (editable()) {\n <button\n matButton=\"outlined\"\n class=\"presence-list-add\"\n (click)=\"addPresenceList(childItem.key, child)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n @else if (child.kind == 'map') {\n @let mapGroup = asFormGroup(formGroup().get(childItem.key));\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!mapGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!mapGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (mapGroup) {\n <nff-node-map-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeMap]=\"child\"\n [formGroup]=\"mapGroup\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n }\n </div>\n </ng-template>\n @if (schema().appearance?.flatten) {\n <div class=\"flattened-form\">\n <ng-container *ngTemplateOutlet=\"formRender\"></ng-container>\n <div class=\"flattened-actions\">\n @if (editable() && index() != null && addButtonCallback() != null) {\n <button matIconButton [matTooltip]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" [attr.aria-label]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" class=\"add-button small-icon-button\" (click)=\"addButtonCallback()!(index()!)\">\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && removable()) {\n <button matIconButton class=\"remove-button small-icon-button\" matTooltip=\"Remove {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'Remove ' + (schema().label ?? schema().name)\" (click)=\"emitRemoveEvent(); $event.stopPropagation()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </div>\n }\n @else {\n <mat-expansion-panel class=\"node-section\" [expanded]=\"!schema().appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title class=\"config-form-subsection-card\">\n {{ title() ?? schema().label ?? schema().name }}\n </mat-panel-title>\n <mat-panel-description class=\"section-actions\">\n <button matIconButton class=\"small-icon-button\" [class]=\"{ 'edit-icon': !editable() }\" [attr.aria-label]=\"editable() ? 'Stop editing' : 'Edit'\" (click)=\"editable.set(!editable()); $event.stopPropagation()\">\n <mat-icon>edit</mat-icon>\n </button>\n @if (editable() && index() != null && addButtonCallback() != null) {\n <button matIconButton [matTooltip]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" [attr.aria-label]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" class=\"add-button small-icon-button\" (click)=\"addButtonCallback()!(index()!); $event.stopPropagation()\">\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && removable()) {\n <button matIconButton class=\"remove-button small-icon-button\" matTooltip=\"Remove {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'Remove ' + (schema().label ?? schema().name)\" (click)=\"emitRemoveEvent(); $event.stopPropagation()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </mat-panel-description>\n </mat-expansion-panel-header>\n <ng-container *ngTemplateOutlet=\"formRender\"></ng-container>\n </mat-expansion-panel>\n }\n} @else {\n <div class=\"form-content\" [formGroup]=\"formGroup()\">\n <div class=\"leafs-container\">\n <!-- The edit toggle sits on its own row: inline it would offset the\n first field row against the rows below (flex) or claim a whole\n track (grid). -->\n <div class=\"form-toolbar\">\n <button matIconButton class=\"small-icon-button\" [class]=\"{ 'edit-icon': !editable() }\" [attr.aria-label]=\"editable() ? 'Stop editing' : 'Edit'\" (click)=\"editable.set(!editable())\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"fieldFlow\"></ng-container>\n </div>\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'choice') {\n @let choiceGroup = asFormGroup(formGroup().get(childItem.key));\n @let selectedCase = activeCase(childItem.key);\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!choiceGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!choiceGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (choiceGroup) {\n <div class=\"choice-group\">\n <mat-form-field [appearance]=\"editable() ? 'fill' : 'outline'\">\n <mat-label>Selected option</mat-label>\n <mat-select\n [value]=\"activeCase(childItem.key)\"\n (selectionChange)=\"switchCase(childItem.key, child, $event.value)\"\n >\n @for (caseName of objectKeys(child.cases); track caseName) {\n <mat-option [value]=\"caseName\">{{ caseLabel(child, caseName) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (selectedCase) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"caseAsGroup(child, selectedCase)\"\n [formGroup]=\"choiceGroup\"\n [editable]=\"editable()\"\n />\n }\n </div>\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'map') {\n @let mapGroup = asFormGroup(formGroup().get(childItem.key));\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!mapGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!mapGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (mapGroup) {\n <nff-node-map-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeMap]=\"child\"\n [formGroup]=\"mapGroup\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList' && !child.presence) {\n <!-- A nodeGroupList has no `appearance` of its own, so its section is\n always shown; only an ancestor's collapse hides it. -->\n <mat-expansion-panel class=\"node-section\" [expanded]=\"true\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>{{ child.label ?? child.name }}</mat-panel-title>\n </mat-expansion-panel-header>\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList' && child.presence) {\n <!-- Optional (advisoryRequired) list: an \"Add <list>\" button while\n absent; clicking it materializes the list with its first entry.\n Removing the last entry de-materializes it (`removeList` → absent). -->\n @let rootListArray = asFormArray(formGroup().get(childItem.key));\n @if (rootListArray) {\n <div class=\"presence-list\">\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"rootListArray\"\n [editable]=\"editable()\"\n (removeList)=\"toggleNodePresence(childItem.key, child, false)\"\n />\n </div>\n } @else if (editable()) {\n <button\n matButton=\"outlined\"\n class=\"presence-list-add\"\n (click)=\"addPresenceList(childItem.key, child)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n @else if (child.kind == 'nodeGroup' && child.presence) {\n <mat-expansion-panel class=\"node-section\" togglePosition=\"before\" [expanded]=\"!!formGroup().get(childItem.key)\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-checkbox\n [checked]=\"!!formGroup().get(childItem.key)\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (formGroup().get(childItem.key)) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"flatGroup(child)\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroup') {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"child\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n }\n }\n </div>\n}\n","import { ChangeDetectorRef, Component, effect, ElementRef, inject, input, model, OnDestroy, untracked } from '@angular/core';\nimport { AbstractControl, FormArray, FormGroup } from '@angular/forms';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { Appearance, CASE_KEY, NodeChoice, NodeGroup, NodeMap, NodeType } from '../types/dynamic-recursive.types';\nimport { descendantLayout } from '../core/appearance';\nimport {\n addMapEntry,\n buildControl,\n buildFormFromSchema,\n caseDisplayLabels,\n caseFields,\n removeMapEntry,\n renameMapEntry,\n setNodePresence,\n switchChoiceCase,\n} from '../core/dynamic-recursive-forms-builder';\nimport { DynamicRecursiveFormComponent } from '../dynamic-recursive-form/dynamic-recursive-form.component';\nimport { NodeMapRendererComponent } from '../dynamic-recursive-form/node-map-renderer/node-map-renderer.component';\n\n/**\n * The transformers package names a root nobody named `__root__` — a sentinel,\n * not display text (the packages share no code, so the string is matched here\n * verbatim). The tree substitutes {@link ROOT_FALLBACK_TITLE} for it; any\n * other root name is an authored one and displays as-is.\n */\nconst ROOT_SENTINEL = '__root__';\nconst ROOT_FALLBACK_TITLE = 'Configuration';\n\n/** Metadata on a list-container node that lets the tree add items to its FormArray. */\ninterface ListRef {\n array: FormArray;\n itemSchema: NodeGroup;\n itemLabel: string;\n minItems: number;\n maxItems?: number;\n}\n\n/** An absent optional (presence) child, offered by its parent node's \"+ Optional field\" menu. */\ninterface OptionalEntry {\n key: string;\n schema: NodeType;\n label: string;\n}\n\n/**\n * One flat section of the detail pane. The selected node's subtree renders as a\n * pre-order list of these — no nesting chrome: each section after the first is\n * separated by a breadcrumb heading (`trail`), and holds only the node's *own*\n * fields (`schema` is a leaf-only slice; complex children are sections of their\n * own, deeper in the list).\n */\ninterface DetailSection {\n node: TreeNode;\n /** Selected-node-to-here trail, rendered as the section's breadcrumb heading (omitted on the first section). */\n trail: TreeNode[];\n /** Leaf-only slice of the node's own schema, or null when it has no own fields. */\n schema: NodeGroup | null;\n /** The group `schema` binds to (the node's group; for a choice, the choice group). */\n group: FormGroup | null;\n /** A trailing add-control section of a list / complex map: renders after the last item, with no heading. */\n footer?: boolean;\n /** The section continues a run of same-list items / same-map entries: its heading draws no divider line. */\n continuation?: boolean;\n}\n\n/**\n * A navigable node in the config tree. Its `id` is the node's stable path from\n * the root (`system/ntp`, `ifaces/0`, `servers/web1`), so expansion and\n * selection survive tree rebuilds. Segments are `%`/`/`-escaped, since map\n * entry keys are arbitrary runtime data; list-item identity is positional.\n */\ninterface TreeNode {\n id: string;\n label: string;\n children: TreeNode[];\n /** The node's own FormGroup, or null for a list-container or map node. */\n group: FormGroup | null;\n /** The node's own schema, set on group-backed nodes (groups, list items, group-valued map entries). */\n schema?: NodeGroup;\n /** Present on a nodeGroupList node: lets a `+` add an item. */\n list?: ListRef;\n /** Present on a list-item node: its current index in the parent list (removal goes through the parent list array). */\n removable?: { index: number };\n /** Absent optional children of this node, offered by its \"+ Optional field\" menu (schema order). */\n optionals?: OptionalEntry[];\n /** Present on a present optional child node: drives the row's remove control. */\n presenceRemovable?: { key: string; schema: NodeType };\n /** Field-layout appearance inherited from ancestor groups, for the node's detail-section form. */\n inherited?: Appearance | null;\n /** Present on a choice node: the choice schema and its FormGroup (holding `__case` + the active case's fields). */\n choice?: { schema: NodeChoice; group: FormGroup };\n /** Present on a map node. `complex` maps expand entries as child nodes. */\n map?: { schema: NodeMap; group: FormGroup; complex: boolean };\n /** Present on a complex-map entry node: addresses the entry in its map for remove/rename. */\n mapEntry?: { mapGroup: FormGroup; mapSchema: NodeMap; key: string };\n}\n\n/**\n * A tree/detail editor for a schema-built form: the structure (groups, lists,\n * maps, choices) is a tree on the left, and selecting a node renders that\n * node's **entire subtree** on the right as a **flat list of sections** — the\n * node's own fields first, then every descendant's fields, each separated by a\n * breadcrumb heading (`Service / Deploy scope / …`) instead of nested panels.\n * Leaf fields render through {@link DynamicRecursiveFormComponent} with a\n * leaf-only schema slice; choice selectors, map rows, and add controls render\n * inline in their section. The tree adds row conveniences of its own: `+` on\n * list and map rows, a delete control on removable rows, and a\n * \"+ Optional field\" menu for absent presence children.\n *\n * The tree is **derived state**: any structural change to the form — made\n * through the tree rows or through the detail sections — triggers a rebuild (a\n * cheap shape signature over `valueChanges` detects it). Node ids are stable\n * paths, so expansion and selection survive rebuilds. Swapping the `schema` or\n * `formGroup` input rebinds the editor to the new pair, resetting expansion\n * and selection.\n *\n * The component draws no outer container — only a divider between the tree and\n * detail panes — so the embedding client owns the surrounding chrome.\n */\n@Component({\n selector: 'nff-config-editor',\n standalone: true,\n imports: [\n NgTemplateOutlet,\n MatIconModule,\n MatButtonModule,\n MatMenuModule,\n MatFormFieldModule,\n MatInputModule,\n MatSelectModule,\n MatTooltip,\n DynamicRecursiveFormComponent,\n NodeMapRendererComponent,\n ],\n templateUrl: './config-editor.component.html',\n styleUrl: './config-editor.component.scss',\n})\nexport class ConfigEditorComponent implements OnDestroy {\n /** The form-description schema whose structure the tree renders. */\n readonly schema = input.required<NodeGroup>();\n /** The schema-built reactive group the editor binds to and mutates. */\n readonly formGroup = input.required<FormGroup>();\n /**\n * Whether fields accept input and structural controls (add/remove/menus)\n * show. Two-way bindable: the root tree row carries a toggle, so the editor\n * can flip it itself and the host observes the change.\n */\n readonly editable = model<boolean>(true);\n /**\n * Title for the root tree row and breadcrumb origin, overriding the schema's\n * own `label`/`name`. Read when the tree is (re)built, so a later change\n * shows on the next rebind or structural rebuild, not immediately.\n */\n readonly rootTitle = input<string>();\n /**\n * Whether selecting a tree row also expands the node's own children.\n * Off by default: a click selects (the detail pane shows the subtree\n * anyway) and the twisty alone controls expansion, so browsing a deep\n * config does not keep unfolding the tree. Ancestors of the selection are\n * always expanded — the selected row itself must stay visible.\n */\n readonly expandOnClick = input<boolean>(false);\n /**\n * Whether the detail pane shows its top breadcrumb (the selected node's\n * path, with the member remove control beside it). Hosts whose tree\n * already tells the user where they are can turn it off — the section\n * trail headings inside the detail stay, and member removal remains\n * available on the tree rows and section headings.\n */\n readonly showBreadcrumb = input<boolean>(true);\n\n root!: TreeNode;\n selected: TreeNode | null = null;\n /** The selected subtree as a flat, breadcrumb-separated section list. */\n sections: DetailSection[] = [];\n /** Root-to-selection trail for the detail-pane breadcrumb, computed once per selection. */\n breadcrumb: TreeNode[] = [];\n readonly expanded = new Set<string>();\n\n private shape = '';\n private changes?: Subscription;\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly cdr = inject(ChangeDetectorRef);\n /** Stable per-instance ids for the shape signature, so replacing a control (setControl) reads as a structural change. */\n private readonly controlIds = new WeakMap<AbstractControl, number>();\n private controlIdSeq = 0;\n\n constructor() {\n // Rebind whenever the schema or form inputs change (a host loading another\n // config document): derived state resets against the new pair. Wrapped in\n // untracked so only the two inputs re-trigger the effect.\n effect(() => {\n const schema = this.schema();\n const group = this.formGroup();\n untracked(() => this.attach(schema, group));\n });\n }\n\n ngOnDestroy() {\n this.changes?.unsubscribe();\n }\n\n /** Bind the editor to a schema/form pair: fresh tree, root selection, and shape-sync subscription. */\n private attach(schema: NodeGroup, group: FormGroup): void {\n this.changes?.unsubscribe();\n this.expanded.clear();\n this.root = this.buildTree(schema, group, this.rootLabelOf(schema), '');\n this.shape = this.shapeOf(group);\n this.expanded.add(this.root.id);\n this.select(this.root);\n // Any change to the bound form — whether from the detail sections or from\n // an external holder of the same FormGroup — must reach the detail pane.\n // Leaf inputs self-heal (the reactive ValueAccessor writes the new value\n // synchronously), but the pane's own non-reactive displays (the case\n // selector, a map entry's key) are one-shot bindings; mark the view so\n // they re-read under OnPush and zoneless change detection. A shape change\n // additionally rebuilds the tree.\n this.changes = group.valueChanges.subscribe(() => {\n this.cdr.markForCheck();\n this.syncShape();\n });\n }\n\n /**\n * Force the editor to re-read the bound form. A leaf field normally reflects\n * an external `setValue` on its own — the reactive value accessor writes the\n * value synchronously, no change detection needed — so this is only for the\n * corners that bypass that: a structural change made with\n * `{ emitEvent: false }` (the tree wouldn't otherwise rebuild), a non-reactive\n * display (the case selector, a map key) that needs re-reading, or a host\n * whose change detector was detached during the mutation.\n *\n * It re-syncs the tree structure and **tears down and recreates** the detail\n * sections, so every rendered control rebinds to the live form and re-pulls\n * its current value — even a field whose bound input somehow missed the\n * external write.\n */\n refresh(): void {\n this.syncShape(); // structural changes (added/removed/renamed controls)\n const selected = this.selected;\n this.sections = []; // tear the embedded detail forms down…\n this.cdr.detectChanges();\n if (selected) this.select(selected, false); // …and rebuild them, fresh-bound\n this.cdr.detectChanges();\n }\n\n select(node: TreeNode, reveal = true) {\n this.selected = node;\n // Sections that would render only their breadcrumb heading (a composite\n // node with no leaf fields and no chrome) are dropped: their children get\n // sections of their own, whose trails carry the full path anyway.\n this.sections = this.markContinuations(\n this.buildSections(node, []).filter((s, i) => i === 0 || this.sectionHasContent(s)),\n );\n this.breadcrumb = this.pathTo(node);\n // Navigating retires any pending just-added-leaf focus request.\n this.focusSectionId = null;\n this.focusLeafKey = null;\n // Reveal the selection: expand every ancestor so the row is visible —\n // and the node itself only under `expandOnClick` (the detail pane shows\n // its subtree regardless). Structural re-syncs pass reveal=false — they\n // must not re-expand what the user collapsed.\n if (reveal) {\n for (const crumb of this.breadcrumb) {\n if (crumb !== node) this.expanded.add(crumb.id);\n else if (this.expandOnClick() && this.hasExpandableContent(crumb)) this.expanded.add(crumb.id);\n }\n }\n }\n\n /**\n * Root-to-`target` path for the detail-pane breadcrumb (inclusive of both ends),\n * or an empty array if `target` is not in the current tree.\n */\n pathTo(target: TreeNode): TreeNode[] {\n const walk = (node: TreeNode, trail: TreeNode[]): TreeNode[] | null => {\n const here = [...trail, node];\n if (node === target) return here;\n for (const child of node.children) {\n const found = walk(child, here);\n if (found) return found;\n }\n return null;\n };\n return this.root ? (walk(this.root, []) ?? []) : [];\n }\n\n protected toggle(node: TreeNode) {\n if (this.expanded.has(node.id)) this.expanded.delete(node.id);\n else this.expanded.add(node.id);\n }\n\n /** Keyboard access for tree rows: Enter/Space selects, ArrowRight expands, ArrowLeft collapses. */\n protected onRowKeydown(event: KeyboardEvent, node: TreeNode) {\n // Keys pressed on the row's inner buttons keep their own meaning.\n if (event.target !== event.currentTarget) return;\n switch (event.key) {\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.select(node);\n break;\n case 'ArrowRight':\n if (this.hasExpandableContent(node) && !this.expanded.has(node.id)) {\n event.preventDefault();\n this.expanded.add(node.id);\n }\n break;\n case 'ArrowLeft':\n if (this.expanded.has(node.id)) {\n event.preventDefault();\n this.expanded.delete(node.id);\n }\n break;\n }\n }\n\n /** Whether the row shows an expand twisty: it has child rows to reveal (children or an optionals menu row). */\n protected hasExpandableContent(node: TreeNode): boolean {\n return node.children.length > 0 || (this.editable() && !!node.optionals?.length);\n }\n\n /**\n * Whether the node's form subtree holds a validation error. Group/choice, list,\n * and map nodes each check their backing control; `invalid` aggregates over\n * descendants, so an error anywhere below lights every ancestor row.\n */\n protected hasError(node: TreeNode): boolean {\n return !!(node.group?.invalid || node.list?.array.invalid || node.map?.group.invalid);\n }\n\n /**\n * Append a new item to a list node's FormArray (up to `maxItems`). A tree-row\n * add selects the new item; a detail-pane add passes `keepSelection` so the\n * current (possibly ancestor) view stays put and the item appears as a new\n * section in it.\n */\n addItem(listNode: TreeNode, keepSelection = false) {\n const list = listNode.list;\n if (!list) return;\n if (list.maxItems != null && list.array.length >= list.maxItems) return;\n list.array.push(buildFormFromSchema(list.itemSchema));\n if (keepSelection) this.selectByPath(this.selected?.id ?? '', false);\n else this.selectByPath(this.join(listNode.id, String(list.array.length - 1)));\n }\n\n /**\n * Remove a list item from its FormArray (down to `minItems`). List-item\n * identity is positional, so expansion state under the list is cleared —\n * otherwise it would silently migrate to the items that shift into the\n * removed indexes.\n */\n removeItem(listNode: TreeNode, item: TreeNode, keepSelection = false) {\n if (!listNode.list || !item.removable) return;\n if (listNode.list.array.length <= listNode.list.minItems) return;\n for (const id of [...this.expanded]) {\n if (id.startsWith(`${listNode.id}/`)) this.expanded.delete(id);\n }\n listNode.list.array.removeAt(item.removable.index);\n // A detail-pane remove keeps the (ancestor) selection; a tree-row remove\n // moves to the list and returns focus to its row.\n if (keepSelection) {\n this.selectByPath(this.selected?.id ?? '', false);\n return;\n }\n this.selectByPath(listNode.id);\n this.focusSelectedRow();\n }\n\n /** The just-added optional leaf (section path + key) whose field grabs focus when rendered. */\n protected focusSectionId: string | null = null;\n protected focusLeafKey: string | null = null;\n\n /** Add an absent optional child from the menu: build its control and select the node it lands on. */\n addOptional(node: TreeNode, entry: OptionalEntry) {\n if (!node.group || !setNodePresence(node.group, entry.schema, entry.key, true)) return;\n // A leaf renders in the parent's detail pane; complex kinds become tree nodes.\n this.selectByPath(entry.schema.kind === 'leaf' ? node.id : this.join(node.id, entry.key));\n // Adding the last optional removes the menu row that held focus.\n if (entry.schema.kind !== 'leaf') this.focusSelectedRow();\n if (entry.schema.kind === 'leaf') {\n // Set after selection (select() retires any pending request): the new\n // field should grab focus, like the form's own add button. Retired after\n // a tick so later re-renders of the section cannot steal focus again.\n this.focusSectionId = node.id;\n this.focusLeafKey = entry.key;\n setTimeout(() => {\n if (this.focusLeafKey === entry.key) {\n this.focusSectionId = null;\n this.focusLeafKey = null;\n }\n });\n }\n }\n\n /** Remove a present optional child node, returning its entry to the parent's menu. */\n removeOptional(parent: TreeNode, node: TreeNode) {\n const removable = node.presenceRemovable;\n if (!removable || !parent.group) return;\n setNodePresence(parent.group, removable.schema, removable.key, false);\n this.selectByPath(parent.id);\n this.focusSelectedRow();\n }\n\n /** The active case name of a choice node, or null when none is selected. */\n activeCase(node: TreeNode): string | null {\n return (node.choice?.group.get(CASE_KEY)?.value as string | null) ?? null;\n }\n\n /** The display label of a choice node's active case, or null when no case is selected. */\n activeCaseLabel(node: TreeNode): string | null {\n const c = node.choice;\n const active = this.activeCase(node);\n return c && active ? this.caseLabel(c.schema, active) : null;\n }\n\n /**\n * The display label for a case: the schema's `caseLabels` entry (colliding\n * labels disambiguated by their distinguishing fields — see\n * {@link caseDisplayLabels}), else the case name.\n */\n protected caseLabel(choice: NodeChoice, caseName: string): string {\n return caseDisplayLabels(choice)[caseName] ?? caseName;\n }\n\n /**\n * Switch a choice node's active case from its detail selector; the\n * structural sync rebuilds the tree and sections. The tree selection stays\n * where it is: detail edits must never steal it, or a flattened ancestor\n * view would collapse to the choice node mid-edit. Selection moves only\n * through the tree itself.\n */\n switchTreeCase(node: TreeNode, caseName: string) {\n const c = node.choice;\n if (!c) return;\n switchChoiceCase(c.group, c.schema, caseName);\n this.selectByPath(this.selected?.id ?? node.id, false);\n }\n\n protected objectKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj);\n }\n\n /**\n * Append a new entry to a complex map node under a generated unique key. A\n * tree-row add selects the new entry; a detail-pane add passes\n * `keepSelection` so the current view stays put (see {@link addItem}).\n */\n addTreeMapEntry(mapNode: TreeNode, keepSelection = false) {\n const m = mapNode.map;\n if (!m) return;\n const key = addMapEntry(m.group, m.schema);\n if (key == null) return;\n if (keepSelection) this.selectByPath(this.selected?.id ?? '', false);\n else this.selectByPath(this.join(mapNode.id, key));\n }\n\n /** Remove a complex map entry (down to `minEntries`). */\n removeTreeMapEntry(mapNode: TreeNode, entryNode: TreeNode, keepSelection = false) {\n const m = mapNode.map;\n const e = entryNode.mapEntry;\n if (!m || !e || !removeMapEntry(m.group, m.schema, e.key)) return;\n if (keepSelection) {\n this.selectByPath(this.selected?.id ?? '', false);\n return;\n }\n this.selectByPath(mapNode.id);\n this.focusSelectedRow();\n }\n\n /**\n * Commit a rename-on-blur of a map entry's key; on success the selection is\n * remapped to the entry's new identity when it pointed at (or inside) the\n * entry — otherwise it stays put — and the fresh key field regains focus\n * (the rename re-renders the section under a new id, destroying the input\n * that held focus).\n */\n renameTreeMapEntry(entryNode: TreeNode, rawKey: string) {\n const e = entryNode.mapEntry;\n if (!e) return;\n // Captured before the mutation: the rename's structural sync reconciles\n // the selection against the stale id (falling back to an ancestor) before\n // this method can remap it.\n const selectedId = this.selected?.id ?? '';\n if (renameMapEntry(e.mapGroup, e.mapSchema, e.key, rawKey)) {\n const parentPath = entryNode.id.slice(0, entryNode.id.lastIndexOf('/'));\n const newId = this.join(parentPath, rawKey.trim());\n // The entry's descendants keep their expansion under the new identity.\n for (const id of [...this.expanded]) {\n if (id === entryNode.id || id.startsWith(`${entryNode.id}/`)) {\n this.expanded.delete(id);\n this.expanded.add(newId + id.slice(entryNode.id.length));\n }\n }\n // Selection is remapped, not moved: it follows the rename only when it\n // sat on the entry (or inside it); an ancestor view stays put.\n const followed =\n selectedId === entryNode.id || selectedId.startsWith(`${entryNode.id}/`)\n ? newId + selectedId.slice(entryNode.id.length)\n : selectedId;\n this.selectByPath(followed, false);\n // Deferred so the rebuilt section's key field exists before focusing.\n setTimeout(() => this.host.nativeElement.querySelector<HTMLElement>('.detail .key-field input')?.focus());\n }\n }\n\n /** Move keyboard focus to the selected tree row once the action's re-render settles. */\n private focusSelectedRow(): void {\n setTimeout(() => this.host.nativeElement.querySelector<HTMLElement>('.tree-row.selected')?.focus());\n }\n\n /** A muted hint for a section whose node currently renders no content of its own. */\n /**\n * Explains a group's `minPresent`/`maxPresent` violation next to the red\n * tree marker: the fix is enabling or removing optional fields, which is not\n * evident from any single field's own error.\n */\n protected presentRangeHint(s: DetailSection): string | null {\n const errors = s.node.group?.errors;\n const min = errors?.['minPresent'];\n if (min) {\n const noun = min.required === 1 ? 'field' : 'fields';\n return `At least ${min.required} ${noun} must be set (${min.actual} set) — add from the optional-fields menu.`;\n }\n const max = errors?.['maxPresent'];\n if (max) return `At most ${max.allowed} of these fields may be set (${max.actual} set).`;\n return null;\n }\n\n protected emptySectionHint(s: DetailSection): string | null {\n const n = s.node;\n if (n.list && !n.children.length) return `No ${n.list.itemLabel} items.`;\n if (n.map?.complex && !n.children.length) return 'No entries.';\n if (n.map && !n.map.complex && !Object.keys(n.map.group.controls).length && !this.editable()) {\n return 'No entries.';\n }\n return null;\n }\n\n /** Whether a list node is at `maxItems` (the add control is hidden). */\n protected listAtMax(node: TreeNode | undefined): boolean {\n const l = node?.list;\n return !!l && l.maxItems != null && l.array.length >= l.maxItems;\n }\n\n /** Whether a list node is at `minItems` (item remove controls are hidden). */\n protected listAtMin(node: TreeNode | undefined): boolean {\n const l = node?.list;\n return !!l && l.array.length <= l.minItems;\n }\n\n /** Whether a map node is at `maxEntries` (the add control is hidden). */\n protected mapAtMax(node: TreeNode | undefined): boolean {\n const m = node?.map;\n return !!m && m.schema.maxEntries != null && Object.keys(m.group.controls).length >= m.schema.maxEntries;\n }\n\n /** Whether a map node is at `minEntries` (entry remove controls are hidden). */\n protected mapAtMin(node: TreeNode | undefined): boolean {\n const m = node?.map;\n return !!m && m.schema.minEntries != null && Object.keys(m.group.controls).length <= m.schema.minEntries;\n }\n\n // --- derived-tree maintenance ----------------------------------------------\n\n /** Rebuild the tree from the current form structure if its shape changed. */\n private syncShape(): void {\n const shape = this.shapeOf(this.formGroup());\n if (shape === this.shape) return;\n this.rebuild();\n this.reconcileSelection();\n }\n\n /**\n * A cheap structural signature of a control tree: group keys (plus the active\n * `__case`), array lengths, leaf placeholders. Value edits don't change it;\n * added/removed/renamed controls and case switches do. Reading `__case` from\n * any group is safe because the name is reserved (the builder rejects it as a\n * case field name or map entry key), so only choice groups carry it.\n */\n private shapeOf(control: AbstractControl): string {\n if (control instanceof FormGroup) {\n const inner = Object.keys(control.controls)\n .sort()\n .map((k) => `${k}:${this.shapeOf(control.controls[k])}`)\n .join(',');\n const active = control.get(CASE_KEY)?.value;\n return `{#${this.uidOf(control)}${typeof active === 'string' ? `=${active};` : ''}${inner}}`;\n }\n if (control instanceof FormArray) {\n return `[#${this.uidOf(control)}${control.controls.map((c) => this.shapeOf(c)).join(',')}]`;\n }\n return '.';\n }\n\n /** The instance id a container contributes to the shape signature. */\n private uidOf(control: AbstractControl): number {\n let id = this.controlIds.get(control);\n if (id == null) {\n id = ++this.controlIdSeq;\n this.controlIds.set(control, id);\n }\n return id;\n }\n\n /** Root row title: host override, else schema label, else its name — with the {@link ROOT_SENTINEL} swapped for a generic title. */\n private rootLabelOf(schema: NodeGroup): string {\n return this.rootTitle() ?? schema.label ?? (schema.name === ROOT_SENTINEL ? ROOT_FALLBACK_TITLE : schema.name);\n }\n\n /** Rebuild the whole tree from schema + form and refresh the shape signature. */\n private rebuild(): void {\n const schema = this.schema();\n this.root = this.buildTree(schema, this.formGroup(), this.rootLabelOf(schema), '');\n this.shape = this.shapeOf(this.formGroup());\n }\n\n /** Re-point `selected` at the rebuilt tree: same path, else the closest surviving ancestor. */\n private reconcileSelection(): void {\n this.selectByPath(this.selected?.id ?? '', false);\n }\n\n /** The node at `path` in the current tree, or null. Walks by id-prefix segments. */\n private byPath(path: string): TreeNode | null {\n if (path === this.root.id) return this.root;\n const walk = (node: TreeNode): TreeNode | null => {\n for (const child of node.children) {\n if (child.id === path) return child;\n if (path.startsWith(child.id + '/')) return walk(child);\n }\n return null;\n };\n return walk(this.root);\n }\n\n /** Select the node at `path`, falling back through its ancestors to the root. */\n private selectByPath(path: string, reveal = true): void {\n let target = this.byPath(path);\n let trimmed = path;\n while (!target && trimmed.includes('/')) {\n trimmed = trimmed.slice(0, trimmed.lastIndexOf('/'));\n target = this.byPath(trimmed);\n }\n this.select(target ?? this.root, reveal);\n }\n\n /**\n * Flatten a subtree into detail sections, pre-order: the node's own fields\n * first, then each child as its own breadcrumb-headed section. No nesting\n * chrome — the headings are the boundaries between children.\n */\n private buildSections(node: TreeNode, trail: TreeNode[]): DetailSection[] {\n const here = [...trail, node];\n const list: DetailSection[] = [{ node, trail: here, ...this.sectionContent(node) }];\n for (const child of node.children) list.push(...this.buildSections(child, here));\n // A list's / complex map's add control trails its items — appending\n // belongs after the last member, not under the container's heading.\n if (node.list || node.map?.complex) {\n list.push({ node, trail: here, schema: null, group: null, footer: true });\n }\n return list;\n }\n\n /**\n * Whether a section renders anything beyond its heading: a leaf slice, the\n * chrome of its node kind (case selector, key field, add controls), or a\n * present-children error that needs explaining. Heading-only sections are\n * dropped from the flat list — a divider with nothing under it is clutter.\n */\n private sectionHasContent(s: DetailSection): boolean {\n if (s.footer) return true;\n const n = s.node;\n // A non-empty list / complex map's leading section would hold only its\n // heading (the add control lives in the footer): drop it — the items'\n // trails carry the container in their breadcrumbs.\n return !!(\n s.schema ||\n n.choice ||\n n.mapEntry ||\n (n.map && !n.map.complex) ||\n this.emptySectionHint(s) ||\n this.presentRangeHint(s)\n );\n }\n\n /** Every expandable node currently expanded — drives the root row's expand/collapse-all toggle. */\n protected allExpanded(): boolean {\n let all = true;\n const walk = (node: TreeNode): void => {\n if (!all) return;\n if (this.hasExpandableContent(node) && !this.expanded.has(node.id)) all = false;\n for (const child of node.children) walk(child);\n };\n walk(this.root);\n return all;\n }\n\n /**\n * Expand every expandable node, or collapse back when all are open. The\n * collapse keeps the root open — a tree reduced to one row reads as empty.\n */\n protected toggleExpandAll(): void {\n if (this.allExpanded()) {\n this.expanded.clear();\n this.expanded.add(this.root.id);\n return;\n }\n const walk = (node: TreeNode): void => {\n if (this.hasExpandableContent(node)) this.expanded.add(node.id);\n for (const child of node.children) walk(child);\n };\n walk(this.root);\n }\n\n /** The selected member's container (list / map), for the breadcrumb's remove control. */\n protected selectedMemberParent(): TreeNode | null {\n if (!this.selected || !(this.selected.removable || this.selected.mapEntry)) return null;\n return this.breadcrumb.length > 1 ? (this.breadcrumb[this.breadcrumb.length - 2] ?? null) : null;\n }\n\n /** The section node's container (list / map), for member controls in its heading. */\n protected memberParent(s: DetailSection): TreeNode | null {\n return s.trail.length > 1 ? (s.trail[s.trail.length - 2] ?? null) : null;\n }\n\n /**\n * Flag the sections that continue a run of siblings — a list item or map\n * entry whose preceding section is inside the same container. Their headings\n * draw no divider line, so a run of same-kind members reads as one list\n * rather than a stack of separated blocks.\n */\n private markContinuations(sections: DetailSection[]): DetailSection[] {\n for (let i = 1; i < sections.length; i++) {\n const s = sections[i];\n if (s.footer || !(s.node.removable || s.node.mapEntry)) continue;\n const containerId = s.node.id.slice(0, s.node.id.lastIndexOf('/'));\n const prev = sections[i - 1].node.id;\n if (prev === containerId || prev.startsWith(`${containerId}/`)) s.continuation = true;\n }\n return sections;\n }\n\n /** A section's own renderable fields: a leaf-only schema slice and the group it binds to. */\n private sectionContent(node: TreeNode): { schema: NodeGroup | null; group: FormGroup | null } {\n if (node.choice) {\n const active = this.activeCase(node);\n const body = active && node.choice.schema.cases[active] ? this.caseAsGroup(node.choice.schema, active) : null;\n return { schema: body ? this.leafOnly(body, node.choice.group) : null, group: node.choice.group };\n }\n if (node.schema && node.group) {\n return { schema: this.leafOnly(node.schema, node.group), group: node.group };\n }\n return { schema: null, group: null };\n }\n\n /**\n * The node's own fields as a flattened schema: leaf and leafList children\n * only. Complex children are rendered as sections of their own, so the\n * embedded form never draws nested section chrome. The node's `appearance`\n * (grid / field-width layout) carries into the slice. Null when there are\n * no own fields.\n */\n private leafOnly(schema: NodeGroup, group: FormGroup | null): NodeGroup | null {\n const children: Record<string, NodeType> = {};\n for (const key of Object.keys(schema.children)) {\n const child = schema.children[key];\n if (child.kind !== 'leaf' && child.kind !== 'leafList') continue;\n // An absent presence leafList has no inline affordance and no control to\n // render — it is offered by the \"+ Optional field\" menu instead.\n if (child.kind === 'leafList' && child.presence && !group?.get(key)) continue;\n children[key] = child;\n }\n if (!Object.keys(children).length) return null;\n return { ...schema, root: false, children, appearance: { ...schema.appearance, flatten: true } };\n }\n\n // --- tree construction -----------------------------------------------------\n\n private buildTree(\n schema: NodeGroup,\n group: FormGroup,\n label: string,\n path: string,\n inherited: Appearance | null = null,\n ): TreeNode {\n const children: TreeNode[] = [];\n const optionals: OptionalEntry[] = [];\n const childInherited = descendantLayout(inherited, schema.appearance);\n\n for (const key of Object.keys(schema.children)) {\n const child = schema.children[key];\n if (child.kind === 'leaf' || child.kind === 'leafList') {\n // Leaves render in the detail pane; an absent presence leaf is also\n // offered by the \"+ Optional field\" menu (addable inline or from the\n // tree row). An absent presence *leafList* has no inline affordance, so\n // it is offered only by the menu (and excluded from the leafOnly slice).\n if (child.presence && !group.get(key)) {\n optionals.push({ key, schema: child, label: this.labelOf(child, key) });\n }\n continue;\n }\n const presence = !!child.presence;\n if (presence && !group.get(key)) {\n optionals.push({ key, schema: child, label: this.labelOf(child, key) });\n continue;\n }\n const node = this.buildChildNode(child, group.get(key), this.labelOf(child, key), this.join(path, key), childInherited);\n if (!node) continue;\n if (presence) node.presenceRemovable = { key, schema: child };\n children.push(node);\n }\n\n const node: TreeNode = { id: path, label, children, group, schema, inherited };\n if (optionals.length) node.optionals = optionals;\n return node;\n }\n\n /** Build the tree node for a single non-leaf child, dispatching on its kind. Null when its control is missing. */\n private buildChildNode(\n schema: NodeType,\n control: AbstractControl | null,\n label: string,\n path: string,\n inherited: Appearance | null = null,\n ): TreeNode | null {\n if (schema.kind === 'nodeGroup') {\n return control instanceof FormGroup ? this.buildTree(schema, control, label, path, inherited) : null;\n }\n if (schema.kind === 'nodeGroupList') {\n const array = control;\n const itemLabel = schema.type.label ?? schema.type.name;\n const items =\n array instanceof FormArray\n ? array.controls\n .filter((c): c is FormGroup => c instanceof FormGroup)\n .map((item, i) => {\n // Just \"#n\": the item sits under its list node, so repeating the\n // item name (e.g. \"Interface #1\") only echoes the parent.\n const node = this.buildTree(schema.type, item, `#${i + 1}`, this.join(path, String(i)), inherited);\n node.removable = { index: i };\n return node;\n })\n : [];\n return {\n id: path,\n label,\n children: items,\n group: null,\n list:\n array instanceof FormArray\n ? { array, itemSchema: schema.type, itemLabel, minItems: schema.minItems ?? 0, maxItems: schema.maxItems }\n : undefined,\n };\n }\n if (schema.kind === 'choice') {\n if (!(control instanceof FormGroup)) return null;\n const active = control.get(CASE_KEY)?.value as string | null;\n const node =\n active && schema.cases[active]\n ? this.buildTree(this.caseAsGroup(schema, active), control, label, path, inherited)\n : ({ id: path, label, children: [], group: control, inherited } as TreeNode);\n node.schema = undefined;\n node.choice = { schema, group: control };\n return node;\n }\n if (schema.kind === 'map') {\n if (!(control instanceof FormGroup)) return null;\n const complex =\n schema.value.kind === 'nodeGroup' ||\n schema.value.kind === 'choice' ||\n schema.value.kind === 'map' ||\n schema.value.kind === 'nodeGroupList';\n const entries = complex\n ? Object.keys(control.controls)\n .map((key) => {\n // Index access, not .get(): entry keys are arbitrary runtime data\n // and .get() would split a key like '10.0.0.1' into a dotted path.\n // Entries inherit through the map node's own appearance.\n const entryNode = this.buildChildNode(\n schema.value,\n control.controls[key],\n key,\n this.join(path, key),\n descendantLayout(inherited, schema.appearance),\n );\n if (entryNode) {\n entryNode.mapEntry = { mapGroup: control, mapSchema: schema, key };\n }\n return entryNode;\n })\n .filter((n): n is TreeNode => n !== null)\n : [];\n return {\n id: path,\n label,\n children: entries,\n group: null,\n map: { schema, group: control, complex },\n };\n }\n return null;\n }\n\n /**\n * Synthetic group over a case's normalized fields, so a case body builds\n * like any group. Carries the choice's own `appearance` so its layout\n * reaches the case fields.\n */\n private caseAsGroup(choice: NodeChoice, caseName: string): NodeGroup {\n return {\n kind: 'nodeGroup',\n name: choice.name,\n children: choice.cases[caseName] ? caseFields(choice.cases[caseName]) : {},\n ...(choice.appearance ? { appearance: choice.appearance } : {}),\n };\n }\n\n /** A node's display label: its schema `label`, else its record key. */\n private labelOf(node: NodeType, key: string): string {\n return ('label' in node ? node.label : undefined) ?? key;\n }\n\n /** Join a parent path and a segment; the root's path is the empty string. */\n private join(parent: string, segment: string): string {\n const seg = this.escapeSeg(segment);\n return parent ? `${parent}/${seg}` : seg;\n }\n\n /**\n * Escape a path segment: `/` is the id separator, and map entry keys are\n * arbitrary runtime data that may contain it. Labels stay unescaped — only\n * node identities encode.\n */\n private escapeSeg(segment: string): string {\n return segment.replace(/%/g, '%25').replace(/\\//g, '%2F');\n }\n}\n","<div class=\"editor\">\n <nav class=\"tree\" role=\"tree\" aria-label=\"Configuration structure\">\n <ng-template #treeNode let-node let-depth=\"depth\" let-parent=\"parent\">\n <div\n class=\"tree-row\"\n role=\"treeitem\"\n tabindex=\"0\"\n [class.selected]=\"node === selected\"\n [class.error]=\"hasError(node)\"\n [attr.aria-selected]=\"node === selected\"\n [attr.aria-expanded]=\"hasExpandableContent(node) ? expanded.has(node.id) : null\"\n [attr.aria-level]=\"depth + 1\"\n [style.padding-left.px]=\"8 + depth * 16\"\n (click)=\"select(node)\"\n (keydown)=\"onRowKeydown($event, node)\"\n >\n @if (hasExpandableContent(node)) {\n <button\n matIconButton\n class=\"twisty\"\n tabindex=\"-1\"\n (click)=\"toggle(node); $event.stopPropagation()\"\n [attr.aria-label]=\"expanded.has(node.id) ? 'Collapse' : 'Expand'\"\n >\n <mat-icon>{{ expanded.has(node.id) ? 'expand_more' : 'chevron_right' }}</mat-icon>\n </button>\n } @else {\n <span class=\"twisty-spacer\"></span>\n }\n\n <span class=\"tree-label\" [matTooltip]=\"node.label\">{{ node.label }}</span>\n @if (node.choice && activeCaseLabel(node)) {\n <span class=\"tree-sublabel\" [matTooltip]=\"activeCaseLabel(node)\">{{ activeCaseLabel(node) }}</span>\n }\n @if (node === root) {\n <button\n matIconButton\n class=\"row-btn root-toggle\"\n [matTooltip]=\"editable() ? 'Stop editing' : 'Edit'\"\n [attr.aria-label]=\"editable() ? 'Stop editing' : 'Edit'\"\n [attr.aria-pressed]=\"editable()\"\n (click)=\"editable.set(!editable()); $event.stopPropagation()\"\n >\n <mat-icon>{{ editable() ? 'edit_off' : 'edit' }}</mat-icon>\n </button>\n <button\n matIconButton\n class=\"row-btn root-toggle\"\n [matTooltip]=\"allExpanded() ? 'Collapse all' : 'Expand all'\"\n [attr.aria-label]=\"allExpanded() ? 'Collapse all' : 'Expand all'\"\n (click)=\"toggleExpandAll(); $event.stopPropagation()\"\n >\n <mat-icon>{{ allExpanded() ? 'unfold_less' : 'unfold_more' }}</mat-icon>\n </button>\n }\n @if (hasError(node)) {\n <!-- A non-color error signal beside the red row text. -->\n <mat-icon class=\"row-error-icon\" aria-hidden=\"false\" role=\"img\" aria-label=\"Has validation errors\"\n >error_outline</mat-icon\n >\n }\n\n @if (editable() && node.list && !listAtMax(node)) {\n <button\n matIconButton\n class=\"row-btn add\"\n [matTooltip]=\"'Add ' + node.list.itemLabel + ' #' + (node.list.array.length + 1)\"\n [attr.aria-label]=\"'Add ' + node.list.itemLabel + ' #' + (node.list.array.length + 1)\"\n (click)=\"addItem(node); $event.stopPropagation()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && node.map?.complex && !mapAtMax(node)) {\n <button\n matIconButton\n class=\"row-btn add\"\n [matTooltip]=\"'Add ' + node.label + ' entry'\"\n [attr.aria-label]=\"'Add ' + node.label + ' entry'\"\n (click)=\"addTreeMapEntry(node); $event.stopPropagation()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && node.removable && !listAtMin(parent)) {\n <button\n matIconButton\n class=\"row-btn remove\"\n [matTooltip]=\"'Remove ' + node.label\"\n [attr.aria-label]=\"'Remove ' + node.label\"\n (click)=\"removeItem(parent, node); $event.stopPropagation()\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n @if (editable() && node.presenceRemovable) {\n <button\n matIconButton\n class=\"row-btn remove\"\n [matTooltip]=\"'Remove ' + node.label\"\n [attr.aria-label]=\"'Remove ' + node.label\"\n (click)=\"removeOptional(parent, node); $event.stopPropagation()\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n @if (editable() && node.mapEntry && !mapAtMin(parent)) {\n <button\n matIconButton\n class=\"row-btn remove\"\n [matTooltip]=\"'Remove ' + node.label + ' entry'\"\n [attr.aria-label]=\"'Remove ' + node.label + ' entry'\"\n (click)=\"removeTreeMapEntry(parent, node); $event.stopPropagation()\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n\n @if (expanded.has(node.id)) {\n @for (child of node.children; track child.id) {\n <ng-container\n *ngTemplateOutlet=\"treeNode; context: { $implicit: child, depth: depth + 1, parent: node }\"\n />\n }\n @if (editable() && node.optionals?.length) {\n <button\n type=\"button\"\n class=\"tree-row optional-row\"\n [style.padding-left.px]=\"8 + (depth + 1) * 16\"\n [matMenuTriggerFor]=\"treeOptionalsMenu\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"twisty-spacer\"></span>\n <mat-icon class=\"optional-icon\">add</mat-icon>\n <span class=\"optional-label\">Optional field</span>\n </button>\n <mat-menu #treeOptionalsMenu=\"matMenu\">\n @for (opt of node.optionals; track opt.key) {\n <button mat-menu-item (click)=\"addOptional(node, opt)\">{{ opt.label }}</button>\n }\n </mat-menu>\n }\n }\n </ng-template>\n\n <ng-container *ngTemplateOutlet=\"treeNode; context: { $implicit: root, depth: 0 }\" />\n </nav>\n\n <section class=\"detail\">\n @if (selected) {\n @if (showBreadcrumb()) {\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n @for (crumb of breadcrumb; track crumb.id; let last = $last) {\n @if (last) {\n <span class=\"crumb-current\" aria-current=\"page\">{{ crumb.label }}</span>\n } @else {\n <button type=\"button\" class=\"item-link crumb-link\" (click)=\"select(crumb)\">{{ crumb.label }}</button>\n <span class=\"crumb-sep\" aria-hidden=\"true\">/</span>\n }\n }\n <!-- A selected member (list item / map entry) is removable from its own\n view; the selection then moves to its container, like a tree-row\n remove — a deleted node cannot stay selected. -->\n @if (editable() && selected.removable && selectedMemberParent(); as parent) {\n @if (!listAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + selected.label\"\n [attr.aria-label]=\"'Remove ' + selected.label\"\n (click)=\"removeItem(parent, selected)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n @if (editable() && selected.mapEntry && selectedMemberParent(); as parent) {\n @if (!mapAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + selected.label + ' entry'\"\n [attr.aria-label]=\"'Remove ' + selected.label + ' entry'\"\n (click)=\"removeTreeMapEntry(parent, selected)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n </nav>\n }\n\n <!-- The selected subtree as a flat section list: each descendant's fields\n under a breadcrumb heading — the headings, not nesting, mark the\n boundary between one child and the next. -->\n @for (s of sections; track s.node.id + (s.footer ? ':footer' : '')) {\n @if (s.trail.length > 1 && !s.footer) {\n <!-- A heading, not a nav landmark: dozens of identical \"Section\"\n landmarks would flood the assistive-tech landmark list. Its\n accessible name is the trail itself. -->\n <div class=\"section-heading\" [class.continuation]=\"s.continuation\" role=\"heading\" aria-level=\"3\">\n @for (crumb of s.trail; track crumb.id; let last = $last) {\n @if (last) {\n <span class=\"crumb-current\">{{ crumb.label }}</span>\n } @else {\n <button type=\"button\" class=\"item-link crumb-link\" (click)=\"select(crumb)\">{{ crumb.label }}</button>\n <span class=\"crumb-sep\" aria-hidden=\"true\">/</span>\n }\n }\n @if (editable() && s.node.removable && memberParent(s); as parent) {\n @if (!listAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + s.node.label\"\n [attr.aria-label]=\"'Remove ' + s.node.label\"\n (click)=\"removeItem(parent, s.node, true)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n @if (editable() && s.node.mapEntry && memberParent(s); as parent) {\n @if (!mapAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + s.node.label + ' entry'\"\n [attr.aria-label]=\"'Remove ' + s.node.label + ' entry'\"\n (click)=\"removeTreeMapEntry(parent, s.node, true)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n </div>\n }\n\n @if (s.node.mapEntry; as entry) {\n <mat-form-field class=\"key-field\" [appearance]=\"editable() ? 'fill' : 'outline'\">\n <mat-label>{{ entry.mapSchema.keyLabel ?? 'Key' }}</mat-label>\n <input\n matInput\n #entryKey\n [readonly]=\"!editable()\"\n [value]=\"entry.key\"\n (change)=\"renameTreeMapEntry(s.node, entryKey.value); entryKey.value = entry.key\"\n />\n </mat-form-field>\n }\n\n @if (s.node.choice; as choice) {\n @if (editable()) {\n <mat-form-field class=\"case-select\" appearance=\"fill\">\n <mat-label>Selected option</mat-label>\n <mat-select [value]=\"activeCase(s.node)\" (selectionChange)=\"switchTreeCase(s.node, $event.value)\">\n @for (caseName of objectKeys(choice.schema.cases); track caseName) {\n <mat-option [value]=\"caseName\">{{ caseLabel(choice.schema, caseName) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n <mat-form-field class=\"case-select\" appearance=\"outline\">\n <mat-label>Selected option</mat-label>\n <input matInput readonly [value]=\"activeCaseLabel(s.node) ?? ''\" />\n </mat-form-field>\n }\n }\n\n @if (s.schema && s.group) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"s.node.inherited ?? null\"\n [schema]=\"s.schema\"\n [formGroup]=\"s.group\"\n [editable]=\"editable()\"\n [focusLeaf]=\"s.node.id === focusSectionId ? focusLeafKey : null\"\n />\n }\n\n @if (s.node.map && !s.node.map.complex) {\n <nff-node-map-renderer\n [nodeMap]=\"s.node.map.schema\"\n [formGroup]=\"s.node.map.group\"\n [editable]=\"editable()\"\n />\n }\n\n @if (s.footer && editable() && s.node.map?.complex && !mapAtMax(s.node)) {\n <div class=\"section-actions\">\n <button matButton [matTooltip]=\"'Add ' + s.node.label + ' entry'\" (click)=\"addTreeMapEntry(s.node, true)\"><mat-icon>add</mat-icon> Add entry</button>\n </div>\n }\n @if (s.footer && editable() && s.node.list; as list) {\n @if (!listAtMax(s.node)) {\n <div class=\"section-actions\">\n <!-- The next entry's number in the label, so the button reads as\n what it does: \"Add Cell #3\" appends the third entry. -->\n <button matButton (click)=\"addItem(s.node, true)\">\n <mat-icon>add</mat-icon> Add {{ list.itemLabel }} #{{ list.array.length + 1 }}\n </button>\n </div>\n }\n }\n @if (!s.footer && emptySectionHint(s); as hint) {\n <p class=\"empty\">{{ hint }}</p>\n }\n @if (!s.footer && presentRangeHint(s); as hint) {\n <p class=\"section-error\" role=\"alert\">{{ hint }}</p>\n }\n }\n\n @if (\n sections.length === 1 &&\n !sections[0].schema &&\n !sections[0].node.choice &&\n !sections[0].node.map &&\n !sections[0].node.list &&\n !sections[0].node.mapEntry\n ) {\n <p class=\"empty\">This node has no fields.</p>\n }\n } @else {\n <p class=\"empty\">Select a node on the left to edit its fields.</p>\n }\n </section>\n</div>\n","/*\n * Public API Surface of ng-form-foundry\n */\n\nexport * from './lib/types/dynamic-recursive.types';\nexport * from './lib/core/dynamic-recursive-forms-builder';\nexport * from './lib/dynamic-recursive-form/dynamic-recursive-form.component';\nexport * from './lib/config-editor/config-editor.component';\nexport * from './lib/dynamic-recursive-form/leaf-renderer/leaf-renderer.component';\nexport * from './lib/dynamic-recursive-form/leaf-list-renderer/leaf-list-renderer.component';\nexport * from './lib/dynamic-recursive-form/leaf-enum-renderer/leaf-enum-renderer.component';\nexport * from './lib/dynamic-recursive-form/radix-input/radix-input.directive';\nexport * from './lib/dynamic-recursive-form/node-group-list-renderer/node-group-list-renderer.component';\nexport * from './lib/dynamic-recursive-form/node-map-renderer/node-map-renderer.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i3","i5","i1","i4","i6"],"mappings":"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"}
1
+ {"version":3,"file":"ng-form-foundry.mjs","sources":["../../../projects/ng-form-foundry/src/lib/types/dynamic-recursive.types.ts","../../../projects/ng-form-foundry/src/lib/core/dynamic-recursive-forms-builder.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-enum-renderer/leaf-enum-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-enum-renderer/leaf-enum-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/radix-input/radix-input.directive.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-renderer/leaf-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-renderer/leaf-renderer.component.html","../../../projects/ng-form-foundry/src/lib/core/appearance.ts","../../../projects/ng-form-foundry/src/lib/directives/overflow-tooltip.directive.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-group-list-renderer/node-group-list-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-group-list-renderer/node-group-list-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/anon-leaf-renderer/anon-leaf-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/anon-leaf-renderer/anon-leaf-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-list-renderer/leaf-list-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/leaf-list-renderer/leaf-list-renderer.component.html","../../../projects/ng-form-foundry/src/lib/core/utils.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-map-renderer/node-map-renderer.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/node-map-renderer/node-map-renderer.component.html","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/dynamic-recursive-form.component.ts","../../../projects/ng-form-foundry/src/lib/dynamic-recursive-form/dynamic-recursive-form.component.html","../../../projects/ng-form-foundry/src/lib/config-editor/config-editor.component.ts","../../../projects/ng-form-foundry/src/lib/config-editor/config-editor.component.html","../../../projects/ng-form-foundry/src/public-api.ts","../../../projects/ng-form-foundry/src/ng-form-foundry.ts"],"sourcesContent":["import { FormArray, FormControl, FormGroup } from '@angular/forms';\n\nexport type LeafRuntimeType<T> = T extends 'string'\n ? string\n : T extends 'number'\n ? number\n : T extends 'boolean'\n ? boolean\n : T extends 'enum'\n ? string | number\n : never;\n\nexport type LeafBase = {\n kind: 'leaf';\n name: string;\n required?: true | undefined;\n label?: string;\n description?: string;\n /**\n * The value may be `null` (JSON Schema `type: [T, 'null']`). Builds a nullable\n * control (drops `nonNullable`), so `null` is a first-class value the\n * constraint validators accept and that survives the round-trip. Distinct from\n * {@link presence}: `nullable` is an explicit `null`, `presence` is an absent key.\n */\n nullable?: boolean;\n /**\n * Optional scalar whose *presence itself* is data (mirrors {@link NodeGroup.presence}).\n * Rendered with an on/off toggle; the control is removed from the parent group\n * when absent (so it drops from `form.value`) and re-added when toggled on. The\n * builder omits it unless an initial value is supplied.\n */\n presence?: boolean;\n /**\n * Render the field read-only even when the surrounding form is editable.\n * Combine with `default` to express a JSON Schema `const` (a fixed,\n * display-only value); single-element `enum` is the alternative for a constant.\n */\n readOnly?: boolean;\n};\n\nexport type AnonLeaf = {\n [K in Leaf['type']]: { type: K };\n}[Leaf['type']];\n\nexport type LeafString = LeafBase & {\n type: 'string';\n default?: LeafRuntimeType<'string'>;\n /**\n * Reject values that don't match this regular expression. Follows JSON Schema\n * `pattern` semantics — an *unanchored* `RegExp.test`, so it matches anywhere\n * in the value unless the pattern itself anchors with `^`/`$`.\n */\n pattern?: string;\n /** Minimum string length (JSON Schema `minLength`). */\n minLength?: number;\n /** Maximum string length (JSON Schema `maxLength`). */\n maxLength?: number;\n /** Semantic string format (JSON Schema `format`); adds a matching validator. */\n format?: 'email' | 'uri' | 'url';\n /**\n * Present the value in this base — for the string leaves that carry an\n * integer beyond ±2^53 as its exact decimal digits. The control value stays\n * that decimal-digit string (`pattern` keeps validating it); only the\n * rendered text is based. See {@link LeafNumber.radix}.\n */\n radix?: 2 | 8 | 16;\n};\nexport type LeafNumber = LeafBase & {\n type: 'number';\n default?: LeafRuntimeType<'number'>;\n /** Require a whole-number value (JSON Schema `type: 'integer'`). */\n integer?: boolean;\n /** Inclusive lower bound (JSON Schema `minimum`). */\n min?: number;\n /** Inclusive upper bound (JSON Schema `maximum`). */\n max?: number;\n /** Require the value to be an integer multiple of this number (JSON Schema `multipleOf`). */\n multipleOf?: number;\n /**\n * Present the value in this base (16 hex, 8 octal, 2 binary) instead of\n * decimal — a display hint set by transformers when the source document\n * wrote the literal that way (`0x1A`, `0o17`, `0b101`). The control value\n * stays a plain number, so every numeric validator applies unchanged; only\n * the rendered text is based. See `RadixInputDirective`.\n */\n radix?: 2 | 8 | 16;\n};\nexport type LeafBoolean = LeafBase & {\n type: 'boolean';\n default?: LeafRuntimeType<'boolean'>;\n};\nexport type LeafEnum = LeafBase & {\n type: 'enum';\n default?: LeafRuntimeType<'enum'>;\n enumLabel?: string[];\n enum: LeafRuntimeType<'enum'>[];\n};\n\nexport type Appearance = {\n flatten?: boolean;\n noBorder?: boolean;\n /** Start this node's section panel collapsed. Ignored when `flatten` is set. */\n collapsed?: boolean;\n /**\n * Fixed grid for the node's scalar fields: `cols` fields per row, filling\n * left-to-right; `rows` alone fills top-to-bottom into that many rows,\n * adding columns as needed. Overrides {@link minFieldWidth}.\n */\n grid?: { rows?: number; cols?: number };\n /**\n * Narrowest a scalar field may get (a CSS length, e.g. `'12rem'`): each row\n * fits as many equal-width fields as stay at least this wide and wraps the\n * rest. Ignored when {@link grid} is set. With neither option the fields\n * share one wrapping row, shrinking down to 10% of it.\n */\n minFieldWidth?: string;\n /**\n * Where boolean (checkbox-rendered) fields go. A checkbox doesn't need a\n * field-sized slot — in a {@link grid} it would claim a whole track —\n * so `'beginning'`/`'end'` gathers them into a compact wrapping row of\n * natural-width items before/after the node's other fields. `'default'`\n * (or unset) keeps them in declaration order within the field flow.\n */\n booleanFields?: 'beginning' | 'end' | 'default';\n /**\n * Narrowest a **text (string) field** may get in the flex flow (a CSS\n * length): the row wraps rather than shrink such a field further. Enum\n * fields (rendered as a select) are text-like and follow it too, as do a\n * string/enum leaf-list's entries. No effect under {@link grid} /\n * {@link minFieldWidth}, whose tracks size every field alike.\n */\n minTextFieldWidth?: string;\n /**\n * Narrowest a **number field** may get in the flex flow (a CSS length) —\n * the numeric counterpart of {@link minTextFieldWidth}, typically smaller.\n * Also bounds a number leaf-list's entries.\n */\n minNumberFieldWidth?: string;\n /**\n * Widest a **number field** may grow in the flex flow (a CSS length):\n * numbers are short, so capping them keeps a lone number from stretching\n * across space a text field could use. Also caps a number leaf-list's\n * entries. No effect under {@link grid} / {@link minFieldWidth}.\n */\n maxNumberFieldWidth?: string;\n}\n\nexport type Leaf = LeafString | LeafNumber | LeafBoolean | LeafEnum;\n\nexport type LeafList<TKind extends Leaf['type'] = Leaf['type']> = {\n kind: 'leafList';\n label?: string;\n name: string;\n description?: string;\n default?: Exclude<Leaf['default'], undefined>[];\n type: TKind;\n minItems?: number;\n maxItems?: number;\n /** Present every item in this base — see {@link LeafNumber.radix}. */\n radix?: 2 | 8 | 16;\n /**\n * Optional scalar list whose *presence itself* is data — an absent key,\n * distinct from a present-but-empty list. Off means no control and no key in\n * the value; on means the (possibly empty) list is materialized. Mirrors\n * {@link NodeGroup.presence}; lets a round-trip distinguish `x = ( )` (present,\n * empty) from an absent `x`.\n */\n presence?: boolean;\n};\n\nexport type NodeGroupList = {\n kind: 'nodeGroupList';\n name: string;\n label?: string;\n description?: string;\n type: NodeGroup;\n minItems?: number;\n maxItems?: number;\n /** Optional list whose presence is itself data — see {@link LeafList.presence}. */\n presence?: boolean;\n};\n\nexport type NodeGroup = {\n kind: 'nodeGroup';\n name: string;\n subType?: string;\n label?: string;\n root?: boolean;\n /**\n * When true, the group is optional: rendered with an on/off toggle and present\n * in the form only while enabled. Its control is removed from the parent\n * FormGroup when absent (so it drops from `form.value`) and re-added when the\n * user toggles it on. The builder omits it unless an initial value is supplied.\n */\n presence?: boolean;\n description?: string;\n /**\n * Minimum / maximum number of keys present in the group's value (JSON Schema\n * `minProperties`/`maxProperties` on a closed object). Meaningful when\n * children are presence-optional: the group carries a `minPresent` /\n * `maxPresent` error while the count of enabled children is out of range.\n */\n minPresent?: number;\n maxPresent?: number;\n children: Record<string, NodeType>;\n appearance?: Appearance;\n};\n\n/**\n * One case of a {@link NodeChoice}: either a record of named fields (an object\n * branch), or a single node (a *leaf-bodied* case — e.g. an `anyOf` branch that\n * is a bare scalar). A single node is normalized to a one-field record keyed by\n * its `name` when the form is built.\n */\nexport type ChoiceCase = Record<string, NodeType> | NodeType;\n\n/**\n * A discriminated selection: the user picks one `case`, and only that case's\n * fields are present. In the form it is a FormGroup holding a `__case` control\n * (the active case name) plus that case's field controls; switching the case\n * swaps the field controls.\n *\n * Cases may be **anonymous / auto-named** (any string key) — for JSON Schema\n * `anyOf`/`oneOf` branches with no name. When a built form is seeded from inline\n * data that carries no `__case`, the builder **infers** the active case from the\n * data shape (the case whose fields best match), so a choice round-trips from\n * real instance data. See the schema reference for the required-set / `const`\n * discriminator recipe.\n */\nexport type NodeChoice = {\n kind: 'choice';\n name: string;\n label?: string;\n cases: Record<string, ChoiceCase>;\n /**\n * Display labels for cases, keyed by case name — for anonymous/auto-named\n * branches whose keys are not human-friendly. Falls back to the case name.\n * Selectors render these through `caseDisplayLabels`, which disambiguates\n * colliding entries by each case's distinguishing fields.\n */\n caseLabels?: Record<string, string>;\n default?: string;\n mandatory?: boolean;\n /** Optional choice: rendered with an on/off toggle, omitted from the value when absent. */\n presence?: boolean;\n appearance?: Appearance;\n};\n\n/**\n * The control name that records which case of a {@link NodeChoice} is active.\n * The name is reserved: it cannot be used as a case field name (the builder\n * throws) or as a map entry key (the entry helpers reject it).\n */\nexport const CASE_KEY = '__case';\n\n/**\n * An open, arbitrary-keyed record: unlike {@link NodeGroup} (a fixed, declared\n * key set), a map's keys are runtime data and every value conforms to one shared\n * `value` schema. Maps JSON Schema `additionalProperties: <schema>` /\n * `patternProperties`. In the form it is a `FormGroup` whose control *names* are\n * the entry keys, so `getRawValue()` is the map object directly; the renderer\n * lets the user add, remove, and rename entries.\n */\nexport type NodeMap = {\n kind: 'map';\n name: string;\n label?: string;\n description?: string;\n /** The schema every entry's value conforms to. */\n value: NodeType;\n /** Label for the key column in the editor. Defaults to \"Key\". */\n keyLabel?: string;\n /** `patternProperties`: entry keys must match this regular expression. */\n keyPattern?: string;\n /** Minimum number of entries (JSON Schema `minProperties`). */\n minEntries?: number;\n /** Maximum number of entries (JSON Schema `maxProperties`). */\n maxEntries?: number;\n /** Optional map: rendered with an on/off toggle, omitted from the value when absent. */\n presence?: boolean;\n appearance?: Appearance;\n};\n\nexport type NodeType = Leaf | LeafList | NodeGroup | NodeGroupList | NodeChoice | NodeMap;\nexport type DFormControl<T extends NodeType> = T extends Leaf\n ? FormControl<LeafRuntimeType<T['type']>>\n : T extends LeafList\n ? FormArray<FormControl<LeafRuntimeType<T['type']>>>\n : T extends NodeGroup\n ? DFormGroup<T>\n : T extends NodeGroupList\n ? FormArray<DFormGroup<T['type']>>\n : T extends NodeChoice\n ? FormGroup<any>\n : T extends NodeMap\n ? FormGroup<any>\n : never;\n\nexport type FormGroupType<T extends NodeGroup> = {\n [TChild in keyof T['children']]: DFormControl<T['children'][TChild]>;\n};\nexport type DFormGroup<T extends NodeGroup> = FormGroup<FormGroupType<T>>;\n","import {\n FormArray,\n FormControl,\n FormGroup,\n ValidatorFn,\n Validators,\n} from '@angular/forms';\nimport {\n CASE_KEY,\n ChoiceCase,\n DFormControl,\n DFormGroup,\n FormGroupType,\n Leaf,\n LeafBase,\n LeafEnum,\n LeafList,\n LeafNumber,\n LeafRuntimeType,\n LeafString,\n NodeChoice,\n NodeGroup,\n NodeGroupList,\n NodeMap,\n NodeType,\n} from '../types/dynamic-recursive.types';\n\n// --- type guards\nfunction isLeaf(node: NodeType): node is Leaf {\n return node.kind === 'leaf';\n}\n\nfunction isLeafList(node: NodeType): node is LeafList {\n return node.kind === 'leafList';\n}\nfunction isNodeGroup(node: NodeType): node is NodeGroup {\n return node.kind === 'nodeGroup';\n}\nfunction isNodeGroupList(node: NodeType): node is NodeGroupList {\n return node.kind === 'nodeGroupList';\n}\nfunction isChoice(node: NodeType): node is NodeChoice {\n return node.kind === 'choice';\n}\nfunction isMap(node: NodeType): node is NodeMap {\n return node.kind === 'map';\n}\n\n/** Whether the node is an optional (presence) node: its key is data, absent until enabled. */\nfunction hasPresence(node: NodeType): boolean {\n return (\n (node.kind === 'leaf' ||\n node.kind === 'nodeGroup' ||\n node.kind === 'map' ||\n node.kind === 'choice' ||\n node.kind === 'leafList' ||\n node.kind === 'nodeGroupList') &&\n node.presence === true\n );\n}\n\n/**\n * Whether a presence child should start absent: there is no initial data\n * object (a scalar seed counts as none), or its key is missing from it. A key\n * that is present with an explicit `null` value keeps its control — `null` is\n * a value (a nullable leaf's), while presence is about the *absent key*.\n */\nfunction presenceAbsent(initial: Record<string, unknown> | null | undefined, key: string): boolean {\n return initial == null || typeof initial !== 'object' || !(key in initial);\n}\n\nfunction enumValidator(choices: readonly (string | number)[]): ValidatorFn {\n const set = new Set(choices);\n return (ctrl) =>\n ctrl.value == null || set.has(ctrl.value) ? null : { enum: true };\n}\n\n/**\n * JSON Schema `pattern`: an *unanchored* `RegExp.test`, unlike Angular's built-in\n * `Validators.pattern` which anchors the expression. An invalid regex disables\n * the check rather than throwing. Empty/absent values pass (use `required`).\n */\nfunction patternValidator(pattern: string): ValidatorFn {\n let re: RegExp;\n try {\n re = new RegExp(pattern);\n } catch {\n return () => null;\n }\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n return re.test(String(v)) ? null : { pattern: { requiredPattern: pattern, actualValue: v } };\n };\n}\n\n/** JSON Schema `type: 'integer'`: reject a value that is not a whole number. */\nfunction integerValidator(): ValidatorFn {\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n const num = typeof v === 'number' ? v : Number(v);\n return Number.isInteger(num) ? null : { integer: true };\n };\n}\n\n/** JSON Schema `multipleOf`: reject a value that is not an integer multiple of `step`. */\nfunction multipleOfValidator(step: number): ValidatorFn {\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n const num = typeof v === 'number' ? v : Number(v);\n if (Number.isNaN(num)) return null;\n const ratio = num / step;\n // A small tolerance absorbs binary float drift (e.g. 0.3 / 0.1).\n return Math.abs(ratio - Math.round(ratio)) < 1e-9\n ? null\n : { multipleOf: { multipleOf: step, actual: num } };\n };\n}\n\n/** JSON Schema `format: uri`: reject a string that is not a parseable absolute URI. */\nfunction uriValidator(): ValidatorFn {\n return (ctrl) => {\n const v = ctrl.value;\n if (v == null || v === '') return null;\n try {\n new URL(String(v));\n return null;\n } catch {\n return { uri: true };\n }\n };\n}\n\nfunction buildLeafControl<L extends Leaf>(\n leaf: L,\n initial?: unknown,\n): FormControl<LeafRuntimeType<L['type']>> {\n const validators: ValidatorFn[] = [];\n if ('required' in leaf && leaf.required) validators.push(Validators.required);\n // A presence leaf only ever has a control while enabled, and enabled means\n // the key goes on the wire — an empty materialized value would serialize as\n // null and fail typed-schema validation. So materialized ⇒ must hold a\n // value; disable the field to omit it. A nullable presence leaf is exempt:\n // explicit null is one of its legal values.\n else if ((leaf as LeafBase).presence === true && (leaf as LeafBase).nullable !== true) {\n validators.push(Validators.required);\n }\n if ('type' in leaf && leaf.type === 'enum') {\n const choices = (leaf as LeafEnum).enum as (string | number)[];\n validators.push(enumValidator(choices));\n }\n if (leaf.type === 'string') {\n const s = leaf as LeafString;\n if (s.pattern != null) validators.push(patternValidator(s.pattern));\n if (s.minLength != null) validators.push(Validators.minLength(s.minLength));\n if (s.maxLength != null) validators.push(Validators.maxLength(s.maxLength));\n if (s.format === 'email') validators.push(Validators.email);\n else if (s.format === 'uri' || s.format === 'url') validators.push(uriValidator());\n } else if (leaf.type === 'number') {\n const n = leaf as LeafNumber;\n if (n.integer) validators.push(integerValidator());\n if (n.min != null) validators.push(Validators.min(n.min));\n if (n.max != null) validators.push(Validators.max(n.max));\n if (n.multipleOf != null) validators.push(multipleOfValidator(n.multipleOf));\n }\n const defaultValue =\n initial ?? ('default' in leaf ? (leaf as any).default : undefined) ?? null;\n // A nullable leaf drops `nonNullable`, so `null` is a first-class value that\n // `reset()` restores and that survives the round-trip (JSON Schema `null`).\n // The typed model still treats a leaf value as non-null, so the runtime\n // nullable control is cast back to the declared type.\n const nullable = 'nullable' in leaf && (leaf as LeafBase).nullable === true;\n return new FormControl<LeafRuntimeType<L['type']>>(defaultValue, {\n nonNullable: !nullable,\n validators,\n }) as FormControl<LeafRuntimeType<L['type']>>;\n}\n\n// The list value with no seed data is the empty array: a phantom null entry\n// would fail validation of the serialized value against typed item schemas,\n// and an empty list is the honest wire shape (renderers offer the add row).\nfunction buildLeafListControl<L extends LeafList>(\n list: L,\n initial: LeafRuntimeType<L['type']>[] | null,\n): FormArray<FormControl<LeafRuntimeType<LeafList['type']> | null>> {\n const values = (Array.isArray(initial) ? initial : undefined) ?? list.default ?? [];\n return new FormArray(values.map((v) => new FormControl(v)));\n}\n\n/**\n * Group error while the number of present (enabled) children is outside the\n * group's `minPresent`/`maxPresent` range — JSON Schema `minProperties` /\n * `maxProperties` on a closed object whose properties are presence-optional.\n * Counted from the live controls, so presence toggles re-evaluate it.\n */\nfunction presentChildrenValidator(group: NodeGroup): ValidatorFn {\n return (control) => {\n const actual = Object.keys((control as FormGroup).controls).length;\n if (group.minPresent != null && actual < group.minPresent) {\n return { minPresent: { required: group.minPresent, actual } };\n }\n if (group.maxPresent != null && actual > group.maxPresent) {\n return { maxPresent: { allowed: group.maxPresent, actual } };\n }\n return null;\n };\n}\n\nfunction buildNodeGroupControl<G extends NodeGroup>(\n group: G,\n initial?: Record<string, unknown> | null,\n): DFormGroup<G> {\n const controls: any = {} as Partial<FormGroupType<G>>;\n for (const key in group.children) {\n const child = group.children[key];\n // An absent presence child gets no control at all, so it is absent from the\n // form value until enabled. Because every nested group is built through this\n // function — plain children, list items, map values, choice case fields —\n // presence is honored at any depth.\n if (hasPresence(child) && presenceAbsent(initial, key)) continue;\n // Forward only this child's slice of the initial data, keyed by the child's\n // record key. Passing the whole `initial` object seeds every leaf with the\n // parent record and prevents list builders from sizing to the real data.\n controls[key] = buildControl(\n child,\n initial?.[key],\n ) as FormGroupType<G>[typeof key];\n }\n const constrained = group.minPresent != null || group.maxPresent != null;\n return new FormGroup(\n controls as FormGroupType<G>,\n constrained ? { validators: presentChildrenValidator(group) } : undefined,\n ) as DFormGroup<G>;\n}\n\nfunction buildNodeGroupListControl<GL extends NodeGroupList>(\n list: GL,\n initial: unknown[] | null = null,\n): FormArray<DFormGroup<GL['type']>> {\n // `initial` is the runtime data array — one group per element. With no data\n // the list is empty: seeding a phantom all-null group would put an invalid\n // member on the wire (see buildLeafListControl).\n const values = Array.isArray(initial) ? initial : [];\n return new FormArray(\n values.map((v) =>\n buildNodeGroupControl(list.type, v as Record<string, unknown> | null),\n ),\n );\n}\n\n/**\n * Normalize a {@link ChoiceCase} to a field record. A field record is returned\n * as-is; a single node (a leaf-bodied case, e.g. a scalar `anyOf` branch) becomes\n * a one-field record keyed by the node's `name`. The discriminant is a top-level\n * `kind` string, which a field record never has (its keys are field names).\n *\n * Throws when a case field is keyed `__case`: that name is reserved for the\n * choice discriminator ({@link CASE_KEY}) and a field under it would silently\n * clobber the active-case control.\n */\nexport function caseFields(body: ChoiceCase): Record<string, NodeType> {\n const fields =\n typeof (body as { kind?: unknown }).kind === 'string'\n ? { [(body as NodeType).name]: body as NodeType }\n : (body as Record<string, NodeType>);\n if (CASE_KEY in fields) {\n throw new Error(`\"${CASE_KEY}\" is reserved for the choice discriminator and cannot name a case field`);\n }\n return fields;\n}\n\n/**\n * Display labels for a choice's cases, keyed by case name, with colliding\n * labels made unique. Schema-supplied `caseLabels` can repeat (e.g. two\n * O-RAN A1 scope branches labeled from the same discriminating field), which\n * makes the case selector ambiguous. Unique labels pass through untouched;\n * each colliding case first gains the fields that set it apart from its\n * same-labeled peers — \"UE ID (Group ID)\" vs \"UE ID (Slice ID)\" — and any\n * cases the field suffix cannot separate (no distinguishing fields, peers\n * with identical field sets among a larger clash group, or distinguishing\n * fields that share one display label) fall back to their case name, which\n * is unique by construction.\n */\nexport function caseDisplayLabels(choice: NodeChoice): Record<string, string> {\n const names = Object.keys(choice.cases);\n const base: Record<string, string> = {};\n const out: Record<string, string> = {};\n const byLabel = new Map<string, string[]>();\n for (const name of names) {\n base[name] = choice.caseLabels?.[name] ?? name;\n out[name] = base[name];\n byLabel.set(base[name], [...(byLabel.get(base[name]) ?? []), name]);\n }\n for (const clashing of byLabel.values()) {\n if (clashing.length < 2) continue;\n for (const name of clashing) {\n const fields = caseFields(choice.cases[name]);\n const others = clashing.filter((o) => o !== name).map((o) => caseFields(choice.cases[o]));\n const distinct = Object.keys(fields).filter((key) => !others.every((o) => key in o));\n const suffix = distinct.length\n ? distinct.map((key) => (fields[key] as { label?: string }).label ?? key).join(', ')\n : name;\n out[name] = `${out[name]} (${suffix})`;\n }\n }\n // Uniqueness guarantee: whatever the collision topology, labels still equal\n // after field-suffixing take the case name instead.\n const byFinal = new Map<string, string[]>();\n for (const name of names) byFinal.set(out[name], [...(byFinal.get(out[name]) ?? []), name]);\n for (const clashing of byFinal.values()) {\n if (clashing.length < 2) continue;\n for (const name of clashing) out[name] = `${base[name]} (${name})`;\n }\n return out;\n}\n\n/**\n * The active case of a choice: an explicit `__case` in the initial value, else\n * the case {@link inferChoiceCase} ranks best against the initial data (inline\n * wire data carries no `__case`), else the schema `default`. This lets a choice\n * seed from real instance data whose branch is discriminated by which fields\n * are present and required.\n */\nexport function resolveChoiceCase(\n choice: NodeChoice,\n initial?: Record<string, unknown> | null,\n): string | undefined {\n const explicit = initial?.[CASE_KEY];\n if (typeof explicit === 'string') return explicit;\n return inferChoiceCase(choice, initial) ?? choice.default;\n}\n\n/**\n * Pick the active case from inline wire data (which carries no `__case`).\n *\n * Candidates are the cases sharing at least one field name with the data; when\n * none does, the caller falls back to the schema `default`. Candidates are\n * ranked by, in order: fewest data keys the case has no field for (the case\n * must be able to hold the data), fewest non-presence fields absent from the\n * data (fields the form would have to materialize empty — this is how\n * required-set-discriminated `oneOf` branches differ, e.g. a branch requiring\n * `{ueId, qosId}` vs one requiring only `{qosId}`), most matched fields, and\n * finally declaration order. Presence fields are exempt from the absence count\n * because their absence is itself a legal state of the data.\n */\nfunction inferChoiceCase(choice: NodeChoice, initial?: Record<string, unknown> | null): string | undefined {\n if (initial == null || typeof initial !== 'object' || Array.isArray(initial)) return undefined;\n const dataKeys = new Set(Object.keys(initial).filter((k) => k !== CASE_KEY));\n let best: string | undefined;\n let bestRank: number[] | undefined;\n for (const name of Object.keys(choice.cases)) {\n const fields = caseFields(choice.cases[name]);\n let matched = 0;\n for (const key of dataKeys) if (key in fields) matched++;\n if (matched === 0) continue;\n const missing = Object.keys(fields).filter(\n (f) => !hasPresence(fields[f]) && !dataKeys.has(f),\n ).length;\n const rank = [dataKeys.size - matched, missing, -matched];\n if (bestRank === undefined || lexLess(rank, bestRank)) {\n bestRank = rank;\n best = name;\n }\n }\n return best;\n}\n\n/** Strictly-less comparison of two equal-length rank vectors, first difference wins. */\nfunction lexLess(a: readonly number[], b: readonly number[]): boolean {\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return a[i] < b[i];\n }\n return false;\n}\n\n/**\n * Group error while a choice that must resolve to a case has none selected.\n * Attached to `mandatory` choices (a case is always due) and `presence` choices\n * (enabled means the key serializes, and `{}` satisfies no case) — a plain\n * optional choice stays validator-free, `{ __case: null }` and all.\n */\nfunction caseRequiredValidator(): ValidatorFn {\n return (group) =>\n (group as FormGroup).get(CASE_KEY)?.value == null ? { caseRequired: true } : null;\n}\n\n/**\n * Build the FormGroup for a choice: a `__case` control holding the active case\n * name plus that case's field controls. Only the active case's fields are built,\n * matching the inline YANG encoding; switching the case swaps them. Mandatory\n * and presence choices carry {@link caseRequiredValidator}.\n */\nfunction buildChoiceControl(\n choice: NodeChoice,\n initial?: Record<string, unknown> | null,\n): FormGroup {\n const active = resolveChoiceCase(choice, initial);\n const controls: any = { [CASE_KEY]: new FormControl(active ?? null) };\n if (active && choice.cases[active]) {\n const caseChildren = caseFields(choice.cases[active]);\n for (const key in caseChildren) {\n // Case fields honor presence like any group's children: an absent\n // presence field gets no control.\n if (hasPresence(caseChildren[key]) && presenceAbsent(initial, key)) continue;\n controls[key] = buildControl(caseChildren[key], initial?.[key]);\n }\n }\n const needsCase = choice.mandatory === true || choice.presence === true;\n return new FormGroup(controls, needsCase ? { validators: caseRequiredValidator() } : undefined);\n}\n\n/**\n * Switch a choice's FormGroup to `caseName`: sets `__case`, removes every other\n * control, and builds `caseName`'s fields (normalized via {@link caseFields})\n * with their defaults. Presence fields of the new case start absent — the\n * switch carries no data that could make them present. An unknown case name\n * leaves only `__case`. The swap is atomic: one value change fires, and every\n * observable snapshot has fields matching its discriminator.\n */\nexport function switchChoiceCase(group: FormGroup, choice: NodeChoice, caseName: string): void {\n group.get(CASE_KEY)?.setValue(caseName, { emitEvent: false });\n for (const name of Object.keys(group.controls)) {\n if (name !== CASE_KEY) group.removeControl(name, { emitEvent: false });\n }\n const caseChildren = choice.cases[caseName] ? caseFields(choice.cases[caseName]) : {};\n for (const name in caseChildren) {\n if (hasPresence(caseChildren[name])) continue;\n group.addControl(name, buildControl(caseChildren[name]) as any, { emitEvent: false });\n }\n group.updateValueAndValidity();\n}\n\n/**\n * Append a map entry built from `map.value` and return its committed key, or\n * `null` when nothing was added. With no `key`, the first free `keyN`\n * placeholder is generated (not checked against `keyPattern` — placeholders are\n * meant to be renamed). An explicit `key` is rejected when it duplicates an\n * existing entry or violates `keyPattern`. Rejects when `maxEntries` is reached.\n */\nexport function addMapEntry(group: FormGroup, map: NodeMap, key?: string): string | null {\n if (map.maxEntries != null && Object.keys(group.controls).length >= map.maxEntries) return null;\n let committed: string;\n if (key != null) {\n const trimmed = key.trim();\n // `__case` is reserved for the choice discriminator; as an entry key it\n // would make the map group indistinguishable from a choice group.\n if (!trimmed || trimmed === CASE_KEY || group.contains(trimmed)) return null;\n if (map.keyPattern && !new RegExp(map.keyPattern).test(trimmed)) return null;\n committed = trimmed;\n } else {\n let n = Object.keys(group.controls).length + 1;\n committed = `key${n}`;\n while (group.contains(committed)) committed = `key${++n}`;\n }\n group.addControl(committed, buildControl(map.value) as any);\n return committed;\n}\n\n/**\n * Rename entry `oldKey` to `newKey.trim()`, preserving the control instance\n * (so the value survives) and the entry's position in the group's key order —\n * the order `getRawValue()` serializes and the tree editor renders. Returns\n * whether the rename was committed: an empty, reserved (`__case`), unchanged,\n * duplicate, or `keyPattern`-violating key is a no-op, leaving the entry under\n * its current name. Entry keys are looked up verbatim — never via\n * `AbstractControl.get`, which would split keys like `10.0.0.1` into\n * dot-delimited paths. Emits a single value change.\n */\nexport function renameMapEntry(group: FormGroup, map: NodeMap, oldKey: string, newKey: string): boolean {\n const committed = newKey.trim();\n if (!committed || committed === CASE_KEY || committed === oldKey || group.contains(committed)) return false;\n if (map.keyPattern && !new RegExp(map.keyPattern).test(committed)) return false;\n const control = group.controls[oldKey];\n if (!control) return false;\n // Re-key in place: swap the name, then re-append every key that followed so\n // the renamed entry does not jump to the end of the key order.\n const following = Object.keys(group.controls);\n following.splice(0, following.indexOf(oldKey) + 1);\n group.removeControl(oldKey, { emitEvent: false });\n group.addControl(committed, control, { emitEvent: false });\n for (const key of following) {\n const sibling = group.controls[key];\n group.removeControl(key, { emitEvent: false });\n group.addControl(key, sibling, { emitEvent: false });\n }\n group.updateValueAndValidity();\n return true;\n}\n\n/** Remove entry `key` unless the map is at `minEntries`. Returns whether it was removed. */\nexport function removeMapEntry(group: FormGroup, map: NodeMap, key: string): boolean {\n if (!group.contains(key)) return false;\n if (map.minEntries != null && Object.keys(group.controls).length <= map.minEntries) return false;\n group.removeControl(key);\n return true;\n}\n\n/**\n * Materialize or de-materialize an optional (presence) child of `group`,\n * mirroring the presence toggle the form UI offers — but callable by any host\n * holding the {@link FormGroup}, for a key at any depth. `present: true` builds\n * the child fresh from `schema` (seeded with `initial` if given; nested\n * presence descendants start absent, as {@link buildControl}); `present: false`\n * removes it, dropping the key from the form value.\n *\n * The materialize direction is why the coupling exists: a materialized\n * non-nullable presence leaf carries `Validators.required`, because an\n * enabled-but-empty key would serialize as `null` and fail a typed schema. A\n * host that materializes fields for editing therefore drops the ones left\n * empty on cancel by de-materializing them — this API is that primitive.\n *\n * `schema` must be the presence node for `key`; a non-presence `schema` is a\n * no-op. Returns whether the form changed.\n */\nexport function setNodePresence(group: FormGroup, schema: NodeType, key: string, present: boolean, initial?: unknown): boolean {\n if (!hasPresence(schema)) return false;\n if (present) {\n if (group.contains(key)) return false;\n group.addControl(key, buildControl(schema, initial) as never);\n return true;\n }\n if (!group.contains(key)) return false;\n group.removeControl(key);\n return true;\n}\n\n/**\n * The map's own constraints as a group validator: entry count against\n * `minEntries`/`maxEntries` and every entry key against `keyPattern`. The UI\n * gates prevent most violations; the validator reports the ones that slip\n * through (seeded wire data, generated `keyN` placeholders awaiting a rename).\n */\nfunction mapValidator(map: NodeMap): ValidatorFn {\n let re: RegExp | null = null;\n if (map.keyPattern) {\n try {\n re = new RegExp(map.keyPattern);\n } catch {\n re = null;\n }\n }\n return (ctrl) => {\n const keys = Object.keys((ctrl as FormGroup).controls);\n const errors: Record<string, unknown> = {};\n if (map.minEntries != null && keys.length < map.minEntries) {\n errors['minEntries'] = { required: map.minEntries, actual: keys.length };\n }\n if (map.maxEntries != null && keys.length > map.maxEntries) {\n errors['maxEntries'] = { allowed: map.maxEntries, actual: keys.length };\n }\n if (re) {\n const invalidKeys = keys.filter((k) => !re!.test(k));\n if (invalidKeys.length) errors['keyPattern'] = { pattern: map.keyPattern, keys: invalidKeys };\n }\n return Object.keys(errors).length ? errors : null;\n };\n}\n\n/**\n * Build the FormGroup for a map: one control per entry, keyed by the entry key,\n * each built from the map's shared `value` schema. Because the entry keys are the\n * control names, `getRawValue()` is the map object directly. Empty when no\n * initial object is supplied; the renderer adds/removes/renames entries. The\n * group carries {@link mapValidator}, so `keyPattern`/`minEntries`/`maxEntries`\n * violations surface as validation errors.\n */\nfunction buildMapControl(\n map: NodeMap,\n initial?: Record<string, unknown> | null,\n): FormGroup {\n const controls: any = {};\n const source = initial && typeof initial === 'object' && !Array.isArray(initial) ? initial : {};\n for (const key of Object.keys(source)) {\n controls[key] = buildControl(map.value, source[key]);\n }\n return new FormGroup(controls, { validators: mapValidator(map) });\n}\n\n/**\n * Build the `AbstractControl` for a single schema node.\n *\n * Dispatches on `node.kind`: a `leaf` becomes a `FormControl`, a `leafList` a\n * `FormArray` of controls, a `nodeGroup` a nested `FormGroup`, and a\n * `nodeGroupList` a `FormArray` of groups. `initial` is the runtime value for\n * this node — a scalar for a leaf, an array for a list, an object for a group —\n * and seeds the control's value (falling back to the node's `default`).\n *\n * Most callers use {@link buildFormFromSchema}; this is exposed for building a\n * control from a single non-root node.\n */\nexport function buildControl<T extends NodeType>(\n node: T,\n initial?: unknown | null,\n): DFormControl<T> | FormControl<LeafRuntimeType<any>> | FormArray<any> {\n if (isLeaf(node)) {\n return buildLeafControl(node, initial);\n }\n if (isChoice(node)) {\n return buildChoiceControl(\n node,\n initial ? (initial as Record<string, unknown>) : null,\n ) as DFormControl<T>;\n }\n if (isMap(node)) {\n return buildMapControl(\n node,\n initial ? (initial as Record<string, unknown>) : null,\n ) as DFormControl<T>;\n }\n if (isLeafList(node)) {\n return buildLeafListControl(\n node,\n initial !== null\n ? (initial as LeafRuntimeType<(T & LeafList)['type']>[])\n : initial,\n ) as DFormControl<T>;\n }\n if (isNodeGroup(node)) {\n return buildNodeGroupControl(\n node,\n initial ? (initial as Record<string, unknown>) : null,\n ) as DFormControl<T>;\n }\n if (isNodeGroupList(node)) {\n return buildNodeGroupListControl(\n node,\n initial ? (initial as unknown[]) : null,\n ) as DFormControl<T>;\n }\n return new FormControl(initial ?? '') as DFormControl<T>;\n}\n\n/**\n * Build a typed `FormGroup` from a root `NodeGroup` schema.\n *\n * The returned group's control structure, keys, and value types are inferred\n * from the schema literal — a `leaf` of `type: 'number'` yields a\n * `FormControl<number>`, a `nodeGroup` a nested `FormGroup`, and so on. `initial`\n * is an optional value object keyed by the schema's `children` keys; each child\n * control is seeded from its matching slice (falling back to the node `default`).\n *\n * Presence nodes whose key is absent from `initial` get no control, at any depth\n * — plain children, list items, map values, and choice case fields alike — so\n * they are absent from the form value until enabled. A key present with an\n * explicit `null` keeps its control: `null` is a value, absence is the missing\n * key.\n *\n * Inference only holds when `schema`'s literal type is preserved. Author schemas\n * with {@link defineSchema} or a `satisfies NodeGroup` annotation — never\n * `const schema: NodeGroup = ...`, which widens `children` and erases the field\n * names and value types.\n */\nexport function buildFormFromSchema<S extends NodeGroup>(\n schema: S,\n initial: Record<string, unknown> | null = null,\n): DFormGroup<S> {\n return buildNodeGroupControl<S>(schema, initial);\n}\n\n/**\n * The wire value at `node`: `value` rebuilt with every choice discriminator\n * removed.\n *\n * A choice's form value is `{ __case, ...fields }` ({@link CASE_KEY}); its wire\n * encoding is the active case's fields inline, with no discriminator — the case\n * is recovered from the field shape when the data is seeded back in\n * ({@link resolveChoiceCase}). The walk is schema-driven: only positions the\n * schema declares as choices are stripped, so a group child or map entry that\n * happens to be named `__case` passes through untouched. Values at positions\n * the schema does not describe pass through unchanged.\n */\nexport function toWireValue(node: NodeType, value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value;\n if (isChoice(node)) {\n const { [CASE_KEY]: active, ...rest } = value as Record<string, unknown>;\n const fields =\n typeof active === 'string' && node.cases[active] ? caseFields(node.cases[active]) : {};\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(rest)) {\n out[key] = key in fields ? toWireValue(fields[key], rest[key]) : rest[key];\n }\n return out;\n }\n if (isNodeGroup(node)) {\n const source = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(source)) {\n out[key] = key in node.children ? toWireValue(node.children[key], source[key]) : source[key];\n }\n return out;\n }\n if (isNodeGroupList(node)) {\n return Array.isArray(value) ? value.map((item) => toWireValue(node.type, item)) : value;\n }\n if (isMap(node)) {\n const source = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(source)) out[key] = toWireValue(node.value, source[key]);\n return out;\n }\n return value;\n}\n\n/**\n * Serialize a form built by {@link buildFormFromSchema} to its wire value:\n * `form.getRawValue()` with every choice's {@link CASE_KEY} discriminator\n * stripped (see {@link toWireValue}). The result is the inline encoding that\n * `buildFormFromSchema` accepts back as `initial`, so serialize → rebuild\n * round-trips the value.\n */\nexport function serializeForm(schema: NodeGroup, form: FormGroup): Record<string, unknown> {\n return toWireValue(schema, form.getRawValue()) as Record<string, unknown>;\n}\n\n/**\n * Capture a schema literal with its exact type while checking it against\n * `NodeGroup`.\n *\n * This is an identity function whose only job is the `const` type parameter,\n * which keeps the narrow literal type of `schema` (field names, each node's\n * `type`) instead of widening it to `NodeGroup`. Assigning a schema to a\n * `: NodeGroup`-annotated constant widens `children` to\n * `Record<string, NodeType>` and erases that information, so\n * {@link buildFormFromSchema} can no longer infer a typed `FormGroup`. Passing\n * the schema through `defineSchema` (or annotating it `satisfies NodeGroup`)\n * preserves the schema-to-`FormGroup` inference.\n */\nexport function defineSchema<const S extends NodeGroup>(schema: S): S {\n return schema;\n}\n","import { Component, Input } from '@angular/core';\nimport { LeafEnum } from '../../types/dynamic-recursive.types';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatSelectModule } from '@angular/material/select';\n\n@Component({\n selector: 'nff-leaf-enum-renderer',\n standalone: true,\n imports: [ReactiveFormsModule, MatFormFieldModule, MatSelectModule],\n templateUrl: './leaf-enum-renderer.component.html',\n styleUrl: './leaf-enum-renderer.component.scss',\n})\nexport class LeafEnumRendererComponent {\n @Input() leafEnum!: LeafEnum;\n @Input() initialValue!: string;\n @Input() control = new FormControl();\n @Input() removable: boolean = false;\n @Input() remove: any;\n @Input() editable: boolean = true;\n /** Placeholder for the empty select — e.g. a ghost preview showing the schema default. */\n @Input() placeholder = '';\n}\n","<mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ leafEnum.label ?? leafEnum.name }}</mat-label>\n @if (editable) {\n <mat-select [formControl]=\"control\" [placeholder]=\"placeholder\">\n @for (option of leafEnum.enum; track $index) {\n <mat-option [value]=\"option\">{{ leafEnum.enumLabel?.[$index] ?? option }}</mat-option>\n }\n </mat-select>\n } @else {\n <!-- Display-only: no formControl binding, so the wire value cannot change. -->\n <mat-select [value]=\"control.value\" disabled [placeholder]=\"placeholder\">\n @for (option of leafEnum.enum; track $index) {\n <mat-option [value]=\"option\">{{ leafEnum.enumLabel?.[$index] ?? option }}</mat-option>\n }\n </mat-select>\n }\n</mat-form-field>\n","import { Directive, ElementRef, Input, OnChanges, forwardRef } from '@angular/core';\nimport {\n AbstractControl,\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator,\n} from '@angular/forms';\n\nexport type Radix = 2 | 8 | 16;\n\nconst PREFIX: Record<Radix, string> = { 16: '0x', 8: '0o', 2: '0b' };\nconst MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);\nconst MIN_SAFE = BigInt(Number.MIN_SAFE_INTEGER);\n\n/**\n * An integer as a prefixed literal in the given base: `0x1A`, `0o17`, `0b101`,\n * hex digits uppercase, a leading `-` for negatives. Accepts a number or a\n * decimal-digit string (the beyond-safe-range carry).\n */\nexport function formatRadix(value: number | string, radix: Radix): string {\n const big = BigInt(value);\n const negative = big < 0n;\n const digits = (negative ? -big : big).toString(radix);\n return (negative ? '-' : '') + PREFIX[radix] + (radix === 16 ? digits.toUpperCase() : digits);\n}\n\n/**\n * Presents an integer control in hex/octal/binary while the control value\n * stays what the schema and validators expect: a plain `number`, or — with\n * `nffRadixValueType=\"string\"` — the exact decimal-digit string that carries\n * integers beyond the safe range (±(2^53 − 1)). Only the visible text is\n * based (`0x1A`, `0o17`, `0b101`); `min`/`max`/`integer`/`pattern` validators\n * therefore apply unchanged.\n *\n * Typing accepts the base's digits with or without prefix, case-insensitive\n * (`0q` is also accepted for octal, as in libconfig); the text normalizes to\n * the prefixed spelling on blur. Unparseable text sets the control to `null`\n * with a `radixFormat` error — never the raw text, so an invalid entry can\n * reach neither the wire value nor a typed write-back; the text itself stays\n * in the input for the user to correct. In number mode a magnitude beyond the\n * safe range likewise yields `null` with `radixRange` instead of a silently\n * rounded number.\n */\n@Directive({\n selector: 'input[nffRadixInput]',\n standalone: true,\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RadixInputDirective), multi: true },\n { provide: NG_VALIDATORS, useExisting: forwardRef(() => RadixInputDirective), multi: true },\n ],\n host: {\n '(input)': 'onInput(el.nativeElement.value)',\n '(blur)': 'onBlur()',\n autocomplete: 'off',\n spellcheck: 'false',\n },\n})\nexport class RadixInputDirective implements ControlValueAccessor, Validator, OnChanges {\n /** The display base. */\n @Input({ required: true, alias: 'nffRadixInput' }) radix!: Radix;\n /**\n * What the control carries: `'number'` (default), or `'string'` for the\n * decimal-digit bigint carry of a string leaf.\n */\n @Input({ alias: 'nffRadixValueType' }) valueType: 'number' | 'string' = 'number';\n\n private modelValue: unknown = null;\n private parseError: 'format' | 'range' | null = null;\n private onChange: (value: unknown) => void = () => {};\n private onTouched: () => void = () => {};\n private onValidatorChange: () => void = () => {};\n\n constructor(protected readonly el: ElementRef<HTMLInputElement>) {}\n\n /** A changed base (or carry mode) re-renders the model and re-validates. */\n ngOnChanges(): void {\n this.render();\n this.onValidatorChange();\n }\n\n writeValue(value: unknown): void {\n this.modelValue = value;\n this.parseError = null;\n this.render();\n }\n\n registerOnChange(fn: (value: unknown) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n registerOnValidatorChange(fn: () => void): void {\n this.onValidatorChange = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.el.nativeElement.disabled = isDisabled;\n }\n\n validate(_control: AbstractControl): ValidationErrors | null {\n if (this.parseError === 'format') return { radixFormat: { radix: this.radix } };\n if (this.parseError === 'range') return { radixRange: { radix: this.radix } };\n return null;\n }\n\n protected onInput(text: string): void {\n const trimmed = text.trim();\n if (trimmed === '') {\n this.parseError = null;\n this.modelValue = null;\n this.onChange(null);\n return;\n }\n const big = this.parse(trimmed);\n if (big === null) {\n // Invalid entry: the control gets null (never the raw text), the error\n // marks it, and the element keeps the text for the user to correct.\n this.parseError = 'format';\n this.modelValue = null;\n this.onChange(null);\n return;\n }\n if (this.valueType === 'string') {\n this.parseError = null;\n this.modelValue = big.toString();\n this.onChange(this.modelValue);\n return;\n }\n if (big > MAX_SAFE || big < MIN_SAFE) {\n // A number control cannot hold this exactly: null it, flag it.\n this.parseError = 'range';\n this.modelValue = null;\n this.onChange(null);\n return;\n }\n this.parseError = null;\n this.modelValue = Number(big);\n this.onChange(this.modelValue);\n }\n\n protected onBlur(): void {\n this.onTouched();\n if (this.parseError === null) this.render(); // normalize e.g. `1a` → `0x1A`\n }\n\n /** Show the model in its base; unrepresentable models pass through as text. */\n private render(): void {\n if (!this.radix) return; // before the first input binding — rendered once bound\n const v = this.modelValue;\n let text: string;\n if (v == null || v === '') text = '';\n else if (typeof v === 'number' && Number.isInteger(v)) text = formatRadix(v, this.radix);\n else if (typeof v === 'string' && /^[-+]?[0-9]+$/.test(v)) text = formatRadix(v, this.radix);\n else text = String(v);\n this.el.nativeElement.value = text;\n }\n\n /**\n * `[-+]?` + this base's optional prefix + this base's digits, or null. The\n * prefix is base-specific so hex digit runs that merely *look* like another\n * base's prefix (`0b11` as hex 0x0B11) parse as digits, not as a rejection.\n */\n private parse(text: string): bigint | null {\n const re =\n this.radix === 16\n ? /^([-+]?)(?:0[xX])?([0-9a-fA-F]+)$/\n : this.radix === 8\n ? /^([-+]?)(?:0[oOqQ])?([0-7]+)$/\n : /^([-+]?)(?:0[bB])?([01]+)$/;\n const m = re.exec(text);\n if (!m) return null;\n const big = BigInt(PREFIX[this.radix] + m[2]!.toLowerCase());\n return m[1] === '-' ? -big : big;\n }\n}\n","import { AfterViewInit, Component, ElementRef, Input, output } from '@angular/core';\nimport { AnonLeaf, Leaf } from '../../types/dynamic-recursive.types';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { LeafEnumRendererComponent } from '../leaf-enum-renderer/leaf-enum-renderer.component';\nimport { RadixInputDirective } from '../radix-input/radix-input.directive';\n\n@Component({\n selector: 'nff-leaf-renderer',\n standalone: true,\n imports: [\n MatFormFieldModule,\n ReactiveFormsModule,\n MatInputModule,\n MatCheckboxModule,\n MatSelectModule,\n MatIconModule,\n MatButtonModule,\n MatTooltip,\n LeafEnumRendererComponent,\n RadixInputDirective,\n ],\n templateUrl: './leaf-renderer.component.html',\n styleUrl: './leaf-renderer.component.scss',\n // The leaf's value type as a host class, so the type-scoped flex minimums\n // (`--nff-min-text-field-width` / `--nff-min-number-field-width`) can size\n // string and number fields differently — see the :host rules in the styles.\n host: { '[class]': '\"leaf-type-\" + (leaf_?.type ?? \"unknown\")' },\n})\nexport class LeafRendererComponent implements AfterViewInit {\n @Input() leaf_!: Leaf | AnonLeaf;\n @Input() control: FormControl = new FormControl();\n @Input() removable: boolean = false;\n @Input() editable = true;\n /** Focus the field once rendered — for fields the user just added (e.g. an enabled presence leaf). */\n @Input() autofocus = false;\n /** Placeholder for the empty field — e.g. a ghost preview showing the schema default. */\n @Input() placeholder = '';\n /** Emitted when the user removes this field (e.g. an optional presence leaf). */\n readonly remove = output<void>();\n\n constructor(private readonly elementRef: ElementRef<HTMLElement>) {}\n\n ngAfterViewInit(): void {\n if (this.autofocus) {\n // Deferred out of the change-detection pass: focusing flips the form\n // field's label-float state, which would otherwise trip NG0100.\n setTimeout(() => this.elementRef.nativeElement.querySelector<HTMLElement>('input, mat-select')?.focus());\n }\n }\n\n /** Whether this field accepts input: the form is editable and the leaf is not `readOnly`. */\n get fieldEditable(): boolean {\n return this.editable && !('name' in this.leaf_ && this.leaf_.readOnly);\n }\n\n /**\n * A human-readable message for the control's active validation error, or `''`\n * when valid. `mat-form-field` only shows it once the field is in an error\n * state (invalid and touched), so it can be bound unconditionally.\n */\n get errorText(): string {\n const e = this.control.errors;\n if (!e) return '';\n const label = 'name' in this.leaf_ ? this.leaf_.label ?? this.leaf_.name : 'Value';\n if (e['required']) return `${label} is required`;\n if (e['radixFormat']) {\n const names: Record<number, string> = { 16: 'hexadecimal (0x…)', 8: 'octal (0o…)', 2: 'binary (0b…)' };\n return `Must be a ${names[e['radixFormat'].radix] ?? 'based'} number`;\n }\n if (e['radixRange']) return 'Too large to edit exactly (beyond ±2^53)';\n if (e['minlength']) return `Must be at least ${e['minlength'].requiredLength} characters`;\n if (e['maxlength']) return `Must be at most ${e['maxlength'].requiredLength} characters`;\n if (e['pattern']) return `Must match ${e['pattern'].requiredPattern ?? 'the required pattern'}`;\n if (e['email']) return 'Must be a valid email address';\n if (e['uri']) return 'Must be a valid URI';\n if (e['min']) return `Must be ≥ ${e['min'].min}`;\n if (e['max']) return `Must be ≤ ${e['max'].max}`;\n if (e['multipleOf']) return `Must be a multiple of ${e['multipleOf'].multipleOf}`;\n if (e['enum']) return 'Not an allowed value';\n return 'Invalid value';\n }\n}\n","@if ('name' in leaf_) {\n @if (leaf_.type === 'string') {\n <mat-form-field [appearance]=\"fieldEditable ? 'fill' : 'outline'\">\n <mat-label>{{ leaf_.label ?? leaf_.name }}</mat-label>\n @if (leaf_.radix) {\n <!-- The bigint decimal-string carry, presented in its source base. -->\n <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [nffRadixInput]=\"leaf_.radix\" nffRadixValueType=\"string\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n } @else {\n <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n }\n <mat-error>{{ errorText }}</mat-error>\n </mat-form-field>\n } @else if (leaf_.type === 'number') {\n <mat-form-field [appearance]=\"fieldEditable ? 'fill' : 'outline'\">\n <mat-label>{{ leaf_.label ?? leaf_.name }}</mat-label>\n @if (leaf_.radix) {\n <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [nffRadixInput]=\"leaf_.radix\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n } @else {\n <input [readonly]=\"!fieldEditable\" matInput type=\"number\" [placeholder]=\"placeholder\" [formControl]=\"control\">\n }\n <mat-error>{{ errorText }}</mat-error>\n </mat-form-field>\n } @else if (leaf_.type === 'boolean') {\n @if (fieldEditable) {\n <mat-checkbox [formControl]=\"control\">{{ leaf_.label ?? leaf_.name }}</mat-checkbox>\n } @else {\n <!-- Display-only: no formControl binding, so the wire value cannot change.\n The control itself is never disable()d — a disabled control would\n still appear in the form value with different semantics. -->\n <mat-checkbox [checked]=\"control.value === true\" disabled>{{ leaf_.label ?? leaf_.name }}</mat-checkbox>\n }\n } @else if (leaf_.type === 'enum') {\n <nff-leaf-enum-renderer [editable]=\"fieldEditable\" [leafEnum]=\"leaf_\" [control]=\"control\" [placeholder]=\"placeholder\"></nff-leaf-enum-renderer>\n }\n @if (removable && editable) {\n <button matIconButton class=\"remove-button small-icon-button\" [matTooltip]=\"'Remove ' + ('label' in leaf_ && leaf_.label ? leaf_.label : 'name' in leaf_ ? leaf_.name : 'field')\" [attr.aria-label]=\"'Remove ' + ('label' in leaf_ && leaf_.label ? leaf_.label : 'name' in leaf_ ? leaf_.name : 'field')\" (click)=\"remove.emit()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n}\n","import { Appearance } from '../types/dynamic-recursive.types';\n\n/**\n * Inline CSS declarations (property → value) for a node's `.fields` area,\n * derived from its {@link Appearance} (see the form component's\n * `fieldsLayout`) and bound via `[style]`. Also handed to a stacked\n * leaf-list's `layout` input so its entries repeat the same grid tracks.\n */\nexport type LayoutStyles = Record<string, string>;\n\n/**\n * The field-layout subset of an {@link Appearance} — the properties\n * descendants inherit, in output order. Chrome flags — `flatten`, `noBorder`,\n * `collapsed` — describe the node's own frame and never cascade.\n */\nconst INHERITED_LAYOUT_KEYS = [\n 'grid',\n 'minFieldWidth',\n 'booleanFields',\n 'minTextFieldWidth',\n 'minNumberFieldWidth',\n 'maxNumberFieldWidth',\n] as const satisfies readonly (keyof Appearance)[];\n\n/**\n * `grid` and `minFieldWidth` form one field-sizing decision: a node that sets\n * either has chosen its sizing, so neither is inherited (otherwise an\n * inherited `grid` would override the node's own `minFieldWidth` by the\n * grid-wins precedence). See {@link mergeAppearance}.\n */\nconst FIELD_SIZING_KEYS: ReadonlySet<keyof Appearance> = new Set(['grid', 'minFieldWidth']);\n\n/** `to[key] = value` keyed generically — the key–value correlation TypeScript cannot track for a union-typed key. */\nfunction assign<K extends keyof Appearance>(to: Appearance, key: K, value: Appearance[K]): void {\n to[key] = value;\n}\n\n/**\n * The subset of an `Appearance` that descendants inherit\n * ({@link INHERITED_LAYOUT_KEYS}). Null when nothing is inheritable.\n * Counterpart of {@link mergeAppearance}.\n */\nexport function inheritableAppearance(appearance: Appearance | null | undefined): Appearance | null {\n if (!appearance) return null;\n const out: Appearance = {};\n for (const key of INHERITED_LAYOUT_KEYS) {\n if (appearance[key] != null) assign(out, key, appearance[key]);\n }\n return Object.keys(out).length ? out : null;\n}\n\n/**\n * A node's effective appearance: its own settings win, layout gaps fall back\n * to `inherited` per property — except the {@link FIELD_SIZING_KEYS} pair,\n * which is only inherited as a whole when the node sets neither.\n */\nexport function mergeAppearance(\n inherited: Appearance | null | undefined,\n own: Appearance | undefined,\n): Appearance | undefined {\n if (!inherited) return own;\n const merged: Appearance = { ...own };\n const ownFieldSizing = own?.grid != null || own?.minFieldWidth != null;\n for (const key of INHERITED_LAYOUT_KEYS) {\n if (ownFieldSizing && FIELD_SIZING_KEYS.has(key)) continue;\n if (merged[key] == null && inherited[key] != null) assign(merged, key, inherited[key]);\n }\n return merged;\n}\n\n/**\n * The layout a node's descendants inherit: the layout cascading down from its\n * ancestors with the node's own `appearance` merged over it\n * ({@link mergeAppearance}), reduced to the inheritable subset\n * ({@link inheritableAppearance}).\n */\nexport function descendantLayout(\n inherited: Appearance | null | undefined,\n own: Appearance | undefined,\n): Appearance | null {\n return inheritableAppearance(mergeAppearance(inherited, own));\n}\n","import { AfterViewInit, Directive, ElementRef, OnDestroy, effect, inject, input } from '@angular/core';\nimport { MatTooltip } from '@angular/material/tooltip';\n\n/**\n * Reveals the full text in a Material tooltip only while the labelled element\n * is actually clipped by its ellipsis — a truncated \"Add <field>\" button reads\n * in full on hover or keyboard focus, while a label that fits stays quiet.\n * Pair with CSS that clips the measured element (`overflow: hidden;\n * text-overflow: ellipsis; white-space: nowrap`).\n *\n * Hosts {@link MatTooltip} and drives its `message` / `disabled` itself. The\n * clip state is tracked with a `ResizeObserver` and kept current as the\n * element's box changes, so it is already correct when the pointer arrives —\n * there is no show-time race with the tooltip's own pointer listeners.\n */\n@Directive({\n selector: '[nffOverflowTooltip]',\n standalone: true,\n hostDirectives: [MatTooltip],\n})\nexport class OverflowTooltipDirective implements AfterViewInit, OnDestroy {\n /** The full text to reveal when the measured element is clipped. */\n readonly text = input.required<string>({ alias: 'nffOverflowTooltip' });\n /**\n * Selector of the clipped element to measure, queried within the host; the\n * host element itself when unset. For a Material button point it at\n * `.mdc-button__label`, the wrapper that holds the text.\n */\n readonly forSelector = input<string | null>(null, { alias: 'nffOverflowTooltipFor' });\n\n private readonly tooltip = inject(MatTooltip);\n private readonly host: ElementRef<HTMLElement> = inject(ElementRef);\n private observer?: ResizeObserver;\n\n constructor() {\n // Keep the message in step with the label, and re-check the clip state — a\n // longer label can start overflowing without the box itself resizing.\n effect(() => {\n this.tooltip.message = this.text();\n this.sync();\n });\n }\n\n ngAfterViewInit(): void {\n if (typeof ResizeObserver !== 'undefined') {\n this.observer = new ResizeObserver(() => this.sync());\n this.observer.observe(this.measured());\n }\n this.sync();\n }\n\n ngOnDestroy(): void {\n this.observer?.disconnect();\n }\n\n /** The element whose overflow decides the tooltip: the `forSelector` match, or the host. */\n private measured(): HTMLElement {\n const selector = this.forSelector();\n return (selector && this.host.nativeElement.querySelector<HTMLElement>(selector)) || this.host.nativeElement;\n }\n\n /** Enable the tooltip only while the measured element's content overflows its box. */\n private sync(): void {\n const el = this.measured();\n this.tooltip.disabled = el.scrollWidth - el.clientWidth <= 1;\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n forwardRef,\n inject,\n Input,\n OnInit,\n Output,\n QueryList,\n ViewChildren\n} from '@angular/core';\nimport { Appearance, NodeGroupList } from '../../types/dynamic-recursive.types';\nimport { FormArray, FormGroup } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { DynamicRecursiveFormComponent } from '../dynamic-recursive-form.component';\nimport { buildFormFromSchema } from '../../core/dynamic-recursive-forms-builder';\nimport { OverflowTooltipDirective } from '../../directives/overflow-tooltip.directive';\n\n@Component({\n selector: 'nff-node-group-list-renderer',\n standalone: true,\n imports: [\n forwardRef(() => DynamicRecursiveFormComponent),\n MatButtonModule,\n MatIconModule,\n OverflowTooltipDirective,\n ],\n templateUrl: './node-group-list-renderer.component.html',\n styleUrl: './node-group-list-renderer.component.scss',\n})\nexport class NodeGroupListRendererComponent implements OnInit, AfterViewInit {\n @Input() nodeGroupList!: NodeGroupList;\n @Input() initialValue!: number[] | string[] | boolean[];\n @Input() formArray = new FormArray<any>([]);\n @Input() editable: boolean = true;\n /** Forwarded to each entry's embedded form — see the form's input of the same name. */\n @Input() showAbsentOptionals = false;\n // Schema-driven bounds, matching the config editor: absent minItems floors\n // at 0 (an unbounded list can be emptied), absent maxItems is unbounded.\n @Input() minItems: number = 0;\n @Input() maxItems: number = Number.POSITIVE_INFINITY;\n /** Field-layout appearance from the enclosing group, forwarded to every item form. */\n @Input() inheritedAppearance: Appearance | null = null;\n @Output() message = new EventEmitter();\n /**\n * Emitted when the last entry of a presence (optional / advisoryRequired) list\n * is removed — the host de-materializes the whole list (→ absent). An optional\n * list has no present-empty state; a required list never routes here.\n */\n @Output() removeList = new EventEmitter<void>();\n // forwardRef: DynamicRecursiveFormComponent and this component import each\n // other, so the class reference is undefined when this query is evaluated at\n // decoration time. forwardRef defers the lookup and keeps the selector valid.\n @ViewChildren(forwardRef(() => DynamicRecursiveFormComponent))\n items!: QueryList<DynamicRecursiveFormComponent>;\n\n cdr = inject(ChangeDetectorRef);\n\n ngOnInit() {\n if (this.initialValue) {\n this.formArray.patchValue(this.initialValue);\n }\n }\n\n // Effective bounds: the schema wins when it declares them (an explicit\n // `minItems: 0` included), else the `@Input` fallback for a host that binds\n // the renderer directly. Getters, so a schema rebind is reflected live.\n get effectiveMin(): number {\n return this.nodeGroupList?.minItems ?? this.minItems;\n }\n get effectiveMax(): number {\n return this.nodeGroupList?.maxItems ?? this.maxItems;\n }\n\n /** Whether another item may be appended (below the effective maximum). */\n get canAdd(): boolean {\n return this.formArray.length < this.effectiveMax;\n }\n\n ngAfterViewInit() {\n this.items.changes.subscribe(() => {\n this.setLastEditable();\n });\n }\n\n removeItem($index: number) {\n // A presence (optional / advisoryRequired) list has no present-empty state:\n // removing its last entry de-materializes the whole list (→ absent). A\n // required (non-presence) list instead stops at its minimum, staying `[]`.\n if (this.nodeGroupList?.presence && this.formArray.length === 1) {\n this.removeList.emit();\n return;\n }\n if (this.formArray.length <= this.effectiveMin) {\n this.message.emit({\n message: `You cannot remove the last ${this.nodeGroupList.type.name} configuration!`,\n type: 'error',\n })\n return;\n }\n this.formArray.removeAt($index);\n }\n\n addItem = (index?: number) => {\n if (this.formArray.length >= this.effectiveMax) return;\n this.formArray.push(buildFormFromSchema(this.nodeGroupList.type, null));\n }\n\n setLastEditable() {\n const lastItem = this.items.last;\n if (lastItem) {\n lastItem.editable.set(true);\n }\n this.cdr.detectChanges();\n }\n\n asFormGroup(group: any) {\n return group as FormGroup;\n }\n\n getTitle($index: number) {\n let title = `${this.nodeGroupList.type.label ?? this.nodeGroupList.type.name}`;\n if (this.formArray.length > 1) {\n return `${title} #${$index + 1}`;\n }\n else {\n return title;\n }\n\n }\n}\n","@if (formArray && nodeGroupList) {\n <div class=\"fields-container\">\n @for (group of formArray.controls; track $index) {\n <div class=\"field-item\">\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"inheritedAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [schema]=\"nodeGroupList.type\"\n [formGroup]=\"asFormGroup(group)\"\n [title]=\"getTitle($index)\"\n [index]=\"0\"\n [removable]=\"formArray.length > effectiveMin\"\n (remove)=\"removeItem($index)\"\n [editable]=\"editable\"\n [addButtonCallback]=\"canAdd ? addItem : null\"\n [addButtonLabel]=\"'Add ' + (nodeGroupList.type.label ?? nodeGroupList.type.name) + ' #' + (formArray.length + 1)\"\n />\n </div>\n }\n @if (editable && formArray.length === 0 && canAdd) {\n <!-- An empty list has no per-item header to host the add button, so it\n would otherwise be an unrecoverable dead end. This footer add\n creates the first item (mirrors the config editor's \"Add … #1\"). -->\n <button\n matButton=\"outlined\"\n class=\"empty-add-button nff-clip-label\"\n [nffOverflowTooltip]=\"'Add ' + (nodeGroupList.type.label ?? nodeGroupList.type.name) + ' #1'\"\n nffOverflowTooltipFor=\".mdc-button__label\"\n (click)=\"addItem()\"\n >\n <mat-icon>add</mat-icon> Add {{ nodeGroupList.type.label ?? nodeGroupList.type.name }} #1\n </button>\n }\n </div>\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { AnonLeaf, LeafList } from '../../types/dynamic-recursive.types';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatButtonModule } from '@angular/material/button';\nimport { RadixInputDirective } from '../radix-input/radix-input.directive';\n\n@Component({\n selector: 'nff-anon-leaf-renderer',\n standalone: true,\n imports: [\n ReactiveFormsModule,\n MatFormFieldModule,\n MatSelectModule,\n MatIconModule,\n MatCheckboxModule,\n MatInputModule,\n MatButtonModule,\n RadixInputDirective,\n ],\n templateUrl: './anon-leaf-renderer.component.html',\n styleUrl: './anon-leaf-renderer.component.scss',\n})\nexport class AnonLeafRendererComponent {\n /** The item's shape: a bare `{ type }`, or the whole leafList for its items. */\n @Input() AnonLeaf!: AnonLeaf | LeafList;\n @Input() initialValue!: string;\n @Input() control = new FormControl();\n @Input() removable: boolean = false;\n @Input() editable: boolean = true;\n @Input() index!: number;\n @Output() remove = new EventEmitter();\n @Input() label!: string;\n\n emitRemoveEvent() {\n this.remove.emit();\n }\n\n /** The items' display base, when the leafList carries one. */\n get radix(): 2 | 8 | 16 | undefined {\n return 'radix' in this.AnonLeaf ? this.AnonLeaf.radix : undefined;\n }\n}\n","<div class=\"anon-leaf-container\">\n@if (AnonLeaf.type === 'string') {\n <mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ label }} #{{ index + 1}}</mat-label>\n @if (radix) {\n <!-- The bigint decimal-string carry, presented in its source base. -->\n <input [readonly]=\"!editable\"\n [nffRadixInput]=\"radix\" nffRadixValueType=\"string\"\n [formControl]=\"control\"\n matInput type=\"text\" >\n } @else {\n <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"text\" >\n }\n </mat-form-field>\n} @else if (AnonLeaf.type === 'number') {\n <mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ label }} #{{ index + 1}}</mat-label>\n @if (radix) {\n <input [readonly]=\"!editable\"\n [nffRadixInput]=\"radix\"\n [formControl]=\"control\"\n matInput type=\"text\">\n } @else {\n <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"number\">\n }\n </mat-form-field>\n} @else if (AnonLeaf.type === 'boolean') {\n @if (editable) {\n <mat-checkbox [formControl]=\"control\">value</mat-checkbox>\n } @else {\n <!-- Display-only: no formControl binding, so the wire value cannot change. -->\n <mat-checkbox [checked]=\"control.value === true\" disabled>value</mat-checkbox>\n }\n}\n @else if (AnonLeaf.type === 'enum' && 'enum' in AnonLeaf) {\n <mat-form-field [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ label }} #{{ index + 1}}</mat-label>\n @if (editable) {\n <mat-select [formControl]=\"control\">\n @for (option of (AnonLeaf.type === 'enum' ? AnonLeaf.enum : []); track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-select>\n } @else {\n <mat-select [value]=\"control.value\" disabled>\n @for (option of (AnonLeaf.type === 'enum' ? AnonLeaf.enum : []); track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-select>\n }\n </mat-form-field>\n}\n</div>\n","import { Component, EventEmitter, HostBinding, inject, Input, OnInit, Output } from '@angular/core';\nimport { LayoutStyles } from '../../core/appearance';\nimport { LeafList } from '../../types/dynamic-recursive.types';\nimport { FormControl } from '@angular/forms';\nimport { MatIconModule } from '@angular/material/icon';\nimport { AnonLeafRendererComponent } from '../anon-leaf-renderer/anon-leaf-renderer.component';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatPrefix } from '@angular/material/input';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { OverflowTooltipDirective } from '../../directives/overflow-tooltip.directive';\n\n@Component({\n selector: 'nff-leaf-list-renderer',\n standalone: true,\n imports: [\n MatIconModule,\n AnonLeafRendererComponent,\n MatButtonModule,\n MatPrefix,\n MatTooltip,\n OverflowTooltipDirective,\n ],\n templateUrl: './leaf-list-renderer.component.html',\n styleUrl: './leaf-list-renderer.component.scss',\n})\nexport class LeafListRendererComponent implements OnInit {\n @Input() leaf_!: LeafList;\n @Input() initialValue!: number[] | string[] | boolean[];\n @Input() formArray!: any;\n @Input() editable: boolean = true;\n // Schema-driven bounds: absent `minItems` floors at 0 (an unbounded list can\n // be emptied), absent `maxItems` is unbounded. Read from the schema in\n // ngOnInit so a bare `[leaf_]` binding honors them without extra wiring.\n @Input() minItems: number = 0;\n @Input() maxItems: number = Number.POSITIVE_INFINITY;\n /**\n * The parent group's grid layout (its `fieldsLayout` styles). A stacked list\n * spans the parent's full row, so its entries repeat the same tracks and\n * stay aligned with the columns above; an inline (single-entry) list sits in\n * one track and ignores it.\n */\n @Input() layout: LayoutStyles | null = null;\n @Output() message = new EventEmitter();\n /**\n * Emitted from the empty-list remove button when the list is a presence list —\n * the host removes the whole list (de-materializes it, → absent). Only wired\n * for a `presence` `leafList`; the parent maps it to `setNodePresence`.\n */\n @Output() removeList = new EventEmitter<void>();\n\n matDialog = inject(MatDialog);\n\n /**\n * Take a full-width row of its own once the array holds more than one entry.\n * A multi-entry array grows vertically as its items wrap; sitting inline next\n * to a regular leaf that would stretch the leaf to match. On its own line it\n * cannot. Consumed by the `:host(.stacked)` rule.\n */\n @HostBinding('class.stacked')\n get stacked(): boolean {\n return (this.formArray?.length ?? 0) > 1;\n }\n\n /** The entries' value type as a host class, so type-scoped min-widths (`--nff-min-*-field-width`) can target them. */\n @HostBinding('class')\n get typeClass(): string {\n return `list-type-${this.leaf_?.type ?? 'unknown'}`;\n }\n\n /** Applies {@link layout} to the host (the entries' container) while stacked. */\n @HostBinding('style')\n get hostLayout(): LayoutStyles | null {\n return this.stacked ? this.layout : null;\n }\n\n ngOnInit() {\n if (this.initialValue) {\n this.formArray.patchValue(this.initialValue);\n }\n }\n\n // Effective bounds: the schema wins when it declares them (an explicit\n // `minItems: 0` included), else the `@Input` fallback for a host that binds\n // the renderer directly. Getters, so a schema rebind is reflected live.\n get effectiveMin(): number {\n return this.leaf_?.minItems ?? this.minItems;\n }\n get effectiveMax(): number {\n return this.leaf_?.maxItems ?? this.maxItems;\n }\n\n /** Whether another item may be appended (below the effective maximum). */\n get canAdd(): boolean {\n return (this.formArray?.length ?? 0) < this.effectiveMax;\n }\n\n removeItem($index: number) {\n // A presence (optional / advisoryRequired) list has no present-empty state:\n // removing its last entry de-materializes the whole list (→ absent). A\n // required (non-presence) list instead stops at its minimum, staying `[]`.\n if (this.leaf_?.presence && this.formArray.length === 1) {\n this.removeList.emit();\n return;\n }\n if (this.formArray.length <= this.effectiveMin) {\n this.message.emit({\n message: 'You cannot remove the last item!',\n type: 'error',\n })\n return;\n }\n this.formArray.removeAt($index);\n }\n\n addItem() {\n if (this.formArray.length >= this.effectiveMax) return;\n this.formArray.push(new FormControl());\n }\n}\n","@if (formArray && leaf_) {\n @for (control of formArray.controls; track $index) {\n <div class=\"field-item\">\n <nff-anon-leaf-renderer\n [AnonLeaf]=\"leaf_\" [control]=\"control\"\n [removable]=\"formArray.length > effectiveMin\"\n [index]=\"$index\"\n [editable]=\"editable\"\n [label]=\"leaf_.label ?? leaf_.name\"\n (remove)=\"removeItem($index)\"\n />\n @if (editable) {\n <div class=\"actions\">\n @if (formArray.length > effectiveMin) {\n <button class=\"remove-button small-icon-button\" matIconButton [matTooltip]=\"'Remove ' + (leaf_.label ?? leaf_.name) + ' item'\" [attr.aria-label]=\"'Remove ' + (leaf_.label ?? leaf_.name) + ' item'\" (click)=\"removeItem($index)\">\n <mat-icon matPrefix>delete</mat-icon>\n </button>\n }\n @if ($last && canAdd) {\n <button class=\"add-button small-icon-button\" matIconButton [matTooltip]=\"'Add ' + (leaf_.label ?? leaf_.name) + ' item'\" [attr.aria-label]=\"'Add ' + (leaf_.label ?? leaf_.name) + ' item'\" (click)=\"addItem()\">\n <mat-icon matPrefix>add</mat-icon>\n </button>\n }\n <div class=\"actions-spacer\"></div>\n </div>\n }\n </div>\n }\n @if (editable && formArray.length === 0 && canAdd) {\n <!-- A required (non-presence) list can be present-but-empty; this labeled\n affordance adds the first entry so an empty list is not a dead end\n (mirrors the node-group list's \"Add … #1\"). A presence list never\n renders empty here — its first entry appears on materialize, and\n removing the last entry de-materializes it. -->\n <button\n matButton=\"outlined\"\n class=\"empty-add-button nff-clip-label\"\n [attr.aria-label]=\"'Add ' + (leaf_.label ?? leaf_.name) + ' item'\"\n [nffOverflowTooltip]=\"'Add ' + (leaf_.label ?? leaf_.name) + ' item'\"\n nffOverflowTooltipFor=\".mdc-button__label\"\n (click)=\"addItem()\"\n >\n <mat-icon>add</mat-icon> Add {{ leaf_.label ?? leaf_.name }} item\n </button>\n }\n}\n","import { FormArray, FormControl, FormGroup } from '@angular/forms';\n\nexport function asFormControl(control: any) {\n return control as FormControl;\n}\n\nexport function asFormArray(control: any) {\n return control as FormArray;\n}\n\nexport function asFormGroup(control: any) {\n return control as FormGroup;\n}\n\n","import { Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { Appearance, Leaf, LeafList, NodeGroup, NodeGroupList, NodeMap } from '../../types/dynamic-recursive.types';\nimport { descendantLayout } from '../../core/appearance';\nimport { addMapEntry, removeMapEntry, renameMapEntry } from '../../core/dynamic-recursive-forms-builder';\nimport { asFormArray, asFormControl, asFormGroup } from '../../core/utils';\nimport { LeafRendererComponent } from '../leaf-renderer/leaf-renderer.component';\nimport { LeafListRendererComponent } from '../leaf-list-renderer/leaf-list-renderer.component';\nimport { NodeGroupListRendererComponent } from '../node-group-list-renderer/node-group-list-renderer.component';\nimport { DynamicRecursiveFormComponent } from '../dynamic-recursive-form.component';\n\n/**\n * Renders a {@link NodeMap}: an open, arbitrary-keyed record. Each entry is a row\n * with an editable key and the shared value schema's control; the user can add,\n * remove, and rename entries. The map's control is a `FormGroup` whose control\n * names are the entry keys, so the key is edited as a *rename* (remove + re-add\n * the same control) committed on blur — see {@link renameEntry}.\n */\n@Component({\n selector: 'nff-node-map-renderer',\n standalone: true,\n imports: [\n MatButtonModule,\n MatIconModule,\n MatFormFieldModule,\n MatInputModule,\n MatTooltip,\n LeafRendererComponent,\n LeafListRendererComponent,\n NodeGroupListRendererComponent,\n // node-map-renderer references itself (a map-valued map) and the form (a\n // group-valued map), which import each other; forwardRef breaks the cycles.\n forwardRef(() => NodeMapRendererComponent),\n forwardRef(() => DynamicRecursiveFormComponent),\n ],\n templateUrl: './node-map-renderer.component.html',\n styleUrl: './node-map-renderer.component.scss',\n})\nexport class NodeMapRendererComponent implements OnChanges {\n @Input() nodeMap!: NodeMap;\n @Input() formGroup = new FormGroup<any>({});\n @Input() editable = true;\n /** Forwarded to each entry's embedded form — see the form's input of the same name. */\n @Input() showAbsentOptionals = false;\n /** Field-layout appearance from the enclosing group, forwarded to group-valued entry forms. */\n @Input() inheritedAppearance: Appearance | null = null;\n\n /** Ordered view of entry keys, kept stable across renames (`addControl` appends). */\n entryKeys: string[] = [];\n\n ngOnChanges(changes: SimpleChanges): void {\n // Re-sync whenever the bound group changes: a host may rebind the renderer\n // to another map (e.g. the tree editor swapping documents) while this\n // component instance survives.\n if (changes['formGroup']) this.entryKeys = Object.keys(this.formGroup.controls);\n }\n\n /**\n * What entry forms inherit: the enclosing group's layout with the map's own\n * `appearance` merged over it. Counterpart of the config editor's map-entry\n * threading in `buildChildNode`.\n */\n get entryAppearance(): Appearance | null {\n return descendantLayout(this.inheritedAppearance, this.nodeMap?.appearance);\n }\n\n /** The value schema as a leaf (used when `value.kind === 'leaf'`). */\n get valueLeaf(): Leaf {\n return this.nodeMap.value as Leaf;\n }\n /** The value schema as a group (used when `value.kind === 'nodeGroup'`). */\n get valueGroup(): NodeGroup {\n return this.nodeMap.value as NodeGroup;\n }\n /** Narrowing casts for the complex value kinds the template renders. */\n protected asLeafList(v: unknown): LeafList {\n return v as LeafList;\n }\n protected asNodeGroupList(v: unknown): NodeGroupList {\n return v as NodeGroupList;\n }\n protected asNodeMap(v: unknown): NodeMap {\n return v as NodeMap;\n }\n\n get atMax(): boolean {\n return this.nodeMap.maxEntries != null && this.entryKeys.length >= this.nodeMap.maxEntries;\n }\n get atMin(): boolean {\n return this.nodeMap.minEntries != null && this.entryKeys.length <= this.nodeMap.minEntries;\n }\n\n /** Append a new entry under a unique placeholder key. Delegates to {@link addMapEntry}. */\n addEntry(): void {\n const key = addMapEntry(this.formGroup, this.nodeMap);\n if (key != null) this.entryKeys = [...this.entryKeys, key];\n }\n\n /** Drop an entry (its control leaves the group, so it drops from the value). Delegates to {@link removeMapEntry}. */\n removeEntry(key: string): void {\n if (removeMapEntry(this.formGroup, this.nodeMap, key)) {\n this.entryKeys = this.entryKeys.filter((k) => k !== key);\n }\n }\n\n /**\n * Commit an edited key by renaming its control once (the value is preserved).\n * An empty, unchanged, duplicate, or `keyPattern`-violating key is a no-op,\n * leaving the entry under its current name. Delegates to {@link renameMapEntry}.\n */\n renameEntry(oldKey: string, rawKey: string): void {\n if (renameMapEntry(this.formGroup, this.nodeMap, oldKey, rawKey)) {\n const newKey = rawKey.trim();\n this.entryKeys = this.entryKeys.map((k) => (k === oldKey ? newKey : k));\n }\n }\n\n protected readonly asFormControl = asFormControl;\n protected readonly asFormGroup = asFormGroup;\n protected readonly asFormArray = asFormArray;\n}\n","@if (formGroup && nodeMap) {\n <div class=\"map-node\">\n @for (key of entryKeys; track key) {\n <div class=\"map-entry\">\n <mat-form-field class=\"key-field\" [appearance]=\"editable ? 'fill' : 'outline'\">\n <mat-label>{{ nodeMap.keyLabel ?? 'Key' }}</mat-label>\n <!-- On a rejected rename (empty, duplicate, keyPattern violation) the\n input snaps back to the committed key, so the display never\n disagrees with the key getRawValue() will emit. -->\n <input\n matInput\n #keyInput\n [readonly]=\"!editable\"\n [value]=\"key\"\n (change)=\"renameEntry(key, keyInput.value); keyInput.value = key\"\n >\n </mat-form-field>\n\n <!-- Index access, not .get(): entry keys are arbitrary runtime data and\n .get() would split a key like 'web.example.com' into a dotted path. -->\n <div class=\"value-field\">\n @if (nodeMap.value.kind === 'leaf') {\n <nff-leaf-renderer\n [leaf_]=\"valueLeaf\"\n [control]=\"asFormControl(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'nodeGroup') {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"entryAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [schema]=\"valueGroup\"\n [formGroup]=\"asFormGroup(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'leafList') {\n <nff-leaf-list-renderer\n [leaf_]=\"asLeafList(nodeMap.value)\"\n [formArray]=\"formGroup.controls[key]\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'nodeGroupList') {\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"entryAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [nodeGroupList]=\"asNodeGroupList(nodeMap.value)\"\n [formArray]=\"asFormArray(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n } @else if (nodeMap.value.kind === 'map') {\n <nff-node-map-renderer\n [inheritedAppearance]=\"entryAppearance\"\n [showAbsentOptionals]=\"showAbsentOptionals\"\n [nodeMap]=\"asNodeMap(nodeMap.value)\"\n [formGroup]=\"asFormGroup(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n }\n <!-- A choice-valued map (additionalProperties: anyOf/oneOf) has no\n standalone bare-choice renderer; use the config editor for it. -->\n </div>\n\n @if (editable && !atMin) {\n <button class=\"remove-button small-icon-button\" matIconButton [matTooltip]=\"'Remove ' + key + ' entry'\" [attr.aria-label]=\"'Remove ' + key + ' entry'\" (click)=\"removeEntry(key)\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n }\n @if (editable && !atMax) {\n <button class=\"add-button small-icon-button\" matIconButton [matTooltip]=\"'Add ' + (nodeMap.label ?? nodeMap.name) + ' entry'\" [attr.aria-label]=\"'Add ' + (nodeMap.label ?? nodeMap.name) + ' entry'\" (click)=\"addEntry()\">\n <mat-icon>add</mat-icon>\n </button>\n }\n </div>\n}\n","import { Component, computed, forwardRef, input, model, OnInit, output } from '@angular/core';\nimport { LeafRendererComponent } from './leaf-renderer/leaf-renderer.component';\nimport { Appearance, CASE_KEY, Leaf, NodeChoice, NodeGroup, NodeType } from '../types/dynamic-recursive.types';\nimport { inheritableAppearance, LayoutStyles, mergeAppearance } from '../core/appearance';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { NodeGroupListRendererComponent } from './node-group-list-renderer/node-group-list-renderer.component';\nimport { LeafListRendererComponent } from './leaf-list-renderer/leaf-list-renderer.component';\nimport { NodeMapRendererComponent } from './node-map-renderer/node-map-renderer.component';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { asFormArray, asFormControl, asFormGroup } from '../core/utils';\nimport { formatRadix } from './radix-input/radix-input.directive';\nimport {\n caseDisplayLabels, buildControl, caseFields, setNodePresence, switchChoiceCase } from '../core/dynamic-recursive-forms-builder';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { OverflowTooltipDirective } from '../directives/overflow-tooltip.directive';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatSelectModule } from '@angular/material/select';\n\n/**\n * A grid track count from `appearance.grid`: positive finite counts floored,\n * anything else (absent, zero, negative, non-finite) is 0 — so a bogus `cols`\n * cannot half-enter grid mode (e.g. suppress the rows-only column flow).\n */\nfunction gridTrackCount(count: number | undefined): number {\n return Number.isFinite(count) && count! > 0 ? Math.floor(count!) : 0;\n}\n\n@Component({\n imports: [\n LeafRendererComponent,\n LeafListRendererComponent,\n // node-group-list-renderer and node-map-renderer import this component back\n // (list items and map values may be groups); forwardRef tolerates either\n // module-evaluation order for the cycle.\n forwardRef(() => NodeGroupListRendererComponent),\n forwardRef(() => NodeMapRendererComponent),\n ReactiveFormsModule,\n MatExpansionModule,\n MatIconModule,\n MatButtonModule,\n NgTemplateOutlet,\n MatCheckboxModule,\n MatFormFieldModule,\n MatSelectModule,\n MatTooltip,\n OverflowTooltipDirective,\n ],\n selector: 'nff-dynamic-recursive-form',\n standalone: true,\n styleUrl: './dynamic-recursive-form.component.scss',\n templateUrl: './dynamic-recursive-form.component.html',\n})\nexport class DynamicRecursiveFormComponent implements OnInit {\n /** The form-description schema to render (a root or nested `NodeGroup`). */\n readonly schema = input.required<NodeGroup>();\n /** Optional value object to seed the form; keyed by the schema's `children` keys. */\n readonly initialValue = input<Record<string, unknown> | null>(null);\n /** The reactive group this form binds to. Defaults to an empty group. */\n readonly formGroup = input<FormGroup>(new FormGroup({}));\n /** Index of this form within a parent list, used by `addButtonCallback`. */\n readonly index = input<number | null>(null);\n /** Whether this form may be removed from a parent list (shows a remove control). */\n readonly removable = input<boolean>(false);\n /** Emitted when the user removes this form from a parent list. */\n readonly remove = output<void>();\n /** Card/section title; falls back to the schema label or name. */\n readonly title = input<string>();\n /** Whether fields accept input. Two-way: also toggled by the built-in edit control. */\n readonly editable = model<boolean>(false);\n /**\n * Preview absent optional (presence) leaves as **ghost fields**: the field\n * renders read-only and empty — its schema `default`, if any, shown as the\n * placeholder — with a (+) button that incorporates it into the form, so the\n * user sees the complete form surface. A ghost holds **no control in the\n * form**: it never appears in `value`/`getRawValue()`/`serializeForm` output\n * and never affects validity until incorporated. Replaces the default\n * \"Add <field>\" button affordance; ignored while the form is not editable\n * (read-only mode hides structural affordances, ghosts included).\n */\n readonly showAbsentOptionals = input<boolean>(false);\n /** Invoked with {@link index} to append a new sibling form to a parent list. */\n readonly addButtonCallback = input<((index: number) => void) | null>(null);\n /**\n * Label for the add-sibling button — the parent list names the appended\n * entry (\"Add Cell #3\"), which this form cannot derive itself (it knows\n * neither the list's label nor its length). Falls back to\n * \"Add new <own label>\".\n */\n readonly addButtonLabel = input<string | null>(null);\n /**\n * Key of a presence leaf whose field should grab focus when it renders — lets\n * a host that added the control itself (e.g. the tree editor's optionals\n * menu) hand focus to the new field, like the form's own add button does.\n */\n readonly focusLeaf = input<string | null>(null);\n /**\n * Field-layout appearance cascading down from the parent group. The node's\n * own `appearance` wins per property — see {@link mergeAppearance}.\n */\n readonly inheritedAppearance = input<Appearance | null>(null);\n\n /** True when the schema is a root group (rendered flat, without a wrapping card). */\n readonly root = computed(() => this.schema().root ?? false);\n\n /** The node's own `appearance` with inherited layout gaps filled in. */\n protected readonly effectiveAppearance = computed<Appearance | undefined>(() =>\n mergeAppearance(this.inheritedAppearance(), this.schema().appearance),\n );\n\n /** The layout subset this node's children inherit. */\n protected readonly childAppearance = computed<Appearance | null>(() =>\n inheritableAppearance(this.effectiveAppearance()),\n );\n\n /**\n * The per-type width bounds are flex-flow-only, and their CSS custom\n * properties inherit into leaf-list internals that the grid-mode resets\n * cannot reach across the encapsulation boundary — so under a grid layout\n * the variables are simply not set at all.\n */\n private flexOnly<T>(value: T | undefined): T | null {\n return this.fieldsLayout() ? null : (value ?? null);\n }\n\n /** `minTextFieldWidth` for the `.fields` CSS custom property, or null. */\n protected readonly textFieldMin = computed(() => this.flexOnly(this.effectiveAppearance()?.minTextFieldWidth));\n /** `minNumberFieldWidth` for the `.fields` CSS custom property, or null. */\n protected readonly numberFieldMin = computed(() => this.flexOnly(this.effectiveAppearance()?.minNumberFieldWidth));\n /** `maxNumberFieldWidth` for the `.fields` CSS custom property, or null. */\n protected readonly numberFieldMax = computed(() => this.flexOnly(this.effectiveAppearance()?.maxNumberFieldWidth));\n\n /**\n * True when the active grid defines explicit column tracks. Only then can a\n * stacked leaf-list meaningfully span the row (`grid-column: 1 / -1`\n * resolves `-1` to line 1 without an explicit column template) and repeat\n * the tracks for its entries; in a rows-only grid the list stays a normal\n * auto-flowed item.\n */\n protected readonly gridHasCols = computed(() => !!this.fieldsLayout()?.['grid-template-columns']);\n\n /**\n * Inline grid styles for the `.fields` area, from `appearance`: `grid`\n * becomes explicit tracks (`cols` fields per row; `rows` alone fills\n * top-to-bottom, adding columns as needed) and `minFieldWidth` becomes\n * as-many-as-fit equal columns of at least that width. `grid` wins over\n * `minFieldWidth`; with neither, `null` keeps the stylesheet's wrapping\n * flex flow. Non-positive `rows`/`cols` are ignored.\n */\n protected readonly fieldsLayout = computed<LayoutStyles | null>(() => {\n const appearance = this.effectiveAppearance();\n const cols = gridTrackCount(appearance?.grid?.cols);\n const rows = gridTrackCount(appearance?.grid?.rows);\n if (cols > 0 || rows > 0) {\n const layout: LayoutStyles = { display: 'grid' };\n if (cols > 0) layout['grid-template-columns'] = `repeat(${cols}, minmax(0, 1fr))`;\n if (rows > 0) layout['grid-template-rows'] = `repeat(${rows}, auto)`;\n if (rows > 0 && cols === 0) {\n layout['grid-auto-flow'] = 'column';\n // The columns this flow creates are implicit; without a bound they\n // size to content and can overflow — match the cols-mode tracks.\n layout['grid-auto-columns'] = 'minmax(0, 1fr)';\n }\n return layout;\n }\n if (appearance?.minFieldWidth) {\n // min(…, 100%) keeps a narrow container to one column instead of overflowing.\n return {\n display: 'grid',\n 'grid-template-columns': `repeat(auto-fit, minmax(min(${appearance.minFieldWidth}, 100%), 1fr))`,\n };\n }\n return null;\n });\n\n /**\n * Whether the gathered boolean row would show anything: a plain boolean, an\n * enabled presence boolean, or (while editable) an absent one's add button.\n * Keeps a read-only form from rendering an empty `.boolean-fields` div,\n * which would add a stray container gap.\n */\n protected booleanAreaVisible(): boolean {\n return Object.entries(this.schema().children ?? {}).some(\n ([key, child]) =>\n child.kind === 'leaf' &&\n child.type === 'boolean' &&\n (!child.presence || !!this.formGroup().get(key) || this.editable()),\n );\n }\n\n /**\n * Whether a leaf renders in the regular `.fields` flow: always, unless it is\n * a boolean that {@link booleanPlacement} gathers into the `.boolean-fields`\n * row instead.\n */\n protected inFieldFlow(child: Leaf): boolean {\n return this.booleanPlacement() === 'default' || child.type !== 'boolean';\n }\n\n /**\n * Where `appearance.booleanFields` places the checkbox fields: `'beginning'`\n * or `'end'` renders them grouped in the `.boolean-fields` row and excludes\n * them from the regular field flow; `'default'` (also when the group has no\n * boolean leaf to move) leaves the flow untouched.\n */\n protected readonly booleanPlacement = computed<'beginning' | 'end' | 'default'>(() => {\n const placement = this.effectiveAppearance()?.booleanFields ?? 'default';\n if (placement === 'default') return 'default';\n const hasBooleans = Object.values(this.schema().children ?? {}).some(\n (child) => child.kind === 'leaf' && child.type === 'boolean',\n );\n return hasBooleans ? placement : 'default';\n });\n\n ngOnInit() {\n const initial = this.initialValue();\n if (initial) {\n const group = this.formGroup();\n // Presence keys carried by the initial value need controls first:\n // patchValue silently skips keys that have none, dropping the data.\n for (const [key, child] of Object.entries(this.schema().children ?? {})) {\n if ('presence' in child && child.presence && key in initial && !group.get(key)) {\n group.addControl(key, buildControl(child, initial[key]) as never);\n }\n }\n group.patchValue(initial);\n }\n }\n\n protected get nodeGroupChildrenList(): Array<{ key: string; value: NodeType }> {\n const children = this.schema().children ?? {};\n return Object.entries(children).map(([key, value]) => ({\n key,\n value: value as NodeType,\n }));\n }\n\n protected emitRemoveEvent() {\n this.remove.emit();\n }\n\n /** The key of the presence leaf the user just enabled; its field grabs focus when rendered. */\n protected presenceFocusKey: string | null = null;\n\n /**\n * Add or remove a presence node's control on this form — any presence kind:\n * group, leaf, map, or choice. Removing it drops the key from `form.value`;\n * adding it builds the control fresh from its schema (nested presence\n * children start absent). Delegates to {@link setNodePresence}, the\n * host-callable primitive.\n */\n toggleNodePresence(key: string, schema: NodeType, present: boolean) {\n setNodePresence(this.formGroup(), schema, key, present);\n // Either way the key's ghost stand-in is stale: drop it, so a later\n // re-ghosting renders a pristine one even if the old instance was mutated.\n this.ghostControls.delete(key);\n }\n\n /**\n * The detached stand-in control a ghost field renders against. Never added\n * to {@link formGroup} — that detachment is the whole guarantee: a ghost\n * cannot reach `value`, `getRawValue()`, or validity. Always `null`-valued\n * (the schema default shows as a placeholder instead, see\n * {@link ghostPlaceholder}); cached per key so change detection re-reads a\n * stable instance.\n */\n protected ghostControl(key: string): FormControl {\n let control = this.ghostControls.get(key);\n if (!control) {\n control = new FormControl(null);\n this.ghostControls.set(key, control);\n }\n return control;\n }\n private readonly ghostControls = new Map<string, FormControl>();\n\n /**\n * A ghost field's placeholder: the leaf's `default`, or empty — spelled in\n * the leaf's `radix` when it has one, matching how the incorporated field\n * will display it.\n */\n protected ghostPlaceholder(schema: Leaf): string {\n if (!('default' in schema) || schema.default == null) return '';\n const radix = 'radix' in schema ? schema.radix : undefined;\n const integral =\n typeof schema.default === 'number'\n ? Number.isInteger(schema.default)\n : typeof schema.default === 'string' && /^[-+]?[0-9]+$/.test(schema.default);\n if (radix && integral) return formatRadix(schema.default as number | string, radix);\n return String(schema.default);\n }\n\n /**\n * {@link toggleNodePresence} for a presence leaf, additionally focusing the\n * rendered field when the toggle just created it.\n */\n toggleLeafPresence(key: string, schema: Leaf, present: boolean) {\n const had = !!this.formGroup().get(key);\n this.toggleNodePresence(key, schema, present);\n if (present && !had) {\n this.presenceFocusKey = key;\n // Retire the request once the field has rendered and taken focus, so a\n // later re-creation of the same renderer cannot steal focus again.\n setTimeout(() => {\n if (this.presenceFocusKey === key) this.presenceFocusKey = null;\n });\n }\n if (!present && this.presenceFocusKey === key) this.presenceFocusKey = null;\n }\n\n /**\n * Materialize an absent presence (optional / `advisoryRequired`) list *with\n * its first entry* — clicking \"Add <list>\" makes the first entry appear at\n * once. An optional list has no present-empty state: removing the last entry\n * de-materializes it (→ absent). A required list is always present instead and\n * uses the renderer's own \"Add item\" affordance, so it never routes here.\n */\n addPresenceList(key: string, schema: NodeType) {\n setNodePresence(this.formGroup(), schema, key, true, [null]);\n this.ghostControls.delete(key);\n }\n\n protected objectKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj);\n }\n\n /** The active case name of a choice control, or null if none is selected. */\n protected activeCase(key: string): string | null {\n return (this.formGroup().get(key) as FormGroup | null)?.get(CASE_KEY)?.value ?? null;\n }\n\n /**\n * A synthetic flattened NodeGroup used to render the active case's fields\n * against the choice's FormGroup. Carries the choice's own `appearance`\n * (grid / field-width layout) onto the case fields.\n */\n protected caseAsGroup(choice: NodeChoice, caseName: string): NodeGroup {\n return {\n kind: 'nodeGroup',\n name: choice.name,\n children: choice.cases[caseName] ? caseFields(choice.cases[caseName]) : {},\n appearance: { ...choice.appearance, flatten: true },\n };\n }\n\n /**\n * The display label for a case: the schema's `caseLabels` entry (colliding\n * labels disambiguated by their distinguishing fields — see\n * {@link caseDisplayLabels}), else the case name.\n */\n caseLabel(choice: NodeChoice, caseName: string): string {\n return caseDisplayLabels(choice)[caseName] ?? caseName;\n }\n\n /**\n * A copy of a group flagged to render its fields inline (no inner panel). Used\n * for a presence group's body, whose container is the presence panel itself, so\n * the group's own section panel would be a redundant second box.\n */\n protected flatGroup(group: NodeGroup): NodeGroup {\n return { ...group, appearance: { ...group.appearance, flatten: true } };\n }\n\n /** Swap a choice's field controls when the selected case changes. Delegates to {@link switchChoiceCase}. */\n switchCase(key: string, choice: NodeChoice, caseName: string) {\n switchChoiceCase(this.formGroup().get(key) as FormGroup, choice, caseName);\n }\n\n protected readonly asFormGroup = asFormGroup;\n protected readonly asFormArray = asFormArray;\n protected readonly asFormControl = asFormControl;\n}\n","<!-- Checkbox fields grouped by appearance.booleanFields: a compact wrapping\n row of natural-width items, rendered before or after the field flow. -->\n<ng-template #booleanArea>\n @if (booleanAreaVisible()) {\n <div class=\"boolean-fields\">\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && child.type == 'boolean') {\n @if (!child.presence) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=false\n [editable]=\"editable()\"\n />\n } @else if (formGroup().get(childItem.key)) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=true\n [editable]=\"editable()\"\n [autofocus]=\"presenceFocusKey === childItem.key || focusLeaf() === childItem.key\"\n (remove)=\"toggleLeafPresence(childItem.key, child, false)\"\n />\n } @else if (editable()) {\n @if (showAbsentOptionals()) {\n <!-- Ghost preview of an absent boolean: unchecked, display-only,\n no control in the form; (+) incorporates it. -->\n <div class=\"ghost-field\">\n <nff-leaf-renderer\n [leaf_]=child\n [control]=\"ghostControl(childItem.key)\"\n [removable]=false\n [editable]=false\n />\n <button\n matIconButton\n class=\"ghost-add small-icon-button\"\n [matTooltip]=\"'Add ' + (child.label ?? child.name)\"\n [attr.aria-label]=\"'Add ' + (child.label ?? child.name)\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n } @else {\n <button\n matButton=\"outlined\"\n class=\"presence-leaf-add nff-clip-label\"\n [nffOverflowTooltip]=\"'Add ' + (child.label ?? child.name)\"\n nffOverflowTooltipFor=\".mdc-button__label\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n }\n }\n </div>\n }\n</ng-template>\n<!-- The node's scalar-field area — gathered booleans (beginning), the .fields\n flow, gathered booleans (end) — shared by the root and non-root branches. -->\n<ng-template #fieldFlow>\n @if (booleanPlacement() === 'beginning') {\n <ng-container *ngTemplateOutlet=\"booleanArea\"></ng-container>\n }\n <div class=\"fields\" [class.grid-fields]=\"!!fieldsLayout()\" [class.grid-cols]=\"gridHasCols()\" [style]=\"fieldsLayout()\" [style.--nff-min-text-field-width]=\"textFieldMin()\" [style.--nff-min-number-field-width]=\"numberFieldMin()\" [style.--nff-max-number-field-width]=\"numberFieldMax()\">\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && !child.presence && inFieldFlow(child)) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=false\n [editable]=\"editable()\"\n />\n }\n }\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leafList' && !child.presence) {\n <nff-leaf-list-renderer\n [layout]=\"gridHasCols() ? fieldsLayout() : null\"\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n />\n }\n @else if (child.kind == 'leafList' && child.presence) {\n <!-- Optional (advisoryRequired) list: an \"Add <list>\" button while\n absent; clicking it materializes the list with its first entry (no\n empty state). Removing the last entry de-materializes it (the\n renderer's `removeList` → absent). -->\n @let leafListArray = asFormArray(formGroup().get(childItem.key));\n @if (leafListArray) {\n <div class=\"presence-list\">\n <nff-leaf-list-renderer\n [layout]=\"gridHasCols() ? fieldsLayout() : null\"\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"leafListArray\"\n (removeList)=\"toggleNodePresence(childItem.key, child, false)\"\n />\n </div>\n } @else if (editable()) {\n <button\n matButton=\"outlined\"\n class=\"presence-list-add nff-clip-label\"\n [nffOverflowTooltip]=\"'Add ' + (child.label ?? child.name)\"\n nffOverflowTooltipFor=\".mdc-button__label\"\n (click)=\"addPresenceList(childItem.key, child)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n }\n <!-- Presence leaves trail the regular fields so their add buttons don't\n interrupt the field flow; an enabled one keeps its trailing spot. -->\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && child.presence && inFieldFlow(child)) {\n @if (formGroup().get(childItem.key)) {\n <nff-leaf-renderer\n [leaf_]=child\n [control]=asFormControl(formGroup().get(childItem.key))\n [removable]=true\n [editable]=\"editable()\"\n [autofocus]=\"presenceFocusKey === childItem.key || focusLeaf() === childItem.key\"\n (remove)=\"toggleLeafPresence(childItem.key, child, false)\"\n />\n } @else if (editable()) {\n <!-- Read-only mode renders nothing for an absent presence leaf:\n the key is simply absent, and add affordances are hidden\n like every other structural control. -->\n @if (showAbsentOptionals()) {\n <!-- Ghost preview: the field itself, read-only against a detached\n null control (never part of the form value), default as\n placeholder; (+) incorporates it. -->\n <div class=\"ghost-field\">\n <nff-leaf-renderer\n [leaf_]=child\n [control]=\"ghostControl(childItem.key)\"\n [removable]=false\n [editable]=false\n [placeholder]=\"ghostPlaceholder(child)\"\n />\n <button\n matIconButton\n class=\"ghost-add small-icon-button\"\n [matTooltip]=\"'Add ' + (child.label ?? child.name)\"\n [attr.aria-label]=\"'Add ' + (child.label ?? child.name)\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </div>\n } @else {\n <button\n matButton=\"outlined\"\n class=\"presence-leaf-add nff-clip-label\"\n [nffOverflowTooltip]=\"'Add ' + (child.label ?? child.name)\"\n nffOverflowTooltipFor=\".mdc-button__label\"\n (click)=\"toggleLeafPresence(childItem.key, child, true)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n }\n }\n </div>\n @if (booleanPlacement() === 'end') {\n <ng-container *ngTemplateOutlet=\"booleanArea\"></ng-container>\n }\n</ng-template>\n@if (!root()) {\n <ng-template #formRender>\n <div class=\"form-content\" [formGroup]=\"formGroup()\">\n <div class=\"leafs-container\">\n <ng-container *ngTemplateOutlet=\"fieldFlow\"></ng-container>\n </div>\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'nodeGroup' && child.presence) {\n <div class=\"presence-group\">\n <mat-checkbox\n [checked]=\"!!formGroup().get(childItem.key)\"\n [disabled]=\"!editable()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n @if (formGroup().get(childItem.key)) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"flatGroup(child)\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [editable]=\"editable()\"\n />\n }\n </div>\n }\n @else if (child.kind == 'nodeGroup') {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"child\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n }\n @else if (child.kind == 'choice') {\n @let choiceGroup = asFormGroup(formGroup().get(childItem.key));\n @let selectedCase = activeCase(childItem.key);\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!choiceGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!choiceGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (choiceGroup) {\n <div class=\"choice-group\">\n <mat-form-field [appearance]=\"editable() ? 'fill' : 'outline'\">\n <mat-label>Selected option</mat-label>\n <mat-select\n [value]=\"activeCase(childItem.key)\"\n (selectionChange)=\"switchCase(childItem.key, child, $event.value)\"\n >\n @for (caseName of objectKeys(child.cases); track caseName) {\n <mat-option [value]=\"caseName\">{{ caseLabel(child, caseName) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (selectedCase) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"caseAsGroup(child, selectedCase)\"\n [formGroup]=\"choiceGroup\"\n [editable]=\"editable()\"\n />\n }\n </div>\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList' && !child.presence) {\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n }\n @else if (child.kind == 'nodeGroupList' && child.presence) {\n <!-- Optional (advisoryRequired) list: an \"Add <list>\" button while\n absent; clicking it materializes the list with its first entry.\n Removing the last entry de-materializes it (`removeList` → absent). -->\n @let presenceListArray = asFormArray(formGroup().get(childItem.key));\n @if (presenceListArray) {\n <div class=\"presence-list\">\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"presenceListArray\"\n [editable]=\"editable()\"\n (removeList)=\"toggleNodePresence(childItem.key, child, false)\"\n />\n </div>\n } @else if (editable()) {\n <button\n matButton=\"outlined\"\n class=\"presence-list-add nff-clip-label\"\n [nffOverflowTooltip]=\"'Add ' + (child.label ?? child.name)\"\n nffOverflowTooltipFor=\".mdc-button__label\"\n (click)=\"addPresenceList(childItem.key, child)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n @else if (child.kind == 'map') {\n @let mapGroup = asFormGroup(formGroup().get(childItem.key));\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!mapGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!mapGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (mapGroup) {\n <nff-node-map-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeMap]=\"child\"\n [formGroup]=\"mapGroup\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n }\n </div>\n </ng-template>\n @if (schema().appearance?.flatten) {\n <div class=\"flattened-form\">\n <ng-container *ngTemplateOutlet=\"formRender\"></ng-container>\n <div class=\"flattened-actions\">\n @if (editable() && index() != null && addButtonCallback() != null) {\n <button matIconButton [matTooltip]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" [attr.aria-label]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" class=\"add-button small-icon-button\" (click)=\"addButtonCallback()!(index()!)\">\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && removable()) {\n <button matIconButton class=\"remove-button small-icon-button\" matTooltip=\"Remove {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'Remove ' + (schema().label ?? schema().name)\" (click)=\"emitRemoveEvent(); $event.stopPropagation()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n </div>\n }\n @else {\n <mat-expansion-panel class=\"node-section\" [expanded]=\"!schema().appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title class=\"config-form-subsection-card\">\n {{ title() ?? schema().label ?? schema().name }}\n </mat-panel-title>\n <mat-panel-description class=\"section-actions\">\n <button matIconButton class=\"small-icon-button\" [class]=\"{ 'edit-icon': !editable() }\" [attr.aria-label]=\"editable() ? 'Stop editing' : 'Edit'\" (click)=\"editable.set(!editable()); $event.stopPropagation()\">\n <mat-icon>edit</mat-icon>\n </button>\n @if (editable() && index() != null && addButtonCallback() != null) {\n <button matIconButton [matTooltip]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" [attr.aria-label]=\"addButtonLabel() ?? 'Add new ' + (schema().label ?? schema().name)\" class=\"add-button small-icon-button\" (click)=\"addButtonCallback()!(index()!); $event.stopPropagation()\">\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && removable()) {\n <button matIconButton class=\"remove-button small-icon-button\" matTooltip=\"Remove {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'Remove ' + (schema().label ?? schema().name)\" (click)=\"emitRemoveEvent(); $event.stopPropagation()\">\n <mat-icon>delete</mat-icon>\n </button>\n }\n </mat-panel-description>\n </mat-expansion-panel-header>\n <ng-container *ngTemplateOutlet=\"formRender\"></ng-container>\n </mat-expansion-panel>\n }\n} @else {\n <div class=\"form-content\" [formGroup]=\"formGroup()\">\n <div class=\"leafs-container\">\n <!-- The edit toggle sits on its own row: inline it would offset the\n first field row against the rows below (flex) or claim a whole\n track (grid). -->\n <div class=\"form-toolbar\">\n <button matIconButton class=\"small-icon-button\" [class]=\"{ 'edit-icon': !editable() }\" [attr.aria-label]=\"editable() ? 'Stop editing' : 'Edit'\" (click)=\"editable.set(!editable())\">\n <mat-icon>edit</mat-icon>\n </button>\n </div>\n <ng-container *ngTemplateOutlet=\"fieldFlow\"></ng-container>\n </div>\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'choice') {\n @let choiceGroup = asFormGroup(formGroup().get(childItem.key));\n @let selectedCase = activeCase(childItem.key);\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!choiceGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!choiceGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (choiceGroup) {\n <div class=\"choice-group\">\n <mat-form-field [appearance]=\"editable() ? 'fill' : 'outline'\">\n <mat-label>Selected option</mat-label>\n <mat-select\n [value]=\"activeCase(childItem.key)\"\n (selectionChange)=\"switchCase(childItem.key, child, $event.value)\"\n >\n @for (caseName of objectKeys(child.cases); track caseName) {\n <mat-option [value]=\"caseName\">{{ caseLabel(child, caseName) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (selectedCase) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"caseAsGroup(child, selectedCase)\"\n [formGroup]=\"choiceGroup\"\n [editable]=\"editable()\"\n />\n }\n </div>\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'map') {\n @let mapGroup = asFormGroup(formGroup().get(childItem.key));\n <mat-expansion-panel class=\"node-section\" [expanded]=\"child.presence ? !!mapGroup : !child.appearance?.collapsed\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n @if (child.presence) {\n <mat-checkbox\n [checked]=\"!!mapGroup\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n } @else {\n {{ child.label ?? child.name }}\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (mapGroup) {\n <nff-node-map-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeMap]=\"child\"\n [formGroup]=\"mapGroup\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList' && !child.presence) {\n <!-- A nodeGroupList has no `appearance` of its own, so its section is\n always shown; only an ancestor's collapse hides it. -->\n <mat-expansion-panel class=\"node-section\" [expanded]=\"true\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>{{ child.label ?? child.name }}</mat-panel-title>\n </mat-expansion-panel-header>\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList' && child.presence) {\n <!-- Optional (advisoryRequired) list: an \"Add <list>\" button while\n absent; clicking it materializes the list with its first entry.\n Removing the last entry de-materializes it (`removeList` → absent). -->\n @let rootListArray = asFormArray(formGroup().get(childItem.key));\n @if (rootListArray) {\n <div class=\"presence-list\">\n <nff-node-group-list-renderer\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [nodeGroupList]=\"child\"\n [formArray]=\"rootListArray\"\n [editable]=\"editable()\"\n (removeList)=\"toggleNodePresence(childItem.key, child, false)\"\n />\n </div>\n } @else if (editable()) {\n <button\n matButton=\"outlined\"\n class=\"presence-list-add nff-clip-label\"\n [nffOverflowTooltip]=\"'Add ' + (child.label ?? child.name)\"\n nffOverflowTooltipFor=\".mdc-button__label\"\n (click)=\"addPresenceList(childItem.key, child)\"\n >\n <mat-icon>add</mat-icon> Add {{ child.label ?? child.name }}\n </button>\n }\n }\n @else if (child.kind == 'nodeGroup' && child.presence) {\n <mat-expansion-panel class=\"node-section\" togglePosition=\"before\" [expanded]=\"!!formGroup().get(childItem.key)\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-checkbox\n [checked]=\"!!formGroup().get(childItem.key)\"\n [disabled]=\"!editable()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleNodePresence(childItem.key, child, $event.checked)\"\n >{{ child.label ?? child.name }}</mat-checkbox>\n </mat-panel-title>\n </mat-expansion-panel-header>\n @if (formGroup().get(childItem.key)) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"flatGroup(child)\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroup') {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"childAppearance()\" [showAbsentOptionals]=\"showAbsentOptionals()\"\n [schema]=\"child\"\n [formGroup]=\"asFormGroup(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\n [editable]=\"editable()\"\n />\n }\n }\n </div>\n}\n","import { ChangeDetectorRef, Component, effect, ElementRef, inject, input, model, OnDestroy, untracked } from '@angular/core';\nimport { AbstractControl, FormArray, FormGroup } from '@angular/forms';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { Subscription } from 'rxjs';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { Appearance, CASE_KEY, NodeChoice, NodeGroup, NodeMap, NodeType } from '../types/dynamic-recursive.types';\nimport { descendantLayout } from '../core/appearance';\nimport {\n addMapEntry,\n buildControl,\n buildFormFromSchema,\n caseDisplayLabels,\n caseFields,\n removeMapEntry,\n renameMapEntry,\n setNodePresence,\n switchChoiceCase,\n} from '../core/dynamic-recursive-forms-builder';\nimport { DynamicRecursiveFormComponent } from '../dynamic-recursive-form/dynamic-recursive-form.component';\nimport { NodeMapRendererComponent } from '../dynamic-recursive-form/node-map-renderer/node-map-renderer.component';\n\n/**\n * The transformers package names a root nobody named `__root__` — a sentinel,\n * not display text (the packages share no code, so the string is matched here\n * verbatim). The tree substitutes {@link ROOT_FALLBACK_TITLE} for it; any\n * other root name is an authored one and displays as-is.\n */\nconst ROOT_SENTINEL = '__root__';\nconst ROOT_FALLBACK_TITLE = 'Configuration';\n\n/** Metadata on a list-container node that lets the tree add items to its FormArray. */\ninterface ListRef {\n array: FormArray;\n itemSchema: NodeGroup;\n itemLabel: string;\n minItems: number;\n maxItems?: number;\n}\n\n/** An absent optional (presence) child, offered by its parent node's \"+ Optional field\" menu. */\ninterface OptionalEntry {\n key: string;\n schema: NodeType;\n label: string;\n}\n\n/**\n * One flat section of the detail pane. The selected node's subtree renders as a\n * pre-order list of these — no nesting chrome: each section after the first is\n * separated by a breadcrumb heading (`trail`), and holds only the node's *own*\n * fields (`schema` is a leaf-only slice; complex children are sections of their\n * own, deeper in the list).\n */\ninterface DetailSection {\n node: TreeNode;\n /** Selected-node-to-here trail, rendered as the section's breadcrumb heading (omitted on the first section). */\n trail: TreeNode[];\n /** Leaf-only slice of the node's own schema, or null when it has no own fields. */\n schema: NodeGroup | null;\n /** The group `schema` binds to (the node's group; for a choice, the choice group). */\n group: FormGroup | null;\n /** A trailing add-control section of a list / complex map: renders after the last item, with no heading. */\n footer?: boolean;\n /** The section continues a run of same-list items / same-map entries: its heading draws no divider line. */\n continuation?: boolean;\n}\n\n/**\n * A navigable node in the config tree. Its `id` is the node's stable path from\n * the root (`system/ntp`, `ifaces/0`, `servers/web1`), so expansion and\n * selection survive tree rebuilds. Segments are `%`/`/`-escaped, since map\n * entry keys are arbitrary runtime data; list-item identity is positional.\n */\ninterface TreeNode {\n id: string;\n label: string;\n children: TreeNode[];\n /** The node's own FormGroup, or null for a list-container or map node. */\n group: FormGroup | null;\n /** The node's own schema, set on group-backed nodes (groups, list items, group-valued map entries). */\n schema?: NodeGroup;\n /** Present on a nodeGroupList node: lets a `+` add an item. */\n list?: ListRef;\n /** Present on a list-item node: its current index in the parent list (removal goes through the parent list array). */\n removable?: { index: number };\n /** Absent optional children of this node, offered by its \"+ Optional field\" menu (schema order). */\n optionals?: OptionalEntry[];\n /** Present on a present optional child node: drives the row's remove control. */\n presenceRemovable?: { key: string; schema: NodeType };\n /** Field-layout appearance inherited from ancestor groups, for the node's detail-section form. */\n inherited?: Appearance | null;\n /** Present on a choice node: the choice schema and its FormGroup (holding `__case` + the active case's fields). */\n choice?: { schema: NodeChoice; group: FormGroup };\n /** Present on a map node. `complex` maps expand entries as child nodes. */\n map?: { schema: NodeMap; group: FormGroup; complex: boolean };\n /** Present on a complex-map entry node: addresses the entry in its map for remove/rename. */\n mapEntry?: { mapGroup: FormGroup; mapSchema: NodeMap; key: string };\n}\n\n/**\n * A tree/detail editor for a schema-built form: the structure (groups, lists,\n * maps, choices) is a tree on the left, and selecting a node renders that\n * node's **entire subtree** on the right as a **flat list of sections** — the\n * node's own fields first, then every descendant's fields, each separated by a\n * breadcrumb heading (`Service / Deploy scope / …`) instead of nested panels.\n * Leaf fields render through {@link DynamicRecursiveFormComponent} with a\n * leaf-only schema slice; choice selectors, map rows, and add controls render\n * inline in their section. The tree adds row conveniences of its own: `+` on\n * list and map rows, a delete control on removable rows, and a\n * \"+ Optional field\" menu for absent presence children.\n *\n * The tree is **derived state**: any structural change to the form — made\n * through the tree rows or through the detail sections — triggers a rebuild (a\n * cheap shape signature over `valueChanges` detects it). Node ids are stable\n * paths, so expansion and selection survive rebuilds. Swapping the `schema` or\n * `formGroup` input rebinds the editor to the new pair, resetting expansion\n * and selection.\n *\n * The component draws no outer container — only a divider between the tree and\n * detail panes — so the embedding client owns the surrounding chrome.\n */\n@Component({\n selector: 'nff-config-editor',\n standalone: true,\n imports: [\n NgTemplateOutlet,\n MatIconModule,\n MatButtonModule,\n MatMenuModule,\n MatFormFieldModule,\n MatInputModule,\n MatSelectModule,\n MatTooltip,\n DynamicRecursiveFormComponent,\n NodeMapRendererComponent,\n ],\n templateUrl: './config-editor.component.html',\n styleUrl: './config-editor.component.scss',\n})\nexport class ConfigEditorComponent implements OnDestroy {\n /** The form-description schema whose structure the tree renders. */\n readonly schema = input.required<NodeGroup>();\n /** The schema-built reactive group the editor binds to and mutates. */\n readonly formGroup = input.required<FormGroup>();\n /**\n * Whether fields accept input and structural controls (add/remove/menus)\n * show. Two-way bindable: the root tree row carries a toggle, so the editor\n * can flip it itself and the host observes the change.\n */\n readonly editable = model<boolean>(true);\n /**\n * Title for the root tree row and breadcrumb origin, overriding the schema's\n * own `label`/`name`. Read when the tree is (re)built, so a later change\n * shows on the next rebind or structural rebuild, not immediately.\n */\n readonly rootTitle = input<string>();\n /**\n * Whether selecting a tree row also expands the node's own children.\n * Off by default: a click selects (the detail pane shows the subtree\n * anyway) and the twisty alone controls expansion, so browsing a deep\n * config does not keep unfolding the tree. Ancestors of the selection are\n * always expanded — the selected row itself must stay visible.\n */\n readonly expandOnClick = input<boolean>(false);\n /**\n * Whether the tree starts **fully expanded** when it (re)binds to a\n * schema/form pair — every node with children unfolded, as if the user had\n * hit expand-all. Off by default (only the root row is open). Read at bind\n * time, so it sets the *initial* state: the user's later collapses/expands\n * and the root row's expand-all toggle take over from there, and a\n * structural rebuild preserves whatever is currently expanded rather than\n * re-expanding.\n */\n readonly initiallyExpanded = input<boolean>(false);\n /**\n * Whether the detail pane shows its top breadcrumb (the selected node's\n * path, with the member remove control beside it). Hosts whose tree\n * already tells the user where they are can turn it off — the section\n * trail headings inside the detail stay, and member removal remains\n * available on the tree rows and section headings.\n */\n readonly showBreadcrumb = input<boolean>(true);\n\n root!: TreeNode;\n selected: TreeNode | null = null;\n /** The selected subtree as a flat, breadcrumb-separated section list. */\n sections: DetailSection[] = [];\n /** Root-to-selection trail for the detail-pane breadcrumb, computed once per selection. */\n breadcrumb: TreeNode[] = [];\n readonly expanded = new Set<string>();\n\n private shape = '';\n private changes?: Subscription;\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly cdr = inject(ChangeDetectorRef);\n /** Stable per-instance ids for the shape signature, so replacing a control (setControl) reads as a structural change. */\n private readonly controlIds = new WeakMap<AbstractControl, number>();\n private controlIdSeq = 0;\n\n constructor() {\n // Rebind whenever the schema or form inputs change (a host loading another\n // config document): derived state resets against the new pair. Wrapped in\n // untracked so only the two inputs re-trigger the effect.\n effect(() => {\n const schema = this.schema();\n const group = this.formGroup();\n untracked(() => this.attach(schema, group));\n });\n }\n\n ngOnDestroy() {\n this.changes?.unsubscribe();\n }\n\n /** Bind the editor to a schema/form pair: fresh tree, root selection, and shape-sync subscription. */\n private attach(schema: NodeGroup, group: FormGroup): void {\n this.changes?.unsubscribe();\n this.expanded.clear();\n this.root = this.buildTree(schema, group, this.rootLabelOf(schema), '');\n this.shape = this.shapeOf(group);\n if (this.initiallyExpanded()) this.expandAll();\n else this.expanded.add(this.root.id);\n this.select(this.root);\n // Any change to the bound form — whether from the detail sections or from\n // an external holder of the same FormGroup — must reach the detail pane.\n // Leaf inputs self-heal (the reactive ValueAccessor writes the new value\n // synchronously), but the pane's own non-reactive displays (the case\n // selector, a map entry's key) are one-shot bindings; mark the view so\n // they re-read under OnPush and zoneless change detection. A shape change\n // additionally rebuilds the tree.\n this.changes = group.valueChanges.subscribe(() => {\n this.cdr.markForCheck();\n this.syncShape();\n });\n }\n\n /**\n * Force the editor to re-read the bound form. A leaf field normally reflects\n * an external `setValue` on its own — the reactive value accessor writes the\n * value synchronously, no change detection needed — so this is only for the\n * corners that bypass that: a structural change made with\n * `{ emitEvent: false }` (the tree wouldn't otherwise rebuild), a non-reactive\n * display (the case selector, a map key) that needs re-reading, or a host\n * whose change detector was detached during the mutation.\n *\n * It re-syncs the tree structure and **tears down and recreates** the detail\n * sections, so every rendered control rebinds to the live form and re-pulls\n * its current value — even a field whose bound input somehow missed the\n * external write.\n */\n refresh(): void {\n this.syncShape(); // structural changes (added/removed/renamed controls)\n const selected = this.selected;\n this.sections = []; // tear the embedded detail forms down…\n this.cdr.detectChanges();\n if (selected) this.select(selected, false); // …and rebuild them, fresh-bound\n this.cdr.detectChanges();\n }\n\n select(node: TreeNode, reveal = true) {\n this.selected = node;\n // Sections that would render only their breadcrumb heading (a composite\n // node with no leaf fields and no chrome) are dropped: their children get\n // sections of their own, whose trails carry the full path anyway.\n this.sections = this.markContinuations(\n this.buildSections(node, []).filter((s, i) => i === 0 || this.sectionHasContent(s)),\n );\n this.breadcrumb = this.pathTo(node);\n // Navigating retires any pending just-added-leaf focus request.\n this.focusSectionId = null;\n this.focusLeafKey = null;\n // Reveal the selection: expand every ancestor so the row is visible —\n // and the node itself only under `expandOnClick` (the detail pane shows\n // its subtree regardless). Structural re-syncs pass reveal=false — they\n // must not re-expand what the user collapsed.\n if (reveal) {\n for (const crumb of this.breadcrumb) {\n if (crumb !== node) this.expanded.add(crumb.id);\n else if (this.expandOnClick() && this.hasExpandableContent(crumb)) this.expanded.add(crumb.id);\n }\n }\n }\n\n /**\n * Root-to-`target` path for the detail-pane breadcrumb (inclusive of both ends),\n * or an empty array if `target` is not in the current tree.\n */\n pathTo(target: TreeNode): TreeNode[] {\n const walk = (node: TreeNode, trail: TreeNode[]): TreeNode[] | null => {\n const here = [...trail, node];\n if (node === target) return here;\n for (const child of node.children) {\n const found = walk(child, here);\n if (found) return found;\n }\n return null;\n };\n return this.root ? (walk(this.root, []) ?? []) : [];\n }\n\n protected toggle(node: TreeNode) {\n if (this.expanded.has(node.id)) this.expanded.delete(node.id);\n else this.expanded.add(node.id);\n }\n\n /** Keyboard access for tree rows: Enter/Space selects, ArrowRight expands, ArrowLeft collapses. */\n protected onRowKeydown(event: KeyboardEvent, node: TreeNode) {\n // Keys pressed on the row's inner buttons keep their own meaning.\n if (event.target !== event.currentTarget) return;\n switch (event.key) {\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.select(node);\n break;\n case 'ArrowRight':\n if (this.hasExpandableContent(node) && !this.expanded.has(node.id)) {\n event.preventDefault();\n this.expanded.add(node.id);\n }\n break;\n case 'ArrowLeft':\n if (this.expanded.has(node.id)) {\n event.preventDefault();\n this.expanded.delete(node.id);\n }\n break;\n }\n }\n\n /** Whether the row shows an expand twisty: it has child rows to reveal (children or an optionals menu row). */\n protected hasExpandableContent(node: TreeNode): boolean {\n return node.children.length > 0 || (this.editable() && !!node.optionals?.length);\n }\n\n /**\n * Whether the node's form subtree holds a validation error. Group/choice, list,\n * and map nodes each check their backing control; `invalid` aggregates over\n * descendants, so an error anywhere below lights every ancestor row.\n */\n protected hasError(node: TreeNode): boolean {\n return !!(node.group?.invalid || node.list?.array.invalid || node.map?.group.invalid);\n }\n\n /**\n * Append a new item to a list node's FormArray (up to `maxItems`). A tree-row\n * add selects the new item; a detail-pane add passes `keepSelection` so the\n * current (possibly ancestor) view stays put and the item appears as a new\n * section in it.\n */\n addItem(listNode: TreeNode, keepSelection = false) {\n const list = listNode.list;\n if (!list) return;\n if (list.maxItems != null && list.array.length >= list.maxItems) return;\n list.array.push(buildFormFromSchema(list.itemSchema));\n if (keepSelection) this.selectByPath(this.selected?.id ?? '', false);\n else this.selectByPath(this.join(listNode.id, String(list.array.length - 1)));\n }\n\n /**\n * Remove a list item from its FormArray (down to `minItems`). List-item\n * identity is positional, so expansion state under the list is cleared —\n * otherwise it would silently migrate to the items that shift into the\n * removed indexes.\n */\n removeItem(listNode: TreeNode, item: TreeNode, keepSelection = false) {\n if (!listNode.list || !item.removable) return;\n if (listNode.list.array.length <= listNode.list.minItems) return;\n for (const id of [...this.expanded]) {\n if (id.startsWith(`${listNode.id}/`)) this.expanded.delete(id);\n }\n listNode.list.array.removeAt(item.removable.index);\n // A detail-pane remove keeps the (ancestor) selection; a tree-row remove\n // moves to the list and returns focus to its row.\n if (keepSelection) {\n this.selectByPath(this.selected?.id ?? '', false);\n return;\n }\n this.selectByPath(listNode.id);\n this.focusSelectedRow();\n }\n\n /** The just-added optional leaf (section path + key) whose field grabs focus when rendered. */\n protected focusSectionId: string | null = null;\n protected focusLeafKey: string | null = null;\n\n /** Add an absent optional child from the menu: build its control and select the node it lands on. */\n addOptional(node: TreeNode, entry: OptionalEntry) {\n if (!node.group || !setNodePresence(node.group, entry.schema, entry.key, true)) return;\n // A leaf renders in the parent's detail pane; complex kinds become tree nodes.\n this.selectByPath(entry.schema.kind === 'leaf' ? node.id : this.join(node.id, entry.key));\n // Adding the last optional removes the menu row that held focus.\n if (entry.schema.kind !== 'leaf') this.focusSelectedRow();\n if (entry.schema.kind === 'leaf') {\n // Set after selection (select() retires any pending request): the new\n // field should grab focus, like the form's own add button. Retired after\n // a tick so later re-renders of the section cannot steal focus again.\n this.focusSectionId = node.id;\n this.focusLeafKey = entry.key;\n setTimeout(() => {\n if (this.focusLeafKey === entry.key) {\n this.focusSectionId = null;\n this.focusLeafKey = null;\n }\n });\n }\n }\n\n /** Remove a present optional child node, returning its entry to the parent's menu. */\n removeOptional(parent: TreeNode, node: TreeNode) {\n const removable = node.presenceRemovable;\n if (!removable || !parent.group) return;\n setNodePresence(parent.group, removable.schema, removable.key, false);\n this.selectByPath(parent.id);\n this.focusSelectedRow();\n }\n\n /** The active case name of a choice node, or null when none is selected. */\n activeCase(node: TreeNode): string | null {\n return (node.choice?.group.get(CASE_KEY)?.value as string | null) ?? null;\n }\n\n /** The display label of a choice node's active case, or null when no case is selected. */\n activeCaseLabel(node: TreeNode): string | null {\n const c = node.choice;\n const active = this.activeCase(node);\n return c && active ? this.caseLabel(c.schema, active) : null;\n }\n\n /**\n * The display label for a case: the schema's `caseLabels` entry (colliding\n * labels disambiguated by their distinguishing fields — see\n * {@link caseDisplayLabels}), else the case name.\n */\n protected caseLabel(choice: NodeChoice, caseName: string): string {\n return caseDisplayLabels(choice)[caseName] ?? caseName;\n }\n\n /**\n * Switch a choice node's active case from its detail selector; the\n * structural sync rebuilds the tree and sections. The tree selection stays\n * where it is: detail edits must never steal it, or a flattened ancestor\n * view would collapse to the choice node mid-edit. Selection moves only\n * through the tree itself.\n */\n switchTreeCase(node: TreeNode, caseName: string) {\n const c = node.choice;\n if (!c) return;\n switchChoiceCase(c.group, c.schema, caseName);\n this.selectByPath(this.selected?.id ?? node.id, false);\n }\n\n protected objectKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj);\n }\n\n /**\n * Append a new entry to a complex map node under a generated unique key. A\n * tree-row add selects the new entry; a detail-pane add passes\n * `keepSelection` so the current view stays put (see {@link addItem}).\n */\n addTreeMapEntry(mapNode: TreeNode, keepSelection = false) {\n const m = mapNode.map;\n if (!m) return;\n const key = addMapEntry(m.group, m.schema);\n if (key == null) return;\n if (keepSelection) this.selectByPath(this.selected?.id ?? '', false);\n else this.selectByPath(this.join(mapNode.id, key));\n }\n\n /** Remove a complex map entry (down to `minEntries`). */\n removeTreeMapEntry(mapNode: TreeNode, entryNode: TreeNode, keepSelection = false) {\n const m = mapNode.map;\n const e = entryNode.mapEntry;\n if (!m || !e || !removeMapEntry(m.group, m.schema, e.key)) return;\n if (keepSelection) {\n this.selectByPath(this.selected?.id ?? '', false);\n return;\n }\n this.selectByPath(mapNode.id);\n this.focusSelectedRow();\n }\n\n /**\n * Commit a rename-on-blur of a map entry's key; on success the selection is\n * remapped to the entry's new identity when it pointed at (or inside) the\n * entry — otherwise it stays put — and the fresh key field regains focus\n * (the rename re-renders the section under a new id, destroying the input\n * that held focus).\n */\n renameTreeMapEntry(entryNode: TreeNode, rawKey: string) {\n const e = entryNode.mapEntry;\n if (!e) return;\n // Captured before the mutation: the rename's structural sync reconciles\n // the selection against the stale id (falling back to an ancestor) before\n // this method can remap it.\n const selectedId = this.selected?.id ?? '';\n if (renameMapEntry(e.mapGroup, e.mapSchema, e.key, rawKey)) {\n const parentPath = entryNode.id.slice(0, entryNode.id.lastIndexOf('/'));\n const newId = this.join(parentPath, rawKey.trim());\n // The entry's descendants keep their expansion under the new identity.\n for (const id of [...this.expanded]) {\n if (id === entryNode.id || id.startsWith(`${entryNode.id}/`)) {\n this.expanded.delete(id);\n this.expanded.add(newId + id.slice(entryNode.id.length));\n }\n }\n // Selection is remapped, not moved: it follows the rename only when it\n // sat on the entry (or inside it); an ancestor view stays put.\n const followed =\n selectedId === entryNode.id || selectedId.startsWith(`${entryNode.id}/`)\n ? newId + selectedId.slice(entryNode.id.length)\n : selectedId;\n this.selectByPath(followed, false);\n // Deferred so the rebuilt section's key field exists before focusing.\n setTimeout(() => this.host.nativeElement.querySelector<HTMLElement>('.detail .key-field input')?.focus());\n }\n }\n\n /** Move keyboard focus to the selected tree row once the action's re-render settles. */\n private focusSelectedRow(): void {\n setTimeout(() => this.host.nativeElement.querySelector<HTMLElement>('.tree-row.selected')?.focus());\n }\n\n /** A muted hint for a section whose node currently renders no content of its own. */\n /**\n * Explains a group's `minPresent`/`maxPresent` violation next to the red\n * tree marker: the fix is enabling or removing optional fields, which is not\n * evident from any single field's own error.\n */\n protected presentRangeHint(s: DetailSection): string | null {\n const errors = s.node.group?.errors;\n const min = errors?.['minPresent'];\n if (min) {\n const noun = min.required === 1 ? 'field' : 'fields';\n return `At least ${min.required} ${noun} must be set (${min.actual} set) — add from the optional-fields menu.`;\n }\n const max = errors?.['maxPresent'];\n if (max) return `At most ${max.allowed} of these fields may be set (${max.actual} set).`;\n return null;\n }\n\n protected emptySectionHint(s: DetailSection): string | null {\n const n = s.node;\n if (n.list && !n.children.length) return `No ${n.list.itemLabel} items.`;\n if (n.map?.complex && !n.children.length) return 'No entries.';\n if (n.map && !n.map.complex && !Object.keys(n.map.group.controls).length && !this.editable()) {\n return 'No entries.';\n }\n return null;\n }\n\n /** Whether a list node is at `maxItems` (the add control is hidden). */\n protected listAtMax(node: TreeNode | undefined): boolean {\n const l = node?.list;\n return !!l && l.maxItems != null && l.array.length >= l.maxItems;\n }\n\n /** Whether a list node is at `minItems` (item remove controls are hidden). */\n protected listAtMin(node: TreeNode | undefined): boolean {\n const l = node?.list;\n return !!l && l.array.length <= l.minItems;\n }\n\n /** Whether a map node is at `maxEntries` (the add control is hidden). */\n protected mapAtMax(node: TreeNode | undefined): boolean {\n const m = node?.map;\n return !!m && m.schema.maxEntries != null && Object.keys(m.group.controls).length >= m.schema.maxEntries;\n }\n\n /** Whether a map node is at `minEntries` (entry remove controls are hidden). */\n protected mapAtMin(node: TreeNode | undefined): boolean {\n const m = node?.map;\n return !!m && m.schema.minEntries != null && Object.keys(m.group.controls).length <= m.schema.minEntries;\n }\n\n // --- derived-tree maintenance ----------------------------------------------\n\n /** Rebuild the tree from the current form structure if its shape changed. */\n private syncShape(): void {\n const shape = this.shapeOf(this.formGroup());\n if (shape === this.shape) return;\n this.rebuild();\n this.reconcileSelection();\n }\n\n /**\n * A cheap structural signature of a control tree: group keys (plus the active\n * `__case`), array lengths, leaf placeholders. Value edits don't change it;\n * added/removed/renamed controls and case switches do. Reading `__case` from\n * any group is safe because the name is reserved (the builder rejects it as a\n * case field name or map entry key), so only choice groups carry it.\n */\n private shapeOf(control: AbstractControl): string {\n if (control instanceof FormGroup) {\n const inner = Object.keys(control.controls)\n .sort()\n .map((k) => `${k}:${this.shapeOf(control.controls[k])}`)\n .join(',');\n const active = control.get(CASE_KEY)?.value;\n return `{#${this.uidOf(control)}${typeof active === 'string' ? `=${active};` : ''}${inner}}`;\n }\n if (control instanceof FormArray) {\n return `[#${this.uidOf(control)}${control.controls.map((c) => this.shapeOf(c)).join(',')}]`;\n }\n return '.';\n }\n\n /** The instance id a container contributes to the shape signature. */\n private uidOf(control: AbstractControl): number {\n let id = this.controlIds.get(control);\n if (id == null) {\n id = ++this.controlIdSeq;\n this.controlIds.set(control, id);\n }\n return id;\n }\n\n /** Root row title: host override, else schema label, else its name — with the {@link ROOT_SENTINEL} swapped for a generic title. */\n private rootLabelOf(schema: NodeGroup): string {\n return this.rootTitle() ?? schema.label ?? (schema.name === ROOT_SENTINEL ? ROOT_FALLBACK_TITLE : schema.name);\n }\n\n /** Rebuild the whole tree from schema + form and refresh the shape signature. */\n private rebuild(): void {\n const schema = this.schema();\n this.root = this.buildTree(schema, this.formGroup(), this.rootLabelOf(schema), '');\n this.shape = this.shapeOf(this.formGroup());\n }\n\n /** Re-point `selected` at the rebuilt tree: same path, else the closest surviving ancestor. */\n private reconcileSelection(): void {\n this.selectByPath(this.selected?.id ?? '', false);\n }\n\n /** The node at `path` in the current tree, or null. Walks by id-prefix segments. */\n private byPath(path: string): TreeNode | null {\n if (path === this.root.id) return this.root;\n const walk = (node: TreeNode): TreeNode | null => {\n for (const child of node.children) {\n if (child.id === path) return child;\n if (path.startsWith(child.id + '/')) return walk(child);\n }\n return null;\n };\n return walk(this.root);\n }\n\n /** Select the node at `path`, falling back through its ancestors to the root. */\n private selectByPath(path: string, reveal = true): void {\n let target = this.byPath(path);\n let trimmed = path;\n while (!target && trimmed.includes('/')) {\n trimmed = trimmed.slice(0, trimmed.lastIndexOf('/'));\n target = this.byPath(trimmed);\n }\n this.select(target ?? this.root, reveal);\n }\n\n /**\n * Flatten a subtree into detail sections, pre-order: the node's own fields\n * first, then each child as its own breadcrumb-headed section. No nesting\n * chrome — the headings are the boundaries between children.\n */\n private buildSections(node: TreeNode, trail: TreeNode[]): DetailSection[] {\n const here = [...trail, node];\n const list: DetailSection[] = [{ node, trail: here, ...this.sectionContent(node) }];\n for (const child of node.children) list.push(...this.buildSections(child, here));\n // A list's / complex map's add control trails its items — appending\n // belongs after the last member, not under the container's heading.\n if (node.list || node.map?.complex) {\n list.push({ node, trail: here, schema: null, group: null, footer: true });\n }\n return list;\n }\n\n /**\n * Whether a section renders anything beyond its heading: a leaf slice, the\n * chrome of its node kind (case selector, key field, add controls), or a\n * present-children error that needs explaining. Heading-only sections are\n * dropped from the flat list — a divider with nothing under it is clutter.\n */\n private sectionHasContent(s: DetailSection): boolean {\n if (s.footer) return true;\n const n = s.node;\n // A non-empty list / complex map's leading section would hold only its\n // heading (the add control lives in the footer): drop it — the items'\n // trails carry the container in their breadcrumbs.\n return !!(\n s.schema ||\n n.choice ||\n n.mapEntry ||\n (n.map && !n.map.complex) ||\n this.emptySectionHint(s) ||\n this.presentRangeHint(s)\n );\n }\n\n /** Every expandable node currently expanded — drives the root row's expand/collapse-all toggle. */\n protected allExpanded(): boolean {\n let all = true;\n const walk = (node: TreeNode): void => {\n if (!all) return;\n if (this.hasExpandableContent(node) && !this.expanded.has(node.id)) all = false;\n for (const child of node.children) walk(child);\n };\n walk(this.root);\n return all;\n }\n\n /**\n * Expand every expandable node, or collapse back when all are open. The\n * collapse keeps the root open — a tree reduced to one row reads as empty.\n */\n protected toggleExpandAll(): void {\n if (this.allExpanded()) {\n this.expanded.clear();\n this.expanded.add(this.root.id);\n return;\n }\n this.expandAll();\n }\n\n /**\n * Mark every expandable node in the current tree as expanded (the root\n * included). Shared by the expand-all toggle and the `initiallyExpanded`\n * bind-time seed.\n */\n private expandAll(): void {\n this.expanded.add(this.root.id);\n const walk = (node: TreeNode): void => {\n if (this.hasExpandableContent(node)) this.expanded.add(node.id);\n for (const child of node.children) walk(child);\n };\n walk(this.root);\n }\n\n /** The selected member's container (list / map), for the breadcrumb's remove control. */\n protected selectedMemberParent(): TreeNode | null {\n if (!this.selected || !(this.selected.removable || this.selected.mapEntry)) return null;\n return this.breadcrumb.length > 1 ? (this.breadcrumb[this.breadcrumb.length - 2] ?? null) : null;\n }\n\n /** The section node's container (list / map), for member controls in its heading. */\n protected memberParent(s: DetailSection): TreeNode | null {\n return s.trail.length > 1 ? (s.trail[s.trail.length - 2] ?? null) : null;\n }\n\n /**\n * Flag the sections that continue a run of siblings — a list item or map\n * entry whose preceding section is inside the same container. Their headings\n * draw no divider line, so a run of same-kind members reads as one list\n * rather than a stack of separated blocks.\n */\n private markContinuations(sections: DetailSection[]): DetailSection[] {\n for (let i = 1; i < sections.length; i++) {\n const s = sections[i];\n if (s.footer || !(s.node.removable || s.node.mapEntry)) continue;\n const containerId = s.node.id.slice(0, s.node.id.lastIndexOf('/'));\n const prev = sections[i - 1].node.id;\n if (prev === containerId || prev.startsWith(`${containerId}/`)) s.continuation = true;\n }\n return sections;\n }\n\n /** A section's own renderable fields: a leaf-only schema slice and the group it binds to. */\n private sectionContent(node: TreeNode): { schema: NodeGroup | null; group: FormGroup | null } {\n if (node.choice) {\n const active = this.activeCase(node);\n const body = active && node.choice.schema.cases[active] ? this.caseAsGroup(node.choice.schema, active) : null;\n return { schema: body ? this.leafOnly(body, node.choice.group) : null, group: node.choice.group };\n }\n if (node.schema && node.group) {\n return { schema: this.leafOnly(node.schema, node.group), group: node.group };\n }\n return { schema: null, group: null };\n }\n\n /**\n * The node's own fields as a flattened schema: leaf and leafList children\n * only. Complex children are rendered as sections of their own, so the\n * embedded form never draws nested section chrome. The node's `appearance`\n * (grid / field-width layout) carries into the slice. Null when there are\n * no own fields.\n */\n private leafOnly(schema: NodeGroup, group: FormGroup | null): NodeGroup | null {\n const children: Record<string, NodeType> = {};\n for (const key of Object.keys(schema.children)) {\n const child = schema.children[key];\n if (child.kind !== 'leaf' && child.kind !== 'leafList') continue;\n // An absent presence leafList has no inline affordance and no control to\n // render — it is offered by the \"+ Optional field\" menu instead.\n if (child.kind === 'leafList' && child.presence && !group?.get(key)) continue;\n children[key] = child;\n }\n if (!Object.keys(children).length) return null;\n return { ...schema, root: false, children, appearance: { ...schema.appearance, flatten: true } };\n }\n\n // --- tree construction -----------------------------------------------------\n\n private buildTree(\n schema: NodeGroup,\n group: FormGroup,\n label: string,\n path: string,\n inherited: Appearance | null = null,\n ): TreeNode {\n const children: TreeNode[] = [];\n const optionals: OptionalEntry[] = [];\n const childInherited = descendantLayout(inherited, schema.appearance);\n\n for (const key of Object.keys(schema.children)) {\n const child = schema.children[key];\n if (child.kind === 'leaf' || child.kind === 'leafList') {\n // Leaves render in the detail pane; an absent presence leaf is also\n // offered by the \"+ Optional field\" menu (addable inline or from the\n // tree row). An absent presence *leafList* has no inline affordance, so\n // it is offered only by the menu (and excluded from the leafOnly slice).\n if (child.presence && !group.get(key)) {\n optionals.push({ key, schema: child, label: this.labelOf(child, key) });\n }\n continue;\n }\n const presence = !!child.presence;\n if (presence && !group.get(key)) {\n optionals.push({ key, schema: child, label: this.labelOf(child, key) });\n continue;\n }\n const node = this.buildChildNode(child, group.get(key), this.labelOf(child, key), this.join(path, key), childInherited);\n if (!node) continue;\n if (presence) node.presenceRemovable = { key, schema: child };\n children.push(node);\n }\n\n const node: TreeNode = { id: path, label, children, group, schema, inherited };\n if (optionals.length) node.optionals = optionals;\n return node;\n }\n\n /** Build the tree node for a single non-leaf child, dispatching on its kind. Null when its control is missing. */\n private buildChildNode(\n schema: NodeType,\n control: AbstractControl | null,\n label: string,\n path: string,\n inherited: Appearance | null = null,\n ): TreeNode | null {\n if (schema.kind === 'nodeGroup') {\n return control instanceof FormGroup ? this.buildTree(schema, control, label, path, inherited) : null;\n }\n if (schema.kind === 'nodeGroupList') {\n const array = control;\n const itemLabel = schema.type.label ?? schema.type.name;\n const items =\n array instanceof FormArray\n ? array.controls\n .filter((c): c is FormGroup => c instanceof FormGroup)\n .map((item, i) => {\n // Just \"#n\": the item sits under its list node, so repeating the\n // item name (e.g. \"Interface #1\") only echoes the parent.\n const node = this.buildTree(schema.type, item, `#${i + 1}`, this.join(path, String(i)), inherited);\n node.removable = { index: i };\n return node;\n })\n : [];\n return {\n id: path,\n label,\n children: items,\n group: null,\n list:\n array instanceof FormArray\n ? { array, itemSchema: schema.type, itemLabel, minItems: schema.minItems ?? 0, maxItems: schema.maxItems }\n : undefined,\n };\n }\n if (schema.kind === 'choice') {\n if (!(control instanceof FormGroup)) return null;\n const active = control.get(CASE_KEY)?.value as string | null;\n const node =\n active && schema.cases[active]\n ? this.buildTree(this.caseAsGroup(schema, active), control, label, path, inherited)\n : ({ id: path, label, children: [], group: control, inherited } as TreeNode);\n node.schema = undefined;\n node.choice = { schema, group: control };\n return node;\n }\n if (schema.kind === 'map') {\n if (!(control instanceof FormGroup)) return null;\n const complex =\n schema.value.kind === 'nodeGroup' ||\n schema.value.kind === 'choice' ||\n schema.value.kind === 'map' ||\n schema.value.kind === 'nodeGroupList';\n const entries = complex\n ? Object.keys(control.controls)\n .map((key) => {\n // Index access, not .get(): entry keys are arbitrary runtime data\n // and .get() would split a key like '10.0.0.1' into a dotted path.\n // Entries inherit through the map node's own appearance.\n const entryNode = this.buildChildNode(\n schema.value,\n control.controls[key],\n key,\n this.join(path, key),\n descendantLayout(inherited, schema.appearance),\n );\n if (entryNode) {\n entryNode.mapEntry = { mapGroup: control, mapSchema: schema, key };\n }\n return entryNode;\n })\n .filter((n): n is TreeNode => n !== null)\n : [];\n return {\n id: path,\n label,\n children: entries,\n group: null,\n map: { schema, group: control, complex },\n };\n }\n return null;\n }\n\n /**\n * Synthetic group over a case's normalized fields, so a case body builds\n * like any group. Carries the choice's own `appearance` so its layout\n * reaches the case fields.\n */\n private caseAsGroup(choice: NodeChoice, caseName: string): NodeGroup {\n return {\n kind: 'nodeGroup',\n name: choice.name,\n children: choice.cases[caseName] ? caseFields(choice.cases[caseName]) : {},\n ...(choice.appearance ? { appearance: choice.appearance } : {}),\n };\n }\n\n /** A node's display label: its schema `label`, else its record key. */\n private labelOf(node: NodeType, key: string): string {\n return ('label' in node ? node.label : undefined) ?? key;\n }\n\n /** Join a parent path and a segment; the root's path is the empty string. */\n private join(parent: string, segment: string): string {\n const seg = this.escapeSeg(segment);\n return parent ? `${parent}/${seg}` : seg;\n }\n\n /**\n * Escape a path segment: `/` is the id separator, and map entry keys are\n * arbitrary runtime data that may contain it. Labels stay unescaped — only\n * node identities encode.\n */\n private escapeSeg(segment: string): string {\n return segment.replace(/%/g, '%25').replace(/\\//g, '%2F');\n }\n}\n","<div class=\"editor\">\n <nav class=\"tree\" role=\"tree\" aria-label=\"Configuration structure\">\n <ng-template #treeNode let-node let-depth=\"depth\" let-parent=\"parent\">\n <div\n class=\"tree-row\"\n role=\"treeitem\"\n tabindex=\"0\"\n [class.selected]=\"node === selected\"\n [class.error]=\"hasError(node)\"\n [attr.aria-selected]=\"node === selected\"\n [attr.aria-expanded]=\"hasExpandableContent(node) ? expanded.has(node.id) : null\"\n [attr.aria-level]=\"depth + 1\"\n [style.padding-left.px]=\"8 + depth * 16\"\n (click)=\"select(node)\"\n (keydown)=\"onRowKeydown($event, node)\"\n >\n @if (hasExpandableContent(node)) {\n <button\n matIconButton\n class=\"twisty\"\n tabindex=\"-1\"\n (click)=\"toggle(node); $event.stopPropagation()\"\n [attr.aria-label]=\"expanded.has(node.id) ? 'Collapse' : 'Expand'\"\n >\n <mat-icon>{{ expanded.has(node.id) ? 'expand_more' : 'chevron_right' }}</mat-icon>\n </button>\n } @else {\n <span class=\"twisty-spacer\"></span>\n }\n\n <span class=\"tree-label\" [matTooltip]=\"node.label\">{{ node.label }}</span>\n @if (node.choice && activeCaseLabel(node)) {\n <span class=\"tree-sublabel\" [matTooltip]=\"activeCaseLabel(node)\">{{ activeCaseLabel(node) }}</span>\n }\n @if (node === root) {\n <button\n matIconButton\n class=\"row-btn root-toggle\"\n [matTooltip]=\"editable() ? 'Stop editing' : 'Edit'\"\n [attr.aria-label]=\"editable() ? 'Stop editing' : 'Edit'\"\n [attr.aria-pressed]=\"editable()\"\n (click)=\"editable.set(!editable()); $event.stopPropagation()\"\n >\n <mat-icon>{{ editable() ? 'edit_off' : 'edit' }}</mat-icon>\n </button>\n <button\n matIconButton\n class=\"row-btn root-toggle\"\n [matTooltip]=\"allExpanded() ? 'Collapse all' : 'Expand all'\"\n [attr.aria-label]=\"allExpanded() ? 'Collapse all' : 'Expand all'\"\n (click)=\"toggleExpandAll(); $event.stopPropagation()\"\n >\n <mat-icon>{{ allExpanded() ? 'unfold_less' : 'unfold_more' }}</mat-icon>\n </button>\n }\n @if (hasError(node)) {\n <!-- A non-color error signal beside the red row text. -->\n <mat-icon class=\"row-error-icon\" aria-hidden=\"false\" role=\"img\" aria-label=\"Has validation errors\"\n >error_outline</mat-icon\n >\n }\n\n @if (editable() && node.list && !listAtMax(node)) {\n <button\n matIconButton\n class=\"row-btn add\"\n [matTooltip]=\"'Add ' + node.list.itemLabel + ' #' + (node.list.array.length + 1)\"\n [attr.aria-label]=\"'Add ' + node.list.itemLabel + ' #' + (node.list.array.length + 1)\"\n (click)=\"addItem(node); $event.stopPropagation()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && node.map?.complex && !mapAtMax(node)) {\n <button\n matIconButton\n class=\"row-btn add\"\n [matTooltip]=\"'Add ' + node.label + ' entry'\"\n [attr.aria-label]=\"'Add ' + node.label + ' entry'\"\n (click)=\"addTreeMapEntry(node); $event.stopPropagation()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n }\n @if (editable() && node.removable && !listAtMin(parent)) {\n <button\n matIconButton\n class=\"row-btn remove\"\n [matTooltip]=\"'Remove ' + node.label\"\n [attr.aria-label]=\"'Remove ' + node.label\"\n (click)=\"removeItem(parent, node); $event.stopPropagation()\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n @if (editable() && node.presenceRemovable) {\n <button\n matIconButton\n class=\"row-btn remove\"\n [matTooltip]=\"'Remove ' + node.label\"\n [attr.aria-label]=\"'Remove ' + node.label\"\n (click)=\"removeOptional(parent, node); $event.stopPropagation()\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n @if (editable() && node.mapEntry && !mapAtMin(parent)) {\n <button\n matIconButton\n class=\"row-btn remove\"\n [matTooltip]=\"'Remove ' + node.label + ' entry'\"\n [attr.aria-label]=\"'Remove ' + node.label + ' entry'\"\n (click)=\"removeTreeMapEntry(parent, node); $event.stopPropagation()\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n </div>\n\n @if (expanded.has(node.id)) {\n @for (child of node.children; track child.id) {\n <ng-container\n *ngTemplateOutlet=\"treeNode; context: { $implicit: child, depth: depth + 1, parent: node }\"\n />\n }\n @if (editable() && node.optionals?.length) {\n <button\n type=\"button\"\n class=\"tree-row optional-row\"\n [style.padding-left.px]=\"8 + (depth + 1) * 16\"\n [matMenuTriggerFor]=\"treeOptionalsMenu\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"twisty-spacer\"></span>\n <mat-icon class=\"optional-icon\">add</mat-icon>\n <span class=\"optional-label\">Optional field</span>\n </button>\n <mat-menu #treeOptionalsMenu=\"matMenu\">\n @for (opt of node.optionals; track opt.key) {\n <button mat-menu-item (click)=\"addOptional(node, opt)\">{{ opt.label }}</button>\n }\n </mat-menu>\n }\n }\n </ng-template>\n\n <ng-container *ngTemplateOutlet=\"treeNode; context: { $implicit: root, depth: 0 }\" />\n </nav>\n\n <section class=\"detail\">\n @if (selected) {\n @if (showBreadcrumb()) {\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n @for (crumb of breadcrumb; track crumb.id; let last = $last) {\n @if (last) {\n <span class=\"crumb-current\" aria-current=\"page\">{{ crumb.label }}</span>\n } @else {\n <button type=\"button\" class=\"item-link crumb-link\" (click)=\"select(crumb)\">{{ crumb.label }}</button>\n <span class=\"crumb-sep\" aria-hidden=\"true\">/</span>\n }\n }\n <!-- A selected member (list item / map entry) is removable from its own\n view; the selection then moves to its container, like a tree-row\n remove — a deleted node cannot stay selected. -->\n @if (editable() && selected.removable && selectedMemberParent(); as parent) {\n @if (!listAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + selected.label\"\n [attr.aria-label]=\"'Remove ' + selected.label\"\n (click)=\"removeItem(parent, selected)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n @if (editable() && selected.mapEntry && selectedMemberParent(); as parent) {\n @if (!mapAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + selected.label + ' entry'\"\n [attr.aria-label]=\"'Remove ' + selected.label + ' entry'\"\n (click)=\"removeTreeMapEntry(parent, selected)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n </nav>\n }\n\n <!-- The selected subtree as a flat section list: each descendant's fields\n under a breadcrumb heading — the headings, not nesting, mark the\n boundary between one child and the next. -->\n @for (s of sections; track s.node.id + (s.footer ? ':footer' : '')) {\n @if (s.trail.length > 1 && !s.footer) {\n <!-- A heading, not a nav landmark: dozens of identical \"Section\"\n landmarks would flood the assistive-tech landmark list. Its\n accessible name is the trail itself. -->\n <div class=\"section-heading\" [class.continuation]=\"s.continuation\" role=\"heading\" aria-level=\"3\">\n @for (crumb of s.trail; track crumb.id; let last = $last) {\n @if (last) {\n <span class=\"crumb-current\">{{ crumb.label }}</span>\n } @else {\n <button type=\"button\" class=\"item-link crumb-link\" (click)=\"select(crumb)\">{{ crumb.label }}</button>\n <span class=\"crumb-sep\" aria-hidden=\"true\">/</span>\n }\n }\n @if (editable() && s.node.removable && memberParent(s); as parent) {\n @if (!listAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + s.node.label\"\n [attr.aria-label]=\"'Remove ' + s.node.label\"\n (click)=\"removeItem(parent, s.node, true)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n @if (editable() && s.node.mapEntry && memberParent(s); as parent) {\n @if (!mapAtMin(parent)) {\n <button\n matIconButton\n class=\"remove-button small-icon-button section-remove\"\n [matTooltip]=\"'Remove ' + s.node.label + ' entry'\"\n [attr.aria-label]=\"'Remove ' + s.node.label + ' entry'\"\n (click)=\"removeTreeMapEntry(parent, s.node, true)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n }\n </div>\n }\n\n @if (s.node.mapEntry; as entry) {\n <mat-form-field class=\"key-field\" [appearance]=\"editable() ? 'fill' : 'outline'\">\n <mat-label>{{ entry.mapSchema.keyLabel ?? 'Key' }}</mat-label>\n <input\n matInput\n #entryKey\n [readonly]=\"!editable()\"\n [value]=\"entry.key\"\n (change)=\"renameTreeMapEntry(s.node, entryKey.value); entryKey.value = entry.key\"\n />\n </mat-form-field>\n }\n\n @if (s.node.choice; as choice) {\n @if (editable()) {\n <mat-form-field class=\"case-select\" appearance=\"fill\">\n <mat-label>Selected option</mat-label>\n <mat-select [value]=\"activeCase(s.node)\" (selectionChange)=\"switchTreeCase(s.node, $event.value)\">\n @for (caseName of objectKeys(choice.schema.cases); track caseName) {\n <mat-option [value]=\"caseName\">{{ caseLabel(choice.schema, caseName) }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n <mat-form-field class=\"case-select\" appearance=\"outline\">\n <mat-label>Selected option</mat-label>\n <input matInput readonly [value]=\"activeCaseLabel(s.node) ?? ''\" />\n </mat-form-field>\n }\n }\n\n @if (s.schema && s.group) {\n <nff-dynamic-recursive-form\n [inheritedAppearance]=\"s.node.inherited ?? null\"\n [schema]=\"s.schema\"\n [formGroup]=\"s.group\"\n [editable]=\"editable()\"\n [focusLeaf]=\"s.node.id === focusSectionId ? focusLeafKey : null\"\n />\n }\n\n @if (s.node.map && !s.node.map.complex) {\n <nff-node-map-renderer\n [nodeMap]=\"s.node.map.schema\"\n [formGroup]=\"s.node.map.group\"\n [editable]=\"editable()\"\n />\n }\n\n @if (s.footer && editable() && s.node.map?.complex && !mapAtMax(s.node)) {\n <div class=\"section-actions\">\n <button matButton [matTooltip]=\"'Add ' + s.node.label + ' entry'\" (click)=\"addTreeMapEntry(s.node, true)\"><mat-icon>add</mat-icon> Add entry</button>\n </div>\n }\n @if (s.footer && editable() && s.node.list; as list) {\n @if (!listAtMax(s.node)) {\n <div class=\"section-actions\">\n <!-- The next entry's number in the label, so the button reads as\n what it does: \"Add Cell #3\" appends the third entry. -->\n <button matButton (click)=\"addItem(s.node, true)\">\n <mat-icon>add</mat-icon> Add {{ list.itemLabel }} #{{ list.array.length + 1 }}\n </button>\n </div>\n }\n }\n @if (!s.footer && emptySectionHint(s); as hint) {\n <p class=\"empty\">{{ hint }}</p>\n }\n @if (!s.footer && presentRangeHint(s); as hint) {\n <p class=\"section-error\" role=\"alert\">{{ hint }}</p>\n }\n }\n\n @if (\n sections.length === 1 &&\n !sections[0].schema &&\n !sections[0].node.choice &&\n !sections[0].node.map &&\n !sections[0].node.list &&\n !sections[0].node.mapEntry\n ) {\n <p class=\"empty\">This node has no fields.</p>\n }\n } @else {\n <p class=\"empty\">Select a node on the left to edit its fields.</p>\n }\n </section>\n</div>\n","/*\n * Public API Surface of ng-form-foundry\n */\n\nexport * from './lib/types/dynamic-recursive.types';\nexport * from './lib/core/dynamic-recursive-forms-builder';\nexport * from './lib/dynamic-recursive-form/dynamic-recursive-form.component';\nexport * from './lib/config-editor/config-editor.component';\nexport * from './lib/dynamic-recursive-form/leaf-renderer/leaf-renderer.component';\nexport * from './lib/dynamic-recursive-form/leaf-list-renderer/leaf-list-renderer.component';\nexport * from './lib/dynamic-recursive-form/leaf-enum-renderer/leaf-enum-renderer.component';\nexport * from './lib/dynamic-recursive-form/radix-input/radix-input.directive';\nexport * from './lib/directives/overflow-tooltip.directive';\nexport * from './lib/dynamic-recursive-form/node-group-list-renderer/node-group-list-renderer.component';\nexport * from './lib/dynamic-recursive-form/node-map-renderer/node-map-renderer.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i3","i5","i1","i4","i6","i7"],"mappings":"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"}