Upload
- Component overview: Drag-and-drop upload area with built-in file upload support. Manages file queue with progress, status, and actions.
- Component group: Atomic
- Implementation: Pure design layer — no
ui/primitive. Supportsaction/customRequest/beforeUploadfor upload lifecycle (similar to antd Upload API). - Figma spec: Upload Drags (21244:1609)
Basic Usage
Empty dropzone — click or drag to select files. Provide action or customRequest to enable auto-upload.
Result
Loading...
Live Editor
const Demo = () => { const [fileList, setFileList] = React.useState([]); return ( <div style={{ maxWidth: 660 }}> <Upload hint="Click or drag audio files to upload" accept="audio/*,video/*" fileList={fileList} onChange={({ fileList: newList }) => setFileList(newList)} /> </div> ); }; render(<Demo />);
Files Queue
When files are selected, the dropzone collapses to a compact view with a file list below.
Result
Loading...
Live Editor
const Demo = () => { const [fileList, setFileList] = React.useState([ { uid: '1', name: 'Thoughts & approach', size: 5600000, status: 'uploading', percent: 57 }, { uid: '2', name: '02_22 PM Meeting April 22', size: 12400000, status: 'error' }, { uid: '3', name: '0820 PM Meeting', size: 3700000, status: 'done' }, ]); return ( <div style={{ maxWidth: 660 }}> <Upload hint="or drag audio files to upload" description={ <> Max file length: <strong>5 hrs.</strong> <br /> Supports audio/*, video/*, .rmvb, .rm, .divx, .ts, .m2ts, .3gp, .f4v, .asr. </> } fileList={fileList} onChange={({ fileList: newList }) => setFileList(newList)} /> </div> ); }; render(<Demo />);
Auto Upload
Provide action (URL) or customRequest to upload files automatically after selection.
Result
Loading...
Live Editor
const Demo = () => { const [fileList, setFileList] = React.useState([]); return ( <div style={{ maxWidth: 660 }}> <Upload hint="Click or drag audio files to upload" action="https://httpbin.org/post" fileList={fileList} onChange={({ file, fileList: newList }) => { setFileList(newList); }} /> </div> ); }; render(<Demo />);
Disabled
Result
Loading...
Live Editor
render( <div style={{ maxWidth: 660 }}> <Upload hint="Click or drag audio files to upload" disabled /> </div>, )
Custom Icon
Pass icon prop to replace the default cloud icon, or null to hide it.
Result
Loading...
Live Editor
render( <div style={{ maxWidth: 660 }}> <Upload icon={<span style={{ fontSize: 48 }}>📁</span>} hint="Drop files here" /> </div>, )
beforeUpload
Use beforeUpload to validate or transform files before upload. Return false to reject.
Result
Loading...
Live Editor
const Demo = () => { const [fileList, setFileList] = React.useState([]); return ( <div style={{ maxWidth: 660 }}> <Upload hint="Only files under 10MB" fileList={fileList} beforeUpload={(file) => { if (file.size > 10 * 1024 * 1024) { alert('File too large!'); return false; } return true; }} onChange={({ fileList: newList }) => setFileList(newList)} /> </div> ); }; render(<Demo />);
Size Tokens
| Token | Value | Usage |
|---|---|---|
--Radius_5 | 5px | Dropzone / FileItem border radius |
--Spacing_4 | 4px | File list gap, status icon gap |
--Spacing_8 | 8px | FileItem padding, meta info gap |
--Spacing_16 | 16px | Dropzone-to-file-list gap |
--Spacing_24 | 24px | Content-to-action gap |
Color Tokens
| Token | Value | Usage |
|---|---|---|
--Labels-Secondary | #3d3d3d | File name, hint text |
--Labels-Tertiary | #757575 | File size, status text |
--Labels-Link | #0066cc | "Click" link in compact mode |
--Grays-Gray_1 | #ebebeb | Drag hover background |
--Grays-Gray_2 | #d6d6d6 | Progress bar track |
--Grays-Gray_7 | #333333 | Progress bar indicator |
--Status-Destructive | #ff503f | Failed status icon |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
fileList | UploadFile[] | — | Controlled file list |
defaultFileList | UploadFile[] | [] | Default file list (uncontrolled) |
action | string | ((file: File) => Promise<string>) | — | Upload URL |
customRequest | (option: UploadRequestOption) => { abort } | — | Custom upload handler |
headers | Record<string, string> | — | Custom request headers |
data | Record | ((file) => Record) | — | Extra upload data |
name | string | 'file' | File field name |
method | string | 'POST' | HTTP method |
withCredentials | boolean | — | Send cookies with request |
accept | string | — | File input accept attribute |
multiple | boolean | true | Allow multiple files |
maxCount | number | — | Max number of files |
beforeUpload | (file, fileList) => boolean | File | Promise | — | Pre-upload hook; return false to reject |
onChange | (info: { file, fileList }) => void | — | Status change callback |
onRemove | (file) => boolean | Promise<boolean> | — | Remove callback; return false to block |
onDrop | (e: DragEvent) => void | — | Drag drop callback |
hint | ReactNode | 'Click or drag files to upload' | Dropzone hint text |
icon | ReactNode | CloudUploadIcon | Dropzone icon; pass null to hide |
description | ReactNode | — | Additional description (formats, limits) |
disabled | boolean | false | Disable interactions |
className | string | — | Additional class names |
UploadFile
| Field | Type | Description |
|---|---|---|
uid | string | Unique identifier |
name | string | File name |
size | number | File size in bytes |
status | 'uploading' | 'error' | 'done' | Upload status |
percent | number | Upload progress (0–100) |
response | unknown | Server response |
originFile | File | Original File object |