11import type { DId } from '../../utils/types' ;
22import type { DFormControl } from '../form' ;
3+ import type { DUploadListPrivateProps } from './UploadList' ;
34
4- import { isNull , isNumber } from 'lodash' ;
5+ import { isNumber } from 'lodash' ;
56import React , { useRef } from 'react' ;
67
78import { useForkRef , useUnmount } from '@react-devui/hooks' ;
@@ -11,10 +12,8 @@ import { useDValue } from '../../hooks';
1112import { registerComponentMate } from '../../utils' ;
1213import { useFormControl } from '../form' ;
1314import { useComponentConfig , usePrefixConfig } from '../root' ;
14- import { DList } from './List' ;
15- import { DPicture } from './Picture' ;
16- import { DPictureList } from './PictureList' ;
1715import { DUploadAction } from './UploadAction' ;
16+ import { DUploadList } from './UploadList' ;
1817import { DUploadPictureButton } from './UploadPictureButton' ;
1918
2019export type DUploadFileStatus = 'load' | 'error' | 'progress' | null ;
@@ -31,26 +30,22 @@ export interface DUploadFile {
3130 [ index : string | symbol ] : any ;
3231}
3332
34- export interface DUploadProps extends React . InputHTMLAttributes < HTMLInputElement > {
35- children : React . ReactElement | null ;
33+ export interface DUploadProps extends Omit < React . InputHTMLAttributes < HTMLInputElement > , 'children' > {
34+ children ?: ( nodes : { trigger : React . ReactNode ; list : React . ReactNode } ) => React . ReactNode ;
3635 dFormControl ?: DFormControl ;
3736 dModel ?: DUploadFile [ ] ;
38- dXHRRequest : {
37+ dTrigger ?: React . ReactElement ;
38+ dList ?: React . ReactElement ;
39+ dXHRRequest ?: {
3940 method ?: string ;
4041 url : string | URL ;
4142 responseType ?: XMLHttpRequestResponseType ;
4243 header ?: { [ index : string ] : string } ;
4344 body ?: ( file : string | Blob ) => Document | XMLHttpRequestBodyInit | null | undefined ;
4445 custom ?: ( xhr : XMLHttpRequest ) => void ;
4546 } ;
46- dListType ?: 'list' | 'picture' | 'picture-list' | false ;
4747 dDrag ?: boolean ;
4848 dMax ?: number ;
49- dDefaultActions ?: {
50- preview ?: ( file : DUploadFile ) => void ;
51- download ?: ( file : DUploadFile ) => void ;
52- } ;
53- dActions ?: ( file : DUploadFile , index : number ) => React . ReactNode [ ] ;
5449 dCustomUpload ?: ( files : FileList ) => void ;
5550 dBeforeUpload ?: ( file : File , files : FileList ) => boolean | string | Blob | Promise < boolean | string | Blob > ;
5651 onModelChange ?: (
@@ -69,12 +64,11 @@ function Upload(props: DUploadProps, ref: React.ForwardedRef<HTMLInputElement>):
6964 children,
7065 dFormControl,
7166 dModel,
67+ dTrigger,
68+ dList,
7269 dXHRRequest,
73- dListType = 'list' ,
7470 dDrag = false ,
7571 dMax,
76- dDefaultActions,
77- dActions,
7872 dCustomUpload,
7973 dBeforeUpload,
8074 onModelChange,
@@ -197,7 +191,7 @@ function Upload(props: DUploadProps, ref: React.ForwardedRef<HTMLInputElement>):
197191 return formData ;
198192 } ,
199193 custom,
200- } = dXHRRequest ;
194+ } = dXHRRequest ! ;
201195
202196 xhr . open ( method , url ) ;
203197 xhr . responseType = responseType ;
@@ -235,65 +229,49 @@ function Upload(props: DUploadProps, ref: React.ForwardedRef<HTMLInputElement>):
235229 }
236230 } ;
237231
238- const child = ( ( ) => {
239- if ( isNull ( children ) ) {
240- return children ;
241- }
242-
243- let dragProps : React . HTMLAttributes < HTMLElement > = { } ;
244- if ( dDrag ) {
245- dragProps = {
246- onDragEnter : ( e ) => {
247- children . props . onDragEnter ?.( e ) ;
248-
249- e . stopPropagation ( ) ;
250- e . preventDefault ( ) ;
251- } ,
252- onDragOver : ( e ) => {
253- children . props . onDragOver ?.( e ) ;
254-
255- e . stopPropagation ( ) ;
256- e . preventDefault ( ) ;
257- } ,
258- onDrop : ( e ) => {
259- children . props . onDrop ?.( e ) ;
232+ const trigger = ( ( ) => {
233+ if ( dTrigger ) {
234+ let dragProps : React . HTMLAttributes < HTMLElement > = { } ;
235+ if ( dDrag ) {
236+ dragProps = {
237+ onDragEnter : ( e ) => {
238+ dTrigger . props . onDragEnter ?.( e ) ;
239+
240+ e . stopPropagation ( ) ;
241+ e . preventDefault ( ) ;
242+ } ,
243+ onDragOver : ( e ) => {
244+ dTrigger . props . onDragOver ?.( e ) ;
245+
246+ e . stopPropagation ( ) ;
247+ e . preventDefault ( ) ;
248+ } ,
249+ onDrop : ( e ) => {
250+ dTrigger . props . onDrop ?.( e ) ;
251+
252+ e . stopPropagation ( ) ;
253+ e . preventDefault ( ) ;
254+
255+ const dt = e . dataTransfer ;
256+ const files = dt . files ;
257+ handleFiles ( files ) ;
258+ } ,
259+ } ;
260+ }
260261
261- e . stopPropagation ( ) ;
262- e . preventDefault ( ) ;
262+ return React . cloneElement < React . HTMLAttributes < HTMLElement > > ( dTrigger , {
263+ ...dragProps ,
264+ onClick : ( e ) => {
265+ dTrigger . props . onClick ?.( e ) ;
263266
264- const dt = e . dataTransfer ;
265- const files = dt . files ;
266- handleFiles ( files ) ;
267+ if ( inputRef . current ) {
268+ inputRef . current . click ( ) ;
269+ }
267270 } ,
268- } ;
271+ } ) ;
269272 }
270-
271- return React . cloneElement < React . HTMLAttributes < HTMLElement > > ( children , {
272- ...dragProps ,
273- onClick : ( e ) => {
274- children . props . onClick ?.( e ) ;
275-
276- if ( inputRef . current ) {
277- inputRef . current . click ( ) ;
278- }
279- } ,
280- } ) ;
281273 } ) ( ) ;
282274
283- const listProps = {
284- dFileList : fileList ,
285- dDefaultActions,
286- onRemove : ( file : DUploadFile ) => {
287- onRemove ?.( file ) ;
288-
289- const newList = changeFileList ( ( draft ) => {
290- const index = draft . findIndex ( ( f ) => f . uid === file . uid ) ;
291- draft . splice ( index , 1 ) ;
292- } ) ;
293- onModelChange ?.( newList , { type : 'remove' , files : [ file ] } ) ;
294- } ,
295- } ;
296-
297275 return (
298276 < >
299277 < input
@@ -312,32 +290,34 @@ function Upload(props: DUploadProps, ref: React.ForwardedRef<HTMLInputElement>):
312290 e . currentTarget . value = '' ;
313291 } }
314292 > </ input >
315- { dListType === 'list' ? (
316- < >
317- { child }
318- < DList { ... listProps } dActions = { dActions ?? ( ( ) => [ < DUploadAction dPreset = "remove" /> ] ) } > </ DList >
319- </ >
320- ) : dListType === 'picture' ? (
321- < DPicture { ... listProps } dActions = { dActions ?? ( ( ) => [ < DUploadAction dPreset = "preview" /> , < DUploadAction dPreset = "remove" /> ] ) } >
322- { child }
323- </ DPicture >
324- ) : dListType === 'picture-list' ? (
325- < >
326- { child }
327- < DPictureList { ... listProps } dActions = { dActions ?? ( ( ) => [ < DUploadAction dPreset = "remove" /> ] ) } > </ DPictureList >
328- </ >
329- ) : (
330- child
331- ) }
293+ { children ?. ( {
294+ trigger ,
295+ list :
296+ dList &&
297+ React . cloneElement < DUploadListPrivateProps > ( dList , {
298+ __fileList : fileList ,
299+ __onRemove ( file ) {
300+ onRemove ?. ( file ) ;
301+
302+ const newList = changeFileList ( ( draft ) => {
303+ const index = draft . findIndex ( ( f ) => f . uid === file . uid ) ;
304+ draft . splice ( index , 1 ) ;
305+ } ) ;
306+ onModelChange ?. ( newList , { type : 'remove' , files : [ file ] } ) ;
307+ } ,
308+ } ) ,
309+ } ) }
332310 </ >
333311 ) ;
334312}
335313
336314export const DUpload : {
337315 ( props : DUploadProps & React . RefAttributes < HTMLInputElement > ) : ReturnType < typeof Upload > ;
338316 Action : typeof DUploadAction ;
317+ List : typeof DUploadList ;
339318 PictureButton : typeof DUploadPictureButton ;
340319} = React . forwardRef ( Upload ) as any ;
341320
342321DUpload . Action = DUploadAction ;
322+ DUpload . List = DUploadList ;
343323DUpload . PictureButton = DUploadPictureButton ;
0 commit comments