Skip to documentation
UI

Upload

Headless file picker trigger with a hidden input, drag-and-drop dragger, and accept/maxCount filtering.

import { Upload } from '@lobehub/ui/base-ui';
Data Entry

Basic

Loading preview

APIs

Upload properties
accept
string
beforeUpload
(file: File, fileList: File[]) => boolean | Promise<boolean | void> | void
description
null | string | number | bigint | false | true | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<AwaitedReactNode>
directory
boolean
disabled
boolean
dragger
boolean
maxCount
number
multiple
boolean
onChange
(info: UploadChangeInfo) => void
onFiles
(files: File[]) => void
openFileDialogOnClick
boolean

Defaults to true.

ref
null | (instance: HTMLElement | null) => void | (() => VoidOrUndefinedOnly) | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES] | RefObject<HTMLElement | null>

Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref).

title
null | string | number | bigint | false | true | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<AwaitedReactNode>

Also accepts all native HTML and ARIA attributes.

Upload renders a native <span> (or a <div> when dragger is set). All standard HTML attributes including className, style, data-*, and ref are forwarded to the root element.

Migrating from antd Upload

Upload has no file list, no XHR uploader, and no progress UI — it only manages the hidden <input type="file">, drag-and-drop, and accept/maxCount filtering, then hands you the accepted File[].

import { Upload } from '@lobehub/ui/base-ui';

<Upload
  accept="image/*"
  beforeUpload={(file) => file.size < 1024 * 1024}
  onFiles={(files) => console.log(files)}
>
  <button type="button">Upload file</button>
</Upload>;

beforeUpload keeps antd's (file, fileList) => boolean | Promise<boolean | void> | void signature — returning (or resolving) false drops that file; returning Upload.LIST_IGNORE or a replacement File is not supported. onFiles fires once with the accepted files after beforeUpload filtering and the maxCount slice; onChange fires once per accepted file with { file, fileList }. maxCount is applied after beforeUpload filtering.

Replace <Upload.Dragger> with <Upload dragger>, or use the UploadDragger convenience component exported alongside Upload (a drop-in rename for Upload.Dragger):

import { UploadDragger } from '@lobehub/ui/base-ui';

<UploadDragger accept="image/*" description="Support for a single upload" onFiles={console.log} />;