@@ -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 { Photograph , Failure } from '@nutui/icons-react'
@@ -70,6 +71,7 @@ export interface UploaderProps extends BasicComponent {
70
71
beforeXhrUpload ?: ( xhr : XMLHttpRequest , options : any ) => void
71
72
beforeDelete ?: ( file : FileItem , files : FileItem [ ] ) => boolean
72
73
onFileItemClick ?: ( file : FileItem , index : number ) => void
74
+ enablePasteUpload ?: boolean
73
75
}
74
76
75
77
const defaultProps = {
@@ -99,6 +101,7 @@ const defaultProps = {
99
101
beforeDelete : ( file : FileItem , files : FileItem [ ] ) => {
100
102
return true
101
103
} ,
104
+ enablePasteUpload : false ,
102
105
} as UploaderProps
103
106
104
107
const InternalUploader : ForwardRefRenderFunction <
@@ -148,6 +151,7 @@ const InternalUploader: ForwardRefRenderFunction<
148
151
beforeUpload,
149
152
beforeXhrUpload,
150
153
beforeDelete,
154
+ enablePasteUpload,
151
155
...restProps
152
156
} = { ...defaultProps , ...props }
153
157
const [ fileList , setFileList ] = usePropsValue ( {
@@ -307,7 +311,7 @@ const InternalUploader: ForwardRefRenderFunction<
307
311
const reader = new FileReader ( )
308
312
reader . onload = ( event : ProgressEvent < FileReader > ) => {
309
313
fileItem . url = ( event . target as FileReader ) . result as string
310
- // setFileList([...fileList, fileItem])
314
+ setFileList ( [ ...fileList , fileItem ] )
311
315
results . push ( fileItem )
312
316
}
313
317
reader . readAsDataURL ( file )
@@ -383,6 +387,85 @@ const InternalUploader: ForwardRefRenderFunction<
383
387
onFileItemClick ?.( file , index )
384
388
}
385
389
390
+ const handlePaste = useCallback (
391
+ ( event : ClipboardEvent ) => {
392
+ if ( ! enablePasteUpload || disabled ) return
393
+
394
+ const clipboardData = event . clipboardData
395
+ if ( ! clipboardData ) return
396
+
397
+ const files : File [ ] = [ ]
398
+
399
+ if ( clipboardData . items && clipboardData . items . length ) {
400
+ for ( let i = 0 ; i < clipboardData . items . length ; i ++ ) {
401
+ const item = clipboardData . items [ i ]
402
+ if ( item . kind === 'file' && item . type . startsWith ( 'image/' ) ) {
403
+ const file = item . getAsFile ( )
404
+ if ( file ) {
405
+ files . push ( file )
406
+ }
407
+ }
408
+ }
409
+ } else if ( clipboardData . files && clipboardData . files . length ) {
410
+ for ( let i = 0 ; i < clipboardData . files . length ; i ++ ) {
411
+ const file = clipboardData . files [ i ]
412
+ if ( file . type . startsWith ( 'image/' ) ) {
413
+ files . push ( file )
414
+ }
415
+ }
416
+ }
417
+
418
+ if ( files . length ) {
419
+ if ( beforeUpload ) {
420
+ beforeUpload ( files ) . then ( ( f : Array < File > | boolean ) => {
421
+ if ( typeof f === 'boolean' ) return
422
+
423
+ const _files = filterFiles ( new Array < File > ( ) . slice . call ( f ) )
424
+ if ( _files . length ) {
425
+ readFile ( _files )
426
+ onChange ?.( [
427
+ ...fileList ,
428
+ ...files . map ( ( file ) => ( {
429
+ name : file . name ,
430
+ type : file . type ,
431
+ status : 'ready' ,
432
+ } ) ) ,
433
+ ] )
434
+ }
435
+ } )
436
+ } else {
437
+ const _files = filterFiles ( new Array < File > ( ) . slice . call ( files ) )
438
+ if ( _files . length ) {
439
+ readFile ( _files )
440
+ onChange ?.( [
441
+ ...fileList ,
442
+ ..._files . map ( ( file ) => ( {
443
+ name : file . name ,
444
+ type : file . type ,
445
+ status : 'ready' ,
446
+ } ) ) ,
447
+ ] )
448
+ }
449
+ }
450
+ }
451
+ } ,
452
+ [ enablePasteUpload , disabled , beforeUpload , filterFiles , readFile , onChange ]
453
+ )
454
+
455
+ useEffect ( ( ) => {
456
+ fileListRef . current = fileList
457
+
458
+ if ( enablePasteUpload ) {
459
+ document . addEventListener ( 'paste' , handlePaste )
460
+ }
461
+
462
+ return ( ) => {
463
+ if ( enablePasteUpload ) {
464
+ document . removeEventListener ( 'paste' , handlePaste )
465
+ }
466
+ }
467
+ } , [ fileList , enablePasteUpload , handlePaste ] )
468
+
386
469
return (
387
470
< div className = { classes } { ...restProps } >
388
471
{ ( children || previewType === 'list' ) && (
0 commit comments