@ptsecurity/mosaic 17.2.13 → 17.2.14

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 (42) hide show
  1. package/core/forms/index.d.ts +1 -0
  2. package/core/forms/validators.d.ts +22 -0
  3. package/core/pop-up/constants.d.ts +13 -0
  4. package/core/pop-up/pop-up-trigger.d.ts +14 -1
  5. package/core/styles/theming/_theming.scss +1 -0
  6. package/esm2022/core/forms/index.mjs +2 -1
  7. package/esm2022/core/forms/validators.mjs +33 -0
  8. package/esm2022/core/pop-up/constants.mjs +10 -1
  9. package/esm2022/core/pop-up/pop-up-trigger.mjs +45 -3
  10. package/esm2022/core/version.mjs +2 -2
  11. package/esm2022/file-upload/file-upload.mjs +39 -2
  12. package/esm2022/file-upload/file-upload.module.mjs +8 -1
  13. package/esm2022/file-upload/multiple-file-upload.component.mjs +129 -37
  14. package/esm2022/file-upload/single-file-upload.component.mjs +124 -46
  15. package/esm2022/popover/popover.component.mjs +2 -2
  16. package/esm2022/select/select.component.mjs +6 -4
  17. package/esm2022/tooltip/tooltip.component.mjs +5 -2
  18. package/esm2022/tree-select/tree-select.component.mjs +6 -4
  19. package/fesm2022/ptsecurity-mosaic-core.mjs +86 -3
  20. package/fesm2022/ptsecurity-mosaic-core.mjs.map +1 -1
  21. package/fesm2022/ptsecurity-mosaic-file-upload.mjs +282 -72
  22. package/fesm2022/ptsecurity-mosaic-file-upload.mjs.map +1 -1
  23. package/fesm2022/ptsecurity-mosaic-popover.mjs +1 -1
  24. package/fesm2022/ptsecurity-mosaic-popover.mjs.map +1 -1
  25. package/fesm2022/ptsecurity-mosaic-select.mjs +5 -3
  26. package/fesm2022/ptsecurity-mosaic-select.mjs.map +1 -1
  27. package/fesm2022/ptsecurity-mosaic-tooltip.mjs +5 -2
  28. package/fesm2022/ptsecurity-mosaic-tooltip.mjs.map +1 -1
  29. package/fesm2022/ptsecurity-mosaic-tree-select.mjs +5 -3
  30. package/fesm2022/ptsecurity-mosaic-tree-select.mjs.map +1 -1
  31. package/file-upload/_file-upload-theme.scss +21 -11
  32. package/file-upload/file-upload.d.ts +31 -3
  33. package/file-upload/file-upload.module.d.ts +11 -10
  34. package/file-upload/file-upload.scss +8 -1
  35. package/file-upload/multiple-file-upload.component.d.ts +54 -13
  36. package/file-upload/multiple-file-upload.component.scss +0 -8
  37. package/file-upload/single-file-upload.component.d.ts +49 -14
  38. package/file-upload/single-file-upload.component.scss +0 -8
  39. package/package.json +45 -45
  40. package/prebuilt-themes/dark-theme.css +1 -1
  41. package/prebuilt-themes/default-theme.css +1 -1
  42. package/tooltip/tooltip.component.d.ts +2 -1
@@ -1,28 +1,64 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, EventEmitter, Directive, Output, TemplateRef, Component, ChangeDetectionStrategy, Optional, Inject, Input, ContentChild, ViewChild, NgModule } from '@angular/core';
2
+ import { InjectionToken, inject, Renderer2, ChangeDetectorRef, DestroyRef, ElementRef, EventEmitter, Directive, Output, TemplateRef, Component, ChangeDetectionStrategy, ViewEncapsulation, Optional, Inject, Input, ContentChild, ViewChild, ContentChildren, NgModule } from '@angular/core';
3
+ import { NgControl, NgForm, FormGroupDirective, FormsModule, ReactiveFormsModule } from '@angular/forms';
4
+ import * as i8 from '@ptsecurity/mosaic/core';
5
+ import { MC_LOCALE_SERVICE, ErrorStateMatcher, ruRULocaleData, McDataSizeModule } from '@ptsecurity/mosaic/core';
6
+ import { Subject, BehaviorSubject } from 'rxjs';
3
7
  import * as i1 from '@angular/common';
4
8
  import { CommonModule } from '@angular/common';
5
9
  import * as i4$1 from '@ptsecurity/mosaic/button';
6
10
  import { McButtonModule } from '@ptsecurity/mosaic/button';
7
- import * as i9 from '@ptsecurity/mosaic/core';
8
- import { ruRULocaleData, MC_LOCALE_SERVICE, McDataSizeModule } from '@ptsecurity/mosaic/core';
9
- import * as i6 from '@ptsecurity/mosaic/ellipsis-center';
11
+ import * as i5 from '@ptsecurity/mosaic/ellipsis-center';
10
12
  import { McEllipsisCenterModule } from '@ptsecurity/mosaic/ellipsis-center';
11
- import * as i5 from '@ptsecurity/mosaic/form-field';
12
- import { McFormFieldModule } from '@ptsecurity/mosaic/form-field';
13
+ import { McHint, McFormFieldModule } from '@ptsecurity/mosaic/form-field';
13
14
  import * as i3 from '@ptsecurity/mosaic/icon';
14
15
  import { McIconModule } from '@ptsecurity/mosaic/icon';
15
- import * as i7 from '@ptsecurity/mosaic/link';
16
+ import * as i6 from '@ptsecurity/mosaic/link';
16
17
  import { McLinkModule } from '@ptsecurity/mosaic/link';
17
18
  import * as i4 from '@ptsecurity/mosaic/list';
18
19
  import { McListModule } from '@ptsecurity/mosaic/list';
19
20
  import * as i2 from '@ptsecurity/mosaic/progress-spinner';
20
21
  import { McProgressSpinnerModule } from '@ptsecurity/mosaic/progress-spinner';
21
22
  import { McToolTipModule } from '@ptsecurity/mosaic/tooltip';
22
- import { Subscription, BehaviorSubject } from 'rxjs';
23
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
24
+ import { distinctUntilChanged } from 'rxjs/operators';
23
25
 
24
26
  /* Object for labels customization inside file upload component */
25
27
  const MC_FILE_UPLOAD_CONFIGURATION = new InjectionToken('McFileUploadConfiguration');
28
+ /** @docs-private */
29
+ class McFileUploadBase {
30
+ constructor() {
31
+ /** Whether the component is in an error state. */
32
+ this.errorState = false;
33
+ /**
34
+ * Emits whenever the component state changes and should cause the parent
35
+ * form-field to update. Implemented as part of `McFormFieldControl`.
36
+ * @docs-private
37
+ */
38
+ this.stateChanges = new Subject();
39
+ this.renderer = inject(Renderer2);
40
+ this.cdr = inject(ChangeDetectorRef);
41
+ this.localeService = inject(MC_LOCALE_SERVICE, { optional: true });
42
+ this.destroyRef = inject(DestroyRef);
43
+ this.ngControl = inject(NgControl, { optional: true, self: true });
44
+ this.parentForm = inject(NgForm, { optional: true });
45
+ this.parentFormGroup = inject(FormGroupDirective, { optional: true });
46
+ this.defaultErrorStateMatcher = inject(ErrorStateMatcher);
47
+ this.elementRef = inject(ElementRef);
48
+ }
49
+ /** implemented as part of base class. Decided not use mixinErrorState, not to over */
50
+ updateErrorState() {
51
+ const oldState = this.errorState;
52
+ const parent = this.parentFormGroup || this.parentForm;
53
+ const matcher = this.errorStateMatcher || this.defaultErrorStateMatcher;
54
+ const control = this.ngControl ? this.ngControl.control : null;
55
+ const newState = matcher.isErrorState(control, parent);
56
+ if (newState !== oldState) {
57
+ this.errorState = newState;
58
+ this.stateChanges.next();
59
+ }
60
+ }
61
+ }
26
62
 
27
63
  const isFolderCanBeDragged = () => 'webkitGetAsEntry' in DataTransferItem.prototype;
28
64
  const entryIsDirectory = (entry) => !!entry && entry.isDirectory;
