File upload

Collects validated files through browse or drop, with optional upload progress, cancellation, and retry.

Choose filesPDF or text, up to 10 MB each. Files stay on this device.

Attach the context

Project files

Add a brief or notes. This example keeps the selected files on your device.

Choose project filesPDF or text, up to 10 MB each

Use it for

  • Validated attachment queues with native file browsing and drag-and-drop.
  • Provide onUpload when the app has a transport; it receives an AbortSignal and progress callback.

Not for

  • Assuming files upload automatically; without onUpload this only collects selected files.
  • Client checks as security enforcement; validate uploaded files again on the server.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { FileUpload } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/file-upload.

2. Vendor the source

npx @noorddev/vlak-cli add file-upload

The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/file-upload.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { FileUpload } from "@noorddev/vlak-react";

<FileUpload label="Project files" name="attachments" accept=".pdf,.txt" maxFiles={5} maxSize={10 * 1024 * 1024} description="PDF or text, up to 10 MB each" />

FileUpload

Validated file selection, with an optional cancellable upload transport.

PropTypeDefaultDescription
valueFile[]
defaultValueFile[][]
onValueChange(files: File[]) => void
acceptstring
multiplebooleantrue
maxFilesnumber
maxSizenumber
disabledboolean
namestring
labelstring"Choose files"
descriptionReactNode"Drop files here or browse"
onReject(rejections: FileUploadRejection[]) => void
onUpload(file: File, context: FileUploadContext) => Promise<void>Optional transport supplied by the app. Omit to collect files without uploading.

Also accepts Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue">.

KeysDoes
Tab, Enter, SpaceReaches the native file picker and labeled Remove, Cancel, and Retry actions.
<div class="rs-file-upload"><div class="rs-file-upload-drop"><span class="rs-file-upload-title">Choose files</span><span class="rs-file-upload-description" id="files-hint">Drop files here or browse</span><input class="rs-file-upload-input" type="file" multiple aria-label="Choose files" aria-describedby="files-hint" /></div></div>
.rs-file-upload.rs-file-upload-drop.rs-file-upload-drag.rs-file-upload-input.rs-file-upload-title.rs-file-upload-description.rs-file-upload-list.rs-file-upload-item.rs-file-upload-row.rs-file-upload-name.rs-file-upload-actions.rs-file-upload-action.rs-file-upload-status