Uploader
Queue, progress, cancel — XHR or your own
Files that upload on their own, with progress, before the form is sent — attachments, a photo set, a batch import. When the files should simply go with the form on submit, use FileInput.
Basic
- With
urlit POSTs each file (asfield, withheaders) and tracks progress. Without it, handle@uploadyourself: callprogress(n), thendone()orfail(message). autostarts as soon as files are picked; otherwise the Upload button does.maxSizerejects large files before they're sent.- Finished and failed uploads are announced; each row's button names its file. Leaving the page, or unmounting, stops uploads in progress.
Usage
ts
import { BlessUploader } from "blessing-ui";API
Props
| Name | Type | Default | Description |
|---|---|---|---|
url | string | — | POST target; omit to handle uploads yourself via the `upload` event |
field | string | "file" | form field name |
headers | Record<string, string> | — | |
accept | string | — | |
multiple | boolean | true | |
auto | boolean | false | start as soon as files are picked |
maxSize | number | — | |
label | string | "Drop files here or click to browse" | |
hint | string | — |
Events
| Name | Payload | Description |
|---|---|---|
done | [item: BlessUpload] | |
error | [item: BlessUpload] | |
upload | [item: BlessUpload, progress: (n: number) => void, done: () => void, fail: (msg?: string | undefined) => void] |
Slots
| Name | Scope | Description |
|---|---|---|
actions | { start: () => void; clear: () => { id: number; file: { readonly lastModified: number; readonly name: string; readonly webkitRelativePath: string; readonly size: number; readonly type: string; arrayBuffer: () => Promise<ArrayBuffer>; bytes: () => Promise<Uint8Array<ArrayBuffer>>; slice: (start?: number | undefined, end?: number | undefined, contentType?: string | undefined) => Blob; stream: () => ReadableStream<Uint8Array<ArrayBuffer>>; text: () => Promise<string>; }; progress: number; status: "done" | "uploading" | "error" | "queued" | "cancelled"; error?: string | undefined; xhr?: { onreadystatechange: ((this: XMLHttpRequest, ev: Event) => any) | null; readonly readyState: number; readonly response: any; readonly responseText: string; responseType: XMLHttpRequestResponseType; readonly responseURL: string; readonly responseXML: Document | null; readonly status: number; readonly statusText: string; timeout: number; readonly upload: { addEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; }; withCredentials: boolean; abort: () => void; getAllResponseHeaders: () => string; getResponseHeader: (name: string) => string | null; open: { (method: string, url: string | URL): void; (method: string, url: string | URL, async: boolean, username?: string | null | undefined, password?: string | null | undefined): void; }; overrideMimeType: (mime: string) => void; send: (body?: Document | XMLHttpRequestBodyInit | null | undefined) => void; setRequestHeader: (name: string, value: string) => void; readonly UNSENT: 0; readonly OPENED: 1; readonly HEADERS_RECEIVED: 2; readonly LOADING: 3; readonly DONE: 4; addEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; } | undefined; }[]; queue: { id: number; file: { readonly lastModified: number; readonly name: string; readonly webkitRelativePath: string; readonly size: number; readonly type: string; arrayBuffer: () => Promise<ArrayBuffer>; bytes: () => Promise<Uint8Array<ArrayBuffer>>; slice: (start?: number | undefined, end?: number | undefined, contentType?: string | undefined) => Blob; stream: () => ReadableStream<Uint8Array<ArrayBuffer>>; text: () => Promise<string>; }; progress: number; status: "done" | "uploading" | "error" | "queued" | "cancelled"; error?: string | undefined; xhr?: { onreadystatechange: ((this: XMLHttpRequest, ev: Event) => any) | null; readonly readyState: number; readonly response: any; readonly responseText: string; responseType: XMLHttpRequestResponseType; readonly responseURL: string; readonly responseXML: Document | null; readonly status: number; readonly statusText: string; timeout: number; readonly upload: { addEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; }; withCredentials: boolean; abort: () => void; getAllResponseHeaders: () => string; getResponseHeader: (name: string) => string | null; open: { (method: string, url: string | URL): void; (method: string, url: string | URL, async: boolean, username?: string | null | undefined, password?: string | null | undefined): void; }; overrideMimeType: (mime: string) => void; send: (body?: Document | XMLHttpRequestBodyInit | null | undefined) => void; setRequestHeader: (name: string, value: string) => void; readonly UNSENT: 0; readonly OPENED: 1; readonly HEADERS_RECEIVED: 2; readonly LOADING: 3; readonly DONE: 4; addEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; } | undefined; }[]; } |
Exposed
| Name | Type | Description |
|---|---|---|
start | () => void | |
clear | () => { id: number; file: { readonly lastModified: number; readonly name: string; readonly webkitRelativePath: string; readonly size: number; readonly type: string; arrayBuffer: () => Promise<ArrayBuffer>; bytes: () => Promise<Uint8Array<ArrayBuffer>>; slice: (start?: number | undefined, end?: number | undefined, contentType?: string | undefined) => Blob; stream: () => ReadableStream<Uint8Array<ArrayBuffer>>; text: () => Promise<string>; }; progress: number; status: "done" | "uploading" | "error" | "queued" | "cancelled"; error?: string | undefined; xhr?: { onreadystatechange: ((this: XMLHttpRequest, ev: Event) => any) | null; readonly readyState: number; readonly response: any; readonly responseText: string; responseType: XMLHttpRequestResponseType; readonly responseURL: string; readonly responseXML: Document | null; readonly status: number; readonly statusText: string; timeout: number; readonly upload: { addEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; }; withCredentials: boolean; abort: () => void; getAllResponseHeaders: () => string; getResponseHeader: (name: string) => string | null; open: { (method: string, url: string | URL): void; (method: string, url: string | URL, async: boolean, username?: string | null | undefined, password?: string | null | undefined): void; }; overrideMimeType: (mime: string) => void; send: (body?: Document | XMLHttpRequestBodyInit | null | undefined) => void; setRequestHeader: (name: string, value: string) => void; readonly UNSENT: 0; readonly OPENED: 1; readonly HEADERS_RECEIVED: 2; readonly LOADING: 3; readonly DONE: 4; addEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; } | undefined; }[] | |
queue | { id: number; file: { readonly lastModified: number; readonly name: string; readonly webkitRelativePath: string; readonly size: number; readonly type: string; arrayBuffer: () => Promise<ArrayBuffer>; bytes: () => Promise<Uint8Array<ArrayBuffer>>; slice: (start?: number | undefined, end?: number | undefined, contentType?: string | undefined) => Blob; stream: () => ReadableStream<Uint8Array<ArrayBuffer>>; text: () => Promise<string>; }; progress: number; status: "done" | "uploading" | "error" | "queued" | "cancelled"; error?: string | undefined; xhr?: { onreadystatechange: ((this: XMLHttpRequest, ev: Event) => any) | null; readonly readyState: number; readonly response: any; readonly responseText: string; responseType: XMLHttpRequestResponseType; readonly responseURL: string; readonly responseXML: Document | null; readonly status: number; readonly statusText: string; timeout: number; readonly upload: { addEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; }; withCredentials: boolean; abort: () => void; getAllResponseHeaders: () => string; getResponseHeader: (name: string) => string | null; open: { (method: string, url: string | URL): void; (method: string, url: string | URL, async: boolean, username?: string | null | undefined, password?: string | null | undefined): void; }; overrideMimeType: (mime: string) => void; send: (body?: Document | XMLHttpRequestBodyInit | null | undefined) => void; setRequestHeader: (name: string, value: string) => void; readonly UNSENT: 0; readonly OPENED: 1; readonly HEADERS_RECEIVED: 2; readonly LOADING: 3; readonly DONE: 4; addEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; }; removeEventListener: { <K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void; }; onabort: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onerror: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onload: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadend: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; onprogress: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent<EventTarget>) => any) | null; dispatchEvent: (event: Event) => boolean; } | undefined; }[] |