File Upload

File upload surface with previews, validation, queue states, and optional real upload hooks.

Installation

npx shadcn@latest add @iconiq/file-upload

File Structure

Usage

"use client";

import { FileUpload } from "@/components/ui/file-upload";

export function FileUploadPreview() {
  return (
    <div className="w-full">
      <FileUpload
        accept="image/*,.pdf"
        maxFiles={5}
        maxSize={1024 * 1024}
        preventDuplicates
      />
    </div>
  );
}

Props

Props
Description

FileUpload

accept

Optional accept string passed to the hidden file input and enforced for dropped or pasted files, including MIME types like image/* and extensions like .pdf.

Type string

multiple

Allows selecting or dropping multiple files. When set to false, the next selection replaces the existing queue.

Type boolean·Default true

maxFiles

Caps the queue length. New files are prepended, and anything beyond the limit is rejected with inline feedback.

Type number

maxSize

Maximum file size in bytes. Files above the limit are rejected with inline feedback.

Type number

disabled

Disables click, drag, paste, keyboard activation, remove, clear-all, and the hidden file input.

Type boolean·Default false

required

Forwards required validation to the hidden file input when the queue is empty.

Type boolean·Default false

invalid

Marks the drop zone with invalid styling for external validation states.

Type boolean·Default false

preventDuplicates

Rejects files that match an existing queue item by name, size, and lastModified.

Type boolean·Default false

simulateUpload

Controls built-in progress simulation. Defaults to true when onUpload is not provided, and false when onUpload is set.

Type boolean

showClearAll

Shows a clear-all action when the queue has files.

Type boolean·Default true

name

Passes a form field name through to the hidden file input. The queue stays synced to the input for native form submission.

Type string

id

Root id used for the hidden file input and internal aria-describedby wiring.

Type string

ariaLabel

Accessible label for the keyboard-focusable drop zone.

Type string·Default Upload files

ariaDescribedBy

Additional ids merged into the drop zone aria-describedby list.

Type string

description

Optional helper text rendered above the drop zone.

Type string

dropzoneTitle

Custom primary drop zone label.

Type string

dropzoneDescription

Custom secondary drop zone hint. When omitted, a hint is generated from accept, maxFiles, and maxSize.

Type string

libraryLabel

Heading label for the queued file list.

Type string·Default Library

browseLabel

Label for the browse affordance in the drop zone.

Type string·Default Browse

clearAllLabel

Label for the clear-all action.

Type string·Default Clear all

className

Adds classes to the outer wrapper without changing the component internals.

Type string

defaultValue

Initial queue files for uncontrolled usage.

Type File[]

value

Controlled queue state including per-file progress and status.

Type FileUploadItem[]

validateFile

Custom per-file validator. Return true to accept, false to reject, or a string error message.

Type (file: File) => boolean | string

onFilesChange

Called when files are added or removed from the queue. It does not fire on every progress tick.

Type (files: File[]) => void

onValueChange

Called when the queue changes, including status and progress updates in controlled mode.

Type (items: FileUploadItem[]) => void

onFileRemove

Called after a queued file is removed. The second argument contains the remaining files in queue order.

Type (file: File, nextFiles: File[]) => void

onReject

Called when one or more files fail accept, size, duplicate, max-files, validation, or disabled checks.

Type (files: File[], reason: FileUploadRejectReason, message: string) => void

onUpload

Optional real upload handler. When provided, built-in progress simulation is disabled unless simulateUpload is explicitly set to true.

Type (file: File, context: { setProgress: (progress: number) => void }) => Promise<void>

onUploadComplete

Called once every item in the current queue reaches done status.

Type (files: File[]) => void

Built-in behavior

progress state

Each added file starts in uploading state. Without onUpload, a simulated progress loop runs until done. With onUpload, progress follows setProgress from your handler.

Type built-in

error + retry

Failed onUpload calls move a file to error status and expose a retry action that reruns the upload handler or restarts simulation.

Type built-in

image and video previews

Image and video files receive object URL previews. Upload progress renders as an overlay on thumbnails and as a ring for other file types.

Type built-in

remove + clear all

Each queued file can be removed individually. Clear all empties the queue and revokes preview URLs immediately.

Type built-in

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: motion, lucide-react.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.

Drop, click, or paste to upload

Images, videos, audio, or documents

Browse