Skip to content

Upload Components

Upload components handle file uploads with drag-and-drop, preview, validation, and progress tracking.

Circular avatar upload for profile photos.

interface UploadAvatarProps {
file: File | string | null;
onDrop: (acceptedFiles: File[]) => void;
helperText?: string;
error?: boolean;
disabled?: boolean;
sx?: SxProps;
}

Simple box-style upload area.

interface UploadBoxProps {
placeholder?: ReactNode;
error?: boolean;
disabled?: boolean;
file?: File | string;
onDrop: (files: File[]) => void;
onDelete?: () => void;
sx?: SxProps;
}

Advanced upload with multiple files, preview grid, and file management.

interface UploadProps {
multiple?: boolean;
files: (File | string)[];
onDrop: (acceptedFiles: File[]) => void;
onRemove?: (file: File | string) => void;
onRemoveAll?: () => void;
helperText?: ReactNode;
error?: boolean;
disabled?: boolean;
}
import { UploadAvatar } from 'src/components/upload';
function ProfilePhotoUpload() {
const [file, setFile] = useState<File | null>(null);
const handleDrop = (acceptedFiles: File[]) => {
const uploadedFile = acceptedFiles[0];
if (uploadedFile) {
setFile(uploadedFile);
}
};
return (
<UploadAvatar
file={file}
onDrop={handleDrop}
helperText="Allowed *.jpeg, *.jpg, *.png (max 5 MB)"
/>
);
}
import { UploadBox } from 'src/components/upload';
function ItemImageUpload() {
const [image, setImage] = useState<File | null>(null);
const handleDrop = (files: File[]) => {
setImage(files[0]);
};
return (
<UploadBox
file={image}
onDrop={handleDrop}
onDelete={() => setImage(null)}
placeholder={
<Box>
<Icon icon="ic:baseline-cloud-upload" />
<Typography>Drop image here or click to browse</Typography>
</Box>
}
/>
);
}
import { Upload } from 'src/components/upload';
function MultipleFileUpload() {
const [files, setFiles] = useState<File[]>([]);
const handleDrop = (acceptedFiles: File[]) => {
setFiles((prev) => [...prev, ...acceptedFiles]);
};
const handleRemove = (file: File) => {
setFiles((prev) => prev.filter((f) => f !== file));
};
return (
<Upload
multiple
files={files}
onDrop={handleDrop}
onRemove={handleRemove}
onRemoveAll={() => setFiles([])}
/>
);
}
  • Drag-and-drop: Uses react-dropzone for file drag-and-drop
  • Validation: File type and size validation before upload
  • Preview: Automatic image preview with URL.createObjectURL
  • Accessibility: Keyboard navigation and screen reader support
it('should handle file drop', async () => {
const onDrop = jest.fn();
render(<UploadBox onDrop={onDrop} />);
const file = new File(['hello'], 'hello.png', { type: 'image/png' });
const input = screen.getByLabelText(/upload/i);
await userEvent.upload(input, file);
expect(onDrop).toHaveBeenCalledWith([file]);
});