- Upload by clicking
- Avatar
- Default Files
- Pictures Wall
- Complete control over file list
- Drag and Drop
- Upload directory
- Upload manually
- Upload png file only
- Pictures with list style
- Customize preview file
- Max Count
- Transform file before request
- Aliyun OSS
- custom action icon
- Drag sorting of uploadList
- Crop image before uploading
- Customize Progress Bar
- API
Upload
Upload file by selecting or dragging.
When To Use#
Uploading is the process of publishing information (web pages, text, pictures, video, etc.) to a remote server via a web page or upload tool.
When you need to upload one or more files.
When you need to show the process of uploading.
When you need to upload files by dragging and dropping.
Examples
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, message, Upload } from 'infrad';
import React from 'react';
const props: UploadProps = {
name: 'file',
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
headers: {
authorization: 'authorization-text',
},
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} file uploaded successfully`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
};
const App: React.FC = () => (
<Upload {...props}>
<Button icon={<IUpload />}>Click to Upload</Button>
</Upload>
);
export default App;
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, Upload } from 'infrad';
import React from 'react';
const props: UploadProps = {
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
onChange({ file, fileList }) {
if (file.status !== 'uploading') {
console.log(file, fileList);
}
},
defaultFileList: [
{
uid: '1',
name: 'xxx.png',
status: 'done',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/xxx.png',
},
{
uid: '2',
name: 'yyy.png',
status: 'done',
url: 'http://www.baidu.com/yyy.png',
},
{
uid: '3',
name: 'zzz.png',
status: 'error',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/zzz.png',
},
],
};
const App: React.FC = () => (
<Upload {...props}>
<Button icon={<IUpload />}>Upload</Button>
</Upload>
);
export default App;
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, Upload } from 'infrad';
import type { UploadFile } from 'infrad/es/upload/interface';
import React, { useState } from 'react';
const App: React.FC = () => {
const [fileList, setFileList] = useState<UploadFile[]>([
{
uid: '-1',
name: 'xxx.png',
status: 'done',
url: 'http://www.baidu.com/xxx.png',
},
]);
const handleChange: UploadProps['onChange'] = info => {
let newFileList = [...info.fileList];
// 1. Limit the number of uploaded files
// Only to show two recent uploaded files, and old ones will be replaced by the new
newFileList = fileList.slice(-2);
// 2. Read from response and show file link
newFileList = fileList.map(file => {
if (file.response) {
// Component will show file.url as link
file.url = file.response.url;
}
return file;
});
setFileList(newFileList);
};
const props = {
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
onChange: handleChange,
multiple: true,
};
return (
<Upload {...props} fileList={fileList}>
<Button icon={<IUpload />}>Upload</Button>
</Upload>
);
};
export default App;
import { IUpload } from 'infra-design-icons';
import { Button, Upload } from 'infrad';
import React from 'react';
const App: React.FC = () => (
<Upload action="https://www.mocky.io/v2/5cc8019d300000980a055e76" directory>
<Button icon={<IUpload />}>Upload Directory</Button>
</Upload>
);
export default App;
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, message, Upload } from 'infrad';
import React from 'react';
const props: UploadProps = {
beforeUpload: file => {
const isPNG = file.type === 'image/png';
if (!isPNG) {
message.error(`${file.name} is not a png file`);
}
return isPNG || Upload.LIST_IGNORE;
},
onChange: info => {
console.log(info.fileList);
},
};
const App: React.FC = () => (
<Upload {...props}>
<Button icon={<IUpload />}>Upload png only</Button>
</Upload>
);
export default App;
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, Upload } from 'infrad';
import React from 'react';
const props: UploadProps = {
action: '//jsonplaceholder.typicode.com/posts/',
listType: 'picture',
previewFile(file) {
console.log('Your upload file:', file);
// Your process logic. Here we just mock to the same file
return fetch('https://next.json-generator.com/api/json/get/4ytyBoLK8', {
method: 'POST',
body: file,
})
.then(res => res.json())
.then(({ thumbnail }) => thumbnail);
},
};
const App: React.FC = () => (
<Upload {...props}>
<Button icon={<IUpload />}>Upload</Button>
</Upload>
);
export default App;
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, Upload } from 'infrad';
import React from 'react';
const props: UploadProps = {
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
listType: 'picture',
beforeUpload(file) {
return new Promise(resolve => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const img = document.createElement('img');
img.src = reader.result as string;
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d')!;
ctx.drawImage(img, 0, 0);
ctx.fillStyle = 'red';
ctx.textBaseline = 'middle';
ctx.font = '33px Arial';
ctx.fillText('Infra Design', 20, 20);
canvas.toBlob(result => resolve(result as any));
};
};
});
},
};
const App: React.FC = () => (
<Upload {...props}>
<Button icon={<IUpload />}>Upload</Button>
</Upload>
);
export default App;
import { IUpload, StarOutlined } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, Upload } from 'infrad';
import React from 'react';
const props: UploadProps = {
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
onChange({ file, fileList }) {
if (file.status !== 'uploading') {
console.log(file, fileList);
}
},
defaultFileList: [
{
uid: '1',
name: 'xxx.png',
status: 'done',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/xxx.png',
},
{
uid: '2',
name: 'yyy.png',
status: 'done',
url: 'http://www.baidu.com/yyy.png',
},
{
uid: '3',
name: 'zzz.png',
status: 'error',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/zzz.png',
},
],
showUploadList: {
showDownloadIcon: true,
downloadIcon: 'Download',
showRemoveIcon: true,
removeIcon: <StarOutlined onClick={e => console.log(e, 'custom removeIcon event')} />,
},
};
const App: React.FC = () => (
<Upload {...props}>
<Button icon={<IUpload />}>Upload</Button>
</Upload>
);
export default App;
import ImgCrop from 'antd-img-crop';
import { Upload } from 'infrad';
import type { RcFile, UploadFile, UploadProps } from 'infrad/es/upload/interface';
import React, { useState } from 'react';
const App: React.FC = () => {
const [fileList, setFileList] = useState<UploadFile[]>([
{
uid: '-1',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
]);
const onChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
setFileList(newFileList);
};
const onPreview = async (file: UploadFile) => {
let src = file.url as string;
if (!src) {
src = await new Promise(resolve => {
const reader = new FileReader();
reader.readAsDataURL(file.originFileObj as RcFile);
reader.onload = () => resolve(reader.result as string);
});
}
const image = new Image();
image.src = src;
const imgWindow = window.open(src);
imgWindow?.document.write(image.outerHTML);
};
return (
<ImgCrop rotate>
<Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
listType="picture-card"
fileList={fileList}
onChange={onChange}
onPreview={onPreview}
>
{fileList.length < 5 && '+ Upload'}
</Upload>
</ImgCrop>
);
};
export default App;
import { LoadingOutlined, PlusOutlined } from 'infra-design-icons';
import { message, Upload } from 'infrad';
import type { UploadChangeParam } from 'infrad/es/upload';
import type { RcFile, UploadFile, UploadProps } from 'infrad/es/upload/interface';
import React, { useState } from 'react';
const getBase64 = (img: RcFile, callback: (url: string) => void) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result as string));
reader.readAsDataURL(img);
};
const beforeUpload = (file: RcFile) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('You can only upload JPG/PNG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
};
const App: React.FC = () => {
const [loading, setLoading] = useState(false);
const [imageUrl, setImageUrl] = useState<string>();
const handleChange: UploadProps['onChange'] = (info: UploadChangeParam<UploadFile>) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj as RcFile, url => {
setLoading(false);
setImageUrl(url);
});
}
};
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
return (
<Upload
name="avatar"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
beforeUpload={beforeUpload}
onChange={handleChange}
>
{imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
</Upload>
);
};
export default App;
import { PlusOutlined } from 'infra-design-icons';
import { Modal, Upload } from 'infrad';
import type { RcFile, UploadProps } from 'infrad/es/upload';
import type { UploadFile } from 'infrad/es/upload/interface';
import React, { useState } from 'react';
const getBase64 = (file: RcFile): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = error => reject(error);
});
const App: React.FC = () => {
const [previewVisible, setPreviewVisible] = useState(false);
const [previewImage, setPreviewImage] = useState('');
const [previewTitle, setPreviewTitle] = useState('');
const [fileList, setFileList] = useState<UploadFile[]>([
{
uid: '-1',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-2',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-3',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-4',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-xxx',
percent: 50,
name: 'image.png',
status: 'uploading',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-5',
name: 'image.png',
status: 'error',
},
]);
const handleCancel = () => setPreviewVisible(false);
const handlePreview = async (file: UploadFile) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj as RcFile);
}
setPreviewImage(file.url || (file.preview as string));
setPreviewVisible(true);
setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1));
};
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) =>
setFileList(newFileList);
const uploadButton = (
<div>
<PlusOutlined />
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
return (
<>
<Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
listType="picture-card"
fileList={fileList}
onPreview={handlePreview}
onChange={handleChange}
>
{fileList.length >= 8 ? null : uploadButton}
</Upload>
<Modal visible={previewVisible} title={previewTitle} footer={null} onCancel={handleCancel}>
<img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal>
</>
);
};
export default App;
Click or drag file to this area to upload
Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files
import { IUploadCloud } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { message, Upload } from 'infrad';
import React from 'react';
const { Dragger } = Upload;
const props: UploadProps = {
name: 'file',
multiple: true,
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
onChange(info) {
const { status } = info.file;
if (status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`);
} else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
onDrop(e) {
console.log('Dropped files', e.dataTransfer.files);
},
};
const App: React.FC = () => (
<Dragger {...props}>
<p className="ant-upload-drag-icon">
<IUploadCloud />
</p>
<p className="ant-upload-text">Click or drag file to this area to upload</p>
<p className="ant-upload-hint">
Support for a single or bulk upload. Strictly prohibit from uploading company data or other
band files
</p>
</Dragger>
);
export default App;
import { IUpload } from 'infra-design-icons';
import { Button, message, Upload } from 'infrad';
import type { RcFile, UploadFile, UploadProps } from 'infrad/es/upload/interface';
import React, { useState } from 'react';
const App: React.FC = () => {
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [uploading, setUploading] = useState(false);
const handleUpload = () => {
const formData = new FormData();
fileList.forEach(file => {
formData.append('files[]', file as RcFile);
});
setUploading(true);
// You can use any AJAX library you like
fetch('https://www.mocky.io/v2/5cc8019d300000980a055e76', {
method: 'POST',
body: formData,
})
.then(res => res.json())
.then(() => {
setFileList([]);
message.success('upload successfully.');
})
.catch(() => {
message.error('upload failed.');
})
.finally(() => {
setUploading(false);
});
};
const props: UploadProps = {
onRemove: file => {
const index = fileList.indexOf(file);
const newFileList = fileList.slice();
newFileList.splice(index, 1);
setFileList(newFileList);
},
beforeUpload: file => {
setFileList([...fileList, file]);
return false;
},
fileList,
};
return (
<>
<Upload {...props}>
<Button icon={<IUpload />}>Select File</Button>
</Upload>
<Button
type="primary"
onClick={handleUpload}
disabled={fileList.length === 0}
loading={uploading}
style={{ marginTop: 16 }}
>
{uploading ? 'Uploading' : 'Start Upload'}
</Button>
</>
);
};
export default App;
import { IUpload } from 'infra-design-icons';
import { Button, Upload } from 'infrad';
import type { UploadFile } from 'infrad/es/upload/interface';
import React from 'react';
const fileList: UploadFile[] = [
{
uid: '-1',
name: 'xxx.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-2',
name: 'yyy.png',
status: 'error',
},
];
const App: React.FC = () => (
<>
<Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
listType="picture"
defaultFileList={[...fileList]}
>
<Button icon={<IUpload />}>Upload</Button>
</Upload>
<br />
<br />
<Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
listType="picture"
defaultFileList={[...fileList]}
className="upload-list-inline"
>
<Button icon={<IUpload />}>Upload</Button>
</Upload>
</>
);
export default App;
/* tile uploaded pictures */
.upload-list-inline .ant-upload-list-item {
float: left;
width: 200px;
margin-right: 8px;
}
.upload-list-inline [class*='-upload-list-rtl'] .ant-upload-list-item {
float: right;
}
import { IUpload } from 'infra-design-icons';
import { Button, Space, Upload } from 'infrad';
import React from 'react';
const App: React.FC = () => (
<Space direction="vertical" style={{ width: '100%' }} size="large">
<Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
listType="picture"
maxCount={1}
>
<Button icon={<IUpload />}>Upload (Max: 1)</Button>
</Upload>
<Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
listType="picture"
maxCount={3}
multiple
>
<Button icon={<IUpload />}>Upload (Max: 3)</Button>
</Upload>
</Space>
);
export default App;
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, Form, message, Upload } from 'infrad';
import type { UploadFile } from 'infrad/es/upload/interface';
import React, { useEffect, useState } from 'react';
interface OSSDataType {
dir: string;
expire: string;
host: string;
accessId: string;
policy: string;
signature: string;
}
interface AliyunOSSUploadProps {
value?: UploadFile[];
onChange?: (fileList: UploadFile[]) => void;
}
const AliyunOSSUpload = ({ value, onChange }: AliyunOSSUploadProps) => {
const [OSSData, setOSSData] = useState<OSSDataType>();
// Mock get OSS api
// https://help.aliyun.com/document_detail/31988.html
const mockGetOSSData = () => ({
dir: 'user-dir/',
expire: '1577811661',
host: '//www.mocky.io/v2/5cc8019d300000980a055e76',
accessId: 'c2hhb2RhaG9uZw==',
policy: 'eGl4aWhhaGFrdWt1ZGFkYQ==',
signature: 'ZGFob25nc2hhbw==',
});
const init = async () => {
try {
const result = await mockGetOSSData();
setOSSData(result);
} catch (error) {
message.error(error);
}
};
useEffect(() => {
init();
}, []);
const handleChange: UploadProps['onChange'] = ({ fileList }) => {
console.log('Aliyun OSS:', fileList);
onChange?.([...fileList]);
};
const onRemove = (file: UploadFile) => {
const files = (value || []).filter(v => v.url !== file.url);
if (onChange) {
onChange(files);
}
};
const getExtraData: UploadProps['data'] = file => ({
key: file.url,
OSSAccessKeyId: OSSData?.accessId,
policy: OSSData?.policy,
Signature: OSSData?.signature,
});
const beforeUpload: UploadProps['beforeUpload'] = async file => {
if (!OSSData) return false;
const expire = Number(OSSData.expire) * 1000;
if (expire < Date.now()) {
await init();
}
const suffix = file.name.slice(file.name.lastIndexOf('.'));
const filename = Date.now() + suffix;
// @ts-ignore
file.url = OSSData.dir + filename;
return file;
};
const uploadProps: UploadProps = {
name: 'file',
fileList: value,
action: OSSData?.host,
onChange: handleChange,
onRemove,
data: getExtraData,
beforeUpload,
};
return (
<Upload {...uploadProps}>
<Button icon={<IUpload />}>Click to Upload</Button>
</Upload>
);
};
const App: React.FC = () => (
<Form labelCol={{ span: 4 }}>
<Form.Item label="Photos" name="photos">
<AliyunOSSUpload />
</Form.Item>
</Form>
);
export default App;
import update from 'immutability-helper';
import { IUpload } from 'infra-design-icons';
import { Button, Tooltip, Upload } from 'infrad';
import type { UploadFile, UploadProps } from 'infrad/es/upload/interface';
import React, { useCallback, useRef, useState } from 'react';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
const type = 'DragableUploadList';
interface DragableUploadListItemProps {
originNode: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
file: UploadFile;
fileList: UploadFile[];
moveRow: (dragIndex: any, hoverIndex: any) => void;
}
const DragableUploadListItem = ({
originNode,
moveRow,
file,
fileList,
}: DragableUploadListItemProps) => {
const ref = useRef<HTMLDivElement>(null);
const index = fileList.indexOf(file);
const [{ isOver, dropClassName }, drop] = useDrop({
accept: type,
collect: monitor => {
const { index: dragIndex } = monitor.getItem() || {};
if (dragIndex === index) {
return {};
}
return {
isOver: monitor.isOver(),
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
};
},
drop: (item: any) => {
moveRow(item.index, index);
},
});
const [, drag] = useDrag({
type,
item: { index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
});
drop(drag(ref));
const errorNode = <Tooltip title="Upload Error">{originNode.props.children}</Tooltip>;
return (
<div
ref={ref}
className={`ant-upload-draggable-list-item ${isOver ? dropClassName : ''}`}
style={{ cursor: 'move' }}
>
{file.status === 'error' ? errorNode : originNode}
</div>
);
};
const App: React.FC = () => {
const [fileList, setFileList] = useState<UploadFile[]>([
{
uid: '-1',
name: 'image1.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-2',
name: 'image2.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-3',
name: 'image3.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-4',
name: 'image4.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-5',
name: 'image.png',
status: 'error',
},
]);
const moveRow = useCallback(
(dragIndex: number, hoverIndex: number) => {
const dragRow = fileList[dragIndex];
setFileList(
update(fileList, {
$splice: [
[dragIndex, 1],
[hoverIndex, 0, dragRow],
],
}),
);
},
[fileList],
);
const onChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
setFileList(newFileList);
};
return (
<DndProvider backend={HTML5Backend}>
<Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
fileList={fileList}
onChange={onChange}
itemRender={(originNode, file, currFileList) => (
<DragableUploadListItem
originNode={originNode}
file={file}
fileList={currFileList}
moveRow={moveRow}
/>
)}
>
<Button icon={<IUpload />}>Click to Upload</Button>
</Upload>
</DndProvider>
);
};
export default App;
#components-upload-demo-drag-sorting .ant-upload-draggable-list-item {
border-top: 2px dashed rgba(0, 0, 0, 0);
border-bottom: 2px dashed rgba(0, 0, 0, 0);
}
#components-upload-demo-drag-sorting .ant-upload-draggable-list-item.drop-over-downward {
border-bottom-color: #2673dd;
}
#components-upload-demo-drag-sorting .ant-upload-draggable-list-item.drop-over-upward {
border-top-color: #2673dd;
}
import { IUpload } from 'infra-design-icons';
import type { UploadProps } from 'infrad';
import { Button, message, Upload } from 'infrad';
import React from 'react';
const props: UploadProps = {
name: 'file',
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
headers: {
authorization: 'authorization-text',
},
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} file uploaded successfully`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
progress: {
strokeColor: {
'0%': '#108ee9',
'100%': '#87d068',
},
strokeWidth: 3,
format: percent => percent && `${parseFloat(percent.toFixed(2))}%`,
},
};
const App: React.FC = () => (
<Upload {...props}>
<Button icon={<IUpload />}>Click to Upload</Button>
</Upload>
);
export default App;
API#
Property | Description | Type | Default | Version |
---|---|---|---|---|
accept | File types that can be accepted. See input accept Attribute | string | - | |
action | Uploading URL | string | (file) => Promise<string> | - | |
beforeUpload | Hook function which will be executed before uploading. Uploading will be stopped with false or a rejected Promise returned. When returned value is Upload.LIST_IGNORE , the list of files that have been uploaded will ignore it. Warning:this function is not supported in IE9 | (file, fileList) => boolean | Promise<File> | Upload.LIST_IGNORE | - | |
customRequest | Override for the default xhr behavior allowing for additional customization and ability to implement your own XMLHttpRequest | function | - | |
data | Uploading extra params or function which can return uploading extra params | object | (file) => object | Promise<object> | - | |
defaultFileList | Default list of files that have been uploaded | object[] | - | |
directory | Support upload whole directory (caniuse) | boolean | false | |
disabled | Disable upload button | boolean | false | |
fileList | List of files that have been uploaded (controlled). Here is a common issue #2423 when using it | UploadFile[] | - | |
headers | Set request headers, valid above IE10 | object | - | |
iconRender | Custom show icon | (file: UploadFile, listType?: UploadListType) => ReactNode | - | |
isImageUrl | Customize if render <img /> in thumbnail | (file: UploadFile) => boolean | (inside implementation) | |
itemRender | Custom item of uploadList | (originNode: ReactElement, file: UploadFile, fileList: object[], actions: { download: function, preview: function, remove: function }) => React.ReactNode | - | 4.16.0 |
listType | Built-in stylesheets, support for three types: text , picture or picture-card | string | text | |
maxCount | Limit the number of uploaded files. Will replace current one when maxCount is 1 | number | - | 4.10.0 |
method | The http method of upload request | string | post | |
multiple | Whether to support selected multiple file. IE10+ supported. You can select multiple files with CTRL holding down while multiple is set to be true | boolean | false | |
name | The name of uploading file | string | file | |
openFileDialogOnClick | Click open file dialog | boolean | true | |
previewFile | Customize preview file logic | (file: File | Blob) => Promise<dataURL: string> | - | |
progress | Custom progress bar | ProgressProps (support type="line" only) | { strokeWidth: 2, showInfo: false } | 4.3.0 |
showUploadList | Whether to show default upload list, could be an object to specify showPreviewIcon , showRemoveIcon , showDownloadIcon , removeIcon and downloadIcon individually | boolean | { showPreviewIcon?: boolean, showDownloadIcon?: boolean, showRemoveIcon?: boolean, previewIcon?: ReactNode | (file: UploadFile) => ReactNode, removeIcon?: ReactNode | (file: UploadFile) => ReactNode, downloadIcon?: ReactNode | (file: UploadFile) => ReactNode } | true | function: 4.7.0 |
withCredentials | The ajax upload with cookie sent | boolean | false | |
onChange | A callback function, can be executed when uploading state is changing, see onChange | function | - | |
onDrop | A callback function executed when files are dragged and dropped into upload area | (event: React.DragEvent) => void | - | 4.16.0 |
onDownload | Click the method to download the file, pass the method to perform the method logic, do not pass the default jump to the new TAB | function(file): void | (Jump to new TAB) | |
onPreview | A callback function, will be executed when file link or preview icon is clicked | function(file) | - | |
onRemove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is false or a Promise which resolve(false) or reject | function(file): boolean | Promise | - |
UploadFile#
Extends File with additional props.
Property | Description | Type | Default | Version |
---|---|---|---|---|
crossOrigin | CORS settings attributes | 'anonymous' | 'use-credentials' | '' | - | 4.20.0 |
name | File name | string | - | - |
percent | Upload progress percent | number | - | - |
status | Upload status. Show different style when configured | error | success | done | uploading | - | - |
thumbUrl | Thumb image url | string | - | - |
uid | unique id. Will auto generate when not provided | string | - | - |
url | Download url | string | - | - |
onChange#
The function will be called when uploading is in progress, completed or failed.
When uploading state change, it returns:
{
file: { /* ... */ },
fileList: [ /* ... */ ],
event: { /* ... */ },
}
file
File object for the current operation.{ uid: 'uid', // unique identifier, negative is recommend, to prevent interference with internal generated id name: 'xx.png', // file name status: 'done', // options:uploading, done, error. Intercepted file by beforeUpload don't have status field. response: '{"status": "success"}', // response from server linkProps: '{"download": "image"}', // additional html props of file link xhr: 'XMLHttpRequest{ ... }', // XMLHttpRequest Header }
fileList
current list of filesevent
response from server, including uploading progress, supported by advanced browsers.
FAQ#
How do I implement upload server side?#
You can consult jQuery-File-Upload about how to implement server side upload interface.
There is a mock example of express in rc-upload.
I want to display download links.#
Please set property url
of each item in fileList
to control content of link.
How to use customRequest
?#
See https://github.com/react-component/upload#customrequest.
Why will the fileList
that's in control not trigger onChange
status
update when the file is not in the list?#
onChange
will only trigger when the file is in the list, it will ignore any events removed from the list. Please note that there does exist a bug which makes an event still trigger even when the file is not in the list before 4.13.0
.
Why does onChange
sometimes return File object and other times return { originFileObj: File }?#
For compatible case, we return File object when beforeUpload
return false
. It will merge to { originFileObj: File }
in next major version. Current version is compatible to get origin file by info.file.originFileObj
. You can change this before major release.
Why sometime Chrome can not upload?#
Chrome update will also break native upload. Please restart chrome to finish the upload work. Ref: