@spaced-out/ui-design-system
Version:
Sense UI components library
140 lines (124 loc) • 3.68 kB
Flow
// @flow strict
import * as React from 'react';
import classify from '../../../utils/classify';
import {ClickableIcon, CloseIcon, Icon} from '../../Icon';
import {LinearLoader} from '../../LinearLoader';
import {Truncate} from '../../Truncate';
import type {FileObject} from '../FileUpload';
import css from '../FileUpload.module.css';
type ClassNames = $ReadOnly<{
wrapper?: string,
}>;
export type FileBlockProps = {
classNames?: ClassNames,
fileObject: FileObject,
onFileRefreshClick?: (file: FileObject) => mixed,
handleFileClear?: (id: string) => mixed,
};
export const FileBlock: React$AbstractComponent<
FileBlockProps,
HTMLDivElement,
> = React.forwardRef<FileBlockProps, HTMLDivElement>(
(
{
classNames,
fileObject,
onFileRefreshClick,
handleFileClear,
}: FileBlockProps,
ref,
): React.Node => (
<>
<div className={classify(css.file, classNames?.wrapper)} ref={ref}>
<div className={css.fileInfo}>
<div className={css.fileNameBlock}>
<div className={css.icon}>
<FileStatusIcon fileObject={fileObject} />
</div>
<div className={css.fileName}>
<Truncate>{fileObject.file.name}</Truncate>
</div>
</div>
{fileObject.success &&
!!fileObject.successMessage &&
!fileObject.progress && (
<div className={css.fileSuccess}>
<Truncate>{fileObject.successMessage}</Truncate>
</div>
)}
{fileObject.reject &&
!!fileObject.rejectReason &&
!fileObject.progress && (
<div className={css.fileError}>
<Truncate>{fileObject.rejectReason}</Truncate>
</div>
)}
{!!fileObject.progress && (
<div className={css.progress}>
<LinearLoader
size="small"
value={
fileObject.progress === 'indeterminate'
? 0
: fileObject.progress
}
indeterminate={fileObject.progress === 'indeterminate'}
></LinearLoader>
</div>
)}
</div>
<div className={css.rightSection}>
{fileObject.showReUpload && (
<div className={css.rightBlock}>
<ClickableIcon
name="refresh"
size="small"
onClick={() => onFileRefreshClick?.(fileObject)}
/>
</div>
)}
<div className={css.rightBlock}>
<CloseIcon
size="small"
onClick={() => handleFileClear?.(fileObject.id)}
/>
</div>
</div>
</div>
</>
),
);
// This function returns the status of a file
const getFileStatus = (fileObject: FileObject) => {
if (fileObject.progress) {
return 'progress';
}
if (fileObject.success) {
return 'success';
}
if (fileObject.reject) {
return 'error';
}
return 'default';
};
// This component renders the status icon for a file
const FileStatusIcon = ({fileObject}: {fileObject: FileObject}) => {
const status = getFileStatus(fileObject);
switch (status) {
case 'progress':
return <Icon size="small" name="loader" color="tertiary" />;
case 'success':
return <Icon size="small" name="check" color="success" />;
case 'error':
return (
<Icon
size="small"
name="circle-exclamation"
color="danger"
type="solid"
/>
);
default:
return <Icon size="small" name="check" color="success" />;
}
};