@shival99/z-ui 2.5.5 → 2.5.7

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.
@@ -95,26 +95,22 @@
95
95
  /*
96
96
  * Khoá scroll trang. Phải nằm NGOÀI `@layer base` để thắng rule `html { ... }` mà app khai báo
97
97
  * không-layer (rule trong layer luôn thua rule không-layer, bất kể specificity).
98
+ *
99
+ * `scrollbar-gutter: auto` nhả dải gutter mà `base.css` giữ sẵn, để overlay `fixed` bám được mép vật
100
+ * lý màn hình — nếu còn giữ gutter thì scrollport hẹp lại, trình duyệt clip mọi thứ vẽ ngoài nó, và
101
+ * thanh cuộn riêng của drawer bị đẩy thụt vào đúng bằng dải đó.
102
+ *
103
+ * Đổi lại chiều rộng layout tăng lên: `ZScrollLockService` bù `padding-right` vào body nên nội dung
104
+ * trong luồng (và cả `position: sticky`) đứng yên, riêng element `position: fixed` của app sẽ nhảy —
105
+ * dùng `--z-scroll-lock-gutter` để tự bù. Đây là cùng đánh đổi mà Reka UI / Nuxt UI / Radix đang chịu.
98
106
  */
99
107
  html.z-scroll-locked {
100
108
  overflow: hidden;
109
+ scrollbar-gutter: auto;
101
110
  }
102
111
 
103
112
  /*
104
- * Trang vốn đang dành chỗ cho scrollbar (scrollbar cổ điển hoặc `scrollbar-gutter: stable`) → giữ
105
- * nguyên đúng chỗ đó trong lúc khoá. Chiều rộng layout không đổi một pixel nào: không layout shift,
106
- * không nháy scrollbar khi mở/đóng overlay, và không phải bù `padding-right` cho body.
107
- *
108
- * Class chỉ được gắn khi đo được gutter thật, nên trang không có scrollbar (overlay scrollbar của
109
- * macOS, trang ngắn hơn viewport) không bị ép sinh ra một dải trống mới.
110
- */
111
- html.z-scroll-locked.z-scroll-locked-gutter {
112
- scrollbar-gutter: stable;
113
- }
114
-
115
- /*
116
- * Fallback cho trình duyệt không giữ được gutter (Safari < 18.4 chưa có `scrollbar-gutter`):
117
- * ZScrollLockService đo lại chiều rộng sau khi khoá, phần bị nhả ra được bù thẳng vào
113
+ * ZScrollLockService đo lại chiều rộng sau khi khoá; phần thật sự bị nhả ra được bù vào
118
114
  * `body.style.paddingRight` và ghi ra `--z-scroll-lock-gutter` để app bù tiếp cho element
119
- * `position: fixed` của riêng mình. Ở nhánh giữ được gutter, biến này luôn là `0px`.
115
+ * `position: fixed` của riêng mình.
120
116
  */
@@ -47,7 +47,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
47
47
  }]
48
48
  }], propDecorators: { zValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "zValue", required: false }] }] } });
49
49
 
