@@ -17,7 +17,6 @@ export interface CSVReaderProps {
17
17
inputId ?: string
18
18
inputName ?: string
19
19
inputStyle ?: object
20
- inputRef ?: React . LegacyRef < HTMLInputElement >
21
20
label ?: string | React . ReactNode
22
21
onError ?: ( error : Error ) => void
23
22
onFileLoaded : ( data : Array < any > , fileInfo : IFileInfo , originalFile ?: File ) => any
@@ -26,75 +25,79 @@ export interface CSVReaderProps {
26
25
strict ?: boolean
27
26
}
28
27
29
- const CSVReader : React . FC < CSVReaderProps > = ( {
30
- accept = '.csv, text/csv' ,
31
- cssClass = 'csv-reader-input' ,
32
- cssInputClass = 'csv-input' ,
33
- cssLabelClass = 'csv-label' ,
34
- fileEncoding = 'UTF-8' ,
35
- inputId = 'react-csv-reader-input' ,
36
- inputName = 'react-csv-reader-input' ,
37
- inputStyle = { } ,
38
- inputRef,
39
- label,
40
- onError = ( ) => { } ,
41
- onFileLoaded,
42
- parserOptions = { } as PapaParse . ParseConfig ,
43
- disabled = false ,
44
- strict = false ,
45
- } ) => {
46
- const handleChangeFile = ( e : React . ChangeEvent < HTMLInputElement > ) => {
47
- let reader : FileReader = new FileReader ( )
48
- const files : FileList = e . target . files !
28
+ const CSVReader = React . forwardRef < HTMLInputElement , CSVReaderProps > (
29
+ (
30
+ {
31
+ accept = '.csv, text/csv' ,
32
+ cssClass = 'csv-reader-input' ,
33
+ cssInputClass = 'csv-input' ,
34
+ cssLabelClass = 'csv-label' ,
35
+ fileEncoding = 'UTF-8' ,
36
+ inputId = 'react-csv-reader-input' ,
37
+ inputName = 'react-csv-reader-input' ,
38
+ inputStyle = { } ,
39
+ label,
40
+ onError = ( ) => { } ,
41
+ onFileLoaded,
42
+ parserOptions = { } as PapaParse . ParseConfig ,
43
+ disabled = false ,
44
+ strict = false ,
45
+ } ,
46
+ inputRef ,
47
+ ) => {
48
+ const handleChangeFile = ( e : React . ChangeEvent < HTMLInputElement > ) => {
49
+ let reader : FileReader = new FileReader ( )
50
+ const files : FileList = e . target . files !
49
51
50
- if ( files . length > 0 ) {
51
- const fileInfo : IFileInfo = {
52
- name : files [ 0 ] . name ,
53
- size : files [ 0 ] . size ,
54
- type : files [ 0 ] . type ,
55
- }
52
+ if ( files . length > 0 ) {
53
+ const fileInfo : IFileInfo = {
54
+ name : files [ 0 ] . name ,
55
+ size : files [ 0 ] . size ,
56
+ type : files [ 0 ] . type ,
57
+ }
56
58
57
- if ( strict && accept . indexOf ( fileInfo . type ) <= 0 ) {
58
- onError ( new Error ( `[strict mode] Accept type not respected: got '${ fileInfo . type } ' but not in '${ accept } '` ) )
59
- return
60
- }
59
+ if ( strict && accept . indexOf ( fileInfo . type ) <= 0 ) {
60
+ onError ( new Error ( `[strict mode] Accept type not respected: got '${ fileInfo . type } ' but not in '${ accept } '` ) )
61
+ return
62
+ }
61
63
62
- reader . onload = ( _event : Event ) => {
63
- const csvData = PapaParse . parse (
64
- reader . result as string ,
65
- Object . assign ( parserOptions , {
66
- error : onError ,
67
- encoding : fileEncoding ,
68
- } ) ,
69
- )
70
- onFileLoaded ( csvData ?. data ?? [ ] , fileInfo , files [ 0 ] )
71
- }
64
+ reader . onload = ( _event : Event ) => {
65
+ const csvData = PapaParse . parse (
66
+ reader . result as string ,
67
+ Object . assign ( parserOptions , {
68
+ error : onError ,
69
+ encoding : fileEncoding ,
70
+ } ) ,
71
+ )
72
+ onFileLoaded ( csvData ?. data ?? [ ] , fileInfo , files [ 0 ] )
73
+ }
72
74
73
- reader . readAsText ( files [ 0 ] , fileEncoding )
75
+ reader . readAsText ( files [ 0 ] , fileEncoding )
76
+ }
74
77
}
75
- }
76
78
77
- return (
78
- < div className = { cssClass } >
79
- { label && (
80
- < label className = { cssLabelClass } htmlFor = { inputId } >
81
- { label }
82
- </ label >
83
- ) }
84
- < input
85
- className = { cssInputClass }
86
- type = "file"
87
- id = { inputId }
88
- name = { inputName }
89
- style = { inputStyle }
90
- accept = { accept }
91
- onChange = { handleChangeFile }
92
- disabled = { disabled }
93
- ref = { inputRef }
94
- />
95
- </ div >
96
- )
97
- }
79
+ return (
80
+ < div className = { cssClass } >
81
+ { label && (
82
+ < label className = { cssLabelClass } htmlFor = { inputId } >
83
+ { label }
84
+ </ label >
85
+ ) }
86
+ < input
87
+ className = { cssInputClass }
88
+ type = "file"
89
+ id = { inputId }
90
+ name = { inputName }
91
+ style = { inputStyle }
92
+ accept = { accept }
93
+ onChange = { handleChangeFile }
94
+ disabled = { disabled }
95
+ ref = { inputRef }
96
+ />
97
+ </ div >
98
+ )
99
+ } ,
100
+ )
98
101
99
102
CSVReader . propTypes = {
100
103
accept : PropTypes . string ,
@@ -105,7 +108,6 @@ CSVReader.propTypes = {
105
108
inputId : PropTypes . string ,
106
109
inputName : PropTypes . string ,
107
110
inputStyle : PropTypes . object ,
108
- inputRef : PropTypes . oneOfType ( [ PropTypes . func , PropTypes . exact ( { current : PropTypes . instanceOf ( HTMLInputElement ) } ) ] ) ,
109
111
label : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . element ] ) ,
110
112
onError : PropTypes . func ,
111
113
onFileLoaded : PropTypes . func . isRequired ,
0 commit comments