Data components

File upload (drag & drop)

Drop, browse or paste files; validate them and upload with progress, cancel and retry.

A drag & drop upload field

FileUploadField is a form field: users drop files on it, browse, or paste. accept, maxSize, maxFiles and maxTotalSize reject wrong files with a reason.

Uploading is your action: onUpload gets { file, onProgress, signal }, sends the file and returns the server's answer. Call onProgress(percent) for the progress bar; signal tells you the user pressed Cancel. Throw an error to mark the file as failed (the user can retry). Or set uploadUrl and the field posts the file itself.

On Submit the field must have finished uploading; its value is the list of files ([{ name, size, status, url, response }]).

Try it

Loading example…
Events0
Use the example — every action it runs shows up here with its data.

Code

Copy Full page.js into app/your-page/page.js of a Next.js app (withrcube-html, react-bootstrap and Bootstrap's CSS installed) — it runs as is. Or copy only the schema and keep your own page.

[
  {
    "type": "row",
    "id": "row-uploads",
    "props": {
      "className": "g-3"
    },
    "children": [
      {
        "type": "column",
        "id": "c-docs",
        "props": {
          "className": "col-12 col-lg-6"
        },
        "children": [
          {
            "type": "FileUploadField",
            "id": "docs",
            "props": {
              "name": "documents",
              "label": "Documents",
              "required": true,
              "accept": ".pdf,.doc,.docx,.txt,image/*",
              "maxSize": "5MB",
              "maxFiles": 4,
              "parallel": 2,
              "hint": "PDF, Word, text or images · up to 5 MB · max 4 files",
              "onUpload": "uploadFile()",
              "onValidate": "checkName()",
              "onFilesAdded": "filesAdded()",
              "onFileRejected": "fileRejected()",
              "onUploadComplete": "uploaded()",
              "onUploadError": "uploadFailed()",
              "onAllComplete": "allDone()",
              "onRemove": "removeFile()"
            }
          }
        ]
      },
      {
        "type": "column",
        "id": "c-photos",
        "props": {
          "className": "col-12 col-lg-6"
        },
        "children": [
          {
            "type": "FileUploadField",
            "id": "photos",
            "props": {
              "name": "photos",
              "label": "Photos (upload when you press the button)",
              "accept": "image/*",
              "variant": "grid",
              "autoUpload": false,
              "maxTotalSize": "20MB",
              "title": "Drop photos here",
              "buttonText": "Choose photos",
              "onUpload": "uploadPhoto()"
            }
          },
          {
            "type": "FileUploadField",
            "id": "avatar",
            "props": {
              "name": "avatar",
              "label": "Avatar (one file, compact)",
              "multiple": false,
              "compact": true,
              "accept": "image/png,image/jpeg",
              "maxSize": "2MB",
              "onUpload": "uploadPhoto()"
            }
          }
        ]
      }
    ]
  },
  {
    "type": "row",
    "id": "row-buttons",
    "children": [
      {
        "type": "column",
        "id": "c-buttons",
        "props": {
          "className": "d-flex flex-wrap gap-2 justify-content-end"
        },
        "children": [
          {
            "type": "ButtonField",
            "id": "upload-photos",
            "props": {
              "text": "Upload photos",
              "variant": "outline-primary",
              "onClick": "uploadPhotosNow()"
            }
          },
          {
            "type": "ButtonField",
            "id": "saved",
            "props": {
              "text": "Load saved documents",
              "variant": "outline-secondary",
              "onClick": "loadSaved()"
            }
          },
          {
            "type": "ButtonField",
            "id": "clear",
            "props": {
              "text": "Clear documents",
              "variant": "outline-danger",
              "onClick": "clearDocs()"
            }
          },
          {
            "type": "ButtonField",
            "id": "submit",
            "props": {
              "type": "submit",
              "text": "Submit",
              "onClick": "runValidation()"
            }
          }
        ]
      }
    ]
  }
]

Options used here

OptionWhat it does
multiple / acceptSeveral files or one; allowed types (.pdf,image/*).
maxSize / minSize / maxTotalSize / maxFiles / minFilesLimits ("5MB" or bytes).
onUpload or uploadUrlYour upload action, or the built-in POST (uploadFieldName, uploadHeaders, uploadData).
autoUpload / parallel / retriesUpload at once or on a button; uploads at a time; automatic retries.
variant / compact / dropAnywhere / pastelist or grid; small zone; drop anywhere on the page; paste files.
defaultFilesFiles already on the server [{ name, size, url }].
api.uploadFiles / clearFiles / removeFile / retryFile / openFilePicker / getFiles(name)Control it from code.

Events

EventWhen it runsYour action receives
onUploadEach file to upload.{ file, name, size, type, onProgress, signal } → return the answer
onValidateBefore a file is added.{ file, name, size, type } → return a message to reject
onFilesAdded / onFileRejectedFiles were added / refused.{ files, source } / { file, reason, message }
onUploadComplete / onUploadErrorOne upload finished / failed.{ file, response } / { file, error }
onAllCompleteA batch of uploads settled.{ files, failed }
onRemoveThe user removes a file.{ file } — return false to keep it