@elasticias/ui 1.0.49 → 1.0.51

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.
@@ -10,7 +10,7 @@ import * as _elasticias_core from '@elasticias/core';
10
10
  import { EfBuildPackage, EfSessionIdleService, EfModule, EfNavSection, EfNavItem, EfModuleId, EfToast, EfToastAction, EfThemeConfigService } from '@elasticias/core';
11
11
  import * as i1 from 'primeng/tooltip';
12
12
  import { BlockableUI } from 'primeng/api';
13
- import { SafeResourceUrl } from '@angular/platform-browser';
13
+ import { SafeResourceUrl, SafeHtml } from '@angular/platform-browser';
14
14
  import { ChartConfiguration } from 'chart.js';
15
15
  import { ControlValueAccessor, NgControl } from '@angular/forms';
16
16
  import { TranslateService } from '@ngx-translate/core';
@@ -70,6 +70,20 @@ declare class EfQuantitySelectorComponent {
70
70
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfQuantitySelectorComponent, "ef-quantity-selector", never, { "quantity": { "alias": "quantity"; "required": false; "isSignal": true; }; }, { "quantityChange": "quantityChange"; }, never, never, true, never>;
71
71
  }
72
72
 
73
+ /**
74
+ * Which catalogue price a new order line starts from.
75
+ * - `wholesale`: the ERP channel price (`variant.price`, then `product.unitPrice`,
76
+ * which mirrors the default variant's, then `product.salePrice`). B2B sales orders.
77
+ * - `retail`: the shop price (`variant.salePrice`, then `product.salePrice`). A Web
78
+ * order must cost what the shop charges, and the shop sells a variant at its
79
+ * `salePrice` only: an unpriced variant is not sold, so retail never falls back to
80
+ * the wholesale price, and `compareAtPrice` (the "was" price) is never charged.
81
+ * With no shop price the line starts at 0 for the staff to set.
82
+ */
83
+ type EfOrderPriceList = 'wholesale' | 'retail';
84
+ /** The unit price a new line for `product` (and its chosen `variant`) starts at under `priceList`. */
85
+ declare function defaultUnitPrice(product: Record<string, unknown>, variant: Record<string, unknown> | null | undefined, priceList?: EfOrderPriceList): number;
86
+
73
87
  /**
74
88
  * Summary item for product count groups
75
89
  */
