├── .gitignore ├── .travis.yml ├── README.md ├── ambient.d.ts ├── build ├── bundles │ └── index.umd.js ├── file-drop-module.d.ts ├── file-drop-module.js ├── file-drop-module.js.map ├── file-drop-module.metadata.json ├── file-drop.d.ts ├── file-drop.js ├── file-drop.js.map ├── file-drop.metadata.json ├── index.d.ts ├── index.js ├── index.js.map └── index.metadata.json ├── package.json ├── rollup.config.js ├── src ├── file-drop-module.ts ├── file-drop.ts └── index.ts ├── tsconfig.json ├── tslint.json └── typings.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | typings 4 | aot 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - '6' 7 | 8 | cache: 9 | directories: 10 | - "$HOME/.npm" 11 | - node_modules 12 | 13 | notifications: 14 | email: false 15 | 16 | before_install: 17 | - npm prune 18 | 19 | deploy: 20 | provider: npm 21 | email: kamil.kisiela@gmail.com 22 | api_key: 23 | secure: B8OeaNoGwXeotY+Xlfuc5KgO4UhfXH1Lq42hVIJkhna4+iMd4aAiT7UWs3VwKmY92oMc8M8sF38QUeMemolgWdy/bLNMZ15zIt08TNUgBZa9KslR/u/CLcMasplTtLseIYDQrC7okvNT2+rH6kCf2h7SJjkkMw1O6B7e39ygLRzp+NXLHLzfTYD9MZPvtEF1UflI/AbpnUSu2KujuekQbIJSEUG1dF3UDUkRfgtPQ7+HA2tzlE8sxTO+ISvLv56yoHtKt85FEKhcvU7O7JLU271eD0ORiCCvOYyGQzKfotmc5Z0X+5z0q5TUw2bTBpW0t/SrNpi11N/Vm0RMxMWHpsKS0kSBhIpv+QxExK4S3G5kd3hzBu9PIplkjcl9r/h9THi34UFfhrs0Z4b4z/+3ZAhkzhpQfNjPcbsCee5slTgyDxvIp1+FfLUt3zuy3pS9tSjdQJKdiiR9LjF8izLwgXSb7Z6bs1Ze/K1E9ttOZCWWkI3Ry+D0nzBJCQEUgSlK5n0VIMqhhUVC9djdVg6A11ryDTnlqi6pHxz00wXhWnKVNvMrs2Lj4Jhwf1sGyJeZY6x1jD7B/E7vBoqzp56UKr0dztnSDwRFnBUwv8HM0bywVzS2hWu+d7sRy2lMorcEYS8P90VF16Papdziytbr4ytyGDx78x4DupGRJGmpODk= 24 | on: 25 | tags: true 26 | repo: jellyjs/angular2-file-drop 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular2-file-drop 2 | 3 | Angular2 component with Drag and Drop support for files 4 | 5 | ## Install 6 | 7 | ```bash 8 | npm install angular2-file-drop 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```ts 14 | import { Component, Output } from '@angular/core'; 15 | import { FileDropDirective } from 'angular2-file-drop'; 16 | 17 | @Component({ 18 | selector: 'upload', 19 | template: ` 20 |
25 | Drop file here 26 |
27 | `, 28 | directives: [ FileDropDirective ] 29 | }) 30 | export class PartiesUpload { 31 | public fileIsOver: boolean = false; 32 | @Output() public options = { 33 | readAs: 'ArrayBuffer' 34 | }; 35 | 36 | private file: File; 37 | 38 | public fileOver(fileIsOver: boolean): void { 39 | this.fileIsOver = fileIsOver; 40 | } 41 | 42 | public onFileDrop(file: File): void { 43 | console.log('Got file!'); 44 | } 45 | } 46 | 47 | ``` 48 | 49 | ## Options 50 | 51 | - **readAs?** : `DataURL`, `ArrayBuffer`, `BinaryString` or `Text` 52 | -------------------------------------------------------------------------------- /ambient.d.ts: -------------------------------------------------------------------------------- 1 | interface iFileAPI { 2 | readAsDataURL(file: File, cb: Function): void; 3 | readAsBinaryString(file: File, cb: Function): void; 4 | readAsArrayBuffer(file: File, cb: Function): void; 5 | readAsText(file: File, cb: Function): void; 6 | } 7 | 8 | declare var FileAPI: iFileAPI; 9 | -------------------------------------------------------------------------------- /build/bundles/index.umd.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('fileapi')) : 3 | typeof define === 'function' && define.amd ? define(['exports', '@angular/core', 'fileapi'], factory) : 4 | (factory((global.ng = global.ng || {}, global.ng['file-drop'] = global.ng['file-drop'] || {}),global.ng.core,global.fileapi)); 5 | }(this, (function (exports,_angular_core,fileapi) { 'use strict'; 6 | 7 | var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { 8 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 9 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 10 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 11 | return c > 3 && r && Object.defineProperty(target, key, r), r; 12 | }; 13 | var __metadata = (undefined && undefined.__metadata) || function (k, v) { 14 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 15 | }; 16 | var FileDropDirective = (function () { 17 | function FileDropDirective(element) { 18 | this.fileOver = new _angular_core.EventEmitter(); 19 | this.onFileDrop = new _angular_core.EventEmitter(); 20 | this.element = element; 21 | } 22 | FileDropDirective.prototype.onDragOver = function (event) { 23 | var transfer = this.getDataTransfer(event); 24 | if (!this.haveFiles(transfer.types)) { 25 | return; 26 | } 27 | transfer.dropEffect = 'copy'; 28 | this.preventAndStop(event); 29 | this.emitFileOver(true); 30 | }; 31 | FileDropDirective.prototype.onDragLeave = function (event) { 32 | if (event.currentTarget === this.element[0]) { 33 | return; 34 | } 35 | this.preventAndStop(event); 36 | this.emitFileOver(false); 37 | }; 38 | FileDropDirective.prototype.onDrop = function (event) { 39 | var transfer = this.getDataTransfer(event); 40 | if (!transfer) { 41 | return; 42 | } 43 | this.preventAndStop(event); 44 | this.emitFileOver(false); 45 | this.readFile(transfer.files[0]); 46 | }; 47 | FileDropDirective.prototype.readFile = function (file) { 48 | var _this = this; 49 | var strategy = this.pickStrategy(); 50 | if (!strategy) { 51 | this.emitFileDrop(file); 52 | } 53 | else { 54 | // XXX Waiting for angular/zone.js#358 55 | var method = "readAs" + strategy; 56 | FileAPI[method](file, function (event) { 57 | if (event.type === 'load') { 58 | _this.emitFileDrop(event.result); 59 | } 60 | else if (event.type === 'error') { 61 | throw new Error("Couldn't read file '" + file.name + "'"); 62 | } 63 | }); 64 | } 65 | }; 66 | FileDropDirective.prototype.emitFileOver = function (isOver) { 67 | this.fileOver.emit(isOver); 68 | }; 69 | FileDropDirective.prototype.emitFileDrop = function (file) { 70 | this.onFileDrop.emit(file); 71 | }; 72 | FileDropDirective.prototype.pickStrategy = function () { 73 | if (!this.options) { 74 | return; 75 | } 76 | if (this.hasStrategy(this.options.readAs)) { 77 | return this.options.readAs; 78 | } 79 | }; 80 | FileDropDirective.prototype.hasStrategy = function (type) { 81 | return [ 82 | 'DataURL', 83 | 'BinaryString', 84 | 'ArrayBuffer', 85 | 'Text', 86 | ].indexOf(type) !== -1; 87 | }; 88 | FileDropDirective.prototype.getDataTransfer = function (event) { 89 | return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; 90 | }; 91 | FileDropDirective.prototype.preventAndStop = function (event) { 92 | event.preventDefault(); 93 | event.stopPropagation(); 94 | }; 95 | FileDropDirective.prototype.haveFiles = function (types) { 96 | if (!types) { 97 | return false; 98 | } 99 | if (types.indexOf) { 100 | return types.indexOf('Files') !== -1; 101 | } 102 | if (types.contains) { 103 | return types.contains('Files'); 104 | } 105 | return false; 106 | }; 107 | return FileDropDirective; 108 | }()); 109 | __decorate$1([ 110 | _angular_core.Output(), 111 | __metadata("design:type", _angular_core.EventEmitter) 112 | ], FileDropDirective.prototype, "fileOver", void 0); 113 | __decorate$1([ 114 | _angular_core.Output(), 115 | __metadata("design:type", _angular_core.EventEmitter) 116 | ], FileDropDirective.prototype, "onFileDrop", void 0); 117 | __decorate$1([ 118 | _angular_core.Input(), 119 | __metadata("design:type", Object) 120 | ], FileDropDirective.prototype, "options", void 0); 121 | __decorate$1([ 122 | _angular_core.HostListener('dragover', [ 123 | '$event', 124 | ]), 125 | __metadata("design:type", Function), 126 | __metadata("design:paramtypes", [Object]), 127 | __metadata("design:returntype", void 0) 128 | ], FileDropDirective.prototype, "onDragOver", null); 129 | __decorate$1([ 130 | _angular_core.HostListener('dragleave', [ 131 | '$event', 132 | ]), 133 | __metadata("design:type", Function), 134 | __metadata("design:paramtypes", [Object]), 135 | __metadata("design:returntype", void 0) 136 | ], FileDropDirective.prototype, "onDragLeave", null); 137 | __decorate$1([ 138 | _angular_core.HostListener('drop', [ 139 | '$event', 140 | ]), 141 | __metadata("design:type", Function), 142 | __metadata("design:paramtypes", [Object]), 143 | __metadata("design:returntype", void 0) 144 | ], FileDropDirective.prototype, "onDrop", null); 145 | FileDropDirective = __decorate$1([ 146 | _angular_core.Directive({ selector: '[fileDrop]' }), 147 | __metadata("design:paramtypes", [_angular_core.ElementRef]) 148 | ], FileDropDirective); 149 | 150 | var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { 151 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 152 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 153 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 154 | return c > 3 && r && Object.defineProperty(target, key, r), r; 155 | }; 156 | exports.FileDropModule = (function () { 157 | function FileDropModule() { 158 | } 159 | return FileDropModule; 160 | }()); 161 | exports.FileDropModule = __decorate([ 162 | _angular_core.NgModule({ 163 | declarations: [ 164 | FileDropDirective, 165 | ], 166 | exports: [FileDropDirective], 167 | imports: [], 168 | providers: [], 169 | }) 170 | ], exports.FileDropModule); 171 | 172 | Object.defineProperty(exports, '__esModule', { value: true }); 173 | 174 | }))); 175 | -------------------------------------------------------------------------------- /build/file-drop-module.d.ts: -------------------------------------------------------------------------------- 1 | export declare class FileDropModule { 2 | } 3 | -------------------------------------------------------------------------------- /build/file-drop-module.js: -------------------------------------------------------------------------------- 1 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 2 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 3 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 4 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 5 | return c > 3 && r && Object.defineProperty(target, key, r), r; 6 | }; 7 | import { NgModule } from '@angular/core'; 8 | import { FileDropDirective } from './file-drop'; 9 | var FileDropModule = (function () { 10 | function FileDropModule() { 11 | } 12 | return FileDropModule; 13 | }()); 14 | FileDropModule = __decorate([ 15 | NgModule({ 16 | declarations: [ 17 | FileDropDirective, 18 | ], 19 | exports: [FileDropDirective], 20 | imports: [], 21 | providers: [], 22 | }) 23 | ], FileDropModule); 24 | export { FileDropModule }; 25 | //# sourceMappingURL=file-drop-module.js.map -------------------------------------------------------------------------------- /build/file-drop-module.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"file-drop-module.js","sourceRoot":"","sources":["../src/file-drop-module.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AACvC,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAU9C,IAAa,cAAc;IAA3B;IAA6B,CAAC;IAAD,qBAAC;AAAD,CAAC,AAA9B,IAA8B;AAAjB,cAAc;IAR1B,QAAQ,CAAC;QACR,YAAY,EAAE;YACZ,iBAAiB;SAClB;QACD,OAAO,EAAE,CAAC,iBAAiB,CAAC;QAC5B,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,EAAE;KACd,CAAC;GACW,cAAc,CAAG;SAAjB,cAAc"} -------------------------------------------------------------------------------- /build/file-drop-module.metadata.json: -------------------------------------------------------------------------------- 1 | [{"__symbolic":"module","version":3,"metadata":{"FileDropModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule"},"arguments":[{"declarations":[{"__symbolic":"reference","module":"./file-drop","name":"FileDropDirective"}],"exports":[{"__symbolic":"reference","module":"./file-drop","name":"FileDropDirective"}],"imports":[],"providers":[]}]}]}}},{"__symbolic":"module","version":1,"metadata":{"FileDropModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule"},"arguments":[{"declarations":[{"__symbolic":"reference","module":"./file-drop","name":"FileDropDirective"}],"exports":[{"__symbolic":"reference","module":"./file-drop","name":"FileDropDirective"}],"imports":[],"providers":[]}]}]}}}] -------------------------------------------------------------------------------- /build/file-drop.d.ts: -------------------------------------------------------------------------------- 1 | import 'fileapi'; 2 | import { EventEmitter, ElementRef } from '@angular/core'; 3 | export interface Options { 4 | readAs?: string; 5 | } 6 | export declare class FileDropDirective { 7 | fileOver: EventEmitter; 8 | onFileDrop: EventEmitter; 9 | options: Options; 10 | private element; 11 | constructor(element: ElementRef); 12 | onDragOver(event: any): void; 13 | onDragLeave(event: any): void; 14 | onDrop(event: any): void; 15 | private readFile(file); 16 | private emitFileOver(isOver); 17 | private emitFileDrop(file); 18 | private pickStrategy(); 19 | private hasStrategy(type); 20 | private getDataTransfer(event); 21 | private preventAndStop(event); 22 | private haveFiles(types); 23 | } 24 | -------------------------------------------------------------------------------- /build/file-drop.js: -------------------------------------------------------------------------------- 1 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 2 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 3 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 4 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 5 | return c > 3 && r && Object.defineProperty(target, key, r), r; 6 | }; 7 | var __metadata = (this && this.__metadata) || function (k, v) { 8 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 9 | }; 10 | import 'fileapi'; 11 | import { Directive, EventEmitter, ElementRef, HostListener, Input, Output, } from '@angular/core'; 12 | var FileDropDirective = (function () { 13 | function FileDropDirective(element) { 14 | this.fileOver = new EventEmitter(); 15 | this.onFileDrop = new EventEmitter(); 16 | this.element = element; 17 | } 18 | FileDropDirective.prototype.onDragOver = function (event) { 19 | var transfer = this.getDataTransfer(event); 20 | if (!this.haveFiles(transfer.types)) { 21 | return; 22 | } 23 | transfer.dropEffect = 'copy'; 24 | this.preventAndStop(event); 25 | this.emitFileOver(true); 26 | }; 27 | FileDropDirective.prototype.onDragLeave = function (event) { 28 | if (event.currentTarget === this.element[0]) { 29 | return; 30 | } 31 | this.preventAndStop(event); 32 | this.emitFileOver(false); 33 | }; 34 | FileDropDirective.prototype.onDrop = function (event) { 35 | var transfer = this.getDataTransfer(event); 36 | if (!transfer) { 37 | return; 38 | } 39 | this.preventAndStop(event); 40 | this.emitFileOver(false); 41 | this.readFile(transfer.files[0]); 42 | }; 43 | FileDropDirective.prototype.readFile = function (file) { 44 | var _this = this; 45 | var strategy = this.pickStrategy(); 46 | if (!strategy) { 47 | this.emitFileDrop(file); 48 | } 49 | else { 50 | // XXX Waiting for angular/zone.js#358 51 | var method = "readAs" + strategy; 52 | FileAPI[method](file, function (event) { 53 | if (event.type === 'load') { 54 | _this.emitFileDrop(event.result); 55 | } 56 | else if (event.type === 'error') { 57 | throw new Error("Couldn't read file '" + file.name + "'"); 58 | } 59 | }); 60 | } 61 | }; 62 | FileDropDirective.prototype.emitFileOver = function (isOver) { 63 | this.fileOver.emit(isOver); 64 | }; 65 | FileDropDirective.prototype.emitFileDrop = function (file) { 66 | this.onFileDrop.emit(file); 67 | }; 68 | FileDropDirective.prototype.pickStrategy = function () { 69 | if (!this.options) { 70 | return; 71 | } 72 | if (this.hasStrategy(this.options.readAs)) { 73 | return this.options.readAs; 74 | } 75 | }; 76 | FileDropDirective.prototype.hasStrategy = function (type) { 77 | return [ 78 | 'DataURL', 79 | 'BinaryString', 80 | 'ArrayBuffer', 81 | 'Text', 82 | ].indexOf(type) !== -1; 83 | }; 84 | FileDropDirective.prototype.getDataTransfer = function (event) { 85 | return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; 86 | }; 87 | FileDropDirective.prototype.preventAndStop = function (event) { 88 | event.preventDefault(); 89 | event.stopPropagation(); 90 | }; 91 | FileDropDirective.prototype.haveFiles = function (types) { 92 | if (!types) { 93 | return false; 94 | } 95 | if (types.indexOf) { 96 | return types.indexOf('Files') !== -1; 97 | } 98 | if (types.contains) { 99 | return types.contains('Files'); 100 | } 101 | return false; 102 | }; 103 | return FileDropDirective; 104 | }()); 105 | __decorate([ 106 | Output(), 107 | __metadata("design:type", EventEmitter) 108 | ], FileDropDirective.prototype, "fileOver", void 0); 109 | __decorate([ 110 | Output(), 111 | __metadata("design:type", EventEmitter) 112 | ], FileDropDirective.prototype, "onFileDrop", void 0); 113 | __decorate([ 114 | Input(), 115 | __metadata("design:type", Object) 116 | ], FileDropDirective.prototype, "options", void 0); 117 | __decorate([ 118 | HostListener('dragover', [ 119 | '$event', 120 | ]), 121 | __metadata("design:type", Function), 122 | __metadata("design:paramtypes", [Object]), 123 | __metadata("design:returntype", void 0) 124 | ], FileDropDirective.prototype, "onDragOver", null); 125 | __decorate([ 126 | HostListener('dragleave', [ 127 | '$event', 128 | ]), 129 | __metadata("design:type", Function), 130 | __metadata("design:paramtypes", [Object]), 131 | __metadata("design:returntype", void 0) 132 | ], FileDropDirective.prototype, "onDragLeave", null); 133 | __decorate([ 134 | HostListener('drop', [ 135 | '$event', 136 | ]), 137 | __metadata("design:type", Function), 138 | __metadata("design:paramtypes", [Object]), 139 | __metadata("design:returntype", void 0) 140 | ], FileDropDirective.prototype, "onDrop", null); 141 | FileDropDirective = __decorate([ 142 | Directive({ selector: '[fileDrop]' }), 143 | __metadata("design:paramtypes", [ElementRef]) 144 | ], FileDropDirective); 145 | export { FileDropDirective }; 146 | //# sourceMappingURL=file-drop.js.map -------------------------------------------------------------------------------- /build/file-drop.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"file-drop.js","sourceRoot":"","sources":["../src/file-drop.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /build/file-drop.metadata.json: -------------------------------------------------------------------------------- 1 | [{"__symbolic":"module","version":3,"metadata":{"FileDropDirective":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Directive"},"arguments":[{"selector":"[fileDrop]"}]}],"members":{"fileOver":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"}}]}],"onFileDrop":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"}}]}],"options":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ElementRef"}]}],"onDragOver":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["dragover",["$event"]]}]}],"onDragLeave":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["dragleave",["$event"]]}]}],"onDrop":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["drop",["$event"]]}]}],"readFile":[{"__symbolic":"method"}],"emitFileOver":[{"__symbolic":"method"}],"emitFileDrop":[{"__symbolic":"method"}],"pickStrategy":[{"__symbolic":"method"}],"hasStrategy":[{"__symbolic":"method"}],"getDataTransfer":[{"__symbolic":"method"}],"preventAndStop":[{"__symbolic":"method"}],"haveFiles":[{"__symbolic":"method"}]}}}},{"__symbolic":"module","version":1,"metadata":{"FileDropDirective":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Directive"},"arguments":[{"selector":"[fileDrop]"}]}],"members":{"fileOver":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"}}]}],"onFileDrop":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output"}}]}],"options":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ElementRef"}]}],"onDragOver":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["dragover",["$event"]]}]}],"onDragLeave":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["dragleave",["$event"]]}]}],"onDrop":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["drop",["$event"]]}]}],"readFile":[{"__symbolic":"method"}],"emitFileOver":[{"__symbolic":"method"}],"emitFileDrop":[{"__symbolic":"method"}],"pickStrategy":[{"__symbolic":"method"}],"hasStrategy":[{"__symbolic":"method"}],"getDataTransfer":[{"__symbolic":"method"}],"preventAndStop":[{"__symbolic":"method"}],"haveFiles":[{"__symbolic":"method"}]}}}}] -------------------------------------------------------------------------------- /build/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './file-drop-module'; 2 | -------------------------------------------------------------------------------- /build/index.js: -------------------------------------------------------------------------------- 1 | export * from './file-drop-module'; 2 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /build/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"} -------------------------------------------------------------------------------- /build/index.metadata.json: -------------------------------------------------------------------------------- 1 | [{"__symbolic":"module","version":3,"metadata":{},"exports":[{"from":"./file-drop-module"}]},{"__symbolic":"module","version":1,"metadata":{},"exports":[{"from":"./file-drop-module"}]}] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-file-drop", 3 | "version": "0.2.0", 4 | "description": "Angular2 component with Drag and Drop support for files", 5 | "main": "build/bundles/index.umd.js", 6 | "typings": "build/index.d.ts", 7 | "module": "build/index.js", 8 | "scripts": { 9 | "test": "npm run build", 10 | "prebuild": "npm run lint", 11 | "build": "tsc && npm run bundle", 12 | "watch": "tsc -w", 13 | "lint": "tslint src/*.ts", 14 | "build:aot": "node_modules/.bin/ngc", 15 | "prepublish": "npm run build && npm run build:aot", 16 | "rollup": "rollup -i ./build/index.js -o ./build/bundles/index.umd.js -n ng.file-drop -c rollup.config.js", 17 | "bundle": "npm run rollup" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/jellyjs/angular2-file-drop.git" 22 | }, 23 | "keywords": [ 24 | "angular", 25 | "angular2", 26 | "file", 27 | "drag", 28 | "drop", 29 | "upload" 30 | ], 31 | "author": "Kamil Kisiela ", 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/jellyjs/angular2-file-drop/issues" 35 | }, 36 | "homepage": "https://github.com/jellyjs/angular2-file-drop#readme", 37 | "dependencies": { 38 | "fileapi": "^2.0.20" 39 | }, 40 | "devDependencies": { 41 | "@angular/common": "^2.4.3", 42 | "@angular/compiler": "^2.4.3", 43 | "@angular/compiler-cli": "^2.4.3", 44 | "@angular/core": "^2.4.3", 45 | "@angular/platform-browser": "^2.4.3", 46 | "@angular/platform-browser-dynamic": "^2.4.3", 47 | "reflect-metadata": "^0.1.8", 48 | "rxjs": "5.0.3", 49 | "tslint": "^3.10.2", 50 | "typescript": "^2.0.10", 51 | "typings": "^1.4.0", 52 | "zone.js": "^0.7.2", 53 | "rollup": "^0.38.0", 54 | "rollup-plugin-babel": "^2.6.1" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | format: 'umd', 3 | globals: { 4 | '@angular/core':'ng.core', 5 | 'fileapi': 'fileapi', 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /src/file-drop-module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {FileDropDirective} from './file-drop'; 3 | 4 | @NgModule({ 5 | declarations: [ 6 | FileDropDirective, 7 | ], 8 | exports: [FileDropDirective], 9 | imports: [], 10 | providers: [], 11 | }) 12 | export class FileDropModule {} 13 | -------------------------------------------------------------------------------- /src/file-drop.ts: -------------------------------------------------------------------------------- 1 | import 'fileapi'; 2 | 3 | import { 4 | Directive, 5 | EventEmitter, 6 | ElementRef, 7 | HostListener, 8 | Input, 9 | Output, 10 | } from '@angular/core'; 11 | 12 | export interface Options { 13 | readAs?: string; 14 | } 15 | 16 | @Directive({ selector: '[fileDrop]' }) 17 | export class FileDropDirective { 18 | @Output() public fileOver: EventEmitter = new EventEmitter(); 19 | @Output() public onFileDrop: EventEmitter = new EventEmitter(); 20 | @Input() public options: Options; 21 | 22 | private element: ElementRef; 23 | 24 | public constructor( 25 | element: ElementRef 26 | ) { 27 | this.element = element; 28 | } 29 | 30 | @HostListener('dragover', [ 31 | '$event', 32 | ]) 33 | public onDragOver(event: any): void { 34 | const transfer = this.getDataTransfer(event); 35 | 36 | if (!this.haveFiles(transfer.types)) { 37 | return; 38 | } 39 | 40 | transfer.dropEffect = 'copy'; 41 | this.preventAndStop(event); 42 | this.emitFileOver(true); 43 | } 44 | 45 | @HostListener('dragleave', [ 46 | '$event', 47 | ]) 48 | public onDragLeave(event: any): void { 49 | if (event.currentTarget === (this as any).element[0]) { 50 | return; 51 | } 52 | 53 | this.preventAndStop(event); 54 | this.emitFileOver(false); 55 | } 56 | 57 | @HostListener('drop', [ 58 | '$event', 59 | ]) 60 | public onDrop(event: any): void { 61 | const transfer = this.getDataTransfer(event); 62 | 63 | if (!transfer) { 64 | return; 65 | } 66 | 67 | this.preventAndStop(event); 68 | this.emitFileOver(false); 69 | this.readFile(transfer.files[0]); 70 | } 71 | 72 | private readFile(file: File): void { 73 | const strategy = this.pickStrategy(); 74 | 75 | if (!strategy) { 76 | this.emitFileDrop(file); 77 | } else { 78 | // XXX Waiting for angular/zone.js#358 79 | const method = `readAs${strategy}`; 80 | 81 | FileAPI[method](file, (event) => { 82 | if (event.type === 'load') { 83 | this.emitFileDrop(event.result); 84 | } else if (event.type === 'error') { 85 | throw new Error(`Couldn't read file '${file.name}'`); 86 | } 87 | }); 88 | } 89 | } 90 | 91 | private emitFileOver(isOver: boolean): void { 92 | this.fileOver.emit(isOver); 93 | } 94 | 95 | private emitFileDrop(file: any): void { 96 | this.onFileDrop.emit(file); 97 | } 98 | 99 | private pickStrategy(): string | void { 100 | if (!this.options) { 101 | return; 102 | } 103 | 104 | if (this.hasStrategy(this.options.readAs)) { 105 | return this.options.readAs; 106 | } 107 | } 108 | 109 | private hasStrategy(type: string): boolean { 110 | return [ 111 | 'DataURL', 112 | 'BinaryString', 113 | 'ArrayBuffer', 114 | 'Text', 115 | ].indexOf(type) !== -1; 116 | } 117 | 118 | private getDataTransfer(event: any | any): DataTransfer { 119 | return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; 120 | } 121 | 122 | private preventAndStop(event: any): void { 123 | event.preventDefault(); 124 | event.stopPropagation(); 125 | } 126 | 127 | private haveFiles(types: any): boolean { 128 | if (!types) { 129 | return false; 130 | } 131 | 132 | if (types.indexOf) { 133 | return types.indexOf('Files') !== -1; 134 | } 135 | 136 | if (types.contains) { 137 | return types.contains('Files'); 138 | } 139 | 140 | return false; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './file-drop-module'; 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "es2015", 5 | "sourceMap": true, 6 | "declaration": true, 7 | "rootDir": "./src", 8 | "outDir": "./build", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "noImplicitAny": false, 12 | "moduleResolution": "node", 13 | "lib": ["es2015", "dom"] 14 | }, 15 | "files": [ 16 | "./src/index.ts", 17 | "./ambient.d.ts" 18 | ], 19 | "exclude": [ 20 | "build", 21 | "node_modules", 22 | "typings" 23 | ], 24 | "angularCompilerOptions": { 25 | "genDir": "aot", 26 | "skipMetadataEmit" : false 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "align": [ 4 | false, 5 | "parameters", 6 | "arguments", 7 | "statements" 8 | ], 9 | "ban": false, 10 | "class-name": true, 11 | "curly": true, 12 | "eofline": true, 13 | "forin": true, 14 | "indent": [ 15 | true, 16 | "spaces" 17 | ], 18 | "interface-name": false, 19 | "jsdoc-format": true, 20 | "label-position": true, 21 | "label-undefined": true, 22 | "max-line-length": [ 23 | true, 24 | 140 25 | ], 26 | "member-access": true, 27 | "member-ordering": [ 28 | true, 29 | "public-before-private", 30 | "static-before-instance", 31 | "variables-before-functions" 32 | ], 33 | "no-any": false, 34 | "no-arg": true, 35 | "no-bitwise": true, 36 | "no-conditional-assignment": true, 37 | "no-consecutive-blank-lines": false, 38 | "no-console": [ 39 | true, 40 | "log", 41 | "debug", 42 | "info", 43 | "time", 44 | "timeEnd", 45 | "trace" 46 | ], 47 | "no-construct": true, 48 | "no-constructor-vars": false, 49 | "no-debugger": true, 50 | "no-duplicate-key": true, 51 | "no-duplicate-variable": true, 52 | "no-empty": true, 53 | "no-eval": true, 54 | "no-inferrable-types": false, 55 | "no-internal-module": true, 56 | "no-null-keyword": false, 57 | "no-require-imports": true, 58 | "no-shadowed-variable": true, 59 | "no-switch-case-fall-through": true, 60 | "no-trailing-whitespace": true, 61 | "no-unreachable": true, 62 | "no-unused-expression": true, 63 | "no-unused-variable": true, 64 | "no-use-before-declare": true, 65 | "no-var-keyword": true, 66 | "no-var-requires": true, 67 | "object-literal-sort-keys": false, 68 | "one-line": [ 69 | true, 70 | "check-open-brace", 71 | "check-catch", 72 | "check-else", 73 | "check-finally", 74 | "check-whitespace" 75 | ], 76 | "quotemark": [ 77 | true, 78 | "single", 79 | "avoid-escape" 80 | ], 81 | "radix": true, 82 | "semicolon": [ 83 | true, 84 | "always" 85 | ], 86 | "switch-default": true, 87 | "trailing-comma": [ 88 | true, 89 | { 90 | "multiline": "always", 91 | "singleline": "never" 92 | } 93 | ], 94 | "triple-equals": [ 95 | true, 96 | "allow-null-check" 97 | ], 98 | "typedef": [ 99 | false, 100 | "call-signature", 101 | "parameter", 102 | "arrow-parameter", 103 | "property-declaration", 104 | "variable-declaration", 105 | "member-variable-declaration" 106 | ], 107 | "typedef-whitespace": [ 108 | true, 109 | { 110 | "call-signature": "nospace", 111 | "index-signature": "nospace", 112 | "parameter": "nospace", 113 | "property-declaration": "nospace", 114 | "variable-declaration": "nospace" 115 | }, 116 | { 117 | "call-signature": "space", 118 | "index-signature": "space", 119 | "parameter": "space", 120 | "property-declaration": "space", 121 | "variable-declaration": "space" 122 | } 123 | ], 124 | "use-strict": [ 125 | false 126 | ], 127 | "variable-name": [ 128 | true, 129 | "check-format", 130 | "allow-leading-underscore", 131 | "ban-keywords" 132 | ], 133 | "whitespace": [ 134 | true, 135 | "check-branch", 136 | "check-decl", 137 | "check-operator", 138 | "check-separator", 139 | "check-type" 140 | ] 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-file-drop", 3 | "dependencies": {}, 4 | "globalDependencies": { 5 | "es6-shim": "registry:dt/es6-shim#0.31.2+20160602141504" 6 | } 7 | } 8 | --------------------------------------------------------------------------------