ng-form-foundry 0.3.1 → 0.3.3

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/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/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};\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};\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\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};\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};\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 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 */\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' || node.kind === 'nodeGroup' || node.kind === 'map' || node.kind === 'choice') &&\n node.presence === true\n );\n}\n\n/**\n * Whether a presence child should start absent: there is no initial data\n * object, or its key is missing from it. A key that is present with an explicit\n * `null` value keeps its control — `null` is a value (a nullable leaf's), while\n * presence is about the *absent key*.\n */\nfunction presenceAbsent(initial: Record<string, unknown> | null | undefined, key: string): boolean {\n return initial == null || !(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 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\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) ??\n list.default ?? [null];\n return new FormArray(values.map((v) => new FormControl(v)));\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 return new FormGroup(controls as FormGroupType<G>) 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. Fall back to a\n // single empty group only when no initial data is supplied.\n const values = Array.isArray(initial) ? initial : [null];\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 * The active case of a choice: an explicit `__case` in the initial value, else\n * the case whose fields best match the initial data (inline wire data carries no\n * `__case`), else the schema `default`. This lets a choice seed from real\n * instance data whose branch is discriminated by which fields are present.\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/** Pick the case whose fields most overlap the initial data (none if nothing matches). */\nfunction inferChoiceCase(choice: NodeChoice, initial?: Record<string, unknown> | null): string | undefined {\n if (!initial) return undefined;\n let best: string | undefined;\n let bestScore = 0;\n for (const name of Object.keys(choice.cases)) {\n const fields = Object.keys(caseFields(choice.cases[name]));\n let score = 0;\n for (const field of fields) if (field in initial) score++;\n if (score > bestScore) {\n bestScore = score;\n best = name;\n }\n }\n return best;\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.\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 return new FormGroup(controls);\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 * 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 * 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}\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\">\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>\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 { 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';\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 ],\n templateUrl: './leaf-renderer.component.html',\n styleUrl: './leaf-renderer.component.scss',\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 /** 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['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 <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [formControl]=\"control\">\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 <input [readonly]=\"!fieldEditable\" matInput type=\"number\" [formControl]=\"control\">\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\"></nff-leaf-enum-renderer>\n }\n @if (removable && editable) {\n <button matIconButton class=\"remove-button small-icon-button\" matTooltip=\"Remove\" [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 {\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 { 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 @Input() minItems: number = 1;\n @Input() maxItems: number = 1;\n @Output() message = new EventEmitter();\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 if (this.nodeGroupList.maxItems) {\n this.maxItems = this.nodeGroupList.maxItems;\n }\n if (this.nodeGroupList.minItems) {\n this.minItems = this.nodeGroupList.minItems;\n }\n }\n\n ngAfterViewInit() {\n this.items.changes.subscribe(() => {\n this.setLastEditable();\n });\n }\n\n removeItem($index: number) {\n if (this.formArray.length <= this.minItems) {\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 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 [schema]=\"nodeGroupList.type\"\n [formGroup]=\"asFormGroup(group)\"\n [title]=\"getTitle($index)\"\n [index]=\"0\"\n [removable]=\"formArray.length > minItems\"\n (remove)=\"removeItem($index)\"\n [editable]=\"editable\"\n [addButtonCallback]=\"addItem\"\n />\n </div>\n }\n </div>\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { AnonLeaf } 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';\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 ],\n templateUrl: './anon-leaf-renderer.component.html',\n styleUrl: './anon-leaf-renderer.component.scss',\n})\nexport class AnonLeafRendererComponent {\n @Input() AnonLeaf!: AnonLeaf;\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","<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 <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"text\" >\n @if (removable) {\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 <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"number\">\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 { 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';\n\n@Component({\n selector: 'nff-leaf-list-renderer',\n standalone: true,\n imports: [\n MatIconModule,\n AnonLeafRendererComponent,\n MatButtonModule,\n MatPrefix,\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 @Input() minItems: number = 1;\n @Output() message = new EventEmitter();\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 ngOnInit() {\n if (this.initialValue) {\n this.formArray.patchValue(this.initialValue);\n }\n }\n\n removeItem($index: number) {\n if (this.formArray.length <= this.minItems) {\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 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]=\"minItems == null || formArray.length > minItems\"\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 > minItems) {\n <button class=\"remove-button small-icon-button\" matIconButton [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) {\n <button class=\"add-button small-icon-button\" matIconButton [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}\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 { Leaf, NodeGroup, NodeMap } from '../../types/dynamic-recursive.types';\nimport { addMapEntry, removeMapEntry, renameMapEntry } from '../../core/dynamic-recursive-forms-builder';\nimport { asFormControl, asFormGroup } from '../../core/utils';\nimport { LeafRendererComponent } from '../leaf-renderer/leaf-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 LeafRendererComponent,\n // node-map-renderer and dynamic-recursive-form import each other (a map value\n // may be a group); forwardRef defers the reference to break the cycle.\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\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 /** 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\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}\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 [schema]=\"valueGroup\"\n [formGroup]=\"asFormGroup(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n }\n </div>\n\n @if (editable && !atMin) {\n <button class=\"remove-button small-icon-button\" matIconButton [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 aria-label=\"Add 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 { CASE_KEY, Leaf, NodeChoice, NodeGroup, NodeType } from '../types/dynamic-recursive.types';\nimport { 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 { buildControl, caseFields, 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@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 /** 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 * 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 /** True when the schema is a root group (rendered flat, without a wrapping card). */\n readonly root = computed(() => this.schema().root ?? false);\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).\n */\n toggleNodePresence(key: string, schema: NodeType, present: boolean) {\n const group = this.formGroup();\n if (present) {\n if (!group.get(key)) {\n group.addControl(key, buildControl(schema) as never);\n }\n } else if (group.get(key)) {\n group.removeControl(key);\n }\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 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 /** A synthetic flattened NodeGroup used to render the active case's fields against the choice's FormGroup. */\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: { flatten: true },\n };\n }\n\n /** The display label for a case: the schema's `caseLabels` entry, else the case name. */\n caseLabel(choice: NodeChoice, caseName: string): string {\n return choice.caseLabels?.[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","@if (!root()) {\n <ng-template #formRender>\n <div class=\"form-content\" [formGroup]=\"formGroup()\">\n <div class=\"leafs-container\">\n <div class=\"fields\">\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && !child.presence) {\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') {\n <nff-leaf-list-renderer\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\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) {\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 <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 </div>\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 [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 [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 [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') {\n <nff-node-group-list-renderer\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 == '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 [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=\"+ Add new {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'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\" [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=\"+ Add new {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'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\" [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 <div class=\"fields\">\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 @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && !child.presence) {\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') {\n <nff-leaf-list-renderer\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\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) {\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 <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 </div>\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 [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 [nodeMap]=\"child\"\n [formGroup]=\"mapGroup\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList') {\n <mat-expansion-panel class=\"node-section\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n {{ child.label ?? child.name }}\n </mat-panel-title>\n </mat-expansion-panel-header>\n <nff-node-group-list-renderer\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 == '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 [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 [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 { Component, effect, ElementRef, inject, input, 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 { CASE_KEY, NodeChoice, NodeGroup, NodeMap, NodeType } from '../types/dynamic-recursive.types';\nimport {\n addMapEntry,\n buildControl,\n buildFormFromSchema,\n caseFields,\n removeMapEntry,\n renameMapEntry,\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/** 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}\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 };\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 /** Whether fields accept input and structural controls (add/remove/menus) show. */\n readonly editable = 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 /** 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, schema.label ?? schema.name, '');\n this.shape = this.shapeOf(group);\n this.expanded.add(this.root.id);\n this.select(this.root);\n // The detail sections mutate the FormGroup directly (presence toggles,\n // list items, map entries, case switches); a shape change there must\n // reflect in the tree.\n this.changes = group.valueChanges.subscribe(() => this.syncShape());\n }\n\n select(node: TreeNode, reveal = true) {\n this.selected = node;\n this.sections = this.buildSections(node, []);\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, and\n // the node itself as it opens on the right. Structural re-syncs pass\n // reveal=false — they must not re-expand what the user collapsed.\n if (reveal) {\n for (const crumb of this.breadcrumb) {\n if (crumb !== node || 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 /** Append a new item to a list node's FormArray (up to `maxItems`), then select it. */\n addItem(listNode: TreeNode) {\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 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) {\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 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 || node.group.get(entry.key)) return;\n node.group.addControl(entry.key, buildControl(entry.schema) as AbstractControl);\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 key = node.presenceRemovable?.key;\n if (!key || !parent.group) return;\n parent.group.removeControl(key);\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 ? (c.schema.caseLabels?.[active] ?? active) : null;\n }\n\n /** The display label for a case: the schema's `caseLabels` entry, else the case name. */\n protected caseLabel(choice: NodeChoice, caseName: string): string {\n return choice.caseLabels?.[caseName] ?? caseName;\n }\n\n /** Switch a choice node's active case; the structural sync rebuilds the tree and sections. */\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(node.id);\n }\n\n protected objectKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj);\n }\n\n /** Append a new entry to a complex map node under a generated unique key, then select it. */\n addTreeMapEntry(mapNode: TreeNode) {\n const m = mapNode.map;\n if (!m) return;\n const key = addMapEntry(m.group, m.schema);\n if (key != null) this.selectByPath(this.join(mapNode.id, key));\n }\n\n /** Remove a complex map entry (down to `minEntries`). */\n removeTreeMapEntry(mapNode: TreeNode, entryNode: TreeNode) {\n const m = mapNode.map;\n const e = entryNode.mapEntry;\n if (!m || !e || !removeMapEntry(m.group, m.schema, e.key)) return;\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 entry is\n * selected under its new path and its fresh key field regains focus (the\n * rename re-renders the section under a new id, destroying the input that\n * held focus).\n */\n renameTreeMapEntry(entryNode: TreeNode, rawKey: string) {\n const e = entryNode.mapEntry;\n if (!e) return;\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 this.selectByPath(newId);\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 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 /** 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(), schema.label ?? schema.name, '');\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 return list;\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) : null, group: node.choice.group };\n }\n if (node.schema && node.group) {\n return { schema: this.leafOnly(node.schema), 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. Null when there are none.\n */\n private leafOnly(schema: NodeGroup): 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') children[key] = child;\n }\n if (!Object.keys(children).length) return null;\n return { ...schema, root: false, children, appearance: { flatten: true } };\n }\n\n // --- tree construction -----------------------------------------------------\n\n private buildTree(schema: NodeGroup, group: FormGroup, label: string, path: string): TreeNode {\n const children: TreeNode[] = [];\n const optionals: OptionalEntry[] = [];\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 offered by the menu.\n if (child.kind === 'leaf' && child.presence && !group.get(key)) {\n optionals.push({ key, schema: child, label: this.labelOf(child, key) });\n }\n continue;\n }\n const presence = child.kind !== 'nodeGroupList' && 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));\n if (!node) continue;\n if (presence) node.presenceRemovable = { key };\n children.push(node);\n }\n\n const node: TreeNode = { id: path, label, children, group, schema };\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 ): TreeNode | null {\n if (schema.kind === 'nodeGroup') {\n return control instanceof FormGroup ? this.buildTree(schema, control, label, path) : 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)));\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)\n : ({ id: path, label, children: [], group: control } 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 const entryNode = this.buildChildNode(schema.value, control.controls[key], key, this.join(path, key));\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 /** Synthetic group over a case's normalized fields, so a case body builds like any group. */\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 };\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 (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\"\n [attr.aria-label]=\"'Add ' + node.list.itemLabel\"\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 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\"\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\"\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 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 <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 </nav>\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) {\n @if (s.trail.length > 1) {\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\" 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 </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 [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 (editable() && s.node.map?.complex && !mapAtMax(s.node)) {\n <div class=\"section-actions\">\n <button matButton (click)=\"addTreeMapEntry(s.node)\"><mat-icon>add</mat-icon> Add entry</button>\n </div>\n }\n @if (editable() && s.node.list && !listAtMax(s.node)) {\n <div class=\"section-actions\">\n <button matButton (click)=\"addItem(s.node)\">\n <mat-icon>add</mat-icon> Add {{ s.node.list.itemLabel }}\n </button>\n </div>\n }\n @if (emptySectionHint(s); as hint) {\n <p class=\"empty\">{{ 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/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":["i1","i3","i5","i6","i2","i4"],"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/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/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};\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};\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\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};\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};\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 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 */\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' || node.kind === 'nodeGroup' || node.kind === 'map' || node.kind === 'choice') &&\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\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 return new FormGroup(controls as FormGroupType<G>) 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 * 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 * 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}\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\">\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>\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 { 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';\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 ],\n templateUrl: './leaf-renderer.component.html',\n styleUrl: './leaf-renderer.component.scss',\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 /** 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['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 <input [readonly]=\"!fieldEditable\" matInput type=\"text\" [formControl]=\"control\">\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 <input [readonly]=\"!fieldEditable\" matInput type=\"number\" [formControl]=\"control\">\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\"></nff-leaf-enum-renderer>\n }\n @if (removable && editable) {\n <button matIconButton class=\"remove-button small-icon-button\" matTooltip=\"Remove\" [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 {\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 { 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 @Input() minItems: number = 1;\n @Input() maxItems: number = 1;\n @Output() message = new EventEmitter();\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 if (this.nodeGroupList.maxItems) {\n this.maxItems = this.nodeGroupList.maxItems;\n }\n if (this.nodeGroupList.minItems) {\n this.minItems = this.nodeGroupList.minItems;\n }\n }\n\n ngAfterViewInit() {\n this.items.changes.subscribe(() => {\n this.setLastEditable();\n });\n }\n\n removeItem($index: number) {\n if (this.formArray.length <= this.minItems) {\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 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 [schema]=\"nodeGroupList.type\"\n [formGroup]=\"asFormGroup(group)\"\n [title]=\"getTitle($index)\"\n [index]=\"0\"\n [removable]=\"formArray.length > minItems\"\n (remove)=\"removeItem($index)\"\n [editable]=\"editable\"\n [addButtonCallback]=\"addItem\"\n />\n </div>\n }\n </div>\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { AnonLeaf } 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';\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 ],\n templateUrl: './anon-leaf-renderer.component.html',\n styleUrl: './anon-leaf-renderer.component.scss',\n})\nexport class AnonLeafRendererComponent {\n @Input() AnonLeaf!: AnonLeaf;\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","<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 <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"text\" >\n @if (removable) {\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 <input [readonly]=\"!editable\"\n [formControl]=\"control\"\n matInput type=\"number\">\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 { 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';\n\n@Component({\n selector: 'nff-leaf-list-renderer',\n standalone: true,\n imports: [\n MatIconModule,\n AnonLeafRendererComponent,\n MatButtonModule,\n MatPrefix,\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 @Input() minItems: number = 1;\n @Output() message = new EventEmitter();\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 ngOnInit() {\n if (this.initialValue) {\n this.formArray.patchValue(this.initialValue);\n }\n }\n\n removeItem($index: number) {\n if (this.formArray.length <= this.minItems) {\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 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]=\"minItems == null || formArray.length > minItems\"\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 > minItems) {\n <button class=\"remove-button small-icon-button\" matIconButton [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) {\n <button class=\"add-button small-icon-button\" matIconButton [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}\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 { Leaf, NodeGroup, NodeMap } from '../../types/dynamic-recursive.types';\nimport { addMapEntry, removeMapEntry, renameMapEntry } from '../../core/dynamic-recursive-forms-builder';\nimport { asFormControl, asFormGroup } from '../../core/utils';\nimport { LeafRendererComponent } from '../leaf-renderer/leaf-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 LeafRendererComponent,\n // node-map-renderer and dynamic-recursive-form import each other (a map value\n // may be a group); forwardRef defers the reference to break the cycle.\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\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 /** 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\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}\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 [schema]=\"valueGroup\"\n [formGroup]=\"asFormGroup(formGroup.controls[key])\"\n [editable]=\"editable\"\n />\n }\n </div>\n\n @if (editable && !atMin) {\n <button class=\"remove-button small-icon-button\" matIconButton [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 aria-label=\"Add 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 { CASE_KEY, Leaf, NodeChoice, NodeGroup, NodeType } from '../types/dynamic-recursive.types';\nimport { 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 { buildControl, caseFields, 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@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 /** 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 * 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 /** True when the schema is a root group (rendered flat, without a wrapping card). */\n readonly root = computed(() => this.schema().root ?? false);\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).\n */\n toggleNodePresence(key: string, schema: NodeType, present: boolean) {\n const group = this.formGroup();\n if (present) {\n if (!group.get(key)) {\n group.addControl(key, buildControl(schema) as never);\n }\n } else if (group.get(key)) {\n group.removeControl(key);\n }\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 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 /** A synthetic flattened NodeGroup used to render the active case's fields against the choice's FormGroup. */\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: { flatten: true },\n };\n }\n\n /** The display label for a case: the schema's `caseLabels` entry, else the case name. */\n caseLabel(choice: NodeChoice, caseName: string): string {\n return choice.caseLabels?.[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","@if (!root()) {\n <ng-template #formRender>\n <div class=\"form-content\" [formGroup]=\"formGroup()\">\n <div class=\"leafs-container\">\n <div class=\"fields\">\n @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && !child.presence) {\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') {\n <nff-leaf-list-renderer\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\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) {\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 <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 </div>\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 [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 [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 [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') {\n <nff-node-group-list-renderer\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 == '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 [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=\"+ Add new {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'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\" [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=\"+ Add new {{ schema().label ?? schema().name }}\" [attr.aria-label]=\"'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\" [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 <div class=\"fields\">\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 @for (childItem of nodeGroupChildrenList; track $index) {\n @let child = childItem.value;\n @if (child.kind == 'leaf' && !child.presence) {\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') {\n <nff-leaf-list-renderer\n [leaf_]=\"child\"\n [editable]=\"editable()\"\n [formArray]=\"asFormArray(formGroup().get(childItem.key))\"\n [initialValue]=\"formGroup().get(childItem.key)?.value\"\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) {\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 <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 </div>\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 [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 [nodeMap]=\"child\"\n [formGroup]=\"mapGroup\"\n [editable]=\"editable()\"\n />\n }\n </mat-expansion-panel>\n }\n @else if (child.kind == 'nodeGroupList') {\n <mat-expansion-panel class=\"node-section\" togglePosition=\"before\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n {{ child.label ?? child.name }}\n </mat-panel-title>\n </mat-expansion-panel-header>\n <nff-node-group-list-renderer\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 == '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 [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 [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 { Component, effect, ElementRef, inject, input, 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 { CASE_KEY, NodeChoice, NodeGroup, NodeMap, NodeType } from '../types/dynamic-recursive.types';\nimport {\n addMapEntry,\n buildControl,\n buildFormFromSchema,\n caseFields,\n removeMapEntry,\n renameMapEntry,\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/** 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}\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 };\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 /** Whether fields accept input and structural controls (add/remove/menus) show. */\n readonly editable = 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 /** 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, schema.label ?? schema.name, '');\n this.shape = this.shapeOf(group);\n this.expanded.add(this.root.id);\n this.select(this.root);\n // The detail sections mutate the FormGroup directly (presence toggles,\n // list items, map entries, case switches); a shape change there must\n // reflect in the tree.\n this.changes = group.valueChanges.subscribe(() => this.syncShape());\n }\n\n select(node: TreeNode, reveal = true) {\n this.selected = node;\n this.sections = this.buildSections(node, []);\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, and\n // the node itself as it opens on the right. Structural re-syncs pass\n // reveal=false — they must not re-expand what the user collapsed.\n if (reveal) {\n for (const crumb of this.breadcrumb) {\n if (crumb !== node || 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 /** Append a new item to a list node's FormArray (up to `maxItems`), then select it. */\n addItem(listNode: TreeNode) {\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 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) {\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 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 || node.group.get(entry.key)) return;\n node.group.addControl(entry.key, buildControl(entry.schema) as AbstractControl);\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 key = node.presenceRemovable?.key;\n if (!key || !parent.group) return;\n parent.group.removeControl(key);\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 ? (c.schema.caseLabels?.[active] ?? active) : null;\n }\n\n /** The display label for a case: the schema's `caseLabels` entry, else the case name. */\n protected caseLabel(choice: NodeChoice, caseName: string): string {\n return choice.caseLabels?.[caseName] ?? caseName;\n }\n\n /** Switch a choice node's active case; the structural sync rebuilds the tree and sections. */\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(node.id);\n }\n\n protected objectKeys(obj: Record<string, unknown>): string[] {\n return Object.keys(obj);\n }\n\n /** Append a new entry to a complex map node under a generated unique key, then select it. */\n addTreeMapEntry(mapNode: TreeNode) {\n const m = mapNode.map;\n if (!m) return;\n const key = addMapEntry(m.group, m.schema);\n if (key != null) this.selectByPath(this.join(mapNode.id, key));\n }\n\n /** Remove a complex map entry (down to `minEntries`). */\n removeTreeMapEntry(mapNode: TreeNode, entryNode: TreeNode) {\n const m = mapNode.map;\n const e = entryNode.mapEntry;\n if (!m || !e || !removeMapEntry(m.group, m.schema, e.key)) return;\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 entry is\n * selected under its new path and its fresh key field regains focus (the\n * rename re-renders the section under a new id, destroying the input that\n * held focus).\n */\n renameTreeMapEntry(entryNode: TreeNode, rawKey: string) {\n const e = entryNode.mapEntry;\n if (!e) return;\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 this.selectByPath(newId);\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 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 /** 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(), schema.label ?? schema.name, '');\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 return list;\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) : null, group: node.choice.group };\n }\n if (node.schema && node.group) {\n return { schema: this.leafOnly(node.schema), 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. Null when there are none.\n */\n private leafOnly(schema: NodeGroup): 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') children[key] = child;\n }\n if (!Object.keys(children).length) return null;\n return { ...schema, root: false, children, appearance: { flatten: true } };\n }\n\n // --- tree construction -----------------------------------------------------\n\n private buildTree(schema: NodeGroup, group: FormGroup, label: string, path: string): TreeNode {\n const children: TreeNode[] = [];\n const optionals: OptionalEntry[] = [];\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 offered by the menu.\n if (child.kind === 'leaf' && child.presence && !group.get(key)) {\n optionals.push({ key, schema: child, label: this.labelOf(child, key) });\n }\n continue;\n }\n const presence = child.kind !== 'nodeGroupList' && 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));\n if (!node) continue;\n if (presence) node.presenceRemovable = { key };\n children.push(node);\n }\n\n const node: TreeNode = { id: path, label, children, group, schema };\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 ): TreeNode | null {\n if (schema.kind === 'nodeGroup') {\n return control instanceof FormGroup ? this.buildTree(schema, control, label, path) : 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)));\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)\n : ({ id: path, label, children: [], group: control } 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 const entryNode = this.buildChildNode(schema.value, control.controls[key], key, this.join(path, key));\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 /** Synthetic group over a case's normalized fields, so a case body builds like any group. */\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 };\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 (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\"\n [attr.aria-label]=\"'Add ' + node.list.itemLabel\"\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 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\"\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\"\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 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 <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 </nav>\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) {\n @if (s.trail.length > 1) {\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\" 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 </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 [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 (editable() && s.node.map?.complex && !mapAtMax(s.node)) {\n <div class=\"section-actions\">\n <button matButton (click)=\"addTreeMapEntry(s.node)\"><mat-icon>add</mat-icon> Add entry</button>\n </div>\n }\n @if (editable() && s.node.list && !listAtMax(s.node)) {\n <div class=\"section-actions\">\n <button matButton (click)=\"addItem(s.node)\">\n <mat-icon>add</mat-icon> Add {{ s.node.list.itemLabel }}\n </button>\n </div>\n }\n @if (emptySectionHint(s); as hint) {\n <p class=\"empty\">{{ 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/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":["i1","i3","i5","i6","i2","i4"],"mappings":"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"}