Skip to content
Work in progress - do not use in production. This component is still being built: it is not flagged Ready for Dev, so its markup, attributes, events and styles can all still change without notice, it is not covered by the accessibility gate, and it is not published to npm. It is on this site so the work can be seen and reviewed - nothing more.

Uploader

An accessible, zero-dependency multi-file upload with client-side previews, built on the native file input: <input type="file" is="root-uploader">.

Usage

<label>Attachments <input type="file" is="root-uploader" variant="image" multiple accept="image/*" /></label>

The previews are the source of truth. Selected files are kept in an insertion-ordered Map (keyed by a name/size/lastModified signature, so picking the same file twice de-duplicates and successive picks append), and the preview list renders from it. The native FileList is left untouched until commit() rebuilds it from the Map via a DataTransfer - which <form is="root-form"> calls on submit, so what gets sent is exactly what the user sees.

Each preview carries the file name and a per-file remove button; a visually-hidden role="status" region announces the count, image thumbnails use alt="" (the filename carries the name), and object URLs are revoked on removal and disconnect.

Drag and drop

The native input is wrapped in a [data-part="dropzone"] - a real target to drop files onto, not just the small native picker button, highlighted while a file is dragged over it. Dropped files are filtered against accept and merge into the same de-duplicated set as picked files; a non-multiple uploader replaces rather than appends, matching what the native picker would do. The native input itself is unaffected and stays keyboard/screen-reader operable - drag and drop is a progressive enhancement alongside it, not a replacement.

Variants

variant Preview
image Image thumbnails (object URLs)
document A document card with icon, name, MIME type and size
(none) Thumbnail for images, document card otherwise

Methods

Method Description
commit() Rebuild the native FileList from the previews (via DataTransfer) - called by root-form on submit
removeFile(key) Remove the file with the given signature key and re-render
ingest() Merge the current native selection into the Map and re-render (runs on change)

Events

Event Detail Description
root-uploader.change { count } Fired after the preview list re-renders

Extends

HTMLInputElement - use with <input type="file" is="root-uploader">.