Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 62 additions & 92 deletions src/components/FileUpload/FileMultiUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ const FileUploadTitle = styled(Title)<{ $isNotSupported: boolean }>`
: theme.click.fileUpload.color.title.default};
`;

const FileUploadDescription = styled(Text)`
const FileUploadDescription = styled(Text)<{ $isError?: boolean }>`
font: ${({ theme }) => theme.click.fileUpload.typography.description.default};
color: ${({ theme }) => theme.click.fileUpload.color.description.default};
color: ${({ theme, $isError }) =>
$isError
? theme.click.fileUpload.color.title.error
: theme.click.fileUpload.color.description.default};
`;

const UploadIcon = styled(Icon)`
Expand Down Expand Up @@ -118,20 +121,6 @@ const DocumentIcon = styled(Icon)`
}
`;

const FileInfoHeader = styled.div`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.click.fileUpload.sm.space.gap};
width: 100%;
`;

const FileInfo = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.click.fileUpload.hasFile.header.space.gap};
flex: 1;
`;

const FileDetails = styled.div`
display: flex;
gap: ${({ theme }) => theme.click.fileUpload.md.space.gap};
Expand All @@ -145,23 +134,17 @@ const FileActions = styled.div`
gap: 0;
`;

const ProgressContainer = styled.div`
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
`;

const ProgressBarContainer = styled.div`
width: 100%;
const FileContentContainer = styled.div`
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 24px;
`;

const ProgressPercentage = styled(Text)`
min-width: ${({ theme }) => theme.sizes[10]};
text-align: right;
padding-right: ${({ theme }) => theme.click.fileUpload.md.space.gap};
const ProgressBarWrapper = styled.div`
margin-top: 8px;
margin-bottom: 4px;
`;

const formatFileSize = (sizeInBytes: number): string => {
Expand Down Expand Up @@ -376,71 +359,58 @@ export const FileMultiUpload = ({
key={file.id}
$isError={file.status === "error"}
>
<FileInfo>
<FileInfoHeader>
<DocumentIcon name={"document"} />
<FileDetails>
<Text size={"md"}>{truncateFilename(file.name)}</Text>
{(file.status === "success" || file.status === "uploading") && (
<Text
size={"md"}
color={"muted"}
>
{formatFileSize(file.size)}
</Text>
)}
{file.status === "error" && (
<Text
size={"md"}
color={"danger"}
>
{file.errorMessage || "Upload failed"}
</Text>
)}
{file.status === "success" && (
<Icon
size={"xs"}
state={"success"}
name={"check"}
/>
)}
</FileDetails>

<FileActions>
{file.status === "error" && (
<IconButton
size={"sm"}
icon={"refresh"}
type={"ghost"}
onClick={() => handleRetryUpload(file.id)}
/>
)}
<IconButton
size={"sm"}
icon={"cross"}
type={"ghost"}
onClick={() => handleRemoveFile(file.id)}
<DocumentIcon name={"document"} />
<FileContentContainer>
<FileDetails>
<FileUploadDescription>
{truncateFilename(file.name)}
</FileUploadDescription>
{file.status === "uploading" && (
<FileUploadDescription>{file.progress}%</FileUploadDescription>
)}
{file.status === "error" && (
<FileUploadDescription $isError>
{file.errorMessage || "Upload failed"}
</FileUploadDescription>
)}
{file.status === "success" && (
<Icon
size={"xs"}
state={"success"}
name={"check"}
/>
</FileActions>
</FileInfoHeader>

)}
</FileDetails>
{file.status === "uploading" && (
<ProgressContainer>
<ProgressBarContainer>
<ProgressBar
progress={file.progress}
type={"small"}
/>
</ProgressBarContainer>
<ProgressPercentage
size={"sm"}
color={"muted"}
>
{file.progress}%
</ProgressPercentage>
</ProgressContainer>
<ProgressBarWrapper>
<ProgressBar
progress={file.progress}
type={"small"}
/>
</ProgressBarWrapper>
)}
{(file.status === "success" || file.status === "error") && (
<FileUploadDescription>
{formatFileSize(file.size)}
</FileUploadDescription>
)}
</FileContentContainer>
<FileActions>
{file.status === "error" && (
<IconButton
size={"sm"}
icon={"refresh"}
type={"ghost"}
onClick={() => handleRetryUpload(file.id)}
/>
)}
</FileInfo>
<IconButton
size={"sm"}
icon={"cross"}
type={"ghost"}
onClick={() => handleRemoveFile(file.id)}
/>
</FileActions>
</FileItem>
))}
</FilesList>
Expand Down
130 changes: 54 additions & 76 deletions src/components/FileUpload/FileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ const UploadArea = styled.div<{
$hasFile || $size === "sm"
? `${theme.click.fileUpload.sm.space.y} ${theme.click.fileUpload.sm.space.x}`
: `${theme.click.fileUpload.md.space.y} ${theme.click.fileUpload.md.space.x}`};
min-height: ${({ theme, $size }) =>
$size === "sm"
? `calc(${theme.click.fileUpload.sm.space.y} * 2 + ${theme.sizes[6]})`
: "auto"};
display: flex;
flex-direction: ${props =>
props.$hasFile ? "row" : props.$size === "sm" ? "row" : "column"};
Expand Down Expand Up @@ -86,16 +90,19 @@ const FileUploadTitle = styled(Title)<{ $isNotSupported: boolean }>`
: theme.click.fileUpload.color.title.default};
`;