50
- const zButtonGroupVariants = cva('inline-flex', {
50
+ const zButtonGroupVariants = cva('inline-flex h-fit', {
51
51
  variants: {
52
52
  zOrientation: {
53
53
  horizontal: [
@@ -1 +1 @@
1
- {"version":3,"file":"shival99-z-ui-components-z-button-group.mjs","sources":["../../../../libs/core-ui/components/z-button-group/z-button-group.define.ts","../../../../libs/core-ui/components/z-button-group/z-button-group-item.directive.ts","../../../../libs/core-ui/components/z-button-group/z-button-group.variants.ts","../../../../libs/core-ui/components/z-button-group/z-button-group-separator.component.ts","../../../../libs/core-ui/components/z-button-group/z-button-group.component.ts","../../../../libs/core-ui/components/z-button-group/shival99-z-ui-components-z-button-group.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport type { ZButtonGroupHost } from './z-button-group.types';\n\nexport const Z_BUTTON_GROUP = new InjectionToken<ZButtonGroupHost>('Z_BUTTON_GROUP');\n","import { computed, Directive, inject, input, signal } from '@angular/core';\nimport { Z_BUTTON_GROUP } from './z-button-group.define';\nimport type { ZButtonGroupValue } from './z-button-group.types';\n\n@Directive({\n selector: '[z-button-group-item]',\n standalone: true,\n host: {\n '[class.z-button-group-item-active]': 'isActive()',\n '(click)': 'onClick()',\n },\n exportAs: 'zButtonGroupItem',\n})\nexport class ZButtonGroupItemDirective {\n private readonly _group = inject(Z_BUTTON_GROUP, { optional: true });\n private readonly _index = signal<number>(-1);\n\n /** Khóa ổn định tùy chọn, ưu tiên hơn index khi xác định active. */\n public readonly zValue = input<ZButtonGroupValue>();\n\n private readonly _value = computed<ZButtonGroupValue>(() => this.zValue() ?? this._index());\n\n public readonly isActive = computed(() => {\n if (!this._group) {\n return false;\n }\n return this._group._isItemActive(this._value());\n });\n\n public readonly index = this._index.asReadonly();\n public _setIndex(index: number): void {\n this._index.set(index);\n }\n\n protected onClick(): void {\n if (!this._group) {\n return;\n }\n this._group._selectItem(this._value(), this._index());\n }\n}\n","import { cva } from 'class-variance-authority';\n\nexport const zButtonGroupVariants = cva('inline-flex', {\n variants: {\n zOrientation: {\n horizontal: [\n 'flex-row',\n 'items-center',\n // First child - only left border radius\n '[&>*:first-child]:rounded-r-none!',\n // Last child - only right border radius\n '[&>*:last-child]:rounded-l-none!',\n // Middle children - no border radius\n '[&>*:not(:first-child):not(:last-child)]:rounded-none!',\n // Remove double borders between buttons\n '[&>*:not(:first-child)]:border-l-0!',\n // Handle single child\n '[&>*:only-child]:rounded-lg!',\n '[&>*:only-child]:border-l!',\n // Active item styling - use primary color from theme\n '[&>*.z-button-group-item-active]:bg-primary',\n '[&>*.z-button-group-item-active]:text-primary-foreground',\n '[&>*.z-button-group-item-active]:border-primary',\n '[&>*.z-button-group-item-active]:z-[1]',\n ],\n vertical: [\n 'flex-col',\n 'items-stretch',\n // First child - only top border radius\n '[&>*:first-child]:rounded-b-none!',\n // Last child - only bottom border radius\n '[&>*:last-child]:rounded-t-none!',\n // Middle children - no border radius\n '[&>*:not(:first-child):not(:last-child)]:rounded-none!',\n // Remove double borders between buttons\n '[&>*:not(:first-child)]:border-t-0!',\n // Handle single child\n '[&>*:only-child]:rounded-lg!',\n '[&>*:only-child]:border-t!',\n // Active item styling - use primary color from theme\n '[&>*.z-button-group-item-active]:bg-primary',\n '[&>*.z-button-group-item-active]:text-primary-foreground',\n '[&>*.z-button-group-item-active]:border-primary',\n '[&>*.z-button-group-item-active]:z-[1]',\n ],\n },\n },\n defaultVariants: {\n zOrientation: 'horizontal',\n },\n});\n\nexport const zButtonGroupSeparatorVariants = cva('shrink-0 bg-border', {\n variants: {\n zOrientation: {\n horizontal: 'h-full w-px',\n vertical: 'w-full h-px',\n },\n },\n defaultVariants: {\n zOrientation: 'horizontal',\n },\n});\n","import { ChangeDetectionStrategy, Component, computed, input, ViewEncapsulation } from '@angular/core';\nimport { zMergeClasses } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport type { ZButtonGroupSeparatorVariants } from './z-button-group.types';\nimport { zButtonGroupSeparatorVariants } from './z-button-group.variants';\n\n@Component({\n selector: 'z-button-group-separator',\n standalone: true,\n template: ``,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'separator',\n '[class]': 'zClasses()',\n },\n exportAs: 'zButtonGroupSeparator',\n})\nexport class ZButtonGroupSeparatorComponent {\n public readonly zClass = input<ClassValue>('');\n public readonly zOrientation = input<ZButtonGroupSeparatorVariants['zOrientation']>('horizontal');\n\n protected readonly zClasses = computed(() =>\n zMergeClasses(\n zButtonGroupSeparatorVariants({\n zOrientation: this.zOrientation(),\n }),\n this.zClass()\n )\n );\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n effect,\n input,\n model,\n output,\n ViewEncapsulation,\n} from '@angular/core';\nimport { zMergeClasses } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport { ZButtonGroupItemDirective } from './z-button-group-item.directive';\nimport { Z_BUTTON_GROUP } from './z-button-group.define';\nimport { type ZButtonGroupHost, type ZButtonGroupValue, type ZButtonGroupVariants } from './z-button-group.types';\nimport { zButtonGroupVariants } from './z-button-group.variants';\n\n@Component({\n selector: 'z-button-group',\n standalone: true,\n template: `\n <ng-content />\n `,\n providers: [\n {\n provide: Z_BUTTON_GROUP,\n useExisting: ZButtonGroupComponent,\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'group',\n '[class]': 'zClasses()',\n },\n exportAs: 'zButtonGroup',\n})\nexport class ZButtonGroupComponent implements ZButtonGroupHost {\n public readonly zClass = input<ClassValue>('');\n public readonly zOrientation = input<ZButtonGroupVariants['zOrientation']>('horizontal');\n\n public readonly zActive = model<ZButtonGroupValue | null>(null);\n public readonly zActiveIndexChange = output<number | null>();\n public readonly zActiveValueChange = output<ZButtonGroupValue | null>();\n private readonly _items = contentChildren(ZButtonGroupItemDirective);\n\n protected readonly zClasses = computed(() =>\n zMergeClasses(\n zButtonGroupVariants({\n zOrientation: this.zOrientation(),\n }),\n this.zClass()\n )\n );\n\n constructor() {\n effect(() => {\n const items = this._items();\n items.forEach((item, index) => {\n item._setIndex(index);\n });\n });\n }\n\n public _selectItem(value: ZButtonGroupValue, index: number): void {\n const newValue = this.zActive() === value ? null : value;\n this.zActive.set(newValue);\n this.zActiveIndexChange.emit(newValue === null ? null : index);\n this.zActiveValueChange.emit(newValue);\n }\n\n public _isItemActive(value: ZButtonGroupValue): boolean {\n return this.zActive() === value;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shival99-z-ui-components-z-button-group.mjs","sources":["../../../../libs/core-ui/components/z-button-group/z-button-group.define.ts","../../../../libs/core-ui/components/z-button-group/z-button-group-item.directive.ts","../../../../libs/core-ui/components/z-button-group/z-button-group.variants.ts","../../../../libs/core-ui/components/z-button-group/z-button-group-separator.component.ts","../../../../libs/core-ui/components/z-button-group/z-button-group.component.ts","../../../../libs/core-ui/components/z-button-group/shival99-z-ui-components-z-button-group.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport type { ZButtonGroupHost } from './z-button-group.types';\n\nexport const Z_BUTTON_GROUP = new InjectionToken<ZButtonGroupHost>('Z_BUTTON_GROUP');\n","import { computed, Directive, inject, input, signal } from '@angular/core';\nimport { Z_BUTTON_GROUP } from './z-button-group.define';\nimport type { ZButtonGroupValue } from './z-button-group.types';\n\n@Directive({\n selector: '[z-button-group-item]',\n standalone: true,\n host: {\n '[class.z-button-group-item-active]': 'isActive()',\n '(click)': 'onClick()',\n },\n exportAs: 'zButtonGroupItem',\n})\nexport class ZButtonGroupItemDirective {\n private readonly _group = inject(Z_BUTTON_GROUP, { optional: true });\n private readonly _index = signal<number>(-1);\n\n /** Khóa ổn định tùy chọn, ưu tiên hơn index khi xác định active. */\n public readonly zValue = input<ZButtonGroupValue>();\n\n private readonly _value = computed<ZButtonGroupValue>(() => this.zValue() ?? this._index());\n\n public readonly isActive = computed(() => {\n if (!this._group) {\n return false;\n }\n return this._group._isItemActive(this._value());\n });\n\n public readonly index = this._index.asReadonly();\n public _setIndex(index: number): void {\n this._index.set(index);\n }\n\n protected onClick(): void {\n if (!this._group) {\n return;\n }\n this._group._selectItem(this._value(), this._index());\n }\n}\n","import { cva } from 'class-variance-authority';\n\nexport const zButtonGroupVariants = cva('inline-flex h-fit', {\n variants: {\n zOrientation: {\n horizontal: [\n 'flex-row',\n 'items-center',\n // First child - only left border radius\n '[&>*:first-child]:rounded-r-none!',\n // Last child - only right border radius\n '[&>*:last-child]:rounded-l-none!',\n // Middle children - no border radius\n '[&>*:not(:first-child):not(:last-child)]:rounded-none!',\n // Remove double borders between buttons\n '[&>*:not(:first-child)]:border-l-0!',\n // Handle single child\n '[&>*:only-child]:rounded-lg!',\n '[&>*:only-child]:border-l!',\n // Active item styling - use primary color from theme\n '[&>*.z-button-group-item-active]:bg-primary',\n '[&>*.z-button-group-item-active]:text-primary-foreground',\n '[&>*.z-button-group-item-active]:border-primary',\n '[&>*.z-button-group-item-active]:z-[1]',\n ],\n vertical: [\n 'flex-col',\n 'items-stretch',\n // First child - only top border radius\n '[&>*:first-child]:rounded-b-none!',\n // Last child - only bottom border radius\n '[&>*:last-child]:rounded-t-none!',\n // Middle children - no border radius\n '[&>*:not(:first-child):not(:last-child)]:rounded-none!',\n // Remove double borders between buttons\n '[&>*:not(:first-child)]:border-t-0!',\n // Handle single child\n '[&>*:only-child]:rounded-lg!',\n '[&>*:only-child]:border-t!',\n // Active item styling - use primary color from theme\n '[&>*.z-button-group-item-active]:bg-primary',\n '[&>*.z-button-group-item-active]:text-primary-foreground',\n '[&>*.z-button-group-item-active]:border-primary',\n '[&>*.z-button-group-item-active]:z-[1]',\n ],\n },\n },\n defaultVariants: {\n zOrientation: 'horizontal',\n },\n});\n\nexport const zButtonGroupSeparatorVariants = cva('shrink-0 bg-border', {\n variants: {\n zOrientation: {\n horizontal: 'h-full w-px',\n vertical: 'w-full h-px',\n },\n },\n defaultVariants: {\n zOrientation: 'horizontal',\n },\n});\n","import { ChangeDetectionStrategy, Component, computed, input, ViewEncapsulation } from '@angular/core';\nimport { zMergeClasses } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport type { ZButtonGroupSeparatorVariants } from './z-button-group.types';\nimport { zButtonGroupSeparatorVariants } from './z-button-group.variants';\n\n@Component({\n selector: 'z-button-group-separator',\n standalone: true,\n template: ``,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'separator',\n '[class]': 'zClasses()',\n },\n exportAs: 'zButtonGroupSeparator',\n})\nexport class ZButtonGroupSeparatorComponent {\n public readonly zClass = input<ClassValue>('');\n public readonly zOrientation = input<ZButtonGroupSeparatorVariants['zOrientation']>('horizontal');\n\n protected readonly zClasses = computed(() =>\n zMergeClasses(\n zButtonGroupSeparatorVariants({\n zOrientation: this.zOrientation(),\n }),\n this.zClass()\n )\n );\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n effect,\n input,\n model,\n output,\n ViewEncapsulation,\n} from '@angular/core';\nimport { zMergeClasses } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport { ZButtonGroupItemDirective } from './z-button-group-item.directive';\nimport { Z_BUTTON_GROUP } from './z-button-group.define';\nimport { type ZButtonGroupHost, type ZButtonGroupValue, type ZButtonGroupVariants } from './z-button-group.types';\nimport { zButtonGroupVariants } from './z-button-group.variants';\n\n@Component({\n selector: 'z-button-group',\n standalone: true,\n template: `\n <ng-content />\n `,\n providers: [\n {\n provide: Z_BUTTON_GROUP,\n useExisting: ZButtonGroupComponent,\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'group',\n '[class]': 'zClasses()',\n },\n exportAs: 'zButtonGroup',\n})\nexport class ZButtonGroupComponent implements ZButtonGroupHost {\n public readonly zClass = input<ClassValue>('');\n public readonly zOrientation = input<ZButtonGroupVariants['zOrientation']>('horizontal');\n\n public readonly zActive = model<ZButtonGroupValue | null>(null);\n public readonly zActiveIndexChange = output<number | null>();\n public readonly zActiveValueChange = output<ZButtonGroupValue | null>();\n private readonly _items = contentChildren(ZButtonGroupItemDirective);\n\n protected readonly zClasses = computed(() =>\n zMergeClasses(\n zButtonGroupVariants({\n zOrientation: this.zOrientation(),\n }),\n this.zClass()\n )\n );\n\n constructor() {\n effect(() => {\n const items = this._items();\n items.forEach((item, index) => {\n item._setIndex(index);\n });\n });\n }\n\n public _selectItem(value: ZButtonGroupValue, index: number): void {\n const newValue = this.zActive() === value ? null : value;\n this.zActive.set(newValue);\n this.zActiveIndexChange.emit(newValue === null ? null : index);\n this.zActiveValueChange.emit(newValue);\n }\n\n public _isItemActive(value: ZButtonGroupValue): boolean {\n return this.zActive() === value;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -425,7 +425,7 @@ class ZMenuComponent {
425
425
  return ZCacheService.get(this.zKey(), false) ?? false;
426
426
  }
427
427
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
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-sm\"\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-sm 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-sm\"\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-sm\" 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-sm 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-sm\"\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-sm 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-sm\"\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-sm 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-sm 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-sm 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-sm\"\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-sm 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:0 0 auto;min-width: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:none;will-change:auto}.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:auto;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);pointer-events:auto;will-change:transform;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{max-width:none;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;-webkit-backdrop-filter:blur(2px);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
+ 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-sm\"\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-sm 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-sm\"\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-sm\" 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-sm 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-sm\"\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-sm 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-sm\"\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-sm 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-sm 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-sm 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-sm\"\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-sm 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:0 0 auto;min-width: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:none;will-change:auto}.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(var(--sidebar-child-width) + 53px - 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:auto;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);pointer-events:auto;will-change:transform;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{max-width:none;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;-webkit-backdrop-filter:blur(2px);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 });
429
429
  }
430
430
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ZMenuComponent, decorators: [{
431
431
  type: Component,
@@ -444,7 +444,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
444
444
  '[class.z-menu-no-child]': 'selectedParentHasNoChild()',
445
445
  '[class.z-menu-mobile]': 'isMobile()',
446
446
  '[class.z-menu-mobile-open]': 'mobileMenuOpen()',
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-sm\"\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-sm 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-sm\"\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-sm\" 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-sm 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-sm\"\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-sm 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-sm\"\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-sm 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-sm 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-sm 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-sm\"\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-sm 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:0 0 auto;min-width: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:none;will-change:auto}.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:auto;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);pointer-events:auto;will-change:transform;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{max-width:none;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;-webkit-backdrop-filter:blur(2px);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-sm\"\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-sm 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-sm\"\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-sm\" 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-sm 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-sm\"\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-sm 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-sm\"\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-sm 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-sm 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-sm 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-sm\"\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-sm 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:0 0 auto;min-width: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:none;will-change:auto}.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(var(--sidebar-child-width) + 53px - 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:auto;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);pointer-events:auto;will-change:transform;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{max-width:none;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;-webkit-backdrop-filter:blur(2px);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"] }]
448
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 }] }] } });
449
449
 
450
450
  class ZMenuV2Component {