ngx-dynamic-entity 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Type, EnvironmentProviders, WritableSignal, OnInit, OnChanges, OnDestroy, EventEmitter, SimpleChanges } from '@angular/core';
3
- import { ReferenceOption as ReferenceOption$1, EntityReferenceLoader as EntityReferenceLoader$1, LookupListSource as LookupListSource$1, RecordMigration as RecordMigration$1, FieldValidators, NestedFieldConfig, ReferenceLoaderContext, EntityFormConfig, DropdownOption, LookupListValue, NestedTabConfig, FormRule, RuleEvaluationResult as RuleEvaluationResult$1 } from '@dynamic-entity/core';
4
- export { AutoPatchConfig, CommonModuleEntry, DropdownOption, EntityFormConfig, EntityPermissions, EntityReferenceConfig, EntityReferenceLoader, FieldTableConfig, FieldValidators, FileRef, FormRule, LocalizedText, NestedFieldConfig, NestedTabConfig, PatchOnTrueMapping, RbacContext, ReferenceLoaderContext, ReferenceOption, RichFieldType, RuleAction, RuleCondition, RuleEvaluationResult, VersionedRecord, formatDisplayValue, normalizeConfig, normalizeOption, resolveLabel, resolveOptionLabel, resolveOptionValue, valuesMatch } from '@dynamic-entity/core';
3
+ import { ReferenceOption as ReferenceOption$1, LocalizedText, EntityReferenceLoader as EntityReferenceLoader$1, LookupListSource as LookupListSource$1, RecordMigration as RecordMigration$1, FieldValidators, NestedFieldConfig, ReferenceLoaderContext, EntityFormConfig, DropdownOption, LookupListValue, NestedTabConfig, FormRule, RuleEvaluationResult as RuleEvaluationResult$1 } from '@dynamic-entity/core';
4
+ export { AutoPatchConfig, CommonModuleEntry, ComponentClass, DropdownOption, EntityFormConfig, EntityPermissions, EntityReferenceConfig, EntityReferenceLoader, FieldTableConfig, FieldValidators, FileRef, FormRule, LocalizedText, NestedFieldConfig, NestedTabConfig, PatchOnTrueMapping, RbacContext, ReferenceLoaderContext, ReferenceOption, RichFieldType, RuleAction, RuleCondition, RuleEvaluationResult, VersionedRecord, formatDisplayValue, normalizeConfig, normalizeOption, resolveLabel, resolveOptionLabel, resolveOptionValue, valuesMatch } from '@dynamic-entity/core';
5
5
  import { ValidatorFn, AsyncValidatorFn, ValidationErrors, FormGroup, FormArray, AbstractControl } from '@angular/forms';
6
6
  import * as rxjs from 'rxjs';
7
7
 
@@ -32,6 +32,134 @@ declare class InMemoryEntityRefCacheStore implements EntityRefCacheStore {
32
32
  clear(): void;
33
33
  }
34
34
 
35
+ /**
36
+ * Every word this library puts on screen that does not come from a config.
37
+ *
38
+ * Field labels, placeholders and options are `LocalizedText` and already follow the form's
39
+ * `language`. The library's *own* chrome — Save, Reset, "No rows yet." — was English
40
+ * literals in twenty-odd templates, so an application in German rendered German labels
41
+ * around English buttons. There was no way to change them short of forking a component.
42
+ *
43
+ * This map is the whole surface: the keys are what a host translates, and the values are
44
+ * the English source strings to translate *from*. It is exported so a translation file can
45
+ * be generated from it rather than transcribed by hand.
46
+ *
47
+ * Keys are grouped by where they appear rather than alphabetically, because a translator
48
+ * works screen by screen and a list sorted by name hides which strings sit together.
49
+ */
50
+ declare const DEFAULT_UI_TEXT: {
51
+ save: string;
52
+ saving: string;
53
+ reset: string;
54
+ saveShortcutHint: string;
55
+ loading: string;
56
+ editSection: string;
57
+ saveSection: string;
58
+ editingSection: string;
59
+ cancel: string;
60
+ edit: string;
61
+ delete: string;
62
+ addRow: string;
63
+ addItem: string;
64
+ itemNumber: string;
65
+ addRowTitle: string;
66
+ editRowTitle: string;
67
+ saveRow: string;
68
+ remove: string;
69
+ noRows: string;
70
+ noItems: string;
71
+ selectPlaceholder: string;
72
+ selectParentFirst: string;
73
+ yes: string;
74
+ no: string;
75
+ uploading: string;
76
+ chooseFile: string;
77
+ replaceFile: string;
78
+ removeFile: string;
79
+ downloadFile: string;
80
+ noImage: string;
81
+ uploadImage: string;
82
+ changeImage: string;
83
+ month: string;
84
+ year: string;
85
+ write: string;
86
+ preview: string;
87
+ markdownEditorMode: string;
88
+ showPassword: string;
89
+ hidePassword: string;
90
+ lockField: string;
91
+ unlockField: string;
92
+ criticalFieldLockHint: string;
93
+ criticalFieldUnlockHint: string;
94
+ dismissBanner: string;
95
+ jumpToField: string;
96
+ entityLabel: string;
97
+ criticalFieldChanged: string;
98
+ recordModified: string;
99
+ accessDenied: string;
100
+ };
101
+ /**
102
+ * The keys above, as a union. Templates are checked against it, so a mistyped key is an
103
+ * AOT error rather than a blank button, and a host writing overrides gets completion.
104
+ */
105
+ type UiTextKey = keyof typeof DEFAULT_UI_TEXT;
106
+ /**
107
+ * One replacement: a plain string, or the same `LocalizedText` map a config uses for a
108
+ * field label — `{ en: 'Save', de: 'Speichern' }`, resolved against the form's `language`
109
+ * by the very function that resolves the labels beside it.
110
+ */
111
+ type UiTextValue = string | LocalizedText;
112
+ /**
113
+ * Asked for one key at render time, given the English default to fall back on and the
114
+ * form's active language.
115
+ *
116
+ * This is the seam for an existing i18n setup — `$localize`, ngx-translate, Transloco —
117
+ * whose catalogue is language-first (`de.json`) rather than key-first, and which already
118
+ * holds its own idea of the current language. Take `language` or ignore it accordingly.
119
+ */
120
+ type UiTextResolverFor<K extends string> = (key: K, defaultText: string, language: string) => string;
121
+ /** The resolver for this library's own keys. */
122
+ type UiTextResolver = UiTextResolverFor<UiTextKey>;
123
+ /**
124
+ * Values substituted into a `{placeholder}` in the text.
125
+ *
126
+ * A sentence with a name in the middle has to travel as one string: word order moves
127
+ * between languages, so splitting it into fragments around an interpolation produces
128
+ * grammatical nonsense in the ones it was not written for.
129
+ */
130
+ type UiTextParams = Record<string, string | number>;
131
+ /** Either a partial map of replacements, or a resolver that answers per key. */
132
+ type UiTextOverridesFor<K extends string> = Partial<Record<K, UiTextValue>> | UiTextResolverFor<K>;
133
+ /** The overrides for this library's own keys. */
134
+ type UiTextOverrides = UiTextOverridesFor<UiTextKey>;
135
+ /**
136
+ * The resolution rule itself, over any key vocabulary.
137
+ *
138
+ * Exported because the builder package renders a second, disjoint set of words and needs
139
+ * the same rule — overrides first, then the English default, per key, with `{placeholder}`
140
+ * substitution. Sharing the function rather than the vocabulary is what keeps a renderer
141
+ * consumer from seeing a hundred and fifty builder keys in completion.
142
+ */
143
+ declare function resolveUiText<K extends string>(overrides: UiTextOverridesFor<K> | null | undefined, defaults: Readonly<Record<K, string>>, key: K, language: string, params?: UiTextParams): string;
144
+ /**
145
+ * Resolves the library's own UI text, honouring `UI_TEXT` before the defaults.
146
+ *
147
+ * Resolution is per key, not all-or-nothing, so a host replacing three buttons does not
148
+ * have to supply the other thirty — and an override that yields nothing for a key still
149
+ * renders English rather than a gap, which is what a translation catalogue asked for a
150
+ * missing entry typically hands back.
151
+ */
152
+ declare class UiTextService {
153
+ private readonly overrides;
154
+ /**
155
+ * One label by key, in `language`; English if nothing overrides it. `params` fill the
156
+ * `{placeholder}` slots, in whatever position the translation puts them.
157
+ */
158
+ text(key: UiTextKey, language?: string, params?: UiTextParams): string;
159
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiTextService, never>;
160
+ static ɵprov: i0.ɵɵInjectableDeclaration<UiTextService>;
161
+ }
162
+
35
163
  /** Roles that see XXXXXXXXX for masked fields. Presentational only — enforce authz server-side. */
