@elasticias/ui 1.0.36 → 1.0.37

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.
@@ -7425,6 +7425,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
7425
7425
  args: ['document:keydown.escape']
7426
7426
  }] } });
7427
7427
 
7428
+ const SIDE_COLLAPSED_KEY = 'ef.shell.side-collapsed';
7429
+ function readSideCollapsed() {
7430
+ try {
7431
+ return localStorage.getItem(SIDE_COLLAPSED_KEY) === '1';
7432
+ }
7433
+ catch {
7434
+ return false;
7435
+ }
7436
+ }
7428
7437
  /**
7429
7438
  * Top-level Comptoir shell.
7430
7439
  *
@@ -7442,7 +7451,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
7442
7451
  * - `EfPermissionService` (via the rail / mobile tabs) for visible modules
7443
7452
  * - `EfActiveModuleService` for the active module accent
7444
7453
  *
7445
- * **Desktop / tablet:** rail (64px) + side (240px) + (top + main).
7454
+ * **Desktop / tablet:** rail (64px) + side (240px) + (top + main). The
7455
+ * side folds away from a toggle at the leading edge of the top bar (or
7456
+ * mod+B); the rail never does.
7446
7457
  * **Mobile:** delegates to `<ef-app-shell-mobile>` — top bar + scrollable
7447
7458
  * body + 5-tab bottom bar + FAB slot.
7448
7459
  *
@@ -7463,6 +7474,36 @@ class EfAppShellComponent {
7463
7474
  viewport = this.vp.current;
7464
7475
  isMobile = this.vp.isMobile;
7465
7476
  showSide = computed(() => !this.vp.isMobile(), ...(ngDevMode ? [{ debugName: "showSide" }] : /* istanbul ignore next */ []));
