@@ -3,14 +3,112 @@ import React from 'react';
3
3
export default class ImageControl extends React . Component {
4
4
constructor ( props ) {
5
5
super ( props ) ;
6
+
7
+ this . state = {
8
+ currentImage : props . value
9
+ } ;
10
+
11
+ this . revokeCurrentImage = this . revokeCurrentImage . bind ( this ) ;
6
12
this . handleChange = this . handleChange . bind ( this ) ;
13
+ this . handleFileInputRef = this . handleFileInputRef . bind ( this ) ;
14
+ this . handleClick = this . handleClick . bind ( this ) ;
15
+ this . handleDragEnter = this . handleDragEnter . bind ( this ) ;
16
+ this . handleDragOver = this . handleDragOver . bind ( this ) ;
17
+ this . renderImageName = this . renderImageName . bind ( this ) ;
18
+ }
19
+
20
+ componentWillUnmount ( ) {
21
+ this . revokeCurrentImage ( ) ;
22
+ }
23
+
24
+ revokeCurrentImage ( ) {
25
+ if ( this . state . currentImage instanceof File ) {
26
+ window . URL . revokeObjectURL ( this . state . currentImage ) ;
27
+ }
28
+ }
29
+
30
+ handleFileInputRef ( el ) {
31
+ this . _fileInput = el ;
32
+ }
33
+
34
+ handleClick ( e ) {
35
+ this . _fileInput . click ( ) ;
36
+ }
37
+
38
+ handleDragEnter ( e ) {
39
+ e . stopPropagation ( ) ;
40
+ e . preventDefault ( ) ;
41
+ }
42
+
43
+ handleDragOver ( e ) {
44
+ e . stopPropagation ( ) ;
45
+ e . preventDefault ( ) ;
7
46
}
8
47
9
48
handleChange ( e ) {
10
- this . props . onChange ( e . target . value ) ;
49
+ e . stopPropagation ( ) ;
50
+ e . preventDefault ( ) ;
51
+ this . revokeCurrentImage ( ) ;
52
+ const fileList = e . dataTransfer ? e . dataTransfer . files : e . target . files ;
53
+ const files = [ ...fileList ] ;
54
+ const imageType = / ^ i m a g e \/ / ;
55
+
56
+ // Iterate through the list of files and return the first image on the list
57
+ const file = files . find ( ( currentFile ) => {
58
+ if ( imageType . test ( currentFile . type ) ) {
59
+ return currentFile ;
60
+ }
61
+ } ) ;
62
+
63
+ if ( file ) {
64
+ // Custom toString function on file, so it can be used on regular image fields
65
+ file . toString = function ( ) {
66
+ return window . URL . createObjectURL ( file ) ;
67
+ } ;
68
+ }
69
+
70
+ this . props . onChange ( file ) ;
71
+ this . setState ( { currentImage : file } ) ;
72
+ }
73
+
74
+ renderImageName ( ) {
75
+ if ( ! this . state . currentImage ) return null ;
76
+
77
+ if ( this . state . currentImage instanceof File ) {
78
+ return this . state . currentImage . name ;
79
+ } else if ( typeof this . state . currentImage === 'string' ) {
80
+ const fileName = this . state . currentImage ;
81
+ return fileName . substring ( fileName . lastIndexOf ( '/' ) + 1 ) ;
82
+ }
83
+
84
+ return null ;
11
85
}
12
86
13
87
render ( ) {
14
- return < input type = "file" onChange = { this . handleChange } /> ;
88
+ const imageName = this . renderImageName ( ) ;
89
+ return (
90
+ < div
91
+ onDragEnter = { this . handleDragEnter }
92
+ onDragOver = { this . handleDragOver }
93
+ onDrop = { this . handleChange }
94
+ >
95
+ < span onClick = { this . handleClick } >
96
+ { imageName ? imageName : 'Click or drop imag here.' }
97
+ </ span >
98
+ < input
99
+ type = "file"
100
+ accept = "image/*"
101
+ onChange = { this . handleChange }
102
+ style = { styles . input }
103
+ ref = { this . handleFileInputRef }
104
+ />
105
+ </ div >
106
+ ) ;
15
107
}
16
108
}
109
+
110
+ const styles = {
111
+ input : {
112
+ display : 'none'
113
+ }
114
+ } ;
0 commit comments