36
164
  declare const MASKED_ROLES: InjectionToken<string[]>;
37
165
  /**
@@ -122,13 +250,18 @@ declare const HOOK_REGISTRY: InjectionToken<Map<string, HookFn>>;
122
250
  * The library ships no built-in implementations. Consumers provide their own list
123
251
  * so the builder's module-picker and the renderer's tab switcher know what's available.
124
252
  *
253
+ * `component` must be the component **class**: it is mounted through `ngComponentOutlet`,
254
+ * which takes a type, not a selector. An entry naming a selector string renders nothing and
255
+ * warns — `COMMON_MODULES` in core is a catalogue of names for the builder's picker, and
256
+ * offering a module the renderer cannot mount is the one way to get this wrong.
257
+ *
125
258
  * @example
126
259
  * providers: [
127
260
  * {
128
261
  * provide: COMMON_MODULES_REGISTRY,
129
262
  * useValue: [
130
- * { id: 'documents', label: { en: 'Documents' }, component: 'app-documents-view' },
131
- * { id: 'audit', label: { en: 'Audit Log' }, component: 'app-audit' },
263
+ * { id: 'documents', label: { en: 'Documents' }, component: DocumentsViewComponent },
264
+ * { id: 'audit', label: { en: 'Audit Log' }, component: AuditLogComponent },
132
265
  * ] satisfies CommonModuleEntry[]
133
266
  * }
134
267
  * ]
@@ -182,6 +315,54 @@ declare const CONFIG_SOURCE: InjectionToken<ConfigSourceHandler>;
182
315
  * { provide: MARKDOWN_RENDERER, useValue: (src: string) => marked.parse(src) as string }
183
316
  */
184
317
  declare const MARKDOWN_RENDERER: InjectionToken<(source: string) => string>;
318
+ /**
319
+ * The text a masked field shows in place of its value. Defaults to `XXXXXXXXX`.
320
+ *
321
+ * Masking is presentational — see SECURITY.md — and what it prints is a product decision:
322
+ * `••••••••` reads as a redaction, "Hidden" reads as a permission, and a localized string
323
+ * reads as neither in English. It was a literal repeated across every field component, so
324
+ * there was no way to choose.
325
+ *
326
+ * @example
327
+ * { provide: MASKED_PLACEHOLDER, useValue: '••••••••' }
328
+ */
329
+ declare const MASKED_PLACEHOLDER: InjectionToken<string>;
330
+ /**
331
+ * Overrides for the library's own chrome — Save, Reset, "No rows yet.", and the rest.
332
+ *
333
+ * Field labels and options come from the config as `LocalizedText` and already follow the
334
+ * form's `language`. This is the text *around* them, which was English literals in the
335
+ * templates: an application in German rendered German labels around English buttons.
336
+ *
337
+ * The library does no translating — it publishes the keys it renders and resolves whatever
338
+ * a host hands back. `DEFAULT_UI_TEXT` is the full list of keys with their English source
339
+ * strings, so a translation file can be generated from it rather than transcribed. Anything
340
+ * left out keeps its English default.
341
+ *
342
+ * @example The config's own shape — `LocalizedText` per key, resolved against `language`
343
+ * {
344
+ * provide: UI_TEXT,
345
+ * useValue: {
346
+ * save: { en: 'Save', de: 'Speichern' },
347
+ * reset: { en: 'Reset', de: 'Zurücksetzen' },
348
+ * },
349
+ * }
350
+ *
351
+ * @example One language, or a host that re-provides on switch
352
+ * { provide: UI_TEXT, useValue: { save: 'Speichern', reset: 'Zurücksetzen' } }
353
+ *
354
+ * @example An existing i18n layer (ngx-translate, Transloco, $localize)
355
+ * {
356
+ * provide: UI_TEXT,
357
+ * useFactory: () => {
358
+ * const translate = inject(TranslateService);
359
+ * return (key, defaultText) => translate.instant(`dynamicEntity.${key}`) || defaultText;
360
+ * },
361
+ * }
362
+ *
363
+ * A resolver is read during change detection, so it must be synchronous and cheap.
364
+ */
365
+ declare const UI_TEXT: InjectionToken<UiTextOverrides>;
185
366
 
