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
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
| Option | What it does |
|---|---|
multiple / accept | Several files or one; allowed types (.pdf,image/*). |
maxSize / minSize / maxTotalSize / maxFiles / minFiles | Limits ("5MB" or bytes). |
onUpload or uploadUrl | Your upload action, or the built-in POST (uploadFieldName, uploadHeaders, uploadData). |
autoUpload / parallel / retries | Upload at once or on a button; uploads at a time; automatic retries. |
variant / compact / dropAnywhere / paste | list or grid; small zone; drop anywhere on the page; paste files. |
defaultFiles | Files already on the server [{ name, size, url }]. |
api.uploadFiles / clearFiles / removeFile / retryFile / openFilePicker / getFiles(name) | Control it from code. |
Events
| Event | When it runs | Your action receives |
|---|---|---|
onUpload | Each file to upload. | { file, name, size, type, onProgress, signal } → return the answer |
onValidate | Before a file is added. | { file, name, size, type } → return a message to reject |
onFilesAdded / onFileRejected | Files were added / refused. | { files, source } / { file, reason, message } |
onUploadComplete / onUploadError | One upload finished / failed. | { file, response } / { file, error } |
onAllComplete | A batch of uploads settled. | { files, failed } |
onRemove | The user removes a file. | { file } — return false to keep it |