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
Usage
<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.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Field label; folded into the zone's accessible name. |
accept | string | — | Native accept filter (e.g. 'application/json,.json'); also enforced on drop. |
multiple | boolean | false | Allow selecting/dropping more than one file. |
disabled | boolean | false | Disables pointer + keyboard activation and mutes the chrome. |
hint | string | — | Supplementary helper text rendered under the zone. |
error | string | — | Error text rendered under the zone; announced to AT via role="alert". |
files | File[] | [] | 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. |