FileInput

A native file picker and drop zone sharing type, size and count validation. File parsing and uploading remain caller-owned; the component provides processing, cancellation, rejection messages and retry around your on_files callback.

Minimal example

Choose or drop up to three text files. A new accepted selection replaces the previous files; it does not append to them. Rejected files leave the current selection intact when no incoming files pass validation.

No files selected yet.

svelte<script lang="ts">
  import { FileInput } from 'svelte-widgets'

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

<FileInput
  bind:files
  accept=".txt,.csv,text/plain,text/csv"
  multiple
  max_files={3}
  max_size={1000000}
  label="Choose text files"
/>
<p>{files.length ? `${files.length} files selected` : `No files selected yet.`}</p>

Parse JSON with cancellation and retry

Select a valid JSON file to preview it, or a malformed one to exercise the error state. Throwing from on_files displays the error with a Retry button. The supplied signal is aborted when accepted files replace the selection, the operation is cancelled, a file is removed, the input becomes disabled or the component unmounts. File.text() itself cannot be cancelled, so check the signal before publishing its result.

No JSON preview available.

svelte<script lang="ts">
  import { FileInput, JsonTree } from 'svelte-widgets'

  let preview = $state<{ value: unknown }>()

  async function read_json(files: File[], signal: AbortSignal): Promise<void> {
    preview = undefined
    const text = await files[0].text()
    signal.throwIfAborted()
    preview = { value: JSON.parse(text) }
  }
</script>

<FileInput
  accept=".json,application/json"
  max_size={1000000}
  label="Choose a JSON file"
  on_files={read_json}
  on_remove={() => (preview = undefined)}
/>
{#if preview}
  <JsonTree value={preview.value} />
{:else}
  <p>No JSON preview available.</p>
{/if}

For uploads, build a FormData and pass the signal to fetch; throw when response.ok is false. Retry calls on_files again with the current accepted files. Cancellation stops the component’s processing state, but your callback must respect the signal to prevent stale results.

Main API

PropPurpose
bind:filesCurrent accepted File[], initially empty.
acceptComma-separated extensions, MIME types or MIME wildcards. Checked for both picker and drops.
multiple={false}, max_files, max_sizePer-selection count and per-file byte limits. Limits otherwise default to infinity.
on_files(files, signal)Parse or upload accepted files, synchronously or asynchronously.
on_reject(rejections)Receive { file, reason } entries with reason type, size or count.
on_remove(file)Observe removal from the default file list.
children(files)Replace the default list with a custom preview; provide your own removal controls if needed.
label, remove_label, disabledPicker label, removal button text and disabled state.

Keyboard and feedback

Tab reaches the native file picker and removal, cancel or retry buttons. Activate them with the browser’s usual keyboard controls; drag and drop is optional. Validation failures are announced through a status region, and asynchronous errors use TaskStatus. Client-side accept checks are for user feedback; validate content and limits again at your upload endpoint.