Skip to main content

FileUpload

FileUpload

File upload component with drag-and-drop support

Tags: component form upload

View Demo

FileUpload provides an intuitive interface for uploading files with drag-and-drop support.

Import​

<script>
  import { FileUpload } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<script>
  let files = $state([]);
</script>

<FileUpload bind:files />

Props​

Prop Type Default Description
files FileMetadata[] [] Uploaded files (bindable)
acceptedTypes string[] ['image/*', 'application/pdf'] Accepted MIME types; type/* matches a whole category
maxSizeBytes number 10485760 (10 MB) Max file size in bytes
maxFiles number 10 Max number of files; above 1 the picker allows several at once
disabled boolean false Disables upload
error string - External error message
onUpload (file: File) => Promise<FileMetadata> - Upload handler; without one, files are kept locally
onFilesChange (files: FileMetadata[]) => void - Called when the file list changes (files added or removed)
label string - Label text
hint string - Hint text shown below the drop zone
typesLabel string - Readable label for the accepted types; derived from acceptedTypes if unset
previewLayout 'list' | 'grid' 'list' list rows, or grid media thumbnails
preview boolean false Open a lightbox when a preview is activated
id string generated Input ID
class string - Additional classes

Types​

interface FileMetadata {
  id: string;
  filename: string;
  contentType: string;
  size: number;
  url?: string;
  progress?: number;
  error?: string;
  uploading?: boolean;
}

Accept Specific Types​

Restrict accepted file types by MIME type:

<!-- Images only -->
<FileUpload acceptedTypes={['image/*']} bind:files />

<!-- PDF documents -->
<FileUpload acceptedTypes={['application/pdf']} bind:files />

<!-- Multiple types -->
<FileUpload
  acceptedTypes={[
    'image/*',
    'application/pdf',
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  ]}
  bind:files
/>

Multiple Files​

maxFiles caps the list; any value above 1 lets the picker select several files at once. Use maxFiles={1} for a single file:

<FileUpload bind:files maxFiles={5} />

Size Limits​

Set maximum file size:

<FileUpload bind:files maxSizeBytes={5 * 1024 * 1024} error={sizeError} />

Custom Upload Handler​

Handle file uploads:

<script>
  async function handleUpload(file: File): Promise<FileMetadata> {
    const formData = new FormData();
    formData.append('file', file);

    const response = await fetch('/api/upload', {
      method: 'POST',
      body: formData,
    });

    const data = await response.json();

    return {
      id: data.id,
      filename: file.name,
      contentType: file.type,
      size: file.size,
      url: data.url,
    };
  }
</script>

<FileUpload bind:files onUpload={handleUpload} />

Examples​

Profile Picture​

<FileUpload
  acceptedTypes={['image/*']}
  maxFiles={1}
  maxSizeBytes={2 * 1024 * 1024}
  bind:files={avatar}
  onUpload={uploadAvatar}
/>

Document Upload​

<FileUpload
  acceptedTypes={['application/pdf', 'application/msword']}
  maxFiles={10}
  maxSizeBytes={10 * 1024 * 1024}
  bind:files={documents}
  onUpload={uploadDocument}
/>

With Progress​

Files show upload progress:

<FileUpload
  bind:files
  onUpload={async (file) => {
    // Upload with progress tracking
    return await uploadWithProgress(file, (progress) => {
      // Progress updates automatically
    });
  }}
/>

Accessibility​

  • Keyboard accessible drop zone
  • Screen reader announcements
  • Clear status indicators
  • Input - Basic file input
  • Button - Manual upload trigger
On this page