@@ -104,23 +140,60 @@ const unwrapDirectory = async (item) => {
104
140
 
105
141
  let nextMultipleFileUploadUniqueId = 0;
106
142
  const MC_MULTIPLE_FILE_UPLOAD_DEFAULT_CONFIGURATION = ruRULocaleData['ru-RU'].fileUpload.multiple;
107
- class McMultipleFileUploadComponent {
143
+ class McMultipleFileUploadComponent extends McFileUploadBase {
144
+ get files() {
145
+ return this._files;
146
+ }
147
+ set files(currentFileList) {
148
+ this._files = currentFileList;
149
+ this.cvaOnChange(this._files);
150
+ this.fileQueueChanged.emit(this._files);
151
+ this.cdr.markForCheck();
152
+ }
108
153
  get acceptedFiles() {
109
154
  return this.accept && this.accept.length > 0 ? this.accept.map((ext) => `.${ext}`).join(',') : '*/*';
110
155
  }
156
+ /**
157
+ * @deprecated use `FormControl.errors`
158
+ */
111
159
  get hasErrors() {
112
160
  return this.errors && !!this.errors.length;
113
161
  }
114
- constructor(renderer, cdr, configuration, localeService) {
115
- this.renderer = renderer;
116
- this.cdr = cdr;
162
+ get hasHint() {
163
+ return this.hint.length > 0;
164
+ }
165
+ /**
166
+ * Indicates an invalid state based on file errors or `errorState`,
167
+ * applying a CSS class in HTML for visual feedback.
168
+ */
169
+ get invalid() {
170
+ return this.errorState;
171
+ }
172
+ constructor(configuration) {
173
+ super();
117
174
  this.configuration = configuration;
118
- this.localeService = localeService;
119
175
  this.errors = [];
120
- this.files = [];
121
176
  this.size = 'default';
177
+ /**
178
+ * custom ID for the file input element.
179
+ */
122
180
  this.inputId = `mc-multiple-file-upload-${nextMultipleFileUploadUniqueId++}`;
181
+ this._files = [];
123
182
  this.fileQueueChanged = new EventEmitter();
183
+ /**
184
+ * Emits an event containing a chunk of files added to the file list.
185
+ */
186
+ this.filesAdded = new EventEmitter();
187
+ /**
188
+ * Emits an event containing a file and file's index when removed from the file list.
189
+ */
190
+ this.fileRemoved = new EventEmitter();
191
+ /** cvaOnChange function registered via registerOnChange (ControlValueAccessor). @docs-private */
192
+ // tslint:disable-next-line:no-empty
193
+ this.cvaOnChange = (_) => { };
194
+ /** onTouch function registered via registerOnTouch (ControlValueAccessor). @docs-private */
195
+ // tslint:disable-next-line:no-empty
196
+ this.onTouched = () => { };
124
197
  this.updateLocaleParams = () => {
125
198
  this.config = this.configuration || this.localeService?.getParams('fileUpload').multiple;
126
199
  this.columnDefs = [
@@ -131,42 +204,92 @@ class McMultipleFileUploadComponent {
131
204
  this.makeCaptionText();
132
205
  this.cdr.markForCheck();
133
206
  };
134
- this.localeSubscription = this.localeService?.changes.subscribe(this.updateLocaleParams) || Subscription.EMPTY;
135
- if (!localeService) {
207
+ this.localeService?.changes.pipe(takeUntilDestroyed()).subscribe(this.updateLocaleParams);
208
+ if (!this.localeService) {
136
209
  this.initDefaultParams();
137
210
  }
211
+ if (this.ngControl) {
212
+ // Note: we provide the value accessor through here, instead of
213
+ // the `providers` to avoid running into a circular import.
214
+ this.ngControl.valueAccessor = this;
215
+ }
216
+ }
217
+ ngAfterViewInit() {
218
+ // FormControl specific errors update
219
+ this.ngControl?.statusChanges
220
+ ?.pipe(takeUntilDestroyed(this.destroyRef))
221
+ .subscribe(() => {
222
+ this.errors = Object.values(this.ngControl?.errors || {});
223
+ this.cdr.markForCheck();
224
+ });
225
+ this.stateChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.cdr.markForCheck());
226
+ }
227
+ ngDoCheck() {
228
+ if (this.ngControl) {
229
+ // We need to re-evaluate this on every change detection cycle, because there are some
230
+ // error triggers that we can't subscribe to (e.g. parent form submissions). This means
231
+ // that whatever logic is in here has to be super lean or we risk destroying the performance.
232
+ this.updateErrorState();
233
+ }
138
234
  }
139
- ngOnDestroy() {
140
- this.localeSubscription.unsubscribe();
235
+ /** Implemented as part of ControlValueAccessor. @docs-private */
236
+ writeValue(files) {
237
+ if (files instanceof FileList || !files) {
238
+ this.files = this.mapToFileItem(files);
239
+ }
240
+ else {
241
+ this.files = files;
242
+ }
243
+ }
244
+ /** Implemented as part of ControlValueAccessor. @docs-private */
245
+ registerOnChange(fn) { this.cvaOnChange = fn; }
246
+ /** Implemented as part of ControlValueAccessor. @docs-private */
247
+ registerOnTouched(fn) { this.onTouched = fn; }
248
+ /**
249
+ * Sets the disabled state of the control. Implemented as a part of ControlValueAccessor.
250
+ * @param isDisabled Whether the control should be disabled.
251
+ * @docs-private
252
+ */
253
+ setDisabledState(isDisabled) {
254
+ this.disabled = isDisabled;
255
+ this.cdr.markForCheck();
141
256
  }
142
257
  onFileSelectedViaClick({ target }) {
143
258
  if (this.disabled) {
144
259
  return;
145
260
  }
261
+ const filesToAdd = this.mapToFileItem(target.files);
146
262
  this.files = [
147
263
  ...this.files,
148
- ...this.mapToFileItem(target.files)
264
+ ...filesToAdd
149
265
  ];
266
+ this.filesAdded.emit(filesToAdd);
267
+ this.onTouched();
150
268
  /* even if the user selects the same file,
151
269
  the onchange event will be triggered every time user clicks on the control.*/
152
270
  this.renderer.setProperty(this.input.nativeElement, 'value', null);
153
- this.onFileListChange();
154
271
  }
155
272
  onFileDropped(files) {
156
273
  if (this.disabled) {
157
274
  return;
158
275
  }
159
- this.files = [...this.files, ...this.mapToFileItem(files)];
160
- this.onFileListChange();
276
+ const filesToAdd = this.mapToFileItem(files);
277
+ this.files = [
278
+ ...this.files,
279
+ ...filesToAdd
280
+ ];
281
+ this.filesAdded.emit(filesToAdd);
282
+ this.onTouched();
161
283
  }
162
284
  deleteFile(index, event) {
163
285
  if (this.disabled) {
164
286
  return;
165
287
  }
166
288
  event?.stopPropagation();
289
+ this.fileRemoved.emit([this.files[index], index]);
167
290
  this.files.splice(index, 1);
168
291
  this.files = [...this.files];
169
- this.onFileListChange();
292
+ this.onTouched();
170
293
  }
171
294
  onFileListChange() {
172
295
  this.fileQueueChanged.emit(this.files);
@@ -215,76 +338,155 @@ class McMultipleFileUploadComponent {
215
338
  this.separatedCaptionTextWhenSelected = this.config.captionTextWhenSelected.split('{{ browseLink }}');
216
339
  this.separatedCaptionTextForCompactSize = this.config.captionTextForCompactSize.split('{{ browseLink }}');
217
340
  }
218
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.0", ngImport: i0, type: McMultipleFileUploadComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: MC_FILE_UPLOAD_CONFIGURATION, optional: true }, { token: MC_LOCALE_SERVICE, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
219
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.0", type: McMultipleFileUploadComponent, selector: "mc-multiple-file-upload", inputs: { accept: "accept", disabled: "disabled", errors: "errors", files: "files", size: "size", inputId: "inputId", customValidation: "customValidation" }, outputs: { fileQueueChanged: "fileQueueChanged" }, host: { classAttribute: "mc-multiple-file-upload" }, queries: [{ propertyName: "customFileIcon", first: true, predicate: ["mcFileIcon"], descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.selected]=\"files && files.length\"\n [ngClass]=\"size\"\n (filesDropped)=\"onFileDropped($event)\"\n>\n <ng-container *ngIf=\"!files.length; else fileOutput\">\n <div class=\"dropzone\">\n <ng-container *ngIf=\"size === 'default' else compactCaption\">\n <i mc-icon=\"mc-upload-to-cloud_64\"></i>\n <div class=\"dropzone__text\">\n <span class=\"multiple__header\">{{ config.title }}</span>\n <div>\n <span class=\"multiple__caption\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<div class=\"mc-file-upload__info-section\">\n <mc-hint class=\"mc-file-upload__hint\">\n <ng-content select=\"[hint]\"></ng-content>\n </mc-hint>\n\n <ng-container *ngIf=\"hasErrors\">\n <mc-hint class=\"mc-file-upload__hint mc-error\"\n *ngFor=\"let error of errors\">\n {{ error }}\n </mc-hint>\n </ng-container>\n</div>\n\n<ng-template #fileOutput>\n <div class=\"file-upload__dropzone\">\n <div class=\"mc-file-upload__grid\">\n <div class=\"mc-file-multiple-uploaded__header\">\n <div class=\"mc-file-multiple-uploaded__header-inner\">\n <div [class]=\"'mc-file-upload__' + column.cssClass\" *ngFor=\"let column of columnDefs\">\n {{ column.header }}\n </div>\n </div>\n </div>\n\n <mc-list-selection [autoSelect]=\"false\" [disabled]=\"disabled\">\n <mc-list-option\n class=\"multiple__uploaded-item\"\n [value]=\"file.file.name\"\n (keydown.delete)=\"deleteFile(index)\"\n (keydown.backspace)=\"deleteFile(index)\"\n *ngFor=\"let file of files; let index = index;\">\n <div class=\"mc-file-upload__row\" [class.error]=\"file.hasError\">\n <div class=\"mc-file-upload__file\">\n <ng-container *ngIf=\"{ loading: file.loading | async, progress: file.progress | async } as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\"\n [ngTemplateOutlet]=\"$any(customFileIcon)\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n >\n </ng-container>\n\n <mc-progress-spinner\n class=\"pt-nat-file-upload-name-cell__icon\"\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <span class=\"file-item__text\" [mcEllipsisCenter]=\"file.file.name\" [minVisibleLength]=\"10\"></span>\n </div>\n <div class=\"mc-file-upload__size\">\n {{ file.file.size | mcDataSize }}\n </div>\n <div class=\"mc-file-upload__action\">\n <i mc-icon=\"mc-close-circle_16\" (click)=\"deleteFile(index, $event)\"></i>\n </div>\n </div>\n </mc-list-option>\n </mc-list-selection>\n </div>\n\n <div class=\"btn-upload\">\n <div class=\"dropzone\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextWhenSelected[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextWhenSelected[1] }}\n </span>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #compactCaption>\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextForCompactSize[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextForCompactSize[1] }}\n </span>\n</ng-template>\n\n<ng-template #inputTemplate>\n <input #input\n type=\"file\"\n class=\"cdk-visually-hidden\"\n multiple\n [id]=\"inputId\"\n [accept]=\"acceptedFiles\"\n [disabled]=\"disabled\"\n (change)=\"onFileSelectedViaClick($event)\">\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{border-radius:var(--mc-file-upload-size-multiple-border-radius, 4px);border-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-style:var(--mc-file-upload-size-multiple-border-style, dashed)}.mc-file-upload .mc-list-option{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);height:36px}.mc-file-upload .mc-list-option .mc-icon{margin-right:0}.mc-file-upload .mc-file-upload__grid{min-height:142px}.mc-file-upload .mc-file-multiple-uploaded__header-inner,.mc-file-upload .mc-file-upload__row{display:flex;align-items:center}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{width:65%;max-width:65%}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__size{width:var(--mc-size-7xl, 64px);min-width:var(--mc-size-7xl, 64px);text-align:left;flex-grow:1}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__action{padding-left:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px);padding-right:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px)}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{display:flex;align-items:center}.mc-file-upload .mc-file-upload__row .mc-file-upload__file .file-item__text{margin-left:0;width:90%}.mc-file-upload .mc-file-multiple-uploaded__header{border-bottom-width:1px;border-bottom-style:solid}.mc-file-upload .mc-file-multiple-uploaded__header-inner{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);border:2px solid transparent;border-bottom:unset;box-sizing:border-box;height:var(--mc-size-3xl, 32px)}.mc-file-upload .btn-upload .dropzone{margin:0;border-top-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-top-style:var(--mc-file-upload-size-multiple-border-style, dashed);padding:3px var(--mc-size-m, 12px) var(--mc-size-xxs, 4px) var(--mc-size-m, 12px)}.mc-file-upload.compact:not(.selected){height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px)}.mc-file-upload.compact .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload.default{min-height:176px;justify-content:center}.mc-file-upload.default .dropzone .dropzone__text{margin-left:var(--mc-size-l, 16px)}.mc-file-upload.default .btn-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-upload__dropzone{width:100%;height:100%}.mc-hint{display:block}.mc-file-upload__hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.McProgressSpinner, selector: "mc-progress-spinner", inputs: ["color", "id", "value", "mode", "size"] }, { kind: "component", type: i3.McIcon, selector: "[mc-icon]", inputs: ["color"] }, { kind: "directive", type: i3.McIconCSSStyler, selector: "[mc-icon]" }, { kind: "component", type: i4.McListSelection, selector: "mc-list-selection", inputs: ["disabled", "autoSelect", "noUnselectLast", "horizontal", "tabIndex", "compareWith"], outputs: ["onSelectAll", "onCopy", "selectionChange"], exportAs: ["mcListSelection"] }, { kind: "component", type: i4.McListOption, selector: "mc-list-option", inputs: ["checkboxPosition", "value", "disabled", "showCheckbox", "selected"], exportAs: ["mcListOption"] }, { kind: "directive", type: i5.McHint, selector: "mc-hint", inputs: ["color", "id"] }, { kind: "directive", type: i6.McEllipsisCenterDirective, selector: "[mcEllipsisCenter]", inputs: ["mcEllipsisCenter", "minVisibleLength"] }, { kind: "directive", type: i7.McLink, selector: "[mc-link]", inputs: ["tabIndex", "disabled", "pseudo", "noUnderline", "caption", "useVisited", "print"], exportAs: ["mcLink"] }, { kind: "directive", type: McFileDropDirective, selector: "[mcFileDrop]", outputs: ["filesDropped"], exportAs: ["mcFileDrop"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i9.McDataSizePipe, name: "mcDataSize" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
341
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.0", ngImport: i0, type: McMultipleFileUploadComponent, deps: [{ token: MC_FILE_UPLOAD_CONFIGURATION, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
342
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.0", type: McMultipleFileUploadComponent, selector: "mc-multiple-file-upload", inputs: { accept: "accept", disabled: "disabled", errors: "errors", size: "size", inputId: "inputId", customValidation: "customValidation", errorStateMatcher: "errorStateMatcher", files: "files" }, outputs: { fileQueueChanged: "fileQueueChanged", filesAdded: "filesAdded", fileRemoved: "fileRemoved" }, host: { classAttribute: "mc-multiple-file-upload" }, queries: [{ propertyName: "customFileIcon", first: true, predicate: ["mcFileIcon"], descendants: true, read: TemplateRef }, { propertyName: "hint", predicate: McHint }], viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.mc-error]=\"errorState\"\n [class.selected]=\"files && files.length\"\n [ngClass]=\"size\"\n (filesDropped)=\"onFileDropped($event)\"\n>\n <ng-container *ngIf=\"!files.length; else fileOutput\">\n <div class=\"dropzone\">\n <ng-container *ngIf=\"size === 'default' else compactCaption\">\n <i mc-icon=\"mc-upload-to-cloud_64\"></i>\n <div class=\"dropzone__text\">\n <span class=\"multiple__header\">{{ config.title }}</span>\n <div>\n <span class=\"multiple__caption\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<ng-container *ngIf=\"hasHint\">\n <div class=\"mc-file-upload__hint\">\n <ng-content select=\"mc-hint,[hint]\" />\n </div>\n</ng-container>\n\n<ng-template #fileOutput>\n <div class=\"file-upload__dropzone\">\n <div class=\"mc-file-upload__grid\">\n <div class=\"mc-file-multiple-uploaded__header\">\n <div class=\"mc-file-multiple-uploaded__header-inner\">\n <div [class]=\"'mc-file-upload__' + column.cssClass\" *ngFor=\"let column of columnDefs\">\n {{ column.header }}\n </div>\n </div>\n </div>\n\n <mc-list-selection [autoSelect]=\"false\" [disabled]=\"disabled\">\n <mc-list-option\n class=\"multiple__uploaded-item\"\n [value]=\"file.file.name\"\n (keydown.delete)=\"deleteFile(index)\"\n (keydown.backspace)=\"deleteFile(index)\"\n *ngFor=\"let file of files; let index = index;\">\n <div class=\"mc-file-upload__row\" [class.error]=\"file.hasError\">\n <div class=\"mc-file-upload__file\">\n <ng-container *ngIf=\"{ loading: file.loading | async, progress: file.progress | async } as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\"\n [ngTemplateOutlet]=\"$any(customFileIcon)\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n >\n </ng-container>\n\n <mc-progress-spinner\n class=\"pt-nat-file-upload-name-cell__icon\"\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <span class=\"file-item__text\" [mcEllipsisCenter]=\"file.file.name\" [minVisibleLength]=\"10\"></span>\n </div>\n <div class=\"mc-file-upload__size\">\n {{ file.file.size | mcDataSize }}\n </div>\n <div class=\"mc-file-upload__action\">\n <i mc-icon=\"mc-close-circle_16\" (click)=\"deleteFile(index, $event)\"></i>\n </div>\n </div>\n </mc-list-option>\n </mc-list-selection>\n </div>\n\n <div class=\"btn-upload\">\n <div class=\"dropzone\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextWhenSelected[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextWhenSelected[1] }}\n </span>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #compactCaption>\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextForCompactSize[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextForCompactSize[1] }}\n </span>\n</ng-template>\n\n<ng-template #inputTemplate>\n <input #input\n type=\"file\"\n class=\"cdk-visually-hidden\"\n multiple\n [id]=\"inputId\"\n [accept]=\"acceptedFiles\"\n [disabled]=\"disabled\"\n (change)=\"onFileSelectedViaClick($event)\">\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}.mc-file-upload__hint>.mc-hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{border-radius:var(--mc-file-upload-size-multiple-border-radius, 4px);border-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-style:var(--mc-file-upload-size-multiple-border-style, dashed)}.mc-file-upload .mc-list-option{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);height:36px}.mc-file-upload .mc-list-option .mc-icon{margin-right:0}.mc-file-upload .mc-file-upload__grid{min-height:142px}.mc-file-upload .mc-file-multiple-uploaded__header-inner,.mc-file-upload .mc-file-upload__row{display:flex;align-items:center}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{width:65%;max-width:65%}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__size{width:var(--mc-size-7xl, 64px);min-width:var(--mc-size-7xl, 64px);text-align:left;flex-grow:1}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__action{padding-left:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px);padding-right:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px)}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{display:flex;align-items:center}.mc-file-upload .mc-file-upload__row .mc-file-upload__file .file-item__text{margin-left:0;width:90%}.mc-file-upload .mc-file-multiple-uploaded__header{border-bottom-width:1px;border-bottom-style:solid}.mc-file-upload .mc-file-multiple-uploaded__header-inner{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);border:2px solid transparent;border-bottom:unset;box-sizing:border-box;height:var(--mc-size-3xl, 32px)}.mc-file-upload .btn-upload .dropzone{margin:0;border-top-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-top-style:var(--mc-file-upload-size-multiple-border-style, dashed);padding:3px var(--mc-size-m, 12px) var(--mc-size-xxs, 4px) var(--mc-size-m, 12px)}.mc-file-upload.compact:not(.selected){height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px)}.mc-file-upload.compact .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload.default{min-height:176px;justify-content:center}.mc-file-upload.default .dropzone .dropzone__text{margin-left:var(--mc-size-l, 16px)}.mc-file-upload.default .btn-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-upload__dropzone{width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.McProgressSpinner, selector: "mc-progress-spinner", inputs: ["color", "id", "value", "mode", "size"] }, { kind: "component", type: i3.McIcon, selector: "[mc-icon]", inputs: ["color"] }, { kind: "directive", type: i3.McIconCSSStyler, selector: "[mc-icon]" }, { kind: "component", type: i4.McListSelection, selector: "mc-list-selection", inputs: ["disabled", "autoSelect", "noUnselectLast", "horizontal", "tabIndex", "compareWith"], outputs: ["onSelectAll", "onCopy", "selectionChange"], exportAs: ["mcListSelection"] }, { kind: "component", type: i4.McListOption, selector: "mc-list-option", inputs: ["checkboxPosition", "value", "disabled", "showCheckbox", "selected"], exportAs: ["mcListOption"] }, { kind: "directive", type: i5.McEllipsisCenterDirective, selector: "[mcEllipsisCenter]", inputs: ["mcEllipsisCenter", "minVisibleLength"] }, { kind: "directive", type: i6.McLink, selector: "[mc-link]", inputs: ["tabIndex", "disabled", "pseudo", "noUnderline", "caption", "useVisited", "print"], exportAs: ["mcLink"] }, { kind: "directive", type: McFileDropDirective, selector: "[mcFileDrop]", outputs: ["filesDropped"], exportAs: ["mcFileDrop"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i8.McDataSizePipe, name: "mcDataSize" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
220
343
  }
221
344
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.0", ngImport: i0, type: McMultipleFileUploadComponent, decorators: [{
222
345
  type: Component,
223
- args: [{ selector: 'mc-multiple-file-upload', changeDetection: ChangeDetectionStrategy.OnPush, host: {
346
+ args: [{ selector: 'mc-multiple-file-upload', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
224
347
  class: 'mc-multiple-file-upload'
225
- }, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.selected]=\"files && files.length\"\n [ngClass]=\"size\"\n (filesDropped)=\"onFileDropped($event)\"\n>\n <ng-container *ngIf=\"!files.length; else fileOutput\">\n <div class=\"dropzone\">\n <ng-container *ngIf=\"size === 'default' else compactCaption\">\n <i mc-icon=\"mc-upload-to-cloud_64\"></i>\n <div class=\"dropzone__text\">\n <span class=\"multiple__header\">{{ config.title }}</span>\n <div>\n <span class=\"multiple__caption\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<div class=\"mc-file-upload__info-section\">\n <mc-hint class=\"mc-file-upload__hint\">\n <ng-content select=\"[hint]\"></ng-content>\n </mc-hint>\n\n <ng-container *ngIf=\"hasErrors\">\n <mc-hint class=\"mc-file-upload__hint mc-error\"\n *ngFor=\"let error of errors\">\n {{ error }}\n </mc-hint>\n </ng-container>\n</div>\n\n<ng-template #fileOutput>\n <div class=\"file-upload__dropzone\">\n <div class=\"mc-file-upload__grid\">\n <div class=\"mc-file-multiple-uploaded__header\">\n <div class=\"mc-file-multiple-uploaded__header-inner\">\n <div [class]=\"'mc-file-upload__' + column.cssClass\" *ngFor=\"let column of columnDefs\">\n {{ column.header }}\n </div>\n </div>\n </div>\n\n <mc-list-selection [autoSelect]=\"false\" [disabled]=\"disabled\">\n <mc-list-option\n class=\"multiple__uploaded-item\"\n [value]=\"file.file.name\"\n (keydown.delete)=\"deleteFile(index)\"\n (keydown.backspace)=\"deleteFile(index)\"\n *ngFor=\"let file of files; let index = index;\">\n <div class=\"mc-file-upload__row\" [class.error]=\"file.hasError\">\n <div class=\"mc-file-upload__file\">\n <ng-container *ngIf=\"{ loading: file.loading | async, progress: file.progress | async } as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\"\n [ngTemplateOutlet]=\"$any(customFileIcon)\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n >\n </ng-container>\n\n <mc-progress-spinner\n class=\"pt-nat-file-upload-name-cell__icon\"\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <span class=\"file-item__text\" [mcEllipsisCenter]=\"file.file.name\" [minVisibleLength]=\"10\"></span>\n </div>\n <div class=\"mc-file-upload__size\">\n {{ file.file.size | mcDataSize }}\n </div>\n <div class=\"mc-file-upload__action\">\n <i mc-icon=\"mc-close-circle_16\" (click)=\"deleteFile(index, $event)\"></i>\n </div>\n </div>\n </mc-list-option>\n </mc-list-selection>\n </div>\n\n <div class=\"btn-upload\">\n <div class=\"dropzone\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextWhenSelected[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextWhenSelected[1] }}\n </span>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #compactCaption>\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextForCompactSize[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextForCompactSize[1] }}\n </span>\n</ng-template>\n\n<ng-template #inputTemplate>\n <input #input\n type=\"file\"\n class=\"cdk-visually-hidden\"\n multiple\n [id]=\"inputId\"\n [accept]=\"acceptedFiles\"\n [disabled]=\"disabled\"\n (change)=\"onFileSelectedViaClick($event)\">\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{border-radius:var(--mc-file-upload-size-multiple-border-radius, 4px);border-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-style:var(--mc-file-upload-size-multiple-border-style, dashed)}.mc-file-upload .mc-list-option{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);height:36px}.mc-file-upload .mc-list-option .mc-icon{margin-right:0}.mc-file-upload .mc-file-upload__grid{min-height:142px}.mc-file-upload .mc-file-multiple-uploaded__header-inner,.mc-file-upload .mc-file-upload__row{display:flex;align-items:center}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{width:65%;max-width:65%}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__size{width:var(--mc-size-7xl, 64px);min-width:var(--mc-size-7xl, 64px);text-align:left;flex-grow:1}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__action{padding-left:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px);padding-right:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px)}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{display:flex;align-items:center}.mc-file-upload .mc-file-upload__row .mc-file-upload__file .file-item__text{margin-left:0;width:90%}.mc-file-upload .mc-file-multiple-uploaded__header{border-bottom-width:1px;border-bottom-style:solid}.mc-file-upload .mc-file-multiple-uploaded__header-inner{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);border:2px solid transparent;border-bottom:unset;box-sizing:border-box;height:var(--mc-size-3xl, 32px)}.mc-file-upload .btn-upload .dropzone{margin:0;border-top-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-top-style:var(--mc-file-upload-size-multiple-border-style, dashed);padding:3px var(--mc-size-m, 12px) var(--mc-size-xxs, 4px) var(--mc-size-m, 12px)}.mc-file-upload.compact:not(.selected){height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px)}.mc-file-upload.compact .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload.default{min-height:176px;justify-content:center}.mc-file-upload.default .dropzone .dropzone__text{margin-left:var(--mc-size-l, 16px)}.mc-file-upload.default .btn-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-upload__dropzone{width:100%;height:100%}.mc-hint{display:block}.mc-file-upload__hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n"] }]
226
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
348
+ }, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.mc-error]=\"errorState\"\n [class.selected]=\"files && files.length\"\n [ngClass]=\"size\"\n (filesDropped)=\"onFileDropped($event)\"\n>\n <ng-container *ngIf=\"!files.length; else fileOutput\">\n <div class=\"dropzone\">\n <ng-container *ngIf=\"size === 'default' else compactCaption\">\n <i mc-icon=\"mc-upload-to-cloud_64\"></i>\n <div class=\"dropzone__text\">\n <span class=\"multiple__header\">{{ config.title }}</span>\n <div>\n <span class=\"multiple__caption\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<ng-container *ngIf=\"hasHint\">\n <div class=\"mc-file-upload__hint\">\n <ng-content select=\"mc-hint,[hint]\" />\n </div>\n</ng-container>\n\n<ng-template #fileOutput>\n <div class=\"file-upload__dropzone\">\n <div class=\"mc-file-upload__grid\">\n <div class=\"mc-file-multiple-uploaded__header\">\n <div class=\"mc-file-multiple-uploaded__header-inner\">\n <div [class]=\"'mc-file-upload__' + column.cssClass\" *ngFor=\"let column of columnDefs\">\n {{ column.header }}\n </div>\n </div>\n </div>\n\n <mc-list-selection [autoSelect]=\"false\" [disabled]=\"disabled\">\n <mc-list-option\n class=\"multiple__uploaded-item\"\n [value]=\"file.file.name\"\n (keydown.delete)=\"deleteFile(index)\"\n (keydown.backspace)=\"deleteFile(index)\"\n *ngFor=\"let file of files; let index = index;\">\n <div class=\"mc-file-upload__row\" [class.error]=\"file.hasError\">\n <div class=\"mc-file-upload__file\">\n <ng-container *ngIf=\"{ loading: file.loading | async, progress: file.progress | async } as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\"\n [ngTemplateOutlet]=\"$any(customFileIcon)\"\n [ngTemplateOutletContext]=\"{ $implicit: file }\"\n >\n </ng-container>\n\n <mc-progress-spinner\n class=\"pt-nat-file-upload-name-cell__icon\"\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <span class=\"file-item__text\" [mcEllipsisCenter]=\"file.file.name\" [minVisibleLength]=\"10\"></span>\n </div>\n <div class=\"mc-file-upload__size\">\n {{ file.file.size | mcDataSize }}\n </div>\n <div class=\"mc-file-upload__action\">\n <i mc-icon=\"mc-close-circle_16\" (click)=\"deleteFile(index, $event)\"></i>\n </div>\n </div>\n </mc-list-option>\n </mc-list-selection>\n </div>\n\n <div class=\"btn-upload\">\n <div class=\"dropzone\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextWhenSelected[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextWhenSelected[1] }}\n </span>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #compactCaption>\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text multiple__caption\">\n {{ separatedCaptionTextForCompactSize[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<ng-container *ngTemplateOutlet=\"inputTemplate\"></ng-container></label>{{ separatedCaptionTextForCompactSize[1] }}\n </span>\n</ng-template>\n\n<ng-template #inputTemplate>\n <input #input\n type=\"file\"\n class=\"cdk-visually-hidden\"\n multiple\n [id]=\"inputId\"\n [accept]=\"acceptedFiles\"\n [disabled]=\"disabled\"\n (change)=\"onFileSelectedViaClick($event)\">\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}.mc-file-upload__hint>.mc-hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{border-radius:var(--mc-file-upload-size-multiple-border-radius, 4px);border-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-style:var(--mc-file-upload-size-multiple-border-style, dashed)}.mc-file-upload .mc-list-option{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);height:36px}.mc-file-upload .mc-list-option .mc-icon{margin-right:0}.mc-file-upload .mc-file-upload__grid{min-height:142px}.mc-file-upload .mc-file-multiple-uploaded__header-inner,.mc-file-upload .mc-file-upload__row{display:flex;align-items:center}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{width:65%;max-width:65%}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__size{width:var(--mc-size-7xl, 64px);min-width:var(--mc-size-7xl, 64px);text-align:left;flex-grow:1}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__file,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__size,.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file,.mc-file-upload .mc-file-upload__row .mc-file-upload__size,.mc-file-upload .mc-file-upload__row .mc-file-upload__action{padding-left:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px);padding-right:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px)}.mc-file-upload .mc-file-multiple-uploaded__header-inner .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__action,.mc-file-upload .mc-file-upload__row .mc-file-upload__file{display:flex;align-items:center}.mc-file-upload .mc-file-upload__row .mc-file-upload__file .file-item__text{margin-left:0;width:90%}.mc-file-upload .mc-file-multiple-uploaded__header{border-bottom-width:1px;border-bottom-style:solid}.mc-file-upload .mc-file-multiple-uploaded__header-inner{padding:var(--mc-file-upload-size-multiple-uploaded-item-horizontal-padding, 8px) var(--mc-file-upload-size-multiple-uploaded-item-vertical-padding, 8px);border:2px solid transparent;border-bottom:unset;box-sizing:border-box;height:var(--mc-size-3xl, 32px)}.mc-file-upload .btn-upload .dropzone{margin:0;border-top-width:var(--mc-file-upload-size-multiple-border-width, 1px);border-top-style:var(--mc-file-upload-size-multiple-border-style, dashed);padding:3px var(--mc-size-m, 12px) var(--mc-size-xxs, 4px) var(--mc-size-m, 12px)}.mc-file-upload.compact:not(.selected){height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px)}.mc-file-upload.compact .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload.default{min-height:176px;justify-content:center}.mc-file-upload.default .dropzone .dropzone__text{margin-left:var(--mc-size-l, 16px)}.mc-file-upload.default .btn-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-upload__dropzone{width:100%;height:100%}\n"] }]
349
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
227
350
  type: Optional
228
351
  }, {
229
352
  type: Inject,
230
353
  args: [MC_FILE_UPLOAD_CONFIGURATION]
231
- }] }, { type: i9.McLocaleService, decorators: [{
232
- type: Optional
233
- }, {
234
- type: Inject,
235
- args: [MC_LOCALE_SERVICE]
236
354
  }] }], propDecorators: { accept: [{
237
355
  type: Input
238
356
  }], disabled: [{
239
357
  type: Input
240
358
  }], errors: [{
241
359
  type: Input
242
- }], files: [{
243
- type: Input
244
360
  }], size: [{
245
361
  type: Input
246
362
  }], inputId: [{
247
363
  type: Input
248
364
  }], customValidation: [{
249
365
  type: Input
366
+ }], errorStateMatcher: [{
367
+ type: Input
368
+ }], files: [{
369
+ type: Input
250
370
  }], fileQueueChanged: [{
251
371
  type: Output
372
+ }], filesAdded: [{
373
+ type: Output
374
+ }], fileRemoved: [{
375
+ type: Output
252
376
  }], customFileIcon: [{
253
377
  type: ContentChild,
254
378
  args: ['mcFileIcon', { static: false, read: TemplateRef }]
255
379
  }], input: [{
256
380
  type: ViewChild,
257
381
  args: ['input']
382
+ }], hint: [{
383
+ type: ContentChildren,
384
+ args: [McHint]
258
385
  }] } });
