Skip to main content

File Upload

Accessible file upload zone covering: drag-drop + click browse, max size + accept validation, progress + status per file, controlled/uncontrolled, full a11y.

Live Preview

Interact with the FileUpload component in real time. Toggle multiple, max files, and disabled to see behavior update.

File upload control. Constraints: max 3 files.

Drop files anywhere in the dashed area.

tsx
1<FileUpload2  value={items}3  onChange={setItems}4  multiple={true}5  maxFiles={3}6  helperText="Drop files anywhere in the dashed area."7/>

Installation

Install the Aidash Components package using your preferred package manager.

$ pnpm add @aidash/components

Import

Import the FileUpload component into your file.

tsx
import { FileUpload } from '@/components/aidash/file-upload';

Basic Usage

Single-file upload restricted to images, with controlled state.

Profile photo. File upload control. Constraints: image/*.

PNG or JPG, up to a few MB.

tsx
1const [items, setItems] = useState<FileUploadItem[]>([]);2 3<FileUpload4  value={items}5  onChange={setItems}6  accept="image/*"7  label="Profile photo"8  helperText="PNG or JPG, up to a few MB."9/>

Multiple Files

Accept multiple files at once and cap the total count with `maxFiles`.

Attachments. File upload control. Constraints: max 5 files.

Up to 5 files.

tsx
1<FileUpload2  value={items}3  onChange={setItems}4  multiple5  maxFiles={5}6  label="Attachments"7  helperText="Up to 5 files."8/>

With Size Limit

Reject files larger than `maxSize` and surface the rejection via `onError`.

Documents. File upload control. Constraints: up to 1.0 MB.

Max 1 MB per file.

tsx
1const [items, setItems] = useState<FileUploadItem[]>([]);2const [error, setError] = useState<string | null>(null);3 4<FileUpload5  value={items}6  onChange={setItems}7  onError={(message) => setError(message)}8  maxSize={1024 * 1024}9  multiple10  label="Documents"11  helperText="Max 1 MB per file."12/>

Sizes

Three size presets to fit different layouts.

Small. File upload control.
Medium. File upload control.
Large. File upload control.
tsx
1<FileUpload size="sm" label="Small" />2<FileUpload size="md" label="Medium" />3<FileUpload size="lg" label="Large" />

States

Visual states mirror the Input component: default, success, warning, and error.

Default. File upload control.

Neutral state.

Success. File upload control.

Upload complete.

Warning. File upload control.

Large file detected.

Error. File upload control.

Something went wrong.

tsx
1<FileUpload state="default" label="Default" />2<FileUpload state="success" label="Success" />3<FileUpload state="warning" label="Warning" />4<FileUpload state="error"   label="Error" />

Disabled State

Disabled dropzones are dimmed, non-interactive, and skipped by drag-and-drop handling.

Uploads temporarily unavailable. File upload control.
tsx
1<FileUpload disabled label="Uploads temporarily unavailable" />

Accessibility

Built-in ARIA wiring so the component is usable by keyboard and screen reader.

role="button" dropzone

The dropzone is a real <button> with role="button" and a descriptive aria-label that reflects the current constraints.

aria-live status region

A visually hidden aria-live="polite" region announces "N files added" or "Removed <file>" so screen readers hear the outcome.

Keyboard support: Space / Enter

Tab focuses the dropzone; pressing Space or Enter opens the native file picker. Focus is visualized with afocus-visible outline.

Per-file remove label

Each remove button carries an aria-label="Remove <file>" so assistive tech announces which file the action targets.

tsx
1{/* Rendered dropzone (simplified) */}2<button3  type="button"4  role="button"5  aria-label="Upload files. Click, press Enter or Space, or drop files here."6  aria-describedby="file-upload-status-... file-upload-helper-..."7>8  ...9</button>10 11{/* Status region */}12<span role="status" aria-live="polite">3 files added</span>13 14{/* Per-item remove */}15<button aria-label="Remove resume.pdf">×</button>

API Reference

Complete list of props for the FileUpload component.

FileUploadProps
PropTypeDefaultDescription
valueFileUploadItem[]Controlled list of files. Omit for uncontrolled behavior.
onChange(items: FileUploadItem[]) => voidCalled whenever the list changes (add / remove).
onError(message: string, file?: File) => voidCalled for every rejected file (size / type / count).
multiplebooleanfalseAllow selecting multiple files at once.
acceptstringComma-separated MIME types or extensions, e.g. `image/*,.pdf`.
maxSizenumberMaximum size per file, in bytes.
maxFilesnumberMaximum number of files that can be selected.
disabledbooleanfalseDisable all interaction and dim the dropzone.
size'sm' | 'md' | 'lg''md'Dropzone size preset.
state'default' | 'success' | 'warning' | 'error''default'Visual state for the dropzone border and text.
labelstringOptional field label rendered above the dropzone.
helperTextstringHelper text rendered below the dropzone.
hideFileListbooleanfalseSuppress the built-in file list so the caller can render their own.
classNamestring''Additional classes appended to the root wrapper.
Note
FileUpload does not perform the actual network upload — callers are responsible for POSTing the files and updating each item's progress and status via onChange.

Other components that work well alongside File Upload.