const FileUploadDescription = styled(Text)`
const FileUploadDescription = styled(Text)<{ $isError?: boolean }>`
font: ${({ theme }) => theme.click.fileUpload.typography.description.default};
color: ${({ theme }) => theme.click.fileUpload.color.description.default};
color: ${({ theme, $isError }) =>
$isError
? theme.click.fileUpload.color.title.error
: theme.click.fileUpload.color.description.default};
`;

const DocumentIcon = styled(Icon)`
svg {
width: ${({ theme }) => theme.click.fileUpload.sm.icon.size.width};
height: ${({ theme }) => theme.click.fileUpload.sm.icon.size.height};
color: ${({ theme }) => theme.click.fileUpload.sm.color.icon.default};
width: ${({ theme }) => theme.click.fileUpload.md.icon.size.width};
height: ${({ theme }) => theme.click.fileUpload.md.icon.size.height};
color: ${({ theme }) => theme.click.fileUpload.md.color.icon.default};
}
`;

Expand Down Expand Up @@ -126,18 +133,10 @@ const UploadText = styled.div<{ $size: "sm" | "md"; $hasFile: boolean }>`
`}
`;

const FileInfoHeader = styled.div`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.click.fileUpload.sm.space.gap};
width: 100%;
`;

const FileInfo = styled.div`
display: flex;
flex-direction: column;
flex-direction: row;
gap: ${({ theme }) => theme.click.fileUpload.hasFile.header.space.gap};
flex: 1;
`;

const FileDetails = styled.div`
Expand All @@ -153,23 +152,17 @@ const FileActions = styled.div`
gap: 0;
`;

const ProgressContainer = styled.div`
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
`;

const ProgressBarContainer = styled.div`
width: 100%;
const FileContentContainer = styled.div<{ $size: "sm" | "md" }>`
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
min-height: ${({ $size }) => ($size === "sm" ? "24px" : "auto")};
`;

const ProgressPercentage = styled(Text)`
min-width: ${({ theme }) => theme.sizes[10]};
text-align: right;
padding-right: ${({ theme }) => theme.click.fileUpload.md.space.gap};
const ProgressBarWrapper = styled.div`
margin-top: 8px;
margin-bottom: 4px;
`;

const formatFileSize = (sizeInBytes: number): string => {
Expand Down Expand Up @@ -393,26 +386,18 @@ export const FileUpload = ({
</Button>
</>
) : (
<FileInfo>
<FileInfoHeader>
<DocumentIcon name={"document"} />
<>
<DocumentIcon name={"document"} />
<FileContentContainer $size={size}>
<FileDetails>
<Text size={"md"}>{truncateFilename(file.name)}</Text>
{(showSuccess || showProgress) && (
<Text
size={"md"}
color={"muted"}
>
{formatFileSize(file.size)}
</Text>
<FileUploadDescription>
{truncateFilename(file.name)}
</FileUploadDescription>
{showProgress && !showSuccess && (
<FileUploadDescription>{progress}%</FileUploadDescription>
)}
{!showProgress && !showSuccess && (
<Text
size={"md"}
color={"danger"}
>
{failureMessage}
</Text>
<FileUploadDescription $isError>{failureMessage}</FileUploadDescription>
)}
{showSuccess && (
<Icon
Expand All @@ -422,42 +407,35 @@ export const FileUpload = ({
/>
)}
</FileDetails>

<FileActions>
{!showProgress && !showSuccess && (
<IconButton
size={"sm"}
icon={"refresh"}
type={"ghost"}
onClick={handleRetryUpload}
/>
)}
<IconButton
size={"sm"}
icon={"cross"}
type={"ghost"}
onClick={handleRemoveFile}
/>
</FileActions>
</FileInfoHeader>

{showProgress && (
<ProgressContainer>
<ProgressBarContainer>
{showProgress && !showSuccess && (
<ProgressBarWrapper>
<ProgressBar
progress={progress}
type={"small"}
/>
</ProgressBarContainer>
<ProgressPercentage
</ProgressBarWrapper>
)}
{(showSuccess || (!showProgress && !showSuccess)) && (
<FileUploadDescription>{formatFileSize(file.size)}</FileUploadDescription>
)}
</FileContentContainer>
<FileActions>
{!showProgress && !showSuccess && (
<IconButton
size={"sm"}
color={"muted"}
>
{progress}%
</ProgressPercentage>
</ProgressContainer>
)}
</FileInfo>
icon={"refresh"}
type={"ghost"}
onClick={handleRetryUpload}
/>
)}
<IconButton
size={"sm"}
icon={"cross"}
type={"ghost"}
onClick={handleRemoveFile}
/>
</FileActions>
</>
)}
</UploadArea>

Expand Down