File upload

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

Choose filesDrop files here or browse

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