ngx-dynamic-entity 2.0.2 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-dynamic-entity",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
4
4
  "description": "Angular standalone UI library for rendering dynamic entity forms.",
5
5
  "//typings": "Local workspace resolution only: ng-packagr 21 writes types/ngx-dynamic-entity.d.ts into dist/package.json. Do NOT add a 'main' field here — ng-packagr does not generate one, so it would be copied verbatim and resolve wrongly in the published package.",
6
6
  "typings": "types/ngx-dynamic-entity.d.ts",
@@ -8,7 +8,7 @@
8
8
  "@angular/common": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
9
9
  "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
10
10
  "@angular/forms": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
11
- "@dynamic-entity/core": "^2.0.2",
11
+ "@dynamic-entity/core": "^2.1.1",
12
12
  "rxjs": "^7.0.0"
13
13
  },
14
14
  "keywords": [
@@ -286,9 +286,8 @@ interface ImportTransport {
286
286
  * choice — and `spec` is that selection already expanded against the config. A transport that
287
287
  * renders locally wants the spec; one that asks a server wants the selection, because the
288
288
  * server has the config and only the choice needs to cross the wire. Passing both means
289
- * neither has to reconstruct the other: the HTTP transport used to recover the selection from
290
- * the expanded spec, which worked only because `stripIndices` happens to be exactly the
291
- * inverse of the expansion. Optional, so an existing implementation keeps compiling.
289
+ * neither has to reconstruct the other. Optional, so an existing implementation keeps
290
+ * compiling.
292
291
  */
293
292
  template(spec: TemplateSpec, format: TemplateFormat, context: ImportContext, fields?: readonly string[]): Promise<Blob>;
294
293
  }
@@ -465,7 +464,7 @@ declare const ENTITY_REF_CACHE_STORE: InjectionToken<EntityRefCacheStore>;
465
464
  declare const SYSTEM_DEFAULT_CAN_EDIT: InjectionToken<(roles: string[]) => boolean>;
466
465
  type ConfigSourceHandler = (entityKey: string) => any;
467
466
  /**
468
- * Registry/Resolver for resolving an EntityFormConfig by entity key across entities (Phase 8).
467
+ * Registry/Resolver for resolving an EntityFormConfig by entity key across entities.
469
468
  * Enables cross-entity field referencing (`isReferenced`, `referencedEntityKey`, `referencedFieldId`, `hasDrift`).
470
469
  */
471
470
  declare const CONFIG_SOURCE: InjectionToken<ConfigSourceHandler>;
@@ -493,8 +492,7 @@ declare const MARKDOWN_RENDERER: InjectionToken<(source: string) => string>;
493
492
  *
494
493
  * Masking is presentational — see SECURITY.md — and what it prints is a product decision:
495
494
  * `••••••••` reads as a redaction, "Hidden" reads as a permission, and a localized string
496
- * reads as neither in English. It was a literal repeated across every field component, so
497
- * there was no way to choose.
495
+ * reads as neither in English, so it is the host's to choose.
498
496
  *
499
497
  * @example
500
498
  * { provide: MASKED_PLACEHOLDER, useValue: '••••••••' }
@@ -709,10 +707,9 @@ declare class ValidatorRegistryService {
709
707
  /**
710
708
  * Say when a named validator resolved to nothing.
711
709
  *
712
- * It used to be dropped in silence, which is the worst failure mode this library has: the
713
- * schema says the field is checked, the field is not checked, the form saves, and nothing
714
- * anywhere said so. For `customAsync` that is typically a uniqueness check, so the duplicate
715
- * lands in the database.
710
+ * Silence would be the worst failure mode this library has: the schema says the field is
711
+ * checked, the field is not checked, the form saves, and nothing says so. For
712
+ * `customAsync` that is typically a uniqueness check, so the duplicate lands in the database.
716
713
  *
717
714
  * Dev only, once per name — this runs while controls are built, which happens on every
718
715
  * config change. `validateConfig` with `knownValidators` is the build-time version of the
@@ -1000,13 +997,8 @@ interface RuleSyncContext {
1000
997
  /**
1001
998
  * RulesEvaluationService — evaluates rules, and owns what a result *means*.
1002
999
  *
1003
- * It used to be two passthrough methods, with the interpretation spread across the component:
1004
- * the render filter decided one way what a rule result did to a field, and the validity sync
1005
- * decided again forty lines further down. They disagreed about what "every field" meant, and
1006
- * the consequence was a required field inside a `group` that a rule had hidden holding
1007
- * `form.invalid` true forever with nothing on screen to explain it.
1008
- *
1009
- * Precedence lives here now, in one method that both callers go through. Still stateless —
1000
+ * Precedence lives in one method that both the render filter and the validity sync go
1001
+ * through, so what is on screen and what counts toward validity cannot disagree. Stateless —
1010
1002
  * every method takes the result it is interpreting, so there is nothing to go stale against a
1011
1003
  * rebuilt form and nothing to reset between configs.
1012
1004
  */
@@ -1081,9 +1073,7 @@ declare class ConfigSourceService {
1081
1073
  /**
1082
1074
  * Resolves an Angular `ValidationErrors` object to the message shown under a field.
1083
1075
  *
1084
- * These strings used to be hardcoded English literals inside each field component, so a
1085
- * German form meant re-implementing every field type — the labels honoured `language` while
1086
- * the errors underneath them did not.
1076
+ * Field components never hardcode these strings, so errors honour `language` just as labels do.
1087
1077
  *
1088
1078
  * A message is a plain string, or a function when it needs the error's own detail
1089
1079
  * (`minlength.requiredLength`, `min.min`, and so on). The active `language` is passed
@@ -1119,12 +1109,10 @@ declare class ValidationMessagesService {
1119
1109
  /**
1120
1110
  * The message for a field, chosen by its **type** rather than by a list the caller supplies.
1121
1111
  *
1122
- * Every field component used to pass its own copy of the key order, and the copies were
1123
- * near-identical — which was tolerable while the field itself was the only thing that
1124
- * rendered a message. It stopped being tolerable when the error summary above the form
1125
- * started naming what is wrong with each field: the summary has no field component to ask
1126
- * (the offending field is usually on a tab that is not rendered), so it would have needed a
1127
- * second copy of the same table, and a dropdown would have said "This field is required" in
1112
+ * Both the field itself and the error summary above the form render this message, and the
1113
+ * summary has no field component to ask (the offending field is usually on a tab that is
1114
+ * not rendered). Per-component key orders would drift, and a dropdown would say "This
1115
+ * field is required" in
1128
1116
  * the summary and "Please select an option" under the control.
1129
1117
  *
1130
1118
  * One table, read from both places, is what keeps those two sentences the same sentence.
@@ -1314,8 +1302,7 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1314
1302
  /**
1315
1303
  * Whether the current roles may see this record at all.
1316
1304
  *
1317
- * `permissions.view` used to be computed and thrown away — a user whose roles failed it
1318
- * still received the complete form with every value in the DOM. It is honoured now.
1305
+ * A user whose roles fail `permissions.view` gets no form, so no value reaches the DOM.
1319
1306
  *
1320
1307
  * As with masking, this is presentational: it stops the browser rendering data, it does
1321
1308
  * not stop the data reaching the browser. Authorize on the server.
@@ -1359,13 +1346,11 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1359
1346
  /**
1360
1347
  * Whether the Save button is unavailable.
1361
1348
  *
1362
- * This used to be `submitBlocked`, so an invalid form greyed Save out — and a greyed button
1363
- * is the worst possible answer to "why can't I save?". It cannot be clicked, so there is no
1364
- * moment at which the form gets to say which field is at fault or which tab it is on; the
1365
- * user is left comparing a disabled button against a form that looks, to them, filled in.
1366
- * On a tabbed form the offending field is usually not even on screen.
1349
+ * Deliberately not `submitBlocked`: a greyed button is the worst answer to "why can't I
1350
+ * save?". It cannot be clicked, so the form never gets to say which field is at fault or
1351
+ * which tab it is on — and on a tabbed form that field is usually not on screen.
1367
1352
  *
1368
- * Save now stays available while the form is merely invalid. Clicking it still saves
1353
+ * Save stays available while the form is merely invalid. Clicking it still saves
1369
1354
  * nothing — `submit()` checks `submitBlocked` and refuses — but the refusal is where the
1370
1355
  * error summary, the tab badges and the jump to the first bad field come from, so pressing
1371
1356
  * Save produces an explanation instead of silence.
@@ -1535,25 +1520,10 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1535
1520
  /**
1536
1521
  * Ids already warned about, per component instance.
1537
1522
  *
1538
- * This was `private static`, so it was module-global mutable state that nothing ever
1539
- * cleared: under SSR every render of every form in the process accumulated into one set
1540
- * that lived as long as the server did, and the first request to render a config
1541
- * suppressed the warning for every request after it. Per instance, the warning is once per
1542
- * form — which is what "warn once" was meant to mean.
1523
+ * Per instance, never `static`: under SSR a module-global set would outlive every request,
1524
+ * and the first render of a config would suppress the warning for every render after it.
1543
1525
  */
1544
1526
  private readonly warnedAmbiguousIds;
1545
- /**
1546
- * The value map rules and `showWhen` are evaluated against.
1547
- *
1548
- * Every field appears under two keys: its bare id, and its `refererField` path wrapped in brackets.
1549
- * The bare id is what every config written so far uses and is kept exactly as it was — but
1550
- * ids are unique per scope, so when two scopes define one the last field walked wins and
1551
- * the rule reads whichever that is. `[personal.address]` names one field and cannot be
1552
- * ambiguous, which is why a rule that has to distinguish them uses the ref.
1553
- *
1554
- * Both live in one flat map on purpose: `evaluateFormRules` takes a `Record<string,
1555
- * unknown>` and needs no knowledge of refs at all — the extra keys simply resolve.
1556
- */
1557
1527
  /**
1558
1528
  * Every name a rule may address this field by.
1559
1529
  *
@@ -1579,28 +1549,16 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1579
1549
  /**
1580
1550
  * Every field in the config with the scope its value is stored under, cached per config.
1581
1551
  *
1582
- * `collectFieldScopes` walks the whole tree. It was called once per field from `pathFor`,
1583
- * which `namesField` calls, which the render filter calls for every field on the active
1584
- * tab — a quadratic walk on every change-detection pass. Keyed by config identity, so a
1552
+ * `collectFieldScopes` walks the whole tree, and `pathFor` runs once per rendered field on
1553
+ * every change-detection pass — uncached, that is quadratic. Keyed by config identity, so a
1585
1554
  * new config invalidates it without an explicit lifecycle hook to forget.
1586
1555
  */
1587
1556
  private fieldScopes;
1588
1557
  private scopeEntryFor;
1589
1558
  private scopeCache?;
1590
- /**
1591
- * The control a scope entry addresses, named by path rather than by bare id.
1592
- *
1593
- * `getControl(field.id)` with no tab falls through to a first-match recursive search of the
1594
- * whole form, so with `address` on two tabs, hiding one disabled the other. The control
1595
- * tree mirrors the scope path exactly — `buildTabControls` nests by tab id and
1596
- * `buildFieldControl` nests a `group` under its own id — so a `[path]` ref resolves through
1597
- * `form.get()` on `getControl`'s first branch and names exactly one control.
1598
- *
1599
- * A field inside an `array` has no static path: its controls live in `FormArray` rows built
1600
- * per row. `form.get()` returns null for those and they are left alone, which is correct —
1601
- * a row's controls are created and destroyed with the row.
1602
- */
1559
+ /** The control a scope entry addresses — see `FormStructureService.controlAt`. */
1603
1560
  private controlForEntry;
1561
+ /** The value map rules and `showWhen` are evaluated against — see `FormStructureService.flattenValues`. */
1604
1562
  private flattenFormValues;
1605
1563
  /**
1606
1564
  * `autoPatch` — copy mapped fields out of the record the user just selected in an
@@ -1610,8 +1568,18 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1610
1568
  /**
1611
1569
  * `patchOnTrue` — when a boolean/checkbox field transitions to `true`,
1612
1570
  * copy `from` → `to` within the current record.
1571
+ *
1572
+ * The trigger is read by its ref, and a bare `from`/`to` resolves to a sibling in the
1573
+ * trigger's own scope before falling back to a form-wide lookup — so two groups that each
1574
+ * carry `home`, `billing` and a "same as" flag patch within themselves, not across.
1613
1575
  */
1614
1576
  private runPatchOnTrue;
1577
+ /**
1578
+ * A field named by a mapping, preferring a sibling in `scope` when the name is a bare id.
1579
+ *
1580
+ * `key` is the field's entry in the flattened value map; `control` is the control it owns.
1581
+ */
1582
+ private resolveInScope;
1615
1583
  /**
1616
1584
  * Prefer a control declared on the configured target tab; fall back to a top-level control.
1617
1585
  *
@@ -1851,10 +1819,8 @@ declare class DynamicRecordFormComponent implements OnChanges {
1851
1819
  /**
1852
1820
  * What this record is called, as opposed to what kind of thing it is.
1853
1821
  *
1854
- * The header used to show the entity's name twice — "clients", with "Entity: clients"
1855
- * underneath — so the one question a record header exists to answer, *which* record am I
1856
- * looking at, was the one thing it did not say. The entity keeps the subtitle; this takes
1857
- * the heading.
1822
+ * A record header exists to answer *which* record am I looking at, so this takes the
1823
+ * heading and the entity name keeps the subtitle.
1858
1824
  *
1859
1825
  * The order is deliberate. `showOnMinimize` is the author saying "this is what identifies a
1860
1826
  * record" — it is what the summary panel and the collapsed view already show — so it is
@@ -1913,11 +1879,6 @@ declare class DynamicRecordFormComponent implements OnChanges {
1913
1879
  rowDrawerTitle(field: NestedFieldConfig): string;
1914
1880
  /** Summary values render through the shared core formatter, not a local stringifier. */
1915
1881
  formatFieldValue(field: NestedFieldConfig): string;
1916
- /**
1917
- * Finds which tab — and, where the field lives one level down, which sub-tab — owns a
1918
- * field. The walk used to check top-level `fields` only, so every field in a sub-tab was
1919
- * simply not found and the jump did nothing at all.
1920
- */
1921
1882
  /**
1922
1883
  * Switches to the tab holding `fieldId`, then scrolls it into view and moves focus to it.
1923
1884
  *
@@ -1987,7 +1948,7 @@ declare class DynamicFieldComponent implements OnChanges, OnDestroy {
1987
1948
  *
1988
1949
  * `detectChanges()` rather than `markForCheck()`: a selection that arrives from a native
1989
1950
  * `change` event (or Playwright) may not be followed by another Angular tick, so a dirty
1990
- * flag would never be flushed. Running CD on the hosted component now is the copy showing up.
1951
+ * flag would never be flushed. Running CD on the hosted component immediately is what shows the copied value.
1991
1952
  *
1992
1953
  * Done here rather than in each of the eighteen field components: the host owns the
1993
1954
  * component reference, so one subscription covers every type including custom ones.
@@ -2512,12 +2473,6 @@ declare class TextareaFieldComponent {
2512
2473
  masked: boolean;
2513
2474
  get label(): string;
2514
2475
  get placeholder(): string;
2515
- /**
2516
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2517
- * validationMessages })` reaches this field. It used to render a fixed
2518
- * "This field has an error", which made a documented, configurable feature work on three
2519
- * of fifteen field types.
2520
- */
2521
2476
  /** Author help text, shown under the control and named by `aria-describedby`. */
2522
2477
  get hint(): string;
2523
2478
  /** The ids of whatever is describing this control right now. */
@@ -2595,12 +2550,6 @@ declare class MarkdownFieldComponent implements OnChanges {
2595
2550
  */
2596
2551
  private cached?;
2597
2552
  protected rendered(): string | null;
2598
- /**
2599
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2600
- * validationMessages })` reaches this field. It used to render a fixed
2601
- * "This field has an error", which made a documented, configurable feature work on three
2602
- * of fifteen field types.
2603
- */
2604
2553
  /** Author help text, shown under the control and named by `aria-describedby`. */
2605
2554
  get hint(): string;
2606
2555
  /** The ids of whatever is describing this control right now. */
@@ -2656,12 +2605,6 @@ declare class CurrencyFieldComponent {
2656
2605
  get placeholder(): string;
2657
2606
  /** Picks the currency symbol from the locale — defaults to '$'. */
2658
2607
  get symbol(): string;
2659
- /**
2660
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2661
- * validationMessages })` reaches this field. It used to render a fixed
2662
- * "This field has an error", which made a documented, configurable feature work on three
2663
- * of fifteen field types.
2664
- */
2665
2608
  /** Author help text, shown under the control and named by `aria-describedby`. */
2666
2609
  get hint(): string;
2667
2610
  /** The ids of whatever is describing this control right now. */
@@ -2689,12 +2632,6 @@ declare class EmailFieldComponent {
2689
2632
  masked: boolean;
2690
2633
  get label(): string;
2691
2634
  get placeholder(): string;
2692
- /**
2693
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2694
- * validationMessages })` reaches this field. It used to render a fixed
2695
- * "This field has an error", which made a documented, configurable feature work on three
2696
- * of fifteen field types.
2697
- */
2698
2635
  /** Author help text, shown under the control and named by `aria-describedby`. */
2699
2636
  get hint(): string;
2700
2637
  /** The ids of whatever is describing this control right now. */
@@ -2726,12 +2663,6 @@ declare class PasswordFieldComponent {
2726
2663
  get label(): string;
2727
2664
  get placeholder(): string;
2728
2665
  toggleVisibility(): void;
2729
- /**
2730
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2731
- * validationMessages })` reaches this field. It used to render a fixed
2732
- * "This field has an error", which made a documented, configurable feature work on three
2733
- * of fifteen field types.
2734
- */
2735
2666
  /** Author help text, shown under the control and named by `aria-describedby`. */
2736
2667
  get hint(): string;
2737
2668
  /** The ids of whatever is describing this control right now. */
@@ -2759,12 +2690,6 @@ declare class CheckboxFieldComponent {
2759
2690
  readonly: boolean;
2760
2691
  masked: boolean;
2761
2692
  get label(): string;
2762
- /**
2763
- * Configured messages reach this field too.
2764
- *
2765
- * It rendered no error element at all, so a required checkbox left unticked told the user
2766
- * nothing — and `validationMessages` could not reach a field that never displayed one.
2767
- */
2768
2693
  /** Author help text, shown under the control and named by `aria-describedby`. */
2769
2694
  get hint(): string;
2770
2695
  /** The ids of whatever is describing this control right now. */
@@ -2797,12 +2722,6 @@ declare class BooleanFieldComponent {
2797
2722
  readonly: boolean;
2798
2723
  masked: boolean;
2799
2724
  get label(): string;
2800
- /**
2801
- * Configured messages reach this field too.
2802
- *
2803
- * It rendered no error element at all, so a required checkbox left unticked told the user
2804
- * nothing — and `validationMessages` could not reach a field that never displayed one.
2805
- */
2806
2725
  /** Author help text, shown under the control and named by `aria-describedby`. */
2807
2726
  get hint(): string;
2808
2727
  /** The ids of whatever is describing this control right now. */
@@ -2831,22 +2750,12 @@ declare class DateFieldComponent {
2831
2750
  /**
2832
2751
  * ISO 8601 date → display string, through the formatter the host configured.
2833
2752
  *
2834
- * This used to call `toLocaleDateString()` directly, which meant `setDateFormatters` — the
2835
- * one seam for choosing how a date is rendered — reached the record summary and the `time`
2836
- * field but not this one. A host that configured formatters got them almost everywhere,
2837
- * and silently did not get them on the field type most likely to be the reason they
2838
- * configured formatters at all.
2753
+ * Never call `toLocaleDateString()` directly here: `setDateFormatters` is the one seam for
2754
+ * choosing how a date renders, and every date display has to go through it.
2839
2755
  *
2840
- * The default formatter is `toLocaleDateString()` with no locale, so an application that
2841
- * has not called `setDateFormatters` renders exactly what it rendered before.
2756
+ * The default formatter is `toLocaleDateString()` with no locale.
2842
2757
  */
2843
2758
  formatDate(value: string | null): string;
2844
- /**
2845
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2846
- * validationMessages })` reaches this field. It used to render a fixed
2847
- * "This field has an error", which made a documented, configurable feature work on three
2848
- * of fifteen field types.
2849
- */
2850
2759
  /** Author help text, shown under the control and named by `aria-describedby`. */
2851
2760
  get hint(): string;
2852
2761
  /** The ids of whatever is describing this control right now. */
@@ -2897,12 +2806,6 @@ declare class DateTimeFieldComponent {
2897
2806
  * handed on as ISO rather than the raw value.
2898
2807
  */
2899
2808
  formatDateTime(value: unknown): string;
2900
- /**
2901
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2902
- * validationMessages })` reaches this field. It used to render a fixed
2903
- * "This field has an error", which made a documented, configurable feature work on three
2904
- * of fifteen field types.
2905
- */
2906
2809
  /** Author help text, shown under the control and named by `aria-describedby`. */
2907
2810
  get hint(): string;
2908
2811
  /** The ids of whatever is describing this control right now. */
@@ -2942,12 +2845,6 @@ declare class TimeFieldComponent {
2942
2845
  * another in the record summary because the two drifted apart.
2943
2846
  */
2944
2847
  formatTime(value: unknown): string;
2945
- /**
2946
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2947
- * validationMessages })` reaches this field. It used to render a fixed
2948
- * "This field has an error", which made a documented, configurable feature work on three
2949
- * of fifteen field types.
2950
- */
2951
2848
  /** Author help text, shown under the control and named by `aria-describedby`. */
2952
2849
  get hint(): string;
2953
2850
  /** The ids of whatever is describing this control right now. */
@@ -2990,12 +2887,6 @@ declare class MonthYearFieldComponent {
2990
2887
  onMonthChange(month: string): void;
2991
2888
  onYearChange(year: string): void;
2992
2889
  formatValue(value: unknown): string;
2993
- /**
2994
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2995
- * validationMessages })` reaches this field. It used to render a fixed
2996
- * "This field has an error", which made a documented, configurable feature work on three
2997
- * of fifteen field types.
2998
- */
2999
2890
  /** Author help text, shown under the control and named by `aria-describedby`. */
3000
2891
  get hint(): string;
3001
2892
  /** The ids of whatever is describing this control right now. */
@@ -3038,10 +2929,7 @@ declare class DropdownFieldComponent {
3038
2929
  * The value this option stores — the option object itself.
3039
2930
  *
3040
2931
  * Kept as a method rather than binding `option` straight into the template, because it is
3041
- * the one place that says *why* the two are the same thing. It used to delegate to
3042
- * `getOptionStoredValue`, an exported identity function whose two branches returned their
3043
- * argument unchanged; naming a transformation that does not happen is worse than naming
3044
- * nothing, because a reader has to go and check.
2932
+ * the one place that says *why* the two are the same thing.
3045
2933
  */
3046
2934
  getOptStoredVal(option: DropdownOption): unknown;
3047
2935
  getOptLabel(option: DropdownOption): string;
@@ -3095,10 +2983,7 @@ declare class RadioFieldComponent implements OnDestroy {
3095
2983
  * The value this option stores — the option object itself.
3096
2984
  *
3097
2985
  * Kept as a method rather than binding `option` straight into the template, because it is
3098
- * the one place that says *why* the two are the same thing. It used to delegate to
3099
- * `getOptionStoredValue`, an exported identity function whose two branches returned their
3100
- * argument unchanged; naming a transformation that does not happen is worse than naming
3101
- * nothing, because a reader has to go and check.
2986
+ * the one place that says *why* the two are the same thing.
3102
2987
  */
3103
2988
  getOptStoredVal(option: DropdownOption): unknown;
3104
2989
  /**
@@ -3121,12 +3006,6 @@ declare class RadioFieldComponent implements OnDestroy {
3121
3006
  isChecked(option: DropdownOption): boolean;
3122
3007
  /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */
3123
3008
  getSelectedLabel(): string;
3124
- /**
3125
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
3126
- * validationMessages })` reaches this field. It used to render a fixed
3127
- * "This field has an error", which made a documented, configurable feature work on three
3128
- * of fifteen field types.
3129
- */
3130
3009
  /** Author help text, shown under the control and named by `aria-describedby`. */
3131
3010
  get hint(): string;
3132
3011
  /** The ids of whatever is describing this control right now. */
@@ -3166,21 +3045,12 @@ declare class MultiSelectFieldComponent {
3166
3045
  * The value this option stores — the option object itself.
3167
3046
  *
3168
3047
  * Kept as a method rather than binding `option` straight into the template, because it is
3169
- * the one place that says *why* the two are the same thing. It used to delegate to
3170
- * `getOptionStoredValue`, an exported identity function whose two branches returned their
3171
- * argument unchanged; naming a transformation that does not happen is worse than naming
3172
- * nothing, because a reader has to go and check.
3048
+ * the one place that says *why* the two are the same thing.
3173
3049
  */
3174
3050
  getOptStoredVal(option: DropdownOption): unknown;
3175
3051
  getOptLabel(option: DropdownOption): string;
3176
3052
  /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */
3177
3053
  getLabels(values: unknown): string;
3178
- /**
3179
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
3180
- * validationMessages })` reaches this field. It used to render a fixed
3181
- * "This field has an error", which made a documented, configurable feature work on three
3182
- * of fifteen field types.
3183
- */
3184
3054
  /** Author help text, shown under the control and named by `aria-describedby`. */
3185
3055
  get hint(): string;
3186
3056
  /** The ids of whatever is describing this control right now. */
@@ -3243,12 +3113,6 @@ declare class EntityRefFieldComponent implements OnInit {
3243
3113
  private parentValue;
3244
3114
  /** Reload (and drop a stale selection) whenever the parent control changes. */
3245
3115
  private watchParent;
3246
- /**
3247
- * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
3248
- * validationMessages })` reaches this field. It used to render a fixed
3249
- * "This field has an error", which made a documented, configurable feature work on three
3250
- * of fifteen field types.
3251
- */
3252
3116
  /** Author help text, shown under the control and named by `aria-describedby`. */
3253
3117
  get hint(): string;
3254
3118
  /** The ids of whatever is describing this control right now. */