ngx-dynamic-entity 1.9.1 → 1.11.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.
@@ -53,6 +53,8 @@ declare const DEFAULT_UI_TEXT: {
53
53
  reset: string;
54
54
  saveShortcutHint: string;
55
55
  loading: string;
56
+ errorSummaryTitle: string;
57
+ tabErrorCount: string;
56
58
  editSection: string;
57
59
  saveSection: string;
58
60
  editingSection: string;
@@ -831,6 +833,8 @@ declare class ConfigSourceService {
831
833
  type ValidationMessage = string | ((language: string, error: any) => string);
832
834
  /** The built-in English messages. Every key here can be overridden individually. */
833
835
  declare const DEFAULT_VALIDATION_MESSAGES: Record<string, ValidationMessage>;
836
+ /** An error key, or a pair mapping one to a different message key. */
837
+ type MessageOrderEntry = string | readonly [errorKey: string, messageKey: string];
834
838
  declare class ValidationMessagesService {
835
839
  private readonly overrides;
836
840
  /**
@@ -841,12 +845,39 @@ declare class ValidationMessagesService {
841
845
  * most specific message is the one shown.
842
846
  */
843
847
  resolve(errors: ValidationErrors | null | undefined, language: string, order: readonly (string | readonly [errorKey: string, messageKey: string])[], fallbackKey?: string): string;
848
+ /**
849
+ * The message for a field, chosen by its **type** rather than by a list the caller supplies.
850
+ *
851
+ * Every field component used to pass its own copy of the key order, and the copies were
852
+ * near-identical — which was tolerable while the field itself was the only thing that
853
+ * rendered a message. It stopped being tolerable when the error summary above the form
854
+ * started naming what is wrong with each field: the summary has no field component to ask
855
+ * (the offending field is usually on a tab that is not rendered), so it would have needed a
856
+ * second copy of the same table, and a dropdown would have said "This field is required" in
857
+ * the summary and "Please select an option" under the control.
858
+ *
859
+ * One table, read from both places, is what keeps those two sentences the same sentence.
860
+ */
861
+ resolveForField(errors: ValidationErrors | null | undefined, language: string, fieldType: string): string;
862
+ /** A field type's key order. An unrecognised type — a consumer's own — gets the common list. */
863
+ orderFor(fieldType: string): {
864
+ order: readonly MessageOrderEntry[];
865
+ fallback: string;
866
+ };
844
867
  /** One message by key, honouring an override before the default. */
845
868
  messageFor(key: string, language: string, error: unknown): string;
846
869
  static ɵfac: i0.ɵɵFactoryDeclaration<ValidationMessagesService, never>;
847
870
  static ɵprov: i0.ɵɵInjectableDeclaration<ValidationMessagesService>;
848
871
  }
849
872
 
873
+ /** A field the form will not save, with what is wrong and where to find it. */
874
+ interface InvalidField {
875
+ field: NestedFieldConfig;
876
+ /** The same message the field renders under itself. */
877
+ message: string;
878
+ tabId: string;
879
+ subTabId?: string;
880
+ }
850
881
  /**
851
882
  * DynamicFormComponent — the main form component.
852
883
  * Renders a reactive form from EntityFormConfig with tab support, responsive 12-col grid,
@@ -898,6 +929,19 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
898
929
  * disable the form. Used by the builder's live preview.
899
930
  */
900
931
  preview: boolean;
932
+ /**
933
+ * How a field with no `colSpan` of its own is sized in the 12-column grid.
934
+ *
935
+ * `stack` — the historic behaviour — gives every such field the full twelve, so a form of
936
+ * eight short text fields renders as an eight-row ladder with two thirds of its width
937
+ * empty. `auto` sizes them by field type instead: a date or a number is half a row, a
938
+ * textarea or a nested group still takes all twelve.
939
+ *
940
+ * An explicit `colSpan` always wins in both modes, so turning `auto` on cannot override a
941
+ * layout somebody authored. The default stays `stack` because changing how existing configs
942
+ * render is not this input's business — opting in is.
943
+ */
944
+ layout: 'stack' | 'auto';
901
945
  formSubmit: EventEmitter<Record<string, any>>;
902
946
  formChange: EventEmitter<Record<string, any>>;
903
947
  formReset: EventEmitter<void>;
@@ -917,9 +961,15 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
917
961
  private readonly hookRegistry;
918
962
  private readonly rbacService;
919
963
  private readonly rulesEvaluation;
964
+ /** Resolves what is wrong with a field, for the error summary — see `resolveForField`. */
965
+ private readonly messages;
920
966
  private readonly entityRefSelection;
921
967
  private readonly commonModulesRegistry;
922
968
  private readonly migrations;
969
+ /** Scopes the field-slot lookup a jump does, so the library never touches global `document`. */
970
+ private readonly host;
971
+ /** Ties `afterNextRender` to this component, so destroying it cancels a pending jump. */
972
+ private readonly injector;
923
973
  protected readonly Object: ObjectConstructor;
924
974
  readonly activeTab: i0.WritableSignal<string>;
925
975
  readonly activeSubTab: i0.WritableSignal<string>;
@@ -1017,8 +1067,31 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1017
1067
  * uniqueness check came back.
1018
1068
  */
1019
1069
  get isValidating(): boolean;
1020
- /** Single source of truth for both the submit guard and the button's disabled state. */
1070
+ /**
1071
+ * Whether a submit would be refused. The guard `submit()` checks — not the button's state.
1072
+ *
1073
+ * See `submitDisabled` for why those are no longer the same question.
1074
+ */
1021
1075
  get submitBlocked(): boolean;
1076
+ /**
1077
+ * Whether the Save button is unavailable.
1078
+ *
1079
+ * This used to be `submitBlocked`, so an invalid form greyed Save out — and a greyed button
1080
+ * is the worst possible answer to "why can't I save?". It cannot be clicked, so there is no
1081
+ * moment at which the form gets to say which field is at fault or which tab it is on; the
1082
+ * user is left comparing a disabled button against a form that looks, to them, filled in.
1083
+ * On a tabbed form the offending field is usually not even on screen.
1084
+ *
1085
+ * Save now stays available while the form is merely invalid. Clicking it still saves
1086
+ * nothing — `submit()` checks `submitBlocked` and refuses — but the refusal is where the
1087
+ * error summary, the tab badges and the jump to the first bad field come from, so pressing
1088
+ * Save produces an explanation instead of silence.
1089
+ *
1090
+ * What is still disabled is what a *retry cannot fix*: a save already in flight, and an
1091
+ * async validator whose answer has not come back. Those are moments where the right answer
1092
+ * is genuinely "wait", and a button that accepts a click would be lying.
1093
+ */
1094
+ get submitDisabled(): boolean;
1022
1095
  ngOnInit(): void;
1023
1096
  ngOnChanges(changes: SimpleChanges): void;
1024
1097
  /**
@@ -1046,6 +1119,47 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1046
1119
  focusPanel?: boolean;
1047
1120
  }): void;
1048
1121
  getFieldSpan(field: NestedFieldConfig): string;
1122
+ /**
1123
+ * Set by a submit that validation refused, cleared by one that went through.
1124
+ *
1125
+ * Gates the error summary rather than `form.invalid` doing it: a form opened on an empty
1126
+ * required field is invalid from the first render, and leading with a block of red before
1127
+ * the user has typed anything is an accusation, not help. The summary is the answer to
1128
+ * "why did Save do nothing", so it appears when Save does nothing.
1129
+ */
1130
+ readonly submitAttempted: i0.WritableSignal<boolean>;
1131
+ /**
1132
+ * Every rendered field whose control is currently invalid, with the tab it lives on.
1133
+ *
1134
+ * Read by the tab badges, the error summary and the jump, so all three agree on what
1135
+ * counts. Hidden fields are excluded because `syncHiddenFieldState` disables them and a
1136
+ * disabled control is not part of validity — pointing the user at one would send them to a
1137
+ * field that is not on screen, or worse, switch tabs to show them nothing.
1138
+ *
1139
+ * Cached per change-detection pass. The walk calls `getControl` once per field and that
1140
+ * falls back to a recursive search of the whole form; the template reads this three times
1141
+ * for the summary and once per tab for the badges, so recomputing it each time turns one
1142
+ * traversal into a dozen on every keystroke. `form.statusChanges` is the only thing that
1143
+ * can alter the answer, and it already runs `markForCheck` — dropping the cache there keeps
1144
+ * it honest without a second subscription.
1145
+ */
1146
+ invalidFields(): InvalidField[];
1147
+ private invalidFieldsCache?;
1148
+ /** How many invalid fields sit on a tab — its own and its sub-tabs'. */
1149
+ tabErrorCount(tab: NestedTabConfig): number;
1150
+ /** The same count for a sub-tab, which is addressed by its own id rather than its parent's. */
1151
+ subTabErrorCount(subTab: NestedTabConfig): number;
1152
+ /**
1153
+ * Switch to the tab holding `fieldId`, scroll it into view, and move focus onto it.
1154
+ *
1155
+ * `afterNextRender` rather than a timer: the panel the field lives in is rendered by the
1156
+ * change detection this call is part of, so the element does not exist yet — and a timeout
1157
+ * is both a guess at how long that takes and something that keeps running after the
1158
+ * component is destroyed. The query is scoped to this component's own element, so the
1159
+ * library never reaches for the global `document`.
1160
+ */
1161
+ jumpToField(fieldId: string): void;
1162
+ private locateField;
1049
1163
  /** A critical field stays read-only until the user deliberately unlocks it. */
1050
1164
  isFieldLocked(field: NestedFieldConfig): boolean;
1051
1165
  /**
@@ -1054,6 +1168,13 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1054
1168
  */
1055
1169
  isFieldReadonly(field: NestedFieldConfig): boolean;
1056
1170
  toggleFieldLock(field: NestedFieldConfig): void;
1171
+ /**
1172
+ * A field's label in the form's language, falling back to its id.
1173
+ *
1174
+ * The fallback matters wherever the label stands alone rather than beside its control: an
1175
+ * error-summary chip or a critical-change banner naming a field with no label for this
1176
+ * language would otherwise be blank, and a blank chip is worse than a raw id.
1177
+ */
1057
1178
  resolveFieldLabel(field: NestedFieldConfig): string;
1058
1179
  /**
1059
1180
  * The changed critical fields as one comma-separated string.
@@ -1213,7 +1334,7 @@ declare class DynamicFormComponent implements OnInit, OnChanges, OnDestroy {
1213
1334
  submit(): Promise<void>;
1214
1335
  reset(): void;
1215
1336
  static ɵfac: i0.ɵɵFactoryDeclaration<DynamicFormComponent, never>;
1216
- static ɵcmp: i0.ɵɵComponentDeclaration<DynamicFormComponent, "ngx-dynamic-form", never, { "config": { "alias": "config"; "required": false; }; "rules": { "alias": "rules"; "required": false; }; "initialData": { "alias": "initialData"; "required": false; }; "originalData": { "alias": "originalData"; "required": false; }; "userRoles": { "alias": "userRoles"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "readOnlyFields": { "alias": "readOnlyFields"; "required": false; }; "showInfoBanners": { "alias": "showInfoBanners"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "error": { "alias": "error"; "required": false; }; "changeDebounceMs": { "alias": "changeDebounceMs"; "required": false; }; "preview": { "alias": "preview"; "required": false; }; }, { "formSubmit": "formSubmit"; "formChange": "formChange"; "formReset": "formReset"; "activeTabChange": "activeTabChange"; "saveRejected": "saveRejected"; }, never, never, true, never>;
1337
+ static ɵcmp: i0.ɵɵComponentDeclaration<DynamicFormComponent, "ngx-dynamic-form", never, { "config": { "alias": "config"; "required": false; }; "rules": { "alias": "rules"; "required": false; }; "initialData": { "alias": "initialData"; "required": false; }; "originalData": { "alias": "originalData"; "required": false; }; "userRoles": { "alias": "userRoles"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "readOnlyFields": { "alias": "readOnlyFields"; "required": false; }; "showInfoBanners": { "alias": "showInfoBanners"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "error": { "alias": "error"; "required": false; }; "changeDebounceMs": { "alias": "changeDebounceMs"; "required": false; }; "preview": { "alias": "preview"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; }, { "formSubmit": "formSubmit"; "formChange": "formChange"; "formReset": "formReset"; "activeTabChange": "activeTabChange"; "saveRejected": "saveRejected"; }, never, never, true, never>;
1217
1338
  }
1218
1339
 
1219
1340
  /**
@@ -1236,6 +1357,8 @@ declare class DynamicRecordFormComponent implements OnChanges {
1236
1357
  isReadOnly: boolean;
1237
1358
  /** Specific field ids forced read-only while the rest of the record stays editable. */
1238
1359
  readOnlyFields: string[];
1360
+ /** Forwarded verbatim to the hosted form — see `DynamicFormComponent.layout`. */
1361
+ layout: 'stack' | 'auto';
1239
1362
  /**
1240
1363
  * Open the record read-only, with a per-tab "Edit section" flow — one tab is edited and
1241
1364
  * validated at a time. This is the framework's `EntityRecordComponent` model and the
@@ -1252,11 +1375,22 @@ declare class DynamicRecordFormComponent implements OnChanges {
1252
1375
  tabId: string;
1253
1376
  record: Record<string, any>;
1254
1377
  }>;
1378
+ /**
1379
+ * A `beforeSave` hook aborted the save — by returning false or throwing.
1380
+ *
1381
+ * Re-exposed from the embedded `ngx-dynamic-form`, and emitted by `saveSection` too. The
1382
+ * inner form already ran the hook and already refused the save, but nothing carried that
1383
+ * out to a host binding this component: the veto worked and looked exactly like a Save
1384
+ * button that did nothing, which is the failure `saveRejected` exists to prevent.
1385
+ */
1386
+ saveRejected: EventEmitter<{
1387
+ reason: string;
1388
+ error?: unknown;
1389
+ }>;
1255
1390
  dynamicFormComp?: DynamicFormComponent;
1256
1391
  private readonly rulesEvaluation;
1257
1392
  private readonly rbacService;
1258
- private readonly host;
1259
- private readonly injector;
1393
+ private readonly hookRegistry;
1260
1394
  readonly currentData: i0.WritableSignal<Record<string, any>>;
1261
1395
  readonly originalBaseline: i0.WritableSignal<Record<string, any>>;
1262
1396
  /**
@@ -1355,7 +1489,18 @@ declare class DynamicRecordFormComponent implements OnChanges {
1355
1489
  * validity of the tab's own controls, and rules filtered to this tab — a rule targeting
1356
1490
  * a hidden tab must not block the save (the reference's OV0-968 fix).
1357
1491
  */
1358
- saveSection(): void;
1492
+ saveSection(): Promise<void>;
1493
+ /**
1494
+ * Put a record to the entity's `beforeSave` hook.
1495
+ *
1496
+ * `sectionSave` carries the *whole* record — `extractRecord()`, not the tab's slice — so
1497
+ * the same payload reached persistence through two buttons, one of which asked the hook
1498
+ * and one of which did not. A hook registered to veto a save is a data-integrity
1499
+ * mechanism; having a second route around it made it advisory.
1500
+ *
1501
+ * @returns the record to emit, or `null` when the hook aborted (already reported).
1502
+ */
1503
+ private runBeforeSave;
1359
1504
  /**
1360
1505
  * Seed the session baseline from the loaded record so `VALUE_CHANGED` rules and the
1361
1506
  * modification banner compare against the record as it was opened — not as it was
@@ -1363,6 +1508,30 @@ declare class DynamicRecordFormComponent implements OnChanges {
1363
1508
  */
1364
1509
  ngOnChanges(changes: SimpleChanges): void;
1365
1510
  get recordTitle(): string;
1511
+ /**
1512
+ * What this record is called, as opposed to what kind of thing it is.
1513
+ *
1514
+ * The header used to show the entity's name twice — "clients", with "Entity: clients"
1515
+ * underneath — so the one question a record header exists to answer, *which* record am I
1516
+ * looking at, was the one thing it did not say. The entity keeps the subtitle; this takes
1517
+ * the heading.
1518
+ *
1519
+ * The order is deliberate. `showOnMinimize` is the author saying "this is what identifies a
1520
+ * record" — it is what the summary panel and the collapsed view already show — so it is
1521
+ * asked first. A text or email field is the fallback because those are what a name is
1522
+ * stored in; a number or a date is a property of the record, not its identity, and would
1523
+ * give a header reading "42". When neither exists there is nothing to name it with and the
1524
+ * entity label stands in, which is the behaviour this replaced.
1525
+ *
1526
+ * A masked field is never a candidate. Masking is presentational (see SECURITY.md), but
1527
+ * that is exactly why: the whole point is that this role does not get to read the value, and
1528
+ * promoting it into the page heading would print in full what every field renders as
1529
+ * `XXXXXXXXX`. A record whose only text field is masked keeps the entity label.
1530
+ *
1531
+ * One pass rather than two filtered ones: this is a getter the header reads on every change
1532
+ * detection, and the preferred candidate is usually the first field it meets.
1533
+ */
1534
+ get recordHeading(): string;
1366
1535
  get avatarLetter(): string;
1367
1536
  /** Every field in the config, at any depth. */
1368
1537
  private allFields;
@@ -1409,21 +1578,18 @@ declare class DynamicRecordFormComponent implements OnChanges {
1409
1578
  * field. The walk used to check top-level `fields` only, so every field in a sub-tab was
1410
1579
  * simply not found and the jump did nothing at all.
1411
1580
  */
1412
- private locateField;
1413
1581
  /**
1414
1582
  * Switches to the tab holding `fieldId`, then scrolls it into view and moves focus to it.
1415
1583
  *
1416
- * The wait for the new tab to render used to be a 50 ms `setTimeout`, which was wrong three
1417
- * ways: `document` is undefined on a server render, 50 ms is a guess that a large tab can
1418
- * outrun, and nothing cancelled the timer if the component went away first.
1419
- * `afterNextRender` fixes all three — it never runs on the server, it runs when the panel
1420
- * has actually rendered rather than when a guess expires, and it is tied to the injector so
1421
- * destroying the component cancels it. The query is scoped to this component's own element,
1422
- * so the library no longer reaches for the global `document` at all.
1584
+ * Delegated rather than implemented twice. The hosted form grew the same jump when a
1585
+ * refused save had to be able to take the user to the first invalid field, and the form is
1586
+ * where it belongs: it owns the tab state, the panel that renders the field, and the
1587
+ * element the jump is looking for. This is kept as the record editor's public entry point
1588
+ * because the summary panel's quick-jump calls it and a host may too.
1423
1589
  */
1424
1590
  jumpToField(fieldId: string): void;
1425
1591
  static ɵfac: i0.ɵɵFactoryDeclaration<DynamicRecordFormComponent, never>;
1426
- static ɵcmp: i0.ɵɵComponentDeclaration<DynamicRecordFormComponent, "ngx-dynamic-record-form", never, { "config": { "alias": "config"; "required": false; }; "rules": { "alias": "rules"; "required": false; }; "initialData": { "alias": "initialData"; "required": false; }; "userRoles": { "alias": "userRoles"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "error": { "alias": "error"; "required": false; }; "isReadOnly": { "alias": "isReadOnly"; "required": false; }; "readOnlyFields": { "alias": "readOnlyFields"; "required": false; }; "viewMode": { "alias": "viewMode"; "required": false; }; }, { "formSubmit": "formSubmit"; "formChange": "formChange"; "formReset": "formReset"; "sectionSave": "sectionSave"; }, never, never, true, never>;
1592
+ static ɵcmp: i0.ɵɵComponentDeclaration<DynamicRecordFormComponent, "ngx-dynamic-record-form", never, { "config": { "alias": "config"; "required": false; }; "rules": { "alias": "rules"; "required": false; }; "initialData": { "alias": "initialData"; "required": false; }; "userRoles": { "alias": "userRoles"; "required": false; }; "language": { "alias": "language"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "error": { "alias": "error"; "required": false; }; "isReadOnly": { "alias": "isReadOnly"; "required": false; }; "readOnlyFields": { "alias": "readOnlyFields"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; "viewMode": { "alias": "viewMode"; "required": false; }; }, { "formSubmit": "formSubmit"; "formChange": "formChange"; "formReset": "formReset"; "sectionSave": "sectionSave"; "saveRejected": "saveRejected"; }, never, never, true, never>;
1427
1593
  }
1428
1594
 
1429
1595
  /**
@@ -1567,6 +1733,25 @@ declare function nextFieldInstanceId(): string;
1567
1733
  declare function fieldDomId(field: {
1568
1734
  id?: string;
1569
1735
  } | undefined, instance: string, suffix?: string): string;
1736
+ /**
1737
+ * The `aria-describedby` a control needs, given what is rendered beside it right now.
1738
+ *
1739
+ * A field can show two things under its control — the author's help text and, once touched, a
1740
+ * validation message — and a screen reader announces only what this attribute names. Three
1741
+ * field components named the error; the other sixteen named nothing at all, so their error
1742
+ * messages were on screen and silent. Help text would have inherited the same gap.
1743
+ *
1744
+ * Order matters: the hint describes the field and the error describes the attempt, so the hint
1745
+ * is read first. `null` rather than an empty string when there is nothing to describe — an
1746
+ * empty `aria-describedby` is a dangling reference, not an absent one.
1747
+ *
1748
+ * Shared rather than written into each of the nineteen field components, because the rule is
1749
+ * the same everywhere and getting it wrong is invisible until somebody uses a screen reader.
1750
+ */
1751
+ declare function fieldDescribedBy(domId: (suffix?: string) => string, parts: {
1752
+ hint?: boolean;
1753
+ error?: boolean;
1754
+ }): string | null;
1570
1755
 
1571
1756
  declare class TextFieldComponent implements OnDestroy {
1572
1757
  /**
@@ -1591,6 +1776,10 @@ declare class TextFieldComponent implements OnDestroy {
1591
1776
  ngOnDestroy(): void;
1592
1777
  get label(): string;
1593
1778
  get placeholder(): string;
1779
+ /** Author help text, shown under the control and named by `aria-describedby`. */
1780
+ get hint(): string;
1781
+ /** The ids of whatever is describing this control right now. */
1782
+ protected describedBy(): string | null;
1594
1783
  get errorMessage(): string;
1595
1784
  static ɵfac: i0.ɵɵFactoryDeclaration<TextFieldComponent, never>;
1596
1785
  static ɵcmp: i0.ɵɵComponentDeclaration<TextFieldComponent, "ngx-text-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>;
@@ -1619,6 +1808,10 @@ declare class TextareaFieldComponent {
1619
1808
  * "This field has an error", which made a documented, configurable feature work on three
1620
1809
  * of fifteen field types.
1621
1810
  */
1811
+ /** Author help text, shown under the control and named by `aria-describedby`. */
1812
+ get hint(): string;
1813
+ /** The ids of whatever is describing this control right now. */
1814
+ protected describedBy(): string | null;
1622
1815
  get errorMessage(): string;
1623
1816
  static ɵfac: i0.ɵɵFactoryDeclaration<TextareaFieldComponent, never>;
1624
1817
  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>;
@@ -1691,6 +1884,10 @@ declare class MarkdownFieldComponent implements OnChanges {
1691
1884
  * "This field has an error", which made a documented, configurable feature work on three
1692
1885
  * of fifteen field types.
1693
1886
  */
1887
+ /** Author help text, shown under the control and named by `aria-describedby`. */
1888
+ get hint(): string;
1889
+ /** The ids of whatever is describing this control right now. */
1890
+ protected describedBy(): string | null;
1694
1891
  get errorMessage(): string;
1695
1892
  static ɵfac: i0.ɵɵFactoryDeclaration<MarkdownFieldComponent, never>;
1696
1893
  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>;
@@ -1713,6 +1910,10 @@ declare class NumberFieldComponent {
1713
1910
  masked: boolean;
1714
1911
  get label(): string;
1715
1912
  get placeholder(): string;
1913
+ /** Author help text, shown under the control and named by `aria-describedby`. */
1914
+ get hint(): string;
1915
+ /** The ids of whatever is describing this control right now. */
1916
+ protected describedBy(): string | null;
1716
1917
  get errorMessage(): string;
1717
1918
  static ɵfac: i0.ɵɵFactoryDeclaration<NumberFieldComponent, never>;
1718
1919
  static ɵcmp: i0.ɵɵComponentDeclaration<NumberFieldComponent, "ngx-number-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>;
@@ -1744,6 +1945,10 @@ declare class CurrencyFieldComponent {
1744
1945
  * "This field has an error", which made a documented, configurable feature work on three
1745
1946
  * of fifteen field types.
1746
1947
  */
1948
+ /** Author help text, shown under the control and named by `aria-describedby`. */
1949
+ get hint(): string;
1950
+ /** The ids of whatever is describing this control right now. */
1951
+ protected describedBy(): string | null;
1747
1952
  get errorMessage(): string;
1748
1953
  static ɵfac: i0.ɵɵFactoryDeclaration<CurrencyFieldComponent, never>;
1749
1954
  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>;
@@ -1773,6 +1978,10 @@ declare class EmailFieldComponent {
1773
1978
  * "This field has an error", which made a documented, configurable feature work on three
1774
1979
  * of fifteen field types.
1775
1980
  */
1981
+ /** Author help text, shown under the control and named by `aria-describedby`. */
1982
+ get hint(): string;
1983
+ /** The ids of whatever is describing this control right now. */
1984
+ protected describedBy(): string | null;
1776
1985
  get errorMessage(): string;
1777
1986
  static ɵfac: i0.ɵɵFactoryDeclaration<EmailFieldComponent, never>;
1778
1987
  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>;
@@ -1806,6 +2015,10 @@ declare class PasswordFieldComponent {
1806
2015
  * "This field has an error", which made a documented, configurable feature work on three
1807
2016
  * of fifteen field types.
1808
2017
  */
2018
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2019
+ get hint(): string;
2020
+ /** The ids of whatever is describing this control right now. */
2021
+ protected describedBy(): string | null;
1809
2022
  get errorMessage(): string;
1810
2023
  static ɵfac: i0.ɵɵFactoryDeclaration<PasswordFieldComponent, never>;
1811
2024
  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>;
@@ -1835,6 +2048,10 @@ declare class CheckboxFieldComponent {
1835
2048
  * It rendered no error element at all, so a required checkbox left unticked told the user
1836
2049
  * nothing — and `validationMessages` could not reach a field that never displayed one.
1837
2050
  */
2051
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2052
+ get hint(): string;
2053
+ /** The ids of whatever is describing this control right now. */
2054
+ protected describedBy(): string | null;
1838
2055
  get errorMessage(): string;
1839
2056
  static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxFieldComponent, never>;
1840
2057
  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>;
@@ -1846,6 +2063,12 @@ declare class CheckboxFieldComponent {
1846
2063
  * toggle switch with Yes/No labels for clearer binary state communication.
1847
2064
  */
1848
2065
  declare class BooleanFieldComponent {
2066
+ /**
2067
+ * Unique to this component instance: an `array` renders the same field once per row, and a
2068
+ * DOM id may not repeat. See `field-dom-id.ts`.
2069
+ */
2070
+ private readonly instanceId;
2071
+ protected domId(suffix?: string): string;
1849
2072
  /** Library chrome, overridable via UI_TEXT. */
1850
2073
  protected readonly ui: UiTextService;
1851
2074
  /** Overridable via MASKED_PLACEHOLDER; the default is the historic literal. */
@@ -1863,6 +2086,10 @@ declare class BooleanFieldComponent {
1863
2086
  * It rendered no error element at all, so a required checkbox left unticked told the user
1864
2087
  * nothing — and `validationMessages` could not reach a field that never displayed one.
1865
2088
  */
2089
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2090
+ get hint(): string;
2091
+ /** The ids of whatever is describing this control right now. */
2092
+ protected describedBy(): string | null;
1866
2093
  get errorMessage(): string;
1867
2094
  static ɵfac: i0.ɵɵFactoryDeclaration<BooleanFieldComponent, never>;
1868
2095
  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>;
@@ -1884,7 +2111,18 @@ declare class DateFieldComponent {
1884
2111
  readonly: boolean;
1885
2112
  masked: boolean;
1886
2113
  get label(): string;
1887
- /** ISO 8601 date → locale display string (ONEHERMES convention: always UTC, display in user locale) */
2114
+ /**
2115
+ * ISO 8601 date → display string, through the formatter the host configured.
2116
+ *
2117
+ * This used to call `toLocaleDateString()` directly, which meant `setDateFormatters` — the
2118
+ * one seam for choosing how a date is rendered — reached the record summary and the `time`
2119
+ * field but not this one. A host that configured formatters got them almost everywhere,
2120
+ * and silently did not get them on the field type most likely to be the reason they
2121
+ * configured formatters at all.
2122
+ *
2123
+ * The default formatter is `toLocaleDateString()` with no locale, so an application that
2124
+ * has not called `setDateFormatters` renders exactly what it rendered before.
2125
+ */
1888
2126
  formatDate(value: string | null): string;
1889
2127
  /**
1890
2128
  * Resolved through `ValidationMessagesService`, so `provideNgxDynamicEntity({
@@ -1892,6 +2130,10 @@ declare class DateFieldComponent {
1892
2130
  * "This field has an error", which made a documented, configurable feature work on three
1893
2131
  * of fifteen field types.
1894
2132
  */
2133
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2134
+ get hint(): string;
2135
+ /** The ids of whatever is describing this control right now. */
2136
+ protected describedBy(): string | null;
1895
2137
  get errorMessage(): string;
1896
2138
  static ɵfac: i0.ɵɵFactoryDeclaration<DateFieldComponent, never>;
1897
2139
  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>;
@@ -1925,9 +2167,17 @@ declare class DateTimeFieldComponent {
1925
2167
  /** The input's local `YYYY-MM-DDTHH:mm` → stored ISO 8601 UTC. */
1926
2168
  onInput(value: string): void;
1927
2169
  /**
1928
- * Displays date *and* time. `DateFieldComponent` used `toLocaleDateString()` here, so a
1929
- * datetime read back through the field showed no time while the same value in the record
1930
- * summary — which goes through core's `formatDisplayValue` — showed it.
2170
+ * Displays date *and* time, through the formatter the host configured.
2171
+ *
2172
+ * Two rounds of the same fault. First this called `toLocaleDateString()`, so a datetime
2173
+ * read back through the field showed no time while the record summary showed it. Then it
2174
+ * called `toLocaleString()` directly, which fixed the time but kept the field outside
2175
+ * `setDateFormatters` — so a host that configured formatters still saw them apply to the
2176
+ * summary and not to the field. Going through `formatDisplayValue` is what makes the two
2177
+ * paths agree by construction rather than by matching literals.
2178
+ *
2179
+ * `parseStored` accepts shapes `new Date(raw)` alone does not, so the *parsed* instant is
2180
+ * handed on as ISO rather than the raw value.
1931
2181
  */
1932
2182
  formatDateTime(value: unknown): string;
1933
2183
  /**
@@ -1936,6 +2186,10 @@ declare class DateTimeFieldComponent {
1936
2186
  * "This field has an error", which made a documented, configurable feature work on three
1937
2187
  * of fifteen field types.
1938
2188
  */
2189
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2190
+ get hint(): string;
2191
+ /** The ids of whatever is describing this control right now. */
2192
+ protected describedBy(): string | null;
1939
2193
  get errorMessage(): string;
1940
2194
  static ɵfac: i0.ɵɵFactoryDeclaration<DateTimeFieldComponent, never>;
1941
2195
  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>;
@@ -1977,6 +2231,10 @@ declare class TimeFieldComponent {
1977
2231
  * "This field has an error", which made a documented, configurable feature work on three
1978
2232
  * of fifteen field types.
1979
2233
  */
2234
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2235
+ get hint(): string;
2236
+ /** The ids of whatever is describing this control right now. */
2237
+ protected describedBy(): string | null;
1980
2238
  get errorMessage(): string;
1981
2239
  static ɵfac: i0.ɵɵFactoryDeclaration<TimeFieldComponent, never>;
1982
2240
  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>;
@@ -2021,6 +2279,10 @@ declare class MonthYearFieldComponent {
2021
2279
  * "This field has an error", which made a documented, configurable feature work on three
2022
2280
  * of fifteen field types.
2023
2281
  */
2282
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2283
+ get hint(): string;
2284
+ /** The ids of whatever is describing this control right now. */
2285
+ protected describedBy(): string | null;
2024
2286
  get errorMessage(): string;
2025
2287
  static ɵfac: i0.ɵɵFactoryDeclaration<MonthYearFieldComponent, never>;
2026
2288
  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>;
@@ -2063,6 +2325,10 @@ declare class DropdownFieldComponent {
2063
2325
  * never wrong, only unlocalised.
2064
2326
  */
2065
2327
  getLabel(value: unknown): string;
2328
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2329
+ get hint(): string;
2330
+ /** The ids of whatever is describing this control right now. */
2331
+ protected describedBy(): string | null;
2066
2332
  get errorMessage(): string;
2067
2333
  static ɵfac: i0.ɵɵFactoryDeclaration<DropdownFieldComponent, never>;
2068
2334
  static ɵcmp: i0.ɵɵComponentDeclaration<DropdownFieldComponent, "ngx-dropdown-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>;
@@ -2118,6 +2384,10 @@ declare class RadioFieldComponent {
2118
2384
  * "This field has an error", which made a documented, configurable feature work on three
2119
2385
  * of fifteen field types.
2120
2386
  */
2387
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2388
+ get hint(): string;
2389
+ /** The ids of whatever is describing this control right now. */
2390
+ protected describedBy(): string | null;
2121
2391
  get errorMessage(): string;
2122
2392
  static ɵfac: i0.ɵɵFactoryDeclaration<RadioFieldComponent, never>;
2123
2393
  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>;
@@ -2159,6 +2429,10 @@ declare class MultiSelectFieldComponent {
2159
2429
  * "This field has an error", which made a documented, configurable feature work on three
2160
2430
  * of fifteen field types.
2161
2431
  */
2432
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2433
+ get hint(): string;
2434
+ /** The ids of whatever is describing this control right now. */
2435
+ protected describedBy(): string | null;
2162
2436
  get errorMessage(): string;
2163
2437
  static ɵfac: i0.ɵɵFactoryDeclaration<MultiSelectFieldComponent, never>;
2164
2438
  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>;
@@ -2223,6 +2497,10 @@ declare class EntityRefFieldComponent implements OnInit {
2223
2497
  * "This field has an error", which made a documented, configurable feature work on three
2224
2498
  * of fifteen field types.
2225
2499
  */
2500
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2501
+ get hint(): string;
2502
+ /** The ids of whatever is describing this control right now. */
2503
+ protected describedBy(): string | null;
2226
2504
  get errorMessage(): string;
2227
2505
  static ɵfac: i0.ɵɵFactoryDeclaration<EntityRefFieldComponent, never>;
2228
2506
  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>;
@@ -2239,6 +2517,8 @@ declare class GroupFieldComponent {
2239
2517
  readonly: boolean;
2240
2518
  masked: boolean;
2241
2519
  userRoles: string[];
2520
+ /** Author help text for the section as a whole. */
2521
+ get hint(): string;
2242
2522
  get label(): string;
2243
2523
  getChildControl(childId: string): AbstractControl;
2244
2524
  static ɵfac: i0.ɵɵFactoryDeclaration<GroupFieldComponent, never>;
@@ -2266,6 +2546,8 @@ declare class ArrayFieldComponent {
2266
2546
  userRoles: string[];
2267
2547
  private readonly fb;
2268
2548
  private readonly validatorRegistry;
2549
+ /** Author help text for the section as a whole. */
2550
+ get hint(): string;
2269
2551
  get label(): string;
2270
2552
  get formArray(): FormArray;
2271
2553
  getItemChildControl(itemGroup: AbstractControl, childId: string): AbstractControl;
@@ -2310,6 +2592,10 @@ declare class ImageFieldComponent implements OnDestroy {
2310
2592
  remove(): void;
2311
2593
  ngOnDestroy(): void;
2312
2594
  /** Validation, as distinct from the upload failures this field already reported. */
2595
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2596
+ get hint(): string;
2597
+ /** The ids of whatever is describing this control right now. */
2598
+ protected describedBy(): string | null;
2313
2599
  get errorMessage(): string;
2314
2600
  static ɵfac: i0.ɵɵFactoryDeclaration<ImageFieldComponent, never>;
2315
2601
  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>;
@@ -2346,10 +2632,14 @@ declare class FileFieldComponent {
2346
2632
  onFileSelect(file: File | undefined): Promise<void>;
2347
2633
  remove(): void;
2348
2634
  /** Validation, as distinct from the upload failures this field already reported. */
2635
+ /** Author help text, shown under the control and named by `aria-describedby`. */
2636
+ get hint(): string;
2637
+ /** The ids of whatever is describing this control right now. */
2638
+ protected describedBy(): string | null;
2349
2639
  get errorMessage(): string;
2350
2640
  static ɵfac: i0.ɵɵFactoryDeclaration<FileFieldComponent, never>;
2351
2641
  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>;
2352
2642
  }
2353
2643
 
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 };
2644
+ 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, fieldDescribedBy, fieldDomId, nextFieldInstanceId, provideBuiltInFieldTypes, provideFieldTypes, provideNgxDynamicEntity, refreshChoiceOptions, resolveUiText };
2645
+ export type { ChoiceOptionHost, ConfigSourceHandler, DynamicFieldComponentContract, EntityRefCacheStore, EntityRefSelection, HookFn, InvalidField, MessageOrderEntry, NgxDynamicEntityConfig, UiTextKey, UiTextOverrides, UiTextOverridesFor, UiTextParams, UiTextResolver, UiTextResolverFor, UiTextValue, ValidationMessage };