@shival99/z-ui 0.0.1 → 1.0.2

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 (114) hide show
  1. package/assets/css/animations.css +207 -0
  2. package/assets/css/base.css +76 -0
  3. package/assets/css/tailwind.css +53 -0
  4. package/assets/css/themes/gray.css +73 -0
  5. package/assets/css/themes/green.css +75 -0
  6. package/assets/css/themes/hospital.css +79 -0
  7. package/assets/css/themes/neutral.css +73 -0
  8. package/assets/css/themes/orange.css +73 -0
  9. package/assets/css/themes/slate.css +73 -0
  10. package/assets/css/themes/stone.css +73 -0
  11. package/assets/css/themes/violet.css +73 -0
  12. package/assets/css/themes/zinc.css +73 -0
  13. package/assets/images/avatar.svg +6 -0
  14. package/assets/images/logo.svg +6 -0
  15. package/fesm2022/shival99-z-ui-components-z-accordion.mjs +148 -0
  16. package/fesm2022/shival99-z-ui-components-z-accordion.mjs.map +1 -0
  17. package/fesm2022/shival99-z-ui-components-z-breadcrumb.mjs +74 -0
  18. package/fesm2022/shival99-z-ui-components-z-breadcrumb.mjs.map +1 -0
  19. package/fesm2022/shival99-z-ui-components-z-button.mjs +155 -0
  20. package/fesm2022/shival99-z-ui-components-z-button.mjs.map +1 -0
  21. package/fesm2022/shival99-z-ui-components-z-calendar.mjs +2335 -0
  22. package/fesm2022/shival99-z-ui-components-z-calendar.mjs.map +1 -0
  23. package/fesm2022/shival99-z-ui-components-z-checkbox.mjs +240 -0
  24. package/fesm2022/shival99-z-ui-components-z-checkbox.mjs.map +1 -0
  25. package/fesm2022/shival99-z-ui-components-z-code.mjs +139 -0
  26. package/fesm2022/shival99-z-ui-components-z-code.mjs.map +1 -0
  27. package/fesm2022/shival99-z-ui-components-z-drawer.mjs +664 -0
  28. package/fesm2022/shival99-z-ui-components-z-drawer.mjs.map +1 -0
  29. package/fesm2022/shival99-z-ui-components-z-dropdown-menu.mjs +55 -0
  30. package/fesm2022/shival99-z-ui-components-z-dropdown-menu.mjs.map +1 -0
  31. package/fesm2022/shival99-z-ui-components-z-editor.mjs +411 -0
  32. package/fesm2022/shival99-z-ui-components-z-editor.mjs.map +1 -0
  33. package/fesm2022/shival99-z-ui-components-z-filter.mjs +794 -0
  34. package/fesm2022/shival99-z-ui-components-z-filter.mjs.map +1 -0
  35. package/fesm2022/shival99-z-ui-components-z-icon.mjs +451 -0
  36. package/fesm2022/shival99-z-ui-components-z-icon.mjs.map +1 -0
  37. package/fesm2022/shival99-z-ui-components-z-input.mjs +804 -0
  38. package/fesm2022/shival99-z-ui-components-z-input.mjs.map +1 -0
  39. package/fesm2022/shival99-z-ui-components-z-loading.mjs +105 -0
  40. package/fesm2022/shival99-z-ui-components-z-loading.mjs.map +1 -0
  41. package/fesm2022/shival99-z-ui-components-z-menu.mjs +351 -0
  42. package/fesm2022/shival99-z-ui-components-z-menu.mjs.map +1 -0
  43. package/fesm2022/shival99-z-ui-components-z-modal.mjs +722 -0
  44. package/fesm2022/shival99-z-ui-components-z-modal.mjs.map +1 -0
  45. package/fesm2022/shival99-z-ui-components-z-pagination.mjs +131 -0
  46. package/fesm2022/shival99-z-ui-components-z-pagination.mjs.map +1 -0
  47. package/fesm2022/shival99-z-ui-components-z-popover.mjs +917 -0
  48. package/fesm2022/shival99-z-ui-components-z-popover.mjs.map +1 -0
  49. package/fesm2022/shival99-z-ui-components-z-radio.mjs +154 -0
  50. package/fesm2022/shival99-z-ui-components-z-radio.mjs.map +1 -0
  51. package/fesm2022/shival99-z-ui-components-z-select.mjs +998 -0
  52. package/fesm2022/shival99-z-ui-components-z-select.mjs.map +1 -0
  53. package/fesm2022/shival99-z-ui-components-z-skeleton.mjs +139 -0
  54. package/fesm2022/shival99-z-ui-components-z-skeleton.mjs.map +1 -0
  55. package/fesm2022/shival99-z-ui-components-z-switch.mjs +127 -0
  56. package/fesm2022/shival99-z-ui-components-z-switch.mjs.map +1 -0
  57. package/fesm2022/shival99-z-ui-components-z-table.mjs +2628 -0
  58. package/fesm2022/shival99-z-ui-components-z-table.mjs.map +1 -0
  59. package/fesm2022/shival99-z-ui-components-z-tabs.mjs +259 -0
  60. package/fesm2022/shival99-z-ui-components-z-tabs.mjs.map +1 -0
  61. package/fesm2022/shival99-z-ui-components-z-timeline.mjs +335 -0
  62. package/fesm2022/shival99-z-ui-components-z-timeline.mjs.map +1 -0
  63. package/fesm2022/shival99-z-ui-components-z-toast.mjs +93 -0
  64. package/fesm2022/shival99-z-ui-components-z-toast.mjs.map +1 -0
  65. package/fesm2022/shival99-z-ui-components-z-tooltip.mjs +660 -0
  66. package/fesm2022/shival99-z-ui-components-z-tooltip.mjs.map +1 -0
  67. package/fesm2022/shival99-z-ui-components-z-upload.mjs +504 -0
  68. package/fesm2022/shival99-z-ui-components-z-upload.mjs.map +1 -0
  69. package/fesm2022/shival99-z-ui-i18n.mjs +258 -0
  70. package/fesm2022/shival99-z-ui-i18n.mjs.map +1 -0
  71. package/fesm2022/shival99-z-ui-pipes.mjs +116 -0
  72. package/fesm2022/shival99-z-ui-pipes.mjs.map +1 -0
  73. package/fesm2022/shival99-z-ui-providers.mjs +203 -0
  74. package/fesm2022/shival99-z-ui-providers.mjs.map +1 -0
  75. package/fesm2022/shival99-z-ui-services.mjs +919 -0
  76. package/fesm2022/shival99-z-ui-services.mjs.map +1 -0
  77. package/fesm2022/shival99-z-ui-utils.mjs +591 -0
  78. package/fesm2022/shival99-z-ui-utils.mjs.map +1 -0
  79. package/fesm2022/z-ui.mjs +3 -19924
  80. package/fesm2022/z-ui.mjs.map +1 -1
  81. package/package.json +129 -1
  82. package/types/shival99-z-ui-components-z-accordion.d.ts +55 -0
  83. package/types/shival99-z-ui-components-z-breadcrumb.d.ts +36 -0
  84. package/types/shival99-z-ui-components-z-button.d.ts +41 -0
  85. package/types/shival99-z-ui-components-z-calendar.d.ts +300 -0
  86. package/types/shival99-z-ui-components-z-checkbox.d.ts +84 -0
  87. package/types/shival99-z-ui-components-z-code.d.ts +35 -0
  88. package/types/shival99-z-ui-components-z-drawer.d.ts +232 -0
  89. package/types/shival99-z-ui-components-z-dropdown-menu.d.ts +50 -0
  90. package/types/shival99-z-ui-components-z-editor.d.ts +115 -0
  91. package/types/shival99-z-ui-components-z-filter.d.ts +268 -0
  92. package/types/shival99-z-ui-components-z-icon.d.ts +291 -0
  93. package/types/shival99-z-ui-components-z-input.d.ts +188 -0
  94. package/types/shival99-z-ui-components-z-loading.d.ts +46 -0
  95. package/types/shival99-z-ui-components-z-menu.d.ts +116 -0
  96. package/types/shival99-z-ui-components-z-modal.d.ts +270 -0
  97. package/types/shival99-z-ui-components-z-pagination.d.ts +52 -0
  98. package/types/shival99-z-ui-components-z-popover.d.ts +134 -0
  99. package/types/shival99-z-ui-components-z-radio.d.ts +63 -0
  100. package/types/shival99-z-ui-components-z-select.d.ts +268 -0
  101. package/types/shival99-z-ui-components-z-skeleton.d.ts +55 -0
  102. package/types/shival99-z-ui-components-z-switch.d.ts +48 -0
  103. package/types/shival99-z-ui-components-z-table.d.ts +482 -0
  104. package/types/shival99-z-ui-components-z-tabs.d.ts +75 -0
  105. package/types/shival99-z-ui-components-z-timeline.d.ts +98 -0
  106. package/types/shival99-z-ui-components-z-toast.d.ts +61 -0
  107. package/types/shival99-z-ui-components-z-tooltip.d.ts +85 -0
  108. package/types/shival99-z-ui-components-z-upload.d.ts +136 -0
  109. package/types/shival99-z-ui-i18n.d.ts +50 -0
  110. package/types/shival99-z-ui-pipes.d.ts +36 -0
  111. package/types/shival99-z-ui-providers.d.ts +132 -0
  112. package/types/shival99-z-ui-services.d.ts +364 -0
  113. package/types/shival99-z-ui-utils.d.ts +145 -0
  114. package/types/z-ui.d.ts +3 -4977
