import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { TemplatePortalDirective } from '@angular/cdk/portal'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Directive, ElementRef, EventEmitter, forwardRef, Input, Output, Renderer2, TemplateRef, ViewChild, ViewContainerRef, } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ICanDisable, IControlValueAccessor, mixinControlValueAccessor, mixinDisabled } from '../../shared/behaviors'; @Directive({ /* tslint:disable-next-line */ selector: '[prutech-file-input-label]ng-template', }) export class NuFileInputLabelDirective extends TemplatePortalDirective { // tslint:disable-next-line:no-any constructor(templateRef: TemplateRef, viewContainerRef: ViewContainerRef) { super(templateRef, viewContainerRef); } } export class NuFileInputBase { constructor(public _changeDetectorRef: ChangeDetectorRef) { } } /* tslint:disable-next-line */ export const _NuFileInputMixinBase = mixinControlValueAccessor(mixinDisabled(NuFileInputBase)); @Component({ changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NuFileInputComponent), multi: true, }, ], selector: 'prutech-file-input', inputs: ['disabled', 'value'], styleUrls: ['./file-input.component.scss'], templateUrl: './file-input.component.html', }) export class NuFileInputComponent extends _NuFileInputMixinBase implements IControlValueAccessor, ICanDisable { private _multiple: boolean = false; /** * color?: 'accent' | 'primary' | 'warn' * Sets button color. Uses same color palette accepted as [MatButton]. */ @Input() color: 'accent' | 'primary' | 'warn'; /** * accept?: string * Sets files accepted when opening the file browser dialog. * Same as 'accept' attribute in element. */ @Input() accept: string; /** * select?: function * Event emitted a file is selected * Emits a [File | FileList] object. */ @Output() select: EventEmitter = new EventEmitter(); /** The native ` element */ @ViewChild('fileInput', {static: true}) _inputElement: ElementRef; constructor(private _renderer: Renderer2, _changeDetectorRef: ChangeDetectorRef) { super(_changeDetectorRef); } get multiple(): boolean { return this._multiple; } /** * multiple?: boolean * Sets if multiple files can be dropped/selected at once in [NuFileInputComponent]. */ @Input('multiple') set multiple(multiple: boolean) { this._multiple = coerceBooleanProperty(multiple); } get inputElement(): HTMLInputElement { return this._inputElement.nativeElement; } /** * Method executed when a file is selected. */ handleSelect(files: File | FileList): void { this.writeValue(files); this.select.emit(files); } /** * Used to clear the selected files from the [NuFileInputComponent]. */ clear(): void { this.writeValue(undefined); this._renderer.setProperty(this.inputElement, 'value', ''); } /** Method executed when the disabled value changes */ onDisabledChange(v: boolean): void { if (v) { this.clear(); } } /** * Sets disable to the component. Implemented as part of ControlValueAccessor. */ setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } }