For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/components/upload.md.

Upload 文件上传

选择或拖拽文件,查看上传进度。

选择与校验

图片、PDF 或文本 · 最多 5 个文件,每个不超过 5 MB
basic.tsx
import { Space, Upload } from '@ifhover/leaf-ui';

export function UploadBasic() {
  return (
    <Space direction="vertical" align="stretch">
      <Upload
        multiple
        accept="image/*,.pdf,.txt"
        maxCount={5}
        maxSize={5 * 1024 * 1024}
        hint="图片、PDF 或文本 · 最多 5 个文件,每个不超过 5 MB"
      />
    </Space>
  );
}

拖拽、进度与取消

此示例在本地模拟上传进度,使用 action 或 customRequest 接入实际上传服务。
advanced.tsx
import type { UploadRequest } from '@ifhover/leaf-ui';

import { Space, Text, Upload } from '@ifhover/leaf-ui';

const demoRequest = ({ signal, onProgress }: UploadRequest) =>
  new Promise<void>((resolve, reject) => {
    let percent = 0;
    const cleanup = () => {
      clearInterval(timer);
      signal.removeEventListener('abort', abort);
    };
    const abort = () => {
      cleanup();
      reject(new DOMException('Aborted', 'AbortError'));
    };
    const timer = setInterval(() => {
      percent += 12;
      onProgress(percent);
      if (percent >= 100) {
        cleanup();
        resolve();
      }
    }, 180);
    signal.addEventListener('abort', abort, { once: true });
    if (signal.aborted) abort();
  });

export function UploadDrag() {
  return (
    <Space direction="vertical" align="stretch">
      <Text tone="muted">
        此示例在本地模拟上传进度,使用 action 或 customRequest 接入实际上传服务。
      </Text>
      <Upload
        drag
        multiple
        accept="image/*"
        maxCount={4}
        customRequest={demoRequest}
        hint="仅限图片 · 支持取消与重试"
      />
    </Space>
  );
}

使用说明

未配置 action 或 customRequest 时只选择文件,保持待上传状态,可由业务统一提交。action 使用 XMLHttpRequest 报告进度:POST 发送 FormData,PUT 发送文件本身。JSON 响应可提供 url 和 name;customRequest 可返回相同字段。选择和拖拽共用校验,上传支持取消、移除与重试;自定义请求须响应 signal。移除或卸载会取消请求并释放本地预览 URL。服务端仍需进行文件校验。

类型

import type { UploadProps, UploadFile, UploadChangeInfo, UploadRejection, UploadRequest, UploadResult, FileItem } from '@ifhover/leaf-ui';

手动上传与图片卡片

capabilities.tsx
import { Button, Space, Upload, type UploadHandle } from '@ifhover/leaf-ui';

import { useRef } from 'react';

export function Capabilities() {
  const upload = useRef<UploadHandle>(null);
  return (
    <Space direction="vertical" align="stretch">
      <Upload
        ref={upload}
        autoUpload={false}
        concurrency={2}
        multiple
        accept="image/*"
        listType="picture-card"
        paste
        customRequest={async (request) => {
          await new Promise<void>((resolve, reject) => {
            const timer = setTimeout(resolve, 700);
            request.signal.addEventListener(
              'abort',
              () => {
                clearTimeout(timer);
                reject(request.signal.reason);
              },
              { once: true },
            );
          });
          return {};
        }}
      />
      <Space>
        <Button onClick={() => upload.current?.upload()}>
          {'开始上传'}
        </Button>
        <Button variant="outline" onClick={() => upload.current?.abort()}>
          {'取消上传'}
        </Button>
      </Space>
    </Space>
  );
}

UploadProps API

