@shival99/z-ui 2.4.5 → 2.4.6

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.
@@ -6,6 +6,7 @@ import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
6
6
  import { Router, NavigationEnd } from '@angular/router';
7
7
  import { TranslatePipe } from '@ngx-translate/core';
8
8
  import { ZButtonComponent } from '@shival99/z-ui/components/z-button';
9
+ import { ZHoverGlideDirective } from '@shival99/z-ui/components/z-hover-glide';
9
10
  import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
10
11
  import { ZPopoverDirective } from '@shival99/z-ui/components/z-popover';
11
12
  import { ZTooltipDirective } from '@shival99/z-ui/components/z-tooltip';
@@ -424,7 +425,7 @@ class ZMenuComponent {
424
425
  return ZCacheService.get(this.zKey(), false) ?? false;
425
426
  }
426
427
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
427
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ZMenuComponent, isStandalone: true, selector: "z-menu", inputs: { zLogo: { classPropertyName: "zLogo", publicName: "zLogo", isSignal: true, isRequired: false, transformFunction: null }, zLogoMobile: { classPropertyName: "zLogoMobile", publicName: "zLogoMobile", isSignal: true, isRequired: false, transformFunction: null }, zMenus: { classPropertyName: "zMenus", publicName: "zMenus", isSignal: true, isRequired: false, transformFunction: null }, zUser: { classPropertyName: "zUser", publicName: "zUser", isSignal: true, isRequired: false, transformFunction: null }, zUserActions: { classPropertyName: "zUserActions", publicName: "zUserActions", isSignal: true, isRequired: false, transformFunction: null }, zActionsTemplate: { classPropertyName: "zActionsTemplate", publicName: "zActionsTemplate", isSignal: true, isRequired: false, transformFunction: null }, zCurrentPath: { classPropertyName: "zCurrentPath", publicName: "zCurrentPath", isSignal: true, isRequired: false, transformFunction: null }, zKey: { classPropertyName: "zKey", publicName: "zKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOnSelect: "zOnSelect", zOnMenuAction: "zOnMenuAction", zControl: "zControl" }, host: { properties: { "class.z-menu-collapsed": "sidebarCollapsed()", "class.z-menu-no-child": "selectedParentHasNoChild()", "class.z-menu-mobile": "isMobile()", "class.z-menu-mobile-open": "mobileMenuOpen()" }, classAttribute: "z-menu block" }, providers: [TranslatePipe], ngImport: i0, template: "<!-- DESKTOP LAYOUT - Hidden on mobile -->\n<div class=\"z-menu-desktop relative z-200 hidden h-full py-1 pl-1 md:block\" [class.collapsed]=\"sidebarCollapsed()\">\n <main class=\"z-menu-main relative flex h-full\">\n <div class=\"z-sidebar-main h-full w-[3.125rem]\">\n <div\n class=\"z-shadow-menu bg-sidebar border-border/40 dark:border-sidebar-border relative flex h-full w-full flex-col items-center gap-1.5 rounded-md border\"></div>\n\n <div class=\"bg-sidebar text-sidebar-foreground absolute inset-px z-20 flex flex-col rounded-md\">\n @if (zLogo()) {\n <div class=\"border-sidebar-border flex h-[3.25rem] items-center justify-center border-b px-2\">\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n </div>\n }\n\n <!-- Expand Button - Only show when collapsed -->\n @if (sidebarCollapsed() && selectedParent()) {\n <div\n class=\"z-expand-btn hover:bg-sidebar-accent mx-auto mt-2 flex h-9 w-9 cursor-pointer items-center justify-center rounded-md\"\n (click)=\"toggleSidebar()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"20\" class=\"opacity-70\" />\n </div>\n }\n\n <div class=\"flex flex-1 flex-col items-center gap-2 p-2\">\n @for (item of menuParents(); track item.id) {\n @let hasActiveChild = parentWithActiveChild()?.id === item.id;\n @let isCurrentlySelected = selectedParent()?.id === item.id;\n @let showActiveIndicator = hasActiveChild && !isCurrentlySelected;\n <div\n zTooltip\n [zContent]=\"item.name | translate\"\n zPosition=\"right\"\n [zAlwaysShow]=\"true\"\n class=\"relative flex h-9 w-9 cursor-pointer items-center justify-center rounded-md select-none\"\n [class.bg-sidebar-primary]=\"selectedParent()?.id === item.id\"\n [class.text-sidebar-primary-foreground]=\"selectedParent()?.id === item.id\"\n [class.hover:bg-sidebar-accent]=\"selectedParent()?.id !== item.id\"\n (click)=\"onDesktopParentClick(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon\" zSize=\"20\" />\n } @else {\n <z-icon [zSvg]=\"item.iconSvg || ''\" zSize=\"20\" />\n }\n @if (showActiveIndicator) {\n <div\n class=\"bg-sidebar-primary absolute top-1/2 -left-[0.3125rem] h-4 w-1 -translate-y-1/2 rounded-full\"></div>\n }\n </div>\n }\n </div>\n\n <div class=\"border-sidebar-border flex items-center justify-center border-t p-2\">\n <div\n z-popover\n [zOffset]=\"11\"\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n class=\"aspect-square h-9 w-9 shrink-0 cursor-pointer overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <!-- User Info Header - Always shown -->\n <div class=\"p-0 text-sm font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-medium\">{{ zUser()?.name || 'User Name' }}</span>\n <span class=\"text-muted-foreground mt-0.5 truncate text-xs\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n </div>\n\n @if (getVisibleUserActions().length > 0 || zActionsTemplate()) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <!-- Actions - Custom or from zUserActions -->\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n\n @if (selectedParent(); as parent) {\n @let hasChildrenOrTemplate = parent.menuTemplate || (parent.children && parent.children.length > 0);\n @if (hasChildrenOrTemplate) {\n <div\n class=\"z-sidebar-child-wrapper\"\n [class.collapsed]=\"sidebarCollapsed()\"\n [style.--sidebar-child-width.px]=\"sidebarChildWidth()\">\n <div\n class=\"z-sidebar-child z-shadow-menu bg-card text-card-foreground border-border/40 dark:border-sidebar-border flex h-full shrink-0 flex-col items-start overflow-hidden rounded-md border\"\n [style.width.px]=\"sidebarChildWidth()\"\n [class.collapsed]=\"sidebarCollapsed()\">\n <div\n #selectedParentHeaderTrigger\n class=\"border-border flex h-[3.25rem] w-full shrink-0 items-center border-b px-3\">\n @if (selectedParent()?.icon) {\n <z-icon [zType]=\"selectedParent()!.icon\" zSize=\"20\" class=\"mr-2 shrink-0\" />\n }\n <div\n class=\"mr-4 min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n zPosition=\"top-left\"\n [zContent]=\"selectedParent()?.name || '' | translate\"\n [zTriggerElement]=\"selectedParentHeaderTrigger\"\n [zOffset]=\"6\">\n {{ selectedParent()?.name | translate }}\n </div>\n\n <z-icon\n zType=\"lucidePanelRightOpen\"\n zSize=\"20\"\n class=\"shrink-0 cursor-pointer opacity-60 hover:opacity-100\"\n (click)=\"toggleSidebar()\" />\n </div>\n\n <!-- Show menuTemplate if available, otherwise show children -->\n @if (selectedParent()?.menuTemplate) {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1\" track=\"vertical\">\n <div class=\"flex w-full flex-col p-3 pr-2\">\n <ng-container\n *ngTemplateOutlet=\"\n selectedParent()!.menuTemplate!;\n context: { $implicit: selectedParent()!, close: closeSidebarFn }\n \" />\n </div>\n </ng-scrollbar>\n } @else {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1 overflow-hidden\" track=\"vertical\">\n <div class=\"flex w-full min-w-0 flex-col gap-1 overflow-hidden py-1 pr-2 pl-2\">\n <ng-container *ngTemplateOutlet=\"menuChildrenTpl; context: { $implicit: menuChildren() }\" />\n </div>\n </ng-scrollbar>\n }\n </div>\n </div>\n }\n }\n </main>\n</div>\n\n<!-- MOBILE LAYOUT - Visible only on mobile -->\n<div class=\"z-menu-mobile-wrapper hidden max-md:block\">\n <!-- Mobile Backdrop -->\n @if (mobileMenuOpen() || mobileTemplateDrawerOpen()) {\n <div\n class=\"z-menu-backdrop fixed inset-0 z-9998\"\n [class.z-menu-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onBackdropClick()\"></div>\n }\n\n <!-- Mobile Drawer -->\n <aside\n class=\"z-menu-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full w-70 flex-col rounded-r-lg border-r\"\n [class.open]=\"mobileMenuOpen()\">\n <!-- Drawer Header -->\n <div class=\"border-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"bg-accent h-9 w-9 shrink-0\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <!-- Drawer Content - Accordion Menu -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-3\">\n @for (parent of menuParents(); track parent.id) {\n <div class=\"mb-1\">\n <!-- Parent Item -->\n @let isParentActive =\n selectedMenuItem()?.id === parent.id && (!parent.children || parent.children.length === 0);\n @let hasActiveChild = parentWithActiveChild()?.id === parent.id && !isParentActive;\n @let isCurrentlyViewing = selectedParent()?.id === parent.id;\n <div\n #mobileParentTrigger\n class=\"relative flex cursor-pointer items-center gap-3 rounded-md p-2\"\n [class.bg-primary/20]=\"isParentActive\"\n [class.text-primary]=\"isParentActive || hasActiveChild\"\n [class.hover:bg-accent]=\"!isParentActive\"\n (click)=\"onMobileParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"parent.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileParentTrigger\">\n {{ parent.name | translate }}\n </span>\n @if ((parent.children && parent.children.length > 0) || parent.menuTemplate) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"16\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"parent.expanded && isCurrentlyViewing\" />\n }\n </div>\n\n <!-- Children (Accordion) - Only render if NO menuTemplate -->\n @if (parent.children && parent.children.length > 0 && !parent.menuTemplate) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"parent.expanded && isCurrentlyViewing\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (child of parent.children; track child.id) {\n @let isChildActive =\n selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n\n <div>\n <div\n #mobileChildTrigger\n class=\"relative flex cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-accent]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1.5 w-1.5 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isChildActive\"\n [class.bg-gray-400]=\"!isChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileChildTrigger\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n <!-- Level 3 -->\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #mobileSubChildTrigger\n class=\"flex cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-accent]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileSubChildTrigger\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </ng-scrollbar>\n\n <!-- Drawer Footer - User Info -->\n <div class=\"border-border shrink-0 border-t p-3\">\n <div\n z-popover\n [zOffset]=\"6\"\n [zPopoverContent]=\"mobileActionsPopoverTpl\"\n zPosition=\"top-right\"\n zTrigger=\"click\"\n class=\"hover:bg-accent flex cursor-pointer items-center gap-3 rounded-md p-2\">\n <div class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div class=\"truncate text-sm font-medium\">{{ zUser()?.name || 'User Name' }}</div>\n <div class=\"text-muted-foreground truncate text-xs\">{{ zUser()?.email || 'user@example.com' }}</div>\n </div>\n <div class=\"text-muted-foreground flex shrink-0 flex-col\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"-mt-1\" />\n </div>\n </div>\n </div>\n </aside>\n\n <!-- Mobile Custom Template Drawer -->\n <aside\n class=\"z-menu-custom-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full max-w-[calc(100vw-1rem)] flex-col rounded-r-lg border-r\"\n [style.width.px]=\"mobileCustomDrawerWidth()\"\n [class.open]=\"mobileTemplateDrawerOpen() && customDrawerParent()?.menuTemplate\">\n @if (customDrawerParent()?.menuTemplate) {\n <!-- Custom Drawer Header -->\n <div #customDrawerHeaderTrigger class=\"border-border flex h-14 shrink-0 items-center gap-3 border-b px-4\">\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"bg-accent h-9 w-9 shrink-0\"\n (click)=\"closeMobileTemplateDrawer()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"20\" />\n </button>\n <span\n class=\"min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n [zContent]=\"customDrawerParent()?.name || '' | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"customDrawerHeaderTrigger\">\n {{ customDrawerParent()?.name | translate }}\n </span>\n </div>\n\n <!-- Custom Template Content -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-4\">\n <ng-container\n *ngTemplateOutlet=\"\n customDrawerParent()!.menuTemplate!;\n context: { $implicit: customDrawerParent()!, close: closeMobileDrawerFn }\n \" />\n </div>\n </ng-scrollbar>\n }\n </aside>\n\n <ng-template #mobileActionsPopoverTpl let-close=\"close\">\n <div class=\"min-w-48 p-1\">\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n</div>\n\n<!-- Shared Template for Menu Children -->\n<ng-template #menuChildrenTpl let-children>\n @for (child of children; track child.id) {\n @let isChildActive = selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n @if (child.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ child.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"w-full min-w-0\">\n <div\n #divLevel1\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-gray-200]=\"!isChildActive\"\n [class.dark:hover:bg-input/50]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel1\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id; let isLast = $last) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #divLevel2\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-gray-200]=\"!isSubChildActive\"\n [class.dark:hover:bg-input/50]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel2\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".z-menu{display:block;flex-shrink:0;height:100%}.z-menu [class*=cursor-pointer]{-webkit-user-select:none;user-select:none}@media(min-width:48rem){.z-menu{contain:layout style;min-width:283px;transition:min-width .25s cubic-bezier(.4,0,.2,1);will-change:min-width}.z-menu.z-menu-collapsed,.z-menu.z-menu-no-child{min-width:53px}}.z-shadow-menu{box-shadow:0 0 10px #0000001f}@media(max-width:47.9375rem){.z-menu-desktop{display:none!important;pointer-events:none;visibility:hidden}}.z-sidebar-main{position:relative;z-index:20;flex-shrink:0}.z-sidebar-main>div{background-color:var(--z-menu-v1-sidebar, var(--sidebar));color:var(--z-menu-v1-sidebar-foreground, var(--sidebar-foreground))}.z-sidebar-main .bg-sidebar-primary{background-color:var(--z-menu-v1-parent-active, var(--sidebar-primary));color:var(--z-menu-v1-parent-active-foreground, var(--sidebar-primary-foreground))}.z-menu-item.bg-primary,.z-menu-mobile-wrapper .bg-primary{background-color:var(--z-menu-v1-item-active, var(--primary));color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-menu-item.bg-primary .bg-primary-foreground,.z-menu-mobile-wrapper .bg-primary .bg-primary-foreground{background-color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-sidebar-child-wrapper{--sidebar-child-width: 230px;position:absolute;left:0;top:0;width:calc(100% + -0px);height:100%;clip-path:inset(0 -100px 0 0);pointer-events:none;transition:clip-path .25s cubic-bezier(.4,0,.2,1);will-change:clip-path;contain:layout}.z-sidebar-child-wrapper.collapsed{clip-path:inset(0 -100px 0 53px)}.z-sidebar-child{flex-shrink:0;height:100%;margin-left:53px;transform:translate(0);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1);pointer-events:auto;will-change:transform,width;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{transform:translate(calc(-1 * (var(--sidebar-child-width) + 50px + .3125rem)))}.z-menu-arrow.expanded{transform:rotate(90deg)}.z-menu-submenu{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-out}.z-menu-submenu.expanded{grid-template-rows:1fr}.z-menu-submenu>.z-menu-submenu-inner{overflow:hidden;min-height:0}.z-menu-backdrop{animation:z-menu-backdrop-enter .2s ease-out forwards}.z-menu-backdrop-dark{background-color:#0009}.z-menu-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a}.z-menu-drawer.open{transform:translate(0)}:host.z-menu-mobile-open .z-menu-drawer{transform:translate(0)}.z-menu-desktop.collapsed .z-sidebar-child-wrapper{pointer-events:none}.z-menu-custom-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-custom-drawer.open{transform:translate(0)}@keyframes z-menu-backdrop-enter{0%{opacity:0}to{opacity:1}}@keyframes z-expand-btn-enter{0%{opacity:0;transform:scale(.5) translateY(.625rem)}70%{transform:scale(1.1) translateY(-.125rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-expand-btn{animation:z-expand-btn-enter .25s cubic-bezier(.34,1.56,.64,1) forwards}.z-menu-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-scrollbar .ng-scroll-viewport,.z-menu-scrollbar .ng-scroll-content{max-width:100%}.z-menu-item{min-width:0;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTooltipPosition", "zTrigger", "zTooltipTrigger", "zTooltipType", "zTooltipSize", "zClass", "zTooltipClass", "zShowDelay", "zTooltipShowDelay", "zHideDelay", "zTooltipHideDelay", "zArrow", "zTooltipArrow", "zDisabled", "zTooltipDisabled", "zOffset", "zTooltipOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zSticky", "zShowArrow", "zKeyboardSafe"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], exportAs: ["zPopover"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
428
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ZMenuComponent, isStandalone: true, selector: "z-menu", inputs: { zLogo: { classPropertyName: "zLogo", publicName: "zLogo", isSignal: true, isRequired: false, transformFunction: null }, zLogoMobile: { classPropertyName: "zLogoMobile", publicName: "zLogoMobile", isSignal: true, isRequired: false, transformFunction: null }, zMenus: { classPropertyName: "zMenus", publicName: "zMenus", isSignal: true, isRequired: false, transformFunction: null }, zUser: { classPropertyName: "zUser", publicName: "zUser", isSignal: true, isRequired: false, transformFunction: null }, zUserActions: { classPropertyName: "zUserActions", publicName: "zUserActions", isSignal: true, isRequired: false, transformFunction: null }, zActionsTemplate: { classPropertyName: "zActionsTemplate", publicName: "zActionsTemplate", isSignal: true, isRequired: false, transformFunction: null }, zCurrentPath: { classPropertyName: "zCurrentPath", publicName: "zCurrentPath", isSignal: true, isRequired: false, transformFunction: null }, zKey: { classPropertyName: "zKey", publicName: "zKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOnSelect: "zOnSelect", zOnMenuAction: "zOnMenuAction", zControl: "zControl" }, host: { properties: { "class.z-menu-collapsed": "sidebarCollapsed()", "class.z-menu-no-child": "selectedParentHasNoChild()", "class.z-menu-mobile": "isMobile()", "class.z-menu-mobile-open": "mobileMenuOpen()" }, classAttribute: "z-menu block" }, providers: [TranslatePipe], ngImport: i0, template: "<!-- DESKTOP LAYOUT - Hidden on mobile -->\n<div class=\"z-menu-desktop relative z-200 hidden h-full py-1 pl-1 md:block\" [class.collapsed]=\"sidebarCollapsed()\">\n <main class=\"z-menu-main relative flex h-full\">\n <div class=\"z-sidebar-main h-full w-[3.125rem]\">\n <div\n class=\"z-shadow-menu bg-sidebar border-border/40 dark:border-sidebar-border relative flex h-full w-full flex-col items-center gap-1.5 rounded-md border\"></div>\n\n <div class=\"bg-sidebar text-sidebar-foreground absolute inset-px z-20 flex flex-col rounded-md\">\n @if (zLogo()) {\n <div class=\"border-sidebar-border flex h-[3.25rem] items-center justify-center border-b px-2\">\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n </div>\n }\n\n <!-- Expand Button - Only show when collapsed -->\n @if (sidebarCollapsed() && selectedParent()) {\n <div\n class=\"z-expand-btn hover:bg-sidebar-accent mx-auto mt-2 flex h-9 w-9 cursor-pointer items-center justify-center rounded-md\"\n (click)=\"toggleSidebar()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"20\" class=\"opacity-70\" />\n </div>\n }\n\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-sidebar-accent rounded-(--radius)\"\n class=\"flex flex-1 flex-col items-center gap-2 p-2\">\n @for (item of menuParents(); track item.id) {\n @let hasActiveChild = parentWithActiveChild()?.id === item.id;\n @let isCurrentlySelected = selectedParent()?.id === item.id;\n @let showActiveIndicator = hasActiveChild && !isCurrentlySelected;\n <div\n zTooltip\n [zContent]=\"item.name | translate\"\n zPosition=\"right\"\n [zAlwaysShow]=\"true\"\n data-glide-item\n class=\"relative z-[1] flex h-9 w-9 cursor-pointer items-center justify-center rounded-(--radius) select-none\"\n [class.bg-sidebar-primary]=\"selectedParent()?.id === item.id\"\n [class.text-sidebar-primary-foreground]=\"selectedParent()?.id === item.id\"\n (click)=\"onDesktopParentClick(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon\" zSize=\"20\" />\n } @else {\n <z-icon [zSvg]=\"item.iconSvg || ''\" zSize=\"20\" />\n }\n @if (showActiveIndicator) {\n <div\n class=\"bg-sidebar-primary absolute top-1/2 -left-[0.3125rem] h-4 w-1 -translate-y-1/2 rounded-full\"></div>\n }\n </div>\n }\n </div>\n\n <div class=\"border-sidebar-border flex items-center justify-center border-t p-2\">\n <div\n z-popover\n [zOffset]=\"11\"\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n class=\"aspect-square h-9 w-9 shrink-0 cursor-pointer overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <!-- User Info Header - Always shown -->\n <div class=\"p-0 text-sm font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-medium\">{{ zUser()?.name || 'User Name' }}</span>\n <span class=\"text-muted-foreground mt-0.5 truncate text-xs\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n </div>\n\n @if (getVisibleUserActions().length > 0 || zActionsTemplate()) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <!-- Actions - Custom or from zUserActions -->\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius-sm)\">\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n data-glide-item\n [class]=\"action.class\"\n class=\"focus:bg-accent relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius-sm) px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n }\n </div>\n </ng-template>\n\n @if (selectedParent(); as parent) {\n @let hasChildrenOrTemplate = parent.menuTemplate || (parent.children && parent.children.length > 0);\n @if (hasChildrenOrTemplate) {\n <div\n class=\"z-sidebar-child-wrapper\"\n [class.collapsed]=\"sidebarCollapsed()\"\n [style.--sidebar-child-width.px]=\"sidebarChildWidth()\">\n <div\n class=\"z-sidebar-child z-shadow-menu bg-card text-card-foreground border-border/40 dark:border-sidebar-border flex h-full shrink-0 flex-col items-start overflow-hidden rounded-md border\"\n [style.width.px]=\"sidebarChildWidth()\"\n [class.collapsed]=\"sidebarCollapsed()\">\n <div\n #selectedParentHeaderTrigger\n class=\"border-border flex h-[3.25rem] w-full shrink-0 items-center border-b px-3\">\n @if (selectedParent()?.icon) {\n <z-icon [zType]=\"selectedParent()!.icon\" zSize=\"20\" class=\"mr-2 shrink-0\" />\n }\n <div\n class=\"mr-4 min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n zPosition=\"top-left\"\n [zContent]=\"selectedParent()?.name || '' | translate\"\n [zTriggerElement]=\"selectedParentHeaderTrigger\"\n [zOffset]=\"6\">\n {{ selectedParent()?.name | translate }}\n </div>\n\n <z-icon\n zType=\"lucidePanelRightOpen\"\n zSize=\"20\"\n class=\"shrink-0 cursor-pointer opacity-60 hover:opacity-100\"\n (click)=\"toggleSidebar()\" />\n </div>\n\n <!-- Show menuTemplate if available, otherwise show children -->\n @if (selectedParent()?.menuTemplate) {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1\" track=\"vertical\">\n <div class=\"flex w-full flex-col p-3 pr-2\">\n <ng-container\n *ngTemplateOutlet=\"\n selectedParent()!.menuTemplate!;\n context: { $implicit: selectedParent()!, close: closeSidebarFn }\n \" />\n </div>\n </ng-scrollbar>\n } @else {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1 overflow-hidden\" track=\"vertical\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"flex w-full min-w-0 flex-col gap-1 overflow-hidden py-1 pr-2 pl-2\">\n <ng-container *ngTemplateOutlet=\"menuChildrenTpl; context: { $implicit: menuChildren() }\" />\n </div>\n </ng-scrollbar>\n }\n </div>\n </div>\n }\n }\n </main>\n</div>\n\n<!-- MOBILE LAYOUT - Visible only on mobile -->\n<div class=\"z-menu-mobile-wrapper hidden max-md:block\">\n <!-- Mobile Backdrop -->\n @if (mobileMenuOpen() || mobileTemplateDrawerOpen()) {\n <div\n class=\"z-menu-backdrop fixed inset-0 z-9998\"\n [class.z-menu-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onBackdropClick()\"></div>\n }\n\n <!-- Mobile Drawer -->\n <aside\n class=\"z-menu-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full w-70 flex-col rounded-r-lg border-r\"\n [class.open]=\"mobileMenuOpen()\">\n <!-- Drawer Header -->\n <div class=\"border-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"bg-accent h-9 w-9 shrink-0\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <!-- Drawer Content - Accordion Menu -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"p-3\">\n @for (parent of menuParents(); track parent.id) {\n <div class=\"mb-1\">\n <!-- Parent Item -->\n @let isParentActive =\n selectedMenuItem()?.id === parent.id && (!parent.children || parent.children.length === 0);\n @let hasActiveChild = parentWithActiveChild()?.id === parent.id && !isParentActive;\n @let isCurrentlyViewing = selectedParent()?.id === parent.id;\n <div\n #mobileParentTrigger\n data-glide-item\n class=\"relative z-[1] flex cursor-pointer items-center gap-3 rounded-(--radius) p-2\"\n [class.bg-primary/20]=\"isParentActive\"\n [class.text-primary]=\"isParentActive || hasActiveChild\"\n (click)=\"onMobileParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"parent.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileParentTrigger\">\n {{ parent.name | translate }}\n </span>\n @if ((parent.children && parent.children.length > 0) || parent.menuTemplate) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"16\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"parent.expanded && isCurrentlyViewing\" />\n }\n </div>\n\n <!-- Children (Accordion) - Only render if NO menuTemplate -->\n @if (parent.children && parent.children.length > 0 && !parent.menuTemplate) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"parent.expanded && isCurrentlyViewing\">\n <div class=\"z-menu-submenu-inner\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (child of parent.children; track child.id) {\n @let isChildActive =\n selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n\n <div>\n <div\n #mobileChildTrigger\n data-glide-item\n class=\"relative z-[1] flex cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1.5 w-1.5 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isChildActive\"\n [class.bg-gray-400]=\"!isChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileChildTrigger\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n <!-- Level 3 -->\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #mobileSubChildTrigger\n data-glide-item\n class=\"relative z-[1] flex cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileSubChildTrigger\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </ng-scrollbar>\n\n <!-- Drawer Footer - User Info -->\n <div class=\"border-border shrink-0 border-t p-3\">\n <div\n z-popover\n [zOffset]=\"6\"\n [zPopoverContent]=\"mobileActionsPopoverTpl\"\n zPosition=\"top-right\"\n zTrigger=\"click\"\n class=\"flex cursor-pointer items-center gap-3 rounded-(--radius) p-2\">\n <div class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div class=\"truncate text-sm font-medium\">{{ zUser()?.name || 'User Name' }}</div>\n <div class=\"text-muted-foreground truncate text-xs\">{{ zUser()?.email || 'user@example.com' }}</div>\n </div>\n <div class=\"text-muted-foreground flex shrink-0 flex-col\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"-mt-1\" />\n </div>\n </div>\n </div>\n </aside>\n\n <!-- Mobile Custom Template Drawer -->\n <aside\n class=\"z-menu-custom-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full max-w-[calc(100vw-1rem)] flex-col rounded-r-lg border-r\"\n [style.width.px]=\"mobileCustomDrawerWidth()\"\n [class.open]=\"mobileTemplateDrawerOpen() && customDrawerParent()?.menuTemplate\">\n @if (customDrawerParent()?.menuTemplate) {\n <!-- Custom Drawer Header -->\n <div #customDrawerHeaderTrigger class=\"border-border flex h-14 shrink-0 items-center gap-3 border-b px-4\">\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"bg-accent h-9 w-9 shrink-0\"\n (click)=\"closeMobileTemplateDrawer()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"20\" />\n </button>\n <span\n class=\"min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n [zContent]=\"customDrawerParent()?.name || '' | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"customDrawerHeaderTrigger\">\n {{ customDrawerParent()?.name | translate }}\n </span>\n </div>\n\n <!-- Custom Template Content -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-4\">\n <ng-container\n *ngTemplateOutlet=\"\n customDrawerParent()!.menuTemplate!;\n context: { $implicit: customDrawerParent()!, close: closeMobileDrawerFn }\n \" />\n </div>\n </ng-scrollbar>\n }\n </aside>\n\n <ng-template #mobileActionsPopoverTpl let-close=\"close\">\n <div class=\"min-w-48 p-1\">\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius-sm)\">\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n data-glide-item\n [class]=\"action.class\"\n class=\"focus:bg-accent relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius-sm) px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n }\n </div>\n </ng-template>\n</div>\n\n<!-- Shared Template for Menu Children -->\n<ng-template #menuChildrenTpl let-children>\n @for (child of children; track child.id) {\n @let isChildActive = selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n @if (child.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ child.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"w-full min-w-0\">\n <div\n #divLevel1\n data-glide-item\n class=\"z-menu-item relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel1\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id; let isLast = $last) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #divLevel2\n data-glide-item\n class=\"z-menu-item relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel2\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".z-menu{display:block;flex-shrink:0;height:100%}.z-menu [class*=cursor-pointer]{-webkit-user-select:none;user-select:none}@media(min-width:48rem){.z-menu{contain:layout style;min-width:283px;transition:min-width .25s cubic-bezier(.4,0,.2,1);will-change:min-width}.z-menu.z-menu-collapsed,.z-menu.z-menu-no-child{min-width:53px}}.z-shadow-menu{box-shadow:0 0 10px #0000001f}@media(max-width:47.9375rem){.z-menu-desktop{display:none!important;pointer-events:none;visibility:hidden}}.z-sidebar-main{position:relative;z-index:20;flex-shrink:0}.z-sidebar-main>div{background-color:var(--z-menu-v1-sidebar, var(--sidebar));color:var(--z-menu-v1-sidebar-foreground, var(--sidebar-foreground))}.z-sidebar-main .bg-sidebar-primary{background-color:var(--z-menu-v1-parent-active, var(--sidebar-primary));color:var(--z-menu-v1-parent-active-foreground, var(--sidebar-primary-foreground))}.z-menu-item.bg-primary,.z-menu-mobile-wrapper .bg-primary{background-color:var(--z-menu-v1-item-active, var(--primary));color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-menu-item.bg-primary .bg-primary-foreground,.z-menu-mobile-wrapper .bg-primary .bg-primary-foreground{background-color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-sidebar-child-wrapper{--sidebar-child-width: 230px;position:absolute;left:0;top:0;width:calc(100% + -0px);height:100%;clip-path:inset(0 -100px 0 0);pointer-events:none;transition:clip-path .25s cubic-bezier(.4,0,.2,1);will-change:clip-path;contain:layout}.z-sidebar-child-wrapper.collapsed{clip-path:inset(0 -100px 0 53px)}.z-sidebar-child{flex-shrink:0;height:100%;margin-left:53px;transform:translate(0);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1);pointer-events:auto;will-change:transform,width;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{transform:translate(calc(-1 * (var(--sidebar-child-width) + 50px + .3125rem)))}.z-menu-arrow.expanded{transform:rotate(90deg)}.z-menu-submenu{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-out}.z-menu-submenu.expanded{grid-template-rows:1fr}.z-menu-submenu>.z-menu-submenu-inner{overflow:hidden;min-height:0}.z-menu-backdrop{animation:z-menu-backdrop-enter .2s ease-out forwards}.z-menu-backdrop-dark{background-color:#0009}.z-menu-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a}.z-menu-drawer.open{transform:translate(0)}:host.z-menu-mobile-open .z-menu-drawer{transform:translate(0)}.z-menu-desktop.collapsed .z-sidebar-child-wrapper{pointer-events:none}.z-menu-custom-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-custom-drawer.open{transform:translate(0)}@keyframes z-menu-backdrop-enter{0%{opacity:0}to{opacity:1}}@keyframes z-expand-btn-enter{0%{opacity:0;transform:scale(.5) translateY(.625rem)}70%{transform:scale(1.1) translateY(-.125rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-expand-btn{animation:z-expand-btn-enter .25s cubic-bezier(.34,1.56,.64,1) forwards}.z-menu-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-scrollbar .ng-scroll-viewport,.z-menu-scrollbar .ng-scroll-content{max-width:100%}.z-menu-item{min-width:0;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZHoverGlideDirective, selector: "[zHoverGlide]", inputs: ["zHoverGlideSelector", "zHoverGlideClass", "zHoverGlideDisabled"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTooltipPosition", "zTrigger", "zTooltipTrigger", "zTooltipType", "zTooltipSize", "zClass", "zTooltipClass", "zShowDelay", "zTooltipShowDelay", "zHideDelay", "zTooltipHideDelay", "zArrow", "zTooltipArrow", "zDisabled", "zTooltipDisabled", "zOffset", "zTooltipOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zSticky", "zShowArrow", "zKeyboardSafe"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], exportAs: ["zPopover"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
428
429
  }
429
430
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZMenuComponent, decorators: [{
430
431
  type: Component,
@@ -432,6 +433,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
432
433
  NgTemplateOutlet,
433
434
  ZButtonComponent,
434
435
  ZIconComponent,
436
+ ZHoverGlideDirective,
435
437
  ZTooltipDirective,
436
438
  ZPopoverDirective,
437
439
  NgScrollbar,
@@ -442,7 +444,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
442
444
  '[class.z-menu-no-child]': 'selectedParentHasNoChild()',
443
445
  '[class.z-menu-mobile]': 'isMobile()',
444
446
  '[class.z-menu-mobile-open]': 'mobileMenuOpen()',
445
- }, template: "<!-- DESKTOP LAYOUT - Hidden on mobile -->\n<div class=\"z-menu-desktop relative z-200 hidden h-full py-1 pl-1 md:block\" [class.collapsed]=\"sidebarCollapsed()\">\n <main class=\"z-menu-main relative flex h-full\">\n <div class=\"z-sidebar-main h-full w-[3.125rem]\">\n <div\n class=\"z-shadow-menu bg-sidebar border-border/40 dark:border-sidebar-border relative flex h-full w-full flex-col items-center gap-1.5 rounded-md border\"></div>\n\n <div class=\"bg-sidebar text-sidebar-foreground absolute inset-px z-20 flex flex-col rounded-md\">\n @if (zLogo()) {\n <div class=\"border-sidebar-border flex h-[3.25rem] items-center justify-center border-b px-2\">\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n </div>\n }\n\n <!-- Expand Button - Only show when collapsed -->\n @if (sidebarCollapsed() && selectedParent()) {\n <div\n class=\"z-expand-btn hover:bg-sidebar-accent mx-auto mt-2 flex h-9 w-9 cursor-pointer items-center justify-center rounded-md\"\n (click)=\"toggleSidebar()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"20\" class=\"opacity-70\" />\n </div>\n }\n\n <div class=\"flex flex-1 flex-col items-center gap-2 p-2\">\n @for (item of menuParents(); track item.id) {\n @let hasActiveChild = parentWithActiveChild()?.id === item.id;\n @let isCurrentlySelected = selectedParent()?.id === item.id;\n @let showActiveIndicator = hasActiveChild && !isCurrentlySelected;\n <div\n zTooltip\n [zContent]=\"item.name | translate\"\n zPosition=\"right\"\n [zAlwaysShow]=\"true\"\n class=\"relative flex h-9 w-9 cursor-pointer items-center justify-center rounded-md select-none\"\n [class.bg-sidebar-primary]=\"selectedParent()?.id === item.id\"\n [class.text-sidebar-primary-foreground]=\"selectedParent()?.id === item.id\"\n [class.hover:bg-sidebar-accent]=\"selectedParent()?.id !== item.id\"\n (click)=\"onDesktopParentClick(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon\" zSize=\"20\" />\n } @else {\n <z-icon [zSvg]=\"item.iconSvg || ''\" zSize=\"20\" />\n }\n @if (showActiveIndicator) {\n <div\n class=\"bg-sidebar-primary absolute top-1/2 -left-[0.3125rem] h-4 w-1 -translate-y-1/2 rounded-full\"></div>\n }\n </div>\n }\n </div>\n\n <div class=\"border-sidebar-border flex items-center justify-center border-t p-2\">\n <div\n z-popover\n [zOffset]=\"11\"\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n class=\"aspect-square h-9 w-9 shrink-0 cursor-pointer overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <!-- User Info Header - Always shown -->\n <div class=\"p-0 text-sm font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-medium\">{{ zUser()?.name || 'User Name' }}</span>\n <span class=\"text-muted-foreground mt-0.5 truncate text-xs\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n </div>\n\n @if (getVisibleUserActions().length > 0 || zActionsTemplate()) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <!-- Actions - Custom or from zUserActions -->\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n\n @if (selectedParent(); as parent) {\n @let hasChildrenOrTemplate = parent.menuTemplate || (parent.children && parent.children.length > 0);\n @if (hasChildrenOrTemplate) {\n <div\n class=\"z-sidebar-child-wrapper\"\n [class.collapsed]=\"sidebarCollapsed()\"\n [style.--sidebar-child-width.px]=\"sidebarChildWidth()\">\n <div\n class=\"z-sidebar-child z-shadow-menu bg-card text-card-foreground border-border/40 dark:border-sidebar-border flex h-full shrink-0 flex-col items-start overflow-hidden rounded-md border\"\n [style.width.px]=\"sidebarChildWidth()\"\n [class.collapsed]=\"sidebarCollapsed()\">\n <div\n #selectedParentHeaderTrigger\n class=\"border-border flex h-[3.25rem] w-full shrink-0 items-center border-b px-3\">\n @if (selectedParent()?.icon) {\n <z-icon [zType]=\"selectedParent()!.icon\" zSize=\"20\" class=\"mr-2 shrink-0\" />\n }\n <div\n class=\"mr-4 min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n zPosition=\"top-left\"\n [zContent]=\"selectedParent()?.name || '' | translate\"\n [zTriggerElement]=\"selectedParentHeaderTrigger\"\n [zOffset]=\"6\">\n {{ selectedParent()?.name | translate }}\n </div>\n\n <z-icon\n zType=\"lucidePanelRightOpen\"\n zSize=\"20\"\n class=\"shrink-0 cursor-pointer opacity-60 hover:opacity-100\"\n (click)=\"toggleSidebar()\" />\n </div>\n\n <!-- Show menuTemplate if available, otherwise show children -->\n @if (selectedParent()?.menuTemplate) {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1\" track=\"vertical\">\n <div class=\"flex w-full flex-col p-3 pr-2\">\n <ng-container\n *ngTemplateOutlet=\"\n selectedParent()!.menuTemplate!;\n context: { $implicit: selectedParent()!, close: closeSidebarFn }\n \" />\n </div>\n </ng-scrollbar>\n } @else {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1 overflow-hidden\" track=\"vertical\">\n <div class=\"flex w-full min-w-0 flex-col gap-1 overflow-hidden py-1 pr-2 pl-2\">\n <ng-container *ngTemplateOutlet=\"menuChildrenTpl; context: { $implicit: menuChildren() }\" />\n </div>\n </ng-scrollbar>\n }\n </div>\n </div>\n }\n }\n </main>\n</div>\n\n<!-- MOBILE LAYOUT - Visible only on mobile -->\n<div class=\"z-menu-mobile-wrapper hidden max-md:block\">\n <!-- Mobile Backdrop -->\n @if (mobileMenuOpen() || mobileTemplateDrawerOpen()) {\n <div\n class=\"z-menu-backdrop fixed inset-0 z-9998\"\n [class.z-menu-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onBackdropClick()\"></div>\n }\n\n <!-- Mobile Drawer -->\n <aside\n class=\"z-menu-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full w-70 flex-col rounded-r-lg border-r\"\n [class.open]=\"mobileMenuOpen()\">\n <!-- Drawer Header -->\n <div class=\"border-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"bg-accent h-9 w-9 shrink-0\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <!-- Drawer Content - Accordion Menu -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-3\">\n @for (parent of menuParents(); track parent.id) {\n <div class=\"mb-1\">\n <!-- Parent Item -->\n @let isParentActive =\n selectedMenuItem()?.id === parent.id && (!parent.children || parent.children.length === 0);\n @let hasActiveChild = parentWithActiveChild()?.id === parent.id && !isParentActive;\n @let isCurrentlyViewing = selectedParent()?.id === parent.id;\n <div\n #mobileParentTrigger\n class=\"relative flex cursor-pointer items-center gap-3 rounded-md p-2\"\n [class.bg-primary/20]=\"isParentActive\"\n [class.text-primary]=\"isParentActive || hasActiveChild\"\n [class.hover:bg-accent]=\"!isParentActive\"\n (click)=\"onMobileParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"parent.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileParentTrigger\">\n {{ parent.name | translate }}\n </span>\n @if ((parent.children && parent.children.length > 0) || parent.menuTemplate) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"16\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"parent.expanded && isCurrentlyViewing\" />\n }\n </div>\n\n <!-- Children (Accordion) - Only render if NO menuTemplate -->\n @if (parent.children && parent.children.length > 0 && !parent.menuTemplate) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"parent.expanded && isCurrentlyViewing\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (child of parent.children; track child.id) {\n @let isChildActive =\n selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n\n <div>\n <div\n #mobileChildTrigger\n class=\"relative flex cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-accent]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1.5 w-1.5 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isChildActive\"\n [class.bg-gray-400]=\"!isChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileChildTrigger\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n <!-- Level 3 -->\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #mobileSubChildTrigger\n class=\"flex cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-accent]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileSubChildTrigger\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </ng-scrollbar>\n\n <!-- Drawer Footer - User Info -->\n <div class=\"border-border shrink-0 border-t p-3\">\n <div\n z-popover\n [zOffset]=\"6\"\n [zPopoverContent]=\"mobileActionsPopoverTpl\"\n zPosition=\"top-right\"\n zTrigger=\"click\"\n class=\"hover:bg-accent flex cursor-pointer items-center gap-3 rounded-md p-2\">\n <div class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div class=\"truncate text-sm font-medium\">{{ zUser()?.name || 'User Name' }}</div>\n <div class=\"text-muted-foreground truncate text-xs\">{{ zUser()?.email || 'user@example.com' }}</div>\n </div>\n <div class=\"text-muted-foreground flex shrink-0 flex-col\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"-mt-1\" />\n </div>\n </div>\n </div>\n </aside>\n\n <!-- Mobile Custom Template Drawer -->\n <aside\n class=\"z-menu-custom-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full max-w-[calc(100vw-1rem)] flex-col rounded-r-lg border-r\"\n [style.width.px]=\"mobileCustomDrawerWidth()\"\n [class.open]=\"mobileTemplateDrawerOpen() && customDrawerParent()?.menuTemplate\">\n @if (customDrawerParent()?.menuTemplate) {\n <!-- Custom Drawer Header -->\n <div #customDrawerHeaderTrigger class=\"border-border flex h-14 shrink-0 items-center gap-3 border-b px-4\">\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"bg-accent h-9 w-9 shrink-0\"\n (click)=\"closeMobileTemplateDrawer()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"20\" />\n </button>\n <span\n class=\"min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n [zContent]=\"customDrawerParent()?.name || '' | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"customDrawerHeaderTrigger\">\n {{ customDrawerParent()?.name | translate }}\n </span>\n </div>\n\n <!-- Custom Template Content -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-4\">\n <ng-container\n *ngTemplateOutlet=\"\n customDrawerParent()!.menuTemplate!;\n context: { $implicit: customDrawerParent()!, close: closeMobileDrawerFn }\n \" />\n </div>\n </ng-scrollbar>\n }\n </aside>\n\n <ng-template #mobileActionsPopoverTpl let-close=\"close\">\n <div class=\"min-w-48 p-1\">\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n</div>\n\n<!-- Shared Template for Menu Children -->\n<ng-template #menuChildrenTpl let-children>\n @for (child of children; track child.id) {\n @let isChildActive = selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n @if (child.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ child.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"w-full min-w-0\">\n <div\n #divLevel1\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-gray-200]=\"!isChildActive\"\n [class.dark:hover:bg-input/50]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel1\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id; let isLast = $last) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #divLevel2\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-md p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-gray-200]=\"!isSubChildActive\"\n [class.dark:hover:bg-input/50]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel2\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".z-menu{display:block;flex-shrink:0;height:100%}.z-menu [class*=cursor-pointer]{-webkit-user-select:none;user-select:none}@media(min-width:48rem){.z-menu{contain:layout style;min-width:283px;transition:min-width .25s cubic-bezier(.4,0,.2,1);will-change:min-width}.z-menu.z-menu-collapsed,.z-menu.z-menu-no-child{min-width:53px}}.z-shadow-menu{box-shadow:0 0 10px #0000001f}@media(max-width:47.9375rem){.z-menu-desktop{display:none!important;pointer-events:none;visibility:hidden}}.z-sidebar-main{position:relative;z-index:20;flex-shrink:0}.z-sidebar-main>div{background-color:var(--z-menu-v1-sidebar, var(--sidebar));color:var(--z-menu-v1-sidebar-foreground, var(--sidebar-foreground))}.z-sidebar-main .bg-sidebar-primary{background-color:var(--z-menu-v1-parent-active, var(--sidebar-primary));color:var(--z-menu-v1-parent-active-foreground, var(--sidebar-primary-foreground))}.z-menu-item.bg-primary,.z-menu-mobile-wrapper .bg-primary{background-color:var(--z-menu-v1-item-active, var(--primary));color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-menu-item.bg-primary .bg-primary-foreground,.z-menu-mobile-wrapper .bg-primary .bg-primary-foreground{background-color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-sidebar-child-wrapper{--sidebar-child-width: 230px;position:absolute;left:0;top:0;width:calc(100% + -0px);height:100%;clip-path:inset(0 -100px 0 0);pointer-events:none;transition:clip-path .25s cubic-bezier(.4,0,.2,1);will-change:clip-path;contain:layout}.z-sidebar-child-wrapper.collapsed{clip-path:inset(0 -100px 0 53px)}.z-sidebar-child{flex-shrink:0;height:100%;margin-left:53px;transform:translate(0);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1);pointer-events:auto;will-change:transform,width;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{transform:translate(calc(-1 * (var(--sidebar-child-width) + 50px + .3125rem)))}.z-menu-arrow.expanded{transform:rotate(90deg)}.z-menu-submenu{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-out}.z-menu-submenu.expanded{grid-template-rows:1fr}.z-menu-submenu>.z-menu-submenu-inner{overflow:hidden;min-height:0}.z-menu-backdrop{animation:z-menu-backdrop-enter .2s ease-out forwards}.z-menu-backdrop-dark{background-color:#0009}.z-menu-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a}.z-menu-drawer.open{transform:translate(0)}:host.z-menu-mobile-open .z-menu-drawer{transform:translate(0)}.z-menu-desktop.collapsed .z-sidebar-child-wrapper{pointer-events:none}.z-menu-custom-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-custom-drawer.open{transform:translate(0)}@keyframes z-menu-backdrop-enter{0%{opacity:0}to{opacity:1}}@keyframes z-expand-btn-enter{0%{opacity:0;transform:scale(.5) translateY(.625rem)}70%{transform:scale(1.1) translateY(-.125rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-expand-btn{animation:z-expand-btn-enter .25s cubic-bezier(.34,1.56,.64,1) forwards}.z-menu-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-scrollbar .ng-scroll-viewport,.z-menu-scrollbar .ng-scroll-content{max-width:100%}.z-menu-item{min-width:0;overflow:hidden}\n"] }]
447
+ }, template: "<!-- DESKTOP LAYOUT - Hidden on mobile -->\n<div class=\"z-menu-desktop relative z-200 hidden h-full py-1 pl-1 md:block\" [class.collapsed]=\"sidebarCollapsed()\">\n <main class=\"z-menu-main relative flex h-full\">\n <div class=\"z-sidebar-main h-full w-[3.125rem]\">\n <div\n class=\"z-shadow-menu bg-sidebar border-border/40 dark:border-sidebar-border relative flex h-full w-full flex-col items-center gap-1.5 rounded-md border\"></div>\n\n <div class=\"bg-sidebar text-sidebar-foreground absolute inset-px z-20 flex flex-col rounded-md\">\n @if (zLogo()) {\n <div class=\"border-sidebar-border flex h-[3.25rem] items-center justify-center border-b px-2\">\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n </div>\n }\n\n <!-- Expand Button - Only show when collapsed -->\n @if (sidebarCollapsed() && selectedParent()) {\n <div\n class=\"z-expand-btn hover:bg-sidebar-accent mx-auto mt-2 flex h-9 w-9 cursor-pointer items-center justify-center rounded-md\"\n (click)=\"toggleSidebar()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"20\" class=\"opacity-70\" />\n </div>\n }\n\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-sidebar-accent rounded-(--radius)\"\n class=\"flex flex-1 flex-col items-center gap-2 p-2\">\n @for (item of menuParents(); track item.id) {\n @let hasActiveChild = parentWithActiveChild()?.id === item.id;\n @let isCurrentlySelected = selectedParent()?.id === item.id;\n @let showActiveIndicator = hasActiveChild && !isCurrentlySelected;\n <div\n zTooltip\n [zContent]=\"item.name | translate\"\n zPosition=\"right\"\n [zAlwaysShow]=\"true\"\n data-glide-item\n class=\"relative z-[1] flex h-9 w-9 cursor-pointer items-center justify-center rounded-(--radius) select-none\"\n [class.bg-sidebar-primary]=\"selectedParent()?.id === item.id\"\n [class.text-sidebar-primary-foreground]=\"selectedParent()?.id === item.id\"\n (click)=\"onDesktopParentClick(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon\" zSize=\"20\" />\n } @else {\n <z-icon [zSvg]=\"item.iconSvg || ''\" zSize=\"20\" />\n }\n @if (showActiveIndicator) {\n <div\n class=\"bg-sidebar-primary absolute top-1/2 -left-[0.3125rem] h-4 w-1 -translate-y-1/2 rounded-full\"></div>\n }\n </div>\n }\n </div>\n\n <div class=\"border-sidebar-border flex items-center justify-center border-t p-2\">\n <div\n z-popover\n [zOffset]=\"11\"\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n class=\"aspect-square h-9 w-9 shrink-0 cursor-pointer overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <!-- User Info Header - Always shown -->\n <div class=\"p-0 text-sm font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-medium\">{{ zUser()?.name || 'User Name' }}</span>\n <span class=\"text-muted-foreground mt-0.5 truncate text-xs\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n </div>\n\n @if (getVisibleUserActions().length > 0 || zActionsTemplate()) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <!-- Actions - Custom or from zUserActions -->\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius-sm)\">\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n data-glide-item\n [class]=\"action.class\"\n class=\"focus:bg-accent relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius-sm) px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n }\n </div>\n </ng-template>\n\n @if (selectedParent(); as parent) {\n @let hasChildrenOrTemplate = parent.menuTemplate || (parent.children && parent.children.length > 0);\n @if (hasChildrenOrTemplate) {\n <div\n class=\"z-sidebar-child-wrapper\"\n [class.collapsed]=\"sidebarCollapsed()\"\n [style.--sidebar-child-width.px]=\"sidebarChildWidth()\">\n <div\n class=\"z-sidebar-child z-shadow-menu bg-card text-card-foreground border-border/40 dark:border-sidebar-border flex h-full shrink-0 flex-col items-start overflow-hidden rounded-md border\"\n [style.width.px]=\"sidebarChildWidth()\"\n [class.collapsed]=\"sidebarCollapsed()\">\n <div\n #selectedParentHeaderTrigger\n class=\"border-border flex h-[3.25rem] w-full shrink-0 items-center border-b px-3\">\n @if (selectedParent()?.icon) {\n <z-icon [zType]=\"selectedParent()!.icon\" zSize=\"20\" class=\"mr-2 shrink-0\" />\n }\n <div\n class=\"mr-4 min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n zPosition=\"top-left\"\n [zContent]=\"selectedParent()?.name || '' | translate\"\n [zTriggerElement]=\"selectedParentHeaderTrigger\"\n [zOffset]=\"6\">\n {{ selectedParent()?.name | translate }}\n </div>\n\n <z-icon\n zType=\"lucidePanelRightOpen\"\n zSize=\"20\"\n class=\"shrink-0 cursor-pointer opacity-60 hover:opacity-100\"\n (click)=\"toggleSidebar()\" />\n </div>\n\n <!-- Show menuTemplate if available, otherwise show children -->\n @if (selectedParent()?.menuTemplate) {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1\" track=\"vertical\">\n <div class=\"flex w-full flex-col p-3 pr-2\">\n <ng-container\n *ngTemplateOutlet=\"\n selectedParent()!.menuTemplate!;\n context: { $implicit: selectedParent()!, close: closeSidebarFn }\n \" />\n </div>\n </ng-scrollbar>\n } @else {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1 overflow-hidden\" track=\"vertical\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"flex w-full min-w-0 flex-col gap-1 overflow-hidden py-1 pr-2 pl-2\">\n <ng-container *ngTemplateOutlet=\"menuChildrenTpl; context: { $implicit: menuChildren() }\" />\n </div>\n </ng-scrollbar>\n }\n </div>\n </div>\n }\n }\n </main>\n</div>\n\n<!-- MOBILE LAYOUT - Visible only on mobile -->\n<div class=\"z-menu-mobile-wrapper hidden max-md:block\">\n <!-- Mobile Backdrop -->\n @if (mobileMenuOpen() || mobileTemplateDrawerOpen()) {\n <div\n class=\"z-menu-backdrop fixed inset-0 z-9998\"\n [class.z-menu-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onBackdropClick()\"></div>\n }\n\n <!-- Mobile Drawer -->\n <aside\n class=\"z-menu-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full w-70 flex-col rounded-r-lg border-r\"\n [class.open]=\"mobileMenuOpen()\">\n <!-- Drawer Header -->\n <div class=\"border-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"bg-accent h-9 w-9 shrink-0\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <!-- Drawer Content - Accordion Menu -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"p-3\">\n @for (parent of menuParents(); track parent.id) {\n <div class=\"mb-1\">\n <!-- Parent Item -->\n @let isParentActive =\n selectedMenuItem()?.id === parent.id && (!parent.children || parent.children.length === 0);\n @let hasActiveChild = parentWithActiveChild()?.id === parent.id && !isParentActive;\n @let isCurrentlyViewing = selectedParent()?.id === parent.id;\n <div\n #mobileParentTrigger\n data-glide-item\n class=\"relative z-[1] flex cursor-pointer items-center gap-3 rounded-(--radius) p-2\"\n [class.bg-primary/20]=\"isParentActive\"\n [class.text-primary]=\"isParentActive || hasActiveChild\"\n (click)=\"onMobileParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"parent.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileParentTrigger\">\n {{ parent.name | translate }}\n </span>\n @if ((parent.children && parent.children.length > 0) || parent.menuTemplate) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"16\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"parent.expanded && isCurrentlyViewing\" />\n }\n </div>\n\n <!-- Children (Accordion) - Only render if NO menuTemplate -->\n @if (parent.children && parent.children.length > 0 && !parent.menuTemplate) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"parent.expanded && isCurrentlyViewing\">\n <div class=\"z-menu-submenu-inner\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (child of parent.children; track child.id) {\n @let isChildActive =\n selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n\n <div>\n <div\n #mobileChildTrigger\n data-glide-item\n class=\"relative z-[1] flex cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1.5 w-1.5 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isChildActive\"\n [class.bg-gray-400]=\"!isChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileChildTrigger\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n <!-- Level 3 -->\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #mobileSubChildTrigger\n data-glide-item\n class=\"relative z-[1] flex cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"mobileSubChildTrigger\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </ng-scrollbar>\n\n <!-- Drawer Footer - User Info -->\n <div class=\"border-border shrink-0 border-t p-3\">\n <div\n z-popover\n [zOffset]=\"6\"\n [zPopoverContent]=\"mobileActionsPopoverTpl\"\n zPosition=\"top-right\"\n zTrigger=\"click\"\n class=\"flex cursor-pointer items-center gap-3 rounded-(--radius) p-2\">\n <div class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div class=\"truncate text-sm font-medium\">{{ zUser()?.name || 'User Name' }}</div>\n <div class=\"text-muted-foreground truncate text-xs\">{{ zUser()?.email || 'user@example.com' }}</div>\n </div>\n <div class=\"text-muted-foreground flex shrink-0 flex-col\">\n <z-icon zType=\"lucideChevronUp\" zSize=\"14\" />\n <z-icon zType=\"lucideChevronDown\" zSize=\"14\" class=\"-mt-1\" />\n </div>\n </div>\n </div>\n </aside>\n\n <!-- Mobile Custom Template Drawer -->\n <aside\n class=\"z-menu-custom-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full max-w-[calc(100vw-1rem)] flex-col rounded-r-lg border-r\"\n [style.width.px]=\"mobileCustomDrawerWidth()\"\n [class.open]=\"mobileTemplateDrawerOpen() && customDrawerParent()?.menuTemplate\">\n @if (customDrawerParent()?.menuTemplate) {\n <!-- Custom Drawer Header -->\n <div #customDrawerHeaderTrigger class=\"border-border flex h-14 shrink-0 items-center gap-3 border-b px-4\">\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"bg-accent h-9 w-9 shrink-0\"\n (click)=\"closeMobileTemplateDrawer()\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"20\" />\n </button>\n <span\n class=\"min-w-0 flex-1 truncate text-base font-semibold\"\n zTooltip\n [zContent]=\"customDrawerParent()?.name || '' | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"top\"\n [zTriggerElement]=\"customDrawerHeaderTrigger\">\n {{ customDrawerParent()?.name | translate }}\n </span>\n </div>\n\n <!-- Custom Template Content -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-4\">\n <ng-container\n *ngTemplateOutlet=\"\n customDrawerParent()!.menuTemplate!;\n context: { $implicit: customDrawerParent()!, close: closeMobileDrawerFn }\n \" />\n </div>\n </ng-scrollbar>\n }\n </aside>\n\n <ng-template #mobileActionsPopoverTpl let-close=\"close\">\n <div class=\"min-w-48 p-1\">\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius-sm)\">\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n data-glide-item\n [class]=\"action.class\"\n class=\"focus:bg-accent relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius-sm) px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n }\n </div>\n </ng-template>\n</div>\n\n<!-- Shared Template for Menu Children -->\n<ng-template #menuChildrenTpl let-children>\n @for (child of children; track child.id) {\n @let isChildActive = selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n @if (child.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ child.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"w-full min-w-0\">\n <div\n #divLevel1\n data-glide-item\n class=\"z-menu-item relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel1\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div\n zHoverGlide\n zHoverGlideClass=\"bg-accent rounded-(--radius)\"\n class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id; let isLast = $last) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #divLevel2\n data-glide-item\n class=\"z-menu-item relative z-[1] flex w-full cursor-pointer items-center gap-2 rounded-(--radius) p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zOffset]=\"6\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel2\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".z-menu{display:block;flex-shrink:0;height:100%}.z-menu [class*=cursor-pointer]{-webkit-user-select:none;user-select:none}@media(min-width:48rem){.z-menu{contain:layout style;min-width:283px;transition:min-width .25s cubic-bezier(.4,0,.2,1);will-change:min-width}.z-menu.z-menu-collapsed,.z-menu.z-menu-no-child{min-width:53px}}.z-shadow-menu{box-shadow:0 0 10px #0000001f}@media(max-width:47.9375rem){.z-menu-desktop{display:none!important;pointer-events:none;visibility:hidden}}.z-sidebar-main{position:relative;z-index:20;flex-shrink:0}.z-sidebar-main>div{background-color:var(--z-menu-v1-sidebar, var(--sidebar));color:var(--z-menu-v1-sidebar-foreground, var(--sidebar-foreground))}.z-sidebar-main .bg-sidebar-primary{background-color:var(--z-menu-v1-parent-active, var(--sidebar-primary));color:var(--z-menu-v1-parent-active-foreground, var(--sidebar-primary-foreground))}.z-menu-item.bg-primary,.z-menu-mobile-wrapper .bg-primary{background-color:var(--z-menu-v1-item-active, var(--primary));color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-menu-item.bg-primary .bg-primary-foreground,.z-menu-mobile-wrapper .bg-primary .bg-primary-foreground{background-color:var(--z-menu-v1-item-active-foreground, var(--primary-foreground))}.z-sidebar-child-wrapper{--sidebar-child-width: 230px;position:absolute;left:0;top:0;width:calc(100% + -0px);height:100%;clip-path:inset(0 -100px 0 0);pointer-events:none;transition:clip-path .25s cubic-bezier(.4,0,.2,1);will-change:clip-path;contain:layout}.z-sidebar-child-wrapper.collapsed{clip-path:inset(0 -100px 0 53px)}.z-sidebar-child{flex-shrink:0;height:100%;margin-left:53px;transform:translate(0);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1);pointer-events:auto;will-change:transform,width;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{transform:translate(calc(-1 * (var(--sidebar-child-width) + 50px + .3125rem)))}.z-menu-arrow.expanded{transform:rotate(90deg)}.z-menu-submenu{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-out}.z-menu-submenu.expanded{grid-template-rows:1fr}.z-menu-submenu>.z-menu-submenu-inner{overflow:hidden;min-height:0}.z-menu-backdrop{animation:z-menu-backdrop-enter .2s ease-out forwards}.z-menu-backdrop-dark{background-color:#0009}.z-menu-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a}.z-menu-drawer.open{transform:translate(0)}:host.z-menu-mobile-open .z-menu-drawer{transform:translate(0)}.z-menu-desktop.collapsed .z-sidebar-child-wrapper{pointer-events:none}.z-menu-custom-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-custom-drawer.open{transform:translate(0)}@keyframes z-menu-backdrop-enter{0%{opacity:0}to{opacity:1}}@keyframes z-expand-btn-enter{0%{opacity:0;transform:scale(.5) translateY(.625rem)}70%{transform:scale(1.1) translateY(-.125rem)}to{opacity:1;transform:scale(1) translateY(0)}}.z-expand-btn{animation:z-expand-btn-enter .25s cubic-bezier(.34,1.56,.64,1) forwards}.z-menu-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-scrollbar .ng-scroll-viewport,.z-menu-scrollbar .ng-scroll-content{max-width:100%}.z-menu-item{min-width:0;overflow:hidden}\n"] }]
446
448
  }], ctorParameters: () => [], propDecorators: { zOnSelect: [{ type: i0.Output, args: ["zOnSelect"] }], zOnMenuAction: [{ type: i0.Output, args: ["zOnMenuAction"] }], zControl: [{ type: i0.Output, args: ["zControl"] }], zLogo: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLogo", required: false }] }], zLogoMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLogoMobile", required: false }] }], zMenus: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMenus", required: false }] }], zUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "zUser", required: false }] }], zUserActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "zUserActions", required: false }] }], zActionsTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "zActionsTemplate", required: false }] }], zCurrentPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCurrentPath", required: false }] }], zKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "zKey", required: false }] }] } });
