Documentation
Forms
File upload
A drop zone for choosing files by dragging or browsing, with the chosen files listed below.
components/file.css
Drop zone and chosen files
- invoice-2026-114.pdf120 kB
- receipt.jpg
<div class="dsgn-stack" data-gap="s" style="max-inline-size: 32rem">
<div class="dsgn-field">
<span class="dsgn-label" id="dx-att-label">Attachments</span>
<label class="dsgn-file">
<input type="file" name="attachments" multiple accept=".pdf,image/*" aria-labelledby="dx-att-label dx-att-title" aria-describedby="dx-att-hint">
<span class="dsgn-icon" aria-hidden="true">upload</span>
<span class="dsgn-file-title" id="dx-att-title">Drop files here or <span class="dsgn-link">browse</span></span>
<span class="dsgn-file-text" id="dx-att-hint">PDF, JPG or PNG, up to 10 MB each</span>
</label>
</div>
<ul class="dsgn-list" aria-label="Chosen files">
<li><div class="dsgn-list-item"><span class="dsgn-icon" aria-hidden="true">description</span><span class="dsgn-list-item-content"><span class="dsgn-list-item-title">invoice-2026-114.pdf</span><span class="dsgn-list-item-text">120 kB</span></span>
<button class="dsgn-icon-button" data-variant="ghost" data-intent="neutral" aria-label="Remove invoice-2026-114.pdf"><span class="dsgn-icon" aria-hidden="true">close</span></button></div></li>
<li><div class="dsgn-list-item"><span class="dsgn-icon" aria-hidden="true">image</span><span class="dsgn-list-item-content"><span class="dsgn-list-item-title">receipt.jpg</span><progress class="dsgn-progress" value="40" max="100" aria-label="Uploading receipt.jpg">40 %</progress></span>
<button class="dsgn-icon-button" data-variant="ghost" data-intent="neutral" aria-label="Cancel upload of receipt.jpg"><span class="dsgn-icon" aria-hidden="true">close</span></button></div></li>
</ul>
</div>Usage
The real <input type="file"> stays in the page (keyboard, screen readers, form submit, mobile camera/gallery pickers); it is only visually hidden. The whole zone is the click target. dsgn.js adds drag and drop: while files are dragged over it the zone gets data-dragover, and dropped files go into the input (a change event fires, as if they were picked). Chosen files: render them under the zone as a List (static rows with a file icon, name, size or a Progress, and a remove icon button). Validate type and size on the server too. States: hover, keyboard focus (ring around the zone), drag over (accent), aria-invalid="true" on the input (danger outline; add a danger hint), disabled input.
Details
- Classes
.dsgn-file.dsgn-icon.dsgn-file-title.dsgn-file-text.dsgn-link- Tokens used
--dsgn-border--dsgn-border-control--dsgn-border-width--dsgn-control-solid--dsgn-control-subtle--dsgn-control-text--dsgn-danger-solid--dsgn-duration-fast--dsgn-ease--dsgn-focus--dsgn-focus-danger--dsgn-focus-offset--dsgn-focus-width--dsgn-font-sans--dsgn-font-size-body-s--dsgn-font-size-caption--dsgn-font-weight-medium--dsgn-inset--dsgn-line-height-body-s--dsgn-line-height-caption--dsgn-line-height-heading--dsgn-neutral-subtle--dsgn-radius-l--dsgn-space-4--dsgn-surface-raised--dsgn-text--dsgn-text-disabled--dsgn-text-muted- In Figma
- File upload
- Import alone
dsgn.systems/components/file.css