@shival99/z-ui 1.9.16 → 1.9.18

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.
Files changed (45) hide show
  1. package/fesm2022/shival99-z-ui-components-z-accordion.mjs +6 -6
  2. package/fesm2022/shival99-z-ui-components-z-autocomplete.mjs +21 -16
  3. package/fesm2022/shival99-z-ui-components-z-autocomplete.mjs.map +1 -1
  4. package/fesm2022/shival99-z-ui-components-z-breadcrumb.mjs +3 -3
  5. package/fesm2022/shival99-z-ui-components-z-button-group.mjs +9 -9
  6. package/fesm2022/shival99-z-ui-components-z-button.mjs +3 -3
  7. package/fesm2022/shival99-z-ui-components-z-calendar.mjs +42 -42
  8. package/fesm2022/shival99-z-ui-components-z-card.mjs +6 -6
  9. package/fesm2022/shival99-z-ui-components-z-chat.mjs +3 -3
  10. package/fesm2022/shival99-z-ui-components-z-checkbox.mjs +3 -3
  11. package/fesm2022/shival99-z-ui-components-z-code.mjs +3 -3
  12. package/fesm2022/shival99-z-ui-components-z-drawer.mjs +15 -15
  13. package/fesm2022/shival99-z-ui-components-z-dropdown-menu.mjs +3 -3
  14. package/fesm2022/shival99-z-ui-components-z-editor.mjs +3 -3
  15. package/fesm2022/shival99-z-ui-components-z-empty.mjs +3 -3
  16. package/fesm2022/shival99-z-ui-components-z-filter.mjs +27 -27
  17. package/fesm2022/shival99-z-ui-components-z-gallery.mjs +12 -12
  18. package/fesm2022/shival99-z-ui-components-z-icon.mjs +3 -3
  19. package/fesm2022/shival99-z-ui-components-z-input.mjs +4 -4
  20. package/fesm2022/shival99-z-ui-components-z-input.mjs.map +1 -1
  21. package/fesm2022/shival99-z-ui-components-z-kanban.mjs +3 -3
  22. package/fesm2022/shival99-z-ui-components-z-loading.mjs +3 -3
  23. package/fesm2022/shival99-z-ui-components-z-menu.mjs +3 -3
  24. package/fesm2022/shival99-z-ui-components-z-modal.mjs +15 -15
  25. package/fesm2022/shival99-z-ui-components-z-pagination.mjs +3 -3
  26. package/fesm2022/shival99-z-ui-components-z-popover.mjs +9 -9
  27. package/fesm2022/shival99-z-ui-components-z-radio.mjs +3 -3
  28. package/fesm2022/shival99-z-ui-components-z-select.mjs +20 -20
  29. package/fesm2022/shival99-z-ui-components-z-select.mjs.map +1 -1
  30. package/fesm2022/shival99-z-ui-components-z-skeleton-auto.mjs +3 -3
  31. package/fesm2022/shival99-z-ui-components-z-skeleton.mjs +3 -3
  32. package/fesm2022/shival99-z-ui-components-z-steps.mjs +3 -3
  33. package/fesm2022/shival99-z-ui-components-z-switch.mjs +3 -3
  34. package/fesm2022/shival99-z-ui-components-z-table.mjs +72 -72
  35. package/fesm2022/shival99-z-ui-components-z-tabs.mjs +6 -6
  36. package/fesm2022/shival99-z-ui-components-z-tags.mjs +12 -12
  37. package/fesm2022/shival99-z-ui-components-z-timeline.mjs +3 -3
  38. package/fesm2022/shival99-z-ui-components-z-toast.mjs +6 -6
  39. package/fesm2022/shival99-z-ui-components-z-tooltip.mjs +6 -6
  40. package/fesm2022/shival99-z-ui-components-z-upload.mjs +3 -3
  41. package/fesm2022/shival99-z-ui-pipes.mjs +18 -18
  42. package/fesm2022/shival99-z-ui-services.mjs +24 -24
  43. package/package.json +2 -1
  44. package/types/shival99-z-ui-components-z-autocomplete.d.ts +2 -1
  45. package/types/shival99-z-ui-providers.d.ts +2 -2
@@ -947,10 +947,10 @@ class ZKanbanComponent {
947
947
  }
