For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt, and this page is available as Markdown at https://wallarm.github.io/design-system/components/file-upload.md.

FileUpload

Attaches files to a form and checks their type, size and count before accepting them — the drop Area when attaching is the main task on the screen, the "Select file" button when space is tight. Picking never uploads: files travel with the form when it is saved, and the product marks a row loading while it sends one. To pick a photo by clicking an avatar, see Data Display/Avatar → Click To Upload.

Source · Storybook

Usage

import { FileUpload, FileUploadDropzone, FileUploadError } from '@wallarm-org/design-system/FileUpload';

Examples

Button trigger

The same picking and checks behind a "Select file" button that hugs its label, for when a 96px Area would crowd the form.

In field

Inside Field: the label names the Area, and the description carries the format and the limit.

Multiple

With maxFiles above one the picker stays and disables once the limit is reached, while each file stacks below it as its own row.

Single file chosen

One file allowed and chosen: the file shows below the picker, and a new pick, or Replace in the row, swaps it.

With description

description adds a second line to the row for size or status — here, that the file goes with the form.

Uploading

A row marked loading dims and shows a spinner, and the picker locks until no row is loading; its X becomes "Cancel upload", and stopping the request is up to the product.

Validation

Only .so / .dylib up to 32 KB: anything else is refused inline, naming the file and the rule.

Disabled

Disabled: nothing responds, and the Area and the row actions dim.

Read only

Read-only removes the picker, Replace and Delete, while a custom FileUploadItemAction such as Download stays.

Stored file

A file already on the server is a row too: FileUploadItem works outside FileUpload from a name and size, and its actions only run your onClick.

Long file name

Long names truncate; hover shows the full name.

Form submission

Nothing uploads on pick: the file travels in the form's FormData under name, and an empty submit of a required Field shows its error.

Props

PropTypeDefaultDescription
valueFile[] | undefinedControlled accepted files.
defaultValueFile[] | undefinedUncontrolled initial files.
onValueChange((files: File[]) => void) | undefinedEvery change to the accepted list — pick, drop, replace, delete (then []).
onFileReject((rejections: FileUploadRejection[]) => void) | undefinedFiles that failed validation (for consumers that also want a toast).
acceptstring | string[] | undefinedExtensions and/or MIME types: '.so,.dylib', 'image/png', ['.lua'].
maxFilesnumber | undefined1Default 1: a new pick replaces the file, and the picker stays visible, with the chosen file shown below it.
maxFileSizenumber | undefinedBytes. Checked on pick, drop and replace.
minFileSizenumber | undefinedBytes.
validate((file: File) => string[] | null) | undefinedCustom rules; returned strings are shown verbatim as rejection messages.
namestring | undefinedHidden input name — the files submit with a native form under it.
requiredboolean | undefined
disabledboolean | undefined
readOnlyboolean | undefinedHides the picker, Delete and Replace; FileUploadItemAction (e.g. Download) stays.
errorboolean | undefinedfalseError state (maps to Ark invalid); also read from a wrapping Field.
allowDropboolean | undefinedtrueDefault true.
titlestring | undefined
defaultCheckedboolean | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
data-testidstring | undefined

FileUploadDropzone

PropTypeDefaultDescription
iconReactNodeReplaces the default upload icon.
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
data-testidstring | undefined

FileUploadError

PropTypeDefaultDescription
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
data-testidstring | undefined

FileUploadItem

PropTypeDefaultDescription
file *FileUploadItemFileA picked File, or a stored file described by { name, size? }.
descriptionReactNodeSecond line, e.g. "32 KB · uploads when you save".
loadingboolean | undefinedfalseUploading: dims the row, shows a spinner and locks the picker until it clears.
iconReactNodeReplaces the default file icon.
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
valuestring | number | readonly string[] | undefined
data-testidstring | undefined

FileUploadItemAction

PropTypeDefaultDescription
size{ small: string; medium: string; large: string; 'inline-edit': string; }
loading{ true: string; }
fullWidth{ true: string; false: string; }
asChildboolean | undefined
data-testidstring | undefined
asC | undefined
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
colorstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
type"button" | "submit" | "reset" | undefined
disabledboolean | undefined
namestring | undefined
valuestring | number | readonly string[] | undefined
variant{ primary: string; outline: string; ghost: string; secondary: string; }

FileUploadItemDeleteTrigger

PropTypeDefaultDescription
size{ small: string; medium: string; large: string; 'inline-edit': string; }
loading{ true: string; }
fullWidth{ true: string; false: string; }
asChildboolean | undefined
data-testidstring | undefined
asC | undefined
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
colorstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
type"button" | "submit" | "reset" | undefined
disabledboolean | undefined
namestring | undefined
valuestring | number | readonly string[] | undefined
variant{ primary: string; outline: string; ghost: string; secondary: string; }

FileUploadItemGroup

PropTypeDefaultDescription
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
data-testidstring | undefined

FileUploadItemReplaceTrigger

PropTypeDefaultDescription
size{ small: string; medium: string; large: string; 'inline-edit': string; }
loading{ true: string; }
fullWidth{ true: string; false: string; }
asChildboolean | undefined
data-testidstring | undefined
asC | undefined
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
colorstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
type"button" | "submit" | "reset" | undefined
disabledboolean | undefined
namestring | undefined
valuestring | number | readonly string[] | undefined
variant{ primary: string; outline: string; ghost: string; secondary: string; }

FileUploadTrigger

PropTypeDefaultDescription
size{ small: string; medium: string; large: string; 'inline-edit': string; }
loading{ true: string; }
fullWidth{ true: string; false: string; }
asChildboolean | undefinedfalse
data-testidstring | undefined
asC | undefined
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
colorstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
type"button" | "submit" | "reset" | undefined
disabledboolean | undefined
namestring | undefined
valuestring | number | readonly string[] | undefined
variant{ primary: string; outline: string; ghost: string; secondary: string; }