7477
+ /* ── Side panel toggle ───────────────────────────────────────
7478
+ The rail stays; only the 240px module side folds away, for
7479
+ the screens that want the width (a wide grid, the order
7480
+ builder). The toggle sits at the leading edge of the top bar
7481
+ rather than inside the side, so it is still there to bring
7482
+ the side back once it is gone. Remembered per browser: it is
7483
+ a reading preference, not something worth a round trip. */
7484
+ sideCollapsed = signal(readSideCollapsed(), ...(ngDevMode ? [{ debugName: "sideCollapsed" }] : /* istanbul ignore next */ []));
7485
+ toggleSide() {
7486
+ const collapsed = !this.sideCollapsed();
7487
+ this.sideCollapsed.set(collapsed);
7488
+ try {
7489
+ localStorage.setItem(SIDE_COLLAPSED_KEY, collapsed ? '1' : '0');
7490
+ }
7491
+ catch {
7492
+ /* private window or blocked storage: the toggle still works for this visit */
7493
+ }
7494
+ }
7495
+ constructor() {
7496
+ inject(EfShortcutService).register({
7497
+ id: 'shell.toggle-side',
7498
+ keys: 'mod+b',
7499
+ labelKey: 'common_sidebar_toggle',
7500
+ group: 'shortcut_group_general',
7501
+ handler: () => {
7502
+ if (!this.isMobile())
7503
+ this.toggleSide();
7504
+ },
7505
+ });
7506
+ }
7466
7507
  /* ── Mobile chrome ───────────────────────────────────────────
7467
7508
  Tabs and the module sheet live here rather than in a child
7468
7509
  component: content has to be declared once, in one template,
@@ -7519,7 +7560,7 @@ class EfAppShellComponent {
7519
7560
  this.switcherOpen.set(false);
7520
7561
  }
7521
7562
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfAppShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7522
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfAppShellComponent, isStandalone: true, selector: "ef-app-shell", inputs: { stripe: "stripe" }, host: { properties: { "attr.data-viewport": "viewport()" } }, ngImport: i0, template: "<!-- One layout, one declaration per slot.\n Angular binds projected content to the LAST matching <ng-content> in a\n template, so declaring the same selector once per viewport branch meant the\n branch that was actually rendered on a phone received nothing \u2014 every\n screen came up blank inside working chrome. The layouts differ by CSS and\n by which chrome is rendered, never by where the content is declared. -->\n\n<ef-module-rail class=\"ef-app-shell__rail\">\n <ng-content select=\"[logo]\" logo></ng-content>\n</ef-module-rail>\n\n@if (showSide()) {\n <ef-module-side class=\"ef-app-shell__side\">\n <ng-content select=\"[side-header-meta]\" side-header-meta></ng-content>\n <ng-content select=\"[side-footer]\" side-footer></ng-content>\n </ef-module-side>\n}\n\n<div class=\"ef-app-shell__column\">\n <ef-app-top>\n <!-- The menu takes the breadcrumb's slot on a phone: the breadcrumb is\n hidden there (ef-app-top), so this is the leading position, which is\n where a menu button belongs and where a thumb reaches. -->\n @if (isMobile()) {\n <button\n breadcrumb\n type=\"button\"\n class=\"ef-app-shell__menu\"\n (click)=\"openSwitcher()\"\n [attr.aria-label]=\"'common_modules' | translate\"\n >\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </button>\n }\n <ng-content select=\"[breadcrumb]\" breadcrumb></ng-content>\n <ng-content select=\"[search]\" search></ng-content>\n <ng-content select=\"[actions]\" actions></ng-content>\n </ef-app-top>\n\n <ef-app-main [stripe]=\"stripe\">\n <ng-content></ng-content>\n </ef-app-main>\n\n @if (isMobile()) {\n <nav class=\"ef-app-shell__tabs\" [attr.aria-label]=\"'common_modules' | translate\">\n @for (module of tabs(); track module.id) {\n <button\n type=\"button\"\n class=\"ef-app-shell__tab\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n [attr.aria-current]=\"activeId() === module.id ? 'page' : null\"\n (click)=\"onSelect(module)\"\n >\n <i class=\"ef-app-shell__tab-icon\" [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span class=\"ef-app-shell__tab-label\">{{ module.labelKey | translate }}</span>\n </button>\n }\n </nav>\n }\n</div>\n\n<ng-content select=\"[fab]\"></ng-content>\n\n@if (isMobile()) {\n <ef-bottom-sheet [open]=\"switcherOpen()\" (openChange)=\"onSwitcherChange($event)\">\n <!-- The screens first: the tab bar already switches modules, so this is\n the only way to reach anything but a module's default screen. -->\n @for (section of moduleSections(); track section.id) {\n @if (section.labelKey) {\n <h2 class=\"ef-app-shell__sheet-title\">{{ section.labelKey | translate }}</h2>\n }\n <ul class=\"ef-app-shell__sheet-list\">\n @for (item of section.items; track item.id) {\n <li>\n <a\n class=\"ef-app-shell__sheet-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"is-active\"\n (click)=\"onNavigate(item)\"\n >\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-app-shell__sheet-badge\">{{ item.badge }}</span>\n }\n </a>\n </li>\n }\n </ul>\n }\n\n <h2 class=\"ef-app-shell__sheet-title\">{{ 'common_modules' | translate }}</h2>\n <ul class=\"ef-app-shell__sheet-list\">\n @for (module of allVisible(); track module.id) {\n <li>\n <button\n type=\"button\"\n class=\"ef-app-shell__sheet-item\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n (click)=\"onSelect(module)\"\n >\n <i [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span>{{ module.labelKey | translate }}</span>\n </button>\n </li>\n }\n </ul>\n\n <!-- App-level entries that live in the rail on a desktop and have nowhere\n else to go on a phone: this sheet is the phone's menu. Declared only\n in the mobile branch, so a desktop simply drops what is projected. -->\n <div class=\"ef-app-shell__sheet-footer\">\n <ng-content select=\"[sheet-footer]\" sheet-footer></ng-content>\n </div>\n </ef-bottom-sheet>\n}\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:row;width:100%;height:100vh;background:var(--paper);color:var(--text);overflow:hidden}.ef-app-shell__column{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;min-height:0;overflow:hidden}.ef-app-shell__menu{display:inline-flex;align-items:center;justify-content:center;width:var(--hit-touch);height:var(--hit-touch);background:transparent;border:0;border-radius:var(--r-md);color:var(--text);cursor:pointer;font-size:18px}.ef-app-shell__menu:hover{background:var(--paper-alt)}.ef-app-shell__tabs{flex:0 0 auto;display:flex;align-items:stretch;height:64px;padding-bottom:env(safe-area-inset-bottom);background:var(--paper);border-top:1px solid var(--rule)}.ef-app-shell__tab{position:relative;flex:1 1 0;min-width:0;display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;background:transparent;border:0;color:var(--text-mute);cursor:pointer;padding:6px 4px;transition:color var(--t-fast) var(--ease-out)}.ef-app-shell__tab.is-active{color:var(--text)}.ef-app-shell__tab.is-active:after{content:\"\";position:absolute;top:0;left:50%;transform:translate(-50%);width:28px;height:3px;background:var(--module);border-radius:0 0 var(--r-sm) var(--r-sm)}.ef-app-shell__tab-icon{font-size:18px;line-height:1}.ef-app-shell__tab-label{font-family:var(--font-ui);font-size:10.5px;font-weight:600;letter-spacing:-.005em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.ef-app-shell__sheet-title{font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-mute);margin:0 0 10px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-title:first-child{padding-top:0;border-top:0}.ef-app-shell__sheet-list{list-style:none;margin:0 0 4px;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:8px}.ef-app-shell__sheet-list+.ef-app-shell__sheet-title{margin-top:8px}.ef-app-shell__sheet-item{display:flex;align-items:center;gap:12px;width:100%;height:var(--hit-touch);padding:0 16px;background:var(--paper-alt);border:0;border-radius:var(--r-md);text-decoration:none;color:var(--text);cursor:pointer;font-family:var(--font-ui);font-size:14px;font-weight:500;text-align:left;transition:background-color var(--t-fast) var(--ease-out)}.ef-app-shell__sheet-item:hover{background:var(--rule)}.ef-app-shell__sheet-item.is-active{border-left:3px solid var(--module);padding-left:13px}@media(max-width:767px){.ef-app-shell__rail{display:none}}.ef-app-shell__sheet-badge{margin-inline-start:auto;font-size:11px;font-weight:700;color:var(--text-mute)}.ef-app-shell__sheet-item.is-active{background:var(--paper);color:var(--text);font-weight:700}.ef-app-shell__sheet-footer{display:grid;gap:8px;margin-top:16px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-footer:empty{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: EfModuleRailComponent, selector: "ef-module-rail", inputs: ["badges"] }, { kind: "component", type: EfModuleSideComponent, selector: "ef-module-side" }, { kind: "component", type: EfAppTopComponent, selector: "ef-app-top", inputs: ["themeToggle", "logout"] }, { kind: "component", type: EfAppMainComponent, selector: "ef-app-main", inputs: ["stripe"] }, { kind: "component", type: EfBottomSheetComponent, selector: "ef-bottom-sheet", inputs: ["open", "dismissOnBackdrop"], outputs: ["openChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7563
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfAppShellComponent, isStandalone: true, selector: "ef-app-shell", inputs: { stripe: "stripe" }, host: { properties: { "attr.data-viewport": "viewport()" } }, ngImport: i0, template: "<!-- One layout, one declaration per slot.\n Angular binds projected content to the LAST matching <ng-content> in a\n template, so declaring the same selector once per viewport branch meant the\n branch that was actually rendered on a phone received nothing \u2014 every\n screen came up blank inside working chrome. The layouts differ by CSS and\n by which chrome is rendered, never by where the content is declared. -->\n\n<ef-module-rail class=\"ef-app-shell__rail\">\n <ng-content select=\"[logo]\" logo></ng-content>\n</ef-module-rail>\n\n@if (showSide()) {\n <!-- Folded by class rather than by @if: the side-footer slot (identity\n menu) is projected into it, and the panel animates closed. `inert`\n takes the hidden links out of the tab order and the a11y tree. -->\n <ef-module-side\n id=\"ef-app-shell-side\"\n class=\"ef-app-shell__side\"\n [class.is-collapsed]=\"sideCollapsed()\"\n [attr.inert]=\"sideCollapsed() ? '' : null\"\n >\n <ng-content select=\"[side-header-meta]\" side-header-meta></ng-content>\n <ng-content select=\"[side-footer]\" side-footer></ng-content>\n </ef-module-side>\n}\n\n<div class=\"ef-app-shell__column\">\n <ef-app-top>\n <!-- The menu takes the breadcrumb's slot on a phone: the breadcrumb is\n hidden there (ef-app-top), so this is the leading position, which is\n where a menu button belongs and where a thumb reaches. -->\n @if (isMobile()) {\n <button\n breadcrumb\n type=\"button\"\n class=\"ef-app-shell__menu\"\n (click)=\"openSwitcher()\"\n [attr.aria-label]=\"'common_modules' | translate\"\n >\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </button>\n } @else if (showSide()) {\n <!-- Same leading position, desktop job: show or hide the side panel.\n Drawn inline because PrimeIcons has no panel glyph. -->\n <button\n breadcrumb\n type=\"button\"\n class=\"ef-app-shell__side-toggle\"\n aria-controls=\"ef-app-shell-side\"\n [attr.aria-expanded]=\"!sideCollapsed()\"\n [attr.aria-label]=\"(sideCollapsed() ? 'common_sidebar_show' : 'common_sidebar_hide') | translate\"\n [attr.title]=\"(sideCollapsed() ? 'common_sidebar_show' : 'common_sidebar_hide') | translate\"\n (click)=\"toggleSide()\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"3.5\" />\n <path d=\"M9.5 4v16\" />\n </svg>\n </button>\n }\n <ng-content select=\"[breadcrumb]\" breadcrumb></ng-content>\n <ng-content select=\"[search]\" search></ng-content>\n <ng-content select=\"[actions]\" actions></ng-content>\n </ef-app-top>\n\n <ef-app-main [stripe]=\"stripe\">\n <ng-content></ng-content>\n </ef-app-main>\n\n @if (isMobile()) {\n <nav class=\"ef-app-shell__tabs\" [attr.aria-label]=\"'common_modules' | translate\">\n @for (module of tabs(); track module.id) {\n <button\n type=\"button\"\n class=\"ef-app-shell__tab\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n [attr.aria-current]=\"activeId() === module.id ? 'page' : null\"\n (click)=\"onSelect(module)\"\n >\n <i class=\"ef-app-shell__tab-icon\" [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span class=\"ef-app-shell__tab-label\">{{ module.labelKey | translate }}</span>\n </button>\n }\n </nav>\n }\n</div>\n\n<ng-content select=\"[fab]\"></ng-content>\n\n@if (isMobile()) {\n <ef-bottom-sheet [open]=\"switcherOpen()\" (openChange)=\"onSwitcherChange($event)\">\n <!-- The screens first: the tab bar already switches modules, so this is\n the only way to reach anything but a module's default screen. -->\n @for (section of moduleSections(); track section.id) {\n @if (section.labelKey) {\n <h2 class=\"ef-app-shell__sheet-title\">{{ section.labelKey | translate }}</h2>\n }\n <ul class=\"ef-app-shell__sheet-list\">\n @for (item of section.items; track item.id) {\n <li>\n <a\n class=\"ef-app-shell__sheet-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"is-active\"\n (click)=\"onNavigate(item)\"\n >\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-app-shell__sheet-badge\">{{ item.badge }}</span>\n }\n </a>\n </li>\n }\n </ul>\n }\n\n <h2 class=\"ef-app-shell__sheet-title\">{{ 'common_modules' | translate }}</h2>\n <ul class=\"ef-app-shell__sheet-list\">\n @for (module of allVisible(); track module.id) {\n <li>\n <button\n type=\"button\"\n class=\"ef-app-shell__sheet-item\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n (click)=\"onSelect(module)\"\n >\n <i [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span>{{ module.labelKey | translate }}</span>\n </button>\n </li>\n }\n </ul>\n\n <!-- App-level entries that live in the rail on a desktop and have nowhere\n else to go on a phone: this sheet is the phone's menu. Declared only\n in the mobile branch, so a desktop simply drops what is projected. -->\n <div class=\"ef-app-shell__sheet-footer\">\n <ng-content select=\"[sheet-footer]\" sheet-footer></ng-content>\n </div>\n </ef-bottom-sheet>\n}\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:row;width:100%;height:100vh;background:var(--paper);color:var(--text);overflow:hidden}.ef-app-shell__column{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;min-height:0;overflow:hidden}.ef-app-shell__side{overflow:hidden;transition:flex-basis var(--t-fast) var(--ease-out),width var(--t-fast) var(--ease-out)}.ef-app-shell__side.is-collapsed{flex-basis:0;width:0;border-right-width:0}.ef-app-shell__side-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:32px;height:32px;margin-inline-start:-6px;background:transparent;border:0;border-radius:var(--r-md);color:var(--text-mute);cursor:pointer;transition:background-color var(--t-fast) var(--ease-out),color var(--t-fast) var(--ease-out)}.ef-app-shell__side-toggle:hover{background:var(--rule);color:var(--text)}.ef-app-shell__side-toggle:focus-visible{outline:2px solid var(--module, var(--text));outline-offset:1px}@media(prefers-reduced-motion:reduce){.ef-app-shell__side{transition:none}}.ef-app-shell__menu{display:inline-flex;align-items:center;justify-content:center;width:var(--hit-touch);height:var(--hit-touch);background:transparent;border:0;border-radius:var(--r-md);color:var(--text);cursor:pointer;font-size:18px}.ef-app-shell__menu:hover{background:var(--paper-alt)}.ef-app-shell__tabs{flex:0 0 auto;display:flex;align-items:stretch;height:64px;padding-bottom:env(safe-area-inset-bottom);background:var(--paper);border-top:1px solid var(--rule)}.ef-app-shell__tab{position:relative;flex:1 1 0;min-width:0;display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;background:transparent;border:0;color:var(--text-mute);cursor:pointer;padding:6px 4px;transition:color var(--t-fast) var(--ease-out)}.ef-app-shell__tab.is-active{color:var(--text)}.ef-app-shell__tab.is-active:after{content:\"\";position:absolute;top:0;left:50%;transform:translate(-50%);width:28px;height:3px;background:var(--module);border-radius:0 0 var(--r-sm) var(--r-sm)}.ef-app-shell__tab-icon{font-size:18px;line-height:1}.ef-app-shell__tab-label{font-family:var(--font-ui);font-size:10.5px;font-weight:600;letter-spacing:-.005em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.ef-app-shell__sheet-title{font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-mute);margin:0 0 10px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-title:first-child{padding-top:0;border-top:0}.ef-app-shell__sheet-list{list-style:none;margin:0 0 4px;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:8px}.ef-app-shell__sheet-list+.ef-app-shell__sheet-title{margin-top:8px}.ef-app-shell__sheet-item{display:flex;align-items:center;gap:12px;width:100%;height:var(--hit-touch);padding:0 16px;background:var(--paper-alt);border:0;border-radius:var(--r-md);text-decoration:none;color:var(--text);cursor:pointer;font-family:var(--font-ui);font-size:14px;font-weight:500;text-align:left;transition:background-color var(--t-fast) var(--ease-out)}.ef-app-shell__sheet-item:hover{background:var(--rule)}.ef-app-shell__sheet-item.is-active{border-left:3px solid var(--module);padding-left:13px}@media(max-width:767px){.ef-app-shell__rail{display:none}}.ef-app-shell__sheet-badge{margin-inline-start:auto;font-size:11px;font-weight:700;color:var(--text-mute)}.ef-app-shell__sheet-item.is-active{background:var(--paper);color:var(--text);font-weight:700}.ef-app-shell__sheet-footer{display:grid;gap:8px;margin-top:16px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-footer:empty{display:none}:host-context([dir=rtl]) .ef-app-shell__side-toggle svg{transform:scaleX(-1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: EfModuleRailComponent, selector: "ef-module-rail", inputs: ["badges"] }, { kind: "component", type: EfModuleSideComponent, selector: "ef-module-side" }, { kind: "component", type: EfAppTopComponent, selector: "ef-app-top", inputs: ["themeToggle", "logout"] }, { kind: "component", type: EfAppMainComponent, selector: "ef-app-main", inputs: ["stripe"] }, { kind: "component", type: EfBottomSheetComponent, selector: "ef-bottom-sheet", inputs: ["open", "dismissOnBackdrop"], outputs: ["openChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7523
7564
  }
7524
7565
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfAppShellComponent, decorators: [{
7525
7566
  type: Component,
@@ -7534,8 +7575,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
7534
7575
  RouterLink,
7535
7576
  ], host: {
7536
7577
  '[attr.data-viewport]': 'viewport()',
7537
- }, template: "<!-- One layout, one declaration per slot.\n Angular binds projected content to the LAST matching <ng-content> in a\n template, so declaring the same selector once per viewport branch meant the\n branch that was actually rendered on a phone received nothing \u2014 every\n screen came up blank inside working chrome. The layouts differ by CSS and\n by which chrome is rendered, never by where the content is declared. -->\n\n<ef-module-rail class=\"ef-app-shell__rail\">\n <ng-content select=\"[logo]\" logo></ng-content>\n</ef-module-rail>\n\n@if (showSide()) {\n <ef-module-side class=\"ef-app-shell__side\">\n <ng-content select=\"[side-header-meta]\" side-header-meta></ng-content>\n <ng-content select=\"[side-footer]\" side-footer></ng-content>\n </ef-module-side>\n}\n\n<div class=\"ef-app-shell__column\">\n <ef-app-top>\n <!-- The menu takes the breadcrumb's slot on a phone: the breadcrumb is\n hidden there (ef-app-top), so this is the leading position, which is\n where a menu button belongs and where a thumb reaches. -->\n @if (isMobile()) {\n <button\n breadcrumb\n type=\"button\"\n class=\"ef-app-shell__menu\"\n (click)=\"openSwitcher()\"\n [attr.aria-label]=\"'common_modules' | translate\"\n >\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </button>\n }\n <ng-content select=\"[breadcrumb]\" breadcrumb></ng-content>\n <ng-content select=\"[search]\" search></ng-content>\n <ng-content select=\"[actions]\" actions></ng-content>\n </ef-app-top>\n\n <ef-app-main [stripe]=\"stripe\">\n <ng-content></ng-content>\n </ef-app-main>\n\n @if (isMobile()) {\n <nav class=\"ef-app-shell__tabs\" [attr.aria-label]=\"'common_modules' | translate\">\n @for (module of tabs(); track module.id) {\n <button\n type=\"button\"\n class=\"ef-app-shell__tab\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n [attr.aria-current]=\"activeId() === module.id ? 'page' : null\"\n (click)=\"onSelect(module)\"\n >\n <i class=\"ef-app-shell__tab-icon\" [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span class=\"ef-app-shell__tab-label\">{{ module.labelKey | translate }}</span>\n </button>\n }\n </nav>\n }\n</div>\n\n<ng-content select=\"[fab]\"></ng-content>\n\n@if (isMobile()) {\n <ef-bottom-sheet [open]=\"switcherOpen()\" (openChange)=\"onSwitcherChange($event)\">\n <!-- The screens first: the tab bar already switches modules, so this is\n the only way to reach anything but a module's default screen. -->\n @for (section of moduleSections(); track section.id) {\n @if (section.labelKey) {\n <h2 class=\"ef-app-shell__sheet-title\">{{ section.labelKey | translate }}</h2>\n }\n <ul class=\"ef-app-shell__sheet-list\">\n @for (item of section.items; track item.id) {\n <li>\n <a\n class=\"ef-app-shell__sheet-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"is-active\"\n (click)=\"onNavigate(item)\"\n >\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-app-shell__sheet-badge\">{{ item.badge }}</span>\n }\n </a>\n </li>\n }\n </ul>\n }\n\n <h2 class=\"ef-app-shell__sheet-title\">{{ 'common_modules' | translate }}</h2>\n <ul class=\"ef-app-shell__sheet-list\">\n @for (module of allVisible(); track module.id) {\n <li>\n <button\n type=\"button\"\n class=\"ef-app-shell__sheet-item\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n (click)=\"onSelect(module)\"\n >\n <i [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span>{{ module.labelKey | translate }}</span>\n </button>\n </li>\n }\n </ul>\n\n <!-- App-level entries that live in the rail on a desktop and have nowhere\n else to go on a phone: this sheet is the phone's menu. Declared only\n in the mobile branch, so a desktop simply drops what is projected. -->\n <div class=\"ef-app-shell__sheet-footer\">\n <ng-content select=\"[sheet-footer]\" sheet-footer></ng-content>\n </div>\n </ef-bottom-sheet>\n}\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:row;width:100%;height:100vh;background:var(--paper);color:var(--text);overflow:hidden}.ef-app-shell__column{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;min-height:0;overflow:hidden}.ef-app-shell__menu{display:inline-flex;align-items:center;justify-content:center;width:var(--hit-touch);height:var(--hit-touch);background:transparent;border:0;border-radius:var(--r-md);color:var(--text);cursor:pointer;font-size:18px}.ef-app-shell__menu:hover{background:var(--paper-alt)}.ef-app-shell__tabs{flex:0 0 auto;display:flex;align-items:stretch;height:64px;padding-bottom:env(safe-area-inset-bottom);background:var(--paper);border-top:1px solid var(--rule)}.ef-app-shell__tab{position:relative;flex:1 1 0;min-width:0;display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;background:transparent;border:0;color:var(--text-mute);cursor:pointer;padding:6px 4px;transition:color var(--t-fast) var(--ease-out)}.ef-app-shell__tab.is-active{color:var(--text)}.ef-app-shell__tab.is-active:after{content:\"\";position:absolute;top:0;left:50%;transform:translate(-50%);width:28px;height:3px;background:var(--module);border-radius:0 0 var(--r-sm) var(--r-sm)}.ef-app-shell__tab-icon{font-size:18px;line-height:1}.ef-app-shell__tab-label{font-family:var(--font-ui);font-size:10.5px;font-weight:600;letter-spacing:-.005em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.ef-app-shell__sheet-title{font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-mute);margin:0 0 10px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-title:first-child{padding-top:0;border-top:0}.ef-app-shell__sheet-list{list-style:none;margin:0 0 4px;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:8px}.ef-app-shell__sheet-list+.ef-app-shell__sheet-title{margin-top:8px}.ef-app-shell__sheet-item{display:flex;align-items:center;gap:12px;width:100%;height:var(--hit-touch);padding:0 16px;background:var(--paper-alt);border:0;border-radius:var(--r-md);text-decoration:none;color:var(--text);cursor:pointer;font-family:var(--font-ui);font-size:14px;font-weight:500;text-align:left;transition:background-color var(--t-fast) var(--ease-out)}.ef-app-shell__sheet-item:hover{background:var(--rule)}.ef-app-shell__sheet-item.is-active{border-left:3px solid var(--module);padding-left:13px}@media(max-width:767px){.ef-app-shell__rail{display:none}}.ef-app-shell__sheet-badge{margin-inline-start:auto;font-size:11px;font-weight:700;color:var(--text-mute)}.ef-app-shell__sheet-item.is-active{background:var(--paper);color:var(--text);font-weight:700}.ef-app-shell__sheet-footer{display:grid;gap:8px;margin-top:16px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-footer:empty{display:none}\n"] }]
7538
- }], propDecorators: { stripe: [{
7578
+ }, template: "<!-- One layout, one declaration per slot.\n Angular binds projected content to the LAST matching <ng-content> in a\n template, so declaring the same selector once per viewport branch meant the\n branch that was actually rendered on a phone received nothing \u2014 every\n screen came up blank inside working chrome. The layouts differ by CSS and\n by which chrome is rendered, never by where the content is declared. -->\n\n<ef-module-rail class=\"ef-app-shell__rail\">\n <ng-content select=\"[logo]\" logo></ng-content>\n</ef-module-rail>\n\n@if (showSide()) {\n <!-- Folded by class rather than by @if: the side-footer slot (identity\n menu) is projected into it, and the panel animates closed. `inert`\n takes the hidden links out of the tab order and the a11y tree. -->\n <ef-module-side\n id=\"ef-app-shell-side\"\n class=\"ef-app-shell__side\"\n [class.is-collapsed]=\"sideCollapsed()\"\n [attr.inert]=\"sideCollapsed() ? '' : null\"\n >\n <ng-content select=\"[side-header-meta]\" side-header-meta></ng-content>\n <ng-content select=\"[side-footer]\" side-footer></ng-content>\n </ef-module-side>\n}\n\n<div class=\"ef-app-shell__column\">\n <ef-app-top>\n <!-- The menu takes the breadcrumb's slot on a phone: the breadcrumb is\n hidden there (ef-app-top), so this is the leading position, which is\n where a menu button belongs and where a thumb reaches. -->\n @if (isMobile()) {\n <button\n breadcrumb\n type=\"button\"\n class=\"ef-app-shell__menu\"\n (click)=\"openSwitcher()\"\n [attr.aria-label]=\"'common_modules' | translate\"\n >\n <i class=\"pi pi-bars\" aria-hidden=\"true\"></i>\n </button>\n } @else if (showSide()) {\n <!-- Same leading position, desktop job: show or hide the side panel.\n Drawn inline because PrimeIcons has no panel glyph. -->\n <button\n breadcrumb\n type=\"button\"\n class=\"ef-app-shell__side-toggle\"\n aria-controls=\"ef-app-shell-side\"\n [attr.aria-expanded]=\"!sideCollapsed()\"\n [attr.aria-label]=\"(sideCollapsed() ? 'common_sidebar_show' : 'common_sidebar_hide') | translate\"\n [attr.title]=\"(sideCollapsed() ? 'common_sidebar_show' : 'common_sidebar_hide') | translate\"\n (click)=\"toggleSide()\"\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"3.5\" />\n <path d=\"M9.5 4v16\" />\n </svg>\n </button>\n }\n <ng-content select=\"[breadcrumb]\" breadcrumb></ng-content>\n <ng-content select=\"[search]\" search></ng-content>\n <ng-content select=\"[actions]\" actions></ng-content>\n </ef-app-top>\n\n <ef-app-main [stripe]=\"stripe\">\n <ng-content></ng-content>\n </ef-app-main>\n\n @if (isMobile()) {\n <nav class=\"ef-app-shell__tabs\" [attr.aria-label]=\"'common_modules' | translate\">\n @for (module of tabs(); track module.id) {\n <button\n type=\"button\"\n class=\"ef-app-shell__tab\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n [attr.aria-current]=\"activeId() === module.id ? 'page' : null\"\n (click)=\"onSelect(module)\"\n >\n <i class=\"ef-app-shell__tab-icon\" [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span class=\"ef-app-shell__tab-label\">{{ module.labelKey | translate }}</span>\n </button>\n }\n </nav>\n }\n</div>\n\n<ng-content select=\"[fab]\"></ng-content>\n\n@if (isMobile()) {\n <ef-bottom-sheet [open]=\"switcherOpen()\" (openChange)=\"onSwitcherChange($event)\">\n <!-- The screens first: the tab bar already switches modules, so this is\n the only way to reach anything but a module's default screen. -->\n @for (section of moduleSections(); track section.id) {\n @if (section.labelKey) {\n <h2 class=\"ef-app-shell__sheet-title\">{{ section.labelKey | translate }}</h2>\n }\n <ul class=\"ef-app-shell__sheet-list\">\n @for (item of section.items; track item.id) {\n <li>\n <a\n class=\"ef-app-shell__sheet-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"is-active\"\n (click)=\"onNavigate(item)\"\n >\n @if (item.icon) {\n <i [class]=\"item.icon\" aria-hidden=\"true\"></i>\n }\n <span>{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-app-shell__sheet-badge\">{{ item.badge }}</span>\n }\n </a>\n </li>\n }\n </ul>\n }\n\n <h2 class=\"ef-app-shell__sheet-title\">{{ 'common_modules' | translate }}</h2>\n <ul class=\"ef-app-shell__sheet-list\">\n @for (module of allVisible(); track module.id) {\n <li>\n <button\n type=\"button\"\n class=\"ef-app-shell__sheet-item\"\n [class.is-active]=\"activeId() === module.id\"\n [attr.data-module]=\"module.id\"\n (click)=\"onSelect(module)\"\n >\n <i [class]=\"module.icon\" aria-hidden=\"true\"></i>\n <span>{{ module.labelKey | translate }}</span>\n </button>\n </li>\n }\n </ul>\n\n <!-- App-level entries that live in the rail on a desktop and have nowhere\n else to go on a phone: this sheet is the phone's menu. Declared only\n in the mobile branch, so a desktop simply drops what is projected. -->\n <div class=\"ef-app-shell__sheet-footer\">\n <ng-content select=\"[sheet-footer]\" sheet-footer></ng-content>\n </div>\n </ef-bottom-sheet>\n}\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:row;width:100%;height:100vh;background:var(--paper);color:var(--text);overflow:hidden}.ef-app-shell__column{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;min-height:0;overflow:hidden}.ef-app-shell__side{overflow:hidden;transition:flex-basis var(--t-fast) var(--ease-out),width var(--t-fast) var(--ease-out)}.ef-app-shell__side.is-collapsed{flex-basis:0;width:0;border-right-width:0}.ef-app-shell__side-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:32px;height:32px;margin-inline-start:-6px;background:transparent;border:0;border-radius:var(--r-md);color:var(--text-mute);cursor:pointer;transition:background-color var(--t-fast) var(--ease-out),color var(--t-fast) var(--ease-out)}.ef-app-shell__side-toggle:hover{background:var(--rule);color:var(--text)}.ef-app-shell__side-toggle:focus-visible{outline:2px solid var(--module, var(--text));outline-offset:1px}@media(prefers-reduced-motion:reduce){.ef-app-shell__side{transition:none}}.ef-app-shell__menu{display:inline-flex;align-items:center;justify-content:center;width:var(--hit-touch);height:var(--hit-touch);background:transparent;border:0;border-radius:var(--r-md);color:var(--text);cursor:pointer;font-size:18px}.ef-app-shell__menu:hover{background:var(--paper-alt)}.ef-app-shell__tabs{flex:0 0 auto;display:flex;align-items:stretch;height:64px;padding-bottom:env(safe-area-inset-bottom);background:var(--paper);border-top:1px solid var(--rule)}.ef-app-shell__tab{position:relative;flex:1 1 0;min-width:0;display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;background:transparent;border:0;color:var(--text-mute);cursor:pointer;padding:6px 4px;transition:color var(--t-fast) var(--ease-out)}.ef-app-shell__tab.is-active{color:var(--text)}.ef-app-shell__tab.is-active:after{content:\"\";position:absolute;top:0;left:50%;transform:translate(-50%);width:28px;height:3px;background:var(--module);border-radius:0 0 var(--r-sm) var(--r-sm)}.ef-app-shell__tab-icon{font-size:18px;line-height:1}.ef-app-shell__tab-label{font-family:var(--font-ui);font-size:10.5px;font-weight:600;letter-spacing:-.005em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.ef-app-shell__sheet-title{font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-mute);margin:0 0 10px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-title:first-child{padding-top:0;border-top:0}.ef-app-shell__sheet-list{list-style:none;margin:0 0 4px;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:8px}.ef-app-shell__sheet-list+.ef-app-shell__sheet-title{margin-top:8px}.ef-app-shell__sheet-item{display:flex;align-items:center;gap:12px;width:100%;height:var(--hit-touch);padding:0 16px;background:var(--paper-alt);border:0;border-radius:var(--r-md);text-decoration:none;color:var(--text);cursor:pointer;font-family:var(--font-ui);font-size:14px;font-weight:500;text-align:left;transition:background-color var(--t-fast) var(--ease-out)}.ef-app-shell__sheet-item:hover{background:var(--rule)}.ef-app-shell__sheet-item.is-active{border-left:3px solid var(--module);padding-left:13px}@media(max-width:767px){.ef-app-shell__rail{display:none}}.ef-app-shell__sheet-badge{margin-inline-start:auto;font-size:11px;font-weight:700;color:var(--text-mute)}.ef-app-shell__sheet-item.is-active{background:var(--paper);color:var(--text);font-weight:700}.ef-app-shell__sheet-footer{display:grid;gap:8px;margin-top:16px;padding-top:16px;border-top:1px solid var(--rule)}.ef-app-shell__sheet-footer:empty{display:none}:host-context([dir=rtl]) .ef-app-shell__side-toggle svg{transform:scaleX(-1)}\n"] }]
7579
+ }], ctorParameters: () => [], propDecorators: { stripe: [{
7539
7580
  type: Input
7540
7581
  }] } });
7541
7582
 
@@ -7980,6 +8021,8 @@ class EfProfileChipComponent {
7980
8021
  tone = 'tenant';
7981
8022
  /** Render as a non-interactive container (no hover/focus, no click). */