259
386
 
260
387
  let nextSingleFileUploadUniqueId = 0;
261
388
  const MC_SINGLE_FILE_UPLOAD_DEFAULT_CONFIGURATION = ruRULocaleData['ru-RU'].fileUpload.single;
262
- class McSingleFileUploadComponent {
389
+ class McSingleFileUploadComponent extends McFileUploadBase {
390
+ get file() {
391
+ return this._file;
392
+ }
393
+ set file(currentFile) {
394
+ this._file = currentFile;
395
+ this.cvaOnChange(this._file);
396
+ this.fileQueueChanged.emit(this._file);
397
+ this.cdr.markForCheck();
398
+ }
263
399
  get acceptedFiles() {
264
400
  return this.accept && this.accept.length > 0 ? this.accept.map((ext) => `.${ext}`).join(',') : '*/*';
265
401
  }
266
- constructor(renderer, cdr, configuration, localeService) {
267
- this.renderer = renderer;
268
- this.cdr = cdr;
402
+ get hasHint() {
403
+ return this.hint.length > 0;
404
+ }
405
+ /**
406
+ * Indicates an invalid state based on `errorState`,
407
+ * applying a CSS class in HTML for visual feedback.
408
+ */
409
+ get invalid() {
410
+ return !!this.file?.hasError || this.errorState;
411
+ }
412
+ constructor(configuration) {
413
+ super();
269
414
  this.configuration = configuration;
270
- this.localeService = localeService;
415
+ this._file = null;
271
416
  this.disabled = false;
417
+ /**
418
+ * @deprecated use `FormControl.errors`
419
+ */
272
420
  this.errors = [];
273
- this.files = [];
274
421
  this.inputId = `mc-single-file-upload-${nextSingleFileUploadUniqueId++}`;
275
422
  this.fileQueueChanged = new EventEmitter();
423
+ /** cvaOnChange function registered via registerOnChange (ControlValueAccessor).
424
+ * @docs-private
425
+ */
426
+ // tslint:disable-next-line:no-empty
427
+ this.cvaOnChange = (_) => { };
428
+ /** onTouch function registered via registerOnTouch (ControlValueAccessor).
429
+ * @docs-private
430
+ */
431
+ // tslint:disable-next-line:no-empty
432
+ this.onTouched = () => { };
276
433
  this.updateLocaleParams = () => {
277
434
  this.config = this.configuration || this.localeService?.getParams('fileUpload').multiple;
278
435
  this.makeCaptionText();
279
436
  this.cdr.markForCheck();
280
437
  };
281
- this.localeSubscription = this.localeService?.changes.subscribe(this.updateLocaleParams) || Subscription.EMPTY;
282
- if (!localeService) {
438
+ this.localeService?.changes.pipe(takeUntilDestroyed())
439
+ .subscribe(this.updateLocaleParams);
440
+ if (!this.localeService) {
283
441
  this.initDefaultParams();
284
442
  }
443
+ if (this.ngControl) {
444
+ // Note: we provide the value accessor through here, instead of
445
+ // the `providers` to avoid running into a circular import.
446
+ this.ngControl.valueAccessor = this;
447
+ }
448
+ }
449
+ ngAfterViewInit() {
450
+ // FormControl specific errors update
451
+ this.ngControl?.statusChanges?.pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
452
+ .subscribe((status) => {
453
+ if (this._file) {
454
+ this._file.hasError = status === 'INVALID';
455
+ }
456
+ this.errors = Object.values(this.ngControl?.errors || {});
457
+ this.cdr.markForCheck();
458
+ });
459
+ this.stateChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.cdr.markForCheck());
460
+ }
461
+ ngDoCheck() {
462
+ if (this.ngControl) {
463
+ // We need to re-evaluate this on every change detection cycle, because there are some
464
+ // error triggers that we can't subscribe to (e.g. parent form submissions). This means
465
+ // that whatever logic is in here has to be super lean or we risk destroying the performance.
466
+ this.updateErrorState();
467
+ }
468
+ }
469
+ /** Implemented as part of ControlValueAccessor. @docs-private */
470
+ writeValue(file) {
471
+ if (file instanceof File) {
472
+ this.file = this.mapToFileItem(file);
473
+ }
474
+ else {
475
+ this.file = file;
476
+ }
285
477
  }
286
- ngOnDestroy() {
287
- this.localeSubscription.unsubscribe();
478
+ /** Implemented as part of ControlValueAccessor. @docs-private */
479
+ registerOnChange(fn) { this.cvaOnChange = fn; }
480
+ /** Implemented as part of ControlValueAccessor. @docs-private */
481
+ registerOnTouched(fn) { this.onTouched = fn; }
482
+ /**
483
+ * Sets the disabled state of the control. Implemented as a part of ControlValueAccessor.
484
+ * @param isDisabled Whether the control should be disabled.
485
+ * @docs-private
486
+ */
487
+ setDisabledState(isDisabled) {
488
+ this.disabled = isDisabled;
489
+ this.cdr.markForCheck();
288
490
  }
289
491
  onFileSelectedViaClick({ target }) {
290
492
  if (this.disabled) {
@@ -292,9 +494,9 @@ class McSingleFileUploadComponent {
292
494
  }
293
495
  const files = target.files;
294
496
  if (files?.length) {
295
- this.files = [this.mapToFileItem(files[0])];
296
- this.fileQueueChanged.emit(this.files[0]);
497
+ this.file = this.mapToFileItem(files[0]);
297
498
  }
499
+ this.onTouched();
298
500
  /* even if the user selects the same file,
299
501
  the onchange event will be triggered every time user clicks on the control.*/
300
502
  this.renderer.setProperty(this.input.nativeElement, 'value', null);
@@ -304,19 +506,20 @@ class McSingleFileUploadComponent {
304
506
  return;
305
507
  }
306
508
  event?.stopPropagation();
307
- this.files = [];
509
+ this.file = null;
308
510
  this.errors = [];
309
- this.fileQueueChanged.emit(null);
511
+ // mark as touched after file drop even if file wasn't correct
512
+ this.onTouched();
310
513
  }
311
514
  onFileDropped(files) {
312
515
  if (this.disabled) {
313
516
  return;
314
517
  }
315
- if (this.isCorrectExtension(files[0])) {
316
- this.files = Array.from(files)
317
- .map((file) => this.mapToFileItem(file));
318
- this.fileQueueChanged.emit(this.files[0]);
518
+ if (files?.length && this.isCorrectExtension(files[0])) {
519
+ this.file = this.mapToFileItem(files[0]);
319
520
  }
521
+ // mark as touched after file drop even if file wasn't correct
522
+ this.onTouched();
320
523
  }
321
524
  mapToFileItem(file) {
322
525
  this.validateFile(file);
@@ -327,12 +530,13 @@ class McSingleFileUploadComponent {
327
530
  };
328
531
  }
329
532
  validateFile(file) {
330
- if (this.customValidation && this.customValidation.length) {
331
- this.errors = this.customValidation.reduce((errors, validatorFn) => {
332
- errors.push(validatorFn(file));
333
- return errors;
334
- }, []).filter(Boolean);
533
+ if (!this.customValidation?.length) {
534
+ return;
335
535
  }
536
+ this.errors = this.customValidation.reduce((errors, validatorFn) => {
537
+ errors.push(validatorFn(file));
538
+ return errors;
539
+ }, []).filter(Boolean);
336
540
  }
337
541
  isCorrectExtension(file) {
338
542
  const fileExt = file.name.split('.').pop() || '';
@@ -345,41 +549,41 @@ class McSingleFileUploadComponent {
345
549
  makeCaptionText() {
346
550
  this.separatedCaptionText = this.config.captionText.split('{{ browseLink }}');
347
551
  }
348
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.0", ngImport: i0, type: McSingleFileUploadComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: MC_FILE_UPLOAD_CONFIGURATION, optional: true }, { token: MC_LOCALE_SERVICE, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
349
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.0", type: McSingleFileUploadComponent, selector: "mc-single-file-upload", inputs: { accept: "accept", disabled: "disabled", errors: "errors", files: "files", inputId: "inputId", customValidation: "customValidation" }, outputs: { fileQueueChanged: "fileQueueChanged" }, host: { classAttribute: "mc-single-file-upload" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.mc-error]=\"errors && errors.length\"\n (filesDropped)=\"onFileDropped($event)\">\n <div class=\"dropzone\" *ngIf=\"!files.length; else fileOutput\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<input #input type=\"file\" class=\"cdk-visually-hidden\" [id]=\"inputId\" [accept]=\"acceptedFiles\" [disabled]=\"disabled\" (change)=\"onFileSelectedViaClick($event)\"></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n</div>\n\n<mc-hint class=\"mc-file-upload__hint\">\n <ng-content select=\"[hint]\"></ng-content>\n</mc-hint>\n<ng-container *ngIf=\"errors && errors.length\">\n <mc-hint class=\"mc-file-upload__hint mc-error\" *ngFor=\"let error of errors\">{{ error }}</mc-hint>\n</ng-container>\n\n\n<ng-template #fileOutput>\n <div class=\"file-item\" *ngIf=\"files && files.length\">\n <div class=\"file-item__text-wrapper\">\n <ng-container *ngIf=\"{ loading: files[0].loading | async, progress: files[0].progress | async} as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\">\n <ng-content select=\"[mc-icon]\"></ng-content>\n </ng-container>\n\n <mc-progress-spinner\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <div class=\"file-item__text\" [mcEllipsisCenter]=\"files[0].file.name\" [minVisibleLength]=\"10\"></div>\n </div>\n <button mc-button\n class=\"mc-button_transparent\"\n [disabled]=\"disabled\"\n (keydown.delete)=\"deleteItem()\"\n (keydown.backspace)=\"deleteItem()\"\n (click)=\"deleteItem($event)\">\n <i mc-icon=\"mc-close-circle_16\"></i>\n </button>\n </div>\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px);border-radius:var(--mc-file-upload-size-single-border-radius, 4px);border-width:var(--mc-file-upload-size-single-border-width, 1px);border-style:var(--mc-file-upload-size-single-border-style, dashed)}.mc-file-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-item{width:100%}.mc-file-upload .file-item .file-item__text-wrapper{display:flex;align-items:center;width:100%}.mc-file-upload .file-item .file-item__text-wrapper .file-item__text{margin-left:var(--mc-size-s, 8px);width:120px;flex-grow:1}.mc-hint{display:block}.mc-file-upload__hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.McProgressSpinner, selector: "mc-progress-spinner", inputs: ["color", "id", "value", "mode", "size"] }, { kind: "component", type: i3.McIcon, selector: "[mc-icon]", inputs: ["color"] }, { kind: "directive", type: i3.McIconCSSStyler, selector: "[mc-icon]" }, { kind: "component", type: i4$1.McButton, selector: "[mc-button]", inputs: ["color", "tabIndex", "disabled"] }, { kind: "directive", type: i4$1.McButtonCssStyler, selector: "[mc-button]" }, { kind: "directive", type: i5.McHint, selector: "mc-hint", inputs: ["color", "id"] }, { kind: "directive", type: i6.McEllipsisCenterDirective, selector: "[mcEllipsisCenter]", inputs: ["mcEllipsisCenter", "minVisibleLength"] }, { kind: "directive", type: i7.McLink, selector: "[mc-link]", inputs: ["tabIndex", "disabled", "pseudo", "noUnderline", "caption", "useVisited", "print"], exportAs: ["mcLink"] }, { kind: "directive", type: McFileDropDirective, selector: "[mcFileDrop]", outputs: ["filesDropped"], exportAs: ["mcFileDrop"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
552
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.0", ngImport: i0, type: McSingleFileUploadComponent, deps: [{ token: MC_FILE_UPLOAD_CONFIGURATION, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
553
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.2.0", type: McSingleFileUploadComponent, selector: "mc-single-file-upload", inputs: { file: "file", accept: "accept", disabled: "disabled", errors: "errors", inputId: "inputId", customValidation: "customValidation", errorStateMatcher: "errorStateMatcher" }, outputs: { fileQueueChanged: "fileQueueChanged" }, host: { classAttribute: "mc-single-file-upload" }, queries: [{ propertyName: "hint", predicate: McHint }], viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.mc-error]=\"invalid\"\n (filesDropped)=\"onFileDropped($event)\">\n <div class=\"dropzone\" *ngIf=\"!file; else fileOutput\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<input #input type=\"file\" class=\"cdk-visually-hidden\" [id]=\"inputId\" [accept]=\"acceptedFiles\" [disabled]=\"disabled\" (change)=\"onFileSelectedViaClick($event)\"></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n</div>\n\n<ng-container *ngIf=\"hasHint\">\n <div class=\"mc-file-upload__hint\">\n <ng-content select=\"mc-hint,[hint]\" />\n </div>\n</ng-container>\n\n<ng-template #fileOutput>\n <div class=\"file-item\" *ngIf=\"file\">\n <div class=\"file-item__text-wrapper\">\n <ng-container *ngIf=\"{ loading: file.loading | async, progress: file.progress | async} as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\">\n <ng-content select=\"[mc-icon]\"></ng-content>\n </ng-container>\n\n <mc-progress-spinner\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <div class=\"file-item__text\" [mcEllipsisCenter]=\"file.file.name\" [minVisibleLength]=\"10\"></div>\n </div>\n <button mc-button\n class=\"mc-button_transparent\"\n [disabled]=\"disabled\"\n (keydown.delete)=\"deleteItem()\"\n (keydown.backspace)=\"deleteItem()\"\n (click)=\"deleteItem($event)\">\n <i mc-icon=\"mc-close-circle_16\"></i>\n </button>\n </div>\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}.mc-file-upload__hint>.mc-hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px);border-radius:var(--mc-file-upload-size-single-border-radius, 4px);border-width:var(--mc-file-upload-size-single-border-width, 1px);border-style:var(--mc-file-upload-size-single-border-style, dashed)}.mc-file-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-item{width:100%}.mc-file-upload .file-item .file-item__text-wrapper{display:flex;align-items:center;width:100%}.mc-file-upload .file-item .file-item__text-wrapper .file-item__text{margin-left:var(--mc-size-s, 8px);width:120px;flex-grow:1}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.McProgressSpinner, selector: "mc-progress-spinner", inputs: ["color", "id", "value", "mode", "size"] }, { kind: "component", type: i3.McIcon, selector: "[mc-icon]", inputs: ["color"] }, { kind: "directive", type: i3.McIconCSSStyler, selector: "[mc-icon]" }, { kind: "component", type: i4$1.McButton, selector: "[mc-button]", inputs: ["color", "tabIndex", "disabled"] }, { kind: "directive", type: i4$1.McButtonCssStyler, selector: "[mc-button]" }, { kind: "directive", type: i5.McEllipsisCenterDirective, selector: "[mcEllipsisCenter]", inputs: ["mcEllipsisCenter", "minVisibleLength"] }, { kind: "directive", type: i6.McLink, selector: "[mc-link]", inputs: ["tabIndex", "disabled", "pseudo", "noUnderline", "caption", "useVisited", "print"], exportAs: ["mcLink"] }, { kind: "directive", type: McFileDropDirective, selector: "[mcFileDrop]", outputs: ["filesDropped"], exportAs: ["mcFileDrop"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
350
554
  }
351
555
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.0", ngImport: i0, type: McSingleFileUploadComponent, decorators: [{
352
556
  type: Component,
353
- args: [{ selector: 'mc-single-file-upload', changeDetection: ChangeDetectionStrategy.OnPush, host: {
557
+ args: [{ selector: 'mc-single-file-upload', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
354
558
  class: 'mc-single-file-upload'
355
- }, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.mc-error]=\"errors && errors.length\"\n (filesDropped)=\"onFileDropped($event)\">\n <div class=\"dropzone\" *ngIf=\"!files.length; else fileOutput\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<input #input type=\"file\" class=\"cdk-visually-hidden\" [id]=\"inputId\" [accept]=\"acceptedFiles\" [disabled]=\"disabled\" (change)=\"onFileSelectedViaClick($event)\"></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n</div>\n\n<mc-hint class=\"mc-file-upload__hint\">\n <ng-content select=\"[hint]\"></ng-content>\n</mc-hint>\n<ng-container *ngIf=\"errors && errors.length\">\n <mc-hint class=\"mc-file-upload__hint mc-error\" *ngFor=\"let error of errors\">{{ error }}</mc-hint>\n</ng-container>\n\n\n<ng-template #fileOutput>\n <div class=\"file-item\" *ngIf=\"files && files.length\">\n <div class=\"file-item__text-wrapper\">\n <ng-container *ngIf=\"{ loading: files[0].loading | async, progress: files[0].progress | async} as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\">\n <ng-content select=\"[mc-icon]\"></ng-content>\n </ng-container>\n\n <mc-progress-spinner\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <div class=\"file-item__text\" [mcEllipsisCenter]=\"files[0].file.name\" [minVisibleLength]=\"10\"></div>\n </div>\n <button mc-button\n class=\"mc-button_transparent\"\n [disabled]=\"disabled\"\n (keydown.delete)=\"deleteItem()\"\n (keydown.backspace)=\"deleteItem()\"\n (click)=\"deleteItem($event)\">\n <i mc-icon=\"mc-close-circle_16\"></i>\n </button>\n </div>\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px);border-radius:var(--mc-file-upload-size-single-border-radius, 4px);border-width:var(--mc-file-upload-size-single-border-width, 1px);border-style:var(--mc-file-upload-size-single-border-style, dashed)}.mc-file-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-item{width:100%}.mc-file-upload .file-item .file-item__text-wrapper{display:flex;align-items:center;width:100%}.mc-file-upload .file-item .file-item__text-wrapper .file-item__text{margin-left:var(--mc-size-s, 8px);width:120px;flex-grow:1}.mc-hint{display:block}.mc-file-upload__hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n"] }]
356
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
559
+ }, template: "<div class=\"mc-file-upload\"\n mcFileDrop\n [class.disabled]=\"disabled\"\n [class.mc-error]=\"invalid\"\n (filesDropped)=\"onFileDropped($event)\">\n <div class=\"dropzone\" *ngIf=\"!file; else fileOutput\">\n <i mc-icon=\"mc-upload-to-cloud_24\"></i>\n <span class=\"dropzone__text\">\n {{ separatedCaptionText[0] }}<label mc-link pseudo [disabled]=\"disabled\" [tabIndex]=\"-1\" [for]=\"inputId\">{{ config.browseLink }}<input #input type=\"file\" class=\"cdk-visually-hidden\" [id]=\"inputId\" [accept]=\"acceptedFiles\" [disabled]=\"disabled\" (change)=\"onFileSelectedViaClick($event)\"></label>{{ separatedCaptionText[1] }}\n </span>\n </div>\n</div>\n\n<ng-container *ngIf=\"hasHint\">\n <div class=\"mc-file-upload__hint\">\n <ng-content select=\"mc-hint,[hint]\" />\n </div>\n</ng-container>\n\n<ng-template #fileOutput>\n <div class=\"file-item\" *ngIf=\"file\">\n <div class=\"file-item__text-wrapper\">\n <ng-container *ngIf=\"{ loading: file.loading | async, progress: file.progress | async} as asyncData\">\n <ng-container *ngIf=\"!asyncData.loading\">\n <ng-content select=\"[mc-icon]\"></ng-content>\n </ng-container>\n\n <mc-progress-spinner\n [value]=\"asyncData.progress || 0\"\n *ngIf=\"asyncData.loading\"\n ></mc-progress-spinner>\n </ng-container>\n\n <div class=\"file-item__text\" [mcEllipsisCenter]=\"file.file.name\" [minVisibleLength]=\"10\"></div>\n </div>\n <button mc-button\n class=\"mc-button_transparent\"\n [disabled]=\"disabled\"\n (keydown.delete)=\"deleteItem()\"\n (keydown.backspace)=\"deleteItem()\"\n (click)=\"deleteItem($event)\">\n <i mc-icon=\"mc-close-circle_16\"></i>\n </button>\n </div>\n</ng-template>\n", styles: [".mc-file-upload{box-sizing:border-box;display:flex;align-items:center;position:relative}.mc-file-upload .dropzone,.mc-file-upload .file-item{display:flex;align-items:center}.mc-file-upload .mc-ellipsis-center{position:relative;display:flex}.mc-file-upload .mc-ellipsis-center .data-text-start{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:pre}.mc-file-upload .mc-ellipsis-center .data-text-end{flex:1 0 auto;overflow:hidden;white-space:pre}.mc-file-upload__hint>.mc-hint{margin-top:var(--mc-form-field-hint-size-margin-top, 4px)}\n", "@keyframes mc-progress{0%{background-position:0 0}to{background-position:29px 0}}.mc-progress{position:relative}.mc-progress:after{content:\"\";position:absolute;border-radius:inherit;inset:0;background:linear-gradient(135deg,rgba(0,0,0,.05) 10px,transparent 10px,transparent 20px,rgba(0,0,0,.05) 20px,rgba(0,0,0,.05) 30px,transparent 30px) repeat;background-size:29px 29px;animation:mc-progress 1s linear infinite}.mc-group{display:flex;flex-direction:row}.mc-group .mc-group_justified>.mc-group-item{width:100%}.mc-group .mc-group-item+.mc-group-item{margin-left:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-top-right-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-bottom-left-radius:0;border-top-left-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group{display:flex;flex-direction:column}.mc-vertical-group>.mc-group-item:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:first-child:not(:last-child)>.mc-form-field__container{border-bottom-right-radius:0;border-bottom-left-radius:0}.mc-vertical-group>.mc-group-item:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:var(--mc-button-size-border-radius, 4px)}.mc-vertical-group>.mc-group-item:last-child:not(:first-child)>.mc-form-field__container{border-top-right-radius:0;border-top-left-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child){border-radius:0}.mc-vertical-group>.mc-group-item:not(:first-child):not(:last-child)>.mc-form-field__container{border-radius:0}.mc-vertical-group .mc-group-item+.mc-group-item{margin-top:calc(-1 * var(--mc-button-size-border-width, 1px))}.mc-no-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mc-file-upload{height:var(--mc-file-upload-size-single-height, 48px);padding-top:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-bottom:var(--mc-file-upload-size-single-vertical-padding, 12px);padding-left:var(--mc-size-m, 12px);border-radius:var(--mc-file-upload-size-single-border-radius, 4px);border-width:var(--mc-file-upload-size-single-border-width, 1px);border-style:var(--mc-file-upload-size-single-border-style, dashed)}.mc-file-upload .dropzone .dropzone__text{margin-left:var(--mc-size-xs, 6px)}.mc-file-upload .file-item{width:100%}.mc-file-upload .file-item .file-item__text-wrapper{display:flex;align-items:center;width:100%}.mc-file-upload .file-item .file-item__text-wrapper .file-item__text{margin-left:var(--mc-size-s, 8px);width:120px;flex-grow:1}\n"] }]
560
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
357
561
  type: Optional
358
562
  }, {
359
563
  type: Inject,
360
564
  args: [MC_FILE_UPLOAD_CONFIGURATION]
361
- }] }, { type: i9.McLocaleService, decorators: [{
362
- type: Optional
363
- }, {
364
- type: Inject,
365
- args: [MC_LOCALE_SERVICE]
366
- }] }], propDecorators: { accept: [{
565
+ }] }], propDecorators: { file: [{
566
+ type: Input
567
+ }], accept: [{
367
568
  type: Input
368
569
  }], disabled: [{
369
570
  type: Input
370
571
  }], errors: [{
371
572
  type: Input
372
- }], files: [{
373
- type: Input
374
573
  }], inputId: [{
375
574
  type: Input
376
575
  }], customValidation: [{
377
576
  type: Input
577
+ }], errorStateMatcher: [{
578
+ type: Input
378
579
  }], fileQueueChanged: [{
379
580
  type: Output
380
581
  }], input: [{
381
582
  type: ViewChild,
382
583
  args: ['input']
584
+ }], hint: [{
585
+ type: ContentChildren,
586
+ args: [McHint]
383
587
  }] } });
