@@ -272,66 +272,68 @@ const FileUpload = ({
272272 { children }
273273 </ FileTrigger >
274274 </ Provider >
275- < ul className = "mt-4 grid gap-y-2" >
276- { controlledOrUncontrolledFiles . map ( ( file , fileIndex ) => {
277- let fileName = file . name ;
278- if (
279- fileTriggerProps . acceptDirectory &&
280- file . webkitRelativePath !== ''
281- ) {
282- fileName = file . webkitRelativePath ;
283- }
284-
285- const validation = validate ?.( file ) ?? true ;
286- const hasError = validation !== true ;
287-
288- return (
289- < li key = { fileName } >
290- < div
291- className = { cx (
292- 'flex items-center justify-between gap-2 rounded-lg border-2 px-4 py-2' ,
293- hasError
294- ? 'border-red bg-red-light'
295- : 'border-gray bg-gray-lightest' ,
296- ) }
297- >
298- { fileName } { ' ' }
299- < button
275+ { controlledOrUncontrolledFiles . length > 0 && (
276+ < ul className = "mt-4 grid gap-y-2" >
277+ { controlledOrUncontrolledFiles . map ( ( file , fileIndex ) => {
278+ let fileName = file . name ;
279+ if (
280+ fileTriggerProps . acceptDirectory &&
281+ file . webkitRelativePath !== ''
282+ ) {
283+ fileName = file . webkitRelativePath ;
284+ }
285+
286+ const validation = validate ?.( file ) ?? true ;
287+ const hasError = validation !== true ;
288+
289+ return (
290+ < li key = { fileName } >
291+ < div
300292 className = { cx (
301- '-m-2 grid h-11 w-11 shrink-0 cursor-pointer place-items-center rounded-xl' ,
302- // Focus styles
303- 'focus-visible:-outline-offset-8 focus-visible:outline-focus' ,
293+ 'flex items-center justify-between gap-2 rounded-lg border-2 px-4 py-2' ,
294+ hasError
295+ ? 'border-red bg-red-light'
296+ : 'border-gray bg-gray-lightest' ,
304297 ) }
305- onClick = { ( ) => {
306- // For controlled component
307- onChange ?.( ( prevFiles ) =>
308- prevFiles . filter ( ( _ , index ) => index !== fileIndex ) ,
309- ) ;
310-
311- // For internal file state
312- setFiles ( ( prevFiles ) =>
313- prevFiles . filter ( ( _ , index ) => index !== fileIndex ) ,
314- ) ;
315-
316- // Make sure screen readers doesn't loose track of focus
317- // (without this, the focus will be set to the top of the page for screen readers)
318- buttonRef . current ?. focus ( ) ;
319- } }
320- aria-label = { translations . remove [ locale ] }
321- type = "button"
322298 >
323- < Trash />
324- </ button >
325- </ div >
326- { hasError && (
327- < ErrorMessage className = "mt-1 block w-full" >
328- { validation }
329- </ ErrorMessage >
330- ) }
331- </ li >
332- ) ;
333- } ) }
334- </ ul >
299+ { fileName } { ' ' }
300+ < button
301+ className = { cx (
302+ '-m-2 grid h-11 w-11 shrink-0 cursor-pointer place-items-center rounded-xl' ,
303+ // Focus styles
304+ 'focus-visible:-outline-offset-8 focus-visible:outline-focus' ,
305+ ) }
306+ onClick = { ( ) => {
307+ // For controlled component
308+ onChange ?.( ( prevFiles ) =>
309+ prevFiles . filter ( ( _ , index ) => index !== fileIndex ) ,
310+ ) ;
311+
312+ // For internal file state
313+ setFiles ( ( prevFiles ) =>
314+ prevFiles . filter ( ( _ , index ) => index !== fileIndex ) ,
315+ ) ;
316+
317+ // Make sure screen readers doesn't loose track of focus
318+ // (without this, the focus will be set to the top of the page for screen readers)
319+ buttonRef . current ?. focus ( ) ;
320+ } }
321+ aria-label = { translations . remove [ locale ] }
322+ type = "button"
323+ >
324+ < Trash />
325+ </ button >
326+ </ div >
327+ { hasError && (
328+ < ErrorMessage className = "mt-1 block w-full" >
329+ { validation }
330+ </ ErrorMessage >
331+ ) }
332+ </ li >
333+ ) ;
334+ } ) }
335+ </ ul >
336+ ) }
335337 { /*
336338 This is necessary since we want to display individual errors for each file based on the validate prop.
337339 But the FieldErrorContext is used to display the general error message for the entire component
0 commit comments