@shival99/z-ui 1.8.13 → 1.9.1

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 (89) hide show
  1. package/assets/css/tailwind.css +7 -11
  2. package/fesm2022/shival99-z-ui-components-z-autocomplete.mjs +45 -71
  3. package/fesm2022/shival99-z-ui-components-z-autocomplete.mjs.map +1 -1
  4. package/fesm2022/shival99-z-ui-components-z-button.mjs +21 -11
  5. package/fesm2022/shival99-z-ui-components-z-button.mjs.map +1 -1
  6. package/fesm2022/shival99-z-ui-components-z-calendar.mjs +61 -32
  7. package/fesm2022/shival99-z-ui-components-z-calendar.mjs.map +1 -1
  8. package/fesm2022/shival99-z-ui-components-z-card.mjs +1 -1
  9. package/fesm2022/shival99-z-ui-components-z-card.mjs.map +1 -1
  10. package/fesm2022/shival99-z-ui-components-z-chat.mjs +429 -0
  11. package/fesm2022/shival99-z-ui-components-z-chat.mjs.map +1 -0
  12. package/fesm2022/shival99-z-ui-components-z-checkbox.mjs +1 -1
  13. package/fesm2022/shival99-z-ui-components-z-checkbox.mjs.map +1 -1
  14. package/fesm2022/shival99-z-ui-components-z-code.mjs +51 -21
  15. package/fesm2022/shival99-z-ui-components-z-code.mjs.map +1 -1
  16. package/fesm2022/shival99-z-ui-components-z-drawer.mjs +8 -3
  17. package/fesm2022/shival99-z-ui-components-z-drawer.mjs.map +1 -1
  18. package/fesm2022/shival99-z-ui-components-z-editor.mjs +3 -3
  19. package/fesm2022/shival99-z-ui-components-z-editor.mjs.map +1 -1
  20. package/fesm2022/shival99-z-ui-components-z-empty.mjs.map +1 -1
  21. package/fesm2022/shival99-z-ui-components-z-filter.mjs +3 -3
  22. package/fesm2022/shival99-z-ui-components-z-filter.mjs.map +1 -1
  23. package/fesm2022/shival99-z-ui-components-z-gallery.mjs +169 -90
  24. package/fesm2022/shival99-z-ui-components-z-gallery.mjs.map +1 -1
  25. package/fesm2022/shival99-z-ui-components-z-icon.mjs +143 -360
  26. package/fesm2022/shival99-z-ui-components-z-icon.mjs.map +1 -1
  27. package/fesm2022/shival99-z-ui-components-z-input.mjs +131 -8
  28. package/fesm2022/shival99-z-ui-components-z-input.mjs.map +1 -1
  29. package/fesm2022/shival99-z-ui-components-z-loading.mjs +2 -2
  30. package/fesm2022/shival99-z-ui-components-z-loading.mjs.map +1 -1
  31. package/fesm2022/shival99-z-ui-components-z-menu.mjs +2 -2
  32. package/fesm2022/shival99-z-ui-components-z-menu.mjs.map +1 -1
  33. package/fesm2022/shival99-z-ui-components-z-modal.mjs +8 -3
  34. package/fesm2022/shival99-z-ui-components-z-modal.mjs.map +1 -1
  35. package/fesm2022/shival99-z-ui-components-z-pagination.mjs +1 -1
  36. package/fesm2022/shival99-z-ui-components-z-pagination.mjs.map +1 -1
  37. package/fesm2022/shival99-z-ui-components-z-popover.mjs +3 -3
  38. package/fesm2022/shival99-z-ui-components-z-popover.mjs.map +1 -1
  39. package/fesm2022/shival99-z-ui-components-z-select.mjs +31 -7
  40. package/fesm2022/shival99-z-ui-components-z-select.mjs.map +1 -1
  41. package/fesm2022/shival99-z-ui-components-z-skeleton.mjs +3 -3
  42. package/fesm2022/shival99-z-ui-components-z-skeleton.mjs.map +1 -1
  43. package/fesm2022/shival99-z-ui-components-z-steps.mjs +31 -29
  44. package/fesm2022/shival99-z-ui-components-z-steps.mjs.map +1 -1
  45. package/fesm2022/shival99-z-ui-components-z-switch.mjs +131 -15
  46. package/fesm2022/shival99-z-ui-components-z-switch.mjs.map +1 -1
  47. package/fesm2022/shival99-z-ui-components-z-table.mjs +57 -13
  48. package/fesm2022/shival99-z-ui-components-z-table.mjs.map +1 -1
  49. package/fesm2022/shival99-z-ui-components-z-tabs.mjs +6 -6
  50. package/fesm2022/shival99-z-ui-components-z-tabs.mjs.map +1 -1
  51. package/fesm2022/shival99-z-ui-components-z-tags.mjs +1 -1
  52. package/fesm2022/shival99-z-ui-components-z-tags.mjs.map +1 -1
  53. package/fesm2022/shival99-z-ui-components-z-timeline.mjs +6 -6
  54. package/fesm2022/shival99-z-ui-components-z-timeline.mjs.map +1 -1
  55. package/fesm2022/shival99-z-ui-components-z-tooltip.mjs +4 -4
  56. package/fesm2022/shival99-z-ui-components-z-tooltip.mjs.map +1 -1
  57. package/fesm2022/shival99-z-ui-components-z-upload.mjs +5 -4
  58. package/fesm2022/shival99-z-ui-components-z-upload.mjs.map +1 -1
  59. package/fesm2022/shival99-z-ui-i18n.mjs +12 -0
  60. package/fesm2022/shival99-z-ui-i18n.mjs.map +1 -1
  61. package/fesm2022/shival99-z-ui-pipes.mjs +18 -0
  62. package/fesm2022/shival99-z-ui-pipes.mjs.map +1 -1
  63. package/fesm2022/shival99-z-ui-providers.mjs +30 -13
  64. package/fesm2022/shival99-z-ui-providers.mjs.map +1 -1
  65. package/fesm2022/shival99-z-ui-services.mjs +53 -29
  66. package/fesm2022/shival99-z-ui-services.mjs.map +1 -1
  67. package/fesm2022/z-ui.mjs +0 -4
  68. package/fesm2022/z-ui.mjs.map +1 -1
  69. package/package.json +6 -1
  70. package/types/shival99-z-ui-components-z-autocomplete.d.ts +25 -38
  71. package/types/shival99-z-ui-components-z-breadcrumb.d.ts +4 -4
  72. package/types/shival99-z-ui-components-z-button.d.ts +5 -4
  73. package/types/shival99-z-ui-components-z-chat.d.ts +148 -0
  74. package/types/shival99-z-ui-components-z-drawer.d.ts +3 -1
  75. package/types/shival99-z-ui-components-z-dropdown-menu.d.ts +2 -2
  76. package/types/shival99-z-ui-components-z-empty.d.ts +3 -3
  77. package/types/shival99-z-ui-components-z-filter.d.ts +2 -2
  78. package/types/shival99-z-ui-components-z-gallery.d.ts +6 -3
  79. package/types/shival99-z-ui-components-z-icon.d.ts +18 -304
  80. package/types/shival99-z-ui-components-z-input.d.ts +42 -1
  81. package/types/shival99-z-ui-components-z-modal.d.ts +4 -2
  82. package/types/shival99-z-ui-components-z-select.d.ts +5 -2
  83. package/types/shival99-z-ui-components-z-steps.d.ts +4 -4
  84. package/types/shival99-z-ui-components-z-switch.d.ts +25 -4
  85. package/types/shival99-z-ui-components-z-table.d.ts +2 -0
  86. package/types/shival99-z-ui-pipes.d.ts +2 -0
  87. package/types/shival99-z-ui-providers.d.ts +10 -16
  88. package/types/shival99-z-ui-services.d.ts +6 -1
  89. package/types/z-ui.d.ts +1 -2
@@ -18,7 +18,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
18
18
 