7982
8023
  readonly = false;
8024
+ /** Avatar only, no name or role: for a trigger that sits in a toolbar. */
8025
+ compact = false;
7983
8026
  clickEvent = new EventEmitter();
7984
8027
  get computedInitial() {
7985
8028
  /* An explicit `initial` is taken verbatim — callers pass real initials
@@ -7998,11 +8041,11 @@ class EfProfileChipComponent {
7998
8041
  }
7999
8042
  }
8000
8043
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8001
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfProfileChipComponent, isStandalone: true, selector: "ef-profile-chip", inputs: { name: "name", role: "role", roleKey: "roleKey", initial: "initial", tone: "tone", readonly: ["readonly", "readonly", booleanAttribute] }, outputs: { clickEvent: "clickEvent" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"ef-profile-chip\"\n [class.is-tenant]=\"tone === 'tenant'\"\n [class.is-readonly]=\"readonly\"\n [attr.aria-label]=\"name || null\"\n [attr.tabindex]=\"readonly ? -1 : null\"\n (click)=\"handleClick($event)\"\n>\n <span class=\"ef-profile-chip__avatar\" aria-hidden=\"true\">{{ computedInitial }}</span>\n <span class=\"ef-profile-chip__text\">\n @if (name) {\n <span class=\"ef-profile-chip__name\">{{ name }}</span>\n }\n @if (roleKey || role) {\n <span class=\"ef-profile-chip__role\">\n @if (roleKey) {\n {{ roleKey | translate }}\n } @else {\n {{ role }}\n }\n </span>\n }\n </span>\n</button>\n", styles: ["@charset \"UTF-8\";:host{display:block}.ef-profile-chip{display:inline-flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:0;border-radius:var(--r-md, 8px);color:var(--text);cursor:pointer;text-align:start;font-family:inherit;transition:background var(--t-fast, .14s) var(--ease-out, ease-out)}.ef-profile-chip:hover:not(.is-readonly){background:color-mix(in srgb,var(--ink-active, #0f1115) 6%,transparent)}.ef-profile-chip:focus-visible{outline:2px solid color-mix(in srgb,var(--tenant-400, #6b7280) 60%,transparent);outline-offset:1px}.ef-profile-chip.is-readonly{cursor:default}.ef-profile-chip__avatar{display:inline-flex;align-items:center;justify-content:center;flex:0 0 32px;width:32px;height:32px;border-radius:var(--r-pill, 999px);background:var(--ink-active, #0f1115);color:var(--paper, #fff);font-family:var(--font-display);font-variation-settings:\"opsz\" 12,\"wght\" 700,\"wdth\" 80;font-size:12px;line-height:1;letter-spacing:-.01em}.is-tenant .ef-profile-chip__avatar{background:var(--tenant-500);color:var(--on-tenant)}.ef-profile-chip__text{display:flex;flex-direction:column;min-width:0;font-size:12px;line-height:1.3}.ef-profile-chip__name{font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ef-profile-chip__role{color:var(--text-mute);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8044
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfProfileChipComponent, isStandalone: true, selector: "ef-profile-chip", inputs: { name: "name", role: "role", roleKey: "roleKey", initial: "initial", tone: "tone", readonly: ["readonly", "readonly", booleanAttribute], compact: ["compact", "compact", booleanAttribute] }, outputs: { clickEvent: "clickEvent" }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"ef-profile-chip\"\n [class.is-tenant]=\"tone === 'tenant'\"\n [class.is-readonly]=\"readonly\"\n [class.is-compact]=\"compact\"\n [attr.aria-label]=\"name || null\"\n [attr.tabindex]=\"readonly ? -1 : null\"\n (click)=\"handleClick($event)\"\n>\n <span class=\"ef-profile-chip__avatar\" aria-hidden=\"true\">{{ computedInitial }}</span>\n @if (!compact) {\n <span class=\"ef-profile-chip__text\">\n @if (name) {\n <span class=\"ef-profile-chip__name\">{{ name }}</span>\n }\n @if (roleKey || role) {\n <span class=\"ef-profile-chip__role\">\n @if (roleKey) {\n {{ roleKey | translate }}\n } @else {\n {{ role }}\n }\n </span>\n }\n </span>\n }\n</button>\n", styles: ["@charset \"UTF-8\";:host{display:block}.ef-profile-chip{display:inline-flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:0;border-radius:var(--r-md, 8px);color:var(--text);cursor:pointer;text-align:start;font-family:inherit;transition:background var(--t-fast, .14s) var(--ease-out, ease-out)}.ef-profile-chip:hover:not(.is-readonly){background:color-mix(in srgb,var(--ink-active, #0f1115) 6%,transparent)}.ef-profile-chip:focus-visible{outline:2px solid color-mix(in srgb,var(--tenant-400, #6b7280) 60%,transparent);outline-offset:1px}.ef-profile-chip.is-readonly{cursor:default}.ef-profile-chip.is-compact{width:auto;padding:2px;border-radius:var(--r-pill, 999px)}.ef-profile-chip__avatar{display:inline-flex;align-items:center;justify-content:center;flex:0 0 32px;width:32px;height:32px;border-radius:var(--r-pill, 999px);background:var(--ink-active, #0f1115);color:var(--paper, #fff);font-family:var(--font-display);font-variation-settings:\"opsz\" 12,\"wght\" 700,\"wdth\" 80;font-size:12px;line-height:1;letter-spacing:-.01em}.is-tenant .ef-profile-chip__avatar{background:var(--tenant-500);color:var(--on-tenant)}.ef-profile-chip__text{display:flex;flex-direction:column;min-width:0;font-size:12px;line-height:1.3}.ef-profile-chip__name{font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ef-profile-chip__role{color:var(--text-mute);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8002
8045
  }
8003
8046
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileChipComponent, decorators: [{
8004
8047
  type: Component,
8005
- args: [{ selector: 'ef-profile-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, TranslateModule], template: "<button\n type=\"button\"\n class=\"ef-profile-chip\"\n [class.is-tenant]=\"tone === 'tenant'\"\n [class.is-readonly]=\"readonly\"\n [attr.aria-label]=\"name || null\"\n [attr.tabindex]=\"readonly ? -1 : null\"\n (click)=\"handleClick($event)\"\n>\n <span class=\"ef-profile-chip__avatar\" aria-hidden=\"true\">{{ computedInitial }}</span>\n <span class=\"ef-profile-chip__text\">\n @if (name) {\n <span class=\"ef-profile-chip__name\">{{ name }}</span>\n }\n @if (roleKey || role) {\n <span class=\"ef-profile-chip__role\">\n @if (roleKey) {\n {{ roleKey | translate }}\n } @else {\n {{ role }}\n }\n </span>\n }\n </span>\n</button>\n", styles: ["@charset \"UTF-8\";:host{display:block}.ef-profile-chip{display:inline-flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:0;border-radius:var(--r-md, 8px);color:var(--text);cursor:pointer;text-align:start;font-family:inherit;transition:background var(--t-fast, .14s) var(--ease-out, ease-out)}.ef-profile-chip:hover:not(.is-readonly){background:color-mix(in srgb,var(--ink-active, #0f1115) 6%,transparent)}.ef-profile-chip:focus-visible{outline:2px solid color-mix(in srgb,var(--tenant-400, #6b7280) 60%,transparent);outline-offset:1px}.ef-profile-chip.is-readonly{cursor:default}.ef-profile-chip__avatar{display:inline-flex;align-items:center;justify-content:center;flex:0 0 32px;width:32px;height:32px;border-radius:var(--r-pill, 999px);background:var(--ink-active, #0f1115);color:var(--paper, #fff);font-family:var(--font-display);font-variation-settings:\"opsz\" 12,\"wght\" 700,\"wdth\" 80;font-size:12px;line-height:1;letter-spacing:-.01em}.is-tenant .ef-profile-chip__avatar{background:var(--tenant-500);color:var(--on-tenant)}.ef-profile-chip__text{display:flex;flex-direction:column;min-width:0;font-size:12px;line-height:1.3}.ef-profile-chip__name{font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ef-profile-chip__role{color:var(--text-mute);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
8048
+ args: [{ selector: 'ef-profile-chip', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, TranslateModule], template: "<button\n type=\"button\"\n class=\"ef-profile-chip\"\n [class.is-tenant]=\"tone === 'tenant'\"\n [class.is-readonly]=\"readonly\"\n [class.is-compact]=\"compact\"\n [attr.aria-label]=\"name || null\"\n [attr.tabindex]=\"readonly ? -1 : null\"\n (click)=\"handleClick($event)\"\n>\n <span class=\"ef-profile-chip__avatar\" aria-hidden=\"true\">{{ computedInitial }}</span>\n @if (!compact) {\n <span class=\"ef-profile-chip__text\">\n @if (name) {\n <span class=\"ef-profile-chip__name\">{{ name }}</span>\n }\n @if (roleKey || role) {\n <span class=\"ef-profile-chip__role\">\n @if (roleKey) {\n {{ roleKey | translate }}\n } @else {\n {{ role }}\n }\n </span>\n }\n </span>\n }\n</button>\n", styles: ["@charset \"UTF-8\";:host{display:block}.ef-profile-chip{display:inline-flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:0;border-radius:var(--r-md, 8px);color:var(--text);cursor:pointer;text-align:start;font-family:inherit;transition:background var(--t-fast, .14s) var(--ease-out, ease-out)}.ef-profile-chip:hover:not(.is-readonly){background:color-mix(in srgb,var(--ink-active, #0f1115) 6%,transparent)}.ef-profile-chip:focus-visible{outline:2px solid color-mix(in srgb,var(--tenant-400, #6b7280) 60%,transparent);outline-offset:1px}.ef-profile-chip.is-readonly{cursor:default}.ef-profile-chip.is-compact{width:auto;padding:2px;border-radius:var(--r-pill, 999px)}.ef-profile-chip__avatar{display:inline-flex;align-items:center;justify-content:center;flex:0 0 32px;width:32px;height:32px;border-radius:var(--r-pill, 999px);background:var(--ink-active, #0f1115);color:var(--paper, #fff);font-family:var(--font-display);font-variation-settings:\"opsz\" 12,\"wght\" 700,\"wdth\" 80;font-size:12px;line-height:1;letter-spacing:-.01em}.is-tenant .ef-profile-chip__avatar{background:var(--tenant-500);color:var(--on-tenant)}.ef-profile-chip__text{display:flex;flex-direction:column;min-width:0;font-size:12px;line-height:1.3}.ef-profile-chip__name{font-weight:700;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ef-profile-chip__role{color:var(--text-mute);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n"] }]
8006
8049
  }], propDecorators: { name: [{
8007
8050
  type: Input
8008
8051
  }], role: [{
@@ -8016,6 +8059,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
8016
8059
  }], readonly: [{
8017
8060
  type: Input,
8018
8061
  args: [{ transform: booleanAttribute }]
8062
+ }], compact: [{
8063
+ type: Input,
8064
+ args: [{ transform: booleanAttribute }]
8019
8065
  }], clickEvent: [{
8020
8066
  type: Output
8021
8067
  }] } });
@@ -8051,6 +8097,8 @@ class EfProfileMenuComponent {
8051
8097
  initial = input('', ...(ngDevMode ? [{ debugName: "initial" }] : /* istanbul ignore next */ []));
