C-26 · Components · Inputs
All elements · Dropzone on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve Dropzone
Approving as
| Axis | Values |
|---|---|
data-state |
idle · active · reject · disabled |
data-compact |
single-row variant |
.qf-dropzone-overlay |
whole-page target for OS drags (overlayScope=page) |
Guidance
When to use
- Use a dropzone where users upload files into a record, such as attaching documents to a case.
-
Use the compact variant (
data-compact) inside forms and comment boxes where space is tight. -
Use the page overlay (
.qf-dropzone-overlay) when files can be dropped anywhere on a view, such as a document library. - Use the reject state to say at once why a dragged file is not accepted.
When to consider something else
- If the user only ever picks one file in a form, a button that opens the file dialog is enough. See Button.
- If you need to show upload progress per file, pair the dropzone with a list and progress bars. See Progress.
- If files are dragged between items already in the app, use the list's or kanban's drag and drop instead. See List.
Usability
- Say what can be uploaded in
__hint: file types and size limit. - Always offer "click to browse" so drag is never required.
- Show the number of files in the active state, such as "Release to upload 3 files".
- Explain the rejection in plain words, such as ".exe files are not accepted".
- Don't make drag and drop the only way to add files.
- Don't rely on the red border alone for the reject state.
- Don't leave a disabled dropzone in the tab order.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves focus to the dropzone. |
| Enter or Space | The binding must open the system file dialog. |
Roles and names
-
The specimen is a
<div tabindex="0">with no role; the binding must make it a<button>(orrole="button") or put a real button inside, backed by a hidden<input type="file">withacceptandmultipleas needed. - The accessible name must include the prompt and hint, such as "Upload files, PDF, DOCX, XLSX up to 25 MB".
- The icon is decorative.
-
data-state="disabled"only dims the zone; the binding must also setaria-disabled="true"and remove it from the tab order.
Focus
- The dropzone shows the token focus ring.
- After the file dialog closes, focus returns to the dropzone; after upload, the binding may move focus to the new file in the list.
Other requirements
- 2.5.7 Dragging Movements: click to browse is the single-pointer alternative to drag, so it must always work.
- Announce accepted files, rejections and upload results in a live region (4.1.3); the reject text is not otherwise read.
- The a11y report lists the reject prompt as dark-theme contrast debt (1.4.3).
- The dashed border must reach 3:1 against the surface (1.4.11).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (2 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (4 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- dropzone --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.