All components (204)
Upload with progress
Management · Uploader · .amset-uploader
What it is and when to use it
Uploading files for real, as soon as they are chosen: the FileUpload zone to drop or choose them and, below, one row per file with its progress bar, the reason if it fails, a button to retry and another to remove it, which cancels the upload. It is FileUpload + FileList + useFileUploads, already mounted together.
When to use it
- Attachments that are uploaded when chosen: invoices, receipts, the photos of a product.
httpuploads over HTTP, with amultipartform:action(the address, or a function that works it out for each file),method(POSTby default, orPUT),headers,data(extra fields that travel with the file),fieldName(fileby default) andwithCredentials. It usesXMLHttpRequestand notfetchbecausefetchdoes not say how much has gone out, and without that the bar would not move.customRequestuploads wherever whoever uses it says (a signed URL, a storage SDK) and wins overhttp: it receives{ file, onProgress, signal }, callsonProgresswith the percentage and returns a promise with what the server answers. It has to respectsignal, which is aborted when the file is removed.concurrencyis how many upload at once (3 by default): the rest wait their turn, and one that fails does not bring down the others.onChangereports the whole list on every change;onUploadedandonFailed, each file that finishes or fails (what the server answered arrives in itsresponse);onReject, what does not pass the type, size or how-many-fit filter.- The zone is that of
FileUpload, with the same props:label,hint,error,acceptedTypes,maxSizeMb,multiple,maxCount,directory,sizeanddisabled. Withoutmultiple, choosing another file replaces the previous one and cancels its upload. - The type and size filter is a convenience: the server has to check it again.
When not to
- Choosing files that travel with the form when it is sent, without uploading them first:
FileUpload. - Uploading when "Send" is pressed and not on choosing:
useFileUploadswithautoStart: falseand itsstart(), withFileUpload(hideList) andFileListrendered on your own. - Showing attachments that are already uploaded:
FileList.
Keyboard: that of FileUpload: Tab reaches the zone and its button (Enter or Space open the system picker; with focus on the zone files can be pasted), and then the buttons of each row: "Retry" if it failed and "Remove". On removing one, focus moves to the list, which says how many are left; on removing the last one, the list disappears and focus goes back to the choose button, with the notice "factura.pdf removed. None left".
Accessibility: the list is a region named after the zone ("Uploads for Invoices"). While a file uploads, its row carries a progress bar with a name ("Uploading factura.pdf"); queued, it carries no bar, because "0 %" would say it had already started. Each change of status is announced once in a status region —"factura.pdf uploaded", "Could not upload falla.pdf: 413 Payload Too Large"—, and several that finish at once are announced together; the progress is seen in the bar, without being announced a hundred times. The buttons say which file they are for ("Remove factura.pdf"). The network, timeout and status errors written by http come out in the language of http.locale (Spanish, by default).
Fine-tuning: --amset-uploader-gap, the gap between the zone and the list; the zone, with the --amset-upload-* of FileUpload, and the list, with the --amset-files-* of FileList.
What it looks like
PDF up to 10 MB. Try a file called falla.pdf.
<Uploader
label="Invoices"
hint="PDF up to 10 MB"
acceptedTypes={['application/pdf']}
maxSizeMb={10}
multiple
maxCount={5}
http={{ action: '/api/facturas' }}
/>Props
Import it with import { Uploader } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | What is being uploaded. It is the name of the drop zone and of the list of chosen items. |
acceptedTypes | readonly string[] | MIME types or extensions: `['application/pdf', '.csv']`. |
className | string | Merged with the library classes; it does not replace them. |
concurrency | number | How many upload at once. By default, 3: more saturates the connection and all of them finish later. |
customRequest | UploadRequest | Your own upload (an SDK, a signed URL...). It wins over `http`. |
directory | boolean | Choose a whole FOLDER instead of separate files. Dropping a folder onto it does not traverse it. |
disabled | boolean | — |
error | string | — |
hiddenLabel | boolean | The label for the screen reader only. The drop zone already carries its own name, so it can be hidden from view without losing anything. |
hint | string | Help text: which formats and what size are accepted. |
http | HttpUploadConfig | Upload over HTTP. Without it `customRequest` is needed. |
inputRef | Ref<HTMLInputElement> | The real `<input type="file">` (it is hidden), to open the picker from your own button with `inputRef.current?.click()` (AMS-735). |
maxCount | number | How many files fit at most. The excess ones are rejected with their reason. Without this, no limit. |
maxSizeMb | number | Maximum size per file, in megabytes. |
multiple | boolean | — |
onChange | (entries: readonly UploadEntry[]) => void | Notifies of each change in the list: a new file, a progress step, a failure, one that finishes. |
onFailed | (entry: UploadEntry) => void | A file has failed. It does not include those cancelled by removing them. |
onReject | (rejected: readonly RejectedFile[]) => void | Called with those that did not pass the filter (type, size, how many fit). |
onUploaded | (entry: UploadEntry) => void | A file has been fully uploaded. |
size | "sm" | "md" | "lg" | — |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-uploader-gap | var(--amset-space-3) |
How to change it
.amset-uploader {
--amset-uploader-gap: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