948
948
  return `${prefix}-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
949
949
  }
950
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZKanbanComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
951
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ZKanbanComponent, isStandalone: true, selector: "z-kanban", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zColumns: { classPropertyName: "zColumns", publicName: "zColumns", isSignal: true, isRequired: false, transformFunction: null }, zTitle: { classPropertyName: "zTitle", publicName: "zTitle", isSignal: true, isRequired: false, transformFunction: null }, zSubtitle: { classPropertyName: "zSubtitle", publicName: "zSubtitle", isSignal: true, isRequired: false, transformFunction: null }, zSearch: { classPropertyName: "zSearch", publicName: "zSearch", isSignal: true, isRequired: false, transformFunction: null }, zShowToolbar: { classPropertyName: "zShowToolbar", publicName: "zShowToolbar", isSignal: true, isRequired: false, transformFunction: null }, zAllowCreateTask: { classPropertyName: "zAllowCreateTask", publicName: "zAllowCreateTask", isSignal: true, isRequired: false, transformFunction: null }, zDisabled: { classPropertyName: "zDisabled", publicName: "zDisabled", isSignal: true, isRequired: false, transformFunction: null }, zDensity: { classPropertyName: "zDensity", publicName: "zDensity", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zTaskDrop: "zTaskDrop", zTaskSave: "zTaskSave", zTaskClick: "zTaskClick", zTaskCreate: "zTaskCreate", zColumns: "zColumnsChange", zSearch: "zSearchChange" }, host: { properties: { "class": "hostClasses()" } }, viewQueries: [{ propertyName: "boardViewportRef", first: true, predicate: ["boardViewport"], descendants: true, isSignal: true }], exportAs: ["zKanban"], ngImport: i0, template: "<div class=\"flex h-full min-h-0 min-w-0 flex-col gap-5\">\n @if (zShowToolbar()) {\n <header class=\"flex flex-col gap-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n <h2 class=\"text-foreground truncate text-xl font-bold\">{{ zTitle() | translate }}</h2>\n <p class=\"text-muted-foreground text-sm\">{{ zSubtitle() | translate }}</p>\n </div>\n\n <div class=\"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center\">\n <z-input\n class=\"w-full sm:w-80\"\n zSize=\"sm\"\n [zSearch]=\"true\"\n [zDebounce]=\"200\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_search_placeholder' | translate\"\n [ngModel]=\"zSearch()\"\n (zOnSearch)=\"onBoardSearchChange($event)\" />\n\n @if (zAllowCreateTask()) {\n <z-button zType=\"outline\" zSize=\"sm\" zTypeIcon=\"lucidePlus\" (click)=\"createTaskInFirstColumn()\">\n {{ 'i18n_z_ui_common_add' | translate }}\n </z-button>\n }\n </div>\n </header>\n }\n\n @if (isSearchActive()) {\n <p class=\"text-muted-foreground text-xs\">\n {{ 'i18n_z_ui_kanban_drag_disabled_while_search' | translate }}\n </p>\n }\n\n <div #boardViewport class=\"z-kanban-board min-h-0 flex-1 overflow-x-auto pb-2\">\n <div class=\"flex h-full min-h-[25rem] min-w-max items-stretch gap-4\">\n @for (column of boardColumnsView(); track column.id) {\n <section [class]=\"columnClass()\">\n <header class=\"mb-2 flex items-center justify-between gap-2 px-0.5\">\n <div class=\"flex min-w-0 items-center gap-2\">\n <h3 class=\"text-foreground truncate text-xs font-bold tracking-wide uppercase\">\n {{ column.title | translate }}\n </h3>\n <span\n class=\"bg-muted text-muted-foreground inline-flex min-w-5 items-center justify-center rounded-full px-1.5 py-0.5 text-[10px] font-bold\">\n {{ column.taskCount }}\n </span>\n </div>\n\n @if (zAllowCreateTask()) {\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground inline-flex size-7 cursor-pointer items-center justify-center rounded-md transition-colors\"\n (click)=\"createTask(column.id)\">\n <z-icon zType=\"lucidePlus\" zSize=\"16\" />\n </button>\n }\n </header>\n\n <div\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.rawTasks\"\n [cdkDropListConnectedTo]=\"connectedDropListIds()\"\n [cdkDropListDisabled]=\"zDisabled() || isSearchActive()\"\n class=\"kanban-drop-list -mr-1 flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto p-0.5 pr-1\"\n (cdkDropListDropped)=\"onTaskDrop($event, column.id)\">\n @if (column.taskCount === 0) {\n <div\n class=\"border-border/70 text-muted-foreground flex h-24 items-center justify-center rounded-lg border border-dashed px-3 text-center text-xs\">\n @if (isSearchActive()) {\n {{ 'i18n_z_ui_kanban_no_matches' | translate }}\n } @else {\n {{ 'i18n_z_ui_kanban_drop_here' | translate }}\n }\n </div>\n }\n\n @for (task of column.tasks; track task.id) {\n <article\n cdkDrag\n cdkDragPreviewClass=\"z-kanban-drag-preview\"\n cdkDragPlaceholderClass=\"z-kanban-drag-placeholder\"\n [cdkDragData]=\"{ columnId: column.id, taskId: task.id }\"\n [cdkDragDisabled]=\"zDisabled() || isSearchActive()\"\n [class]=\"'kanban-card shrink-0 ' + task.taskCardClass\"\n (cdkDragStarted)=\"onTaskDragStarted()\"\n (cdkDragMoved)=\"onTaskDragMoved($event)\"\n (cdkDragEnded)=\"onTaskDragEnded($event)\"\n (click)=\"onTaskCardClick(column.id, task.id)\">\n <div class=\"flex items-start justify-between gap-2\">\n <div class=\"min-w-0 space-y-1\">\n @if (task.code) {\n <p class=\"text-muted-foreground text-[10px] font-semibold tracking-wide uppercase\">\n {{ task.code }}\n </p>\n }\n <h4 class=\"line-clamp-2 text-sm leading-5 font-semibold\">{{ task.title }}</h4>\n </div>\n\n <button\n cdkDragHandle\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground inline-flex size-6 shrink-0 cursor-grab items-center justify-center rounded-md transition-colors\"\n (click)=\"onTaskHandleClick($event)\">\n <z-icon zType=\"lucideGripVertical\" zSize=\"14\" />\n </button>\n </div>\n\n <div class=\"flex items-center gap-2\">\n <span [class]=\"task.priorityBadgeClass\">\n {{ task.priorityLabelKey | translate }}\n </span>\n @if (task.completed) {\n <span class=\"inline-flex items-center gap-1 text-[11px] font-semibold text-emerald-500\">\n <z-icon zType=\"lucideCircleCheck\" zSize=\"12\" />\n {{ 'i18n_z_ui_kanban_done' | translate }}\n </span>\n }\n </div>\n\n @if (task.descriptionPreview) {\n <p class=\"text-muted-foreground line-clamp-3 text-xs leading-4\">{{ task.descriptionPreview }}</p>\n }\n\n <div class=\"text-muted-foreground flex flex-wrap items-center gap-3 text-[11px]\">\n @if (task.dueDateLabel) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucideCalendar\" zSize=\"12\" />\n {{ task.dueDateLabel }}\n </span>\n }\n\n @if (task.commentsCount > 0) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucideMessageSquare\" zSize=\"12\" />\n {{ task.commentsCount }}\n </span>\n }\n\n @if (task.attachmentCount > 0) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucidePaperclip\" zSize=\"12\" />\n {{ task.attachmentCount }}\n </span>\n }\n\n @if (task.checklistCount > 0) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucideListChecks\" zSize=\"12\" />\n {{ task.checklistDoneCount }}/{{ task.checklistCount }}\n </span>\n }\n </div>\n\n <footer class=\"flex items-center justify-between gap-2\">\n <div class=\"flex -space-x-2\">\n @for (assignee of task.visibleAssignees; track assignee.name) {\n <span\n z-tooltip\n zAlwaysShow\n zPosition=\"top\"\n [zContent]=\"assignee.name\"\n class=\"relative inline-flex size-6 items-center justify-center rounded-full text-[10px] font-bold\"\n [class]=\"assignee.className\"\n [style.zIndex]=\"assignee.zIndex\">\n {{ assignee.initials }}\n </span>\n }\n @if (task.hiddenAssigneesCount > 0) {\n <span\n z-tooltip\n zAlwaysShow\n zPosition=\"top\"\n [zContent]=\"task.hiddenAssigneesLabel\"\n class=\"bg-muted text-muted-foreground border-background relative inline-flex size-6 items-center justify-center rounded-full border text-[10px] font-bold shadow-xs\"\n [style.zIndex]=\"20\">\n +{{ task.hiddenAssigneesCount }}\n </span>\n }\n </div>\n\n <z-icon zType=\"lucideChevronRight\" zSize=\"14\" class=\"text-muted-foreground\" />\n </footer>\n </article>\n }\n </div>\n </section>\n }\n </div>\n </div>\n</div>\n\n<z-modal\n [zVisible]=\"editorVisible()\"\n zTitle=\"i18n_z_ui_kanban_editor_title\"\n [zDescription]=\"editorMeta()\"\n [zOkText]=\"'i18n_z_ui_common_save' | translate\"\n [zCancelText]=\"'i18n_z_ui_common_cancel' | translate\"\n zWidth=\"min(96vw, 72rem)\"\n zOverlay=\"blur\"\n [zOkDisabled]=\"isEditorSaveDisabled()\"\n (zVisibleChange)=\"onEditorVisibleChange($event)\"\n (zAfterClose)=\"onEditorAfterClose()\"\n (zOk)=\"saveTaskChanges()\"\n (zCancel)=\"closeEditor()\">\n @if (activeTask()) {\n <div class=\"grid gap-6 xl:grid-cols-[minmax(0,1fr)_20rem]\">\n <div class=\"space-y-5\">\n <section class=\"space-y-2\">\n <z-input\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_title' | translate\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_title_placeholder' | translate\"\n [zRequired]=\"true\"\n [ngModel]=\"draftTitle()\"\n (ngModelChange)=\"draftTitle.set($event)\" />\n </section>\n\n <section class=\"space-y-2\">\n <z-editor\n zSize=\"sm\"\n [zLabel]=\"'i18n_z_ui_kanban_description' | translate\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_description_placeholder' | translate\"\n [ngModel]=\"draftDescription()\"\n (ngModelChange)=\"draftDescription.set($event)\" />\n </section>\n\n <section class=\"grid gap-3 md:grid-cols-2\">\n <ng-template #statusSelectedTpl let-option>\n <span class=\"inline-flex min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"statusIconClassByValue()[option.value] + ' shrink-0'\" />\n <span class=\"truncate\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <ng-template #statusOptionTpl let-option let-selected=\"selected\">\n <span class=\"inline-flex w-full min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"statusIconClassByValue()[option.value] + ' shrink-0'\" />\n <span class=\"truncate\" [class.font-medium]=\"selected\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <ng-template #prioritySelectedTpl let-option>\n <span class=\"inline-flex min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"priorityIconClassByValue[option.value] + ' shrink-0'\" />\n <span class=\"truncate\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <ng-template #priorityOptionTpl let-option let-selected=\"selected\">\n <span class=\"inline-flex w-full min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"priorityIconClassByValue[option.value] + ' shrink-0'\" />\n <span class=\"truncate\" [class.font-medium]=\"selected\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <z-select\n class=\"w-full\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_status' | translate\"\n [zAllowClear]=\"false\"\n [zOptions]=\"statusOptions()\"\n [zSelectedTemplate]=\"statusSelectedTpl\"\n [zOptionTemplate]=\"statusOptionTpl\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_status_placeholder' | translate\"\n [ngModel]=\"draftStatus()\"\n (ngModelChange)=\"onEditorStatusChange($event)\" />\n\n <z-select\n class=\"w-full\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_priority' | translate\"\n [zAllowClear]=\"false\"\n [zOptions]=\"prioritySelectOptions()\"\n [zSelectedTemplate]=\"prioritySelectedTpl\"\n [zOptionTemplate]=\"priorityOptionTpl\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_priority_placeholder' | translate\"\n [ngModel]=\"draftPriority()\"\n (ngModelChange)=\"onEditorPriorityChange($event)\" />\n\n <z-select\n class=\"w-full md:col-span-2\"\n zMode=\"tags\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_assignees' | translate\"\n [zAllowClear]=\"true\"\n [zOptions]=\"assigneeOptions()\"\n [zMaxTagCount]=\"5\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_assignees_select_placeholder' | translate\"\n [ngModel]=\"draftAssignees()\"\n (ngModelChange)=\"onEditorAssigneesChange($event)\" />\n\n <z-calendar\n zMode=\"single\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_start_date' | translate\"\n zAllowClear\n zValueType=\"date\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_start_date' | translate\"\n [ngModel]=\"draftStartDate()\"\n (ngModelChange)=\"onEditorStartDateChange($event)\" />\n\n <z-calendar\n zMode=\"single\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_end_date' | translate\"\n zAllowClear\n zValueType=\"date\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_end_date' | translate\"\n [ngModel]=\"draftEndDate()\"\n (ngModelChange)=\"onEditorEndDateChange($event)\" />\n </section>\n\n <section class=\"space-y-3\">\n <div class=\"flex items-center justify-between gap-2\">\n <h4 class=\"text-sm font-semibold\">\n {{ 'i18n_z_ui_kanban_checklist' | translate }} ({{ checklistDoneCount() }}/{{ draftChecklist().length }})\n </h4>\n <span class=\"text-muted-foreground text-xs font-semibold\">{{ checklistProgress() }}%</span>\n </div>\n\n <div class=\"bg-muted h-2 w-full rounded-full\">\n <div class=\"bg-primary h-2 rounded-full transition-all\" [style.width.%]=\"checklistProgress()\"></div>\n </div>\n\n <div class=\"max-h-44 space-y-1 overflow-y-auto\">\n @for (item of draftChecklist(); track item.id) {\n <div [class]=\"item.done ? checklistDoneRowClass : checklistPendingRowClass\">\n <z-checkbox\n [class]=\"item.done ? 'min-w-0 flex-1 line-through' : 'min-w-0 flex-1'\"\n [zChecked]=\"item.done\"\n [zText]=\"item.label\"\n (zChange)=\"toggleChecklistItem(item.id, $event)\" />\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:text-destructive hover:bg-destructive/10 ml-auto inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded transition-colors\"\n (click)=\"removeChecklistItem(item.id)\">\n <z-icon zType=\"lucideTrash2\" zSize=\"12\" />\n </button>\n </div>\n } @empty {\n <p class=\"text-muted-foreground bg-muted/35 rounded-md px-3 py-2 text-xs\">\n {{ 'i18n_z_ui_kanban_no_checklist_items' | translate }}\n </p>\n }\n </div>\n\n <div class=\"flex items-end gap-2\">\n <z-input\n class=\"flex-1\"\n zSize=\"lg\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_checklist_add_placeholder' | translate\"\n [ngModel]=\"draftChecklistItemLabel()\"\n (ngModelChange)=\"draftChecklistItemLabel.set($event)\"\n (zOnEnter)=\"addChecklistItem()\" />\n <button\n type=\"button\"\n zSize=\"lg\"\n z-button\n zType=\"outline\"\n zTypeIcon=\"lucidePlus\"\n (click)=\"addChecklistItem()\">\n {{ 'i18n_z_ui_common_add' | translate }}\n </button>\n </div>\n </section>\n\n <section class=\"space-y-2\">\n <z-upload\n [zLabel]=\"'i18n_z_ui_kanban_attachments' | translate\"\n [zNote]=\"'i18n_z_ui_kanban_attachments_note' | translate\"\n [zMultipleFile]=\"true\"\n [zShowProgress]=\"true\"\n [ngModel]=\"draftAttachments()\"\n (ngModelChange)=\"onDraftAttachmentsChange($event)\" />\n </section>\n </div>\n\n <aside\n class=\"bg-muted/25 border-border/70 flex h-[34rem] min-h-0 flex-col overflow-hidden rounded-lg border p-4 shadow-xs xl:h-[38rem]\">\n <section class=\"flex min-h-0 flex-1 flex-col gap-1.5\">\n <label class=\"text-muted-foreground text-[11px] font-semibold tracking-widest uppercase\">\n {{ 'i18n_z_ui_kanban_activity' | translate }}\n </label>\n <div class=\"-mr-3 min-h-0 flex-1 space-y-2 overflow-y-auto pr-3 pb-2\">\n @for (entry of activeTaskActivityView(); track entry.id) {\n <div class=\"border-border/70 bg-background/60 rounded-md border px-3 py-2\">\n <p class=\"text-xs font-semibold\">{{ entry.actor }}</p>\n <p class=\"text-muted-foreground mt-1 text-xs leading-4\">{{ entry.action }}</p>\n <p class=\"text-muted-foreground mt-1 text-[10px]\">{{ entry.createdAtLabel }}</p>\n </div>\n } @empty {\n <p class=\"text-muted-foreground bg-muted/40 rounded-md px-3 py-2 text-xs\">\n {{ 'i18n_z_ui_kanban_no_activity' | translate }}\n </p>\n }\n </div>\n </section>\n\n <section class=\"border-border/70 mt-3 shrink-0 space-y-2 border-t pt-3\">\n <z-input\n zType=\"textarea\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_add_comment' | translate\"\n [zRows]=\"3\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_comment_placeholder' | translate\"\n [ngModel]=\"draftComment()\"\n (ngModelChange)=\"draftComment.set($event)\" />\n\n <div class=\"flex justify-end pt-2\">\n <button\n type=\"button\"\n zTypeIcon=\"lucideSend\"\n z-button\n [disabled]=\"isCommentSubmitDisabled()\"\n (click)=\"submitTaskComment()\">\n {{ 'i18n_z_ui_kanban_comment_submit' | translate }}\n </button>\n </div>\n </section>\n </aside>\n </div>\n }\n</z-modal>\n", styles: [":host{display:block;height:100%;min-height:0}.z-kanban-board{overscroll-behavior-x:contain;scrollbar-width:thin;scrollbar-color:color-mix(in oklab,var(--muted-foreground) 45%,transparent) transparent}.z-kanban-board::-webkit-scrollbar{height:8px}.z-kanban-board::-webkit-scrollbar-thumb{background:color-mix(in oklab,var(--muted-foreground) 38%,transparent);border-radius:9999px}.z-kanban-board::-webkit-scrollbar-track{background:transparent}.kanban-drop-list{scrollbar-width:thin}.kanban-card{cursor:pointer}.kanban-card.cdk-drag-dragging{cursor:grabbing;transform:rotate(.35deg)}.kanban-drop-list.cdk-drop-list-dragging .kanban-card:not(.cdk-drag-placeholder){transition:transform .16s cubic-bezier(.2,0,0,1)}:host ::ng-deep .z-kanban-drag-preview{border:1px solid color-mix(in oklab,var(--primary) 35%,var(--border));box-shadow:0 14px 32px color-mix(in oklab,var(--foreground) 15%,transparent);transform:rotate(-.2deg)}:host ::ng-deep .z-kanban-drag-placeholder{opacity:.2;border:1px dashed color-mix(in oklab,var(--primary) 38%,var(--border));background:color-mix(in oklab,var(--primary) 8%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZCalendarComponent, selector: "z-calendar", inputs: ["class", "zMode", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zShowTime", "zTimeFormat", "zShowHour", "zShowMinute", "zShowSecond", "zQuickSelect", "zAllowClear", "zFormat", "zMinDate", "zMaxDate", "zValueType", "zValidators", "zShowOk", "zOkText", "zShowCancel", "zCancelText", "zDisabledDate", "zScrollClose", "zDefaultTime", "zRangeDefaultTime"], outputs: ["zControl", "zChange", "zOnBlur", "zOnFocus", "zEvent"], exportAs: ["zCalendar"] }, { kind: "component", type: ZCheckboxComponent, selector: "z-checkbox", inputs: ["class", "zType", "zSize", "zLabel", "zText", "zDisabled", "zIndeterminate", "zValue", "zOptions", "zOrientation", "zCheckAll", "zCheckAllText", "zChecked", "zGroupValue"], outputs: ["zChange", "zGroupChange", "zOnBlur", "zOnFocus", "zControl", "zEvent", "zCheckedChange", "zGroupValueChange"] }, { kind: "component", type: ZEditorComponent, selector: "z-editor", inputs: ["class", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zModules", "zFormats", "zBounds", "zTheme", "zValidators"], outputs: ["zOnChange", "zOnFocus", "zOnBlur", "zControl", "zEvent"], exportAs: ["zEditor"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "component", type: ZInputComponent, selector: "z-input", inputs: ["class", "zType", "zSize", "zAlign", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zPrefix", "zSuffix", "zMin", "zMax", "zStep", "zShowArrows", "zMask", "zDecimalPlaces", "zAllowNegative", "zThousandSeparator", "zDecimalMarker", "zValidators", "zAsyncValidators", "zAsyncDebounce", "zAsyncValidateOn", "zShowPasswordToggle", "zSearch", "zDebounce", "zAutofocus", "zAutoComplete", "zAllowClear", "zAutoSizeContent", "zRows", "zResize", "zMaxLength", "zAutoSuggest", "zColorConfig"], outputs: ["zOnSearch", "zOnChange", "zOnBlur", "zOnFocus", "zOnKeydown", "zOnEnter", "zOnColorCollapse", "zControl", "zEvent"], exportAs: ["zInput"] }, { kind: "component", type: ZModalComponent, selector: "z-modal", inputs: ["class", "zVisible", "zTitle", "zDescription", "zWidth", "zClosable", "zMaskClosable", "zHideHeader", "zHideFooter", "zOkText", "zCancelText", "zOkDestructive", "zOkDisabled", "zLoading", "zContentLoading", "zSkeletonRows", "zOverlay"], outputs: ["zOk", "zCancel", "zAfterClose", "zScrollbar", "zVisibleChange"], exportAs: ["zModal"] }, { kind: "component", type: ZSelectComponent, selector: "z-select", inputs: ["class", "zMode", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zLoading", "zPrefix", "zAllowClear", "zWrap", "zShowSearch", "zPlaceholderSearch", "zDebounce", "zNotFoundText", "zEmptyText", "zEmptyIcon", "zMaxTagCount", "zDropdownMaxHeight", "zOptionHeight", "zVirtualScroll", "zShowAction", "zOptions", "zTranslateLabels", "zKey", "zSearchServer", "zLoadingMore", "zEnableLoadMore", "zScrollDistance", "zMaxVisible", "zScrollClose", "zPosition", "zSelectedTemplate", "zOptionTemplate", "zActionTemplate", "zAsyncValidators", "zAsyncDebounce", "zAsyncValidateOn", "zValidators"], outputs: ["zOnSearch", "zOnLoadMore", "zOnBlur", "zOnFocus", "zControl", "zEvent"], exportAs: ["zSelect"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTrigger", "zTooltipType", "zTooltipSize", "zClass", "zShowDelay", "zHideDelay", "zArrow", "zDisabled", "zOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "component", type: ZUploadComponent, selector: "z-upload", inputs: ["class", "zLabel", "zLabelClass", "zNote", "zSize", "zAcceptFile", "zMultipleFile", "zMaxSize", "zMaxFiles", "zRequired", "zDisabled", "zReadonly", "zLoading", "zShowProgress", "zValidators"], outputs: ["zOnUpload", "zOnRemove", "zOnDownload", "zOnError", "zOnFileChange", "zOnDragover", "zOnDragleave", "zOnDrop", "zControl", "zEvent"], exportAs: ["zUpload"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
950
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZKanbanComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
951
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZKanbanComponent, isStandalone: true, selector: "z-kanban", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zColumns: { classPropertyName: "zColumns", publicName: "zColumns", isSignal: true, isRequired: false, transformFunction: null }, zTitle: { classPropertyName: "zTitle", publicName: "zTitle", isSignal: true, isRequired: false, transformFunction: null }, zSubtitle: { classPropertyName: "zSubtitle", publicName: "zSubtitle", isSignal: true, isRequired: false, transformFunction: null }, zSearch: { classPropertyName: "zSearch", publicName: "zSearch", isSignal: true, isRequired: false, transformFunction: null }, zShowToolbar: { classPropertyName: "zShowToolbar", publicName: "zShowToolbar", isSignal: true, isRequired: false, transformFunction: null }, zAllowCreateTask: { classPropertyName: "zAllowCreateTask", publicName: "zAllowCreateTask", isSignal: true, isRequired: false, transformFunction: null }, zDisabled: { classPropertyName: "zDisabled", publicName: "zDisabled", isSignal: true, isRequired: false, transformFunction: null }, zDensity: { classPropertyName: "zDensity", publicName: "zDensity", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zTaskDrop: "zTaskDrop", zTaskSave: "zTaskSave", zTaskClick: "zTaskClick", zTaskCreate: "zTaskCreate", zColumns: "zColumnsChange", zSearch: "zSearchChange" }, host: { properties: { "class": "hostClasses()" } }, viewQueries: [{ propertyName: "boardViewportRef", first: true, predicate: ["boardViewport"], descendants: true, isSignal: true }], exportAs: ["zKanban"], ngImport: i0, template: "<div class=\"flex h-full min-h-0 min-w-0 flex-col gap-5\">\n @if (zShowToolbar()) {\n <header class=\"flex flex-col gap-3 md:flex-row md:items-center md:justify-between\">\n <div class=\"min-w-0\">\n <h2 class=\"text-foreground truncate text-xl font-bold\">{{ zTitle() | translate }}</h2>\n <p class=\"text-muted-foreground text-sm\">{{ zSubtitle() | translate }}</p>\n </div>\n\n <div class=\"flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center\">\n <z-input\n class=\"w-full sm:w-80\"\n zSize=\"sm\"\n [zSearch]=\"true\"\n [zDebounce]=\"200\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_search_placeholder' | translate\"\n [ngModel]=\"zSearch()\"\n (zOnSearch)=\"onBoardSearchChange($event)\" />\n\n @if (zAllowCreateTask()) {\n <z-button zType=\"outline\" zSize=\"sm\" zTypeIcon=\"lucidePlus\" (click)=\"createTaskInFirstColumn()\">\n {{ 'i18n_z_ui_common_add' | translate }}\n </z-button>\n }\n </div>\n </header>\n }\n\n @if (isSearchActive()) {\n <p class=\"text-muted-foreground text-xs\">\n {{ 'i18n_z_ui_kanban_drag_disabled_while_search' | translate }}\n </p>\n }\n\n <div #boardViewport class=\"z-kanban-board min-h-0 flex-1 overflow-x-auto pb-2\">\n <div class=\"flex h-full min-h-[25rem] min-w-max items-stretch gap-4\">\n @for (column of boardColumnsView(); track column.id) {\n <section [class]=\"columnClass()\">\n <header class=\"mb-2 flex items-center justify-between gap-2 px-0.5\">\n <div class=\"flex min-w-0 items-center gap-2\">\n <h3 class=\"text-foreground truncate text-xs font-bold tracking-wide uppercase\">\n {{ column.title | translate }}\n </h3>\n <span\n class=\"bg-muted text-muted-foreground inline-flex min-w-5 items-center justify-center rounded-full px-1.5 py-0.5 text-[10px] font-bold\">\n {{ column.taskCount }}\n </span>\n </div>\n\n @if (zAllowCreateTask()) {\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground inline-flex size-7 cursor-pointer items-center justify-center rounded-md transition-colors\"\n (click)=\"createTask(column.id)\">\n <z-icon zType=\"lucidePlus\" zSize=\"16\" />\n </button>\n }\n </header>\n\n <div\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.rawTasks\"\n [cdkDropListConnectedTo]=\"connectedDropListIds()\"\n [cdkDropListDisabled]=\"zDisabled() || isSearchActive()\"\n class=\"kanban-drop-list -mr-1 flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto p-0.5 pr-1\"\n (cdkDropListDropped)=\"onTaskDrop($event, column.id)\">\n @if (column.taskCount === 0) {\n <div\n class=\"border-border/70 text-muted-foreground flex h-24 items-center justify-center rounded-lg border border-dashed px-3 text-center text-xs\">\n @if (isSearchActive()) {\n {{ 'i18n_z_ui_kanban_no_matches' | translate }}\n } @else {\n {{ 'i18n_z_ui_kanban_drop_here' | translate }}\n }\n </div>\n }\n\n @for (task of column.tasks; track task.id) {\n <article\n cdkDrag\n cdkDragPreviewClass=\"z-kanban-drag-preview\"\n cdkDragPlaceholderClass=\"z-kanban-drag-placeholder\"\n [cdkDragData]=\"{ columnId: column.id, taskId: task.id }\"\n [cdkDragDisabled]=\"zDisabled() || isSearchActive()\"\n [class]=\"'kanban-card shrink-0 ' + task.taskCardClass\"\n (cdkDragStarted)=\"onTaskDragStarted()\"\n (cdkDragMoved)=\"onTaskDragMoved($event)\"\n (cdkDragEnded)=\"onTaskDragEnded($event)\"\n (click)=\"onTaskCardClick(column.id, task.id)\">\n <div class=\"flex items-start justify-between gap-2\">\n <div class=\"min-w-0 space-y-1\">\n @if (task.code) {\n <p class=\"text-muted-foreground text-[10px] font-semibold tracking-wide uppercase\">\n {{ task.code }}\n </p>\n }\n <h4 class=\"line-clamp-2 text-sm leading-5 font-semibold\">{{ task.title }}</h4>\n </div>\n\n <button\n cdkDragHandle\n type=\"button\"\n class=\"text-muted-foreground hover:bg-muted hover:text-foreground inline-flex size-6 shrink-0 cursor-grab items-center justify-center rounded-md transition-colors\"\n (click)=\"onTaskHandleClick($event)\">\n <z-icon zType=\"lucideGripVertical\" zSize=\"14\" />\n </button>\n </div>\n\n <div class=\"flex items-center gap-2\">\n <span [class]=\"task.priorityBadgeClass\">\n {{ task.priorityLabelKey | translate }}\n </span>\n @if (task.completed) {\n <span class=\"inline-flex items-center gap-1 text-[11px] font-semibold text-emerald-500\">\n <z-icon zType=\"lucideCircleCheck\" zSize=\"12\" />\n {{ 'i18n_z_ui_kanban_done' | translate }}\n </span>\n }\n </div>\n\n @if (task.descriptionPreview) {\n <p class=\"text-muted-foreground line-clamp-3 text-xs leading-4\">{{ task.descriptionPreview }}</p>\n }\n\n <div class=\"text-muted-foreground flex flex-wrap items-center gap-3 text-[11px]\">\n @if (task.dueDateLabel) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucideCalendar\" zSize=\"12\" />\n {{ task.dueDateLabel }}\n </span>\n }\n\n @if (task.commentsCount > 0) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucideMessageSquare\" zSize=\"12\" />\n {{ task.commentsCount }}\n </span>\n }\n\n @if (task.attachmentCount > 0) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucidePaperclip\" zSize=\"12\" />\n {{ task.attachmentCount }}\n </span>\n }\n\n @if (task.checklistCount > 0) {\n <span class=\"inline-flex items-center gap-1\">\n <z-icon zType=\"lucideListChecks\" zSize=\"12\" />\n {{ task.checklistDoneCount }}/{{ task.checklistCount }}\n </span>\n }\n </div>\n\n <footer class=\"flex items-center justify-between gap-2\">\n <div class=\"flex -space-x-2\">\n @for (assignee of task.visibleAssignees; track assignee.name) {\n <span\n z-tooltip\n zAlwaysShow\n zPosition=\"top\"\n [zContent]=\"assignee.name\"\n class=\"relative inline-flex size-6 items-center justify-center rounded-full text-[10px] font-bold\"\n [class]=\"assignee.className\"\n [style.zIndex]=\"assignee.zIndex\">\n {{ assignee.initials }}\n </span>\n }\n @if (task.hiddenAssigneesCount > 0) {\n <span\n z-tooltip\n zAlwaysShow\n zPosition=\"top\"\n [zContent]=\"task.hiddenAssigneesLabel\"\n class=\"bg-muted text-muted-foreground border-background relative inline-flex size-6 items-center justify-center rounded-full border text-[10px] font-bold shadow-xs\"\n [style.zIndex]=\"20\">\n +{{ task.hiddenAssigneesCount }}\n </span>\n }\n </div>\n\n <z-icon zType=\"lucideChevronRight\" zSize=\"14\" class=\"text-muted-foreground\" />\n </footer>\n </article>\n }\n </div>\n </section>\n }\n </div>\n </div>\n</div>\n\n<z-modal\n [zVisible]=\"editorVisible()\"\n zTitle=\"i18n_z_ui_kanban_editor_title\"\n [zDescription]=\"editorMeta()\"\n [zOkText]=\"'i18n_z_ui_common_save' | translate\"\n [zCancelText]=\"'i18n_z_ui_common_cancel' | translate\"\n zWidth=\"min(96vw, 72rem)\"\n zOverlay=\"blur\"\n [zOkDisabled]=\"isEditorSaveDisabled()\"\n (zVisibleChange)=\"onEditorVisibleChange($event)\"\n (zAfterClose)=\"onEditorAfterClose()\"\n (zOk)=\"saveTaskChanges()\"\n (zCancel)=\"closeEditor()\">\n @if (activeTask()) {\n <div class=\"grid gap-6 xl:grid-cols-[minmax(0,1fr)_20rem]\">\n <div class=\"space-y-5\">\n <section class=\"space-y-2\">\n <z-input\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_title' | translate\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_title_placeholder' | translate\"\n [zRequired]=\"true\"\n [ngModel]=\"draftTitle()\"\n (ngModelChange)=\"draftTitle.set($event)\" />\n </section>\n\n <section class=\"space-y-2\">\n <z-editor\n zSize=\"sm\"\n [zLabel]=\"'i18n_z_ui_kanban_description' | translate\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_description_placeholder' | translate\"\n [ngModel]=\"draftDescription()\"\n (ngModelChange)=\"draftDescription.set($event)\" />\n </section>\n\n <section class=\"grid gap-3 md:grid-cols-2\">\n <ng-template #statusSelectedTpl let-option>\n <span class=\"inline-flex min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"statusIconClassByValue()[option.value] + ' shrink-0'\" />\n <span class=\"truncate\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <ng-template #statusOptionTpl let-option let-selected=\"selected\">\n <span class=\"inline-flex w-full min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"statusIconClassByValue()[option.value] + ' shrink-0'\" />\n <span class=\"truncate\" [class.font-medium]=\"selected\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <ng-template #prioritySelectedTpl let-option>\n <span class=\"inline-flex min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"priorityIconClassByValue[option.value] + ' shrink-0'\" />\n <span class=\"truncate\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <ng-template #priorityOptionTpl let-option let-selected=\"selected\">\n <span class=\"inline-flex w-full min-w-0 items-center gap-2\">\n <z-icon\n [zType]=\"option.icon || 'lucideCircleDot'\"\n zSize=\"14\"\n [class]=\"priorityIconClassByValue[option.value] + ' shrink-0'\" />\n <span class=\"truncate\" [class.font-medium]=\"selected\">{{ option.label }}</span>\n </span>\n </ng-template>\n\n <z-select\n class=\"w-full\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_status' | translate\"\n [zAllowClear]=\"false\"\n [zOptions]=\"statusOptions()\"\n [zSelectedTemplate]=\"statusSelectedTpl\"\n [zOptionTemplate]=\"statusOptionTpl\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_status_placeholder' | translate\"\n [ngModel]=\"draftStatus()\"\n (ngModelChange)=\"onEditorStatusChange($event)\" />\n\n <z-select\n class=\"w-full\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_priority' | translate\"\n [zAllowClear]=\"false\"\n [zOptions]=\"prioritySelectOptions()\"\n [zSelectedTemplate]=\"prioritySelectedTpl\"\n [zOptionTemplate]=\"priorityOptionTpl\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_priority_placeholder' | translate\"\n [ngModel]=\"draftPriority()\"\n (ngModelChange)=\"onEditorPriorityChange($event)\" />\n\n <z-select\n class=\"w-full md:col-span-2\"\n zMode=\"tags\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_assignees' | translate\"\n [zAllowClear]=\"true\"\n [zOptions]=\"assigneeOptions()\"\n [zMaxTagCount]=\"5\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_assignees_select_placeholder' | translate\"\n [ngModel]=\"draftAssignees()\"\n (ngModelChange)=\"onEditorAssigneesChange($event)\" />\n\n <z-calendar\n zMode=\"single\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_start_date' | translate\"\n zAllowClear\n zValueType=\"date\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_start_date' | translate\"\n [ngModel]=\"draftStartDate()\"\n (ngModelChange)=\"onEditorStartDateChange($event)\" />\n\n <z-calendar\n zMode=\"single\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_end_date' | translate\"\n zAllowClear\n zValueType=\"date\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_end_date' | translate\"\n [ngModel]=\"draftEndDate()\"\n (ngModelChange)=\"onEditorEndDateChange($event)\" />\n </section>\n\n <section class=\"space-y-3\">\n <div class=\"flex items-center justify-between gap-2\">\n <h4 class=\"text-sm font-semibold\">\n {{ 'i18n_z_ui_kanban_checklist' | translate }} ({{ checklistDoneCount() }}/{{ draftChecklist().length }})\n </h4>\n <span class=\"text-muted-foreground text-xs font-semibold\">{{ checklistProgress() }}%</span>\n </div>\n\n <div class=\"bg-muted h-2 w-full rounded-full\">\n <div class=\"bg-primary h-2 rounded-full transition-all\" [style.width.%]=\"checklistProgress()\"></div>\n </div>\n\n <div class=\"max-h-44 space-y-1 overflow-y-auto\">\n @for (item of draftChecklist(); track item.id) {\n <div [class]=\"item.done ? checklistDoneRowClass : checklistPendingRowClass\">\n <z-checkbox\n [class]=\"item.done ? 'min-w-0 flex-1 line-through' : 'min-w-0 flex-1'\"\n [zChecked]=\"item.done\"\n [zText]=\"item.label\"\n (zChange)=\"toggleChecklistItem(item.id, $event)\" />\n <button\n type=\"button\"\n class=\"text-muted-foreground hover:text-destructive hover:bg-destructive/10 ml-auto inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded transition-colors\"\n (click)=\"removeChecklistItem(item.id)\">\n <z-icon zType=\"lucideTrash2\" zSize=\"12\" />\n </button>\n </div>\n } @empty {\n <p class=\"text-muted-foreground bg-muted/35 rounded-md px-3 py-2 text-xs\">\n {{ 'i18n_z_ui_kanban_no_checklist_items' | translate }}\n </p>\n }\n </div>\n\n <div class=\"flex items-end gap-2\">\n <z-input\n class=\"flex-1\"\n zSize=\"lg\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_checklist_add_placeholder' | translate\"\n [ngModel]=\"draftChecklistItemLabel()\"\n (ngModelChange)=\"draftChecklistItemLabel.set($event)\"\n (zOnEnter)=\"addChecklistItem()\" />\n <button\n type=\"button\"\n zSize=\"lg\"\n z-button\n zType=\"outline\"\n zTypeIcon=\"lucidePlus\"\n (click)=\"addChecklistItem()\">\n {{ 'i18n_z_ui_common_add' | translate }}\n </button>\n </div>\n </section>\n\n <section class=\"space-y-2\">\n <z-upload\n [zLabel]=\"'i18n_z_ui_kanban_attachments' | translate\"\n [zNote]=\"'i18n_z_ui_kanban_attachments_note' | translate\"\n [zMultipleFile]=\"true\"\n [zShowProgress]=\"true\"\n [ngModel]=\"draftAttachments()\"\n (ngModelChange)=\"onDraftAttachmentsChange($event)\" />\n </section>\n </div>\n\n <aside\n class=\"bg-muted/25 border-border/70 flex h-[34rem] min-h-0 flex-col overflow-hidden rounded-lg border p-4 shadow-xs xl:h-[38rem]\">\n <section class=\"flex min-h-0 flex-1 flex-col gap-1.5\">\n <label class=\"text-muted-foreground text-[11px] font-semibold tracking-widest uppercase\">\n {{ 'i18n_z_ui_kanban_activity' | translate }}\n </label>\n <div class=\"-mr-3 min-h-0 flex-1 space-y-2 overflow-y-auto pr-3 pb-2\">\n @for (entry of activeTaskActivityView(); track entry.id) {\n <div class=\"border-border/70 bg-background/60 rounded-md border px-3 py-2\">\n <p class=\"text-xs font-semibold\">{{ entry.actor }}</p>\n <p class=\"text-muted-foreground mt-1 text-xs leading-4\">{{ entry.action }}</p>\n <p class=\"text-muted-foreground mt-1 text-[10px]\">{{ entry.createdAtLabel }}</p>\n </div>\n } @empty {\n <p class=\"text-muted-foreground bg-muted/40 rounded-md px-3 py-2 text-xs\">\n {{ 'i18n_z_ui_kanban_no_activity' | translate }}\n </p>\n }\n </div>\n </section>\n\n <section class=\"border-border/70 mt-3 shrink-0 space-y-2 border-t pt-3\">\n <z-input\n zType=\"textarea\"\n zSize=\"lg\"\n [zLabel]=\"'i18n_z_ui_kanban_add_comment' | translate\"\n [zRows]=\"3\"\n [zPlaceholder]=\"'i18n_z_ui_kanban_comment_placeholder' | translate\"\n [ngModel]=\"draftComment()\"\n (ngModelChange)=\"draftComment.set($event)\" />\n\n <div class=\"flex justify-end pt-2\">\n <button\n type=\"button\"\n zTypeIcon=\"lucideSend\"\n z-button\n [disabled]=\"isCommentSubmitDisabled()\"\n (click)=\"submitTaskComment()\">\n {{ 'i18n_z_ui_kanban_comment_submit' | translate }}\n </button>\n </div>\n </section>\n </aside>\n </div>\n }\n</z-modal>\n", styles: [":host{display:block;height:100%;min-height:0}.z-kanban-board{overscroll-behavior-x:contain;scrollbar-width:thin;scrollbar-color:color-mix(in oklab,var(--muted-foreground) 45%,transparent) transparent}.z-kanban-board::-webkit-scrollbar{height:8px}.z-kanban-board::-webkit-scrollbar-thumb{background:color-mix(in oklab,var(--muted-foreground) 38%,transparent);border-radius:9999px}.z-kanban-board::-webkit-scrollbar-track{background:transparent}.kanban-drop-list{scrollbar-width:thin}.kanban-card{cursor:pointer}.kanban-card.cdk-drag-dragging{cursor:grabbing;transform:rotate(.35deg)}.kanban-drop-list.cdk-drop-list-dragging .kanban-card:not(.cdk-drag-placeholder){transition:transform .16s cubic-bezier(.2,0,0,1)}:host ::ng-deep .z-kanban-drag-preview{border:1px solid color-mix(in oklab,var(--primary) 35%,var(--border));box-shadow:0 14px 32px color-mix(in oklab,var(--foreground) 15%,transparent);transform:rotate(-.2deg)}:host ::ng-deep .z-kanban-drag-placeholder{opacity:.2;border:1px dashed color-mix(in oklab,var(--primary) 38%,var(--border));background:color-mix(in oklab,var(--primary) 8%,transparent)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZCalendarComponent, selector: "z-calendar", inputs: ["class", "zMode", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zShowTime", "zTimeFormat", "zShowHour", "zShowMinute", "zShowSecond", "zQuickSelect", "zAllowClear", "zFormat", "zMinDate", "zMaxDate", "zValueType", "zValidators", "zShowOk", "zOkText", "zShowCancel", "zCancelText", "zDisabledDate", "zScrollClose", "zDefaultTime", "zRangeDefaultTime"], outputs: ["zControl", "zChange", "zOnBlur", "zOnFocus", "zEvent"], exportAs: ["zCalendar"] }, { kind: "component", type: ZCheckboxComponent, selector: "z-checkbox", inputs: ["class", "zType", "zSize", "zLabel", "zText", "zDisabled", "zIndeterminate", "zValue", "zOptions", "zOrientation", "zCheckAll", "zCheckAllText", "zChecked", "zGroupValue"], outputs: ["zChange", "zGroupChange", "zOnBlur", "zOnFocus", "zControl", "zEvent", "zCheckedChange", "zGroupValueChange"] }, { kind: "component", type: ZEditorComponent, selector: "z-editor", inputs: ["class", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zModules", "zFormats", "zBounds", "zTheme", "zValidators"], outputs: ["zOnChange", "zOnFocus", "zOnBlur", "zControl", "zEvent"], exportAs: ["zEditor"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "component", type: ZInputComponent, selector: "z-input", inputs: ["class", "zType", "zSize", "zAlign", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zPrefix", "zSuffix", "zMin", "zMax", "zStep", "zShowArrows", "zMask", "zDecimalPlaces", "zAllowNegative", "zThousandSeparator", "zDecimalMarker", "zValidators", "zAsyncValidators", "zAsyncDebounce", "zAsyncValidateOn", "zShowPasswordToggle", "zSearch", "zDebounce", "zAutofocus", "zAutoComplete", "zAllowClear", "zAutoSizeContent", "zRows", "zResize", "zMaxLength", "zAutoSuggest", "zColorConfig"], outputs: ["zOnSearch", "zOnChange", "zOnBlur", "zOnFocus", "zOnKeydown", "zOnEnter", "zOnColorCollapse", "zControl", "zEvent"], exportAs: ["zInput"] }, { kind: "component", type: ZModalComponent, selector: "z-modal", inputs: ["class", "zVisible", "zTitle", "zDescription", "zWidth", "zClosable", "zMaskClosable", "zHideHeader", "zHideFooter", "zOkText", "zCancelText", "zOkDestructive", "zOkDisabled", "zLoading", "zContentLoading", "zSkeletonRows", "zOverlay"], outputs: ["zOk", "zCancel", "zAfterClose", "zScrollbar", "zVisibleChange"], exportAs: ["zModal"] }, { kind: "component", type: ZSelectComponent, selector: "z-select", inputs: ["class", "zMode", "zSize", "zLabel", "zLabelClass", "zPlaceholder", "zRequired", "zDisabled", "zReadonly", "zLoading", "zPrefix", "zAllowClear", "zWrap", "zShowSearch", "zPlaceholderSearch", "zDebounce", "zNotFoundText", "zEmptyText", "zEmptyIcon", "zMaxTagCount", "zDropdownMaxHeight", "zOptionHeight", "zVirtualScroll", "zShowAction", "zOptions", "zTranslateLabels", "zKey", "zSearchServer", "zLoadingMore", "zEnableLoadMore", "zScrollDistance", "zMaxVisible", "zScrollClose", "zPosition", "zSelectedTemplate", "zOptionTemplate", "zActionTemplate", "zAsyncValidators", "zAsyncDebounce", "zAsyncValidateOn", "zValidators"], outputs: ["zOnSearch", "zOnLoadMore", "zOnBlur", "zOnFocus", "zControl", "zEvent"], exportAs: ["zSelect"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTrigger", "zTooltipType", "zTooltipSize", "zClass", "zShowDelay", "zHideDelay", "zArrow", "zDisabled", "zOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "component", type: ZUploadComponent, selector: "z-upload", inputs: ["class", "zLabel", "zLabelClass", "zNote", "zSize", "zAcceptFile", "zMultipleFile", "zMaxSize", "zMaxFiles", "zRequired", "zDisabled", "zReadonly", "zLoading", "zShowProgress", "zValidators"], outputs: ["zOnUpload", "zOnRemove", "zOnDownload", "zOnError", "zOnFileChange", "zOnDragover", "zOnDragleave", "zOnDrop", "zControl", "zEvent"], exportAs: ["zUpload"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
952
952
  }
953
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZKanbanComponent, decorators: [{
953
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZKanbanComponent, decorators: [{
954
954
  type: Component,
955
955
  args: [{ selector: 'z-kanban', imports: [
956
956
  FormsModule,
@@ -87,10 +87,10 @@ class ZLoadingComponent {
87
87
  this.isLeaving.set(false);
88
88
  }, 100);
89
89
  }
90
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
91
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ZLoadingComponent, isStandalone: true, selector: "z-loading", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zSpinner: { classPropertyName: "zSpinner", publicName: "zSpinner", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zColor: { classPropertyName: "zColor", publicName: "zColor", isSignal: true, isRequired: false, transformFunction: null }, zText: { classPropertyName: "zText", publicName: "zText", isSignal: true, isRequired: false, transformFunction: null }, zOverlay: { classPropertyName: "zOverlay", publicName: "zOverlay", isSignal: true, isRequired: false, transformFunction: null }, zOverlayType: { classPropertyName: "zOverlayType", publicName: "zOverlayType", isSignal: true, isRequired: false, transformFunction: null }, zFullscreen: { classPropertyName: "zFullscreen", publicName: "zFullscreen", isSignal: true, isRequired: false, transformFunction: null }, zLoading: { classPropertyName: "zLoading", publicName: "zLoading", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "z-loading inline-flex" }, ngImport: i0, template: "@if (!zOverlay() && !zFullscreen()) {\n <div\n class=\"z-loading-wrapper inline-flex items-center justify-center transition-opacity duration-150\"\n [class.opacity-0]=\"!zLoading()\"\n [class.pointer-events-none]=\"!zLoading()\">\n <ng-container *ngTemplateOutlet=\"spinnerContent\" />\n </div>\n}\n\n@if ((zOverlay() || zFullscreen()) && isVisible()) {\n <div\n class=\"z-loading-wrapper inline-flex items-center justify-center\"\n [class.z-loading-overlay]=\"zOverlay()\"\n [class.z-loading-fullscreen]=\"zFullscreen()\"\n [class.z-loading-leaving]=\"isLeaving()\"\n [class]=\"overlayClasses()\">\n <ng-container *ngTemplateOutlet=\"spinnerContent\" />\n </div>\n}\n\n<ng-template #spinnerContent>\n <div class=\"z-loading-content flex flex-col items-center justify-center gap-3\">\n @switch (zSpinner()) {\n @case ('spinner') {\n <svg [class]=\"spinnerClasses()\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n }\n @case ('orbit') {\n <div [class]=\"spinnerClasses()\" class=\"z-loading-orbit relative\">\n <div class=\"absolute top-1/2 left-0 h-2 w-2 -translate-y-1/2 rounded-full bg-current\"></div>\n <div class=\"absolute top-1/2 right-0 h-2 w-2 -translate-y-1/2 rounded-full bg-current opacity-30\"></div>\n </div>\n }\n @case ('matrix') {\n <div [class]=\"baseClasses()\" class=\"z-loading-matrix\"></div>\n }\n @case ('conic') {\n <div [class]=\"baseClasses()\" class=\"z-loading-conic rounded-full\"></div>\n }\n @case ('polygon') {\n <div [class]=\"baseClasses()\" class=\"z-loading-polygon rounded-full\"></div>\n }\n @case ('triple') {\n <div [class]=\"baseClasses()\" class=\"z-loading-triple rounded-full\"></div>\n }\n }\n\n @if (zText()) {\n <p [class]=\"textSizeClasses()\" class=\"z-loading-text font-medium\" [style.color]=\"'currentColor'\">\n {{ zText() }}\n </p>\n }\n </div>\n</ng-template>\n", styles: [".z-loading:has(.z-loading-overlay),.z-loading:has(.z-loading-fullscreen){display:contents}.z-loading-overlay,.z-loading-fullscreen{position:absolute;inset:0;z-index:150;display:flex;align-items:center;justify-content:center}.z-loading-fullscreen{position:fixed;z-index:9999}.z-loading-overlay-dark{background-color:#0009;animation:z-backdrop-enter .15s ease-out forwards}.z-loading-overlay-blur{background-color:#0000000d;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);animation:z-backdrop-enter .15s ease-out forwards}.z-loading-overlay-default{background-color:var(--loading-overlay-bg, rgba(255, 255, 255, .85));animation:z-backdrop-enter .15s ease-out forwards}.dark .z-loading-overlay-default{background-color:#000000d9}.z-loading-leaving.z-loading-overlay-dark,.z-loading-leaving.z-loading-overlay-blur,.z-loading-leaving.z-loading-overlay-default{animation:z-backdrop-exit .12s ease-in forwards}.z-loading-content{position:relative;z-index:51}.z-loading-orbit{animation:z-loading-spin 1.2s linear infinite}.z-loading-matrix{width:1.5rem;height:1.3125rem;background:linear-gradient(transparent 16.6666666667%,currentColor 0 50%,transparent 0),linear-gradient(transparent 33.3333333333%,currentColor 0 66.6666666667%,transparent 0),linear-gradient(transparent 50%,currentColor 0 83.3333333333%,transparent 0);background-size:6px 400%;background-repeat:no-repeat;animation:z-loading-matrix 1s infinite linear}.z-loading-matrix.size-8{width:2rem;height:1.75rem;background-size:8px 400%}.z-loading-matrix.size-12{width:3rem;height:2.625rem;background-size:12px 400%}.z-loading-conic{padding:.5rem;aspect-ratio:1;background:currentColor;-webkit-mask:conic-gradient(transparent 10%,#000),linear-gradient(#000 0 0) content-box;mask:conic-gradient(transparent 10%,#000),linear-gradient(#000 0 0) content-box;-webkit-mask-composite:source-out;mask-composite:subtract;animation:z-loading-conic 1s infinite linear}.z-loading-polygon{aspect-ratio:1;border:8px solid currentColor;animation:z-loading-polygon-1 .8s infinite linear alternate,z-loading-polygon-2 1.6s infinite linear}.z-loading-triple{aspect-ratio:1;border:8px solid transparent;border-right-color:currentColor;position:relative;animation:z-loading-triple 1s infinite linear}.z-loading-triple:before,.z-loading-triple:after{content:\"\";position:absolute;inset:-.5rem;border-radius:50%;border:inherit;animation:inherit}.z-loading-triple:before{animation-duration:2s;opacity:.6}.z-loading-triple:after{animation-duration:4s;opacity:.3}@keyframes z-loading-matrix{0%{background-position:0% 100%,50% 100%,100% 100%}to{background-position:0% 0%,50% 0%,100% 0%}}@keyframes z-loading-conic{to{transform:rotate(1turn)}}@keyframes z-loading-polygon-1{0%{clip-path:polygon(50% 50%,0 0,50% 0%,50% 0%,50% 0%,50% 0%,50% 0%)}12.5%{clip-path:polygon(50% 50%,0 0,50% 0%,100% 0%,100% 0%,100% 0%,100% 0%)}25%{clip-path:polygon(50% 50%,0 0,50% 0%,100% 0%,100% 100%,100% 100%,100% 100%)}50%{clip-path:polygon(50% 50%,0 0,50% 0%,100% 0%,100% 100%,50% 100%,0% 100%)}62.5%{clip-path:polygon(50% 50%,100% 0,100% 0%,100% 0%,100% 100%,50% 100%,0% 100%)}75%{clip-path:polygon(50% 50%,100% 100%,100% 100%,100% 100%,100% 100%,50% 100%,0% 100%)}to{clip-path:polygon(50% 50%,50% 100%,50% 100%,50% 100%,50% 100%,50% 100%,0% 100%)}}@keyframes z-loading-polygon-2{0%{transform:scaleY(1) rotate(0)}49.99%{transform:scaleY(1) rotate(135deg)}50%{transform:scaleY(-1) rotate(0)}to{transform:scaleY(-1) rotate(-135deg)}}@keyframes z-loading-triple{to{transform:rotate(1turn)}}@keyframes z-loading-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
90
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
91
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZLoadingComponent, isStandalone: true, selector: "z-loading", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zSpinner: { classPropertyName: "zSpinner", publicName: "zSpinner", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zColor: { classPropertyName: "zColor", publicName: "zColor", isSignal: true, isRequired: false, transformFunction: null }, zText: { classPropertyName: "zText", publicName: "zText", isSignal: true, isRequired: false, transformFunction: null }, zOverlay: { classPropertyName: "zOverlay", publicName: "zOverlay", isSignal: true, isRequired: false, transformFunction: null }, zOverlayType: { classPropertyName: "zOverlayType", publicName: "zOverlayType", isSignal: true, isRequired: false, transformFunction: null }, zFullscreen: { classPropertyName: "zFullscreen", publicName: "zFullscreen", isSignal: true, isRequired: false, transformFunction: null }, zLoading: { classPropertyName: "zLoading", publicName: "zLoading", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "z-loading inline-flex" }, ngImport: i0, template: "@if (!zOverlay() && !zFullscreen()) {\n <div\n class=\"z-loading-wrapper inline-flex items-center justify-center transition-opacity duration-150\"\n [class.opacity-0]=\"!zLoading()\"\n [class.pointer-events-none]=\"!zLoading()\">\n <ng-container *ngTemplateOutlet=\"spinnerContent\" />\n </div>\n}\n\n@if ((zOverlay() || zFullscreen()) && isVisible()) {\n <div\n class=\"z-loading-wrapper inline-flex items-center justify-center\"\n [class.z-loading-overlay]=\"zOverlay()\"\n [class.z-loading-fullscreen]=\"zFullscreen()\"\n [class.z-loading-leaving]=\"isLeaving()\"\n [class]=\"overlayClasses()\">\n <ng-container *ngTemplateOutlet=\"spinnerContent\" />\n </div>\n}\n\n<ng-template #spinnerContent>\n <div class=\"z-loading-content flex flex-col items-center justify-center gap-3\">\n @switch (zSpinner()) {\n @case ('spinner') {\n <svg [class]=\"spinnerClasses()\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\" />\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\" />\n </svg>\n }\n @case ('orbit') {\n <div [class]=\"spinnerClasses()\" class=\"z-loading-orbit relative\">\n <div class=\"absolute top-1/2 left-0 h-2 w-2 -translate-y-1/2 rounded-full bg-current\"></div>\n <div class=\"absolute top-1/2 right-0 h-2 w-2 -translate-y-1/2 rounded-full bg-current opacity-30\"></div>\n </div>\n }\n @case ('matrix') {\n <div [class]=\"baseClasses()\" class=\"z-loading-matrix\"></div>\n }\n @case ('conic') {\n <div [class]=\"baseClasses()\" class=\"z-loading-conic rounded-full\"></div>\n }\n @case ('polygon') {\n <div [class]=\"baseClasses()\" class=\"z-loading-polygon rounded-full\"></div>\n }\n @case ('triple') {\n <div [class]=\"baseClasses()\" class=\"z-loading-triple rounded-full\"></div>\n }\n }\n\n @if (zText()) {\n <p [class]=\"textSizeClasses()\" class=\"z-loading-text font-medium\" [style.color]=\"'currentColor'\">\n {{ zText() }}\n </p>\n }\n </div>\n</ng-template>\n", styles: [".z-loading:has(.z-loading-overlay),.z-loading:has(.z-loading-fullscreen){display:contents}.z-loading-overlay,.z-loading-fullscreen{position:absolute;inset:0;z-index:150;display:flex;align-items:center;justify-content:center}.z-loading-fullscreen{position:fixed;z-index:9999}.z-loading-overlay-dark{background-color:#0009;animation:z-backdrop-enter .15s ease-out forwards}.z-loading-overlay-blur{background-color:#0000000d;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);animation:z-backdrop-enter .15s ease-out forwards}.z-loading-overlay-default{background-color:var(--loading-overlay-bg, rgba(255, 255, 255, .85));animation:z-backdrop-enter .15s ease-out forwards}.dark .z-loading-overlay-default{background-color:#000000d9}.z-loading-leaving.z-loading-overlay-dark,.z-loading-leaving.z-loading-overlay-blur,.z-loading-leaving.z-loading-overlay-default{animation:z-backdrop-exit .12s ease-in forwards}.z-loading-content{position:relative;z-index:51}.z-loading-orbit{animation:z-loading-spin 1.2s linear infinite}.z-loading-matrix{width:1.5rem;height:1.3125rem;background:linear-gradient(transparent 16.6666666667%,currentColor 0 50%,transparent 0),linear-gradient(transparent 33.3333333333%,currentColor 0 66.6666666667%,transparent 0),linear-gradient(transparent 50%,currentColor 0 83.3333333333%,transparent 0);background-size:6px 400%;background-repeat:no-repeat;animation:z-loading-matrix 1s infinite linear}.z-loading-matrix.size-8{width:2rem;height:1.75rem;background-size:8px 400%}.z-loading-matrix.size-12{width:3rem;height:2.625rem;background-size:12px 400%}.z-loading-conic{padding:.5rem;aspect-ratio:1;background:currentColor;-webkit-mask:conic-gradient(transparent 10%,#000),linear-gradient(#000 0 0) content-box;mask:conic-gradient(transparent 10%,#000),linear-gradient(#000 0 0) content-box;-webkit-mask-composite:source-out;mask-composite:subtract;animation:z-loading-conic 1s infinite linear}.z-loading-polygon{aspect-ratio:1;border:8px solid currentColor;animation:z-loading-polygon-1 .8s infinite linear alternate,z-loading-polygon-2 1.6s infinite linear}.z-loading-triple{aspect-ratio:1;border:8px solid transparent;border-right-color:currentColor;position:relative;animation:z-loading-triple 1s infinite linear}.z-loading-triple:before,.z-loading-triple:after{content:\"\";position:absolute;inset:-.5rem;border-radius:50%;border:inherit;animation:inherit}.z-loading-triple:before{animation-duration:2s;opacity:.6}.z-loading-triple:after{animation-duration:4s;opacity:.3}@keyframes z-loading-matrix{0%{background-position:0% 100%,50% 100%,100% 100%}to{background-position:0% 0%,50% 0%,100% 0%}}@keyframes z-loading-conic{to{transform:rotate(1turn)}}@keyframes z-loading-polygon-1{0%{clip-path:polygon(50% 50%,0 0,50% 0%,50% 0%,50% 0%,50% 0%,50% 0%)}12.5%{clip-path:polygon(50% 50%,0 0,50% 0%,100% 0%,100% 0%,100% 0%,100% 0%)}25%{clip-path:polygon(50% 50%,0 0,50% 0%,100% 0%,100% 100%,100% 100%,100% 100%)}50%{clip-path:polygon(50% 50%,0 0,50% 0%,100% 0%,100% 100%,50% 100%,0% 100%)}62.5%{clip-path:polygon(50% 50%,100% 0,100% 0%,100% 0%,100% 100%,50% 100%,0% 100%)}75%{clip-path:polygon(50% 50%,100% 100%,100% 100%,100% 100%,100% 100%,50% 100%,0% 100%)}to{clip-path:polygon(50% 50%,50% 100%,50% 100%,50% 100%,50% 100%,50% 100%,0% 100%)}}@keyframes z-loading-polygon-2{0%{transform:scaleY(1) rotate(0)}49.99%{transform:scaleY(1) rotate(135deg)}50%{transform:scaleY(-1) rotate(0)}to{transform:scaleY(-1) rotate(-135deg)}}@keyframes z-loading-triple{to{transform:rotate(1turn)}}@keyframes z-loading-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
92
92
  }
93
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZLoadingComponent, decorators: [{
93
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZLoadingComponent, decorators: [{
94
94
  type: Component,
95
95
  args: [{ selector: 'z-loading', imports: [CommonModule, NgTemplateOutlet], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
96
96
  class: 'z-loading inline-flex',
@@ -391,10 +391,10 @@ class ZMenuComponent {
391
391
  _getStateMenuCollapsed() {
392
392
  return ZCacheService.get(this.zKey(), false) ?? false;
393
393
  }
394
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
395
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.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-[0.375rem] border\"></div>\n\n <div class=\"bg-sidebar text-sidebar-foreground absolute inset-px z-20 flex flex-col rounded-[0.375rem]\">\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-[0.375rem]\"\n (click)=\"toggleSidebar()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"20\" class=\"opacity-70\" />\n </div>\n }\n\n <div class=\"flex flex-1 flex-col items-center gap-2 p-2\">\n @for (item of menuParents(); track item.id) {\n @let hasActiveChild = parentWithActiveChild()?.id === item.id;\n @let isCurrentlySelected = selectedParent()?.id === item.id;\n @let showActiveIndicator = hasActiveChild && !isCurrentlySelected;\n <div\n zTooltip\n [zContent]=\"item.name | translate\"\n zPosition=\"right\"\n [zArrow]=\"false\"\n [zAlwaysShow]=\"true\"\n class=\"relative flex h-9 w-9 cursor-pointer items-center justify-center rounded-[0.375rem] select-none\"\n [class.bg-sidebar-primary]=\"selectedParent()?.id === item.id\"\n [class.text-sidebar-primary-foreground]=\"selectedParent()?.id === item.id\"\n [class.hover:bg-sidebar-accent]=\"selectedParent()?.id !== item.id\"\n (click)=\"onDesktopParentClick(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon\" zSize=\"20\" />\n } @else {\n <z-icon [zSvg]=\"item.iconSvg || ''\" zSize=\"20\" />\n }\n @if (showActiveIndicator) {\n <div\n class=\"bg-sidebar-primary absolute top-1/2 -left-[0.3125rem] h-4 w-1 -translate-y-1/2 rounded-full\"></div>\n }\n </div>\n }\n </div>\n\n <div class=\"border-sidebar-border flex items-center justify-center border-t p-2\">\n <div\n z-popover\n [zOffset]=\"11\"\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n class=\"aspect-square h-9 w-9 shrink-0 cursor-pointer overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <!-- User Info Header - Always shown -->\n <div class=\"p-0 text-sm font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-medium\">{{ zUser()?.name || 'User Name' }}</span>\n <span class=\"text-muted-foreground mt-0.5 truncate text-xs\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n </div>\n\n @if (getVisibleUserActions().length > 0 || zActionsTemplate()) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <!-- Actions - Custom or from zUserActions -->\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n\n @if (selectedParent(); as parent) {\n @let hasChildrenOrTemplate = parent.menuTemplate || (parent.children && parent.children.length > 0);\n @if (hasChildrenOrTemplate) {\n <div\n class=\"z-sidebar-child-wrapper\"\n [class.collapsed]=\"sidebarCollapsed()\"\n [style.--sidebar-child-width.px]=\"sidebarChildWidth()\">\n <div\n class=\"z-sidebar-child z-shadow-menu bg-card text-card-foreground border-border/40 dark:border-sidebar-border flex h-full shrink-0 flex-col items-start overflow-hidden rounded-[0.375rem] border\"\n [style.width.px]=\"sidebarChildWidth()\"\n [class.collapsed]=\"sidebarCollapsed()\">\n <div 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 [zArrow]=\"false\">\n {{ selectedParent()?.name | translate }}\n </div>\n\n <z-icon\n zType=\"lucidePanelRightOpen\"\n zSize=\"20\"\n class=\"shrink-0 cursor-pointer opacity-60 hover:opacity-100\"\n (click)=\"toggleSidebar()\" />\n </div>\n\n <!-- Show menuTemplate if available, otherwise show children -->\n @if (selectedParent()?.menuTemplate) {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1\" track=\"vertical\">\n <div class=\"flex w-full flex-col p-3 pr-2\">\n <ng-container\n *ngTemplateOutlet=\"\n selectedParent()!.menuTemplate!;\n context: { $implicit: selectedParent()!, close: closeSidebarFn }\n \" />\n </div>\n </ng-scrollbar>\n } @else {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1 overflow-hidden\" track=\"vertical\">\n <div class=\"flex w-full min-w-0 flex-col gap-1 overflow-hidden py-1 pr-2 pl-2\">\n <ng-container *ngTemplateOutlet=\"menuChildrenTpl; context: { $implicit: menuChildren() }\" />\n </div>\n </ng-scrollbar>\n }\n </div>\n </div>\n }\n }\n </main>\n</div>\n\n<!-- MOBILE LAYOUT - Visible only on mobile -->\n<div class=\"z-menu-mobile-wrapper hidden max-md:block\">\n <!-- Mobile Backdrop -->\n @if (mobileMenuOpen() || mobileTemplateDrawerOpen()) {\n <div\n class=\"z-menu-backdrop fixed inset-0 z-9998\"\n [class.z-menu-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onBackdropClick()\"></div>\n }\n\n <!-- Mobile Drawer -->\n <aside\n class=\"z-menu-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full w-70 flex-col rounded-r-lg border-r\"\n [class.open]=\"mobileMenuOpen()\">\n <!-- Drawer Header -->\n <div class=\"border-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"bg-accent h-9 w-9 shrink-0\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <!-- Drawer Content - Accordion Menu -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-3\">\n @for (parent of menuParents(); track parent.id) {\n <div class=\"mb-1\">\n <!-- Parent Item -->\n @let isParentActive =\n selectedMenuItem()?.id === parent.id && (!parent.children || parent.children.length === 0);\n @let hasActiveChild = parentWithActiveChild()?.id === parent.id && !isParentActive;\n @let isCurrentlyViewing = selectedParent()?.id === parent.id;\n <div\n class=\"relative flex cursor-pointer items-center gap-3 rounded-[0.375rem] p-2\"\n [class.bg-primary/20]=\"isParentActive\"\n [class.text-primary]=\"isParentActive || hasActiveChild\"\n [class.hover:bg-accent]=\"!isParentActive\"\n (click)=\"onMobileParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\">{{ parent.name | translate }}</span>\n @if ((parent.children && parent.children.length > 0) || parent.menuTemplate) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"16\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"parent.expanded && isCurrentlyViewing\" />\n }\n </div>\n\n <!-- Children (Accordion) - Only render if NO menuTemplate -->\n @if (parent.children && parent.children.length > 0 && !parent.menuTemplate) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"parent.expanded && isCurrentlyViewing\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (child of parent.children; track child.id) {\n @let isChildActive =\n selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n\n <div>\n <div\n class=\"relative flex cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-accent]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1.5 w-1.5 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isChildActive\"\n [class.bg-gray-400]=\"!isChildActive\"></div>\n }\n <span class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n <!-- Level 3 -->\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n class=\"flex cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-accent]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n <span class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\">\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]=\"8\"\n [zPopoverContent]=\"mobileActionsPopoverTpl\"\n zPosition=\"top-right\"\n zTrigger=\"click\"\n class=\"hover:bg-accent flex cursor-pointer items-center gap-3 rounded-[0.375rem] 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 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 class=\"min-w-0 flex-1 truncate text-base font-semibold\">\n {{ customDrawerParent()?.name | translate }}\n </span>\n </div>\n\n <!-- Custom Template Content -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-4\">\n <ng-container\n *ngTemplateOutlet=\"\n customDrawerParent()!.menuTemplate!;\n context: { $implicit: customDrawerParent()!, close: closeMobileDrawerFn }\n \" />\n </div>\n </ng-scrollbar>\n }\n </aside>\n\n <ng-template #mobileActionsPopoverTpl let-close=\"close\">\n <div class=\"min-w-48 p-1\">\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n</div>\n\n<!-- Shared Template for Menu Children -->\n<ng-template #menuChildrenTpl let-children>\n @for (child of children; track child.id) {\n @let isChildActive = selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n <div class=\"w-full min-w-0\">\n <div\n #divLevel1\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-gray-200]=\"!isChildActive\"\n [class.dark:hover:bg-input/50]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zArrow]=\"false\"\n [zOffset]=\"10\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel1\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id; let isLast = $last) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #divLevel2\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-gray-200]=\"!isSubChildActive\"\n [class.dark:hover:bg-input/50]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zArrow]=\"false\"\n [zOffset]=\"10\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel2\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".z-menu{display:block;flex-shrink:0;height:100%}.z-menu [class*=cursor-pointer]{-webkit-user-select:none;user-select:none}@media(min-width:48rem){.z-menu{contain:layout style;min-width:283px;transition:min-width .25s cubic-bezier(.4,0,.2,1);will-change:min-width}.z-menu.z-menu-collapsed,.z-menu.z-menu-no-child{min-width:53px}}.z-shadow-menu{box-shadow:0 0 10px #0000001f}@media(max-width:47.9375rem){.z-menu-desktop{display:none!important;pointer-events:none;visibility:hidden}}.z-sidebar-main{position:relative;z-index:20;flex-shrink:0}.z-sidebar-child-wrapper{--sidebar-child-width: 230px;position:absolute;left:0;top:0;width:calc(100% + -0px);height:100%;clip-path:inset(0 -100px 0 0);pointer-events:none;transition:clip-path .25s cubic-bezier(.4,0,.2,1);will-change:clip-path;contain:layout}.z-sidebar-child-wrapper.collapsed{clip-path:inset(0 -100px 0 53px)}.z-sidebar-child{flex-shrink:0;height:100%;margin-left:53px;transform:translate(0);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1);pointer-events:auto;will-change:transform,width;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{transform:translate(calc(-1 * (var(--sidebar-child-width) + 50px + .3125rem)))}.z-menu-arrow.expanded{transform:rotate(90deg)}.z-menu-submenu{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-out}.z-menu-submenu.expanded{grid-template-rows:1fr}.z-menu-submenu>.z-menu-submenu-inner{overflow:hidden;min-height:0}.z-menu-backdrop{animation:z-menu-backdrop-enter .2s ease-out forwards}.z-menu-backdrop-dark{background-color:#0009}.z-menu-backdrop-blur{background-color:#0000000d;-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", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTrigger", "zTooltipType", "zTooltipSize", "zClass", "zShowDelay", "zHideDelay", "zArrow", "zDisabled", "zOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zManualClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange"], 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 });
394
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
395
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", 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-[0.375rem] border\"></div>\n\n <div class=\"bg-sidebar text-sidebar-foreground absolute inset-px z-20 flex flex-col rounded-[0.375rem]\">\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-[0.375rem]\"\n (click)=\"toggleSidebar()\">\n <z-icon zType=\"lucideChevronsRight\" zSize=\"20\" class=\"opacity-70\" />\n </div>\n }\n\n <div class=\"flex flex-1 flex-col items-center gap-2 p-2\">\n @for (item of menuParents(); track item.id) {\n @let hasActiveChild = parentWithActiveChild()?.id === item.id;\n @let isCurrentlySelected = selectedParent()?.id === item.id;\n @let showActiveIndicator = hasActiveChild && !isCurrentlySelected;\n <div\n zTooltip\n [zContent]=\"item.name | translate\"\n zPosition=\"right\"\n [zArrow]=\"false\"\n [zAlwaysShow]=\"true\"\n class=\"relative flex h-9 w-9 cursor-pointer items-center justify-center rounded-[0.375rem] select-none\"\n [class.bg-sidebar-primary]=\"selectedParent()?.id === item.id\"\n [class.text-sidebar-primary-foreground]=\"selectedParent()?.id === item.id\"\n [class.hover:bg-sidebar-accent]=\"selectedParent()?.id !== item.id\"\n (click)=\"onDesktopParentClick(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon\" zSize=\"20\" />\n } @else {\n <z-icon [zSvg]=\"item.iconSvg || ''\" zSize=\"20\" />\n }\n @if (showActiveIndicator) {\n <div\n class=\"bg-sidebar-primary absolute top-1/2 -left-[0.3125rem] h-4 w-1 -translate-y-1/2 rounded-full\"></div>\n }\n </div>\n }\n </div>\n\n <div class=\"border-sidebar-border flex items-center justify-center border-t p-2\">\n <div\n z-popover\n [zOffset]=\"11\"\n [zPopoverContent]=\"userPopoverTpl\"\n zPosition=\"right-bottom\"\n class=\"aspect-square h-9 w-9 shrink-0 cursor-pointer overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"h-full w-full object-cover\" />\n </div>\n </div>\n </div>\n </div>\n\n <ng-template #userPopoverTpl let-close=\"close\">\n <div class=\"min-w-56 p-1\">\n <!-- User Info Header - Always shown -->\n <div class=\"p-0 text-sm font-normal\">\n <div class=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <div class=\"h-8 w-8 shrink-0 overflow-hidden rounded-full\">\n <img [src]=\"avatarSrc()\" alt=\"User Avatar\" class=\"aspect-square size-full object-cover\" />\n </div>\n <div class=\"grid flex-1 text-left text-sm leading-tight\">\n <span class=\"truncate font-medium\">{{ zUser()?.name || 'User Name' }}</span>\n <span class=\"text-muted-foreground mt-0.5 truncate text-xs\">\n {{ zUser()?.email || 'user@example.com' }}\n </span>\n </div>\n </div>\n </div>\n\n @if (getVisibleUserActions().length > 0 || zActionsTemplate()) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <!-- Actions - Custom or from zUserActions -->\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n\n @if (selectedParent(); as parent) {\n @let hasChildrenOrTemplate = parent.menuTemplate || (parent.children && parent.children.length > 0);\n @if (hasChildrenOrTemplate) {\n <div\n class=\"z-sidebar-child-wrapper\"\n [class.collapsed]=\"sidebarCollapsed()\"\n [style.--sidebar-child-width.px]=\"sidebarChildWidth()\">\n <div\n class=\"z-sidebar-child z-shadow-menu bg-card text-card-foreground border-border/40 dark:border-sidebar-border flex h-full shrink-0 flex-col items-start overflow-hidden rounded-[0.375rem] border\"\n [style.width.px]=\"sidebarChildWidth()\"\n [class.collapsed]=\"sidebarCollapsed()\">\n <div 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 [zArrow]=\"false\">\n {{ selectedParent()?.name | translate }}\n </div>\n\n <z-icon\n zType=\"lucidePanelRightOpen\"\n zSize=\"20\"\n class=\"shrink-0 cursor-pointer opacity-60 hover:opacity-100\"\n (click)=\"toggleSidebar()\" />\n </div>\n\n <!-- Show menuTemplate if available, otherwise show children -->\n @if (selectedParent()?.menuTemplate) {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1\" track=\"vertical\">\n <div class=\"flex w-full flex-col p-3 pr-2\">\n <ng-container\n *ngTemplateOutlet=\"\n selectedParent()!.menuTemplate!;\n context: { $implicit: selectedParent()!, close: closeSidebarFn }\n \" />\n </div>\n </ng-scrollbar>\n } @else {\n <ng-scrollbar class=\"z-menu-scrollbar min-h-0 w-full flex-1 overflow-hidden\" track=\"vertical\">\n <div class=\"flex w-full min-w-0 flex-col gap-1 overflow-hidden py-1 pr-2 pl-2\">\n <ng-container *ngTemplateOutlet=\"menuChildrenTpl; context: { $implicit: menuChildren() }\" />\n </div>\n </ng-scrollbar>\n }\n </div>\n </div>\n }\n }\n </main>\n</div>\n\n<!-- MOBILE LAYOUT - Visible only on mobile -->\n<div class=\"z-menu-mobile-wrapper hidden max-md:block\">\n <!-- Mobile Backdrop -->\n @if (mobileMenuOpen() || mobileTemplateDrawerOpen()) {\n <div\n class=\"z-menu-backdrop fixed inset-0 z-9998\"\n [class.z-menu-backdrop-dark]=\"overlayType() === 'dark'\"\n [class.z-menu-backdrop-blur]=\"overlayType() === 'blur'\"\n (click)=\"onBackdropClick()\"></div>\n }\n\n <!-- Mobile Drawer -->\n <aside\n class=\"z-menu-drawer bg-background border-border fixed top-0 left-0 z-9999 flex h-full w-70 flex-col rounded-r-lg border-r\"\n [class.open]=\"mobileMenuOpen()\">\n <!-- Drawer Header -->\n <div class=\"border-border flex h-14 shrink-0 items-center justify-between border-b px-4\">\n @if (mobileLogo()) {\n <img [src]=\"mobileLogo()\" alt=\"Logo\" class=\"h-8 w-auto object-contain\" />\n }\n <button z-button zType=\"ghost\" [zWave]=\"false\" class=\"bg-accent h-9 w-9 shrink-0\" (click)=\"closeMobileMenu()\">\n <z-icon zType=\"lucideX\" zSize=\"20\" />\n </button>\n </div>\n\n <!-- Drawer Content - Accordion Menu -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-3\">\n @for (parent of menuParents(); track parent.id) {\n <div class=\"mb-1\">\n <!-- Parent Item -->\n @let isParentActive =\n selectedMenuItem()?.id === parent.id && (!parent.children || parent.children.length === 0);\n @let hasActiveChild = parentWithActiveChild()?.id === parent.id && !isParentActive;\n @let isCurrentlyViewing = selectedParent()?.id === parent.id;\n <div\n class=\"relative flex cursor-pointer items-center gap-3 rounded-[0.375rem] p-2\"\n [class.bg-primary/20]=\"isParentActive\"\n [class.text-primary]=\"isParentActive || hasActiveChild\"\n [class.hover:bg-accent]=\"!isParentActive\"\n (click)=\"onMobileParentClick(parent)\">\n @if (parent.icon) {\n <z-icon [zType]=\"parent.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (parent.iconSvg) {\n <z-icon [zSvg]=\"parent.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\">{{ parent.name | translate }}</span>\n @if ((parent.children && parent.children.length > 0) || parent.menuTemplate) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"16\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"parent.expanded && isCurrentlyViewing\" />\n }\n </div>\n\n <!-- Children (Accordion) - Only render if NO menuTemplate -->\n @if (parent.children && parent.children.length > 0 && !parent.menuTemplate) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"parent.expanded && isCurrentlyViewing\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (child of parent.children; track child.id) {\n @let isChildActive =\n selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n\n <div>\n <div\n class=\"relative flex cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-accent]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1.5 w-1.5 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isChildActive\"\n [class.bg-gray-400]=\"!isChildActive\"></div>\n }\n <span class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n <!-- Level 3 -->\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n class=\"flex cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-accent]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n <span class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\">\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]=\"8\"\n [zPopoverContent]=\"mobileActionsPopoverTpl\"\n zPosition=\"top-right\"\n zTrigger=\"click\"\n class=\"hover:bg-accent flex cursor-pointer items-center gap-3 rounded-[0.375rem] 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 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 class=\"min-w-0 flex-1 truncate text-base font-semibold\">\n {{ customDrawerParent()?.name | translate }}\n </span>\n </div>\n\n <!-- Custom Template Content -->\n <ng-scrollbar class=\"z-menu-scrollbar flex-1\" track=\"vertical\">\n <div class=\"p-4\">\n <ng-container\n *ngTemplateOutlet=\"\n customDrawerParent()!.menuTemplate!;\n context: { $implicit: customDrawerParent()!, close: closeMobileDrawerFn }\n \" />\n </div>\n </ng-scrollbar>\n }\n </aside>\n\n <ng-template #mobileActionsPopoverTpl let-close=\"close\">\n <div class=\"min-w-48 p-1\">\n @if (zActionsTemplate()) {\n <ng-container *ngTemplateOutlet=\"zActionsTemplate(); context: { close: close }\" />\n } @else if (getVisibleUserActions().length > 0) {\n @for (action of getVisibleUserActions(); track action.id; let idx = $index) {\n @if (shouldShowDividerBefore(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n\n <button\n type=\"button\"\n [disabled]=\"action.disabled\"\n [class]=\"action.class\"\n class=\"hover:bg-accent focus:bg-accent flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"onUserActionClick(action); close()\">\n @if (action.icon) {\n <z-icon [zType]=\"action.icon\" zSize=\"14\" class=\"text-muted-foreground\" />\n }\n <span>{{ action.label | translate }}</span>\n </button>\n\n @if (shouldShowDividerAfter(action, idx)) {\n <div class=\"bg-border -mx-1 my-1 h-px\"></div>\n }\n }\n }\n </div>\n </ng-template>\n</div>\n\n<!-- Shared Template for Menu Children -->\n<ng-template #menuChildrenTpl let-children>\n @for (child of children; track child.id) {\n @let isChildActive = selectedMenuItem()?.id === child.id && (!child.children || child.children.length === 0);\n @let isChildParentOfActive = isParentOfActiveItem(child);\n @let hasChildren = child.children && child.children.length > 0;\n <div class=\"w-full min-w-0\">\n <div\n #divLevel1\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isChildActive\"\n [class.text-primary-foreground]=\"isChildActive\"\n [class.text-primary]=\"isChildParentOfActive && !isChildActive\"\n [class.hover:bg-gray-200]=\"!isChildActive\"\n [class.dark:hover:bg-input/50]=\"!isChildActive\"\n (click)=\"onMenuItemClick(child)\">\n @if (child.icon) {\n <z-icon [zType]=\"child.icon\" zSize=\"18\" class=\"shrink-0\" />\n } @else if (child.iconSvg) {\n <z-icon [zSvg]=\"child.iconSvg\" zSize=\"18\" class=\"shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"child.name | translate\"\n [zArrow]=\"false\"\n [zOffset]=\"10\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel1\">\n {{ child.name | translate }}\n </span>\n @if (hasChildren) {\n <z-icon\n zType=\"lucideChevronRight\"\n zSize=\"14\"\n class=\"z-menu-arrow shrink-0 opacity-60 transition-transform\"\n [class.expanded]=\"child.expanded\" />\n }\n </div>\n\n @if (hasChildren) {\n <div class=\"z-menu-submenu\" [class.expanded]=\"child.expanded\">\n <div class=\"z-menu-submenu-inner\">\n <div class=\"z-menu-tree relative ml-4 flex flex-col gap-1 pt-1 pl-3\">\n <div class=\"absolute top-0 bottom-2 left-0 w-px bg-gray-300 dark:bg-gray-600\"></div>\n\n @for (subChild of child.children; track subChild.id; let isLast = $last) {\n @let isSubChildActive = selectedMenuItem()?.id === subChild.id;\n <div class=\"relative w-full min-w-0\">\n <div class=\"absolute top-1/2 -left-3 h-px w-3 bg-gray-300 dark:bg-gray-600\"></div>\n\n <div\n #divLevel2\n class=\"z-menu-item flex w-full cursor-pointer items-center gap-2 rounded-[0.375rem] p-2\"\n [class.bg-primary]=\"isSubChildActive\"\n [class.text-primary-foreground]=\"isSubChildActive\"\n [class.hover:bg-gray-200]=\"!isSubChildActive\"\n [class.dark:hover:bg-input/50]=\"!isSubChildActive\"\n (click)=\"onMenuItemClick(subChild)\">\n @if (subChild.icon) {\n <z-icon [zType]=\"subChild.icon\" zSize=\"16\" class=\"shrink-0\" />\n } @else if (subChild.iconSvg) {\n <z-icon [zSvg]=\"subChild.iconSvg\" zSize=\"16\" class=\"shrink-0\" />\n } @else {\n <div\n class=\"h-1 w-1 shrink-0 rounded-full\"\n [class.bg-primary-foreground]=\"isSubChildActive\"\n [class.bg-gray-400]=\"!isSubChildActive\"></div>\n }\n <span\n class=\"min-w-0 flex-1 truncate text-[0.8125rem] font-[450]\"\n zTooltip\n [zContent]=\"subChild.name | translate\"\n [zArrow]=\"false\"\n [zOffset]=\"10\"\n zMaxWidth=\"200px\"\n zPosition=\"right\"\n [zTriggerElement]=\"divLevel2\">\n {{ subChild.name | translate }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n</ng-template>\n", styles: [".z-menu{display:block;flex-shrink:0;height:100%}.z-menu [class*=cursor-pointer]{-webkit-user-select:none;user-select:none}@media(min-width:48rem){.z-menu{contain:layout style;min-width:283px;transition:min-width .25s cubic-bezier(.4,0,.2,1);will-change:min-width}.z-menu.z-menu-collapsed,.z-menu.z-menu-no-child{min-width:53px}}.z-shadow-menu{box-shadow:0 0 10px #0000001f}@media(max-width:47.9375rem){.z-menu-desktop{display:none!important;pointer-events:none;visibility:hidden}}.z-sidebar-main{position:relative;z-index:20;flex-shrink:0}.z-sidebar-child-wrapper{--sidebar-child-width: 230px;position:absolute;left:0;top:0;width:calc(100% + -0px);height:100%;clip-path:inset(0 -100px 0 0);pointer-events:none;transition:clip-path .25s cubic-bezier(.4,0,.2,1);will-change:clip-path;contain:layout}.z-sidebar-child-wrapper.collapsed{clip-path:inset(0 -100px 0 53px)}.z-sidebar-child{flex-shrink:0;height:100%;margin-left:53px;transform:translate(0);transition:transform .25s cubic-bezier(.4,0,.2,1),width .25s cubic-bezier(.4,0,.2,1);pointer-events:auto;will-change:transform,width;overflow:hidden;max-width:100%}.z-sidebar-child *{max-width:100%}.z-sidebar-child.collapsed{transform:translate(calc(-1 * (var(--sidebar-child-width) + 50px + .3125rem)))}.z-menu-arrow.expanded{transform:rotate(90deg)}.z-menu-submenu{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-out}.z-menu-submenu.expanded{grid-template-rows:1fr}.z-menu-submenu>.z-menu-submenu-inner{overflow:hidden;min-height:0}.z-menu-backdrop{animation:z-menu-backdrop-enter .2s ease-out forwards}.z-menu-backdrop-dark{background-color:#0009}.z-menu-backdrop-blur{background-color:#0000000d;-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", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTrigger", "zTooltipType", "zTooltipSize", "zClass", "zShowDelay", "zHideDelay", "zArrow", "zDisabled", "zOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zManualClose", "zScrollClose", "zShowArrow"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange"], 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 });
396
396
  }
397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZMenuComponent, decorators: [{
397
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZMenuComponent, decorators: [{
398
398
  type: Component,
399
399
  args: [{ selector: 'z-menu', imports: [
400
400
  NgTemplateOutlet,
@@ -20,10 +20,10 @@ import { Subject, takeUntil, fromEvent, filter } from 'rxjs';
20
20
 
21
21
  class ZModalContentDirective {
22
22
  templateRef = inject((TemplateRef));
23
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
24
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: ZModalContentDirective, isStandalone: true, selector: "[z-modal-content], [zModalContent]", ngImport: i0 });
23
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
24
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.9", type: ZModalContentDirective, isStandalone: true, selector: "[z-modal-content], [zModalContent]", ngImport: i0 });
25
25
  }
26
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalContentDirective, decorators: [{
26
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalContentDirective, decorators: [{
27
27
  type: Directive,
28
28
  args: [{
29
29
  selector: '[z-modal-content], [zModalContent]',
@@ -33,10 +33,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
33
33
 
34
34
  class ZModalFooterDirective {
35
35
  templateRef = inject((TemplateRef));
36
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
37
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: ZModalFooterDirective, isStandalone: true, selector: "[z-modal-footer], [zModalFooter]", ngImport: i0 });
36
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
37
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.9", type: ZModalFooterDirective, isStandalone: true, selector: "[z-modal-footer], [zModalFooter]", ngImport: i0 });
38
38
  }
39
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalFooterDirective, decorators: [{
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalFooterDirective, decorators: [{
40
40
  type: Directive,
41
41
  args: [{
42
42
  selector: '[z-modal-footer], [zModalFooter]',
@@ -46,10 +46,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
46
46
 
47
47
  class ZModalHeaderDirective {
48
48
  templateRef = inject((TemplateRef));
49
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
50
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: ZModalHeaderDirective, isStandalone: true, selector: "[z-modal-header], [zModalHeader]", ngImport: i0 });
49
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
50
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.9", type: ZModalHeaderDirective, isStandalone: true, selector: "[z-modal-header], [zModalHeader]", ngImport: i0 });
51
51
  }
52
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalHeaderDirective, decorators: [{
52
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalHeaderDirective, decorators: [{
53
53
  type: Directive,
54
54
  args: [{
55
55
  selector: '[z-modal-header], [zModalHeader]',
@@ -510,10 +510,10 @@ class ZModalComponent extends BasePortalOutlet {
510
510
  this._backdropSubscription = null;
511
511
  }
512
512
  }
513
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
514
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ZModalComponent, isStandalone: true, selector: "z-modal", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zVisible: { classPropertyName: "zVisible", publicName: "zVisible", isSignal: true, isRequired: false, transformFunction: null }, zTitle: { classPropertyName: "zTitle", publicName: "zTitle", isSignal: true, isRequired: false, transformFunction: null }, zDescription: { classPropertyName: "zDescription", publicName: "zDescription", isSignal: true, isRequired: false, transformFunction: null }, zWidth: { classPropertyName: "zWidth", publicName: "zWidth", isSignal: true, isRequired: false, transformFunction: null }, zClosable: { classPropertyName: "zClosable", publicName: "zClosable", isSignal: true, isRequired: false, transformFunction: null }, zMaskClosable: { classPropertyName: "zMaskClosable", publicName: "zMaskClosable", isSignal: true, isRequired: false, transformFunction: null }, zHideHeader: { classPropertyName: "zHideHeader", publicName: "zHideHeader", isSignal: true, isRequired: false, transformFunction: null }, zHideFooter: { classPropertyName: "zHideFooter", publicName: "zHideFooter", isSignal: true, isRequired: false, transformFunction: null }, zOkText: { classPropertyName: "zOkText", publicName: "zOkText", isSignal: true, isRequired: false, transformFunction: null }, zCancelText: { classPropertyName: "zCancelText", publicName: "zCancelText", isSignal: true, isRequired: false, transformFunction: null }, zOkDestructive: { classPropertyName: "zOkDestructive", publicName: "zOkDestructive", isSignal: true, isRequired: false, transformFunction: null }, zOkDisabled: { classPropertyName: "zOkDisabled", publicName: "zOkDisabled", isSignal: true, isRequired: false, transformFunction: null }, zLoading: { classPropertyName: "zLoading", publicName: "zLoading", isSignal: true, isRequired: false, transformFunction: null }, zContentLoading: { classPropertyName: "zContentLoading", publicName: "zContentLoading", isSignal: true, isRequired: false, transformFunction: null }, zSkeletonRows: { classPropertyName: "zSkeletonRows", publicName: "zSkeletonRows", isSignal: true, isRequired: false, transformFunction: null }, zOverlay: { classPropertyName: "zOverlay", publicName: "zOverlay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOk: "zOk", zCancel: "zCancel", zAfterClose: "zAfterClose", zScrollbar: "zScrollbar", zVisible: "zVisibleChange" }, host: { properties: { "class": "hostClasses()", "style.width": "effectiveWidth()" } }, providers: [TranslatePipe], queries: [{ propertyName: "customHeader", first: true, predicate: ZModalHeaderDirective, descendants: true, isSignal: true }, { propertyName: "customContent", first: true, predicate: ZModalContentDirective, descendants: true, isSignal: true }, { propertyName: "customFooter", first: true, predicate: ZModalFooterDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, isSignal: true }, { propertyName: "dummyTemplateRef", first: true, predicate: ["dummyTemplate"], descendants: true, isSignal: true }, { propertyName: "mainContentRef", first: true, predicate: ["mainContent"], descendants: true, isSignal: true }], exportAs: ["zModal"], usesInheritance: true, ngImport: i0, template: "<!-- Dummy template to trigger CDK backdrop creation -->\n<ng-template #dummyTemplate />\n\n<!-- Template mode content (rendered in host element, which is moved to overlay) -->\n@if (isTemplateMode() && shouldRenderContent()) {\n @if (!effectiveContentLoading()) {\n @if (customHeader(); as headerDir) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex items-start justify-between px-4\">\n <ng-container *ngTemplateOutlet=\"headerDir.templateRef\" />\n </div>\n </header>\n } @else if (!effectiveHideHeader()) {\n @if (effectiveTitle()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex w-full items-start justify-between overflow-hidden px-4\">\n <div class=\"min-w-0 flex-1 overflow-hidden pr-2\">\n @if (effectiveTitle(); as title) {\n @switch (title | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(title)\" />\n }\n @case ('html') {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"title\"\n [innerHTML]=\"$any(title) | zSafeHtml\"></h4>\n }\n @default {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"$any(title) | translate\">\n {{ $any(title) | translate }}\n </h4>\n }\n }\n }\n @if (effectiveDescription(); as description) {\n @switch (description | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(description)\" />\n }\n @case ('html') {\n <p\n data-testid=\"z-modal-description\"\n class=\"text-muted-foreground m-0 mt-1 text-sm\"\n [innerHTML]=\"$any(description) | zSafeHtml\"></p>\n }\n @default {\n <p data-testid=\"z-modal-description\" class=\"text-muted-foreground m-0 mt-1 text-sm\">\n {{ $any(description) | translate }}\n </p>\n }\n }\n }\n </div>\n @if (effectiveClosable()) {\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n }\n </div>\n </header>\n } @else if (effectiveClosable()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex justify-end px-4\">\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n </div>\n </header>\n }\n }\n\n <ng-scrollbar\n class=\"z-modal-scrollbar flex-1\"\n #mainContent\n track=\"vertical\"\n cdkScrollable\n (scroll)=\"onContentScroll($event)\">\n <main class=\"flex min-h-0 flex-col gap-4 px-4 py-4\">\n @if (customContent(); as contentDir) {\n <ng-container *ngTemplateOutlet=\"contentDir.templateRef\" />\n } @else {\n <ng-content />\n }\n </main>\n </ng-scrollbar>\n\n @if (customFooter(); as footerDir) {\n <footer [class.z-modal-footer-shadow]=\"shouldShowShadow()\">\n <div class=\"flex flex-row justify-end gap-2 px-4\">\n <ng-container *ngTemplateOutlet=\"footerDir.templateRef\" />\n </div>\n </footer>\n } @else if (!effectiveHideFooter()) {\n <footer [class.z-modal-footer-shadow]=\"shouldShowShadow()\">\n <div class=\"flex flex-row justify-end gap-2 px-4\">\n @if (effectiveCancelText() !== null) {\n <button type=\"button\" data-testid=\"z-modal-cancel-button\" z-button zType=\"outline\" (click)=\"onCloseClick()\">\n {{ effectiveCancelText() ?? ('i18n_z_ui_modal_cancel' | translate) }}\n </button>\n }\n\n @if (effectiveOkText() !== null) {\n <button\n type=\"button\"\n data-testid=\"z-modal-ok-button\"\n z-button\n [zType]=\"effectiveOkDestructive() ? 'destructive' : 'default'\"\n [disabled]=\"effectiveOkDisabled() || effectiveLoading()\"\n [zLoading]=\"effectiveLoading()\"\n (click)=\"onOkClick()\">\n {{ effectiveOkText() ?? ('i18n_z_ui_common_ok' | translate) }}\n </button>\n }\n </div>\n </footer>\n }\n } @else {\n <div class=\"flex h-[12.5rem] flex-col gap-4 px-4\">\n <z-skeleton class=\"h-full\" [zRows]=\"effectiveSkeletonRows()\" />\n </div>\n }\n}\n\n<!-- Service mode content -->\n@if (isServiceMode()) {\n <!-- Confirm Modal Layout (no skeleton) -->\n @if (isConfirmMode()) {\n <div class=\"flex flex-col items-center px-4 pt-2 pb-4 text-center\">\n @if (config.zConfirmIcon) {\n <div class=\"relative mb-4 flex size-20 items-center justify-center\">\n <div class=\"absolute inset-0 rounded-full\" [class]=\"confirmIconColors().ring\"></div>\n <div class=\"relative flex size-14 items-center justify-center rounded-full\" [class]=\"confirmIconColors().bg\">\n <z-icon [zType]=\"config.zConfirmIcon\" zSize=\"30\" [zStrokeWidth]=\"2.6\" [class]=\"confirmIconColors().icon\" />\n </div>\n </div>\n }\n\n <!-- Title centered -->\n @if (effectiveTitle(); as title) {\n @switch (title | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(title)\" />\n }\n @case ('html') {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 text-lg leading-snug font-semibold\"\n [innerHTML]=\"$any(title) | zSafeHtml\"></h4>\n }\n @default {\n <h4 data-testid=\"z-modal-title\" class=\"m-0 text-lg leading-snug font-semibold\">\n {{ $any(title) | translate }}\n </h4>\n }\n }\n }\n\n <!-- Description centered -->\n @if (config.zContent; as content) {\n <p\n data-testid=\"z-modal-description\"\n class=\"text-muted-foreground m-0 mt-2 text-sm\"\n [innerHTML]=\"$any(content) | translate | zSafeHtml\"></p>\n }\n </div>\n\n <!-- Footer centered -->\n @if (!effectiveHideFooter()) {\n <footer class=\"mt-4 flex flex-row justify-center gap-3 pb-2\">\n @if (effectiveCancelText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-cancel-button\"\n z-button\n zType=\"outline\"\n (click)=\"onCloseClick()\">\n {{ effectiveCancelText() ?? 'i18n_z_ui_modal_cancel' | translate }}\n </button>\n }\n\n @if (effectiveOkText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-ok-button\"\n z-button\n [zType]=\"effectiveTypeOk()\"\n [disabled]=\"effectiveOkDisabled() || effectiveLoading()\"\n [zLoading]=\"effectiveLoading()\"\n (click)=\"onOkClick()\">\n {{ effectiveOkText() ?? 'i18n_z_ui_common_ok' | translate }}\n </button>\n }\n </footer>\n }\n } @else {\n <!-- Normal Modal Layout -->\n @if (!effectiveContentLoading()) {\n @if (!effectiveHideHeader()) {\n @if (effectiveTitle()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex w-full items-start justify-between overflow-hidden px-4\">\n <div class=\"min-w-0 flex-1 overflow-hidden pr-2\">\n @if (effectiveTitle(); as title) {\n @switch (title | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(title)\" />\n }\n @case ('html') {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"title\"\n [innerHTML]=\"$any(title) | zSafeHtml\"></h4>\n }\n @default {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"$any(title) | translate\">\n {{ $any(title) | translate }}\n </h4>\n }\n }\n }\n </div>\n @if (effectiveClosable()) {\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n }\n </div>\n </header>\n } @else if (effectiveClosable()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex justify-end px-4\">\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n </div>\n </header>\n }\n }\n\n <ng-scrollbar\n class=\"z-modal-scrollbar flex-1\"\n #mainContent\n track=\"vertical\"\n cdkScrollable\n (scroll)=\"onContentScroll($event)\">\n <main class=\"flex min-h-0 flex-col gap-4 px-4 py-4\">\n <ng-template cdkPortalOutlet />\n\n @if (isStringContent()) {\n <div data-testid=\"z-modal-content\" [innerHTML]=\"$any(config.zContent) | zSafeHtml\"></div>\n }\n </main>\n </ng-scrollbar>\n\n @if (!effectiveHideFooter()) {\n <footer [class.z-modal-footer-shadow]=\"shouldShowShadow()\">\n <div class=\"flex flex-row justify-end gap-2 px-4\">\n @if (effectiveCancelText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-cancel-button\"\n z-button\n zType=\"outline\"\n (click)=\"onCloseClick()\">\n @if (config.zCancelIcon) {\n <z-icon [zType]=\"config.zCancelIcon\" />\n }\n {{ effectiveCancelText() ?? 'i18n_z_ui_modal_cancel' | translate }}\n </button>\n }\n\n @if (effectiveOkText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-ok-button\"\n z-button\n [zType]=\"effectiveOkDestructive() ? 'destructive' : 'default'\"\n [disabled]=\"effectiveOkDisabled() || effectiveLoading()\"\n [zLoading]=\"effectiveLoading()\"\n (click)=\"onOkClick()\">\n @if (config.zOkIcon && !effectiveLoading()) {\n <z-icon [zType]=\"config.zOkIcon\" />\n }\n {{ effectiveOkText() ?? 'i18n_z_ui_common_ok' | translate }}\n </button>\n }\n </div>\n </footer>\n }\n } @else {\n <div class=\"flex h-[12.5rem] flex-col gap-4 px-4\">\n <z-skeleton [zRows]=\"effectiveSkeletonRows()\" />\n </div>\n }\n }\n}\n", styles: [":host.z-modal-service-mode,:host.z-modal-template-mode{--z-enter-opacity: 0;--z-enter-scale: .96;transform-origin:center center;animation:z-enter .18s cubic-bezier(.16,1,.3,1) forwards}:host.z-modal-service-mode.modal-leave,:host.z-modal-template-mode.modal-leave{--z-exit-opacity: 0;--z-exit-scale: .96;transform-origin:center center;animation:z-exit .15s cubic-bezier(.4,0,1,1) forwards}:host.z-modal-template-host{display:contents}::ng-deep .z-modal-backdrop-dark{background-color:#0009;animation:z-backdrop-enter .15s ease-out forwards}::ng-deep .z-modal-backdrop-blur{background-color:#0000000d;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);animation:z-backdrop-enter .15s ease-out forwards}::ng-deep .z-modal-backdrop-dark.z-backdrop-leaving,::ng-deep .z-modal-backdrop-blur.z-backdrop-leaving{animation:z-backdrop-exit .12s ease-in forwards}.z-modal-header-shadow{padding-bottom:1rem;box-shadow:0 2px 8px -2px #0000001a}.z-modal-footer-shadow{padding-top:1rem;box-shadow:0 -2px 8px -2px #0000001a}:host main{overscroll-behavior:contain}:host header,:host footer{transition:box-shadow .2s ease-out,padding .2s ease-out}.z-modal-scrollbar{--scrollbar-padding: .125rem}\n"], dependencies: [{ kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { 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", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTrigger", "zTooltipType", "zTooltipSize", "zClass", "zShowDelay", "zHideDelay", "zArrow", "zDisabled", "zOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "component", type: ZSkeletonComponent, selector: "z-skeleton", inputs: ["class", "zType", "zSize", "zWidth", "zHeight", "zRows", "zGap", "zAnimated", "zRadius"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "directive", type: CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: ZContentTypePipe, name: "zContentType" }, { kind: "pipe", type: ZSafeHtmlPipe, name: "zSafeHtml" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
513
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
514
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZModalComponent, isStandalone: true, selector: "z-modal", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zVisible: { classPropertyName: "zVisible", publicName: "zVisible", isSignal: true, isRequired: false, transformFunction: null }, zTitle: { classPropertyName: "zTitle", publicName: "zTitle", isSignal: true, isRequired: false, transformFunction: null }, zDescription: { classPropertyName: "zDescription", publicName: "zDescription", isSignal: true, isRequired: false, transformFunction: null }, zWidth: { classPropertyName: "zWidth", publicName: "zWidth", isSignal: true, isRequired: false, transformFunction: null }, zClosable: { classPropertyName: "zClosable", publicName: "zClosable", isSignal: true, isRequired: false, transformFunction: null }, zMaskClosable: { classPropertyName: "zMaskClosable", publicName: "zMaskClosable", isSignal: true, isRequired: false, transformFunction: null }, zHideHeader: { classPropertyName: "zHideHeader", publicName: "zHideHeader", isSignal: true, isRequired: false, transformFunction: null }, zHideFooter: { classPropertyName: "zHideFooter", publicName: "zHideFooter", isSignal: true, isRequired: false, transformFunction: null }, zOkText: { classPropertyName: "zOkText", publicName: "zOkText", isSignal: true, isRequired: false, transformFunction: null }, zCancelText: { classPropertyName: "zCancelText", publicName: "zCancelText", isSignal: true, isRequired: false, transformFunction: null }, zOkDestructive: { classPropertyName: "zOkDestructive", publicName: "zOkDestructive", isSignal: true, isRequired: false, transformFunction: null }, zOkDisabled: { classPropertyName: "zOkDisabled", publicName: "zOkDisabled", isSignal: true, isRequired: false, transformFunction: null }, zLoading: { classPropertyName: "zLoading", publicName: "zLoading", isSignal: true, isRequired: false, transformFunction: null }, zContentLoading: { classPropertyName: "zContentLoading", publicName: "zContentLoading", isSignal: true, isRequired: false, transformFunction: null }, zSkeletonRows: { classPropertyName: "zSkeletonRows", publicName: "zSkeletonRows", isSignal: true, isRequired: false, transformFunction: null }, zOverlay: { classPropertyName: "zOverlay", publicName: "zOverlay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOk: "zOk", zCancel: "zCancel", zAfterClose: "zAfterClose", zScrollbar: "zScrollbar", zVisible: "zVisibleChange" }, host: { properties: { "class": "hostClasses()", "style.width": "effectiveWidth()" } }, providers: [TranslatePipe], queries: [{ propertyName: "customHeader", first: true, predicate: ZModalHeaderDirective, descendants: true, isSignal: true }, { propertyName: "customContent", first: true, predicate: ZModalContentDirective, descendants: true, isSignal: true }, { propertyName: "customFooter", first: true, predicate: ZModalFooterDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, isSignal: true }, { propertyName: "dummyTemplateRef", first: true, predicate: ["dummyTemplate"], descendants: true, isSignal: true }, { propertyName: "mainContentRef", first: true, predicate: ["mainContent"], descendants: true, isSignal: true }], exportAs: ["zModal"], usesInheritance: true, ngImport: i0, template: "<!-- Dummy template to trigger CDK backdrop creation -->\n<ng-template #dummyTemplate />\n\n<!-- Template mode content (rendered in host element, which is moved to overlay) -->\n@if (isTemplateMode() && shouldRenderContent()) {\n @if (!effectiveContentLoading()) {\n @if (customHeader(); as headerDir) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex items-start justify-between px-4\">\n <ng-container *ngTemplateOutlet=\"headerDir.templateRef\" />\n </div>\n </header>\n } @else if (!effectiveHideHeader()) {\n @if (effectiveTitle()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex w-full items-start justify-between overflow-hidden px-4\">\n <div class=\"min-w-0 flex-1 overflow-hidden pr-2\">\n @if (effectiveTitle(); as title) {\n @switch (title | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(title)\" />\n }\n @case ('html') {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"title\"\n [innerHTML]=\"$any(title) | zSafeHtml\"></h4>\n }\n @default {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"$any(title) | translate\">\n {{ $any(title) | translate }}\n </h4>\n }\n }\n }\n @if (effectiveDescription(); as description) {\n @switch (description | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(description)\" />\n }\n @case ('html') {\n <p\n data-testid=\"z-modal-description\"\n class=\"text-muted-foreground m-0 mt-1 text-sm\"\n [innerHTML]=\"$any(description) | zSafeHtml\"></p>\n }\n @default {\n <p data-testid=\"z-modal-description\" class=\"text-muted-foreground m-0 mt-1 text-sm\">\n {{ $any(description) | translate }}\n </p>\n }\n }\n }\n </div>\n @if (effectiveClosable()) {\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n }\n </div>\n </header>\n } @else if (effectiveClosable()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex justify-end px-4\">\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n </div>\n </header>\n }\n }\n\n <ng-scrollbar\n class=\"z-modal-scrollbar flex-1\"\n #mainContent\n track=\"vertical\"\n cdkScrollable\n (scroll)=\"onContentScroll($event)\">\n <main class=\"flex min-h-0 flex-col gap-4 px-4 py-4\">\n @if (customContent(); as contentDir) {\n <ng-container *ngTemplateOutlet=\"contentDir.templateRef\" />\n } @else {\n <ng-content />\n }\n </main>\n </ng-scrollbar>\n\n @if (customFooter(); as footerDir) {\n <footer [class.z-modal-footer-shadow]=\"shouldShowShadow()\">\n <div class=\"flex flex-row justify-end gap-2 px-4\">\n <ng-container *ngTemplateOutlet=\"footerDir.templateRef\" />\n </div>\n </footer>\n } @else if (!effectiveHideFooter()) {\n <footer [class.z-modal-footer-shadow]=\"shouldShowShadow()\">\n <div class=\"flex flex-row justify-end gap-2 px-4\">\n @if (effectiveCancelText() !== null) {\n <button type=\"button\" data-testid=\"z-modal-cancel-button\" z-button zType=\"outline\" (click)=\"onCloseClick()\">\n {{ effectiveCancelText() ?? ('i18n_z_ui_modal_cancel' | translate) }}\n </button>\n }\n\n @if (effectiveOkText() !== null) {\n <button\n type=\"button\"\n data-testid=\"z-modal-ok-button\"\n z-button\n [zType]=\"effectiveOkDestructive() ? 'destructive' : 'default'\"\n [disabled]=\"effectiveOkDisabled() || effectiveLoading()\"\n [zLoading]=\"effectiveLoading()\"\n (click)=\"onOkClick()\">\n {{ effectiveOkText() ?? ('i18n_z_ui_common_ok' | translate) }}\n </button>\n }\n </div>\n </footer>\n }\n } @else {\n <div class=\"flex h-[12.5rem] flex-col gap-4 px-4\">\n <z-skeleton class=\"h-full\" [zRows]=\"effectiveSkeletonRows()\" />\n </div>\n }\n}\n\n<!-- Service mode content -->\n@if (isServiceMode()) {\n <!-- Confirm Modal Layout (no skeleton) -->\n @if (isConfirmMode()) {\n <div class=\"flex flex-col items-center px-4 pt-2 pb-4 text-center\">\n @if (config.zConfirmIcon) {\n <div class=\"relative mb-4 flex size-20 items-center justify-center\">\n <div class=\"absolute inset-0 rounded-full\" [class]=\"confirmIconColors().ring\"></div>\n <div class=\"relative flex size-14 items-center justify-center rounded-full\" [class]=\"confirmIconColors().bg\">\n <z-icon [zType]=\"config.zConfirmIcon\" zSize=\"30\" [zStrokeWidth]=\"2.6\" [class]=\"confirmIconColors().icon\" />\n </div>\n </div>\n }\n\n <!-- Title centered -->\n @if (effectiveTitle(); as title) {\n @switch (title | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(title)\" />\n }\n @case ('html') {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 text-lg leading-snug font-semibold\"\n [innerHTML]=\"$any(title) | zSafeHtml\"></h4>\n }\n @default {\n <h4 data-testid=\"z-modal-title\" class=\"m-0 text-lg leading-snug font-semibold\">\n {{ $any(title) | translate }}\n </h4>\n }\n }\n }\n\n <!-- Description centered -->\n @if (config.zContent; as content) {\n <p\n data-testid=\"z-modal-description\"\n class=\"text-muted-foreground m-0 mt-2 text-sm\"\n [innerHTML]=\"$any(content) | translate | zSafeHtml\"></p>\n }\n </div>\n\n <!-- Footer centered -->\n @if (!effectiveHideFooter()) {\n <footer class=\"mt-4 flex flex-row justify-center gap-3 pb-2\">\n @if (effectiveCancelText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-cancel-button\"\n z-button\n zType=\"outline\"\n (click)=\"onCloseClick()\">\n {{ effectiveCancelText() ?? 'i18n_z_ui_modal_cancel' | translate }}\n </button>\n }\n\n @if (effectiveOkText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-ok-button\"\n z-button\n [zType]=\"effectiveTypeOk()\"\n [disabled]=\"effectiveOkDisabled() || effectiveLoading()\"\n [zLoading]=\"effectiveLoading()\"\n (click)=\"onOkClick()\">\n {{ effectiveOkText() ?? 'i18n_z_ui_common_ok' | translate }}\n </button>\n }\n </footer>\n }\n } @else {\n <!-- Normal Modal Layout -->\n @if (!effectiveContentLoading()) {\n @if (!effectiveHideHeader()) {\n @if (effectiveTitle()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex w-full items-start justify-between overflow-hidden px-4\">\n <div class=\"min-w-0 flex-1 overflow-hidden pr-2\">\n @if (effectiveTitle(); as title) {\n @switch (title | zContentType) {\n @case ('template') {\n <ng-container *ngTemplateOutlet=\"$any(title)\" />\n }\n @case ('html') {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"title\"\n [innerHTML]=\"$any(title) | zSafeHtml\"></h4>\n }\n @default {\n <h4\n data-testid=\"z-modal-title\"\n class=\"m-0 truncate text-base leading-snug font-semibold\"\n z-tooltip\n [zContent]=\"$any(title) | translate\">\n {{ $any(title) | translate }}\n </h4>\n }\n }\n }\n </div>\n @if (effectiveClosable()) {\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n }\n </div>\n </header>\n } @else if (effectiveClosable()) {\n <header [class.z-modal-header-shadow]=\"shouldShowShadow()\">\n <div class=\"flex justify-end px-4\">\n <button\n type=\"button\"\n data-testid=\"z-modal-close-header-button\"\n z-button\n zType=\"subtle\"\n zSize=\"xs\"\n [zWave]=\"false\"\n (click)=\"onCloseClick()\">\n <z-icon zType=\"lucideX\" />\n </button>\n </div>\n </header>\n }\n }\n\n <ng-scrollbar\n class=\"z-modal-scrollbar flex-1\"\n #mainContent\n track=\"vertical\"\n cdkScrollable\n (scroll)=\"onContentScroll($event)\">\n <main class=\"flex min-h-0 flex-col gap-4 px-4 py-4\">\n <ng-template cdkPortalOutlet />\n\n @if (isStringContent()) {\n <div data-testid=\"z-modal-content\" [innerHTML]=\"$any(config.zContent) | zSafeHtml\"></div>\n }\n </main>\n </ng-scrollbar>\n\n @if (!effectiveHideFooter()) {\n <footer [class.z-modal-footer-shadow]=\"shouldShowShadow()\">\n <div class=\"flex flex-row justify-end gap-2 px-4\">\n @if (effectiveCancelText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-cancel-button\"\n z-button\n zType=\"outline\"\n (click)=\"onCloseClick()\">\n @if (config.zCancelIcon) {\n <z-icon [zType]=\"config.zCancelIcon\" />\n }\n {{ effectiveCancelText() ?? 'i18n_z_ui_modal_cancel' | translate }}\n </button>\n }\n\n @if (effectiveOkText() !== null) {\n <button\n type=\"button\"\n class=\"min-w-28\"\n data-testid=\"z-modal-ok-button\"\n z-button\n [zType]=\"effectiveOkDestructive() ? 'destructive' : 'default'\"\n [disabled]=\"effectiveOkDisabled() || effectiveLoading()\"\n [zLoading]=\"effectiveLoading()\"\n (click)=\"onOkClick()\">\n @if (config.zOkIcon && !effectiveLoading()) {\n <z-icon [zType]=\"config.zOkIcon\" />\n }\n {{ effectiveOkText() ?? 'i18n_z_ui_common_ok' | translate }}\n </button>\n }\n </div>\n </footer>\n }\n } @else {\n <div class=\"flex h-[12.5rem] flex-col gap-4 px-4\">\n <z-skeleton [zRows]=\"effectiveSkeletonRows()\" />\n </div>\n }\n }\n}\n", styles: [":host.z-modal-service-mode,:host.z-modal-template-mode{--z-enter-opacity: 0;--z-enter-scale: .96;transform-origin:center center;animation:z-enter .18s cubic-bezier(.16,1,.3,1) forwards}:host.z-modal-service-mode.modal-leave,:host.z-modal-template-mode.modal-leave{--z-exit-opacity: 0;--z-exit-scale: .96;transform-origin:center center;animation:z-exit .15s cubic-bezier(.4,0,1,1) forwards}:host.z-modal-template-host{display:contents}::ng-deep .z-modal-backdrop-dark{background-color:#0009;animation:z-backdrop-enter .15s ease-out forwards}::ng-deep .z-modal-backdrop-blur{background-color:#0000000d;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);animation:z-backdrop-enter .15s ease-out forwards}::ng-deep .z-modal-backdrop-dark.z-backdrop-leaving,::ng-deep .z-modal-backdrop-blur.z-backdrop-leaving{animation:z-backdrop-exit .12s ease-in forwards}.z-modal-header-shadow{padding-bottom:1rem;box-shadow:0 2px 8px -2px #0000001a}.z-modal-footer-shadow{padding-top:1rem;box-shadow:0 -2px 8px -2px #0000001a}:host main{overscroll-behavior:contain}:host header,:host footer{transition:box-shadow .2s ease-out,padding .2s ease-out}.z-modal-scrollbar{--scrollbar-padding: .125rem}\n"], dependencies: [{ kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { 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", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTrigger", "zTooltipType", "zTooltipSize", "zClass", "zShowDelay", "zHideDelay", "zArrow", "zDisabled", "zOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "component", type: ZSkeletonComponent, selector: "z-skeleton", inputs: ["class", "zType", "zSize", "zWidth", "zHeight", "zRows", "zGap", "zAnimated", "zRadius"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "directive", type: CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "pipe", type: ZContentTypePipe, name: "zContentType" }, { kind: "pipe", type: ZSafeHtmlPipe, name: "zSafeHtml" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
515
515
  }
516
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalComponent, decorators: [{
516
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalComponent, decorators: [{
517
517
  type: Component,
518
518
  args: [{ selector: 'z-modal', imports: [
519
519
  PortalModule,
@@ -740,10 +740,10 @@ class ZModalService {
740
740
  ],
741
741
  });
742
742
  }
743
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
744
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalService, providedIn: 'root' });
743
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
744
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalService, providedIn: 'root' });
745
745
  }
746
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZModalService, decorators: [{
746
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZModalService, decorators: [{
747
747
  type: Injectable,
748
748
  args: [{
749
749
  providedIn: 'root',