Skip to content

Commit 149c818

Browse files
authored
FileUpload: dont create ul-tag if there are no files present (#1363)
1 parent a0d7ddf commit 149c818

File tree

2 files changed

+64
-57
lines changed

2 files changed

+64
-57
lines changed

.changeset/major-turkeys-join.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@obosbbl/grunnmuren-react": patch
3+
---
4+
5+
FileUpload: don't create ul-tag for files if there are no files added to file upload

packages/react/src/file-upload/file-upload.tsx

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)