GitHub repository

FileDrop

Drag-and-drop file upload with click-to-browse.

A focusable drop zone that wraps a visually-hidden file input. Drag files in, or activate it with click / Enter / Space to open the native picker. Selections honour `accept` and `multiple`, render each file name with a human-readable size, and expose per-file remove plus a Clear control. Two-way `bind:files` and an `onfiles` callback keep callers in sync; `hint`/`error` provide field chrome and the error is announced to assistive tech.

Demo

live · storybook Open in Storybook

Demo loads from https://dssoca-storybook.vercel.app/. Run pnpm storybook for it to render locally.

Usage

svelte
<script>
  import { FileDrop } from 'dssoca';
  let files = $state([]);
</script>

<FileDrop label="Attachments" bind:files onfiles={(f) => console.log(f)} />
<FileDrop label="Config" accept="application/json,.json" hint="JSON only" />

The drop zone is `role="button"` + `tabindex=0` with an `aria-label` derived from the label/hint; the native `<input type="file">` is visually hidden and activated programmatically. WCAG 2.2 AA; vitest-axe clean.

HTML

CSS only — static markup The exact markup the component renders, generated at build time. Use it with dssoca/vanilla.css — see Plain HTML & CSS.

html
<div class="ss-filedrop">
  <span class="lbl" id="file-drop-s1-label">Upload</span>
  <input class="native" id="file-drop-s1-input" type="file" accept="image/*" tabindex="-1" aria-hidden="true"/>
  <div class="zone" role="button" tabindex="0" aria-label="Upload. PNG or JPG, up to 5 MB" aria-describedby="file-drop-s1-hint">
    <span class="prompt">
      <span class="title">Drop files here</span>
      <span class="sub">or click to browse</span>
    </span>
  </div>
  <span class="msg hint" id="file-drop-s1-hint">PNG or JPG, up to 5 MB</span>
</div>

Static zone + hidden input: wire drag/drop and the file list yourself.

Props

PropTypeDefaultDescription
labelstring—Field label; folded into the zone's accessible name.
acceptstring—Native accept filter (e.g. 'application/json,.json'); also enforced on drop.
multiplebooleanfalseAllow selecting/dropping more than one file.
disabledbooleanfalseDisables pointer + keyboard activation and mutes the chrome.
hintstring—Supplementary helper text rendered under the zone.
errorstring—Error text rendered under the zone; announced to AT via role="alert".
filesFile[][]Selected files. Bindable (`bind:files`).
onfiles(files: File[]) => void—Fired with the resolved file list whenever the selection changes.
size'sm' | 'md' | 'lg'—Per-instance size override; inherits the ancestor `data-size-variant` when unset.
↑↓ navigate · ↵ open · esc close

Keyboard shortcuts

No shortcuts registered

Shortcuts added through the dssoca registry will show up here.

Single-key shortcuts