@miaopazzz/react-upload
v0.1.4
Published
基于 React、Tailwind CSS 4、shadcn 风格的上传组件(裁剪/多文件/粘贴导入),提取自项目内可复用组件
Maintainers
Readme
@miaopazzz/react-upload
基于 React + Tailwind CSS 4 + Radix(shadcn 风格) 的上传组件集合,支持:
- 拖拽/点击选择文件
- 单文件与多文件模式
- 图片裁剪(基于 Cropper.js)
- 剪贴板导入图片(右键菜单或快捷键粘贴)
- 文件类型与提示信息展示
安装与依赖
安装(稳定版):
# npm
npm i @miaopazzz/react-upload@latest
# 或 pnpm / yarn
pnpm add @miaopazzz/react-upload@latest
yarn add @miaopazzz/react-upload@latest本包为自用组件,要求宿主项目已安装并配置以下依赖(peerDependencies):
- react、react-dom(>=18)
- react-dropzone
- react-cropper、cropperjs(裁剪功能)
- lucide-react(图标,仅少量使用)
- sonner(消息提示)
- tailwind-merge、clsx、class-variance-authority、@radix-ui/react-*(UI 基座)
样式:请在应用入口引入 Cropper 的样式
import 'cropperjs/dist/cropper.css';
// (推荐)引入本包独立样式,保障未扫描包源码时的 UI 一致性
import '@miaopazzz/react-upload/styles.css';快速使用
import { ImageCropUploader } from '@miaopazzz/react-upload';
// 单文件(默认启用裁剪)
<ImageCropUploader
value={fileList}
onChange={setFileList}
inputName="avatar"
accept={{ 'image/*': [] }}
cropSize={{ width: 800, height: 800 }}
maxSize={2 * 1024 * 1024}
/>
// 多文件(不裁剪)
<ImageCropUploader
value={files}
onChange={setFiles}
multiple
// 不限制类型:去掉 accept 或传 undefined
accept={undefined}
// 不限制大小(按需):
maxSize={Number.POSITIVE_INFINITY}
/>多文件“异步队列上传”(推荐)
import { QueueImageUploader } from '@miaopazzz/react-upload';
// 选择即入队,组件内部并发上传(XHR),带进度/状态
<QueueImageUploader
inputName="images"
endpoint={'/upload'}
// 每个文件的额外字段(FormData):
extraFields={() => ({ key: 'value' })}
concurrency={3}
// 进度样式(可选):使用宿主 Tailwind 类(若确保被扫描生成)
progressClasses={{ container: 'h-1 bg-muted rounded-full', bar: 'bg-primary' }}
onAllDone={() => console.log('all done')}
/> 说明:
QueueImageUploader负责并发队列、XHR 上传、CSRF 头注入、进度/状态渲染;页面仅传endpoint/extraFields/concurrency等配置。- 进度条默认采用 CSS 变量颜色(无需 Tailwind 支持),若希望使用 Tailwind 类可通过
progressClasses传入。
行为说明(重要)
- 裁剪模式跳过大小限制(单文件模式):
- 当
enableCrop=true且传入的是可裁剪图片时,组件会直接进入裁剪流程,并“忽略maxSize限制”。 - 原因:裁剪会在前端重新导出较低质量/尺寸的图片,最终提交的文件体积通常远小于原图,因此无需在选择阶段拦截。
- 若未启用裁剪或文件并非可裁剪图片,则按
maxSize常规校验。
- 当
- 多文件模式不支持裁剪:
- 保持简单直观,支持文件列表展示与移除;如需限制类型或大小,可通过
accept / maxSize控制。
- 保持简单直观,支持文件列表展示与移除;如需限制类型或大小,可通过
队列上传 vs 表单同步提交
ImageCropUploader:只负责“选择/预览/裁剪”,不发网络请求。常用于“表单同步提交”场景。QueueImageUploader:组件内“选择即入队并上传”,一次多个文件,失败不影响其他文件,带进度/完成回调。
主要 Props
value: FileList | null、onChange(next: FileList | null):受控文件状态multiple?: boolean:是否启用多文件模式(默认 false)enableCrop?: boolean:单文件模式下是否启用裁剪(默认 true)accept?: Accept:同 react-dropzone 的acceptmaxSize?: number:单文件/多文件的大小限制(字节)。单文件+裁剪时会被跳过。cropSize?: { width: number; height: number }:裁剪目标参考尺寸(影响提示与裁剪比例)initialUrl?: string:编辑场景下的已有图片地址inputName?: string:用于表单提交的隐藏input[type=file]名称
QueueImageUploader Props(多文件异步队列)
endpoint: string | (file) => string:单文件上传 JSON 接口地址(或按文件决定端点)。method?: 'POST'|'PUT'|'PATCH':HTTP 方法(默认POST)。headers?: Record<string,string>:额外请求头;组件会自动注入X-CSRF-TOKEN(从 Cookie 读取)与X-Requested-With。extraFields?: (file) => Record<string,string|Blob>:每个文件的额外 FormData 字段(如is_homepage)。concurrency?: number:并发数(默认 3)。accept?: Accept、maxSize?: number、hints?:与ImageCropUploader类似。onAllDone?: () => void:全部文件状态为success时触发。progressClasses?: { container?: string; bar?: string }:进度条容器/条自定义类名(可使用宿主 Tailwind 类)。
进度条主题(CSS 变量)
- 默认使用以下 CSS 变量(无需 Tailwind 也能显示):
--ru-progress-bg(容器背景,默认回退到--muted)--ru-progress-fg(进度颜色,默认回退到--primary)
- 可在宿主项目主题中覆盖:
:root {
--ru-progress-bg: oklch(0.92 0 0);
--ru-progress-fg: oklch(0.65 0.12 240);
}许可证
MIT