447
449
 
448
450
  class ZMenuV2Component {
@@ -874,7 +876,7 @@ class ZMenuV2Component {
874
876
  return ZCacheService.get(key, false) ?? false;
875
877
  }
876
878
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZMenuV2Component, deps: [], target: i0.ɵɵFactoryTarget.Component });
877
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ZMenuV2Component, isStandalone: true, selector: "z-menu-v2", inputs: { zLogo: { classPropertyName: "zLogo", publicName: "zLogo", isSignal: true, isRequired: false, transformFunction: null }, zLogoMobile: { classPropertyName: "zLogoMobile", publicName: "zLogoMobile", isSignal: true, isRequired: false, transformFunction: null }, zMenus: { classPropertyName: "zMenus", publicName: "zMenus", isSignal: true, isRequired: false, transformFunction: null }, zUser: { classPropertyName: "zUser", publicName: "zUser", isSignal: true, isRequired: false, transformFunction: null }, zUserActions: { classPropertyName: "zUserActions", publicName: "zUserActions", isSignal: true, isRequired: false, transformFunction: null }, zCurrentPath: { classPropertyName: "zCurrentPath", publicName: "zCurrentPath", isSignal: true, isRequired: false, transformFunction: null }, zKey: { classPropertyName: "zKey", publicName: "zKey", isSignal: true, isRequired: false, transformFunction: null }, zClass: { classPropertyName: "zClass", publicName: "zClass", isSignal: true, isRequired: false, transformFunction: null }, zTitle: { classPropertyName: "zTitle", publicName: "zTitle", isSignal: true, isRequired: false, transformFunction: null }, zCollapsedWidth: { classPropertyName: "zCollapsedWidth", publicName: "zCollapsedWidth", isSignal: true, isRequired: false, transformFunction: null }, zExpandedWidth: { classPropertyName: "zExpandedWidth", publicName: "zExpandedWidth", isSignal: true, isRequired: false, transformFunction: null }, zExpandMode: { classPropertyName: "zExpandMode", publicName: "zExpandMode", isSignal: true, isRequired: false, transformFunction: null }, zShowMobileBar: { classPropertyName: "zShowMobileBar", publicName: "zShowMobileBar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOnSelect: "zOnSelect", zOnMenuAction: "zOnMenuAction", zControl: "zControl" }, host: { properties: { "class.z-menu-v2-collapsed": "sidebarCollapsed()", "class.z-menu-v2-mobile-open": "mobileMenuOpen()", "class.z-menu-v2-mobile": "isMobile()" }, classAttribute: "z-menu-v2 block" }, providers: [TranslatePipe], ngImport: i0, template: "<aside\n class=\"hidden h-full min-h-0 flex-col overflow-hidden border-r shadow-sm md:flex\"\n [class]=\"zClasses()\"\n [style.--z-menu-v2-expanded-width.px]=\"zExpandedWidth()\"\n [style.--z-menu-v2-collapsed-width.px]=\"zCollapsedWidth()\">\n <div\n class=\"border-sidebar-border flex h-14 shrink-0 items-center gap-2 border-b px-3\"\n [class.justify-center]=\"sidebarCollapsed()\">\n @if (!sidebarCollapsed() && zLogo()) {\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto shrink-0 object-contain transition-opacity\" />\n }\n\n @if (!sidebarCollapsed()) {\n <div\n class=\"min-w-0 flex-1 overflow-hidden text-sm font-semibold text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"effectiveTitle() | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ effectiveTitle() | translate }}\n </div>\n }\n\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"z-menu-v2-toggle h-9 w-9 shrink-0\"\n [class.z-menu-v2-toggle-collapsed]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"\n (sidebarCollapsed() ? 'i18n_z_ui_menu_expand_sidebar' : 'i18n_z_ui_menu_collapse_sidebar') | translate\n \"\n (click)=\"toggleSidebar()\">\n <z-icon [zType]=\"sidebarCollapsed() ? 'lucidePanelLeftOpen' : 'lucidePanelLeftClose'\" zSize=\"18\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar min-h-0 flex-1\" track=\"vertical\">\n <nav class=\"z-menu-v2-nav flex flex-col p-2\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n @if (parent.groupLabel && !sidebarCollapsed()) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n @if (sidebarCollapsed() && parentHasChildren) {\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"parentPopoverTpl\"\n [zPopoverWidth]=\"256\"\n zPosition=\"right-top\"\n [zOffset]=\"10\"\n class=\"z-menu-v2-icon-item\"\n [class.active]=\"parentActive || parentLeafActive\"\n [attr.aria-label]=\"parent.name | translate\"\n (click)=\"onCollapsedParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"20\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"20\" />\n }\n </button>\n\n <ng-template #parentPopoverTpl let-close=\"close\">\n <div class=\"z-menu-v2-popover w-64 max-w-64 min-w-0 pt-1 pl-1\">\n <div\n #parentPopoverHeaderTrigger\n class=\"text-muted-foreground flex items-center gap-2 px-2 py-2 text-xs font-medium\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"15\" />\n }\n <span\n class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentPopoverHeaderTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n </div>\n <ng-scrollbar class=\"z-menu-v2-popover-scrollbar\" orientation=\"vertical\" visibility=\"visible\">\n <div class=\"z-menu-v2-popover-scroll-content pr-2 pb-1\">\n <ng-container\n *ngTemplateOutlet=\"collapsedChildrenTpl; context: { $implicit: parent.children, close: close }\" />\n </div>\n </ng-scrollbar>\n </div>\n </ng-template>\n }\n @if (!(sidebarCollapsed() && parentHasChildren)) {\n <ng-container *ngTemplateOutlet=\"openParentTpl; context: { $implicit: parent }\" />\n }\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"userFooterTpl\" />\n</aside>\n\n<ng-template #openParentTpl let-parent>\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n <div class=\"z-menu-v2-menu-group\">\n <button\n #parentTrigger\n type=\"button\"\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n [class.icon-only]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? (parent.name | translate) : null\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\"\n [zDisabled]=\"!sidebarCollapsed()\"\n [zAlwaysShow]=\"sidebarCollapsed()\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n\n @if (!sidebarCollapsed()) {\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n }\n </button>\n\n @if (!sidebarCollapsed() && parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'right' }\" />\n </div>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #collapsedChildrenTpl let-children let-close=\"close\">\n <div class=\"z-menu-v2-submenu z-menu-v2-popover-tree\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #collapsedChildTrigger\n type=\"button\"\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"childHasChildren ? onMenuItemClick(child) : onCollapsedLeafClick(child, close)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"collapsedChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel collapsed-popover\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <div class=\"z-menu-v2-submenu z-menu-v2-submenu-nested\">\n @for (subChild of child.children; track subChild.id) {\n @let subChildActive = selectedMenuItem()?.id === subChild.id;\n <button\n #collapsedSubChildTrigger\n type=\"button\"\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"subChildActive\"\n (click)=\"onCollapsedLeafClick(subChild, close)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && !subChild.iconSvg) {\n <span class=\"z-menu-v2-dot small\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"subChild.name | translate\"\n [zTriggerElement]=\"collapsedSubChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ subChild.name | translate }}\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #userFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-2\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n [zOffset]=\"10\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-md p-2 text-left\"\n [class.justify-center]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? zUser()?.name || 'User Name' : null\">\n <span class=\"h-9 w-9 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n @if (!sidebarCollapsed()) {\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n }\n </button>\n </div>\n</ng-template>\n\n<ng-template #mobileUserFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-3\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"top-right\"\n [zOffset]=\"6\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-md p-2 text-left\">\n <span class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n </button>\n </div>\n</ng-template>\n\n<ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"overflow-hidden font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground mt-0.5 overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n\n @if (visibleUserActions().length > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n @for (action of visibleUserActions(); track action.id; let idx = $index) {\n @if (action.divide === 'before' && idx > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n #userActionTrigger\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span\n class=\"min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"action.label | translate\"\n [zTriggerElement]=\"userActionTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ action.label | translate }}\n </span>\n </button>\n\n @if (action.divide === 'after' && idx < visibleUserActions().length - 1) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n</ng-template>\n\n<ng-template #openChildrenTpl let-children let-position=\"position\">\n <div class=\"z-menu-v2-submenu\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #openChildTrigger\n type=\"button\"\n class=\"z-menu-v2-item z-menu-v2-item-child\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"openChildTrigger\"\n [zPosition]=\"position\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: child.children, position: position }\" />\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n@if (zShowMobileBar()) {\n <div\n class=\"z-menu-v2-mobile-bar border-border bg-background flex h-14 items-center justify-between border-b px-4 md:hidden\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"openMobileMenu()\">\n <z-icon zType=\"lucideMenu\" zSize=\"20\" />\n </button>\n </div>\n}\n\n@if (mobileMenuOpen()) {\n <div\n class=\"z-menu-v2-backdrop fixed inset-0 z-9998 md:hidden\"\n [class.z-menu-v2-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-v2-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onMobileBackdropClick()\"></div>\n}\n\n<aside\n class=\"z-menu-v2-mobile-drawer fixed top-0 left-0 z-9999 flex h-full w-72 max-w-[calc(100vw-1rem)] flex-col border-r md:hidden\"\n [class.open]=\"mobileMenuOpen()\">\n <div class=\"border-sidebar-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar flex-1\" track=\"vertical\">\n <nav class=\"z-menu-v2-nav flex flex-col p-3\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n @if (parent.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"z-menu-v2-menu-group\">\n <button\n #mobileParentTrigger\n type=\"button\"\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"mobileParentTrigger\"\n zPosition=\"top\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n </button>\n\n @if (parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'top' }\" />\n </div>\n </div>\n }\n </div>\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"mobileUserFooterTpl\" />\n</aside>\n", styles: [".z-menu-v2{display:block;flex-shrink:0;height:100%}.z-menu-v2 [class*=cursor-pointer],.z-menu-v2 button{-webkit-user-select:none;user-select:none}.z-menu-v2-shell{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border));width:var(--z-menu-v2-expanded-width, 248px);transition:width .2s cubic-bezier(.4,0,.2,1);will-change:width}.z-menu-v2-collapsed .z-menu-v2-shell{width:var(--z-menu-v2-collapsed-width, 60px)}.z-menu-v2-toggle{position:relative;z-index:1}.z-menu-v2-toggle.z-menu-v2-toggle-collapsed{background-color:var(--z-menu-v2-accent, var(--sidebar-accent));color:var(--z-menu-v2-accent-foreground, var(--sidebar-accent-foreground))}.z-menu-v2-nav{gap:.25rem}.z-menu-v2-menu-group{display:flex;min-width:0;flex-direction:column}.z-menu-v2-item,.z-menu-v2-popover-item,.z-menu-v2-icon-item{min-width:0;border-radius:var(--radius-md);outline:none;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.625rem;padding:.5rem .625rem;font-size:.8125rem;font-weight:450}.z-menu-v2-item:hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-item.parent-active:not(.active){color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.parent-active:not(.active):hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.active .z-menu-v2-dot,.z-menu-v2-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item.icon-only{justify-content:center;padding-inline:0;width:2.5rem;height:2.5rem;margin-inline:auto}.z-menu-v2-icon-item{display:flex;width:2.5rem;height:2.5rem;cursor:pointer;align-items:center;justify-content:center;margin-inline:auto}.z-menu-v2-icon-item:hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-icon-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.5rem;padding:.45rem .5rem;font-size:.8125rem;font-weight:450}.z-menu-v2-popover-item:hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-popover-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item.parent-active:not(.active){background-color:transparent;color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.parent-active:not(.active):hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.active .z-menu-v2-dot,.z-menu-v2-popover-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item-child{position:relative;padding-left:.75rem}.z-menu-v2-item-sub-child{position:relative;padding-left:.75rem;font-size:.78125rem}.z-menu-v2-submenu-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .24s cubic-bezier(.16,1,.3,1)}.z-menu-v2-submenu-panel.expanded{grid-template-rows:1fr}.z-menu-v2-submenu-panel-inner{min-height:0;overflow:hidden}.z-menu-v2-submenu-panel-inner:before{content:\"\";display:block;height:.25rem}.z-menu-v2-submenu{position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;gap:.25rem;margin:0 0 0 .875rem;padding-left:.875rem}.z-menu-v2-submenu:before{content:\"\";position:absolute;top:0;bottom:.75rem;left:0;width:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item,.z-menu-v2-submenu .z-menu-v2-popover-item{position:relative}.z-menu-v2-submenu .z-menu-v2-item:before,.z-menu-v2-submenu .z-menu-v2-popover-item:before{content:\"\";position:absolute;top:50%;left:-.875rem;width:.875rem;height:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item.active:before,.z-menu-v2-submenu .z-menu-v2-item.parent-active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.parent-active:before{background-color:color-mix(in oklab,var(--z-menu-v2-active, var(--sidebar-primary)) 72%,var(--z-menu-v2-border, var(--sidebar-border)))}.z-menu-v2-mobile-drawer{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .border-sidebar-border,.z-menu-v2-mobile-drawer .border-sidebar-border{border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .hover\\:bg-sidebar-accent:hover,.z-menu-v2-mobile-drawer .hover\\:bg-sidebar-accent:hover{background-color:var(--z-menu-v2-accent, var(--sidebar-accent))}.z-menu-v2-submenu-nested{margin-left:.75rem}.z-menu-v2-popover-tree{margin-top:0;margin-bottom:0}.z-menu-v2-popover-scrollbar{--scrollbar-padding: 0;--scrollbar-overscroll-behavior: contain;max-height:min(28rem,100vh - 8rem);min-height:0;overflow-x:hidden;overflow-y:auto}.z-menu-v2-popover-scroll-content{min-width:0}.z-menu-v2-arrow{transition:transform .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-arrow.expanded{transform:rotate(90deg)}.z-menu-v2-dot{display:inline-flex;width:.375rem;height:.375rem;flex-shrink:0;border-radius:9999px;background-color:color-mix(in oklab,var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground)) 58%,transparent)}.z-menu-v2-dot.small{width:.25rem;height:.25rem}.z-menu-v2-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-v2-scrollbar .ng-scroll-viewport,.z-menu-v2-scrollbar .ng-scroll-content{max-width:100%}.z-menu-v2-backdrop{animation:z-menu-v2-backdrop-enter .2s ease-out forwards}.z-menu-v2-backdrop-dark{background-color:#0009}.z-menu-v2-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-v2-mobile-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-v2-mobile-drawer.open{transform:translate(0)}@keyframes z-menu-v2-backdrop-enter{0%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zSticky", "zShowArrow", "zKeyboardSafe"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], exportAs: ["zPopover"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTooltipPosition", "zTrigger", "zTooltipTrigger", "zTooltipType", "zTooltipSize", "zClass", "zTooltipClass", "zShowDelay", "zTooltipShowDelay", "zHideDelay", "zTooltipHideDelay", "zArrow", "zTooltipArrow", "zDisabled", "zTooltipDisabled", "zOffset", "zTooltipOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
879
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: ZMenuV2Component, isStandalone: true, selector: "z-menu-v2", inputs: { zLogo: { classPropertyName: "zLogo", publicName: "zLogo", isSignal: true, isRequired: false, transformFunction: null }, zLogoMobile: { classPropertyName: "zLogoMobile", publicName: "zLogoMobile", isSignal: true, isRequired: false, transformFunction: null }, zMenus: { classPropertyName: "zMenus", publicName: "zMenus", isSignal: true, isRequired: false, transformFunction: null }, zUser: { classPropertyName: "zUser", publicName: "zUser", isSignal: true, isRequired: false, transformFunction: null }, zUserActions: { classPropertyName: "zUserActions", publicName: "zUserActions", isSignal: true, isRequired: false, transformFunction: null }, zCurrentPath: { classPropertyName: "zCurrentPath", publicName: "zCurrentPath", isSignal: true, isRequired: false, transformFunction: null }, zKey: { classPropertyName: "zKey", publicName: "zKey", isSignal: true, isRequired: false, transformFunction: null }, zClass: { classPropertyName: "zClass", publicName: "zClass", isSignal: true, isRequired: false, transformFunction: null }, zTitle: { classPropertyName: "zTitle", publicName: "zTitle", isSignal: true, isRequired: false, transformFunction: null }, zCollapsedWidth: { classPropertyName: "zCollapsedWidth", publicName: "zCollapsedWidth", isSignal: true, isRequired: false, transformFunction: null }, zExpandedWidth: { classPropertyName: "zExpandedWidth", publicName: "zExpandedWidth", isSignal: true, isRequired: false, transformFunction: null }, zExpandMode: { classPropertyName: "zExpandMode", publicName: "zExpandMode", isSignal: true, isRequired: false, transformFunction: null }, zShowMobileBar: { classPropertyName: "zShowMobileBar", publicName: "zShowMobileBar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOnSelect: "zOnSelect", zOnMenuAction: "zOnMenuAction", zControl: "zControl" }, host: { properties: { "class.z-menu-v2-collapsed": "sidebarCollapsed()", "class.z-menu-v2-mobile-open": "mobileMenuOpen()", "class.z-menu-v2-mobile": "isMobile()" }, classAttribute: "z-menu-v2 block" }, providers: [TranslatePipe], ngImport: i0, template: "<aside\n class=\"hidden h-full min-h-0 flex-col overflow-hidden border-r shadow-sm md:flex\"\n [class]=\"zClasses()\"\n [style.--z-menu-v2-expanded-width.px]=\"zExpandedWidth()\"\n [style.--z-menu-v2-collapsed-width.px]=\"zCollapsedWidth()\">\n <div\n class=\"border-sidebar-border flex h-14 shrink-0 items-center gap-2 border-b px-3\"\n [class.justify-center]=\"sidebarCollapsed()\">\n @if (!sidebarCollapsed() && zLogo()) {\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto shrink-0 object-contain transition-opacity\" />\n }\n\n @if (!sidebarCollapsed()) {\n <div\n class=\"min-w-0 flex-1 overflow-hidden text-sm font-semibold text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"effectiveTitle() | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ effectiveTitle() | translate }}\n </div>\n }\n\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"z-menu-v2-toggle h-9 w-9 shrink-0\"\n [class.z-menu-v2-toggle-collapsed]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"\n (sidebarCollapsed() ? 'i18n_z_ui_menu_expand_sidebar' : 'i18n_z_ui_menu_collapse_sidebar') | translate\n \"\n (click)=\"toggleSidebar()\">\n <z-icon [zType]=\"sidebarCollapsed() ? 'lucidePanelLeftOpen' : 'lucidePanelLeftClose'\" zSize=\"18\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar min-h-0 flex-1\" track=\"vertical\">\n <nav zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-nav flex flex-col p-2\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n @if (parent.groupLabel && !sidebarCollapsed()) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n @if (sidebarCollapsed() && parentHasChildren) {\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"parentPopoverTpl\"\n [zPopoverWidth]=\"256\"\n zPosition=\"right-top\"\n [zOffset]=\"10\"\n data-glide-item\n class=\"z-menu-v2-icon-item\"\n [class.active]=\"parentActive || parentLeafActive\"\n [attr.aria-label]=\"parent.name | translate\"\n (click)=\"onCollapsedParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"20\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"20\" />\n }\n </button>\n\n <ng-template #parentPopoverTpl let-close=\"close\">\n <div class=\"z-menu-v2-popover w-64 max-w-64 min-w-0 pt-1 pl-1\">\n <div\n #parentPopoverHeaderTrigger\n class=\"text-muted-foreground flex items-center gap-2 px-2 py-2 text-xs font-medium\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"15\" />\n }\n <span\n class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentPopoverHeaderTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n </div>\n <ng-scrollbar class=\"z-menu-v2-popover-scrollbar\" orientation=\"vertical\" visibility=\"visible\">\n <div class=\"z-menu-v2-popover-scroll-content pr-2 pb-1\">\n <ng-container\n *ngTemplateOutlet=\"collapsedChildrenTpl; context: { $implicit: parent.children, close: close }\" />\n </div>\n </ng-scrollbar>\n </div>\n </ng-template>\n }\n @if (!(sidebarCollapsed() && parentHasChildren)) {\n <ng-container *ngTemplateOutlet=\"openParentTpl; context: { $implicit: parent }\" />\n }\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"userFooterTpl\" />\n</aside>\n\n<ng-template #openParentTpl let-parent>\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n <div class=\"z-menu-v2-menu-group\">\n <button\n #parentTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n [class.icon-only]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? (parent.name | translate) : null\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\"\n [zDisabled]=\"!sidebarCollapsed()\"\n [zAlwaysShow]=\"sidebarCollapsed()\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n\n @if (!sidebarCollapsed()) {\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n }\n </button>\n\n @if (!sidebarCollapsed() && parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'right' }\" />\n </div>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #collapsedChildrenTpl let-children let-close=\"close\">\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-submenu z-menu-v2-popover-tree\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #collapsedChildTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"childHasChildren ? onMenuItemClick(child) : onCollapsedLeafClick(child, close)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"collapsedChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel collapsed-popover\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <div class=\"z-menu-v2-submenu z-menu-v2-submenu-nested\">\n @for (subChild of child.children; track subChild.id) {\n @let subChildActive = selectedMenuItem()?.id === subChild.id;\n <button\n #collapsedSubChildTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"subChildActive\"\n (click)=\"onCollapsedLeafClick(subChild, close)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && !subChild.iconSvg) {\n <span class=\"z-menu-v2-dot small\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"subChild.name | translate\"\n [zTriggerElement]=\"collapsedSubChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ subChild.name | translate }}\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #userFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-2\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n [zOffset]=\"10\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-(--radius) p-2 text-left\"\n [class.justify-center]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? zUser()?.name || 'User Name' : null\">\n <span class=\"h-9 w-9 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n @if (!sidebarCollapsed()) {\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n }\n </button>\n </div>\n</ng-template>\n\n<ng-template #mobileUserFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-3\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"top-right\"\n [zOffset]=\"6\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-(--radius) p-2 text-left\">\n <span class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n </button>\n </div>\n</ng-template>\n\n<ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"overflow-hidden font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground mt-0.5 overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n\n @if (visibleUserActions().length > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius-sm)\">\n @for (action of visibleUserActions(); track action.id; let idx = $index) {\n @if (action.divide === 'before' && idx > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n #userActionTrigger\n type=\"button\"\n [disabled]=\"action.disabled\"\n data-glide-item\n [class]=\"action.class\"\n class=\"focus:bg-accent relative flex w-full cursor-pointer items-center gap-2 rounded-(--radius-sm) px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span\n class=\"min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"action.label | translate\"\n [zTriggerElement]=\"userActionTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ action.label | translate }}\n </span>\n </button>\n\n @if (action.divide === 'after' && idx < visibleUserActions().length - 1) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #openChildrenTpl let-children let-position=\"position\">\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-submenu\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #openChildTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-item z-menu-v2-item-child\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"openChildTrigger\"\n [zPosition]=\"position\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: child.children, position: position }\" />\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n@if (zShowMobileBar()) {\n <div\n class=\"z-menu-v2-mobile-bar border-border bg-background flex h-14 items-center justify-between border-b px-4 md:hidden\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"openMobileMenu()\">\n <z-icon zType=\"lucideMenu\" zSize=\"20\" />\n </button>\n </div>\n}\n\n@if (mobileMenuOpen()) {\n <div\n class=\"z-menu-v2-backdrop fixed inset-0 z-9998 md:hidden\"\n [class.z-menu-v2-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-v2-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onMobileBackdropClick()\"></div>\n}\n\n<aside\n class=\"z-menu-v2-mobile-drawer fixed top-0 left-0 z-9999 flex h-full w-72 max-w-[calc(100vw-1rem)] flex-col border-r md:hidden\"\n [class.open]=\"mobileMenuOpen()\">\n <div class=\"border-sidebar-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar flex-1\" track=\"vertical\">\n <nav zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-nav flex flex-col p-3\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n @if (parent.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"z-menu-v2-menu-group\">\n <button\n #mobileParentTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"mobileParentTrigger\"\n zPosition=\"top\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n </button>\n\n @if (parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'top' }\" />\n </div>\n </div>\n }\n </div>\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"mobileUserFooterTpl\" />\n</aside>\n", styles: [".z-menu-v2{display:block;flex-shrink:0;height:100%}.z-menu-v2 [class*=cursor-pointer],.z-menu-v2 button{-webkit-user-select:none;user-select:none}.z-menu-v2-shell{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border));width:var(--z-menu-v2-expanded-width, 248px);transition:width .2s cubic-bezier(.4,0,.2,1);will-change:width}.z-menu-v2-collapsed .z-menu-v2-shell{width:var(--z-menu-v2-collapsed-width, 60px)}.z-menu-v2-toggle{position:relative;z-index:1}.z-menu-v2-toggle.z-menu-v2-toggle-collapsed{background-color:var(--z-menu-v2-accent, var(--sidebar-accent));color:var(--z-menu-v2-accent-foreground, var(--sidebar-accent-foreground))}.z-menu-v2-nav{gap:.25rem}.z-menu-v2-menu-group{display:flex;min-width:0;flex-direction:column}.z-menu-v2-item,.z-menu-v2-popover-item,.z-menu-v2-icon-item{min-width:0;border-radius:var(--radius);position:relative;z-index:1;outline:none;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.625rem;padding:.5rem .625rem;font-size:.8125rem;font-weight:450}.z-menu-v2-item:hover{color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-item.parent-active:not(.active){color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.parent-active:not(.active):hover{color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.active .z-menu-v2-dot,.z-menu-v2-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item.icon-only{justify-content:center;padding-inline:0;width:2.5rem;height:2.5rem;margin-inline:auto}.z-menu-v2-icon-item{display:flex;width:2.5rem;height:2.5rem;cursor:pointer;align-items:center;justify-content:center;margin-inline:auto}.z-menu-v2-icon-item:hover{color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-icon-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.5rem;padding:.45rem .5rem;font-size:.8125rem;font-weight:450}.z-menu-v2-popover-item:hover{color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-popover-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item.parent-active:not(.active){background-color:transparent;color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.parent-active:not(.active):hover{color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.active .z-menu-v2-dot,.z-menu-v2-popover-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item-child{position:relative;padding-left:.75rem}.z-menu-v2-item-sub-child{position:relative;padding-left:.75rem;font-size:.78125rem}.z-menu-v2-submenu-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .24s cubic-bezier(.16,1,.3,1)}.z-menu-v2-submenu-panel.expanded{grid-template-rows:1fr}.z-menu-v2-submenu-panel-inner{min-height:0;overflow:hidden}.z-menu-v2-submenu-panel-inner:before{content:\"\";display:block;height:.25rem}.z-menu-v2-submenu{position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;gap:.25rem;margin:0 0 0 .875rem;padding-left:.875rem}.z-menu-v2-submenu:before{content:\"\";position:absolute;top:0;bottom:.75rem;left:0;width:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item,.z-menu-v2-submenu .z-menu-v2-popover-item{position:relative}.z-menu-v2-submenu .z-menu-v2-item:before,.z-menu-v2-submenu .z-menu-v2-popover-item:before{content:\"\";position:absolute;top:50%;left:-.875rem;width:.875rem;height:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item.active:before,.z-menu-v2-submenu .z-menu-v2-item.parent-active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.parent-active:before{background-color:color-mix(in oklab,var(--z-menu-v2-active, var(--sidebar-primary)) 72%,var(--z-menu-v2-border, var(--sidebar-border)))}.z-menu-v2-mobile-drawer{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .border-sidebar-border,.z-menu-v2-mobile-drawer .border-sidebar-border{border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .hover\\:bg-sidebar-accent:hover,.z-menu-v2-mobile-drawer .hover\\:bg-sidebar-accent:hover{background-color:var(--z-menu-v2-accent, var(--sidebar-accent))}.z-menu-v2-submenu-nested{margin-left:.75rem}.z-menu-v2-popover-tree{margin-top:0;margin-bottom:0}.z-menu-v2-popover-scrollbar{--scrollbar-padding: 0;--scrollbar-overscroll-behavior: contain;max-height:min(28rem,100vh - 8rem);min-height:0;overflow-x:hidden;overflow-y:auto}.z-menu-v2-popover-scroll-content{min-width:0}.z-menu-v2-arrow{transition:transform .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-arrow.expanded{transform:rotate(90deg)}.z-menu-v2-dot{display:inline-flex;width:.375rem;height:.375rem;flex-shrink:0;border-radius:9999px;background-color:color-mix(in oklab,var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground)) 58%,transparent)}.z-menu-v2-dot.small{width:.25rem;height:.25rem}.z-menu-v2-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-v2-scrollbar .ng-scroll-viewport,.z-menu-v2-scrollbar .ng-scroll-content{max-width:100%}.z-menu-v2-backdrop{animation:z-menu-v2-backdrop-enter .2s ease-out forwards}.z-menu-v2-backdrop-dark{background-color:#0009}.z-menu-v2-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-v2-mobile-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-v2-mobile-drawer.open{transform:translate(0)}@keyframes z-menu-v2-backdrop-enter{0%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZHoverGlideDirective, selector: "[zHoverGlide]", inputs: ["zHoverGlideSelector", "zHoverGlideClass", "zHoverGlideDisabled"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zSticky", "zShowArrow", "zKeyboardSafe"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], exportAs: ["zPopover"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTooltipPosition", "zTrigger", "zTooltipTrigger", "zTooltipType", "zTooltipSize", "zClass", "zTooltipClass", "zShowDelay", "zTooltipShowDelay", "zHideDelay", "zTooltipHideDelay", "zArrow", "zTooltipArrow", "zDisabled", "zTooltipDisabled", "zOffset", "zTooltipOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
878
880
  }
879
881
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZMenuV2Component, decorators: [{
880
882
  type: Component,
@@ -882,6 +884,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
882
884
  NgTemplateOutlet,
883
885
  ZButtonComponent,
884
886
  ZIconComponent,
887
+ ZHoverGlideDirective,
885
888
  ZPopoverDirective,
886
889
  ZTooltipDirective,
887
890
  NgScrollbar,
@@ -891,7 +894,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
891
894
  '[class.z-menu-v2-collapsed]': 'sidebarCollapsed()',
892
895
  '[class.z-menu-v2-mobile-open]': 'mobileMenuOpen()',
893
896
  '[class.z-menu-v2-mobile]': 'isMobile()',
894
- }, template: "<aside\n class=\"hidden h-full min-h-0 flex-col overflow-hidden border-r shadow-sm md:flex\"\n [class]=\"zClasses()\"\n [style.--z-menu-v2-expanded-width.px]=\"zExpandedWidth()\"\n [style.--z-menu-v2-collapsed-width.px]=\"zCollapsedWidth()\">\n <div\n class=\"border-sidebar-border flex h-14 shrink-0 items-center gap-2 border-b px-3\"\n [class.justify-center]=\"sidebarCollapsed()\">\n @if (!sidebarCollapsed() && zLogo()) {\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto shrink-0 object-contain transition-opacity\" />\n }\n\n @if (!sidebarCollapsed()) {\n <div\n class=\"min-w-0 flex-1 overflow-hidden text-sm font-semibold text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"effectiveTitle() | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ effectiveTitle() | translate }}\n </div>\n }\n\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"z-menu-v2-toggle h-9 w-9 shrink-0\"\n [class.z-menu-v2-toggle-collapsed]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"\n (sidebarCollapsed() ? 'i18n_z_ui_menu_expand_sidebar' : 'i18n_z_ui_menu_collapse_sidebar') | translate\n \"\n (click)=\"toggleSidebar()\">\n <z-icon [zType]=\"sidebarCollapsed() ? 'lucidePanelLeftOpen' : 'lucidePanelLeftClose'\" zSize=\"18\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar min-h-0 flex-1\" track=\"vertical\">\n <nav class=\"z-menu-v2-nav flex flex-col p-2\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n @if (parent.groupLabel && !sidebarCollapsed()) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n @if (sidebarCollapsed() && parentHasChildren) {\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"parentPopoverTpl\"\n [zPopoverWidth]=\"256\"\n zPosition=\"right-top\"\n [zOffset]=\"10\"\n class=\"z-menu-v2-icon-item\"\n [class.active]=\"parentActive || parentLeafActive\"\n [attr.aria-label]=\"parent.name | translate\"\n (click)=\"onCollapsedParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"20\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"20\" />\n }\n </button>\n\n <ng-template #parentPopoverTpl let-close=\"close\">\n <div class=\"z-menu-v2-popover w-64 max-w-64 min-w-0 pt-1 pl-1\">\n <div\n #parentPopoverHeaderTrigger\n class=\"text-muted-foreground flex items-center gap-2 px-2 py-2 text-xs font-medium\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"15\" />\n }\n <span\n class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentPopoverHeaderTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n </div>\n <ng-scrollbar class=\"z-menu-v2-popover-scrollbar\" orientation=\"vertical\" visibility=\"visible\">\n <div class=\"z-menu-v2-popover-scroll-content pr-2 pb-1\">\n <ng-container\n *ngTemplateOutlet=\"collapsedChildrenTpl; context: { $implicit: parent.children, close: close }\" />\n </div>\n </ng-scrollbar>\n </div>\n </ng-template>\n }\n @if (!(sidebarCollapsed() && parentHasChildren)) {\n <ng-container *ngTemplateOutlet=\"openParentTpl; context: { $implicit: parent }\" />\n }\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"userFooterTpl\" />\n</aside>\n\n<ng-template #openParentTpl let-parent>\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n <div class=\"z-menu-v2-menu-group\">\n <button\n #parentTrigger\n type=\"button\"\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n [class.icon-only]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? (parent.name | translate) : null\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\"\n [zDisabled]=\"!sidebarCollapsed()\"\n [zAlwaysShow]=\"sidebarCollapsed()\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n\n @if (!sidebarCollapsed()) {\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n }\n </button>\n\n @if (!sidebarCollapsed() && parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'right' }\" />\n </div>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #collapsedChildrenTpl let-children let-close=\"close\">\n <div class=\"z-menu-v2-submenu z-menu-v2-popover-tree\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #collapsedChildTrigger\n type=\"button\"\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"childHasChildren ? onMenuItemClick(child) : onCollapsedLeafClick(child, close)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"collapsedChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel collapsed-popover\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <div class=\"z-menu-v2-submenu z-menu-v2-submenu-nested\">\n @for (subChild of child.children; track subChild.id) {\n @let subChildActive = selectedMenuItem()?.id === subChild.id;\n <button\n #collapsedSubChildTrigger\n type=\"button\"\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"subChildActive\"\n (click)=\"onCollapsedLeafClick(subChild, close)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && !subChild.iconSvg) {\n <span class=\"z-menu-v2-dot small\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"subChild.name | translate\"\n [zTriggerElement]=\"collapsedSubChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ subChild.name | translate }}\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #userFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-2\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n [zOffset]=\"10\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-md p-2 text-left\"\n [class.justify-center]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? zUser()?.name || 'User Name' : null\">\n <span class=\"h-9 w-9 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n @if (!sidebarCollapsed()) {\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n }\n </button>\n </div>\n</ng-template>\n\n<ng-template #mobileUserFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-3\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"top-right\"\n [zOffset]=\"6\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-md p-2 text-left\">\n <span class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n </button>\n </div>\n</ng-template>\n\n<ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"overflow-hidden font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground mt-0.5 overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n\n @if (visibleUserActions().length > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n @for (action of visibleUserActions(); track action.id; let idx = $index) {\n @if (action.divide === 'before' && idx > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n #userActionTrigger\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span\n class=\"min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"action.label | translate\"\n [zTriggerElement]=\"userActionTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ action.label | translate }}\n </span>\n </button>\n\n @if (action.divide === 'after' && idx < visibleUserActions().length - 1) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n</ng-template>\n\n<ng-template #openChildrenTpl let-children let-position=\"position\">\n <div class=\"z-menu-v2-submenu\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #openChildTrigger\n type=\"button\"\n class=\"z-menu-v2-item z-menu-v2-item-child\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"openChildTrigger\"\n [zPosition]=\"position\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: child.children, position: position }\" />\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n@if (zShowMobileBar()) {\n <div\n class=\"z-menu-v2-mobile-bar border-border bg-background flex h-14 items-center justify-between border-b px-4 md:hidden\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"openMobileMenu()\">\n <z-icon zType=\"lucideMenu\" zSize=\"20\" />\n </button>\n </div>\n}\n\n@if (mobileMenuOpen()) {\n <div\n class=\"z-menu-v2-backdrop fixed inset-0 z-9998 md:hidden\"\n [class.z-menu-v2-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-v2-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onMobileBackdropClick()\"></div>\n}\n\n<aside\n class=\"z-menu-v2-mobile-drawer fixed top-0 left-0 z-9999 flex h-full w-72 max-w-[calc(100vw-1rem)] flex-col border-r md:hidden\"\n [class.open]=\"mobileMenuOpen()\">\n <div class=\"border-sidebar-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar flex-1\" track=\"vertical\">\n <nav class=\"z-menu-v2-nav flex flex-col p-3\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n @if (parent.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"z-menu-v2-menu-group\">\n <button\n #mobileParentTrigger\n type=\"button\"\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"mobileParentTrigger\"\n zPosition=\"top\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n </button>\n\n @if (parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'top' }\" />\n </div>\n </div>\n }\n </div>\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"mobileUserFooterTpl\" />\n</aside>\n", styles: [".z-menu-v2{display:block;flex-shrink:0;height:100%}.z-menu-v2 [class*=cursor-pointer],.z-menu-v2 button{-webkit-user-select:none;user-select:none}.z-menu-v2-shell{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border));width:var(--z-menu-v2-expanded-width, 248px);transition:width .2s cubic-bezier(.4,0,.2,1);will-change:width}.z-menu-v2-collapsed .z-menu-v2-shell{width:var(--z-menu-v2-collapsed-width, 60px)}.z-menu-v2-toggle{position:relative;z-index:1}.z-menu-v2-toggle.z-menu-v2-toggle-collapsed{background-color:var(--z-menu-v2-accent, var(--sidebar-accent));color:var(--z-menu-v2-accent-foreground, var(--sidebar-accent-foreground))}.z-menu-v2-nav{gap:.25rem}.z-menu-v2-menu-group{display:flex;min-width:0;flex-direction:column}.z-menu-v2-item,.z-menu-v2-popover-item,.z-menu-v2-icon-item{min-width:0;border-radius:var(--radius-md);outline:none;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.625rem;padding:.5rem .625rem;font-size:.8125rem;font-weight:450}.z-menu-v2-item:hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-item.parent-active:not(.active){color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.parent-active:not(.active):hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.active .z-menu-v2-dot,.z-menu-v2-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item.icon-only{justify-content:center;padding-inline:0;width:2.5rem;height:2.5rem;margin-inline:auto}.z-menu-v2-icon-item{display:flex;width:2.5rem;height:2.5rem;cursor:pointer;align-items:center;justify-content:center;margin-inline:auto}.z-menu-v2-icon-item:hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-icon-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.5rem;padding:.45rem .5rem;font-size:.8125rem;font-weight:450}.z-menu-v2-popover-item:hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-popover-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item.parent-active:not(.active){background-color:transparent;color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.parent-active:not(.active):hover{background-color:var(--z-menu-v2-accent, var(--accent));color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.active .z-menu-v2-dot,.z-menu-v2-popover-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item-child{position:relative;padding-left:.75rem}.z-menu-v2-item-sub-child{position:relative;padding-left:.75rem;font-size:.78125rem}.z-menu-v2-submenu-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .24s cubic-bezier(.16,1,.3,1)}.z-menu-v2-submenu-panel.expanded{grid-template-rows:1fr}.z-menu-v2-submenu-panel-inner{min-height:0;overflow:hidden}.z-menu-v2-submenu-panel-inner:before{content:\"\";display:block;height:.25rem}.z-menu-v2-submenu{position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;gap:.25rem;margin:0 0 0 .875rem;padding-left:.875rem}.z-menu-v2-submenu:before{content:\"\";position:absolute;top:0;bottom:.75rem;left:0;width:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item,.z-menu-v2-submenu .z-menu-v2-popover-item{position:relative}.z-menu-v2-submenu .z-menu-v2-item:before,.z-menu-v2-submenu .z-menu-v2-popover-item:before{content:\"\";position:absolute;top:50%;left:-.875rem;width:.875rem;height:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item.active:before,.z-menu-v2-submenu .z-menu-v2-item.parent-active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.parent-active:before{background-color:color-mix(in oklab,var(--z-menu-v2-active, var(--sidebar-primary)) 72%,var(--z-menu-v2-border, var(--sidebar-border)))}.z-menu-v2-mobile-drawer{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .border-sidebar-border,.z-menu-v2-mobile-drawer .border-sidebar-border{border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .hover\\:bg-sidebar-accent:hover,.z-menu-v2-mobile-drawer .hover\\:bg-sidebar-accent:hover{background-color:var(--z-menu-v2-accent, var(--sidebar-accent))}.z-menu-v2-submenu-nested{margin-left:.75rem}.z-menu-v2-popover-tree{margin-top:0;margin-bottom:0}.z-menu-v2-popover-scrollbar{--scrollbar-padding: 0;--scrollbar-overscroll-behavior: contain;max-height:min(28rem,100vh - 8rem);min-height:0;overflow-x:hidden;overflow-y:auto}.z-menu-v2-popover-scroll-content{min-width:0}.z-menu-v2-arrow{transition:transform .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-arrow.expanded{transform:rotate(90deg)}.z-menu-v2-dot{display:inline-flex;width:.375rem;height:.375rem;flex-shrink:0;border-radius:9999px;background-color:color-mix(in oklab,var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground)) 58%,transparent)}.z-menu-v2-dot.small{width:.25rem;height:.25rem}.z-menu-v2-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-v2-scrollbar .ng-scroll-viewport,.z-menu-v2-scrollbar .ng-scroll-content{max-width:100%}.z-menu-v2-backdrop{animation:z-menu-v2-backdrop-enter .2s ease-out forwards}.z-menu-v2-backdrop-dark{background-color:#0009}.z-menu-v2-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-v2-mobile-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-v2-mobile-drawer.open{transform:translate(0)}@keyframes z-menu-v2-backdrop-enter{0%{opacity:0}to{opacity:1}}\n"] }]
897
+ }, template: "<aside\n class=\"hidden h-full min-h-0 flex-col overflow-hidden border-r shadow-sm md:flex\"\n [class]=\"zClasses()\"\n [style.--z-menu-v2-expanded-width.px]=\"zExpandedWidth()\"\n [style.--z-menu-v2-collapsed-width.px]=\"zCollapsedWidth()\">\n <div\n class=\"border-sidebar-border flex h-14 shrink-0 items-center gap-2 border-b px-3\"\n [class.justify-center]=\"sidebarCollapsed()\">\n @if (!sidebarCollapsed() && zLogo()) {\n <img [src]=\"zLogo()\" alt=\"Logo\" class=\"h-8 w-auto shrink-0 object-contain transition-opacity\" />\n }\n\n @if (!sidebarCollapsed()) {\n <div\n class=\"min-w-0 flex-1 overflow-hidden text-sm font-semibold text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"effectiveTitle() | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ effectiveTitle() | translate }}\n </div>\n }\n\n <button\n z-button\n zType=\"ghost\"\n [zWave]=\"false\"\n class=\"z-menu-v2-toggle h-9 w-9 shrink-0\"\n [class.z-menu-v2-toggle-collapsed]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"\n (sidebarCollapsed() ? 'i18n_z_ui_menu_expand_sidebar' : 'i18n_z_ui_menu_collapse_sidebar') | translate\n \"\n (click)=\"toggleSidebar()\">\n <z-icon [zType]=\"sidebarCollapsed() ? 'lucidePanelLeftOpen' : 'lucidePanelLeftClose'\" zSize=\"18\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar min-h-0 flex-1\" track=\"vertical\">\n <nav zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-nav flex flex-col p-2\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n @if (parent.groupLabel && !sidebarCollapsed()) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n @if (sidebarCollapsed() && parentHasChildren) {\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"parentPopoverTpl\"\n [zPopoverWidth]=\"256\"\n zPosition=\"right-top\"\n [zOffset]=\"10\"\n data-glide-item\n class=\"z-menu-v2-icon-item\"\n [class.active]=\"parentActive || parentLeafActive\"\n [attr.aria-label]=\"parent.name | translate\"\n (click)=\"onCollapsedParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"20\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"20\" />\n }\n </button>\n\n <ng-template #parentPopoverTpl let-close=\"close\">\n <div class=\"z-menu-v2-popover w-64 max-w-64 min-w-0 pt-1 pl-1\">\n <div\n #parentPopoverHeaderTrigger\n class=\"text-muted-foreground flex items-center gap-2 px-2 py-2 text-xs font-medium\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"15\" />\n }\n <span\n class=\"overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentPopoverHeaderTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n </div>\n <ng-scrollbar class=\"z-menu-v2-popover-scrollbar\" orientation=\"vertical\" visibility=\"visible\">\n <div class=\"z-menu-v2-popover-scroll-content pr-2 pb-1\">\n <ng-container\n *ngTemplateOutlet=\"collapsedChildrenTpl; context: { $implicit: parent.children, close: close }\" />\n </div>\n </ng-scrollbar>\n </div>\n </ng-template>\n }\n @if (!(sidebarCollapsed() && parentHasChildren)) {\n <ng-container *ngTemplateOutlet=\"openParentTpl; context: { $implicit: parent }\" />\n }\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"userFooterTpl\" />\n</aside>\n\n<ng-template #openParentTpl let-parent>\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n\n <div class=\"z-menu-v2-menu-group\">\n <button\n #parentTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n [class.icon-only]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? (parent.name | translate) : null\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n zPosition=\"right\"\n [zOffset]=\"6\"\n [zDisabled]=\"!sidebarCollapsed()\"\n [zAlwaysShow]=\"sidebarCollapsed()\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" [zSize]=\"sidebarCollapsed() ? '20' : '18'\" class=\"shrink-0\" />\n }\n\n @if (!sidebarCollapsed()) {\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"parentTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n }\n </button>\n\n @if (!sidebarCollapsed() && parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'right' }\" />\n </div>\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #collapsedChildrenTpl let-children let-close=\"close\">\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-submenu z-menu-v2-popover-tree\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #collapsedChildTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"childHasChildren ? onMenuItemClick(child) : onCollapsedLeafClick(child, close)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"collapsedChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel collapsed-popover\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <div class=\"z-menu-v2-submenu z-menu-v2-submenu-nested\">\n @for (subChild of child.children; track subChild.id) {\n @let subChildActive = selectedMenuItem()?.id === subChild.id;\n <button\n #collapsedSubChildTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-popover-item\"\n [class.active]=\"subChildActive\"\n (click)=\"onCollapsedLeafClick(subChild, close)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"15\" class=\"shrink-0\" />\n }\n @if (!subChild.icon && !subChild.iconSvg) {\n <span class=\"z-menu-v2-dot small\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"subChild.name | translate\"\n [zTriggerElement]=\"collapsedSubChildTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ subChild.name | translate }}\n </span>\n </button>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #userFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-2\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n [zOffset]=\"10\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-(--radius) p-2 text-left\"\n [class.justify-center]=\"sidebarCollapsed()\"\n [attr.aria-label]=\"sidebarCollapsed() ? zUser()?.name || 'User Name' : null\">\n <span class=\"h-9 w-9 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n @if (!sidebarCollapsed()) {\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n }\n </button>\n </div>\n</ng-template>\n\n<ng-template #mobileUserFooterTpl>\n <div class=\"border-sidebar-border shrink-0 border-t p-3\">\n <button\n type=\"button\"\n z-popover\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"top-right\"\n [zOffset]=\"6\"\n class=\"hover:bg-sidebar-accent flex w-full cursor-pointer items-center gap-3 rounded-(--radius) p-2 text-left\">\n <span class=\"h-10 w-10 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </span>\n <span class=\"min-w-0 flex-1\">\n <span class=\"block overflow-hidden text-sm font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground block overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </span>\n <z-icon zType=\"lucideChevronsUpDown\" zSize=\"15\" class=\"text-muted-foreground shrink-0\" />\n </button>\n </div>\n</ng-template>\n\n<ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"overflow-hidden font-medium text-ellipsis whitespace-nowrap\">\n {{ zUser()?.name || 'User Name' }}\n </span>\n <span class=\"text-muted-foreground mt-0.5 overflow-hidden text-xs text-ellipsis whitespace-nowrap\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n\n @if (visibleUserActions().length > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius-sm)\">\n @for (action of visibleUserActions(); track action.id; let idx = $index) {\n @if (action.divide === 'before' && idx > 0) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n #userActionTrigger\n type=\"button\"\n [disabled]=\"action.disabled\"\n data-glide-item\n [class]=\"action.class\"\n class=\"focus:bg-accent relative flex w-full cursor-pointer items-center gap-2 rounded-(--radius-sm) px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span\n class=\"min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"action.label | translate\"\n [zTriggerElement]=\"userActionTrigger\"\n zPosition=\"right\"\n [zOffset]=\"6\">\n {{ action.label | translate }}\n </span>\n </button>\n\n @if (action.divide === 'after' && idx < visibleUserActions().length - 1) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #openChildrenTpl let-children let-position=\"position\">\n <div zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-submenu\">\n @for (child of children; track child.id) {\n @let childActive = selectedMenuItem()?.id === child.id;\n @let childParentActive = selectedMenuItem()?.parent?.includes(child.id);\n @let childHasChildren = child.children && child.children.length > 0;\n <div class=\"z-menu-v2-menu-group\">\n <button\n #openChildTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-item z-menu-v2-item-child\"\n [class.active]=\"childActive\"\n [class.parent-active]=\"childParentActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n }\n @if (!child.icon && !child.iconSvg) {\n <span class=\"z-menu-v2-dot\"></span>\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"child.name | translate\"\n [zTriggerElement]=\"openChildTrigger\"\n [zPosition]=\"position\"\n [zOffset]=\"6\">\n {{ child.name | translate }}\n </span>\n @if (childHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"child.expanded\" />\n }\n </button>\n\n @if (childHasChildren && child.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"child.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: child.children, position: position }\" />\n </div>\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n\n@if (zShowMobileBar()) {\n <div\n class=\"z-menu-v2-mobile-bar border-border bg-background flex h-14 items-center justify-between border-b px-4 md:hidden\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"openMobileMenu()\">\n <z-icon zType=\"lucideMenu\" zSize=\"20\" />\n </button>\n </div>\n}\n\n@if (mobileMenuOpen()) {\n <div\n class=\"z-menu-v2-backdrop fixed inset-0 z-9998 md:hidden\"\n [class.z-menu-v2-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-v2-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onMobileBackdropClick()\"></div>\n}\n\n<aside\n class=\"z-menu-v2-mobile-drawer fixed top-0 left-0 z-9999 flex h-full w-72 max-w-[calc(100vw-1rem)] flex-col border-r md:hidden\"\n [class.open]=\"mobileMenuOpen()\">\n <div class=\"border-sidebar-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"h-9 w-9\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <ng-scrollbar class=\"z-menu-v2-scrollbar flex-1\" track=\"vertical\">\n <nav zHoverGlide zHoverGlideClass=\"bg-accent rounded-(--radius)\" class=\"z-menu-v2-nav flex flex-col p-3\">\n @for (parent of menuParents(); track parent.id) {\n @let parentActive = parentWithActiveChild()?.id === parent.id;\n @let parentLeafActive = selectedMenuItem()?.id === parent.id;\n @let parentHasChildren = parent.children && parent.children.length > 0;\n @if (parent.groupLabel) {\n <div class=\"mt-1 first:mt-0\">\n <div class=\"border-sidebar-border mb-2.5 border-t\"></div>\n <div class=\"text-muted-foreground px-2 pb-0.5 text-[0.6875rem] font-semibold tracking-wider uppercase\">\n {{ parent.groupLabel | translate }}\n </div>\n </div>\n }\n <div class=\"z-menu-v2-menu-group\">\n <button\n #mobileParentTrigger\n type=\"button\"\n data-glide-item\n class=\"z-menu-v2-item\"\n [class.active]=\"parentLeafActive\"\n [class.parent-active]=\"parentActive && !parentLeafActive\"\n (click)=\"onMenuItemClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n }\n @if (!parent.icon && parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 overflow-hidden text-left text-ellipsis whitespace-nowrap\"\n z-tooltip\n [zContent]=\"parent.name | translate\"\n [zTriggerElement]=\"mobileParentTrigger\"\n zPosition=\"top\"\n [zOffset]=\"6\">\n {{ parent.name | translate }}\n </span>\n @if (parentHasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"15\"\n class=\"z-menu-v2-arrow shrink-0 opacity-60\"\n [class.expanded]=\"parent.expanded\" />\n }\n </button>\n\n @if (parentHasChildren && parent.renderChildren) {\n <div class=\"z-menu-v2-submenu-panel\" [class.expanded]=\"parent.renderExpanded\">\n <div class=\"z-menu-v2-submenu-panel-inner\">\n <ng-container\n *ngTemplateOutlet=\"openChildrenTpl; context: { $implicit: parent.children, position: 'top' }\" />\n </div>\n </div>\n }\n </div>\n }\n </nav>\n </ng-scrollbar>\n\n <ng-container *ngTemplateOutlet=\"mobileUserFooterTpl\" />\n</aside>\n", styles: [".z-menu-v2{display:block;flex-shrink:0;height:100%}.z-menu-v2 [class*=cursor-pointer],.z-menu-v2 button{-webkit-user-select:none;user-select:none}.z-menu-v2-shell{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border));width:var(--z-menu-v2-expanded-width, 248px);transition:width .2s cubic-bezier(.4,0,.2,1);will-change:width}.z-menu-v2-collapsed .z-menu-v2-shell{width:var(--z-menu-v2-collapsed-width, 60px)}.z-menu-v2-toggle{position:relative;z-index:1}.z-menu-v2-toggle.z-menu-v2-toggle-collapsed{background-color:var(--z-menu-v2-accent, var(--sidebar-accent));color:var(--z-menu-v2-accent-foreground, var(--sidebar-accent-foreground))}.z-menu-v2-nav{gap:.25rem}.z-menu-v2-menu-group{display:flex;min-width:0;flex-direction:column}.z-menu-v2-item,.z-menu-v2-popover-item,.z-menu-v2-icon-item{min-width:0;border-radius:var(--radius);position:relative;z-index:1;outline:none;transition:background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.625rem;padding:.5rem .625rem;font-size:.8125rem;font-weight:450}.z-menu-v2-item:hover{color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-item.parent-active:not(.active){color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.parent-active:not(.active):hover{color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-item.active .z-menu-v2-dot,.z-menu-v2-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item.icon-only{justify-content:center;padding-inline:0;width:2.5rem;height:2.5rem;margin-inline:auto}.z-menu-v2-icon-item{display:flex;width:2.5rem;height:2.5rem;cursor:pointer;align-items:center;justify-content:center;margin-inline:auto}.z-menu-v2-icon-item:hover{color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-icon-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item{display:flex;width:100%;cursor:pointer;align-items:center;gap:.5rem;padding:.45rem .5rem;font-size:.8125rem;font-weight:450}.z-menu-v2-popover-item:hover{color:var(--z-menu-v2-accent-foreground, var(--accent-foreground))}.z-menu-v2-popover-item.active{background-color:var(--z-menu-v2-active, var(--sidebar-primary));color:var(--z-menu-v2-active-foreground, var(--sidebar-primary-foreground))}.z-menu-v2-popover-item.parent-active:not(.active){background-color:transparent;color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.parent-active:not(.active):hover{color:var(--z-menu-v2-active, var(--sidebar-primary))}.z-menu-v2-popover-item.active .z-menu-v2-dot,.z-menu-v2-popover-item.parent-active .z-menu-v2-dot{background-color:currentColor}.z-menu-v2-item-child{position:relative;padding-left:.75rem}.z-menu-v2-item-sub-child{position:relative;padding-left:.75rem;font-size:.78125rem}.z-menu-v2-submenu-panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .24s cubic-bezier(.16,1,.3,1)}.z-menu-v2-submenu-panel.expanded{grid-template-rows:1fr}.z-menu-v2-submenu-panel-inner{min-height:0;overflow:hidden}.z-menu-v2-submenu-panel-inner:before{content:\"\";display:block;height:.25rem}.z-menu-v2-submenu{position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;gap:.25rem;margin:0 0 0 .875rem;padding-left:.875rem}.z-menu-v2-submenu:before{content:\"\";position:absolute;top:0;bottom:.75rem;left:0;width:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item,.z-menu-v2-submenu .z-menu-v2-popover-item{position:relative}.z-menu-v2-submenu .z-menu-v2-item:before,.z-menu-v2-submenu .z-menu-v2-popover-item:before{content:\"\";position:absolute;top:50%;left:-.875rem;width:.875rem;height:1px;background-color:color-mix(in oklab,var(--z-menu-v2-border, var(--sidebar-border)) 84%,transparent)}.z-menu-v2-submenu .z-menu-v2-item.active:before,.z-menu-v2-submenu .z-menu-v2-item.parent-active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.active:before,.z-menu-v2-submenu .z-menu-v2-popover-item.parent-active:before{background-color:color-mix(in oklab,var(--z-menu-v2-active, var(--sidebar-primary)) 72%,var(--z-menu-v2-border, var(--sidebar-border)))}.z-menu-v2-mobile-drawer{background-color:var(--z-menu-v2-sidebar, var(--sidebar));color:var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground));border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .border-sidebar-border,.z-menu-v2-mobile-drawer .border-sidebar-border{border-color:var(--z-menu-v2-border, var(--sidebar-border))}.z-menu-v2-shell .hover\\:bg-sidebar-accent:hover,.z-menu-v2-mobile-drawer .hover\\:bg-sidebar-accent:hover{background-color:var(--z-menu-v2-accent, var(--sidebar-accent))}.z-menu-v2-submenu-nested{margin-left:.75rem}.z-menu-v2-popover-tree{margin-top:0;margin-bottom:0}.z-menu-v2-popover-scrollbar{--scrollbar-padding: 0;--scrollbar-overscroll-behavior: contain;max-height:min(28rem,100vh - 8rem);min-height:0;overflow-x:hidden;overflow-y:auto}.z-menu-v2-popover-scroll-content{min-width:0}.z-menu-v2-arrow{transition:transform .2s cubic-bezier(.4,0,.2,1)}.z-menu-v2-arrow.expanded{transform:rotate(90deg)}.z-menu-v2-dot{display:inline-flex;width:.375rem;height:.375rem;flex-shrink:0;border-radius:9999px;background-color:color-mix(in oklab,var(--z-menu-v2-sidebar-foreground, var(--sidebar-foreground)) 58%,transparent)}.z-menu-v2-dot.small{width:.25rem;height:.25rem}.z-menu-v2-scrollbar{--scrollbar-padding: 0;max-width:100%}.z-menu-v2-scrollbar .ng-scroll-viewport,.z-menu-v2-scrollbar .ng-scroll-content{max-width:100%}.z-menu-v2-backdrop{animation:z-menu-v2-backdrop-enter .2s ease-out forwards}.z-menu-v2-backdrop-dark{background-color:#0009}.z-menu-v2-backdrop-blur{background-color:#0000000d;backdrop-filter:blur(2px)}.z-menu-v2-mobile-drawer{transform:translate(-100%);transition:transform .3s cubic-bezier(.32,.72,0,1);box-shadow:4px 0 24px #0000001a;will-change:transform}.z-menu-v2-mobile-drawer.open{transform:translate(0)}@keyframes z-menu-v2-backdrop-enter{0%{opacity:0}to{opacity:1}}\n"] }]
895
898
  }], ctorParameters: () => [], propDecorators: { zOnSelect: [{ type: i0.Output, args: ["zOnSelect"] }], zOnMenuAction: [{ type: i0.Output, args: ["zOnMenuAction"] }], zControl: [{ type: i0.Output, args: ["zControl"] }], zLogo: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLogo", required: false }] }], zLogoMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLogoMobile", required: false }] }], zMenus: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMenus", required: false }] }], zUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "zUser", required: false }] }], zUserActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "zUserActions", required: false }] }], zCurrentPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCurrentPath", required: false }] }], zKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "zKey", required: false }] }], zClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "zClass", required: false }] }], zTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTitle", required: false }] }], zCollapsedWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCollapsedWidth", required: false }] }], zExpandedWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "zExpandedWidth", required: false }] }], zExpandMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "zExpandMode", required: false }] }], zShowMobileBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowMobileBar", required: false }] }] } });
896
899
 
897
900
  /**