upload-pulse 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -0
- package/dist/components/upload/Dropzone.d.ts +19 -0
- package/dist/components/upload/FileTypeIcon.d.ts +6 -0
- package/dist/components/upload/MockUpload.d.ts +2 -0
- package/dist/components/upload/Picker.d.ts +2 -0
- package/dist/components/upload/Upload.d.ts +2 -0
- package/dist/components/upload/UploadActions.d.ts +11 -0
- package/dist/components/upload/UploadRequest.d.ts +2 -0
- package/dist/components/upload/config.d.ts +116 -0
- package/dist/components/upload/hooks/useMockUpload.d.ts +15 -0
- package/dist/components/upload/hooks/useUpload.d.ts +9 -0
- package/dist/components/upload/hooks/useUploadDisplay.d.ts +34 -0
- package/dist/components/upload/hooks/useUploadDragDrop.d.ts +22 -0
- package/dist/components/upload/hooks/useUploadPicker.d.ts +17 -0
- package/dist/components/upload/icons.d.ts +10 -0
- package/dist/components/upload/index.d.ts +26 -0
- package/dist/components/upload/interface.d.ts +237 -0
- package/dist/components/upload/utils/fileAccept.d.ts +10 -0
- package/dist/components/upload/utils/index.d.ts +3 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1088 -0
- package/dist/upload-pulse.css +3 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# upload-pulse
|
|
2
|
+
|
|
3
|
+
React 文件上传进度 UI 组件库:深色/浅色主题、拖拽投放、格式限制、多选与数量上限、XHR / Mock Hooks。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install upload-pulse
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Peer dependencies:** `react`、`react-dom`(>=18)
|
|
12
|
+
|
|
13
|
+
**样式:** 需配合 [Tailwind CSS v4](https://tailwindcss.com/) 使用。
|
|
14
|
+
|
|
15
|
+
## 快速开始
|
|
16
|
+
|
|
17
|
+
### 1. 引入样式
|
|
18
|
+
|
|
19
|
+
在应用入口 CSS 中:
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
@import 'tailwindcss';
|
|
23
|
+
@import 'upload-pulse/styles.css';
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`upload-pulse/styles.css` 已包含组件所需的 Tailwind utility 与动画,一般无需再 `@source` 扫描包内 JS。
|
|
27
|
+
|
|
28
|
+
若你自行从源码集成组件(非 npm 包),需确保 Tailwind 能扫描到组件目录,例如:
|
|
29
|
+
|
|
30
|
+
```css
|
|
31
|
+
@import 'tailwindcss';
|
|
32
|
+
@source "./node_modules/upload-pulse/dist/index.js";
|
|
33
|
+
@import 'upload-pulse/styles.css';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 2. 使用组件
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { Upload, UploadPicker, UploadWithUpload } from 'upload-pulse';
|
|
40
|
+
|
|
41
|
+
function App() {
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
<UploadPicker
|
|
45
|
+
config={{
|
|
46
|
+
accept: ['.xlsx', '.xls'],
|
|
47
|
+
multiple: true,
|
|
48
|
+
maxCount: 5,
|
|
49
|
+
showButton: true,
|
|
50
|
+
drag: { enabled: true, showDropzone: true },
|
|
51
|
+
}}
|
|
52
|
+
currentCount={0}
|
|
53
|
+
onFilesSelected={(files) => console.log(files)}
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<UploadWithUpload
|
|
57
|
+
file={file}
|
|
58
|
+
url="/api/upload"
|
|
59
|
+
config={{ theme: 'dark', pausable: false }}
|
|
60
|
+
onComplete={() => {}}
|
|
61
|
+
/>
|
|
62
|
+
</>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 导出
|
|
68
|
+
|
|
69
|
+
| 组件 / Hook | 说明 |
|
|
70
|
+
|-------------|------|
|
|
71
|
+
| `Upload` | 受控进度卡片 |
|
|
72
|
+
| `UploadPicker` | 选文件 + 拖拽 + 校验 |
|
|
73
|
+
| `UploadDropzone` | 拖拽投放区 |
|
|
74
|
+
| `UploadWithUpload` | XHR 上传封装 |
|
|
75
|
+
| `UploadWithMock` | Mock 演示 |
|
|
76
|
+
| `useUpload` | XHR Hook |
|
|
77
|
+
| `useUploadPicker` | 选文件校验 |
|
|
78
|
+
| `useUploadDragDrop` | 拖拽逻辑 |
|
|
79
|
+
| `useUploadDisplay` | 进度展示计算 |
|
|
80
|
+
|
|
81
|
+
类型与常量:`UploadConfig`、`UploadPickerConfig`、`DARK_THEME_COLORS`、`LIGHT_THEME_COLORS` 等。
|
|
82
|
+
|
|
83
|
+
## 本地开发
|
|
84
|
+
|
|
85
|
+
源码目录遵循 [Ant Design](https://github.com/ant-design/ant-design) 规范:`src/components/upload/` 下按组件分子目录,`interface.ts` 定义类型,`hooks/`、`style/`、`utils/` 分模块组织。
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install
|
|
89
|
+
npm run dev
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
浏览器会打开预览页,可直接体验 `UploadPicker` 与 `UploadWithMock` 的交互效果。修改 `src/` 下组件源码会热更新。
|
|
93
|
+
|
|
94
|
+
构建组件库:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npm run build
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
预览生产构建:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm run preview
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 发布
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm run build
|
|
110
|
+
npm publish --access public
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 在其他项目中链接本地包
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"dependencies": {
|
|
118
|
+
"upload-pulse": "file:../UploadPulse"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
安装后执行 `npm install`,用法与 npm 包相同。
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { UploadDropzoneLabels, UploadDropzoneStyle } from './interface';
|
|
2
|
+
interface UploadDropzoneProps {
|
|
3
|
+
disabled: boolean;
|
|
4
|
+
isDragging: boolean;
|
|
5
|
+
labels: Required<UploadDropzoneLabels>;
|
|
6
|
+
style: Required<UploadDropzoneStyle>;
|
|
7
|
+
dropHandlers: {
|
|
8
|
+
onDragEnter?: (event: React.DragEvent) => void;
|
|
9
|
+
onDragLeave?: (event: React.DragEvent) => void;
|
|
10
|
+
onDragOver?: (event: React.DragEvent) => void;
|
|
11
|
+
onDrop?: (event: React.DragEvent) => void;
|
|
12
|
+
};
|
|
13
|
+
onOpen: () => void;
|
|
14
|
+
className?: string;
|
|
15
|
+
/** 是否显示「或点击选择文件」提示,与独立按钮并存时可设为 false */
|
|
16
|
+
showClickHint?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function Dropzone({ disabled, isDragging, labels, style, dropHandlers, onOpen, className, showClickHint, }: UploadDropzoneProps): import("react").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { UploadProps } from './interface';
|
|
2
|
+
export declare function Upload({ file, status, progress, errorMessage, completedVariant, config, onPause, onResume, onCancel, onDelete, onChange, onDownload, onRetry, className, exiting, }: UploadProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { UploadCallbacks, UploadStatus } from './interface';
|
|
2
|
+
interface UploadActionsProps extends Pick<UploadCallbacks, 'onPause' | 'onResume' | 'onCancel' | 'onDelete' | 'onRetry'> {
|
|
3
|
+
status: UploadStatus;
|
|
4
|
+
pausable: boolean;
|
|
5
|
+
cancelable: boolean;
|
|
6
|
+
deletable: boolean;
|
|
7
|
+
retryable: boolean;
|
|
8
|
+
retryLabel: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function UploadActions({ status, pausable, cancelable, deletable, retryable, retryLabel, onPause, onResume, onCancel, onDelete, onRetry, }: UploadActionsProps): import("react").JSX.Element | null;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { UploadWithUploadProps } from './interface';
|
|
2
|
+
export declare function UploadRequest({ file, url, method, fieldName, headers, withCredentials, extraFields, completedVariant, config, onComplete, onError, onCancel, onDelete, onChange, onDownload, onRetry, className, }: UploadWithUploadProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { UploadConfig, UploadDropzoneLabels, UploadDropzoneStyle, UploadLabels, UploadPickerConfig, UploadPickerDragConfig, UploadPickerLabels, UploadTheme, UploadThemeColors } from './interface';
|
|
2
|
+
export declare const DARK_THEME_COLORS: Required<UploadThemeColors>;
|
|
3
|
+
export declare const LIGHT_THEME_COLORS: Required<UploadThemeColors>;
|
|
4
|
+
export declare const DEFAULT_UPLOAD_CONFIG: Required<Omit<UploadConfig, 'labels' | 'colors'>> & {
|
|
5
|
+
labels: Required<UploadLabels>;
|
|
6
|
+
colors: Required<UploadThemeColors>;
|
|
7
|
+
};
|
|
8
|
+
export declare const DEFAULT_PICKER_LABELS: Required<UploadPickerLabels>;
|
|
9
|
+
export declare const DEFAULT_DROPZONE_LABELS: Required<UploadDropzoneLabels>;
|
|
10
|
+
export declare const LIGHT_DROPZONE_STYLE: Required<UploadDropzoneStyle>;
|
|
11
|
+
export declare const DEFAULT_DROPZONE_STYLE: Required<UploadDropzoneStyle>;
|
|
12
|
+
export declare const DEFAULT_DRAG_CONFIG: Required<Omit<UploadPickerDragConfig, 'labels' | 'style'>> & {
|
|
13
|
+
labels: Required<UploadDropzoneLabels>;
|
|
14
|
+
style: Required<UploadDropzoneStyle>;
|
|
15
|
+
};
|
|
16
|
+
export declare const PICKER_BUTTON_CLASS: {
|
|
17
|
+
readonly dark: "cursor-pointer rounded-lg border border-gray-700 bg-neutral-800 px-4 py-2 text-[13px] text-gray-100 transition-colors duration-150 hover:bg-gray-700 disabled:cursor-not-allowed disabled:opacity-50";
|
|
18
|
+
readonly light: "cursor-pointer rounded-lg border border-gray-300 bg-white px-4 py-2 text-[13px] text-gray-900 transition-colors duration-150 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50";
|
|
19
|
+
};
|
|
20
|
+
export declare const DEFAULT_PICKER_CONFIG: Required<Omit<UploadPickerConfig, 'accept' | 'maxCount' | 'labels' | 'drag'>> & {
|
|
21
|
+
labels: Required<UploadPickerLabels>;
|
|
22
|
+
drag: typeof DEFAULT_DRAG_CONFIG;
|
|
23
|
+
};
|
|
24
|
+
export declare function resolveUploadConfig(config?: UploadConfig): {
|
|
25
|
+
theme: UploadTheme;
|
|
26
|
+
colors: {
|
|
27
|
+
cardBackground: string;
|
|
28
|
+
cardShadow: string;
|
|
29
|
+
fileName: string;
|
|
30
|
+
statusUploading: string;
|
|
31
|
+
statusPaused: string;
|
|
32
|
+
statusError: string;
|
|
33
|
+
statusCompleted: string;
|
|
34
|
+
metaMuted: string;
|
|
35
|
+
metaSeparator: string;
|
|
36
|
+
progressTrack: string;
|
|
37
|
+
progressBackground: string;
|
|
38
|
+
progressFill: string;
|
|
39
|
+
progressGlow: string;
|
|
40
|
+
iconButtonBackground: string;
|
|
41
|
+
iconButtonHover: string;
|
|
42
|
+
iconButtonText: string;
|
|
43
|
+
closeButtonText: string;
|
|
44
|
+
closeButtonHover: string;
|
|
45
|
+
deleteButtonBackground: string;
|
|
46
|
+
deleteButtonText: string;
|
|
47
|
+
deleteButtonHoverBackground: string;
|
|
48
|
+
deleteButtonHoverText: string;
|
|
49
|
+
deleteButtonShadow: string;
|
|
50
|
+
deleteButtonHoverShadow: string;
|
|
51
|
+
successBadgeBackground: string;
|
|
52
|
+
changeButtonBackground: string;
|
|
53
|
+
changeButtonHover: string;
|
|
54
|
+
changeButtonText: string;
|
|
55
|
+
downloadButtonBackground: string;
|
|
56
|
+
downloadButtonHover: string;
|
|
57
|
+
downloadButtonText: string;
|
|
58
|
+
};
|
|
59
|
+
labels: {
|
|
60
|
+
uploading: (percent: number) => string;
|
|
61
|
+
paused: (percent: number) => string;
|
|
62
|
+
completed: string;
|
|
63
|
+
error: string | ((message?: string) => string);
|
|
64
|
+
change: string;
|
|
65
|
+
download: string;
|
|
66
|
+
retry: string;
|
|
67
|
+
};
|
|
68
|
+
progressInset: number;
|
|
69
|
+
maxWidth: number;
|
|
70
|
+
showProgressBar: boolean;
|
|
71
|
+
showBackgroundProgress: boolean;
|
|
72
|
+
pausable: boolean;
|
|
73
|
+
cancelable: boolean;
|
|
74
|
+
deletable: boolean;
|
|
75
|
+
retryable: boolean;
|
|
76
|
+
};
|
|
77
|
+
export declare function resolveUploadPickerConfig(config?: UploadPickerConfig): {
|
|
78
|
+
theme: UploadTheme;
|
|
79
|
+
buttonClassName: "cursor-pointer rounded-lg border border-gray-700 bg-neutral-800 px-4 py-2 text-[13px] text-gray-100 transition-colors duration-150 hover:bg-gray-700 disabled:cursor-not-allowed disabled:opacity-50" | "cursor-pointer rounded-lg border border-gray-300 bg-white px-4 py-2 text-[13px] text-gray-900 transition-colors duration-150 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50";
|
|
80
|
+
labels: {
|
|
81
|
+
maxCountExceeded: (max: number) => string;
|
|
82
|
+
invalidFormat: (filename: string) => string;
|
|
83
|
+
};
|
|
84
|
+
drag: {
|
|
85
|
+
labels: {
|
|
86
|
+
hint: string;
|
|
87
|
+
hintActive: string;
|
|
88
|
+
hintDisabled: string;
|
|
89
|
+
clickHint: string;
|
|
90
|
+
};
|
|
91
|
+
style: {
|
|
92
|
+
borderColor: string;
|
|
93
|
+
borderColorActive: string;
|
|
94
|
+
borderColorDisabled: string;
|
|
95
|
+
background: string;
|
|
96
|
+
backgroundActive: string;
|
|
97
|
+
textColor: string;
|
|
98
|
+
textColorActive: string;
|
|
99
|
+
textColorDisabled: string;
|
|
100
|
+
minHeight: number;
|
|
101
|
+
borderRadius: number;
|
|
102
|
+
};
|
|
103
|
+
enabled: boolean;
|
|
104
|
+
showDropzone: boolean;
|
|
105
|
+
global: boolean;
|
|
106
|
+
preventDocumentDrop: boolean;
|
|
107
|
+
};
|
|
108
|
+
accept?: string | string[];
|
|
109
|
+
multiple: boolean;
|
|
110
|
+
maxCount?: number;
|
|
111
|
+
showButton: boolean;
|
|
112
|
+
buttonLabel: string;
|
|
113
|
+
};
|
|
114
|
+
export declare function themeColorsToCssVars(colors: Required<UploadThemeColors>): Record<string, string>;
|
|
115
|
+
export declare const BTN_BASE = "inline-flex items-center justify-center border-none cursor-pointer p-0 transition-[background,opacity,transform,color,box-shadow] duration-150 hover:opacity-85 active:scale-95";
|
|
116
|
+
export declare const CARD_BASE = "relative w-full overflow-hidden rounded-2xl font-sans bg-[var(--upload-card-bg)] shadow-[var(--upload-card-shadow)]";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { UploadStatus } from '../interface';
|
|
2
|
+
interface UseMockUploadOptions {
|
|
3
|
+
file: File;
|
|
4
|
+
speed?: number;
|
|
5
|
+
onComplete?: () => void;
|
|
6
|
+
}
|
|
7
|
+
interface UseMockUploadReturn {
|
|
8
|
+
status: UploadStatus;
|
|
9
|
+
progress: number;
|
|
10
|
+
pause: () => void;
|
|
11
|
+
resume: () => void;
|
|
12
|
+
cancel: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function useMockUpload({ file, speed, onComplete, }: UseMockUploadOptions): UseMockUploadReturn;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { UploadStatus, UseUploadOptions } from '../interface';
|
|
2
|
+
export interface UseUploadReturn {
|
|
3
|
+
status: UploadStatus;
|
|
4
|
+
progress: number;
|
|
5
|
+
error: string | null;
|
|
6
|
+
cancel: () => void;
|
|
7
|
+
retry: () => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function useUpload({ file, url, method, fieldName, headers, withCredentials, extraFields, onComplete, onError, }: UseUploadOptions): UseUploadReturn;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { UploadStatus, UploadThemeColors } from '../interface';
|
|
2
|
+
interface UseUploadDisplayOptions {
|
|
3
|
+
file: File;
|
|
4
|
+
status: UploadStatus;
|
|
5
|
+
progress: number;
|
|
6
|
+
progressInset: number;
|
|
7
|
+
errorMessage?: string;
|
|
8
|
+
colors: Required<UploadThemeColors>;
|
|
9
|
+
labels: {
|
|
10
|
+
uploading: (percent: number) => string;
|
|
11
|
+
paused: (percent: number) => string;
|
|
12
|
+
completed: string;
|
|
13
|
+
error: string | ((message?: string) => string);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function useUploadDisplay({ file, status, progress, progressInset, errorMessage, colors, labels, }: UseUploadDisplayOptions): {
|
|
17
|
+
displayPct: number;
|
|
18
|
+
isActive: boolean;
|
|
19
|
+
progressWidth: string;
|
|
20
|
+
bgProgressStyle: {
|
|
21
|
+
width: string;
|
|
22
|
+
background: string;
|
|
23
|
+
};
|
|
24
|
+
progressFillStyle: {
|
|
25
|
+
width: string;
|
|
26
|
+
background: string;
|
|
27
|
+
};
|
|
28
|
+
statusText: string;
|
|
29
|
+
sizeText: string;
|
|
30
|
+
statusColor: string;
|
|
31
|
+
progressInsetPx: number;
|
|
32
|
+
showProgressGlow: boolean;
|
|
33
|
+
};
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface UseUploadDragDropOptions {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
global?: boolean;
|
|
4
|
+
preventDocumentDrop?: boolean;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
onDropFiles: (files: File[]) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useUploadDragDrop({ enabled, global, preventDocumentDrop, disabled, onDropFiles, }: UseUploadDragDropOptions): {
|
|
9
|
+
isDragging: boolean;
|
|
10
|
+
dropHandlers: {
|
|
11
|
+
onDragEnter: (event: React.DragEvent) => void;
|
|
12
|
+
onDragLeave: (event: React.DragEvent) => void;
|
|
13
|
+
onDragOver: (event: React.DragEvent) => void;
|
|
14
|
+
onDrop: (event: React.DragEvent) => void;
|
|
15
|
+
} | {
|
|
16
|
+
onDragEnter?: undefined;
|
|
17
|
+
onDragLeave?: undefined;
|
|
18
|
+
onDragOver?: undefined;
|
|
19
|
+
onDrop?: undefined;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { UploadPickerConfig, UploadRejectReason } from '../interface';
|
|
2
|
+
interface UseUploadPickerOptions {
|
|
3
|
+
config?: UploadPickerConfig;
|
|
4
|
+
currentCount?: number;
|
|
5
|
+
onFilesSelected: (files: File[]) => void;
|
|
6
|
+
onReject?: (reason: UploadRejectReason, files: File[]) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useUploadPicker({ config, currentCount, onFilesSelected, onReject, }: UseUploadPickerOptions): {
|
|
9
|
+
accept: string | undefined;
|
|
10
|
+
multiple: boolean;
|
|
11
|
+
labels: {
|
|
12
|
+
maxCountExceeded: (max: number) => string;
|
|
13
|
+
invalidFormat: (filename: string) => string;
|
|
14
|
+
};
|
|
15
|
+
processFiles: (fileList: FileList | File[]) => void;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface IconProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function PauseIcon({ className }: IconProps): import("react").JSX.Element;
|
|
5
|
+
export declare function PlayIcon({ className }: IconProps): import("react").JSX.Element;
|
|
6
|
+
export declare function CloseIcon({ className }: IconProps): import("react").JSX.Element;
|
|
7
|
+
export declare function TrashIcon({ className }: IconProps): import("react").JSX.Element;
|
|
8
|
+
export declare function CheckIcon({ className }: IconProps): import("react").JSX.Element;
|
|
9
|
+
export declare function RetryIcon({ className }: IconProps): import("react").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Upload as InternalUpload } from './Upload';
|
|
2
|
+
import { Dropzone } from './Dropzone';
|
|
3
|
+
import { Picker } from './Picker';
|
|
4
|
+
import { MockUpload } from './MockUpload';
|
|
5
|
+
import { UploadRequest } from './UploadRequest';
|
|
6
|
+
export { UploadActions } from './UploadActions';
|
|
7
|
+
export { FileTypeIcon } from './FileTypeIcon';
|
|
8
|
+
export { Dropzone, Dropzone as UploadDropzone };
|
|
9
|
+
export { Picker, Picker as UploadPicker };
|
|
10
|
+
export { MockUpload, MockUpload as UploadWithMock };
|
|
11
|
+
export { UploadRequest, UploadRequest as UploadWithUpload };
|
|
12
|
+
export { useMockUpload } from './hooks/useMockUpload';
|
|
13
|
+
export { useUpload } from './hooks/useUpload';
|
|
14
|
+
export type { UseUploadReturn } from './hooks/useUpload';
|
|
15
|
+
export { useUploadDisplay } from './hooks/useUploadDisplay';
|
|
16
|
+
export { useUploadDragDrop } from './hooks/useUploadDragDrop';
|
|
17
|
+
export { useUploadPicker } from './hooks/useUploadPicker';
|
|
18
|
+
export { DARK_THEME_COLORS, DEFAULT_DROPZONE_STYLE, DEFAULT_DRAG_CONFIG, DEFAULT_PICKER_CONFIG, DEFAULT_UPLOAD_CONFIG, LIGHT_THEME_COLORS, resolveUploadConfig, resolveUploadPickerConfig, } from './config';
|
|
19
|
+
export { applyMaxCount, filterAcceptedFiles, isFileAccepted, normalizeAccept, } from './utils/fileAccept';
|
|
20
|
+
export type { CompletedVariant, UploadCallbacks, UploadConfig, UploadLabels, UploadDropzoneLabels, UploadDropzoneStyle, UploadPickerConfig, UploadPickerDragConfig, UploadPickerLabels, UploadPickerProps, UploadProps, UploadRejectReason, UploadStatus, UploadTheme, UploadThemeColors, UploadWithMockProps, UploadWithUploadProps, UseUploadOptions, } from './interface';
|
|
21
|
+
export { cn, formatBytes, getFileExtension } from './utils';
|
|
22
|
+
type UploadComponent = typeof InternalUpload & {
|
|
23
|
+
Dropzone: typeof Dropzone;
|
|
24
|
+
Picker: typeof Picker;
|
|
25
|
+
};
|
|
26
|
+
export declare const Upload: UploadComponent;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export type UploadStatus = 'uploading' | 'paused' | 'completed' | 'error';
|
|
3
|
+
export type CompletedVariant = 'compact' | 'expanded';
|
|
4
|
+
export type UploadTheme = 'dark' | 'light';
|
|
5
|
+
export interface UploadThemeColors {
|
|
6
|
+
/** 卡片背景 */
|
|
7
|
+
cardBackground?: string;
|
|
8
|
+
/** 卡片阴影 */
|
|
9
|
+
cardShadow?: string;
|
|
10
|
+
/** 文件名 */
|
|
11
|
+
fileName?: string;
|
|
12
|
+
/** 上传中状态文字 */
|
|
13
|
+
statusUploading?: string;
|
|
14
|
+
/** 暂停状态文字 */
|
|
15
|
+
statusPaused?: string;
|
|
16
|
+
/** 失败状态文字 */
|
|
17
|
+
statusError?: string;
|
|
18
|
+
/** 完成状态文字 */
|
|
19
|
+
statusCompleted?: string;
|
|
20
|
+
/** 次要信息(文件大小等) */
|
|
21
|
+
metaMuted?: string;
|
|
22
|
+
/** 分隔符 */
|
|
23
|
+
metaSeparator?: string;
|
|
24
|
+
/** 底部进度条轨道 */
|
|
25
|
+
progressTrack?: string;
|
|
26
|
+
/** 背景进度渐变 */
|
|
27
|
+
progressBackground?: string;
|
|
28
|
+
/** 底部进度条填充渐变 */
|
|
29
|
+
progressFill?: string;
|
|
30
|
+
/** 进度条发光色(rgba) */
|
|
31
|
+
progressGlow?: string;
|
|
32
|
+
/** 圆形操作按钮背景 */
|
|
33
|
+
iconButtonBackground?: string;
|
|
34
|
+
/** 圆形操作按钮 hover */
|
|
35
|
+
iconButtonHover?: string;
|
|
36
|
+
/** 圆形操作按钮文字 */
|
|
37
|
+
iconButtonText?: string;
|
|
38
|
+
/** 关闭/取消按钮文字 */
|
|
39
|
+
closeButtonText?: string;
|
|
40
|
+
/** 关闭/取消按钮 hover 文字 */
|
|
41
|
+
closeButtonHover?: string;
|
|
42
|
+
/** 删除按钮背景 */
|
|
43
|
+
deleteButtonBackground?: string;
|
|
44
|
+
/** 删除按钮文字 */
|
|
45
|
+
deleteButtonText?: string;
|
|
46
|
+
/** 删除按钮 hover 背景 */
|
|
47
|
+
deleteButtonHoverBackground?: string;
|
|
48
|
+
/** 删除按钮 hover 文字 */
|
|
49
|
+
deleteButtonHoverText?: string;
|
|
50
|
+
/** 删除按钮阴影 */
|
|
51
|
+
deleteButtonShadow?: string;
|
|
52
|
+
/** 删除按钮 hover 阴影 */
|
|
53
|
+
deleteButtonHoverShadow?: string;
|
|
54
|
+
/** 完成勾选徽章背景 */
|
|
55
|
+
successBadgeBackground?: string;
|
|
56
|
+
/** expanded 态 Change 按钮背景 */
|
|
57
|
+
changeButtonBackground?: string;
|
|
58
|
+
changeButtonHover?: string;
|
|
59
|
+
changeButtonText?: string;
|
|
60
|
+
/** expanded 态 Download 按钮背景 */
|
|
61
|
+
downloadButtonBackground?: string;
|
|
62
|
+
downloadButtonHover?: string;
|
|
63
|
+
downloadButtonText?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface UploadLabels {
|
|
66
|
+
uploading?: (percent: number) => string;
|
|
67
|
+
paused?: (percent: number) => string;
|
|
68
|
+
completed?: string;
|
|
69
|
+
error?: string | ((message?: string) => string);
|
|
70
|
+
change?: string;
|
|
71
|
+
download?: string;
|
|
72
|
+
retry?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface UploadConfig {
|
|
75
|
+
/** 主题:light 浅色(默认)| dark 深色 */
|
|
76
|
+
theme?: UploadTheme;
|
|
77
|
+
/** 覆盖主题预设颜色 */
|
|
78
|
+
colors?: UploadThemeColors;
|
|
79
|
+
/** 底部进度条左右内边距;背景进度左贴边,右边缘与线条对齐 */
|
|
80
|
+
progressInset?: number;
|
|
81
|
+
/** 卡片最大宽度,默认 480 */
|
|
82
|
+
maxWidth?: number;
|
|
83
|
+
/** 是否显示底部进度条 */
|
|
84
|
+
showProgressBar?: boolean;
|
|
85
|
+
/** 是否显示背景进度渐变 */
|
|
86
|
+
showBackgroundProgress?: boolean;
|
|
87
|
+
/** 是否允许暂停/恢复(真实上传无断点续传时应设为 false) */
|
|
88
|
+
pausable?: boolean;
|
|
89
|
+
/** 是否允许取消 */
|
|
90
|
+
cancelable?: boolean;
|
|
91
|
+
/** 是否允许删除 */
|
|
92
|
+
deletable?: boolean;
|
|
93
|
+
/** 失败时是否显示重试按钮 */
|
|
94
|
+
retryable?: boolean;
|
|
95
|
+
/** 文案配置 */
|
|
96
|
+
labels?: UploadLabels;
|
|
97
|
+
}
|
|
98
|
+
export interface UploadPickerLabels {
|
|
99
|
+
maxCountExceeded?: (max: number) => string;
|
|
100
|
+
invalidFormat?: (filename: string) => string;
|
|
101
|
+
}
|
|
102
|
+
export interface UploadDropzoneLabels {
|
|
103
|
+
/** 默认提示 */
|
|
104
|
+
hint?: string;
|
|
105
|
+
/** 拖拽悬停提示 */
|
|
106
|
+
hintActive?: string;
|
|
107
|
+
/** 禁用态提示 */
|
|
108
|
+
hintDisabled?: string;
|
|
109
|
+
/** 点击选择补充文案 */
|
|
110
|
+
clickHint?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface UploadDropzoneStyle {
|
|
113
|
+
borderColor?: string;
|
|
114
|
+
borderColorActive?: string;
|
|
115
|
+
borderColorDisabled?: string;
|
|
116
|
+
background?: string;
|
|
117
|
+
backgroundActive?: string;
|
|
118
|
+
textColor?: string;
|
|
119
|
+
textColorActive?: string;
|
|
120
|
+
textColorDisabled?: string;
|
|
121
|
+
minHeight?: number;
|
|
122
|
+
borderRadius?: number;
|
|
123
|
+
}
|
|
124
|
+
export interface UploadPickerDragConfig {
|
|
125
|
+
/** 是否启用拖拽上传,默认 false */
|
|
126
|
+
enabled?: boolean;
|
|
127
|
+
/** 是否渲染内置拖拽投放区,默认 true(enabled 时) */
|
|
128
|
+
showDropzone?: boolean;
|
|
129
|
+
/** 是否在 document 级别监听拖拽(整页投放),默认 false */
|
|
130
|
+
global?: boolean;
|
|
131
|
+
/** 阻止浏览器默认打开拖拽文件,默认 true */
|
|
132
|
+
preventDocumentDrop?: boolean;
|
|
133
|
+
/** 投放区文案 */
|
|
134
|
+
labels?: UploadDropzoneLabels;
|
|
135
|
+
/** 投放区样式 */
|
|
136
|
+
style?: UploadDropzoneStyle;
|
|
137
|
+
}
|
|
138
|
+
export interface UploadPickerConfig {
|
|
139
|
+
/** 主题:light 浅色(默认)| dark 深色 */
|
|
140
|
+
theme?: UploadTheme;
|
|
141
|
+
/** 允许的文件格式,如 `.xlsx`、`.pdf` 或 MIME `image/*` */
|
|
142
|
+
accept?: string | string[];
|
|
143
|
+
/** 是否允许多选,默认 false */
|
|
144
|
+
multiple?: boolean;
|
|
145
|
+
/** 最多上传数量(含已选列表),不设则不限制 */
|
|
146
|
+
maxCount?: number;
|
|
147
|
+
/** 是否显示「选择文件」按钮,可与拖拽投放区同时存在,默认 true */
|
|
148
|
+
showButton?: boolean;
|
|
149
|
+
/** 选择按钮文案 */
|
|
150
|
+
buttonLabel?: string;
|
|
151
|
+
/** 校验失败文案 */
|
|
152
|
+
labels?: UploadPickerLabels;
|
|
153
|
+
/** 拖拽上传配置 */
|
|
154
|
+
drag?: UploadPickerDragConfig;
|
|
155
|
+
}
|
|
156
|
+
export type UploadRejectReason = 'max-count' | 'invalid-format';
|
|
157
|
+
export interface UploadCallbacks {
|
|
158
|
+
onPause?: () => void;
|
|
159
|
+
onResume?: () => void;
|
|
160
|
+
onCancel?: () => void;
|
|
161
|
+
onDelete?: () => void;
|
|
162
|
+
onChange?: () => void;
|
|
163
|
+
onDownload?: () => void;
|
|
164
|
+
onRetry?: () => void;
|
|
165
|
+
}
|
|
166
|
+
export interface UploadProps extends UploadCallbacks {
|
|
167
|
+
file: File;
|
|
168
|
+
status?: UploadStatus;
|
|
169
|
+
progress?: number;
|
|
170
|
+
errorMessage?: string;
|
|
171
|
+
completedVariant?: CompletedVariant;
|
|
172
|
+
config?: UploadConfig;
|
|
173
|
+
className?: string;
|
|
174
|
+
exiting?: boolean;
|
|
175
|
+
}
|
|
176
|
+
export interface UploadWithMockProps extends UploadCallbacks {
|
|
177
|
+
file: File;
|
|
178
|
+
completedVariant?: CompletedVariant;
|
|
179
|
+
config?: UploadConfig;
|
|
180
|
+
speed?: number;
|
|
181
|
+
onComplete?: () => void;
|
|
182
|
+
className?: string;
|
|
183
|
+
}
|
|
184
|
+
export interface UseUploadOptions {
|
|
185
|
+
file: File;
|
|
186
|
+
url: string;
|
|
187
|
+
method?: 'POST' | 'PUT';
|
|
188
|
+
fieldName?: string;
|
|
189
|
+
headers?: Record<string, string>;
|
|
190
|
+
withCredentials?: boolean;
|
|
191
|
+
extraFields?: Record<string, string>;
|
|
192
|
+
onComplete?: (response: XMLHttpRequest) => void;
|
|
193
|
+
onError?: (error: Error) => void;
|
|
194
|
+
}
|
|
195
|
+
export interface UploadWithUploadProps extends UploadCallbacks {
|
|
196
|
+
file: File;
|
|
197
|
+
url: string;
|
|
198
|
+
method?: 'POST' | 'PUT';
|
|
199
|
+
fieldName?: string;
|
|
200
|
+
headers?: Record<string, string>;
|
|
201
|
+
withCredentials?: boolean;
|
|
202
|
+
extraFields?: Record<string, string>;
|
|
203
|
+
completedVariant?: CompletedVariant;
|
|
204
|
+
config?: UploadConfig;
|
|
205
|
+
onComplete?: (response: XMLHttpRequest) => void;
|
|
206
|
+
onError?: (error: Error) => void;
|
|
207
|
+
className?: string;
|
|
208
|
+
}
|
|
209
|
+
export interface UploadPickerProps {
|
|
210
|
+
config?: UploadPickerConfig;
|
|
211
|
+
/** 当前已选文件数,用于 maxCount 校验 */
|
|
212
|
+
currentCount?: number;
|
|
213
|
+
onFilesSelected: (files: File[]) => void;
|
|
214
|
+
onReject?: (reason: UploadRejectReason, files: File[]) => void;
|
|
215
|
+
disabled?: boolean;
|
|
216
|
+
className?: string;
|
|
217
|
+
/** 选择按钮 className */
|
|
218
|
+
buttonClassName?: string;
|
|
219
|
+
/** 拖拽投放区容器 className */
|
|
220
|
+
dropzoneClassName?: string;
|
|
221
|
+
/** 默认布局容器 className(按钮 + 投放区) */
|
|
222
|
+
wrapperClassName?: string;
|
|
223
|
+
/** 自定义布局;可通过 button / dropzone 分别放置 */
|
|
224
|
+
children?: (api: {
|
|
225
|
+
open: () => void;
|
|
226
|
+
disabled: boolean;
|
|
227
|
+
isDragging: boolean;
|
|
228
|
+
dropHandlers: {
|
|
229
|
+
onDragEnter?: (event: React.DragEvent) => void;
|
|
230
|
+
onDragLeave?: (event: React.DragEvent) => void;
|
|
231
|
+
onDragOver?: (event: React.DragEvent) => void;
|
|
232
|
+
onDrop?: (event: React.DragEvent) => void;
|
|
233
|
+
};
|
|
234
|
+
button: ReactNode;
|
|
235
|
+
dropzone: ReactNode | null;
|
|
236
|
+
}) => ReactNode;
|
|
237
|
+
}
|