384
588
 
385
589
  class McFileUploadModule {
@@ -387,6 +591,8 @@ class McFileUploadModule {
387
591
  /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.2.0", ngImport: i0, type: McFileUploadModule, declarations: [McFileDropDirective,
388
592
  McSingleFileUploadComponent,
389
593
  McMultipleFileUploadComponent], imports: [CommonModule,
594
+ FormsModule,
595
+ ReactiveFormsModule,
390
596
  McToolTipModule,
391
597
  McProgressSpinnerModule,
392
598
  McIconModule,
@@ -399,6 +605,8 @@ class McFileUploadModule {
399
605
  McMultipleFileUploadComponent,
400
606
  McFileDropDirective] }); }
401
607
  /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.2.0", ngImport: i0, type: McFileUploadModule, imports: [CommonModule,
608
+ FormsModule,
609
+ ReactiveFormsModule,
402
610
  McToolTipModule,
403
611
  McProgressSpinnerModule,
404
612
  McIconModule,
@@ -414,6 +622,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.0", ngImpor
414
622
  args: [{
415
623
  imports: [
416
624
  CommonModule,
625
+ FormsModule,
626
+ ReactiveFormsModule,
417
627
  McToolTipModule,
418
628
  McProgressSpinnerModule,
419
629
  McIconModule,
@@ -441,5 +651,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.0", ngImpor
441
651
  * Generated bundle index. Do not edit.
442
652
  */
443
653
 
444
- export { MC_FILE_UPLOAD_CONFIGURATION, MC_MULTIPLE_FILE_UPLOAD_DEFAULT_CONFIGURATION, MC_SINGLE_FILE_UPLOAD_DEFAULT_CONFIGURATION, McFileDropDirective, McFileUploadModule, McMultipleFileUploadComponent, McSingleFileUploadComponent };
654
+ export { MC_FILE_UPLOAD_CONFIGURATION, MC_MULTIPLE_FILE_UPLOAD_DEFAULT_CONFIGURATION, MC_SINGLE_FILE_UPLOAD_DEFAULT_CONFIGURATION, McFileDropDirective, McFileUploadBase, McFileUploadModule, McMultipleFileUploadComponent, McSingleFileUploadComponent };
445
655
  //# sourceMappingURL=ptsecurity-mosaic-file-upload.mjs.map