Skip to main content

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. Supports action / customRequest / beforeUpload for 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

TokenValueUsage
--Radius_55pxDropzone / FileItem border radius
--Spacing_44pxFile list gap, status icon gap
--Spacing_88pxFileItem padding, meta info gap
--Spacing_1616pxDropzone-to-file-list gap
--Spacing_2424pxContent-to-action gap

Color Tokens

TokenValueUsage
--Labels-Secondary#3d3d3dFile name, hint text
--Labels-Tertiary#757575File size, status text
--Labels-Link#0066cc"Click" link in compact mode
--Grays-Gray_1#ebebebDrag hover background
--Grays-Gray_2#d6d6d6Progress bar track
--Grays-Gray_7#333333Progress bar indicator
--Status-Destructive#ff503fFailed status icon

Props

PropTypeDefaultDescription
fileListUploadFile[]Controlled file list
defaultFileListUploadFile[][]Default file list (uncontrolled)
actionstring | ((file: File) => Promise<string>)Upload URL
customRequest(option: UploadRequestOption) => { abort }Custom upload handler
headersRecord<string, string>Custom request headers
dataRecord | ((file) => Record)Extra upload data
namestring'file'File field name
methodstring'POST'HTTP method
withCredentialsbooleanSend cookies with request
acceptstringFile input accept attribute
multiplebooleantrueAllow multiple files
maxCountnumberMax number of files
beforeUpload(file, fileList) => boolean | File | PromisePre-upload hook; return false to reject
onChange(info: { file, fileList }) => voidStatus change callback
onRemove(file) => boolean | Promise<boolean>Remove callback; return false to block
onDrop(e: DragEvent) => voidDrag drop callback
hintReactNode'Click or drag files to upload'Dropzone hint text
iconReactNodeCloudUploadIconDropzone icon; pass null to hide
descriptionReactNodeAdditional description (formats, limits)
disabledbooleanfalseDisable interactions
classNamestringAdditional class names

UploadFile

FieldTypeDescription
uidstringUnique identifier
namestringFile name
sizenumberFile size in bytes
status'uploading' | 'error' | 'done'Upload status
percentnumberUpload progress (0–100)
responseunknownServer response
originFileFileOriginal File object