@tft/crispr-forms 13.0.1 → 13.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1169,11 +1169,18 @@ class ImageUploadFieldComponent extends ImageUploadFieldMixin {
1169
1169
  this.cdr.detectChanges();
1170
1170
  }
1171
1171
  };
1172
- const compressedFile = await imageCompression(file, options);
1173
- return compressedFile;
1172
+ return await imageCompression(file, options);
1174
1173
  }
1175
1174
  else
1176
1175
  return file;
1176
+ }), map((compressedFileOrString) => {
1177
+ if (!compressedFileOrString || typeof compressedFileOrString === 'string')
1178
+ return compressedFileOrString;
1179
+ const { type, name, lastModified } = compressedFileOrString;
1180
+ return new File([compressedFileOrString], this.config.fileName || name, {
1181
+ type,
1182
+ lastModified
1183
+ });
1177
1184
  }), tap(file => {
1178
1185
  this.control.setValue(file);
1179
1186
  if (file || this.value) {
@@ -1187,9 +1194,7 @@ class ImageUploadFieldComponent extends ImageUploadFieldMixin {
1187
1194
  if (!file)
1188
1195
  return null;
1189
1196
  const compressedStringImage = await imageCompression.getDataUrlFromFile(file);
1190
- return file.type.includes('svg')
1191
- ? this.domSanitizer.bypassSecurityTrustResourceUrl(compressedStringImage)
1192
- : compressedStringImage;
1197
+ return this.domSanitizer.bypassSecurityTrustResourceUrl(compressedStringImage);
1193
1198
  }), shareReplay(1));
1194
1199
  this.isUploaded = false;
1195
1200
  if (this.ngControl != null) {
@@ -1236,10 +1241,10 @@ class ImageUploadFieldComponent extends ImageUploadFieldMixin {
1236
1241
  registerOnTouched(fn) { }
1237
1242
  }
1238
1243
  ImageUploadFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldComponent, deps: [{ token: i4$1.NgControl, optional: true, self: true }, { token: i2$3.DomSanitizer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1239
- ImageUploadFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: ImageUploadFieldComponent, selector: "crispr-image-upload-field", viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>{{config.label}}</mat-label>\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n [accept]=\"config.acceptedTypes\"\n (change)=\"filesChanged($event.target.files)\"/>\n <div class=\"ui-container\">\n\n <div class=\"image-preview\" [style.height]=\"config.imagePreviewHeight\">\n <crispr-selected-file\n *ngIf=\"(progress < 100) && inputImageFile$ | async as file; else dropzoneOrPreview\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"'Compressing: ' + file.name\"\n [showProgress]=\"true\"\n [progress]=\"progress\">\n </crispr-selected-file>\n\n <ng-template #dropzoneOrPreview>\n <!-- <img *ngIf=\"(initialUrlString$ | async) as initialUrlString;\" [src]=\"initialUrlString\" alt=\"\"> -->\n <img *ngIf=\"imageSrcUrl$ | async as srcUrl; else noImage\" [src]=\"srcUrl\" alt=\"\">\n <ng-template #noImage>\n <div class=\"drop-container\"\n [crisprFileDropzone]=\"!(disabled$ | async)\"\n (fileDrop)=\"filesChanged($event)\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n </div>\n </ng-template>\n\n </ng-template>\n </div>\n\n\n\n <!-- </ng-template> -->\n <div class=\"button-container\" *ngIf=\"true\">\n\n <button\n mat-button\n (click)=\"clearFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>delete</mat-icon>\n {{config.clearFilesButtonText}}\n </button>\n\n <button\n *ngIf=\"value\"\n mat-button\n (click)=\"resetToInitialValue(value)\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>replay</mat-icon>\n {{config.resetFilesButtonText}}\n </button>\n\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async)\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n <mat-icon>\n camera\n </mat-icon>\n SELECT\n </button>\n </div>\n </div>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0}:host ::ng-deep .mat-form-field .mat-button-wrapper{display:flex;flex-direction:column;align-items:center;padding-top:8px}:host .ui-container{display:flex;flex-direction:column}:host .ui-container .image-preview{display:flex;flex-direction:column;align-content:space-between;justify-content:center;align-items:center;margin:8px 0;flex-grow:1}:host .ui-container .image-preview crispr-selected-file{width:100%}:host .ui-container .image-preview .drop-container{display:flex;flex-direction:column;align-items:center;border:3px dashed gray;height:100%;width:100%;align-content:center;justify-content:center;border-radius:8px}:host .ui-container .image-preview .drop-container .drop-icon{height:32px;width:32px;font-size:36px}:host .ui-container .image-preview .drop-container .mat-h2{margin:0}:host .ui-container .image-preview img{height:inherit;max-width:100%}:host .ui-container .button-container{display:flex;flex-direction:var(--image-upload-button-container-direction);justify-content:flex-end}:host .ui-container .button-container button{margin-left:8px}:host input{position:absolute;max-height:0;visibility:hidden}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: SelectedFileComponent, selector: "crispr-selected-file", inputs: ["fileName", "progress", "showProgress", "color"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: FileDropzoneDirective, selector: "[crisprFileDropzone]", inputs: ["crisprFileDropzone"], outputs: ["fileDrop"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1244
+ ImageUploadFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: ImageUploadFieldComponent, selector: "crispr-image-upload-field", viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>{{config.label}}</mat-label>\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n [accept]=\"config.acceptedTypes\"\n (change)=\"filesChanged($event.target.files)\"/>\n <div class=\"ui-container\">\n\n <div class=\"image-preview\" [style.height]=\"config.imagePreviewHeight\">\n <crispr-selected-file\n *ngIf=\"(progress < 100) && inputImageFile$ | async as file; else dropzoneOrPreview\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"'Compressing: ' + file.name\"\n [showProgress]=\"true\"\n [progress]=\"progress\">\n </crispr-selected-file>\n\n <ng-template #dropzoneOrPreview>\n <!-- <img *ngIf=\"(initialUrlString$ | async) as initialUrlString;\" [src]=\"initialUrlString\" alt=\"\"> -->\n <img *ngIf=\"imageSrcUrl$ | async as srcUrl; else noImage\" [src]=\"srcUrl\" alt=\"\">\n <ng-template #noImage>\n <div class=\"drop-container\"\n [crisprFileDropzone]=\"!(disabled$ | async)\"\n (fileDrop)=\"filesChanged($event)\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n </div>\n </ng-template>\n\n </ng-template>\n </div>\n\n\n\n <!-- </ng-template> -->\n <div class=\"button-container\" *ngIf=\"true\">\n\n <button\n mat-button\n (click)=\"clearFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>delete</mat-icon>\n {{config.clearFilesButtonText}}\n </button>\n\n <button\n *ngIf=\"value\"\n mat-button\n (click)=\"resetToInitialValue(value)\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>replay</mat-icon>\n {{config.resetFilesButtonText}}\n </button>\n\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async)\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n <mat-icon>\n camera\n </mat-icon>\n SELECT\n </button>\n </div>\n </div>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0}:host ::ng-deep .mat-form-field .mat-button-wrapper{display:flex;flex-direction:column;align-items:center;padding-top:8px}:host .ui-container{display:flex;flex-direction:column}:host .ui-container .image-preview{display:flex;flex-direction:column;align-content:space-between;justify-content:center;align-items:center;margin:8px 0;flex-grow:1}:host .ui-container .image-preview crispr-selected-file{width:100%}:host .ui-container .image-preview .drop-container{display:flex;box-sizing:border-box;flex-direction:column;align-items:center;border:3px dashed gray;height:100%;width:100%;align-content:center;justify-content:center;border-radius:8px}:host .ui-container .image-preview .drop-container .drop-icon{height:32px;width:32px;font-size:36px}:host .ui-container .image-preview .drop-container .mat-h2{margin:0}:host .ui-container .image-preview img{height:inherit;max-width:100%}:host .ui-container .button-container{display:flex;flex-direction:var(--image-upload-button-container-direction);justify-content:flex-end}:host .ui-container .button-container button{margin-left:8px}:host input{position:absolute;max-height:0;visibility:hidden}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: SelectedFileComponent, selector: "crispr-selected-file", inputs: ["fileName", "progress", "showProgress", "color"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: FileDropzoneDirective, selector: "[crisprFileDropzone]", inputs: ["crisprFileDropzone"], outputs: ["fileDrop"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1240
1245
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldComponent, decorators: [{
1241
1246
  type: Component,
1242
- args: [{ selector: 'crispr-image-upload-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>{{config.label}}</mat-label>\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n [accept]=\"config.acceptedTypes\"\n (change)=\"filesChanged($event.target.files)\"/>\n <div class=\"ui-container\">\n\n <div class=\"image-preview\" [style.height]=\"config.imagePreviewHeight\">\n <crispr-selected-file\n *ngIf=\"(progress < 100) && inputImageFile$ | async as file; else dropzoneOrPreview\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"'Compressing: ' + file.name\"\n [showProgress]=\"true\"\n [progress]=\"progress\">\n </crispr-selected-file>\n\n <ng-template #dropzoneOrPreview>\n <!-- <img *ngIf=\"(initialUrlString$ | async) as initialUrlString;\" [src]=\"initialUrlString\" alt=\"\"> -->\n <img *ngIf=\"imageSrcUrl$ | async as srcUrl; else noImage\" [src]=\"srcUrl\" alt=\"\">\n <ng-template #noImage>\n <div class=\"drop-container\"\n [crisprFileDropzone]=\"!(disabled$ | async)\"\n (fileDrop)=\"filesChanged($event)\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n </div>\n </ng-template>\n\n </ng-template>\n </div>\n\n\n\n <!-- </ng-template> -->\n <div class=\"button-container\" *ngIf=\"true\">\n\n <button\n mat-button\n (click)=\"clearFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>delete</mat-icon>\n {{config.clearFilesButtonText}}\n </button>\n\n <button\n *ngIf=\"value\"\n mat-button\n (click)=\"resetToInitialValue(value)\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>replay</mat-icon>\n {{config.resetFilesButtonText}}\n </button>\n\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async)\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n <mat-icon>\n camera\n </mat-icon>\n SELECT\n </button>\n </div>\n </div>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0}:host ::ng-deep .mat-form-field .mat-button-wrapper{display:flex;flex-direction:column;align-items:center;padding-top:8px}:host .ui-container{display:flex;flex-direction:column}:host .ui-container .image-preview{display:flex;flex-direction:column;align-content:space-between;justify-content:center;align-items:center;margin:8px 0;flex-grow:1}:host .ui-container .image-preview crispr-selected-file{width:100%}:host .ui-container .image-preview .drop-container{display:flex;flex-direction:column;align-items:center;border:3px dashed gray;height:100%;width:100%;align-content:center;justify-content:center;border-radius:8px}:host .ui-container .image-preview .drop-container .drop-icon{height:32px;width:32px;font-size:36px}:host .ui-container .image-preview .drop-container .mat-h2{margin:0}:host .ui-container .image-preview img{height:inherit;max-width:100%}:host .ui-container .button-container{display:flex;flex-direction:var(--image-upload-button-container-direction);justify-content:flex-end}:host .ui-container .button-container button{margin-left:8px}:host input{position:absolute;max-height:0;visibility:hidden}\n"] }]
1247
+ args: [{ selector: 'crispr-image-upload-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>{{config.label}}</mat-label>\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n [accept]=\"config.acceptedTypes\"\n (change)=\"filesChanged($event.target.files)\"/>\n <div class=\"ui-container\">\n\n <div class=\"image-preview\" [style.height]=\"config.imagePreviewHeight\">\n <crispr-selected-file\n *ngIf=\"(progress < 100) && inputImageFile$ | async as file; else dropzoneOrPreview\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"'Compressing: ' + file.name\"\n [showProgress]=\"true\"\n [progress]=\"progress\">\n </crispr-selected-file>\n\n <ng-template #dropzoneOrPreview>\n <!-- <img *ngIf=\"(initialUrlString$ | async) as initialUrlString;\" [src]=\"initialUrlString\" alt=\"\"> -->\n <img *ngIf=\"imageSrcUrl$ | async as srcUrl; else noImage\" [src]=\"srcUrl\" alt=\"\">\n <ng-template #noImage>\n <div class=\"drop-container\"\n [crisprFileDropzone]=\"!(disabled$ | async)\"\n (fileDrop)=\"filesChanged($event)\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n </div>\n </ng-template>\n\n </ng-template>\n </div>\n\n\n\n <!-- </ng-template> -->\n <div class=\"button-container\" *ngIf=\"true\">\n\n <button\n mat-button\n (click)=\"clearFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>delete</mat-icon>\n {{config.clearFilesButtonText}}\n </button>\n\n <button\n *ngIf=\"value\"\n mat-button\n (click)=\"resetToInitialValue(value)\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>replay</mat-icon>\n {{config.resetFilesButtonText}}\n </button>\n\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async)\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n <mat-icon>\n camera\n </mat-icon>\n SELECT\n </button>\n </div>\n </div>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0}:host ::ng-deep .mat-form-field .mat-button-wrapper{display:flex;flex-direction:column;align-items:center;padding-top:8px}:host .ui-container{display:flex;flex-direction:column}:host .ui-container .image-preview{display:flex;flex-direction:column;align-content:space-between;justify-content:center;align-items:center;margin:8px 0;flex-grow:1}:host .ui-container .image-preview crispr-selected-file{width:100%}:host .ui-container .image-preview .drop-container{display:flex;box-sizing:border-box;flex-direction:column;align-items:center;border:3px dashed gray;height:100%;width:100%;align-content:center;justify-content:center;border-radius:8px}:host .ui-container .image-preview .drop-container .drop-icon{height:32px;width:32px;font-size:36px}:host .ui-container .image-preview .drop-container .mat-h2{margin:0}:host .ui-container .image-preview img{height:inherit;max-width:100%}:host .ui-container .button-container{display:flex;flex-direction:var(--image-upload-button-container-direction);justify-content:flex-end}:host .ui-container .button-container button{margin-left:8px}:host input{position:absolute;max-height:0;visibility:hidden}\n"] }]
1243
1248
  }], ctorParameters: function () { return [{ type: i4$1.NgControl, decorators: [{
1244
1249
  type: Optional
1245
1250
  }, {
@@ -1299,14 +1304,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImpor
1299
1304
  function maxFileSizeValidator(maxFileSize) {
1300
1305
  return (control) => {
1301
1306
  const controlValue = control.value;
1302
- if (!(controlValue instanceof Blob))
1307
+ if (!(controlValue instanceof File)) {
1303
1308
  return null;
1309
+ }
1304
1310
  const actualFileSize = +convertBytesToMb(controlValue.size).toPrecision(3);
1305
1311
  if (maxFileSize > actualFileSize)
1306
1312
  return null;
1307
- control.setErrors({ maxFileSize: { maxFileSize, actualFileSize } });
1313
+ // control.setErrors({maxFileSize: { maxFileSize, actualFileSize }} )
1308
1314
  return { maxFileSize: { maxFileSize, actualFileSize } };
1309
1315
  };
1316
+ }
1317
+ function allowedFileExtValidator(allowedFileExtensions, onlyAllowFiles = true) {
1318
+ return (control) => {
1319
+ const controlValue = control.value;
1320
+ const isFile = controlValue instanceof File;
1321
+ if (!onlyAllowFiles && !isFile)
1322
+ return null;
1323
+ const actualExtension = isFile ? controlValue.name.split('.').pop() : 'Not a file';
1324
+ const isAllowedExtension = allowedFileExtensions.includes(actualExtension);
1325
+ if (isAllowedExtension) {
1326
+ return null;
1327
+ }
1328
+ return { allowedExtension: { allowedFileExtensions, actualExtension } };
1329
+ };
1310
1330
  }
1311
1331
 
1312
1332
  // TODO: Should we import UI library?
@@ -1487,6 +1507,7 @@ var index$2 = /*#__PURE__*/Object.freeze({
1487
1507
  ImageUploadFieldComponent: ImageUploadFieldComponent,
1488
1508
  ImageUploadFieldModule: ImageUploadFieldModule,
1489
1509
  maxFileSizeValidator: maxFileSizeValidator,
1510
+ allowedFileExtValidator: allowedFileExtValidator,
1490
1511
  FileDropzoneDirective: FileDropzoneDirective,
1491
1512
  FileUploadFieldComponent: FileUploadFieldComponent,
1492
1513
  FileUploadFieldModule: FileUploadFieldModule,
@@ -1871,5 +1892,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImpor
1871
1892
  * Generated bundle index. Do not edit.
1872
1893
  */
1873
1894
 
1874
- export { AbstractAutocompleteComponent, AutocompleteChiplistFieldComponent, AutocompleteFieldComponent, ButtonComponent, CheckboxFieldComponent, ControlType, CrisprFieldComponent, CrisprFormComponent, CrisprFormsModule, DEFAULT_EMPTY_OPTIONS_MESSAGE, DatepickerFieldComponent, DividerComponent, FieldContainerComponent, FieldContainerModule, FileDropzoneDirective, FileUploadFieldComponent, FileUploadFieldModule, HeadingComponent, HeadingModule, ImageUploadFieldComponent, ImageUploadFieldModule, InputFieldComponent, MaterialModule, OptionComponent, RadioFieldComponent, SelectFieldComponent, SliderFieldComponent, TextareaFieldComponent, UnitConversionFieldComponent, buildFormGroupFromConfig, callOptionsIfFunction, checkControlForValues, checkControlsForValues, computeValueFromFields, createControlForType, crisprControlMixin, filterOptionsByLabel, isControlConfig, maxFileSizeValidator, observablifyOptions };
1895
+ export { AbstractAutocompleteComponent, AutocompleteChiplistFieldComponent, AutocompleteFieldComponent, ButtonComponent, CheckboxFieldComponent, ControlType, CrisprFieldComponent, CrisprFormComponent, CrisprFormsModule, DEFAULT_EMPTY_OPTIONS_MESSAGE, DatepickerFieldComponent, DividerComponent, FieldContainerComponent, FieldContainerModule, FileDropzoneDirective, FileUploadFieldComponent, FileUploadFieldModule, HeadingComponent, HeadingModule, ImageUploadFieldComponent, ImageUploadFieldModule, InputFieldComponent, MaterialModule, OptionComponent, RadioFieldComponent, SelectFieldComponent, SliderFieldComponent, TextareaFieldComponent, UnitConversionFieldComponent, allowedFileExtValidator, buildFormGroupFromConfig, callOptionsIfFunction, checkControlForValues, checkControlsForValues, computeValueFromFields, createControlForType, crisprControlMixin, filterOptionsByLabel, isControlConfig, maxFileSizeValidator, observablifyOptions };
1875
1896
  //# sourceMappingURL=tft-crispr-forms.mjs.map