@@ -5,6 +5,7 @@ import React, {
55 PropsWithChildren ,
66 useRef ,
77 useEffect ,
8+ useCallback ,
89} from 'react'
910import classNames from 'classnames'
1011import Taro , {
@@ -119,6 +120,7 @@ export interface UploaderProps extends BasicComponent {
119120 beforeXhrUpload ?: ( xhr : XMLHttpRequest , options : any ) => void
120121 beforeDelete ?: ( file : FileItem , files : FileItem [ ] ) => boolean
121122 onFileItemClick ?: ( file : FileItem , index : number ) => void
123+ enablePasteUpload ?: boolean
122124}
123125
124126const defaultProps = {
@@ -152,6 +154,7 @@ const defaultProps = {
152154 beforeDelete : ( file : FileItem , files : FileItem [ ] ) => {
153155 return true
154156 } ,
157+ enablePasteUpload : false ,
155158} as UploaderProps
156159
157160const InternalUploader : ForwardRefRenderFunction <
@@ -202,6 +205,7 @@ const InternalUploader: ForwardRefRenderFunction<
202205 beforeUpload,
203206 beforeXhrUpload,
204207 beforeDelete,
208+ enablePasteUpload,
205209 ...restProps
206210 } = { ...defaultProps , ...props }
207211 const [ fileList , setFileList ] = usePropsValue ( {
@@ -439,7 +443,7 @@ const InternalUploader: ForwardRefRenderFunction<
439443 setFileList ( [ ...fileList , ...results ] )
440444 }
441445
442- reader . readAsDataURL ( file as unknown as Blob )
446+ reader . readAsDataURL ( file . originalFileObj ?? ( file as unknown as Blob ) )
443447 } else {
444448 executeUpload ( fileItem , index )
445449 results . push ( fileItem )
@@ -520,6 +524,62 @@ const InternalUploader: ForwardRefRenderFunction<
520524 onFileItemClick ?.( file , index )
521525 }
522526
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+
523583 return (
524584 < div className = { classes } { ...restProps } >
525585 { ( children || previewType === 'list' ) && (
0 commit comments