186
367
  interface NgxDynamicEntityConfig {
187
368
  /** Roles that see masked field values as XXXXXXXXX */
@@ -205,6 +386,14 @@ interface NgxDynamicEntityConfig {
205
386
  * Unlisted keys keep their English default.
206
387
  */
207
388
  validationMessages?: Record<string, string | ((language: string, error: any) => string)>;
389
+ /**
390
+ * Override the library's own chrome — Save, Reset, "No rows yet.". Either a partial map
391
+ * keyed by `UiTextKey`, whose values are strings or the same `LocalizedText` a field label
392
+ * uses (`{ en, de }`, resolved against the form's `language`), or a resolver
393
+ * `(key, defaultText, language) => string` that hands the key to an existing i18n layer.
394
+ * `DEFAULT_UI_TEXT` lists every key with its English source string; unlisted keys keep it.
395
+ */
396
+ uiText?: UiTextOverrides;
208
397
  /**
209
398
  * Async validator functions keyed by name, for checks that need a server — uniqueness,
210
399
  * availability, a remote rule. Name them from a schema with
@@ -665,6 +854,8 @@ declare class ValidationMessagesService {
665
854
  * keyboard shortcuts (Ctrl+S, Esc), and RBAC-gated submission.
666
855
  */
667
856
  declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
857
+ /** Library chrome, overridable via UI_TEXT. */
858
+ protected readonly ui: UiTextService;
668
859
  /**
669
860
  * The schema to render.
670
861
  *
@@ -761,7 +952,21 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
761
952
  get activeTabConfig(): NestedTabConfig | null;
762
953
  get visibleSubTabs(): NestedTabConfig[];
763
954
  get activeSubTabConfig(): NestedTabConfig | null;
955
+ /**
956
+ * The component to mount for the active tab, or `null` if there is nothing to mount.
957
+ *
958
+ * A registry entry may name its component with a **selector string** — `COMMON_MODULES`
959
+ * is a catalogue of names for the builder's picker, and the token's own example showed
960
+ * one. `ngComponentOutlet` mounts a component *type*, so a string reached it and Angular
961
+ * threw an assertion the moment somebody opened that tab. Following the documented shape
962
+ * broke the feature, which is worse than the feature not existing.
963
+ *
964
+ * A string now resolves to nothing renderable and says why, once per module.
965
+ */
764
966
  get activeTabModuleComponent(): any | null;
967
+ /** Warned once per module id, because a getter runs on every change-detection pass. */
968
+ private readonly warnedSelectorModules;
969
+ private warnSelectorModule;
765
970
  get fieldsForActiveTab(): NestedFieldConfig[];
766
971
  /**
767
972
  * Entity-level permissions for the current roles.
@@ -850,6 +1055,14 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
850
1055
  isFieldReadonly(field: NestedFieldConfig): boolean;
851
1056
  toggleFieldLock(field: NestedFieldConfig): void;
852
1057
  resolveFieldLabel(field: NestedFieldConfig): string;
1058
+ /**
1059
+ * The changed critical fields as one comma-separated string.
1060
+ *
1061
+ * Joined here rather than looped in the template because the banner is a sentence with the
1062
+ * list inside it, and a sentence has to reach `UI_TEXT` whole — a translation moves the
1063
+ * list somewhere else in the clause.
1064
+ */
1065
+ changedCriticalFieldLabels(): string;
853
1066
  private buildForm;
854
1067
  private buildFieldControl;
855
1068
  /** One row of an `array` field: a FormGroup when the field declares columns, else a bare control. */
@@ -1009,6 +1222,8 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1009
1222
  * interactive quick-jump links, and baseline modification tracking.
1010
1223
  */
1011
1224
  declare class DynamicRecordFormComponent implements OnChanges {
1225
+ /** Library chrome, overridable via UI_TEXT. */
1226
+ protected readonly ui: UiTextService;
1012
1227
  config: EntityFormConfig;
1013
1228
  rules?: FormRule[];
1014
1229
  initialData?: Record<string, any>;
@@ -1185,6 +1400,8 @@ declare class DynamicRecordFormComponent implements OnChanges {
1185
1400
  onFormSubmit(data: Record<string, any>): void;
1186
1401
  onFormReset(): void;
1187
1402
  formatFieldLabel(field: NestedFieldConfig): string;
1403
+ /** "Add <field> row" / "Edit <field> row" — one key each, because word order moves. */
1404
+ rowDrawerTitle(field: NestedFieldConfig): string;
1188
1405
  /** Summary values render through the shared core formatter, not a local stringifier. */
1189
1406
  formatFieldValue(field: NestedFieldConfig): string;
1190
1407
  /**
@@ -1318,6 +1535,12 @@ declare class DynamicFieldComponent implements OnChanges, OnDestroy {
1318
1535
  * - `masked` means the value must not be displayed. Render a placeholder rather than the
1319
1536
  * control's value. This is presentational: the real value stays in the control and is
1320
1537
  * included in the submitted record, so it is not an access-control boundary.
1538
+ * - If you emit a DOM `id` — for a `<label for>`, or an `aria-describedby` — do not build it
1539
+ * from `field.id` alone. An `array` renders the same field once per row, so `field.id` is
1540
+ * unique in a config and not in a document, and `for` resolves to the first match on the
1541
+ * page. `nextFieldInstanceId()` and `fieldDomId()` are what the built-in types use; a
1542
+ * counter of your own does just as well. Address controls in tests through `data-testid`
1543
+ * or their label, never through these ids.
1321
1544
  */
1322
1545
  interface DynamicFieldComponentContract {
1323
1546
  /** The field's schema entry: id, type, label, validators, options, and so on. */
@@ -1332,7 +1555,28 @@ interface DynamicFieldComponentContract {
1332
1555
  masked: boolean;
1333
1556
  }
1334
1557
 
1558
+ /** A token unique to one component instance, for the lifetime of the page. */
1559
+ declare function nextFieldInstanceId(): string;
1560
+ /**
1561
+ * `{fieldId}-{instance}{suffix}` — the field first, so the id still reads as the field it
1562
+ * belongs to when someone is looking at the DOM.
1563
+ *
1564
+ * `field` is undefined until the renderer assigns it, and a template can be checked once
1565
+ * before that happens.
1566
+ */
1567
+ declare function fieldDomId(field: {
1568
+ id?: string;
1569
+ } | undefined, instance: string, suffix?: string): string;
1570
+
1335
1571
  declare class TextFieldComponent implements OnDestroy {
1572
+ /**
1573
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1574
+ * DOM id may not repeat. See `field-dom-id.ts`.
1575
+ */
1576
+ private readonly instanceId;
1577
+ protected domId(suffix?: string): string;
1578
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1579
+ protected readonly maskedText: string;
1336
1580
  private readonly messages;
1337
1581
  private displaySub?;
1338
1582
  field: NestedFieldConfig;
@@ -1353,6 +1597,15 @@ declare class TextFieldComponent implements OnDestroy {
1353
1597
  }
1354
1598
 
1355
1599
  declare class TextareaFieldComponent {
1600
+ /**
1601
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1602
+ * DOM id may not repeat. See `field-dom-id.ts`.
1603
+ */
1604
+ private readonly instanceId;
1605
+ protected domId(suffix?: string): string;
1606
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1607
+ protected readonly maskedText: string;
1608
+ private readonly messages;
1356
1609
  field: NestedFieldConfig;
1357
1610
  control: AbstractControl;
1358
1611
  language: string;
@@ -1360,6 +1613,13 @@ declare class TextareaFieldComponent {
1360
1613
  masked: boolean;
1361
1614
  get label(): string;
1362
1615
  get placeholder(): string;
1616
+ /**
1617
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1618
+ * validationMessages })` reaches this field. It used to render a fixed
1619
+ * "This field has an error", which made a documented, configurable feature work on three
1620
+ * of fifteen field types.
1621
+ */
1622
+ get errorMessage(): string;
1363
1623
  static ɵfac: i0.ɵɵFactoryDeclaration<TextareaFieldComponent, never>;
1364
1624
  static ɵcmp: i0.ɵɵComponentDeclaration<TextareaFieldComponent, "ngx-textarea-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1365
1625
  }
@@ -1381,6 +1641,17 @@ declare class TextareaFieldComponent {
1381
1641
  * the token's own note on why that is a backstop rather than a licence.
1382
1642
  */
1383
1643
  declare class MarkdownFieldComponent implements OnChanges {
1644
+ /**
1645
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1646
+ * DOM id may not repeat. See `field-dom-id.ts`.
1647
+ */
1648
+ private readonly instanceId;
1649
+ protected domId(suffix?: string): string;
1650
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1651
+ protected readonly maskedText: string;
1652
+ private readonly messages;
1653
+ /** Library chrome, overridable via UI_TEXT. */
1654
+ protected readonly ui: UiTextService;
1384
1655
  field: NestedFieldConfig;
1385
1656
  control: AbstractControl;
1386
1657
  language: string;
@@ -1414,11 +1685,26 @@ declare class MarkdownFieldComponent implements OnChanges {
1414
1685
  * source text — which is what the field would have shown with no renderer at all.
1415
1686
  */
1416
1687
  protected rendered(): string | null;
1688
+ /**
1689
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1690
+ * validationMessages })` reaches this field. It used to render a fixed
1691
+ * "This field has an error", which made a documented, configurable feature work on three
1692
+ * of fifteen field types.
1693
+ */
1694
+ get errorMessage(): string;
1417
1695
  static ɵfac: i0.ɵɵFactoryDeclaration<MarkdownFieldComponent, never>;
1418
1696
  static ɵcmp: i0.ɵɵComponentDeclaration<MarkdownFieldComponent, "ngx-markdown-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1419
1697
  }
1420
1698
 
1421
1699
  declare class NumberFieldComponent {
1700
+ /**
1701
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1702
+ * DOM id may not repeat. See `field-dom-id.ts`.
1703
+ */
1704
+ private readonly instanceId;
1705
+ protected domId(suffix?: string): string;
1706
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1707
+ protected readonly maskedText: string;
1422
1708
  private readonly messages;
1423
1709
  field: NestedFieldConfig;
1424
1710
  control: AbstractControl;
@@ -1434,6 +1720,15 @@ declare class NumberFieldComponent {
1434
1720
 
1435
1721
  /** Currency field: number input with locale-aware currency symbol prefix. */
1436
1722
  declare class CurrencyFieldComponent {
1723
+ /**
1724
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1725
+ * DOM id may not repeat. See `field-dom-id.ts`.
1726
+ */
1727
+ private readonly instanceId;
1728
+ protected domId(suffix?: string): string;
1729
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1730
+ protected readonly maskedText: string;
1731
+ private readonly messages;
1437
1732
  field: NestedFieldConfig;
1438
1733
  control: AbstractControl;
1439
1734
  language: string;
@@ -1443,12 +1738,28 @@ declare class CurrencyFieldComponent {
1443
1738
  get placeholder(): string;
1444
1739
  /** Picks the currency symbol from the locale — defaults to '$'. */
1445
1740
  get symbol(): string;
1741
+ /**
1742
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1743
+ * validationMessages })` reaches this field. It used to render a fixed
1744
+ * "This field has an error", which made a documented, configurable feature work on three
1745
+ * of fifteen field types.
1746
+ */
1747
+ get errorMessage(): string;
1446
1748
  static ɵfac: i0.ɵɵFactoryDeclaration<CurrencyFieldComponent, never>;
1447
1749
  static ɵcmp: i0.ɵɵComponentDeclaration<CurrencyFieldComponent, "ngx-currency-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1448
1750
  }
1449
1751
 
1450
1752
  /** Email field: type="email" input with inline validation hint. */
1451
1753
  declare class EmailFieldComponent {
1754
+ /**
1755
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1756
+ * DOM id may not repeat. See `field-dom-id.ts`.
1757
+ */
1758
+ private readonly instanceId;
1759
+ protected domId(suffix?: string): string;
1760
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1761
+ protected readonly maskedText: string;
1762
+ private readonly messages;
1452
1763
  field: NestedFieldConfig;
1453
1764
  control: AbstractControl;
1454
1765
  language: string;
@@ -1456,12 +1767,30 @@ declare class EmailFieldComponent {
1456
1767
  masked: boolean;
1457
1768
  get label(): string;
1458
1769
  get placeholder(): string;
1770
+ /**
1771
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1772
+ * validationMessages })` reaches this field. It used to render a fixed
1773
+ * "This field has an error", which made a documented, configurable feature work on three
1774
+ * of fifteen field types.
1775
+ */
1776
+ get errorMessage(): string;
1459
1777
  static ɵfac: i0.ɵɵFactoryDeclaration<EmailFieldComponent, never>;
1460
1778
  static ɵcmp: i0.ɵɵComponentDeclaration<EmailFieldComponent, "ngx-email-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1461
1779
  }
1462
1780
 
1463
1781
  /** Password field: masked input with show/hide eye toggle. */
1464
1782
  declare class PasswordFieldComponent {
1783
+ /**
1784
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1785
+ * DOM id may not repeat. See `field-dom-id.ts`.
1786
+ */
1787
+ private readonly instanceId;
1788
+ protected domId(suffix?: string): string;
1789
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1790
+ protected readonly maskedText: string;
1791
+ private readonly messages;
1792
+ /** Library chrome, overridable via UI_TEXT. */
1793
+ protected readonly ui: UiTextService;
1465
1794
  field: NestedFieldConfig;
1466
1795
  control: AbstractControl;
1467
1796
  language: string;
@@ -1471,17 +1800,42 @@ declare class PasswordFieldComponent {
1471
1800
  get label(): string;
1472
1801
  get placeholder(): string;
1473
1802
  toggleVisibility(): void;
1803
+ /**
1804
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1805
+ * validationMessages })` reaches this field. It used to render a fixed
1806
+ * "This field has an error", which made a documented, configurable feature work on three
1807
+ * of fifteen field types.
1808
+ */
1809
+ get errorMessage(): string;
1474
1810
  static ɵfac: i0.ɵɵFactoryDeclaration<PasswordFieldComponent, never>;
1475
1811
  static ɵcmp: i0.ɵɵComponentDeclaration<PasswordFieldComponent, "ngx-password-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1476
1812
  }
1477
1813
 
1478
1814
  declare class CheckboxFieldComponent {
1815
+ /**
1816
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1817
+ * DOM id may not repeat. See `field-dom-id.ts`.
1818
+ */
1819
+ private readonly instanceId;
1820
+ protected domId(suffix?: string): string;
1821
+ /** Library chrome, overridable via UI_TEXT. */
1822
+ protected readonly ui: UiTextService;
1823
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1824
+ protected readonly maskedText: string;
1825
+ private readonly messages;
1479
1826
  field: NestedFieldConfig;
1480
1827
  control: AbstractControl;
1481
1828
  language: string;
1482
1829
  readonly: boolean;
1483
1830
  masked: boolean;
1484
1831
  get label(): string;
1832
+ /**
1833
+ * Configured messages reach this field too.
1834
+ *
1835
+ * It rendered no error element at all, so a required checkbox left unticked told the user
1836
+ * nothing — and `validationMessages` could not reach a field that never displayed one.
1837
+ */
1838
+ get errorMessage(): string;
1485
1839
  static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxFieldComponent, never>;
1486
1840
  static ɵcmp: i0.ɵɵComponentDeclaration<CheckboxFieldComponent, "ngx-checkbox-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1487
1841
  }
@@ -1492,17 +1846,38 @@ declare class CheckboxFieldComponent {
1492
1846
  * toggle switch with Yes/No labels for clearer binary state communication.
1493
1847
  */
1494
1848
  declare class BooleanFieldComponent {
1849
+ /** Library chrome, overridable via UI_TEXT. */
1850
+ protected readonly ui: UiTextService;
1851
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1852
+ protected readonly maskedText: string;
1853
+ private readonly messages;
1495
1854
  field: NestedFieldConfig;
1496
1855
  control: AbstractControl;
1497
1856
  language: string;
1498
1857
  readonly: boolean;
1499
1858
  masked: boolean;
1500
1859
  get label(): string;
1860
+ /**
1861
+ * Configured messages reach this field too.
1862
+ *
1863
+ * It rendered no error element at all, so a required checkbox left unticked told the user
1864
+ * nothing — and `validationMessages` could not reach a field that never displayed one.
1865
+ */
1866
+ get errorMessage(): string;
1501
1867
  static ɵfac: i0.ɵɵFactoryDeclaration<BooleanFieldComponent, never>;
1502
1868
  static ɵcmp: i0.ɵɵComponentDeclaration<BooleanFieldComponent, "ngx-boolean-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1503
1869
  }
1504
1870
 
1505
1871
  declare class DateFieldComponent {
1872
+ /**
1873
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1874
+ * DOM id may not repeat. See `field-dom-id.ts`.
1875
+ */
1876
+ private readonly instanceId;
1877
+ protected domId(suffix?: string): string;
1878
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1879
+ protected readonly maskedText: string;
1880
+ private readonly messages;
1506
1881
  field: NestedFieldConfig;
1507
1882
  control: AbstractControl;
1508
1883
  language: string;
@@ -1511,6 +1886,13 @@ declare class DateFieldComponent {
1511
1886
  get label(): string;
1512
1887
  /** ISO 8601 date → locale display string (ONEHERMES convention: always UTC, display in user locale) */
1513
1888
  formatDate(value: string | null): string;
1889
+ /**
1890
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1891
+ * validationMessages })` reaches this field. It used to render a fixed
1892
+ * "This field has an error", which made a documented, configurable feature work on three
1893
+ * of fifteen field types.
1894
+ */
1895
+ get errorMessage(): string;
1514
1896
  static ɵfac: i0.ɵɵFactoryDeclaration<DateFieldComponent, never>;
1515
1897
  static ɵcmp: i0.ɵɵComponentDeclaration<DateFieldComponent, "ngx-date-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1516
1898
  }
@@ -1523,6 +1905,15 @@ declare class DateFieldComponent {
1523
1905
  * conversions here are what keep a value stable across a round trip.
1524
1906
  */
1525
1907
  declare class DateTimeFieldComponent {
1908
+ /**
1909
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1910
+ * DOM id may not repeat. See `field-dom-id.ts`.
1911
+ */
1912
+ private readonly instanceId;
1913
+ protected domId(suffix?: string): string;
1914
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1915
+ protected readonly maskedText: string;
1916
+ private readonly messages;
1526
1917
  field: NestedFieldConfig;
1527
1918
  control: AbstractControl;
1528
1919
  language: string;
@@ -1539,6 +1930,13 @@ declare class DateTimeFieldComponent {
1539
1930
  * summary — which goes through core's `formatDisplayValue` — showed it.
1540
1931
  */
1541
1932
  formatDateTime(value: unknown): string;
1933
+ /**
1934
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1935
+ * validationMessages })` reaches this field. It used to render a fixed
1936
+ * "This field has an error", which made a documented, configurable feature work on three
1937
+ * of fifteen field types.
1938
+ */
1939
+ get errorMessage(): string;
1542
1940
  static ɵfac: i0.ɵɵFactoryDeclaration<DateTimeFieldComponent, never>;
1543
1941
  static ɵcmp: i0.ɵɵComponentDeclaration<DateTimeFieldComponent, "ngx-date-time-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1544
1942
  }
@@ -1552,6 +1950,15 @@ declare class DateTimeFieldComponent {
1552
1950
  * and converting it to UTC would move it whenever the offset changed.
1553
1951
  */
1554
1952
  declare class TimeFieldComponent {
1953
+ /**
1954
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1955
+ * DOM id may not repeat. See `field-dom-id.ts`.
1956
+ */
1957
+ private readonly instanceId;
1958
+ protected domId(suffix?: string): string;
1959
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1960
+ protected readonly maskedText: string;
1961
+ private readonly messages;
1555
1962
  field: NestedFieldConfig;
1556
1963
  control: AbstractControl;
1557
1964
  language: string;
@@ -1564,6 +1971,13 @@ declare class TimeFieldComponent {
1564
1971
  * another in the record summary because the two drifted apart.
1565
1972
  */
1566
1973
  formatTime(value: unknown): string;
1974
+ /**
1975
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
1976
+ * validationMessages })` reaches this field. It used to render a fixed
1977
+ * "This field has an error", which made a documented, configurable feature work on three
1978
+ * of fifteen field types.
1979
+ */
1980
+ get errorMessage(): string;
1567
1981
  static ɵfac: i0.ɵɵFactoryDeclaration<TimeFieldComponent, never>;
1568
1982
  static ɵcmp: i0.ɵɵComponentDeclaration<TimeFieldComponent, "ngx-time-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1569
1983
  }
@@ -1573,6 +1987,17 @@ declare class TimeFieldComponent {
1573
1987
  * Value stored as ISO partial date string "YYYY-MM" for unambiguous storage.
1574
1988
  */
1575
1989
  declare class MonthYearFieldComponent {
1990
+ /**
1991
+ * Unique to this component instance: an `array` renders the same field once per row, and a
1992
+ * DOM id may not repeat. See `field-dom-id.ts`.
1993
+ */
1994
+ private readonly instanceId;
1995
+ protected domId(suffix?: string): string;
1996
+ /** Library chrome, overridable via UI_TEXT. */
1997
+ protected readonly ui: UiTextService;
1998
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
1999
+ protected readonly maskedText: string;
2000
+ private readonly messages;
1576
2001
  field: NestedFieldConfig;
1577
2002
  control: AbstractControl;
1578
2003
  language: string;
@@ -1590,11 +2015,28 @@ declare class MonthYearFieldComponent {
1590
2015
  onMonthChange(month: string): void;
1591
2016
  onYearChange(year: string): void;
1592
2017
  formatValue(value: unknown): string;
2018
+ /**
2019
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2020
+ * validationMessages })` reaches this field. It used to render a fixed
2021
+ * "This field has an error", which made a documented, configurable feature work on three
2022
+ * of fifteen field types.
2023
+ */
2024
+ get errorMessage(): string;
1593
2025
  static ɵfac: i0.ɵɵFactoryDeclaration<MonthYearFieldComponent, never>;
1594
2026
  static ɵcmp: i0.ɵɵComponentDeclaration<MonthYearFieldComponent, "ngx-month-year-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1595
2027
  }
1596
2028
 
1597
2029
  declare class DropdownFieldComponent {
2030
+ /**
2031
+ * Unique to this component instance: an `array` renders the same field once per row, and a
2032
+ * DOM id may not repeat. See `field-dom-id.ts`.
2033
+ */
2034
+ private readonly instanceId;
2035
+ protected domId(suffix?: string): string;
2036
+ /** Library chrome, overridable via UI_TEXT. */
2037
+ protected readonly ui: UiTextService;
2038
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2039
+ protected readonly maskedText: string;
1598
2040
  private readonly lookups;
1599
2041
  private readonly messages;
1600
2042
  private _field;
@@ -1628,6 +2070,15 @@ declare class DropdownFieldComponent {
1628
2070
 
1629
2071
  /** Radio field: a group of radio buttons built from field.options. */
1630
2072
  declare class RadioFieldComponent {
2073
+ /**
2074
+ * Unique to this component instance: an `array` renders the same field once per row, and a
2075
+ * DOM id may not repeat. See `field-dom-id.ts`.
2076
+ */
2077
+ private readonly instanceId;
2078
+ protected domId(suffix?: string): string;
2079
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2080
+ protected readonly maskedText: string;
2081
+ private readonly messages;
1631
2082
  private readonly lookups;
1632
2083
  private _field;
1633
2084
  private _language;
@@ -1649,15 +2100,39 @@ declare class RadioFieldComponent {
1649
2100
  * into an id attribute.
1650
2101
  */
1651
2102
  getRadioId(option: DropdownOption): string;
2103
+ /**
2104
+ * The option's part of an id or a test hook.
2105
+ *
2106
+ * `??` cannot fire here: `resolveOptionValue` returns '' for an empty option, not null, so
2107
+ * every valueless option produced the same slug — and two radios sharing an id break the
2108
+ * `for` that ties each label to its input.
2109
+ */
2110
+ optionSlug(option: DropdownOption): string;
1652
2111
  getOptVal(option: DropdownOption): string | number | boolean;
1653
2112
  getOptLabel(option: DropdownOption): string;
1654
2113
  /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */
1655
2114
  getSelectedLabel(): string;
2115
+ /**
2116
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2117
+ * validationMessages })` reaches this field. It used to render a fixed
2118
+ * "This field has an error", which made a documented, configurable feature work on three
2119
+ * of fifteen field types.
2120
+ */
2121
+ get errorMessage(): string;
1656
2122
  static ɵfac: i0.ɵɵFactoryDeclaration<RadioFieldComponent, never>;
1657
2123
  static ɵcmp: i0.ɵɵComponentDeclaration<RadioFieldComponent, "ngx-radio-field", never, { "field": { "alias": "field"; "required": false; }; "language": { "alias": "language"; "required": false; }; "control": { "alias": "control"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1658
2124
  }
1659
2125
 
1660
2126
  declare class MultiSelectFieldComponent {
2127
+ /**
2128
+ * Unique to this component instance: an `array` renders the same field once per row, and a
2129
+ * DOM id may not repeat. See `field-dom-id.ts`.
2130
+ */
2131
+ private readonly instanceId;
2132
+ protected domId(suffix?: string): string;
2133
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2134
+ protected readonly maskedText: string;
2135
+ private readonly messages;
1661
2136
  private readonly lookups;
1662
2137
  private _field;
1663
2138
  private _language;
@@ -1678,6 +2153,13 @@ declare class MultiSelectFieldComponent {
1678
2153
  getOptLabel(option: DropdownOption): string;
1679
2154
  /** Read-only display — synchronous, per §6.2. See `DropdownFieldComponent.getLabel`. */
1680
2155
  getLabels(values: unknown): string;
2156
+ /**
2157
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2158
+ * validationMessages })` reaches this field. It used to render a fixed
2159
+ * "This field has an error", which made a documented, configurable feature work on three
2160
+ * of fifteen field types.
2161
+ */
2162
+ get errorMessage(): string;
1681
2163
  static ɵfac: i0.ɵɵFactoryDeclaration<MultiSelectFieldComponent, never>;
1682
2164
  static ɵcmp: i0.ɵɵComponentDeclaration<MultiSelectFieldComponent, "ngx-multi-select-field", never, { "field": { "alias": "field"; "required": false; }; "language": { "alias": "language"; "required": false; }; "control": { "alias": "control"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1683
2165
  }
@@ -1691,6 +2173,17 @@ declare class MultiSelectFieldComponent {
1691
2173
  * `EntityRefSelectionService` so the owning form can run `autoPatch`.
1692
2174
  */
1693
2175
  declare class EntityRefFieldComponent implements OnInit {
2176
+ /**
2177
+ * Unique to this component instance: an `array` renders the same field once per row, and a
2178
+ * DOM id may not repeat. See `field-dom-id.ts`.
2179
+ */
2180
+ private readonly instanceId;
2181
+ protected domId(suffix?: string): string;
2182
+ /** Library chrome, overridable via UI_TEXT. */
2183
+ protected readonly ui: UiTextService;
2184
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2185
+ protected readonly maskedText: string;
2186
+ private readonly messages;
1694
2187
  field: NestedFieldConfig;
1695
2188
  control: AbstractControl;
1696
2189
  language: string;
@@ -1724,12 +2217,21 @@ declare class EntityRefFieldComponent implements OnInit {
1724
2217
  private parentValue;
1725
2218
  /** Reload (and drop a stale selection) whenever the parent control changes. */
1726
2219
  private watchParent;
2220
+ /**
2221
+ * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
2222
+ * validationMessages })` reaches this field. It used to render a fixed
2223
+ * "This field has an error", which made a documented, configurable feature work on three
2224
+ * of fifteen field types.
2225
+ */
2226
+ get errorMessage(): string;
1727
2227
  static ɵfac: i0.ɵɵFactoryDeclaration<EntityRefFieldComponent, never>;
1728
2228
  static ɵcmp: i0.ɵɵComponentDeclaration<EntityRefFieldComponent, "ngx-entity-ref-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1729
2229
  }
1730
2230
 
1731
2231
  /** Renders a nested fieldset container for a group field's children. */
1732
2232
  declare class GroupFieldComponent {
2233
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2234
+ protected readonly maskedText: string;
1733
2235
  field: NestedFieldConfig;
1734
2236
  control: AbstractControl;
1735
2237
  config: EntityFormConfig;
@@ -1745,6 +2247,10 @@ declare class GroupFieldComponent {
1745
2247
 
1746
2248
  /** Renders repeating rows for a FormArray, with Add Item and Remove. */
1747
2249
  declare class ArrayFieldComponent {
2250
+ /** Library chrome, overridable via UI_TEXT. */
2251
+ protected readonly ui: UiTextService;
2252
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2253
+ protected readonly maskedText: string;
1748
2254
  /**
1749
2255
  * addItem/removeItem are public and may be called from outside this component's template,
1750
2256
  * which under OnPush would not re-render. The host also watches the control, but this
@@ -1776,6 +2282,17 @@ declare class ArrayFieldComponent {
1776
2282
  * it is stored as `{ file }` and previewed from an object URL (revoked when replaced/destroyed).
1777
2283
  */
1778
2284
  declare class ImageFieldComponent implements OnDestroy {
2285
+ /**
2286
+ * Unique to this component instance: an `array` renders the same field once per row, and a
2287
+ * DOM id may not repeat. See `field-dom-id.ts`.
2288
+ */
2289
+ private readonly instanceId;
2290
+ protected domId(suffix?: string): string;
2291
+ /** Library chrome, overridable via UI_TEXT. */
2292
+ protected readonly ui: UiTextService;
2293
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2294
+ protected readonly maskedText: string;
2295
+ private readonly messages;
1779
2296
  field: NestedFieldConfig;
1780
2297
  control: AbstractControl;
1781
2298
  language: string;
@@ -1792,6 +2309,8 @@ declare class ImageFieldComponent implements OnDestroy {
1792
2309
  onFileSelect(file: File | undefined): Promise<void>;
1793
2310
  remove(): void;
1794
2311
  ngOnDestroy(): void;
2312
+ /** Validation, as distinct from the upload failures this field already reported. */
2313
+ get errorMessage(): string;
1795
2314
  static ɵfac: i0.ɵɵFactoryDeclaration<ImageFieldComponent, never>;
1796
2315
  static ɵcmp: i0.ɵɵComponentDeclaration<ImageFieldComponent, "ngx-image-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1797
2316
  }
@@ -1801,6 +2320,17 @@ declare class ImageFieldComponent implements OnDestroy {
1801
2320
  * Shares the `FileRef` / `UPLOAD_HANDLER` contract with image-field via FileUploadService.
1802
2321
  */
1803
2322
  declare class FileFieldComponent {
2323
+ /**
2324
+ * Unique to this component instance: an `array` renders the same field once per row, and a
2325
+ * DOM id may not repeat. See `field-dom-id.ts`.
2326
+ */
2327
+ private readonly instanceId;
2328
+ protected domId(suffix?: string): string;
2329
+ /** Library chrome, overridable via UI_TEXT. */
2330
+ protected readonly ui: UiTextService;
2331
+ /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
2332
+ protected readonly maskedText: string;
2333
+ private readonly messages;
1804
2334
  field: NestedFieldConfig;
1805
2335
  control: AbstractControl;
1806
2336
  language: string;
@@ -1815,9 +2345,11 @@ declare class FileFieldComponent {
1815
2345
  fileName(): string | null;
1816
2346
  onFileSelect(file: File | undefined): Promise<void>;
1817
2347
  remove(): void;
2348
+ /** Validation, as distinct from the upload failures this field already reported. */
2349
+ get errorMessage(): string;
1818
2350
  static ɵfac: i0.ɵɵFactoryDeclaration<FileFieldComponent, never>;
1819
2351
  static ɵcmp: i0.ɵɵComponentDeclaration<FileFieldComponent, "ngx-file-field", never, { "field": { "alias": "field"; "required": false; }; "control": { "alias": "control"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "masked": { "alias": "masked"; "required": false; }; }, {}, never, never, true, never>;
1820
2352
  }
1821
2353
 
1822
- export { ASYNC_VALIDATOR_REGISTRY, ArrayFieldComponent, BooleanFieldComponent, COMMON_MODULES_REGISTRY, CONFIG_SOURCE, CascadeDataService, CheckboxFieldComponent, ConfigSourceService, CurrencyFieldComponent, DEFAULT_VALIDATION_MESSAGES, DateFieldComponent, DateTimeFieldComponent, DropdownFieldComponent, DynamicFieldComponent, DynamicFormComponent, DynamicRecordFormComponent, ENTITY_REF_CACHE_STORE, ENTITY_REF_REGISTRY, EmailFieldComponent, EntityRefFieldComponent, EntityRefRegistryService, EntityRefSelectionService, EntityReferenceService, FIELD_TYPE_REGISTRY, FIELD_TYPE_SETS, FieldRegistryService, FileFieldComponent, GroupFieldComponent, HOOK_REGISTRY, HookRegistryService, ImageFieldComponent, InMemoryEntityRefCacheStore, LOOKUP_REGISTRY, LookupRegistryService, MARKDOWN_RENDERER, MASKED_ROLES, MarkdownFieldComponent, MonthYearFieldComponent, MultiSelectFieldComponent, NumberFieldComponent, PasswordFieldComponent, RECORD_MIGRATIONS, RadioFieldComponent, RbacService, RulesEvaluationService, SYSTEM_DEFAULT_CAN_EDIT, TextFieldComponent, TextareaFieldComponent, TimeFieldComponent, UPLOAD_HANDLER, VALIDATION_MESSAGES, VALIDATOR_REGISTRY, ValidationMessagesService, ValidatorRegistryService, builtInFieldTypes, provideBuiltInFieldTypes, provideFieldTypes, provideNgxDynamicEntity, refreshChoiceOptions };
1823
- export type { ChoiceOptionHost, ConfigSourceHandler, DynamicFieldComponentContract, EntityRefCacheStore, EntityRefSelection, HookFn, NgxDynamicEntityConfig, ValidationMessage };
2354
+ export { ASYNC_VALIDATOR_REGISTRY, ArrayFieldComponent, BooleanFieldComponent, COMMON_MODULES_REGISTRY, CONFIG_SOURCE, CascadeDataService, CheckboxFieldComponent, ConfigSourceService, CurrencyFieldComponent, DEFAULT_UI_TEXT, DEFAULT_VALIDATION_MESSAGES, DateFieldComponent, DateTimeFieldComponent, DropdownFieldComponent, DynamicFieldComponent, DynamicFormComponent, DynamicRecordFormComponent, ENTITY_REF_CACHE_STORE, ENTITY_REF_REGISTRY, EmailFieldComponent, EntityRefFieldComponent, EntityRefRegistryService, EntityRefSelectionService, EntityReferenceService, FIELD_TYPE_REGISTRY, FIELD_TYPE_SETS, FieldRegistryService, FileFieldComponent, GroupFieldComponent, HOOK_REGISTRY, HookRegistryService, ImageFieldComponent, InMemoryEntityRefCacheStore, LOOKUP_REGISTRY, LookupRegistryService, MARKDOWN_RENDERER, MASKED_PLACEHOLDER, MASKED_ROLES, MarkdownFieldComponent, MonthYearFieldComponent, MultiSelectFieldComponent, NumberFieldComponent, PasswordFieldComponent, RECORD_MIGRATIONS, RadioFieldComponent, RbacService, RulesEvaluationService, SYSTEM_DEFAULT_CAN_EDIT, TextFieldComponent, TextareaFieldComponent, TimeFieldComponent, UI_TEXT, UPLOAD_HANDLER, UiTextService, VALIDATION_MESSAGES, VALIDATOR_REGISTRY, ValidationMessagesService, ValidatorRegistryService, builtInFieldTypes, fieldDomId, nextFieldInstanceId, provideBuiltInFieldTypes, provideFieldTypes, provideNgxDynamicEntity, refreshChoiceOptions, resolveUiText };
2355
+ export type { ChoiceOptionHost, ConfigSourceHandler, DynamicFieldComponentContract, EntityRefCacheStore, EntityRefSelection, HookFn, NgxDynamicEntityConfig, UiTextKey, UiTextOverrides, UiTextOverridesFor, UiTextParams, UiTextResolver, UiTextResolverFor, UiTextValue, ValidationMessage };