import { NOOP } from '@vue/shared' import { buildProps, definePropType, mutable } from '@element-plus/utils' import { ajaxUpload } from './ajax' import type { UploadAjaxError } from './ajax' import type { Awaitable } from '@element-plus/utils' import type { ExtractPropTypes } from 'vue' import type Upload from './upload.vue' export const uploadListTypes = ['text', 'picture', 'picture-card'] as const let fileId = 1 export const genFileId = () => Date.now() + fileId++ export type UploadStatus = 'ready' | 'uploading' | 'success' | 'fail' export interface UploadProgressEvent extends ProgressEvent { percent: number } export interface UploadRequestOptions { action: string method: string data: Record filename: string file: File headers: Headers | Record onError: (evt: UploadAjaxError) => void onProgress: (evt: UploadProgressEvent) => void onSuccess: (response: any) => void withCredentials: boolean } export interface UploadFile { name: string percentage?: number status: UploadStatus size?: number response?: unknown uid: number url?: string raw?: UploadRawFile } export type UploadUserFile = Omit & Partial> export type UploadFiles = UploadFile[] export interface UploadRawFile extends File { uid: number } export type UploadRequestHandler = ( options: UploadRequestOptions ) => XMLHttpRequest | Promise export interface UploadHooks { beforeUpload: ( rawFile: UploadRawFile ) => Awaitable beforeRemove: ( uploadFile: UploadFile, uploadFiles: UploadFiles ) => Awaitable onRemove: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void onChange: (uploadFile: UploadFile, uploadFiles: UploadFiles) => void onPreview: (uploadFile: UploadFile) => void onSuccess: ( response: any, uploadFile: UploadFile, uploadFiles: UploadFiles ) => void onProgress: ( evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles ) => void onError: ( error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles ) => void onExceed: (files: File[], uploadFiles: UploadUserFile[]) => void } export const uploadBaseProps = buildProps({ action: { type: String, required: true, }, headers: { type: definePropType>(Object), }, method: { type: String, default: 'post', }, data: { type: Object, default: () => mutable({} as const), }, multiple: { type: Boolean, default: false, }, name: { type: String, default: 'file', }, drag: { type: Boolean, default: false, }, withCredentials: Boolean, showFileList: { type: Boolean, default: true, }, accept: { type: String, default: '', }, type: { type: String, default: 'select', }, fileList: { type: definePropType(Array), default: () => mutable([] as const), }, autoUpload: { type: Boolean, default: true, }, listType: { type: String, values: uploadListTypes, default: 'text', }, httpRequest: { type: definePropType(Function), default: ajaxUpload, }, disabled: Boolean, limit: Number, } as const) export const uploadProps = buildProps({ ...uploadBaseProps, beforeUpload: { type: definePropType(Function), default: NOOP, }, beforeRemove: { type: definePropType(Function), }, onRemove: { type: definePropType(Function), default: NOOP, }, onChange: { type: definePropType(Function), default: NOOP, }, onPreview: { type: definePropType(Function), default: NOOP, }, onSuccess: { type: definePropType(Function), default: NOOP, }, onProgress: { type: definePropType(Function), default: NOOP, }, onError: { type: definePropType(Function), default: NOOP, }, onExceed: { type: definePropType(Function), default: NOOP, }, } as const) export type UploadProps = ExtractPropTypes export type UploadInstance = InstanceType