import { Component , ElementRef , SimpleChanges , ViewEncapsulation , EventEmitter , NgZone , Input , Output , AfterViewInit , OnChanges , OnDestroy , } from "@angular/core" ; import { create , supported , FilePond , FilePondOptions } from "filepond" ; const isSupported = supported ( ) ; const inputAttributes = [ "id" , "name" , "class" , "multiple" , "required" , "disabled" , "capture" , "accept" , ] ; const filteredComponentMethods = [ "setOptions" , "on" , "off" , "onOnce" , "appendTo" , "insertAfter" , "insertBefore" , "isAttachedTo" , "replaceElement" , "restoreElement" , "destroy" , ] ; const outputs = [ "oninit" , "onwarning" , "onerror" , "onactivatefile" , "onaddfilestart" , "onaddfileprogress" , "onaddfile" , "onprocessfilestart" , "onprocessfileprogress" , "onprocessfileabort" , "onprocessfilerevert" , "onprocessfile" , "onprocessfiles" , "onremovefile" , "onpreparefile" , "onupdatefiles" , ] ; @ Component ( { selector : "file-pond" , encapsulation : ViewEncapsulation . None , templateUrl : "./filepond.component.html" , styleUrls : [ "./filepond.component.css" ] , } ) export class FilePondComponent implements AfterViewInit , OnChanges , OnDestroy { @ Input ( ) options : FilePondOptions = { } ; @ Input ( ) files : FilePondOptions [ "files" ] ; @ Output ( ) oninit = new EventEmitter < any > ( ) ; @ Output ( ) onwarning = new EventEmitter < any > ( ) ; @ Output ( ) onerror = new EventEmitter < any > ( ) ; @ Output ( ) onactivatefile = new EventEmitter < any > ( ) ; @ Output ( ) onaddfilestart = new EventEmitter < any > ( ) ; @ Output ( ) onaddfileprogress = new EventEmitter < any > ( ) ; @ Output ( ) onaddfile = new EventEmitter < any > ( ) ; @ Output ( ) onprocessfilestart = new EventEmitter < any > ( ) ; @ Output ( ) onprocessfileprogress = new EventEmitter < any > ( ) ; @ Output ( ) onprocessfileabort = new EventEmitter < any > ( ) ; @ Output ( ) onprocessfilerevert = new EventEmitter < any > ( ) ; @ Output ( ) onprocessfile = new EventEmitter < any > ( ) ; @ Output ( ) onprocessfiles = new EventEmitter < any > ( ) ; @ Output ( ) onremovefile = new EventEmitter < any > ( ) ; @ Output ( ) onpreparefile = new EventEmitter < any > ( ) ; @ Output ( ) onupdatefiles = new EventEmitter < any > ( ) ; private root : ElementRef ; private zone : NgZone ; private pond : FilePond ; private handleEvent : Function = null ; constructor ( root , zone ) { this . root = root ; this . zone = zone ; } ngAfterViewInit ( ) { const input = this . root . nativeElement . querySelector ( "input" ) ; const attributes = this . root . nativeElement . attributes ; inputAttributes . forEach ( ( name ) => { const value = attributes [ name ] ? attributes [ name ] . value : this . options [ name ] ; if ( ! value ) { return ; } input . setAttribute ( name , value ) ; } ) ; if ( ! isSupported ) { return ; } this . handleEvent = ( e ) => { this [ `on${ e . type . split ( ":" ) [ 1 ] }` ] . emit ( { ... e . detail } ) ; } ; outputs . forEach ( ( event ) => { this . root . nativeElement . addEventListener ( `FilePond:${ event . substr ( 2 ) }` , this . handleEvent ) ; } ) ; this . zone . runOutsideAngular ( ( ) => { this . pond = create ( input , { ... this . options , files : this . files , } ) ; } ) ; Object . keys ( this . pond ) . filter ( ( key ) => filteredComponentMethods . indexOf ( key ) === - 1 ) . forEach ( ( key ) => { this [ key ] = this . pond [ key ] ; } ) ; } ngOnChanges ( changes ) { if ( changes . firstChange ) { return ; } if ( ! this . pond ) { return ; } const options = changes . options ? changes . options . currentValue : this . options ; if ( changes . files && JSON . stringify ( changes . files . previousValue ) !== JSON . stringify ( changes . files . currentValue ) ) { options . files = changes . files . currentValue ; } this . pond . setOptions ( options ) ; } ngOnDestroy ( ) { if ( ! this . pond ) { return ; } outputs . forEach ( ( event ) => { this . root . nativeElement . removeEventListener ( `FilePond:${ event . substr ( 2 ) }` , this . handleEvent ) ; } ) ; this . pond . destroy ( ) ; } }