1+ import React from "react" ;
2+ import Uppy , { Locale , Restrictions , UppyEventMap , UppyFile } from "@uppy/core" ;
3+ import { DragDrop , ProgressBar , useUppy } from "@uppy/react" ;
4+ import XHRUpload , { XHRUploadOptions } from "@uppy/xhr-upload" ;
5+
6+ import { TestableComponent } from "../../components/interfaces" ;
7+
8+ import "@uppy/core/dist/style.css" ;
9+ import "@uppy/drag-drop/dist/style.css" ;
10+ import "@uppy/progress-bar/dist/style.css" ;
11+
12+ type eventNames = keyof UppyEventMap ;
13+
14+ export interface FileUploadProps extends TestableComponent {
15+ /**
16+ * upload instance id
17+ */
18+ id ?: string ;
19+ /**
20+ * upload error callback function
21+ */
22+ onError ?: ( responseText : string ) => void ;
23+ /**
24+ * upload success callback function
25+ */
26+ onSuccess ?: ( responseText : string ) => void ;
27+ /**
28+ * upload response callback function
29+ */
30+ handleResponseData ?: ( responseText : string ) => void ;
31+ /**
32+ * locale options, like button labels etc.
33+ */
34+ localeOptions ?: Locale ;
35+ /**
36+ * reset form after upload or in case of error/navigation steps
37+ */
38+ resetForm ?: boolean ;
39+ /**
40+ * auto proceed bolean
41+ */
42+ autoProceed ?: boolean ;
43+ /**
44+ * upload restrictions
45+ */
46+ restrictions ?: Restrictions ;
47+ /**
48+ * additional upload files
49+ */
50+ additionalFiles ?: {
51+ id : string ;
52+ name : string ;
53+ size : number ;
54+ data : Blob ;
55+ } [ ] ;
56+ /**
57+ * xhr upload options
58+ */
59+ xhrUploadOptions : XHRUploadOptions ;
60+ /**
61+ * uppy events to register and unregister to
62+ */
63+ events ?: { [ key in eventNames ] ?: any } ;
64+ /**
65+ * set uppy instance
66+ */
67+ setInstance ?: ( instance : Uppy ) => void ;
68+ }
69+
70+ export { ProgressBar as FileUploadProgressBar , DragDrop as FileUploadDragDrop } from "@uppy/react" ;
71+ export type { XHRUploadOptions } from "@uppy/xhr-upload"
72+
73+
74+ export const FileUpload : React . FC < FileUploadProps > = ( {
75+ id,
76+ onError,
77+ onSuccess,
78+ handleResponseData,
79+ resetForm,
80+ autoProceed = false ,
81+ restrictions,
82+ additionalFiles,
83+ xhrUploadOptions,
84+ localeOptions,
85+ events,
86+ setInstance,
87+ children,
88+ ...rest
89+ } ) => {
90+ const uppy = useUppy ( ( ) => {
91+ return new Uppy ( {
92+ id,
93+ autoProceed,
94+ restrictions,
95+ locale : localeOptions ,
96+ } )
97+ . on ( "upload-success" , ( _ , response ) => {
98+ onSuccess ?.( response . body ) ;
99+ } )
100+ . use ( XHRUpload , {
101+ ...xhrUploadOptions ,
102+ getResponseData : ( responseText ) => {
103+ handleResponseData ?.( responseText ) ;
104+ return responseText ;
105+ } ,
106+ getResponseError : ( responseText ) => {
107+ uppy . reset ( ) ;
108+
109+ onError ?.( responseText ) ;
110+ return new Error ( responseText ) ;
111+ } ,
112+ } ) ;
113+ } ) ;
114+
115+ //events
116+ React . useEffect ( ( ) => {
117+ uppy && setInstance && setInstance ( uppy ) ;
118+ const eventEntries = Object . entries ( events ?? { } ) as [ keyof UppyEventMap , ( file : UppyFile ) => Promise < void > ] [ ] ;
119+ const unregisterEvents = ( ) => {
120+ eventEntries . length && eventEntries . forEach ( ( [ event , handler ] ) => uppy . off ( event , handler ) ) ;
121+ } ;
122+
123+ unregisterEvents ( ) ;
124+
125+ eventEntries . length &&
126+ eventEntries . forEach ( ( [ event , handler ] ) => {
127+ uppy . on ( event , handler ) ;
128+ } ) ;
129+
130+ return ( ) => unregisterEvents ( ) ;
131+ } , [ events , uppy ] ) ;
132+
133+ React . useEffect ( ( ) => {
134+ if ( resetForm ) {
135+ uppy . reset ( ) ;
136+ }
137+
138+ return ( ) => {
139+ uppy . close ( ) ;
140+ } ;
141+ } , [ resetForm , uppy ] ) ;
142+
143+ React . useEffect ( ( ) => {
144+ if ( additionalFiles ) {
145+ additionalFiles . forEach ( ( file ) => {
146+ uppy . addFile ( {
147+ name : file . name ,
148+ data : file . data ,
149+ size : file . size ,
150+ id : file . id ,
151+ } ) ;
152+ } ) ;
153+ }
154+ } , [ additionalFiles , uppy ] ) ;
155+
156+ if ( ! uppy ) return null ;
157+
158+
159+ return (
160+ < div { ...rest } >
161+ { children ? (
162+ children
163+ ) : (
164+ < >
165+ < DragDrop uppy = { uppy } />
166+ < ProgressBar uppy = { uppy } />
167+ </ >
168+ ) }
169+ </ div >
170+ ) ;
171+ } ;
0 commit comments