属性类型默认值说明
fileListreadonly UploadFile[][]受控 / 初始文件列表
defaultFileListreadonly UploadFile[][]受控 / 初始文件列表
onChange(files: UploadFile[], info: UploadChangeInfo) => void—列表及上传状态变化
acceptstring—允许的 MIME 或后缀,如 image/*,.pdf
multiplebooleanfalse多文件选择 / 禁用 / 拖拽区域
disabledbooleanfalse禁用交互。
dragbooleanfalse多文件选择 / 禁用 / 拖拽区域
maxCountnumber—允许的文件总数
maxSizenumber—单个文件最大字节数
beforeUpload(file: File) => boolean | File | Promise<boolean | File>—上传前校验,false 拒绝,File 可转换文件
onReject(rejections: readonly UploadRejection[]) => void—格式、大小、数量或校验拒绝
actionstring | ((file: File) => string | Promise<string>)—上传地址,未配置时只选择文件
method'POST' | 'PUT''POST'POST 使用 FormData,PUT 上传文件本身
headersReadonly<Record<string, string>>—请求头
dataReadonly<Record<string, string | Blob>>—POST 的额外表单数据
withCredentialsbooleanfalse跨域发送凭证
fieldNamestring'file'POST 中的文件字段名
customRequest(request: UploadRequest) => Promise<UploadResult | void>—自定义异步上传,配合 signal 取消
onRemove(file: UploadFile) => boolean | void | Promise<boolean> | Promise<void>—移除前回调,返回 false 保留文件
showFileListbooleantrue展示文件列表
hintReactNode—提示 / 选择按钮或拖拽区域标题
childrenReactNode—提示 / 选择按钮或拖拽区域标题
namestring—原生 FormData 中的字段名。
formstring—关联的原生表单 ID。
requiredboolean—要求整体值非空,复合控件只校验一次。
autoUploadbooleantrue文件校验通过后自动开始;false 时用 ref.upload()。
concurrencynumber3同时进行的上传请求数。
directoryboolean—选择目录及其文件;依赖浏览器的目录选择能力。
pasteboolean—接收剪贴板中的文件。
listType'text' | 'picture' | 'picture-card''text'文件列表的展示形式。

UploadFile API

继承 FileItem,并增加以下字段。

属性类型默认值说明
uidstring必填必需。唯一标识
urlstring—设置 url。
namestring—原生 FormData 中的字段名。
sizenumber—展示尺寸。
typestring—设置 type。
status'ready' | 'uploading' | 'done' | 'error' | 'cancelled'—设置 status。
percentnumber—完成百分比。
errorstring—设置 error。
originFileglobalThis.File—设置 originFile。
responseunknown—服务端返回的数据

UploadChangeInfo API

属性类型默认值说明
fileUploadFile—本次变化的文件
reason'add' | 'progress' | 'success' | 'error' | 'remove' | 'cancel'必填必需。变化原因

UploadRejection API

属性类型默认值说明
fileFile必填必需。被拒绝的文件
reason'type' | 'size' | 'count' | 'validation'必填必需。拒绝原因
messagestring必填必需。用户可读的说明

UploadRequest API

属性类型默认值说明
fileFile必填必需。待上传文件
signalAbortSignal必填必需。取消信号,移除或卸载也会取消
onProgress(percent: number) => void必填必需。报告上传进度

UploadResult API

属性类型默认值说明
urlstring—上传后的地址 / 名称
namestring—上传后的地址 / 名称
responseunknown—保留业务响应

FileItem API

属性类型默认值说明
uidstring—稳定标识,建议提供
urlstring—文件地址
namestring—文件名称,默认取 URL 的文件名
sizenumber—字节数,可不提供;未提供时不显示大小
typestring—MIME 类型,未提供时根据扩展名识别
status'ready' | 'uploading' | 'done' | 'error' | 'cancelled'—上传状态,可不提供
percentnumber—上传进度 0–100
errorstring—失败说明
originFileFile—浏览器选择的原始文件

UploadHandle

属性类型默认值说明
upload(uid?: string) => void—必需。开始指定文件或所有待处理文件的上传。
abort(uid?: string) => void—必需。取消指定文件或所有上传。
focus() => void—必需。聚焦控件。