@ngx-dropzone/material
Version:
Dropzone with Material Design implementation.
146 lines (139 loc) • 6.95 kB
JavaScript
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