UNPKG

@ngx-dropzone/material

Version:

Dropzone with Material Design implementation.

146 lines (139 loc) 6.95 kB
import * as i0 from '@angular/core'; import { inject, ElementRef, HostBinding, Input, ContentChildren, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core'; import { Validators } from '@angular/forms'; import { MatChipRow } from '@angular/material/chips'; import { MatFormField, MatFormFieldControl } from '@angular/material/form-field'; import { DropzoneComponent, coerceBoolean, DropzoneService, AcceptService, FileInputDirective } from '@ngx-dropzone/cdk'; import { Subject, merge, tap, takeUntil } from 'rxjs'; class MatDropzone extends DropzoneComponent { static nextId = 0; _elementRef = inject(ElementRef); _formField = inject(MatFormField); id = `mat-dropzone-component-${MatDropzone.nextId++}`; controlType = 'ngx-mat-dropzone'; _matChips; // The file input is never autofilled autofilled = false; stateChanges = new Subject(); ngControl = this.fileInputDirective?.ngControl ?? null; userAriaDescribedBy; get placeholder() { return this._placeholder; } set placeholder(value) { this._placeholder = value; this.stateChanges.next(); } _placeholder = ''; get required() { const controlRequired = this.ngControl?.control?.hasValidator(Validators.required); return this._required || controlRequired || false; } set required(value) { this._required = coerceBoolean(value); this.stateChanges.next(); } _required = false; get filled() { return this._formField?.appearance === 'fill'; } get empty() { return this.fileInputDirective?.empty || true; } get shouldLabelFloat() { return this._matChips.length > 0; } get ariaInvalid() { return this.empty && this.required ? null : this.errorState; } get ariaRequired() { // Accessibility guidelines say that the attribute should be omitted when false, // so we return null instead of false to remove it from the DOM. return this.required || null; } ngAfterContentInit() { super.ngAfterContentInit(); // Forward the stateChanges from the fileInputDirective to the MatFormFieldControl const stateEvents = [this.dragover$]; if (this.fileInputDirective) stateEvents.push(this.fileInputDirective.stateChanges); merge(...stateEvents) .pipe(tap(() => this.stateChanges.next()), takeUntil(this._destroy$)) .subscribe(); } ngAfterContentChecked() { // Set the dropzone to cover the whole form field const formField = this._formField?._elementRef?.nativeElement; this._elementRef.nativeElement.style.width = `${formField?.offsetWidth ?? 0}px`; // Set the dropzone height depending on the form field appearance this._elementRef.nativeElement.style.marginTop = `-${this.filled ? 24 : 16}px`; this._elementRef.nativeElement.style.marginBottom = `-${this.filled ? 8 : 16}px`; } onContainerClick() { this.openFilePicker(); } setDescribedByIds(ids) { if (ids.length) { this._elementRef.nativeElement.setAttribute('aria-describedby', ids.join(' ')); } else { this._elementRef.nativeElement.removeAttribute('aria-describedby'); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: MatDropzone, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: MatDropzone, isStandalone: true, selector: "ngx-mat-dropzone", inputs: { userAriaDescribedBy: ["aria-describedby", "userAriaDescribedBy"], placeholder: "placeholder", required: "required" }, host: { properties: { "id": "this.id", "attr.aria-invalid": "this.ariaInvalid", "attr.aria-required": "this.ariaRequired" } }, providers: [ DropzoneService, AcceptService, { provide: MatFormFieldControl, useExisting: MatDropzone, }, ], queries: [{ propertyName: "_matChips", predicate: MatChipRow }], exportAs: ["matDropzone"], usesInheritance: true, ngImport: i0, template: ` <ng-content select="[fileInput]"></ng-content> <div class="mat-chip-grid" [class.filled-and-float]="filled && shouldLabelFloat"> <ng-content select="mat-chip-row"></ng-content> </div> `, isInline: true, styles: ["ngx-mat-dropzone{display:flex;position:relative;z-index:10;min-height:56px;margin:0 -16px;color:currentcolor;outline:none;cursor:pointer;font:inherit}.mat-chip-grid{display:flex;flex-flow:wrap;margin:8px}.mat-chip-grid.filled-and-float{padding-top:16px}.mat-chip-grid>.mdc-evolution-chip{margin:4px 0 4px 8px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: MatDropzone, decorators: [{ type: Component, args: [{ selector: 'ngx-mat-dropzone', exportAs: 'matDropzone', imports: [MatFormField, MatChipRow, FileInputDirective, DropzoneComponent], providers: [ DropzoneService, AcceptService, { provide: MatFormFieldControl, useExisting: MatDropzone, }, ], template: ` <ng-content select="[fileInput]"></ng-content> <div class="mat-chip-grid" [class.filled-and-float]="filled && shouldLabelFloat"> <ng-content select="mat-chip-row"></ng-content> </div> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["ngx-mat-dropzone{display:flex;position:relative;z-index:10;min-height:56px;margin:0 -16px;color:currentcolor;outline:none;cursor:pointer;font:inherit}.mat-chip-grid{display:flex;flex-flow:wrap;margin:8px}.mat-chip-grid.filled-and-float{padding-top:16px}.mat-chip-grid>.mdc-evolution-chip{margin:4px 0 4px 8px}\n"] }] }], propDecorators: { id: [{ type: HostBinding }], _matChips: [{ type: ContentChildren, args: [MatChipRow] }], userAriaDescribedBy: [{ type: Input, args: ['aria-describedby'] }], placeholder: [{ type: Input }], required: [{ type: Input }], ariaInvalid: [{ type: HostBinding, args: ['attr.aria-invalid'] }], ariaRequired: [{ type: HostBinding, args: ['attr.aria-required'] }] } }); /* * Public API Surface of material */ /** * Generated bundle index. Do not edit. */ export { MatDropzone }; //# sourceMappingURL=ngx-dropzone-material.mjs.map