# Flux 2.0 — File upload
A dropzone over a native file input, and a list of the chosen files with their progress and errors.
Reference: https://flux.kaptio.com/components/file-upload/
Requires: https://flux.kaptio.com/tokens/v2/flux.css and flux-components.css
## Use it when
For attaching documents to a record: passport scans, supplier contracts, invoices. The native file input covers the dropzone, so a click anywhere opens the picker and a dropped file lands in the input without scripting. Each file joins a list with its size and state. The script checks the accepted types and the size limit, then hands valid files to the page through a flux-upload event; the page uploads them and reports progress, success or failure back to the item.
## Do not use it when
Not for importing data that needs mapping and validation row by row; that is a dedicated import flow. Not for a single avatar or logo, where a button that opens the picker is enough.
## Markup
### Default
PDF, JPG or PNG, up to 10 MB each. One file per traveller.
Choose files or drop them here
### File states
passport-anna-jonsdottir.pdf1.2 MB · Uploaded
passport-marianne-hollis.jpg3.4 MB · Uploading
passport-scan-full-resolution.png14.8 MB · Larger than 10 MB.
passport-olafur-gunnarsson.pdf0.9 MB · The connection dropped.
## API
- flux-upload (class): Wraps the dropzone and the list.
- data-flux-upload (attribute): Wires dragging, checking, listing and the upload events.
- data-max-mb (attribute): On flux-upload: the largest file accepted, in megabytes. State it in the info bubble too.
- flux-upload__dropzone | __icon | __prompt | __action (class): The dropzone and its contents.
- flux-upload__input (class): On the input type="file". Use accept and multiple as usual. It is cleared after each pick, so the same file can be chosen again.
- flux-upload__list | __item (class): The file list and each file. data-state is ready, uploading, done or error.
- flux-upload__remove (class): The remove button. Label it "Remove" and the file name.
- flux-upload (element): Event dispatched per valid file, with detail.file, detail.progress(percent), detail.complete() and detail.fail(message).
- flux-upload-remove (element): Event dispatched when a file is removed, with detail.file.
## Accessibility
- The input is the real control, labelled by the field label, with the constraints in the info bubble it references.
- The file list is a polite live region, so added files, failures and completions are announced.
- Every state is in words as well as colour.
- Removing a file moves focus to the next file’s remove button, or back to the input.
## Keyboard
- Tab: Focuses the input, then each item’s actions.
- Enter, Space: Opens the file picker.
## Tokens
- --flux-upload-padding | -gap | -bg | -bg-active
- --flux-upload-border | -border-active
- --flux-upload-icon | -icon-size | -text
- --flux-upload-item-padding-y | -item-padding-x | -item-gap | -item-divider
- --flux-upload-meta | -success
## Do
- State the accepted types and size limit in the info bubble before anyone picks a file.
- Say why a file failed: too large, wrong type, or what the server said.
- Let people remove a file at any point, including while it uploads.
## Do not
- Do not put the size limit below the dropzone as help text.
- Do not silently drop a file that fails a check.
- Do not block the rest of the form while files upload.