19
19
  const zCardVariants = cva([
20
20
  'block w-full',
21
- 'rounded-[6px] border border-border',
21
+ 'rounded-[0.375rem] border border-border',
22
22
  'bg-card text-card-foreground',
23
23
  'shadow-card',
24
24
  'transition-shadow duration-200',
@@ -1 +1 @@
1
- {"version":3,"file":"shival99-z-ui-components-z-card.mjs","sources":["../../../../libs/core-ui/components/z-card/directives/z-card-title.directive.ts","../../../../libs/core-ui/components/z-card/z-card.variants.ts","../../../../libs/core-ui/components/z-card/z-card.component.ts","../../../../libs/core-ui/components/z-card/z-card.component.html","../../../../libs/core-ui/components/z-card/shival99-z-ui-components-z-card.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[zCardTitle], [z-card-title]',\n standalone: true,\n})\nexport class ZCardTitleDirective {}\n","import { cva, type VariantProps } from 'class-variance-authority';\n\nexport const zCardVariants = cva(\n [\n 'block w-full',\n 'rounded-[6px] border border-border',\n 'bg-card text-card-foreground',\n 'shadow-card',\n 'transition-shadow duration-200',\n ],\n {\n variants: {\n zSize: {\n sm: '',\n default: '',\n lg: '',\n },\n },\n defaultVariants: {\n zSize: 'default',\n },\n }\n);\n\nexport const zCardHeaderVariants = cva(['flex items-center justify-between', 'transition-colors duration-200 w-full'], {\n variants: {\n zSize: {\n sm: 'px-3 py-2',\n default: 'px-4 py-3',\n lg: 'px-5 py-4',\n },\n zCollapsible: {\n true: 'cursor-pointer select-none hover:bg-muted/50',\n false: '',\n },\n zCollapsed: {\n true: 'border-b !border-transparent',\n false: 'border-b !border-border',\n },\n },\n defaultVariants: {\n zSize: 'default',\n zCollapsible: false,\n zCollapsed: false,\n },\n});\n\nexport const zCardTitleVariants = cva(['font-medium text-foreground w-full'], {\n variants: {\n zSize: {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n },\n zCollapsible: {\n true: '[&_*]:select-none',\n false: '',\n },\n },\n defaultVariants: {\n zSize: 'default',\n zCollapsible: false,\n },\n});\n\nexport const zCardContentVariants = cva([''], {\n variants: {\n zSize: {\n sm: 'p-3',\n default: 'p-4',\n lg: 'p-5',\n },\n },\n defaultVariants: {\n zSize: 'default',\n },\n});\n\nexport type ZCardVariants = VariantProps<typeof zCardVariants>;\nexport type ZCardHeaderVariants = VariantProps<typeof zCardHeaderVariants>;\nexport type ZCardTitleVariants = VariantProps<typeof zCardTitleVariants>;\nexport type ZCardContentVariants = VariantProps<typeof zCardContentVariants>;\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n ElementRef,\n input,\n model,\n output,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ZIconComponent } from '@shival99/z-ui/components/z-icon';\nimport { zMergeClasses, zTransform } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport { ZCardTitleDirective } from './directives/z-card-title.directive';\nimport type { ZCardSize } from './z-card.types';\nimport { zCardContentVariants, zCardHeaderVariants, zCardTitleVariants, zCardVariants } from './z-card.variants';\n\n@Component({\n selector: 'z-card',\n imports: [ZIconComponent],\n standalone: true,\n templateUrl: './z-card.component.html',\n styleUrl: './z-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'hostClasses()',\n },\n})\nexport class ZCardComponent {\n private readonly _customTitle = contentChild(ZCardTitleDirective);\n private readonly _customTitleContent = contentChild<ElementRef>('zCardTitle');\n\n public readonly zCollapsedChange = output<boolean>();\n\n public readonly class = input<ClassValue>('');\n public readonly zTitle = input<string>('');\n public readonly zSize = input<ZCardSize>('default');\n public readonly zCollapsible = input(false, { transform: zTransform });\n public readonly zHiddenIcon = input(false, { transform: zTransform });\n public readonly zCollapsed = model<boolean>(false);\n\n protected readonly isCollapsed = computed(() => {\n if (!this.zCollapsible()) {\n return false;\n }\n return this.zCollapsed();\n });\n\n protected readonly hasCustomTitle = computed(() => !!this._customTitle() || !!this._customTitleContent());\n protected readonly hostClasses = computed(() => zMergeClasses(zCardVariants({ zSize: this.zSize() }), this.class()));\n protected readonly headerClasses = computed(() =>\n zCardHeaderVariants({\n zSize: this.zSize(),\n zCollapsible: this.zCollapsible(),\n zCollapsed: this.isCollapsed(),\n })\n );\n\n protected readonly titleClasses = computed(() =>\n zCardTitleVariants({ zSize: this.zSize(), zCollapsible: this.zCollapsible() })\n );\n\n protected readonly contentClasses = computed(() => zCardContentVariants({ zSize: this.zSize() }));\n\n protected onHeaderClick(): void {\n if (!this.zCollapsible()) {\n return;\n }\n\n const newState = !this.zCollapsed();\n this.zCollapsed.set(newState);\n this.zCollapsedChange.emit(newState);\n }\n}\n","@if (zTitle() || zCollapsible() || hasCustomTitle()) {\n <div\n [class]=\"headerClasses()\"\n (click)=\"onHeaderClick()\"\n (keydown.enter)=\"onHeaderClick()\"\n (keydown.space)=\"onHeaderClick()\"\n [tabindex]=\"zCollapsible() ? 0 : -1\"\n [attr.role]=\"zCollapsible() ? 'button' : null\"\n [attr.aria-expanded]=\"zCollapsible() ? !isCollapsed() : null\">\n <span [class]=\"titleClasses()\">\n <ng-content select=\"[zCardTitle]\" />\n @if (!hasCustomTitle()) {\n {{ zTitle() }}\n }\n </span>\n @if (zCollapsible() && !zHiddenIcon()) {\n <z-icon\n zType=\"lucideChevronDown\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 transition-transform duration-200\"\n [class.rotate-180]=\"!isCollapsed()\" />\n }\n <ng-content select=\"[zCardExtra]\" />\n </div>\n}\n\n<div class=\"z-card-content\" [class.z-card-content-open]=\"!isCollapsed()\">\n <div class=\"z-card-content-inner\">\n <div [class]=\"contentClasses()\">\n <ng-content />\n </div>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shival99-z-ui-components-z-card.mjs","sources":["../../../../libs/core-ui/components/z-card/directives/z-card-title.directive.ts","../../../../libs/core-ui/components/z-card/z-card.variants.ts","../../../../libs/core-ui/components/z-card/z-card.component.ts","../../../../libs/core-ui/components/z-card/z-card.component.html","../../../../libs/core-ui/components/z-card/shival99-z-ui-components-z-card.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[zCardTitle], [z-card-title]',\n standalone: true,\n})\nexport class ZCardTitleDirective {}\n","import { cva, type VariantProps } from 'class-variance-authority';\n\nexport const zCardVariants = cva(\n [\n 'block w-full',\n 'rounded-[0.375rem] border border-border',\n 'bg-card text-card-foreground',\n 'shadow-card',\n 'transition-shadow duration-200',\n ],\n {\n variants: {\n zSize: {\n sm: '',\n default: '',\n lg: '',\n },\n },\n defaultVariants: {\n zSize: 'default',\n },\n }\n);\n\nexport const zCardHeaderVariants = cva(['flex items-center justify-between', 'transition-colors duration-200 w-full'], {\n variants: {\n zSize: {\n sm: 'px-3 py-2',\n default: 'px-4 py-3',\n lg: 'px-5 py-4',\n },\n zCollapsible: {\n true: 'cursor-pointer select-none hover:bg-muted/50',\n false: '',\n },\n zCollapsed: {\n true: 'border-b !border-transparent',\n false: 'border-b !border-border',\n },\n },\n defaultVariants: {\n zSize: 'default',\n zCollapsible: false,\n zCollapsed: false,\n },\n});\n\nexport const zCardTitleVariants = cva(['font-medium text-foreground w-full'], {\n variants: {\n zSize: {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n },\n zCollapsible: {\n true: '[&_*]:select-none',\n false: '',\n },\n },\n defaultVariants: {\n zSize: 'default',\n zCollapsible: false,\n },\n});\n\nexport const zCardContentVariants = cva([''], {\n variants: {\n zSize: {\n sm: 'p-3',\n default: 'p-4',\n lg: 'p-5',\n },\n },\n defaultVariants: {\n zSize: 'default',\n },\n});\n\nexport type ZCardVariants = VariantProps<typeof zCardVariants>;\nexport type ZCardHeaderVariants = VariantProps<typeof zCardHeaderVariants>;\nexport type ZCardTitleVariants = VariantProps<typeof zCardTitleVariants>;\nexport type ZCardContentVariants = VariantProps<typeof zCardContentVariants>;\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n ElementRef,\n input,\n model,\n output,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ZIconComponent } from '@shival99/z-ui/components/z-icon';\nimport { zMergeClasses, zTransform } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport { ZCardTitleDirective } from './directives/z-card-title.directive';\nimport type { ZCardSize } from './z-card.types';\nimport { zCardContentVariants, zCardHeaderVariants, zCardTitleVariants, zCardVariants } from './z-card.variants';\n\n@Component({\n selector: 'z-card',\n imports: [ZIconComponent],\n standalone: true,\n templateUrl: './z-card.component.html',\n styleUrl: './z-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'hostClasses()',\n },\n})\nexport class ZCardComponent {\n private readonly _customTitle = contentChild(ZCardTitleDirective);\n private readonly _customTitleContent = contentChild<ElementRef>('zCardTitle');\n\n public readonly zCollapsedChange = output<boolean>();\n\n public readonly class = input<ClassValue>('');\n public readonly zTitle = input<string>('');\n public readonly zSize = input<ZCardSize>('default');\n public readonly zCollapsible = input(false, { transform: zTransform });\n public readonly zHiddenIcon = input(false, { transform: zTransform });\n public readonly zCollapsed = model<boolean>(false);\n\n protected readonly isCollapsed = computed(() => {\n if (!this.zCollapsible()) {\n return false;\n }\n return this.zCollapsed();\n });\n\n protected readonly hasCustomTitle = computed(() => !!this._customTitle() || !!this._customTitleContent());\n protected readonly hostClasses = computed(() => zMergeClasses(zCardVariants({ zSize: this.zSize() }), this.class()));\n protected readonly headerClasses = computed(() =>\n zCardHeaderVariants({\n zSize: this.zSize(),\n zCollapsible: this.zCollapsible(),\n zCollapsed: this.isCollapsed(),\n })\n );\n\n protected readonly titleClasses = computed(() =>\n zCardTitleVariants({ zSize: this.zSize(), zCollapsible: this.zCollapsible() })\n );\n\n protected readonly contentClasses = computed(() => zCardContentVariants({ zSize: this.zSize() }));\n\n protected onHeaderClick(): void {\n if (!this.zCollapsible()) {\n return;\n }\n\n const newState = !this.zCollapsed();\n this.zCollapsed.set(newState);\n this.zCollapsedChange.emit(newState);\n }\n}\n","@if (zTitle() || zCollapsible() || hasCustomTitle()) {\n <div\n [class]=\"headerClasses()\"\n (click)=\"onHeaderClick()\"\n (keydown.enter)=\"onHeaderClick()\"\n (keydown.space)=\"onHeaderClick()\"\n [tabindex]=\"zCollapsible() ? 0 : -1\"\n [attr.role]=\"zCollapsible() ? 'button' : null\"\n [attr.aria-expanded]=\"zCollapsible() ? !isCollapsed() : null\">\n <span [class]=\"titleClasses()\">\n <ng-content select=\"[zCardTitle]\" />\n @if (!hasCustomTitle()) {\n {{ zTitle() }}\n }\n </span>\n @if (zCollapsible() && !zHiddenIcon()) {\n <z-icon\n zType=\"lucideChevronDown\"\n zSize=\"16\"\n class=\"text-muted-foreground shrink-0 transition-transform duration-200\"\n [class.rotate-180]=\"!isCollapsed()\" />\n }\n <ng-content select=\"[zCardExtra]\" />\n </div>\n}\n\n<div class=\"z-card-content\" [class.z-card-content-open]=\"!isCollapsed()\">\n <div class=\"z-card-content-inner\">\n <div [class]=\"contentClasses()\">\n <ng-content />\n </div>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,429 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, model, output, signal, viewChild, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from '@angular/forms';
4
+ import { FormsModule } from '@angular/forms';
5
+ import { TranslatePipe } from '@ngx-translate/core';
6
+ import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
7
+ import { ZModalComponent } from '@shival99/z-ui/components/z-modal';
8
+ import { zTransform, zMergeClasses, zUuid } from '@shival99/z-ui/utils';
9
+ import { NgScrollbar } from 'ngx-scrollbar';
10
+ import { cva } from 'class-variance-authority';
11
+
12
+ const zChatWrapperVariants = cva('z-chat fixed z-[95] pointer-events-none', {
13
+ variants: {
14
+ zPosition: {
15
+ 'bottom-right': '',
16
+ 'bottom-left': '',
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ zPosition: 'bottom-right',
21
+ },
22
+ });
23
+ const zChatPanelVariants = cva('absolute bottom-16 flex flex-col overflow-hidden rounded-2xl shadow-2xl transition-all duration-200', {
24
+ variants: {
25
+ zPosition: {
26
+ 'bottom-right': 'right-0 origin-bottom-right',
27
+ 'bottom-left': 'left-0 origin-bottom-left',
28
+ },
29
+ zSize: {
30
+ sm: 'h-[28rem] w-[20rem]',
31
+ default: 'h-[35rem] w-[25rem]',
32
+ lg: 'h-[39rem] w-[29rem]',
33
+ },
34
+ zOpen: {
35
+ true: 'pointer-events-auto visible translate-y-0 scale-100 opacity-100',
36
+ false: 'pointer-events-none invisible translate-y-3 scale-95 opacity-0',
37
+ },
38
+ },
39
+ defaultVariants: {
40
+ zPosition: 'bottom-right',
41
+ zSize: 'default',
42
+ zOpen: false,
43
+ },
44
+ });
45
+ const zChatFabVariants = cva('relative inline-flex size-14 items-center justify-center rounded-full shadow-lg ring-1 ring-black/5 transition-all duration-200 hover:scale-[1.03] active:scale-95', {
46
+ variants: {
47
+ zOpen: {
48
+ true: 'bg-background text-foreground border border-border shadow-xl dark:border-white/15 dark:bg-[#2b2b2b] dark:text-white',
49
+ false: 'from-primary via-primary to-primary/75 bg-gradient-to-br text-white shadow-xl',
50
+ },
51
+ },
52
+ defaultVariants: {
53
+ zOpen: false,
54
+ },
55
+ });
56
+
57
+ const DEFAULT_SUGGESTIONS = [
58
+ {
59
+ label: 'i18n_z_ui_chat_ai_suggestion_1',
60
+ prompt: 'Create release notes from recent commits',
61
+ icon: 'lucideSparkles',
62
+ },
63
+ {
64
+ label: 'i18n_z_ui_chat_ai_suggestion_2',
65
+ prompt: 'Suggest test cases for a new feature',
66
+ icon: 'lucideFlaskConical',
67
+ },
68
+ { label: 'i18n_z_ui_chat_ai_suggestion_3', prompt: 'Generate a concise PR summary', icon: 'lucideGitPullRequest' },
69
+ ];
70
+ class ZChatComponent {
71
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
72
+ zOpen = model(false, ...(ngDevMode ? [{ debugName: "zOpen" }] : []));
73
+ zMessages = model([], ...(ngDevMode ? [{ debugName: "zMessages" }] : []));
74
+ zTitle = input('i18n_z_ui_chat_ai_title', ...(ngDevMode ? [{ debugName: "zTitle" }] : []));
75
+ zSubtitle = input('i18n_z_ui_chat_ai_subtitle', ...(ngDevMode ? [{ debugName: "zSubtitle" }] : []));
76
+ zPlaceholder = input('i18n_z_ui_chat_ai_placeholder', ...(ngDevMode ? [{ debugName: "zPlaceholder" }] : []));
77
+ zPosition = input('bottom-right', ...(ngDevMode ? [{ debugName: "zPosition" }] : []));
78
+ zOffset = input({}, ...(ngDevMode ? [{ debugName: "zOffset" }] : []));
79
+ zSize = input('default', ...(ngDevMode ? [{ debugName: "zSize" }] : []));
80
+ zSuggestions = input(DEFAULT_SUGGESTIONS, ...(ngDevMode ? [{ debugName: "zSuggestions" }] : []));
81
+ zShowSuggestions = input(true, { ...(ngDevMode ? { debugName: "zShowSuggestions" } : {}), transform: zTransform });
82
+ zShowPulse = input(true, { ...(ngDevMode ? { debugName: "zShowPulse" } : {}), transform: zTransform });
83
+ zDisabled = input(false, { ...(ngDevMode ? { debugName: "zDisabled" } : {}), transform: zTransform });
84
+ zLoading = input(false, { ...(ngDevMode ? { debugName: "zLoading" } : {}), transform: zTransform });
85
+ zAllowAttachments = input(true, { ...(ngDevMode ? { debugName: "zAllowAttachments" } : {}), transform: zTransform });
86
+ zAcceptedFiles = input('image/*,.pdf,.doc,.docx,.txt,.csv,.xlsx', ...(ngDevMode ? [{ debugName: "zAcceptedFiles" }] : []));
87
+ zAutoReply = input(true, { ...(ngDevMode ? { debugName: "zAutoReply" } : {}), transform: zTransform });
88
+ zAutoReplyDelay = input(1200, ...(ngDevMode ? [{ debugName: "zAutoReplyDelay" }] : []));
89
+ zFabIcon = input('lucideMessageSquareDot', ...(ngDevMode ? [{ debugName: "zFabIcon" }] : []));
90
+ zBotIcon = input('lucideBot', ...(ngDevMode ? [{ debugName: "zBotIcon" }] : []));
91
+ zSendIcon = input('lucideArrowUp', ...(ngDevMode ? [{ debugName: "zSendIcon" }] : []));
92
+ zSend = output();
93
+ zResponse = output();
94
+ zToggle = output();
95
+ zClear = output();
96
+ draftMessage = signal('', ...(ngDevMode ? [{ debugName: "draftMessage" }] : []));
97
+ showRipple = signal(false, ...(ngDevMode ? [{ debugName: "showRipple" }] : []));
98
+ attachments = signal([], ...(ngDevMode ? [{ debugName: "attachments" }] : []));
99
+ isComposerExpanded = signal(false, ...(ngDevMode ? [{ debugName: "isComposerExpanded" }] : []));
100
+ isComposerOverflowing = signal(false, ...(ngDevMode ? [{ debugName: "isComposerOverflowing" }] : []));
101
+ isPreviewVisible = signal(false, ...(ngDevMode ? [{ debugName: "isPreviewVisible" }] : []));
102
+ previewImage = signal(null, ...(ngDevMode ? [{ debugName: "previewImage" }] : []));
103
+ _mockTyping = signal(false, ...(ngDevMode ? [{ debugName: "_mockTyping" }] : []));
104
+ _messagesScrollbarRef = viewChild('messagesScrollbar', ...(ngDevMode ? [{ debugName: "_messagesScrollbarRef" }] : []));
105
+ _chatInputRef = viewChild('chatInput', ...(ngDevMode ? [{ debugName: "_chatInputRef" }] : []));
106
+ _fileInputRef = viewChild('fileInput', ...(ngDevMode ? [{ debugName: "_fileInputRef" }] : []));
107
+ _mockReplyTimer = null;
108
+ _rippleTimer = null;
109
+ _scrollTimer = null;
110
+ wrapperClasses = computed(() => zMergeClasses(zChatWrapperVariants({ zPosition: this.zPosition() }), this.class()), ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : []));
111
+ wrapperTop = computed(() => this._resolveOffsetValue('top'), ...(ngDevMode ? [{ debugName: "wrapperTop" }] : []));
112
+ wrapperRight = computed(() => this._resolveOffsetValue('right'), ...(ngDevMode ? [{ debugName: "wrapperRight" }] : []));
113
+ wrapperBottom = computed(() => this._resolveOffsetValue('bottom'), ...(ngDevMode ? [{ debugName: "wrapperBottom" }] : []));
114
+ wrapperLeft = computed(() => this._resolveOffsetValue('left'), ...(ngDevMode ? [{ debugName: "wrapperLeft" }] : []));
115
+ panelClasses = computed(() => zChatPanelVariants({
116
+ zPosition: this.zPosition(),
117
+ zSize: this.zSize(),
118
+ zOpen: this.zOpen(),
119
+ }), ...(ngDevMode ? [{ debugName: "panelClasses" }] : []));
120
+ fabClasses = computed(() => zChatFabVariants({
121
+ zOpen: this.zOpen(),
122
+ }), ...(ngDevMode ? [{ debugName: "fabClasses" }] : []));
123
+ isTyping = computed(() => this.zLoading() || this._mockTyping(), ...(ngDevMode ? [{ debugName: "isTyping" }] : []));
124
+ canSend = computed(() => (!!this.draftMessage().trim() || this.attachments().length > 0) && !this.zDisabled() && !this.isTyping(), ...(ngDevMode ? [{ debugName: "canSend" }] : []));
125
+ hasMessages = computed(() => this.zMessages().length > 0, ...(ngDevMode ? [{ debugName: "hasMessages" }] : []));
126
+ showEmptyState = computed(() => !this.hasMessages() && this.zShowSuggestions(), ...(ngDevMode ? [{ debugName: "showEmptyState" }] : []));
127
+ previewImageSizeLabel = computed(() => {
128
+ const preview = this.previewImage();
129
+ return preview ? this.formatFileSize(preview.size) : '';
130
+ }, ...(ngDevMode ? [{ debugName: "previewImageSizeLabel" }] : []));
131
+ ngOnDestroy() {
132
+ if (this._mockReplyTimer) {
133
+ clearTimeout(this._mockReplyTimer);
134
+ }
135
+ if (this._rippleTimer) {
136
+ clearTimeout(this._rippleTimer);
137
+ }
138
+ if (this._scrollTimer) {
139
+ clearTimeout(this._scrollTimer);
140
+ }
141
+ const filesInMessages = this.zMessages().flatMap(item => item.files ?? []);
142
+ this._releaseAttachmentUrls(filesInMessages);
143
+ this._releaseAttachmentUrls(this.attachments());
144
+ }
145
+ open() {
146
+ if (this.zOpen()) {
147
+ return;
148
+ }
149
+ this._toggle(true);
150
+ }
151
+ close() {
152
+ if (!this.zOpen()) {
153
+ return;
154
+ }
155
+ this._toggle(false);
156
+ }
157
+ clearMessages() {
158
+ const filesInMessages = this.zMessages().flatMap(item => item.files ?? []);
159
+ this._releaseAttachmentUrls(filesInMessages);
160
+ this.zMessages.set([]);
161
+ this.zClear.emit();
162
+ }
163
+ onToggle() {
164
+ this._toggle(!this.zOpen());
165
+ }
166
+ onSuggestionSelect(item) {
167
+ this.draftMessage.set((item.prompt ?? item.label).trim());
168
+ this.onSendMessage();
169
+ }
170
+ onClickAttach() {
171
+ this._fileInputRef()?.nativeElement.click();
172
+ }
173
+ onFileChange(event) {
174
+ const inputEl = event.target;
175
+ const { files } = inputEl;
176
+ if (!files || files.length === 0) {
177
+ return;
178
+ }
179
+ this._appendFiles(Array.from(files));
180
+ inputEl.value = '';
181
+ }
182
+ onTextareaPaste(event) {
183
+ if (!this.zAllowAttachments()) {
184
+ return;
185
+ }
186
+ const items = event.clipboardData?.items;
187
+ if (!items || items.length === 0) {
188
+ return;
189
+ }
190
+ const files = [];
191
+ Array.from(items).forEach(item => {
192
+ if (item.kind === 'file') {
193
+ const file = item.getAsFile();
194
+ if (file) {
195
+ files.push(file);
196
+ }
197
+ }
198
+ });
199
+ if (files.length > 0) {
200
+ event.preventDefault();
201
+ this._appendFiles(files);
202
+ }
203
+ }
204
+ removeAttachment(id) {
205
+ const target = this.attachments().find(item => item.id === id);
206
+ if (target?.previewUrl) {
207
+ URL.revokeObjectURL(target.previewUrl);
208
+ }
209
+ this.attachments.update(files => files.filter(item => item.id !== id));
210
+ }
211
+ formatFileSize(size) {
212
+ if (size < 1024) {
213
+ return `${size} B`;
214
+ }
215
+ if (size < 1024 * 1024) {
216
+ return `${(size / 1024).toFixed(1)} KB`;
217
+ }
218
+ if (size < 1024 * 1024 * 1024) {
219
+ return `${(size / (1024 * 1024)).toFixed(1)} MB`;
220
+ }
221
+ return `${(size / (1024 * 1024 * 1024)).toFixed(1)} GB`;
222
+ }
223
+ isImageAttachment(file) {
224
+ return file.type.startsWith('image/');
225
+ }
226
+ openImagePreview(file) {
227
+ if (!file.previewUrl || !this.isImageAttachment(file)) {
228
+ return;
229
+ }
230
+ this.previewImage.set({
231
+ url: file.previewUrl,
232
+ name: file.name,
233
+ size: file.size,
234
+ });
235
+ this.isPreviewVisible.set(true);
236
+ }
237
+ closeImagePreview() {
238
+ setTimeout(() => {
239
+ this.isPreviewVisible.set(false);
240
+ this.previewImage.set(null);
241
+ }, 300);
242
+ }
243
+ onInputKeydown(event) {
244
+ if (event.key === 'Enter' && !event.shiftKey) {
245
+ event.preventDefault();
246
+ this.onSendMessage();
247
+ }
248
+ }
249
+ onTextareaInput(event) {
250
+ const textarea = event.target;
251
+ textarea.style.height = 'auto';
252
+ const nextHeight = Math.min(textarea.scrollHeight, 66);
253
+ textarea.style.height = `${nextHeight}px`;
254
+ textarea.style.overflowY = textarea.scrollHeight > 66 ? 'auto' : 'hidden';
255
+ this.isComposerExpanded.set(nextHeight > 44 || textarea.value.includes('\n'));
256
+ this.isComposerOverflowing.set(textarea.scrollHeight > nextHeight + 1);
257
+ }
258
+ onSendMessage() {
259
+ const message = this.draftMessage().trim();
260
+ if (!message && this.attachments().length === 0) {
261
+ return;
262
+ }
263
+ if (!this.canSend()) {
264
+ return;
265
+ }
266
+ const attachedFiles = this.attachments().map(file => ({
267
+ ...file,
268
+ // Keep message preview URLs alive after composer files are cleared.
269
+ previewUrl: this._createMessagePreviewUrl(file),
270
+ file: undefined,
271
+ }));
272
+ const messageContent = message || `Attached ${attachedFiles.length} file(s).`;
273
+ const userMessage = this._createMessage('user', messageContent, attachedFiles);
274
+ const nextMessages = [...this.zMessages(), userMessage];
275
+ this.zMessages.set(nextMessages);
276
+ requestAnimationFrame(() => this._scrollToBottom());
277
+ this.draftMessage.set('');
278
+ this._releaseAttachmentUrls(this.attachments());
279
+ this.attachments.set([]);
280
+ const inputEl = this._chatInputRef()?.nativeElement;
281
+ if (inputEl) {
282
+ inputEl.style.height = '66px';
283
+ inputEl.style.overflowY = 'hidden';
284
+ }
285
+ this.isComposerExpanded.set(false);
286
+ this.isComposerOverflowing.set(false);
287
+ this.zSend.emit({ message: messageContent, files: attachedFiles, messages: nextMessages });
288
+ if (this.zAutoReply()) {
289
+ this._simulateReply(messageContent, attachedFiles.length);
290
+ }
291
+ this._focusInputSoon();
292
+ }
293
+ _toggle(isOpen) {
294
+ this.zOpen.set(isOpen);
295
+ this.zToggle.emit(isOpen);
296
+ this._triggerRipple();
297
+ if (isOpen) {
298
+ this._focusInputSoon();
299
+ requestAnimationFrame(() => {
300
+ this._scheduleScrollToBottom(250);
301
+ });
302
+ }
303
+ }
304
+ _createMessage(role, content, files) {
305
+ return {
306
+ id: zUuid(),
307
+ role,
308
+ content,
309
+ files,
310
+ createdAt: Date.now(),
311
+ };
312
+ }
313
+ _simulateReply(userMessage, fileCount) {
314
+ if (this._mockReplyTimer) {
315
+ clearTimeout(this._mockReplyTimer);
316
+ }
317
+ this._mockTyping.set(true);
318
+ const delay = Math.max(200, this.zAutoReplyDelay());
319
+ this._mockReplyTimer = setTimeout(() => {
320
+ this._mockTyping.set(false);
321
+ const botMessage = this._createMessage('assistant', this._buildMockReply(userMessage, fileCount));
322
+ this.zMessages.update(messages => [...messages, botMessage]);
323
+ this.zResponse.emit(botMessage);
324
+ requestAnimationFrame(() => this._scrollToBottom());
325
+ }, delay);
326
+ }
327
+ _buildMockReply(message, fileCount) {
328
+ const normalized = message.toLowerCase();
329
+ if (fileCount > 0) {
330
+ return `Received ${fileCount} attachment(s). I can summarize, extract key points, or draft a reply from these files.`;
331
+ }
332
+ if (normalized.includes('deploy') || normalized.includes('release')) {
333
+ return 'Deployment checklist: run lint, build artifact, smoke test staging, then promote to production.';
334
+ }
335
+ if (normalized.includes('bug') || normalized.includes('error')) {
336
+ return 'Please share logs, repro steps, expected behavior, and current environment so I can triage precisely.';
337
+ }
338
+ if (normalized.includes('test')) {
339
+ return 'I suggest coverage for happy path, validation failures, edge cases, and retry/error handling.';
340
+ }
341
+ return 'Got it. I can help you break this task into actionable steps and propose code changes.';
342
+ }
343
+ _triggerRipple() {
344
+ this.showRipple.set(true);
345
+ if (this._rippleTimer) {
346
+ clearTimeout(this._rippleTimer);
347
+ }
348
+ this._rippleTimer = setTimeout(() => this.showRipple.set(false), 350);
349
+ }
350
+ onMessagesScrollbarInit() {
351
+ requestAnimationFrame(() => this._scrollToBottom());
352
+ }
353
+ onEscapeKey() {
354
+ if (this.previewImage()) {
355
+ this.closeImagePreview();
356
+ }
357
+ }
358
+ _scheduleScrollToBottom(delay = 0) {
359
+ if (this._scrollTimer) {
360
+ clearTimeout(this._scrollTimer);
361
+ }
362
+ this._scrollTimer = setTimeout(() => {
363
+ this._scrollToBottom();
364
+ }, delay);
365
+ }
366
+ _scrollToBottom() {
367
+ const scrollbar = this._messagesScrollbarRef();
368
+ if (!scrollbar) {
369
+ return;
370
+ }
371
+ void scrollbar.scrollTo({ bottom: 0, duration: 300, easing: { x1: 0.25, y1: 0.1, x2: 0.25, y2: 1 } });
372
+ }
373
+ _focusInputSoon() {
374
+ setTimeout(() => this._chatInputRef()?.nativeElement.focus(), 50);
375
+ }
376
+ _releaseAttachmentUrls(files) {
377
+ files.forEach(file => {
378
+ if (file.previewUrl) {
379
+ URL.revokeObjectURL(file.previewUrl);
380
+ }
381
+ });
382
+ }
383
+ _appendFiles(files) {
384
+ const nextFiles = files.map(file => ({
385
+ id: zUuid(),
386
+ name: file.name,
387
+ size: file.size,
388
+ type: file.type,
389
+ previewUrl: file.type.startsWith('image/') ? URL.createObjectURL(file) : undefined,
390
+ file,
391
+ }));
392
+ this.attachments.update(current => [...current, ...nextFiles]);
393
+ }
394
+ _createMessagePreviewUrl(file) {
395
+ if (!this.isImageAttachment(file)) {
396
+ return undefined;
397
+ }
398
+ if (file.file) {
399
+ return URL.createObjectURL(file.file);
400
+ }
401
+ return file.previewUrl;
402
+ }
403
+ _resolveOffsetValue(side) {
404
+ const override = this.zOffset()[side];
405
+ if (override !== undefined && override !== null && override !== '') {
406
+ return typeof override === 'number' ? `${override}px` : String(override);
407
+ }
408
+ const defaults = this.zPosition() === 'bottom-left'
409
+ ? { top: null, right: null, bottom: '1.25rem', left: '1.5rem' }
410
+ : { top: null, right: '1.5rem', bottom: '1.25rem', left: null };
411
+ return defaults[side];
412
+ }
413
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
414
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ZChatComponent, isStandalone: true, selector: "z-chat", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zOpen: { classPropertyName: "zOpen", publicName: "zOpen", isSignal: true, isRequired: false, transformFunction: null }, zMessages: { classPropertyName: "zMessages", publicName: "zMessages", 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 }, zPlaceholder: { classPropertyName: "zPlaceholder", publicName: "zPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, zPosition: { classPropertyName: "zPosition", publicName: "zPosition", isSignal: true, isRequired: false, transformFunction: null }, zOffset: { classPropertyName: "zOffset", publicName: "zOffset", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zSuggestions: { classPropertyName: "zSuggestions", publicName: "zSuggestions", isSignal: true, isRequired: false, transformFunction: null }, zShowSuggestions: { classPropertyName: "zShowSuggestions", publicName: "zShowSuggestions", isSignal: true, isRequired: false, transformFunction: null }, zShowPulse: { classPropertyName: "zShowPulse", publicName: "zShowPulse", isSignal: true, isRequired: false, transformFunction: null }, zDisabled: { classPropertyName: "zDisabled", publicName: "zDisabled", isSignal: true, isRequired: false, transformFunction: null }, zLoading: { classPropertyName: "zLoading", publicName: "zLoading", isSignal: true, isRequired: false, transformFunction: null }, zAllowAttachments: { classPropertyName: "zAllowAttachments", publicName: "zAllowAttachments", isSignal: true, isRequired: false, transformFunction: null }, zAcceptedFiles: { classPropertyName: "zAcceptedFiles", publicName: "zAcceptedFiles", isSignal: true, isRequired: false, transformFunction: null }, zAutoReply: { classPropertyName: "zAutoReply", publicName: "zAutoReply", isSignal: true, isRequired: false, transformFunction: null }, zAutoReplyDelay: { classPropertyName: "zAutoReplyDelay", publicName: "zAutoReplyDelay", isSignal: true, isRequired: false, transformFunction: null }, zFabIcon: { classPropertyName: "zFabIcon", publicName: "zFabIcon", isSignal: true, isRequired: false, transformFunction: null }, zBotIcon: { classPropertyName: "zBotIcon", publicName: "zBotIcon", isSignal: true, isRequired: false, transformFunction: null }, zSendIcon: { classPropertyName: "zSendIcon", publicName: "zSendIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOpen: "zOpenChange", zMessages: "zMessagesChange", zSend: "zSend", zResponse: "zResponse", zToggle: "zToggle", zClear: "zClear" }, host: { listeners: { "document:keydown.escape": "onEscapeKey()" }, classAttribute: "z-chat block" }, viewQueries: [{ propertyName: "_messagesScrollbarRef", first: true, predicate: ["messagesScrollbar"], descendants: true, isSignal: true }, { propertyName: "_chatInputRef", first: true, predicate: ["chatInput"], descendants: true, isSignal: true }, { propertyName: "_fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], exportAs: ["zChat"], ngImport: i0, template: "<div\n [class]=\"wrapperClasses()\"\n [style.top]=\"wrapperTop()\"\n [style.right]=\"wrapperRight()\"\n [style.bottom]=\"wrapperBottom()\"\n [style.left]=\"wrapperLeft()\">\n <div class=\"relative\">\n <section class=\"z-chat-panel-shell\" [class]=\"panelClasses()\">\n <header class=\"from-primary/95 to-primary/75 text-primary-foreground bg-gradient-to-r px-4 py-3.5\">\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <span\n class=\"bg-primary-foreground/15 relative inline-flex size-8 shrink-0 items-center justify-center rounded-full\">\n <z-icon [zType]=\"zBotIcon()\" zSize=\"16\" class=\"text-primary-foreground\" />\n <span\n class=\"ring-primary inline-block size-2.5 rounded-full bg-emerald-300 ring-2\"\n style=\"position: absolute; right: -0.0625rem; bottom: -0.0625rem\"></span>\n </span>\n <h3 class=\"truncate text-sm font-semibold\">{{ zTitle() | translate }}</h3>\n </div>\n </div>\n <div class=\"flex items-center gap-1\">\n <button\n type=\"button\"\n class=\"text-primary-foreground/90 hover:bg-primary-foreground/15 inline-flex size-8 cursor-pointer items-center justify-center rounded-md transition\"\n (click)=\"clearMessages()\"\n title=\"{{ 'i18n_z_ui_chat_ai_new_chat' | translate }}\">\n <z-icon zType=\"lucideRefreshCcw\" zSize=\"17\" />\n </button>\n <button\n type=\"button\"\n class=\"text-primary-foreground/90 hover:bg-primary-foreground/15 inline-flex size-8 cursor-pointer items-center justify-center rounded-md transition\"\n (click)=\"close()\"\n title=\"{{ 'i18n_z_ui_chat_ai_close' | translate }}\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"18\" />\n </button>\n </div>\n </div>\n </header>\n\n <div class=\"z-chat-lower-shell\">\n <ng-scrollbar\n #messagesScrollbar\n (afterInit)=\"onMessagesScrollbarInit()\"\n class=\"z-chat-scrollbar z-chat-content-surface flex-1 overflow-x-hidden\"\n track=\"vertical\"\n orientation=\"vertical\"\n appearance=\"compact\"\n visibility=\"hover\">\n <div class=\"z-chat-messages\">\n @if (hasMessages()) {\n @for (item of zMessages(); track item.id) {\n <div\n class=\"z-chat-message z-chat-message--enter\"\n [class.justify-end]=\"item.role === 'user'\"\n [class.justify-start]=\"item.role === 'assistant'\">\n <div\n class=\"z-chat-message-bubble max-w-[88%] min-w-0 rounded-2xl px-3 py-2.5 text-sm leading-5 [overflow-wrap:anywhere] break-all shadow-xs\"\n [class.bg-primary]=\"item.role === 'user'\"\n [class.text-primary-foreground]=\"item.role === 'user'\"\n [class.rounded-br-md]=\"item.role === 'user'\"\n [class.bg-background]=\"item.role === 'assistant'\"\n [class.border-border/60]=\"item.role === 'assistant'\"\n [class.text-foreground]=\"item.role === 'assistant'\"\n [class.rounded-bl-md]=\"item.role === 'assistant'\"\n [class.border]=\"item.role === 'assistant'\">\n @if (item.files && item.files.length > 0) {\n <div class=\"mb-2 flex flex-col gap-1.5\">\n @for (file of item.files; track file.id) {\n <div\n class=\"flex items-center gap-2 rounded-[0.5rem] px-2 py-1.5 text-xs\"\n [class.bg-white/15]=\"item.role === 'user'\"\n [class.bg-muted/40]=\"item.role === 'assistant'\">\n @if (isImageAttachment(file) && file.previewUrl) {\n <img\n [src]=\"file.previewUrl\"\n [alt]=\"file.name\"\n class=\"size-8 cursor-pointer rounded-[0.5rem] object-cover\"\n (click)=\"openImagePreview(file)\"\n title=\"Click to preview\" />\n } @else {\n <span\n class=\"bg-background/80 text-muted-foreground inline-flex size-8 items-center justify-center rounded-[0.5rem]\"\n [class.bg-white/20]=\"item.role === 'user'\"\n [class.text-white]=\"item.role === 'user'\">\n <z-icon zType=\"lucideFileText\" zSize=\"14\" />\n </span>\n }\n <div class=\"min-w-0 flex-1\">\n <p class=\"truncate text-[0.6875rem] font-medium\">{{ file.name }}</p>\n <p class=\"truncate text-[0.625rem] opacity-80\">{{ formatFileSize(file.size) }}</p>\n </div>\n </div>\n }\n </div>\n }\n {{ item.content }}\n </div>\n </div>\n }\n } @else if (showEmptyState()) {\n <div class=\"flex h-full min-h-60 flex-col items-center justify-center px-2 text-center\">\n <div\n class=\"from-primary/20 to-primary/5 mb-3 inline-flex size-14 items-center justify-center rounded-full bg-gradient-to-br\">\n <z-icon zType=\"lucideBot\" zSize=\"28\" class=\"text-primary\" />\n </div>\n <h4 class=\"text-foreground text-sm font-semibold\">{{ 'i18n_z_ui_chat_ai_empty_title' | translate }}</h4>\n <p class=\"text-muted-foreground mt-1 text-xs\">{{ 'i18n_z_ui_chat_ai_empty_desc' | translate }}</p>\n\n @if (zSuggestions().length > 0) {\n <div class=\"mt-4 flex w-full flex-col gap-2\">\n @for (item of zSuggestions(); track item.label) {\n <button\n type=\"button\"\n class=\"z-chat-suggestion-item bg-background/95 hover:bg-background border-border/60 text-foreground flex w-full cursor-pointer items-center gap-2 rounded-xl border px-3 py-2 text-left text-xs transition hover:shadow-sm\"\n [style.animation-delay.ms]=\"$index * 70\"\n (click)=\"onSuggestionSelect(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon!\" zSize=\"14\" class=\"text-primary shrink-0\" />\n }\n <span class=\"line-clamp-2\">{{ item.label | translate }}</span>\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (isTyping()) {\n <div class=\"z-chat-message z-chat-message--enter justify-start\">\n <div class=\"bg-background border-border/60 rounded-2xl rounded-bl-md border px-3 py-2\">\n <div class=\"flex items-center gap-1\">\n <span class=\"bg-muted-foreground/60 inline-block size-1.5 animate-bounce rounded-full\"></span>\n <span\n class=\"bg-muted-foreground/60 inline-block size-1.5 animate-bounce rounded-full\"\n style=\"animation-delay: 0.15s\"></span>\n <span\n class=\"bg-muted-foreground/60 inline-block size-1.5 animate-bounce rounded-full\"\n style=\"animation-delay: 0.3s\"></span>\n </div>\n </div>\n </div>\n }\n </div>\n </ng-scrollbar>\n\n <footer class=\"z-chat-footer-surface p-3\">\n @if (attachments().length > 0) {\n <div class=\"mb-2 flex max-h-32 flex-col gap-2 overflow-y-auto pr-1\">\n @for (file of attachments(); track file.id) {\n <div\n class=\"bg-muted/45 border-border/55 relative flex w-full items-center gap-2 rounded-[0.5rem] border px-2 py-1.5\">\n @if (isImageAttachment(file) && file.previewUrl) {\n <img\n [src]=\"file.previewUrl\"\n [alt]=\"file.name\"\n class=\"size-8 shrink-0 cursor-pointer rounded-[0.5rem] object-cover\"\n (click)=\"openImagePreview(file)\"\n title=\"Click to preview\" />\n } @else {\n <span\n class=\"bg-background text-muted-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-[0.5rem]\">\n <z-icon zType=\"lucideFileText\" zSize=\"14\" />\n </span>\n }\n <div class=\"min-w-0 flex-1\">\n <p class=\"truncate text-[0.6875rem] font-medium\">{{ file.name }}</p>\n <p class=\"text-muted-foreground truncate text-[0.625rem]\">{{ formatFileSize(file.size) }}</p>\n </div>\n <button\n type=\"button\"\n class=\"bg-background/80 hover:bg-background text-muted-foreground inline-flex size-5 cursor-pointer items-center justify-center rounded-full transition\"\n (click)=\"removeAttachment(file.id)\">\n <z-icon zType=\"lucideX\" zSize=\"12\" />\n </button>\n </div>\n }\n </div>\n }\n\n <div class=\"z-chat-composer-shell\">\n <div class=\"z-chat-composer-main\" [class.z-chat-composer__field--overflow]=\"isComposerOverflowing()\">\n <textarea\n #chatInput\n class=\"z-chat-composer-textarea\"\n [placeholder]=\"zPlaceholder() | translate\"\n [disabled]=\"zDisabled()\"\n [ngModel]=\"draftMessage()\"\n (ngModelChange)=\"draftMessage.set($event)\"\n (input)=\"onTextareaInput($event)\"\n (paste)=\"onTextareaPaste($event)\"\n (keydown)=\"onInputKeydown($event)\"\n rows=\"3\"></textarea>\n </div>\n\n <div class=\"z-chat-composer-toolbar\">\n <div class=\"z-chat-composer-toolbar-left\">\n @if (zAllowAttachments()) {\n <input\n #fileInput\n type=\"file\"\n class=\"hidden\"\n [attr.accept]=\"zAcceptedFiles()\"\n multiple\n (change)=\"onFileChange($event)\" />\n <button\n type=\"button\"\n class=\"z-chat-composer-tool-btn\"\n [disabled]=\"zDisabled()\"\n (click)=\"onClickAttach()\"\n title=\"{{ 'i18n_z_ui_chat_ai_attach' | translate }}\">\n <z-icon zType=\"lucidePlus\" zSize=\"18\" />\n </button>\n }\n </div>\n\n <div class=\"z-chat-composer-toolbar-right\">\n <button\n type=\"button\"\n class=\"z-chat-composer-send-btn\"\n [disabled]=\"!canSend()\"\n (click)=\"onSendMessage()\"\n title=\"{{ 'i18n_z_ui_chat_ai_send' | translate }}\">\n <z-icon\n [zType]=\"isTyping() ? 'lucideLoaderCircle' : zSendIcon()\"\n zSize=\"16\"\n [class]=\"isTyping() ? 'animate-spin' : ''\" />\n </button>\n </div>\n </div>\n </div>\n </footer>\n </div>\n\n <z-modal\n [zVisible]=\"isPreviewVisible()\"\n [zTitle]=\"previewImage()?.name\"\n [zDescription]=\"previewImageSizeLabel()\"\n zWidth=\"min(92vw, 720px)\"\n [zHideFooter]=\"true\"\n [zMaskClosable]=\"true\"\n zOverlay=\"blur\"\n (zCancel)=\"closeImagePreview()\">\n <div class=\"z-chat-preview-modal-body\">\n <img [src]=\"previewImage()?.url\" [alt]=\"previewImage()?.name\" class=\"z-chat-preview-image\" />\n </div>\n </z-modal>\n </section>\n\n <button\n type=\"button\"\n class=\"pointer-events-auto cursor-pointer\"\n [class]=\"fabClasses()\"\n (click)=\"onToggle()\"\n [attr.aria-expanded]=\"zOpen()\"\n [attr.aria-label]=\"'i18n_z_ui_chat_ai_toggle' | translate\"\n title=\"{{ 'i18n_z_ui_chat_ai_toggle' | translate }}\">\n @if (zShowPulse() && !zOpen()) {\n <span class=\"bg-primary/30 absolute inset-0 animate-ping rounded-full\"></span>\n }\n\n @if (showRipple()) {\n <span class=\"bg-primary-foreground/30 absolute inset-0 animate-ping rounded-full\"></span>\n }\n\n <z-icon\n [zType]=\"zOpen() ? 'lucideX' : zFabIcon()\"\n zSize=\"24\"\n class=\"relative z-1 transition-transform duration-200\"\n [class.rotate-180]=\"zOpen()\" />\n </button>\n </div>\n</div>\n", styles: [".z-chat textarea{scrollbar-width:thin}.z-chat-panel-shell{box-shadow:0 0 28px #00000024!important}:is(.dark,[data-theme=dark]) .z-chat-panel-shell{box-shadow:0 0 28px #00000057!important}.z-chat-composer__field--overflow:after{position:absolute;right:0;bottom:0;left:0;height:1rem;pointer-events:none;content:\"\";background:linear-gradient(to top,var(--background) 22%,transparent)}.z-chat-composer-shell{position:relative;display:flex;width:100%;flex-direction:column;border:1px solid color-mix(in oklab,var(--border) 82%,transparent);border-radius:1rem;background:linear-gradient(180deg,color-mix(in oklab,var(--card) 98%,var(--background) 2%),color-mix(in oklab,var(--card) 92%,var(--background) 8%));box-shadow:0 6px 18px #00000014;transition:box-shadow .2s ease}.z-chat-composer-shell:focus-within{box-shadow:0 6px 18px #00000014}:is(.dark,[data-theme=dark]) .z-chat-composer-shell{border-color:var(--border);background:linear-gradient(180deg,color-mix(in oklab,var(--card) 96%,var(--background) 4%),color-mix(in oklab,var(--card) 88%,var(--background) 12%));box-shadow:0 10px 24px #00000057}.z-chat-composer-main{position:relative;overflow:hidden;padding:.7rem .35rem .45rem .85rem}.z-chat-composer-textarea{width:100%;height:4.125rem;max-height:4.125rem;border:none;background:transparent;resize:none;overflow-x:hidden;font-size:.875rem;line-height:1.4rem;color:var(--foreground);outline:none;padding-right:.2rem;scrollbar-width:thin;overflow-wrap:anywhere;word-break:break-word}.z-chat-composer-textarea::placeholder{color:var(--muted-foreground)}.z-chat-composer-textarea::-webkit-scrollbar{width:.375rem}.z-chat-composer-textarea::-webkit-scrollbar-track{background:transparent}.z-chat-composer-textarea::-webkit-scrollbar-thumb{border-radius:62.4375rem;background:#64748b73}:is(.dark,[data-theme=dark]) .z-chat-composer-textarea::-webkit-scrollbar-thumb{background:#94a3b88c}.z-chat-composer-toolbar{display:flex;align-items:center;justify-content:space-between;border-top:.0625rem solid rgba(219,219,219,.6);padding:.55rem .7rem .65rem}:is(.dark,[data-theme=dark]) .z-chat-composer-toolbar{border-top-color:#00000038}.z-chat-composer-toolbar-left,.z-chat-composer-toolbar-right{display:flex;align-items:center}.z-chat-composer-tool-btn{display:inline-flex;height:1.75rem;width:1.75rem;cursor:pointer;align-items:center;justify-content:center;border-radius:.6rem;border:none;background:transparent;color:#374151;transition:background-color .2s ease}.z-chat-composer-tool-btn:hover{background:#0000000f}:is(.dark,[data-theme=dark]) .z-chat-composer-tool-btn{color:#e5e7ebe6}:is(.dark,[data-theme=dark]) .z-chat-composer-tool-btn:hover{background:#ffffff1a}.z-chat-composer-tool-btn:disabled{cursor:not-allowed;opacity:.5}.z-chat-composer-send-btn{display:inline-flex;height:2rem;width:2rem;cursor:pointer;align-items:center;justify-content:center;border-radius:62.4375rem;border:1px solid rgba(0,0,0,.1);background:var(--primary);color:var(--primary-foreground);box-shadow:0 2px 8px #0000002e,inset 0 1px #ffffff2e;transition:transform .15s ease,opacity .2s ease,box-shadow .2s ease}.z-chat-composer-send-btn:hover{transform:translateY(-.0625rem);box-shadow:0 4px 12px #00000038,inset 0 1px #ffffff38}.z-chat-composer-send-btn:disabled{cursor:not-allowed;opacity:.45;box-shadow:none}.z-chat-scrollbar{contain:layout}.z-chat-content-surface{background:var(--card)}.z-chat-lower-shell{display:flex;min-height:0;flex:1;flex-direction:column;overflow:hidden;background:var(--card);color:var(--card-foreground);border:1px solid transparent;border-top:0;border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}:is(.dark,[data-theme=dark]) .z-chat-lower-shell{border-color:var(--border);border-top:0}.z-chat-footer-surface{background:transparent;border-top:.0625rem solid color-mix(in oklab,var(--border) 70%,transparent)}:is(.dark,[data-theme=dark]) .z-chat-footer-surface{background:transparent;border-top-color:var(--border)}.z-chat-messages{min-height:100%;overflow-x:hidden;padding:.875rem .75rem;contain:content}.z-chat-message{display:flex;margin:.5rem 0;padding:0 2px;transform-origin:bottom center;contain:layout style}.z-chat-message-bubble{transform:translateZ(0);backface-visibility:hidden}.z-chat-message--enter{animation:z-chat-message-push-in .3s ease-out;will-change:transform,opacity}.z-chat-suggestion-item{animation:z-chat-suggestion-reveal .28s ease-out both;will-change:transform,opacity}.z-chat-preview-modal-body{display:flex;align-items:center;justify-content:center;max-height:min(70vh,40rem);padding:.25rem}.z-chat-preview-image{max-width:100%;max-height:min(66vh,37.5rem);border-radius:.5rem;object-fit:contain}@keyframes z-chat-message-push-in{0%{opacity:0;transform:translateY(.9375rem) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes z-chat-suggestion-reveal{0%{opacity:0;transform:translateY(.5rem) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { 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: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
415
+ }
416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZChatComponent, decorators: [{
417
+ type: Component,
418
+ args: [{ selector: 'z-chat', imports: [FormsModule, TranslatePipe, ZIconComponent, ZModalComponent, NgScrollbar], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
419
+ class: 'z-chat block',
420
+ '(document:keydown.escape)': 'onEscapeKey()',
421
+ }, exportAs: 'zChat', template: "<div\n [class]=\"wrapperClasses()\"\n [style.top]=\"wrapperTop()\"\n [style.right]=\"wrapperRight()\"\n [style.bottom]=\"wrapperBottom()\"\n [style.left]=\"wrapperLeft()\">\n <div class=\"relative\">\n <section class=\"z-chat-panel-shell\" [class]=\"panelClasses()\">\n <header class=\"from-primary/95 to-primary/75 text-primary-foreground bg-gradient-to-r px-4 py-3.5\">\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <span\n class=\"bg-primary-foreground/15 relative inline-flex size-8 shrink-0 items-center justify-center rounded-full\">\n <z-icon [zType]=\"zBotIcon()\" zSize=\"16\" class=\"text-primary-foreground\" />\n <span\n class=\"ring-primary inline-block size-2.5 rounded-full bg-emerald-300 ring-2\"\n style=\"position: absolute; right: -0.0625rem; bottom: -0.0625rem\"></span>\n </span>\n <h3 class=\"truncate text-sm font-semibold\">{{ zTitle() | translate }}</h3>\n </div>\n </div>\n <div class=\"flex items-center gap-1\">\n <button\n type=\"button\"\n class=\"text-primary-foreground/90 hover:bg-primary-foreground/15 inline-flex size-8 cursor-pointer items-center justify-center rounded-md transition\"\n (click)=\"clearMessages()\"\n title=\"{{ 'i18n_z_ui_chat_ai_new_chat' | translate }}\">\n <z-icon zType=\"lucideRefreshCcw\" zSize=\"17\" />\n </button>\n <button\n type=\"button\"\n class=\"text-primary-foreground/90 hover:bg-primary-foreground/15 inline-flex size-8 cursor-pointer items-center justify-center rounded-md transition\"\n (click)=\"close()\"\n title=\"{{ 'i18n_z_ui_chat_ai_close' | translate }}\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"18\" />\n </button>\n </div>\n </div>\n </header>\n\n <div class=\"z-chat-lower-shell\">\n <ng-scrollbar\n #messagesScrollbar\n (afterInit)=\"onMessagesScrollbarInit()\"\n class=\"z-chat-scrollbar z-chat-content-surface flex-1 overflow-x-hidden\"\n track=\"vertical\"\n orientation=\"vertical\"\n appearance=\"compact\"\n visibility=\"hover\">\n <div class=\"z-chat-messages\">\n @if (hasMessages()) {\n @for (item of zMessages(); track item.id) {\n <div\n class=\"z-chat-message z-chat-message--enter\"\n [class.justify-end]=\"item.role === 'user'\"\n [class.justify-start]=\"item.role === 'assistant'\">\n <div\n class=\"z-chat-message-bubble max-w-[88%] min-w-0 rounded-2xl px-3 py-2.5 text-sm leading-5 [overflow-wrap:anywhere] break-all shadow-xs\"\n [class.bg-primary]=\"item.role === 'user'\"\n [class.text-primary-foreground]=\"item.role === 'user'\"\n [class.rounded-br-md]=\"item.role === 'user'\"\n [class.bg-background]=\"item.role === 'assistant'\"\n [class.border-border/60]=\"item.role === 'assistant'\"\n [class.text-foreground]=\"item.role === 'assistant'\"\n [class.rounded-bl-md]=\"item.role === 'assistant'\"\n [class.border]=\"item.role === 'assistant'\">\n @if (item.files && item.files.length > 0) {\n <div class=\"mb-2 flex flex-col gap-1.5\">\n @for (file of item.files; track file.id) {\n <div\n class=\"flex items-center gap-2 rounded-[0.5rem] px-2 py-1.5 text-xs\"\n [class.bg-white/15]=\"item.role === 'user'\"\n [class.bg-muted/40]=\"item.role === 'assistant'\">\n @if (isImageAttachment(file) && file.previewUrl) {\n <img\n [src]=\"file.previewUrl\"\n [alt]=\"file.name\"\n class=\"size-8 cursor-pointer rounded-[0.5rem] object-cover\"\n (click)=\"openImagePreview(file)\"\n title=\"Click to preview\" />\n } @else {\n <span\n class=\"bg-background/80 text-muted-foreground inline-flex size-8 items-center justify-center rounded-[0.5rem]\"\n [class.bg-white/20]=\"item.role === 'user'\"\n [class.text-white]=\"item.role === 'user'\">\n <z-icon zType=\"lucideFileText\" zSize=\"14\" />\n </span>\n }\n <div class=\"min-w-0 flex-1\">\n <p class=\"truncate text-[0.6875rem] font-medium\">{{ file.name }}</p>\n <p class=\"truncate text-[0.625rem] opacity-80\">{{ formatFileSize(file.size) }}</p>\n </div>\n </div>\n }\n </div>\n }\n {{ item.content }}\n </div>\n </div>\n }\n } @else if (showEmptyState()) {\n <div class=\"flex h-full min-h-60 flex-col items-center justify-center px-2 text-center\">\n <div\n class=\"from-primary/20 to-primary/5 mb-3 inline-flex size-14 items-center justify-center rounded-full bg-gradient-to-br\">\n <z-icon zType=\"lucideBot\" zSize=\"28\" class=\"text-primary\" />\n </div>\n <h4 class=\"text-foreground text-sm font-semibold\">{{ 'i18n_z_ui_chat_ai_empty_title' | translate }}</h4>\n <p class=\"text-muted-foreground mt-1 text-xs\">{{ 'i18n_z_ui_chat_ai_empty_desc' | translate }}</p>\n\n @if (zSuggestions().length > 0) {\n <div class=\"mt-4 flex w-full flex-col gap-2\">\n @for (item of zSuggestions(); track item.label) {\n <button\n type=\"button\"\n class=\"z-chat-suggestion-item bg-background/95 hover:bg-background border-border/60 text-foreground flex w-full cursor-pointer items-center gap-2 rounded-xl border px-3 py-2 text-left text-xs transition hover:shadow-sm\"\n [style.animation-delay.ms]=\"$index * 70\"\n (click)=\"onSuggestionSelect(item)\">\n @if (item.icon) {\n <z-icon [zType]=\"item.icon!\" zSize=\"14\" class=\"text-primary shrink-0\" />\n }\n <span class=\"line-clamp-2\">{{ item.label | translate }}</span>\n </button>\n }\n </div>\n }\n </div>\n }\n\n @if (isTyping()) {\n <div class=\"z-chat-message z-chat-message--enter justify-start\">\n <div class=\"bg-background border-border/60 rounded-2xl rounded-bl-md border px-3 py-2\">\n <div class=\"flex items-center gap-1\">\n <span class=\"bg-muted-foreground/60 inline-block size-1.5 animate-bounce rounded-full\"></span>\n <span\n class=\"bg-muted-foreground/60 inline-block size-1.5 animate-bounce rounded-full\"\n style=\"animation-delay: 0.15s\"></span>\n <span\n class=\"bg-muted-foreground/60 inline-block size-1.5 animate-bounce rounded-full\"\n style=\"animation-delay: 0.3s\"></span>\n </div>\n </div>\n </div>\n }\n </div>\n </ng-scrollbar>\n\n <footer class=\"z-chat-footer-surface p-3\">\n @if (attachments().length > 0) {\n <div class=\"mb-2 flex max-h-32 flex-col gap-2 overflow-y-auto pr-1\">\n @for (file of attachments(); track file.id) {\n <div\n class=\"bg-muted/45 border-border/55 relative flex w-full items-center gap-2 rounded-[0.5rem] border px-2 py-1.5\">\n @if (isImageAttachment(file) && file.previewUrl) {\n <img\n [src]=\"file.previewUrl\"\n [alt]=\"file.name\"\n class=\"size-8 shrink-0 cursor-pointer rounded-[0.5rem] object-cover\"\n (click)=\"openImagePreview(file)\"\n title=\"Click to preview\" />\n } @else {\n <span\n class=\"bg-background text-muted-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-[0.5rem]\">\n <z-icon zType=\"lucideFileText\" zSize=\"14\" />\n </span>\n }\n <div class=\"min-w-0 flex-1\">\n <p class=\"truncate text-[0.6875rem] font-medium\">{{ file.name }}</p>\n <p class=\"text-muted-foreground truncate text-[0.625rem]\">{{ formatFileSize(file.size) }}</p>\n </div>\n <button\n type=\"button\"\n class=\"bg-background/80 hover:bg-background text-muted-foreground inline-flex size-5 cursor-pointer items-center justify-center rounded-full transition\"\n (click)=\"removeAttachment(file.id)\">\n <z-icon zType=\"lucideX\" zSize=\"12\" />\n </button>\n </div>\n }\n </div>\n }\n\n <div class=\"z-chat-composer-shell\">\n <div class=\"z-chat-composer-main\" [class.z-chat-composer__field--overflow]=\"isComposerOverflowing()\">\n <textarea\n #chatInput\n class=\"z-chat-composer-textarea\"\n [placeholder]=\"zPlaceholder() | translate\"\n [disabled]=\"zDisabled()\"\n [ngModel]=\"draftMessage()\"\n (ngModelChange)=\"draftMessage.set($event)\"\n (input)=\"onTextareaInput($event)\"\n (paste)=\"onTextareaPaste($event)\"\n (keydown)=\"onInputKeydown($event)\"\n rows=\"3\"></textarea>\n </div>\n\n <div class=\"z-chat-composer-toolbar\">\n <div class=\"z-chat-composer-toolbar-left\">\n @if (zAllowAttachments()) {\n <input\n #fileInput\n type=\"file\"\n class=\"hidden\"\n [attr.accept]=\"zAcceptedFiles()\"\n multiple\n (change)=\"onFileChange($event)\" />\n <button\n type=\"button\"\n class=\"z-chat-composer-tool-btn\"\n [disabled]=\"zDisabled()\"\n (click)=\"onClickAttach()\"\n title=\"{{ 'i18n_z_ui_chat_ai_attach' | translate }}\">\n <z-icon zType=\"lucidePlus\" zSize=\"18\" />\n </button>\n }\n </div>\n\n <div class=\"z-chat-composer-toolbar-right\">\n <button\n type=\"button\"\n class=\"z-chat-composer-send-btn\"\n [disabled]=\"!canSend()\"\n (click)=\"onSendMessage()\"\n title=\"{{ 'i18n_z_ui_chat_ai_send' | translate }}\">\n <z-icon\n [zType]=\"isTyping() ? 'lucideLoaderCircle' : zSendIcon()\"\n zSize=\"16\"\n [class]=\"isTyping() ? 'animate-spin' : ''\" />\n </button>\n </div>\n </div>\n </div>\n </footer>\n </div>\n\n <z-modal\n [zVisible]=\"isPreviewVisible()\"\n [zTitle]=\"previewImage()?.name\"\n [zDescription]=\"previewImageSizeLabel()\"\n zWidth=\"min(92vw, 720px)\"\n [zHideFooter]=\"true\"\n [zMaskClosable]=\"true\"\n zOverlay=\"blur\"\n (zCancel)=\"closeImagePreview()\">\n <div class=\"z-chat-preview-modal-body\">\n <img [src]=\"previewImage()?.url\" [alt]=\"previewImage()?.name\" class=\"z-chat-preview-image\" />\n </div>\n </z-modal>\n </section>\n\n <button\n type=\"button\"\n class=\"pointer-events-auto cursor-pointer\"\n [class]=\"fabClasses()\"\n (click)=\"onToggle()\"\n [attr.aria-expanded]=\"zOpen()\"\n [attr.aria-label]=\"'i18n_z_ui_chat_ai_toggle' | translate\"\n title=\"{{ 'i18n_z_ui_chat_ai_toggle' | translate }}\">\n @if (zShowPulse() && !zOpen()) {\n <span class=\"bg-primary/30 absolute inset-0 animate-ping rounded-full\"></span>\n }\n\n @if (showRipple()) {\n <span class=\"bg-primary-foreground/30 absolute inset-0 animate-ping rounded-full\"></span>\n }\n\n <z-icon\n [zType]=\"zOpen() ? 'lucideX' : zFabIcon()\"\n zSize=\"24\"\n class=\"relative z-1 transition-transform duration-200\"\n [class.rotate-180]=\"zOpen()\" />\n </button>\n </div>\n</div>\n", styles: [".z-chat textarea{scrollbar-width:thin}.z-chat-panel-shell{box-shadow:0 0 28px #00000024!important}:is(.dark,[data-theme=dark]) .z-chat-panel-shell{box-shadow:0 0 28px #00000057!important}.z-chat-composer__field--overflow:after{position:absolute;right:0;bottom:0;left:0;height:1rem;pointer-events:none;content:\"\";background:linear-gradient(to top,var(--background) 22%,transparent)}.z-chat-composer-shell{position:relative;display:flex;width:100%;flex-direction:column;border:1px solid color-mix(in oklab,var(--border) 82%,transparent);border-radius:1rem;background:linear-gradient(180deg,color-mix(in oklab,var(--card) 98%,var(--background) 2%),color-mix(in oklab,var(--card) 92%,var(--background) 8%));box-shadow:0 6px 18px #00000014;transition:box-shadow .2s ease}.z-chat-composer-shell:focus-within{box-shadow:0 6px 18px #00000014}:is(.dark,[data-theme=dark]) .z-chat-composer-shell{border-color:var(--border);background:linear-gradient(180deg,color-mix(in oklab,var(--card) 96%,var(--background) 4%),color-mix(in oklab,var(--card) 88%,var(--background) 12%));box-shadow:0 10px 24px #00000057}.z-chat-composer-main{position:relative;overflow:hidden;padding:.7rem .35rem .45rem .85rem}.z-chat-composer-textarea{width:100%;height:4.125rem;max-height:4.125rem;border:none;background:transparent;resize:none;overflow-x:hidden;font-size:.875rem;line-height:1.4rem;color:var(--foreground);outline:none;padding-right:.2rem;scrollbar-width:thin;overflow-wrap:anywhere;word-break:break-word}.z-chat-composer-textarea::placeholder{color:var(--muted-foreground)}.z-chat-composer-textarea::-webkit-scrollbar{width:.375rem}.z-chat-composer-textarea::-webkit-scrollbar-track{background:transparent}.z-chat-composer-textarea::-webkit-scrollbar-thumb{border-radius:62.4375rem;background:#64748b73}:is(.dark,[data-theme=dark]) .z-chat-composer-textarea::-webkit-scrollbar-thumb{background:#94a3b88c}.z-chat-composer-toolbar{display:flex;align-items:center;justify-content:space-between;border-top:.0625rem solid rgba(219,219,219,.6);padding:.55rem .7rem .65rem}:is(.dark,[data-theme=dark]) .z-chat-composer-toolbar{border-top-color:#00000038}.z-chat-composer-toolbar-left,.z-chat-composer-toolbar-right{display:flex;align-items:center}.z-chat-composer-tool-btn{display:inline-flex;height:1.75rem;width:1.75rem;cursor:pointer;align-items:center;justify-content:center;border-radius:.6rem;border:none;background:transparent;color:#374151;transition:background-color .2s ease}.z-chat-composer-tool-btn:hover{background:#0000000f}:is(.dark,[data-theme=dark]) .z-chat-composer-tool-btn{color:#e5e7ebe6}:is(.dark,[data-theme=dark]) .z-chat-composer-tool-btn:hover{background:#ffffff1a}.z-chat-composer-tool-btn:disabled{cursor:not-allowed;opacity:.5}.z-chat-composer-send-btn{display:inline-flex;height:2rem;width:2rem;cursor:pointer;align-items:center;justify-content:center;border-radius:62.4375rem;border:1px solid rgba(0,0,0,.1);background:var(--primary);color:var(--primary-foreground);box-shadow:0 2px 8px #0000002e,inset 0 1px #ffffff2e;transition:transform .15s ease,opacity .2s ease,box-shadow .2s ease}.z-chat-composer-send-btn:hover{transform:translateY(-.0625rem);box-shadow:0 4px 12px #00000038,inset 0 1px #ffffff38}.z-chat-composer-send-btn:disabled{cursor:not-allowed;opacity:.45;box-shadow:none}.z-chat-scrollbar{contain:layout}.z-chat-content-surface{background:var(--card)}.z-chat-lower-shell{display:flex;min-height:0;flex:1;flex-direction:column;overflow:hidden;background:var(--card);color:var(--card-foreground);border:1px solid transparent;border-top:0;border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}:is(.dark,[data-theme=dark]) .z-chat-lower-shell{border-color:var(--border);border-top:0}.z-chat-footer-surface{background:transparent;border-top:.0625rem solid color-mix(in oklab,var(--border) 70%,transparent)}:is(.dark,[data-theme=dark]) .z-chat-footer-surface{background:transparent;border-top-color:var(--border)}.z-chat-messages{min-height:100%;overflow-x:hidden;padding:.875rem .75rem;contain:content}.z-chat-message{display:flex;margin:.5rem 0;padding:0 2px;transform-origin:bottom center;contain:layout style}.z-chat-message-bubble{transform:translateZ(0);backface-visibility:hidden}.z-chat-message--enter{animation:z-chat-message-push-in .3s ease-out;will-change:transform,opacity}.z-chat-suggestion-item{animation:z-chat-suggestion-reveal .28s ease-out both;will-change:transform,opacity}.z-chat-preview-modal-body{display:flex;align-items:center;justify-content:center;max-height:min(70vh,40rem);padding:.25rem}.z-chat-preview-image{max-width:100%;max-height:min(66vh,37.5rem);border-radius:.5rem;object-fit:contain}@keyframes z-chat-message-push-in{0%{opacity:0;transform:translateY(.9375rem) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes z-chat-suggestion-reveal{0%{opacity:0;transform:translateY(.5rem) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
422
+ }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "zOpen", required: false }] }, { type: i0.Output, args: ["zOpenChange"] }], zMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMessages", required: false }] }, { type: i0.Output, args: ["zMessagesChange"] }], zTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTitle", required: false }] }], zSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSubtitle", required: false }] }], zPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "zPlaceholder", required: false }] }], zPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "zPosition", required: false }] }], zOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "zOffset", required: false }] }], zSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSize", required: false }] }], zSuggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSuggestions", required: false }] }], zShowSuggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowSuggestions", required: false }] }], zShowPulse: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowPulse", required: false }] }], zDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabled", required: false }] }], zLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLoading", required: false }] }], zAllowAttachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAllowAttachments", required: false }] }], zAcceptedFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAcceptedFiles", required: false }] }], zAutoReply: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAutoReply", required: false }] }], zAutoReplyDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAutoReplyDelay", required: false }] }], zFabIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "zFabIcon", required: false }] }], zBotIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "zBotIcon", required: false }] }], zSendIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSendIcon", required: false }] }], zSend: [{ type: i0.Output, args: ["zSend"] }], zResponse: [{ type: i0.Output, args: ["zResponse"] }], zToggle: [{ type: i0.Output, args: ["zToggle"] }], zClear: [{ type: i0.Output, args: ["zClear"] }], _messagesScrollbarRef: [{ type: i0.ViewChild, args: ['messagesScrollbar', { isSignal: true }] }], _chatInputRef: [{ type: i0.ViewChild, args: ['chatInput', { isSignal: true }] }], _fileInputRef: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
423
+
424
+ /**
425
+ * Generated bundle index. Do not edit.
426
+ */
427
+
428
+ export { ZChatComponent, zChatFabVariants, zChatPanelVariants, zChatWrapperVariants };
429
+ //# sourceMappingURL=shival99-z-ui-components-z-chat.mjs.map