@@ -5,6 +5,7 @@ import React, {
5
5
PropsWithChildren ,
6
6
useRef ,
7
7
useEffect ,
8
+ useCallback ,
8
9
} from 'react'
9
10
import classNames from 'classnames'
10
11
import Taro , {
@@ -119,6 +120,7 @@ export interface UploaderProps extends BasicComponent {
119
120
beforeXhrUpload ?: ( xhr : XMLHttpRequest , options : any ) => void
120
121
beforeDelete ?: ( file : FileItem , files : FileItem [ ] ) => boolean
121
122
onFileItemClick ?: ( file : FileItem , index : number ) => void
123
+ enablePasteUpload ?: boolean
122
124
}
123
125
124
126
const defaultProps = {
@@ -152,6 +154,7 @@ const defaultProps = {
152
154
beforeDelete : ( file : FileItem , files : FileItem [ ] ) => {
153
155
return true
154
156
} ,
157
+ enablePasteUpload : false ,
155
158
} as UploaderProps
156
159
157
160
const InternalUploader : ForwardRefRenderFunction <
@@ -202,6 +205,7 @@ const InternalUploader: ForwardRefRenderFunction<
202
205
beforeUpload,
203
206
beforeXhrUpload,
204
207
beforeDelete,
208
+ enablePasteUpload,
205
209
...restProps
206
210
} = { ...defaultProps , ...props }
207
211
const [ fileList , setFileList ] = usePropsValue ( {
@@ -439,7 +443,7 @@ const InternalUploader: ForwardRefRenderFunction<
439
443
setFileList ( [ ...fileList , ...results ] )
440
444
}
441
445
442
- reader . readAsDataURL ( file as unknown as Blob )
446
+ reader . readAsDataURL ( file . originalFileObj ?? ( file as unknown as Blob ) )
443
447
} else {
444
448
executeUpload ( fileItem , index )
445
449
results . push ( fileItem )
@@ -520,6 +524,62 @@ const InternalUploader: ForwardRefRenderFunction<
520
524
onFileItemClick ?.( file , index )
521
525
}
522
526
527
+ const handlePaste = useCallback (
528
+ ( event : ClipboardEvent ) => {
529
+ if ( ! enablePasteUpload || disabled ) return
530
+
531
+ const clipboardData = event . clipboardData
532
+ if ( ! clipboardData ) return
533
+
534
+ const files : TFileType [ ] = [ ]
535
+
536
+ if ( clipboardData ?. items && clipboardData . items . length ) {
537
+ for ( let i = 0 ; i < clipboardData . items . length ; i ++ ) {
538
+ const item = clipboardData . items [ i ]
539
+ if ( item . kind === 'file' && item . type . startsWith ( 'image/' ) ) {
540
+ const file = item . getAsFile ( )
541
+ if ( file ) {
542
+ files . push ( {
543
+ originalFileObj : file ,
544
+ size : file . size ,
545
+ path : '' ,
546
+ tempFilePath : '' ,
547
+ type : file . type ,
548
+ fileType : file . type ,
549
+ } )
550
+ }
551
+ }
552
+ }
553
+ } else if ( clipboardData ?. files && clipboardData . files . length ) {
554
+ for ( let i = 0 ; i < clipboardData . files . length ; i ++ ) {
555
+ const file = clipboardData . files [ i ]
556
+ if ( file . type . startsWith ( 'image/' ) ) {
557
+ files . push ( file )
558
+ }
559
+ }
560
+ }
561
+
562
+ if ( files . length ) {
563
+ readFile ( files )
564
+ }
565
+ } ,
566
+ [ enablePasteUpload , disabled , beforeUpload , filterFiles , readFile , onChange ]
567
+ )
568
+
569
+ useEffect ( ( ) => {
570
+ fileListRef . current = fileList
571
+
572
+ if ( enablePasteUpload ) {
573
+ document . addEventListener ( 'paste' , handlePaste )
574
+ }
575
+
576
+ return ( ) => {
577
+ if ( enablePasteUpload ) {
578
+ document . removeEventListener ( 'paste' , handlePaste )
579
+ }
580
+ }
581
+ } , [ fileList , enablePasteUpload , handlePaste ] )
582
+
523
583
return (
524
584
< div className = { classes } { ...restProps } >
525
585
{ ( children || previewType === 'list' ) && (
0 commit comments