Media and files
Dropzone
Drag and drop, click to browse or paste files, with type, size and count validation, previews for images, GIFs, video, audio and documents, progress, retry, remove, reorder and a total; the native input stays in sync so a normal form submit sends the files. It needs monsoon.js. Without it the native file input still works.
Needs monsoon.js. The styles work on their own, and the behavior comes from the optional interactive layer: add <script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script> or import 'monsooncss/js'. See the interactive layer.
Example
<div class="dropzone max-w-xl" data-m-dropzone data-m-dropzone-max-size="10mb" data-m-dropzone-max-files="8"><label class="dropzone-area"><input type="file" name="attachments" multiple accept="image/*,video/*,audio/*,.pdf,.zip,.csv,.docx,.txt"><span class="dropzone-glyph"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 16V4M7 9l5-5 5 5M4 16v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/></svg></span><span class="grid gap-1"><span class="dropzone-title">Drop files here or <span class="dropzone-browse">browse</span></span><span class="dropzone-hint">Images, video, audio, PDF and documents up to 10 MB, 8 files at most. You can also paste.</span></span></label></div>JavaScript API
Attribute
data-m-dropzone on a .dropzone that wraps a label.dropzone-area with an <input type="file">
Options
| Option | Description |
|---|---|
data-m-dropzone-max-size | Largest file, like 10mb, 500kb or a byte count. |
data-m-dropzone-min-size | Smallest file. |
data-m-dropzone-max-files | Most files in the list (1 when the input has no multiple attribute). |
data-m-dropzone-accept | Accepted types, defaults to the input accept attribute (image/*, .pdf, application/zip). |
data-m-dropzone-simulate | false turns off the simulated upload progress, files are marked done at once. |
Methods
| Method | Description |
|---|---|
Monsoon.dropzone(el).files | The files in list order. |
Monsoon.dropzone(el).add(files) | Validates and adds files, returns the accepted ones. |
Monsoon.dropzone(el).remove(indexOrFile) | Removes one file. |
Monsoon.dropzone(el).clear() | Removes every file. |
Monsoon.dropzone(el).retry(index) | Uploads one file again. |
Monsoon.dropzone(el).validate(files) | Returns { accepted, errors } without adding anything. |
Events
| Event | Description |
|---|---|
monsoon:dropzone-change | detail.files after any add, remove or reorder. |
monsoon:dropzone-upload | One per file. Call event.preventDefault() to upload it yourself and report with detail.progress(0 to 1), detail.done(response) and detail.error(message). |
monsoon:dropzone-complete | detail.file and detail.response when an upload finishes. |
monsoon:dropzone-failed | detail.file and detail.error; the row shows a retry button. |
monsoon:dropzone-error | detail.errors: [{ file, code, message }] for rejected files (code is type, size, count or duplicate). |
monsoon:dropzone-reorder | detail.from, detail.to and detail.files after a drag or Arrow key move on the handle. |
Classes
18 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.
| Class | Type | What it does |
|---|---|---|
| Base | Base class of the dropzone. On a <div> in the example. Sets grid display, gap, width, border, background and shadow, and --tone and --tone-fg.CSS |
|
| Part | Part of the dropzone. On a <label> in the example. Sets flex display, alignment, gap, height, padding and border.CSS |
|
| Part | Part of the dropzone. On a <span> in the example. Sets grid display, alignment, width, height, margin and corner radius.CSS |
|
| Part | Part of the dropzone. On a <span> in the example. Sets text color, text size and font weight.CSS |
|
| Part | Part of the dropzone. On a <span> in the example. Sets text color and text style.CSS |
|
| Part | Part of the dropzone. On a <span> in the example. Sets text color.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets grid display, gap, padding, border, corner radius and background.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets grid display, gap, margin and padding.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets flex display, alignment, gap, width, padding and border, and 5 custom properties.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets grid display, alignment, width, height, padding and border.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets grid display, alignment, width, height, overflow and corner radius, and --kind.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets grid display, alignment, width, height, absolute position and offsets.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets border, grid display, alignment, width, height and padding.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets grid display, alignment, gap and width.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets overflow, text color, text size, font weight and text style.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets text color and text size.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets height, margin, overflow, corner radius, background and transition.CSS |
|
| Modifier | Modifier, combined with the dropzone class. Not used in the example above. Sets flex display, alignment, gap, padding, text color and text size.CSS |
Usage
The styles ship inside the same stylesheet as the utilities, and the behavior comes from the optional monsoon.js script, which enhances any element with a matching data-m attribute, including markup added later.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script>
<!-- Dropzone: start from the base class, then add modifiers -->
<div class="dropzone max-w-xl" data-m-dropzone data-m-dropzone-max-size="10mb" data-m-dropzone-max-files="8"><label class="dropzone-area"><input type="file" name="attachments" multiple accept="image/*,video/*,audio/*,.pdf,.zip,.csv,.docx,.txt"><span class="dropzone-glyph"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 16V4M7 9l5-5 5 5M4 16v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/></svg></span><span class="grid gap-1"><span class="dropzone-title">Drop files here or <span class="dropzone-browse">browse</span></span><span class="dropzone-hint">Images, video, audio, PDF and documents up to 10 MB, 8 files at most. You can also paste.</span></span></label></div>Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.
Accessibility
- Give every control a visible
labellinked withfor, or anaria-labelwhen the purpose is obvious from context. Link help and error text witharia-describedby; invalid styles use:user-invalid, so they appear only after the user interacts. - Every interactive part shows a visible focus ring with
:focus-visible, and tone colors pair with-foregroundtokens that keep text at 4.5:1 or better in light and dark mode.