8052
8098
  tone = input('tenant', ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
8053
8099
  items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
8100
+ /** `avatar` is the chip without its text, for the top bar while the
8101
+ * side panel (and the full chip in its footer) is folded away. */
8054
8102
  variant = input('chip', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
8055
8103
  itemSelected = output();
8056
8104
  /** Id of the one expanded group, or null. One at a time: a menu that
@@ -8079,11 +8127,11 @@ class EfProfileMenuComponent {
8079
8127
  popover?.hide();
8080
8128
  }
8081
8129
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8082
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfProfileMenuComponent, isStandalone: true, selector: "ef-profile-menu", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, secondary: { classPropertyName: "secondary", publicName: "secondary", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, initial: { classPropertyName: "initial", publicName: "initial", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, ngImport: i0, template: "@if (variant() === 'chip') {\n <ef-profile-chip\n [name]=\"name()\"\n [role]=\"chipRole()\"\n [initial]=\"initial()\"\n [tone]=\"tone()\"\n (clickEvent)=\"op.toggle($event)\"\n />\n <!-- The popover is reduced to a placement mechanism: `.ef-menu` inside it\n draws the surface, so `ef-menu-popover` strips PrimeNG's own panel and\n arrow rather than letting two panels stack. -->\n <p-popover #op styleClass=\"ef-menu-popover\" appendTo=\"body\">\n <ng-container *ngTemplateOutlet=\"panel; context: { $implicit: op }\" />\n </p-popover>\n} @else {\n <ng-container *ngTemplateOutlet=\"panel\" />\n}\n\n<ng-template #panel let-op>\n <div class=\"ef-menu\" role=\"menu\" [attr.aria-label]=\"name() || null\">\n @if (name() || secondary()) {\n <div class=\"ef-menu__head\">\n @if (name()) {\n <span class=\"ef-menu__head-name\">{{ name() }}</span>\n }\n @if (secondary()) {\n <span class=\"ef-menu__head-sub\">{{ secondary() }}</span>\n }\n </div>\n }\n\n @for (item of items(); track item.id) {\n @if (item.groupStart) {\n <div class=\"ef-menu__divider\" role=\"separator\"></div>\n }\n\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n [class.danger]=\"item.severity === 'danger'\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"select(item, op)\"\n >\n @if (item.icon) {\n <i [class]=\"'ico ' + item.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-menu__badge\">{{ item.badge }}</span>\n }\n @if (item.children?.length) {\n <i\n class=\"ef-menu__caret pi\"\n [class.pi-chevron-down]=\"!isExpanded(item.id)\"\n [class.pi-chevron-up]=\"isExpanded(item.id)\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <div class=\"ef-menu__sublist\" role=\"group\">\n @for (child of item.children; track child.id) {\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n (click)=\"select(child, op)\"\n >\n @if (child.icon) {\n <i [class]=\"'ico ' + child.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ child.labelKey | translate }}</span>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-width:0}.ef-menu{min-width:232px;max-width:288px;max-height:calc(100vh - 32px);overflow-y:auto}@media(max-width:767px){.ef-menu{min-width:0}.ef-menu__item{min-height:var(--hit-touch);padding-block:0;font-size:14px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$4.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: EfProfileChipComponent, selector: "ef-profile-chip", inputs: ["name", "role", "roleKey", "initial", "tone", "readonly"], outputs: ["clickEvent"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8130
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EfProfileMenuComponent, isStandalone: true, selector: "ef-profile-menu", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, secondary: { classPropertyName: "secondary", publicName: "secondary", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, initial: { classPropertyName: "initial", publicName: "initial", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelected: "itemSelected" }, ngImport: i0, template: "@if (variant() !== 'list') {\n <ef-profile-chip\n [name]=\"name()\"\n [role]=\"chipRole()\"\n [initial]=\"initial()\"\n [tone]=\"tone()\"\n [compact]=\"variant() === 'avatar'\"\n (clickEvent)=\"op.toggle($event)\"\n />\n <!-- The popover is reduced to a placement mechanism: `.ef-menu` inside it\n draws the surface, so `ef-menu-popover` strips PrimeNG's own panel and\n arrow rather than letting two panels stack. -->\n <p-popover #op styleClass=\"ef-menu-popover\" appendTo=\"body\">\n <ng-container *ngTemplateOutlet=\"panel; context: { $implicit: op }\" />\n </p-popover>\n} @else {\n <ng-container *ngTemplateOutlet=\"panel\" />\n}\n\n<ng-template #panel let-op>\n <div class=\"ef-menu\" role=\"menu\" [attr.aria-label]=\"name() || null\">\n @if (name() || secondary()) {\n <div class=\"ef-menu__head\">\n @if (name()) {\n <span class=\"ef-menu__head-name\">{{ name() }}</span>\n }\n @if (secondary()) {\n <span class=\"ef-menu__head-sub\">{{ secondary() }}</span>\n }\n </div>\n }\n\n @for (item of items(); track item.id) {\n @if (item.groupStart) {\n <div class=\"ef-menu__divider\" role=\"separator\"></div>\n }\n\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n [class.danger]=\"item.severity === 'danger'\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"select(item, op)\"\n >\n @if (item.icon) {\n <i [class]=\"'ico ' + item.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-menu__badge\">{{ item.badge }}</span>\n }\n @if (item.children?.length) {\n <i\n class=\"ef-menu__caret pi\"\n [class.pi-chevron-down]=\"!isExpanded(item.id)\"\n [class.pi-chevron-up]=\"isExpanded(item.id)\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <div class=\"ef-menu__sublist\" role=\"group\">\n @for (child of item.children; track child.id) {\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n (click)=\"select(child, op)\"\n >\n @if (child.icon) {\n <i [class]=\"'ico ' + child.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ child.labelKey | translate }}</span>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-width:0}.ef-menu{min-width:232px;max-width:288px;max-height:calc(100vh - 32px);overflow-y:auto}@media(max-width:767px){.ef-menu{min-width:0}.ef-menu__item{min-height:var(--hit-touch);padding-block:0;font-size:14px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$4.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: EfProfileChipComponent, selector: "ef-profile-chip", inputs: ["name", "role", "roleKey", "initial", "tone", "readonly", "compact"], outputs: ["clickEvent"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8083
8131
  }
8084
8132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EfProfileMenuComponent, decorators: [{
8085
8133
  type: Component,
8086
- args: [{ selector: 'ef-profile-menu', standalone: true, imports: [CommonModule, TranslateModule, PopoverModule, EfProfileChipComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (variant() === 'chip') {\n <ef-profile-chip\n [name]=\"name()\"\n [role]=\"chipRole()\"\n [initial]=\"initial()\"\n [tone]=\"tone()\"\n (clickEvent)=\"op.toggle($event)\"\n />\n <!-- The popover is reduced to a placement mechanism: `.ef-menu` inside it\n draws the surface, so `ef-menu-popover` strips PrimeNG's own panel and\n arrow rather than letting two panels stack. -->\n <p-popover #op styleClass=\"ef-menu-popover\" appendTo=\"body\">\n <ng-container *ngTemplateOutlet=\"panel; context: { $implicit: op }\" />\n </p-popover>\n} @else {\n <ng-container *ngTemplateOutlet=\"panel\" />\n}\n\n<ng-template #panel let-op>\n <div class=\"ef-menu\" role=\"menu\" [attr.aria-label]=\"name() || null\">\n @if (name() || secondary()) {\n <div class=\"ef-menu__head\">\n @if (name()) {\n <span class=\"ef-menu__head-name\">{{ name() }}</span>\n }\n @if (secondary()) {\n <span class=\"ef-menu__head-sub\">{{ secondary() }}</span>\n }\n </div>\n }\n\n @for (item of items(); track item.id) {\n @if (item.groupStart) {\n <div class=\"ef-menu__divider\" role=\"separator\"></div>\n }\n\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n [class.danger]=\"item.severity === 'danger'\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"select(item, op)\"\n >\n @if (item.icon) {\n <i [class]=\"'ico ' + item.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-menu__badge\">{{ item.badge }}</span>\n }\n @if (item.children?.length) {\n <i\n class=\"ef-menu__caret pi\"\n [class.pi-chevron-down]=\"!isExpanded(item.id)\"\n [class.pi-chevron-up]=\"isExpanded(item.id)\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <div class=\"ef-menu__sublist\" role=\"group\">\n @for (child of item.children; track child.id) {\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n (click)=\"select(child, op)\"\n >\n @if (child.icon) {\n <i [class]=\"'ico ' + child.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ child.labelKey | translate }}</span>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-width:0}.ef-menu{min-width:232px;max-width:288px;max-height:calc(100vh - 32px);overflow-y:auto}@media(max-width:767px){.ef-menu{min-width:0}.ef-menu__item{min-height:var(--hit-touch);padding-block:0;font-size:14px}}\n"] }]
8134
+ args: [{ selector: 'ef-profile-menu', standalone: true, imports: [CommonModule, TranslateModule, PopoverModule, EfProfileChipComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (variant() !== 'list') {\n <ef-profile-chip\n [name]=\"name()\"\n [role]=\"chipRole()\"\n [initial]=\"initial()\"\n [tone]=\"tone()\"\n [compact]=\"variant() === 'avatar'\"\n (clickEvent)=\"op.toggle($event)\"\n />\n <!-- The popover is reduced to a placement mechanism: `.ef-menu` inside it\n draws the surface, so `ef-menu-popover` strips PrimeNG's own panel and\n arrow rather than letting two panels stack. -->\n <p-popover #op styleClass=\"ef-menu-popover\" appendTo=\"body\">\n <ng-container *ngTemplateOutlet=\"panel; context: { $implicit: op }\" />\n </p-popover>\n} @else {\n <ng-container *ngTemplateOutlet=\"panel\" />\n}\n\n<ng-template #panel let-op>\n <div class=\"ef-menu\" role=\"menu\" [attr.aria-label]=\"name() || null\">\n @if (name() || secondary()) {\n <div class=\"ef-menu__head\">\n @if (name()) {\n <span class=\"ef-menu__head-name\">{{ name() }}</span>\n }\n @if (secondary()) {\n <span class=\"ef-menu__head-sub\">{{ secondary() }}</span>\n }\n </div>\n }\n\n @for (item of items(); track item.id) {\n @if (item.groupStart) {\n <div class=\"ef-menu__divider\" role=\"separator\"></div>\n }\n\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n [class.danger]=\"item.severity === 'danger'\"\n [attr.aria-expanded]=\"item.children?.length ? isExpanded(item.id) : null\"\n (click)=\"select(item, op)\"\n >\n @if (item.icon) {\n <i [class]=\"'ico ' + item.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ item.labelKey | translate }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <span class=\"ef-menu__badge\">{{ item.badge }}</span>\n }\n @if (item.children?.length) {\n <i\n class=\"ef-menu__caret pi\"\n [class.pi-chevron-down]=\"!isExpanded(item.id)\"\n [class.pi-chevron-up]=\"isExpanded(item.id)\"\n aria-hidden=\"true\"\n ></i>\n }\n </button>\n\n @if (item.children?.length && isExpanded(item.id)) {\n <div class=\"ef-menu__sublist\" role=\"group\">\n @for (child of item.children; track child.id) {\n <button\n type=\"button\"\n class=\"ef-menu__item\"\n role=\"menuitem\"\n (click)=\"select(child, op)\"\n >\n @if (child.icon) {\n <i [class]=\"'ico ' + child.icon\" aria-hidden=\"true\"></i>\n }\n <span class=\"ef-menu__label\">{{ child.labelKey | translate }}</span>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;min-width:0}.ef-menu{min-width:232px;max-width:288px;max-height:calc(100vh - 32px);overflow-y:auto}@media(max-width:767px){.ef-menu{min-width:0}.ef-menu__item{min-height:var(--hit-touch);padding-block:0;font-size:14px}}\n"] }]
8087
8135
  }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], secondary: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondary", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], initial: [{ type: i0.Input, args: [{ isSignal: true, alias: "initial", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
8088
8136
 
8089
8137
  class EfBlockUiComponent {