Forms

FileUpload

File picker and drag-and-drop surface that validates files locally and can render upload progress rows.

import { FileUpload } from '@lostgradient/cinder/file-upload';
formupload
01

Overview

Accessible file picker and drag-and-drop surface that validates dropped files, announces results, and can render consumer-driven upload progress rows.

Usage

svelte
<script lang="ts">
  import FileUpload from '@lostgradient/cinder/file-upload';
  import type { FileUploadEntry } from '@lostgradient/cinder/file-upload';
  import FormField from '@lostgradient/cinder/form-field';

  let entries = $state<FileUploadEntry[]>([]);
  let uploadQueue = $state<File[]>([]);

  function queueFiles(acceptedFiles: File[]) {
    uploadQueue.push(...acceptedFiles);
  }
</script>

<FormField id="resume" label="Resume" description="PDF up to 5 MB">
  <FileUpload
    id="resume"
    accept=".pdf"
    maxSize={5 * 1024 * 1024}
    onFilesAccepted={queueFiles}
    onFilesChange={(nextEntries) => (entries = nextEntries)}
    files={entries}
  />
</FormField>

Use browseLabel when the picker action needs more specific text, such as directory or import flows. Native input attributes still pass through to the real file input, so directory selection can use webkitdirectory:

svelte
<FileUpload id="history" browseLabel="Choose directory" multiple webkitdirectory />

Upload queue and retry

FileUpload owns local validation, not network upload. Each picker selection or drop is validated as one batch before callbacks run:

  • onFilesAccepted receives the accepted native File[] so you can enqueue uploads.
  • onReject receives rejected files with too-large, wrong-type, or too-many reasons.
  • onFilesChange receives the full locally resolved queue. Accepted rows start as pending; rejected rows start as error with a visible message and rejectionReason.

The default file list includes a remove button for every row. In uncontrolled use, removing a row immediately updates the local queue and frees a maxFiles slot. In controlled use, removal reports the next queue through onFilesChange; update files with that value to reflect the change. Resetting an associated native form clears the uncontrolled queue and reports an empty list through onFilesChange.

Pass the controlled files prop to show your uploader's current pending, uploading, success, or error state. Set progress from 0–100 while an entry uploads. When you provide onFileRetry, failed rows render a retry button and return the complete entry to your upload queue handler. The component never starts, cancels, or retries a network request by itself.

Live preview
02

When to use

Use when
  • Collecting one or more files while keeping the native picker available for keyboard and assistive-technology users.
  • Showing per-file upload progress or rejection errors below a prominent dropzone surface.
Avoid when
  • You only need a hidden native file input with no custom UI.
03

Examples

Basic file upload

Drag-and-drop file picker with acceptance and rejection feedback.

04

Props

Props for file-upload
NameTypeDefaultDescription
id text Stable id for the native file input. Required when composing with FormField.
accept text Native file accept filter.
multiple boolean false Allow more than one file. Default false.
maxSize number Maximum allowed file size in bytes.
maxFiles number Maximum number of files allowed. Files beyond this limit are rejected.
disabled boolean Disables the file picker and drag-and-drop surface.
required boolean
name text Native input name used for form submission.
title text 'Click to upload or drop files' Visible title for the dropzone.
description text Visible description below the title. Defaults to a summary derived from accept.
draggingLabel text 'Drop to add' Visible label shown while files are dragged over the dropzone.
browseLabel text 'Browse files' Visible text for the browse button.
borderBeamVisible boolean true Adds focus and drag-active border emphasis to the dropzone.
files FileUploadEntry[] Consumer-driven file rows, including upload progress and error states.
idle snippet Replaces the default resting-state dropzone body.
dragActive snippet Replaces the default drag-active dropzone body.
fileList snippet Replaces the default file-list renderer. Receives the live resolved rows, including an empty array, and a removal callback when the queue is mutable.
onFilesAccepted (files: File[]) => void Fires with accepted files after local validation passes.
onFilesChange (entries: FileUploadEntry[]) => void Fires with the full resolved entry list after local validation changes it.
onReject (files: RejectedFile[]) => void Fires with rejected files and reasons after local validation runs.
onFileRetry (entry: FileUploadEntry) => void Called when the retry button is activated for a failed file.
oncancel EventHandler<Event, T>undefinednull