@@ -0,0 +1,504 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, output, viewChild, signal, inject, Injector, DestroyRef, computed, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
+ import { NgControl, NgModel, PristineChangeEvent, TouchedChangeEvent, NG_VALUE_ACCESSOR } from '@angular/forms';
5
+ import { merge, filter } from 'rxjs';
6
+ import { cva } from 'class-variance-authority';
7
+ import { zTransform, zGenerateId, zMergeClasses } from '@shival99/z-ui/utils';
8
+ import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
9
+ import { ZLoadingComponent } from '@shival99/z-ui/components/z-loading';
10
+ import { ZTooltipDirective } from '@shival99/z-ui/components/z-tooltip';
11
+
12
+ const formatFileSize = (bytes) => {
13
+ if (bytes === 0) {
14
+ return '0 B';
15
+ }
16
+ const units = ['B', 'KB', 'MB', 'GB'];
17
+ const k = 1024;
18
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
19
+ const size = bytes / Math.pow(k, i);
20
+ return `${size.toFixed(i > 0 ? 1 : 0)} ${units[i]}`;
21
+ };
22
+
23
+ const zUploadDropzoneVariants = cva([
24
+ 'relative flex flex-col items-center justify-center rounded-[6px] border-2 border-dashed',
25
+ 'transition-[border-color,background-color] duration-200 cursor-pointer',
26
+ 'hover:border-primary/50 hover:bg-primary/5',
27
+ ], {
28
+ variants: {
29
+ zSize: {
30
+ sm: 'min-h-24 gap-1 p-3',
31
+ default: 'min-h-32 gap-2 p-4',
32
+ lg: 'min-h-40 gap-3 p-6',
33
+ },
34
+ zStatus: {
35
+ default: 'border-input bg-background',
36
+ active: 'border-primary bg-primary/10',
37
+ disabled: 'opacity-50 cursor-not-allowed bg-muted border-muted',
38
+ readonly: 'opacity-70 cursor-default bg-muted/50 border-muted',
39
+ error: 'border-destructive! bg-destructive/5 hover:border-destructive!',
40
+ },
41
+ },
42
+ defaultVariants: {
43
+ zSize: 'default',
44
+ zStatus: 'default',
45
+ },
46
+ });
47
+ const zUploadFileItemVariants = cva([
48
+ 'relative flex items-center gap-3 rounded-[6px] border border-input bg-background p-3',
49
+ 'transition-all duration-200',
50
+ ], {
51
+ variants: {
52
+ zStatus: {
53
+ pending: '',
54
+ uploading: '',
55
+ success: '',
56
+ error: '',
57
+ },
58
+ },
59
+ defaultVariants: {
60
+ zStatus: 'pending',
61
+ },
62
+ });
63
+
64
+ class ZUploadComponent {
65
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
66
+ zLabel = input('', ...(ngDevMode ? [{ debugName: "zLabel" }] : []));
67
+ zLabelClass = input('', ...(ngDevMode ? [{ debugName: "zLabelClass" }] : []));
68
+ zNote = input('', ...(ngDevMode ? [{ debugName: "zNote" }] : []));
69
+ zSize = input('default', ...(ngDevMode ? [{ debugName: "zSize" }] : []));
70
+ zAcceptFile = input('*', ...(ngDevMode ? [{ debugName: "zAcceptFile" }] : []));
71
+ zMultipleFile = input(false, { ...(ngDevMode ? { debugName: "zMultipleFile" } : {}), transform: zTransform });
72
+ zMaxSize = input(10, ...(ngDevMode ? [{ debugName: "zMaxSize" }] : []));
73
+ zMaxFiles = input(5, ...(ngDevMode ? [{ debugName: "zMaxFiles" }] : []));
74
+ zRequired = input(false, { ...(ngDevMode ? { debugName: "zRequired" } : {}), transform: zTransform });
75
+ zDisabled = input(false, { ...(ngDevMode ? { debugName: "zDisabled" } : {}), transform: zTransform });
76
+ zReadonly = input(false, { ...(ngDevMode ? { debugName: "zReadonly" } : {}), transform: zTransform });
77
+ zLoading = input(false, { ...(ngDevMode ? { debugName: "zLoading" } : {}), transform: zTransform });
78
+ zShowProgress = input(true, { ...(ngDevMode ? { debugName: "zShowProgress" } : {}), transform: zTransform });
79
+ zValidators = input([], ...(ngDevMode ? [{ debugName: "zValidators" }] : []));
80
+ zOnUpload = output();
81
+ zOnRemove = output();
82
+ zOnDownload = output();
83
+ zOnError = output();
84
+ zOnFileChange = output();
85
+ zControl = output();
86
+ fileInputRef = viewChild('fileInput', ...(ngDevMode ? [{ debugName: "fileInputRef" }] : []));
87
+ files = signal([], ...(ngDevMode ? [{ debugName: "files" }] : []));
88
+ inputId = zGenerateId('z-upload');
89
+ isDragOver = signal(false, ...(ngDevMode ? [{ debugName: "isDragOver" }] : []));
90
+ isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
91
+ _dirty = signal(false, ...(ngDevMode ? [{ debugName: "_dirty" }] : []));
92
+ _fileError = signal('', ...(ngDevMode ? [{ debugName: "_fileError" }] : []));
93
+ _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
94
+ _formControl = signal(null, ...(ngDevMode ? [{ debugName: "_formControl" }] : []));
95
+ _formStateVersion = signal(0, ...(ngDevMode ? [{ debugName: "_formStateVersion" }] : []));
96
+ _isNgModel = signal(false, ...(ngDevMode ? [{ debugName: "_isNgModel" }] : []));
97
+ _injector = inject(Injector);
98
+ _destroyRef = inject(DestroyRef);
99
+ _onChange = () => void 0;
100
+ _onTouched = () => void 0;
101
+ _ngControl = null;
102
+ isDisabled = computed(() => this._disabled() || this.zDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
103
+ isBlocked = computed(() => this.isDisabled() || this.zLoading() || this.zReadonly(), ...(ngDevMode ? [{ debugName: "isBlocked" }] : []));
104
+ _shouldShowValidation = computed(() => {
105
+ const control = this._formControl();
106
+ this._formStateVersion();
107
+ if (this._isNgModel()) {
108
+ return this._dirty() || this.isTouched();
109
+ }
110
+ if (control) {
111
+ return control.dirty;
112
+ }
113
+ return this._dirty() || this.isTouched();
114
+ }, ...(ngDevMode ? [{ debugName: "_shouldShowValidation" }] : []));
115
+ hasError = computed(() => {
116
+ if (this._fileError()) {
117
+ return true;
118
+ }
119
+ const customErrors = this._getValidationErrors();
120
+ if (customErrors.length > 0) {
121
+ return true;
122
+ }
123
+ const control = this._formControl();
124
+ this._formStateVersion();
125
+ if (!control) {
126
+ return false;
127
+ }
128
+ return control.invalid && this._shouldShowValidation();
129
+ }, ...(ngDevMode ? [{ debugName: "hasError" }] : []));
130
+ showError = computed(() => this.hasError() && (this._shouldShowValidation() || !!this._fileError()), ...(ngDevMode ? [{ debugName: "showError" }] : []));
131
+ errorMessage = computed(() => {
132
+ const fileError = this._fileError();
133
+ if (fileError) {
134
+ return fileError;
135
+ }
136
+ const customErrors = this._getValidationErrors();
137
+ if (customErrors.length > 0) {
138
+ return customErrors[0];
139
+ }
140
+ const control = this._formControl();
141
+ const errors = control?.errors;
142
+ if (!errors) {
143
+ return '';
144
+ }
145
+ const validators = this.zValidators();
146
+ for (const validator of validators) {
147
+ if (errors[validator.error]) {
148
+ return validator.message;
149
+ }
150
+ }
151
+ return '';
152
+ }, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
153
+ currentStatus = computed(() => {
154
+ if (this.isDisabled()) {
155
+ return 'disabled';
156
+ }
157
+ if (this.zReadonly()) {
158
+ return 'readonly';
159
+ }
160
+ if (this._fileError()) {
161
+ return 'error';
162
+ }
163
+ if (this.hasError() && this._shouldShowValidation()) {
164
+ return 'error';
165
+ }
166
+ if (this.isDragOver()) {
167
+ return 'active';
168
+ }
169
+ return 'default';
170
+ }, ...(ngDevMode ? [{ debugName: "currentStatus" }] : []));
171
+ dropzoneClasses = computed(() => zMergeClasses(zUploadDropzoneVariants({
172
+ zSize: this.zSize(),
173
+ zStatus: this.currentStatus(),
174
+ }), this.class()), ...(ngDevMode ? [{ debugName: "dropzoneClasses" }] : []));
175
+ acceptTypes = computed(() => {
176
+ const accept = this.zAcceptFile();
177
+ return accept === '*' ? '' : accept;
178
+ }, ...(ngDevMode ? [{ debugName: "acceptTypes" }] : []));
179
+ formatFileSize = formatFileSize;
180
+ getFileItemClasses = (file) => zUploadFileItemVariants({ zStatus: file.status });
181
+ ngOnInit() {
182
+ void Promise.resolve().then(() => {
183
+ try {
184
+ this._ngControl = this._injector.get(NgControl, null);
185
+ this._isNgModel.set(this._ngControl instanceof NgModel);
186
+ if (this._ngControl?.control) {
187
+ const { control } = this._ngControl;
188
+ this._formControl.set(control);
189
+ merge(control.statusChanges, control.valueChanges, control.events.pipe(filter(event => event instanceof PristineChangeEvent || event instanceof TouchedChangeEvent)))
190
+ .pipe(takeUntilDestroyed(this._destroyRef))
191
+ .subscribe(() => {
192
+ this._formStateVersion.update(v => v + 1);
193
+ });
194
+ }
195
+ }
196
+ catch {
197
+ this._ngControl = null;
198
+ }
199
+ });
200
+ setTimeout(() => this._emitControl());
201
+ }
202
+ writeValue(value) {
203
+ this.files.set(value ?? []);
204
+ }
205
+ registerOnChange(fn) {
206
+ this._onChange = fn;
207
+ }
208
+ registerOnTouched(fn) {
209
+ this._onTouched = fn;
210
+ }
211
+ setDisabledState(isDisabled) {
212
+ this._disabled.set(isDisabled);
213
+ }
214
+ updateProgress(fileId, progress) {
215
+ this.files.update(files => files.map(f => {
216
+ if (f.id !== fileId) {
217
+ return f;
218
+ }
219
+ return {
220
+ ...f,
221
+ progress: Math.min(100, Math.max(0, progress)),
222
+ status: progress >= 100 ? 'success' : 'uploading',
223
+ };
224
+ }));
225
+ this._notifyChange();
226
+ }
227
+ setFileStatus(fileId, status) {
228
+ this.files.update(files => files.map(f => {
229
+ if (f.id !== fileId) {
230
+ return f;
231
+ }
232
+ return { ...f, status };
233
+ }));
234
+ this._notifyChange();
235
+ }
236
+ clearFiles() {
237
+ this.files.set([]);
238
+ this._notifyChange();
239
+ }
240
+ validate() {
241
+ this.isTouched.set(true);
242
+ this._dirty.set(true);
243
+ this._onTouched();
244
+ if (this._ngControl?.control) {
245
+ this._ngControl.control.markAsDirty();
246
+ this._ngControl.control.markAsTouched();
247
+ }
248
+ }
249
+ reset() {
250
+ this.files.set([]);
251
+ this.isTouched.set(false);
252
+ this._dirty.set(false);
253
+ this._fileError.set('');
254
+ this._onChange([]);
255
+ if (this._ngControl?.control) {
256
+ this._ngControl.control.markAsPristine();
257
+ this._ngControl.control.markAsUntouched();
258
+ }
259
+ }
260
+ markAsTouched() {
261
+ this.isTouched.set(true);
262
+ this._onTouched();
263
+ }
264
+ markAsUntouched() {
265
+ this.isTouched.set(false);
266
+ }
267
+ markAsDirty() {
268
+ this._dirty.set(true);
269
+ }
270
+ markAsPristine() {
271
+ this._dirty.set(false);
272
+ }
273
+ _emitControl() {
274
+ this.zControl.emit({
275
+ validate: () => this.validate(),
276
+ reset: () => this.reset(),
277
+ clearFiles: () => this.clearFiles(),
278
+ openFileDialog: () => this.openFileDialog(),
279
+ markAsTouched: () => this.markAsTouched(),
280
+ markAsUntouched: () => this.markAsUntouched(),
281
+ markAsDirty: () => this.markAsDirty(),
282
+ markAsPristine: () => this.markAsPristine(),
283
+ hasError: this.hasError,
284
+ files: this.files.asReadonly(),
285
+ errorMessage: this.errorMessage,
286
+ });
287
+ }
288
+ getFiles() {
289
+ return this.files()
290
+ .filter(f => f.file)
291
+ .map(f => f.file);
292
+ }
293
+ openFileDialog() {
294
+ if (this.isBlocked()) {
295
+ return;
296
+ }
297
+ this.fileInputRef()?.nativeElement.click();
298
+ }
299
+ onFileSelected(event) {
300
+ const input = event.target;
301
+ if (!input.files?.length) {
302
+ return;
303
+ }
304
+ this._processFiles(Array.from(input.files));
305
+ input.value = '';
306
+ }
307
+ onDragOver(event) {
308
+ event.preventDefault();
309
+ event.stopPropagation();
310
+ if (this.isBlocked()) {
311
+ return;
312
+ }
313
+ this.isDragOver.set(true);
314
+ }
315
+ onDragLeave(event) {
316
+ event.preventDefault();
317
+ event.stopPropagation();
318
+ this.isDragOver.set(false);
319
+ }
320
+ onDrop(event) {
321
+ event.preventDefault();
322
+ event.stopPropagation();
323
+ this.isDragOver.set(false);
324
+ if (this.isBlocked()) {
325
+ return;
326
+ }
327
+ const droppedFiles = event.dataTransfer?.files;
328
+ if (!droppedFiles?.length) {
329
+ return;
330
+ }
331
+ this._processFiles(Array.from(droppedFiles));
332
+ }
333
+ removeFile(file) {
334
+ if (this.zLoading()) {
335
+ return;
336
+ }
337
+ this.files.update(files => files.filter(f => f.id !== file.id));
338
+ this._notifyChange();
339
+ this._emitFileChange();
340
+ this.zOnRemove.emit(file);
341
+ }
342
+ downloadFile(file) {
343
+ if (this.zLoading()) {
344
+ return;
345
+ }
346
+ this.zOnDownload.emit(file);
347
+ if (file.url) {
348
+ const link = document.createElement('a');
349
+ link.href = file.url;
350
+ link.download = file.name;
351
+ link.target = '_blank';
352
+ document.body.appendChild(link);
353
+ link.click();
354
+ document.body.removeChild(link);
355
+ return;
356
+ }
357
+ if (file.file) {
358
+ const url = URL.createObjectURL(file.file);
359
+ const link = document.createElement('a');
360
+ link.href = url;
361
+ link.download = file.name;
362
+ document.body.appendChild(link);
363
+ link.click();
364
+ document.body.removeChild(link);
365
+ URL.revokeObjectURL(url);
366
+ }
367
+ }
368
+ _getValidationErrors() {
369
+ const validators = this.zValidators();
370
+ const currentFiles = this.files();
371
+ const control = this._formControl();
372
+ const errors = [];
373
+ const isRequired = this.zRequired() || control?.errors?.['required'];
374
+ if (isRequired && currentFiles.length === 0) {
375
+ errors.push('Vui lòng chọn file');
376
+ }
377
+ for (const validator of validators) {
378
+ if (validator.validate && !validator.validate(currentFiles)) {
379
+ errors.push(validator.message);
380
+ }
381
+ }
382
+ return errors;
383
+ }
384
+ _processFiles(newFiles) {
385
+ const maxFiles = this.zMaxFiles();
386
+ const maxSize = this.zMaxSize() * 1024 * 1024;
387
+ const accept = this.zAcceptFile();
388
+ const validFiles = [];
389
+ if (!this.zMultipleFile()) {
390
+ this.files.set([]);
391
+ }
392
+ for (const file of newFiles) {
393
+ if (!this.zMultipleFile() && validFiles.length > 0) {
394
+ break;
395
+ }
396
+ if (this.zMultipleFile()) {
397
+ const currentCount = this.files().length + validFiles.length;
398
+ if (currentCount >= maxFiles) {
399
+ const errorMsg = `Maximum ${maxFiles} files allowed`;
400
+ this._fileError.set(errorMsg);
401
+ this.zOnError.emit({ file, error: errorMsg });
402
+ continue;
403
+ }
404
+ }
405
+ if (file.size > maxSize) {
406
+ const errorMsg = `File size exceeds ${this.zMaxSize()}MB limit`;
407
+ this._fileError.set(errorMsg);
408
+ this.zOnError.emit({ file, error: errorMsg });
409
+ continue;
410
+ }
411
+ if (accept !== '*' && !this._isValidFileType(file, accept)) {
412
+ const errorMsg = `File type not allowed. Accepted: ${accept}`;
413
+ this._fileError.set(errorMsg);
414
+ this.zOnError.emit({ file, error: errorMsg });
415
+ continue;
416
+ }
417
+ validFiles.push({
418
+ id: zGenerateId('file'),
419
+ name: file.name,
420
+ size: file.size,
421
+ type: file.type,
422
+ file,
423
+ progress: 0,
424
+ status: 'pending',
425
+ });
426
+ }
427
+ if (validFiles.length === 0) {
428
+ this._notifyChange();
429
+ return;
430
+ }
431
+ this._fileError.set('');
432
+ if (!this.zMultipleFile()) {
433
+ this.files.set(validFiles.slice(0, 1));
434
+ this.isTouched.set(true);
435
+ this._dirty.set(true);
436
+ this._onTouched();
437
+ this._notifyChange();
438
+ this._emitFileChange();
439
+ this.zOnUpload.emit(validFiles);
440
+ return;
441
+ }
442
+ this.files.update(files => [...files, ...validFiles]);
443
+ this.isTouched.set(true);
444
+ this._dirty.set(true);
445
+ this._onTouched();
446
+ this._notifyChange();
447
+ this._emitFileChange();
448
+ this.zOnUpload.emit(validFiles);
449
+ }
450
+ _emitFileChange() {
451
+ const rawFiles = this.getFiles();
452
+ this.zOnFileChange.emit(rawFiles);
453
+ }
454
+ _isValidFileType(file, accept) {
455
+ const acceptTypes = accept.split(',').map(t => t.trim().toLowerCase());
456
+ for (const type of acceptTypes) {
457
+ if (type.startsWith('.')) {
458
+ if (file.name.toLowerCase().endsWith(type)) {
459
+ return true;
460
+ }
461
+ continue;
462
+ }
463
+ if (type.endsWith('/*')) {
464
+ const category = type.slice(0, -2);
465
+ if (file.type.startsWith(category + '/')) {
466
+ return true;
467
+ }
468
+ continue;
469
+ }
470
+ if (file.type.toLowerCase() === type) {
471
+ return true;
472
+ }
473
+ }
474
+ return false;
475
+ }
476
+ _notifyChange() {
477
+ this._onChange(this.files());
478
+ }
479
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
480
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: ZUploadComponent, isStandalone: true, selector: "z-upload", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zLabel: { classPropertyName: "zLabel", publicName: "zLabel", isSignal: true, isRequired: false, transformFunction: null }, zLabelClass: { classPropertyName: "zLabelClass", publicName: "zLabelClass", isSignal: true, isRequired: false, transformFunction: null }, zNote: { classPropertyName: "zNote", publicName: "zNote", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zAcceptFile: { classPropertyName: "zAcceptFile", publicName: "zAcceptFile", isSignal: true, isRequired: false, transformFunction: null }, zMultipleFile: { classPropertyName: "zMultipleFile", publicName: "zMultipleFile", isSignal: true, isRequired: false, transformFunction: null }, zMaxSize: { classPropertyName: "zMaxSize", publicName: "zMaxSize", isSignal: true, isRequired: false, transformFunction: null }, zMaxFiles: { classPropertyName: "zMaxFiles", publicName: "zMaxFiles", isSignal: true, isRequired: false, transformFunction: null }, zRequired: { classPropertyName: "zRequired", publicName: "zRequired", isSignal: true, isRequired: false, transformFunction: null }, zDisabled: { classPropertyName: "zDisabled", publicName: "zDisabled", isSignal: true, isRequired: false, transformFunction: null }, zReadonly: { classPropertyName: "zReadonly", publicName: "zReadonly", isSignal: true, isRequired: false, transformFunction: null }, zLoading: { classPropertyName: "zLoading", publicName: "zLoading", isSignal: true, isRequired: false, transformFunction: null }, zShowProgress: { classPropertyName: "zShowProgress", publicName: "zShowProgress", isSignal: true, isRequired: false, transformFunction: null }, zValidators: { classPropertyName: "zValidators", publicName: "zValidators", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zOnUpload: "zOnUpload", zOnRemove: "zOnRemove", zOnDownload: "zOnDownload", zOnError: "zOnError", zOnFileChange: "zOnFileChange", zControl: "zControl" }, providers: [
481
+ {
482
+ provide: NG_VALUE_ACCESSOR,
483
+ useExisting: forwardRef(() => ZUploadComponent),
484
+ multi: true,
485
+ },
486
+ ], viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], exportAs: ["zUpload"], ngImport: i0, template: "<div class=\"z-upload-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"inputId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div\n class=\"z-upload-dropzone\"\n [class]=\"dropzoneClasses()\"\n (click)=\"openFileDialog()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n @if (zLoading()) {\n <div class=\"bg-background/80 absolute inset-0 z-10 flex items-center justify-center rounded-[6px]\">\n <svg\n class=\"text-primary size-6 animate-spin\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\">\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n </div>\n }\n\n <svg\n class=\"text-muted-foreground\"\n [class.size-5]=\"zSize() === 'sm'\"\n [class.size-6]=\"zSize() === 'default'\"\n [class.size-8]=\"zSize() === 'lg'\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n @if (isDragOver()) {\n <path d=\"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" />\n <path d=\"M12 12v9\" />\n <path d=\"m16 16-4-4-4 4\" />\n } @else {\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\" />\n }\n </svg>\n\n <div class=\"text-center\">\n <p class=\"text-muted-foreground m-0 text-sm\">\n @if (isDragOver()) {\n Drop files here\n } @else {\n Drag files here or\n <span class=\"text-primary cursor-pointer font-medium\">browse</span>\n }\n </p>\n\n @if (zNote() || zAcceptFile() !== '*') {\n <div class=\"text-muted-foreground/70 mt-2 flex flex-col gap-0.5 text-xs\">\n @if (zNote()) {\n <span>{{ zNote() }}</span>\n }\n @if (zAcceptFile() !== '*') {\n <span>Accepted: {{ zAcceptFile() }}</span>\n }\n </div>\n }\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"hidden\"\n [id]=\"inputId\"\n [accept]=\"acceptTypes()\"\n [multiple]=\"zMultipleFile()\"\n [disabled]=\"isBlocked()\"\n (change)=\"onFileSelected($event)\" />\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n\n @if (files().length > 0) {\n <div class=\"z-upload-file-list flex flex-col gap-1.5\">\n @for (file of files(); track file.id) {\n <div [class]=\"getFileItemClasses(file)\" class=\"relative overflow-hidden p-2!\">\n <!-- Progress border at bottom -->\n @if (zShowProgress() && file.status === 'uploading') {\n <div\n class=\"bg-primary absolute bottom-0 left-0 h-0.5 transition-all duration-300\"\n [style.width.%]=\"file.progress\"></div>\n }\n\n <div class=\"bg-muted relative flex size-8 shrink-0 items-center justify-center self-start rounded\">\n <z-icon zType=\"lucideFile\" zSize=\"16\" class=\"text-muted-foreground\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <div class=\"flex items-center gap-1.5\">\n <span class=\"line-clamp-2 text-xs font-medium\" z-tooltip [zContent]=\"file.name\" [zAlwaysShow]=\"false\">\n {{ file.name }}\n </span>\n\n @if (file.status === 'uploading') {\n <z-loading zSize=\"2xs\" class=\"shrink-0\" [zLoading]=\"true\" />\n @if (zShowProgress() && file.progress > 0) {\n <span class=\"text-primary shrink-0 text-[10px] font-medium\">{{ file.progress }}%</span>\n }\n }\n @if (file.status === 'success') {\n <z-icon zType=\"lucideCheckCircle\" zSize=\"14\" class=\"shrink-0 text-green-500\" />\n }\n @if (file.status === 'error') {\n <z-icon zType=\"lucideXCircle\" zSize=\"14\" class=\"text-destructive shrink-0\" />\n }\n </div>\n\n <span class=\"text-muted-foreground mt-0.5 text-[10px]\">\n {{ formatFileSize(file.size) }}\n </span>\n </div>\n\n <div class=\"flex shrink-0 items-center gap-0.5\">\n @if (file.url || file.file) {\n <button\n type=\"button\"\n class=\"group hover:bg-accent flex size-6 cursor-pointer items-center justify-center rounded transition-colors\"\n [class.pointer-events-none]=\"zLoading()\"\n [class.opacity-50]=\"zLoading()\"\n (click)=\"downloadFile(file); $event.stopPropagation()\">\n <z-icon zType=\"lucideDownload\" zSize=\"14\" class=\"text-muted-foreground\" />\n </button>\n }\n\n @if (!zReadonly()) {\n <button\n type=\"button\"\n class=\"hover:bg-destructive/10 flex size-6 cursor-pointer items-center justify-center rounded transition-colors\"\n [class.pointer-events-none]=\"zLoading()\"\n [class.opacity-50]=\"zLoading()\"\n (click)=\"removeFile(file); $event.stopPropagation()\">\n <z-icon zType=\"lucideX\" zSize=\"14\" class=\"text-destructive\" />\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".z-upload-wrapper .z-upload-dropzone:focus-visible{outline:2px solid var(--color-ring);outline-offset:2px}.z-upload-wrapper .z-upload-progress-bar .z-upload-progress-fill{transition:width .3s ease-out}.z-upload-wrapper .z-upload-file-list{animation:z-upload-slide-in .2s ease-out}@keyframes z-upload-slide-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "component", type: ZLoadingComponent, selector: "z-loading", inputs: ["class", "zSpinner", "zSize", "zColor", "zText", "zOverlay", "zOverlayType", "zFullscreen", "zLoading"] }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
487
+ }
488
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ZUploadComponent, decorators: [{
489
+ type: Component,
490
+ args: [{ selector: 'z-upload', imports: [ZIconComponent, ZLoadingComponent, ZTooltipDirective], standalone: true, providers: [
491
+ {
492
+ provide: NG_VALUE_ACCESSOR,
493
+ useExisting: forwardRef(() => ZUploadComponent),
494
+ multi: true,
495
+ },
496
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'zUpload', template: "<div class=\"z-upload-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"inputId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div\n class=\"z-upload-dropzone\"\n [class]=\"dropzoneClasses()\"\n (click)=\"openFileDialog()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n @if (zLoading()) {\n <div class=\"bg-background/80 absolute inset-0 z-10 flex items-center justify-center rounded-[6px]\">\n <svg\n class=\"text-primary size-6 animate-spin\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\">\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n </div>\n }\n\n <svg\n class=\"text-muted-foreground\"\n [class.size-5]=\"zSize() === 'sm'\"\n [class.size-6]=\"zSize() === 'default'\"\n [class.size-8]=\"zSize() === 'lg'\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n @if (isDragOver()) {\n <path d=\"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" />\n <path d=\"M12 12v9\" />\n <path d=\"m16 16-4-4-4 4\" />\n } @else {\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\" />\n }\n </svg>\n\n <div class=\"text-center\">\n <p class=\"text-muted-foreground m-0 text-sm\">\n @if (isDragOver()) {\n Drop files here\n } @else {\n Drag files here or\n <span class=\"text-primary cursor-pointer font-medium\">browse</span>\n }\n </p>\n\n @if (zNote() || zAcceptFile() !== '*') {\n <div class=\"text-muted-foreground/70 mt-2 flex flex-col gap-0.5 text-xs\">\n @if (zNote()) {\n <span>{{ zNote() }}</span>\n }\n @if (zAcceptFile() !== '*') {\n <span>Accepted: {{ zAcceptFile() }}</span>\n }\n </div>\n }\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"hidden\"\n [id]=\"inputId\"\n [accept]=\"acceptTypes()\"\n [multiple]=\"zMultipleFile()\"\n [disabled]=\"isBlocked()\"\n (change)=\"onFileSelected($event)\" />\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n\n @if (files().length > 0) {\n <div class=\"z-upload-file-list flex flex-col gap-1.5\">\n @for (file of files(); track file.id) {\n <div [class]=\"getFileItemClasses(file)\" class=\"relative overflow-hidden p-2!\">\n <!-- Progress border at bottom -->\n @if (zShowProgress() && file.status === 'uploading') {\n <div\n class=\"bg-primary absolute bottom-0 left-0 h-0.5 transition-all duration-300\"\n [style.width.%]=\"file.progress\"></div>\n }\n\n <div class=\"bg-muted relative flex size-8 shrink-0 items-center justify-center self-start rounded\">\n <z-icon zType=\"lucideFile\" zSize=\"16\" class=\"text-muted-foreground\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <div class=\"flex items-center gap-1.5\">\n <span class=\"line-clamp-2 text-xs font-medium\" z-tooltip [zContent]=\"file.name\" [zAlwaysShow]=\"false\">\n {{ file.name }}\n </span>\n\n @if (file.status === 'uploading') {\n <z-loading zSize=\"2xs\" class=\"shrink-0\" [zLoading]=\"true\" />\n @if (zShowProgress() && file.progress > 0) {\n <span class=\"text-primary shrink-0 text-[10px] font-medium\">{{ file.progress }}%</span>\n }\n }\n @if (file.status === 'success') {\n <z-icon zType=\"lucideCheckCircle\" zSize=\"14\" class=\"shrink-0 text-green-500\" />\n }\n @if (file.status === 'error') {\n <z-icon zType=\"lucideXCircle\" zSize=\"14\" class=\"text-destructive shrink-0\" />\n }\n </div>\n\n <span class=\"text-muted-foreground mt-0.5 text-[10px]\">\n {{ formatFileSize(file.size) }}\n </span>\n </div>\n\n <div class=\"flex shrink-0 items-center gap-0.5\">\n @if (file.url || file.file) {\n <button\n type=\"button\"\n class=\"group hover:bg-accent flex size-6 cursor-pointer items-center justify-center rounded transition-colors\"\n [class.pointer-events-none]=\"zLoading()\"\n [class.opacity-50]=\"zLoading()\"\n (click)=\"downloadFile(file); $event.stopPropagation()\">\n <z-icon zType=\"lucideDownload\" zSize=\"14\" class=\"text-muted-foreground\" />\n </button>\n }\n\n @if (!zReadonly()) {\n <button\n type=\"button\"\n class=\"hover:bg-destructive/10 flex size-6 cursor-pointer items-center justify-center rounded transition-colors\"\n [class.pointer-events-none]=\"zLoading()\"\n [class.opacity-50]=\"zLoading()\"\n (click)=\"removeFile(file); $event.stopPropagation()\">\n <z-icon zType=\"lucideX\" zSize=\"14\" class=\"text-destructive\" />\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".z-upload-wrapper .z-upload-dropzone:focus-visible{outline:2px solid var(--color-ring);outline-offset:2px}.z-upload-wrapper .z-upload-progress-bar .z-upload-progress-fill{transition:width .3s ease-out}.z-upload-wrapper .z-upload-file-list{animation:z-upload-slide-in .2s ease-out}@keyframes z-upload-slide-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
497
+ }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabel", required: false }] }], zLabelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabelClass", required: false }] }], zNote: [{ type: i0.Input, args: [{ isSignal: true, alias: "zNote", required: false }] }], zSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSize", required: false }] }], zAcceptFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "zAcceptFile", required: false }] }], zMultipleFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMultipleFile", required: false }] }], zMaxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMaxSize", required: false }] }], zMaxFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMaxFiles", required: false }] }], zRequired: [{ type: i0.Input, args: [{ isSignal: true, alias: "zRequired", required: false }] }], zDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabled", required: false }] }], zReadonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "zReadonly", required: false }] }], zLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLoading", required: false }] }], zShowProgress: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowProgress", required: false }] }], zValidators: [{ type: i0.Input, args: [{ isSignal: true, alias: "zValidators", required: false }] }], zOnUpload: [{ type: i0.Output, args: ["zOnUpload"] }], zOnRemove: [{ type: i0.Output, args: ["zOnRemove"] }], zOnDownload: [{ type: i0.Output, args: ["zOnDownload"] }], zOnError: [{ type: i0.Output, args: ["zOnError"] }], zOnFileChange: [{ type: i0.Output, args: ["zOnFileChange"] }], zControl: [{ type: i0.Output, args: ["zControl"] }], fileInputRef: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
498
+
499
+ /**
500
+ * Generated bundle index. Do not edit.
501
+ */
502
+
503
+ export { ZUploadComponent, formatFileSize, zUploadDropzoneVariants, zUploadFileItemVariants };
504
+ //# sourceMappingURL=shival99-z-ui-components-z-upload.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shival99-z-ui-components-z-upload.mjs","sources":["../../../../libs/core-ui/components/z-upload/z-upload.types.ts","../../../../libs/core-ui/components/z-upload/z-upload.variants.ts","../../../../libs/core-ui/components/z-upload/z-upload.component.ts","../../../../libs/core-ui/components/z-upload/z-upload.component.html","../../../../libs/core-ui/components/z-upload/shival99-z-ui-components-z-upload.ts"],"sourcesContent":["import type { Signal } from '@angular/core';\r\n\r\nexport type ZUploadSize = 'sm' | 'default' | 'lg';\r\nexport type ZUploadStatus = 'pending' | 'uploading' | 'success' | 'error';\r\n\r\nexport interface ZUploadFile {\r\n id: string;\r\n name: string;\r\n size: number;\r\n type: string;\r\n file?: File;\r\n url?: string;\r\n progress: number;\r\n status: ZUploadStatus;\r\n}\r\n\r\nexport interface ZUploadError {\r\n file: File;\r\n error: string;\r\n}\r\n\r\nexport interface ZUploadValidator {\r\n error: string;\r\n message: string;\r\n validate?: (files: ZUploadFile[]) => boolean;\r\n}\r\n\r\nexport interface ZUploadControl {\r\n validate: () => void;\r\n reset: () => void;\r\n clearFiles: () => void;\r\n openFileDialog: () => void;\r\n markAsTouched: () => void;\r\n markAsUntouched: () => void;\r\n markAsDirty: () => void;\r\n markAsPristine: () => void;\r\n hasError: Signal<boolean>;\r\n files: Signal<ZUploadFile[]>;\r\n errorMessage: Signal<string>;\r\n}\r\n\r\nexport const formatFileSize = (bytes: number): string => {\r\n if (bytes === 0) {\r\n return '0 B';\r\n }\r\n\r\n const units = ['B', 'KB', 'MB', 'GB'];\r\n const k = 1024;\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n const size = bytes / Math.pow(k, i);\r\n return `${size.toFixed(i > 0 ? 1 : 0)} ${units[i]}`;\r\n};\r\n","import { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nexport const zUploadDropzoneVariants = cva(\r\n [\r\n 'relative flex flex-col items-center justify-center rounded-[6px] border-2 border-dashed',\r\n 'transition-[border-color,background-color] duration-200 cursor-pointer',\r\n 'hover:border-primary/50 hover:bg-primary/5',\r\n ],\r\n {\r\n variants: {\r\n zSize: {\r\n sm: 'min-h-24 gap-1 p-3',\r\n default: 'min-h-32 gap-2 p-4',\r\n lg: 'min-h-40 gap-3 p-6',\r\n },\r\n zStatus: {\r\n default: 'border-input bg-background',\r\n active: 'border-primary bg-primary/10',\r\n disabled: 'opacity-50 cursor-not-allowed bg-muted border-muted',\r\n readonly: 'opacity-70 cursor-default bg-muted/50 border-muted',\r\n error: 'border-destructive! bg-destructive/5 hover:border-destructive!',\r\n },\r\n },\r\n defaultVariants: {\r\n zSize: 'default',\r\n zStatus: 'default',\r\n },\r\n }\r\n);\r\n\r\nexport type ZUploadDropzoneVariants = VariantProps<typeof zUploadDropzoneVariants>;\r\n\r\nexport const zUploadFileItemVariants = cva(\r\n [\r\n 'relative flex items-center gap-3 rounded-[6px] border border-input bg-background p-3',\r\n 'transition-all duration-200',\r\n ],\r\n {\r\n variants: {\r\n zStatus: {\r\n pending: '',\r\n uploading: '',\r\n success: '',\r\n error: '',\r\n },\r\n },\r\n defaultVariants: {\r\n zStatus: 'pending',\r\n },\r\n }\r\n);\r\n\r\nexport type ZUploadFileItemVariants = VariantProps<typeof zUploadFileItemVariants>;\r\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n forwardRef,\n inject,\n Injector,\n input,\n type OnInit,\n output,\n signal,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n type AbstractControl,\n ControlValueAccessor,\n NG_VALUE_ACCESSOR,\n NgControl,\n NgModel,\n PristineChangeEvent,\n TouchedChangeEvent,\n} from '@angular/forms';\nimport type { ClassValue } from 'clsx';\nimport { filter, merge } from 'rxjs';\nimport {\n formatFileSize,\n type ZUploadControl,\n type ZUploadError,\n type ZUploadFile,\n type ZUploadSize,\n type ZUploadValidator,\n} from './z-upload.types';\nimport { zUploadDropzoneVariants, zUploadFileItemVariants } from './z-upload.variants';\nimport { zGenerateId, zMergeClasses, zTransform } from '@shival99/z-ui/utils';\nimport { ZIconComponent } from '@shival99/z-ui/components/z-icon';\nimport { ZLoadingComponent } from '@shival99/z-ui/components/z-loading';\nimport { ZTooltipDirective } from '@shival99/z-ui/components/z-tooltip';\n\n@Component({\n selector: 'z-upload',\n imports: [ZIconComponent, ZLoadingComponent, ZTooltipDirective],\n standalone: true,\n templateUrl: './z-upload.component.html',\n styleUrl: './z-upload.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => ZUploadComponent),\n multi: true,\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n exportAs: 'zUpload',\n})\nexport class ZUploadComponent implements OnInit, ControlValueAccessor {\n public readonly class = input<ClassValue>('');\n public readonly zLabel = input<string>('');\n public readonly zLabelClass = input<string>('');\n public readonly zNote = input<string>('');\n public readonly zSize = input<ZUploadSize>('default');\n public readonly zAcceptFile = input<string>('*');\n public readonly zMultipleFile = input(false, { transform: zTransform });\n public readonly zMaxSize = input<number>(10);\n public readonly zMaxFiles = input<number>(5);\n public readonly zRequired = input(false, { transform: zTransform });\n public readonly zDisabled = input(false, { transform: zTransform });\n public readonly zReadonly = input(false, { transform: zTransform });\n public readonly zLoading = input(false, { transform: zTransform });\n public readonly zShowProgress = input(true, { transform: zTransform });\n public readonly zValidators = input<ZUploadValidator[]>([]);\n\n public readonly zOnUpload = output<ZUploadFile[]>();\n public readonly zOnRemove = output<ZUploadFile>();\n public readonly zOnDownload = output<ZUploadFile>();\n public readonly zOnError = output<ZUploadError>();\n public readonly zOnFileChange = output<File[]>();\n public readonly zControl = output<ZUploadControl>();\n\n protected readonly fileInputRef = viewChild<ElementRef<HTMLInputElement>>('fileInput');\n\n public readonly files = signal<ZUploadFile[]>([]);\n protected readonly inputId = zGenerateId('z-upload');\n protected readonly isDragOver = signal(false);\n protected readonly isTouched = signal(false);\n private readonly _dirty = signal(false);\n private readonly _fileError = signal<string>('');\n\n private readonly _disabled = signal(false);\n private readonly _formControl = signal<AbstractControl | null>(null);\n private readonly _formStateVersion = signal(0);\n private readonly _isNgModel = signal(false);\n private readonly _injector = inject(Injector);\n private readonly _destroyRef = inject(DestroyRef);\n\n private _onChange: (value: ZUploadFile[]) => void = () => void 0;\n private _onTouched: () => void = () => void 0;\n private _ngControl: NgControl | null = null;\n\n protected readonly isDisabled = computed(() => this._disabled() || this.zDisabled());\n\n protected readonly isBlocked = computed(() => this.isDisabled() || this.zLoading() || this.zReadonly());\n\n private readonly _shouldShowValidation = computed(() => {\n const control = this._formControl();\n this._formStateVersion();\n\n if (this._isNgModel()) {\n return this._dirty() || this.isTouched();\n }\n\n if (control) {\n return control.dirty;\n }\n\n return this._dirty() || this.isTouched();\n });\n\n protected readonly hasError = computed(() => {\n if (this._fileError()) {\n return true;\n }\n\n const customErrors = this._getValidationErrors();\n if (customErrors.length > 0) {\n return true;\n }\n\n const control = this._formControl();\n this._formStateVersion();\n if (!control) {\n return false;\n }\n\n return control.invalid && this._shouldShowValidation();\n });\n\n protected readonly showError = computed(\n () => this.hasError() && (this._shouldShowValidation() || !!this._fileError())\n );\n\n protected readonly errorMessage = computed(() => {\n const fileError = this._fileError();\n if (fileError) {\n return fileError;\n }\n\n const customErrors = this._getValidationErrors();\n if (customErrors.length > 0) {\n return customErrors[0];\n }\n\n const control = this._formControl();\n const errors = control?.errors;\n if (!errors) {\n return '';\n }\n\n const validators = this.zValidators();\n for (const validator of validators) {\n if (errors[validator.error]) {\n return validator.message;\n }\n }\n\n return '';\n });\n\n protected readonly currentStatus = computed(() => {\n if (this.isDisabled()) {\n return 'disabled';\n }\n if (this.zReadonly()) {\n return 'readonly';\n }\n if (this._fileError()) {\n return 'error';\n }\n if (this.hasError() && this._shouldShowValidation()) {\n return 'error';\n }\n if (this.isDragOver()) {\n return 'active';\n }\n return 'default';\n });\n\n protected readonly dropzoneClasses = computed(() =>\n zMergeClasses(\n zUploadDropzoneVariants({\n zSize: this.zSize(),\n zStatus: this.currentStatus(),\n }),\n this.class()\n )\n );\n\n protected readonly acceptTypes = computed(() => {\n const accept = this.zAcceptFile();\n return accept === '*' ? '' : accept;\n });\n\n protected readonly formatFileSize = formatFileSize;\n protected readonly getFileItemClasses = (file: ZUploadFile) => zUploadFileItemVariants({ zStatus: file.status });\n\n public ngOnInit(): void {\n void Promise.resolve().then(() => {\n try {\n this._ngControl = this._injector.get(NgControl, null);\n this._isNgModel.set(this._ngControl instanceof NgModel);\n\n if (this._ngControl?.control) {\n const { control } = this._ngControl;\n this._formControl.set(control);\n merge(\n control.statusChanges,\n control.valueChanges,\n control.events.pipe(\n filter(event => event instanceof PristineChangeEvent || event instanceof TouchedChangeEvent)\n )\n )\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n this._formStateVersion.update(v => v + 1);\n });\n }\n } catch {\n this._ngControl = null;\n }\n });\n\n setTimeout(() => this._emitControl());\n }\n\n public writeValue(value: ZUploadFile[] | null): void {\n this.files.set(value ?? []);\n }\n\n public registerOnChange(fn: (value: ZUploadFile[]) => void): void {\n this._onChange = fn;\n }\n\n public registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n public setDisabledState(isDisabled: boolean): void {\n this._disabled.set(isDisabled);\n }\n\n public updateProgress(fileId: string, progress: number): void {\n this.files.update(files =>\n files.map(f => {\n if (f.id !== fileId) {\n return f;\n }\n return {\n ...f,\n progress: Math.min(100, Math.max(0, progress)),\n status: progress >= 100 ? 'success' : 'uploading',\n };\n })\n );\n this._notifyChange();\n }\n\n public setFileStatus(fileId: string, status: ZUploadFile['status']): void {\n this.files.update(files =>\n files.map(f => {\n if (f.id !== fileId) {\n return f;\n }\n return { ...f, status };\n })\n );\n this._notifyChange();\n }\n\n public clearFiles(): void {\n this.files.set([]);\n this._notifyChange();\n }\n\n public validate(): void {\n this.isTouched.set(true);\n this._dirty.set(true);\n this._onTouched();\n\n if (this._ngControl?.control) {\n this._ngControl.control.markAsDirty();\n this._ngControl.control.markAsTouched();\n }\n }\n\n public reset(): void {\n this.files.set([]);\n this.isTouched.set(false);\n this._dirty.set(false);\n this._fileError.set('');\n this._onChange([]);\n\n if (this._ngControl?.control) {\n this._ngControl.control.markAsPristine();\n this._ngControl.control.markAsUntouched();\n }\n }\n\n public markAsTouched(): void {\n this.isTouched.set(true);\n this._onTouched();\n }\n\n public markAsUntouched(): void {\n this.isTouched.set(false);\n }\n\n public markAsDirty(): void {\n this._dirty.set(true);\n }\n\n public markAsPristine(): void {\n this._dirty.set(false);\n }\n\n private _emitControl(): void {\n this.zControl.emit({\n validate: () => this.validate(),\n reset: () => this.reset(),\n clearFiles: () => this.clearFiles(),\n openFileDialog: () => this.openFileDialog(),\n markAsTouched: () => this.markAsTouched(),\n markAsUntouched: () => this.markAsUntouched(),\n markAsDirty: () => this.markAsDirty(),\n markAsPristine: () => this.markAsPristine(),\n hasError: this.hasError,\n files: this.files.asReadonly(),\n errorMessage: this.errorMessage,\n });\n }\n\n public getFiles(): File[] {\n return this.files()\n .filter(f => f.file)\n .map(f => f.file as File);\n }\n\n protected openFileDialog(): void {\n if (this.isBlocked()) {\n return;\n }\n this.fileInputRef()?.nativeElement.click();\n }\n\n protected onFileSelected(event: Event): void {\n const input = event.target as HTMLInputElement;\n if (!input.files?.length) {\n return;\n }\n\n this._processFiles(Array.from(input.files));\n input.value = '';\n }\n\n protected onDragOver(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n if (this.isBlocked()) {\n return;\n }\n this.isDragOver.set(true);\n }\n\n protected onDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.isDragOver.set(false);\n }\n\n protected onDrop(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.isDragOver.set(false);\n\n if (this.isBlocked()) {\n return;\n }\n\n const droppedFiles = event.dataTransfer?.files;\n if (!droppedFiles?.length) {\n return;\n }\n\n this._processFiles(Array.from(droppedFiles));\n }\n\n protected removeFile(file: ZUploadFile): void {\n if (this.zLoading()) {\n return;\n }\n\n this.files.update(files => files.filter(f => f.id !== file.id));\n this._notifyChange();\n this._emitFileChange();\n this.zOnRemove.emit(file);\n }\n\n protected downloadFile(file: ZUploadFile): void {\n if (this.zLoading()) {\n return;\n }\n\n this.zOnDownload.emit(file);\n if (file.url) {\n const link = document.createElement('a');\n link.href = file.url;\n link.download = file.name;\n link.target = '_blank';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n return;\n }\n\n if (file.file) {\n const url = URL.createObjectURL(file.file);\n const link = document.createElement('a');\n link.href = url;\n link.download = file.name;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n }\n\n private _getValidationErrors(): string[] {\n const validators = this.zValidators();\n const currentFiles = this.files();\n const control = this._formControl();\n const errors: string[] = [];\n\n const isRequired = this.zRequired() || control?.errors?.['required'];\n if (isRequired && currentFiles.length === 0) {\n errors.push('Vui lòng chọn file');\n }\n\n for (const validator of validators) {\n if (validator.validate && !validator.validate(currentFiles)) {\n errors.push(validator.message);\n }\n }\n\n return errors;\n }\n\n private _processFiles(newFiles: File[]): void {\n const maxFiles = this.zMaxFiles();\n const maxSize = this.zMaxSize() * 1024 * 1024;\n const accept = this.zAcceptFile();\n const validFiles: ZUploadFile[] = [];\n if (!this.zMultipleFile()) {\n this.files.set([]);\n }\n\n for (const file of newFiles) {\n if (!this.zMultipleFile() && validFiles.length > 0) {\n break;\n }\n\n if (this.zMultipleFile()) {\n const currentCount = this.files().length + validFiles.length;\n if (currentCount >= maxFiles) {\n const errorMsg = `Maximum ${maxFiles} files allowed`;\n this._fileError.set(errorMsg);\n this.zOnError.emit({ file, error: errorMsg });\n continue;\n }\n }\n\n if (file.size > maxSize) {\n const errorMsg = `File size exceeds ${this.zMaxSize()}MB limit`;\n this._fileError.set(errorMsg);\n this.zOnError.emit({ file, error: errorMsg });\n continue;\n }\n\n if (accept !== '*' && !this._isValidFileType(file, accept)) {\n const errorMsg = `File type not allowed. Accepted: ${accept}`;\n this._fileError.set(errorMsg);\n this.zOnError.emit({ file, error: errorMsg });\n continue;\n }\n\n validFiles.push({\n id: zGenerateId('file'),\n name: file.name,\n size: file.size,\n type: file.type,\n file,\n progress: 0,\n status: 'pending',\n });\n }\n\n if (validFiles.length === 0) {\n this._notifyChange();\n return;\n }\n\n this._fileError.set('');\n if (!this.zMultipleFile()) {\n this.files.set(validFiles.slice(0, 1));\n this.isTouched.set(true);\n this._dirty.set(true);\n this._onTouched();\n this._notifyChange();\n this._emitFileChange();\n this.zOnUpload.emit(validFiles);\n return;\n }\n\n this.files.update(files => [...files, ...validFiles]);\n this.isTouched.set(true);\n this._dirty.set(true);\n this._onTouched();\n this._notifyChange();\n this._emitFileChange();\n this.zOnUpload.emit(validFiles);\n }\n\n private _emitFileChange(): void {\n const rawFiles = this.getFiles();\n this.zOnFileChange.emit(rawFiles);\n }\n\n private _isValidFileType(file: File, accept: string): boolean {\n const acceptTypes = accept.split(',').map(t => t.trim().toLowerCase());\n\n for (const type of acceptTypes) {\n if (type.startsWith('.')) {\n if (file.name.toLowerCase().endsWith(type)) {\n return true;\n }\n continue;\n }\n\n if (type.endsWith('/*')) {\n const category = type.slice(0, -2);\n if (file.type.startsWith(category + '/')) {\n return true;\n }\n continue;\n }\n\n if (file.type.toLowerCase() === type) {\n return true;\n }\n }\n\n return false;\n }\n\n private _notifyChange(): void {\n this._onChange(this.files());\n }\n}\n","<div class=\"z-upload-wrapper flex w-full flex-col gap-2\">\n @if (zLabel()) {\n <label [for]=\"inputId\" class=\"text-xs leading-none font-medium\" [class]=\"zLabelClass()\">\n {{ zLabel() }}\n @if (zRequired()) {\n <span class=\"text-destructive! ml-0.5\">*</span>\n }\n </label>\n }\n\n <div\n class=\"z-upload-dropzone\"\n [class]=\"dropzoneClasses()\"\n (click)=\"openFileDialog()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n @if (zLoading()) {\n <div class=\"bg-background/80 absolute inset-0 z-10 flex items-center justify-center rounded-[6px]\">\n <svg\n class=\"text-primary size-6 animate-spin\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\">\n <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n </svg>\n </div>\n }\n\n <svg\n class=\"text-muted-foreground\"\n [class.size-5]=\"zSize() === 'sm'\"\n [class.size-6]=\"zSize() === 'default'\"\n [class.size-8]=\"zSize() === 'lg'\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n @if (isDragOver()) {\n <path d=\"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" />\n <path d=\"M12 12v9\" />\n <path d=\"m16 16-4-4-4 4\" />\n } @else {\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" x2=\"12\" y1=\"3\" y2=\"15\" />\n }\n </svg>\n\n <div class=\"text-center\">\n <p class=\"text-muted-foreground m-0 text-sm\">\n @if (isDragOver()) {\n Drop files here\n } @else {\n Drag files here or\n <span class=\"text-primary cursor-pointer font-medium\">browse</span>\n }\n </p>\n\n @if (zNote() || zAcceptFile() !== '*') {\n <div class=\"text-muted-foreground/70 mt-2 flex flex-col gap-0.5 text-xs\">\n @if (zNote()) {\n <span>{{ zNote() }}</span>\n }\n @if (zAcceptFile() !== '*') {\n <span>Accepted: {{ zAcceptFile() }}</span>\n }\n </div>\n }\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"hidden\"\n [id]=\"inputId\"\n [accept]=\"acceptTypes()\"\n [multiple]=\"zMultipleFile()\"\n [disabled]=\"isBlocked()\"\n (change)=\"onFileSelected($event)\" />\n </div>\n\n @if (showError()) {\n <p class=\"text-destructive animate-in fade-in slide-in-from-top-1 m-0 text-xs duration-200\">\n {{ errorMessage() }}\n </p>\n }\n\n @if (files().length > 0) {\n <div class=\"z-upload-file-list flex flex-col gap-1.5\">\n @for (file of files(); track file.id) {\n <div [class]=\"getFileItemClasses(file)\" class=\"relative overflow-hidden p-2!\">\n <!-- Progress border at bottom -->\n @if (zShowProgress() && file.status === 'uploading') {\n <div\n class=\"bg-primary absolute bottom-0 left-0 h-0.5 transition-all duration-300\"\n [style.width.%]=\"file.progress\"></div>\n }\n\n <div class=\"bg-muted relative flex size-8 shrink-0 items-center justify-center self-start rounded\">\n <z-icon zType=\"lucideFile\" zSize=\"16\" class=\"text-muted-foreground\" />\n </div>\n\n <div class=\"flex min-w-0 flex-1 flex-col\">\n <div class=\"flex items-center gap-1.5\">\n <span class=\"line-clamp-2 text-xs font-medium\" z-tooltip [zContent]=\"file.name\" [zAlwaysShow]=\"false\">\n {{ file.name }}\n </span>\n\n @if (file.status === 'uploading') {\n <z-loading zSize=\"2xs\" class=\"shrink-0\" [zLoading]=\"true\" />\n @if (zShowProgress() && file.progress > 0) {\n <span class=\"text-primary shrink-0 text-[10px] font-medium\">{{ file.progress }}%</span>\n }\n }\n @if (file.status === 'success') {\n <z-icon zType=\"lucideCheckCircle\" zSize=\"14\" class=\"shrink-0 text-green-500\" />\n }\n @if (file.status === 'error') {\n <z-icon zType=\"lucideXCircle\" zSize=\"14\" class=\"text-destructive shrink-0\" />\n }\n </div>\n\n <span class=\"text-muted-foreground mt-0.5 text-[10px]\">\n {{ formatFileSize(file.size) }}\n </span>\n </div>\n\n <div class=\"flex shrink-0 items-center gap-0.5\">\n @if (file.url || file.file) {\n <button\n type=\"button\"\n class=\"group hover:bg-accent flex size-6 cursor-pointer items-center justify-center rounded transition-colors\"\n [class.pointer-events-none]=\"zLoading()\"\n [class.opacity-50]=\"zLoading()\"\n (click)=\"downloadFile(file); $event.stopPropagation()\">\n <z-icon zType=\"lucideDownload\" zSize=\"14\" class=\"text-muted-foreground\" />\n </button>\n }\n\n @if (!zReadonly()) {\n <button\n type=\"button\"\n class=\"hover:bg-destructive/10 flex size-6 cursor-pointer items-center justify-center rounded transition-colors\"\n [class.pointer-events-none]=\"zLoading()\"\n [class.opacity-50]=\"zLoading()\"\n (click)=\"removeFile(file); $event.stopPropagation()\">\n <z-icon zType=\"lucideX\" zSize=\"14\" class=\"text-destructive\" />\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}