// preview in
saved for every page

File upload

A drop area with a real file input behind a button, plus a list that shows each file's progress, result or error. It reports files; sending them is up to your app.

Built on HTMLPattern Native file input + role=groupClient componentSource ↗
minimal · light · #3fa34d

Drag files here or browse your computer

PDF, PNG or JPG up to 10 MB

multiple
disabled

Installation

Set up Camaleo once (Installation), then import the zone and the list.

import { Dropzone, FileList, FileItem } from "@camaleo/react";

Anatomy

The Dropzone is a labelled group with a button that opens the file picker. Each FileItem in a FileList has an icon, the name, a progress bar or meta line, and your actions.

icontitledescriptionChoose filesq3-report.pdf · 64%
[data-slot="dropzone"] · [data-slot="file-list"] · [data-slot="file-item"][data-slot="dropzone-icon"] · [data-slot="dropzone-title"] · [data-slot="dropzone-description"] · button[data-slot="file-item-name"] · [data-slot="file-item-meta"] · progress

Examples

Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above. Nothing leaves your browser: uploads are simulated with timers.

minimal · light · #3fa34d

Drag files here or browse your computer

PDF, PNG or JPG up to 10 MB

    Add product photos

    PNG or JPG up to 2 MB each

      Types and size limit

      Drop a PDF or a large photo. accept and maxSize sort the files, onFilesRejected says why for each one, and a status line announces the result.

      Drag files here or browse your computer

      PDF, PNG or JPG up to 10 MB

      • cover.png
        Uploaded · 1.2 MB

      Progress, cancel and remove

      Add a file. Keep the upload state yourself and map it to status, progress and meta; the bar takes its name from the file.

      • board-minutes.docx
        Ready to send · 0.8 MB
      • q3-report.pdf64% · 2.4 of 3.8 MB
        x
      • cover.png
        Uploaded · 1.2 MB
      • site-tour.mov

        Larger than 10 MB. Trim the video or share a link to it.

      Every status

      status drives the row: idle before sending, uploading with a bar, done with a check, error with the message.

      • bank-statement-september.pdf

        Connection lost at 48%. Your file is still here.

      Retry after an error

      Click retry. A failed row keeps the file and offers the next step, so people never pick it again from the folder.

      Upload your logo

      SVG, PNG or JPG up to 5 MB

      One image

      With multiple={false} only the first file is reported, and choosing again replaces it; the row shows its name, type and size.

      • lease-agreement-signed.pdfScanning for viruses…
        x

      Unknown progress

      When the server can't measure it (a virus scan, a conversion), pass progress={null} and say in meta what is happening.

      Drag files here or browse your computer

      Storage full: 15 GB of 15 GB used. Delete old files or upgrade your plan.

      Disabled, with a reason

      disabled ignores drops and disables the button. Use the description to say why and what to do instead.

      In context

      Uploads are part of a task. These are whole pieces of UI you can copy, in the skin you picked.

      New support ticket

      We usually answer within 4 business hours.

      Attach screenshots or logs

      PNG, JPG, PDF or TXT up to 10 MB

      • checkout-error.png
        0.4 MB
      Support ticket attachmentsCard · Field · Input · Textarea · Dropzone · FileList · IconButton

      Profile photo

      Shown next to your comments and in the team directory.

      AS
      Ana Souza
      Product designer

      Drop a photo or browse

      Square PNG or JPG up to 2 MB

      Profile photoCard · Avatar · Dropzone · FileItem · Button

      Import contacts

      Upload a CSV exported from your CRM. Columns: name, email, company.

      Drop your CSV file

      CSV up to 20 MB, one contact per row

      Import contacts from CSVCard · Dropzone · FileItem · Button

      Guidelines

      Drag files here or browse

      PDF, PNG or JPG up to 10 MB

      DoSay the types and the limit.

      People check before they drag, and no file is refused by surprise.

      Drop files here

      Don’tA bare drop area.

      The rules exist anyway; people only learn them when a file fails.

      • site-tour.mov

        Larger than 10 MB. Trim the video or share a link to it.

      DoSay how to fix it.

      The error names the limit and the way out, right on the file.

      • site-tour.mov

        Upload failed.

      Don’tA generic error.

      "Upload failed." leaves people retrying the same file.

      Props

      PropTypeDefaultDescription
      titleReactNode—The zone's heading; it also names the group.
      descriptionReactNode—Accepted types and size, in words ("PNG, JPG ou PDF até 10 MB").
      buttonLabelReactNode"Choose files"Text of the button that opens the file picker.
      iconReactNode—Replaces the upload icon.
      acceptstring—Same syntax as <input accept>: extensions, MIME types, image/*.
      multiplebooleantrueAccepts several files at once; when false, only the first one is reported.
      maxSizenumber—Largest accepted file, in bytes.
      disabledbooleanfalseIgnores drops and disables the button.
      onFilesAccepted((files: File[]) => void)—Called with the files that pass accept and maxSize.
      onFilesRejected((rejections: FileRejection[]) => void)—Called with the files that fail, each with reason: "type" | "size".

      These are the props of Dropzone; children render between the description and the button. A rejection is { file, reason: "type" | "size" }. FileList takes the attributes of <ul>; give it an aria-label.

      FileItem shows one file:

      PropTypeDefaultDescription
      name*ReactNode—The file name. It also labels the progress bar.
      metaReactNode—Size, progress text or status ("64% · 2,4 de 3,8 MB", "Enviado · 1,2 MB").
      status"done" | "error" | "idle" | "uploading""idle"Uploading shows a progress bar; done adds a check; error shows error.
      progressnumber | nullnull0–100 while uploading; null is indeterminate.
      errorReactNode—Message shown when status="error".
      iconReactNode—Replaces the file icon (the danger icon on error).
      actionsReactNode—Buttons at the end of the row (cancel, remove, retry). Name them with the file.

      Other <li> attributes pass through.

      Styling hooks

      Restyle it without forking: target the attributes, or set the tokens on a parent, a skin or the zone itself.

      Attributes

      data-slot"dropzone" · "dropzone-icon" · "dropzone-title" · "dropzone-description" · "file-list" · "file-item" · "file-item-icon" · "file-item-body" · "file-item-header" · "file-item-name" · "file-item-meta" · "file-item-error"
      data-draggingon the dropzone while files are dragged over it
      data-disabledon the dropzone when disabled
      data-status"idle" · "uploading" · "done" · "error", on each file item

      Tokens it reads

      Color

      --cml-accent-text--cml-border--cml-border-control--cml-danger--cml-fg--cml-fg-muted--cml-fg-secondary--cml-file-icon-fg--cml-file-item-bg--cml-file-item-border--cml-file-item-shadow--cml-focus-ring--cml-radius-surface--cml-surface-raised

      Shape & size

      --cml-file-icon-radius--cml-file-item-radius--cml-font-size-field--cml-font-size-help--cml-radius-control--cml-radius-pill--cml-radius-popover

      Type & motion

      --cml-duration-fast--cml-ease-standard--cml-font-label--cml-font-weight-label--cml-tone-line

      This component only

      --cml-corner-shape--cml-disabled-opacity--cml-dropzone-border--cml-dropzone-icon-bg--cml-dropzone-icon-border--cml-dropzone-icon-fg--cml-dropzone-icon-shadow--cml-dropzone-radius--cml-dropzone-shadow--cml-tone-soft

      Accessibility

      TabMoves focus to the button inside the zone.
      Enter / SpaceOpens the system file picker.
      Tab (in the list)Moves through each file's actions.
      Was this page helpful? · Edit this page on GitHub