@elasticias/ui 1.0.11 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elasticias/ui",
3
- "version": "1.0.11",
3
+ "version": "1.0.14",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.0.0",
6
6
  "@angular/core": "^21.0.0",
@@ -888,7 +888,8 @@
888
888
  than inventing a third kind of icon button. */
889
889
 
890
890
  .ef-theme-toggle,
891
- .ef-app-top__logout {
891
+ .ef-app-top__logout,
892
+ .ef-app-top__action {
892
893
  appearance: none;
893
894
  background: var(--paper-alt);
894
895
  border: 1px solid var(--rule);
@@ -906,13 +907,15 @@
906
907
  }
907
908
 
908
909
  .ef-theme-toggle:hover,
909
- .ef-app-top__logout:hover {
910
+ .ef-app-top__logout:hover,
911
+ .ef-app-top__action:hover {
910
912
  color: var(--text);
911
913
  border-color: var(--ink-400);
912
914
  }
913
915
 
914
916
  .ef-theme-toggle:focus-visible,
915
- .ef-app-top__logout:focus-visible {
917
+ .ef-app-top__logout:focus-visible,
918
+ .ef-app-top__action:focus-visible {
916
919
  outline: 0;
917
920
  border-color: var(--tenant-400);
918
921
  box-shadow: 0 0 0 4px var(--tenant-100);
@@ -920,7 +923,8 @@
920
923
  }
921
924
 
922
925
  .ef-theme-toggle i,
923
- .ef-app-top__logout i {
926
+ .ef-app-top__logout i,
927
+ .ef-app-top__action i {
924
928
  font-size: 14px;
925
929
  line-height: 1;
926
930
  }
@@ -1586,7 +1590,8 @@
1586
1590
  }
1587
1591
  }
1588
1592
 
1589
- .row-actions__item {
1593
+ .row-actions__item,
1594
+ .ef-menu__item {
1590
1595
  appearance: none;
1591
1596
  background: transparent;
1592
1597
  border: 0;
@@ -1606,19 +1611,24 @@
1606
1611
  }
1607
1612
 
1608
1613
  .row-actions__item:hover,
1609
- .row-actions__item:focus-visible {
1614
+ .row-actions__item:focus-visible,
1615
+ .ef-menu__item:hover,
1616
+ .ef-menu__item:focus-visible {
1610
1617
  background: var(--paper);
1611
1618
  outline: 0;
1612
1619
  }
1613
1620
 
1614
- .row-actions__item[disabled] {
1621
+ .row-actions__item[disabled],
1622
+ .ef-menu__item[disabled] {
1615
1623
  opacity: 0.45;
1616
1624
  cursor: not-allowed;
1617
1625
  background: transparent;
1618
1626
  }
1619
1627
 
1620
1628
  .row-actions__item .ico,
1621
- .row-actions__item i {
1629
+ .row-actions__item i,
1630
+ .ef-menu__item .ico,
1631
+ .ef-menu__item i {
1622
1632
  width: 16px;
1623
1633
  height: 16px;
1624
1634
  font-size: 16px;
@@ -1633,11 +1643,16 @@
1633
1643
  .row-actions__item:hover .ico,
1634
1644
  .row-actions__item:hover i,
1635
1645
  .row-actions__item:focus-visible .ico,
1636
- .row-actions__item:focus-visible i {
1646
+ .row-actions__item:focus-visible i,
1647
+ .ef-menu__item:hover .ico,
1648
+ .ef-menu__item:hover i,
1649
+ .ef-menu__item:focus-visible .ico,
1650
+ .ef-menu__item:focus-visible i {
1637
1651
  color: var(--text);
1638
1652
  }
1639
1653
 
1640
- .row-actions__item .kbd {
1654
+ .row-actions__item .kbd,
1655
+ .ef-menu__item .kbd {
1641
1656
  margin-inline-start: auto;
1642
1657
  font-family: 'JetBrains Mono', monospace;
1643
1658
  font-size: 10px;
@@ -1650,26 +1665,142 @@
1650
1665
  line-height: 1;
1651
1666
  }
1652
1667
 
1653
- .row-actions__item.danger {
1668
+ .row-actions__item.danger,
1669
+ .ef-menu__item.danger {
1654
1670
  color: var(--st-cancelled-fg);
1655
1671
  }
1656
1672
 
1657
1673
  .row-actions__item.danger .ico,
1658
- .row-actions__item.danger i {
1674
+ .row-actions__item.danger i,
1675
+ .ef-menu__item.danger .ico,
1676
+ .ef-menu__item.danger i {
1659
1677
  color: var(--st-cancelled-fg);
1660
1678
  }
1661
1679
 
1662
1680
  .row-actions__item.danger:hover,
1663
- .row-actions__item.danger:focus-visible {
1681
+ .row-actions__item.danger:focus-visible,
1682
+ .ef-menu__item.danger:hover,
1683
+ .ef-menu__item.danger:focus-visible {
1664
1684
  background: var(--st-cancelled-bg);
1665
1685
  }
1666
1686
 
1667
- .row-actions__divider {
1687
+ .row-actions__divider,
1688
+ .ef-menu__divider {
1668
1689
  height: 1px;
1669
1690
  background: var(--rule);
1670
1691
  margin: 4px;
1671
1692
  }
1672
1693
 
1694
+ /* ──────────── MENU (shared) ─────────────────────────────────────
1695
+ The panel half of the menu language above, without the absolute
1696
+ positioning `.row-actions__menu` needs for its own trigger. Anything
1697
+ that already owns its placement (a popover, a bottom sheet) styles its
1698
+ surface with `.ef-menu` and fills it with `.ef-menu__item`. */
1699
+
1700
+ .ef-menu {
1701
+ display: grid;
1702
+ /* A grid track defaults to auto, so one long row would size the column and
1703
+ widen the whole panel. minmax(0, 1fr) is what lets a label truncate. */
1704
+ grid-template-columns: minmax(0, 1fr);
1705
+ gap: 1px;
1706
+ min-width: 212px;
1707
+ padding: 6px;
1708
+ background: var(--paper-alt);
1709
+ border: 1px solid var(--rule);
1710
+ border-radius: var(--r-xl);
1711
+ box-shadow: var(--shadow-3);
1712
+ }
1713
+
1714
+ /* Identity block at the top of a menu: a name and a secondary line.
1715
+ Sized to sit level with the items rather than tower over them. */
1716
+ .ef-menu__head {
1717
+ display: grid;
1718
+ gap: 1px;
1719
+ min-width: 0;
1720
+ padding: 8px 12px 7px;
1721
+ margin-bottom: 4px;
1722
+ border-bottom: 1px solid var(--rule);
1723
+ }
1724
+
1725
+ .ef-menu__head-name {
1726
+ min-width: 0;
1727
+ overflow: hidden;
1728
+ text-overflow: ellipsis;
1729
+ white-space: nowrap;
1730
+ font-size: 13.5px;
1731
+ font-weight: 700;
1732
+ line-height: 1.3;
1733
+ color: var(--text);
1734
+ }
1735
+
1736
+ .ef-menu__head-sub {
1737
+ min-width: 0;
1738
+ overflow: hidden;
1739
+ text-overflow: ellipsis;
1740
+ white-space: nowrap;
1741
+ font-size: 12px;
1742
+ line-height: 1.3;
1743
+ color: var(--text-mute);
1744
+ }
1745
+
1746
+ /* A nested group, revealed by expanding its parent row. Indented to the
1747
+ label column so the children line up under the text, not the icon. */
1748
+ /* Label takes the free space so a trailing chip or caret can sit at the
1749
+ inline end, and a long name truncates instead of widening the panel. */
1750
+ .ef-menu__label {
1751
+ flex: 1 1 auto;
1752
+ min-width: 0;
1753
+ overflow: hidden;
1754
+ text-overflow: ellipsis;
1755
+ white-space: nowrap;
1756
+ }
1757
+
1758
+ .ef-menu__item .ef-menu__caret {
1759
+ margin-inline-start: auto;
1760
+ width: 12px;
1761
+ height: 12px;
1762
+ font-size: 12px;
1763
+ }
1764
+
1765
+ .ef-menu__item .ef-menu__badge {
1766
+ margin-inline-start: auto;
1767
+ flex: 0 0 auto;
1768
+ padding: 1px 7px;
1769
+ border-radius: var(--r-pill);
1770
+ background: var(--st-cancelled-fg);
1771
+ color: #fff;
1772
+ font-size: 11px;
1773
+ font-weight: 700;
1774
+ line-height: 1.5;
1775
+ }
1776
+
1777
+ /* A popover reduced to a placement mechanism. The `.ef-menu` inside draws
1778
+ the surface, so PrimeNG must not draw a second panel or an arrow. */
1779
+ .p-popover.ef-menu-popover {
1780
+ background: transparent;
1781
+ border: 0;
1782
+ box-shadow: none;
1783
+ padding: 0;
1784
+ }
1785
+
1786
+ .p-popover.ef-menu-popover .p-popover-content {
1787
+ padding: 0;
1788
+ }
1789
+
1790
+ .p-popover.ef-menu-popover:before,
1791
+ .p-popover.ef-menu-popover:after {
1792
+ display: none;
1793
+ }
1794
+
1795
+ .ef-menu__sublist {
1796
+ display: grid;
1797
+ gap: 1px;
1798
+ margin: 0;
1799
+ padding: 0 0 2px 28px;
1800
+ list-style: none;
1801
+ min-width: 0;
1802
+ }
1803
+
1673
1804
  /* When a row-actions menu is open inside a data card, the table-wrap
1674
1805
  should let the popover escape its overflow. The data-card binds
1675
1806
  .has-open-menu when any descendant trigger is in `.open` state. */
@@ -2,7 +2,7 @@ import * as _angular_core from '@angular/core';
2
2
  import { PipeTransform, OnInit, OnChanges, TemplateRef, EventEmitter, AfterContentInit, OnDestroy, SimpleChanges, InjectionToken, AfterViewInit } from '@angular/core';
3
3
  import { Menu } from 'primeng/menu';
4
4
  import * as _elasticias_core from '@elasticias/core';
5
- import { EfBuildPackage, EfModule, EfNavSection, EfNavItem, EfModuleId, EfToast, EfToastAction, EfThemeConfigService } from '@elasticias/core';
5
+ import { EfBuildPackage, EfShortcutGroup, EfModule, EfNavSection, EfNavItem, EfModuleId, EfToast, EfToastAction, EfThemeConfigService } from '@elasticias/core';
6
6
  import * as i1 from 'primeng/tooltip';
7
7
  import * as _elasticias_screens from '@elasticias/screens';
8
8
  import { ScreenContext, EfDetailToolbarAction, EfSearchToolbarAction, EfDataCardColumn, EfDataCardSort, EfDateRange, EfDatePresetKey } from '@elasticias/screens';
@@ -1079,6 +1079,39 @@ declare class EfTooltipDirective {
1079
1079
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<EfTooltipDirective, "[efTooltip]", never, {}, {}, never, never, true, [{ directive: typeof i1.Tooltip; inputs: { "pTooltip": "efTooltip"; "tooltipPosition": "efTooltipPosition"; "tooltipDisabled": "efTooltipDisabled"; "tooltipStyleClass": "efTooltipStyleClass"; "tooltipEvent": "efTooltipEvent"; "showDelay": "efTooltipShowDelay"; "hideDelay": "efTooltipHideDelay"; "appendTo": "efTooltipAppendTo"; "autoHide": "efTooltipAutoHide"; "escape": "efTooltipEscape"; "life": "efTooltipLife"; }; outputs: {}; }]>;
1080
1080
  }
1081
1081
 
1082
+ /**
1083
+ * The keyboard-shortcuts reference: every registration currently sitting
1084
+ * in `EfShortcutService`, grouped and rendered with the same `.kbd` chip
1085
+ * `ef-row-actions` and `ef-menu` already use, so a chip means one thing
1086
+ * everywhere it appears.
1087
+ *
1088
+ * Reads `EfShortcutService.list()` directly, so it stays live: open it
1089
+ * while a row menu is on screen and its row-scoped shortcuts are already
1090
+ * listed under "Row actions". Close the row menu and, since a row's
1091
+ * shortcuts unregister with it, they're gone from here too.
1092
+ *
1093
+ * ```html
1094
+ * <ef-shortcuts-dialog [(visible)]="shortcutsOpen" />
1095
+ * ```
1096
+ */
1097
+ declare class EfShortcutsDialogComponent {
1098
+ private readonly shortcutService;
1099
+ /** Two-way open state. */
1100
+ readonly visible: _angular_core.ModelSignal<boolean>;
1101
+ /** `list()`, reordered Global → Screen → Row. An unrecognised group
1102
+ * (a future tier this component doesn't know about yet) sorts last
1103
+ * rather than being dropped. */
1104
+ protected readonly groups: _angular_core.Signal<EfShortcutGroup[]>;
1105
+ /** Only macOS shows every chip already resolved to its own glyphs.
1106
+ * Everyone else gets a line saying the chips already match their
1107
+ * system, since nothing here prints a Mac glyph for them to decode. */
1108
+ protected readonly isMacPlatform: boolean;
1109
+ protected readonly closeAction: EfDialogAction[];
1110
+ protected formatKeys(keys: string): string;
1111
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfShortcutsDialogComponent, never>;
1112
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfShortcutsDialogComponent, "ef-shortcuts-dialog", never, { "visible": { "alias": "visible"; "required": false; "isSignal": true; }; }, { "visible": "visibleChange"; }, never, never, true, never>;
1113
+ }
1114
+
1082
1115
  declare class EfFieldsetComponent {
1083
1116
  /** Direct legend text (not translated) */
1084
1117
  legend?: string;
@@ -1920,6 +1953,89 @@ declare class EfProfileChipComponent {
1920
1953
  static ngAcceptInputType_readonly: unknown;
1921
1954
  }
1922
1955
 
1956
+ /**
1957
+ * One row in `ef-profile-menu`.
1958
+ *
1959
+ * Navigation is a `command` like everything else: a host that wants to
1960
+ * route passes `command: () => this.router.navigate([...])`, which keeps
1961
+ * the lib free of `RouterModule`.
1962
+ */
1963
+ interface EfProfileMenuItem {
1964
+ /** Stable identifier, used for tracking and for expansion state. */
1965
+ id: string;
1966
+ /** Translation key for the row label. */
1967
+ labelKey: string;
1968
+ /** PrimeIcons class, e.g. `'pi pi-user'`. */
1969
+ icon?: string;
1970
+ /** Trailing count pill. `0` renders; `undefined` and `null` do not. */
1971
+ badge?: string | number;
1972
+ /** `'danger'` tints the row, for log out and other one-way actions. */
1973
+ severity?: 'default' | 'danger';
1974
+ /** Draw a separating rule above this row. */
1975
+ groupStart?: boolean;
1976
+ /** Rows shown when this one is expanded. A row with children never
1977
+ * runs its own `command`; choosing it toggles the group. */
1978
+ children?: EfProfileMenuItem[];
1979
+ /** What choosing the row does. */
1980
+ command?: () => void;
1981
+ }
1982
+
1983
+ /** The slice of PrimeNG's Popover this component actually calls. Typing it
1984
+ * structurally keeps the template ref usable and the tests free of PrimeNG. */
1985
+ interface Dismissible {
1986
+ hide: () => void;
1987
+ /** PrimeNG positions a popover once, when it opens. Expanding a group
1988
+ * changes the panel's height afterwards, so the host has to ask for a
1989
+ * reposition or the panel grows past the edge it was anchored to. */
1990
+ align?: () => void;
1991
+ }
1992
+ /**
1993
+ * The signed-in user's menu.
1994
+ *
1995
+ * Two renderings of one `items` array. `variant="chip"` (the default) shows
1996
+ * an `ef-profile-chip` that opens a popover, for the side footer on a
1997
+ * desktop. `variant="list"` renders the same rows flat, with no popover,
1998
+ * for the mobile sheet: `ef-app-shell` does not render the side footer on a
1999
+ * phone, and this menu is the only way to sign out, so it cannot live only
2000
+ * there.
2001
+ *
2002
+ * ```html
2003
+ * <ef-profile-menu
2004
+ * side-footer
2005
+ * [name]="userName()"
2006
+ * [secondary]="userEmail()"
2007
+ * [initial]="userInitial()"
2008
+ * [items]="menuItems()"
2009
+ * />
2010
+ * ```
2011
+ */
2012
+ declare class EfProfileMenuComponent {
2013
+ /** Display name, shown on the chip and in the panel header. */
2014
+ readonly name: _angular_core.InputSignal<string>;
2015
+ /** Second header line. The email, usually. */
2016
+ readonly secondary: _angular_core.InputSignal<string>;
2017
+ /** Chip subtitle. Falls back to `secondary` when empty. */
2018
+ readonly role: _angular_core.InputSignal<string>;
2019
+ /** Avatar glyph. Up to two characters; falls back to the first of `name`. */
2020
+ readonly initial: _angular_core.InputSignal<string>;
2021
+ readonly tone: _angular_core.InputSignal<"tenant" | "neutral">;
2022
+ readonly items: _angular_core.InputSignal<readonly EfProfileMenuItem[]>;
2023
+ readonly variant: _angular_core.InputSignal<"chip" | "list">;
2024
+ readonly itemSelected: _angular_core.OutputEmitterRef<EfProfileMenuItem>;
2025
+ /** Id of the one expanded group, or null. One at a time: a menu that
2026
+ * grows in two directions at once stops being scannable. */
2027
+ private readonly expandedId;
2028
+ readonly chipRole: _angular_core.Signal<string>;
2029
+ isExpanded(id: string): boolean;
2030
+ /**
2031
+ * Choose a row. A row with children toggles its group and leaves the
2032
+ * popover open; a leaf runs its command, reports it, and dismisses.
2033
+ */
2034
+ select(item: EfProfileMenuItem, popover?: Dismissible): void;
2035
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfProfileMenuComponent, never>;
2036
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfProfileMenuComponent, "ef-profile-menu", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "secondary": { "alias": "secondary"; "required": false; "isSignal": true; }; "role": { "alias": "role"; "required": false; "isSignal": true; }; "initial": { "alias": "initial"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, { "itemSelected": "itemSelected"; }, never, never, true, never>;
2037
+ }
2038
+
1923
2039
  declare class EfBlockUiComponent {
1924
2040
  isLoading: boolean;
1925
2041
  contentPanel: any;
@@ -4246,7 +4362,11 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
4246
4362
  /** Items array for the auto row-actions cell. Rebuilt per call so
4247
4363
  * the ef-row-actions component receives a fresh closure per row.
4248
4364
  * Visibility is filtered later by ef-row-actions against
4249
- * `rowActionsContext` (ScreenContext.isGranted). */
4365
+ * `rowActionsContext` (ScreenContext.isGranted).
4366
+ *
4367
+ * `kbd` is rendered through `formatShortcut()`, not a literal glyph:
4368
+ * `ef-row-actions` binds these same keys for real while the row's
4369
+ * menu is open, and a hardcoded `'⌘D'` would lie to a Windows user. */
4250
4370
  defaultRowActions(row: TRow): ReadonlyArray<EfRowAction>;
4251
4371
  bodyTemplate(columnId: string): TemplateRef<unknown> | undefined;
4252
4372
  headerTemplate(columnId: string): TemplateRef<unknown> | undefined;
@@ -4355,11 +4475,11 @@ declare class EfColumnHeaderTemplateDirective {
4355
4475
  *
4356
4476
  * ```ts
4357
4477
  * actions: ReadonlyArray<EfRowAction> = [
4358
- * { id: 'view', labelKey: 'common_view', icon: 'pi pi-eye', kbd: '',
4478
+ * { id: 'view', labelKey: 'common_view', icon: 'pi pi-eye', kbd: formatShortcut('enter'),
4359
4479
  * permission: Permissions.Read, command: () => view(row) },
4360
- * { id: 'edit', labelKey: 'common_edit', icon: 'pi pi-pencil', kbd: 'E',
4480
+ * { id: 'edit', labelKey: 'common_edit', icon: 'pi pi-pencil', kbd: formatShortcut('e'),
4361
4481
  * permission: Permissions.Edit, command: () => edit(row) },
4362
- * { id: 'duplicate', labelKey: 'common_duplicate', icon: 'pi pi-copy',
4482
+ * { id: 'duplicate', labelKey: 'common_duplicate', icon: 'pi pi-copy', kbd: formatShortcut('mod+d'),
4363
4483
  * command: () => duplicate(row) },
4364
4484
  * { separator: true },
4365
4485
  * { id: 'delete', labelKey: 'common_delete', icon: 'pi pi-trash', severity: 'danger',
@@ -4385,9 +4505,25 @@ declare class EfColumnHeaderTemplateDirective {
4385
4505
  * Permission filtering: pass `[context]="..."` (a `ScreenContext`); items
4386
4506
  * declaring a `permission` are hidden unless that permission is granted.
4387
4507
  * Items with no `permission` always show.
4508
+ *
4509
+ * The `kbd` hint is decorative unless it's one of `view` / `edit` /
4510
+ * `duplicate`: this component registers Enter, `E` and `mod+D` against
4511
+ * `EfShortcutService`, gated on `open()`, so they only fire while this
4512
+ * row's menu is on screen. Render `kbd` through `formatShortcut()` (as
4513
+ * above): a hardcoded `'⌘D'` is wrong for a Windows user, which is
4514
+ * exactly the bug this wiring fixes.
4388
4515
  */
4389
4516
  declare class EfRowActionsComponent {
4390
4517
  private readonly host;
4518
+ private readonly shortcuts;
4519
+ /** Distinguishes this instance's registrations from every other row's:
4520
+ * each row on screen constructs its own component, and ids must not
4521
+ * collide or one row's disposer (and its `when`) would clobber
4522
+ * another's still-live registration. */
4523
+ private static nextInstanceId;
4524
+ private readonly instanceId;
4525
+ constructor();
4526
+ private isFocusInsideMenu;
4391
4527
  /** Action descriptors. */
4392
4528
  readonly items: _angular_core.InputSignal<readonly EfRowAction[]>;
4393
4529
  /** Optional context — when present, items with a `permission` are
@@ -4562,8 +4698,8 @@ declare class EfEmptyStateComponent {
4562
4698
  /**
4563
4699
  * Comptoir smart bar — the search/filter card every list screen
4564
4700
  * starts with. Composes:
4565
- * 1. Search input (with `⌘K` kbd hint) + Effacer / Rechercher
4566
- * action buttons.
4701
+ * 1. Search input (with an optional keyboard-shortcut hint chip) +
4702
+ * Effacer / Rechercher action buttons.
4567
4703
  * 2. A filter-row slot for `[filters]` (pill-group + filter-pill +
4568
4704
  * preset-pill + "+ Plus de filtres").
4569
4705
  * 3. A drawer slot for `[drawer]` (advanced filters via
@@ -4573,6 +4709,12 @@ declare class EfEmptyStateComponent {
4573
4709
  * for two-way binding, or watch the (search) output for explicit
4574
4710
  * Rechercher clicks.
4575
4711
  *
4712
+ * `shortcut` defaults to `'mod+k'`: this component registers it with
4713
+ * `EfShortcutService` and focuses the search input when it fires (the
4714
+ * user still has to type and submit; the shortcut only gets them into
4715
+ * the field). Pass `[shortcut]="null"` on a screen with a second smart
4716
+ * bar so only one of them claims the binding.
4717
+ *
4576
4718
  * ```html
4577
4719
  * <ef-smart-bar
4578
4720
  * [(searchText)]="searchQuery"
@@ -4592,6 +4734,12 @@ declare class EfEmptyStateComponent {
4592
4734
  * ```
4593
4735
  */
4594
4736
  declare class EfSmartBarComponent {
4737
+ private readonly shortcuts;
4738
+ /** Distinguishes this instance's registration from any other
4739
+ * ef-smart-bar on screen, the same convention ef-row-actions uses. */
4740
+ private static nextInstanceId;
4741
+ private readonly instanceId;
4742
+ private readonly searchInput;
4595
4743
  /** Two-way bound search input. */
4596
4744
  readonly searchText: _angular_core.ModelSignal<string>;
4597
4745
  readonly placeholderKey: _angular_core.InputSignal<string>;
@@ -4603,12 +4751,18 @@ declare class EfSmartBarComponent {
4603
4751
  readonly hideClear: _angular_core.InputSignalWithTransform<boolean, unknown>;
4604
4752
  readonly hideSearch: _angular_core.InputSignalWithTransform<boolean, unknown>;
4605
4753
  readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
4754
+ /** Keyboard shortcut that focuses the search input. `null` opts out
4755
+ * (a screen with two smart bars registers the binding on only one
4756
+ * of them). Defaults to `'mod+k'`. */
4757
+ readonly shortcut: _angular_core.InputSignal<string>;
4758
+ protected readonly kbdLabel: _angular_core.Signal<string>;
4606
4759
  readonly search: _angular_core.OutputEmitterRef<string>;
4607
4760
  readonly clear: _angular_core.OutputEmitterRef<void>;
4761
+ constructor();
4608
4762
  onSubmit(): void;
4609
4763
  onClear(): void;
4610
4764
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfSmartBarComponent, never>;
4611
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfSmartBarComponent, "ef-smart-bar", never, { "searchText": { "alias": "searchText"; "required": false; "isSignal": true; }; "placeholderKey": { "alias": "placeholderKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "clearLabelKey": { "alias": "clearLabelKey"; "required": false; "isSignal": true; }; "clearTitleKey": { "alias": "clearTitleKey"; "required": false; "isSignal": true; }; "searchLabelKey": { "alias": "searchLabelKey"; "required": false; "isSignal": true; }; "showKbdHint": { "alias": "showKbdHint"; "required": false; "isSignal": true; }; "hideClear": { "alias": "hideClear"; "required": false; "isSignal": true; }; "hideSearch": { "alias": "hideSearch"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; }, { "searchText": "searchTextChange"; "search": "search"; "clear": "clear"; }, never, ["[filters]", "[drawer]"], true, never>;
4765
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfSmartBarComponent, "ef-smart-bar", never, { "searchText": { "alias": "searchText"; "required": false; "isSignal": true; }; "placeholderKey": { "alias": "placeholderKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "clearLabelKey": { "alias": "clearLabelKey"; "required": false; "isSignal": true; }; "clearTitleKey": { "alias": "clearTitleKey"; "required": false; "isSignal": true; }; "searchLabelKey": { "alias": "searchLabelKey"; "required": false; "isSignal": true; }; "showKbdHint": { "alias": "showKbdHint"; "required": false; "isSignal": true; }; "hideClear": { "alias": "hideClear"; "required": false; "isSignal": true; }; "hideSearch": { "alias": "hideSearch"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "shortcut": { "alias": "shortcut"; "required": false; "isSignal": true; }; }, { "searchText": "searchTextChange"; "search": "search"; "clear": "clear"; }, never, ["[filters]", "[drawer]"], true, never>;
4612
4766
  }
4613
4767
 
4614
4768
  /**
@@ -4732,6 +4886,58 @@ declare class EfClearButtonComponent {
4732
4886
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfClearButtonComponent, "ef-clear-button", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "clear": "clear"; }, never, never, true, never>;
4733
4887
  }
4734
4888
 
4889
+ /** What the form hands back. `currentPassword` is absent when the host
4890
+ * did not ask for one (an administrator resetting someone else's). */
4891
+ interface EfChangePasswordSubmit {
4892
+ currentPassword?: string;
4893
+ newPassword: string;
4894
+ }
4895
+ /**
4896
+ * Password form, deliberately without an API client.
4897
+ *
4898
+ * `@elasticias/ui` cannot import an app's generated HTTP client, and that
4899
+ * limitation is what makes one component serve two different endpoints: a
4900
+ * user changing their own password proves the old one, an administrator
4901
+ * resetting someone else's does not. The host reads `canSubmit()`, calls
4902
+ * `submit()` from its dialog footer, and listens to `submitted`.
4903
+ *
4904
+ * ```html
4905
+ * <ef-change-password
4906
+ * #form
4907
+ * [requireCurrent]="!userId()"
4908
+ * [busy]="saving()"
4909
+ * [errors]="serverErrors()"
4910
+ * (submitted)="save($event)"
4911
+ * />
4912
+ * ```
4913
+ *
4914
+ * There is no `reset()`: hosts mount it under `@if`, so every open is a
4915
+ * fresh instance.
4916
+ */
4917
+ declare class EfChangePasswordComponent {
4918
+ /** Ask for the existing password. False for an administrator reset. */
4919
+ readonly requireCurrent: _angular_core.InputSignalWithTransform<boolean, unknown>;
4920
+ /** A request is in flight: the form refuses to submit again. */
4921
+ readonly busy: _angular_core.InputSignalWithTransform<boolean, unknown>;
4922
+ /** Already-translated server messages, rendered under the fields. */
4923
+ readonly errors: _angular_core.InputSignal<readonly string[]>;
4924
+ /** Minimum length. Kept in step with the backend validator's 8. */
4925
+ readonly minLength: _angular_core.InputSignal<number>;
4926
+ readonly submitted: _angular_core.OutputEmitterRef<EfChangePasswordSubmit>;
4927
+ readonly currentPassword: _angular_core.WritableSignal<string>;
4928
+ readonly newPassword: _angular_core.WritableSignal<string>;
4929
+ readonly confirmation: _angular_core.WritableSignal<string>;
4930
+ /**
4931
+ * Translation keys for every rule the current input breaks. Empty while
4932
+ * the user has typed nothing, so the form does not scold on open.
4933
+ */
4934
+ readonly validationKeys: _angular_core.Signal<string[]>;
4935
+ readonly canSubmit: _angular_core.Signal<boolean>;
4936
+ submit(): void;
4937
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfChangePasswordComponent, never>;
4938
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfChangePasswordComponent, "ef-change-password", never, { "requireCurrent": { "alias": "requireCurrent"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; }, { "submitted": "submitted"; }, never, never, true, never>;
4939
+ }
4940
+
4735
4941
  /**
4736
4942
  * Native Comptoir textarea — no PrimeNG wrapper. Pairs with the
4737
4943
  * `.ef-textarea` rule in `@elasticias/ui/styles/patterns` (focus
@@ -5318,5 +5524,5 @@ declare class EfEmailMetricsCardComponent {
5318
5524
  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>;
5319
5525
  }
5320
5526
 
5321
- 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, EfChartComponent, EfCheckboxComponent, EfClearButtonComponent, EfColumnHeaderTemplateDirective, EfColumnTemplateDirective, EfCompactPipe, EfConfirmDialogComponent, EfCurrencyPipe, EfDataCardComponent, EfDatatableActionBarComponent, EfDatatableComponent, EfDatepickerAdvancedComponent, EfDatepickerComponent, EfDetailToolbarComponent, EfDialogComponent, EfEmailMetricsCardComponent, EfEmptyStateComponent, EfFabComponent, EfFieldsetComponent, EfFilterDrawerComponent, EfFilterPillComponent, EfFormGridComponent, EfInputNumberComponent, EfInputTextComponent, EfKpiCardComponent, EfLabelComponent, EfModuleRailComponent, EfModuleSideComponent, EfMultiSelectComponent, EfOrderBuilderComponent, EfOrderSummaryComponent, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, EfRankListComponent, EfRowActionsComponent, EfSearchToolbarComponent, EfSelectButtonComponent, EfSelectComponent, EfServerErrorsDirective, EfSkeletonComponent, EfSmartBarComponent, EfStatsComponent, EfStatusChipComponent, EfTabPanelDirective, EfTabsComponent, EfTextareaComponent, EfThemeConfiguratorComponent, EfThemeToggleComponent, EfTimelineComponent, EfToastRegionComponent, EfToggleSwitchComponent, EfToolbarComponent, EfTooltipDirective, EfTotalsComponent, OrderEntityHelper, OrderLineItemHelper, TruncatePipe, buildChartConfig, getColumnAlignment, mergeColumnDefaults, resolveEfStatusColor };
5322
- export type { CatalogueProduct, CatalogueProductVariant, CategoryAssignment, CategoryGroup, CategoryItem, DatatableSearchEntity, DocumentConfig, EfAboutServer, EfBadgeColor, EfBadgeConfig, EfBadgeSize, EfBadgeVariant, EfButtonComptoirSeverity, EfButtonPrimeNGSeverity, EfButtonSeverity, EfChangeHistoryEntry, EfChangeHistoryFieldChange, EfChartSeries, EfChartType, EfDataCardMobileLayout, EfDataCardRowAction, EfDatatableActions, EfDatatableColumn, EfDatatableColumnAlign, EfDatatableColumnType, EfDatatableConfig, EfDateFieldValue, EfDatePreset, EfDialogAction, EfDialogSeverity, EfDialogSize, EfFabPosition, EfKpiDeltaTone, EfKpiSparkline, EfPillItem, EfPresetItem, 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 };
5527
+ 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, EfFilterDrawerComponent, EfFilterPillComponent, EfFormGridComponent, EfInputNumberComponent, EfInputTextComponent, EfKpiCardComponent, EfLabelComponent, EfModuleRailComponent, EfModuleSideComponent, EfMultiSelectComponent, EfOrderBuilderComponent, EfOrderSummaryComponent, EfPagerComponent, EfPasswordComponent, EfPdfPreviewComponent, EfPillGroupComponent, EfPresetPillComponent, EfPriceDisplayComponent, EfProductCatalogueComponent, EfProductCatalogueFilterComponent, EfProductTypeaheadComponent, EfProfileChipComponent, EfProfileMenuComponent, EfPulseComponent, EfQuantitySelectorComponent, EfQuantityStepperComponent, EfRankListComponent, EfRowActionsComponent, EfSearchToolbarComponent, EfSelectButtonComponent, EfSelectComponent, EfServerErrorsDirective, EfShortcutsDialogComponent, EfSkeletonComponent, EfSmartBarComponent, EfStatsComponent, EfStatusChipComponent, EfTabPanelDirective, EfTabsComponent, EfTextareaComponent, EfThemeConfiguratorComponent, EfThemeToggleComponent, EfTimelineComponent, EfToastRegionComponent, EfToggleSwitchComponent, EfToolbarComponent, EfTooltipDirective, EfTotalsComponent, OrderEntityHelper, OrderLineItemHelper, TruncatePipe, buildChartConfig, getColumnAlignment, mergeColumnDefaults, resolveEfStatusColor };
5528
+ export type { CatalogueProduct, CatalogueProductVariant, CategoryAssignment, CategoryGroup, CategoryItem, DatatableSearchEntity, DocumentConfig, EfAboutServer, EfBadgeColor, EfBadgeConfig, EfBadgeSize, EfBadgeVariant, EfButtonComptoirSeverity, EfButtonPrimeNGSeverity, EfButtonSeverity, EfChangeHistoryEntry, EfChangeHistoryFieldChange, EfChangePasswordSubmit, EfChartSeries, EfChartType, EfDataCardMobileLayout, EfDataCardRowAction, EfDatatableActions, EfDatatableColumn, EfDatatableColumnAlign, EfDatatableColumnType, EfDatatableConfig, EfDateFieldValue, EfDatePreset, EfDialogAction, EfDialogSeverity, EfDialogSize, EfFabPosition, EfKpiDeltaTone, EfKpiSparkline, EfPillItem, EfPresetItem, 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 };