Dropzone
Drop, choose or paste files; checked for type, size and count before they are handed over.
Rendering Dropzone…
Installation
Copy the source into your project with the CLI. It lands under @/components/ui and is yours to edit.
npx mlola-ui add dropzoneUsage
"use client";
import * as React from "react";
import { Dropzone } from "@/components/ui/dropzone";
export default function Example() {
const [files, setFiles] = React.useState<File[]>([]);
return (
<Dropzone
label="Attachments"
hint={files.length ? `${files.length} selected` : "PNG or PDF, up to 10 MB"}
accept="image/png,application/pdf"
maxSize={10 * 1024 * 1024}
multiple
onFiles={setFiles}
/>
);
}Styling comes from the engine stylesheet and the nearest theme. Set it once at the root:
<html data-theme="graphite" data-mode="light">HTML
The markup the example above renders, at rest. The interaction lives in the React component; from another framework, set the attributes below as the state changes.
<div class="ml-dropzone-root">
<div class="ml-input-field">
<label class="ml-input-label" id="dropzone-1-label" for="dropzone-1">Attachments</label>
<div class="ml-dropzone" id="dropzone-1" role="button" tabindex="0" aria-label="Attachments: drop files here, or press Enter to choose" aria-describedby="dropzone-1-hint">
<span class="ml-dropzone-icon" aria-hidden="true"><svg class="mlola-glyph" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="var(--mlola-glyph-stroke, var(--ml-icon-stroke, 1.75))" stroke-linecap="round" stroke-linejoin="round" focusable="false" aria-hidden="true" data-optical-size="default" style="color:var(--mlola-glyph-color, currentColor);scale:var(--mlola-glyph-optical-scale, 1);transform-origin:center"><path d="M12 15V3m-5 5 5-5 5 5M5 21h14" pathLength="1"></path></svg></span>
<span class="ml-dropzone-title">Drop files here, or choose</span>
<span class="ml-dropzone-rules">PNG, PDF · up to 10.0 MB</span>
<input type="file" hidden="" accept="image/png,application/pdf" multiple=""/>
</div>
<p class="ml-input-hint" id="dropzone-1-hint">PNG or PDF, up to 10 MB</p>
</div>
</div>Classes and attributes
A class names each element; data-* and aria-* attributes carry its variant and state. The values listed are the ones the stylesheet draws; the default needs no attribute.
| Class | Attributes |
|---|---|
ml-dropzone-root | — |
ml-dropzone | aria-disableddata-dragging |
ml-dropzone-icon | — |
ml-dropzone-title | — |
ml-dropzone-rules | — |
ml-dropzone-rejected | — |
ml-dropzone-files | — |
ml-dropzone-file | data-status="error" |
ml-dropzone-file-name | — |
ml-dropzone-file-meta | — |
ml-dropzone-remove | — |
ml-dropzone-progress | — |
Accessibility and theming
- Semantic elements, accessible names and state relationships are part of the contract.
- Keyboard, pointer and touch paths are operable; focus stays visible in every theme.
- Light and dark modes pass WCAG AA contrast in all 5 canonical themes.
- Reduced motion and forced colors keep meaning and operation.
Dependencies
Installed alongside this component. No third-party UI runtime is ever added.
- input
@mlola-ui/icons