@@ -91,7 +105,7 @@ interface OrderProductsSummary {
91
105
  */
92
106
  interface OrderLineItem {
93
107
  id?: string | number;
94
- product?: Record<string, unknown>;
108
+ product?: Record<string, unknown> | null;
95
109
  productId?: unknown;
96
110
  variantId?: string | null;
97
111
  countGroup?: string;
@@ -135,6 +149,17 @@ interface OrderEntity {
135
149
  billingAddress?: string;
136
150
  productsSummary?: OrderProductsSummary;
137
151
  }
152
+ /**
153
+ * The person an order goes to when there is no client to pick (a storefront
154
+ * order placed by a shopper). The builder shows it read-only in place of the
155
+ * customer select.
156
+ */
157
+ interface EfOrderRecipient {
158
+ name: string;
159
+ phone?: string | null;
160
+ city?: string | null;
161
+ address?: string | null;
162
+ }
138
163
  /**
139
164
  * Configuration for document types (order, invoice, quote)
140
165
  */
@@ -201,8 +226,9 @@ declare class OrderLineItemHelper {
201
226
  /**
202
227
  * Create a line item from product selection
203
228
  * @param keyField - Field name used to identify the product (default: 'id')
229
+ * @param priceList - Which catalogue price the line starts at (see `EfOrderPriceList`)
204
230
  */
205
- static createFromProduct(product: Record<string, unknown>, quantity?: number, keyField?: string, variantId?: string): OrderLineItem;
231
+ static createFromProduct(product: Record<string, unknown>, quantity?: number, keyField?: string, variantId?: string, priceList?: EfOrderPriceList): OrderLineItem;
206
232
  /**
207
233
  * Update calculations for an existing line item
208
234
  */
@@ -359,6 +385,13 @@ interface EfChangeHistoryEntry {
359
385
  toStatus?: string | null;
360
386
  note?: string | null;
361
387
  }
388
+ /** A reference-list item used to translate a raw audit value: matched on
389
+ * `code`, shown as `label`. Structurally compatible with the static reference
390
+ * data items screens already load. */
391
+ interface EfChangeHistoryValueItem {
392
+ code: string;
393
+ label?: string | null;
394
+ }
362
395
 
363
396
  /** Emitted when the user picks a product (with its active variant) from the menu. */
364
397
  interface ProductTypeaheadSelection {
@@ -397,15 +430,38 @@ interface ProductTypeaheadRow {
397
430
  /** Numeric line columns that support inline click-to-edit. */
398
431
  type EditableLineField = 'price' | 'qty' | 'discount' | 'tva';
399
432
  declare class EfOrderBuilderComponent implements OnInit {
400
- rowTrackBy: (_: number, item: OrderLineItem) => string | number;
433
+ rowTrackBy: (_: number, item: OrderLineItem) => string | number | undefined;
401
434
  config: _angular_core.InputSignal<DocumentConfig>;
402
435
  order: _angular_core.ModelSignal<OrderEntity>;
403
436
  products: _angular_core.InputSignal<Record<string, unknown>[]>;
404
437
  customers: _angular_core.InputSignal<Record<string, unknown>[]>;
438
+ /**
439
+ * Who the order goes to when it has no client to pick (a storefront order).
440
+ * When set, the header shows it read-only instead of the customer select,
441
+ * `customers` may be `[]` and the order validates without a `customerId`.
442
+ * Null keeps the customer select and its required rule.
443
+ */
444
+ recipient: _angular_core.InputSignal<EfOrderRecipient | null>;
445
+ /**
446
+ * Calling code (`'212'` or `'+212'`) for a national recipient phone, so the
447
+ * `tel:` link dials `+212612345678` for `0612345678` from anywhere.
448
+ */
449
+ defaultCallingCode: _angular_core.InputSignal<string>;
450
+ /**
451
+ * `tel:` target for the recipient's phone: E.164 when it can be made, else
452
+ * the digits as typed (a national number still dials inside the country).
453
+ */
454
+ recipientTel: _angular_core.Signal<string | null>;
405
455
  readonly: _angular_core.InputSignal<boolean>;
406
456
  countGroupLabels: _angular_core.InputSignal<ProductCountGroupLabel[]>;
407
457
  /** Field name used to identify products (must match catalogue's trackByField) */
408
458
  productKeyField: _angular_core.InputSignal<string>;
459
+ /**
460
+ * Which catalogue price a new line starts at, in quick-add, its typeahead
461
+ * and the catalogue: `'wholesale'` (default, B2B sales) or `'retail'`, the
462
+ * shop price a Web order is charged. Lines already on the order keep theirs.
463
+ */
464
+ priceList: _angular_core.InputSignal<EfOrderPriceList>;
409
465
  backendErrors: _angular_core.InputSignal<{
410
466
  [key: string]: string[];
411
467
  }>;
@@ -416,16 +472,28 @@ declare class EfOrderBuilderComponent implements OnInit {
416
472
  * the bound order then carries no `shippingTotal` at all. A negative or
417
473
  * non-numeric fee is treated as 0.
418
474
  */
419
- shippingTotal: _angular_core.InputSignalWithTransform<number, number>;
420
- /** Optional change-history entries; when non-empty the Historique rail card renders. */
475
+ shippingTotal: _angular_core.InputSignalWithTransform<number, number | null | undefined>;
476
+ /**
477
+ * Optional change-history entries; when non-empty the Historique rail card renders.
478
+ *
479
+ * Host cards that belong in the rail (a delivery card, internal notes) are
480
+ * projected with the `obRail` attribute: `<ef-card obRail ...>`. They sit
481
+ * after the totals and the recap and before the history, as a column at
482
+ * desktop width and inside the drawer below that or in focus mode.
483
+ */
421
484
  auditEntries: _angular_core.InputSignal<EfChangeHistoryEntry[]>;
485
+ /** Passed to the history's `valueLists`: field path to reference items, so
486
+ * raw statuses show as translated labels. */
487
+ auditValueLists: _angular_core.InputSignal<Readonly<Record<string, readonly EfChangeHistoryValueItem[]>> | null>;
488
+ /** Passed to the history's `noteFormatter`: returns the text for a note, or null for the raw note. */
489
+ auditNoteFormatter: _angular_core.InputSignal<((note: string) => string | null) | null>;
422
490
  openCatalogue: _angular_core.OutputEmitterRef<void>;
423
491
  orderChanged: _angular_core.OutputEmitterRef<OrderChangeInfo>;
424
492
  orderValidated: _angular_core.OutputEmitterRef<ValidationResult>;
425
493
  productsAdded: _angular_core.OutputEmitterRef<OrderLineItem[]>;
426
494
  private originalOrder;
427
495
  private initialized;
428
- quickAddSelection: _angular_core.WritableSignal<ProductTypeaheadSelection>;
496
+ quickAddSelection: _angular_core.WritableSignal<ProductTypeaheadSelection | null>;
429
497
  quickAddPrice: _angular_core.WritableSignal<number>;
430
498
  quickAddQuantity: _angular_core.WritableSignal<number>;
431
499
  quickAddDisabled: _angular_core.Signal<boolean>;
@@ -444,7 +512,7 @@ declare class EfOrderBuilderComponent implements OnInit {
444
512
  }>;
445
513
  hasErrors: _angular_core.Signal<boolean>;
446
514
  isValid: _angular_core.Signal<boolean>;
447
- changeInfo: _angular_core.Signal<OrderChangeInfo>;
515
+ changeInfo: _angular_core.Signal<OrderChangeInfo | null>;
448
516
  hasChanges: _angular_core.Signal<boolean>;
449
517
  focusMode: _angular_core.ModelSignal<boolean>;
450
518
  railOpen: _angular_core.WritableSignal<boolean>;
@@ -457,7 +525,7 @@ declare class EfOrderBuilderComponent implements OnInit {
457
525
  editingCell: _angular_core.WritableSignal<{
458
526
  id: OrderLineItem["id"];
459
527
  field: EditableLineField;
460
- }>;
528
+ } | null>;
461
529
  /**
462
530
  * Columns for the lines table.
463
531
  *
@@ -535,7 +603,7 @@ declare class EfOrderBuilderComponent implements OnInit {
535
603
  */
536
604
  private withTotals;
537
605
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfOrderBuilderComponent, never>;
538
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfOrderBuilderComponent, "ef-order-builder", never, { "config": { "alias": "config"; "required": false; "isSignal": true; }; "order": { "alias": "order"; "required": true; "isSignal": true; }; "products": { "alias": "products"; "required": true; "isSignal": true; }; "customers": { "alias": "customers"; "required": true; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "countGroupLabels": { "alias": "countGroupLabels"; "required": false; "isSignal": true; }; "productKeyField": { "alias": "productKeyField"; "required": false; "isSignal": true; }; "backendErrors": { "alias": "backendErrors"; "required": false; "isSignal": true; }; "shippingTotal": { "alias": "shippingTotal"; "required": false; "isSignal": true; }; "auditEntries": { "alias": "auditEntries"; "required": false; "isSignal": true; }; "focusMode": { "alias": "focusMode"; "required": false; "isSignal": true; }; }, { "order": "orderChange"; "openCatalogue": "openCatalogue"; "orderChanged": "orderChanged"; "orderValidated": "orderValidated"; "productsAdded": "productsAdded"; "focusMode": "focusModeChange"; }, never, never, true, never>;
606
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfOrderBuilderComponent, "ef-order-builder", never, { "config": { "alias": "config"; "required": false; "isSignal": true; }; "order": { "alias": "order"; "required": true; "isSignal": true; }; "products": { "alias": "products"; "required": true; "isSignal": true; }; "customers": { "alias": "customers"; "required": true; "isSignal": true; }; "recipient": { "alias": "recipient"; "required": false; "isSignal": true; }; "defaultCallingCode": { "alias": "defaultCallingCode"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "countGroupLabels": { "alias": "countGroupLabels"; "required": false; "isSignal": true; }; "productKeyField": { "alias": "productKeyField"; "required": false; "isSignal": true; }; "priceList": { "alias": "priceList"; "required": false; "isSignal": true; }; "backendErrors": { "alias": "backendErrors"; "required": false; "isSignal": true; }; "shippingTotal": { "alias": "shippingTotal"; "required": false; "isSignal": true; }; "auditEntries": { "alias": "auditEntries"; "required": false; "isSignal": true; }; "auditValueLists": { "alias": "auditValueLists"; "required": false; "isSignal": true; }; "auditNoteFormatter": { "alias": "auditNoteFormatter"; "required": false; "isSignal": true; }; "focusMode": { "alias": "focusMode"; "required": false; "isSignal": true; }; }, { "order": "orderChange"; "openCatalogue": "openCatalogue"; "orderChanged": "orderChanged"; "orderValidated": "orderValidated"; "productsAdded": "productsAdded"; "focusMode": "focusModeChange"; }, never, ["[obRail]"], true, never>;
539
607
  }
540
608
 
541
609
  /**
@@ -569,6 +637,11 @@ declare class EfProductTypeaheadComponent {
569
637
  * variant + unit price) is identical either way.
570
638
  */
571
639
  showVariants: _angular_core.InputSignalWithTransform<boolean, unknown>;
640
+ /**
641
+ * Which catalogue price each row shows and its selection carries: the
642
+ * wholesale price (default) or the shop price for a Web order.
643
+ */
644
+ priceList: _angular_core.InputSignal<EfOrderPriceList>;
572
645
  productSelect: _angular_core.OutputEmitterRef<ProductTypeaheadSelection>;
573
646
  query: _angular_core.WritableSignal<string>;
574
647
  open: _angular_core.WritableSignal<boolean>;
@@ -591,7 +664,7 @@ declare class EfProductTypeaheadComponent {
591
664
  /** Clear the field after the consumer has consumed the selection. */
592
665
  reset(): void;
593
666
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfProductTypeaheadComponent, never>;
594
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfProductTypeaheadComponent, "ef-product-typeahead", never, { "products": { "alias": "products"; "required": true; "isSignal": true; }; "productKeyField": { "alias": "productKeyField"; "required": false; "isSignal": true; }; "placeholderKey": { "alias": "placeholderKey"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "currency": { "alias": "currency"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "showVariants": { "alias": "showVariants"; "required": false; "isSignal": true; }; }, { "productSelect": "productSelect"; }, never, never, true, never>;
667
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfProductTypeaheadComponent, "ef-product-typeahead", never, { "products": { "alias": "products"; "required": true; "isSignal": true; }; "productKeyField": { "alias": "productKeyField"; "required": false; "isSignal": true; }; "placeholderKey": { "alias": "placeholderKey"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "currency": { "alias": "currency"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "showVariants": { "alias": "showVariants"; "required": false; "isSignal": true; }; "priceList": { "alias": "priceList"; "required": false; "isSignal": true; }; }, { "productSelect": "productSelect"; }, never, never, true, never>;
595
668
  }
596
669
 
597
670
  /**
@@ -854,7 +927,7 @@ declare class EfProductPickerComponent {
854
927
  readonly confirm: _angular_core.OutputEmitterRef<string[]>;
855
928
  readonly closed: _angular_core.OutputEmitterRef<void>;
856
929
  /** The list screen behind the dialog already owns the search shortcut. */
857
- readonly searchShortcut: any;
930
+ readonly searchShortcut: null;
858
931
  protected readonly isMobile: _angular_core.Signal<boolean>;
859
932
  private readonly selected;
860
933
  readonly selectedIds: _angular_core.Signal<string[]>;
@@ -1007,6 +1080,12 @@ declare class EfProductCatalogueComponent implements OnChanges {
1007
1080
  trackByField: _angular_core.InputSignal<string>;
1008
1081
  /** Currency code for price formatting */
1009
1082
  currencyCode: _angular_core.InputSignal<string>;
1083
+ /**
1084
+ * Which price the cards show: `'wholesale'` (default) or `'retail'`, the shop price.
1085
+ * Bind the same value as the order builder's `priceList`, so a card shows the price
1086
+ * of the line it adds (the rule lives in `defaultUnitPrice`).
1087
+ */
1088
+ priceList: _angular_core.InputSignal<EfOrderPriceList>;
1010
1089
  /** Locale used for number/currency formatting and the quantity stepper */
1011
1090
  localeCode: _angular_core.InputSignal<string>;
1012
1091
  /**
@@ -1020,7 +1099,7 @@ declare class EfProductCatalogueComponent implements OnChanges {
1020
1099
  * </ng-template>
1021
1100
  * </ef-product-catalogue>
1022
1101
  */
1023
- productThumbnailTpl: _angular_core.Signal<TemplateRef<unknown>>;
1102
+ productThumbnailTpl: _angular_core.Signal<TemplateRef<unknown> | undefined>;
1024
1103
  sortMenu: Menu;
1025
1104
  /** Emitted when products are validated */
1026
1105
  productsValidated: _angular_core.OutputEmitterRef<{
@@ -1073,11 +1152,13 @@ declare class EfProductCatalogueComponent implements OnChanges {
1073
1152
  getPackagingLabel(product: CatalogueProduct): string;
1074
1153
  getVariantTitle(product: CatalogueProduct, variantId: string): string;
1075
1154
  trackKey(product: CatalogueProduct): unknown;
1155
+ /** The price a variant (or a simple product, `variant` null) is shown at under the active list. */
1156
+ private priceOf;
1076
1157
  formatPrice(product: CatalogueProduct): string;
1077
- formatVariantPrice(variant: CatalogueProductVariant): string;
1158
+ formatVariantPrice(variant: CatalogueProductVariant, product?: CatalogueProduct): string;
1078
1159
  private formatCurrency;
1079
1160
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfProductCatalogueComponent, never>;
1080
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfProductCatalogueComponent, "ef-product-catalogue", never, { "products": { "alias": "products"; "required": false; "isSignal": true; }; "categoryGroups": { "alias": "categoryGroups"; "required": false; "isSignal": true; }; "initialSelectedItems": { "alias": "initialSelectedItems"; "required": false; "isSignal": true; }; "defaultFilters": { "alias": "defaultFilters"; "required": false; "isSignal": true; }; "trackByField": { "alias": "trackByField"; "required": false; "isSignal": true; }; "currencyCode": { "alias": "currencyCode"; "required": false; "isSignal": true; }; "localeCode": { "alias": "localeCode"; "required": false; "isSignal": true; }; }, { "productsValidated": "productsValidated"; }, ["productThumbnailTpl"], never, true, never>;
1161
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfProductCatalogueComponent, "ef-product-catalogue", never, { "products": { "alias": "products"; "required": false; "isSignal": true; }; "categoryGroups": { "alias": "categoryGroups"; "required": false; "isSignal": true; }; "initialSelectedItems": { "alias": "initialSelectedItems"; "required": false; "isSignal": true; }; "defaultFilters": { "alias": "defaultFilters"; "required": false; "isSignal": true; }; "trackByField": { "alias": "trackByField"; "required": false; "isSignal": true; }; "currencyCode": { "alias": "currencyCode"; "required": false; "isSignal": true; }; "priceList": { "alias": "priceList"; "required": false; "isSignal": true; }; "localeCode": { "alias": "localeCode"; "required": false; "isSignal": true; }; }, { "productsValidated": "productsValidated"; }, ["productThumbnailTpl"], never, true, never>;
1081
1162
  }
1082
1163
 
1083
1164
  /**
@@ -1137,7 +1218,7 @@ declare class EfThemeToggleComponent {
1137
1218
  * Where the tooltip opens. Below suits a top bar (the app bar, the
1138
1219
  * login header); a toggle placed low on a page can open it above.
1139
1220
  */
1140
- readonly tooltipPosition: _angular_core.InputSignal<"top" | "left" | "bottom" | "right">;
1221
+ readonly tooltipPosition: _angular_core.InputSignal<"top" | "bottom" | "left" | "right">;
1141
1222
  /** Translation key for the accessible name (also the tooltip text). */
1142
1223
  readonly ariaLabelKey: _angular_core.InputSignal<string>;
1143
1224
  readonly isDark: _angular_core.Signal<boolean>;
@@ -1162,7 +1243,7 @@ declare class EfThemeToggleComponent {
1162
1243
  declare class EfBuildStampComponent {
1163
1244
  /** Copyright holder shown before the build. Omit for the build alone. */
1164
1245
  readonly owner: _angular_core.InputSignal<string>;
1165
- protected readonly info: _elasticias_core.EfBuildInfo;
1246
+ protected readonly info: _elasticias_core.EfBuildInfo | null;
1166
1247
  protected readonly year: number;
1167
1248
  /**
1168
1249
  * A released build is known by its version; an unreleased one has no
@@ -1231,7 +1312,7 @@ declare class EfAboutDialogComponent {
1231
1312
  readonly initial: _angular_core.InputSignal<string>;
1232
1313
  /** Copyright holder on the last line. */
1233
1314
  readonly owner: _angular_core.InputSignal<string>;
1234
- protected readonly info: _elasticias_core.EfBuildInfo;
1315
+ protected readonly info: _elasticias_core.EfBuildInfo | null;
1235
1316
  protected readonly year: number;
1236
1317
  protected readonly packages: _angular_core.Signal<EfBuildPackage[]>;
1237
1318
  /**
@@ -1350,7 +1431,7 @@ declare class EfShortcutsDialogComponent {
1350
1431
  declare class EfSessionIdleDialogComponent {
1351
1432
  protected readonly idle: EfSessionIdleService;
1352
1433
  private readonly session;
1353
- protected readonly secondsLeft: _angular_core.Signal<number>;
1434
+ protected readonly secondsLeft: _angular_core.Signal<number | null>;
1354
1435
  protected readonly actions: EfDialogAction[];
1355
1436
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfSessionIdleDialogComponent, never>;
1356
1437
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfSessionIdleDialogComponent, "ef-session-idle-dialog", never, {}, {}, never, never, true, never>;
@@ -1490,7 +1571,7 @@ declare class EfButtonComponent implements OnInit {
1490
1571
  * `'small' | 'large'`, with the default (unset) being the normal height, so
1491
1572
  * `'base'` maps to `null` rather than being forwarded verbatim.
1492
1573
  */
1493
- get pnSize(): 'small' | 'large' | null;
1574
+ get pnSize(): 'small' | 'large' | undefined;
1494
1575
  /** Composed class string for the Comptoir variant —
1495
1576
  * `btn btn-{severity} btn-sm` plus any caller-supplied `styleClass`. */
1496
1577
  get comptoirClass(): string;
@@ -1537,6 +1618,8 @@ declare class EfLabelComponent {
1537
1618
  label?: string;
1538
1619
  /** Translation key — preferred. */
1539
1620
  labelKey?: string;
1621
+ /** Interpolation params for `labelKey`. */
1622
+ labelParams?: Record<string, unknown>;
1540
1623
  /** DOM id of the labelled input. Empty / unset → no `for` attr. */
1541
1624
  for?: string;
1542
1625
  /** Caller-supplied extra class. The Comptoir `.ef-label` class is
@@ -1550,7 +1633,7 @@ declare class EfLabelComponent {
1550
1633
  * binding replaces (doesn't merge) so we do the joining here. */
1551
1634
  get resolvedClass(): string;
1552
1635
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfLabelComponent, never>;
1553
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfLabelComponent, "ef-label", never, { "label": { "alias": "label"; "required": false; }; "labelKey": { "alias": "labelKey"; "required": false; }; "for": { "alias": "for"; "required": false; }; "styleClass": { "alias": "styleClass"; "required": false; }; "required": { "alias": "required"; "required": false; }; }, {}, never, never, true, never>;
1636
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfLabelComponent, "ef-label", never, { "label": { "alias": "label"; "required": false; }; "labelKey": { "alias": "labelKey"; "required": false; }; "labelParams": { "alias": "labelParams"; "required": false; }; "for": { "alias": "for"; "required": false; }; "styleClass": { "alias": "styleClass"; "required": false; }; "required": { "alias": "required"; "required": false; }; }, {}, never, never, true, never>;
1554
1637
  static ngAcceptInputType_required: unknown;
1555
1638
  }
1556
1639
 
@@ -1656,11 +1739,11 @@ declare class EfBadgeComponent {
1656
1739
  /**
1657
1740
  * Badge label text
1658
1741
  */
1659
- label: _angular_core.InputSignal<string>;
1742
+ label: _angular_core.InputSignal<string | undefined>;
1660
1743
  /**
1661
1744
  * Translation key for the label; wins over `label`.
1662
1745
  */
1663
- labelKey: _angular_core.InputSignal<string>;
1746
+ labelKey: _angular_core.InputSignal<string | undefined>;
1664
1747
  /**
1665
1748
  * Opt in to the pointer cursor and hover lift. Off by default so a
1666
1749
  * read-only badge does not look like a button.
@@ -1685,7 +1768,7 @@ declare class EfBadgeComponent {
1685
1768
  /**
1686
1769
  * Icon class (e.g., PrimeIcons)
1687
1770
  */
1688
- icon: _angular_core.InputSignal<string>;
1771
+ icon: _angular_core.InputSignal<string | undefined>;
1689
1772
  /**
1690
1773
  * Whether to show the dot indicator
1691
1774
  */
@@ -1818,7 +1901,7 @@ declare class EfAppShellComponent {
1818
1901
  readonly shortcutHint: string;
1819
1902
  toggleSide(): void;
1820
1903
  constructor();
1821
- readonly activeId: _angular_core.Signal<_elasticias_core.EfModuleId>;
1904
+ readonly activeId: _angular_core.Signal<_elasticias_core.EfModuleId | null>;
1822
1905
  readonly switcherOpen: _angular_core.WritableSignal<boolean>;
1823
1906
  /** Five tabs is what fits a phone; the rest live in the sheet. */
1824
1907
  readonly tabs: _angular_core.Signal<EfModule[]>;
@@ -1870,7 +1953,7 @@ declare class EfAppShellMobileComponent {
1870
1953
  private readonly perms;
1871
1954
  private readonly active;
1872
1955
  private readonly router;
1873
- readonly activeId: _angular_core.Signal<_elasticias_core.EfModuleId>;
1956
+ readonly activeId: _angular_core.Signal<_elasticias_core.EfModuleId | null>;
1874
1957
  readonly switcherOpen: _angular_core.WritableSignal<boolean>;
1875
1958
  readonly tabs: _angular_core.Signal<EfModule[]>;
1876
1959
  readonly allVisible: _angular_core.Signal<readonly EfModule[]>;
@@ -1902,7 +1985,7 @@ declare class EfAppMainComponent {
1902
1985
  /** Render the 3px module-color stripe at the top of the content area. */
1903
1986
  stripe: boolean;
1904
1987
  /** `data-module` value bound to the host. Null when no module is active. */
1905
- readonly moduleId: _angular_core.Signal<_elasticias_core.EfModuleId>;
1988
+ readonly moduleId: _angular_core.Signal<_elasticias_core.EfModuleId | null>;
1906
1989
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfAppMainComponent, never>;
1907
1990
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfAppMainComponent, "ef-app-main", never, { "stripe": { "alias": "stripe"; "required": false; }; }, {}, never, ["*"], true, never>;
1908
1991
  static ngAcceptInputType_stripe: unknown;
@@ -1937,7 +2020,7 @@ declare class EfAppTopComponent {
1937
2020
  */
1938
2021
  readonly logout: _angular_core.InputSignalWithTransform<boolean, unknown>;
1939
2022
  /** Present only when the app provides `EF_SESSION`. */
1940
- protected readonly session: _elasticias_core.EfSession;
2023
+ protected readonly session: _elasticias_core.EfSession | null;
1941
2024
  protected signOut(): void;
1942
2025
  /** A touch or pen press at least this long is a hold, not a tap. */
1943
2026
  static readonly HOLD_MS = 500;
@@ -1955,8 +2038,8 @@ declare class EfAppTopComponent {
1955
2038
  protected forgetSignOutPress(): void;
1956
2039
  protected onSignOutClick(event: MouseEvent): void;
1957
2040
  private readonly active;
1958
- readonly module: _angular_core.Signal<_elasticias_core.EfModule>;
1959
- readonly navItem: _angular_core.Signal<_elasticias_core.EfNavItem>;
2041
+ readonly module: _angular_core.Signal<_elasticias_core.EfModule | null>;
2042
+ readonly navItem: _angular_core.Signal<_elasticias_core.EfNavItem | null>;
1960
2043
  readonly hasBreadcrumb: _angular_core.Signal<boolean>;
1961
2044
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfAppTopComponent, never>;
1962
2045
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfAppTopComponent, "ef-app-top", never, { "themeToggle": { "alias": "themeToggle"; "required": false; "isSignal": true; }; "logout": { "alias": "logout"; "required": false; "isSignal": true; }; }, {}, never, ["[breadcrumb]", "[actions]"], true, never>;
@@ -1999,7 +2082,7 @@ declare class EfModuleRailComponent {
1999
2082
  /** Optional notification badges per module id. */
2000
2083
  badges: Partial<Record<EfModuleId, string | number>>;
2001
2084
  readonly visibleModules: _angular_core.Signal<readonly EfModule[]>;
2002
- readonly activeId: _angular_core.Signal<EfModuleId>;
2085
+ readonly activeId: _angular_core.Signal<EfModuleId | null>;
2003
2086
  /** Visible modules interleaved with dividers at group boundaries. */
2004
2087
  readonly rows: _angular_core.Signal<RailRow[]>;
2005
2088
  readonly hasBadges: _angular_core.Signal<boolean>;
@@ -2022,8 +2105,8 @@ declare class EfModuleRailComponent {
2022
2105
  declare class EfModuleSideComponent {
2023
2106
  private readonly active;
2024
2107
  private readonly perms;
2025
- readonly module: _angular_core.Signal<_elasticias_core.EfModule>;
2026
- readonly moduleId: _angular_core.Signal<_elasticias_core.EfModuleId>;
2108
+ readonly module: _angular_core.Signal<_elasticias_core.EfModule | null>;
2109
+ readonly moduleId: _angular_core.Signal<_elasticias_core.EfModuleId | null>;
2027
2110
  readonly visibleSections: _angular_core.Signal<EfNavSection[]>;
2028
2111
  trackSection(_: number, s: EfNavSection): string;
2029
2112
  trackItem(_: number, i: EfNavItem): string;
@@ -2128,8 +2211,15 @@ interface EfPillItem<T = string> {
2128
2211
  */
2129
2212
  declare class EfPillGroupComponent<T = string> {
2130
2213
  readonly items: _angular_core.InputSignal<readonly EfPillItem<T>[]>;
2131
- /** Two-way bound selection. */
2132
- readonly value: _angular_core.ModelSignal<T>;
2214
+ /** Selected value; `null` when nothing is selected. Two-way bindable
2215
+ * with `[(value)]`. */
2216
+ readonly value: _angular_core.InputSignal<T | null>;
2217
+ /** Emits the picked pill's value. Never `null`: a click always picks
2218
+ * a pill, so handlers can take `T` without a null check. */
2219
+ readonly valueChange: _angular_core.OutputEmitterRef<T>;
2220
+ /** What the pills render: the bound value, or the last pick when the
2221
+ * caller only listens to `valueChange`. */
2222
+ protected readonly selected: _angular_core.WritableSignal<T | null>;
2133
2223
  /** Translation key for the group's accessible name. */
2134
2224
  readonly ariaLabelKey: _angular_core.InputSignal<string>;
2135
2225
  /** Hide counts even when items provide them. */
@@ -2149,7 +2239,7 @@ declare class EfPillGroupComponent<T = string> {
2149
2239
  private measure;
2150
2240
  private scrollActiveIntoView;
2151
2241
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfPillGroupComponent<any>, never>;
2152
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfPillGroupComponent<any>, "ef-pill-group", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "ariaLabelKey": { "alias": "ariaLabelKey"; "required": false; "isSignal": true; }; "hideCounts": { "alias": "hideCounts"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
2242
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfPillGroupComponent<any>, "ef-pill-group", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "ariaLabelKey": { "alias": "ariaLabelKey"; "required": false; "isSignal": true; }; "hideCounts": { "alias": "hideCounts"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
2153
2243
  }
2154
2244
 
2155
2245
  /** Visual treatment of the tabset. `'pill'` is the default. */
@@ -2228,7 +2318,10 @@ declare class EfTabsComponent<T = string> implements AfterContentInit {
2228
2318
  overflow: boolean;
2229
2319
  /** Hide count badges even when items provide them. */
2230
2320
  hideCounts: boolean;
2321
+ /** Untranslated accessible name of the tablist. Prefer `ariaLabelKey`. */
2231
2322
  ariaLabel: string;
2323
+ /** Translation key for the tablist's accessible name; wins over `ariaLabel`. */
2324
+ ariaLabelKey?: string;
2232
2325
  /** Translation key used as the `aria-label` of the dirty dot.
2233
2326
  * Defaults to `'common.dirty'` — apps add the matching entry to
2234
2327
  * `fr.json` / `ar.json`. */
@@ -2249,7 +2342,7 @@ declare class EfTabsComponent<T = string> implements AfterContentInit {
2249
2342
  onKeydown(event: KeyboardEvent, index: number): void;
2250
2343
  trackValue(_: number, item: EfTabItem<T>): T;
2251
2344
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfTabsComponent<any>, never>;
2252
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfTabsComponent<any>, "ef-tabs", never, { "items": { "alias": "items"; "required": true; }; "value": { "alias": "value"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "module": { "alias": "module"; "required": false; }; "overflow": { "alias": "overflow"; "required": false; }; "hideCounts": { "alias": "hideCounts"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "dirtyLabelKey": { "alias": "dirtyLabelKey"; "required": false; }; }, { "valueChange": "valueChange"; }, ["panels"], never, true, never>;
2345
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfTabsComponent<any>, "ef-tabs", never, { "items": { "alias": "items"; "required": true; }; "value": { "alias": "value"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "module": { "alias": "module"; "required": false; }; "overflow": { "alias": "overflow"; "required": false; }; "hideCounts": { "alias": "hideCounts"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "ariaLabelKey": { "alias": "ariaLabelKey"; "required": false; }; "dirtyLabelKey": { "alias": "dirtyLabelKey"; "required": false; }; }, { "valueChange": "valueChange"; }, ["panels"], never, true, never>;
2253
2346
  static ngAcceptInputType_overflow: unknown;
2254
2347
  static ngAcceptInputType_hideCounts: unknown;
2255
2348
  }
@@ -2479,7 +2572,7 @@ declare class EfPulseComponent {
2479
2572
  declare class EfPdfPreviewComponent {
2480
2573
  private readonly sanitizer;
2481
2574
  /** The PDF blob to preview. Setting it (re)creates the object URL. */
2482
- blob: _angular_core.InputSignal<Blob>;
2575
+ blob: _angular_core.InputSignal<Blob | null>;
2483
2576
  /** File name shown in the header + used for download / share. */
2484
2577
  fileName: _angular_core.InputSignal<string>;
2485
2578
  /** Two-way dialog visibility. */
@@ -2491,11 +2584,16 @@ declare class EfPdfPreviewComponent {
2491
2584
  showOpenInNewTab: _angular_core.InputSignalWithTransform<boolean, unknown>;
2492
2585
  /** Show the WhatsApp share button (Web Share API → wa.me fallback). */
2493
2586
  showWhatsappShare: _angular_core.InputSignalWithTransform<boolean, unknown>;
2494
- /** Optional recipient phone for the wa.me fallback (digits / +). */
2587
+ /** Optional recipient phone for the wa.me fallback, as typed: international
2588
+ * (`+`/`00`) or national with `defaultCallingCode`. */
2495
2589
  whatsappPhone: _angular_core.InputSignal<string>;
2590
+ /** Calling code (`'212'` or `'+212'`) that turns a national
2591
+ * `whatsappPhone` (`0612345678`) into the international number wa.me
2592
+ * needs. Without it a national number opens the contact picker. */
2593
+ defaultCallingCode: _angular_core.InputSignal<string>;
2496
2594
  private readonly objectUrl;
2497
2595
  private currentUrl;
2498
- readonly safeUrl: _angular_core.Signal<SafeResourceUrl>;
2596
+ readonly safeUrl: _angular_core.Signal<SafeResourceUrl | null>;
2499
2597
  /** Footer buttons, rendered by `ef-dialog`'s `[actions]`. `dismiss:false`
2500
2598
  * keeps the preview open after download/print/share/open. */
2501
2599
  readonly actions: _angular_core.Signal<EfDialogAction[]>;
@@ -2508,7 +2606,56 @@ declare class EfPdfPreviewComponent {
2508
2606
  shareWhatsapp(): void;
2509
2607
  private openWhatsappWeb;
2510
2608
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfPdfPreviewComponent, never>;
2511
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfPdfPreviewComponent, "ef-pdf-preview", never, { "blob": { "alias": "blob"; "required": false; "isSignal": true; }; "fileName": { "alias": "fileName"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "titleKey": { "alias": "titleKey"; "required": false; "isSignal": true; }; "showDownload": { "alias": "showDownload"; "required": false; "isSignal": true; }; "showPrint": { "alias": "showPrint"; "required": false; "isSignal": true; }; "showOpenInNewTab": { "alias": "showOpenInNewTab"; "required": false; "isSignal": true; }; "showWhatsappShare": { "alias": "showWhatsappShare"; "required": false; "isSignal": true; }; "whatsappPhone": { "alias": "whatsappPhone"; "required": false; "isSignal": true; }; }, { "visible": "visibleChange"; }, never, never, true, never>;
2609
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfPdfPreviewComponent, "ef-pdf-preview", never, { "blob": { "alias": "blob"; "required": false; "isSignal": true; }; "fileName": { "alias": "fileName"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "titleKey": { "alias": "titleKey"; "required": false; "isSignal": true; }; "showDownload": { "alias": "showDownload"; "required": false; "isSignal": true; }; "showPrint": { "alias": "showPrint"; "required": false; "isSignal": true; }; "showOpenInNewTab": { "alias": "showOpenInNewTab"; "required": false; "isSignal": true; }; "showWhatsappShare": { "alias": "showWhatsappShare"; "required": false; "isSignal": true; }; "whatsappPhone": { "alias": "whatsappPhone"; "required": false; "isSignal": true; }; "defaultCallingCode": { "alias": "defaultCallingCode"; "required": false; "isSignal": true; }; }, { "visible": "visibleChange"; }, never, never, true, never>;
2610
+ }
2611
+
2612
+ /**
2613
+ * Shows a complete HTML document (an email template, rendered with sample
2614
+ * data) inside a frame that cannot act.
2615
+ *
2616
+ * The frame's `sandbox` attribute is written in the template and empty, and
2617
+ * no input reaches it: the document runs no script, has an opaque origin
2618
+ * (no cookies, no storage, no access to the parent), cannot submit a form,
2619
+ * open a popup or navigate the top window. The document comes from
2620
+ * `srcdoc`, so there is no URL to load and no new origin for the CSP; it
2621
+ * inherits the host page's policy, whose `style-src 'unsafe-inline'` lets
2622
+ * the template's own styles apply.
2623
+ *
2624
+ * The frame always has an accessible name (WCAG 4.1.2): `titleKey`, or the
2625
+ * shared `ef_html_preview_title` key when none is given. Consuming apps define it:
2626
+ * fr "Aperçu", ar "معاينة", en "Preview".
2627
+ *
2628
+ * `width: 100%` and `min-width: 0` keep a 600px email table scrolling inside
2629
+ * the frame on a phone instead of widening the page.
2630
+ *
2631
+ * ```html
2632
+ * <ef-html-preview [html]="previewHtml()" titleKey="email_templates_preview_title" [height]="560" />
2633
+ * ```
2634
+ */
2635
+ /** The title key the frame falls back to; apps add it to fr.json, ar.json and en.json. */
2636
+ declare const EF_HTML_PREVIEW_DEFAULT_TITLE_KEY = "ef_html_preview_title";
2637
+ declare class EfHtmlPreviewComponent {
2638
+ /** The full document to show. Sanitized by the server before it gets here. */
2639
+ readonly html: _angular_core.InputSignal<string>;
2640
+ /** i18n key of the frame's accessible title; `ef_html_preview_title` when empty. */
2641
+ readonly titleKey: _angular_core.InputSignal<string>;
2642
+ /** Frame height in pixels. */
2643
+ readonly height: _angular_core.InputSignal<number>;
2644
+ private readonly sanitizer;
2645
+ protected readonly effectiveTitleKey: _angular_core.Signal<string>;
2646
+ /**
2647
+ * Angular's sanitizer strips every `style` attribute and `<style>` block
2648
+ * from a bound `srcdoc`, which would preview an email without its
2649
+ * layout, so the HTML is trusted explicitly. The guarantee is the frame's
2650
+ * empty sandbox: nothing in the document can run, submit, open a window
2651
+ * or reach this page, even for raw author HTML of an unsaved edit. The
2652
+ * server's sanitization of stored templates is a second layer, not the
2653
+ * reason this is safe. Never reuse this bypass for markup rendered
2654
+ * outside such a frame.
2655
+ */
2656
+ protected readonly trustedHtml: _angular_core.Signal<SafeHtml>;
2657
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfHtmlPreviewComponent, never>;
2658
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfHtmlPreviewComponent, "ef-html-preview", never, { "html": { "alias": "html"; "required": false; "isSignal": true; }; "titleKey": { "alias": "titleKey"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2512
2659
  }
2513
2660
 
2514
2661
  /**
@@ -2884,13 +3031,19 @@ interface EfRowAction {
2884
3031
  * ```
2885
3032
  *
2886
3033
  * Phone overflow: on the mobile tier, when the visible actions (custom and
2887
- * standard, Save included) outnumber `[overflowAfter]`, Save stays in view
2888
- * and every other action moves into a kebab menu (`ef-row-actions`, so it is
3034
+ * standard, Save included) outnumber `[overflowAfter]`, Save and any custom
3035
+ * action flagged `keepInView` stay in view and every other action moves
3036
+ * into a kebab menu (`ef-row-actions`, so it is
2889
3037
  * a `role="menu"` with Escape, outside-click and RTL placement). The split
2890
3038
  * happens after permission and `requiresWrite` filtering, so a hidden action
2891
3039
  * is hidden in the menu too. The projected `[actions]` slot is not moved.
2892
3040
  * Buttons are 48px on a coarse pointer (see `.detail-toolbar` in patterns).
2893
3041
  *
3042
+ * Tablet and desktop reflow: the identity has a basis
3043
+ * (`--detail-toolbar-identity-min`, 22rem), so when it and the actions
3044
+ * cannot share a row the actions wrap below it, rather than squeezing the
3045
+ * identity until its notices are cut.
3046
+ *
2894
3047
  * Custom actions can declare `permission` and `visible` like
2895
3048
  * `EfRowAction`. With `[context]` bound, the toolbar filters them
2896
3049
  * against `ScreenContext.isGranted()` automatically.
@@ -2910,7 +3063,7 @@ declare class EfDetailToolbarComponent {
2910
3063
  /** Optional ScreenContext — when present, custom actions with a
2911
3064
  * `permission` field and standard actions Print / Duplicate /
2912
3065
  * Delete are filtered against `context.isGranted(...)`. */
2913
- readonly context: _angular_core.InputSignal<ScreenContext>;
3066
+ readonly context: _angular_core.InputSignal<ScreenContext | undefined>;
2914
3067
  /** Render the standard Print action (left of the standard group). */
2915
3068
  readonly showPrintAction: _angular_core.InputSignalWithTransform<boolean, unknown>;
2916
3069
  /** Render the standard Duplicate action. */
@@ -2951,10 +3104,21 @@ declare class EfDetailToolbarComponent {
2951
3104
  readonly hasCustomActions: _angular_core.Signal<boolean>;
2952
3105
  /** The phone is showing the overflow menu instead of inline buttons. */
2953
3106
  readonly overflowing: _angular_core.Signal<boolean>;
2954
- /** Everything but Save, as menu items, in toolbar order. */
3107
+ /** Visible custom actions that stay inline on a phone even when the rest overflow. */
3108
+ readonly keptInView: _angular_core.Signal<readonly EfDetailToolbarAction[]>;
3109
+ /** Everything but Save and the keepInView actions, as menu items, in toolbar order. */
2955
3110
  readonly overflowItems: _angular_core.Signal<readonly EfRowAction[]>;
2956
3111
  /** Whether the `|` separator should render — both groups present. */
2957
3112
  readonly showSeparator: _angular_core.Signal<boolean>;
3113
+ private readonly host;
3114
+ private readonly destroyRef;
3115
+ /** The standard group (separator, Print … Save) starts a row of its own,
3116
+ * below the custom actions: its leading separator would separate nothing. */
3117
+ readonly standardWrapped: _angular_core.WritableSignal<boolean>;
3118
+ constructor();
3119
+ /** Compares the standard group's row with the first item of the right
3120
+ * group. Public for specs: jsdom lays nothing out. */
3121
+ measureWrap(): void;
2958
3122
  onCustomClick(action: EfDetailToolbarAction): void;
2959
3123
  private isCustomVisible;
2960
3124
  /** Standard action visibility: `show*Action` flag AND permission
@@ -3016,7 +3180,7 @@ declare class EfSearchToolbarComponent {
3016
3180
  /** Optional ScreenContext — when present, custom actions with a
3017
3181
  * `permission` field and standard actions Export / Add are
3018
3182
  * filtered against `context.isGranted(...)`. */
3019
- readonly context: _angular_core.InputSignal<ScreenContext>;
3183
+ readonly context: _angular_core.InputSignal<ScreenContext | undefined>;
3020
3184
  /** Render the standard Export action (left of the standard group). */
3021
3185
  readonly showExportAction: _angular_core.InputSignalWithTransform<boolean, unknown>;
3022
3186
  /** Render the standard Add action (rightmost, tenant-styled). */
@@ -3101,7 +3265,7 @@ interface EfTotalsGrand {
3101
3265
  */
3102
3266
  declare class EfTotalsComponent {
3103
3267
  readonly rows: _angular_core.InputSignal<readonly EfTotalsRow[]>;
3104
- readonly grand: _angular_core.InputSignal<EfTotalsGrand>;
3268
+ readonly grand: _angular_core.InputSignal<EfTotalsGrand | undefined>;
3105
3269
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfTotalsComponent, never>;
3106
3270
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfTotalsComponent, "ef-totals", never, { "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "grand": { "alias": "grand"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3107
3271
  }
@@ -3209,6 +3373,19 @@ interface OpMeta {
3209
3373
  * ```html
3210
3374
  * <ef-change-history [entries]="auditEntries()" />
3211
3375
  * ```
3376
+ *
3377
+ * Values are shown raw by default (`Received → Confirmed`). To show a field's
3378
+ * values translated, pass `valueLists`: a map of field path to the
3379
+ * `{ code, label }` items of a reference list. Each old/new value that matches
3380
+ * an item `code` (case-insensitive) is shown as its `label` (translated when
3381
+ * the label is an i18n key); anything unmatched stays raw. The reserved key
3382
+ * `status` maps the `fromStatus` / `toStatus` of status-change entries.
3383
+ * On a V2 detail screen, `AbstractDetailScreenV2.auditValueLists()` builds this
3384
+ * map from `ScreenConfig.AUDIT_VALUE_LISTS`.
3385
+ *
3386
+ * ```html
3387
+ * <ef-change-history [entries]="auditEntries()" [valueLists]="auditValueLists()" />
3388
+ * ```
3212
3389
  */
3213
3390
  declare class EfChangeHistoryComponent {
3214
3391
  private readonly translate;
@@ -3224,6 +3401,14 @@ declare class EfChangeHistoryComponent {
3224
3401
  readonly collapsible: _angular_core.InputSignal<boolean>;
3225
3402
  /** Initial collapsed state — expanded by default. */
3226
3403
  readonly startCollapsed: _angular_core.InputSignal<boolean>;
3404
+ /** Optional field path to reference items, used to show a field's raw
3405
+ * old/new values as translated labels. Unmapped fields and unmatched
3406
+ * values stay raw. Key `status` covers `fromStatus` / `toStatus`. */
3407
+ readonly valueLists: _angular_core.InputSignal<Readonly<Record<string, readonly EfChangeHistoryValueItem[]>> | null>;
3408
+ /** Optional formatter for an entry's free-text note. Return the text to show,
3409
+ * or null to keep the raw note. Rendered as plain text (never HTML). A
3410
+ * screen uses it to translate coded notes such as `order_email_resent:order_confirmed`. */
3411
+ readonly noteFormatter: _angular_core.InputSignal<((note: string) => string | null) | null>;
3227
3412
  /** "Show more" dialog visibility. */
3228
3413
  readonly dialogVisible: _angular_core.WritableSignal<boolean>;
3229
3414
  /** First `previewLimit` rows shown inline in the card. */
@@ -3245,6 +3430,11 @@ declare class EfChangeHistoryComponent {
3245
3430
  * (`clientCode` → "Client code"), so new entities/fields work with zero
3246
3431
  * i18n maintenance. Add a key only for a properly localized (fr/ar) term. */
3247
3432
  fieldLabel(field: string | undefined): string;
3433
+ /** The note as shown: the formatter's text, else the raw note. */
3434
+ noteText(note: string | null | undefined): string;
3435
+ /** Display value for a field's raw value: the matching list item's label
3436
+ * (translated when it is an i18n key), else the raw value. */
3437
+ valueLabel(field: string | undefined, value: string | null | undefined): string;
3248
3438
  /** Returns the translation when present, otherwise a humanized fallback of
3249
3439
  * the source token (ngx-translate echoes the key on a miss). */
3250
3440
  private resolveLabel;
@@ -3254,7 +3444,7 @@ declare class EfChangeHistoryComponent {
3254
3444
  * registration (the app's default locale is fr-MA). */
3255
3445
  formatWhen(value: string | Date | null | undefined): string;
3256
3446
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfChangeHistoryComponent, never>;
3257
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfChangeHistoryComponent, "ef-change-history", never, { "entries": { "alias": "entries"; "required": false; "isSignal": true; }; "titleKey": { "alias": "titleKey"; "required": false; "isSignal": true; }; "emptyKey": { "alias": "emptyKey"; "required": false; "isSignal": true; }; "limit": { "alias": "limit"; "required": false; "isSignal": true; }; "previewLimit": { "alias": "previewLimit"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "startCollapsed": { "alias": "startCollapsed"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3447
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfChangeHistoryComponent, "ef-change-history", never, { "entries": { "alias": "entries"; "required": false; "isSignal": true; }; "titleKey": { "alias": "titleKey"; "required": false; "isSignal": true; }; "emptyKey": { "alias": "emptyKey"; "required": false; "isSignal": true; }; "limit": { "alias": "limit"; "required": false; "isSignal": true; }; "previewLimit": { "alias": "previewLimit"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "startCollapsed": { "alias": "startCollapsed"; "required": false; "isSignal": true; }; "valueLists": { "alias": "valueLists"; "required": false; "isSignal": true; }; "noteFormatter": { "alias": "noteFormatter"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3258
3448
  }
3259
3449
 
3260
3450
  /**
@@ -3320,7 +3510,7 @@ declare class EfKpiCardComponent {
3320
3510
  /** Computed `points="x,y x,y …"` attribute, normalized into the
3321
3511
  * 200×28 viewBox so the polyline always fits. Returns null
3322
3512
  * when the series is empty. */
3323
- readonly sparkPoints: _angular_core.Signal<string>;
3513
+ readonly sparkPoints: _angular_core.Signal<string | null>;
3324
3514
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfKpiCardComponent, never>;
3325
3515
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfKpiCardComponent, "ef-kpi-card", never, { "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; "delta": { "alias": "delta"; "required": false; "isSignal": true; }; "deltaTone": { "alias": "deltaTone"; "required": false; "isSignal": true; }; "hintKey": { "alias": "hintKey"; "required": false; "isSignal": true; }; "hintParams": { "alias": "hintParams"; "required": false; "isSignal": true; }; "spark": { "alias": "spark"; "required": false; "isSignal": true; }; "sparkColor": { "alias": "sparkColor"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3326
3516
  }
@@ -3400,8 +3590,8 @@ type EfIdentityThumbSize = 'sm' | 'md';
3400
3590
  * ```
3401
3591
  */
3402
3592
  declare class EfIdentityThumbComponent {
3403
- readonly imageUrl: _angular_core.InputSignal<string>;
3404
- readonly name: _angular_core.InputSignal<string>;
3593
+ readonly imageUrl: _angular_core.InputSignal<string | null | undefined>;
3594
+ readonly name: _angular_core.InputSignal<string | null | undefined>;
3405
3595
  readonly size: _angular_core.InputSignal<EfIdentityThumbSize>;
3406
3596
  /** Set when the image fails; reset whenever the url changes. */
3407
3597
  protected readonly failed: _angular_core.WritableSignal<boolean>;
@@ -3437,18 +3627,18 @@ declare class EfIdentityThumbComponent {
3437
3627
  */
3438
3628
  declare class EfSeoPreviewComponent {
3439
3629
  /** The page title. Named `pageTitle` so it does not become the host's tooltip. */
3440
- readonly pageTitle: _angular_core.InputSignal<string>;
3630
+ readonly pageTitle: _angular_core.InputSignal<string | null | undefined>;
3441
3631
  /** The address as shown (no scheme needed), always rendered left to right. */
3442
- readonly url: _angular_core.InputSignal<string>;
3443
- readonly description: _angular_core.InputSignal<string>;
3632
+ readonly url: _angular_core.InputSignal<string | null | undefined>;
3633
+ readonly description: _angular_core.InputSignal<string | null | undefined>;
3444
3634
  /** i18n key of the small heading above the preview. */
3445
3635
  readonly labelKey: _angular_core.InputSignal<string>;
3446
3636
  /** Characters kept of the title; `null` shows it whole. */
3447
- readonly titleMaxLength: _angular_core.InputSignal<number>;
3637
+ readonly titleMaxLength: _angular_core.InputSignal<number | null>;
3448
3638
  /** Characters kept of the description; `null` shows it whole. */
3449
- readonly descriptionMaxLength: _angular_core.InputSignal<number>;
3639
+ readonly descriptionMaxLength: _angular_core.InputSignal<number | null>;
3450
3640
  /** Language of the previewed text (`fr`, `ar`, `en`), for screen readers and hyphenation. */
3451
- readonly contentLang: _angular_core.InputSignal<string>;
3641
+ readonly contentLang: _angular_core.InputSignal<string | null>;
3452
3642
  protected readonly labelId: string;
3453
3643
  protected readonly shownTitle: _angular_core.Signal<string>;
3454
3644
  protected readonly shownUrl: _angular_core.Signal<string>;
@@ -3514,8 +3704,12 @@ declare abstract class AbstractEfFormControl {
3514
3704
  /** Translation key for the label — preferred (memory:
3515
3705
  * feedback_i18n_keys says always use `*Key`). */
3516
3706
  readonly labelKey: _angular_core.InputSignal<string>;
3707
+ /** Interpolation params for `labelKey` (`{{name}}` in the translation). */
3708
+ readonly labelParams: _angular_core.InputSignal<Record<string, unknown> | undefined>;
3517
3709
  readonly placeholder: _angular_core.InputSignal<string>;
3518
3710
  readonly placeholderKey: _angular_core.InputSignal<string>;
3711
+ /** Interpolation params for `placeholderKey` (`{{last4}}` and the like). */
3712
+ readonly placeholderParams: _angular_core.InputSignal<Record<string, unknown> | undefined>;
3519
3713
  /** Short help text shown under the control. Use `hintKey` for i18n. */
3520
3714
  readonly hint: _angular_core.InputSignal<string>;
3521
3715
  /** Translation key for the hint, preferred over `hint`. The hint is
@@ -3524,6 +3718,8 @@ declare abstract class AbstractEfFormControl {
3524
3718
  * Rendered by ef-input-text, ef-textarea, ef-inputnumber and ef-select;
3525
3719
  * the other controls inherit the input but do not render it yet. */
3526
3720
  readonly hintKey: _angular_core.InputSignal<string>;
3721
+ /** Interpolation params for `hintKey`. */
3722
+ readonly hintParams: _angular_core.InputSignal<Record<string, unknown> | undefined>;
3527
3723
  readonly ariaLabel: _angular_core.InputSignal<string>;
3528
3724
  readonly ariaLabelKey: _angular_core.InputSignal<string>;
3529
3725
  readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -3574,7 +3770,7 @@ declare abstract class AbstractEfFormControl {
3574
3770
  * Falls back to the `NgControl` `serverError` path when neither is
3575
3771
  * present, so `ngModel`-based (v1) screens keep working unchanged.
3576
3772
  */
3577
- readonly errors: _angular_core.InputSignal<string[]>;
3773
+ readonly errors: _angular_core.InputSignal<string[] | null | undefined>;
3578
3774
  /** Optional enclosing `[efServerErrors]` scope (auto-link by `name`). */
3579
3775
  private readonly serverErrorsScope;
3580
3776
  /**
@@ -3584,7 +3780,7 @@ declare abstract class AbstractEfFormControl {
3584
3780
  * the subclass `serverErrors` / `isInvalid` getters track the source
3585
3781
  * signals under zoneless change detection.
3586
3782
  */
3587
- readonly resolvedExternalErrors: _angular_core.Signal<string[]>;
3783
+ readonly resolvedExternalErrors: _angular_core.Signal<string[] | null>;
3588
3784
  protected readonly translateService: TranslateService;
3589
3785
  /** Resolved DOM id. Always non-empty so `<label for>` and
3590
3786
  * `<input id>` can match unambiguously. */
@@ -3598,6 +3794,9 @@ declare abstract class AbstractEfFormControl {
3598
3794
  * accessible name and duplicate `aria-label` would override it.
3599
3795
  */
3600
3796
  get effectiveAriaLabel(): string | null;
3797
+ /** Ids of elements outside the control that describe it too (a character
3798
+ * counter, a help block), appended to `aria-describedby`. */
3799
+ readonly describedByExtra: _angular_core.InputSignal<string>;
3601
3800
  /** Translated hint (or empty string). */
3602
3801
  get effectiveHint(): string;
3603
3802
  /** Stable id of the hint element, `<id>-hint`. */
@@ -3614,7 +3813,7 @@ declare abstract class AbstractEfFormControl {
3614
3813
  * the validation message together with the field name. */
3615
3814
  get errorsId(): string;
3616
3815
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AbstractEfFormControl, never>;
3617
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AbstractEfFormControl, "ng-component", never, { "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "placeholderKey": { "alias": "placeholderKey"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "hintKey": { "alias": "hintKey"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelKey": { "alias": "ariaLabelKey"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3816
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AbstractEfFormControl, "ng-component", never, { "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "labelParams": { "alias": "labelParams"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "placeholderKey": { "alias": "placeholderKey"; "required": false; "isSignal": true; }; "placeholderParams": { "alias": "placeholderParams"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "hintKey": { "alias": "hintKey"; "required": false; "isSignal": true; }; "hintParams": { "alias": "hintParams"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelKey": { "alias": "ariaLabelKey"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "describedByExtra": { "alias": "describedByExtra"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3618
3817
  }
3619
3818
 
3620
3819
  declare class EfInputTextComponent extends AbstractEfFormControl implements ControlValueAccessor {
@@ -3624,6 +3823,11 @@ declare class EfInputTextComponent extends AbstractEfFormControl implements Cont
3624
3823
  fluid: boolean;
3625
3824
  inline: boolean;
3626
3825
  autocomplete?: string;
3826
+ /** Direction of the typed value, applied to the native input. Use
3827
+ * `'ltr'` for IBAN / RIB / phone values on an Arabic screen, `'auto'` to
3828
+ * follow the value's first strong character. The label and messages keep
3829
+ * the page direction. Null or absent leaves the input unchanged. */
3830
+ dir: 'ltr' | 'rtl' | 'auto' | null;
3627
3831
  /** Clearable (showClear / canClear) is inherited from AbstractEfFormControl;
3628
3832
  * we only supply the value predicate + the reset. */
3629
3833
  protected get hasValue(): boolean;
@@ -3652,7 +3856,8 @@ declare class EfInputTextComponent extends AbstractEfFormControl implements Cont
3652
3856
  value: string;
3653
3857
  private onChange;
3654
3858
  private onTouched;
3655
- readonly ngControl: NgControl;
3859
+ readonly ngControl: NgControl | null;
3860
+ private readonly hostRef;
3656
3861
  constructor();
3657
3862
  get showRequired(): boolean;
3658
3863
  get serverErrors(): string[] | null;
@@ -3662,9 +3867,25 @@ declare class EfInputTextComponent extends AbstractEfFormControl implements Cont
3662
3867
  registerOnTouched(fn: () => void): void;
3663
3868
  setDisabledState(isDisabled: boolean): void;
3664
3869
  handleInput(value: string): void;
3870
+ /** Set once the field itself has had focus; see {@link insertAtSelection}. */
3871
+ private wasFocused;
3872
+ protected markFocused(event: FocusEvent): void;
3873
+ /**
3874
+ * Inserts `text` at the caret (replacing a selection), or at the end when
3875
+ * the field was never focused, then puts the caret after it. Emits the
3876
+ * change once, exactly as typing would. Does nothing when read-only or
3877
+ * disabled, and refuses the whole insert when the result would pass
3878
+ * `maxlength` (a cut placeholder token is worse than none).
3879
+ *
3880
+ * The value is written programmatically, so the browser's undo history for
3881
+ * the field is reset and no DOM `input` event fires; the form control
3882
+ * (`onChange`) and `valueChangeEvent` are the contract.
3883
+ */
3884
+ insertAtCursor(text: string): void;
3885
+ private nativeField;
3665
3886
  handleBlur(): void;
3666
3887
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfInputTextComponent, never>;
3667
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfInputTextComponent, "ef-input-text", never, { "size": { "alias": "size"; "required": false; }; "type": { "alias": "type"; "required": false; }; "maxlength": { "alias": "maxlength"; "required": false; }; "fluid": { "alias": "fluid"; "required": false; }; "inline": { "alias": "inline"; "required": false; }; "autocomplete": { "alias": "autocomplete"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "prefix": { "alias": "prefix"; "required": false; }; "suffix": { "alias": "suffix"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, { "valueChangeEvent": "valueChangeEvent"; }, never, never, true, never>;
3888
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfInputTextComponent, "ef-input-text", never, { "size": { "alias": "size"; "required": false; }; "type": { "alias": "type"; "required": false; }; "maxlength": { "alias": "maxlength"; "required": false; }; "fluid": { "alias": "fluid"; "required": false; }; "inline": { "alias": "inline"; "required": false; }; "autocomplete": { "alias": "autocomplete"; "required": false; }; "dir": { "alias": "dir"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "prefix": { "alias": "prefix"; "required": false; }; "suffix": { "alias": "suffix"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, { "valueChangeEvent": "valueChangeEvent"; }, never, never, true, never>;
3668
3889
  static ngAcceptInputType_fluid: unknown;
3669
3890
  static ngAcceptInputType_inline: unknown;
3670
3891
  }
@@ -3937,7 +4158,7 @@ declare class EfCheckboxComponent extends AbstractEfFormControl implements Contr
3937
4158
  checkedChange: EventEmitter<any>;
3938
4159
  private onChange;
3939
4160
  private onTouched;
3940
- readonly ngControl: NgControl;
4161
+ readonly ngControl: NgControl | null;
3941
4162
  constructor();
3942
4163
  get showRequired(): boolean;
3943
4164
  get serverErrors(): string[] | null;
@@ -3991,7 +4212,7 @@ declare class EfToggleSwitchComponent extends AbstractEfFormControl implements C
3991
4212
  checkedChange: EventEmitter<boolean>;
3992
4213
  private onChange;
3993
4214
  private onTouched;
3994
- readonly ngControl: NgControl;
4215
+ readonly ngControl: NgControl | null;
3995
4216
  constructor();
3996
4217
  writeValue(value: unknown): void;
3997
4218
  registerOnChange(fn: (value: boolean) => void): void;
@@ -4053,7 +4274,7 @@ declare class EfDatepickerComponent implements ControlValueAccessor {
4053
4274
  value: any;
4054
4275
  private onChange;
4055
4276
  private onTouched;
4056
- readonly ngControl: NgControl;
4277
+ readonly ngControl: NgControl | null;
4057
4278
  private readonly translateService;
4058
4279
  constructor();
4059
4280
  get effectivePlaceholder(): string;
@@ -4194,7 +4415,7 @@ declare class EfInputNumberComponent extends AbstractEfFormControl implements Co
4194
4415
  get displayText(): string | number;
4195
4416
  private onChange;
4196
4417
  private onTouched;
4197
- readonly ngControl: NgControl;
4418
+ readonly ngControl: NgControl | null;
4198
4419
  private readonly localeId;
4199
4420
  private readonly cdr;
4200
4421
  constructor();
@@ -4252,6 +4473,15 @@ declare class EfPasswordComponent extends AbstractEfFormControl implements Contr
4252
4473
  toggleMask: boolean;
4253
4474
  feedback: boolean;
4254
4475
  autocomplete?: string;
4476
+ /**
4477
+ * Rendering variant, as `ef-input-text`. `'comptoir'` skins the PrimeNG
4478
+ * input to the native `.ef-input` look (--hit-field height, --r-md radius,
4479
+ * 12px padding, --paper-alt fill) so it lines up with the comptoir inputs
4480
+ * beside it; the show/hide toggle becomes a --hit-field square target.
4481
+ * `'primeng'` (default) keeps the stock PrimeNG look.
4482
+ */
4483
+ variant: 'primeng' | 'comptoir';
4484
+ get fieldStyleClass(): string;
4255
4485
  /**
4256
4486
  * Take focus on load. Bound explicitly rather than left unset: PrimeNG's
4257
4487
  * AutoFocus directive tests `autofocus === false`, and the control declares
@@ -4266,7 +4496,8 @@ declare class EfPasswordComponent extends AbstractEfFormControl implements Contr
4266
4496
  value: string;
4267
4497
  private onChange;
4268
4498
  private onTouched;
4269
- readonly ngControl: NgControl;
4499
+ readonly ngControl: NgControl | null;
4500
+ private readonly host;
4270
4501
  constructor();
4271
4502
  get showRequired(): boolean;
4272
4503
  get serverErrors(): string[] | null;
@@ -4281,7 +4512,7 @@ declare class EfPasswordComponent extends AbstractEfFormControl implements Contr
4281
4512
  handleChange(value: string): void;
4282
4513
  handleBlur(): void;
4283
4514
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfPasswordComponent, never>;
4284
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfPasswordComponent, "ef-password", never, { "size": { "alias": "size"; "required": false; }; "fluid": { "alias": "fluid"; "required": false; }; "inline": { "alias": "inline"; "required": false; }; "toggleMask": { "alias": "toggleMask"; "required": false; }; "feedback": { "alias": "feedback"; "required": false; }; "autocomplete": { "alias": "autocomplete"; "required": false; }; "autofocus": { "alias": "autofocus"; "required": false; }; }, { "valueChangeEvent": "valueChangeEvent"; }, never, never, true, never>;
4515
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfPasswordComponent, "ef-password", never, { "size": { "alias": "size"; "required": false; }; "fluid": { "alias": "fluid"; "required": false; }; "inline": { "alias": "inline"; "required": false; }; "toggleMask": { "alias": "toggleMask"; "required": false; }; "feedback": { "alias": "feedback"; "required": false; }; "autocomplete": { "alias": "autocomplete"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "autofocus": { "alias": "autofocus"; "required": false; }; }, { "valueChangeEvent": "valueChangeEvent"; }, never, never, true, never>;
4285
4516
  static ngAcceptInputType_fluid: unknown;
4286
4517
  static ngAcceptInputType_inline: unknown;
4287
4518
  static ngAcceptInputType_toggleMask: unknown;
@@ -4306,7 +4537,7 @@ declare class EfMultiSelectComponent extends AbstractEfFormControl implements Co
4306
4537
  selectedValues: any[];
4307
4538
  private propagateChange;
4308
4539
  private propagateTouched;
4309
- readonly ngControl: NgControl;
4540
+ readonly ngControl: NgControl | null;
4310
4541
  constructor();
4311
4542
  get showRequired(): boolean;
4312
4543
  get serverErrors(): string[] | null;
@@ -4335,7 +4566,7 @@ declare class EfSelectButtonComponent extends AbstractEfFormControl implements C
4335
4566
  value: any;
4336
4567
  private onChange;
4337
4568
  private onTouched;
4338
- readonly ngControl: NgControl;
4569
+ readonly ngControl: NgControl | null;
4339
4570
  constructor();
4340
4571
  writeValue(value: any): void;
4341
4572
  registerOnChange(fn: (value: any) => void): void;
@@ -4401,7 +4632,7 @@ declare class EfQuantityStepperComponent implements ControlValueAccessor {
4401
4632
  /**
4402
4633
  * Callback to invoke when the value changes
4403
4634
  */
4404
- valueChange: EventEmitter<number>;
4635
+ valueChange: EventEmitter<number | null>;
4405
4636
  /**
4406
4637
  * Pass Through configuration for custom styling
4407
4638
  */
@@ -4634,23 +4865,23 @@ declare class EfDatatableComponent implements OnInit {
4634
4865
  /**
4635
4866
  * Action column configuration (edit/delete/duplicate buttons)
4636
4867
  */
4637
- actions: _angular_core.InputSignal<EfDatatableActions>;
4868
+ actions: _angular_core.InputSignal<EfDatatableActions | undefined>;
4638
4869
  /**
4639
4870
  * SearchEntity containing items, pagination, etc.
4640
4871
  */
4641
- searchEntity: _angular_core.InputSignal<DatatableSearchEntity>;
4872
+ searchEntity: _angular_core.InputSignal<DatatableSearchEntity | undefined>;
4642
4873
  /**
4643
4874
  * ScreenContext for reference data access
4644
4875
  */
4645
- context: _angular_core.InputSignal<ScreenContext>;
4876
+ context: _angular_core.InputSignal<ScreenContext | undefined>;
4646
4877
  /**
4647
4878
  * PassThrough options for deep DOM customization
4648
4879
  */
4649
- pt: _angular_core.InputSignal<Record<string, unknown>>;
4880
+ pt: _angular_core.InputSignal<Record<string, unknown> | undefined>;
4650
4881
  /**
4651
4882
  * Screen state key for state persistence (auto-generates stateKey if not provided in config)
4652
4883
  */
4653
- screenStateKey: _angular_core.InputSignal<string>;
4884
+ screenStateKey: _angular_core.InputSignal<string | undefined>;
4654
4885
  /**
4655
4886
  * Emitted when edit button is clicked (emits row ID)
4656
4887
  */
@@ -4711,7 +4942,7 @@ declare class EfDatatableComponent implements OnInit {
4711
4942
  /**
4712
4943
  * Computed sort field from searchEntity for restoring table state
4713
4944
  */
4714
- sortField: _angular_core.Signal<string>;
4945
+ sortField: _angular_core.Signal<string | undefined>;
4715
4946
  /**
4716
4947
  * Computed sort order from searchEntity for restoring table state
4717
4948
  * 1 = ascending, -1 = descending
@@ -4881,7 +5112,7 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
4881
5112
  private readonly configuredMobileLayout;
4882
5113
  readonly isMobile: _angular_core.Signal<boolean>;
4883
5114
  /** Per-screen override of the app-wide default. */
4884
- readonly mobileLayout: _angular_core.InputSignal<EfDataCardMobileLayout>;
5115
+ readonly mobileLayout: _angular_core.InputSignal<EfDataCardMobileLayout | null>;
4885
5116
  protected readonly effectiveMobileLayout: _angular_core.Signal<EfDataCardMobileLayout>;
4886
5117
  /** Rows currently showing their detail, keyed the same way as trackByRow. */
4887
5118
  private readonly expandedRows;
@@ -4916,8 +5147,8 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
4916
5147
  type?: string;
4917
5148
  }): string;
4918
5149
  private readonly derivedPrimaryId;
4919
- protected readonly primaryColumn: _angular_core.Signal<EfDataCardColumn>;
4920
- protected readonly statusColumn: _angular_core.Signal<EfDataCardColumn>;
5150
+ protected readonly primaryColumn: _angular_core.Signal<EfDataCardColumn | undefined>;
5151
+ protected readonly statusColumn: _angular_core.Signal<EfDataCardColumn | undefined>;
4921
5152
  protected readonly secondaryColumns: _angular_core.Signal<EfDataCardColumn[]>;
4922
5153
  /**
4923
5154
  * Fields shown once a row opens. The primary column is excluded: the
@@ -4951,7 +5182,7 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
4951
5182
  readonly pageSizeOptions: _angular_core.InputSignal<readonly number[]>;
4952
5183
  readonly hidePager: _angular_core.InputSignalWithTransform<boolean, unknown>;
4953
5184
  /** Currently active sort. Header click toggles asc / desc. */
4954
- readonly sort: _angular_core.InputSignal<EfDataCardSort>;
5185
+ readonly sort: _angular_core.InputSignal<EfDataCardSort | undefined>;
4955
5186
  /**
4956
5187
  * First load and every refresh. While true with no rows yet, the body
4957
5188
  * shimmers `ef-skeleton` placeholders instead of the empty state — a
@@ -5020,18 +5251,18 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
5020
5251
  * not have, and `aria-selected` is not allowed on a button. Unset, no
5021
5252
  * attribute is written.
5022
5253
  */
5023
- readonly rowPressed: _angular_core.InputSignal<(row: TRow) => boolean>;
5254
+ readonly rowPressed: _angular_core.InputSignal<((row: TRow) => boolean) | null>;
5024
5255
  /**
5025
5256
  * A row that is shown but cannot be activated (a product already in the
5026
5257
  * collection): `.is-disabled` dims it, `aria-disabled` says so, and
5027
5258
  * click, Enter and Space are ignored. It stays focusable, so a screen
5028
5259
  * reader user can still find it and hear why nothing happens.
5029
5260
  */
5030
- readonly rowDisabled: _angular_core.InputSignal<(row: TRow) => boolean>;
5261
+ readonly rowDisabled: _angular_core.InputSignal<((row: TRow) => boolean) | null>;
5031
5262
  protected pressedAttr(row: TRow): 'true' | 'false' | null;
5032
5263
  protected isRowDisabled(row: TRow): boolean;
5033
5264
  readonly hasActionsColumn: _angular_core.InputSignalWithTransform<boolean, unknown>;
5034
- readonly rowActionsContext: _angular_core.InputSignal<ScreenContext>;
5265
+ readonly rowActionsContext: _angular_core.InputSignal<ScreenContext | undefined>;
5035
5266
  readonly showViewAction: _angular_core.InputSignalWithTransform<boolean, unknown>;
5036
5267
  readonly showEditAction: _angular_core.InputSignalWithTransform<boolean, unknown>;
5037
5268
  readonly showDuplicateAction: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -5049,7 +5280,7 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
5049
5280
  * on desktop rows and phone cards alike. A row whose actions are all
5050
5281
  * hidden gets a disabled trigger. Unset, every row keeps every action.
5051
5282
  */
5052
- readonly rowActionState: _angular_core.InputSignal<(action: EfDataCardRowAction, row: TRow) => EfDataCardRowActionState>;
5283
+ readonly rowActionState: _angular_core.InputSignal<((action: EfDataCardRowAction, row: TRow) => EfDataCardRowActionState) | null>;
5053
5284
  /** Render the Density control in the head row. */
5054
5285
  readonly showDensityControl: _angular_core.InputSignalWithTransform<boolean, unknown>;
5055
5286
  /** Render the Columns picker in the head row. */
@@ -5073,7 +5304,7 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
5073
5304
  * moving Export out of `ef-search-toolbar` does not quietly drop the
5074
5305
  * permission check that lived there.
5075
5306
  */
5076
- readonly screenContext: _angular_core.InputSignal<ScreenContext>;
5307
+ readonly screenContext: _angular_core.InputSignal<ScreenContext | undefined>;
5077
5308
  /**
5078
5309
  * Mirrors `ef-search-toolbar`'s rule exactly: hidden unless asked for,
5079
5310
  * and with a context present it obeys `hasExportPermission`. No
@@ -5139,6 +5370,14 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
5139
5370
  headerTemplate(columnId: string): TemplateRef<unknown> | undefined;
5140
5371
  /** Pluck `column.field` (or `column.id`) from a row, dotted-path safe. */
5141
5372
  cellValue(row: TRow, col: EfDataCardColumn): unknown;
5373
+ /**
5374
+ * Whether a cell has anything to show. The mobile secondary line joins its
5375
+ * parts with a "·" drawn before every part but the first, so an empty part
5376
+ * left a dangling separator; skipping it keeps separators between present
5377
+ * values only. A column with a custom body template is always present (the
5378
+ * template decides what to render); a boolean always renders a glyph.
5379
+ */
5380
+ hasCellContent(row: TRow, col: EfDataCardColumn): boolean;
5142
5381
  headerAlignClass(col: EfDataCardColumn): string;
5143
5382
  cellAlignClass(col: EfDataCardColumn): string;
5144
5383
  /** Sort indicator: '↑' / '↓' / '' for the given column. */
@@ -5154,7 +5393,7 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
5154
5393
  /** Build an Angular DigitInfo string from min/max fraction-digit hints. */
5155
5394
  numberFormat(col: EfDataCardColumn): string;
5156
5395
  /** Which tools panel is open, if any. */
5157
- readonly openTool: _angular_core.WritableSignal<"density" | "columns">;
5396
+ readonly openTool: _angular_core.WritableSignal<"density" | "columns" | null>;
5158
5397
  /**
5159
5398
  * Density this table starts at.
5160
5399
  *
@@ -5178,8 +5417,8 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
5178
5417
  to: number;
5179
5418
  }>;
5180
5419
  /** Index being dragged, and the index it would land on. */
5181
- readonly dragFrom: _angular_core.WritableSignal<number>;
5182
- readonly dragTo: _angular_core.WritableSignal<number>;
5420
+ readonly dragFrom: _angular_core.WritableSignal<number | null>;
5421
+ readonly dragTo: _angular_core.WritableSignal<number | null>;
5183
5422
  onDragPointerDown(index: number, ev: PointerEvent): void;
5184
5423
  onDragPointerMove(ev: PointerEvent): void;
5185
5424
  onDragPointerUp(): void;
@@ -5474,7 +5713,7 @@ declare class EfRowActionsComponent {
5474
5713
  readonly items: _angular_core.InputSignal<readonly EfRowAction[]>;
5475
5714
  /** Optional context — when present, items with a `permission` are
5476
5715
  * filtered against `context.isGranted(permission)`. */
5477
- readonly context: _angular_core.InputSignal<ScreenContext>;
5716
+ readonly context: _angular_core.InputSignal<ScreenContext | undefined>;
5478
5717
  /** Override the trigger icon (default ellipsis). */
5479
5718
  readonly triggerIcon: _angular_core.InputSignal<string>;
5480
5719
  /** Override the trigger aria-label translation key. */
@@ -5541,7 +5780,7 @@ declare class EfRowActionsComponent {
5541
5780
  bottom: string;
5542
5781
  left: string;
5543
5782
  maxHeight: string;
5544
- }>;
5783
+ } | null>;
5545
5784
  /**
5546
5785
  * Fixed rather than absolute: inside ef-data-card the table sits in a
5547
5786
  * horizontal scroller, and `overflow-x: auto` makes the block axis clip
@@ -5763,7 +6002,7 @@ declare class EfSmartBarComponent {
5763
6002
  /** Keyboard shortcut that focuses the search input. `null` opts out
5764
6003
  * (a screen with two smart bars registers the binding on only one
5765
6004
  * of them). Defaults to `'mod+k'`. */
5766
- readonly shortcut: _angular_core.InputSignal<string>;
6005
+ readonly shortcut: _angular_core.InputSignal<string | null>;
5767
6006
  /**
5768
6007
  * Accessible name for the search field: the placeholder text, which
5769
6008
  * already says what this box searches ("Search by order N, customer,
@@ -5828,7 +6067,7 @@ declare class EfFilterPillComponent {
5828
6067
  /** Current value displayed after the label. */
5829
6068
  readonly value: _angular_core.InputSignal<string>;
5830
6069
  /** `'active'` paints ink-active; `'tenant'` paints the tenant-50 surface. */
5831
- readonly tone: _angular_core.InputSignal<"active" | "tenant" | "neutral">;
6070
+ readonly tone: _angular_core.InputSignal<"tenant" | "neutral" | "active">;
5832
6071
  /** Show the ✕ clear button at the end of the pill. */
5833
6072
  readonly hasClear: _angular_core.InputSignalWithTransform<boolean, unknown>;
5834
6073
  /** Show a chevron + position the projected `[popover]` slot. */
@@ -5899,7 +6138,7 @@ declare class EfServerErrorsDirective {
5899
6138
  /** Field-name → messages map (camelCase keys, matching control `name`). */
5900
6139
  readonly errors: _angular_core.InputSignal<{
5901
6140
  [key: string]: string[];
5902
- }>;
6141
+ } | null>;
5903
6142
  /** Messages for a control by its `name`, or `null` when none. */
5904
6143
  errorsFor(name: string | undefined | null): string[] | null;
5905
6144
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfServerErrorsDirective, never>;
@@ -6023,7 +6262,7 @@ declare class EfRadioComponent extends AbstractEfFormControl implements ControlV
6023
6262
  selectionChangeEvent: EventEmitter<any>;
6024
6263
  private onChange;
6025
6264
  private onTouched;
6026
- readonly ngControl: NgControl;
6265
+ readonly ngControl: NgControl | null;
6027
6266
  constructor();
6028
6267
  get hasLabel(): boolean;
6029
6268
  /** Shared `name` so the browser treats the options as one group. */
@@ -6082,7 +6321,8 @@ declare class EfTextareaComponent extends AbstractEfFormControl implements Contr
6082
6321
  clearValue(): void;
6083
6322
  private onChange;
6084
6323
  private onTouched;
6085
- readonly ngControl: NgControl;
6324
+ readonly ngControl: NgControl | null;
6325
+ private readonly hostRef;
6086
6326
  constructor();
6087
6327
  get isInvalid(): boolean;
6088
6328
  get serverErrors(): string[] | null;
@@ -6092,6 +6332,22 @@ declare class EfTextareaComponent extends AbstractEfFormControl implements Contr
6092
6332
  registerOnTouched(fn: () => void): void;
6093
6333
  setDisabledState(isDisabled: boolean): void;
6094
6334
  handleInput(value: string): void;
6335
+ /** Set once the field itself has had focus; see {@link insertAtSelection}. */
6336
+ private wasFocused;
6337
+ protected markFocused(event: FocusEvent): void;
6338
+ /**
6339
+ * Inserts `text` at the caret (replacing a selection), or at the end when
6340
+ * the field was never focused, then puts the caret after it. Emits the
6341
+ * change once, exactly as typing would. Does nothing when read-only or
6342
+ * disabled, and refuses the whole insert when the result would pass
6343
+ * `maxlength` (a cut placeholder token is worse than none).
6344
+ *
6345
+ * The value is written programmatically, so the browser's undo history for
6346
+ * the field is reset and no DOM `input` event fires; the form control
6347
+ * (`onChange`) and `valueChangeEvent` are the contract.
6348
+ */
6349
+ insertAtCursor(text: string): void;
6350
+ private nativeField;
6095
6351
  handleBlur(): void;
6096
6352
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfTextareaComponent, never>;
6097
6353
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfTextareaComponent, "ef-textarea", never, { "rows": { "alias": "rows"; "required": false; }; "maxlength": { "alias": "maxlength"; "required": false; }; "autofocus": { "alias": "autofocus"; "required": false; }; "mono": { "alias": "mono"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, { "valueChangeEvent": "valueChangeEvent"; }, never, never, true, never>;
@@ -6099,6 +6355,65 @@ declare class EfTextareaComponent extends AbstractEfFormControl implements Contr
6099
6355
  static ngAcceptInputType_mono: unknown;
6100
6356
  }
6101
6357
 
6358
+ /** A language the SEO texts are written in. */
6359
+ interface EfSeoLocale {
6360
+ code: string;
6361
+ labelKey: string;
6362
+ dir: 'auto' | 'rtl' | 'ltr';
6363
+ }
6364
+ /** What the fields write back: French is the scalar, every other language a dictionary entry. */
6365
+ interface EfSeoPatch {
6366
+ seoTitle?: string;
6367
+ seoDescription?: string;
6368
+ seoTitleTranslations?: Record<string, string>;
6369
+ seoDescriptionTranslations?: Record<string, string>;
6370
+ }
6371
+ type Field = 'title' | 'description';
6372
+ declare const EF_SEO_DEFAULT_LOCALES: ReadonlyArray<EfSeoLocale>;
6373
+ /**
6374
+ * SEO title and description per language, each with a counter against what a
6375
+ * search engine shows (60 / 160), capped at the server's limits (256 / 512),
6376
+ * and the shared `ef-seo-preview` of the French result with the entity's own
6377
+ * title and description as the fallback the shop uses. Card-less: each screen
6378
+ * wraps it in its own `ef-card`.
6379
+ *
6380
+ * The French controls carry the backend names (`seoTitle`, `seoDescription`)
6381
+ * so `[efServerErrors]` links their errors; the others (`seoTitleAr`, ...) are
6382
+ * dictionary entries whose errors are toasted (ADR-010).
6383
+ *
6384
+ * ```html
6385
+ * <ef-seo-fields [seoTitle]="p.seoTitle" ... [previewUrl]="url()" (seoChange)="patch($event)" />
6386
+ * ```
6387
+ */
6388
+ declare class EfSeoFieldsComponent {
6389
+ readonly seoTitle: _angular_core.InputSignal<string | null | undefined>;
6390
+ readonly seoDescription: _angular_core.InputSignal<string | null | undefined>;
6391
+ readonly seoTitleTranslations: _angular_core.InputSignal<Record<string, string> | null | undefined>;
6392
+ readonly seoDescriptionTranslations: _angular_core.InputSignal<Record<string, string> | null | undefined>;
6393
+ /** The entity's own texts, which the shop uses when SEO is empty. */
6394
+ readonly fallbackTitle: _angular_core.InputSignal<string | null | undefined>;
6395
+ readonly fallbackDescription: _angular_core.InputSignal<string | null | undefined>;
6396
+ /** The page address shown in the preview, computed by the app. */
6397
+ readonly previewUrl: _angular_core.InputSignal<string>;
6398
+ readonly titleMax: _angular_core.InputSignal<number>;
6399
+ readonly descriptionMax: _angular_core.InputSignal<number>;
6400
+ readonly titleAdvised: _angular_core.InputSignal<number>;
6401
+ readonly descriptionAdvised: _angular_core.InputSignal<number>;
6402
+ readonly locales: _angular_core.InputSignal<readonly EfSeoLocale[]>;
6403
+ readonly seoChange: _angular_core.OutputEmitterRef<EfSeoPatch>;
6404
+ text(locale: string, field: Field): string;
6405
+ /** Id of a counter, which the field it counts points at with `aria-describedby`. */
6406
+ counterId(locale: string, field: Field): string;
6407
+ private readonly uid;
6408
+ /** French matches the backend property; the others are unique for the label link. */
6409
+ name(locale: string, field: Field): string;
6410
+ setText(locale: string, field: Field, value: string): void;
6411
+ protected readonly previewTitle: _angular_core.Signal<string>;
6412
+ protected readonly previewDescription: _angular_core.Signal<string>;
6413
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfSeoFieldsComponent, never>;
6414
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfSeoFieldsComponent, "ef-seo-fields", never, { "seoTitle": { "alias": "seoTitle"; "required": false; "isSignal": true; }; "seoDescription": { "alias": "seoDescription"; "required": false; "isSignal": true; }; "seoTitleTranslations": { "alias": "seoTitleTranslations"; "required": false; "isSignal": true; }; "seoDescriptionTranslations": { "alias": "seoDescriptionTranslations"; "required": false; "isSignal": true; }; "fallbackTitle": { "alias": "fallbackTitle"; "required": false; "isSignal": true; }; "fallbackDescription": { "alias": "fallbackDescription"; "required": false; "isSignal": true; }; "previewUrl": { "alias": "previewUrl"; "required": false; "isSignal": true; }; "titleMax": { "alias": "titleMax"; "required": false; "isSignal": true; }; "descriptionMax": { "alias": "descriptionMax"; "required": false; "isSignal": true; }; "titleAdvised": { "alias": "titleAdvised"; "required": false; "isSignal": true; }; "descriptionAdvised": { "alias": "descriptionAdvised"; "required": false; "isSignal": true; }; "locales": { "alias": "locales"; "required": false; "isSignal": true; }; }, { "seoChange": "seoChange"; }, never, never, true, never>;
6415
+ }
6416
+
6102
6417
  type EfFileRejectReason = 'size' | 'type';
6103
6418
  interface EfFileRejection {
6104
6419
  file: File;
@@ -6129,13 +6444,13 @@ interface EfFileRejection {
6129
6444
  */
6130
6445
  declare class EfFileUploadComponent {
6131
6446
  /** Visible label (translation key). Omit for an icon-only button and set `ariaLabelKey`. */
6132
- readonly labelKey: _angular_core.InputSignal<string>;
6133
- readonly ariaLabelKey: _angular_core.InputSignal<string>;
6134
- readonly icon: _angular_core.InputSignal<string>;
6447
+ readonly labelKey: _angular_core.InputSignal<string | undefined>;
6448
+ readonly ariaLabelKey: _angular_core.InputSignal<string | undefined>;
6449
+ readonly icon: _angular_core.InputSignal<string | undefined>;
6135
6450
  readonly severity: _angular_core.InputSignal<"primary" | "danger" | "tenant" | "ghost">;
6136
6451
  /** The `<input accept>` list: MIME types, `type/*` and `.ext`, comma separated. */
6137
- readonly accept: _angular_core.InputSignal<string>;
6138
- readonly maxSizeBytes: _angular_core.InputSignal<number>;
6452
+ readonly accept: _angular_core.InputSignal<string | undefined>;
6453
+ readonly maxSizeBytes: _angular_core.InputSignal<number | undefined>;
6139
6454
  /** Translation key shown when the file is over `maxSizeBytes`. */
6140
6455
  readonly sizeErrorKey: _angular_core.InputSignal<string>;
6141
6456
  /** Translation key shown when the file does not match `accept`. */
@@ -6145,7 +6460,7 @@ declare class EfFileUploadComponent {
6145
6460
  readonly fileRejected: _angular_core.OutputEmitterRef<EfFileRejection>;
6146
6461
  private readonly picker;
6147
6462
  private readonly reason;
6148
- protected readonly errorKey: _angular_core.Signal<string>;
6463
+ protected readonly errorKey: _angular_core.Signal<string | null>;
6149
6464
  protected open(): void;
6150
6465
  protected onChange(event: Event): void;
6151
6466
  private check;
@@ -6188,9 +6503,9 @@ declare class EfPresetPillComponent<T = string> {
6188
6503
  readonly icon: _angular_core.InputSignal<string>;
6189
6504
  readonly labelKey: _angular_core.InputSignal<string>;
6190
6505
  readonly label: _angular_core.InputSignal<string>;
6191
- readonly tone: _angular_core.InputSignal<"active" | "tenant" | "neutral">;
6506
+ readonly tone: _angular_core.InputSignal<"tenant" | "neutral" | "active">;
6192
6507
  readonly presets: _angular_core.InputSignal<readonly EfPresetItem<T>[]>;
6193
- readonly activeKey: _angular_core.ModelSignal<T>;
6508
+ readonly activeKey: _angular_core.ModelSignal<T | null>;
6194
6509
  /** Two-way; consumer can hoist for controlled mode. */
6195
6510
  readonly open: _angular_core.ModelSignal<boolean>;
6196
6511
  /** Auto-close the popover after selection (default on). */
@@ -6269,6 +6584,11 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6269
6584
  private readonly vcr;
6270
6585
  private readonly destroyRef;
6271
6586
  private readonly cdr;
6587
+ private readonly viewport;
6588
+ /** The one picker whose panel is open on the page, if any. A click on
6589
+ * another picker's trigger never reaches the document (the trigger
6590
+ * stops it), so opening a picker closes this one explicitly. */
6591
+ private static openPicker;
6272
6592
  /**
6273
6593
  * Self-injected form control (present only when the consumer binds
6274
6594
  * `[(ngModel)]` / `formControlName` in field mode). We register as its
@@ -6276,7 +6596,7 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6276
6596
  * `NG_VALUE_ACCESSOR` provider is needed and there's no circular DI.
6277
6597
  * `null` in filter mode (the output-only smart-bar usage).
6278
6598
  */
6279
- readonly ngControl: NgControl;
6599
+ readonly ngControl: NgControl | null;
6280
6600
  /** Always-present wrapper — the anchor for portal positioning (the
6281
6601
  * trigger itself lives behind an `@if`, so we anchor to the host box). */
6282
6602
  private anchorEl;
@@ -6285,7 +6605,19 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6285
6605
  /** Active embedded view + its root node, while the panel is open. */
6286
6606
  private panelView;
6287
6607
  private panelRoot;
6288
- private resizeHandler;
6608
+ /** Every root node the panel template rendered (the sheet backdrop too). */
6609
+ private portalNodes;
6610
+ private repositionListener;
6611
+ private resizeObserver;
6612
+ private repositionFrame;
6613
+ /** Phone width (EfViewportService, <= 767px): the panel opens as a
6614
+ * full-width bottom sheet with 48px targets instead of a popover. */
6615
+ readonly sheet: _angular_core.Signal<boolean>;
6616
+ /** The dialog's accessible name: the field's own label in field mode
6617
+ * (the panel no longer repeats it as a visible title), else the
6618
+ * trigger label. */
6619
+ readonly panelLabelKey: _angular_core.Signal<string>;
6620
+ readonly panelLabel: _angular_core.Signal<string>;
6289
6621
  constructor();
6290
6622
  ngAfterViewInit(): void;
6291
6623
  /** Trigger left-side label (translation key). Default: `'filter_date'`. */
@@ -6298,13 +6630,13 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6298
6630
  * `last_90_days`, `this_quarter`, `this_year` — pass anything to
6299
6631
  * replace them outright (e.g. include a `last_year` preset).
6300
6632
  */
6301
- readonly presets: _angular_core.InputSignal<readonly EfDatePreset[]>;
6633
+ readonly presets: _angular_core.InputSignal<readonly EfDatePreset[] | undefined>;
6302
6634
  /** Currently active preset key (controlled). */
6303
- readonly activePreset: _angular_core.InputSignal<string>;
6635
+ readonly activePreset: _angular_core.InputSignal<string | undefined>;
6304
6636
  /** Currently selected start (controlled — pairs with `activePreset`). */
6305
- readonly start: _angular_core.InputSignal<Date>;
6637
+ readonly start: _angular_core.InputSignal<Date | null | undefined>;
6306
6638
  /** Currently selected end. */
6307
- readonly end: _angular_core.InputSignal<Date>;
6639
+ readonly end: _angular_core.InputSignal<Date | null | undefined>;
6308
6640
  /** Show a `'Personnalisé…'` row that opens the calendar view. */
6309
6641
  readonly allowCustomRange: _angular_core.InputSignalWithTransform<boolean, unknown>;
6310
6642
  /**
@@ -6361,8 +6693,8 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6361
6693
  /** Custom view: month being displayed (1st of the month, 00:00). */
6362
6694
  readonly visibleMonth: _angular_core.WritableSignal<Date>;
6363
6695
  /** Custom view: working start/end, before the user clicks Apply. */
6364
- readonly draftStart: _angular_core.WritableSignal<Date>;
6365
- readonly draftEnd: _angular_core.WritableSignal<Date>;
6696
+ readonly draftStart: _angular_core.WritableSignal<Date | null>;
6697
+ readonly draftEnd: _angular_core.WritableSignal<Date | null>;
6366
6698
  /** Effective preset list — defaults if none provided. */
6367
6699
  readonly effectivePresets: _angular_core.Signal<readonly EfDatePreset[]>;
6368
6700
  /** Current value resolved against today's date. */
@@ -6403,11 +6735,24 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6403
6735
  /** Du / Au inputs as DD/MM/YYYY strings (kept in sync with drafts). */
6404
6736
  readonly fromText: _angular_core.Signal<string>;
6405
6737
  readonly toText: _angular_core.Signal<string>;
6738
+ /** Bumps whenever the language or its translations change, so the
6739
+ * placeholder below re-reads the dictionary. */
6740
+ private readonly i18nTick;
6741
+ /**
6742
+ * Placeholder of the typed-date inputs. The parser takes ASCII digits
6743
+ * only, day first (`\d` and the keydown filter are [0-9/]), so the hint
6744
+ * spells that order in the reader's terms, in Latin letters: `JJ/MM/AAAA`
6745
+ * for French, `DD/MM/YYYY` otherwise, Arabic included. An Arabic-word
6746
+ * pattern (يوم/شهر/سنة) would lay out right to left, the reverse of the
6747
+ * digits the user then types. An app can override it per language with
6748
+ * the `date_input_placeholder` key.
6749
+ */
6750
+ readonly datePlaceholder: _angular_core.Signal<string>;
6406
6751
  /** Committed value pushed in via `writeValue` / day-pick / Apply. */
6407
6752
  private readonly fieldValue;
6408
6753
  /** Committed start / end derived from `fieldValue`. */
6409
- readonly fieldStart: _angular_core.Signal<Date>;
6410
- readonly fieldEnd: _angular_core.Signal<Date>;
6754
+ readonly fieldStart: _angular_core.Signal<Date | null>;
6755
+ readonly fieldEnd: _angular_core.Signal<Date | null>;
6411
6756
  /** Whether the field currently holds a value (vs. placeholder). */
6412
6757
  readonly hasFieldValue: _angular_core.Signal<boolean>;
6413
6758
  /** Text rendered in the field-mode trigger (date, +time when enabled). */
@@ -6464,8 +6809,19 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6464
6809
  /** Commit a typed `HH:mm` value to the start or end draft time. */
6465
6810
  commitTimeInput(which: 'start' | 'end', el: HTMLInputElement): void;
6466
6811
  toggle(event: MouseEvent): void;
6467
- close(): void;
6812
+ /**
6813
+ * Close the panel. `returnFocus` puts focus back on the trigger; Escape
6814
+ * and a commit pass it, so a keyboard user is not dropped on <body>
6815
+ * when the panel's DOM goes. An outside click or another picker opening
6816
+ * does not, since the user has just put focus somewhere else.
6817
+ */
6818
+ close(returnFocus?: boolean): void;
6819
+ /** The trigger sits behind an `@if` (field box or pill), so find it now. */
6820
+ private focusTrigger;
6468
6821
  onDocumentClick(event: MouseEvent): void;
6822
+ /** The phone sheet is aria-modal, so Tab wraps inside it instead of
6823
+ * reaching the page behind the backdrop. */
6824
+ onTab(event: KeyboardEvent): void;
6469
6825
  onEscape(): void;
6470
6826
  selectPreset(preset: EfDatePreset): void;
6471
6827
  isActivePreset(key: EfDatePresetKey): boolean;
@@ -6489,12 +6845,22 @@ declare class EfDatepickerAdvancedComponent extends AbstractEfFormControl implem
6489
6845
  commitDateInput(which: 'start' | 'end', el: HTMLInputElement): void;
6490
6846
  private attachPortal;
6491
6847
  private detachPortal;
6492
- /** Anchor the panel's top-left to the trigger's bottom-left, using
6493
- * page coords so the panel scrolls with the trigger naturally.
6494
- * Flips to right-aligned (and clamps to the viewport) when the
6495
- * default left-anchor would overflow the right edge — otherwise the
6496
- * panel is clipped for triggers that sit near the right of the page. */
6848
+ /** The sheet is modal and sits at the end of <body>, far from the
6849
+ * trigger in tab order, so focus moves into it: the picked day, else
6850
+ * today, else the first day of the month. A day, not the date input,
6851
+ * which would raise the on-screen keyboard over the calendar. */
6852
+ private focusIntoSheet;
6853
+ private schedulePosition;
6854
+ /** Place the popover against the trigger (see `placeDpPanel`). Sizes
6855
+ * come from offsetWidth / scrollHeight, not getBoundingClientRect:
6856
+ * the entry animation scales the panel, and scrollHeight still tells
6857
+ * the natural height once a previous placement capped it. */
6497
6858
  private positionPanel;
6859
+ /** The trigger button's box, not the wrapper's: the wrapper also holds
6860
+ * the label above and the error text below. */
6861
+ private triggerRect;
6862
+ /** The nearest `dir` wins (the app sets it on <html>); computed style covers a page without one. */
6863
+ private isRtl;
6498
6864
  /** Click handling: 1st click sets start, 2nd click sets end (or swap).
6499
6865
  * Field single-date mode short-circuits — one click commits & closes. */
6500
6866
  selectDay(day: Date): void;
@@ -6599,13 +6965,17 @@ declare class EfActivationFilterComponent {
6599
6965
  readonly allLabelKey: _angular_core.InputSignal<string>;
6600
6966
  readonly activeLabelKey: _angular_core.InputSignal<string>;
6601
6967
  readonly inactiveLabelKey: _angular_core.InputSignal<string>;
6602
- readonly valueChange: _angular_core.OutputEmitterRef<boolean>;
6968
+ readonly valueChange: _angular_core.OutputEmitterRef<boolean | undefined>;
6603
6969
  readonly selected: _angular_core.Signal<"active" | "inactive" | "all">;
6604
- readonly buckets: _angular_core.Signal<{
6970
+ readonly buckets: _angular_core.Signal<({
6971
+ key: string;
6972
+ labelKey: string;
6973
+ value: undefined;
6974
+ } | {
6605
6975
  key: string;
6606
6976
  labelKey: string;
6607
6977
  value: boolean;
6608
- }[]>;
6978
+ })[]>;
6609
6979
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfActivationFilterComponent, never>;
6610
6980
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfActivationFilterComponent, "ef-activation-filter", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "allLabelKey": { "alias": "allLabelKey"; "required": false; "isSignal": true; }; "activeLabelKey": { "alias": "activeLabelKey"; "required": false; "isSignal": true; }; "inactiveLabelKey": { "alias": "inactiveLabelKey"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
6611
6981
  }
@@ -6637,7 +7007,7 @@ declare class EfThemeConfiguratorComponent implements OnInit {
6637
7007
  presetsDisplayNameKeys: Record<string, string>;
6638
7008
  get ripple(): boolean;
6639
7009
  set ripple(value: boolean);
6640
- get isRTL(): boolean;
7010
+ get isRTL(): boolean | undefined;
6641
7011
  config: PrimeNG;
6642
7012
  configService: EfThemeConfigService;
6643
7013
  platformId: Object;
@@ -6661,9 +7031,9 @@ declare class EfThemeConfiguratorComponent implements OnInit {
6661
7031
  950: string;
6662
7032
  };
6663
7033
  }[];
6664
- selectedPrimaryColor: _angular_core.Signal<string>;
6665
- selectedSurfaceColor: _angular_core.Signal<string>;
6666
- selectedPreset: _angular_core.Signal<string>;
7034
+ selectedPrimaryColor: _angular_core.Signal<string | undefined>;
7035
+ selectedSurfaceColor: _angular_core.Signal<string | undefined>;
7036
+ selectedPreset: _angular_core.Signal<string | undefined>;
6667
7037
  primaryColors: _angular_core.Signal<{
6668
7038
  name: string;
6669
7039
  palette: Record<string, string>;
@@ -6704,7 +7074,7 @@ declare class EfEmailMetricsCardComponent {
6704
7074
  protected readonly noAutofocus: {
6705
7075
  autofocus: boolean;
6706
7076
  };
6707
- metrics: _angular_core.InputSignal<EmailMetrics>;
7077
+ metrics: _angular_core.InputSignal<EmailMetrics | null>;
6708
7078
  recentEvents: _angular_core.InputSignal<EmailEventRecord[]>;
6709
7079
  loading: _angular_core.InputSignal<boolean>;
6710
7080
  title: _angular_core.InputSignal<string>;
@@ -6733,5 +7103,5 @@ declare class EfEmailMetricsCardComponent {
6733
7103
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfEmailMetricsCardComponent, "ef-email-metrics-card", never, { "metrics": { "alias": "metrics"; "required": false; "isSignal": true; }; "recentEvents": { "alias": "recentEvents"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; }, { "rangeChange": "rangeChange"; }, never, never, true, never>;
6734
7104
  }
6735
7105
 
6736
- export { EF_BADGE_BG_COLORS, EF_BADGE_BG_LIGHT_COLORS, EF_BADGE_BORDER_COLORS, EF_BADGE_DEFAULTS, EF_BADGE_TEXT_COLORS, EF_CHART_PALETTE, EF_DATATABLE_ACTIONS_DEFAULTS, EF_DATATABLE_COLUMN_DEFAULTS, EF_DATATABLE_DEFAULTS, EF_DATA_CARD_MOBILE_LAYOUT, EF_STATUS_COLORS, EF_STATUS_COLOR_ALIASES, EfAboutDialogComponent, EfActivationFilterComponent, EfAppMainComponent, EfAppShellComponent, EfAppShellMobileComponent, EfAppTopComponent, EfBadgeComponent, EfBlockUiComponent, EfBlockableDivComponent, EfBottomSheetComponent, EfBuildStampComponent, EfBulkBarComponent, EfButtonComponent, EfButtonGroupComponent, EfCardComponent, EfChangeHistoryComponent, EfChangePasswordComponent, EfChartComponent, EfCheckboxComponent, EfClearButtonComponent, EfColumnHeaderTemplateDirective, EfColumnTemplateDirective, EfCompactPipe, EfConfirmDialogComponent, EfCurrencyPipe, EfDataCardComponent, EfDatatableActionBarComponent, EfDatatableComponent, EfDatepickerAdvancedComponent, EfDatepickerComponent, EfDetailToolbarComponent, EfDialogComponent, EfEmailMetricsCardComponent, EfEmptyStateComponent, EfFabComponent, EfFieldsetComponent, EfFileUploadComponent, EfFilterDrawerComponent, EfFilterPillComponent, EfFormGridComponent, EfIdentityThumbComponent, EfInputNumberComponent, EfInputTextComponent, EfKpiCardComponent, EfLabelComponent, EfModuleRailComponent, EfModuleSideComponent, EfMultiSelectComponent, EfOrderBuilderComponent, EfOrderSummaryComponent, EfOverflowTooltipDirective, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductPickerComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfProfileMenuComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, EfRadioComponent, EfRankListComponent, EfReadOnlyDirective, EfRowActionsComponent, EfSearchToolbarComponent, EfSelectButtonComponent, EfSelectComponent, EfSeoPreviewComponent, EfServerErrorsDirective, EfSessionIdleDialogComponent, EfShortcutsDialogComponent, EfSkeletonComponent, EfSmartBarComponent, EfStatsComponent, EfStatusChipComponent, EfTabPanelDirective, EfTabsComponent, EfTextareaComponent, EfThemeConfiguratorComponent, EfThemeToggleComponent, EfTimelineComponent, EfToastRegionComponent, EfToggleSwitchComponent, EfToolbarComponent, EfTooltipDirective, EfTotalsComponent, OrderEntityHelper, OrderLineItemHelper, TruncatePipe, buildChartConfig, getColumnAlignment, mergeColumnDefaults, resolveEfStatusColor };
6737
- export type { CatalogueProduct, CatalogueProductVariant, CategoryAssignment, CategoryGroup, CategoryItem, DatatableSearchEntity, DocumentConfig, EfAboutServer, EfBadgeColor, EfBadgeConfig, EfBadgeSize, EfBadgeVariant, EfButtonComptoirSeverity, EfButtonPrimeNGSeverity, EfButtonSeverity, EfChangeHistoryEntry, EfChangeHistoryFieldChange, EfChangePasswordSubmit, EfChartSeries, EfChartType, EfDataCardMobileLayout, EfDataCardRowAction, EfDataCardRowActionState, EfDatatableActions, EfDatatableColumn, EfDatatableColumnAlign, EfDatatableColumnType, EfDatatableConfig, EfDateFieldOutput, EfDateFieldValue, EfDatePreset, EfDialogAction, EfDialogSeverity, EfDialogSize, EfFabPosition, EfFileRejectReason, EfFileRejection, EfIdentityThumbSize, EfKpiDeltaTone, EfKpiSparkline, EfPillItem, EfPresetItem, EfProductPickerItem, EfProductPickerQuery, EfProfileMenuItem, EfRankRow, EfRowAction, EfSkeletonVariant, EfStatsRow, EfStatusColor, EfStatusReferenceItem, EfTabItem, EfTabsModule, EfTabsVariant, EfTimelineItem, EfTimelineState, EfToastRegionPosition, EfTotalsGrand, EfTotalsRow, HighlightSegment, OrderChangeInfo, OrderEntity, OrderLineItem, OrderProductsSummary, OrderSummaryItem, ProductCountGroup, ProductCountGroupLabel, ProductTypeaheadRow, ProductTypeaheadSelection, ProductWithCountGroup, SelectedFilter, ValidationResult };
7106
+ export { EF_BADGE_BG_COLORS, EF_BADGE_BG_LIGHT_COLORS, EF_BADGE_BORDER_COLORS, EF_BADGE_DEFAULTS, EF_BADGE_TEXT_COLORS, EF_CHART_PALETTE, EF_DATATABLE_ACTIONS_DEFAULTS, EF_DATATABLE_COLUMN_DEFAULTS, EF_DATATABLE_DEFAULTS, EF_DATA_CARD_MOBILE_LAYOUT, EF_HTML_PREVIEW_DEFAULT_TITLE_KEY, EF_SEO_DEFAULT_LOCALES, EF_STATUS_COLORS, EF_STATUS_COLOR_ALIASES, EfAboutDialogComponent, EfActivationFilterComponent, EfAppMainComponent, EfAppShellComponent, EfAppShellMobileComponent, EfAppTopComponent, EfBadgeComponent, EfBlockUiComponent, EfBlockableDivComponent, EfBottomSheetComponent, EfBuildStampComponent, EfBulkBarComponent, EfButtonComponent, EfButtonGroupComponent, EfCardComponent, EfChangeHistoryComponent, EfChangePasswordComponent, EfChartComponent, EfCheckboxComponent, EfClearButtonComponent, EfColumnHeaderTemplateDirective, EfColumnTemplateDirective, EfCompactPipe, EfConfirmDialogComponent, EfCurrencyPipe, EfDataCardComponent, EfDatatableActionBarComponent, EfDatatableComponent, EfDatepickerAdvancedComponent, EfDatepickerComponent, EfDetailToolbarComponent, EfDialogComponent, EfEmailMetricsCardComponent, EfEmptyStateComponent, EfFabComponent, EfFieldsetComponent, EfFileUploadComponent, EfFilterDrawerComponent, EfFilterPillComponent, EfFormGridComponent, EfHtmlPreviewComponent, EfIdentityThumbComponent, EfInputNumberComponent, EfInputTextComponent, EfKpiCardComponent, EfLabelComponent, EfModuleRailComponent, EfModuleSideComponent, EfMultiSelectComponent, EfOrderBuilderComponent, EfOrderSummaryComponent, EfOverflowTooltipDirective, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductPickerComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfProfileMenuComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, EfRadioComponent, EfRankListComponent, EfReadOnlyDirective, EfRowActionsComponent, EfSearchToolbarComponent, EfSelectButtonComponent, EfSelectComponent, EfSeoFieldsComponent, EfSeoPreviewComponent, EfServerErrorsDirective, EfSessionIdleDialogComponent, EfShortcutsDialogComponent, EfSkeletonComponent, EfSmartBarComponent, EfStatsComponent, EfStatusChipComponent, EfTabPanelDirective, EfTabsComponent, EfTextareaComponent, EfThemeConfiguratorComponent, EfThemeToggleComponent, EfTimelineComponent, EfToastRegionComponent, EfToggleSwitchComponent, EfToolbarComponent, EfTooltipDirective, EfTotalsComponent, OrderEntityHelper, OrderLineItemHelper, TruncatePipe, buildChartConfig, defaultUnitPrice, getColumnAlignment, mergeColumnDefaults, resolveEfStatusColor };
7107
+ export type { CatalogueProduct, CatalogueProductVariant, CategoryAssignment, CategoryGroup, CategoryItem, DatatableSearchEntity, DocumentConfig, EfAboutServer, EfBadgeColor, EfBadgeConfig, EfBadgeSize, EfBadgeVariant, EfButtonComptoirSeverity, EfButtonPrimeNGSeverity, EfButtonSeverity, EfChangeHistoryEntry, EfChangeHistoryFieldChange, EfChangeHistoryValueItem, EfChangePasswordSubmit, EfChartSeries, EfChartType, EfDataCardMobileLayout, EfDataCardRowAction, EfDataCardRowActionState, EfDatatableActions, EfDatatableColumn, EfDatatableColumnAlign, EfDatatableColumnType, EfDatatableConfig, EfDateFieldOutput, EfDateFieldValue, EfDatePreset, EfDialogAction, EfDialogSeverity, EfDialogSize, EfFabPosition, EfFileRejectReason, EfFileRejection, EfIdentityThumbSize, EfKpiDeltaTone, EfKpiSparkline, EfOrderPriceList, EfOrderRecipient, EfPillItem, EfPresetItem, EfProductPickerItem, EfProductPickerQuery, EfProfileMenuItem, EfRankRow, EfRowAction, EfSeoLocale, EfSeoPatch, EfSkeletonVariant, EfStatsRow, EfStatusColor, EfStatusReferenceItem, EfTabItem, EfTabsModule, EfTabsVariant, EfTimelineItem, EfTimelineState, EfToastRegionPosition, EfTotalsGrand, EfTotalsRow, HighlightSegment, OrderChangeInfo, OrderEntity, OrderLineItem, OrderProductsSummary, OrderSummaryItem, ProductCountGroup, ProductCountGroupLabel, ProductTypeaheadRow, ProductTypeaheadSelection, ProductWithCountGroup, SelectedFilter, ValidationResult };