11/* eslint-disable react-hooks/exhaustive-deps */
22import React , {
3- useReducer ,
3+ DragEventHandler ,
4+ FocusEventHandler ,
5+ HTMLAttributes ,
6+ KeyboardEventHandler ,
7+ MouseEventHandler ,
48 useCallback ,
5- useMemo ,
69 useEffect ,
7- ReactNode ,
10+ useMemo ,
11+ useReducer ,
812 useRef ,
913} from 'react' ;
1014import PapaParse , { ParseResult } from 'papaparse' ;
@@ -28,7 +32,13 @@ import Remove, { Props as RemoveComponentProps } from './Remove';
2832const DEFAULT_ACCEPT = 'text/csv, .csv, application/vnd.ms-excel' ;
2933
3034export interface Props < T > {
31- children : ( fn : any ) => void | ReactNode ;
35+ children : ( fn : {
36+ getRootProps : ( ) => HTMLAttributes < HTMLDivElement > ;
37+ acceptedFile : File ;
38+ ProgressBar : React . ComponentType < ProgressBarComponentProps > ;
39+ getRemoveFileProps : ( ) => HTMLAttributes < HTMLDivElement > ;
40+ Remove : React . ComponentType < RemoveComponentProps > ;
41+ } ) => void | React . ReactNode ;
3242 accept ?: string ;
3343 config ?: CustomConfig < T > ;
3444 minSize ?: number ;
@@ -49,17 +59,17 @@ export interface Props<T> {
4959 ) => void ;
5060 onUploadRejected ?: ( file ?: File , event ?: DragEvent | Event ) => void ;
5161 validator ?: ( file : File ) => void ;
52- onDragEnter ?: ( event ? : DragEvent ) => void ;
53- onDragOver ?: ( event ? : DragEvent ) => void ;
54- onDragLeave ?: ( event ? : DragEvent ) => void ;
62+ onDragEnter ?: ( event : DragEvent ) => void ;
63+ onDragOver ?: ( event : DragEvent ) => void ;
64+ onDragLeave ?: ( event : DragEvent ) => void ;
5565}
5666
57- export interface ProgressBarComponentProp {
58- style ?: any ;
67+ export interface ProgressBarComponentProps {
68+ style ?: React . CSSProperties ;
5969 className ?: string ;
6070}
6171
62- function useCSVReaderComponent < T = any > ( ) {
72+ function useCSVReaderComponent < T = void > ( ) {
6373 const CSVReaderComponent = ( {
6474 children,
6575 accept = DEFAULT_ACCEPT ,
@@ -82,8 +92,8 @@ function useCSVReaderComponent<T = any>() {
8292 onDragOver,
8393 onDragLeave,
8494 } : Props < T > ) => {
85- const inputRef : any = useRef < ReactNode > ( null ) ;
86- const rootRef : any = useRef < ReactNode > ( null ) ;
95+ const inputRef = useRef < HTMLInputElement > ( null ) ;
96+ const rootRef = useRef < HTMLDivElement > ( null ) ;
8797 const dragTargetsRef = useRef ( [ ] ) ;
8898
8999 const [ state , dispatch ] = useReducer ( reducer , initialState ) ;
@@ -96,7 +106,10 @@ function useCSVReaderComponent<T = any>() {
96106 } = state ;
97107
98108 const onDocumentDrop = ( event : DragEvent ) => {
99- if ( rootRef . current && rootRef . current . contains ( event . target ) ) {
109+ if (
110+ rootRef . current &&
111+ rootRef . current . contains ( event . target as Element )
112+ ) {
100113 // If we intercepted an event for our instance, let it propagate down to the instance's onDrop handler
101114 return ;
102115 }
@@ -154,7 +167,7 @@ function useCSVReaderComponent<T = any>() {
154167 } ) ;
155168 } ;
156169
157- const ProgressBarComponent = ( props : ProgressBarComponentProp ) => {
170+ const ProgressBarComponent = ( props : ProgressBarComponentProps ) => {
158171 return (
159172 < ProgressBar
160173 display = { displayProgressBar }
@@ -182,7 +195,7 @@ function useCSVReaderComponent<T = any>() {
182195 const openFileDialog = useCallback ( ( ) => {
183196 if ( inputRef . current && state . displayProgressBar ) {
184197 dispatch ( { type : 'openDialog' } ) ;
185- inputRef . current . value = null ;
198+ inputRef . current . files = null ;
186199 inputRef . current . click ( ) ;
187200 }
188201 } , [ dispatch ] ) ;
@@ -195,7 +208,7 @@ function useCSVReaderComponent<T = any>() {
195208 if ( inputRef . current ) {
196209 const { files } = inputRef . current ;
197210
198- if ( ! files . length ) {
211+ if ( ! files || ! files . length ) {
199212 dispatch ( { type : 'closeDialog' } ) ;
200213 }
201214 }
@@ -467,7 +480,10 @@ function useCSVReaderComponent<T = any>() {
467480 const onKeyDownCb = useCallback (
468481 ( event : KeyboardEvent ) => {
469482 // Ignore keyboard events bubbling up the DOM tree
470- if ( ! rootRef . current || ! rootRef . current . isEqualNode ( event . target ) ) {
483+ if (
484+ ! rootRef . current ||
485+ ! rootRef . current . isEqualNode ( event . target as Element )
486+ ) {
471487 return ;
472488 }
473489
@@ -501,6 +517,15 @@ function useCSVReaderComponent<T = any>() {
501517 onDragEnter = ( ) => { } ,
502518 // refKey = rootRef,
503519 ...rest
520+ } : {
521+ onClick ?: MouseEventHandler < HTMLDivElement > ;
522+ onDrop ?: DragEventHandler < HTMLDivElement > ;
523+ onDragEnter ?: DragEventHandler < HTMLDivElement > ;
524+ onDragLeave ?: DragEventHandler < HTMLDivElement > ;
525+ onDragOver ?: DragEventHandler < HTMLDivElement > ;
526+ onKeyDown ?: KeyboardEventHandler < HTMLDivElement > ;
527+ onFocus ?: FocusEventHandler < HTMLDivElement > ;
528+ onBlur ?: FocusEventHandler < HTMLDivElement > ;
504529 } = { } ) => ( {
505530 onClick : composeHandler ( composeEventHandlers ( onClick , onClickCb ) ) ,
506531 onDrop : composeDragHandler ( composeEventHandlers ( onDrop , onDropCb ) ) ,
@@ -576,15 +601,20 @@ function useCSVReaderComponent<T = any>() {
576601 // ===========
577602
578603 const removeFileProgrammaticallyCb = useCallback ( ( event : Event ) => {
579- inputRef . current . value = '' ;
604+ if ( inputRef . current ) {
605+ inputRef . current . files = null ;
606+ }
580607 dispatch ( { type : 'reset' } ) ;
581608 // To prevent a parents onclick event from firing when a child is clicked
582609 event . stopPropagation ( ) ;
583610 } , [ ] ) ;
584611
585612 const getRemoveFileProps = useMemo (
586613 ( ) =>
587- ( { onClick = ( ) => { } , ...rest } = { } ) => ( {
614+ ( {
615+ onClick = ( ) => { } ,
616+ ...rest
617+ } : { onClick ?: MouseEventHandler < HTMLElement > } = { } ) => ( {
588618 onClick : composeHandler (
589619 composeEventHandlers ( onClick , removeFileProgrammaticallyCb ) ,
590620 ) ,
@@ -601,13 +631,16 @@ function useCSVReaderComponent<T = any>() {
601631 ) ;
602632 } ;
603633
604- const CSVReader = useMemo ( ( ) => CSVReaderComponent , [ ] ) as any ;
634+ const CSVReader = useMemo (
635+ ( ) => CSVReaderComponent ,
636+ [ ] ,
637+ ) as React . ComponentType < Props < T > > ;
605638
606639 return CSVReader ;
607640}
608641
609- export function useCSVReader ( ) {
610- const CSVReader = useCSVReaderComponent ( ) ;
642+ export function useCSVReader < T = void > ( ) {
643+ const CSVReader = useCSVReaderComponent < T > ( ) ;
611644
612645 return {
613646 CSVReader,
0 commit comments